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.CreatePaymentMethodForm;
020import com.echothree.control.user.payment.common.result.CreatePaymentMethodResult;
021import com.echothree.control.user.payment.common.result.PaymentResultFactory;
022import com.echothree.model.control.party.common.PartyTypes;
023import com.echothree.model.control.payment.common.PaymentMethodTypes;
024import com.echothree.model.control.payment.server.control.PaymentMethodControl;
025import com.echothree.model.control.payment.server.control.PaymentProcessorControl;
026import com.echothree.model.control.payment.server.logic.PaymentMethodTypeLogic;
027import com.echothree.model.control.security.common.SecurityRoleGroups;
028import com.echothree.model.control.security.common.SecurityRoles;
029import com.echothree.model.control.selector.common.SelectorKinds;
030import com.echothree.model.control.selector.common.SelectorTypes;
031import com.echothree.model.control.selector.server.control.SelectorControl;
032import com.echothree.model.data.party.server.entity.Language;
033import com.echothree.model.data.payment.server.entity.PaymentMethod;
034import com.echothree.model.data.payment.server.entity.PaymentMethodType;
035import com.echothree.model.data.payment.server.entity.PaymentProcessor;
036import com.echothree.model.data.selector.server.entity.Selector;
037import com.echothree.model.data.user.common.pk.UserVisitPK;
038import com.echothree.util.common.command.BaseResult;
039import com.echothree.util.common.form.ValidationResult;
040import com.echothree.util.common.message.ExecutionErrors;
041import com.echothree.util.common.validation.FieldDefinition;
042import com.echothree.util.common.validation.FieldType;
043import com.echothree.util.server.control.BaseSimpleCommand;
044import com.echothree.util.server.control.CommandSecurityDefinition;
045import com.echothree.util.server.control.PartyTypeDefinition;
046import com.echothree.util.server.control.SecurityRoleDefinition;
047import com.echothree.util.server.persistence.Session;
048import com.echothree.util.server.validation.Validator;
049import java.util.Arrays;
050import java.util.Collections;
051import java.util.List;
052
053public class CreatePaymentMethodCommand
054        extends BaseSimpleCommand<CreatePaymentMethodForm> {
055    
056    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
057    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
058    private final static List<FieldDefinition> formCheckFieldDefinitions;
059    private final static List<FieldDefinition> formCreditCardFieldDefinitions;
060    
061    static {
062        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
063                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
064                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
065                        new SecurityRoleDefinition(SecurityRoleGroups.PaymentMethod.name(), SecurityRoles.Create.name())
066                        )))
067                )));
068
069        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
070                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null),
071                new FieldDefinition("PaymentMethodTypeName", FieldType.ENTITY_NAME, true, null, null),
072                new FieldDefinition("PaymentProcessorName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("ItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("SalesOrderItemSelectorName", FieldType.ENTITY_NAME, false, null, null),
075                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
076                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
077                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
078                ));
079        
080        formCheckFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
081                new FieldDefinition("HoldDays", FieldType.UNSIGNED_INTEGER, true, null, null)
082                ));
083        
084        formCreditCardFieldDefinitions = Collections.unmodifiableList(Arrays.asList(
085                new FieldDefinition("RequestNameOnCard", FieldType.BOOLEAN, true, null, null),
086                new FieldDefinition("RequireNameOnCard", FieldType.BOOLEAN, true, null, null),
087                new FieldDefinition("CheckCardNumber", FieldType.BOOLEAN, true, null, null),
088                new FieldDefinition("RequestExpirationDate", FieldType.BOOLEAN, true, null, null),
089                new FieldDefinition("RequireExpirationDate", FieldType.BOOLEAN, true, null, null),
090                new FieldDefinition("CheckExpirationDate", FieldType.BOOLEAN, true, null, null),
091                new FieldDefinition("RequestSecurityCode", FieldType.BOOLEAN, true, null, null),
092                new FieldDefinition("RequireSecurityCode", FieldType.BOOLEAN, true, null, null),
093                new FieldDefinition("CardNumberValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
094                new FieldDefinition("SecurityCodeValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
095                new FieldDefinition("RetainCreditCard", FieldType.BOOLEAN, true, null, null),
096                new FieldDefinition("RetainSecurityCode", FieldType.BOOLEAN, true, null, null),
097                new FieldDefinition("RequestBilling", FieldType.BOOLEAN, true, null, null),
098                new FieldDefinition("RequireBilling", FieldType.BOOLEAN, true, null, null),
099                new FieldDefinition("RequestIssuer", FieldType.BOOLEAN, true, null, null),
100                new FieldDefinition("RequireIssuer", FieldType.BOOLEAN, true, null, null)
101                ));
102    }
103    
104    /** Creates a new instance of CreatePaymentMethodCommand */
105    public CreatePaymentMethodCommand(UserVisitPK userVisitPK, CreatePaymentMethodForm form) {
106        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, null, false);
107    }
108    
109    @Override
110    protected ValidationResult validate() {
111        Validator validator = new Validator(this);
112        ValidationResult validationResult = validator.validate(form, FORM_FIELD_DEFINITIONS);
113        
114        if(!validationResult.getHasErrors()) {
115            String paymentMethodTypeName = form.getPaymentMethodTypeName();
116            
117            if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
118                validationResult = validator.validate(form, formCheckFieldDefinitions);
119            } else if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
120                validationResult = validator.validate(form, formCreditCardFieldDefinitions);
121            }
122        }
123        
124        return validationResult;
125    }
126    
127    @Override
128    protected BaseResult execute() {
129        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
130        CreatePaymentMethodResult result = PaymentResultFactory.getCreatePaymentMethodResult();
131        String paymentMethodName = form.getPaymentMethodName();
132        PaymentMethod paymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
133
134        if(paymentMethod == null) {
135            String paymentMethodTypeName = form.getPaymentMethodTypeName();
136            PaymentMethodType paymentMethodType = PaymentMethodTypeLogic.getInstance().getPaymentMethodTypeByName(this, paymentMethodTypeName);
137
138            if(!hasExecutionErrors()) {
139                var paymentProcessorControl = Session.getModelController(PaymentProcessorControl.class);
140                String paymentProcessorName = form.getPaymentProcessorName();
141                PaymentProcessor paymentProcessor = paymentProcessorName == null ? null : paymentProcessorControl.getPaymentProcessorByName(paymentProcessorName);
142
143                if(paymentProcessorName == null || paymentProcessor != null) {
144                    var selectorControl = Session.getModelController(SelectorControl.class);
145                    String itemSelectorName = form.getItemSelectorName();
146                    Selector itemSelector = itemSelectorName == null ? null : selectorControl.getSelectorUsingNames(this, SelectorKinds.ITEM.name(),
147                            SelectorTypes.PAYMENT_METHOD.name(), itemSelectorName, ExecutionErrors.UnknownItemSelectorName.name());
148
149                    if(!hasExecutionErrors()) {
150                        String salesOrderItemSelectorName = form.getSalesOrderItemSelectorName();
151                        Selector salesOrderItemSelector = salesOrderItemSelectorName == null ? null : selectorControl.getSelectorUsingNames(this,
152                                SelectorKinds.SALES_ORDER_ITEM.name(), SelectorTypes.PAYMENT_METHOD.name(), salesOrderItemSelectorName,
153                                ExecutionErrors.UnknownSalesOrderItemSelectorName.name());
154
155                        if(!hasExecutionErrors()) {
156                            var partyPK = getPartyPK();
157                            var isDefault = Boolean.valueOf(form.getIsDefault());
158                            var sortOrder = Integer.valueOf(form.getSortOrder());
159                            var description = form.getDescription();
160
161                            paymentMethod = paymentMethodControl.createPaymentMethod(paymentMethodName, paymentMethodType, paymentProcessor, itemSelector, salesOrderItemSelector,
162                                    isDefault, sortOrder, partyPK);
163
164                            if(paymentMethodTypeName.equals(PaymentMethodTypes.CHECK.name())) {
165                                Integer holdDays = Integer.valueOf(form.getHoldDays());
166
167                                paymentMethodControl.createPaymentMethodCheck(paymentMethod, holdDays, partyPK);
168                            } else {
169                                if(paymentMethodTypeName.equals(PaymentMethodTypes.CREDIT_CARD.name())) {
170                                    Boolean requestNameOnCard = Boolean.valueOf(form.getRequestNameOnCard());
171                                    Boolean requireNameOnCard = Boolean.valueOf(form.getRequireNameOnCard());
172                                    Boolean checkCardNumber = Boolean.valueOf(form.getCheckCardNumber());
173                                    Boolean requestExpirationDate = Boolean.valueOf(form.getRequestExpirationDate());
174                                    Boolean requireExpirationDate = Boolean.valueOf(form.getRequireExpirationDate());
175                                    Boolean checkExpirationDate = Boolean.valueOf(form.getCheckExpirationDate());
176                                    Boolean requestSecurityCode = Boolean.valueOf(form.getRequestSecurityCode());
177                                    Boolean requireSecurityCode = Boolean.valueOf(form.getRequireSecurityCode());
178                                    String cardNumberValidationPattern = form.getCardNumberValidationPattern();
179                                    String securityCodeValidationPattern = form.getSecurityCodeValidationPattern();
180                                    Boolean retainCreditCard = Boolean.valueOf(form.getRetainCreditCard());
181                                    Boolean retainSecurityCode = Boolean.valueOf(form.getRetainSecurityCode());
182                                    Boolean requestBilling = Boolean.valueOf(form.getRequestBilling());
183                                    Boolean requireBilling = Boolean.valueOf(form.getRequireBilling());
184                                    Boolean requestIssuer = Boolean.valueOf(form.getRequestIssuer());
185                                    Boolean requireIssuer = Boolean.valueOf(form.getRequireIssuer());
186
187                                    paymentMethodControl.createPaymentMethodCreditCard(paymentMethod, requestNameOnCard, requireNameOnCard,
188                                            checkCardNumber, requestExpirationDate, requireExpirationDate, checkExpirationDate, requestSecurityCode,
189                                            requireSecurityCode, cardNumberValidationPattern, securityCodeValidationPattern, retainCreditCard,
190                                            retainSecurityCode, requestBilling, requireBilling, requestIssuer, requireIssuer, partyPK);
191                                }
192                            }
193
194                            if(description != null) {
195                                Language language = getPreferredLanguage();
196
197                                paymentMethodControl.createPaymentMethodDescription(paymentMethod, language, description, partyPK);
198                            }
199                        }
200                    }
201                } else {
202                    addExecutionError(ExecutionErrors.UnknownPaymentProcessorName.name(), paymentProcessorName);
203                }
204            }
205        } else {
206            addExecutionError(ExecutionErrors.DuplicatePaymentMethodName.name(), paymentMethodName);
207        }
208
209        if(paymentMethod != null) {
210            result.setEntityRef(paymentMethod.getPrimaryKey().getEntityRef());
211        }
212
213        return result;
214    }
215    
216}