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