001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 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.GeoConstants;
023import com.echothree.model.control.geo.server.control.GeoControl;
024import com.echothree.model.control.geo.server.logic.GeoCodeLogic;
025import com.echothree.model.control.geo.server.logic.GeoCodeScopeLogic;
026import com.echothree.model.control.geo.server.logic.GeoCodeTypeLogic;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.control.security.common.SecurityRoleGroups;
029import com.echothree.model.control.security.common.SecurityRoles;
030import com.echothree.model.control.sequence.common.SequenceTypes;
031import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
032import com.echothree.model.data.contact.server.entity.PostalAddressFormat;
033import com.echothree.model.data.geo.server.entity.GeoCode;
034import com.echothree.model.data.geo.server.entity.GeoCodeAliasType;
035import com.echothree.model.data.geo.server.entity.GeoCodeScope;
036import com.echothree.model.data.geo.server.entity.GeoCodeType;
037import com.echothree.model.data.party.server.entity.Language;
038import com.echothree.model.data.user.common.pk.UserVisitPK;
039import com.echothree.util.common.command.BaseResult;
040import com.echothree.util.common.message.ExecutionErrors;
041import com.echothree.util.common.persistence.BasePK;
042import com.echothree.util.common.validation.FieldDefinition;
043import com.echothree.util.common.validation.FieldType;
044import com.echothree.util.server.control.BaseSimpleCommand;
045import com.echothree.util.server.control.CommandSecurityDefinition;
046import com.echothree.util.server.control.PartyTypeDefinition;
047import com.echothree.util.server.control.SecurityRoleDefinition;
048import com.echothree.util.server.persistence.Session;
049import java.util.Arrays;
050import java.util.Collections;
051import java.util.List;
052
053public class CreateCountryCommand
054        extends BaseSimpleCommand<CreateCountryForm> {
055    
056    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
057    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
058    
059    static {
060        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
061                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
062                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
063                        new SecurityRoleDefinition(SecurityRoleGroups.Country.name(), SecurityRoles.Create.name())
064                        )))
065                )));
066        
067        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
068                new FieldDefinition("CountryName", FieldType.ENTITY_NAME, true, null, null),
069                new FieldDefinition("Iso3Number", FieldType.NUMBER_3, true, null, null),
070                new FieldDefinition("Iso3Letter", FieldType.UPPER_LETTER_3, true, null, null),
071                new FieldDefinition("Iso2Letter", FieldType.UPPER_LETTER_2, true, null, null),
072                new FieldDefinition("TelephoneCode", FieldType.STRING, false, 1L, 5L),
073                new FieldDefinition("AreaCodePattern", FieldType.REGULAR_EXPRESSION, false, null, null),
074                new FieldDefinition("AreaCodeRequired", FieldType.BOOLEAN, true, null, null),
075                new FieldDefinition("AreaCodeExample", FieldType.STRING, false, 1L, 5L),
076                new FieldDefinition("TelephoneNumberPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
077                new FieldDefinition("TelephoneNumberExample", FieldType.STRING, false, 1L, 25L),
078                new FieldDefinition("PostalAddressFormatName", FieldType.ENTITY_NAME, true, null, null),
079                new FieldDefinition("CityRequired", FieldType.BOOLEAN, true, null, null),
080                new FieldDefinition("CityGeoCodeRequired", FieldType.BOOLEAN, true, null, null),
081                new FieldDefinition("StateRequired", FieldType.BOOLEAN, true, null, null),
082                new FieldDefinition("StateGeoCodeRequired", FieldType.BOOLEAN, true, null, null),
083                new FieldDefinition("PostalCodePattern", FieldType.REGULAR_EXPRESSION, false, null, null),
084                new FieldDefinition("PostalCodeRequired", FieldType.BOOLEAN, true, null, null),
085                new FieldDefinition("PostalCodeGeoCodeRequired", FieldType.BOOLEAN, true, null, null),
086                new FieldDefinition("PostalCodeLength", FieldType.UNSIGNED_INTEGER, false, null, null),
087                new FieldDefinition("PostalCodeGeoCodeLength", FieldType.UNSIGNED_INTEGER, false, null, null),
088                new FieldDefinition("PostalCodeExample", FieldType.STRING, false, 1L, 15L),
089                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
090                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
091                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
092                ));
093    }
094    
095    /** Creates a new instance of CreateCountryCommand */
096    public CreateCountryCommand(UserVisitPK userVisitPK, CreateCountryForm form) {
097        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
098    }
099
100    @Override
101    protected BaseResult execute() {
102        var geoCodeTypeLogic = GeoCodeTypeLogic.getInstance();
103        var result = GeoResultFactory.getCreateCountryResult();
104        var geoControl = Session.getModelController(GeoControl.class);
105        GeoCode geoCode = null;
106        GeoCodeType geoCodeType = geoCodeTypeLogic.getGeoCodeTypeByName(this, GeoConstants.GeoCodeType_COUNTRY);
107
108        if(!hasExecutionErrors()) {
109            var geoCodeScopeLogic = GeoCodeScopeLogic.getInstance();
110            GeoCodeScope geoCodeScope = geoCodeScopeLogic.getGeoCodeScopeByName(this, GeoConstants.GeoCodeScope_COUNTRIES);
111
112            if(!hasExecutionErrors()) {
113                var geoCodeLogic = GeoCodeLogic.getInstance();
114                String iso3Number = form.getIso3Number();
115
116                geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoConstants.GeoCodeAliasType_ISO_3_NUMBER, iso3Number);
117
118                if(geoCode == null && !hasExecutionErrors()) {
119                    String iso3Letter = form.getIso3Letter();
120
121                    geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoConstants.GeoCodeAliasType_ISO_3_LETTER, iso3Letter);
122
123                    if(geoCode == null && !hasExecutionErrors()) {
124                        String iso2Letter = form.getIso2Letter();
125
126                        geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoConstants.GeoCodeAliasType_ISO_2_LETTER, iso2Letter);
127
128                        if(geoCode == null && !hasExecutionErrors()) {
129                            String countryName = form.getCountryName();
130
131                            geoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoConstants.GeoCodeAliasType_COUNTRY_NAME, countryName);
132
133                            if(geoCode == null && !hasExecutionErrors()) {
134                                var contactControl = Session.getModelController(ContactControl.class);
135                                String postalAddressFormatName = form.getPostalAddressFormatName();
136                                PostalAddressFormat postalAddressFormat = contactControl.getPostalAddressFormatByName(postalAddressFormatName);
137
138                                if(postalAddressFormat != null) {
139                                    BasePK createdBy = getPartyPK();
140                                    String geoCodeName = SequenceGeneratorLogic.getInstance().getNextSequenceValue(null, SequenceTypes.GEO_CODE.name());
141                                    String telephoneCode = form.getTelephoneCode();
142                                    String areaCodePattern = form.getAreaCodePattern();
143                                    Boolean areaCodeRequired = Boolean.valueOf(form.getAreaCodeRequired());
144                                    String areaCodeExample = form.getAreaCodeExample();
145                                    String telephoneNumberPattern = form.getTelephoneNumberPattern();
146                                    String telephoneNumberExample = form.getTelephoneNumberExample();
147                                    Boolean cityRequired = Boolean.valueOf(form.getCityRequired());
148                                    Boolean cityGeoCodeRequired = Boolean.valueOf(form.getCityGeoCodeRequired());
149                                    Boolean stateRequired = Boolean.valueOf(form.getStateRequired());
150                                    Boolean stateGeoCodeRequired = Boolean.valueOf(form.getStateGeoCodeRequired());
151                                    String postalCodePattern = form.getPostalCodePattern();
152                                    Boolean postalCodeRequired = Boolean.valueOf(form.getPostalCodeRequired());
153                                    Boolean postalCodeGeoCodeRequired = Boolean.valueOf(form.getPostalCodeGeoCodeRequired());
154                                    String strPostalCodeLength = form.getPostalCodeLength();
155                                    Integer postalCodeLength = strPostalCodeLength == null ? null : Integer.valueOf(strPostalCodeLength);
156                                    String strPostalCodeGeoCodeLength = form.getPostalCodeGeoCodeLength();
157                                    Integer postalCodeGeoCodeLength = strPostalCodeGeoCodeLength == null ? null : Integer.valueOf(strPostalCodeGeoCodeLength);
158                                    String postalCodeExample = form.getPostalCodeExample();
159                                    var isDefault = Boolean.valueOf(form.getIsDefault());
160                                    var sortOrder = Integer.valueOf(form.getSortOrder());
161                                    var description = form.getDescription();
162
163                                    geoCode = geoControl.createGeoCode(geoCodeName, geoCodeType, geoCodeScope, isDefault, sortOrder, createdBy);
164                                    geoControl.createGeoCodeCountry(geoCode, telephoneCode, areaCodePattern, areaCodeRequired, areaCodeExample,
165                                            telephoneNumberPattern, telephoneNumberExample, postalAddressFormat, cityRequired, cityGeoCodeRequired,
166                                            stateRequired, stateGeoCodeRequired, postalCodePattern, postalCodeRequired, postalCodeGeoCodeRequired,
167                                            postalCodeLength, postalCodeGeoCodeLength, postalCodeExample, createdBy);
168
169                                    GeoCodeAliasType geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoConstants.GeoCodeAliasType_ISO_3_NUMBER);
170                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, iso3Number, createdBy);
171                                    geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoConstants.GeoCodeAliasType_ISO_3_LETTER);
172                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, iso3Letter, createdBy);
173                                    geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoConstants.GeoCodeAliasType_ISO_2_LETTER);
174                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, iso2Letter, createdBy);
175                                    geoCodeAliasType = geoControl.getGeoCodeAliasTypeByName(geoCodeType, GeoConstants.GeoCodeAliasType_COUNTRY_NAME);
176                                    geoControl.createGeoCodeAlias(geoCode, geoCodeAliasType, countryName, createdBy);
177
178                                    if(description != null) {
179                                        Language language = getPreferredLanguage();
180
181                                        geoControl.createGeoCodeDescription(geoCode, language, description, createdBy);
182                                    }
183                                } else {
184                                    addExecutionError(ExecutionErrors.UnknownPostalAddressFormatName.name(), postalAddressFormatName);
185                                }
186                            } else {
187                                if(geoCode != null) {
188                                    addExecutionError(ExecutionErrors.DuplicateCountryName.name(), countryName);
189                                }
190                            }
191                        } else {
192                            if(geoCode != null) {
193                                addExecutionError(ExecutionErrors.DuplicateIso2Letter.name(), iso2Letter);
194                            }
195                        }
196                    } else {
197                        if(geoCode != null) {
198                            addExecutionError(ExecutionErrors.DuplicateIso3Letter.name(), iso3Letter);
199                        }
200                    }
201                } else {
202                    if(geoCode != null) {
203                        addExecutionError(ExecutionErrors.DuplicateIso3Number.name(), iso3Number);
204                    }
205                }
206            }
207        }
208
209        if(geoCode != null) {
210            result.setEntityRef(geoCode.getPrimaryKey().getEntityRef());
211            result.setGeoCodeName(geoCode.getLastDetail().getGeoCodeName());
212        }
213        
214        return result;
215    }
216    
217}