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