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.model.control.inventory.server.logic;
018
019import com.echothree.control.user.inventory.common.spec.InventoryLayerUniversalSpec;
020import com.echothree.model.control.core.common.ComponentVendors;
021import com.echothree.model.control.core.common.EntityTypes;
022import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
023import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
024import com.echothree.model.control.inventory.common.exception.DuplicateInventoryLayerSequenceException;
025import com.echothree.model.control.inventory.common.exception.UnknownInventoryLayerSequenceException;
026import com.echothree.model.control.inventory.server.control.InventoryLayerControl;
027import com.echothree.model.control.party.server.control.PartyControl;
028import com.echothree.model.data.inventory.server.entity.InventoryCostingPool;
029import com.echothree.model.data.inventory.server.entity.InventoryLayer;
030import com.echothree.model.data.inventory.server.entity.InventoryTransactionLine;
031import com.echothree.model.data.inventory.server.value.InventoryLayerDetailValue;
032import com.echothree.util.common.message.ExecutionErrors;
033import com.echothree.util.common.persistence.BasePK;
034import com.echothree.util.server.control.BaseLogic;
035import com.echothree.util.server.message.ExecutionErrorAccumulator;
036import com.echothree.util.server.persistence.EntityPermission;
037import javax.enterprise.context.ApplicationScoped;
038import javax.inject.Inject;
039
040@ApplicationScoped
041public class InventoryLayerLogic
042        extends BaseLogic {
043
044    @Inject
045    InventoryLayerControl inventoryLayerControl;
046
047    @Inject
048    PartyControl partyControl;
049
050    @Inject
051    EntityInstanceLogic entityInstanceLogic;
052
053    @Inject
054    InventoryCostingPoolLogic inventoryCostingPoolLogic;
055
056    protected InventoryLayerLogic() {
057        super();
058    }
059
060    public InventoryLayer createInventoryLayer(final ExecutionErrorAccumulator eea, final InventoryCostingPool inventoryCostingPool,
061            final InventoryTransactionLine inventoryTransactionLine, final Long receiptQuantity, final Long unitCost,
062            final String description, final BasePK createdBy) {
063        return createInventoryLayer(eea, inventoryCostingPool, null, inventoryTransactionLine, receiptQuantity, unitCost, description, createdBy);
064    }
065
066    public InventoryLayer createInventoryLayer(final ExecutionErrorAccumulator eea, final InventoryCostingPool inventoryCostingPool,
067            final Integer inventoryLayerSequence, final InventoryTransactionLine inventoryTransactionLine, final Long receiptQuantity,
068            final Long unitCost, final String description, final BasePK createdBy) {
069        var inventoryLayer = inventoryLayerSequence == null ? null
070                : inventoryLayerControl.getInventoryLayerBySequence(inventoryCostingPool, inventoryLayerSequence);
071
072        if(inventoryLayer == null) {
073            inventoryLayer = inventoryLayerControl.createInventoryLayer(inventoryCostingPool, inventoryLayerSequence,
074                    inventoryTransactionLine, receiptQuantity, unitCost, description, createdBy);
075        } else {
076            var inventoryCostingPoolDetail = inventoryCostingPool.getLastDetail();
077
078            handleExecutionError(DuplicateInventoryLayerSequenceException.class, eea, ExecutionErrors.DuplicateInventoryLayerSequence.name(),
079                    partyControl.getPartyCompany(inventoryCostingPoolDetail.getCompanyParty()).getPartyCompanyName(),
080                    inventoryCostingPoolDetail.getItem().getLastDetail().getItemName(),
081                    inventoryCostingPoolDetail.getInventoryCondition().getLastDetail().getInventoryConditionName(), inventoryLayerSequence);
082        }
083
084        return inventoryLayer;
085    }
086
087    public InventoryLayer getInventoryLayerBySequence(final ExecutionErrorAccumulator eea, final InventoryCostingPool inventoryCostingPool,
088            final Integer inventoryLayerSequence, final EntityPermission entityPermission) {
089        var inventoryLayer = inventoryLayerControl.getInventoryLayerBySequence(inventoryCostingPool, inventoryLayerSequence, entityPermission);
090
091        if(inventoryLayer == null) {
092            var inventoryCostingPoolDetail = inventoryCostingPool.getLastDetail();
093
094            handleExecutionError(UnknownInventoryLayerSequenceException.class, eea, ExecutionErrors.UnknownInventoryLayerSequence.name(),
095                    partyControl.getPartyCompany(inventoryCostingPoolDetail.getCompanyParty()).getPartyCompanyName(),
096                    inventoryCostingPoolDetail.getItem().getLastDetail().getItemName(),
097                    inventoryCostingPoolDetail.getInventoryCondition().getLastDetail().getInventoryConditionName(), inventoryLayerSequence);
098        }
099
100        return inventoryLayer;
101    }
102
103    public InventoryLayer getInventoryLayerBySequence(final ExecutionErrorAccumulator eea, final InventoryCostingPool inventoryCostingPool,
104            final Integer inventoryLayerSequence) {
105        return getInventoryLayerBySequence(eea, inventoryCostingPool, inventoryLayerSequence, EntityPermission.READ_ONLY);
106    }
107
108    public InventoryLayer getInventoryLayerBySequenceForUpdate(final ExecutionErrorAccumulator eea, final InventoryCostingPool inventoryCostingPool,
109            final Integer inventoryLayerSequence) {
110        return getInventoryLayerBySequence(eea, inventoryCostingPool, inventoryLayerSequence, EntityPermission.READ_WRITE);
111    }
112
113    public InventoryLayer getInventoryLayerByName(final ExecutionErrorAccumulator eea, final String companyName, final String partyName,
114            final String itemName, final String inventoryConditionName, final Integer inventoryLayerSequence, final EntityPermission entityPermission) {
115        var inventoryCostingPool = inventoryCostingPoolLogic.getInventoryCostingPoolByName(eea, companyName, partyName, itemName, inventoryConditionName);
116        InventoryLayer inventoryLayer = null;
117
118        if(eea == null || !eea.hasExecutionErrors()) {
119            inventoryLayer = getInventoryLayerBySequence(eea, inventoryCostingPool, inventoryLayerSequence, entityPermission);
120        }
121
122        return inventoryLayer;
123    }
124
125    public InventoryLayer getInventoryLayerByName(final ExecutionErrorAccumulator eea, final String companyName, final String partyName,
126            final String itemName, final String inventoryConditionName, final Integer inventoryLayerSequence) {
127        return getInventoryLayerByName(eea, companyName, partyName, itemName, inventoryConditionName, inventoryLayerSequence, EntityPermission.READ_ONLY);
128    }
129
130    public InventoryLayer getInventoryLayerByUniversalSpec(final ExecutionErrorAccumulator eea,
131            final InventoryLayerUniversalSpec universalSpec, final EntityPermission entityPermission) {
132        var companyName = universalSpec.getCompanyName();
133        var partyName = universalSpec.getPartyName();
134        var itemName = universalSpec.getItemName();
135        var inventoryConditionName = universalSpec.getInventoryConditionName();
136        var inventoryLayerSequence = universalSpec.getInventoryLayerSequence();
137        var companyParameterCount = (companyName == null ? 0 : 1) + (partyName == null ? 0 : 1);
138        var hasNameParameters = companyParameterCount != 0 || itemName != null || inventoryConditionName != null || inventoryLayerSequence != null;
139        var hasCompleteName = companyParameterCount == 1 && itemName != null && inventoryConditionName != null
140                && inventoryLayerSequence != null;
141        var entitySpecCount = entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
142        InventoryLayer inventoryLayer = null;
143
144        if(hasCompleteName && entitySpecCount == 0) {
145            inventoryLayer = getInventoryLayerByName(eea, companyName, partyName, itemName, inventoryConditionName, Integer.valueOf(inventoryLayerSequence), entityPermission);
146        } else if(!hasNameParameters && entitySpecCount == 1) {
147            var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
148                    ComponentVendors.ECHO_THREE.name(), EntityTypes.InventoryLayer.name());
149
150            if(eea == null || !eea.hasExecutionErrors()) {
151                inventoryLayer = inventoryLayerControl.getInventoryLayerByEntityInstance(entityInstance, entityPermission);
152            }
153        } else {
154            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
155        }
156
157        return inventoryLayer;
158    }
159
160    public InventoryLayer getInventoryLayerByUniversalSpec(final ExecutionErrorAccumulator eea,
161            final InventoryLayerUniversalSpec universalSpec) {
162        return getInventoryLayerByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY);
163    }
164
165    public InventoryLayer getInventoryLayerByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea,
166            final InventoryLayerUniversalSpec universalSpec) {
167        return getInventoryLayerByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE);
168    }
169
170    public void updateInventoryLayerFromValue(final InventoryLayerDetailValue value, final BasePK updatedBy) {
171        inventoryLayerControl.updateInventoryLayerFromValue(value, updatedBy);
172    }
173
174    public void deleteInventoryLayer(final InventoryLayer inventoryLayer, final BasePK deletedBy) {
175        inventoryLayerControl.deleteInventoryLayer(inventoryLayer, deletedBy);
176    }
177
178}