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