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.logic; 018 019import com.echothree.model.control.core.server.control.EntityInstanceControl; 020import com.echothree.model.control.item.common.exception.DuplicateItemNameException; 021import com.echothree.model.control.item.common.exception.UnknownItemNameException; 022import com.echothree.model.control.item.common.exception.UnknownItemNameOrAliasException; 023import com.echothree.model.control.item.common.exception.UnknownItemStatusChoiceException; 024import com.echothree.model.control.item.common.exception.UnknownItemTypeNameException; 025import com.echothree.model.control.item.common.exception.UnknownItemUseTypeNameException; 026import com.echothree.model.control.item.common.workflow.ItemStatusConstants; 027import com.echothree.model.control.item.server.control.ItemControl; 028import com.echothree.model.control.sequence.common.SequenceTypes; 029import com.echothree.model.control.sequence.common.exception.MissingDefaultSequenceException; 030import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic; 031import com.echothree.model.control.workflow.server.control.WorkflowControl; 032import com.echothree.model.control.workflow.server.logic.WorkflowDestinationLogic; 033import com.echothree.model.control.workflow.server.logic.WorkflowLogic; 034import com.echothree.model.data.accounting.server.entity.ItemAccountingCategory; 035import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy; 036import com.echothree.model.data.item.server.entity.Item; 037import com.echothree.model.data.item.server.entity.ItemCategory; 038import com.echothree.model.data.item.server.entity.ItemDeliveryType; 039import com.echothree.model.data.item.server.entity.ItemInventoryType; 040import com.echothree.model.data.item.server.entity.ItemPriceType; 041import com.echothree.model.data.item.server.entity.ItemType; 042import com.echothree.model.data.item.server.entity.ItemUseType; 043import com.echothree.model.data.party.common.pk.PartyPK; 044import com.echothree.model.data.party.server.entity.Party; 045import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy; 046import com.echothree.model.data.sequence.server.entity.Sequence; 047import com.echothree.model.data.style.server.entity.StylePath; 048import com.echothree.model.data.uom.server.entity.UnitOfMeasureKind; 049import com.echothree.model.data.vendor.server.entity.ItemPurchasingCategory; 050import com.echothree.util.common.message.ExecutionErrors; 051import com.echothree.util.common.persistence.BasePK; 052import com.echothree.util.server.control.BaseLogic; 053import com.echothree.util.server.message.ExecutionErrorAccumulator; 054import com.echothree.util.server.persistence.Session; 055import javax.enterprise.context.ApplicationScoped; 056import javax.inject.Inject; 057 058@ApplicationScoped 059public class ItemLogic 060 extends BaseLogic { 061 062 @Inject 063 EntityInstanceControl entityInstanceControl; 064 065 @Inject 066 ItemControl itemControl; 067 068 @Inject 069 WorkflowControl workflowControl; 070 071 @Inject 072 ItemCategoryLogic itemCategoryLogic; 073 074 @Inject 075 SequenceGeneratorLogic sequenceGeneratorLogic; 076 077 @Inject 078 WorkflowDestinationLogic workflowDestinationLogic; 079 080 @Inject 081 WorkflowLogic workflowLogic; 082 083 protected ItemLogic() { 084 super(); 085 } 086 087 public ItemType getItemTypeByName(final ExecutionErrorAccumulator eea, final String itemTypeName) { 088 var itemType = itemControl.getItemTypeByName(itemTypeName); 089 090 if(itemType == null) { 091 handleExecutionError(UnknownItemTypeNameException.class, eea, ExecutionErrors.UnknownItemTypeName.name(), itemTypeName); 092 } 093 094 return itemType; 095 } 096 097 public ItemUseType getItemUseTypeByName(final ExecutionErrorAccumulator eea, final String itemUseTypeName) { 098 var itemUseType = itemControl.getItemUseTypeByName(itemUseTypeName); 099 100 if(itemUseType == null) { 101 handleExecutionError(UnknownItemUseTypeNameException.class, eea, ExecutionErrors.UnknownItemUseTypeName.name(), itemUseTypeName); 102 } 103 104 return itemUseType; 105 } 106 107 public Item getItemByName(final ExecutionErrorAccumulator eea, final String itemName) { 108 var item = itemControl.getItemByName(itemName); 109 110 if(item == null) { 111 handleExecutionError(UnknownItemNameException.class, eea, ExecutionErrors.UnknownItemName.name(), itemName); 112 } 113 114 return item; 115 } 116 117 public Item getItemByNameThenAlias(final ExecutionErrorAccumulator eea, final String itemNameOrAlias) { 118 var item = itemControl.getItemByNameThenAlias(itemNameOrAlias); 119 120 if(item == null) { 121 handleExecutionError(UnknownItemNameOrAliasException.class, eea, ExecutionErrors.UnknownItemNameOrAlias.name(), itemNameOrAlias); 122 } 123 124 return item; 125 } 126 127 public Item createItem(final ExecutionErrorAccumulator eea, String itemName, final ItemType itemType, final ItemUseType itemUseType, 128 ItemCategory itemCategory, final ItemAccountingCategory itemAccountingCategory, final ItemPurchasingCategory itemPurchasingCategory, 129 final Party companyParty, final ItemDeliveryType itemDeliveryType, final ItemInventoryType itemInventoryType, 130 final Boolean inventorySerialized, final Sequence serialNumberSequence, final Boolean shippingChargeExempt, 131 final Long shippingStartTime, final Long shippingEndTime, final Long salesOrderStartTime, final Long salesOrderEndTime, 132 final Long purchaseOrderStartTime, final Long purchaseOrderEndTime, final Boolean allowClubDiscounts, final Boolean allowCouponDiscounts, 133 final Boolean allowAssociatePayments, final UnitOfMeasureKind unitOfMeasureKind, final ItemPriceType itemPriceType, 134 final CancellationPolicy cancellationPolicy, final ReturnPolicy returnPolicy, final StylePath stylePath, final BasePK createdBy) { 135 Item item = null; 136 137 if(itemCategory == null) { 138 itemCategory = itemCategoryLogic.getDefaultItemCategory(eea); 139 } 140 141 if(itemName == null && !hasExecutionErrors(eea)) { 142 itemName = getItemName(eea, itemCategory); 143 } 144 145 if(itemControl.getItemByNameThenAlias(itemName) != null) { 146 handleExecutionError(DuplicateItemNameException.class, eea, ExecutionErrors.DuplicateItemName.name(), 147 itemName); 148 } 149 150 if(!hasExecutionErrors(eea)) { 151 item = itemControl.createItem(itemName, itemType, itemUseType, itemCategory, itemAccountingCategory, 152 itemPurchasingCategory, companyParty, itemDeliveryType, itemInventoryType, inventorySerialized, 153 serialNumberSequence, shippingChargeExempt, shippingStartTime, shippingEndTime, salesOrderStartTime, 154 salesOrderEndTime, purchaseOrderStartTime, purchaseOrderEndTime, allowClubDiscounts, allowCouponDiscounts, 155 allowAssociatePayments, unitOfMeasureKind, itemPriceType, cancellationPolicy, returnPolicy, stylePath, 156 createdBy); 157 } 158 159 return item; 160 } 161 162 private String getItemName(final ExecutionErrorAccumulator eea, final ItemCategory itemCategory) { 163 String itemName = null; 164 var itemSequence = itemCategory.getLastDetail().getItemSequence(); 165 166 if(itemSequence == null) { 167 itemSequence = sequenceGeneratorLogic.getDefaultSequence(eea, SequenceTypes.ITEM.name()); 168 } 169 170 if(!hasExecutionErrors(eea)) { 171 itemName = sequenceGeneratorLogic.getNextSequenceValue(eea, itemSequence); 172 } else { 173 handleExecutionError(MissingDefaultSequenceException.class, eea, ExecutionErrors.MissingDefaultSequence.name(), 174 SequenceTypes.ITEM.name()); 175 } 176 177 return itemName; 178 } 179 180 public void setItemStatus(final Session session, final ExecutionErrorAccumulator eea, final Item item, final String itemStatusChoice, final PartyPK modifiedBy) { 181 var workflow = workflowLogic.getWorkflowByName(eea, ItemStatusConstants.Workflow_ITEM_STATUS); 182 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(item.getPrimaryKey()); 183 var workflowEntityStatus = workflowControl.getWorkflowEntityStatusByEntityInstanceForUpdate(workflow, entityInstance); 184 var workflowDestination = itemStatusChoice == null ? null : workflowControl.getWorkflowDestinationByName(workflowEntityStatus.getWorkflowStep(), itemStatusChoice); 185 186 if(workflowDestination != null || itemStatusChoice == null) { 187 var currentWorkflowStepName = workflowEntityStatus.getWorkflowStep().getLastDetail().getWorkflowStepName(); 188 var map = workflowDestinationLogic.getWorkflowDestinationsAsMap(workflowDestination); 189 var handled = false; 190 Long triggerTime = null; 191 192 if(currentWorkflowStepName.equals(ItemStatusConstants.WorkflowStep_ITEM_STATUS_ACTIVE)) { 193 if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, ItemStatusConstants.Workflow_ITEM_STATUS, ItemStatusConstants.WorkflowStep_ITEM_STATUS_DISCONTINUED)) { 194 // TODO 195 handled = true; 196 } else if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, ItemStatusConstants.Workflow_ITEM_STATUS, ItemStatusConstants.WorkflowStep_ITEM_STATUS_CANCEL_IF_NOT_IN_STOCK)) { 197 // TODO 198 handled = true; 199 } 200 } else if(currentWorkflowStepName.equals(ItemStatusConstants.WorkflowStep_ITEM_STATUS_DISCONTINUED)) { 201 if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, ItemStatusConstants.Workflow_ITEM_STATUS, ItemStatusConstants.WorkflowStep_ITEM_STATUS_ACTIVE)) { 202 // TODO 203 handled = true; 204 } else if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, ItemStatusConstants.Workflow_ITEM_STATUS, ItemStatusConstants.WorkflowStep_ITEM_STATUS_CANCEL_IF_NOT_IN_STOCK)) { 205 // TODO 206 handled = true; 207 } 208 } else if(currentWorkflowStepName.equals(ItemStatusConstants.WorkflowStep_ITEM_STATUS_CANCEL_IF_NOT_IN_STOCK)) { 209 if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, ItemStatusConstants.Workflow_ITEM_STATUS, ItemStatusConstants.WorkflowStep_ITEM_STATUS_ACTIVE)) { 210 // TODO 211 handled = true; 212 } else if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, ItemStatusConstants.Workflow_ITEM_STATUS, ItemStatusConstants.WorkflowStep_ITEM_STATUS_DISCONTINUED)) { 213 // TODO 214 handled = true; 215 } 216 } 217 218 if(eea == null || !eea.hasExecutionErrors()) { 219 if(handled) { 220 workflowControl.transitionEntityInWorkflow(eea, workflowEntityStatus, workflowDestination, triggerTime, modifiedBy); 221 } else { 222 // TODO: An error of some sort. 223 } 224 } 225 } else { 226 handleExecutionError(UnknownItemStatusChoiceException.class, eea, ExecutionErrors.UnknownItemStatusChoice.name(), itemStatusChoice); 227 } 228 } 229 230}