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.chain.server.command;
018
019import com.echothree.control.user.chain.common.edit.ChainEdit;
020import com.echothree.control.user.chain.common.edit.ChainEditFactory;
021import com.echothree.control.user.chain.common.form.EditChainForm;
022import com.echothree.control.user.chain.common.result.ChainResultFactory;
023import com.echothree.control.user.chain.common.result.EditChainResult;
024import com.echothree.control.user.chain.common.spec.ChainSpec;
025import com.echothree.model.control.chain.server.control.ChainControl;
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.control.sequence.common.SequenceTypes;
030import com.echothree.model.control.sequence.server.control.SequenceControl;
031import com.echothree.model.data.chain.server.entity.Chain;
032import com.echothree.model.data.chain.server.entity.ChainDescription;
033import com.echothree.model.data.chain.server.entity.ChainDetail;
034import com.echothree.model.data.chain.server.entity.ChainKind;
035import com.echothree.model.data.chain.server.entity.ChainType;
036import com.echothree.model.data.chain.server.entity.ChainTypeDetail;
037import com.echothree.model.data.chain.server.value.ChainDescriptionValue;
038import com.echothree.model.data.chain.server.value.ChainDetailValue;
039import com.echothree.model.data.sequence.server.entity.Sequence;
040import com.echothree.model.data.sequence.server.entity.SequenceType;
041import com.echothree.model.data.user.common.pk.UserVisitPK;
042import com.echothree.util.common.message.ExecutionErrors;
043import com.echothree.util.common.validation.FieldDefinition;
044import com.echothree.util.common.validation.FieldType;
045import com.echothree.util.common.command.EditMode;
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.Session;
051import java.util.Arrays;
052import java.util.Collections;
053import java.util.List;
054
055public class EditChainCommand
056        extends BaseAbstractEditCommand<ChainSpec, ChainEdit, EditChainResult, Chain, Chain> {
057
058    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
059    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
060    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
061
062    static {
063        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
064                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
065                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
066                        new SecurityRoleDefinition(SecurityRoleGroups.Chain.name(), SecurityRoles.Edit.name())
067                        )))
068                )));
069
070        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
071                new FieldDefinition("ChainKindName", FieldType.ENTITY_NAME, true, null, null),
072                new FieldDefinition("ChainTypeName", FieldType.ENTITY_NAME, true, null, null),
073                new FieldDefinition("ChainName", FieldType.ENTITY_NAME, true, null, null)
074                ));
075
076        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
077                new FieldDefinition("ChainName", FieldType.ENTITY_NAME, true, null, null),
078                new FieldDefinition("ChainInstanceSequenceName", FieldType.ENTITY_NAME, false, null, null),
079                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
080                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
081                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
082                ));
083    }
084
085    /** Creates a new instance of EditChainCommand */
086    public EditChainCommand(UserVisitPK userVisitPK, EditChainForm form) {
087        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
088    }
089
090    @Override
091    public EditChainResult getResult() {
092        return ChainResultFactory.getEditChainResult();
093    }
094
095    @Override
096    public ChainEdit getEdit() {
097        return ChainEditFactory.getChainEdit();
098    }
099
100    ChainType chainType;
101
102    @Override
103    public Chain getEntity(EditChainResult result) {
104        var chainControl = Session.getModelController(ChainControl.class);
105        Chain chain = null;
106        String chainKindName = spec.getChainKindName();
107        ChainKind chainKind = chainControl.getChainKindByName(chainKindName);
108
109        if(chainKind != null) {
110            String chainTypeName = spec.getChainTypeName();
111
112            chainType = chainControl.getChainTypeByName(chainKind, chainTypeName);
113
114            if(chainType != null) {
115                String chainName = spec.getChainName();
116
117                if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
118                    chain = chainControl.getChainByName(chainType, chainName);
119                } else { // EditMode.UPDATE
120                    chain = chainControl.getChainByNameForUpdate(chainType, chainName);
121                }
122
123                if(chain == null) {
124                    addExecutionError(ExecutionErrors.UnknownChainName.name(), chainTypeName, chainTypeName, chainName);
125                }
126            } else {
127                addExecutionError(ExecutionErrors.UnknownChainTypeName.name(), chainKindName, chainTypeName);
128            }
129        } else {
130            addExecutionError(ExecutionErrors.UnknownChainKindName.name(), chainKindName);
131        }
132
133        return chain;
134    }
135
136    @Override
137    public Chain getLockEntity(Chain chain) {
138        return chain;
139    }
140
141    @Override
142    public void fillInResult(EditChainResult result, Chain chain) {
143        var chainControl = Session.getModelController(ChainControl.class);
144
145        result.setChain(chainControl.getChainTransfer(getUserVisit(), chain));
146    }
147
148    Sequence chainInstanceSequence;
149    
150    @Override
151    public void doLock(ChainEdit edit, Chain chain) {
152        var chainControl = Session.getModelController(ChainControl.class);
153        ChainDescription chainDescription = chainControl.getChainDescription(chain, getPreferredLanguage());
154        ChainDetail chainDetail = chain.getLastDetail();
155        
156        chainInstanceSequence = chainDetail.getChainInstanceSequence();
157
158        edit.setChainName(chainDetail.getChainName());
159        edit.setChainInstanceSequenceName(chainInstanceSequence == null ? null : chainInstanceSequence.getLastDetail().getSequenceName());
160        edit.setIsDefault(chainDetail.getIsDefault().toString());
161        edit.setSortOrder(chainDetail.getSortOrder().toString());
162
163        if(chainDescription != null) {
164            edit.setDescription(chainDescription.getDescription());
165        }
166    }
167
168    @Override
169    public void canUpdate(Chain chain) {
170        var chainControl = Session.getModelController(ChainControl.class);
171        ChainTypeDetail chainTypeDetail = chainType.getLastDetail();
172        String chainName = edit.getChainName();
173        Chain duplicateChain = chainControl.getChainByName(chainType, chainName);
174
175        if(duplicateChain != null && !chain.equals(duplicateChain)) {
176            addExecutionError(ExecutionErrors.DuplicateChainName.name(), chainTypeDetail.getChainTypeName(), chainName);
177        } else {
178            var sequenceControl = Session.getModelController(SequenceControl.class);
179            SequenceType sequenceType = sequenceControl.getSequenceTypeByName(SequenceTypes.CHAIN_INSTANCE.name());
180            String chainInstanceSequenceName = edit.getChainInstanceSequenceName();
181
182            chainInstanceSequence = sequenceControl.getSequenceByName(sequenceType, chainInstanceSequenceName);
183            
184            if(chainInstanceSequenceName != null && chainInstanceSequence == null) {
185                addExecutionError(ExecutionErrors.UnknownChainInstanceSequenceName.name(), chainInstanceSequenceName);
186            }
187        }
188    }
189
190    @Override
191    public void doUpdate(Chain chain) {
192        var chainControl = Session.getModelController(ChainControl.class);
193        var partyPK = getPartyPK();
194        ChainDetailValue chainDetailValue = chainControl.getChainDetailValueForUpdate(chain);
195        ChainDescription chainDescription = chainControl.getChainDescriptionForUpdate(chain, getPreferredLanguage());
196        String description = edit.getDescription();
197
198        chainDetailValue.setChainName(edit.getChainName());
199        chainDetailValue.setChainInstanceSequencePK(chainInstanceSequence == null ? null : chainInstanceSequence.getPrimaryKey());
200        chainDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
201        chainDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
202
203        chainControl.updateChainFromValue(chainDetailValue, partyPK);
204
205        if(chainDescription == null && description != null) {
206            chainControl.createChainDescription(chain, getPreferredLanguage(), description, partyPK);
207        } else if(chainDescription != null && description == null) {
208            chainControl.deleteChainDescription(chainDescription, partyPK);
209        } else if(chainDescription != null && description != null) {
210            ChainDescriptionValue chainDescriptionValue = chainControl.getChainDescriptionValue(chainDescription);
211
212            chainDescriptionValue.setDescription(description);
213            chainControl.updateChainDescriptionFromValue(chainDescriptionValue, partyPK);
214        }
215    }
216
217}