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.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 java.util.List;
044import javax.enterprise.context.Dependent;
045import javax.inject.Inject;
046
047@Dependent
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    @Inject
080    WorkflowControl workflowControl;
081
082    @Inject
083    SecurityRoleGroupLogic securityRoleGroupLogic;
084
085    @Inject
086    SelectorTypeLogic selectorTypeLogic;
087
088    @Inject
089    WorkflowLogic workflowLogic;
090
091    
092    /** Creates a new instance of EditWorkflowCommand */
093    public EditWorkflowCommand() {
094        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
095    }
096
097    @Override
098    public EditWorkflowResult getResult() {
099        return WorkflowResultFactory.getEditWorkflowResult();
100    }
101
102    @Override
103    public WorkflowEdit getEdit() {
104        return WorkflowEditFactory.getWorkflowEdit();
105    }
106
107    @Override
108    public Workflow getEntity(EditWorkflowResult result) {
109        return workflowLogic.getWorkflowByUniversalSpec(this, spec, editModeToEntityPermission(editMode));
110    }
111
112    @Override
113    public Workflow getLockEntity(Workflow freeOnBoard) {
114        return freeOnBoard;
115    }
116
117    @Override
118    public void fillInResult(EditWorkflowResult result, Workflow freeOnBoard) {
119        var workflow = workflowControl;
120
121        result.setWorkflow(workflow.getWorkflowTransfer(getUserVisit(), freeOnBoard));
122    }
123
124    @Override
125    public void doLock(WorkflowEdit edit, Workflow workflow) {
126        var workflowDescription = workflowControl.getWorkflowDescription(workflow, getPreferredLanguage());
127        var workflowDetail = workflow.getLastDetail();
128        var selectorType = workflowDetail.getSelectorType();
129        var selectorKind = selectorType == null ? null : selectorType.getLastDetail().getSelectorKind();
130        var securityRoleGroup = workflowDetail.getSecurityRoleGroup();
131
132        edit.setWorkflowName(workflowDetail.getWorkflowName());
133        edit.setSelectorKindName(selectorKind == null ? null : selectorKind.getLastDetail().getSelectorKindName());
134        edit.setSelectorTypeName(selectorType == null ? null : selectorType.getLastDetail().getSelectorTypeName());
135        edit.setSecurityRoleGroupName(securityRoleGroup == null ? null : securityRoleGroup.getLastDetail().getSecurityRoleGroupName());
136        edit.setSortOrder(workflowDetail.getSortOrder().toString());
137
138        if(workflowDescription != null) {
139            edit.setDescription(workflowDescription.getDescription());
140        }
141    }
142
143    SelectorType selectorType;
144    SecurityRoleGroup securityRoleGroup;
145
146    @Override
147    public void canUpdate(Workflow workflow) {
148        var workflowName = edit.getWorkflowName();
149        var duplicateWorkflow = workflowControl.getWorkflowByName(workflowName);
150
151        if(duplicateWorkflow != null && !workflow.equals(duplicateWorkflow)) {
152            addExecutionError(ExecutionErrors.DuplicateWorkflowName.name(), workflowName);
153        } else {
154            var selectorKindName = edit.getSelectorKindName();
155            var selectorTypeName = edit.getSelectorTypeName();
156            var parameterCount = (selectorKindName == null ? 0 : 1) + (selectorTypeName == null ? 0 : 1);
157
158            if(parameterCount == 0 || parameterCount == 2) {
159                selectorType = parameterCount == 0 ? null : selectorTypeLogic.getSelectorTypeByName(this, selectorKindName, selectorTypeName);
160
161                if(!hasExecutionErrors()) {
162                    var securityRoleGroupName = edit.getSecurityRoleGroupName();
163
164                    securityRoleGroup = securityRoleGroupName == null ? null : securityRoleGroupLogic.getSecurityRoleGroupByName(this, securityRoleGroupName);
165                }
166            } else {
167                addExecutionError(ExecutionErrors.InvalidParameterCount.name());
168            }
169        }
170    }
171
172    @Override
173    public void doUpdate(Workflow workflow) {
174        var partyPK = getPartyPK();
175        var workflowDetailValue = workflowControl.getWorkflowDetailValueForUpdate(workflow);
176        var workflowDescription = workflowControl.getWorkflowDescriptionForUpdate(workflow, getPreferredLanguage());
177        var description = edit.getDescription();
178
179        workflowDetailValue.setWorkflowName(edit.getWorkflowName());
180        workflowDetailValue.setSelectorTypePK(selectorType == null ? null : selectorType.getPrimaryKey());
181        workflowDetailValue.setSecurityRoleGroupPK(securityRoleGroup == null ? null : securityRoleGroup.getPrimaryKey());
182        workflowDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
183
184        workflowControl.updateWorkflowFromValue(workflowDetailValue, partyPK);
185
186        if(workflowDescription == null && description != null) {
187            workflowControl.createWorkflowDescription(workflow, getPreferredLanguage(), description, partyPK);
188        } else if(workflowDescription != null && description == null) {
189            workflowControl.deleteWorkflowDescription(workflowDescription, partyPK);
190        } else if(workflowDescription != null && description != null) {
191            var workflowDescriptionValue = workflowControl.getWorkflowDescriptionValue(workflowDescription);
192
193            workflowDescriptionValue.setDescription(description);
194            workflowControl.updateWorkflowDescriptionFromValue(workflowDescriptionValue, partyPK);
195        }
196    }
197    
198}