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.result.EditOfferItemPriceResult; 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.item.common.ItemPriceTypes; 026import com.echothree.model.control.offer.server.control.OfferItemControl; 027import com.echothree.model.control.offer.server.logic.OfferItemLogic; 028import com.echothree.model.control.offer.server.logic.OfferItemPriceLogic; 029import com.echothree.model.control.offer.server.logic.OfferLogic; 030import com.echothree.model.control.party.common.PartyTypes; 031import com.echothree.model.control.security.common.SecurityRoleGroups; 032import com.echothree.model.control.security.common.SecurityRoles; 033import com.echothree.model.data.offer.server.entity.OfferItem; 034import com.echothree.model.data.offer.server.entity.OfferItemPrice; 035import com.echothree.util.common.form.BaseForm; 036import com.echothree.util.common.command.EditMode; 037import com.echothree.util.common.message.ExecutionErrors; 038import com.echothree.util.common.validation.FieldDefinition; 039import com.echothree.util.common.validation.FieldType; 040import com.echothree.util.server.control.BaseAbstractEditCommand; 041import com.echothree.util.server.control.CommandSecurityDefinition; 042import com.echothree.util.server.control.PartyTypeDefinition; 043import com.echothree.util.server.control.SecurityRoleDefinition; 044import com.echothree.util.server.string.AmountUtils; 045import com.echothree.util.server.validation.Validator; 046import java.util.List; 047import javax.enterprise.context.Dependent; 048import javax.inject.Inject; 049 050@Dependent 051public class EditOfferItemPriceCommand 052 extends BaseAbstractEditCommand<OfferItemPriceSpec, OfferItemPriceEdit, EditOfferItemPriceResult, OfferItemPrice, OfferItem> { 053 054 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 055 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 056 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 057 058 static { 059 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 060 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 061 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 062 new SecurityRoleDefinition(SecurityRoleGroups.OfferItemPrice.name(), SecurityRoles.Edit.name()) 063 )) 064 )); 065 066 SPEC_FIELD_DEFINITIONS = List.of( 067 new FieldDefinition("OfferName", FieldType.ENTITY_NAME, true, null, 20L), 068 new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null), 069 new FieldDefinition("InventoryConditionName", FieldType.ENTITY_NAME, true, null, null), 070 new FieldDefinition("UnitOfMeasureTypeName", FieldType.ENTITY_NAME, true, null, null), 071 new FieldDefinition("CurrencyIsoName", FieldType.ENTITY_NAME, true, null, null) 072 ); 073 074 EDIT_FIELD_DEFINITIONS = List.of( 075 new FieldDefinition("UnitPrice", FieldType.UNSIGNED_PRICE_UNIT, false, null, null), 076 new FieldDefinition("MinimumUnitPrice", FieldType.UNSIGNED_PRICE_UNIT, false, null, null), 077 new FieldDefinition("MaximumUnitPrice", FieldType.UNSIGNED_PRICE_UNIT, false, null, null), 078 new FieldDefinition("UnitPriceIncrement", FieldType.UNSIGNED_PRICE_UNIT, false, null, null) 079 ); 080 } 081 082 @Inject 083 AccountingControl accountingControl; 084 085 @Inject 086 OfferItemControl offerItemControl; 087 088 @Inject 089 OfferItemLogic offerItemLogic; 090 091 @Inject 092 OfferItemPriceLogic offerItemPriceLogic; 093 094 @Inject 095 OfferLogic offerLogic; 096 097 /** Creates a new instance of EditOfferItemPriceCommand */ 098 public EditOfferItemPriceCommand() { 099 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 100 } 101 102 @Override 103 protected void setupValidatorForEdit(Validator validator, BaseForm specForm) { 104 var currencyIsoName = spec.getCurrencyIsoName(); 105 106 validator.setCurrency(accountingControl.getCurrencyByIsoName(currencyIsoName)); 107 } 108 109 @Override 110 public EditOfferItemPriceResult getResult() { 111 return OfferResultFactory.getEditOfferItemPriceResult(); 112 } 113 114 @Override 115 public OfferItemPriceEdit getEdit() { 116 return OfferEditFactory.getOfferItemPriceEdit(); 117 } 118 119 @Override 120 public OfferItemPrice getEntity(EditOfferItemPriceResult result) { 121 OfferItemPrice offerItemPrice = null; 122 var offer = offerLogic.getOfferByName(this, spec.getOfferName()); 123 124 if(!hasExecutionErrors()) { 125 if(editMode != EditMode.ABANDON && offer.getLastDetail().getOfferItemPriceFilter() != null) { 126 addExecutionError(ExecutionErrors.CannotManuallyEditOfferItemPriceWhenOfferItemPriceFilterSet.name(), spec.getOfferName()); 127 } else { 128 offerItemPrice = offerItemPriceLogic.getOfferItemPriceBySpec(this, spec, editModeToEntityPermission(editMode)); 129 } 130 } 131 132 return offerItemPrice; 133 } 134 135 @Override 136 public OfferItem getLockEntity(OfferItemPrice offerItemPrice) { 137 return offerItemPrice.getOfferItem(); 138 } 139 140 @Override 141 public void fillInResult(EditOfferItemPriceResult result, OfferItemPrice offerItemPrice) { 142 result.setOfferItemPrice(offerItemControl.getOfferItemPriceTransfer(getUserVisit(), offerItemPrice)); 143 } 144 145 private String getItemPriceTypeName(OfferItemPrice offerItemPrice) { 146 return offerItemPrice.getOfferItem().getItem().getLastDetail().getItemPriceType().getItemPriceTypeName(); 147 } 148 149 @Override 150 public void doLock(OfferItemPriceEdit edit, OfferItemPrice offerItemPrice) { 151 var itemPriceTypeName = getItemPriceTypeName(offerItemPrice); 152 var currency = offerItemPrice.getCurrency(); 153 var amountUtils = AmountUtils.getInstance(); 154 155 if(itemPriceTypeName.equals(ItemPriceTypes.FIXED.name())) { 156 var offerItemFixedPrice = offerItemControl.getOfferItemFixedPrice(offerItemPrice); 157 158 edit.setUnitPrice(amountUtils.formatPriceUnit(currency, offerItemFixedPrice.getUnitPrice())); 159 } else if(itemPriceTypeName.equals(ItemPriceTypes.VARIABLE.name())) { 160 var offerItemVariablePrice = offerItemControl.getOfferItemVariablePrice(offerItemPrice); 161 162 edit.setMinimumUnitPrice(amountUtils.formatPriceUnit(currency, offerItemVariablePrice.getMinimumUnitPrice())); 163 edit.setMaximumUnitPrice(amountUtils.formatPriceUnit(currency, offerItemVariablePrice.getMaximumUnitPrice())); 164 edit.setUnitPriceIncrement(amountUtils.formatPriceUnit(currency, offerItemVariablePrice.getUnitPriceIncrement())); 165 } else { 166 addExecutionError(ExecutionErrors.UnknownItemPriceType.name(), itemPriceTypeName); 167 } 168 } 169 170 @Override 171 public void canUpdate(OfferItemPrice offerItemPrice) { 172 var itemPriceTypeName = getItemPriceTypeName(offerItemPrice); 173 174 if(itemPriceTypeName.equals(ItemPriceTypes.FIXED.name())) { 175 if(edit.getUnitPrice() == null) { 176 addExecutionError(ExecutionErrors.MissingUnitPrice.name()); 177 } 178 } else if(itemPriceTypeName.equals(ItemPriceTypes.VARIABLE.name())) { 179 if(edit.getMinimumUnitPrice() == null) { 180 addExecutionError(ExecutionErrors.MissingMinimumUnitPrice.name()); 181 } 182 if(edit.getMaximumUnitPrice() == null) { 183 addExecutionError(ExecutionErrors.MissingMaximumUnitPrice.name()); 184 } 185 if(edit.getUnitPriceIncrement() == null) { 186 addExecutionError(ExecutionErrors.MissingUnitPriceIncrement.name()); 187 } 188 } else { 189 addExecutionError(ExecutionErrors.UnknownItemPriceType.name(), itemPriceTypeName); 190 } 191 } 192 193 @Override 194 public void doUpdate(OfferItemPrice offerItemPrice) { 195 if(getItemPriceTypeName(offerItemPrice).equals(ItemPriceTypes.FIXED.name())) { 196 var offerItemFixedPriceValue = offerItemControl.getOfferItemFixedPriceValueForUpdate(offerItemPrice); 197 198 offerItemFixedPriceValue.setUnitPrice(Long.valueOf(edit.getUnitPrice())); 199 200 offerItemLogic.updateOfferItemFixedPriceFromValue(offerItemFixedPriceValue, getPartyPK()); 201 } else { 202 var offerItemVariablePriceValue = offerItemControl.getOfferItemVariablePriceValueForUpdate(offerItemPrice); 203 204 offerItemVariablePriceValue.setMinimumUnitPrice(Long.valueOf(edit.getMinimumUnitPrice())); 205 offerItemVariablePriceValue.setMaximumUnitPrice(Long.valueOf(edit.getMaximumUnitPrice())); 206 offerItemVariablePriceValue.setUnitPriceIncrement(Long.valueOf(edit.getUnitPriceIncrement())); 207 208 offerItemLogic.updateOfferItemVariablePriceFromValue(offerItemVariablePriceValue, getPartyPK()); 209 } 210 } 211 212}