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