001// -------------------------------------------------------------------------------- 002// Copyright 2002-2026 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.payment.server.command; 018 019import com.echothree.control.user.payment.common.edit.PartyPaymentMethodEdit; 020import com.echothree.control.user.payment.common.edit.PaymentEditFactory; 021import com.echothree.control.user.payment.common.result.EditPartyPaymentMethodResult; 022import com.echothree.control.user.payment.common.result.PaymentResultFactory; 023import com.echothree.control.user.payment.common.spec.PartyPaymentMethodSpec; 024import com.echothree.model.control.contact.server.control.ContactControl; 025import com.echothree.model.control.party.common.PartyTypes; 026import com.echothree.model.control.party.server.control.PartyControl; 027import com.echothree.model.control.payment.common.PaymentMethodTypes; 028import com.echothree.model.control.payment.server.control.PartyPaymentMethodControl; 029import com.echothree.model.control.payment.server.logic.PartyPaymentMethodLogic; 030import com.echothree.model.control.security.common.SecurityRoleGroups; 031import com.echothree.model.control.security.common.SecurityRoles; 032import com.echothree.model.data.party.server.entity.Party; 033import com.echothree.model.data.payment.server.entity.PartyPaymentMethod; 034import com.echothree.util.common.command.EditMode; 035import com.echothree.util.common.message.ExecutionErrors; 036import com.echothree.util.common.validation.FieldDefinition; 037import com.echothree.util.common.validation.FieldType; 038import com.echothree.util.server.control.BaseAbstractEditCommand; 039import com.echothree.util.server.control.CommandSecurityDefinition; 040import com.echothree.util.server.control.PartyTypeDefinition; 041import com.echothree.util.server.control.SecurityRoleDefinition; 042import com.echothree.util.server.persistence.EntityPermission; 043import java.util.List; 044import javax.enterprise.context.Dependent; 045import javax.inject.Inject; 046import org.apache.commons.codec.language.Soundex; 047 048@Dependent 049public class EditPartyPaymentMethodCommand 050 extends BaseAbstractEditCommand<PartyPaymentMethodSpec, PartyPaymentMethodEdit, EditPartyPaymentMethodResult, PartyPaymentMethod, PartyPaymentMethod> { 051 052 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 053 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 054 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 055 056 static { 057 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 058 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 059 new PartyTypeDefinition(PartyTypes.CUSTOMER.name(), null), 060 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 061 new SecurityRoleDefinition(SecurityRoleGroups.PartyPaymentMethod.name(), SecurityRoles.Edit.name()) 062 )) 063 )); 064 065 SPEC_FIELD_DEFINITIONS = List.of( 066 new FieldDefinition("PartyPaymentMethodName", FieldType.ENTITY_NAME, true, null, null) 067 ); 068 069 EDIT_FIELD_DEFINITIONS = List.of( 070 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L), 071 new FieldDefinition("DeleteWhenUnused", FieldType.BOOLEAN, true, null, null), 072 new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null), 073 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 074 new FieldDefinition("Number", FieldType.STRING, false, 1L, 20L), // RegExp Validated 075 new FieldDefinition("SecurityCode", FieldType.STRING, false, 1L, 10L), // RegExp Validated 076 new FieldDefinition("ExpirationMonth", FieldType.CREDIT_CARD_MONTH, false, null, null), 077 new FieldDefinition("ExpirationYear", FieldType.CREDIT_CARD_YEAR, false, null, null), 078 new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null), 079 new FieldDefinition("FirstName", FieldType.STRING, false, 1L, 20L), 080 new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L), 081 new FieldDefinition("LastName", FieldType.STRING, false, 1L, 20L), 082 new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null), 083 new FieldDefinition("Name", FieldType.STRING, false, 1L, 60L), 084 new FieldDefinition("BillingContactMechanismName", FieldType.ENTITY_NAME, false, null, null), 085 new FieldDefinition("IssuerName", FieldType.STRING, false, 1L, 60L), 086 new FieldDefinition("IssuerContactMechanismName", FieldType.ENTITY_NAME, false, null, null) 087 ); 088 } 089 090 @Inject 091 ContactControl contactControl; 092 093 @Inject 094 PartyControl partyControl; 095 096 @Inject 097 PartyPaymentMethodControl partyPaymentMethodControl; 098 099 @Inject 100 PartyPaymentMethodLogic partyPaymentMethodLogic; 101 102 103 /** Creates a new instance of EditPartyPaymentMethodCommand */ 104 public EditPartyPaymentMethodCommand() { 105 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 106 } 107 108 @Override 109 public EditPartyPaymentMethodResult getResult() { 110 return PaymentResultFactory.getEditPartyPaymentMethodResult(); 111 } 112 113 @Override 114 public PartyPaymentMethodEdit getEdit() { 115 return PaymentEditFactory.getPartyPaymentMethodEdit(); 116 } 117 118 @Override 119 public PartyPaymentMethod getEntity(EditPartyPaymentMethodResult result) { 120 PartyPaymentMethod partyPaymentMethod; 121 var partyPaymentMethodName = spec.getPartyPaymentMethodName(); 122 123 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 124 partyPaymentMethod = partyPaymentMethodControl.getPartyPaymentMethodByName(partyPaymentMethodName); 125 } else { // EditMode.UPDATE 126 partyPaymentMethod = partyPaymentMethodControl.getPartyPaymentMethodByNameForUpdate(partyPaymentMethodName); 127 } 128 129 if(partyPaymentMethod != null) { 130 var party = getParty(); 131 var partyTypeName = party.getLastDetail().getPartyType().getPartyTypeName(); 132 133 // If the executing Party is a CUSTOMER, and the PartyPaymentMethod isn't for the executing Party, 134 // return a UnknownPartyPaymentMethodName error. 135 if(partyTypeName.equals(PartyTypes.CUSTOMER.name())) { 136 if(!partyPaymentMethod.getLastDetail().getParty().equals(party)) { 137 partyPaymentMethod = null; 138 } 139 } 140 } 141 142 if(partyPaymentMethod == null) { 143 addExecutionError(ExecutionErrors.UnknownPartyPaymentMethodName.name(), partyPaymentMethodName); 144 } else { 145 result.setPartyPaymentMethod(partyPaymentMethodControl.getPartyPaymentMethodTransfer(getUserVisit(), partyPaymentMethod)); 146 } 147 148 return partyPaymentMethod; 149 } 150 151 @Override 152 public PartyPaymentMethod getLockEntity(PartyPaymentMethod partyPaymentMethod) { 153 return partyPaymentMethod; 154 } 155 156 @Override 157 public void fillInResult(EditPartyPaymentMethodResult result, PartyPaymentMethod partyPaymentMethod) { 158 result.setPartyPaymentMethod(partyPaymentMethodControl.getPartyPaymentMethodTransfer(getUserVisit(), partyPaymentMethod)); 159 } 160 161 @Override 162 public void doLock(PartyPaymentMethodEdit edit, PartyPaymentMethod partyPaymentMethod) { 163 var partyPaymentMethodDetail = partyPaymentMethod.getLastDetail(); 164 var paymentMethodTypeName = partyPaymentMethodDetail.getPaymentMethod().getLastDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName(); 165 166 edit.setDescription(partyPaymentMethodDetail.getDescription()); 167 edit.setDeleteWhenUnused(partyPaymentMethodDetail.getDeleteWhenUnused().toString()); 168 edit.setIsDefault(partyPaymentMethodDetail.getIsDefault().toString()); 169 edit.setSortOrder(partyPaymentMethodDetail.getSortOrder().toString()); 170 171 if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) { 172 var partyPaymentMethodCreditCard = partyPaymentMethodControl.getPartyPaymentMethodCreditCard(partyPaymentMethod); 173 var partyPaymentMethodCreditCardSecurityCode = partyPaymentMethodControl.getPartyPaymentMethodCreditCardSecurityCode(partyPaymentMethod); 174 var includeCreditCardNumber = securityRoleLogic.hasSecurityRoleUsingNames(null, getParty(), 175 SecurityRoleGroups.PartyPaymentMethod.name(), SecurityRoles.CreditCard.name()); 176 177 if(partyPaymentMethodCreditCard != null) { 178 var personalTitle = partyPaymentMethodCreditCard.getPersonalTitle(); 179 var nameSuffix = partyPaymentMethodCreditCard.getNameSuffix(); 180 var expirationMonth = partyPaymentMethodCreditCard.getExpirationMonth(); 181 var expirationYear = partyPaymentMethodCreditCard.getExpirationYear(); 182 var billingPartyContactMechanism = partyPaymentMethodCreditCard.getBillingPartyContactMechanism(); 183 var issuerPartyContactMechanism = partyPaymentMethodCreditCard.getIssuerPartyContactMechanism(); 184 185 edit.setPersonalTitleId(personalTitle == null? null: personalTitle.getPrimaryKey().getEntityId().toString()); 186 edit.setFirstName(partyPaymentMethodCreditCard.getFirstName()); 187 edit.setMiddleName(partyPaymentMethodCreditCard.getMiddleName()); 188 edit.setLastName(partyPaymentMethodCreditCard.getLastName()); 189 edit.setNameSuffixId(nameSuffix == null? null: nameSuffix.getPrimaryKey().getEntityId().toString()); 190 edit.setName(partyPaymentMethodCreditCard.getName()); 191 if(includeCreditCardNumber) { 192 edit.setNumber(partyPaymentMethodControl.decodePartyPaymentMethodCreditCardNumber(partyPaymentMethodCreditCard)); 193 } 194 edit.setExpirationMonth(expirationMonth == null? null: expirationMonth.toString()); 195 edit.setExpirationYear(expirationYear == null? null: expirationYear.toString()); 196 edit.setBillingContactMechanismName(billingPartyContactMechanism == null? null: billingPartyContactMechanism.getLastDetail().getContactMechanism().getLastDetail().getContactMechanismName()); 197 edit.setIssuerName(partyPaymentMethodCreditCard.getIssuerName()); 198 edit.setIssuerContactMechanismName(issuerPartyContactMechanism == null? null: issuerPartyContactMechanism.getLastDetail().getContactMechanism().getLastDetail().getContactMechanismName()); 199 } 200 201 if(partyPaymentMethodCreditCardSecurityCode != null) { 202 if(includeCreditCardNumber) { 203 edit.setSecurityCode(partyPaymentMethodControl.decodePartyPaymentMethodCreditCardSecurityCodeSecurityCode(partyPaymentMethodCreditCardSecurityCode)); 204 } 205 } 206 } 207 } 208 209 private Party getPartyFromPartyPaymentMethod(PartyPaymentMethod partyPaymentMethod) { 210 return partyPaymentMethod.getLastDetail().getParty(); 211 } 212 213 @Override 214 public void canUpdate(PartyPaymentMethod partyPaymentMethod) { 215 partyPaymentMethodLogic.checkPartyPaymentMethod(session, getUserVisit(), this, getPartyFromPartyPaymentMethod(partyPaymentMethod), 216 partyPaymentMethod.getLastDetail().getPaymentMethod(), edit); 217 } 218 219 @Override 220 public void doUpdate(PartyPaymentMethod partyPaymentMethod) { 221 var executingPartyPK = getPartyPK(); 222 var partyPaymentMethodDetailValue = partyPaymentMethodControl.getPartyPaymentMethodDetailValueForUpdate(partyPaymentMethod); 223 var paymentMethodTypeName = partyPaymentMethod.getLastDetail().getPaymentMethod().getLastDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName(); 224 225 partyPaymentMethodDetailValue.setDescription(edit.getDescription()); 226 partyPaymentMethodDetailValue.setDeleteWhenUnused(Boolean.valueOf(edit.getDeleteWhenUnused())); 227 partyPaymentMethodDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault())); 228 partyPaymentMethodDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder())); 229 230 partyPaymentMethodControl.updatePartyPaymentMethodFromValue(partyPaymentMethodDetailValue, executingPartyPK); 231 232 if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) { 233 var party = getPartyFromPartyPaymentMethod(partyPaymentMethod); 234 var soundex = new Soundex(); 235 var personalTitleId = edit.getPersonalTitleId(); 236 var personalTitle = personalTitleId == null ? null : partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY); 237 var firstName = edit.getFirstName(); 238 var middleName = edit.getMiddleName(); 239 var lastName = edit.getLastName(); 240 var nameSuffixId = edit.getNameSuffixId(); 241 var nameSuffix = nameSuffixId == null ? null : partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY); 242 var name = edit.getName(); 243 var number = edit.getNumber(); 244 var securityCode = edit.getSecurityCode(); 245 var strExpirationMonth = edit.getExpirationMonth(); 246 var expirationMonth = strExpirationMonth != null? Integer.valueOf(strExpirationMonth): null; 247 var strExpirationYear = edit.getExpirationYear(); 248 var expirationYear = strExpirationYear != null? Integer.valueOf(strExpirationYear): null; 249 var billingContactMechanismName = edit.getBillingContactMechanismName(); 250 var billingContactMechanism = billingContactMechanismName == null ? null : contactControl.getContactMechanismByName(billingContactMechanismName); 251 var billingPartyContactMechanism = billingContactMechanism == null? null: contactControl.getPartyContactMechanism(party, billingContactMechanism); 252 var issuerName = edit.getIssuerName(); 253 var issuerContactMechanismName = edit.getIssuerContactMechanismName(); 254 var issuerContactMechanism = issuerContactMechanismName == null ? null : contactControl.getContactMechanismByName(issuerContactMechanismName); 255 var issuerPartyContactMechanism = issuerContactMechanism == null? null: contactControl.getPartyContactMechanism(party, issuerContactMechanism); 256 var partyPaymentMethodCreditCardValue = partyPaymentMethodControl.getPartyPaymentMethodCreditCardValueForUpdate(partyPaymentMethod); 257 var partyPaymentMethodCreditCardSecurityCode = partyPaymentMethodControl.getPartyPaymentMethodCreditCardSecurityCodeForUpdate(partyPaymentMethod); 258 259 String firstNameSdx; 260 try { 261 firstNameSdx = firstName == null ? null : soundex.encode(firstName); 262 } catch(IllegalArgumentException iae) { 263 firstNameSdx = null; 264 } 265 266 String middleNameSdx; 267 try { 268 middleNameSdx = middleName == null ? null : soundex.encode(middleName); 269 } catch(IllegalArgumentException iae) { 270 middleNameSdx = null; 271 } 272 273 String lastNameSdx; 274 try { 275 lastNameSdx = lastName == null ? null : soundex.encode(lastName); 276 } catch(IllegalArgumentException iae) { 277 lastNameSdx = null; 278 } 279 280 partyPaymentMethodCreditCardValue.setNumber(partyPaymentMethodControl.encodePartyPaymentMethodCreditCardNumber( 281 partyPaymentMethodCreditCardValue.getInitializationVector(), number)); 282 partyPaymentMethodCreditCardValue.setExpirationMonth(expirationMonth); 283 partyPaymentMethodCreditCardValue.setExpirationYear(expirationYear); 284 partyPaymentMethodCreditCardValue.setPersonalTitlePK(personalTitle == null? null: personalTitle.getPrimaryKey()); 285 partyPaymentMethodCreditCardValue.setFirstName(firstName); 286 partyPaymentMethodCreditCardValue.setFirstNameSdx(firstNameSdx); 287 partyPaymentMethodCreditCardValue.setMiddleName(middleName); 288 partyPaymentMethodCreditCardValue.setMiddleNameSdx(middleNameSdx); 289 partyPaymentMethodCreditCardValue.setLastName(lastName); 290 partyPaymentMethodCreditCardValue.setLastNameSdx(lastNameSdx); 291 partyPaymentMethodCreditCardValue.setNameSuffixPK(nameSuffix == null? null: nameSuffix.getPrimaryKey()); 292 partyPaymentMethodCreditCardValue.setName(name); 293 partyPaymentMethodCreditCardValue.setBillingPartyContactMechanismPK(billingPartyContactMechanism == null? null: billingPartyContactMechanism.getPrimaryKey()); 294 partyPaymentMethodCreditCardValue.setIssuerName(issuerName); 295 partyPaymentMethodCreditCardValue.setIssuerPartyContactMechanismPK(issuerPartyContactMechanism == null? null: issuerPartyContactMechanism.getPrimaryKey()); 296 297 partyPaymentMethodControl.updatePartyPaymentMethodCreditCardFromValue(partyPaymentMethodCreditCardValue, executingPartyPK); 298 299 if(partyPaymentMethodCreditCardSecurityCode == null && securityCode != null) { 300 partyPaymentMethodControl.createPartyPaymentMethodCreditCardSecurityCode(partyPaymentMethod, securityCode, executingPartyPK); 301 } else { 302 if(partyPaymentMethodCreditCardSecurityCode != null && securityCode == null) { 303 partyPaymentMethodControl.deletePartyPaymentMethodCreditCardSecurityCode(partyPaymentMethodCreditCardSecurityCode, executingPartyPK); 304 } else { 305 if(partyPaymentMethodCreditCardSecurityCode != null && securityCode != null) { 306 var partyPaymentMethodCreditCardSecurityCodeValue = partyPaymentMethodControl.getPartyPaymentMethodCreditCardSecurityCodeValueForUpdate(partyPaymentMethod); 307 308 partyPaymentMethodCreditCardSecurityCodeValue.setSecurityCode(partyPaymentMethodControl.encodePartyPaymentMethodCreditCardSecurityCodeSecurityCode( 309 partyPaymentMethodCreditCardSecurityCodeValue.getInitializationVector(), securityCode)); 310 partyPaymentMethodControl.updatePartyPaymentMethodCreditCardSecurityCodeFromValue(partyPaymentMethodCreditCardSecurityCodeValue, executingPartyPK); 311 } 312 } 313 } 314 } 315 } 316 317}