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.letter.server.command;
018
019import com.echothree.control.user.letter.common.edit.LetterEditFactory;
020import com.echothree.control.user.letter.common.edit.LetterSourceEdit;
021import com.echothree.control.user.letter.common.form.EditLetterSourceForm;
022import com.echothree.control.user.letter.common.result.LetterResultFactory;
023import com.echothree.control.user.letter.common.spec.LetterSourceSpec;
024import com.echothree.model.control.contact.server.control.ContactControl;
025import com.echothree.model.control.letter.server.control.LetterControl;
026import com.echothree.model.control.party.common.PartyTypes;
027import com.echothree.model.control.security.common.SecurityRoleGroups;
028import com.echothree.model.control.security.common.SecurityRoles;
029import com.echothree.model.data.user.common.pk.UserVisitPK;
030import com.echothree.util.common.message.ExecutionErrors;
031import com.echothree.util.common.validation.FieldDefinition;
032import com.echothree.util.common.validation.FieldType;
033import com.echothree.util.common.command.BaseResult;
034import com.echothree.util.common.command.EditMode;
035import com.echothree.util.server.control.BaseEditCommand;
036import com.echothree.util.server.control.CommandSecurityDefinition;
037import com.echothree.util.server.control.PartyTypeDefinition;
038import com.echothree.util.server.control.SecurityRoleDefinition;
039import java.util.List;
040import javax.enterprise.context.Dependent;
041import javax.inject.Inject;
042
043@Dependent
044public class EditLetterSourceCommand
045        extends BaseEditCommand<LetterSourceSpec, LetterSourceEdit> {
046    
047    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
048    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
049    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
050    
051    static {
052        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
053                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
054                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
055                        new SecurityRoleDefinition(SecurityRoleGroups.LetterSource.name(), SecurityRoles.Edit.name())
056                ))
057        ));
058        
059        SPEC_FIELD_DEFINITIONS = List.of(
060                new FieldDefinition("LetterSourceName", FieldType.ENTITY_NAME, true, null, null)
061        );
062        
063        EDIT_FIELD_DEFINITIONS = List.of(
064                new FieldDefinition("LetterSourceName", FieldType.ENTITY_NAME, true, null, null),
065                new FieldDefinition("EmailAddressContactMechanismName", FieldType.ENTITY_NAME, false, null, null),
066                new FieldDefinition("EmailAddressContactMechanismAliasTypeName", FieldType.ENTITY_NAME, false, null, null),
067                new FieldDefinition("EmailAddressContactMechanismAlias", FieldType.ENTITY_NAME, false, null, null),
068                new FieldDefinition("PostalAddressContactMechanismName", FieldType.ENTITY_NAME, false, null, null),
069                new FieldDefinition("PostalAddressContactMechanismAliasTypeName", FieldType.ENTITY_NAME, false, null, null),
070                new FieldDefinition("PostalAddressContactMechanismAlias", FieldType.ENTITY_NAME, false, null, null),
071                new FieldDefinition("LetterSourceContactMechanismName", FieldType.ENTITY_NAME, false, null, null),
072                new FieldDefinition("LetterSourceContactMechanismAliasTypeName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("LetterSourceContactMechanismAlias", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
075                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
076                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
077        );
078    }
079
080    @Inject
081    ContactControl contactControl;
082
083    @Inject
084    LetterControl letterControl;
085
086    
087    /** Creates a new instance of EditLetterSourceCommand */
088    public EditLetterSourceCommand() {
089        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
090    }
091    
092    @Override
093    protected BaseResult execute() {
094        var result = LetterResultFactory.getEditLetterSourceResult();
095        
096        if(editMode.equals(EditMode.LOCK)) {
097            var letterSourceName = spec.getLetterSourceName();
098            var letterSource = letterControl.getLetterSourceByName(letterSourceName);
099            
100            if(letterSource != null) {
101                result.setLetterSource(letterControl.getLetterSourceTransfer(getUserVisit(), letterSource));
102                
103                if(lockEntity(letterSource)) {
104                    var letterSourceDescription = letterControl.getLetterSourceDescription(letterSource, getPreferredLanguage());
105                    var edit = LetterEditFactory.getLetterSourceEdit();
106                    var letterSourceDetail = letterSource.getLastDetail();
107                    
108                    result.setEdit(edit);
109                    edit.setLetterSourceName(letterSourceDetail.getLetterSourceName());
110                    edit.setEmailAddressContactMechanismName(letterSourceDetail.getEmailAddressPartyContactMechanism().getLastDetail().getContactMechanism().getLastDetail().getContactMechanismName());
111                    edit.setPostalAddressContactMechanismName(letterSourceDetail.getPostalAddressPartyContactMechanism().getLastDetail().getContactMechanism().getLastDetail().getContactMechanismName());
112                    edit.setLetterSourceContactMechanismName(letterSourceDetail.getLetterSourcePartyContactMechanism().getLastDetail().getContactMechanism().getLastDetail().getContactMechanismName());
113                    edit.setIsDefault(letterSourceDetail.getIsDefault().toString());
114                    edit.setSortOrder(letterSourceDetail.getSortOrder().toString());
115                    
116                    if(letterSourceDescription != null)
117                        edit.setDescription(letterSourceDescription.getDescription());
118                } else {
119                    addExecutionError(ExecutionErrors.EntityLockFailed.name());
120                }
121                
122                result.setEntityLock(getEntityLockTransfer(letterSource));
123            } else {
124                addExecutionError(ExecutionErrors.UnknownLetterSourceName.name(), letterSourceName);
125            }
126        } else if(editMode.equals(EditMode.UPDATE)) {
127            var letterSourceName = spec.getLetterSourceName();
128            var letterSource = letterControl.getLetterSourceByNameForUpdate(letterSourceName);
129            
130            if(letterSource != null) {
131                letterSourceName = edit.getLetterSourceName();
132                var duplicateLetterSource = letterControl.getLetterSourceByName(letterSourceName);
133                
134                if(duplicateLetterSource == null || letterSource.equals(duplicateLetterSource)) {
135                    var companyParty = letterSource.getLastDetail().getCompanyParty();
136                    var letterSourceCommandUtil = LetterSourceCommandUtil.getInstance();
137                    var emailAddressPartyContactMechanism = letterSourceCommandUtil.getEmailAddressContactMechanism(this, edit, contactControl,
138                            companyParty);
139                    
140                    if(!hasExecutionErrors()) {
141                        var postalAddressPartyContactMechanism = letterSourceCommandUtil.getPostalAddressContactMechanism(this, edit,
142                                contactControl, companyParty);
143                        
144                        if(!hasExecutionErrors()) {
145                            var letterSourcePartyContactMechanism = letterSourceCommandUtil.getLetterSourceContactMechanism(this, edit,
146                                    contactControl, companyParty);
147                            
148                            if(!hasExecutionErrors()) {
149                                if(lockEntityForUpdate(letterSource)) {
150                                    try {
151                                        var partyPK = getPartyPK();
152                                        var letterSourceDetailValue = letterControl.getLetterSourceDetailValueForUpdate(letterSource);
153                                        var letterSourceDescription = letterControl.getLetterSourceDescriptionForUpdate(letterSource, getPreferredLanguage());
154                                        var description = edit.getDescription();
155                                        
156                                        letterSourceDetailValue.setLetterSourceName(edit.getLetterSourceName());
157                                        letterSourceDetailValue.setEmailAddressPartyContactMechanismPK(emailAddressPartyContactMechanism.getPrimaryKey());
158                                        letterSourceDetailValue.setPostalAddressPartyContactMechanismPK(postalAddressPartyContactMechanism.getPrimaryKey());
159                                        letterSourceDetailValue.setLetterSourcePartyContactMechanismPK(letterSourcePartyContactMechanism.getPrimaryKey());
160                                        letterSourceDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
161                                        letterSourceDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
162                                        
163                                        letterControl.updateLetterSourceFromValue(letterSourceDetailValue, partyPK);
164                                        
165                                        if(letterSourceDescription == null && description != null) {
166                                            letterControl.createLetterSourceDescription(letterSource, getPreferredLanguage(), description, partyPK);
167                                        } else if(letterSourceDescription != null && description == null) {
168                                            letterControl.deleteLetterSourceDescription(letterSourceDescription, partyPK);
169                                        } else if(letterSourceDescription != null && description != null) {
170                                            var letterSourceDescriptionValue = letterControl.getLetterSourceDescriptionValue(letterSourceDescription);
171                                            
172                                            letterSourceDescriptionValue.setDescription(description);
173                                            letterControl.updateLetterSourceDescriptionFromValue(letterSourceDescriptionValue, partyPK);
174                                        }
175                                    } finally {
176                                        unlockEntity(letterSource);
177                                    }
178                                } else {
179                                    addExecutionError(ExecutionErrors.EntityLockStale.name());
180                                }
181                            }
182                        }
183                    }
184                    
185                } else {
186                    addExecutionError(ExecutionErrors.DuplicateLetterSourceName.name(), letterSourceName);
187                }
188            } else {
189                addExecutionError(ExecutionErrors.UnknownLetterSourceName.name(), letterSourceName);
190            }
191            
192            if(hasExecutionErrors()) {
193                result.setLetterSource(letterControl.getLetterSourceTransfer(getUserVisit(), letterSource));
194                result.setEntityLock(getEntityLockTransfer(letterSource));
195            }
196        }
197        
198        return result;
199    }
200    
201}