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.edit.ItemEdit; 020import com.echothree.control.user.item.common.edit.ItemEditFactory; 021import com.echothree.control.user.item.common.result.EditItemResult; 022import com.echothree.control.user.item.common.result.ItemResultFactory; 023import com.echothree.control.user.item.common.spec.ItemSpec; 024import com.echothree.model.control.accounting.server.control.AccountingControl; 025import com.echothree.model.control.cancellationpolicy.common.CancellationKinds; 026import com.echothree.model.control.cancellationpolicy.server.control.CancellationPolicyControl; 027import com.echothree.model.control.item.common.ItemTypes; 028import com.echothree.model.control.item.server.control.ItemControl; 029import com.echothree.model.control.party.common.PartyTypes; 030import com.echothree.model.control.returnpolicy.common.ReturnKinds; 031import com.echothree.model.control.returnpolicy.server.control.ReturnPolicyControl; 032import com.echothree.model.control.security.common.SecurityRoleGroups; 033import com.echothree.model.control.security.common.SecurityRoles; 034import com.echothree.model.control.vendor.server.control.VendorControl; 035import com.echothree.model.data.accounting.server.entity.ItemAccountingCategory; 036import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy; 037import com.echothree.model.data.item.server.entity.Item; 038import com.echothree.model.data.item.server.entity.ItemCategory; 039import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy; 040import com.echothree.model.data.vendor.server.entity.ItemPurchasingCategory; 041import com.echothree.util.common.command.EditMode; 042import com.echothree.util.common.message.ExecutionErrors; 043import com.echothree.util.common.validation.FieldDefinition; 044import com.echothree.util.common.validation.FieldType; 045import com.echothree.util.server.control.BaseAbstractEditCommand; 046import com.echothree.util.server.control.CommandSecurityDefinition; 047import com.echothree.util.server.control.PartyTypeDefinition; 048import com.echothree.util.server.control.SecurityRoleDefinition; 049import com.echothree.util.server.string.DateUtils; 050import java.util.List; 051import javax.enterprise.context.Dependent; 052import javax.inject.Inject; 053 054@Dependent 055public class EditItemCommand 056 extends BaseAbstractEditCommand<ItemSpec, ItemEdit, EditItemResult, Item, Item> { 057 058 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 059 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 060 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 061 062 static { 063 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 064 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 065 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 066 new SecurityRoleDefinition(SecurityRoleGroups.ItemCategory.name(), SecurityRoles.Edit.name()) 067 )) 068 )); 069 070 SPEC_FIELD_DEFINITIONS = List.of( 071 new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null) 072 ); 073 074 EDIT_FIELD_DEFINITIONS = List.of( 075 new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null), 076 new FieldDefinition("ItemCategoryName", FieldType.ENTITY_NAME, true, 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("ShippingChargeExempt", FieldType.BOOLEAN, true, null, null), 080 new FieldDefinition("ShippingStartTime", FieldType.DATE_TIME, false, null, null), 081 new FieldDefinition("ShippingEndTime", FieldType.DATE_TIME, false, null, null), 082 new FieldDefinition("SalesOrderStartTime", FieldType.DATE_TIME, false, null, null), 083 new FieldDefinition("SalesOrderEndTime", FieldType.DATE_TIME, false, null, null), 084 new FieldDefinition("PurchaseOrderStartTime", FieldType.DATE_TIME, false, null, null), 085 new FieldDefinition("PurchaseOrderEndTime", FieldType.DATE_TIME, false, null, null), 086 new FieldDefinition("AllowClubDiscounts", FieldType.BOOLEAN, true, null, null), 087 new FieldDefinition("AllowCouponDiscounts", FieldType.BOOLEAN, true, null, null), 088 new FieldDefinition("AllowAssociatePayments", FieldType.BOOLEAN, true, null, null), 089 new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null), 090 new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null) 091 ); 092 } 093 094 @Inject 095 AccountingControl accountingControl; 096 097 @Inject 098 CancellationPolicyControl cancellationPolicyControl; 099 100 @Inject 101 ItemControl itemControl; 102 103 @Inject 104 ReturnPolicyControl returnPolicyControl; 105 106 @Inject 107 VendorControl vendorControl; 108 109 110 /** Creates a new instance of EditItemCommand */ 111 public EditItemCommand() { 112 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 113 } 114 115 @Override 116 public EditItemResult getResult() { 117 return ItemResultFactory.getEditItemResult(); 118 } 119 120 @Override 121 public ItemEdit getEdit() { 122 return ItemEditFactory.getItemEdit(); 123 } 124 125 @Override 126 public Item getEntity(EditItemResult result) { 127 Item item; 128 var itemName = spec.getItemName(); 129 130 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 131 item = itemControl.getItemByName(itemName); 132 } else { // EditMode.UPDATE 133 item = itemControl.getItemByNameForUpdate(itemName); 134 } 135 136 if(item != null) { 137 result.setItem(itemControl.getItemTransfer(getUserVisit(), item)); 138 } else { 139 addExecutionError(ExecutionErrors.UnknownItemName.name(), itemName); 140 } 141 142 return item; 143 } 144 145 @Override 146 public Item getLockEntity(Item item) { 147 return item; 148 } 149 150 @Override 151 public void fillInResult(EditItemResult result, Item item) { 152 result.setItem(itemControl.getItemTransfer(getUserVisit(), item)); 153 } 154 155 @Override 156 public void doLock(ItemEdit edit, Item item) { 157 var dateUtils = DateUtils.getInstance(); 158 var itemDetail = item.getLastDetail(); 159 var userVisit = getUserVisit(); 160 var preferredDateTimeFormat = getPreferredDateTimeFormat(); 161 162 itemAccountingCategory = itemDetail.getItemAccountingCategory(); 163 itemPurchasingCategory = itemDetail.getItemPurchasingCategory(); 164 cancellationPolicy = itemDetail.getCancellationPolicy(); 165 returnPolicy = itemDetail.getReturnPolicy(); 166 167 edit.setItemName(itemDetail.getItemName()); 168 edit.setItemName(edit.getItemName()); 169 edit.setItemCategoryName(itemDetail.getItemCategory().getLastDetail().getItemCategoryName()); 170 edit.setItemAccountingCategoryName(itemAccountingCategory == null? null: itemAccountingCategory.getLastDetail().getItemAccountingCategoryName()); 171 edit.setItemPurchasingCategoryName(itemPurchasingCategory == null? null: itemPurchasingCategory.getLastDetail().getItemPurchasingCategoryName()); 172 edit.setShippingChargeExempt(itemDetail.getShippingChargeExempt().toString()); 173 edit.setShippingStartTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getShippingStartTime())); 174 edit.setShippingEndTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getShippingEndTime())); 175 edit.setSalesOrderStartTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getSalesOrderStartTime())); 176 edit.setSalesOrderEndTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getSalesOrderEndTime())); 177 edit.setPurchaseOrderStartTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getPurchaseOrderStartTime())); 178 edit.setPurchaseOrderEndTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getPurchaseOrderEndTime())); 179 edit.setAllowClubDiscounts(itemDetail.getAllowClubDiscounts().toString()); 180 edit.setAllowCouponDiscounts(itemDetail.getAllowCouponDiscounts().toString()); 181 edit.setAllowAssociatePayments(itemDetail.getAllowAssociatePayments().toString()); 182 edit.setCancellationPolicyName(cancellationPolicy == null? null: cancellationPolicy.getLastDetail().getCancellationPolicyName()); 183 edit.setReturnPolicyName(returnPolicy == null? null: returnPolicy.getLastDetail().getReturnPolicyName()); 184 } 185 186 ItemCategory itemCategory; 187 boolean isKit; 188 ItemAccountingCategory itemAccountingCategory; 189 ItemPurchasingCategory itemPurchasingCategory; 190 CancellationPolicy cancellationPolicy; 191 ReturnPolicy returnPolicy; 192 193 @Override 194 public void canUpdate(Item item) { 195 var itemName = edit.getItemName(); 196 var duplicateItem = itemControl.getItemByName(itemName); 197 198 if(duplicateItem == null || item.equals(duplicateItem)) { 199 var itemCategoryName = edit.getItemCategoryName(); 200 var itemTypeName = item.getLastDetail().getItemType().getItemTypeName(); 201 202 itemCategory = itemControl.getItemCategoryByName(itemCategoryName); 203 204 if(itemCategory != null) { 205 var itemAccountingCategoryName = edit.getItemAccountingCategoryName(); 206 207 isKit = itemTypeName.equals(ItemTypes.KIT.name()); 208 209 if(isKit) { 210 if(itemAccountingCategoryName != null) { 211 addExecutionError(ExecutionErrors.NotPermittedItemAccountingCategory.name(), itemAccountingCategoryName); 212 } 213 } else { 214 itemAccountingCategory = itemAccountingCategoryName == null? null: accountingControl.getItemAccountingCategoryByName(itemAccountingCategoryName); 215 216 if(itemAccountingCategoryName == null) { 217 addExecutionError(ExecutionErrors.MissingItemAccountingCategoryName.name()); 218 } else if(itemAccountingCategory == null) { 219 addExecutionError(ExecutionErrors.UnknownItemAccountingCategoryName.name(), itemAccountingCategoryName); 220 } 221 } 222 223 if(!hasExecutionErrors()) { 224 var itemPurchasingCategoryName = edit.getItemPurchasingCategoryName(); 225 226 if(isKit) { 227 if(itemPurchasingCategoryName != null) { 228 addExecutionError(ExecutionErrors.NotPermittedItemPurchasingCategory.name(), itemPurchasingCategoryName); 229 } 230 } else { 231 itemPurchasingCategory = itemPurchasingCategoryName == null? null: vendorControl.getItemPurchasingCategoryByName(itemPurchasingCategoryName); 232 233 if(itemPurchasingCategoryName == null) { 234 addExecutionError(ExecutionErrors.MissingItemPurchasingCategoryName.name()); 235 } else if(itemPurchasingCategory == null) { 236 addExecutionError(ExecutionErrors.UnknownItemPurchasingCategoryName.name(), itemPurchasingCategoryName); 237 } 238 } 239 240 if(!hasExecutionErrors()) { 241 var cancellationPolicyName = edit.getCancellationPolicyName(); 242 243 if(cancellationPolicyName != null) { 244 var cancellationKind = cancellationPolicyControl.getCancellationKindByName(CancellationKinds.CUSTOMER_CANCELLATION.name()); 245 246 cancellationPolicy = cancellationPolicyControl.getCancellationPolicyByName(cancellationKind, cancellationPolicyName); 247 } 248 249 if(cancellationPolicyName == null || cancellationPolicy != null) { 250 var returnPolicyName = edit.getReturnPolicyName(); 251 252 if(returnPolicyName != null) { 253 var returnKind = returnPolicyControl.getReturnKindByName(ReturnKinds.CUSTOMER_RETURN.name()); 254 255 returnPolicy = returnPolicyControl.getReturnPolicyByName(returnKind, returnPolicyName); 256 } 257 258 if(returnPolicyName != null && returnPolicy == null) { 259 addExecutionError(ExecutionErrors.UnknownReturnPolicyName.name(), returnPolicyName); 260 } 261 } else { 262 addExecutionError(ExecutionErrors.UnknownCancellationPolicyName.name(), cancellationPolicyName); 263 } 264 } 265 } 266 } else { 267 addExecutionError(ExecutionErrors.UnknownItemCategoryName.name(), itemCategoryName); 268 } 269 } else { 270 addExecutionError(ExecutionErrors.DuplicateItemName.name(), itemName); 271 } 272 } 273 274 @Override 275 public void doUpdate(Item item) { 276 var partyPK = getPartyPK(); 277 var itemDetailValue = itemControl.getItemDetailValueForUpdate(item); 278 var shippingChargeExempt = Boolean.valueOf(edit.getShippingChargeExempt()); 279 var strShippingStartTime = edit.getShippingStartTime(); 280 var shippingStartTime = strShippingStartTime == null? session.getStartTime(): Long.valueOf(strShippingStartTime); 281 var strShippingEndTime = edit.getShippingEndTime(); 282 var shippingEndTime = strShippingEndTime == null? null: Long.valueOf(strShippingEndTime); 283 var strSalesOrderStartTime = edit.getSalesOrderStartTime(); 284 var salesOrderStartTime = strSalesOrderStartTime == null? session.getStartTime(): Long.valueOf(strSalesOrderStartTime); 285 var strSalesOrderEndTime = edit.getSalesOrderEndTime(); 286 var salesOrderEndTime = strSalesOrderEndTime == null? null: Long.valueOf(strSalesOrderEndTime); 287 var strPurchaseOrderStartTime = edit.getPurchaseOrderStartTime(); 288 var purchaseOrderStartTime = isKit? null: strPurchaseOrderStartTime == null? session.getStartTime(): Long.valueOf(strPurchaseOrderStartTime); 289 var strPurchaseOrderEndTime = edit.getPurchaseOrderEndTime(); 290 var purchaseOrderEndTime = isKit? null: strPurchaseOrderEndTime == null? null: Long.valueOf(strPurchaseOrderEndTime); 291 var allowClubDiscounts = Boolean.valueOf(edit.getAllowClubDiscounts()); 292 var allowCouponDiscounts = Boolean.valueOf(edit.getAllowCouponDiscounts()); 293 var allowAssociatePayments = Boolean.valueOf(edit.getAllowAssociatePayments()); 294 295 itemDetailValue.setItemName(edit.getItemName()); 296 itemDetailValue.setItemCategoryPK(itemCategory.getPrimaryKey()); 297 itemDetailValue.setItemAccountingCategoryPK(itemAccountingCategory == null? null: itemAccountingCategory.getPrimaryKey()); 298 itemDetailValue.setItemPurchasingCategoryPK(itemPurchasingCategory == null? null: itemPurchasingCategory.getPrimaryKey()); 299 itemDetailValue.setShippingChargeExempt(shippingChargeExempt); 300 itemDetailValue.setShippingStartTime(shippingStartTime); 301 itemDetailValue.setShippingEndTime(shippingEndTime); 302 itemDetailValue.setSalesOrderStartTime(salesOrderStartTime); 303 itemDetailValue.setSalesOrderEndTime(salesOrderEndTime); 304 itemDetailValue.setPurchaseOrderStartTime(purchaseOrderStartTime); 305 itemDetailValue.setPurchaseOrderEndTime(purchaseOrderEndTime); 306 itemDetailValue.setAllowClubDiscounts(allowClubDiscounts); 307 itemDetailValue.setAllowCouponDiscounts(allowCouponDiscounts); 308 itemDetailValue.setAllowAssociatePayments(allowAssociatePayments); 309 itemDetailValue.setCancellationPolicyPK(cancellationPolicy == null? null: cancellationPolicy.getPrimaryKey()); 310 itemDetailValue.setReturnPolicyPK(returnPolicy == null? null: returnPolicy.getPrimaryKey()); 311 312 itemControl.updateItemFromValue(itemDetailValue, partyPK); 313 } 314 315}