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.vendor.server.logic;
018
019import com.echothree.control.user.core.common.spec.UniversalEntitySpec;
020import com.echothree.control.user.vendor.common.spec.VendorUniversalSpec;
021import com.echothree.model.control.core.common.ComponentVendors;
022import com.echothree.model.control.core.common.EntityTypes;
023import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
024import com.echothree.model.control.core.server.control.EntityInstanceControl;
025import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
026import com.echothree.model.control.party.common.PartyTypes;
027import com.echothree.model.control.party.common.exception.UnknownPartyNameException;
028import com.echothree.model.control.party.server.control.PartyControl;
029import com.echothree.model.control.party.server.logic.PartyLogic;
030import com.echothree.model.control.sequence.common.SequenceTypes;
031import com.echothree.model.control.sequence.common.exception.MissingDefaultSequenceException;
032import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
033import com.echothree.model.control.user.server.logic.UserKeyLogic;
034import com.echothree.model.control.user.server.logic.UserSessionLogic;
035import com.echothree.model.control.vendor.common.exception.UnknownVendorNameException;
036import com.echothree.model.control.vendor.common.exception.UnknownVendorStatusChoiceException;
037import com.echothree.model.control.vendor.common.workflow.VendorStatusConstants;
038import com.echothree.model.control.vendor.server.control.VendorControl;
039import com.echothree.model.control.workflow.server.control.WorkflowControl;
040import com.echothree.model.control.workflow.server.logic.WorkflowDestinationLogic;
041import com.echothree.model.control.workflow.server.logic.WorkflowLogic;
042import com.echothree.model.data.accounting.server.entity.GlAccount;
043import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy;
044import com.echothree.model.data.filter.server.entity.Filter;
045import com.echothree.model.data.item.server.entity.ItemAliasType;
046import com.echothree.model.data.party.common.pk.PartyPK;
047import com.echothree.model.data.party.server.entity.Party;
048import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy;
049import com.echothree.model.data.selector.server.entity.Selector;
050import com.echothree.model.data.vendor.server.entity.Vendor;
051import com.echothree.model.data.vendor.server.entity.VendorType;
052import com.echothree.util.common.message.ExecutionErrors;
053import com.echothree.util.common.persistence.BasePK;
054import com.echothree.util.server.control.BaseLogic;
055import com.echothree.util.server.message.ExecutionErrorAccumulator;
056import com.echothree.util.server.persistence.EntityPermission;
057import com.echothree.util.server.persistence.Session;
058import javax.enterprise.context.ApplicationScoped;
059import javax.inject.Inject;
060
061@ApplicationScoped
062public class VendorLogic
063        extends BaseLogic {
064
065    @Inject
066    EntityInstanceControl entityInstanceControl;
067
068    @Inject
069    PartyControl partyControl;
070
071    @Inject
072    VendorControl vendorControl;
073
074    @Inject
075    WorkflowControl workflowControl;
076
077    @Inject
078    EntityInstanceLogic entityInstanceLogic;
079
080    @Inject
081    PartyLogic partyLogic;
082
083    @Inject
084    SequenceGeneratorLogic sequenceGeneratorLogic;
085
086    @Inject
087    UserKeyLogic userKeyLogic;
088
089    @Inject
090    UserSessionLogic userSessionLogic;
091
092    @Inject
093    WorkflowDestinationLogic workflowDestinationLogic;
094
095    @Inject
096    WorkflowLogic workflowLogic;
097
098    protected VendorLogic() {
099        super();
100    }
101
102    private String getVendorName(final ExecutionErrorAccumulator eea) {
103        String vendorName = null;
104        var vendorSequence = sequenceGeneratorLogic.getDefaultSequence(eea, SequenceTypes.VENDOR.name());
105
106        if(!hasExecutionErrors(eea)) {
107            vendorName = sequenceGeneratorLogic.getNextSequenceValue(eea, vendorSequence);
108        } else {
109            handleExecutionError(MissingDefaultSequenceException.class, eea, ExecutionErrors.MissingDefaultSequence.name(),
110                    SequenceTypes.VENDOR.name());
111        }
112
113        return vendorName;
114    }
115    
116    public Vendor createVendor(final ExecutionErrorAccumulator eea, final Party party, String vendorName,
117            final VendorType vendorType, final Integer minimumPurchaseOrderLines, final Integer maximumPurchaseOrderLines,
118            final Long minimumPurchaseOrderAmount, final Long maximumPurchaseOrderAmount,
119            final Boolean useItemPurchasingCategories, final ItemAliasType defaultItemAliasType,
120            final CancellationPolicy cancellationPolicy, final ReturnPolicy returnPolicy, final GlAccount apGlAccount,
121            final Boolean holdUntilComplete, final Boolean allowBackorders, final Boolean allowSubstitutions,
122            final Boolean allowCombiningShipments, final Boolean requireReference, final Boolean allowReferenceDuplicates,
123            final String referenceValidationPattern, final Selector vendorItemSelector, final Filter vendorItemCostFilter,
124            final BasePK createdBy) {
125        if(vendorName == null) {
126            vendorName = getVendorName(eea);
127        }
128
129        return vendorControl.createVendor(party, vendorName, vendorType, minimumPurchaseOrderLines, maximumPurchaseOrderLines,
130                minimumPurchaseOrderAmount, maximumPurchaseOrderAmount, useItemPurchasingCategories, defaultItemAliasType,
131                cancellationPolicy, returnPolicy, apGlAccount, holdUntilComplete, allowBackorders, allowSubstitutions,
132                allowCombiningShipments, requireReference, allowReferenceDuplicates, referenceValidationPattern,
133                vendorItemSelector, vendorItemCostFilter, createdBy);
134    }
135
136    public Vendor getVendorByName(final ExecutionErrorAccumulator eea, final String vendorName, final String partyName,
137            final UniversalEntitySpec universalEntitySpec, final EntityPermission entityPermission) {
138        var parameterCount = (vendorName == null ? 0 : 1) + (partyName == null ? 0 : 1) +
139                entityInstanceLogic.countPossibleEntitySpecs(universalEntitySpec);
140        Vendor vendor = null;
141
142        if(parameterCount == 1) {
143            if(vendorName != null) {
144                vendor = vendorControl.getVendorByName(vendorName, entityPermission);
145
146                if(vendor == null) {
147                    handleExecutionError(UnknownVendorNameException.class, eea, ExecutionErrors.UnknownVendorName.name(), vendorName);
148                }
149            } else if(partyName != null) {
150                var party = partyControl.getPartyByName(partyName);
151
152                if(party != null) {
153                    partyLogic.checkPartyType(eea, party, PartyTypes.VENDOR.name());
154
155                    vendor = vendorControl.getVendor(party, entityPermission);
156                } else {
157                    handleExecutionError(UnknownPartyNameException.class, eea, ExecutionErrors.UnknownPartyName.name(), partyName);
158                }
159            } else if(universalEntitySpec != null){
160                var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalEntitySpec,
161                        ComponentVendors.ECHO_THREE.name(), EntityTypes.Party.name());
162
163                if(eea == null || !eea.hasExecutionErrors()) {
164                    var party = partyControl.getPartyByEntityInstance(entityInstance);
165
166                    partyLogic.checkPartyType(eea, party, PartyTypes.VENDOR.name());
167
168                    vendor = vendorControl.getVendor(party, entityPermission);
169                }
170            }
171        } else {
172            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
173        }
174
175        return vendor;
176    }
177
178    public Vendor getVendorByName(final ExecutionErrorAccumulator eea, final String vendorName, final String partyName,
179            final UniversalEntitySpec universalEntitySpec) {
180        return getVendorByName(eea, vendorName, partyName, universalEntitySpec, EntityPermission.READ_ONLY);
181    }
182
183    public Vendor getVendorByNameForUpdate(final ExecutionErrorAccumulator eea, final String vendorName, final String partyName,
184            final UniversalEntitySpec universalEntitySpec) {
185        return getVendorByName(eea, vendorName, partyName, universalEntitySpec, EntityPermission.READ_WRITE);
186    }
187
188    public Vendor getVendorByUniversalSpec(final ExecutionErrorAccumulator eea, final VendorUniversalSpec universalSpec) {
189        return getVendorByName(eea, universalSpec.getVendorName(), universalSpec.getPartyName(), universalSpec);
190    }
191
192    public Vendor getVendorByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final VendorUniversalSpec universalSpec) {
193        return getVendorByNameForUpdate(eea, universalSpec.getVendorName(), universalSpec.getPartyName(), universalSpec);
194    }
195
196    public void setVendorStatus(final Session session, ExecutionErrorAccumulator eea, Party party, String vendorStatusChoice, PartyPK modifiedBy) {
197        var workflow = workflowLogic.getWorkflowByName(eea, VendorStatusConstants.Workflow_VENDOR_STATUS);
198        var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(party.getPrimaryKey());
199        var workflowEntityStatus = workflowControl.getWorkflowEntityStatusByEntityInstanceForUpdate(workflow, entityInstance);
200        var workflowDestination = vendorStatusChoice == null ? null : workflowControl.getWorkflowDestinationByName(workflowEntityStatus.getWorkflowStep(), vendorStatusChoice);
201
202        if(workflowDestination != null || vendorStatusChoice == null) {
203            var currentWorkflowStepName = workflowEntityStatus.getWorkflowStep().getLastDetail().getWorkflowStepName();
204            var map = workflowDestinationLogic.getWorkflowDestinationsAsMap(workflowDestination);
205            Long triggerTime = null;
206
207            if(currentWorkflowStepName.equals(VendorStatusConstants.WorkflowStep_ACTIVE)) {
208                if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, VendorStatusConstants.Workflow_VENDOR_STATUS, VendorStatusConstants.WorkflowStep_INACTIVE)) {
209                    userKeyLogic.clearUserKeysByParty(party);
210                    userSessionLogic.deleteUserSessionsByParty(party);
211                }
212            } else if(currentWorkflowStepName.equals(VendorStatusConstants.WorkflowStep_INACTIVE)) {
213                if(workflowDestinationLogic.workflowDestinationMapContainsStep(map, VendorStatusConstants.Workflow_VENDOR_STATUS, VendorStatusConstants.WorkflowStep_ACTIVE)) {
214                    // Nothing at this time.
215                }
216            }
217
218            if(eea == null || !eea.hasExecutionErrors()) {
219                workflowControl.transitionEntityInWorkflow(eea, workflowEntityStatus, workflowDestination, triggerTime, modifiedBy);
220            }
221        } else {
222            handleExecutionError(UnknownVendorStatusChoiceException.class, eea, ExecutionErrors.UnknownVendorStatusChoice.name(), vendorStatusChoice);
223        }
224    }
225
226}