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