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