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.party.server.command;
018
019import com.echothree.control.user.party.common.form.CreateEmployeeForm;
020import com.echothree.control.user.party.common.result.PartyResultFactory;
021import com.echothree.model.control.accounting.server.control.AccountingControl;
022import com.echothree.model.control.contact.common.ContactMechanismPurposes;
023import com.echothree.model.control.contact.server.logic.ContactEmailAddressLogic;
024import com.echothree.model.control.contactlist.server.logic.ContactListLogic;
025import com.echothree.model.control.core.server.control.EntityInstanceControl;
026import com.echothree.model.control.employee.common.workflow.EmployeeAvailabilityConstants;
027import com.echothree.model.control.employee.common.workflow.EmployeeStatusConstants;
028import com.echothree.model.control.employee.server.control.EmployeeControl;
029import com.echothree.model.control.party.common.PartyTypes;
030import com.echothree.model.control.party.server.control.PartyControl;
031import com.echothree.model.control.party.server.logic.PasswordStringPolicyLogic;
032import com.echothree.model.control.security.common.SecurityRoleGroups;
033import com.echothree.model.control.security.common.SecurityRoles;
034import com.echothree.model.control.security.server.control.SecurityControl;
035import com.echothree.model.control.sequence.common.SequenceTypes;
036import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
037import com.echothree.model.control.user.common.UserConstants;
038import com.echothree.model.control.workflow.server.control.WorkflowControl;
039import com.echothree.model.data.accounting.server.entity.Currency;
040import com.echothree.model.data.employee.server.entity.PartyEmployee;
041import com.echothree.util.common.command.BaseResult;
042import com.echothree.util.common.message.ExecutionErrors;
043import com.echothree.util.common.persistence.BasePK;
044import com.echothree.util.common.validation.FieldDefinition;
045import com.echothree.util.common.validation.FieldType;
046import com.echothree.util.server.control.BaseSimpleCommand;
047import com.echothree.util.server.control.CommandSecurityDefinition;
048import com.echothree.util.server.control.PartyTypeDefinition;
049import com.echothree.util.server.control.SecurityRoleDefinition;
050import com.echothree.util.server.persistence.EntityPermission;
051import java.util.List;
052import org.apache.commons.codec.language.Soundex;
053import javax.enterprise.context.Dependent;
054import javax.inject.Inject;
055
056@Dependent
057public class CreateEmployeeCommand
058        extends BaseSimpleCommand<CreateEmployeeForm> {
059    
060    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
061    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
062    
063    static {
064        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
065                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
066                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
067                        new SecurityRoleDefinition(SecurityRoleGroups.Employee.name(), SecurityRoles.Create.name())
068                ))
069        ));
070        
071        FORM_FIELD_DEFINITIONS = List.of(
072                new FieldDefinition("EmployeeTypeName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null),
074                new FieldDefinition("FirstName", FieldType.STRING, true, 1L, 20L),
075                new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L),
076                new FieldDefinition("LastName", FieldType.STRING, true, 1L, 20L),
077                new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null),
078                new FieldDefinition("PreferredLanguageIsoName", FieldType.ENTITY_NAME, false, null, null),
079                new FieldDefinition("PreferredCurrencyIsoName", FieldType.ENTITY_NAME, false, null, null),
080                new FieldDefinition("PreferredJavaTimeZoneName", FieldType.TIME_ZONE_NAME, false, null, null),
081                new FieldDefinition("PreferredDateTimeFormatName", FieldType.ENTITY_NAME, false, null, null),
082                new FieldDefinition("EmailAddress", FieldType.EMAIL_ADDRESS, true, null, null),
083                new FieldDefinition("AllowSolicitation", FieldType.BOOLEAN, true, null, null),
084                new FieldDefinition("Username", FieldType.STRING, true, 1L, 80L),
085                new FieldDefinition("Password1", FieldType.STRING, true, 1L, 40L),
086                new FieldDefinition("Password2", FieldType.STRING, true, 1L, 40L),
087                new FieldDefinition("PartySecurityRoleTemplateName", FieldType.ENTITY_NAME, true, null, null)
088        );
089    }
090
091    @Inject
092    AccountingControl accountingControl;
093
094    @Inject
095    EmployeeControl employeeControl;
096
097    @Inject
098    EntityInstanceControl entityInstanceControl;
099
100    @Inject
101    PartyControl partyControl;
102
103    @Inject
104    SecurityControl securityControl;
105
106    @Inject
107    WorkflowControl workflowControl;
108
109    @Inject
110    ContactEmailAddressLogic contactEmailAddressLogic;
111
112    @Inject
113    ContactListLogic contactListLogic;
114
115    @Inject
116    PasswordStringPolicyLogic passwordStringPolicyLogic;
117
118    @Inject
119    SequenceGeneratorLogic sequenceGeneratorLogic;
120
121    
122    /** Creates a new instance of CreateEmployeeCommand */
123    public CreateEmployeeCommand() {
124        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
125    }
126    
127    @Override
128    protected BaseResult execute() {
129        var result = PartyResultFactory.getCreateEmployeeResult();
130        PartyEmployee partyEmployee = null;
131        var username = form.getUsername();
132        var userLogin = userControl.getUserLoginByUsername(username);
133        
134        if(userLogin == null) {
135            var password1 = form.getPassword1();
136            var password2 = form.getPassword2();
137            
138            if(password1.equals(password2)) {
139                var partyType = partyControl.getPartyTypeByName(PartyTypes.EMPLOYEE.name());
140                var partyTypePasswordStringPolicy = passwordStringPolicyLogic.checkStringPassword(session,
141                        getUserVisit(), this, partyType, null, null, password1);
142                
143                if(!hasExecutionErrors()) {
144                    var employeeTypeName = form.getEmployeeTypeName();
145                    var employeeType = employeeTypeName == null? employeeControl.getDefaultEmployeeType(): employeeControl.getEmployeeTypeByName(employeeTypeName);
146                    
147                    if(employeeType != null) {
148                        var preferredLanguageIsoName = form.getPreferredLanguageIsoName();
149                        var preferredLanguage = preferredLanguageIsoName == null? null: partyControl.getLanguageByIsoName(preferredLanguageIsoName);
150                        
151                        if(preferredLanguageIsoName == null || (preferredLanguage != null)) {
152                            var preferredJavaTimeZoneName = form.getPreferredJavaTimeZoneName();
153                            var preferredTimeZone = preferredJavaTimeZoneName == null? null: partyControl.getTimeZoneByJavaName(preferredJavaTimeZoneName);
154                            
155                            if(preferredJavaTimeZoneName == null || (preferredTimeZone != null)) {
156                                var preferredDateTimeFormatName = form.getPreferredDateTimeFormatName();
157                                var preferredDateTimeFormat = preferredDateTimeFormatName == null? null: partyControl.getDateTimeFormatByName(preferredDateTimeFormatName);
158                                
159                                if(preferredDateTimeFormatName == null || (preferredDateTimeFormat != null)) {
160                                    var preferredCurrencyIsoName = form.getPreferredCurrencyIsoName();
161                                    Currency preferredCurrency;
162                                    
163                                    if(preferredCurrencyIsoName == null)
164                                        preferredCurrency = null;
165                                    else {
166                                        preferredCurrency = accountingControl.getCurrencyByIsoName(preferredCurrencyIsoName);
167                                    }
168                                    
169                                    if(preferredCurrencyIsoName == null || (preferredCurrency != null)) {
170                                        var partySecurityRoleTemplateName = form.getPartySecurityRoleTemplateName();
171                                        var partySecurityRoleTemplate = securityControl.getPartySecurityRoleTemplateByName(partySecurityRoleTemplateName);
172                                        
173                                        if(partySecurityRoleTemplate != null) {
174                                            var soundex = new Soundex();
175                                            BasePK createdBy = getPartyPK();
176                                            var personalTitleId = form.getPersonalTitleId();
177                                            var personalTitle = personalTitleId == null? null: partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY);
178                                            var firstName = form.getFirstName();
179                                            var firstNameSdx = soundex.encode(firstName);
180                                            var middleName = form.getMiddleName();
181                                            var middleNameSdx = middleName == null? null: soundex.encode(middleName);
182                                            var lastName = form.getLastName();
183                                            var lastNameSdx = soundex.encode(lastName);
184                                            var nameSuffixId = form.getNameSuffixId();
185                                            var nameSuffix = nameSuffixId == null? null: partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY);
186                                            var emailAddress = form.getEmailAddress();
187                                            var allowSolicitation = Boolean.valueOf(form.getAllowSolicitation());
188                                            var partyEmployeeName = sequenceGeneratorLogic.getNextSequenceValue(null, SequenceTypes.EMPLOYEE.name());
189
190                                            var party = partyControl.createParty(null, partyType, preferredLanguage, preferredCurrency, preferredTimeZone, preferredDateTimeFormat, createdBy);
191                                            partyControl.createPerson(party, personalTitle, firstName, firstNameSdx, middleName, middleNameSdx, lastName, lastNameSdx, nameSuffix, createdBy);
192                                            partyEmployee = employeeControl.createPartyEmployee(party, partyEmployeeName, employeeType, createdBy);
193                                            userControl.createUserLogin(party, username, createdBy);
194                                            
195                                            contactEmailAddressLogic.createContactEmailAddress(party,
196                                                    emailAddress, allowSolicitation, null,
197                                                    ContactMechanismPurposes.PRIMARY_EMAIL.name(), createdBy);
198
199                                            var userLoginPasswordType = userControl.getUserLoginPasswordTypeByName(UserConstants.UserLoginPasswordType_STRING);
200                                            var userLoginPassword = userControl.createUserLoginPassword(party, userLoginPasswordType, createdBy);
201                                            userControl.createUserLoginPasswordString(userLoginPassword, password1, session.getStartTime(), false, createdBy);
202
203                                            if(partyTypePasswordStringPolicy != null && partyTypePasswordStringPolicy.getLastDetail().getForceChangeAfterCreate()) {
204                                                var userLoginStatus = userControl.getUserLoginStatusForUpdate(party);
205
206                                                userLoginStatus.setForceChange(true);
207                                            }
208
209                                            securityControl.createPartySecurityRoleTemplateUse(party, partySecurityRoleTemplate, createdBy);
210
211                                            var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(party.getPrimaryKey());
212                                            workflowControl.addEntityToWorkflowUsingNames(null, EmployeeStatusConstants.Workflow_EMPLOYEE_STATUS,
213                                                    EmployeeStatusConstants.WorkflowEntrance_NEW_ACTIVE, entityInstance, null, null, createdBy);
214                                            workflowControl.addEntityToWorkflowUsingNames(null, EmployeeAvailabilityConstants.Workflow_EMPLOYEE_AVAILABILITY,
215                                                    EmployeeAvailabilityConstants.WorkflowEntrance_NEW_AVAILABLE, entityInstance, null, null, createdBy);
216                                            
217                                            contactListLogic.setupInitialContactLists(this, party, createdBy);
218                                        } else {
219                                            addExecutionError(ExecutionErrors.UnknownPartySecurityRoleTemplateName.name(), partySecurityRoleTemplateName);
220                                        }
221                                    } else {
222                                        addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), preferredCurrencyIsoName);
223                                    }
224                                } else {
225                                    addExecutionError(ExecutionErrors.UnknownDateTimeFormatName.name(), preferredDateTimeFormatName);
226                                }
227                            } else {
228                                addExecutionError(ExecutionErrors.UnknownJavaTimeZoneName.name(), preferredJavaTimeZoneName);
229                            }
230                        } else {
231                            addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), preferredLanguageIsoName);
232                        }
233                    } else {
234                        if(employeeTypeName != null) {
235                            addExecutionError(ExecutionErrors.UnknownEmployeeTypeName.name(), employeeTypeName);
236                        } else {
237                            addExecutionError(ExecutionErrors.UnknownDefaultEmployeeType.name());
238                        }
239                    }
240                }
241            } else {
242                addExecutionError(ExecutionErrors.MismatchedPasswords.name());
243            }
244        } else {
245            addExecutionError(ExecutionErrors.DuplicateUsername.name());
246
247            var party = userLogin.getParty();
248            partyEmployee = employeeControl.getPartyEmployee(party);
249        }
250        
251        if(partyEmployee != null) {
252            var party = partyEmployee.getParty();
253            
254            result.setEntityRef(party.getPrimaryKey().getEntityRef());
255            result.setEmployeeName(partyEmployee.getPartyEmployeeName());
256            result.setPartyName(party.getLastDetail().getPartyName());
257        }
258        
259        return result;
260    }
261    
262}