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