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