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.workflow.server.command;
018
019import com.echothree.control.user.workflow.common.edit.WorkflowDestinationEdit;
020import com.echothree.control.user.workflow.common.edit.WorkflowEditFactory;
021import com.echothree.control.user.workflow.common.form.EditWorkflowDestinationForm;
022import com.echothree.control.user.workflow.common.result.EditWorkflowDestinationResult;
023import com.echothree.control.user.workflow.common.result.WorkflowResultFactory;
024import com.echothree.control.user.workflow.common.spec.WorkflowDestinationSpec;
025import com.echothree.model.control.party.common.PartyTypes;
026import com.echothree.model.control.security.common.SecurityRoleGroups;
027import com.echothree.model.control.security.common.SecurityRoles;
028import com.echothree.model.control.workflow.server.control.WorkflowControl;
029import com.echothree.model.data.user.common.pk.UserVisitPK;
030import com.echothree.model.data.workflow.server.entity.Workflow;
031import com.echothree.model.data.workflow.server.entity.WorkflowDestination;
032import com.echothree.model.data.workflow.server.entity.WorkflowDestinationDescription;
033import com.echothree.model.data.workflow.server.entity.WorkflowDestinationDetail;
034import com.echothree.model.data.workflow.server.entity.WorkflowStep;
035import com.echothree.model.data.workflow.server.value.WorkflowDestinationDescriptionValue;
036import com.echothree.model.data.workflow.server.value.WorkflowDestinationDetailValue;
037import com.echothree.util.common.message.ExecutionErrors;
038import com.echothree.util.common.validation.FieldDefinition;
039import com.echothree.util.common.validation.FieldType;
040import com.echothree.util.common.command.BaseResult;
041import com.echothree.util.common.command.EditMode;
042import com.echothree.util.server.control.BaseEditCommand;
043import com.echothree.util.server.control.CommandSecurityDefinition;
044import com.echothree.util.server.control.PartyTypeDefinition;
045import com.echothree.util.server.control.SecurityRoleDefinition;
046import com.echothree.util.server.persistence.Session;
047import java.util.Arrays;
048import java.util.Collections;
049import java.util.List;
050
051public class EditWorkflowDestinationCommand
052        extends BaseEditCommand<WorkflowDestinationSpec, WorkflowDestinationEdit> {
053    
054    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
055    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
056    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
057    
058    static {
059        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
060                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
061                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
062                    new SecurityRoleDefinition(SecurityRoleGroups.WorkflowDestination.name(), SecurityRoles.Edit.name())
063                    )))
064                )));
065        
066        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
067                new FieldDefinition("WorkflowName", FieldType.ENTITY_NAME, true, null, null),
068                new FieldDefinition("WorkflowStepName", FieldType.ENTITY_NAME, true, null, null),
069                new FieldDefinition("WorkflowDestinationName", FieldType.ENTITY_NAME, true, null, null)
070                ));
071        
072        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
073                new FieldDefinition("WorkflowDestinationName", FieldType.ENTITY_NAME, true, 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    /** Creates a new instance of EditWorkflowDestinationCommand */
081    public EditWorkflowDestinationCommand(UserVisitPK userVisitPK, EditWorkflowDestinationForm form) {
082        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
083    }
084    
085    @Override
086    protected BaseResult execute() {
087        var workflowControl = Session.getModelController(WorkflowControl.class);
088        EditWorkflowDestinationResult result = WorkflowResultFactory.getEditWorkflowDestinationResult();
089        String workflowName = spec.getWorkflowName();
090        var workflow = workflowControl.getWorkflowByName(workflowName);
091        
092        if(workflow != null) {
093            String workflowStepName = spec.getWorkflowStepName();
094            var workflowStep = workflowControl.getWorkflowStepByName(workflow, workflowStepName);
095            
096            if(workflowStep != null) {
097                if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
098                    String workflowDestinationName = spec.getWorkflowDestinationName();
099                    WorkflowDestination workflowDestination = workflowControl.getWorkflowDestinationByName(workflowStep, workflowDestinationName);
100
101                    if(workflowDestination != null) {
102                        if(editMode.equals(EditMode.LOCK)) {
103                            if(lockEntity(workflowDestination)) {
104                                WorkflowDestinationDescription workflowDestinationDescription = workflowControl.getWorkflowDestinationDescription(workflowDestination, getPreferredLanguage());
105                                WorkflowDestinationEdit edit = WorkflowEditFactory.getWorkflowDestinationEdit();
106                                WorkflowDestinationDetail workflowDestinationDetail = workflowDestination.getLastDetail();
107
108                                result.setWorkflowDestination(workflowControl.getWorkflowDestinationTransfer(getUserVisit(), workflowDestination));
109
110                                result.setEdit(edit);
111                                edit.setWorkflowDestinationName(workflowDestinationDetail.getWorkflowDestinationName());
112                                edit.setIsDefault(workflowDestinationDetail.getIsDefault().toString());
113                                edit.setSortOrder(workflowDestinationDetail.getSortOrder().toString());
114
115                                if(workflowDestinationDescription != null) {
116                                    edit.setDescription(workflowDestinationDescription.getDescription());
117                                }
118                            } else {
119                                addExecutionError(ExecutionErrors.EntityLockFailed.name());
120                            }
121
122                            result.setEntityLock(getEntityLockTransfer(workflowDestination));
123                        } else { // EditMode.ABANDON
124                            unlockEntity(workflowDestination);
125                        }
126                    } else {
127                        addExecutionError(ExecutionErrors.UnknownWorkflowDestinationName.name(), workflowName, workflowStepName, workflowDestinationName);
128                    }
129                } else if(editMode.equals(EditMode.UPDATE)) {
130                    String workflowDestinationName = spec.getWorkflowDestinationName();
131                    WorkflowDestination workflowDestination = workflowControl.getWorkflowDestinationByNameForUpdate(workflowStep, workflowDestinationName);
132
133                    if(workflowDestination != null) {
134                        workflowDestinationName = edit.getWorkflowDestinationName();
135                        WorkflowDestination duplicateWorkflowDestination = workflowControl.getWorkflowDestinationByName(workflowStep, workflowDestinationName);
136
137                        if(duplicateWorkflowDestination == null || workflowDestination.equals(duplicateWorkflowDestination)) {
138                            if(lockEntityForUpdate(workflowDestination)) {
139                                try {
140                                    var partyPK = getPartyPK();
141                                    WorkflowDestinationDetailValue workflowDestinationDetailValue = workflowControl.getWorkflowDestinationDetailValueForUpdate(workflowDestination);
142                                    WorkflowDestinationDescription workflowDestinationDescription = workflowControl.getWorkflowDestinationDescriptionForUpdate(workflowDestination, getPreferredLanguage());
143                                    String description = edit.getDescription();
144
145                                    workflowDestinationDetailValue.setWorkflowDestinationName(workflowDestinationName);
146                                    workflowDestinationDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
147                                    workflowDestinationDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
148
149                                    workflowControl.updateWorkflowDestinationFromValue(workflowDestinationDetailValue, partyPK);
150
151                                    if(workflowDestinationDescription == null && description != null) {
152                                        workflowControl.createWorkflowDestinationDescription(workflowDestination, getPreferredLanguage(), description, partyPK);
153                                    } else if(workflowDestinationDescription != null && description == null) {
154                                        workflowControl.deleteWorkflowDestinationDescription(workflowDestinationDescription, partyPK);
155                                    } else if(workflowDestinationDescription != null && description != null) {
156                                        WorkflowDestinationDescriptionValue workflowDestinationDescriptionValue = workflowControl.getWorkflowDestinationDescriptionValue(workflowDestinationDescription);
157
158                                        workflowDestinationDescriptionValue.setDescription(description);
159                                        workflowControl.updateWorkflowDestinationDescriptionFromValue(workflowDestinationDescriptionValue, partyPK);
160                                    }
161                                } finally {
162                                    unlockEntity(workflowDestination);
163                                }
164                            } else {
165                                addExecutionError(ExecutionErrors.EntityLockStale.name());
166                            }
167                        } else {
168                            addExecutionError(ExecutionErrors.DuplicateWorkflowDestinationName.name(), workflowName, workflowStepName, workflowDestinationName);
169                        }
170                    } else {
171                        addExecutionError(ExecutionErrors.UnknownWorkflowDestinationName.name(), workflowName, workflowStepName, workflowDestinationName);
172                    }
173
174                    if(hasExecutionErrors()) {
175                        result.setWorkflowDestination(workflowControl.getWorkflowDestinationTransfer(getUserVisit(), workflowDestination));
176                        result.setEntityLock(getEntityLockTransfer(workflowDestination));
177                    }
178                }
179            } else {
180                addExecutionError(ExecutionErrors.UnknownWorkflowStepName.name(), workflowStepName);
181            }
182        } else {
183            addExecutionError(ExecutionErrors.UnknownWorkflowName.name(), workflowName);
184        }
185        
186        return result;
187    }
188    
189}