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.control.user.item.server.command; 018 019import com.echothree.control.user.item.common.form.CreateItemForm; 020import com.echothree.control.user.item.common.result.ItemResultFactory; 021import com.echothree.model.control.accounting.server.control.AccountingControl; 022import com.echothree.model.control.cancellationpolicy.common.CancellationKinds; 023import com.echothree.model.control.cancellationpolicy.server.control.CancellationPolicyControl; 024import com.echothree.model.control.core.server.control.EntityInstanceControl; 025import com.echothree.model.control.item.common.workflow.ItemStatusConstants; 026import com.echothree.model.control.item.common.ItemTypes; 027import com.echothree.model.control.item.server.control.ItemControl; 028import com.echothree.model.control.item.server.logic.ItemLogic; 029import com.echothree.model.control.party.common.PartyTypes; 030import com.echothree.model.control.party.server.control.PartyControl; 031import com.echothree.model.control.returnpolicy.common.ReturnKinds; 032import com.echothree.model.control.returnpolicy.server.control.ReturnPolicyControl; 033import com.echothree.model.control.security.common.SecurityRoleGroups; 034import com.echothree.model.control.security.common.SecurityRoles; 035import com.echothree.model.control.uom.server.control.UomControl; 036import com.echothree.model.control.vendor.server.control.VendorControl; 037import com.echothree.model.control.workflow.server.control.WorkflowControl; 038import com.echothree.model.control.workflow.server.logic.WorkflowSecurityLogic; 039import com.echothree.model.data.accounting.server.entity.ItemAccountingCategory; 040import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy; 041import com.echothree.model.data.item.server.entity.ItemDeliveryType; 042import com.echothree.model.data.item.server.entity.ItemInventoryType; 043import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy; 044import com.echothree.model.data.vendor.server.entity.ItemPurchasingCategory; 045import com.echothree.util.common.command.BaseResult; 046import com.echothree.util.common.message.ExecutionErrors; 047import com.echothree.util.common.validation.FieldDefinition; 048import com.echothree.util.common.validation.FieldType; 049import com.echothree.util.server.control.BaseSimpleCommand; 050import com.echothree.util.server.control.CommandSecurityDefinition; 051import com.echothree.util.server.control.PartyTypeDefinition; 052import com.echothree.util.server.control.SecurityRoleDefinition; 053import com.echothree.util.server.persistence.Session; 054import java.util.List; 055import javax.enterprise.context.Dependent; 056 057@Dependent 058public class CreateItemCommand 059 extends BaseSimpleCommand<CreateItemForm> { 060 061 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 062 private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS; 063 064 static { 065 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 066 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 067 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 068 new SecurityRoleDefinition(SecurityRoleGroups.ItemCategory.name(), SecurityRoles.Create.name()) 069 )) 070 )); 071 072 FORM_FIELD_DEFINITIONS = List.of( 073 new FieldDefinition("ItemName", FieldType.ENTITY_NAME, false, null, null), 074 new FieldDefinition("ItemTypeName", FieldType.ENTITY_NAME, true, null, null), 075 new FieldDefinition("ItemUseTypeName", FieldType.ENTITY_NAME, true, null, null), 076 new FieldDefinition("ItemCategoryName", FieldType.ENTITY_NAME, false, null, null), 077 new FieldDefinition("ItemAccountingCategoryName", FieldType.ENTITY_NAME, false, null, null), 078 new FieldDefinition("ItemPurchasingCategoryName", FieldType.ENTITY_NAME, false, null, null), 079 new FieldDefinition("CompanyName", FieldType.ENTITY_NAME, true, null, null), 080 new FieldDefinition("ItemDeliveryTypeName", FieldType.ENTITY_NAME, false, null, null), 081 new FieldDefinition("ItemInventoryTypeName", FieldType.ENTITY_NAME, false, null, null), 082 new FieldDefinition("InventorySerialized", FieldType.BOOLEAN, false, null, null), 083 new FieldDefinition("ShippingChargeExempt", FieldType.BOOLEAN, true, null, null), 084 new FieldDefinition("ShippingStartTime", FieldType.DATE_TIME, false, null, null), 085 new FieldDefinition("ShippingEndTime", FieldType.DATE_TIME, false, null, null), 086 new FieldDefinition("SalesOrderStartTime", FieldType.DATE_TIME, false, null, null), 087 new FieldDefinition("SalesOrderEndTime", FieldType.DATE_TIME, false, null, null), 088 new FieldDefinition("PurchaseOrderStartTime", FieldType.DATE_TIME, false, null, null), 089 new FieldDefinition("PurchaseOrderEndTime", FieldType.DATE_TIME, false, null, null), 090 new FieldDefinition("AllowClubDiscounts", FieldType.BOOLEAN, true, null, null), 091 new FieldDefinition("AllowCouponDiscounts", FieldType.BOOLEAN, true, null, null), 092 new FieldDefinition("AllowAssociatePayments", FieldType.BOOLEAN, true, null, null), 093 new FieldDefinition("ItemStatus", FieldType.ENTITY_NAME, true, null, null), 094 new FieldDefinition("UnitOfMeasureKindName", FieldType.ENTITY_NAME, true, null, null), 095 new FieldDefinition("ItemPriceTypeName", FieldType.ENTITY_NAME, true, null, null), 096 new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null), 097 new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null) 098 ); 099 } 100 101 /** Creates a new instance of CreateItemCommand */ 102 public CreateItemCommand() { 103 super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false); 104 } 105 106 @Override 107 protected BaseResult execute() { 108 var result = ItemResultFactory.getCreateItemResult(); 109 var itemControl = Session.getModelController(ItemControl.class); 110 var itemName = form.getItemName(); 111 var item = itemName == null ? null : itemControl.getItemByNameThenAlias(itemName); 112 113 if(item == null) { 114 var itemTypeName = form.getItemTypeName(); 115 var itemType = itemControl.getItemTypeByName(itemTypeName); 116 117 if(itemType != null) { 118 var itemUseTypeName = form.getItemUseTypeName(); 119 var itemUseType = itemControl.getItemUseTypeByName(itemUseTypeName); 120 121 itemTypeName = itemType.getItemTypeName(); 122 123 if(itemUseType != null) { 124 var itemCategoryName = form.getItemCategoryName(); 125 var itemCategory = itemCategoryName == null ? null : itemControl.getItemCategoryByName(itemCategoryName); 126 127 if(itemCategoryName == null || itemCategory != null) { 128 var isKitOrStyle = itemTypeName.equals(ItemTypes.KIT.name()) 129 || itemTypeName.equals(ItemTypes.STYLE.name()); 130 var itemAccountingCategoryName = form.getItemAccountingCategoryName(); 131 ItemAccountingCategory itemAccountingCategory = null; 132 133 if(isKitOrStyle) { 134 if(itemAccountingCategoryName != null) { 135 addExecutionError(ExecutionErrors.NotPermittedItemAccountingCategory.name(), itemAccountingCategoryName); 136 } 137 } else { 138 var accountingControl = Session.getModelController(AccountingControl.class); 139 140 itemAccountingCategory = itemAccountingCategoryName == null? null: accountingControl.getItemAccountingCategoryByName(itemAccountingCategoryName); 141 142 if(itemAccountingCategoryName == null) { 143 addExecutionError(ExecutionErrors.MissingItemAccountingCategoryName.name()); 144 } else if(itemAccountingCategory == null) { 145 addExecutionError(ExecutionErrors.UnknownItemAccountingCategoryName.name(), itemAccountingCategoryName); 146 } 147 } 148 149 if(!hasExecutionErrors()) { 150 var itemPurchasingCategoryName = form.getItemPurchasingCategoryName(); 151 ItemPurchasingCategory itemPurchasingCategory = null; 152 153 if(isKitOrStyle) { 154 if(itemPurchasingCategoryName != null) { 155 addExecutionError(ExecutionErrors.NotPermittedItemPurchasingCategory.name(), itemPurchasingCategoryName); 156 } 157 } else { 158 var vendorControl = Session.getModelController(VendorControl.class); 159 160 itemPurchasingCategory = itemPurchasingCategoryName == null? null: vendorControl.getItemPurchasingCategoryByName(itemPurchasingCategoryName); 161 162 if(itemPurchasingCategoryName == null) { 163 addExecutionError(ExecutionErrors.MissingItemPurchasingCategoryName.name()); 164 } else if(itemPurchasingCategory == null) { 165 addExecutionError(ExecutionErrors.UnknownItemPurchasingCategoryName.name(), itemPurchasingCategoryName); 166 } 167 } 168 169 if(!hasExecutionErrors()) { 170 var partyControl = Session.getModelController(PartyControl.class); 171 var companyName = form.getCompanyName(); 172 var partyCompany = partyControl.getPartyCompanyByName(companyName); 173 174 if(partyCompany != null) { 175 var itemDeliveryTypeName = form.getItemDeliveryTypeName(); 176 ItemDeliveryType itemDeliveryType = null; 177 178 if(isKitOrStyle) { 179 if(itemDeliveryTypeName != null) { 180 addExecutionError(ExecutionErrors.NotPermittedItemDeliveryType.name(), itemDeliveryTypeName); 181 } 182 } else { 183 itemDeliveryType = itemDeliveryTypeName == null? null: itemControl.getItemDeliveryTypeByName(itemDeliveryTypeName); 184 185 if(itemDeliveryTypeName == null) { 186 addExecutionError(ExecutionErrors.MissingItemDeliveryTypeName.name()); 187 } else if(itemDeliveryType == null) { 188 addExecutionError(ExecutionErrors.UnknownItemDeliveryTypeName.name(), itemDeliveryTypeName); 189 } 190 } 191 192 if(!hasExecutionErrors()) { 193 var itemInventoryTypeName = form.getItemInventoryTypeName(); 194 ItemInventoryType itemInventoryType = null; 195 196 if(isKitOrStyle) { 197 if(itemInventoryTypeName != null) { 198 addExecutionError(ExecutionErrors.NotPermittedItemInventoryType.name(), itemInventoryTypeName); 199 } 200 } else { 201 itemInventoryType = itemInventoryTypeName == null? null: itemControl.getItemInventoryTypeByName(itemInventoryTypeName); 202 203 if(itemInventoryTypeName == null) { 204 addExecutionError(ExecutionErrors.MissingItemInventoryTypeName.name()); 205 } else if(itemInventoryType == null) { 206 addExecutionError(ExecutionErrors.UnknownItemInventoryTypeName.name(), itemInventoryTypeName); 207 } 208 } 209 210 if(!hasExecutionErrors()) { 211 var uomControl = Session.getModelController(UomControl.class); 212 var unitOfMeasureKindName = form.getUnitOfMeasureKindName(); 213 var unitOfMeasureKind = uomControl.getUnitOfMeasureKindByName(unitOfMeasureKindName); 214 215 if(unitOfMeasureKind != null) { 216 var itemPriceTypeName = form.getItemPriceTypeName(); 217 var itemPriceType = itemControl.getItemPriceTypeByName(itemPriceTypeName); 218 219 if(itemPriceType != null) { 220 var cancellationPolicyName = form.getCancellationPolicyName(); 221 CancellationPolicy cancellationPolicy = null; 222 223 if(cancellationPolicyName != null) { 224 var cancellationPolicyControl = Session.getModelController(CancellationPolicyControl.class); 225 var cancellationKind = cancellationPolicyControl.getCancellationKindByName(CancellationKinds.CUSTOMER_CANCELLATION.name()); 226 227 cancellationPolicy = cancellationPolicyControl.getCancellationPolicyByName(cancellationKind, cancellationPolicyName); 228 } 229 230 if(cancellationPolicyName == null || cancellationPolicy != null) { 231 var returnPolicyName = form.getReturnPolicyName(); 232 ReturnPolicy returnPolicy = null; 233 234 if(returnPolicyName != null) { 235 var returnPolicyControl = Session.getModelController(ReturnPolicyControl.class); 236 var returnKind = returnPolicyControl.getReturnKindByName(ReturnKinds.CUSTOMER_RETURN.name()); 237 238 returnPolicy = returnPolicyControl.getReturnPolicyByName(returnKind, returnPolicyName); 239 } 240 241 if(returnPolicyName == null || returnPolicy != null) { 242 var rawInventorySerialized = form.getInventorySerialized(); 243 var inventorySerialized = rawInventorySerialized == null? null: Boolean.valueOf(rawInventorySerialized); 244 245 if(isKitOrStyle ? inventorySerialized == null : inventorySerialized != null) { 246 var workflowControl = Session.getModelController(WorkflowControl.class); 247 var itemStatusChoice = form.getItemStatus(); 248 var itemStatus = workflowControl.getWorkflowEntranceUsingNames(this, ItemStatusConstants.Workflow_ITEM_STATUS, 249 itemStatusChoice); 250 var createdBy = getPartyPK(); 251 252 if(!hasExecutionErrors() && WorkflowSecurityLogic.getInstance().checkAddEntityToWorkflow(this, itemStatus, createdBy)) { 253 var shippingChargeExempt = Boolean.valueOf(form.getShippingChargeExempt()); 254 var strShippingStartTime = form.getShippingStartTime(); 255 var shippingStartTime = strShippingStartTime == null ? session.getStartTime() : Long.valueOf(strShippingStartTime); 256 var strShippingEndTime = form.getShippingEndTime(); 257 var shippingEndTime = strShippingEndTime == null ? null : Long.valueOf(strShippingEndTime); 258 var strSalesOrderStartTime = form.getSalesOrderStartTime(); 259 var salesOrderStartTime = strSalesOrderStartTime == null ? session.getStartTime() : Long.valueOf(strSalesOrderStartTime); 260 var strSalesOrderEndTime = form.getSalesOrderEndTime(); 261 var salesOrderEndTime = strSalesOrderEndTime == null ? null : Long.valueOf(strSalesOrderEndTime); 262 var strPurchaseOrderStartTime = form.getPurchaseOrderStartTime(); 263 var purchaseOrderStartTime = isKitOrStyle ? null : strPurchaseOrderStartTime == null ? session.getStartTime() : Long.valueOf(strPurchaseOrderStartTime); 264 var strPurchaseOrderEndTime = form.getPurchaseOrderEndTime(); 265 var purchaseOrderEndTime = isKitOrStyle ? null : strPurchaseOrderEndTime == null ? null : Long.valueOf(strPurchaseOrderEndTime); 266 var allowClubDiscounts = Boolean.valueOf(form.getAllowClubDiscounts()); 267 var allowCouponDiscounts = Boolean.valueOf(form.getAllowCouponDiscounts()); 268 var allowAssociatePayments = Boolean.valueOf(form.getAllowAssociatePayments()); 269 270 // TODO: SerialNumberSequenceName is currently ignored. 271 item = ItemLogic.getInstance().createItem(this, itemName, itemType, itemUseType, itemCategory, 272 itemAccountingCategory, itemPurchasingCategory, partyCompany.getParty(), 273 itemDeliveryType, itemInventoryType, inventorySerialized, null, shippingChargeExempt, 274 shippingStartTime, shippingEndTime, salesOrderStartTime, salesOrderEndTime, 275 purchaseOrderStartTime, purchaseOrderEndTime, allowClubDiscounts, allowCouponDiscounts, 276 allowAssociatePayments, unitOfMeasureKind, itemPriceType, cancellationPolicy, 277 returnPolicy, null, createdBy); 278 279 if(!hasExecutionErrors()) { 280 var entityInstanceControl = Session.getModelController(EntityInstanceControl.class); 281 var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(item.getPrimaryKey()); 282 283 workflowControl.addEntityToWorkflow(itemStatus, entityInstance, null, null, createdBy); 284 } 285 } 286 } else { 287 if(isKitOrStyle) { 288 if(inventorySerialized != null) { 289 addExecutionError(ExecutionErrors.NotPermittedInventorySerialized.name()); 290 } 291 } else { 292 if(inventorySerialized == null) { 293 addExecutionError(ExecutionErrors.MissingInventorySerialized.name()); 294 } 295 } 296 } 297 } else { 298 addExecutionError(ExecutionErrors.UnknownReturnPolicyName.name(), returnPolicyName); 299 } 300 } else { 301 addExecutionError(ExecutionErrors.UnknownCancellationPolicyName.name(), cancellationPolicyName); 302 } 303 } else { 304 addExecutionError(ExecutionErrors.UnknownItemPriceTypeName.name(), itemPriceTypeName); 305 } 306 } else { 307 addExecutionError(ExecutionErrors.UnknownUnitOfMeasureKindName.name(), unitOfMeasureKindName); 308 } 309 } 310 } 311 } else { 312 addExecutionError(ExecutionErrors.UnknownCompanyName.name(), companyName); 313 } 314 } 315 } 316 } else { 317 addExecutionError(ExecutionErrors.UnknownItemCategoryName.name(), itemCategoryName); 318 } 319 } else { 320 addExecutionError(ExecutionErrors.UnknownItemUseTypeName.name(), itemUseTypeName); 321 } 322 } else { 323 addExecutionError(ExecutionErrors.UnknownItemTypeName.name(), itemTypeName); 324 } 325 } else { 326 addExecutionError(ExecutionErrors.DuplicateItemName.name(), itemName); 327 } 328 329 if(item != null) { 330 result.setItemName(item.getLastDetail().getItemName()); 331 result.setEntityRef(item.getPrimaryKey().getEntityRef()); 332 } 333 334 return result; 335 } 336 337}