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.batch.server.logic;
018
019import com.echothree.model.control.batch.common.exception.MissingDefaultWorkflowEntranceException;
020import com.echothree.model.control.batch.common.exception.UnknownBatchAliasTypeNameException;
021import com.echothree.model.control.batch.common.exception.UnknownBatchNameException;
022import com.echothree.model.control.batch.common.exception.UnknownBatchSequenceException;
023import com.echothree.model.control.batch.common.exception.UnknownBatchSequenceTypeException;
024import com.echothree.model.control.batch.common.exception.UnknownBatchTypeEntityTypeException;
025import com.echothree.model.control.batch.common.exception.UnknownBatchTypeNameException;
026import com.echothree.model.control.batch.server.control.BatchControl;
027import com.echothree.model.control.core.server.control.EntityInstanceControl;
028import com.echothree.model.control.sequence.server.control.SequenceControl;
029import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
030import com.echothree.model.control.workflow.server.control.WorkflowControl;
031import com.echothree.model.data.batch.server.entity.Batch;
032import com.echothree.model.data.batch.server.entity.BatchAliasType;
033import com.echothree.model.data.batch.server.entity.BatchEntity;
034import com.echothree.model.data.batch.server.entity.BatchType;
035import com.echothree.model.data.core.server.entity.EntityInstance;
036import com.echothree.model.data.sequence.server.entity.Sequence;
037import com.echothree.model.data.sequence.server.entity.SequenceType;
038import com.echothree.util.common.message.ExecutionErrors;
039import com.echothree.util.common.persistence.BasePK;
040import com.echothree.util.server.control.BaseLogic;
041import com.echothree.util.server.message.ExecutionErrorAccumulator;
042import com.echothree.util.server.persistence.BaseEntity;
043import javax.enterprise.context.ApplicationScoped;
044import javax.enterprise.inject.spi.CDI;
045import javax.inject.Inject;
046
047@ApplicationScoped
048public class BatchLogic
049        extends BaseLogic {
050
051    protected BatchLogic() {
052        super();
053    }
054
055    public static BatchLogic getInstance() {
056        return CDI.current().select(BatchLogic.class).get();
057    }
058
059    @Inject
060    BatchControl batchControl;
061
062    @Inject
063    EntityInstanceControl entityInstanceControl;
064
065    @Inject
066    SequenceControl sequenceControl;
067
068    @Inject
069    WorkflowControl workflowControl;
070
071    @Inject
072    SequenceGeneratorLogic sequenceGeneratorLogic;
073    
074    public SequenceType getBatchSequenceType(final ExecutionErrorAccumulator eea, final BatchType batchType) {
075        SequenceType sequenceType;
076        var parentBatchType = batchType;
077
078        do {
079            var batchTypeDetail = parentBatchType.getLastDetail();
080
081            sequenceType = batchTypeDetail.getBatchSequenceType();
082
083            if(sequenceType == null) {
084                parentBatchType = batchTypeDetail.getParentBatchType();
085            } else {
086                break;
087            }
088        } while(parentBatchType != null);
089
090        if(sequenceType == null) {
091            sequenceType = sequenceControl.getDefaultSequenceType();
092        }
093
094        if(sequenceType == null) {
095            handleExecutionError(UnknownBatchSequenceTypeException.class, eea, ExecutionErrors.UnknownBatchSequenceType.name(),
096                    batchType.getLastDetail().getBatchTypeName());
097        }
098
099        return sequenceType;
100    }
101
102    public Sequence getBatchSequence(final ExecutionErrorAccumulator eea, final BatchType batchType) {
103        Sequence sequence = null;
104        var sequenceType = getBatchSequenceType(eea, batchType);
105
106        if(eea == null || !eea.hasExecutionErrors()) {
107            sequence = sequenceControl.getDefaultSequence(sequenceType);
108        }
109
110        if(sequence == null) {
111            handleExecutionError(UnknownBatchSequenceException.class, eea, ExecutionErrors.UnknownBatchSequence.name(),
112                    batchType.getLastDetail().getBatchTypeName());
113        }
114
115        return sequence;
116    }
117
118    public String getBatchName(final ExecutionErrorAccumulator eea, final BatchType batchType) {
119        String batchName = null;
120        var sequence = getBatchSequence(eea, batchType);
121
122        if(eea == null || !eea.hasExecutionErrors()) {
123            batchName = sequenceGeneratorLogic.getNextSequenceValue(sequence);
124        }
125
126        return batchName;
127    }
128
129    public Batch createBatch(final ExecutionErrorAccumulator eea, final String batchTypeName, final BasePK createdBy) {
130        var batchType = batchControl.getBatchTypeByName(batchTypeName);
131        Batch batch = null;
132
133        if(batchType != null) {
134            var batchName = getBatchName(eea, batchType);
135
136            if(eea == null || !eea.hasExecutionErrors()) {
137                var batchTypeDetail = batchType.getLastDetail();
138                var workflowEntrance = batchTypeDetail.getBatchWorkflowEntrance();
139
140                if(workflowEntrance == null) {
141                    var workflow = batchTypeDetail.getBatchWorkflow();
142
143                    if(workflow != null) {
144                        workflowEntrance = workflowControl.getDefaultWorkflowEntrance(workflow);
145
146                        if(workflowEntrance == null) {
147                            handleExecutionError(MissingDefaultWorkflowEntranceException.class, eea, ExecutionErrors.MissingDefaultWorkflowEntrance.name(),
148                                    workflow.getLastDetail().getWorkflowName());
149                        }
150                    }
151                }
152
153                if(eea == null || !eea.hasExecutionErrors()) {
154                    batch = batchControl.createBatch(batchType, batchName, createdBy);
155
156                    if(workflowEntrance != null) {
157                        var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(batch.getPrimaryKey());
158
159                        // TODO: A WorkEffort should be created for the batch entry, if it's manually entered.
160                        workflowControl.addEntityToWorkflow(workflowEntrance, entityInstance, null, null, createdBy);
161                    }
162                }
163            }
164        } else {
165            handleExecutionError(UnknownBatchTypeNameException.class, eea, ExecutionErrors.UnknownBatchTypeName.name(), batchTypeName);
166        }
167
168        return batch;
169    }
170
171    public void deleteBatch(final ExecutionErrorAccumulator eea, final Batch batch, final BasePK deletedBy) {
172        batchControl.deleteBatch(batch, deletedBy);
173    }
174
175    public BatchType getBatchTypeByName(final ExecutionErrorAccumulator eea, final String batchTypeName) {
176        var batchType = batchControl.getBatchTypeByName(batchTypeName);
177
178        if(batchType == null) {
179            handleExecutionError(UnknownBatchTypeNameException.class, eea, ExecutionErrors.UnknownBatchTypeName.name(), batchTypeName);
180        }
181
182        return batchType;
183    }
184
185    public BatchAliasType getBatchAliasTypeByName(final ExecutionErrorAccumulator eea, final BatchType batchType, final String batchAliasTypeName) {
186        var batchAliasType = batchControl.getBatchAliasTypeByName(batchType, batchAliasTypeName);
187
188        if(batchAliasType == null) {
189            handleExecutionError(UnknownBatchAliasTypeNameException.class, eea, ExecutionErrors.UnknownBatchAliasTypeName.name(),
190                    batchType.getLastDetail().getBatchTypeName(), batchAliasTypeName);
191        }
192
193        return batchAliasType;
194    }
195
196    public Batch getBatchByName(final ExecutionErrorAccumulator eea, final BatchType batchType, final String batchName) {
197        var batch = batchControl.getBatchByName(batchType, batchName);
198
199        if(batch == null) {
200            handleExecutionError(UnknownBatchNameException.class, eea, ExecutionErrors.UnknownBatchName.name(),
201                    batchType.getLastDetail().getBatchTypeName(), batchName);
202        }
203
204        return batch;
205    }
206
207    public Batch getBatchByName(final ExecutionErrorAccumulator eea, final String batchTypeName, final String batchName) {
208        var batchType = getBatchTypeByName(eea, batchTypeName);
209        Batch batch = null;
210
211        if(eea == null || !eea.hasExecutionErrors()) {
212            batch = getBatchByName(eea, batchType, batchName);
213        }
214
215        return batch;
216    }
217
218    public Batch getBatchByNameForUpdate(final ExecutionErrorAccumulator eea, final String batchTypeName, final String batchName) {
219        var batchType = getBatchTypeByName(eea, batchTypeName);
220        Batch batch = null;
221
222        if(eea == null || !eea.hasExecutionErrors()) {
223            batch = batchControl.getBatchByNameForUpdate(batchType, batchName);
224
225            if(batch == null) {
226                handleExecutionError(UnknownBatchNameException.class, eea, ExecutionErrors.UnknownBatchName.name(),
227                        batchType.getLastDetail().getBatchTypeName(), batchName);
228            }
229        }
230
231        return batch;
232    }
233
234    public BatchEntity createBatchEntity(final ExecutionErrorAccumulator eea, final BaseEntity baseEntity, final Batch batch, final BasePK createdBy) {
235        return createBatchEntity(eea, getEntityInstanceByBaseEntity(baseEntity), batch, createdBy);
236    }
237    
238    public BatchEntity createBatchEntity(final ExecutionErrorAccumulator eea, final EntityInstance entityInstance, final Batch batch, final BasePK createdBy) {
239        var batchType = batch.getLastDetail().getBatchType();
240        BatchEntity batchEntity = null;
241
242        if(batchControl.countBatchTypeEntityTypesByBatchType(batchType) != 0) {
243            var entityType = entityInstance.getEntityType();
244
245            if(!batchControl.getBatchTypeEntityTypeExists(batchType, entityType)) {
246                var entityTypeDetail = entityType.getLastDetail();
247
248                handleExecutionError(UnknownBatchTypeEntityTypeException.class, eea, ExecutionErrors.UnknownBatchTypeEntityType.name(),
249                        batchType.getLastDetail().getBatchTypeName(), entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
250                        entityTypeDetail.getEntityTypeName());
251            }
252        }
253
254        if(!hasExecutionErrors(eea)) {
255            batchEntity = batchControl.createBatchEntity(entityInstance, batch, createdBy);
256        }
257
258        return batchEntity;
259    }
260
261    public boolean batchEntityExists(final BaseEntity baseEntity, final Batch batch) {
262        return batchEntityExists(getEntityInstanceByBaseEntity(baseEntity), batch);
263    }
264    
265    public boolean batchEntityExists(final EntityInstance entityInstance, final Batch batch) {
266        return batchControl.batchEntityExists(entityInstance, batch);
267    }
268    
269    public void deleteBatchEntity(BatchEntity batchEntity, BasePK deletedBy) {
270        batchControl.deleteBatchEntity(batchEntity, deletedBy);
271    }
272
273}