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.model.control.associate.server.logic;
018
019import com.echothree.control.user.associate.common.spec.AssociateProgramUniversalSpec;
020import com.echothree.model.control.associate.common.exception.CannotDeleteAssociateProgramInUseException;
021import com.echothree.model.control.associate.common.exception.DuplicateAssociateProgramNameException;
022import com.echothree.model.control.associate.common.exception.UnknownAssociateProgramNameException;
023import com.echothree.model.control.associate.common.exception.UnknownDefaultAssociateProgramException;
024import com.echothree.model.control.associate.server.control.AssociateControl;
025import com.echothree.model.control.core.common.ComponentVendors;
026import com.echothree.model.control.core.common.EntityTypes;
027import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
028import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
029import com.echothree.model.data.associate.server.entity.AssociateProgram;
030import com.echothree.model.data.party.server.entity.Language;
031import com.echothree.model.data.sequence.server.entity.Sequence;
032import com.echothree.util.common.message.ExecutionErrors;
033import com.echothree.util.common.persistence.BasePK;
034import com.echothree.util.server.control.BaseLogic;
035import com.echothree.util.server.message.ExecutionErrorAccumulator;
036import com.echothree.util.server.persistence.EntityPermission;
037import javax.enterprise.context.ApplicationScoped;
038import javax.inject.Inject;
039
040@ApplicationScoped
041public class AssociateProgramLogic
042        extends BaseLogic {
043
044    @Inject
045    AssociateControl associateControl;
046
047    @Inject
048    EntityInstanceLogic entityInstanceLogic;
049
050    protected AssociateProgramLogic() {
051        super();
052    }
053
054    public AssociateProgram createAssociateProgram(final ExecutionErrorAccumulator eea, final String associateProgramName,
055            final Sequence associateSequence, final Sequence associatePartyContactMechanismSequence,
056            final Sequence associateReferralSequence, final Integer itemIndirectSalePercent,
057            final Integer itemDirectSalePercent, final Boolean isDefault, final Integer sortOrder,
058            final Language language, final String description, final BasePK createdBy) {
059        var associateProgram = associateControl.getAssociateProgramByName(associateProgramName);
060
061        if(associateProgram == null) {
062            associateProgram = associateControl.createAssociateProgram(associateProgramName, associateSequence,
063                    associatePartyContactMechanismSequence, associateReferralSequence, itemIndirectSalePercent,
064                    itemDirectSalePercent, isDefault, sortOrder, createdBy);
065
066            if(description != null) {
067                associateControl.createAssociateProgramDescription(associateProgram, language, description, createdBy);
068            }
069        } else {
070            handleExecutionError(DuplicateAssociateProgramNameException.class, eea,
071                    ExecutionErrors.DuplicateAssociateProgramName.name(), associateProgramName);
072        }
073
074        return associateProgram;
075    }
076
077    public AssociateProgram getAssociateProgramByName(final ExecutionErrorAccumulator eea,
078            final String associateProgramName, final EntityPermission entityPermission) {
079        var associateProgram = associateControl.getAssociateProgramByName(associateProgramName, entityPermission);
080
081        if(associateProgram == null) {
082            handleExecutionError(UnknownAssociateProgramNameException.class, eea,
083                    ExecutionErrors.UnknownAssociateProgramName.name(), associateProgramName);
084        }
085
086        return associateProgram;
087    }
088
089    public AssociateProgram getAssociateProgramByName(final ExecutionErrorAccumulator eea,
090            final String associateProgramName) {
091        return getAssociateProgramByName(eea, associateProgramName, EntityPermission.READ_ONLY);
092    }
093
094    public AssociateProgram getAssociateProgramByNameForUpdate(final ExecutionErrorAccumulator eea,
095            final String associateProgramName) {
096        return getAssociateProgramByName(eea, associateProgramName, EntityPermission.READ_WRITE);
097    }
098
099    public AssociateProgram getAssociateProgramByUniversalSpec(final ExecutionErrorAccumulator eea,
100            final AssociateProgramUniversalSpec universalSpec, final boolean allowDefault,
101            final EntityPermission entityPermission) {
102        AssociateProgram associateProgram = null;
103        var associateProgramName = universalSpec.getAssociateProgramName();
104        var parameterCount = (associateProgramName == null ? 0 : 1)
105                + entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
106
107        switch(parameterCount) {
108            case 0 -> {
109                if(allowDefault) {
110                    associateProgram = associateControl.getDefaultAssociateProgram(entityPermission);
111
112                    if(associateProgram == null) {
113                        handleExecutionError(UnknownDefaultAssociateProgramException.class, eea,
114                                ExecutionErrors.UnknownDefaultAssociateProgram.name());
115                    }
116                } else {
117                    handleExecutionError(InvalidParameterCountException.class, eea,
118                            ExecutionErrors.InvalidParameterCount.name());
119                }
120            }
121            case 1 -> {
122                if(associateProgramName == null) {
123                    var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
124                            ComponentVendors.ECHO_THREE.name(), EntityTypes.AssociateProgram.name());
125
126                    if(eea == null || !eea.hasExecutionErrors()) {
127                        associateProgram = associateControl.getAssociateProgramByEntityInstance(entityInstance,
128                                entityPermission);
129                    }
130                } else {
131                    associateProgram = getAssociateProgramByName(eea, associateProgramName, entityPermission);
132                }
133            }
134            default -> handleExecutionError(InvalidParameterCountException.class, eea,
135                    ExecutionErrors.InvalidParameterCount.name());
136        }
137
138        return associateProgram;
139    }
140
141    public AssociateProgram getAssociateProgramByUniversalSpec(final ExecutionErrorAccumulator eea,
142            final AssociateProgramUniversalSpec universalSpec, final boolean allowDefault) {
143        return getAssociateProgramByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY);
144    }
145
146    public AssociateProgram getAssociateProgramByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea,
147            final AssociateProgramUniversalSpec universalSpec, final boolean allowDefault) {
148        return getAssociateProgramByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE);
149    }
150
151    public void deleteAssociateProgram(final ExecutionErrorAccumulator eea, final AssociateProgram associateProgram,
152            final BasePK deletedBy) {
153        var associateCount = associateControl.countAssociatesByAssociateProgram(associateProgram);
154
155        if(associateCount == 0) {
156            associateControl.deleteAssociateProgram(associateProgram, deletedBy);
157        } else {
158            handleExecutionError(CannotDeleteAssociateProgramInUseException.class, eea,
159                    ExecutionErrors.CannotDeleteAssociateProgramInUse.name(),
160                    associateProgram.getLastDetail().getAssociateProgramName());
161        }
162    }
163
164}