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.PaymentEditFactory;
020import com.echothree.control.user.payment.common.edit.PaymentMethodEdit;
021import com.echothree.control.user.payment.common.form.EditPaymentMethodForm;
022import com.echothree.control.user.payment.common.result.EditPaymentMethodResult;
023import com.echothree.control.user.payment.common.result.PaymentResultFactory;
024import com.echothree.control.user.payment.common.spec.PaymentMethodSpec;
025import com.echothree.model.control.party.common.PartyTypes;
026import com.echothree.model.control.payment.common.PaymentMethodTypes;
027import com.echothree.model.control.payment.server.control.PaymentMethodControl;
028import com.echothree.model.control.security.common.SecurityRoleGroups;
029import com.echothree.model.control.security.common.SecurityRoles;
030import com.echothree.model.control.selector.common.SelectorKinds;
031import com.echothree.model.control.selector.common.SelectorTypes;
032import com.echothree.model.control.selector.server.control.SelectorControl;
033import com.echothree.model.data.payment.server.entity.PaymentMethod;
034import com.echothree.model.data.selector.server.entity.Selector;
035import com.echothree.model.data.user.common.pk.UserVisitPK;
036import com.echothree.util.common.command.EditMode;
037import com.echothree.util.common.form.ValidationResult;
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.validation.Validator;
046import java.util.List;
047import javax.enterprise.context.Dependent;
048import javax.inject.Inject;
049
050@Dependent
051public class EditPaymentMethodCommand
052        extends BaseAbstractEditCommand<PaymentMethodSpec, PaymentMethodEdit, EditPaymentMethodResult, PaymentMethod, PaymentMethod> {
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    private final static List<FieldDefinition> editCheckFieldDefinitions;
058    private final static List<FieldDefinition> editCreditCardFieldDefinitions;
059    
060    static {
061        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
062                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
063                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
064                        new SecurityRoleDefinition(SecurityRoleGroups.PaymentMethod.name(), SecurityRoles.Edit.name())
065                ))
066        ));
067
068        SPEC_FIELD_DEFINITIONS = List.of(
069                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null)
070        );
071        
072        EDIT_FIELD_DEFINITIONS = List.of(
073                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null),
074                new FieldDefinition("ItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
075                new FieldDefinition("SalesOrderItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
076                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
077                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
078                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
079        );
080        
081        editCheckFieldDefinitions = List.of(
082                new FieldDefinition("HoldDays", FieldType.UNSIGNED_INTEGER, true, null, null)
083        );
084        
085        editCreditCardFieldDefinitions = List.of(
086                new FieldDefinition("RequestNameOnCard", FieldType.BOOLEAN, true, null, null),
087                new FieldDefinition("RequireNameOnCard", FieldType.BOOLEAN, true, null, null),
088                new FieldDefinition("CheckCardNumber", FieldType.BOOLEAN, true, null, null),
089                new FieldDefinition("RequestExpirationDate", FieldType.BOOLEAN, true, null, null),
090                new FieldDefinition("RequireExpirationDate", FieldType.BOOLEAN, true, null, null),
091                new FieldDefinition("CheckExpirationDate", FieldType.BOOLEAN, true, null, null),
092                new FieldDefinition("RequestSecurityCode", FieldType.BOOLEAN, true, null, null),
093                new FieldDefinition("RequireSecurityCode", FieldType.BOOLEAN, true, null, null),
094                new FieldDefinition("CardNumberValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
095                new FieldDefinition("SecurityCodeValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
096                new FieldDefinition("RetainCreditCard", FieldType.BOOLEAN, true, null, null),
097                new FieldDefinition("RetainSecurityCode", FieldType.BOOLEAN, true, null, null),
098                new FieldDefinition("RequestBilling", FieldType.BOOLEAN, true, null, null),
099                new FieldDefinition("RequireBilling", FieldType.BOOLEAN, true, null, null),
100                new FieldDefinition("RequestIssuer", FieldType.BOOLEAN, true, null, null),
101                new FieldDefinition("RequireIssuer", FieldType.BOOLEAN, true, null, null)
102        );
103    }
104
105    @Inject
106    PaymentMethodControl paymentMethodControl;
107
108    @Inject
109    SelectorControl selectorControl;
110
111    
112    /** Creates a new instance of EditPaymentMethodCommand */
113    public EditPaymentMethodCommand() {
114        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
115    }
116    
117    @Override
118    protected ValidationResult validateEdit(Validator validator) {
119        var validationResult = validator.validate(edit, getEditFieldDefinitions());
120        
121        if(!validationResult.getHasErrors()) {
122            var paymentMethod = paymentMethodControl.getPaymentMethodByName(spec.getPaymentMethodName());
123            
124            if(paymentMethod != null) {
125                var paymentMethodTypeName = paymentMethod.getLastDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName();
126                
127                if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
128                    validationResult = validator.validate(edit, editCheckFieldDefinitions);
129                } else if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
130                    validationResult = validator.validate(edit, editCreditCardFieldDefinitions);
131                }
132            }
133        }
134        
135        return validationResult;
136    }
137    
138    @Override
139    public EditPaymentMethodResult getResult() {
140        return PaymentResultFactory.getEditPaymentMethodResult();
141    }
142
143    @Override
144    public PaymentMethodEdit getEdit() {
145        return PaymentEditFactory.getPaymentMethodEdit();
146    }
147
148    @Override
149    public PaymentMethod getEntity(EditPaymentMethodResult result) {
150        PaymentMethod paymentMethod;
151        var paymentMethodName = spec.getPaymentMethodName();
152
153        if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
154            paymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
155        } else { // EditMode.UPDATE
156            paymentMethod = paymentMethodControl.getPaymentMethodByNameForUpdate(paymentMethodName);
157        }
158
159        if(paymentMethod != null) {
160            result.setPaymentMethod(paymentMethodControl.getPaymentMethodTransfer(getUserVisit(), paymentMethod));
161        } else {
162            addExecutionError(ExecutionErrors.UnknownPaymentMethodName.name(), paymentMethodName);
163        }
164
165        return paymentMethod;
166    }
167
168    @Override
169    public PaymentMethod getLockEntity(PaymentMethod paymentMethod) {
170        return paymentMethod;
171    }
172
173    @Override
174    public void fillInResult(EditPaymentMethodResult result, PaymentMethod paymentMethod) {
175        result.setPaymentMethod(paymentMethodControl.getPaymentMethodTransfer(getUserVisit(), paymentMethod));
176    }
177
178    Selector itemSelector = null;
179    Selector salesOrderItemSelector = null;
180
181    @Override
182    public void doLock(PaymentMethodEdit edit, PaymentMethod paymentMethod) {
183        var paymentMethodDescription = paymentMethodControl.getPaymentMethodDescription(paymentMethod, getPreferredLanguage());
184        var paymentMethodDetail = paymentMethod.getLastDetail();
185        var paymentMethodTypeName = paymentMethodDetail.getPaymentMethodType().getLastDetail().getPaymentMethodTypeName();
186
187        itemSelector = paymentMethodDetail.getItemSelector();
188        salesOrderItemSelector = paymentMethodDetail.getSalesOrderItemSelector();
189
190        edit.setPaymentMethodName(paymentMethodDetail.getPaymentMethodName());
191        edit.setItemSelectorName(itemSelector == null? null: itemSelector.getLastDetail().getSelectorName());
192        edit.setSalesOrderItemSelectorName(salesOrderItemSelector == null? null: salesOrderItemSelector.getLastDetail().getSelectorName());
193        edit.setIsDefault(paymentMethodDetail.getIsDefault().toString());
194        edit.setSortOrder(paymentMethodDetail.getSortOrder().toString());
195
196        if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
197            var paymentMethodCheck = paymentMethodControl.getPaymentMethodCheck(paymentMethod);
198
199            edit.setHoldDays(paymentMethodCheck.getHoldDays().toString());
200        } else if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
201            var paymentMethodCreditCard = paymentMethodControl.getPaymentMethodCreditCard(paymentMethod);
202
203            edit.setRequestNameOnCard(paymentMethodCreditCard.getRequestNameOnCard().toString());
204            edit.setRequireNameOnCard(paymentMethodCreditCard.getRequireNameOnCard().toString());
205            edit.setCheckCardNumber(paymentMethodCreditCard.getCheckCardNumber().toString());
206            edit.setRequestExpirationDate(paymentMethodCreditCard.getRequestExpirationDate().toString());
207            edit.setRequireExpirationDate(paymentMethodCreditCard.getRequireExpirationDate().toString());
208            edit.setCheckExpirationDate(paymentMethodCreditCard.getCheckExpirationDate().toString());
209            edit.setRequestSecurityCode(paymentMethodCreditCard.getRequestSecurityCode().toString());
210            edit.setRequireSecurityCode(paymentMethodCreditCard.getRequireSecurityCode().toString());
211            edit.setCardNumberValidationPattern(paymentMethodCreditCard.getCardNumberValidationPattern());
212            edit.setSecurityCodeValidationPattern(paymentMethodCreditCard.getSecurityCodeValidationPattern());
213            edit.setRetainCreditCard(paymentMethodCreditCard.getRetainCreditCard().toString());
214            edit.setRetainSecurityCode(paymentMethodCreditCard.getRetainSecurityCode().toString());
215            edit.setRequestBilling(paymentMethodCreditCard.getRequestBilling().toString());
216            edit.setRequireBilling(paymentMethodCreditCard.getRequireBilling().toString());
217            edit.setRequestIssuer(paymentMethodCreditCard.getRequestIssuer().toString());
218            edit.setRequireIssuer(paymentMethodCreditCard.getRequireIssuer().toString());
219        }
220
221        if(paymentMethodDescription != null) {
222            edit.setDescription(paymentMethodDescription.getDescription());
223        }
224    }
225
226    @Override
227    public void canUpdate(PaymentMethod paymentMethod) {
228        var paymentMethodName = edit.getPaymentMethodName();
229        var duplicatePaymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
230
231        if(duplicatePaymentMethod != null && !paymentMethod.equals(duplicatePaymentMethod)) {
232            addExecutionError(ExecutionErrors.DuplicatePaymentMethodName.name(), paymentMethodName);
233        } else {
234            var itemSelectorName = edit.getItemSelectorName();
235            itemSelector = itemSelectorName == null ? null : selectorControl.getSelectorUsingNames(this, SelectorKinds.ITEM.name(),
236                    SelectorTypes.PAYMENT_METHOD.name(), itemSelectorName, ExecutionErrors.UnknownItemSelectorName.name());
237
238            if(!hasExecutionErrors()) {
239                var salesOrderItemSelectorName = edit.getSalesOrderItemSelectorName();
240                salesOrderItemSelector = salesOrderItemSelectorName == null ? null : selectorControl.getSelectorUsingNames(this,
241                        SelectorKinds.SALES_ORDER_ITEM.name(), SelectorTypes.PAYMENT_METHOD.name(), salesOrderItemSelectorName,
242                        ExecutionErrors.UnknownSalesOrderItemSelectorName.name());
243            }
244        }
245    }
246
247    @Override
248    public void doUpdate(PaymentMethod paymentMethod) {
249        var partyPK = getPartyPK();
250        var paymentMethodDetailValue = paymentMethodControl.getPaymentMethodDetailValueForUpdate(paymentMethod);
251        var paymentMethodDescription = paymentMethodControl.getPaymentMethodDescriptionForUpdate(paymentMethod, getPreferredLanguage());
252        var paymentMethodTypeName = paymentMethod.getLastDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName();
253        var description = edit.getDescription();
254
255        paymentMethodDetailValue.setPaymentMethodName(edit.getPaymentMethodName());
256        paymentMethodDetailValue.setItemSelectorPK(itemSelector == null? null: itemSelector.getPrimaryKey());
257        paymentMethodDetailValue.setSalesOrderItemSelectorPK(salesOrderItemSelector == null? null: salesOrderItemSelector.getPrimaryKey());
258        paymentMethodDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
259        paymentMethodDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
260
261        paymentMethodControl.updatePaymentMethodFromValue(paymentMethodDetailValue, partyPK);
262
263        if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
264            var paymentMethodCheckValue = paymentMethodControl.getPaymentMethodCheckValueForUpdate(paymentMethod);
265
266            paymentMethodCheckValue.setHoldDays(Integer.valueOf(edit.getHoldDays()));
267
268            paymentMethodControl.updatePaymentMethodCheckFromValue(paymentMethodCheckValue, partyPK);
269        } else {
270            if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
271                var paymentMethodCreditCardValue = paymentMethodControl.getPaymentMethodCreditCardValueForUpdate(paymentMethod);
272
273                paymentMethodCreditCardValue.setRequestNameOnCard(Boolean.valueOf(edit.getRequestNameOnCard()));
274                paymentMethodCreditCardValue.setRequireNameOnCard(Boolean.valueOf(edit.getRequireNameOnCard()));
275                paymentMethodCreditCardValue.setCheckCardNumber(Boolean.valueOf(edit.getCheckCardNumber()));
276                paymentMethodCreditCardValue.setRequestExpirationDate(Boolean.valueOf(edit.getRequestExpirationDate()));
277                paymentMethodCreditCardValue.setRequireExpirationDate(Boolean.valueOf(edit.getRequireExpirationDate()));
278                paymentMethodCreditCardValue.setCheckExpirationDate(Boolean.valueOf(edit.getCheckExpirationDate()));
279                paymentMethodCreditCardValue.setRequestSecurityCode(Boolean.valueOf(edit.getRequestSecurityCode()));
280                paymentMethodCreditCardValue.setRequireSecurityCode(Boolean.valueOf(edit.getRequireSecurityCode()));
281                paymentMethodCreditCardValue.setCardNumberValidationPattern(edit.getCardNumberValidationPattern());
282                paymentMethodCreditCardValue.setSecurityCodeValidationPattern(edit.getSecurityCodeValidationPattern());
283                paymentMethodCreditCardValue.setRetainCreditCard(Boolean.valueOf(edit.getRetainCreditCard()));
284                paymentMethodCreditCardValue.setRetainSecurityCode(Boolean.valueOf(edit.getRetainSecurityCode()));
285                paymentMethodCreditCardValue.setRequestBilling(Boolean.valueOf(edit.getRequestBilling()));
286                paymentMethodCreditCardValue.setRequireBilling(Boolean.valueOf(edit.getRequireBilling()));
287                paymentMethodCreditCardValue.setRequestIssuer(Boolean.valueOf(edit.getRequestIssuer()));
288                paymentMethodCreditCardValue.setRequireIssuer(Boolean.valueOf(edit.getRequireIssuer()));
289
290                paymentMethodControl.updatePaymentMethodCreditCardFromValue(paymentMethodCreditCardValue, partyPK);
291            }
292        }
293
294        if(paymentMethodDescription == null && description != null) {
295            paymentMethodControl.createPaymentMethodDescription(paymentMethod, getPreferredLanguage(), description, partyPK);
296        } else {
297            if(paymentMethodDescription != null && description == null) {
298                paymentMethodControl.deletePaymentMethodDescription(paymentMethodDescription, partyPK);
299            } else {
300                if(paymentMethodDescription != null && description != null) {
301                    var paymentMethodDescriptionValue = paymentMethodControl.getPaymentMethodDescriptionValue(paymentMethodDescription);
302
303                    paymentMethodDescriptionValue.setDescription(description);
304                    paymentMethodControl.updatePaymentMethodDescriptionFromValue(paymentMethodDescriptionValue, partyPK);
305                }
306            }
307        }
308    }
309
310}