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.control.user.employee.server.command;
018
019import com.echothree.control.user.employee.common.form.CreateLeaveForm;
020import com.echothree.control.user.employee.common.result.EmployeeResultFactory;
021import com.echothree.model.control.employee.common.workflow.LeaveStatusConstants;
022import com.echothree.model.control.employee.server.control.EmployeeControl;
023import com.echothree.model.control.employee.server.logic.LeaveLogic;
024import com.echothree.model.control.party.common.PartyTypes;
025import com.echothree.model.control.party.server.control.PartyControl;
026import com.echothree.model.control.security.common.SecurityRoleGroups;
027import com.echothree.model.control.security.common.SecurityRoles;
028import com.echothree.model.control.uom.common.UomConstants;
029import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic;
030import com.echothree.model.control.workflow.server.control.WorkflowControl;
031import com.echothree.model.control.workflow.server.logic.WorkflowSecurityLogic;
032import com.echothree.model.data.employee.server.entity.Leave;
033import com.echothree.model.data.user.common.pk.UserVisitPK;
034import com.echothree.model.data.workflow.server.entity.WorkflowEntrance;
035import com.echothree.util.common.command.BaseResult;
036import com.echothree.util.common.message.ExecutionErrors;
037import com.echothree.util.common.validation.FieldDefinition;
038import com.echothree.util.common.validation.FieldType;
039import com.echothree.util.server.control.BaseSimpleCommand;
040import com.echothree.util.server.control.CommandSecurityDefinition;
041import com.echothree.util.server.control.PartyTypeDefinition;
042import com.echothree.util.server.control.SecurityRoleDefinition;
043import java.util.List;
044import javax.enterprise.context.Dependent;
045import javax.inject.Inject;
046
047@Dependent
048public class CreateLeaveCommand
049        extends BaseSimpleCommand<CreateLeaveForm> {
050    
051    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
052    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
053    
054    static {
055        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
056                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
057                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
058                        new SecurityRoleDefinition(SecurityRoleGroups.Leave.name(), SecurityRoles.Create.name())
059                ))
060        ));
061        
062        FORM_FIELD_DEFINITIONS = List.of(
063                new FieldDefinition("PartyName", FieldType.ENTITY_NAME, true, null, null),
064                new FieldDefinition("CompanyName", FieldType.ENTITY_NAME, true, null, null),
065                new FieldDefinition("LeaveTypeName", FieldType.ENTITY_NAME, true, null, null),
066                new FieldDefinition("LeaveReasonName", FieldType.ENTITY_NAME, true, null, null),
067                new FieldDefinition("StartTime", FieldType.DATE_TIME, true, null, null),
068                new FieldDefinition("EndTime", FieldType.DATE_TIME, false, null, null),
069                new FieldDefinition("TotalTime", FieldType.UNSIGNED_LONG, false, null, null),
070                new FieldDefinition("TotalTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
071                new FieldDefinition("LeaveStatus", FieldType.ENTITY_NAME, false, null, null)
072        );
073    }
074
075    @Inject
076    EmployeeControl employeeControl;
077
078    @Inject
079    PartyControl partyControl;
080
081    @Inject
082    WorkflowControl workflowControl;
083
084    @Inject
085    LeaveLogic leaveLogic;
086
087    @Inject
088    UnitOfMeasureTypeLogic unitOfMeasureTypeLogic;
089
090    @Inject
091    WorkflowSecurityLogic workflowSecurityLogic;
092
093    
094    /** Creates a new instance of CreateLeaveCommand */
095    public CreateLeaveCommand() {
096        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
097    }
098    
099    @Override
100    protected BaseResult execute() {
101        var result = EmployeeResultFactory.getCreateLeaveResult();
102        Leave leave = null;
103        var partyName = form.getPartyName();
104        var party = partyControl.getPartyByName(partyName);
105
106        if(party != null) {
107            var companyName = form.getCompanyName();
108            var partyCompany = partyControl.getPartyCompanyByName(companyName);
109
110            if(partyCompany != null) {
111                var leaveTypeName = form.getLeaveTypeName();
112                var leaveType = employeeControl.getLeaveTypeByName(leaveTypeName);
113
114                if(leaveTypeName == null || leaveType != null) {
115                    var leaveReasonName = form.getLeaveReasonName();
116                    var leaveReason = employeeControl.getLeaveReasonByName(leaveReasonName);
117
118                    if(leaveReasonName == null || leaveReason != null) {
119                        var totalTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
120                                form.getTotalTime(), form.getTotalTimeUnitOfMeasureTypeName(),
121                                null, ExecutionErrors.MissingRequiredTotalTime.name(), null, ExecutionErrors.MissingRequiredTotalTimeUnitOfMeasureTypeName.name(),
122                                null, ExecutionErrors.UnknownTotalTimeUnitOfMeasureTypeName.name());
123
124                        if(!hasExecutionErrors()) {
125                            var createdBy = getPartyPK();
126                            WorkflowEntrance leaveStatus = null;
127                            var leaveStatusChoice = form.getLeaveStatus();
128
129                            if(leaveStatusChoice != null) {
130                                leaveStatus = workflowControl.getWorkflowEntranceUsingNames(this, LeaveStatusConstants.Workflow_LEAVE_STATUS,
131                                        leaveStatusChoice);
132
133                                if(!hasExecutionErrors()) {
134                                    workflowSecurityLogic.checkAddEntityToWorkflow(this, leaveStatus, createdBy);
135                                }
136                            }
137
138                            if(!hasExecutionErrors()) {
139                                var startTime = Long.valueOf(form.getStartTime());
140                                var strEndTime = form.getEndTime();
141                                var endTime = strEndTime == null ? null : Long.valueOf(strEndTime);
142
143                                if(endTime == null || endTime > startTime) {
144                                    leave = leaveLogic.createLeave(session, party, partyCompany.getParty(), leaveType, leaveReason, startTime, endTime,
145                                            totalTime, leaveStatus, createdBy);
146                                } else {
147                                    addExecutionError(endTime.equals(startTime) ? ExecutionErrors.EndTimeEqualToStartTime.name() : ExecutionErrors.EndTimeBeforeStartTime.name());
148                                }
149                            }
150                        }
151                    } else {
152                        addExecutionError(ExecutionErrors.UnknownLeaveReasonName.name(), leaveReasonName);
153                    }
154                } else {
155                    addExecutionError(ExecutionErrors.UnknownLeaveTypeName.name(), leaveTypeName);
156                }
157            } else {
158                addExecutionError(ExecutionErrors.UnknownCompanyName.name(), companyName);
159            }
160        } else {
161            addExecutionError(ExecutionErrors.UnknownPartyName.name(), partyName);
162        }
163        
164        if(leave != null) {
165            result.setEntityRef(leave.getPrimaryKey().getEntityRef());
166            result.setLeaveName(leave.getLastDetail().getLeaveName());
167        }
168
169        return result;
170    }
171    
172}