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.associate.server.command;
018
019import com.echothree.control.user.associate.common.edit.AssociateEditFactory;
020import com.echothree.control.user.associate.common.edit.AssociateProgramEdit;
021import com.echothree.control.user.associate.common.form.EditAssociateProgramForm;
022import com.echothree.control.user.associate.common.result.AssociateResultFactory;
023import com.echothree.control.user.associate.common.spec.AssociateProgramSpec;
024import com.echothree.model.control.associate.server.control.AssociateControl;
025import com.echothree.model.control.sequence.common.SequenceTypes;
026import com.echothree.model.control.sequence.server.control.SequenceControl;
027import com.echothree.model.data.sequence.server.entity.Sequence;
028import com.echothree.model.data.user.common.pk.UserVisitPK;
029import com.echothree.util.common.command.BaseResult;
030import com.echothree.util.common.command.EditMode;
031import com.echothree.util.common.message.ExecutionErrors;
032import com.echothree.util.common.validation.FieldDefinition;
033import com.echothree.util.common.validation.FieldType;
034import com.echothree.util.server.control.BaseEditCommand;
035import com.echothree.util.server.persistence.Session;
036import com.echothree.util.server.string.PercentUtils;
037import java.util.ArrayList;
038import java.util.Collections;
039import java.util.List;
040import javax.enterprise.context.RequestScoped;
041
042@RequestScoped
043public class EditAssociateProgramCommand
044        extends BaseEditCommand<AssociateProgramSpec, AssociateProgramEdit> {
045    
046    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
047    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
048    
049    static {
050        List<FieldDefinition> temp = new ArrayList<>(1);
051        temp.add(new FieldDefinition("AssociateProgramName", FieldType.ENTITY_NAME, true, null, null));
052        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(temp);
053        
054        temp = new ArrayList<>(4);
055        temp.add(new FieldDefinition("AssociateProgramName", FieldType.ENTITY_NAME, true, null, null));
056        temp.add(new FieldDefinition("AssociateSequenceName", FieldType.ENTITY_NAME, false, null, null));
057        temp.add(new FieldDefinition("AssociatePartyContactMechanismSequenceName", FieldType.ENTITY_NAME, false, null, null));
058        temp.add(new FieldDefinition("AssociateReferralSequenceName", FieldType.ENTITY_NAME, false, null, null));
059        temp.add(new FieldDefinition("ItemIndirectSalePercent", FieldType.FRACTIONAL_PERCENT, false, null, null));
060        temp.add(new FieldDefinition("ItemDirectSalePercent", FieldType.FRACTIONAL_PERCENT, false, null, null));
061        temp.add(new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null));
062        temp.add(new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null));
063        temp.add(new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L));
064        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(temp);
065    }
066    
067    /** Creates a new instance of EditAssociateProgramCommand */
068    public EditAssociateProgramCommand() {
069        super(null, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
070    }
071    
072    @Override
073    protected BaseResult execute() {
074        var associateControl = Session.getModelController(AssociateControl.class);
075        var result = AssociateResultFactory.getEditAssociateProgramResult();
076        
077        if(editMode.equals(EditMode.LOCK)) {
078            var associateProgramName = spec.getAssociateProgramName();
079            var associateProgram = associateControl.getAssociateProgramByName(associateProgramName);
080            
081            if(associateProgram != null) {
082                result.setAssociateProgram(associateControl.getAssociateProgramTransfer(getUserVisit(), associateProgram));
083                
084                if(lockEntity(associateProgram)) {
085                    var associateProgramDescription = associateControl.getAssociateProgramDescription(associateProgram, getPreferredLanguage());
086                    var edit = AssociateEditFactory.getAssociateProgramEdit();
087                    var associateProgramDetail = associateProgram.getLastDetail();
088                    var associateSequence = associateProgramDetail.getAssociateSequence();
089                    var associatePartyContactMechanismSequence = associateProgramDetail.getAssociatePartyContactMechanismSequence();
090                    var associateReferralSequence = associateProgramDetail.getAssociateReferralSequence();
091                    
092                    result.setEdit(edit);
093                    edit.setAssociateProgramName(associateProgramDetail.getAssociateProgramName());
094                    edit.setAssociateSequenceName(associateSequence == null? null: associateSequence.getLastDetail().getSequenceName());
095                    edit.setAssociatePartyContactMechanismSequenceName(associatePartyContactMechanismSequence == null? null: associatePartyContactMechanismSequence.getLastDetail().getSequenceName());
096                    edit.setAssociateReferralSequenceName(associateReferralSequence == null? null: associateReferralSequence.getLastDetail().getSequenceName());
097                    edit.setItemIndirectSalePercent(PercentUtils.getInstance().formatFractionalPercent(associateProgramDetail.getItemIndirectSalePercent()));
098                    edit.setItemDirectSalePercent(PercentUtils.getInstance().formatFractionalPercent(associateProgramDetail.getItemDirectSalePercent()));
099                    edit.setIsDefault(associateProgramDetail.getIsDefault().toString());
100                    edit.setSortOrder(associateProgramDetail.getSortOrder().toString());
101                    
102                    if(associateProgramDescription != null)
103                        edit.setDescription(associateProgramDescription.getDescription());
104                } else {
105                    addExecutionError(ExecutionErrors.EntityLockFailed.name());
106                }
107                
108                result.setEntityLock(getEntityLockTransfer(associateProgram));
109            } else {
110                addExecutionError(ExecutionErrors.UnknownAssociateProgramName.name(), associateProgramName);
111            }
112        } else if(editMode.equals(EditMode.UPDATE)) {
113            var associateProgramName = spec.getAssociateProgramName();
114            var associateProgram = associateControl.getAssociateProgramByNameForUpdate(associateProgramName);
115            
116            if(associateProgram != null) {
117                associateProgramName = edit.getAssociateProgramName();
118                var duplicateAssociateProgram = associateControl.getAssociateProgramByName(associateProgramName);
119                
120                if(duplicateAssociateProgram == null || associateProgram.equals(duplicateAssociateProgram)) {
121                    var sequenceControl = Session.getModelController(SequenceControl.class);
122                    var associateSequenceName = edit.getAssociateSequenceName();
123                    Sequence associateSequence = null;
124                    
125                    if(associateSequenceName != null) {
126                        var sequenceType = sequenceControl.getSequenceTypeByName(SequenceTypes.ASSOCIATE.name());
127                        
128                        if(sequenceType != null) {
129                            associateSequence = sequenceControl.getSequenceByName(sequenceType, associateSequenceName);
130                        } else {
131                            addExecutionError(ExecutionErrors.UnknownSequenceTypeName.name(), SequenceTypes.ASSOCIATE.name());
132                        }
133                    }
134                    
135                    if(associateSequenceName == null || associateSequence != null) {
136                        var associatePartyContactMechanismSequenceName = edit.getAssociatePartyContactMechanismSequenceName();
137                        Sequence associatePartyContactMechanismSequence = null;
138                        
139                        if(associatePartyContactMechanismSequenceName != null) {
140                            var sequenceType = sequenceControl.getSequenceTypeByName(SequenceTypes.ASSOCIATE_PARTY_CONTACT_MECHANISM.name());
141                            
142                            if(sequenceType != null) {
143                                associatePartyContactMechanismSequence = sequenceControl.getSequenceByName(sequenceType, associatePartyContactMechanismSequenceName);
144                            } else {
145                                addExecutionError(ExecutionErrors.UnknownSequenceTypeName.name(), SequenceTypes.ASSOCIATE_PARTY_CONTACT_MECHANISM.name());
146                            }
147                        }
148                        
149                        if(associatePartyContactMechanismSequenceName == null || associatePartyContactMechanismSequence != null) {
150                            var associateReferralSequenceName = edit.getAssociateReferralSequenceName();
151                            Sequence associateReferralSequence = null;
152                            
153                            if(associateReferralSequenceName != null) {
154                                var sequenceType = sequenceControl.getSequenceTypeByName(SequenceTypes.ASSOCIATE_REFERRAL.name());
155                                
156                                if(sequenceType != null) {
157                                    associateReferralSequence = sequenceControl.getSequenceByName(sequenceType, associateReferralSequenceName);
158                                } else {
159                                    addExecutionError(ExecutionErrors.UnknownSequenceTypeName.name(), SequenceTypes.ASSOCIATE_REFERRAL.name());
160                                }
161                            }
162                            
163                            if(associateReferralSequenceName == null || associateReferralSequence != null) {
164                                if(lockEntityForUpdate(associateProgram)) {
165                                    try {
166                                        var partyPK = getPartyPK();
167                                        var strItemIndirectSalePercent = edit.getItemIndirectSalePercent();
168                                        var strItemDirectSalePercent = edit.getItemDirectSalePercent();
169                                        var associateProgramDetailValue = associateControl.getAssociateProgramDetailValueForUpdate(associateProgram);
170                                        var associateProgramDescription = associateControl.getAssociateProgramDescriptionForUpdate(associateProgram, getPreferredLanguage());
171                                        var description = edit.getDescription();
172                                        
173                                        associateProgramDetailValue.setAssociateProgramName(edit.getAssociateProgramName());
174                                        associateProgramDetailValue.setAssociateSequencePK(associateSequence == null? null: associateSequence.getPrimaryKey());
175                                        associateProgramDetailValue.setAssociatePartyContactMechanismSequencePK(associatePartyContactMechanismSequence == null? null: associatePartyContactMechanismSequence.getPrimaryKey());
176                                        associateProgramDetailValue.setAssociateReferralSequencePK(associateReferralSequence == null? null: associateReferralSequence.getPrimaryKey());
177                                        associateProgramDetailValue.setItemIndirectSalePercent(strItemIndirectSalePercent == null? null: Integer.valueOf(strItemIndirectSalePercent));
178                                        associateProgramDetailValue.setItemDirectSalePercent(strItemDirectSalePercent == null? null: Integer.valueOf(strItemDirectSalePercent));
179                                        associateProgramDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
180                                        associateProgramDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
181                                        
182                                        associateControl.updateAssociateProgramFromValue(associateProgramDetailValue, partyPK);
183                                        
184                                        if(associateProgramDescription == null && description != null) {
185                                            associateControl.createAssociateProgramDescription(associateProgram, getPreferredLanguage(), description, partyPK);
186                                        } else if(associateProgramDescription != null && description == null) {
187                                            associateControl.deleteAssociateProgramDescription(associateProgramDescription, partyPK);
188                                        } else if(associateProgramDescription != null && description != null) {
189                                            var associateProgramDescriptionValue = associateControl.getAssociateProgramDescriptionValue(associateProgramDescription);
190                                            
191                                            associateProgramDescriptionValue.setDescription(description);
192                                            associateControl.updateAssociateProgramDescriptionFromValue(associateProgramDescriptionValue, partyPK);
193                                        }
194                                    } finally {
195                                        unlockEntity(associateProgram);
196                                    }
197                                } else {
198                                    addExecutionError(ExecutionErrors.EntityLockStale.name());
199                                }
200                            } else {
201                                addExecutionError(ExecutionErrors.UnknownSequenceName.name(), associateReferralSequenceName);
202                            }
203                        } else {
204                            addExecutionError(ExecutionErrors.UnknownSequenceName.name(), associatePartyContactMechanismSequenceName);
205                        }
206                    } else {
207                        addExecutionError(ExecutionErrors.UnknownSequenceName.name(), associateSequenceName);
208                    }
209                } else {
210                    addExecutionError(ExecutionErrors.DuplicateAssociateProgramName.name(), associateProgramName);
211                }
212            } else {
213                addExecutionError(ExecutionErrors.UnknownAssociateProgramName.name(), associateProgramName);
214            }
215        }
216        
217        return result;
218    }
219    
220}