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