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.offer.server.command; 018 019import com.echothree.control.user.offer.common.edit.OfferEditFactory; 020import com.echothree.control.user.offer.common.edit.OfferItemPriceEdit; 021import com.echothree.control.user.offer.common.form.EditOfferItemPriceForm; 022import com.echothree.control.user.offer.common.result.OfferResultFactory; 023import com.echothree.control.user.offer.common.spec.OfferItemPriceSpec; 024import com.echothree.model.control.accounting.server.control.AccountingControl; 025import com.echothree.model.control.accounting.server.logic.CurrencyLogic; 026import com.echothree.model.control.inventory.server.logic.InventoryConditionLogic; 027import com.echothree.model.control.item.common.ItemPriceTypes; 028import com.echothree.model.control.item.server.logic.ItemLogic; 029import com.echothree.model.control.offer.server.control.OfferItemControl; 030import com.echothree.model.control.offer.server.logic.OfferItemLogic; 031import com.echothree.model.control.offer.server.logic.OfferLogic; 032import com.echothree.model.control.party.common.PartyTypes; 033import com.echothree.model.control.security.common.SecurityRoleGroups; 034import com.echothree.model.control.security.common.SecurityRoles; 035import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic; 036import com.echothree.model.data.user.common.pk.UserVisitPK; 037import com.echothree.util.common.command.BaseResult; 038import com.echothree.util.common.command.EditMode; 039import com.echothree.util.common.form.BaseForm; 040import com.echothree.util.common.message.ExecutionErrors; 041import com.echothree.util.common.validation.FieldDefinition; 042import com.echothree.util.common.validation.FieldType; 043import com.echothree.util.server.control.BaseEditCommand; 044import com.echothree.util.server.control.CommandSecurityDefinition; 045import com.echothree.util.server.control.PartyTypeDefinition; 046import com.echothree.util.server.control.SecurityRoleDefinition; 047import com.echothree.util.server.persistence.Session; 048import com.echothree.util.server.string.AmountUtils; 049import com.echothree.util.server.validation.Validator; 050import java.util.List; 051import javax.enterprise.context.Dependent; 052 053@Dependent 054public class EditOfferItemPriceCommand 055 extends BaseEditCommand<OfferItemPriceSpec, OfferItemPriceEdit> { 056 057 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 058 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 059 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 060 061 static { 062 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 063 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 064 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 065 new SecurityRoleDefinition(SecurityRoleGroups.OfferItemPrice.name(), SecurityRoles.Edit.name()) 066 )) 067 )); 068 069 SPEC_FIELD_DEFINITIONS = List.of( 070 new FieldDefinition("OfferName", FieldType.ENTITY_NAME, true, null, 20L), 071 new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null), 072 new FieldDefinition("InventoryConditionName", FieldType.ENTITY_NAME, true, null, null), 073 new FieldDefinition("UnitOfMeasureTypeName", FieldType.ENTITY_NAME, true, null, null), 074 new FieldDefinition("CurrencyIsoName", FieldType.ENTITY_NAME, true, null, null) 075 ); 076 077 EDIT_FIELD_DEFINITIONS = List.of( 078 new FieldDefinition("UnitPrice", FieldType.UNSIGNED_PRICE_UNIT, false, null, null), 079 new FieldDefinition("MinimumUnitPrice", FieldType.UNSIGNED_PRICE_UNIT, false, null, null), 080 new FieldDefinition("MaximumUnitPrice", FieldType.UNSIGNED_PRICE_UNIT, false, null, null), 081 new FieldDefinition("UnitPriceIncrement", FieldType.UNSIGNED_PRICE_UNIT, false, null, null) 082 ); 083 } 084 085 /** Creates a new instance of EditOfferItemPriceCommand */ 086 public EditOfferItemPriceCommand() { 087 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 088 } 089 090 @Override 091 protected void setupValidatorForEdit(Validator validator, BaseForm specForm) { 092 var accountingControl = Session.getModelController(AccountingControl.class); 093 var currencyIsoName = spec.getCurrencyIsoName(); 094 095 validator.setCurrency(accountingControl.getCurrencyByIsoName(currencyIsoName)); 096 } 097 098 @Override 099 protected BaseResult execute() { 100 var result = OfferResultFactory.getEditOfferItemPriceResult(); 101 var offerName = spec.getOfferName(); 102 var offer = OfferLogic.getInstance().getOfferByName(this, offerName); 103 104 if(!hasExecutionErrors()) { 105 final var offerDetail = offer.getLastDetail(); 106 107 if(offerDetail.getOfferItemPriceFilter() == null) { 108 var itemName = spec.getItemName(); 109 var inventoryConditionName = spec.getInventoryConditionName(); 110 var unitOfMeasureTypeName = spec.getUnitOfMeasureTypeName(); 111 var currencyIsoName = spec.getCurrencyIsoName(); 112 var item = ItemLogic.getInstance().getItemByName(this, itemName); 113 var inventoryCondition = InventoryConditionLogic.getInstance().getInventoryConditionByName(this, inventoryConditionName); 114 var currency = CurrencyLogic.getInstance().getCurrencyByName(this, currencyIsoName); 115 116 if(!hasExecutionErrors()) { 117 var offerItemControl = Session.getModelController(OfferItemControl.class); 118 var offerItem = offerItemControl.getOfferItem(offer, item); 119 120 if(offerItem != null) { 121 var itemDetail = item.getLastDetail(); 122 var unitOfMeasureKind = item.getLastDetail().getUnitOfMeasureKind(); 123 var unitOfMeasureType = UnitOfMeasureTypeLogic.getInstance().getUnitOfMeasureTypeByName(this, 124 unitOfMeasureKind, unitOfMeasureTypeName); 125 126 if(!hasExecutionErrors()) { 127 var offerItemPrice = offerItemControl.getOfferItemPrice(offerItem, inventoryCondition, 128 unitOfMeasureType, currency); 129 130 if(offerItemPrice != null) { 131 var itemPriceTypeName = itemDetail.getItemPriceType().getItemPriceTypeName(); 132 133 if(editMode.equals(EditMode.LOCK)) { 134 result.setOfferItemPrice(offerItemControl.getOfferItemPriceTransfer(getUserVisit(), offerItemPrice)); 135 136 if(lockEntity(offerItem)) { 137 var edit = OfferEditFactory.getOfferItemPriceEdit(); 138 139 result.setEdit(edit); 140 141 if(itemPriceTypeName.equals(ItemPriceTypes.FIXED.name())) { 142 var offerItemFixedPrice = offerItemControl.getOfferItemFixedPrice(offerItemPrice); 143 144 edit.setUnitPrice(AmountUtils.getInstance().formatPriceUnit(currency, offerItemFixedPrice.getUnitPrice())); 145 } else if(itemPriceTypeName.equals(ItemPriceTypes.VARIABLE.name())) { 146 var offerItemVariablePrice = offerItemControl.getOfferItemVariablePrice(offerItemPrice); 147 148 edit.setMinimumUnitPrice(AmountUtils.getInstance().formatPriceUnit(currency, offerItemVariablePrice.getMinimumUnitPrice())); 149 edit.setMaximumUnitPrice(AmountUtils.getInstance().formatPriceUnit(currency, offerItemVariablePrice.getMaximumUnitPrice())); 150 edit.setUnitPriceIncrement(AmountUtils.getInstance().formatPriceUnit(currency, offerItemVariablePrice.getUnitPriceIncrement())); 151 } else { 152 addExecutionError(ExecutionErrors.UnknownItemPriceType.name(), itemPriceTypeName); 153 } 154 } else { 155 addExecutionError(ExecutionErrors.EntityLockFailed.name()); 156 } 157 158 result.setEntityLock(getEntityLockTransfer(offerItem)); 159 } else if(editMode.equals(EditMode.UPDATE)) { 160 if(itemPriceTypeName.equals(ItemPriceTypes.FIXED.name())) { 161 var strUnitPrice = edit.getUnitPrice(); 162 163 if(strUnitPrice != null) { 164 var unitPrice = Long.valueOf(strUnitPrice); 165 166 if(lockEntityForUpdate(offerItem)) { 167 try { 168 var offerItemFixedPriceValue = offerItemControl.getOfferItemFixedPriceValueForUpdate(offerItemPrice); 169 170 offerItemFixedPriceValue.setUnitPrice(unitPrice); 171 172 OfferItemLogic.getInstance().updateOfferItemFixedPriceFromValue(offerItemFixedPriceValue, getPartyPK()); 173 } finally { 174 unlockEntity(offerItem); 175 } 176 } else { 177 addExecutionError(ExecutionErrors.EntityLockStale.name()); 178 } 179 } else { 180 addExecutionError(ExecutionErrors.MissingUnitPrice.name()); 181 } 182 } else if(itemPriceTypeName.equals(ItemPriceTypes.VARIABLE.name())) { 183 var strMinimumUnitPrice = edit.getMinimumUnitPrice(); 184 Long minimumUnitPrice = null; 185 var strMaximumUnitPrice = edit.getMaximumUnitPrice(); 186 Long maximumUnitPrice = null; 187 var strUnitPriceIncrement = edit.getUnitPriceIncrement(); 188 Long unitPriceIncrement = null; 189 190 if(strMinimumUnitPrice != null) { 191 minimumUnitPrice = Long.valueOf(strMinimumUnitPrice); 192 } else { 193 addExecutionError(ExecutionErrors.MissingMinimumUnitPrice.name()); 194 } 195 196 if(strMaximumUnitPrice != null) { 197 maximumUnitPrice = Long.valueOf(strMaximumUnitPrice); 198 } else { 199 addExecutionError(ExecutionErrors.MissingMaximumUnitPrice.name()); 200 } 201 202 if(strUnitPriceIncrement != null) { 203 unitPriceIncrement = Long.valueOf(strUnitPriceIncrement); 204 } else { 205 addExecutionError(ExecutionErrors.MissingUnitPriceIncrement.name()); 206 } 207 208 if(minimumUnitPrice != null && maximumUnitPrice != null && unitPriceIncrement != null) { 209 if(lockEntityForUpdate(offerItem)) { 210 try { 211 var offerItemVariablePriceValue = offerItemControl.getOfferItemVariablePriceValueForUpdate(offerItemPrice); 212 213 offerItemVariablePriceValue.setMinimumUnitPrice(minimumUnitPrice); 214 offerItemVariablePriceValue.setMaximumUnitPrice(maximumUnitPrice); 215 offerItemVariablePriceValue.setUnitPriceIncrement(unitPriceIncrement); 216 217 OfferItemLogic.getInstance().updateOfferItemVariablePriceFromValue(offerItemVariablePriceValue, getPartyPK()); 218 } finally { 219 unlockEntity(offerItem); 220 } 221 } else { 222 addExecutionError(ExecutionErrors.EntityLockStale.name()); 223 } 224 } 225 } else { 226 addExecutionError(ExecutionErrors.UnknownItemPriceType.name(), itemPriceTypeName); 227 } 228 } 229 } else { 230 addExecutionError(ExecutionErrors.DuplicateOfferItemPrice.name()); 231 } 232 } 233 } else { 234 addExecutionError(ExecutionErrors.UnknownOfferItem.name(), offerName, itemName); 235 } 236 } 237 } else { 238 addExecutionError(ExecutionErrors.CannotManuallyEditOfferItemPriceWhenOfferItemPriceFilterSet.name(), 239 offerDetail.getOfferName()); 240 } 241 } 242 243 return result; 244 } 245 246}