001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.control.user.geo.server.command;
018
019import com.echothree.control.user.geo.common.form.CreateCountryForm;
020import com.echothree.control.user.geo.common.result.GeoResultFactory;
021import com.echothree.model.control.contact.server.control.ContactControl;
022import com.echothree.model.control.geo.common.GeoCodeAliasTypes;
023import com.echothree.model.control.geo.common.GeoCodeScopes;
024import com.echothree.model.control.geo.common.GeoCodeTypes;
025import com.echothree.model.control.geo.server.control.GeoControl;
026import com.echothree.model.control.geo.server.logic.GeoCodeLogic;
027import com.echothree.model.control.geo.server.logic.GeoCodeScopeLogic;
028import com.echothree.model.control.geo.server.logic.GeoCodeTypeLogic;
029import com.echothree.model.control.party.common.PartyTypes;
030import com.echothree.model.control.security.common.SecurityRoleGroups;
031import com.echothree.model.control.security.common.SecurityRoles;
032import com.echothree.model.control.sequence.common.SequenceTypes;
033import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
034import com.echothree.model.data.geo.server.entity.GeoCode;
035import com.echothree.util.common.command.BaseResult;
036import com.echothree.util.common.message.ExecutionErrors;
037import com.echothree.util.common.persistence.BasePK;
038import com.echothree.util.common.validation.FieldDefinition;
039import com.echothree.util.common.validation.FieldType;
040import com.echothree.util.server.control.BaseSimpleCommand;
041import com.echothree.util.server.control.CommandSecurityDefinition;
042import com.echothree.util.server.control.PartyTypeDefinition;
043import com.echothree.util.server.control.SecurityRoleDefinition;
044import com.echothree.util.server.persistence.Session;
045import java.util.Arrays;
046import java.util.Collections;
047import java.util.List;
048import javax.enterprise.context.RequestScoped;
049
050@RequestScoped
051public class CreateCountryCommand
052        extends BaseSimpleCommand<CreateCountryForm> {
053    
054    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
055    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
056    
057    static {
058        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
059                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
060                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
061                        new SecurityRoleDefinition(SecurityRoleGroups.Country.name(), SecurityRoles.Create.name())
062                        )))
063                )));
064        
065        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
066                new FieldDefinition("CountryName", FieldType.ENTITY_NAME, true, null, null),
067                new FieldDefinition("Iso3Number", FieldType.NUMBER_3, true, null, null),
068                new FieldDefinition("Iso3Letter", FieldType.UPPER_LETTER_3, true, null, null),
069                new FieldDefinition("Iso2Letter", FieldType.UPPER_LETTER_2, true, null, null),
070                new FieldDefinition("TelephoneCode", FieldType.STRING, false, 1L, 5L),
071                new FieldDefinition("AreaCodePattern", FieldType.REGULAR_EXPRESSION, false, null, null),
072                new FieldDefinition("AreaCodeRequired", FieldType.BOOLEAN, true, null, null),
073                new FieldDefinition("AreaCodeExample", FieldType.STRING, false, 1L, 5L),
074                new FieldDefinition("TelephoneNumberPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
075                new FieldDefinition("TelephoneNumberExample", FieldType.STRING, false, 1L, 25L),
076                new FieldDefinition("PostalAddressFormatName", FieldType.ENTITY_NAME, true, null, null),
077                new FieldDefinition("CityRequired", FieldType.BOOLEAN, true, null, null),
078                new FieldDefinition("CityGeoCodeRequired", FieldType.BOOLEAN, true, null, null),
079                new FieldDefinition("StateRequired", FieldType.BOOLEAN, true, null, null),
080                new FieldDefinition("StateGeoCodeRequired", FieldType.BOOLEAN, true, null, null),
081                new FieldDefinition("PostalCodePattern", FieldType.REGULAR_EXPRESSION, false, null, null),
082                new FieldDefinition("PostalCodeRequired", FieldType.BOOLEAN, true, null, null),
083                new FieldDefinition("PostalCodeGeoCodeRequired", FieldType.BOOLEAN, true, null, null),
084                new FieldDefinition("PostalCodeLength", FieldType.UNSIGNED_INTEGER, false, null, null),
085                new FieldDefinition("PostalCodeGeoCodeLength", FieldType.UNSIGNED_INTEGER, false, null, null),
086                new FieldDefinition("PostalCodeExample", FieldType.STRING, false, 1L, 15L),
087                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
088                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
089                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
090                ));
091    }
092    
093    /** Creates a new instance of CreateCountryCommand */
094    public CreateCountryCommand() {
095        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
096    }
097
098    @Override
099    protected BaseResult execute() {
100        var geoCodeTypeLogic = GeoCodeTypeLogic.getInstance();
101        var result = GeoResultFactory.getCreateCountryResult();
102        var geoControl = Session.getModelController(GeoControl.class);
103        GeoCode geoCode = null;
104        var geoCodeType = geoCodeTypeLogic.getGeoCodeTypeByName(this, GeoCodeTypes.COUNTRY.name());
105
106        if(!hasExecutionErrors()) {
107            var geoCodeScopeLogic = GeoCodeScopeLogic.getInstance();
108            var geoCodeScope = geoCodeScopeLogic.getGeoCodeScopeByName(this, GeoCodeScopes.COUNTRIES.name());
109
110            if(!hasExecutionErrors()) {
111                var geoCodeLogic = GeoCodeLogic.getInstance();
112                var iso3Number = form.getIso3Number();
113
114                geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.ISO_3_NUMBER.name(), iso3Number);
115
116                if(geoCode == null && !hasExecutionErrors()) {
117                    var iso3Letter = form.getIso3Letter();
118
119                    geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.ISO_3_LETTER.name(), iso3Letter);
120
121                    if(geoCode == null && !hasExecutionErrors()) {
122                        var iso2Letter = form.getIso2Letter();
123
124                        geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.ISO_2_LETTER.name(), iso2Letter);
125
126                        if(geoCode == null && !hasExecutionErrors()) {
127                            var countryName = form.getCountryName();
128
129                            geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.COUNTRY_NAME.name(), countryName);
130
131                            if(geoCode == null && !hasExecutionErrors()) {
132                                var contactControl = Session.getModelController(ContactControl.class);
133                                var postalAddressFormatName = form.getPostalAddressFormatName();
134                                var postalAddressFormat = contactControl.getPostalAddressFormatByName(postalAddressFormatName);
135
136                                if(postalAddressFormat != null) {
137                                    BasePK createdBy = getPartyPK();
138                                    var geoCodeName = SequenceGeneratorLogic.getInstance().getNextSequenceValue(null, SequenceTypes.GEO_CODE.name());
139                                    var telephoneCode = form.getTelephoneCode();
140                                    var areaCodePattern = form.getAreaCodePattern();
141                                    var areaCodeRequired = Boolean.valueOf(form.getAreaCodeRequired());
142                                    var areaCodeExample = form.getAreaCodeExample();
143                                    var telephoneNumberPattern = form.getTelephoneNumberPattern();
144                                    var telephoneNumberExample = form.getTelephoneNumberExample();
145                                    var cityRequired = Boolean.valueOf(form.getCityRequired());
146                                    var cityGeoCodeRequired = Boolean.valueOf(form.getCityGeoCodeRequired());
147                                    var stateRequired = Boolean.valueOf(form.getStateRequired());
148                                    var stateGeoCodeRequired = Boolean.valueOf(form.getStateGeoCodeRequired());
149                                    var postalCodePattern = form.getPostalCodePattern();
150                                    var postalCodeRequired = Boolean.valueOf(form.getPostalCodeRequired());
151                                    var postalCodeGeoCodeRequired = Boolean.valueOf(form.getPostalCodeGeoCodeRequired());
152                                    var strPostalCodeLength = form.getPostalCodeLength();
153                                    var postalCodeLength = strPostalCodeLength == null ? null : Integer.valueOf(strPostalCodeLength);
154                                    var strPostalCodeGeoCodeLength = form.getPostalCodeGeoCodeLength();
155                                    var postalCodeGeoCodeLength = strPostalCodeGeoCodeLength == null ? null : Integer.valueOf(strPostalCodeGeoCodeLength);
156                                    var postalCodeExample = form.getPostalCodeExample();
157                                    var isDefault = Boolean.valueOf(form.getIsDefault());
158                                    var sortOrder = Integer.valueOf(form.getSortOrder());
159                                    var description = form.getDescription();
160
161                                    geoCode = geoControl.createGeoCode(geoCodeName, geoCodeType, geoCodeScope, isDefault, sortOrder, createdBy);
162                                    geoControl.createGeoCodeCountry(geoCode, telephoneCode, areaCodePattern, areaCodeRequired, areaCodeExample,
163                                            telephoneNumberPattern, telephoneNumberExample, postalAddressFormat, cityRequired, cityGeoCodeRequired,
164                                            stateRequired, stateGeoCodeRequired, postalCodePattern, postalCodeRequired, postalCodeGeoCodeRequired,
165                                            postalCodeLength, postalCodeGeoCodeLength, postalCodeExample, createdBy);
166
167                                    var geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoCodeAliasTypes.ISO_3_NUMBER.name());
168                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, iso3Number, createdBy);
169                                    geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoCodeAliasTypes.ISO_3_LETTER.name());
170                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, iso3Letter, createdBy);
171                                    geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoCodeAliasTypes.ISO_2_LETTER.name());
172                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, iso2Letter, createdBy);
173                                    geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoCodeAliasTypes.COUNTRY_NAME.name());
174                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, countryName, createdBy);
175
176                                    if(description != null) {
177                                        var language = getPreferredLanguage();
178
179                                        geoControl.createGeoCodeDescription(geoCode, language, description, createdBy);
180                                    }
181                                } else {
182                                    addExecutionError(ExecutionErrors.UnknownPostalAddressFormatName.name(), postalAddressFormatName);
183                                }
184                            } else {
185                                if(geoCode != null) {
186                                    addExecutionError(ExecutionErrors.DuplicateCountryName.name(), countryName);
187                                }
188                            }
189                        } else {
190                            if(geoCode != null) {
191                                addExecutionError(ExecutionErrors.DuplicateIso2Letter.name(), iso2Letter);
192                            }
193                        }
194                    } else {
195                        if(geoCode != null) {
196                            addExecutionError(ExecutionErrors.DuplicateIso3Letter.name(), iso3Letter);
197                        }
198                    }
199                } else {
200                    if(geoCode != null) {
201                        addExecutionError(ExecutionErrors.DuplicateIso3Number.name(), iso3Number);
202                    }
203                }
204            }
205        }
206
207        if(geoCode != null) {
208            result.setEntityRef(geoCode.getPrimaryKey().getEntityRef());
209            result.setGeoCodeName(geoCode.getLastDetail().getGeoCodeName());
210        }
211        
212        return result;
213    }
214    
215}