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.model.control.offer.server.graphql;
018
019import com.echothree.model.control.filter.server.graphql.FilterObject;
020import com.echothree.model.control.filter.server.graphql.FilterSecurityUtils;
021import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject;
022import com.echothree.model.control.graphql.server.graphql.count.Connections;
023import com.echothree.model.control.graphql.server.graphql.count.CountedObjects;
024import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher;
025import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData;
026import com.echothree.model.control.graphql.server.util.BaseGraphQl;
027import com.echothree.model.control.graphql.server.util.count.ObjectLimiter;
028import com.echothree.model.control.offer.server.control.OfferControl;
029import com.echothree.model.control.offer.server.control.OfferItemControl;
030import com.echothree.model.control.party.server.graphql.DepartmentObject;
031import com.echothree.model.control.party.server.graphql.PartySecurityUtils;
032import com.echothree.model.control.sequence.server.graphql.SequenceObject;
033import com.echothree.model.control.sequence.server.graphql.SequenceSecurityUtils;
034import com.echothree.model.control.user.server.control.UserControl;
035import com.echothree.model.data.offer.common.OfferItemConstants;
036import com.echothree.model.data.offer.server.entity.Offer;
037import com.echothree.model.data.offer.server.entity.OfferDetail;
038import com.echothree.util.server.persistence.Session;
039import graphql.annotations.annotationTypes.GraphQLDescription;
040import graphql.annotations.annotationTypes.GraphQLField;
041import graphql.annotations.annotationTypes.GraphQLName;
042import graphql.annotations.annotationTypes.GraphQLNonNull;
043import graphql.annotations.connection.GraphQLConnection;
044import graphql.schema.DataFetchingEnvironment;
045import java.util.ArrayList;
046import java.util.stream.Collectors;
047
048@GraphQLDescription("offer object")
049@GraphQLName("Offer")
050public class OfferObject
051        extends BaseEntityInstanceObject {
052    
053    private final Offer offer; // Always Present
054    
055    public OfferObject(Offer offer) {
056        super(offer.getPrimaryKey());
057        
058        this.offer = offer;
059    }
060
061    private OfferDetail offerDetail; // Optional, offer getOfferDetail()
062    
063    private OfferDetail getOfferDetail() {
064        if(offerDetail == null) {
065            offerDetail = offer.getLastDetail();
066        }
067        
068        return offerDetail;
069    }
070    
071    @GraphQLField
072    @GraphQLDescription("offer name")
073    @GraphQLNonNull
074    public String getOfferName() {
075        return getOfferDetail().getOfferName();
076    }
077
078    @GraphQLField
079    @GraphQLDescription("sales order sequence")
080    public SequenceObject getSalesOrderSequence(final DataFetchingEnvironment env) {
081        if(SequenceSecurityUtils.getHasSequenceAccess(env)) {
082            var salesOrderSequence = getOfferDetail().getSalesOrderSequence();
083
084            return salesOrderSequence == null ? null : new SequenceObject(salesOrderSequence);
085        } else {
086            return null;
087        }
088    }
089
090    @GraphQLField
091    @GraphQLDescription("department")
092    public DepartmentObject getDepartment(final DataFetchingEnvironment env) {
093        var departmentParty = getOfferDetail().getDepartmentParty();
094
095        return PartySecurityUtils.getHasPartyAccess(env, departmentParty) ? new DepartmentObject(departmentParty) : null;
096    }
097
098    // TODO: OfferItemSelector
099
100    @GraphQLField
101    @GraphQLDescription("offer item price filter")
102    public FilterObject getOfferItemPriceFilter(final DataFetchingEnvironment env) {
103        if(FilterSecurityUtils.getHasFilterAccess(env)) {
104            var offerItemPriceFilter = getOfferDetail().getOfferItemPriceFilter();
105
106            return offerItemPriceFilter == null ? null : new FilterObject(offerItemPriceFilter);
107        } else {
108            return null;
109        }
110    }
111    
112    @GraphQLField
113    @GraphQLDescription("is default")
114    @GraphQLNonNull
115    public boolean getIsDefault() {
116        return getOfferDetail().getIsDefault();
117    }
118    
119    @GraphQLField
120    @GraphQLDescription("sort order")
121    @GraphQLNonNull
122    public int getSortOrder() {
123        return getOfferDetail().getSortOrder();
124    }
125    
126    @GraphQLField
127    @GraphQLDescription("description")
128    @GraphQLNonNull
129    public String getDescription(final DataFetchingEnvironment env) {
130        var offerControl = Session.getModelController(OfferControl.class);
131        var userControl = Session.getModelController(UserControl.class);
132
133        return offerControl.getBestOfferDescription(offer, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
134    }
135
136    @GraphQLField
137    @GraphQLDescription("offer items")
138    @GraphQLNonNull
139    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
140    public CountingPaginatedData<OfferItemObject> getOfferItems(final DataFetchingEnvironment env) {
141        if(OfferSecurityUtils.getHasOfferItemsAccess(env)) {
142            var offerItemControl = Session.getModelController(OfferItemControl.class);
143            var totalCount = offerItemControl.countOfferItemsByOffer(offer);
144
145            try(var objectLimiter = new ObjectLimiter(env, OfferItemConstants.COMPONENT_VENDOR_NAME, OfferItemConstants.ENTITY_TYPE_NAME, totalCount)) {
146                var entities = offerItemControl.getOfferItemsByOffer(offer);
147                var offerItems = entities.stream().map(OfferItemObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
148
149                return new CountedObjects<>(objectLimiter, offerItems);
150            }
151        } else {
152            return Connections.emptyConnection();
153        }
154    }
155
156}