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