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.warehouse.server.graphql;
018
019import com.echothree.model.control.graphql.server.graphql.count.Connections;
020import com.echothree.model.control.graphql.server.graphql.count.CountedObjects;
021import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher;
022import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData;
023import com.echothree.model.control.graphql.server.util.count.ObjectLimiter;
024import com.echothree.model.control.inventory.server.control.InventoryControl;
025import com.echothree.model.control.inventory.server.graphql.InventoryLocationGroupObject;
026import com.echothree.model.control.inventory.server.graphql.InventorySecurityUtils;
027import com.echothree.model.control.party.server.graphql.BasePartyObject;
028import com.echothree.model.control.warehouse.server.control.WarehouseControl;
029import com.echothree.model.data.inventory.common.InventoryLocationGroupConstants;
030import com.echothree.model.data.party.server.entity.Party;
031import com.echothree.model.data.warehouse.common.LocationConstants;
032import com.echothree.model.data.warehouse.common.LocationTypeConstants;
033import com.echothree.model.data.warehouse.server.entity.Warehouse;
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("warehouse object")
045@GraphQLName("Warehouse")
046public class WarehouseObject
047        extends BasePartyObject {
048
049    public WarehouseObject(Party party) {
050        super(party);
051    }
052
053    public WarehouseObject(Warehouse warehouse) {
054        super(warehouse.getParty());
055
056        this.warehouse = warehouse;
057    }
058
059    private Warehouse warehouse;  // Optional, use getWarehouse()
060
061    protected Warehouse getWarehouse() {
062        if(warehouse == null) {
063            var warehouseControl = Session.getModelController(WarehouseControl.class);
064
065            warehouse = warehouseControl.getWarehouse(party);
066        }
067
068        return warehouse;
069    }
070
071    @GraphQLField
072    @GraphQLDescription("warehouse name")
073    @GraphQLNonNull
074    public String getWarehouseName() {
075        return getWarehouse().getWarehouseName();
076    }
077
078    @GraphQLField
079    @GraphQLDescription("warehouse type")
080    public WarehouseTypeObject getWarehouseType(final DataFetchingEnvironment env) {
081        return WarehouseSecurityUtils.getHasWarehouseTypeAccess(env) ?
082                new WarehouseTypeObject(getWarehouse().getWarehouseType()) : null;
083    }
084
085    @GraphQLField
086    @GraphQLDescription("is default")
087    @GraphQLNonNull
088    public boolean getIsDefault() {
089        return getWarehouse().getIsDefault();
090    }
091
092    @GraphQLField
093    @GraphQLDescription("sort order")
094    @GraphQLNonNull
095    public int getSortOrder() {
096        return getWarehouse().getSortOrder();
097    }
098
099    @GraphQLField
100    @GraphQLDescription("inventory location groups")
101    @GraphQLNonNull
102    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
103    public CountingPaginatedData<InventoryLocationGroupObject> getInventoryLocationGroups(final DataFetchingEnvironment env) {
104        if(InventorySecurityUtils.getHasInventoryLocationGroupsAccess(env)) {
105            var inventoryControl = Session.getModelController(InventoryControl.class);
106            var warehouseParty = getWarehouse().getParty();
107            var totalCount = inventoryControl.countInventoryLocationGroupsByWarehouseParty(warehouseParty);
108
109            try(var objectLimiter = new ObjectLimiter(env, InventoryLocationGroupConstants.COMPONENT_VENDOR_NAME, InventoryLocationGroupConstants.ENTITY_TYPE_NAME, totalCount)) {
110                var entities = inventoryControl.getInventoryLocationGroupsByWarehouseParty(warehouseParty);
111                var items = entities.stream().map(InventoryLocationGroupObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
112
113                return new CountedObjects<>(objectLimiter, items);
114            }
115        } else {
116            return Connections.emptyConnection();
117        }
118    }
119
120    @GraphQLField
121    @GraphQLDescription("location types")
122    @GraphQLNonNull
123    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
124    public CountingPaginatedData<LocationTypeObject> getLocationTypes(final DataFetchingEnvironment env) {
125        if(WarehouseSecurityUtils.getHasLocationTypesAccess(env)) {
126            var warehouseControl = Session.getModelController(WarehouseControl.class);
127            var warehouseParty = getWarehouse().getParty();
128            var totalCount = warehouseControl.countLocationTypesByWarehouseParty(warehouseParty);
129
130            try(var objectLimiter = new ObjectLimiter(env, LocationTypeConstants.COMPONENT_VENDOR_NAME, LocationTypeConstants.ENTITY_TYPE_NAME, totalCount)) {
131                var entities = warehouseControl.getLocationTypesByWarehouseParty(warehouseParty);
132                var items = entities.stream().map(LocationTypeObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
133
134                return new CountedObjects<>(objectLimiter, items);
135            }
136        } else {
137            return Connections.emptyConnection();
138        }
139    }
140
141    @GraphQLField
142    @GraphQLDescription("locations")
143    @GraphQLNonNull
144    @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class)
145    public CountingPaginatedData<LocationObject> getLocations(final DataFetchingEnvironment env) {
146        if(WarehouseSecurityUtils.getHasLocationsAccess(env)) {
147            var warehouseControl = Session.getModelController(WarehouseControl.class);
148            var warehouseParty = getWarehouse().getParty();
149            var totalCount = warehouseControl.countLocationsByWarehouseParty(warehouseParty);
150
151            try(var objectLimiter = new ObjectLimiter(env, LocationConstants.COMPONENT_VENDOR_NAME, LocationConstants.ENTITY_TYPE_NAME, totalCount)) {
152                var entities = warehouseControl.getLocationsByWarehouseParty(warehouseParty);
153                var items = entities.stream().map(LocationObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size())));
154
155                return new CountedObjects<>(objectLimiter, items);
156            }
157        } else {
158            return Connections.emptyConnection();
159        }
160    }
161
162}