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