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