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.edit.EmployeeEdit;
020import com.echothree.control.user.party.common.edit.PartyEditFactory;
021import com.echothree.control.user.party.common.form.EditEmployeeForm;
022import com.echothree.control.user.party.common.result.EditEmployeeResult;
023import com.echothree.control.user.party.common.result.PartyResultFactory;
024import com.echothree.control.user.party.common.spec.EmployeeSpec;
025import com.echothree.model.control.accounting.server.control.AccountingControl;
026import com.echothree.model.control.employee.server.control.EmployeeControl;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.control.party.server.control.PartyControl;
029import com.echothree.model.control.security.common.SecurityRoleGroups;
030import com.echothree.model.control.security.common.SecurityRoles;
031import com.echothree.model.control.security.server.control.SecurityControl;
032import com.echothree.model.data.accounting.server.entity.Currency;
033import com.echothree.model.data.employee.server.entity.EmployeeType;
034import com.echothree.model.data.employee.server.entity.PartyEmployee;
035import com.echothree.model.data.party.server.entity.DateTimeFormat;
036import com.echothree.model.data.party.server.entity.Language;
037import com.echothree.model.data.party.server.entity.Party;
038import com.echothree.model.data.party.server.entity.TimeZone;
039import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplate;
040import com.echothree.model.data.user.common.pk.UserVisitPK;
041import com.echothree.util.common.command.EditMode;
042import com.echothree.util.common.message.ExecutionErrors;
043import com.echothree.util.common.validation.FieldDefinition;
044import com.echothree.util.common.validation.FieldType;
045import com.echothree.util.server.control.BaseAbstractEditCommand;
046import com.echothree.util.server.control.CommandSecurityDefinition;
047import com.echothree.util.server.control.PartyTypeDefinition;
048import com.echothree.util.server.control.SecurityRoleDefinition;
049import com.echothree.util.server.persistence.EntityPermission;
050import com.echothree.util.server.persistence.Session;
051import java.util.Arrays;
052import java.util.Collections;
053import java.util.List;
054import org.apache.commons.codec.language.Soundex;
055import javax.enterprise.context.RequestScoped;
056
057@RequestScoped
058public class EditEmployeeCommand
059        extends BaseAbstractEditCommand<EmployeeSpec, EmployeeEdit, EditEmployeeResult, Party, Party> {
060    
061    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
062    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
063    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
064    
065    static {
066        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
067                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
068                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
069                    new SecurityRoleDefinition(SecurityRoleGroups.Employee.name(), SecurityRoles.Edit.name())
070                    )))
071                )));
072        
073        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
074            new FieldDefinition("EmployeeName", FieldType.ENTITY_NAME, true, null, null)
075        ));
076        
077        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
078            new FieldDefinition("EmployeeTypeName", FieldType.ENTITY_NAME, true, null, null),
079            new FieldDefinition("PersonalTitleId", FieldType.ID, false, null, null),
080            new FieldDefinition("FirstName", FieldType.STRING, true, 1L, 20L),
081            new FieldDefinition("MiddleName", FieldType.STRING, false, 1L, 20L),
082            new FieldDefinition("LastName", FieldType.STRING, true, 1L, 20L),
083            new FieldDefinition("NameSuffixId", FieldType.ID, false, null, null),
084            new FieldDefinition("PreferredLanguageIsoName", FieldType.ENTITY_NAME, false, null, null),
085            new FieldDefinition("PreferredCurrencyIsoName", FieldType.ENTITY_NAME, false, null, null),
086            new FieldDefinition("PreferredJavaTimeZoneName", FieldType.TIME_ZONE_NAME, false, null, null),
087            new FieldDefinition("PreferredDateTimeFormatName", FieldType.ENTITY_NAME, false, null, null),
088            new FieldDefinition("PartySecurityRoleTemplateName", FieldType.ENTITY_NAME, true, null, null)
089        ));
090    }
091    
092    /** Creates a new instance of EditEmployeeCommand */
093    public EditEmployeeCommand() {
094        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
095    }
096
097    @Override
098    public EditEmployeeResult getResult() {
099        return PartyResultFactory.getEditEmployeeResult();
100    }
101
102    @Override
103    public EmployeeEdit getEdit() {
104        return PartyEditFactory.getEmployeeEdit();
105    }
106
107    @Override
108    public Party getEntity(EditEmployeeResult result) {
109        var employeeControl = Session.getModelController(EmployeeControl.class);
110        PartyEmployee partyEmployee;
111        var employeeName = spec.getEmployeeName();
112
113        if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
114            partyEmployee = employeeControl.getPartyEmployeeByName(employeeName);
115        } else { // EditMode.UPDATE
116            partyEmployee = employeeControl.getPartyEmployeeByNameForUpdate(employeeName);
117        }
118
119        if(partyEmployee != null) {
120            result.setEmployee(employeeControl.getEmployeeTransfer(getUserVisit(), partyEmployee.getParty()));
121        } else {
122            addExecutionError(ExecutionErrors.UnknownEmployeeName.name(), employeeName);
123        }
124
125        return partyEmployee.getParty();
126    }
127
128    @Override
129    public Party getLockEntity(Party party) {
130        return party;
131    }
132
133    @Override
134    public void fillInResult(EditEmployeeResult result, Party party) {
135        var employeeControl = Session.getModelController(EmployeeControl.class);
136
137        result.setEmployee(employeeControl.getEmployeeTransfer(getUserVisit(), party));
138    }
139
140    @Override
141    public void doLock(EmployeeEdit edit, Party party) {
142        var employeeControl = Session.getModelController(EmployeeControl.class);
143        var partyControl = Session.getModelController(PartyControl.class);
144        var securityControl = Session.getModelController(SecurityControl.class);
145        var partyEmployee = employeeControl.getPartyEmployee(party);
146        var partyDetail = party.getLastDetail();
147        var preferredLanguage = partyDetail.getPreferredLanguage();
148        var preferredCurrency = partyDetail.getPreferredCurrency();
149        var preferredTimeZone = partyDetail.getPreferredTimeZone();
150        var dateTimeFormat = partyDetail.getPreferredDateTimeFormat();
151        var person = partyControl.getPerson(party);
152        var personalTitle = person.getPersonalTitle();
153        var nameSuffix = person.getNameSuffix();
154        var partySecurityRoleTemplateUse = securityControl.getPartySecurityRoleTemplateUse(party);
155
156        edit.setEmployeeTypeName(partyEmployee.getEmployeeType().getLastDetail().getEmployeeTypeName());
157        edit.setPersonalTitleId(personalTitle == null? null: personalTitle.getPrimaryKey().getEntityId().toString());
158        edit.setFirstName(person.getFirstName());
159        edit.setMiddleName(person.getMiddleName());
160        edit.setLastName(person.getLastName());
161        edit.setNameSuffixId(nameSuffix == null? null: nameSuffix.getPrimaryKey().getEntityId().toString());
162        edit.setPreferredLanguageIsoName(preferredLanguage == null? null: preferredLanguage.getLanguageIsoName());
163        edit.setPreferredCurrencyIsoName(preferredCurrency == null? null: preferredCurrency.getCurrencyIsoName());
164        edit.setPreferredJavaTimeZoneName(preferredTimeZone == null? null: preferredTimeZone.getLastDetail().getJavaTimeZoneName());
165        edit.setPreferredDateTimeFormatName(dateTimeFormat == null? null: dateTimeFormat.getLastDetail().getDateTimeFormatName());
166        edit.setPartySecurityRoleTemplateName(partySecurityRoleTemplateUse.getPartySecurityRoleTemplate().getLastDetail().getPartySecurityRoleTemplateName());
167    }
168
169    EmployeeType employeeType;
170    Language preferredLanguage;
171    TimeZone preferredTimeZone;
172    DateTimeFormat preferredDateTimeFormat;
173    Currency preferredCurrency;
174    PartySecurityRoleTemplate partySecurityRoleTemplate;
175
176    @Override
177    public void canUpdate(Party party) {
178        var employeeControl = Session.getModelController(EmployeeControl.class);
179        var partyControl = Session.getModelController(PartyControl.class);
180        var securityControl = Session.getModelController(SecurityControl.class);
181        var employeeTypeName = edit.getEmployeeTypeName();
182
183        employeeType = employeeControl.getEmployeeTypeByName(employeeTypeName);
184
185        if(employeeType != null) {
186            var preferredLanguageIsoName = edit.getPreferredLanguageIsoName();
187
188            preferredLanguage = preferredLanguageIsoName == null ? null : partyControl.getLanguageByIsoName(preferredLanguageIsoName);
189
190            if(preferredLanguageIsoName == null || (preferredLanguage != null)) {
191                var preferredJavaTimeZoneName = edit.getPreferredJavaTimeZoneName();
192
193                preferredTimeZone = preferredJavaTimeZoneName == null ? null : partyControl.getTimeZoneByJavaName(preferredJavaTimeZoneName);
194
195                if(preferredJavaTimeZoneName == null || (preferredTimeZone != null)) {
196                    var preferredDateTimeFormatName = edit.getPreferredDateTimeFormatName();
197
198                    preferredDateTimeFormat = preferredDateTimeFormatName == null ? null : partyControl.getDateTimeFormatByName(preferredDateTimeFormatName);
199
200                    if(preferredDateTimeFormatName == null || (preferredDateTimeFormat != null)) {
201                        var preferredCurrencyIsoName = edit.getPreferredCurrencyIsoName();
202
203                        if(preferredCurrencyIsoName == null) {
204                            preferredCurrency = null;
205                        } else {
206                            var accountingControl = Session.getModelController(AccountingControl.class);
207                            preferredCurrency = accountingControl.getCurrencyByIsoName(preferredCurrencyIsoName);
208                        }
209
210                        if(preferredCurrencyIsoName == null || (preferredCurrency != null)) {
211                            var partySecurityRoleTemplateName = edit.getPartySecurityRoleTemplateName();
212
213                            partySecurityRoleTemplate = securityControl.getPartySecurityRoleTemplateByName(partySecurityRoleTemplateName);
214
215                            if(partySecurityRoleTemplate == null) {
216                                addExecutionError(ExecutionErrors.UnknownPartySecurityRoleTemplateName.name(), partySecurityRoleTemplateName);
217                            }
218                        } else {
219                            addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), preferredCurrencyIsoName);
220                        }
221                    } else {
222                        addExecutionError(ExecutionErrors.UnknownDateTimeFormatName.name(), preferredDateTimeFormatName);
223                    }
224                } else {
225                    addExecutionError(ExecutionErrors.UnknownJavaTimeZoneName.name(), preferredJavaTimeZoneName);
226                }
227            } else {
228                addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), preferredLanguageIsoName);
229            }
230        } else {
231            addExecutionError(ExecutionErrors.UnknownEmployeeTypeName.name(), employeeTypeName);
232        }
233    }
234
235    @Override
236    public void doUpdate(Party party) {
237        var employeeControl = Session.getModelController(EmployeeControl.class);
238        var partyControl = Session.getModelController(PartyControl.class);
239        var securityControl = Session.getModelController(SecurityControl.class);
240        var soundex = new Soundex();
241        var partyDetailValue = partyControl.getPartyDetailValueForUpdate(party);
242        var partyEmployee = employeeControl.getPartyEmployeeForUpdate(party);
243        var partyEmployeeValue = employeeControl.getPartyEmployeeValue(partyEmployee);
244        var personValue = partyControl.getPersonValueForUpdate(party);
245        var personalTitleId = edit.getPersonalTitleId();
246        var personalTitle = personalTitleId == null ? null : partyControl.convertPersonalTitleIdToEntity(personalTitleId, EntityPermission.READ_ONLY);
247        var firstName = edit.getFirstName();
248        var firstNameSdx = soundex.encode(firstName);
249        var middleName = edit.getMiddleName();
250        var middleNameSdx = middleName == null ? null : soundex.encode(middleName);
251        var lastName = edit.getLastName();
252        var lastNameSdx = soundex.encode(lastName);
253        var nameSuffixId = edit.getNameSuffixId();
254        var nameSuffix = nameSuffixId == null ? null : partyControl.convertNameSuffixIdToEntity(nameSuffixId, EntityPermission.READ_ONLY);
255        var partySecurityRoleTemplateUseValue = securityControl.getPartySecurityRoleTemplateUseValueForUpdate(party);
256
257        partyEmployeeValue.setEmployeeTypePK(employeeType.getPrimaryKey());
258
259        partyDetailValue.setPreferredLanguagePK(preferredLanguage == null? null: preferredLanguage.getPrimaryKey());
260        partyDetailValue.setPreferredTimeZonePK(preferredTimeZone == null? null: preferredTimeZone.getPrimaryKey());
261        partyDetailValue.setPreferredDateTimeFormatPK(preferredDateTimeFormat == null? null: preferredDateTimeFormat.getPrimaryKey());
262        partyDetailValue.setPreferredCurrencyPK(preferredCurrency == null? null: preferredCurrency.getPrimaryKey());
263
264        personValue.setPersonalTitlePK(personalTitle == null? null: personalTitle.getPrimaryKey());
265        personValue.setFirstName(firstName);
266        personValue.setFirstNameSdx(firstNameSdx);
267        personValue.setMiddleName(middleName);
268        personValue.setMiddleNameSdx(middleNameSdx);
269        personValue.setLastName(lastName);
270        personValue.setLastNameSdx(lastNameSdx);
271        personValue.setNameSuffixPK(nameSuffix == null? null: nameSuffix.getPrimaryKey());
272
273        partySecurityRoleTemplateUseValue.setPartySecurityRoleTemplatePK(partySecurityRoleTemplate.getPrimaryKey());
274
275        var updatedBy = getPartyPK();
276        employeeControl.updatePartyEmployeeFromValue(partyEmployeeValue, updatedBy);
277        partyControl.updatePartyFromValue(partyDetailValue, updatedBy);
278        partyControl.updatePersonFromValue(personValue, updatedBy);
279        securityControl.updatePartySecurityRoleTemplateUseFromValue(partySecurityRoleTemplateUseValue, updatedBy);
280    }
281
282}