001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 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.persistence.Session;
046import com.echothree.util.server.validation.Validator;
047import java.util.Arrays;
048import java.util.Collections;
049import java.util.List;
050import javax.enterprise.context.RequestScoped;
051
052@RequestScoped
053public class EditPaymentMethodCommand
054        extends BaseAbstractEditCommand<PaymentMethodSpec, PaymentMethodEdit, EditPaymentMethodResult, PaymentMethod, PaymentMethod> {
055    
056    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
057    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
058    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
059    private final static List<FieldDefinition> editCheckFieldDefinitions;
060    private final static List<FieldDefinition> editCreditCardFieldDefinitions;
061    
062    static {
063        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
064                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
065                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
066                    new SecurityRoleDefinition(SecurityRoleGroups.PaymentMethod.name(), SecurityRoles.Edit.name())
067                    )))
068                )));
069
070        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
071                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null)
072                ));
073        
074        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
075                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null),
076                new FieldDefinition("ItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
077                new FieldDefinition("SalesOrderItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
078                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
079                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
080                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
081                ));
082        
083        editCheckFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
084                new FieldDefinition("HoldDays", FieldType.UNSIGNED_INTEGER, true, null, null)
085                ));
086        
087        editCreditCardFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
088                new FieldDefinition("RequestNameOnCard", FieldType.BOOLEAN, true, null, null),
089                new FieldDefinition("RequireNameOnCard", FieldType.BOOLEAN, true, null, null),
090                new FieldDefinition("CheckCardNumber", FieldType.BOOLEAN, true, null, null),
091                new FieldDefinition("RequestExpirationDate", FieldType.BOOLEAN, true, null, null),
092                new FieldDefinition("RequireExpirationDate", FieldType.BOOLEAN, true, null, null),
093                new FieldDefinition("CheckExpirationDate", FieldType.BOOLEAN, true, null, null),
094                new FieldDefinition("RequestSecurityCode", FieldType.BOOLEAN, true, null, null),
095                new FieldDefinition("RequireSecurityCode", FieldType.BOOLEAN, true, null, null),
096                new FieldDefinition("CardNumberValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
097                new FieldDefinition("SecurityCodeValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
098                new FieldDefinition("RetainCreditCard", FieldType.BOOLEAN, true, null, null),
099                new FieldDefinition("RetainSecurityCode", FieldType.BOOLEAN, true, null, null),
100                new FieldDefinition("RequestBilling", FieldType.BOOLEAN, true, null, null),
101                new FieldDefinition("RequireBilling", FieldType.BOOLEAN, true, null, null),
102                new FieldDefinition("RequestIssuer", FieldType.BOOLEAN, true, null, null),
103                new FieldDefinition("RequireIssuer", FieldType.BOOLEAN, true, null, null)
104                ));
105    }
106    
107    /** Creates a new instance of EditPaymentMethodCommand */
108    public EditPaymentMethodCommand() {
109        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
110    }
111    
112    @Override
113    protected ValidationResult validateEdit(Validator validator) {
114        var validationResult = validator.validate(edit, getEditFieldDefinitions());
115        
116        if(!validationResult.getHasErrors()) {
117            var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
118            var paymentMethod = paymentMethodControl.getPaymentMethodByName(spec.getPaymentMethodName());
119            
120            if(paymentMethod != null) {
121                var paymentMethodTypeName = paymentMethod.getLastDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName();
122                
123                if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
124                    validationResult = validator.validate(edit, editCheckFieldDefinitions);
125                } else if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
126                    validationResult = validator.validate(edit, editCreditCardFieldDefinitions);
127                }
128            }
129        }
130        
131        return validationResult;
132    }
133    
134    @Override
135    public EditPaymentMethodResult getResult() {
136        return PaymentResultFactory.getEditPaymentMethodResult();
137    }
138
139    @Override
140    public PaymentMethodEdit getEdit() {
141        return PaymentEditFactory.getPaymentMethodEdit();
142    }
143
144    @Override
145    public PaymentMethod getEntity(EditPaymentMethodResult result) {
146        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
147        PaymentMethod paymentMethod;
148        var paymentMethodName = spec.getPaymentMethodName();
149
150        if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
151            paymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
152        } else { // EditMode.UPDATE
153            paymentMethod = paymentMethodControl.getPaymentMethodByNameForUpdate(paymentMethodName);
154        }
155
156        if(paymentMethod != null) {
157            result.setPaymentMethod(paymentMethodControl.getPaymentMethodTransfer(getUserVisit(), paymentMethod));
158        } else {
159            addExecutionError(ExecutionErrors.UnknownPaymentMethodName.name(), paymentMethodName);
160        }
161
162        return paymentMethod;
163    }
164
165    @Override
166    public PaymentMethod getLockEntity(PaymentMethod paymentMethod) {
167        return paymentMethod;
168    }
169
170    @Override
171    public void fillInResult(EditPaymentMethodResult result, PaymentMethod paymentMethod) {
172        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
173
174        result.setPaymentMethod(paymentMethodControl.getPaymentMethodTransfer(getUserVisit(), paymentMethod));
175    }
176
177    Selector itemSelector = null;
178    Selector salesOrderItemSelector = null;
179
180    @Override
181    public void doLock(PaymentMethodEdit edit, PaymentMethod paymentMethod) {
182        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
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 paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
229        var paymentMethodName = edit.getPaymentMethodName();
230        var duplicatePaymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
231
232        if(duplicatePaymentMethod != null && !paymentMethod.equals(duplicatePaymentMethod)) {
233            addExecutionError(ExecutionErrors.DuplicatePaymentMethodName.name(), paymentMethodName);
234        } else {
235            var selectorControl = Session.getModelController(SelectorControl.class);
236            var itemSelectorName = edit.getItemSelectorName();
237            itemSelector = itemSelectorName == null ? null : selectorControl.getSelectorUsingNames(this, SelectorKinds.ITEM.name(),
238                    SelectorTypes.PAYMENT_METHOD.name(), itemSelectorName, ExecutionErrors.UnknownItemSelectorName.name());
239
240            if(!hasExecutionErrors()) {
241                var salesOrderItemSelectorName = edit.getSalesOrderItemSelectorName();
242                salesOrderItemSelector = salesOrderItemSelectorName == null ? null : selectorControl.getSelectorUsingNames(this,
243                        SelectorKinds.SALES_ORDER_ITEM.name(), SelectorTypes.PAYMENT_METHOD.name(), salesOrderItemSelectorName,
244                        ExecutionErrors.UnknownSalesOrderItemSelectorName.name());
245            }
246        }
247    }
248
249    @Override
250    public void doUpdate(PaymentMethod paymentMethod) {
251        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
252        var partyPK = getPartyPK();
253        var paymentMethodDetailValue = paymentMethodControl.getPaymentMethodDetailValueForUpdate(paymentMethod);
254        var paymentMethodDescription = paymentMethodControl.getPaymentMethodDescriptionForUpdate(paymentMethod, getPreferredLanguage());
255        var paymentMethodTypeName = paymentMethod.getLastDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName();
256        var description = edit.getDescription();
257
258        paymentMethodDetailValue.setPaymentMethodName(edit.getPaymentMethodName());
259        paymentMethodDetailValue.setItemSelectorPK(itemSelector == null? null: itemSelector.getPrimaryKey());
260        paymentMethodDetailValue.setSalesOrderItemSelectorPK(salesOrderItemSelector == null? null: salesOrderItemSelector.getPrimaryKey());
261        paymentMethodDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
262        paymentMethodDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
263
264        paymentMethodControl.updatePaymentMethodFromValue(paymentMethodDetailValue, partyPK);
265
266        if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
267            var paymentMethodCheckValue = paymentMethodControl.getPaymentMethodCheckValueForUpdate(paymentMethod);
268
269            paymentMethodCheckValue.setHoldDays(Integer.valueOf(edit.getHoldDays()));
270
271            paymentMethodControl.updatePaymentMethodCheckFromValue(paymentMethodCheckValue, partyPK);
272        } else {
273            if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
274                var paymentMethodCreditCardValue = paymentMethodControl.getPaymentMethodCreditCardValueForUpdate(paymentMethod);
275
276                paymentMethodCreditCardValue.setRequestNameOnCard(Boolean.valueOf(edit.getRequestNameOnCard()));
277                paymentMethodCreditCardValue.setRequireNameOnCard(Boolean.valueOf(edit.getRequireNameOnCard()));
278                paymentMethodCreditCardValue.setCheckCardNumber(Boolean.valueOf(edit.getCheckCardNumber()));
279                paymentMethodCreditCardValue.setRequestExpirationDate(Boolean.valueOf(edit.getRequestExpirationDate()));
280                paymentMethodCreditCardValue.setRequireExpirationDate(Boolean.valueOf(edit.getRequireExpirationDate()));
281                paymentMethodCreditCardValue.setCheckExpirationDate(Boolean.valueOf(edit.getCheckExpirationDate()));
282                paymentMethodCreditCardValue.setRequestSecurityCode(Boolean.valueOf(edit.getRequestSecurityCode()));
283                paymentMethodCreditCardValue.setRequireSecurityCode(Boolean.valueOf(edit.getRequireSecurityCode()));
284                paymentMethodCreditCardValue.setCardNumberValidationPattern(edit.getCardNumberValidationPattern());
285                paymentMethodCreditCardValue.setSecurityCodeValidationPattern(edit.getSecurityCodeValidationPattern());
286                paymentMethodCreditCardValue.setRetainCreditCard(Boolean.valueOf(edit.getRetainCreditCard()));
287                paymentMethodCreditCardValue.setRetainSecurityCode(Boolean.valueOf(edit.getRetainSecurityCode()));
288                paymentMethodCreditCardValue.setRequestBilling(Boolean.valueOf(edit.getRequestBilling()));
289                paymentMethodCreditCardValue.setRequireBilling(Boolean.valueOf(edit.getRequireBilling()));
290                paymentMethodCreditCardValue.setRequestIssuer(Boolean.valueOf(edit.getRequestIssuer()));
291                paymentMethodCreditCardValue.setRequireIssuer(Boolean.valueOf(edit.getRequireIssuer()));
292
293                paymentMethodControl.updatePaymentMethodCreditCardFromValue(paymentMethodCreditCardValue, partyPK);
294            }
295        }
296
297        if(paymentMethodDescription == null && description != null) {
298            paymentMethodControl.createPaymentMethodDescription(paymentMethod, getPreferredLanguage(), description, partyPK);
299        } else {
300            if(paymentMethodDescription != null && description == null) {
301                paymentMethodControl.deletePaymentMethodDescription(paymentMethodDescription, partyPK);
302            } else {
303                if(paymentMethodDescription != null && description != null) {
304                    var paymentMethodDescriptionValue = paymentMethodControl.getPaymentMethodDescriptionValue(paymentMethodDescription);
305
306                    paymentMethodDescriptionValue.setDescription(description);
307                    paymentMethodControl.updatePaymentMethodDescriptionFromValue(paymentMethodDescriptionValue, partyPK);
308                }
309            }
310        }
311    }
312
313}