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