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.search.server.command;
018
019import com.echothree.control.user.search.common.form.SearchEmployeesForm;
020import com.echothree.control.user.search.common.result.SearchResultFactory;
021import com.echothree.model.control.party.common.PartyTypes;
022import com.echothree.model.control.party.server.control.PartyControl;
023import com.echothree.model.control.search.common.SearchKinds;
024import com.echothree.model.control.search.server.control.SearchControl;
025import com.echothree.model.control.employee.server.search.EmployeeSearchEvaluator;
026import com.echothree.model.control.search.server.logic.SearchLogic;
027import com.echothree.model.control.employee.common.workflow.EmployeeAvailabilityConstants;
028import com.echothree.model.control.employee.common.workflow.EmployeeStatusConstants;
029import com.echothree.model.control.security.common.SecurityRoleGroups;
030import com.echothree.model.control.security.common.SecurityRoles;
031import com.echothree.model.control.workflow.server.control.WorkflowControl;
032import com.echothree.model.data.party.server.entity.PartyAliasType;
033import com.echothree.model.data.user.common.pk.UserVisitPK;
034import com.echothree.util.common.message.ExecutionErrors;
035import com.echothree.util.common.validation.FieldDefinition;
036import com.echothree.util.common.validation.FieldType;
037import com.echothree.util.common.command.BaseResult;
038import com.echothree.util.server.control.BaseSimpleCommand;
039import com.echothree.util.server.control.CommandSecurityDefinition;
040import com.echothree.util.server.control.PartyTypeDefinition;
041import com.echothree.util.server.control.SecurityRoleDefinition;
042import com.google.common.base.Splitter;
043import java.util.List;
044import javax.enterprise.context.Dependent;
045import javax.inject.Inject;
046
047@Dependent
048public class SearchEmployeesCommand
049        extends BaseSimpleCommand<SearchEmployeesForm> {
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.Employee.name(), SecurityRoles.Search.name())
059                ))
060        ));
061
062        FORM_FIELD_DEFINITIONS = List.of(
063                new FieldDefinition("SearchTypeName", FieldType.ENTITY_NAME, true, null, null),
064                new FieldDefinition("FirstName", FieldType.STRING, false, 1L, 20L),
065                new FieldDefinition("FirstNameSoundex", FieldType.BOOLEAN, false, null, null),
066                new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L),
067                new FieldDefinition("MiddleNameSoundex", FieldType.BOOLEAN, false, null, null),
068                new FieldDefinition("LastName", FieldType.STRING, false, 1L, 20L),
069                new FieldDefinition("LastNameSoundex", FieldType.BOOLEAN, false, null, null),
070                new FieldDefinition("EmployeeName", FieldType.ENTITY_NAME, false, null, null),
071                new FieldDefinition("PartyName", FieldType.ENTITY_NAME, false, null, null),
072                new FieldDefinition("PartyAliasTypeName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("Alias", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("EmployeeStatusChoice", FieldType.ENTITY_NAME, false, null, null),
075                new FieldDefinition("EmployeeAvailabilityChoice", FieldType.ENTITY_NAME, false, null, null),
076                new FieldDefinition("CreatedSince", FieldType.DATE_TIME, false, null, null),
077                new FieldDefinition("ModifiedSince", FieldType.DATE_TIME, false, null, null),
078                new FieldDefinition("Fields", FieldType.STRING, false, null, null)
079        );
080    }
081
082    @Inject
083    PartyControl partyControl;
084
085    @Inject
086    SearchControl searchControl;
087
088    @Inject
089    WorkflowControl workflowControl;
090
091    @Inject
092    SearchLogic searchLogic;
093
094    /** Creates a new instance of SearchEmployeesCommand */
095    public SearchEmployeesCommand() {
096        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
097    }
098    
099    @Override
100    protected BaseResult execute() {
101        var result = SearchResultFactory.getSearchEmployeesResult();
102        var employeeName = form.getEmployeeName();
103        var partyName = form.getPartyName();
104        var parameterCount = (employeeName == null ? 0 : 1) + (partyName == null ? 0 : 1);
105
106        if(parameterCount < 2) {
107            var searchKind = searchControl.getSearchKindByName(SearchKinds.EMPLOYEE.name());
108
109            if(searchKind != null) {
110                var searchTypeName = form.getSearchTypeName();
111                var searchType = searchControl.getSearchTypeByName(searchKind, searchTypeName);
112
113                if(searchType != null) {
114                    var partyAliasTypeName = form.getPartyAliasTypeName();
115                    var alias = form.getAlias();
116                    PartyAliasType partyAliasType = null;
117
118                    if(partyAliasTypeName != null) {
119                        var partyType = partyControl.getPartyTypeByName(PartyTypes.CUSTOMER.name());
120
121                        if(partyType != null) {
122                            partyAliasType = partyControl.getPartyAliasTypeByName(partyType, partyAliasTypeName);
123
124                            if(partyAliasType == null) {
125                                addExecutionError(ExecutionErrors.UnknownPartyAliasTypeName.name(), PartyTypes.CUSTOMER.name(), partyAliasTypeName);
126                            }
127                        } else {
128                            addExecutionError(ExecutionErrors.UnknownPartyTypeName.name(), PartyTypes.CUSTOMER.name());
129                        }
130                    }
131
132                    if(!hasExecutionErrors()) {
133                        var employeeStatusChoice = form.getEmployeeStatusChoice();
134                        var employeeStatusWorkflowStep = employeeStatusChoice == null ? null : workflowControl.getWorkflowStepByName(workflowControl.getWorkflowByName(EmployeeStatusConstants.Workflow_EMPLOYEE_STATUS), employeeStatusChoice);
135
136                        if(employeeStatusChoice == null || employeeStatusWorkflowStep != null) {
137                            var employeeAvailabilityChoice = form.getEmployeeAvailabilityChoice();
138                            var employeeAvailabilityWorkflowStep = employeeAvailabilityChoice == null ? null : workflowControl.getWorkflowStepByName(workflowControl.getWorkflowByName(EmployeeAvailabilityConstants.Workflow_EMPLOYEE_AVAILABILITY), employeeAvailabilityChoice);
139
140                            if(employeeAvailabilityChoice == null || employeeAvailabilityWorkflowStep != null) {
141                                var userVisit = getUserVisit();
142                                var employeeSearchEvaluator = new EmployeeSearchEvaluator(userVisit, searchType, searchLogic.getDefaultSearchDefaultOperator(null), searchLogic.getDefaultSearchSortOrder(null, searchKind), searchLogic.getDefaultSearchSortDirection(null));
143                                var createdSince = form.getCreatedSince();
144                                var modifiedSince = form.getModifiedSince();
145                                var fields = form.getFields();
146
147                                employeeSearchEvaluator.setFirstName(form.getFirstName());
148                                employeeSearchEvaluator.setFirstNameSoundex(Boolean.parseBoolean(form.getFirstNameSoundex()));
149                                employeeSearchEvaluator.setMiddleName(form.getMiddleName());
150                                employeeSearchEvaluator.setMiddleNameSoundex(Boolean.parseBoolean(form.getMiddleNameSoundex()));
151                                employeeSearchEvaluator.setLastName(form.getLastName());
152                                employeeSearchEvaluator.setLastNameSoundex(Boolean.parseBoolean(form.getLastNameSoundex()));
153                                employeeSearchEvaluator.setPartyAliasType(partyAliasType);
154                                employeeSearchEvaluator.setAlias(alias);
155                                employeeSearchEvaluator.setPartyEmployeeName(form.getEmployeeName());
156                                employeeSearchEvaluator.setPartyName(form.getPartyName());
157                                employeeSearchEvaluator.setEmployeeStatusWorkflowStep(employeeStatusWorkflowStep);
158                                employeeSearchEvaluator.setEmployeeAvailabilityWorkflowStep(employeeAvailabilityWorkflowStep);
159                                employeeSearchEvaluator.setCreatedSince(createdSince == null ? null : Long.valueOf(createdSince));
160                                employeeSearchEvaluator.setModifiedSince(modifiedSince == null ? null : Long.valueOf(modifiedSince));
161                                employeeSearchEvaluator.setFields(fields == null ? null : Splitter.on(':').trimResults().omitEmptyStrings().splitToList(fields).toArray(new String[0]));
162
163                                result.setCount(employeeSearchEvaluator.execute(this));
164                            } else {
165                                addExecutionError(ExecutionErrors.UnknownEmployeeAvailabilityChoice.name(), employeeAvailabilityChoice);
166                            }
167                        } else {
168                            addExecutionError(ExecutionErrors.UnknownEmployeeStatusChoice.name(), employeeStatusChoice);
169                        }
170                    }
171                } else {
172                    addExecutionError(ExecutionErrors.UnknownSearchTypeName.name(), SearchKinds.EMPLOYEE.name(), searchTypeName);
173                }
174            } else {
175                addExecutionError(ExecutionErrors.UnknownSearchKindName.name(), SearchKinds.EMPLOYEE.name());
176            }
177        } else {
178            addExecutionError(ExecutionErrors.InvalidParameterCount.name());
179        }
180
181        return result;
182    }
183
184}