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