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.accounting.server.graphql;
018
019import com.echothree.model.control.accounting.server.control.AccountingControl;
020import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject;
021import com.echothree.model.control.graphql.server.util.BaseGraphQl;
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.count.ObjectLimiter;
027import com.echothree.model.control.item.server.control.ItemControl;
028import com.echothree.model.control.item.server.graphql.ItemObject;
029import com.echothree.model.control.item.server.graphql.ItemSecurityUtils;
030import com.echothree.model.control.user.server.control.UserControl;
031import com.echothree.model.data.accounting.server.entity.ItemAccountingCategory;
032import com.echothree.model.data.accounting.server.entity.ItemAccountingCategoryDetail;
033import com.echothree.model.data.item.common.ItemConstants;
034import com.echothree.util.server.persistence.Session;
035import graphql.annotations.annotationTypes.GraphQLDescription;
036import graphql.annotations.annotationTypes.GraphQLField;
037import graphql.annotations.annotationTypes.GraphQLName;
038import graphql.annotations.annotationTypes.GraphQLNonNull;
039import graphql.annotations.connection.GraphQLConnection;
040import graphql.schema.DataFetchingEnvironment;
041import java.util.ArrayList;
042import java.util.stream.Collectors;
043
044@GraphQLDescription("item accounting category object")
045@GraphQLName("ItemAccountingCategory")
046public class ItemAccountingCategoryObject
047        extends BaseEntityInstanceObject {
048    
049    private final ItemAccountingCategory itemAccountingCategory; // Always Present
050    
051    public ItemAccountingCategoryObject(ItemAccountingCategory itemAccountingCategory) {
052        super(itemAccountingCategory.getPrimaryKey());
053        
054        this.itemAccountingCategory = itemAccountingCategory;
055    }
056
057    private ItemAccountingCategoryDetail itemAccountingCategoryDetail; // Optional, use getItemAccountingCategoryDetail()
058    
059    private ItemAccountingCategoryDetail getItemAccountingCategoryDetail() {
060        if(itemAccountingCategoryDetail == null) {
061            itemAccountingCategoryDetail = itemAccountingCategory.getLastDetail();
062        }
063        
064        return itemAccountingCategoryDetail;
065    }
066    
067    @GraphQLField
068    @GraphQLDescription("item accounting category name")
069    @GraphQLNonNull
070    public String getItemAccountingCategoryName() {
071        return getItemAccountingCategoryDetail().getItemAccountingCategoryName();
072    }
073
074    @GraphQLField
075    @GraphQLDescription("parent item accounting category")
076    public ItemAccountingCategoryObject getParentItemAccountingCategory() {
077        var parentItemAccountingCategory = getItemAccountingCategoryDetail().getParentItemAccountingCategory();
078        
079        return parentItemAccountingCategory == null ? null : new ItemAccountingCategoryObject(parentItemAccountingCategory);
080    }
081
082    @GraphQLField
083    @GraphQLDescription("inventory GL account")
084    public GlAccountObject getInventoryGlAccount(final DataFetchingEnvironment env) {
085        var inventoryGlAccount = getItemAccountingCategoryDetail().getInventoryGlAccount();
086
087        return inventoryGlAccount == null ? null : AccountingSecurityUtils.getHasGlAccountAccess(env) ?
088                new GlAccountObject(inventoryGlAccount) : null;
089    }
090
091    @GraphQLField
092    @GraphQLDescription("sales GL account")
093    public GlAccountObject getSalesGlAccount(final DataFetchingEnvironment env) {
094        var salesGlAccount = getItemAccountingCategoryDetail().getSalesGlAccount();
095
096        return salesGlAccount == null ? null : AccountingSecurityUtils.getHasGlAccountAccess(env) ?
097                new GlAccountObject(salesGlAccount) : null;
098    }
099
100    @GraphQLField
101    @GraphQLDescription("returns GL account")
102    public GlAccountObject getReturnsGlAccount(final DataFetchingEnvironment env) {
103        var returnsGlAccount = getItemAccountingCategoryDetail().getReturnsGlAccount();
104
105        return returnsGlAccount == null ? null : AccountingSecurityUtils.getHasGlAccountAccess(env) ?
106                new GlAccountObject(returnsGlAccount) : null;
107    }
108
109    @GraphQLField
110    @GraphQLDescription("COGS GL account")
111    public GlAccountObject getCogsGlAccount(final DataFetchingEnvironment env) {
112        var cogsGlAccount = getItemAccountingCategoryDetail().getCogsGlAccount();
113
114        return cogsGlAccount == null ? null : AccountingSecurityUtils.getHasGlAccountAccess(env) ?
115                new GlAccountObject(cogsGlAccount) : null;
116    }
117
118    @GraphQLField
119    @GraphQLDescription("returns COGS GL account")
120    public GlAccountObject getReturnsCogsGlAccount(final DataFetchingEnvironment env) {
121        var returnsCogsGlAccount = getItemAccountingCategoryDetail().getReturnsCogsGlAccount();
122
123        return returnsCogsGlAccount == null ? null : AccountingSecurityUtils.getHasGlAccountAccess(env) ?
124                new GlAccountObject(returnsCogsGlAccount) : null;
125    }
126
127    @GraphQLField
128    @GraphQLDescription("is default")
129    @GraphQLNonNull
130    public boolean getIsDefault() {
131        return getItemAccountingCategoryDetail().getIsDefault();
132    }
133    
134    @GraphQLField
135    @GraphQLDescription("sort order")
136    @GraphQLNonNull
137    public int getSortOrder() {
138        return getItemAccountingCategoryDetail().getSortOrder();
139    }
140    
141    @GraphQLField
142    @GraphQLDescription("description")
143    @GraphQLNonNull
144    public String getDescription(final DataFetchingEnvironment env) {
145        var accountingControl = Session.getModelController(AccountingControl.class);
146        var userControl = Session.getModelController(UserControl.class);
147
148        return accountingControl.getBestItemAccountingCategoryDescription(itemAccountingCategory, userControl.getPreferredLanguageFromUserVisit(BaseGraphQl.getUserVisit(env)));
149    }
150
151    @GraphQLField
152    @GraphQLDescription("items")
153    @GraphQLNonNull
154    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
155    public CountingPaginatedData<ItemObject> getItems(final DataFetchingEnvironment env) {
156        if(ItemSecurityUtils.getHasItemsAccess(env)) {
157            var itemControl = Session.getModelController(ItemControl.class);
158            var totalCount = itemControl.countItemsByItemAccountingCategory(itemAccountingCategory);
159
160            try(var objectLimiter = new ObjectLimiter(env, ItemConstants.COMPONENT_VENDOR_NAME, ItemConstants.ENTITY_TYPE_NAME, totalCount)) {
161                var entities = itemControl.getItemsByItemAccountingCategory(itemAccountingCategory);
162                var items = entities.stream().map(ItemObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
163
164                return new CountedObjects<>(objectLimiter, items);
165            }
166        } else {
167            return Connections.emptyConnection();
168        }
169    }
170
171}