001// -------------------------------------------------------------------------------- 002// Copyright 2002-2024 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.inventory.server.command; 018 019import com.echothree.control.user.inventory.common.edit.InventoryEditFactory; 020import com.echothree.control.user.inventory.common.edit.PartyInventoryLevelEdit; 021import com.echothree.control.user.inventory.common.form.EditPartyInventoryLevelForm; 022import com.echothree.control.user.inventory.common.result.EditPartyInventoryLevelResult; 023import com.echothree.control.user.inventory.common.result.InventoryResultFactory; 024import com.echothree.control.user.inventory.common.spec.PartyInventoryLevelSpec; 025import com.echothree.model.control.inventory.server.control.InventoryControl; 026import com.echothree.model.control.item.server.control.ItemControl; 027import com.echothree.model.control.party.common.PartyTypes; 028import com.echothree.model.control.party.server.control.PartyControl; 029import com.echothree.model.control.uom.server.control.UomControl; 030import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic; 031import com.echothree.model.control.uom.server.util.Conversion; 032import com.echothree.model.control.warehouse.server.control.WarehouseControl; 033import com.echothree.model.data.inventory.server.entity.InventoryCondition; 034import com.echothree.model.data.inventory.server.entity.PartyInventoryLevel; 035import com.echothree.model.data.inventory.server.value.PartyInventoryLevelValue; 036import com.echothree.model.data.item.server.entity.Item; 037import com.echothree.model.data.party.server.entity.Party; 038import com.echothree.model.data.party.server.entity.PartyCompany; 039import com.echothree.model.data.uom.server.entity.UnitOfMeasureKind; 040import com.echothree.model.data.user.common.pk.UserVisitPK; 041import com.echothree.model.data.warehouse.server.entity.Warehouse; 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.common.command.EditMode; 046import com.echothree.util.server.control.BaseAbstractEditCommand; 047import com.echothree.util.server.persistence.Session; 048import java.util.Arrays; 049import java.util.Collections; 050import java.util.List; 051 052public class EditPartyInventoryLevelCommand 053 extends BaseAbstractEditCommand<PartyInventoryLevelSpec, PartyInventoryLevelEdit, EditPartyInventoryLevelResult, PartyInventoryLevel, Item> { 054 055 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 056 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 057 058 static { 059 SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 060 new FieldDefinition("PartyName", FieldType.ENTITY_NAME, false, null, null), 061 new FieldDefinition("CompanyName", FieldType.ENTITY_NAME, false, null, null), 062 new FieldDefinition("WarehouseName", FieldType.ENTITY_NAME, false, null, null), 063 new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null), 064 new FieldDefinition("InventoryConditionName", FieldType.ENTITY_NAME, true, null, null) 065 )); 066 067 EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 068 new FieldDefinition("MinimumInventoryUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 069 new FieldDefinition("MinimumInventory", FieldType.UNSIGNED_LONG, false, null, null), 070 new FieldDefinition("MaximumInventoryUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 071 new FieldDefinition("MaximumInventory", FieldType.UNSIGNED_LONG, false, null, null), 072 new FieldDefinition("ReorderQuantityUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 073 new FieldDefinition("ReorderQuantity", FieldType.UNSIGNED_LONG, false, null, null) 074 )); 075 } 076 077 /** Creates a new instance of EditPartyInventoryLevelCommand */ 078 public EditPartyInventoryLevelCommand(UserVisitPK userVisitPK, EditPartyInventoryLevelForm form) { 079 super(userVisitPK, form, null, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 080 } 081 082 @Override 083 public EditPartyInventoryLevelResult getResult() { 084 return InventoryResultFactory.getEditPartyInventoryLevelResult(); 085 } 086 087 @Override 088 public PartyInventoryLevelEdit getEdit() { 089 return InventoryEditFactory.getPartyInventoryLevelEdit(); 090 } 091 092 // TODO: Duplicated from BasePartyInventoryLevelCommand 093 protected String getPartyTypeName(final Party party) { 094 return party.getLastDetail().getPartyType().getPartyTypeName(); 095 } 096 097 protected Party getParty(final String partyName, final String companyName, final String warehouseName) { 098 Party party = null; 099 100 if(partyName != null || companyName != null) { 101 var partyControl = Session.getModelController(PartyControl.class); 102 103 if(partyName != null) { 104 party = partyControl.getPartyByName(partyName); 105 106 if(party != null) { 107 String partyTypeName = getPartyTypeName(party); 108 109 if(!partyTypeName.equals(PartyTypes.COMPANY.name()) 110 && !partyTypeName.equals(PartyTypes.WAREHOUSE.name())) { 111 party = null; 112 addExecutionError(ExecutionErrors.InvalidPartyType.name()); 113 } 114 } else { 115 addExecutionError(ExecutionErrors.UnknownPartyName.name(), partyName); 116 } 117 } else if(companyName != null) { 118 PartyCompany partyCompany = partyControl.getPartyCompanyByName(companyName); 119 120 if(partyCompany != null) { 121 party = partyCompany.getParty(); 122 } else { 123 addExecutionError(ExecutionErrors.UnknownCompanyName.name(), companyName); 124 } 125 } 126 } else if(warehouseName != null) { 127 var warehouseControl = Session.getModelController(WarehouseControl.class); 128 Warehouse warehouse = warehouseControl.getWarehouseByName(warehouseName); 129 130 if(warehouse != null) { 131 party = warehouse.getParty(); 132 } else { 133 addExecutionError(ExecutionErrors.UnknownWarehouseName.name(), warehouseName); 134 } 135 } 136 return party; 137 } 138 139 protected Party getParty(PartyInventoryLevelSpec spec) { 140 String partyName = spec.getPartyName(); 141 String companyName = spec.getCompanyName(); 142 String warehouseName = spec.getWarehouseName(); 143 var parameterCount = (partyName == null ? 0 : 1) + (companyName == null ? 0 : 1) + (warehouseName == null ? 0 : 1); 144 Party party = null; 145 146 if(parameterCount == 1) { 147 party = getParty(partyName, companyName, warehouseName); 148 } else { 149 addExecutionError(ExecutionErrors.InvalidParameterCount.name()); 150 } 151 152 return party; 153 } 154 155 UnitOfMeasureKind unitOfMeasureKind; 156 157 @Override 158 public PartyInventoryLevel getEntity(EditPartyInventoryLevelResult result) { 159 var itemControl = Session.getModelController(ItemControl.class); 160 PartyInventoryLevel partyInventoryLevel = null; 161 Party party = getParty(spec); 162 163 if(party != null) { 164 String itemName = spec.getItemName(); 165 Item item = itemControl.getItemByName(itemName); 166 167 if(item != null) { 168 String partyTypeName = getPartyTypeName(party); 169 170 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.UPDATE)) { 171 unitOfMeasureKind = item.getLastDetail().getUnitOfMeasureKind(); 172 } 173 174 if(partyTypeName.equals(PartyTypes.COMPANY.name())) { 175 if(!party.equals(item.getLastDetail().getCompanyParty())) { 176 addExecutionError(ExecutionErrors.InvalidCompany.name()); 177 } 178 } 179 180 if(!hasExecutionErrors()) { 181 var inventoryControl = Session.getModelController(InventoryControl.class); 182 String inventoryConditionName = spec.getInventoryConditionName(); 183 InventoryCondition inventoryCondition = inventoryControl.getInventoryConditionByName(inventoryConditionName); 184 185 if(inventoryCondition != null) { 186 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 187 partyInventoryLevel = inventoryControl.getPartyInventoryLevel(party, item, inventoryCondition); 188 } else { // EditMode.UPDATE 189 partyInventoryLevel = inventoryControl.getPartyInventoryLevelForUpdate(party, item, inventoryCondition); 190 } 191 192 if(partyInventoryLevel == null) { 193 addExecutionError(ExecutionErrors.UnknownPartyInventoryLevel.name(), party.getLastDetail().getPartyName(), itemName, inventoryConditionName); 194 } 195 } else { 196 addExecutionError(ExecutionErrors.UnknownInventoryConditionName.name(), inventoryConditionName); 197 } 198 } 199 } else { 200 addExecutionError(ExecutionErrors.UnknownItemName.name(), itemName); 201 } 202 } 203 204 return partyInventoryLevel; 205 } 206 207 @Override 208 public Item getLockEntity(PartyInventoryLevel partyInventoryLevel) { 209 return partyInventoryLevel.getItem(); 210 } 211 212 @Override 213 public void fillInResult(EditPartyInventoryLevelResult result, PartyInventoryLevel partyInventoryLevel) { 214 var inventoryControl = Session.getModelController(InventoryControl.class); 215 216 result.setPartyInventoryLevel(inventoryControl.getPartyInventoryLevelTransfer(getUserVisit(), partyInventoryLevel)); 217 } 218 219 @Override 220 public void doLock(PartyInventoryLevelEdit edit, PartyInventoryLevel partyInventoryLevel) { 221 var uomControl = Session.getModelController(UomControl.class); 222 223 minimumInventory = partyInventoryLevel.getMinimumInventory(); 224 Conversion minimumInventoryConversion = minimumInventory == null ? null : new Conversion(uomControl, unitOfMeasureKind, minimumInventory).convertToHighestUnitOfMeasureType(); 225 226 maximumInventory = partyInventoryLevel.getMaximumInventory(); 227 Conversion maximumInventoryConversion = maximumInventory == null ? null : new Conversion(uomControl, unitOfMeasureKind, maximumInventory).convertToHighestUnitOfMeasureType(); 228 229 reorderQuantity = partyInventoryLevel.getReorderQuantity(); 230 Conversion reorderQuantityConversion = reorderQuantity == null ? null : new Conversion(uomControl, unitOfMeasureKind, reorderQuantity).convertToHighestUnitOfMeasureType(); 231 232 edit.setMinimumInventory(minimumInventoryConversion.getQuantity().toString()); 233 edit.setMinimumInventoryUnitOfMeasureTypeName(minimumInventoryConversion.getUnitOfMeasureType().getLastDetail().getUnitOfMeasureTypeName()); 234 edit.setMaximumInventory(maximumInventoryConversion.getQuantity().toString()); 235 edit.setMaximumInventoryUnitOfMeasureTypeName(maximumInventoryConversion.getUnitOfMeasureType().getLastDetail().getUnitOfMeasureTypeName()); 236 edit.setReorderQuantity(reorderQuantityConversion.getQuantity().toString()); 237 edit.setReorderQuantityUnitOfMeasureTypeName(reorderQuantityConversion.getUnitOfMeasureType().getLastDetail().getUnitOfMeasureTypeName()); 238 } 239 240 Long minimumInventory; 241 Long maximumInventory; 242 Long reorderQuantity; 243 244 @Override 245 public void canUpdate(PartyInventoryLevel partyInventoryLevel) { 246 UnitOfMeasureTypeLogic unitOfMeasureTypeLogic = UnitOfMeasureTypeLogic.getInstance(); 247 248 minimumInventory = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, unitOfMeasureKind, 249 edit.getMinimumInventory(), edit.getMinimumInventoryUnitOfMeasureTypeName(), 250 null, ExecutionErrors.MissingRequiredMinimumInventory.name(), null, ExecutionErrors.MissingRequiredMinimumInventoryUnitOfMeasureTypeName.name(), 251 null, ExecutionErrors.UnknownMinimumInventoryUnitOfMeasureTypeName.name()); 252 253 if(!hasExecutionErrors()) { 254 maximumInventory = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, unitOfMeasureKind, 255 edit.getMaximumInventory(), edit.getMaximumInventoryUnitOfMeasureTypeName(), 256 null, ExecutionErrors.MissingRequiredMaximumInventory.name(), null, ExecutionErrors.MissingRequiredMaximumInventoryUnitOfMeasureTypeName.name(), 257 null, ExecutionErrors.UnknownMaximumInventoryUnitOfMeasureTypeName.name()); 258 259 if(!hasExecutionErrors()) { 260 reorderQuantity = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, unitOfMeasureKind, 261 edit.getReorderQuantity(), edit.getReorderQuantityUnitOfMeasureTypeName(), 262 null, ExecutionErrors.MissingRequiredReorderQuantity.name(), null, ExecutionErrors.MissingRequiredReorderQuantityUnitOfMeasureTypeName.name(), 263 null, ExecutionErrors.UnknownReorderQuantityUnitOfMeasureTypeName.name()); 264 } 265 } 266 } 267 268 @Override 269 public void doUpdate(PartyInventoryLevel partyInventoryLevel) { 270 var inventoryControl = Session.getModelController(InventoryControl.class); 271 PartyInventoryLevelValue partyInventoryLevelValue = inventoryControl.getPartyInventoryLevelValue(partyInventoryLevel); 272 273 partyInventoryLevelValue.setMinimumInventory(minimumInventory); 274 partyInventoryLevelValue.setMaximumInventory(maximumInventory); 275 partyInventoryLevelValue.setReorderQuantity(reorderQuantity); 276 277 inventoryControl.updatePartyInventoryLevelFromValue(partyInventoryLevelValue, getPartyPK()); 278 } 279 280}