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.customer.server.command; 018 019import com.echothree.control.user.customer.common.edit.CustomerEdit; 020import com.echothree.control.user.customer.common.edit.CustomerEditFactory; 021import com.echothree.control.user.customer.common.form.EditCustomerForm; 022import com.echothree.control.user.customer.common.result.CustomerResultFactory; 023import com.echothree.control.user.customer.common.result.EditCustomerResult; 024import com.echothree.control.user.customer.common.spec.CustomerSpec; 025import com.echothree.model.control.accounting.common.AccountingConstants; 026import com.echothree.model.control.accounting.server.control.AccountingControl; 027import com.echothree.model.control.cancellationpolicy.common.CancellationKinds; 028import com.echothree.model.control.cancellationpolicy.server.control.CancellationPolicyControl; 029import com.echothree.model.control.customer.server.control.CustomerControl; 030import com.echothree.model.control.party.server.control.PartyControl; 031import com.echothree.model.control.returnpolicy.common.ReturnKinds; 032import com.echothree.model.control.returnpolicy.server.control.ReturnPolicyControl; 033import com.echothree.model.data.accounting.server.entity.Currency; 034import com.echothree.model.data.accounting.server.entity.GlAccount; 035import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy; 036import com.echothree.model.data.customer.server.entity.Customer; 037import com.echothree.model.data.customer.server.entity.CustomerType; 038import com.echothree.model.data.party.server.entity.DateTimeFormat; 039import com.echothree.model.data.party.server.entity.Language; 040import com.echothree.model.data.party.server.entity.Party; 041import com.echothree.model.data.party.server.entity.TimeZone; 042import com.echothree.model.data.party.server.value.PartyGroupValue; 043import com.echothree.model.data.party.server.value.PersonValue; 044import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy; 045import com.echothree.model.data.user.common.pk.UserVisitPK; 046import com.echothree.util.common.command.EditMode; 047import com.echothree.util.common.message.ExecutionErrors; 048import com.echothree.util.common.validation.FieldDefinition; 049import com.echothree.util.common.validation.FieldType; 050import com.echothree.util.server.control.BaseAbstractEditCommand; 051import com.echothree.util.server.persistence.EntityPermission; 052import com.echothree.util.server.persistence.Session; 053import java.util.Arrays; 054import java.util.Collections; 055import java.util.List; 056import org.apache.commons.codec.language.Soundex; 057 058public class EditCustomerCommand 059 extends BaseAbstractEditCommand<CustomerSpec, CustomerEdit, EditCustomerResult, Party, Party> { 060 061 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 062 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 063 064 static { 065 SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 066 new FieldDefinition("CustomerName", FieldType.ENTITY_NAME, true, null, null) 067 )); 068 069 EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 070 new FieldDefinition("CustomerTypeName", FieldType.ENTITY_NAME, true, null, null), 071 new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null), 072 new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null), 073 new FieldDefinition("ArGlAccountName", FieldType.ENTITY_NAME, false, null, null), 074 new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null), 075 new FieldDefinition("FirstName", FieldType.STRING, false, 1L, 20L), 076 new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L), 077 new FieldDefinition("LastName", FieldType.STRING, false, 1L, 20L), 078 new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null), 079 new FieldDefinition("Name", FieldType.STRING, false, 1L, 60L), 080 new FieldDefinition("PreferredLanguageIsoName", FieldType.ENTITY_NAME, false, null, null), 081 new FieldDefinition("PreferredCurrencyIsoName", FieldType.ENTITY_NAME, false, null, null), 082 new FieldDefinition("PreferredJavaTimeZoneName", FieldType.TIME_ZONE_NAME, false, null, null), 083 new FieldDefinition("PreferredDateTimeFormatName", FieldType.ENTITY_NAME, false, null, null), 084 new FieldDefinition("HoldUntilComplete", FieldType.BOOLEAN, true, null, null), 085 new FieldDefinition("AllowBackorders", FieldType.BOOLEAN, true, null, null), 086 new FieldDefinition("AllowSubstitutions", FieldType.BOOLEAN, true, null, null), 087 new FieldDefinition("AllowCombiningShipments", FieldType.BOOLEAN, true, null, null), 088 new FieldDefinition("RequireReference", FieldType.BOOLEAN, true, null, null), 089 new FieldDefinition("AllowReferenceDuplicates", FieldType.BOOLEAN, true, null, null), 090 new FieldDefinition("ReferenceValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null) 091 )); 092 } 093 094 /** Creates a new instance of EditCustomerCommand */ 095 public EditCustomerCommand(UserVisitPK userVisitPK, EditCustomerForm form) { 096 super(userVisitPK, form, null, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 097 } 098 099 @Override 100 public EditCustomerResult getResult() { 101 return CustomerResultFactory.getEditCustomerResult(); 102 } 103 104 @Override 105 public CustomerEdit getEdit() { 106 return CustomerEditFactory.getCustomerEdit(); 107 } 108 109 @Override 110 public Party getEntity(EditCustomerResult result) { 111 var customerControl = Session.getModelController(CustomerControl.class); 112 Customer customer; 113 var customerName = spec.getCustomerName(); 114 115 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 116 customer = customerControl.getCustomerByName(customerName); 117 } else { // EditMode.UPDATE 118 customer = customerControl.getCustomerByNameForUpdate(customerName); 119 } 120 121 if(customer != null) { 122 result.setCustomer(customerControl.getCustomerTransfer(getUserVisit(), customer)); 123 } else { 124 addExecutionError(ExecutionErrors.UnknownCustomerName.name(), customerName); 125 } 126 127 return customer.getParty(); 128 } 129 130 @Override 131 public Party getLockEntity(Party party) { 132 return party; 133 } 134 135 @Override 136 public void fillInResult(EditCustomerResult result, Party party) { 137 var customerControl = Session.getModelController(CustomerControl.class); 138 139 result.setCustomer(customerControl.getCustomerTransfer(getUserVisit(), party)); 140 } 141 142 @Override 143 public void doLock(CustomerEdit edit, Party party) { 144 var customerControl = Session.getModelController(CustomerControl.class); 145 var partyControl = Session.getModelController(PartyControl.class); 146 var customer = customerControl.getCustomer(party); 147 var partyDetail = party.getLastDetail(); 148 var partyGroup = partyControl.getPartyGroup(party); 149 var arGlAccount = customer.getArGlAccount(); 150 var cancellationPolicy = customer.getCancellationPolicy(); 151 var returnPolicy = customer.getReturnPolicy(); 152 var preferredLanguage = partyDetail.getPreferredLanguage(); 153 var preferredCurrency = partyDetail.getPreferredCurrency(); 154 var preferredTimeZone = partyDetail.getPreferredTimeZone(); 155 var dateTimeFormat = partyDetail.getPreferredDateTimeFormat(); 156 var person = partyControl.getPerson(party); 157 var personalTitle = person == null ? null : person.getPersonalTitle(); 158 var nameSuffix = person == null ? null : person.getNameSuffix(); 159 160 edit.setCustomerTypeName(customer.getCustomerType().getLastDetail().getCustomerTypeName()); 161 edit.setPersonalTitleId(personalTitle == null ? null : personalTitle.getPrimaryKey().getEntityId().toString()); 162 edit.setFirstName(person == null ? null : person.getFirstName()); 163 edit.setMiddleName(person == null ? null : person.getMiddleName()); 164 edit.setLastName(person == null ? null : person.getLastName()); 165 edit.setNameSuffixId(nameSuffix == null ? null : nameSuffix.getPrimaryKey().getEntityId().toString()); 166 edit.setName(partyGroup == null ? null : partyGroup.getName()); 167 edit.setPreferredLanguageIsoName(preferredLanguage == null ? null : preferredLanguage.getLanguageIsoName()); 168 edit.setPreferredCurrencyIsoName(preferredCurrency == null ? null : preferredCurrency.getCurrencyIsoName()); 169 edit.setPreferredJavaTimeZoneName(preferredTimeZone == null ? null : preferredTimeZone.getLastDetail().getJavaTimeZoneName()); 170 edit.setPreferredDateTimeFormatName(dateTimeFormat == null ? null : dateTimeFormat.getLastDetail().getDateTimeFormatName()); 171 edit.setArGlAccountName(arGlAccount == null ? null : arGlAccount.getLastDetail().getGlAccountName()); 172 edit.setCancellationPolicyName(cancellationPolicy == null ? null : cancellationPolicy.getLastDetail().getCancellationPolicyName()); 173 edit.setReturnPolicyName(returnPolicy == null ? null : returnPolicy.getLastDetail().getReturnPolicyName()); 174 edit.setHoldUntilComplete(customer.getHoldUntilComplete().toString()); 175 edit.setAllowBackorders(customer.getAllowBackorders().toString()); 176 edit.setAllowSubstitutions(customer.getAllowSubstitutions().toString()); 177 edit.setAllowCombiningShipments(customer.getAllowCombiningShipments().toString()); 178 edit.setRequireReference(customer.getRequireReference().toString()); 179 edit.setAllowReferenceDuplicates(customer.getAllowReferenceDuplicates().toString()); 180 edit.setReferenceValidationPattern(customer.getReferenceValidationPattern()); 181 } 182 183 CustomerType customerType; 184 CancellationPolicy cancellationPolicy; 185 ReturnPolicy returnPolicy; 186 GlAccount arGlAccount; 187 Language preferredLanguage; 188 TimeZone preferredTimeZone; 189 DateTimeFormat preferredDateTimeFormat; 190 Currency preferredCurrency; 191 192 @Override 193 public void canUpdate(Party party) { 194 var customerControl = Session.getModelController(CustomerControl.class); 195 var partyControl = Session.getModelController(PartyControl.class); 196 var customerTypeName = edit.getCustomerTypeName(); 197 198 customerType = customerControl.getCustomerTypeByName(customerTypeName); 199 200 if(customerType != null) { 201 var cancellationPolicyName = edit.getCancellationPolicyName(); 202 203 if(cancellationPolicyName != null) { 204 var cancellationPolicyControl = Session.getModelController(CancellationPolicyControl.class); 205 var cancellationKind = cancellationPolicyControl.getCancellationKindByName(CancellationKinds.CUSTOMER_CANCELLATION.name()); 206 207 cancellationPolicy = cancellationPolicyControl.getCancellationPolicyByName(cancellationKind, cancellationPolicyName); 208 } 209 210 if(cancellationPolicyName == null || cancellationPolicy != null) { 211 var returnPolicyName = edit.getReturnPolicyName(); 212 213 if(returnPolicyName != null) { 214 var returnPolicyControl = Session.getModelController(ReturnPolicyControl.class); 215 var returnKind = returnPolicyControl.getReturnKindByName(ReturnKinds.CUSTOMER_RETURN.name()); 216 217 returnPolicy = returnPolicyControl.getReturnPolicyByName(returnKind, returnPolicyName); 218 } 219 220 if(returnPolicyName == null || returnPolicy != null) { 221 var accountingControl = Session.getModelController(AccountingControl.class); 222 var arGlAccountName = edit.getArGlAccountName(); 223 224 arGlAccount = arGlAccountName == null ? null : accountingControl.getGlAccountByName(arGlAccountName); 225 226 if(arGlAccountName == null || arGlAccount != null) { 227 var glAccountCategoryName = arGlAccount == null ? null : arGlAccount.getLastDetail().getGlAccountCategory().getLastDetail().getGlAccountCategoryName(); 228 229 if(glAccountCategoryName == null || glAccountCategoryName.equals(AccountingConstants.GlAccountCategory_ACCOUNTS_RECEIVABLE)) { 230 var preferredLanguageIsoName = edit.getPreferredLanguageIsoName(); 231 232 preferredLanguage = preferredLanguageIsoName == null ? null : partyControl.getLanguageByIsoName(preferredLanguageIsoName); 233 234 if(preferredLanguageIsoName == null || (preferredLanguage != null)) { 235 var preferredJavaTimeZoneName = edit.getPreferredJavaTimeZoneName(); 236 237 preferredTimeZone = preferredJavaTimeZoneName == null ? null : partyControl.getTimeZoneByJavaName(preferredJavaTimeZoneName); 238 239 if(preferredJavaTimeZoneName == null || (preferredTimeZone != null)) { 240 var preferredDateTimeFormatName = edit.getPreferredDateTimeFormatName(); 241 242 preferredDateTimeFormat = preferredDateTimeFormatName == null ? null : partyControl.getDateTimeFormatByName(preferredDateTimeFormatName); 243 244 if(preferredDateTimeFormatName == null || (preferredDateTimeFormat != null)) { 245 var preferredCurrencyIsoName = edit.getPreferredCurrencyIsoName(); 246 247 if(preferredCurrencyIsoName == null) { 248 preferredCurrency = null; 249 } else { 250 preferredCurrency = accountingControl.getCurrencyByIsoName(preferredCurrencyIsoName); 251 } 252 253 if(preferredCurrencyIsoName != null && (preferredCurrency == null)) { 254 addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), preferredCurrencyIsoName); 255 } 256 } else { 257 addExecutionError(ExecutionErrors.UnknownDateTimeFormatName.name(), preferredDateTimeFormatName); 258 } 259 } else { 260 addExecutionError(ExecutionErrors.UnknownJavaTimeZoneName.name(), preferredJavaTimeZoneName); 261 } 262 } else { 263 addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), preferredLanguageIsoName); 264 } 265 } else { 266 addExecutionError(ExecutionErrors.InvalidGlAccountCategory.name(), glAccountCategoryName); 267 } 268 } else { 269 addExecutionError(ExecutionErrors.UnknownArGlAccountName.name(), arGlAccountName); 270 } 271 } else { 272 addExecutionError(ExecutionErrors.UnknownReturnPolicyName.name(), returnPolicyName); 273 } 274 } else { 275 addExecutionError(ExecutionErrors.UnknownCancellationPolicyName.name(), cancellationPolicyName); 276 } 277 } else { 278 addExecutionError(ExecutionErrors.UnknownCustomerTypeName.name(), customerTypeName); 279 } 280 } 281 282 @Override 283 public void doUpdate(Party party) { 284 var customerControl = Session.getModelController(CustomerControl.class); 285 var partyControl = Session.getModelController(PartyControl.class); 286 var soundex = new Soundex(); 287 var partyDetailValue = partyControl.getPartyDetailValueForUpdate(party); 288 var customer = customerControl.getCustomerForUpdate(party); 289 var customerValue = customerControl.getCustomerValue(customer); 290 var partyGroup = partyControl.getPartyGroupForUpdate(party); 291 var person = partyControl.getPersonForUpdate(party); 292 var personalTitleId = edit.getPersonalTitleId(); 293 var personalTitle = personalTitleId == null ? null : partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY); 294 var firstName = edit.getFirstName(); 295 var firstNameSdx = soundex.encode(firstName); 296 var middleName = edit.getMiddleName(); 297 var middleNameSdx = middleName == null ? null : soundex.encode(middleName); 298 var lastName = edit.getLastName(); 299 var lastNameSdx = soundex.encode(lastName); 300 var nameSuffixId = edit.getNameSuffixId(); 301 var nameSuffix = nameSuffixId == null ? null : partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY); 302 var name = edit.getName(); 303 var updatedBy = getPartyPK(); 304 305 customerValue.setCustomerTypePK(customerType.getPrimaryKey()); 306 customerValue.setArGlAccountPK(arGlAccount == null ? null : arGlAccount.getPrimaryKey()); 307 customerValue.setCancellationPolicyPK(cancellationPolicy == null ? null : cancellationPolicy.getPrimaryKey()); 308 customerValue.setReturnPolicyPK(returnPolicy == null ? null : returnPolicy.getPrimaryKey()); 309 customerValue.setHoldUntilComplete(Boolean.valueOf(edit.getHoldUntilComplete())); 310 customerValue.setAllowBackorders(Boolean.valueOf(edit.getAllowBackorders())); 311 customerValue.setAllowSubstitutions(Boolean.valueOf(edit.getAllowSubstitutions())); 312 customerValue.setAllowCombiningShipments(Boolean.valueOf(edit.getAllowCombiningShipments())); 313 customerValue.setRequireReference(Boolean.valueOf(edit.getRequireReference())); 314 customerValue.setAllowReferenceDuplicates(Boolean.valueOf(edit.getAllowReferenceDuplicates())); 315 customerValue.setReferenceValidationPattern(edit.getReferenceValidationPattern()); 316 317 partyDetailValue.setPreferredLanguagePK(preferredLanguage == null ? null : preferredLanguage.getPrimaryKey()); 318 partyDetailValue.setPreferredTimeZonePK(preferredTimeZone == null ? null : preferredTimeZone.getPrimaryKey()); 319 partyDetailValue.setPreferredDateTimeFormatPK(preferredDateTimeFormat == null ? null : preferredDateTimeFormat.getPrimaryKey()); 320 partyDetailValue.setPreferredCurrencyPK(preferredCurrency == null ? null : preferredCurrency.getPrimaryKey()); 321 322 if(name != null) { 323 if(partyGroup != null) { 324 PartyGroupValue partyGroupValue = partyControl.getPartyGroupValue(partyGroup); 325 326 partyGroupValue.setName(name); 327 partyControl.updatePartyGroupFromValue(partyGroupValue, updatedBy); 328 } else { 329 partyControl.createPartyGroup(party, name, updatedBy); 330 } 331 } else { 332 if(partyGroup != null) { 333 partyControl.deletePartyGroup(partyGroup, updatedBy); 334 } 335 } 336 337 if(personalTitle != null || firstName != null || middleName != null || lastName != null || nameSuffix != null) { 338 if(person != null) { 339 PersonValue personValue = partyControl.getPersonValue(person); 340 341 personValue.setPersonalTitlePK(personalTitle == null ? null : personalTitle.getPrimaryKey()); 342 personValue.setFirstName(firstName); 343 personValue.setFirstNameSdx(firstNameSdx); 344 personValue.setMiddleName(middleName); 345 personValue.setMiddleNameSdx(middleNameSdx); 346 personValue.setLastName(lastName); 347 personValue.setLastNameSdx(lastNameSdx); 348 personValue.setNameSuffixPK(nameSuffix == null ? null : nameSuffix.getPrimaryKey()); 349 partyControl.updatePersonFromValue(personValue, updatedBy); 350 } else { 351 partyControl.createPerson(party, personalTitle, firstName, firstNameSdx, middleName, middleNameSdx, 352 lastName, lastNameSdx, nameSuffix, updatedBy); 353 } 354 } else { 355 if(person != null) { 356 partyControl.deletePerson(person, updatedBy); 357 } 358 } 359 360 customerControl.updateCustomerFromValue(customerValue, updatedBy); 361 partyControl.updatePartyFromValue(partyDetailValue, updatedBy); 362 } 363 364}