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.item.server.graphql; 018 019import com.echothree.model.control.accounting.server.graphql.AccountingSecurityUtils; 020import com.echothree.model.control.accounting.server.graphql.ItemAccountingCategoryObject; 021import com.echothree.model.control.cancellationpolicy.server.graphql.CancellationPolicyObject; 022import com.echothree.model.control.cancellationpolicy.server.graphql.CancellationPolicySecurityUtils; 023import com.echothree.model.control.graphql.server.graphql.BaseEntityInstanceObject; 024import com.echothree.model.control.graphql.server.graphql.TimeObject; 025import com.echothree.model.control.graphql.server.graphql.count.Connections; 026import com.echothree.model.control.graphql.server.graphql.count.CountedObjects; 027import com.echothree.model.control.graphql.server.graphql.count.CountingDataConnectionFetcher; 028import com.echothree.model.control.graphql.server.graphql.count.CountingPaginatedData; 029import com.echothree.model.control.graphql.server.util.BaseGraphQl; 030import com.echothree.model.control.graphql.server.util.count.ObjectLimiter; 031import com.echothree.model.control.inventory.server.control.InventoryLocationControl; 032import com.echothree.model.control.inventory.server.graphql.InventoryLocationObject; 033import com.echothree.model.control.inventory.server.graphql.InventorySecurityUtils; 034import com.echothree.model.control.item.common.ItemDescriptionTypes; 035import com.echothree.model.control.item.common.workflow.ItemStatusConstants; 036import com.echothree.model.control.item.server.control.ItemControl; 037import com.echothree.model.control.offer.server.control.OfferItemControl; 038import com.echothree.model.control.offer.server.graphql.OfferItemObject; 039import com.echothree.model.control.offer.server.graphql.OfferSecurityUtils; 040import com.echothree.model.control.party.server.graphql.CompanyObject; 041import com.echothree.model.control.party.server.graphql.PartySecurityUtils; 042import com.echothree.model.control.returnpolicy.server.graphql.ReturnPolicyObject; 043import com.echothree.model.control.returnpolicy.server.graphql.ReturnPolicySecurityUtils; 044import com.echothree.model.control.sequence.server.graphql.SequenceObject; 045import com.echothree.model.control.sequence.server.graphql.SequenceSecurityUtils; 046import com.echothree.model.control.uom.server.graphql.UnitOfMeasureKindObject; 047import com.echothree.model.control.uom.server.graphql.UomSecurityUtils; 048import com.echothree.model.control.vendor.server.control.VendorControl; 049import com.echothree.model.control.vendor.server.graphql.ItemPurchasingCategoryObject; 050import com.echothree.model.control.vendor.server.graphql.VendorItemObject; 051import com.echothree.model.control.vendor.server.graphql.VendorSecurityUtils; 052import com.echothree.model.control.workflow.server.graphql.WorkflowEntityStatusObject; 053import com.echothree.model.data.inventory.common.InventoryLocationConstants; 054import com.echothree.model.data.item.common.ItemAliasConstants; 055import com.echothree.model.data.item.common.ItemPriceConstants; 056import com.echothree.model.data.item.common.ItemUnitOfMeasureTypeConstants; 057import com.echothree.model.data.item.common.RelatedItemTypeConstants; 058import com.echothree.model.data.item.server.entity.Item; 059import com.echothree.model.data.item.server.entity.ItemDetail; 060import com.echothree.model.data.item.server.entity.RelatedItemType; 061import com.echothree.model.data.offer.common.OfferItemConstants; 062import com.echothree.model.data.vendor.common.VendorItemConstants; 063import com.echothree.util.server.persistence.Session; 064import graphql.annotations.annotationTypes.GraphQLDescription; 065import graphql.annotations.annotationTypes.GraphQLField; 066import graphql.annotations.annotationTypes.GraphQLName; 067import graphql.annotations.annotationTypes.GraphQLNonNull; 068import graphql.annotations.connection.GraphQLConnection; 069import graphql.schema.DataFetchingEnvironment; 070import java.util.ArrayList; 071import java.util.stream.Collectors; 072 073@GraphQLDescription("item object") 074@GraphQLName("Item") 075public class ItemObject 076 extends BaseEntityInstanceObject { 077 078 private final Item item; // Always Present 079 080 public ItemObject(Item item) { 081 super(item.getPrimaryKey()); 082 083 this.item = item; 084 } 085 086 private ItemDetail itemDetail; // Optional, use getItemDetail() 087 088 private ItemDetail getItemDetail() { 089 if(itemDetail == null) { 090 itemDetail = item.getLastDetail(); 091 } 092 093 return itemDetail; 094 } 095 096 @GraphQLField 097 @GraphQLDescription("item name") 098 @GraphQLNonNull 099 public String getItemName() { 100 return getItemDetail().getItemName(); 101 } 102 103 @GraphQLField 104 @GraphQLDescription("item type") 105 @GraphQLNonNull 106 public ItemTypeObject getItemType(final DataFetchingEnvironment env) { 107 return ItemSecurityUtils.getHasItemTypeAccess(env) ? new ItemTypeObject(getItemDetail().getItemType()) : null; 108 } 109 110 @GraphQLField 111 @GraphQLDescription("item use type") 112 @GraphQLNonNull 113 public ItemUseTypeObject getItemUseType(final DataFetchingEnvironment env) { 114 return ItemSecurityUtils.getHasItemUseTypeAccess(env) ? new ItemUseTypeObject(getItemDetail().getItemUseType()) : null; 115 } 116 117 @GraphQLField 118 @GraphQLDescription("item category") 119 public ItemCategoryObject getItemCategory(final DataFetchingEnvironment env) { 120 return ItemSecurityUtils.getHasItemCategoryAccess(env) ? new ItemCategoryObject(getItemDetail().getItemCategory()) : null; 121 } 122 123 @GraphQLField 124 @GraphQLDescription("item accounting category") 125 public ItemAccountingCategoryObject getItemAccountingCategory(final DataFetchingEnvironment env) { 126 return AccountingSecurityUtils.getHasItemAccountingCategoryAccess(env) ? new ItemAccountingCategoryObject(getItemDetail().getItemAccountingCategory()) : null; 127 } 128 129 @GraphQLField 130 @GraphQLDescription("item purchasing category") 131 public ItemPurchasingCategoryObject getItemPurchasingCategory(final DataFetchingEnvironment env) { 132 return VendorSecurityUtils.getHasItemPurchasingCategoryAccess(env) ? new ItemPurchasingCategoryObject(getItemDetail().getItemPurchasingCategory()) : null; 133 } 134 135 @GraphQLField 136 @GraphQLDescription("company") 137 @GraphQLNonNull 138 public CompanyObject getCompany(final DataFetchingEnvironment env) { 139 var companyParty = getItemDetail().getCompanyParty(); 140 141 return PartySecurityUtils.getHasPartyAccess(env, companyParty) ? new CompanyObject(companyParty) : null; 142 } 143 144 @GraphQLField 145 @GraphQLDescription("item delivery type") 146 @GraphQLNonNull 147 public ItemDeliveryTypeObject getItemDeliveryType(final DataFetchingEnvironment env) { 148 return ItemSecurityUtils.getHasItemDeliveryTypeAccess(env) ? new ItemDeliveryTypeObject(getItemDetail().getItemDeliveryType()) : null; 149 } 150 151 @GraphQLField 152 @GraphQLDescription("item inventory type") 153 @GraphQLNonNull 154 public ItemInventoryTypeObject getItemInventoryType(final DataFetchingEnvironment env) { 155 return ItemSecurityUtils.getHasItemInventoryTypeAccess(env) ? new ItemInventoryTypeObject(getItemDetail().getItemInventoryType()) : null; 156 } 157 158 @GraphQLField 159 @GraphQLDescription("inventory serialized") 160 public Boolean getInventorySerialized() { 161 return getItemDetail().getInventorySerialized(); 162 } 163 164 @GraphQLField 165 @GraphQLDescription("serial number sequence") 166 public SequenceObject getSalesOrderSequence(final DataFetchingEnvironment env) { 167 var salesOrderSequence = getItemDetail().getSerialNumberSequence(); 168 169 return salesOrderSequence == null ? null : (SequenceSecurityUtils.getHasSequenceAccess(env) ? new SequenceObject(salesOrderSequence) : null); 170 } 171 172 @GraphQLField 173 @GraphQLDescription("shipping charge exempt") 174 @GraphQLNonNull 175 public Boolean getShippingChargeExempt() { 176 return getItemDetail().getShippingChargeExempt(); 177 } 178 179 @GraphQLField 180 @GraphQLDescription("shipping start time") 181 @GraphQLNonNull 182 public TimeObject getShippingStartTime(final DataFetchingEnvironment env) { 183 return new TimeObject(getItemDetail().getShippingStartTime()); 184 } 185 186 @GraphQLField 187 @GraphQLDescription("shipping end time") 188 public TimeObject getShippingEndTime(final DataFetchingEnvironment env) { 189 var shippingEndTime = getItemDetail().getShippingEndTime(); 190 191 return shippingEndTime == null ? null : new TimeObject(shippingEndTime); 192 } 193 194 @GraphQLField 195 @GraphQLDescription("sales order start time") 196 @GraphQLNonNull 197 public TimeObject getSalesOrderStartTime(final DataFetchingEnvironment env) { 198 return new TimeObject(getItemDetail().getSalesOrderStartTime()); 199 } 200 201 @GraphQLField 202 @GraphQLDescription("sales order end time") 203 public TimeObject getSalesOrderEndTime(final DataFetchingEnvironment env) { 204 var salesOrderEndTime = getItemDetail().getSalesOrderEndTime(); 205 206 return salesOrderEndTime == null ? null : new TimeObject(salesOrderEndTime); 207 } 208 209 @GraphQLField 210 @GraphQLDescription("purchase order start time") 211 public TimeObject getPurchaseOrderStartTime(final DataFetchingEnvironment env) { 212 var purchaseOrderStartTime = getItemDetail().getPurchaseOrderStartTime(); 213 214 return purchaseOrderStartTime == null ? null : new TimeObject(purchaseOrderStartTime); 215 } 216 217 @GraphQLField 218 @GraphQLDescription("purchase order end time") 219 public TimeObject getPurchaseOrderEndTime(final DataFetchingEnvironment env) { 220 var purchaseOrderEndTime = getItemDetail().getPurchaseOrderEndTime(); 221 222 return purchaseOrderEndTime == null ? null : new TimeObject(purchaseOrderEndTime); 223 } 224 225 @GraphQLField 226 @GraphQLDescription("allow club discounts") 227 @GraphQLNonNull 228 public Boolean getAllowClubDiscounts() { 229 return getItemDetail().getAllowClubDiscounts(); 230 } 231 232 @GraphQLField 233 @GraphQLDescription("allow coupon discounts") 234 @GraphQLNonNull 235 public Boolean getAllowCouponDiscounts() { 236 return getItemDetail().getAllowCouponDiscounts(); 237 } 238 239 @GraphQLField 240 @GraphQLDescription("allow associate payments") 241 @GraphQLNonNull 242 public Boolean getAllowAssociatePayments() { 243 return getItemDetail().getAllowAssociatePayments(); 244 } 245 246 @GraphQLField 247 @GraphQLDescription("unit of measure kind") 248 public UnitOfMeasureKindObject getUnitOfMeasureKind(final DataFetchingEnvironment env) { 249 return UomSecurityUtils.getHasUnitOfMeasureKindAccess(env) ? new UnitOfMeasureKindObject(getItemDetail().getUnitOfMeasureKind()) : null; 250 } 251 252 @GraphQLField 253 @GraphQLDescription("item price type") 254 public ItemPriceTypeObject getItemPriceType(final DataFetchingEnvironment env) { 255 return ItemSecurityUtils.getHasItemPriceTypeAccess(env) ? new ItemPriceTypeObject(getItemDetail().getItemPriceType()) : null; 256 } 257 258 @GraphQLField 259 @GraphQLDescription("cancellation policy") 260 public CancellationPolicyObject getCancellationPolicy(final DataFetchingEnvironment env) { 261 var cancellationPolicy = getItemDetail().getCancellationPolicy(); 262 263 return cancellationPolicy == null ? null : (CancellationPolicySecurityUtils.getHasCancellationPolicyAccess(env) ? new CancellationPolicyObject(cancellationPolicy) : null); 264 } 265 266 @GraphQLField 267 @GraphQLDescription("return policy") 268 public ReturnPolicyObject getReturnPolicy(final DataFetchingEnvironment env) { 269 var returnPolicy = getItemDetail().getReturnPolicy(); 270 271 return returnPolicy == null ? null : (ReturnPolicySecurityUtils.getHasReturnPolicyAccess(env) ? new ReturnPolicyObject(returnPolicy) : null); 272 } 273 274 //| itm_stylpth_stylepathid | bigint | YES | | NULL | | 275 276 @GraphQLField 277 @GraphQLDescription("item prices") 278 @GraphQLNonNull 279 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 280 public CountingPaginatedData<ItemPriceObject> getItemPrices(final DataFetchingEnvironment env) { 281 if(ItemSecurityUtils.getHasItemPricesAccess(env)) { 282 var itemControl = Session.getModelController(ItemControl.class); 283 var totalCount = itemControl.countItemPricesByItem(item); 284 285 try(var objectLimiter = new ObjectLimiter(env, ItemPriceConstants.COMPONENT_VENDOR_NAME, ItemPriceConstants.ENTITY_TYPE_NAME, totalCount)) { 286 var entities = itemControl.getItemPricesByItem(item); 287 var itemPrices = entities.stream().map(ItemPriceObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 288 289 return new CountedObjects<>(objectLimiter, itemPrices); 290 } 291 } else { 292 return Connections.emptyConnection(); 293 } 294 } 295 296 @GraphQLField 297 @GraphQLDescription("item unit of measure types") 298 @GraphQLNonNull 299 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 300 public CountingPaginatedData<ItemUnitOfMeasureTypeObject> getItemUnitOfMeasureTypes(final DataFetchingEnvironment env) { 301 if(ItemSecurityUtils.getHasItemUnitOfMeasureTypesAccess(env)) { 302 var itemControl = Session.getModelController(ItemControl.class); 303 var totalCount = itemControl.countItemUnitOfMeasureTypesByItem(item); 304 305 try(var objectLimiter = new ObjectLimiter(env, ItemUnitOfMeasureTypeConstants.COMPONENT_VENDOR_NAME, ItemUnitOfMeasureTypeConstants.ENTITY_TYPE_NAME, totalCount)) { 306 var entities = itemControl.getItemUnitOfMeasureTypesByItem(item); 307 var itemAliass = entities.stream().map(ItemUnitOfMeasureTypeObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 308 309 return new CountedObjects<>(objectLimiter, itemAliass); 310 } 311 } else { 312 return Connections.emptyConnection(); 313 } 314 } 315 316 @GraphQLField 317 @GraphQLDescription("item aliases") 318 @GraphQLNonNull 319 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 320 public CountingPaginatedData<ItemAliasObject> getItemAliases(final DataFetchingEnvironment env) { 321 if(ItemSecurityUtils.getHasItemAliasesAccess(env)) { 322 var itemControl = Session.getModelController(ItemControl.class); 323 var totalCount = itemControl.countItemAliasesByItem(item); 324 325 try(var objectLimiter = new ObjectLimiter(env, ItemAliasConstants.COMPONENT_VENDOR_NAME, ItemAliasConstants.ENTITY_TYPE_NAME, totalCount)) { 326 var entities = itemControl.getItemAliasesByItem(item); 327 var itemAliases = entities.stream().map(ItemAliasObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 328 329 return new CountedObjects<>(objectLimiter, itemAliases); 330 } 331 } else { 332 return Connections.emptyConnection(); 333 } 334 } 335 336 @GraphQLField 337 @GraphQLDescription("description") 338 public String getDescription(final DataFetchingEnvironment env) { 339 var itemControl = Session.getModelController(ItemControl.class); 340 var itemDescriptionType = itemControl.getItemDescriptionTypeByName(ItemDescriptionTypes.DEFAULT_DESCRIPTION.name()); 341 342 return itemDescriptionType == null ? null : itemControl.getBestItemStringDescription(itemDescriptionType, item, BaseGraphQl.getLanguageEntity(env)); 343 } 344 345 @GraphQLField 346 @GraphQLDescription("item status") 347 public WorkflowEntityStatusObject getItemStatus(final DataFetchingEnvironment env) { 348 return getWorkflowEntityStatusObject(env, ItemStatusConstants.Workflow_ITEM_STATUS); 349 } 350 351 @GraphQLField 352 @GraphQLDescription("offer items") 353 @GraphQLNonNull 354 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 355 public CountingPaginatedData<OfferItemObject> getOfferItems(final DataFetchingEnvironment env) { 356 if(OfferSecurityUtils.getHasOfferItemsAccess(env)) { 357 var offerItemControl = Session.getModelController(OfferItemControl.class); 358 var totalCount = offerItemControl.countOfferItemsByItem(item); 359 360 try(var objectLimiter = new ObjectLimiter(env, OfferItemConstants.COMPONENT_VENDOR_NAME, OfferItemConstants.ENTITY_TYPE_NAME, totalCount)) { 361 var entities = offerItemControl.getOfferItemsByItem(item); 362 var offerItems = entities.stream().map(OfferItemObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 363 364 return new CountedObjects<>(objectLimiter, offerItems); 365 } 366 } else { 367 return Connections.emptyConnection(); 368 } 369 } 370 371 @GraphQLField 372 @GraphQLDescription("related item types") 373 @GraphQLNonNull 374 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 375 public CountingPaginatedData<RelatedItemTypeObject> getRelatedItemTypes(final DataFetchingEnvironment env) { 376 if(ItemSecurityUtils.getHasRelatedItemTypesAccess(env)) { 377 var itemControl = Session.getModelController(ItemControl.class); 378 var totalCount = itemControl.countRelatedItemTypes(); 379 380 try(var objectLimiter = new ObjectLimiter(env, RelatedItemTypeConstants.COMPONENT_VENDOR_NAME, RelatedItemTypeConstants.ENTITY_TYPE_NAME, totalCount)) { 381 var entities = itemControl.getRelatedItemTypes(); 382 var relatedItemTypes = entities.stream() 383 .map((RelatedItemType relatedItemType) -> new RelatedItemTypeObject(relatedItemType, item)) 384 .collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 385 386 return new CountedObjects<>(objectLimiter, relatedItemTypes); 387 } 388 } else { 389 return Connections.emptyConnection(); 390 } 391 } 392 393 @GraphQLField 394 @GraphQLDescription("vendor items") 395 @GraphQLNonNull 396 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 397 public CountingPaginatedData<VendorItemObject> getVendorItems(final DataFetchingEnvironment env) { 398 if(VendorSecurityUtils.getHasVendorItemsAccess(env)) { 399 var itemControl = Session.getModelController(VendorControl.class); 400 var totalCount = itemControl.countVendorItemsByItem(item); 401 402 try(var objectLimiter = new ObjectLimiter(env, VendorItemConstants.COMPONENT_VENDOR_NAME, VendorItemConstants.ENTITY_TYPE_NAME, totalCount)) { 403 var entities = itemControl.getVendorItemsByItem(item); 404 var items = entities.stream().map(VendorItemObject::new).collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 405 406 return new CountedObjects<>(objectLimiter, items); 407 } 408 } else { 409 return Connections.emptyConnection(); 410 } 411 } 412 413 @GraphQLField 414 @GraphQLDescription("inventory locations") 415 @GraphQLNonNull 416 @GraphQLConnection(connectionFetcher = CountingDataConnectionFetcher.class) 417 public CountingPaginatedData<InventoryLocationObject> getInventoryLocations(final DataFetchingEnvironment env) { 418 if(InventorySecurityUtils.getHasInventoryLocationsAccess(env)) { 419 var inventoryLocationControl = Session.getModelController(InventoryLocationControl.class); 420 var totalCount = inventoryLocationControl.countInventoryLocationsByItem(item); 421 422 try(var objectLimiter = new ObjectLimiter(env, InventoryLocationConstants.COMPONENT_VENDOR_NAME, 423 InventoryLocationConstants.ENTITY_TYPE_NAME, totalCount)) { 424 var entities = inventoryLocationControl.getInventoryLocationsByItem(item); 425 var inventoryLocations = entities.stream() 426 .map(InventoryLocationObject::new) 427 .collect(Collectors.toCollection(() -> new ArrayList<>(entities.size()))); 428 429 return new CountedObjects<>(objectLimiter, inventoryLocations); 430 } 431 } else { 432 return Connections.emptyConnection(); 433 } 434 } 435 436}