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.model.control.payment.server.graphql;
018
019import com.echothree.model.control.customer.server.control.CustomerControl;
020import com.echothree.model.control.customer.server.graphql.CustomerSecurityUtils;
021import com.echothree.model.control.customer.server.graphql.CustomerTypePaymentMethodObject;
022import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject;
023import com.echothree.model.control.graphql.server.graphql.count.Connections;
024import com.echothree.model.control.graphql.server.graphql.count.CountedObjects;
025import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher;
026import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData;
027import com.echothree.model.control.graphql.server.util.BaseGraphQl;
028import com.echothree.model.control.graphql.server.util.count.ObjectLimiter;
029import com.echothree.model.control.payment.common.PaymentMethodTypes;
030import com.echothree.model.control.payment.server.control.PaymentMethodControl;
031import com.echothree.model.control.selector.server.graphql.SelectorObject;
032import com.echothree.model.control.selector.server.graphql.SelectorSecurityUtils;
033import com.echothree.model.control.user.server.control.UserControl;
034import com.echothree.model.data.customer.common.CustomerTypePaymentMethodConstants;
035import com.echothree.model.data.payment.server.entity.PaymentMethod;
036import com.echothree.model.data.payment.server.entity.PaymentMethodDetail;
037import com.echothree.util.server.persistence.Session;
038import graphql.annotations.annotationTypes.GraphQLDescription;
039import graphql.annotations.annotationTypes.GraphQLField;
040import graphql.annotations.annotationTypes.GraphQLName;
041import graphql.annotations.annotationTypes.GraphQLNonNull;
042import graphql.annotations.connection.GraphQLConnection;
043import graphql.schema.DataFetchingEnvironment;
044import java.util.ArrayList;
045import java.util.stream.Collectors;
046
047@GraphQLDescription("payment method object")
048@GraphQLName("PaymentMethod")
049public class PaymentMethodObject
050        extends BaseEntityInstanceObject {
051    
052    private final PaymentMethod paymentMethod; // Always Present
053    
054    public PaymentMethodObject(PaymentMethod paymentMethod) {
055        super(paymentMethod.getPrimaryKey());
056        
057        this.paymentMethod = paymentMethod;
058    }
059
060    private PaymentMethodDetail paymentMethodDetail; // Optional, use getPaymentMethodDetail()
061    
062    private PaymentMethodDetail getPaymentMethodDetail() {
063        if(paymentMethodDetail == null) {
064            paymentMethodDetail = paymentMethod.getLastDetail();
065        }
066        
067        return paymentMethodDetail;
068    }
069    
070    @GraphQLField
071    @GraphQLDescription("payment method name")
072    @GraphQLNonNull
073    public String getPaymentMethodName() {
074        return getPaymentMethodDetail().getPaymentMethodName();
075    }
076
077    @GraphQLField
078    @GraphQLDescription("payment method type")
079    public PaymentMethodTypeObject getPaymentMethodType(final DataFetchingEnvironment env) {
080        return PaymentSecurityUtils.getHasPaymentMethodTypeAccess(env) ? new PaymentMethodTypeObject(getPaymentMethodDetail().getPaymentMethodType()) : null;
081    }
082
083    @GraphQLField
084    @GraphQLDescription("payment processor")
085    public PaymentProcessorObject getPaymentProcessor(final DataFetchingEnvironment env) {
086        if(PaymentSecurityUtils.getHasPaymentProcessorAccess(env)) {
087            var paymentProcessor = getPaymentMethodDetail().getPaymentProcessor();
088
089            return paymentProcessor == null ? null : new PaymentProcessorObject(paymentProcessor);
090        }
091
092        return null;
093    }
094
095    @GraphQLField
096    @GraphQLDescription("item selector")
097    public SelectorObject getItemSelector(final DataFetchingEnvironment env) {
098        if(SelectorSecurityUtils.getHasSelectorAccess(env)) {
099            var itemSelector = getPaymentMethodDetail().getItemSelector();
100
101            return itemSelector == null ? null : new SelectorObject(itemSelector);
102        }
103
104        return null;
105    }
106
107    @GraphQLField
108    @GraphQLDescription("sales order item selector")
109    public SelectorObject getSalesOrderItemSelector(final DataFetchingEnvironment env) {
110        if(SelectorSecurityUtils.getHasSelectorAccess(env)) {
111            var salesOrderItemSelector = getPaymentMethodDetail().getSalesOrderItemSelector();
112
113            return salesOrderItemSelector == null ? null : new SelectorObject(salesOrderItemSelector);
114        }
115
116        return null;
117    }
118
119    @GraphQLField
120    @GraphQLDescription("is default")
121    @GraphQLNonNull
122    public boolean getIsDefault() {
123        return getPaymentMethodDetail().getIsDefault();
124    }
125    
126    @GraphQLField
127    @GraphQLDescription("sort order")
128    @GraphQLNonNull
129    public int getSortOrder() {
130        return getPaymentMethodDetail().getSortOrder();
131    }
132    
133    @GraphQLField
134    @GraphQLDescription("description")
135    @GraphQLNonNull
136    public String getDescription(final DataFetchingEnvironment env) {
137        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
138        var userControl = Session.getModelController(UserControl.class);
139
140        return paymentMethodControl.getBestPaymentMethodDescription(paymentMethod, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
141    }
142
143    private PaymentMethodTypes paymentMethodTypeEnum = null; // Optional, use getPaymentMethodTypeEnum()
144
145    protected PaymentMethodTypes getPaymentMethodTypeEnum() {
146        if(paymentMethodTypeEnum == null) {
147            paymentMethodTypeEnum = PaymentMethodTypes.valueOf(getPaymentMethodDetail().getPaymentMethodType().getLastDetail().getPaymentMethodTypeName());
148        }
149
150        return paymentMethodTypeEnum;
151    }
152
153    @GraphQLField
154    @GraphQLDescription("payment method")
155    public PaymentMethodInterface getPaymentMethod(final DataFetchingEnvironment env) {
156        var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
157
158        return switch(getPaymentMethodTypeEnum()) {
159            case ACCOUNT -> null;
160            case CHECK -> new PaymentMethodCheckObject(paymentMethodControl.getPaymentMethodCheck(paymentMethod));
161            case COD -> null;
162            case CREDIT_CARD -> new PaymentMethodCreditCardObject(paymentMethodControl.getPaymentMethodCreditCard(paymentMethod));
163            case PREPAID -> null;
164            case GIFT_CARD -> null;
165            case GIFT_CERTIFICATE -> null;
166        };
167    }
168
169    @GraphQLField
170    @GraphQLDescription("customer type payment methods")
171    @GraphQLNonNull
172    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
173    public CountingPaginatedData<CustomerTypePaymentMethodObject> getCustomerTypePaymentMethods(final DataFetchingEnvironment env) {
174        if(CustomerSecurityUtils.getHasCustomerTypePaymentMethodsAccess(env)) {
175            var customerControl = Session.getModelController(CustomerControl.class);
176            var totalCount = customerControl.countCustomerTypePaymentMethodsByPaymentMethod(paymentMethod);
177
178            try(var objectLimiter = new ObjectLimiter(env, CustomerTypePaymentMethodConstants.COMPONENT_VENDOR_NAME, CustomerTypePaymentMethodConstants.ENTITY_TYPE_NAME, totalCount)) {
179                var entities = customerControl.getCustomerTypePaymentMethodsByPaymentMethod(paymentMethod);
180                var objects = entities.stream().map(CustomerTypePaymentMethodObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
181
182                return new CountedObjects<>(objectLimiter, objects);
183            }
184        } else {
185            return Connections.emptyConnection();
186        }
187    }
188
189}