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.payment.server.command; 018 019import com.echothree.control.user.payment.common.form.CreatePartyPaymentMethodForm; 020import com.echothree.control.user.payment.common.result.CreatePartyPaymentMethodResult; 021import com.echothree.control.user.payment.common.result.PaymentResultFactory; 022import com.echothree.model.control.contact.common.ContactMechanismPurposes; 023import com.echothree.model.control.contact.server.control.ContactControl; 024import com.echothree.model.control.party.common.PartyTypes; 025import com.echothree.model.control.party.server.control.PartyControl; 026import com.echothree.model.control.payment.common.PaymentMethodTypes; 027import com.echothree.model.control.payment.server.control.PartyPaymentMethodControl; 028import com.echothree.model.control.payment.server.control.PaymentMethodControl; 029import com.echothree.model.control.payment.server.control.PaymentMethodTypePartyTypeControl; 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.workflow.server.control.WorkflowControl; 034import com.echothree.model.data.contact.server.entity.ContactMechanism; 035import com.echothree.model.data.contact.server.entity.ContactMechanismPurpose; 036import com.echothree.model.data.contact.server.entity.PartyContactMechanism; 037import com.echothree.model.data.contact.server.entity.PartyContactMechanismPurpose; 038import com.echothree.model.data.party.common.pk.PartyPK; 039import com.echothree.model.data.party.server.entity.NameSuffix; 040import com.echothree.model.data.party.server.entity.Party; 041import com.echothree.model.data.party.server.entity.PartyType; 042import com.echothree.model.data.party.server.entity.PersonalTitle; 043import com.echothree.model.data.payment.server.entity.PartyPaymentMethod; 044import com.echothree.model.data.payment.server.entity.PartyPaymentMethodContactMechanism; 045import com.echothree.model.data.payment.server.entity.PaymentMethod; 046import com.echothree.model.data.payment.server.entity.PaymentMethodType; 047import com.echothree.model.data.user.common.pk.UserVisitPK; 048import com.echothree.util.common.command.BaseResult; 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.BaseSimpleCommand; 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.EntityPermission; 057import com.echothree.util.server.persistence.Session; 058import java.util.Arrays; 059import java.util.Collections; 060import java.util.List; 061import org.apache.commons.codec.language.Soundex; 062 063public class CreatePartyPaymentMethodCommand 064 extends BaseSimpleCommand<CreatePartyPaymentMethodForm> { 065 066 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 067 private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS; 068 069 static { 070 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList( 071 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 072 new PartyTypeDefinition(PartyTypes.CUSTOMER.name(), null), 073 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList( 074 new SecurityRoleDefinition(SecurityRoleGroups.PartyPaymentMethod.name(), SecurityRoles.Create.name()) 075 ))) 076 ))); 077 078 FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 079 new FieldDefinition("PartyName", FieldType.ENTITY_NAME, false, null, null), 080 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L), 081 new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null), 082 new FieldDefinition("DeleteWhenUnused", FieldType.BOOLEAN, true, null, null), 083 new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null), 084 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 085 new FieldDefinition("Number", FieldType.STRING, false, 1L, 20L), // RegExp Validated 086 new FieldDefinition("SecurityCode", FieldType.STRING, false, 1L, 10L), // RegExp Validated 087 new FieldDefinition("ExpirationMonth", FieldType.CREDIT_CARD_MONTH, false, null, null), 088 new FieldDefinition("ExpirationYear", FieldType.CREDIT_CARD_YEAR, false, null, null), 089 new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null), 090 new FieldDefinition("FirstName", FieldType.STRING, false, 1L, 20L), 091 new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L), 092 new FieldDefinition("LastName", FieldType.STRING, false, 1L, 20L), 093 new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null), 094 new FieldDefinition("Name", FieldType.STRING, false, 1L, 60L), 095 new FieldDefinition("BillingContactMechanismName", FieldType.ENTITY_NAME, false, null, null), 096 new FieldDefinition("IssuerName", FieldType.STRING, false, 1L, 60L), 097 new FieldDefinition("IssuerContactMechanismName", FieldType.ENTITY_NAME, false, null, null) 098 )); 099 } 100 101 /** Creates a new instance of CreatePartyPaymentMethodCommand */ 102 public CreatePartyPaymentMethodCommand(UserVisitPK userVisitPK, CreatePartyPaymentMethodForm form) { 103 super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false); 104 } 105 106 private void setupWorkflows(final PaymentMethodType paymentMethodType, final PartyType partyType, 107 final PartyPaymentMethodContactMechanism billingPartyPaymentMethodContactMechanism, 108 final PartyPaymentMethod partyPaymentMethod, final PartyPK createdBy) { 109 var paymentMethodTypePartyTypeControl = Session.getModelController(PaymentMethodTypePartyTypeControl.class); 110 var workflowControl = Session.getModelController(WorkflowControl.class); 111 var paymentMethodTypePartyType = paymentMethodTypePartyTypeControl.getPaymentMethodTypePartyType(paymentMethodType, partyType); 112 113 if(paymentMethodTypePartyType != null) { 114 var paymentMethodTypePartyTypeDetail = paymentMethodTypePartyType.getLastDetail(); 115 116 if(billingPartyPaymentMethodContactMechanism != null) { 117 var contactMechanismWorkflow = paymentMethodTypePartyTypeDetail.getPartyContactMechanismWorkflow(); 118 119 if(contactMechanismWorkflow != null) { 120 var entityInstance = getCoreControl().getEntityInstanceByBasePK(billingPartyPaymentMethodContactMechanism.getPrimaryKey()); 121 122 if(!workflowControl.isEntityInWorkflow(contactMechanismWorkflow, entityInstance)) { 123 workflowControl.addEntityToWorkflow(contactMechanismWorkflow, entityInstance, null, null, createdBy); 124 } 125 } 126 } 127 128 var partyPaymentMethodWorkflow = paymentMethodTypePartyTypeDetail.getPartyPaymentMethodWorkflow(); 129 130 if(partyPaymentMethodWorkflow != null) { 131 var entityInstance = getCoreControl().getEntityInstanceByBasePK(partyPaymentMethod.getPrimaryKey()); 132 133 workflowControl.addEntityToWorkflow(partyPaymentMethodWorkflow, entityInstance, null, null, createdBy); 134 } 135 } 136 } 137 138 private PartyPaymentMethodContactMechanism setupPartyPaymentMethodContactMechanism(final ContactControl contactControl, 139 final PartyPaymentMethodControl partyPaymentMethodControl, final PartyContactMechanism partyContactMechanism, 140 final PartyPaymentMethod partyPaymentMethod, final PartyPK createdBy) { 141 ContactMechanismPurpose contactMechanismPurpose = contactControl.getContactMechanismPurposeByName(ContactMechanismPurposes.PHYSICAL_BILLING.name()); 142 PartyContactMechanismPurpose partyContactMechanismPurpose = contactControl.getPartyContactMechanismPurpose(partyContactMechanism, 143 contactMechanismPurpose); 144 145 if(partyContactMechanismPurpose == null) { 146 partyContactMechanismPurpose = contactControl.createPartyContactMechanismPurpose(partyContactMechanism, 147 contactMechanismPurpose, Boolean.FALSE, 1, createdBy); 148 } 149 150 return partyPaymentMethodControl.createPartyPaymentMethodContactMechanism(partyPaymentMethod, partyContactMechanismPurpose, createdBy); 151 } 152 153 @Override 154 protected BaseResult execute() { 155 var partyControl = Session.getModelController(PartyControl.class); 156 CreatePartyPaymentMethodResult result = PaymentResultFactory.getCreatePartyPaymentMethodResult(); 157 Party party = getParty(); 158 String partyTypeName = party.getLastDetail().getPartyType().getPartyTypeName(); 159 160 // If the caller is a CUSTOMER, then they're the Party. If they're not, the PartyName parameter is 161 // required, and we'll look them up. 162 if(!partyTypeName.equals(PartyTypes.CUSTOMER.name())) { 163 String partyName = form.getPartyName(); 164 165 if(partyName == null) { 166 addExecutionError(ExecutionErrors.PartyNameRequired.name()); 167 } else { 168 party = partyControl.getPartyByName(partyName); 169 170 if(party == null) { 171 addExecutionError(ExecutionErrors.UnknownPartyName.name(), partyName); 172 } 173 } 174 } 175 176 if(!hasExecutionErrors()) { 177 var paymentMethodControl = Session.getModelController(PaymentMethodControl.class); 178 String paymentMethodName = form.getPaymentMethodName(); 179 PaymentMethod paymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName); 180 181 if(paymentMethod != null) { 182 PartyPaymentMethodLogic.getInstance().checkPartyPaymentMethod(session, getUserVisit(), this, party, paymentMethod, form); 183 184 if(!hasExecutionErrors()) { 185 PaymentMethodType paymentMethodType = paymentMethod.getLastDetail().getPaymentMethodType(); 186 String paymentMethodTypeName = paymentMethodType.getLastDetail().getPaymentMethodTypeName(); 187 188 if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) { 189 var partyPaymentMethodControl = Session.getModelController(PartyPaymentMethodControl.class); 190 var contactControl = Session.getModelController(ContactControl.class); 191 Soundex soundex = new Soundex(); 192 String personalTitleId = form.getPersonalTitleId(); 193 PersonalTitle personalTitle = personalTitleId == null ? null : partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY); 194 String firstName = form.getFirstName(); 195 String middleName = form.getMiddleName(); 196 String lastName = form.getLastName(); 197 String nameSuffixId = form.getNameSuffixId(); 198 NameSuffix nameSuffix = nameSuffixId == null ? null : partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY); 199 String name = form.getName(); 200 String number = form.getNumber(); 201 String securityCode = form.getSecurityCode(); 202 String strExpirationMonth = form.getExpirationMonth(); 203 Integer expirationMonth = strExpirationMonth != null? Integer.valueOf(strExpirationMonth): null; 204 String strExpirationYear = form.getExpirationYear(); 205 Integer expirationYear = strExpirationYear != null? Integer.valueOf(strExpirationYear): null; 206 String billingContactMechanismName = form.getBillingContactMechanismName(); 207 ContactMechanism billingContactMechanism = billingContactMechanismName == null ? null : contactControl.getContactMechanismByName(billingContactMechanismName); 208 PartyContactMechanism billingPartyContactMechanism = billingContactMechanism == null? null: contactControl.getPartyContactMechanism(party, billingContactMechanism); 209 String issuerName = form.getIssuerName(); 210 String issuerContactMechanismName = form.getIssuerContactMechanismName(); 211 ContactMechanism issuerContactMechanism = issuerContactMechanismName == null ? null : contactControl.getContactMechanismByName(issuerContactMechanismName); 212 PartyContactMechanism issuerPartyContactMechanism = issuerContactMechanism == null? null: contactControl.getPartyContactMechanism(party, issuerContactMechanism); 213 214 String firstNameSdx; 215 try { 216 firstNameSdx = firstName == null ? null : soundex.encode(firstName); 217 } catch(IllegalArgumentException iae) { 218 firstNameSdx = null; 219 } 220 221 String middleNameSdx; 222 try { 223 middleNameSdx = middleName == null ? null : soundex.encode(middleName); 224 } catch(IllegalArgumentException iae) { 225 middleNameSdx = null; 226 } 227 228 String lastNameSdx; 229 try { 230 lastNameSdx = lastName == null ? null : soundex.encode(lastName); 231 } catch(IllegalArgumentException iae) { 232 lastNameSdx = null; 233 } 234 235 PartyPK createdBy = getPartyPK(); 236 var description = form.getDescription(); 237 Boolean deleteWhenUnused = Boolean.valueOf(form.getDeleteWhenUnused()); 238 var isDefault = Boolean.valueOf(form.getIsDefault()); 239 var sortOrder = Integer.valueOf(form.getSortOrder()); 240 241 var partyPaymentMethod = partyPaymentMethodControl.createPartyPaymentMethod(party, description, 242 paymentMethod, deleteWhenUnused, isDefault, sortOrder, createdBy); 243 244 partyPaymentMethodControl.createPartyPaymentMethodCreditCard(partyPaymentMethod, number, expirationMonth, 245 expirationYear, personalTitle, firstName, firstNameSdx, middleName, middleNameSdx, lastName, 246 lastNameSdx, nameSuffix, name, billingPartyContactMechanism, issuerName, issuerPartyContactMechanism, 247 createdBy); 248 249 partyPaymentMethodControl.createPartyPaymentMethodCreditCardSecurityCode(partyPaymentMethod, securityCode, 250 createdBy); 251 252 PartyPaymentMethodContactMechanism billingPartyPaymentMethodContactMechanism = billingPartyContactMechanism == null ? null 253 : setupPartyPaymentMethodContactMechanism(contactControl, partyPaymentMethodControl, billingPartyContactMechanism, partyPaymentMethod, 254 createdBy); 255 256 setupWorkflows(paymentMethodType, party.getLastDetail().getPartyType(), 257 billingPartyPaymentMethodContactMechanism, partyPaymentMethod, createdBy); 258 259 result.setEntityRef(partyPaymentMethod.getPrimaryKey().getEntityRef()); 260 result.setPartyPaymentMethodName(partyPaymentMethod.getLastDetail().getPartyPaymentMethodName()); 261 } 262 } 263 } else { 264 addExecutionError(ExecutionErrors.UnknownPaymentMethodName.name(), paymentMethodName); 265 } 266 } 267 268 return result; 269 } 270 271}