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.workflow.server.command;
018
019import com.echothree.control.user.workflow.common.edit.WorkflowEdit;
020import com.echothree.control.user.workflow.common.edit.WorkflowEditFactory;
021import com.echothree.control.user.workflow.common.form.EditWorkflowForm;
022import com.echothree.control.user.workflow.common.result.EditWorkflowResult;
023import com.echothree.control.user.workflow.common.result.WorkflowResultFactory;
024import com.echothree.control.user.workflow.common.spec.WorkflowUniversalSpec;
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.security.server.logic.SecurityRoleGroupLogic;
029import com.echothree.model.control.selector.server.logic.SelectorTypeLogic;
030import com.echothree.model.control.workflow.server.control.WorkflowControl;
031import com.echothree.model.control.workflow.server.logic.WorkflowLogic;
032import com.echothree.model.data.security.server.entity.SecurityRoleGroup;
033import com.echothree.model.data.selector.server.entity.SelectorType;
034import com.echothree.model.data.user.common.pk.UserVisitPK;
035import com.echothree.model.data.workflow.server.entity.Workflow;
036import com.echothree.util.common.message.ExecutionErrors;
037import com.echothree.util.common.validation.FieldDefinition;
038import com.echothree.util.common.validation.FieldType;
039import com.echothree.util.server.control.BaseAbstractEditCommand;
040import com.echothree.util.server.control.CommandSecurityDefinition;
041import com.echothree.util.server.control.PartyTypeDefinition;
042import com.echothree.util.server.control.SecurityRoleDefinition;
043import com.echothree.util.server.persistence.Session;
044import java.util.List;
045import javax.enterprise.context.RequestScoped;
046
047@RequestScoped
048public class EditWorkflowCommand
049        extends BaseAbstractEditCommand<WorkflowUniversalSpec, WorkflowEdit, EditWorkflowResult, Workflow, Workflow> {
050
051    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
052    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
053    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
054    
055    static {
056        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
057                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
058                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
059                    new SecurityRoleDefinition(SecurityRoleGroups.Workflow.name(), SecurityRoles.Edit.name())
060            ))
061        ));
062        
063        SPEC_FIELD_DEFINITIONS = List.of(
064                new FieldDefinition("WorkflowName", FieldType.ENTITY_NAME, false, null, null),
065                new FieldDefinition("EntityRef", FieldType.ENTITY_REF, false, null, null),
066                new FieldDefinition("Uuid", FieldType.UUID, false, null, null)
067        );
068        
069        EDIT_FIELD_DEFINITIONS = List.of(
070                new FieldDefinition("WorkflowName", FieldType.ENTITY_NAME, true, null, null),
071                new FieldDefinition("SelectorKindName", FieldType.ENTITY_NAME, false, null, null),
072                new FieldDefinition("SelectorTypeName", FieldType.ENTITY_NAME, false, null, null),
073                new FieldDefinition("SecurityRoleGroupName", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
075                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
076        );
077    }
078    
079    /** Creates a new instance of EditWorkflowCommand */
080    public EditWorkflowCommand() {
081        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
082    }
083
084    @Override
085    public EditWorkflowResult getResult() {
086        return WorkflowResultFactory.getEditWorkflowResult();
087    }
088
089    @Override
090    public WorkflowEdit getEdit() {
091        return WorkflowEditFactory.getWorkflowEdit();
092    }
093
094    @Override
095    public Workflow getEntity(EditWorkflowResult result) {
096        return WorkflowLogic.getInstance().getWorkflowByUniversalSpec(this, spec, editModeToEntityPermission(editMode));
097    }
098
099    @Override
100    public Workflow getLockEntity(Workflow freeOnBoard) {
101        return freeOnBoard;
102    }
103
104    @Override
105    public void fillInResult(EditWorkflowResult result, Workflow freeOnBoard) {
106        var workflow = Session.getModelController(WorkflowControl.class);
107
108        result.setWorkflow(workflow.getWorkflowTransfer(getUserVisit(), freeOnBoard));
109    }
110
111    @Override
112    public void doLock(WorkflowEdit edit, Workflow workflow) {
113        var workflowControl = Session.getModelController(WorkflowControl.class);
114        var workflowDescription = workflowControl.getWorkflowDescription(workflow, getPreferredLanguage());
115        var workflowDetail = workflow.getLastDetail();
116        var selectorType = workflowDetail.getSelectorType();
117        var selectorKind = selectorType == null ? null : selectorType.getLastDetail().getSelectorKind();
118        var securityRoleGroup = workflowDetail.getSecurityRoleGroup();
119
120        edit.setWorkflowName(workflowDetail.getWorkflowName());
121        edit.setSelectorKindName(selectorKind == null ? null : selectorKind.getLastDetail().getSelectorKindName());
122        edit.setSelectorTypeName(selectorType == null ? null : selectorType.getLastDetail().getSelectorTypeName());
123        edit.setSecurityRoleGroupName(securityRoleGroup == null ? null : securityRoleGroup.getLastDetail().getSecurityRoleGroupName());
124        edit.setSortOrder(workflowDetail.getSortOrder().toString());
125
126        if(workflowDescription != null) {
127            edit.setDescription(workflowDescription.getDescription());
128        }
129    }
130
131    SelectorType selectorType;
132    SecurityRoleGroup securityRoleGroup;
133
134    @Override
135    public void canUpdate(Workflow workflow) {
136        var workflowControl = Session.getModelController(WorkflowControl.class);
137        var workflowName = edit.getWorkflowName();
138        var duplicateWorkflow = workflowControl.getWorkflowByName(workflowName);
139
140        if(duplicateWorkflow != null && !workflow.equals(duplicateWorkflow)) {
141            addExecutionError(ExecutionErrors.DuplicateWorkflowName.name(), workflowName);
142        } else {
143            var selectorKindName = edit.getSelectorKindName();
144            var selectorTypeName = edit.getSelectorTypeName();
145            var parameterCount = (selectorKindName == null ? 0 : 1) + (selectorTypeName == null ? 0 : 1);
146
147            if(parameterCount == 0 || parameterCount == 2) {
148                selectorType = parameterCount == 0 ? null : SelectorTypeLogic.getInstance().getSelectorTypeByName(this, selectorKindName, selectorTypeName);
149
150                if(!hasExecutionErrors()) {
151                    var securityRoleGroupName = edit.getSecurityRoleGroupName();
152
153                    securityRoleGroup = securityRoleGroupName == null ? null : SecurityRoleGroupLogic.getInstance().getSecurityRoleGroupByName(this, securityRoleGroupName);
154                }
155            } else {
156                addExecutionError(ExecutionErrors.InvalidParameterCount.name());
157            }
158        }
159    }
160
161    @Override
162    public void doUpdate(Workflow workflow) {
163        var workflowControl = Session.getModelController(WorkflowControl.class);
164        var partyPK = getPartyPK();
165        var workflowDetailValue = workflowControl.getWorkflowDetailValueForUpdate(workflow);
166        var workflowDescription = workflowControl.getWorkflowDescriptionForUpdate(workflow, getPreferredLanguage());
167        var description = edit.getDescription();
168
169        workflowDetailValue.setWorkflowName(edit.getWorkflowName());
170        workflowDetailValue.setSelectorTypePK(selectorType == null ? null : selectorType.getPrimaryKey());
171        workflowDetailValue.setSecurityRoleGroupPK(securityRoleGroup == null ? null : securityRoleGroup.getPrimaryKey());
172        workflowDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
173
174        workflowControl.updateWorkflowFromValue(workflowDetailValue, partyPK);
175
176        if(workflowDescription == null && description != null) {
177            workflowControl.createWorkflowDescription(workflow, getPreferredLanguage(), description, partyPK);
178        } else if(workflowDescription != null && description == null) {
179            workflowControl.deleteWorkflowDescription(workflowDescription, partyPK);
180        } else if(workflowDescription != null && description != null) {
181            var workflowDescriptionValue = workflowControl.getWorkflowDescriptionValue(workflowDescription);
182
183            workflowDescriptionValue.setDescription(description);
184            workflowControl.updateWorkflowDescriptionFromValue(workflowDescriptionValue, partyPK);
185        }
186    }
187    
188}