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