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.InventoryTransactionLineUniversalSpec;
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.DuplicateInventoryTransactionLineSequenceException;
025import com.echothree.model.control.inventory.common.exception.InvalidInventoryTransactionTypeException;
026import com.echothree.model.control.inventory.common.exception.UnknownInventoryTransactionLineSequenceException;
027import com.echothree.model.control.inventory.server.control.InventoryTransactionLineControl;
028import com.echothree.model.data.inventory.server.entity.InventoryAdjustmentType;
029import com.echothree.model.data.inventory.server.entity.InventoryCondition;
030import com.echothree.model.data.inventory.server.entity.InventoryTransaction;
031import com.echothree.model.data.inventory.server.entity.InventoryTransactionLine;
032import com.echothree.model.data.inventory.server.entity.InventoryTransactionLineDestination;
033import com.echothree.model.data.inventory.server.entity.InventoryTransactionLineSource;
034import com.echothree.model.data.inventory.server.entity.InventoryTransactionReason;
035import com.echothree.model.data.inventory.server.entity.Lot;
036import com.echothree.model.data.inventory.server.value.InventoryTransactionLineDetailValue;
037import com.echothree.model.data.inventory.server.value.InventoryTransactionLineDestinationValue;
038import com.echothree.model.data.inventory.server.value.InventoryTransactionLineSourceValue;
039import com.echothree.model.data.item.server.entity.Item;
040import com.echothree.model.data.party.server.entity.Party;
041import com.echothree.model.data.uom.server.entity.UnitOfMeasureType;
042import com.echothree.model.data.warehouse.server.entity.Location;
043import com.echothree.util.common.message.ExecutionErrors;
044import com.echothree.util.common.persistence.BasePK;
045import com.echothree.util.server.control.BaseLogic;
046import com.echothree.util.server.message.ExecutionErrorAccumulator;
047import com.echothree.util.server.persistence.EntityPermission;
048import javax.enterprise.context.ApplicationScoped;
049import javax.inject.Inject;
050
051@ApplicationScoped
052public class InventoryTransactionLineLogic
053        extends BaseLogic {
054
055    @Inject
056    InventoryTransactionLineControl inventoryTransactionLineControl;
057
058    @Inject
059    EntityInstanceLogic entityInstanceLogic;
060
061    @Inject
062    InventoryTransactionLogic inventoryTransactionLogic;
063
064    @Inject
065    InventoryTransactionTypeLogic inventoryTransactionTypeLogic;
066
067    /** Creates a new instance of InventoryTransactionLineLogic */
068    protected InventoryTransactionLineLogic() {
069        super();
070    }
071
072    // --------------------------------------------------------------------------------
073    //   Inventory Transaction Lines
074    // --------------------------------------------------------------------------------
075
076    public InventoryTransactionLine createInventoryTransactionLine(final ExecutionErrorAccumulator eea,
077            final String inventoryTransactionTypeName, final String inventoryTransactionName,
078            final InventoryTransactionReason inventoryTransactionReason, final Item item, final Lot lot,
079            final InventoryAdjustmentType inventoryAdjustmentType, final Long unitAmount, final String description, final BasePK createdBy) {
080        return createInventoryTransactionLine(eea, inventoryTransactionTypeName, inventoryTransactionName, null,
081                inventoryTransactionReason, item, lot, inventoryAdjustmentType, unitAmount, description, createdBy);
082    }
083
084    public InventoryTransactionLine createInventoryTransactionLine(final ExecutionErrorAccumulator eea,
085            final String inventoryTransactionTypeName, final String inventoryTransactionName, final Integer inventoryTransactionLineSequence,
086            final InventoryTransactionReason inventoryTransactionReason, final Item item, final Lot lot,
087            final InventoryAdjustmentType inventoryAdjustmentType, final Long unitAmount, final String description, final BasePK createdBy) {
088        var inventoryTransaction = inventoryTransactionLogic.getInventoryTransactionByName(eea, inventoryTransactionTypeName, inventoryTransactionName);
089        InventoryTransactionLine inventoryTransactionLine = null;
090
091        if(eea == null || !eea.hasExecutionErrors()) {
092            inventoryTransactionLine = createInventoryTransactionLine(eea, inventoryTransaction, inventoryTransactionLineSequence,
093                    inventoryTransactionReason, item, lot, inventoryAdjustmentType, unitAmount, description, createdBy);
094        }
095
096        return inventoryTransactionLine;
097    }
098
099    public InventoryTransactionLine createInventoryTransactionLine(final ExecutionErrorAccumulator eea,
100            final InventoryTransaction inventoryTransaction, final Integer inventoryTransactionLineSequence,
101            final InventoryTransactionReason inventoryTransactionReason, final Item item, final Lot lot,
102            final InventoryAdjustmentType inventoryAdjustmentType, final Long unitAmount, final String description, final BasePK createdBy) {
103        var inventoryTransactionLine = inventoryTransactionLineSequence == null ? null
104                : inventoryTransactionLineControl.getInventoryTransactionLineBySequence(inventoryTransaction, inventoryTransactionLineSequence);
105
106        if(inventoryTransactionLine == null) {
107            inventoryTransactionLine = inventoryTransactionLineControl.createInventoryTransactionLine(inventoryTransaction,
108                    inventoryTransactionLineSequence, inventoryTransactionReason, item, lot, inventoryAdjustmentType, unitAmount, description, createdBy);
109        } else {
110            handleExecutionError(DuplicateInventoryTransactionLineSequenceException.class, eea,
111                    ExecutionErrors.DuplicateInventoryTransactionLineSequence.name(),
112                    inventoryTransaction.getLastDetail().getInventoryTransactionType().getLastDetail().getInventoryTransactionTypeName(),
113                    inventoryTransaction.getLastDetail().getInventoryTransactionName(), inventoryTransactionLineSequence);
114        }
115
116        return inventoryTransactionLine;
117    }
118
119    public InventoryTransactionLine getInventoryTransactionLineBySequence(final ExecutionErrorAccumulator eea,
120            final InventoryTransaction inventoryTransaction, final Integer inventoryTransactionLineSequence, final EntityPermission entityPermission) {
121        var inventoryTransactionLine = inventoryTransactionLineControl.getInventoryTransactionLineBySequence(inventoryTransaction,
122                inventoryTransactionLineSequence, entityPermission);
123
124        if(inventoryTransactionLine == null) {
125            handleExecutionError(UnknownInventoryTransactionLineSequenceException.class, eea,
126                    ExecutionErrors.UnknownInventoryTransactionLineSequence.name(),
127                    inventoryTransaction.getLastDetail().getInventoryTransactionType().getLastDetail().getInventoryTransactionTypeName(),
128                    inventoryTransaction.getLastDetail().getInventoryTransactionName(), inventoryTransactionLineSequence);
129        }
130
131        return inventoryTransactionLine;
132    }
133
134    public InventoryTransactionLine getInventoryTransactionLineBySequence(final ExecutionErrorAccumulator eea,
135            final InventoryTransaction inventoryTransaction, final Integer inventoryTransactionLineSequence) {
136        return getInventoryTransactionLineBySequence(eea, inventoryTransaction, inventoryTransactionLineSequence, EntityPermission.READ_ONLY);
137    }
138
139    public InventoryTransactionLine getInventoryTransactionLineBySequenceForUpdate(final ExecutionErrorAccumulator eea,
140            final InventoryTransaction inventoryTransaction, final Integer inventoryTransactionLineSequence) {
141        return getInventoryTransactionLineBySequence(eea, inventoryTransaction, inventoryTransactionLineSequence, EntityPermission.READ_WRITE);
142    }
143
144    public InventoryTransactionLine getInventoryTransactionLineBySequence(final ExecutionErrorAccumulator eea,
145            final String inventoryTransactionTypeName, final String inventoryTransactionName, final Integer inventoryTransactionLineSequence,
146            final EntityPermission entityPermission) {
147        var inventoryTransaction = inventoryTransactionLogic.getInventoryTransactionByName(eea, inventoryTransactionTypeName, inventoryTransactionName);
148        InventoryTransactionLine inventoryTransactionLine = null;
149
150        if(eea == null || !eea.hasExecutionErrors()) {
151            inventoryTransactionLine = getInventoryTransactionLineBySequence(eea, inventoryTransaction, inventoryTransactionLineSequence, entityPermission);
152        }
153
154        return inventoryTransactionLine;
155    }
156
157    public InventoryTransactionLine getInventoryTransactionLineBySequence(final ExecutionErrorAccumulator eea,
158            final String inventoryTransactionTypeName, final String inventoryTransactionName, final Integer inventoryTransactionLineSequence) {
159        return getInventoryTransactionLineBySequence(eea, inventoryTransactionTypeName, inventoryTransactionName,
160                inventoryTransactionLineSequence, EntityPermission.READ_ONLY);
161    }
162
163    public InventoryTransactionLine getInventoryTransactionLineBySequenceForUpdate(final ExecutionErrorAccumulator eea,
164            final String inventoryTransactionTypeName, final String inventoryTransactionName, final Integer inventoryTransactionLineSequence) {
165        return getInventoryTransactionLineBySequence(eea, inventoryTransactionTypeName, inventoryTransactionName,
166                inventoryTransactionLineSequence, EntityPermission.READ_WRITE);
167    }
168
169    public InventoryTransactionLine getInventoryTransactionLineByUniversalSpec(final ExecutionErrorAccumulator eea,
170            final InventoryTransactionLineUniversalSpec universalSpec, final String inventoryTransactionTypeName,
171            final EntityPermission entityPermission) {
172        var inventoryTransactionType = inventoryTransactionTypeLogic.getInventoryTransactionTypeByName(eea, inventoryTransactionTypeName);
173        InventoryTransactionLine inventoryTransactionLine = null;
174
175        if(eea == null || !eea.hasExecutionErrors()) {
176            var inventoryTransactionName = universalSpec.getInventoryTransactionName();
177            var inventoryTransactionLineSequence = universalSpec.getInventoryTransactionLineSequence();
178            var possibleEntitySpecs = entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
179
180            if(inventoryTransactionName != null && inventoryTransactionLineSequence != null && possibleEntitySpecs == 0) {
181                var inventoryTransaction = inventoryTransactionLogic.getInventoryTransactionByName(eea, inventoryTransactionType, inventoryTransactionName);
182
183                if(eea == null || !eea.hasExecutionErrors()) {
184                    inventoryTransactionLine = getInventoryTransactionLineBySequence(eea, inventoryTransaction,
185                            Integer.valueOf(inventoryTransactionLineSequence), entityPermission);
186                }
187            } else if(inventoryTransactionName == null && inventoryTransactionLineSequence == null && possibleEntitySpecs == 1) {
188                var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
189                        ComponentVendors.ECHO_THREE.name(), EntityTypes.InventoryTransactionLine.name());
190
191                if(eea == null || !eea.hasExecutionErrors()) {
192                    inventoryTransactionLine = inventoryTransactionLineControl.getInventoryTransactionLineByEntityInstance(entityInstance, entityPermission);
193                }
194            } else {
195                handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
196            }
197
198            if((eea == null || !eea.hasExecutionErrors()) && inventoryTransactionLine != null) {
199                var foundInventoryTransactionType = inventoryTransactionLine.getLastDetail().getInventoryTransaction().getLastDetail().getInventoryTransactionType();
200
201                if(!foundInventoryTransactionType.equals(inventoryTransactionType)) {
202                    handleExecutionError(InvalidInventoryTransactionTypeException.class, eea, ExecutionErrors.InvalidInventoryTransactionType.name(),
203                            foundInventoryTransactionType.getLastDetail().getInventoryTransactionTypeName());
204                }
205            }
206        }
207
208        return inventoryTransactionLine;
209    }
210
211    public InventoryTransactionLine getInventoryTransactionLineByUniversalSpec(final ExecutionErrorAccumulator eea,
212            final InventoryTransactionLineUniversalSpec universalSpec, final String inventoryTransactionTypeName) {
213        return getInventoryTransactionLineByUniversalSpec(eea, universalSpec, inventoryTransactionTypeName, EntityPermission.READ_ONLY);
214    }
215
216    public InventoryTransactionLine getInventoryTransactionLineByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea,
217            final InventoryTransactionLineUniversalSpec universalSpec, final String inventoryTransactionTypeName) {
218        return getInventoryTransactionLineByUniversalSpec(eea, universalSpec, inventoryTransactionTypeName, EntityPermission.READ_WRITE);
219    }
220
221    public void updateInventoryTransactionLineFromValue(final InventoryTransactionLineDetailValue inventoryTransactionLineDetailValue,
222            final BasePK updatedBy) {
223        inventoryTransactionLineControl.updateInventoryTransactionLineFromValue(inventoryTransactionLineDetailValue, updatedBy);
224    }
225
226    public void deleteInventoryTransactionLine(final ExecutionErrorAccumulator eea, final InventoryTransactionLine inventoryTransactionLine,
227            final BasePK deletedBy) {
228        inventoryTransactionLineControl.deleteInventoryTransactionLine(inventoryTransactionLine, deletedBy);
229    }
230
231    // --------------------------------------------------------------------------------
232    //   Inventory Transaction Line Sources
233    // --------------------------------------------------------------------------------
234
235    public InventoryTransactionLineSource createInventoryTransactionLineSource(final InventoryTransactionLine inventoryTransactionLine,
236            final Party sourceOwnerParty, final Location sourceLocation, final InventoryCondition sourceInventoryCondition,
237            final UnitOfMeasureType sourceUnitOfMeasureType, final BasePK createdBy) {
238        return inventoryTransactionLineControl.createInventoryTransactionLineSource(inventoryTransactionLine, sourceOwnerParty,
239                sourceLocation, sourceInventoryCondition, sourceUnitOfMeasureType, createdBy);
240    }
241
242    public void updateInventoryTransactionLineSourceFromValue(final InventoryTransactionLineSourceValue inventoryTransactionLineSourceValue,
243            final BasePK updatedBy) {
244        inventoryTransactionLineControl.updateInventoryTransactionLineSourceFromValue(inventoryTransactionLineSourceValue, updatedBy);
245    }
246
247    // --------------------------------------------------------------------------------
248    //   Inventory Transaction Line Destinations
249    // --------------------------------------------------------------------------------
250
251    public InventoryTransactionLineDestination createInventoryTransactionLineDestination(final InventoryTransactionLine inventoryTransactionLine,
252            final Party destinationOwnerParty, final Location destinationLocation, final InventoryCondition destinationInventoryCondition,
253            final UnitOfMeasureType destinationUnitOfMeasureType, final BasePK createdBy) {
254        return inventoryTransactionLineControl.createInventoryTransactionLineDestination(inventoryTransactionLine, destinationOwnerParty,
255                destinationLocation, destinationInventoryCondition, destinationUnitOfMeasureType, createdBy);
256    }
257
258    public void updateInventoryTransactionLineDestinationFromValue(final InventoryTransactionLineDestinationValue inventoryTransactionLineDestinationValue,
259            final BasePK updatedBy) {
260        inventoryTransactionLineControl.updateInventoryTransactionLineDestinationFromValue(inventoryTransactionLineDestinationValue, updatedBy);
261    }
262
263}