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.inventory.server.graphql; 018 019import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject; 020import com.echothree.model.control.graphql.server.graphql.UnitCostObject; 021import com.echothree.model.control.graphql.server.graphql.count.Connections; 022import com.echothree.model.control.graphql.server.graphql.count.CountedObjects; 023import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher; 024import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData; 025import com.echothree.model.control.graphql.server.util.count.ObjectLimiter; 026import com.echothree.model.control.inventory.server.control.BucketControl; 027import com.echothree.model.control.party.server.control.PartyControl; 028import com.echothree.model.data.inventory.common.InventoryLayerBucketConstants; 029import com.echothree.model.data.inventory.server.entity.InventoryLayer; 030import com.echothree.model.data.inventory.server.entity.InventoryLayerDetail; 031import com.echothree.util.server.persistence.Session; 032import graphql.annotations.annotationTypes.GraphQLDescription; 033import graphql.annotations.annotationTypes.GraphQLField; 034import graphql.annotations.annotationTypes.GraphQLName; 035import graphql.annotations.annotationTypes.GraphQLNonNull; 036import graphql.annotations.connection.GraphQLConnection; 037import graphql.schema.DataFetchingEnvironment; 038import java.util.ArrayList; 039import java.util.stream.Collectors; 040 041@GraphQLDescription("inventory layer object") 042@GraphQLName("InventoryLayer") 043public class InventoryLayerObject 044 extends BaseEntityInstanceObject { 045 046 private final InventoryLayer inventoryLayer; // Always Present 047 048 public InventoryLayerObject(final InventoryLayer inventoryLayer) { 049 super(inventoryLayer.getPrimaryKey()); 050 051 this.inventoryLayer = inventoryLayer; 052 } 053 054 private InventoryLayerDetail inventoryLayerDetail; // Optional, use getInventoryLayerDetail() 055 056 private InventoryLayerDetail getInventoryLayerDetail() { 057 if(inventoryLayerDetail == null) { 058 inventoryLayerDetail = inventoryLayer.getLastDetail(); 059 } 060 061 return inventoryLayerDetail; 062 } 063 064 @GraphQLField 065 @GraphQLDescription("inventory costing pool") 066 public InventoryCostingPoolObject getInventoryCostingPool(final DataFetchingEnvironment env) { 067 return InventorySecurityUtils.getHasInventoryCostingPoolAccess(env) 068 ? new InventoryCostingPoolObject(getInventoryLayerDetail().getInventoryCostingPool()) : null; 069 } 070 071 @GraphQLField 072 @GraphQLDescription("inventory layer sequence") 073 @GraphQLNonNull 074 public Integer getInventoryLayerSequence() { 075 return getInventoryLayerDetail().getInventoryLayerSequence(); 076 } 077 078 // TODO: Add the InventoryTransactionLineObject relationship when transaction-line GraphQL objects are implemented. 079 080 @GraphQLField 081 @GraphQLDescription("receipt quantity") 082 @GraphQLNonNull 083 public Long getReceiptQuantity() { 084 return getInventoryLayerDetail().getReceiptQuantity(); 085 } 086 087 @GraphQLField 088 @GraphQLDescription("unit cost") 089 public UnitCostObject getUnitCost() { 090 var unitCost = getInventoryLayerDetail().getUnitCost(); 091 var partyControl = Session.getModelController(PartyControl.class); 092 093 return unitCost == null ? null : new UnitCostObject(partyControl.getPreferredCurrency( 094 getInventoryLayerDetail().getInventoryCostingPool().getLastDetail().getCompanyParty()), unitCost); 095 } 096 097 @GraphQLField 098 @GraphQLDescription("description") 099 public String getDescription() { 100 return getInventoryLayerDetail().getDescription(); 101 } 102 103 @GraphQLField 104 @GraphQLDescription("inventory layer buckets") 105 @GraphQLNonNull 106 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 107 public CountingPaginatedData<InventoryLayerBucketObject> getInventoryLayerBuckets(final DataFetchingEnvironment env) { 108 if(InventorySecurityUtils.getHasInventoryLayerBucketsAccess(env)) { 109 var bucketControl = Session.getModelController(BucketControl.class); 110 var totalCount = bucketControl.countInventoryLayerBucketsByInventoryLayer(inventoryLayer); 111 112 try(var objectLimiter = new ObjectLimiter(env, InventoryLayerBucketConstants.COMPONENT_VENDOR_NAME, 113 InventoryLayerBucketConstants.ENTITY_TYPE_NAME, totalCount)) { 114 var entities = bucketControl.getInventoryLayerBucketsByInventoryLayer(inventoryLayer); 115 var inventoryLayerBuckets = entities.stream() 116 .map(InventoryLayerBucketObject::new) 117 .collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 118 119 return new CountedObjects<>(objectLimiter, inventoryLayerBuckets); 120 } 121 } else { 122 return Connections.emptyConnection(); 123 } 124 } 125 126}