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.edit.CountryEdit; 020import com.echothree.control.user.geo.common.edit.GeoEditFactory; 021import com.echothree.control.user.geo.common.result.EditCountryResult; 022import com.echothree.control.user.geo.common.result.GeoResultFactory; 023import com.echothree.control.user.geo.common.spec.GeoCodeSpec; 024import com.echothree.model.control.contact.server.control.ContactControl; 025import com.echothree.model.control.geo.common.GeoCodeAliasTypes; 026import com.echothree.model.control.geo.common.GeoCodeScopes; 027import com.echothree.model.control.geo.common.GeoCodeTypes; 028import com.echothree.model.control.geo.server.control.GeoControl; 029import com.echothree.model.control.geo.server.logic.GeoCodeAliasLogic; 030import com.echothree.model.control.geo.server.logic.GeoCodeLogic; 031import com.echothree.model.control.geo.server.logic.GeoCodeScopeLogic; 032import com.echothree.model.control.geo.server.logic.GeoCodeTypeLogic; 033import com.echothree.model.control.party.common.PartyTypes; 034import com.echothree.model.control.security.common.SecurityRoleGroups; 035import com.echothree.model.control.security.common.SecurityRoles; 036import com.echothree.model.data.contact.server.entity.PostalAddressFormat; 037import com.echothree.model.data.geo.server.entity.GeoCode; 038import com.echothree.util.common.command.EditMode; 039import com.echothree.util.common.message.ExecutionErrors; 040import com.echothree.util.common.validation.FieldDefinition; 041import com.echothree.util.common.validation.FieldType; 042import com.echothree.util.server.control.BaseAbstractEditCommand; 043import com.echothree.util.server.control.CommandSecurityDefinition; 044import com.echothree.util.server.control.PartyTypeDefinition; 045import com.echothree.util.server.control.SecurityRoleDefinition; 046import com.echothree.util.server.persistence.Session; 047import java.util.Arrays; 048import java.util.Collections; 049import java.util.List; 050import javax.enterprise.context.RequestScoped; 051 052@RequestScoped 053public class EditCountryCommand 054 extends BaseAbstractEditCommand<GeoCodeSpec, CountryEdit, EditCountryResult, GeoCode, GeoCode> { 055 056 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 057 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 058 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 059 060 static { 061 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList( 062 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 063 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList( 064 new SecurityRoleDefinition(SecurityRoleGroups.Country.name(), SecurityRoles.Edit.name()) 065 ))) 066 ))); 067 068 SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 069 new FieldDefinition("GeoCodeName", FieldType.ENTITY_NAME, true, null, null) 070 )); 071 072 EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 073 new FieldDefinition("CountryName", FieldType.ENTITY_NAME, true, null, null), 074 new FieldDefinition("Iso3Number", FieldType.NUMBER_3, true, null, null), 075 new FieldDefinition("Iso3Letter", FieldType.UPPER_LETTER_3, true, null, null), 076 new FieldDefinition("Iso2Letter", FieldType.UPPER_LETTER_2, true, null, null), 077 new FieldDefinition("TelephoneCode", FieldType.STRING, false, 1L, 5L), 078 new FieldDefinition("AreaCodePattern", FieldType.REGULAR_EXPRESSION, false, null, null), 079 new FieldDefinition("AreaCodeRequired", FieldType.BOOLEAN, true, null, null), 080 new FieldDefinition("AreaCodeExample", FieldType.STRING, false, 1L, 5L), 081 new FieldDefinition("TelephoneNumberPattern", FieldType.REGULAR_EXPRESSION, false, null, null), 082 new FieldDefinition("TelephoneNumberExample", FieldType.STRING, false, 1L, 25L), 083 new FieldDefinition("PostalAddressFormatName", FieldType.ENTITY_NAME, true, null, null), 084 new FieldDefinition("CityRequired", FieldType.BOOLEAN, true, null, null), 085 new FieldDefinition("CityGeoCodeRequired", FieldType.BOOLEAN, true, null, null), 086 new FieldDefinition("StateRequired", FieldType.BOOLEAN, true, null, null), 087 new FieldDefinition("StateGeoCodeRequired", FieldType.BOOLEAN, true, null, null), 088 new FieldDefinition("PostalCodePattern", FieldType.REGULAR_EXPRESSION, false, null, null), 089 new FieldDefinition("PostalCodeRequired", FieldType.BOOLEAN, true, null, null), 090 new FieldDefinition("PostalCodeGeoCodeRequired", FieldType.BOOLEAN, true, null, null), 091 new FieldDefinition("PostalCodeLength", FieldType.UNSIGNED_INTEGER, false, null, null), 092 new FieldDefinition("PostalCodeGeoCodeLength", FieldType.UNSIGNED_INTEGER, false, null, null), 093 new FieldDefinition("PostalCodeExample", FieldType.STRING, false, 1L, 15L), 094 new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null), 095 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 096 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L) 097 )); 098 } 099 100 /** Creates a new instance of EditCountryCommand */ 101 public EditCountryCommand() { 102 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 103 } 104 105 @Override 106 public EditCountryResult getResult() { 107 return GeoResultFactory.getEditCountryResult(); 108 } 109 110 @Override 111 public CountryEdit getEdit() { 112 return GeoEditFactory.getCountryEdit(); 113 } 114 115 @Override 116 public GeoCode getEntity(EditCountryResult result) { 117 var geoControl = Session.getModelController(GeoControl.class); 118 GeoCode geoCode; 119 var geoCodeName = spec.getGeoCodeName(); 120 121 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 122 geoCode = geoControl.getGeoCodeByName(geoCodeName); 123 } else { // EditMode.UPDATE 124 geoCode = geoControl.getGeoCodeByNameForUpdate(geoCodeName); 125 } 126 127 if(geoCode != null) { 128 var geoCodeTypeName = geoCode.getLastDetail().getGeoCodeType().getLastDetail().getGeoCodeTypeName(); 129 130 if(!geoCodeTypeName.equals(GeoCodeTypes.COUNTRY.name())) { 131 addExecutionError(ExecutionErrors.InvalidGeoCodeType.name(), geoCodeTypeName); 132 } 133 } else { 134 addExecutionError(ExecutionErrors.UnknownGeoCodeName.name(), geoCodeName); 135 } 136 137 return geoCode; 138 } 139 140 @Override 141 public GeoCode getLockEntity(GeoCode geoCode) { 142 return geoCode; 143 } 144 145 @Override 146 public void fillInResult(EditCountryResult result, GeoCode geoCode) { 147 var geoControl = Session.getModelController(GeoControl.class); 148 149 result.setCountry(geoControl.getCountryTransfer(getUserVisit(), geoCode)); 150 } 151 152 @Override 153 public void doLock(CountryEdit edit, GeoCode geoCode) { 154 var geoControl = Session.getModelController(GeoControl.class); 155 var geoCodeAliasLogic = GeoCodeAliasLogic.getInstance(); 156 var geoCodeDescription = geoControl.getGeoCodeDescription(geoCode, getPreferredLanguage()); 157 var geoCodeDetail = geoCode.getLastDetail(); 158 var geoCodeCountry = geoControl.getGeoCodeCountry(geoCode); 159 var postalCodeLength = geoCodeCountry.getPostalCodeGeoCodeLength(); 160 var postalCodeGeoCodeLength = geoCodeCountry.getPostalCodeGeoCodeLength(); 161 162 var geoCodeAlias = geoCodeAliasLogic.getGeoCodeAliasUsingNames(null, geoCode, GeoCodeAliasTypes.COUNTRY_NAME.name()); 163 edit.setCountryName(geoCodeAlias.getAlias()); 164 165 geoCodeAlias = geoCodeAliasLogic.getGeoCodeAliasUsingNames(null, geoCode, GeoCodeAliasTypes.ISO_3_NUMBER.name()); 166 edit.setIso3Number(geoCodeAlias.getAlias()); 167 168 geoCodeAlias = geoCodeAliasLogic.getGeoCodeAliasUsingNames(null, geoCode, GeoCodeAliasTypes.ISO_3_LETTER.name()); 169 edit.setIso3Letter(geoCodeAlias.getAlias()); 170 171 geoCodeAlias = geoCodeAliasLogic.getGeoCodeAliasUsingNames(null, geoCode, GeoCodeAliasTypes.ISO_2_LETTER.name()); 172 edit.setIso2Letter(geoCodeAlias.getAlias()); 173 174 edit.setTelephoneCode(geoCodeCountry.getTelephoneCode()); 175 edit.setAreaCodePattern(geoCodeCountry.getAreaCodePattern()); 176 edit.setAreaCodeRequired(geoCodeCountry.getAreaCodeRequired().toString()); 177 edit.setAreaCodeExample(geoCodeCountry.getAreaCodeExample()); 178 edit.setTelephoneNumberPattern(geoCodeCountry.getTelephoneNumberPattern()); 179 edit.setTelephoneNumberExample(geoCodeCountry.getTelephoneNumberExample()); 180 edit.setPostalAddressFormatName(geoCodeCountry.getPostalAddressFormat().getLastDetail().getPostalAddressFormatName()); 181 edit.setCityRequired(geoCodeCountry.getCityRequired().toString()); 182 edit.setCityGeoCodeRequired(geoCodeCountry.getCityGeoCodeRequired().toString()); 183 edit.setStateRequired(geoCodeCountry.getStateRequired().toString()); 184 edit.setStateGeoCodeRequired(geoCodeCountry.getStateGeoCodeRequired().toString()); 185 edit.setPostalCodePattern(geoCodeCountry.getPostalCodePattern()); 186 edit.setPostalCodeRequired(geoCodeCountry.getPostalCodeRequired().toString()); 187 edit.setPostalCodeGeoCodeRequired(geoCodeCountry.getPostalCodeGeoCodeRequired().toString()); 188 edit.setPostalCodeLength(postalCodeLength == null ? null : postalCodeLength.toString()); 189 edit.setPostalCodeGeoCodeLength(postalCodeGeoCodeLength == null ? null : postalCodeGeoCodeLength.toString()); 190 edit.setPostalCodeExample(geoCodeCountry.getPostalCodeExample()); 191 edit.setIsDefault(geoCodeDetail.getIsDefault().toString()); 192 edit.setSortOrder(geoCodeDetail.getSortOrder().toString()); 193 194 if(geoCodeDescription != null) { 195 edit.setDescription(geoCodeDescription.getDescription()); 196 } 197 } 198 199 PostalAddressFormat postalAddressFormat; 200 201 @Override 202 public void canUpdate(GeoCode geoCode) { 203 var geoCodeTypeLogic = GeoCodeTypeLogic.getInstance(); 204 var geoCodeType = geoCodeTypeLogic.getGeoCodeTypeByName(this, GeoCodeTypes.COUNTRY.name()); 205 206 if(!hasExecutionErrors()) { 207 var geoCodeScopeLogic = GeoCodeScopeLogic.getInstance(); 208 var geoCodeScope = geoCodeScopeLogic.getGeoCodeScopeByName(this, GeoCodeScopes.COUNTRIES.name()); 209 210 if(!hasExecutionErrors()) { 211 var geoCodeLogic = GeoCodeLogic.getInstance(); 212 var iso3Number = edit.getIso3Number(); 213 var duplicateGeoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.ISO_3_NUMBER.name(), iso3Number); 214 215 if((duplicateGeoCode == null || duplicateGeoCode.equals(geoCode)) && !hasExecutionErrors()) { 216 var iso3Letter = edit.getIso3Letter(); 217 218 duplicateGeoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.ISO_3_LETTER.name(), iso3Letter); 219 220 if((duplicateGeoCode == null || duplicateGeoCode.equals(geoCode)) && !hasExecutionErrors()) { 221 var iso2Letter = edit.getIso2Letter(); 222 223 duplicateGeoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.ISO_2_LETTER.name(), iso2Letter); 224 225 if((duplicateGeoCode == null || duplicateGeoCode.equals(geoCode)) && !hasExecutionErrors()) { 226 var countryName = edit.getCountryName(); 227 228 duplicateGeoCode = geoCodeLogic.getGeoCodeByAlias(this, geoCodeType, geoCodeScope, GeoCodeAliasTypes.COUNTRY_NAME.name(), countryName); 229 230 if((duplicateGeoCode == null || duplicateGeoCode.equals(geoCode)) && !hasExecutionErrors()) { 231 var contactControl = Session.getModelController(ContactControl.class); 232 var postalAddressFormatName = edit.getPostalAddressFormatName(); 233 234 postalAddressFormat = contactControl.getPostalAddressFormatByName(postalAddressFormatName); 235 236 if(postalAddressFormat == null) { 237 addExecutionError(ExecutionErrors.UnknownPostalAddressFormatName.name(), postalAddressFormatName); 238 } 239 } else { 240 if(geoCode != null) { 241 addExecutionError(ExecutionErrors.DuplicateCountryName.name(), countryName); 242 } 243 } 244 } else { 245 if(geoCode != null) { 246 addExecutionError(ExecutionErrors.DuplicateIso2Letter.name(), iso2Letter); 247 } 248 } 249 } else { 250 if(geoCode != null) { 251 addExecutionError(ExecutionErrors.DuplicateIso3Letter.name(), iso3Letter); 252 } 253 } 254 } else { 255 if(geoCode != null) { 256 addExecutionError(ExecutionErrors.DuplicateIso3Number.name(), iso3Number); 257 } 258 } 259 } 260 } 261 } 262 263 @Override 264 public void doUpdate(GeoCode geoCode) { 265 var geoControl = Session.getModelController(GeoControl.class); 266 var geoCodeAliasLogic = GeoCodeAliasLogic.getInstance(); 267 var partyPK = getPartyPK(); 268 var geoCodeDetailValue = geoControl.getGeoCodeDetailValueForUpdate(geoCode); 269 var geoCodeDescription = geoControl.getGeoCodeDescriptionForUpdate(geoCode, getPreferredLanguage()); 270 var geoCodeCountryValue = geoControl.getGeoCodeCountryValueForUpdate(geoCode); 271 var strPostalCodeLength = edit.getPostalCodeLength(); 272 var postalCodeLength = strPostalCodeLength == null ? null : Integer.valueOf(strPostalCodeLength); 273 var strPostalCodeGeoCodeLength = edit.getPostalCodeGeoCodeLength(); 274 var postalCodeGeoCodeLength = strPostalCodeGeoCodeLength == null ? null : Integer.valueOf(strPostalCodeGeoCodeLength); 275 var description = edit.getDescription(); 276 277 var geoCodeAliasValue = geoCodeAliasLogic.getGeoCodeAliasValueUsingNames(null, geoCode, GeoCodeAliasTypes.COUNTRY_NAME.name()); 278 geoCodeAliasValue.setAlias(edit.getCountryName()); 279 geoControl.updateGeoCodeAliasFromValue(geoCodeAliasValue, partyPK); 280 281 geoCodeAliasValue = geoCodeAliasLogic.getGeoCodeAliasValueUsingNames(null, geoCode, GeoCodeAliasTypes.ISO_3_NUMBER.name()); 282 geoCodeAliasValue.setAlias(edit.getIso3Number()); 283 geoControl.updateGeoCodeAliasFromValue(geoCodeAliasValue, partyPK); 284 285 geoCodeAliasValue = geoCodeAliasLogic.getGeoCodeAliasValueUsingNames(null, geoCode, GeoCodeAliasTypes.ISO_3_LETTER.name()); 286 geoCodeAliasValue.setAlias(edit.getIso3Letter()); 287 geoControl.updateGeoCodeAliasFromValue(geoCodeAliasValue, partyPK); 288 289 geoCodeAliasValue = geoCodeAliasLogic.getGeoCodeAliasValueUsingNames(null, geoCode, GeoCodeAliasTypes.ISO_2_LETTER.name()); 290 geoCodeAliasValue.setAlias(edit.getIso2Letter()); 291 geoControl.updateGeoCodeAliasFromValue(geoCodeAliasValue, partyPK); 292 293 geoCodeCountryValue.setTelephoneCode(edit.getTelephoneCode()); 294 geoCodeCountryValue.setAreaCodePattern(edit.getAreaCodePattern()); 295 geoCodeCountryValue.setAreaCodeRequired(Boolean.valueOf(edit.getAreaCodeRequired())); 296 geoCodeCountryValue.setAreaCodeExample(edit.getAreaCodeExample()); 297 geoCodeCountryValue.setTelephoneNumberPattern(edit.getTelephoneNumberPattern()); 298 geoCodeCountryValue.setTelephoneNumberExample(edit.getTelephoneNumberExample()); 299 geoCodeCountryValue.setPostalAddressFormatPK(postalAddressFormat.getPrimaryKey()); 300 geoCodeCountryValue.setCityRequired(Boolean.valueOf(edit.getCityRequired())); 301 geoCodeCountryValue.setCityGeoCodeRequired(Boolean.valueOf(edit.getCityGeoCodeRequired())); 302 geoCodeCountryValue.setStateRequired(Boolean.valueOf(edit.getStateRequired())); 303 geoCodeCountryValue.setStateGeoCodeRequired(Boolean.valueOf(edit.getStateGeoCodeRequired())); 304 geoCodeCountryValue.setPostalCodePattern(edit.getPostalCodePattern()); 305 geoCodeCountryValue.setPostalCodeRequired(Boolean.valueOf(edit.getPostalCodeRequired())); 306 geoCodeCountryValue.setPostalCodeGeoCodeRequired(Boolean.valueOf(edit.getPostalCodeGeoCodeRequired())); 307 geoCodeCountryValue.setPostalCodeLength(postalCodeLength); 308 geoCodeCountryValue.setPostalCodeGeoCodeLength(postalCodeGeoCodeLength); 309 geoCodeCountryValue.setPostalCodeExample(edit.getPostalCodeExample()); 310 311 geoCodeDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault())); 312 geoCodeDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder())); 313 314 geoControl.updateGeoCodeFromValue(geoCodeDetailValue, partyPK); 315 geoControl.updateGeoCodeCountryFromValue(geoCodeCountryValue, partyPK); 316 317 if(geoCodeDescription == null && description != null) { 318 geoControl.createGeoCodeDescription(geoCode, getPreferredLanguage(), description, partyPK); 319 } else { 320 if(geoCodeDescription != null && description == null) { 321 geoControl.deleteGeoCodeDescription(geoCodeDescription, partyPK); 322 } else { 323 if(geoCodeDescription != null && description != null) { 324 var geoCodeDescriptionValue = geoControl.getGeoCodeDescriptionValue(geoCodeDescription); 325 326 geoCodeDescriptionValue.setDescription(description); 327 geoControl.updateGeoCodeDescriptionFromValue(geoCodeDescriptionValue, partyPK); 328 } 329 } 330 } 331 } 332 333}