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