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.employee.server.logic;
018
019import com.echothree.model.control.core.server.control.CoreControl;
020import com.echothree.model.control.employee.common.exception.InvalidLeaveStatusException;
021import com.echothree.model.control.employee.common.exception.UnknownLeaveReasonNameException;
022import com.echothree.model.control.employee.common.exception.UnknownLeaveTypeNameException;
023import com.echothree.model.control.employee.server.control.EmployeeControl;
024import com.echothree.model.control.employee.common.workflow.LeaveStatusConstants;
025import com.echothree.model.control.workflow.server.control.WorkflowControl;
026import com.echothree.model.control.workflow.server.logic.WorkflowLogic;
027import com.echothree.model.data.core.server.entity.EntityInstance;
028import com.echothree.model.data.employee.server.entity.Leave;
029import com.echothree.model.data.employee.server.entity.LeaveReason;
030import com.echothree.model.data.employee.server.entity.LeaveType;
031import com.echothree.model.data.employee.server.value.LeaveDetailValue;
032import com.echothree.model.data.party.common.pk.PartyPK;
033import com.echothree.model.data.party.server.entity.Party;
034import com.echothree.model.data.workflow.server.entity.Workflow;
035import com.echothree.model.data.workflow.server.entity.WorkflowEntityStatus;
036import com.echothree.model.data.workflow.server.entity.WorkflowEntrance;
037import com.echothree.util.common.message.ExecutionErrors;
038import com.echothree.util.common.persistence.BasePK;
039import com.echothree.util.server.control.BaseLogic;
040import com.echothree.util.server.message.ExecutionErrorAccumulator;
041import com.echothree.util.server.persistence.Session;
042
043public class LeaveLogic
044        extends BaseLogic {
045    
046    private LeaveLogic() {
047        super();
048    }
049    
050    private static class LeaveLogicHolder {
051        static LeaveLogic instance = new LeaveLogic();
052    }
053    
054    public static LeaveLogic getInstance() {
055        return LeaveLogicHolder.instance;
056    }
057    
058    public LeaveType getLeaveTypeByName(final ExecutionErrorAccumulator eea, final String leaveTypeName) {
059        var employeeControl = Session.getModelController(EmployeeControl.class);
060        LeaveType leaveType = employeeControl.getLeaveTypeByName(leaveTypeName);
061
062        if(leaveType == null) {
063            handleExecutionError(UnknownLeaveTypeNameException.class, eea, ExecutionErrors.UnknownLeaveTypeName.name(), leaveTypeName);
064        }
065
066        return leaveType;
067    }
068    
069    public LeaveReason getLeaveReasonByName(final ExecutionErrorAccumulator eea, final String leaveReasonName) {
070        var employeeControl = Session.getModelController(EmployeeControl.class);
071        LeaveReason leaveReason = employeeControl.getLeaveReasonByName(leaveReasonName);
072
073        if(leaveReason == null) {
074            handleExecutionError(UnknownLeaveReasonNameException.class, eea, ExecutionErrors.UnknownLeaveReasonName.name(), leaveReasonName);
075        }
076
077        return leaveReason;
078    }
079    
080    private void insertLeaveIntoWorkflow(final EntityInstance entityInstance, final WorkflowEntrance leaveStatus, final PartyPK createdBy) {
081        var workflowControl = Session.getModelController(WorkflowControl.class);
082        
083        if(leaveStatus == null) {
084            workflowControl.addEntityToWorkflowUsingNames(null, LeaveStatusConstants.Workflow_LEAVE_STATUS, LeaveStatusConstants.WorkflowEntrance_NEW_SUBMITTED,
085                    entityInstance, null, null, createdBy);
086        } else {
087            workflowControl.addEntityToWorkflow(leaveStatus, entityInstance, null, null, createdBy);
088        }
089    }
090
091    public Leave createLeave(final Session session, final Party party, final Party companyParty, final LeaveType leaveType, final LeaveReason leaveReason,
092            final Long startTime, final Long endTime, final Long totalTime, final WorkflowEntrance leaveStatus, final PartyPK createdBy) {
093        var coreControl = Session.getModelController(CoreControl.class);
094        var employeeControl = Session.getModelController(EmployeeControl.class);
095
096        Leave leave = employeeControl.createLeave(party, companyParty, leaveType, leaveReason, startTime, endTime, totalTime, createdBy);
097        EntityInstance entityInstance = coreControl.getEntityInstanceByBasePK(leave.getPrimaryKey());
098
099        insertLeaveIntoWorkflow(entityInstance, leaveStatus, createdBy);
100
101        return leave;
102    }
103
104    public void updateLeaveFromValue(final ExecutionErrorAccumulator eea, final LeaveDetailValue leaveDetailValue, final PartyPK updatedBy) {
105        var workflowControl = Session.getModelController(WorkflowControl.class);
106        EntityInstance entityInstance = getEntityInstanceByBasePK(leaveDetailValue.getLeavePK());
107        WorkflowLogic workflowLogic = WorkflowLogic.getInstance();
108        Workflow workflow = workflowLogic.getWorkflowByName(null, LeaveStatusConstants.Workflow_LEAVE_STATUS);
109        WorkflowEntityStatus workflowEntityStatus = workflowControl.getWorkflowEntityStatusByEntityInstanceForUpdate(workflow, entityInstance);
110        String workflowStepName = workflowEntityStatus.getWorkflowStep().getLastDetail().getWorkflowStepName();
111        String workflowDestinationName = null;
112        
113        if(workflowStepName.equals(LeaveStatusConstants.WorkflowStep_APPROVED)) {
114            workflowDestinationName = LeaveStatusConstants.WorkflowDestination_APPROVED_TO_REVISED;
115        } else if(workflowStepName.equals(LeaveStatusConstants.WorkflowStep_DENIED)) {
116            workflowDestinationName = LeaveStatusConstants.WorkflowDestination_DENIED_TO_REVISED;
117        }
118        
119        if(workflowDestinationName == null && !workflowStepName.equals(LeaveStatusConstants.WorkflowStep_SUBMITTED)) {
120            handleExecutionError(InvalidLeaveStatusException.class, eea, ExecutionErrors.InvalidLeaveStatus.name(), leaveDetailValue.getLeaveName(), workflowStepName);
121        } else {
122            var employeeControl = Session.getModelController(EmployeeControl.class);
123            
124            if(workflowDestinationName != null) {
125                workflowControl.transitionEntityInWorkflowUsingNames(eea, workflowEntityStatus, workflowDestinationName, null, updatedBy);
126            }
127            
128            employeeControl.updateLeaveFromValue(leaveDetailValue, updatedBy);
129        }
130    }
131    
132    public void deleteLeave(Leave leave, final BasePK deleteBy) {
133        var employeeControl = Session.getModelController(EmployeeControl.class);
134        
135        employeeControl.deleteLeave(leave, deleteBy);
136    }
137    
138}