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