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.model.control.offer.server.logic; 018 019import com.echothree.control.user.offer.common.spec.OfferUniversalSpec; 020import com.echothree.model.control.core.common.ComponentVendors; 021import com.echothree.model.control.core.common.EntityTypes; 022import com.echothree.model.control.core.common.exception.InvalidParameterCountException; 023import com.echothree.model.control.core.server.logic.EntityInstanceLogic; 024import com.echothree.model.control.offer.common.exception.CannotDeleteOfferInUseException; 025import com.echothree.model.control.offer.common.exception.DuplicateOfferNameException; 026import com.echothree.model.control.offer.common.exception.UnknownDefaultOfferException; 027import com.echothree.model.control.offer.common.exception.UnknownOfferNameException; 028import com.echothree.model.control.offer.server.control.OfferControl; 029import com.echothree.model.control.offer.server.control.OfferItemControl; 030import com.echothree.model.control.offer.server.control.OfferUseControl; 031import com.echothree.model.data.filter.server.entity.Filter; 032import com.echothree.model.data.offer.server.entity.Offer; 033import com.echothree.model.data.offer.server.factory.OfferFactory; 034import com.echothree.model.data.offer.server.value.OfferDetailValue; 035import com.echothree.model.data.party.server.entity.Language; 036import com.echothree.model.data.party.server.entity.Party; 037import com.echothree.model.data.selector.server.entity.Selector; 038import com.echothree.model.data.sequence.server.entity.Sequence; 039import com.echothree.util.common.message.ExecutionErrors; 040import com.echothree.util.common.persistence.BasePK; 041import com.echothree.util.server.control.BaseLogic; 042import com.echothree.util.server.message.ExecutionErrorAccumulator; 043import com.echothree.util.server.persistence.EntityPermission; 044import com.echothree.util.server.persistence.Session; 045import javax.enterprise.context.ApplicationScoped; 046import javax.enterprise.inject.spi.CDI; 047 048@ApplicationScoped 049public class OfferLogic 050 extends BaseLogic { 051 052 protected OfferLogic() { 053 super(); 054 } 055 056 public static OfferLogic getInstance() { 057 return CDI.current().select(OfferLogic.class).get(); 058 } 059 060 public Offer createOffer(final ExecutionErrorAccumulator eea, final String offerName, final Sequence salesOrderSequence, 061 final Party departmentParty, final Selector offerItemSelector, final Filter offerItemPriceFilter, final Boolean isDefault, 062 final Integer sortOrder, final Language language, final String description, final BasePK createdBy) { 063 var offerControl = Session.getModelController(OfferControl.class); 064 var offer = offerControl.getOfferByName(offerName); 065 066 if(offer == null) { 067 offer = offerControl.createOffer(offerName, salesOrderSequence, departmentParty, offerItemSelector, 068 offerItemPriceFilter, isDefault, sortOrder, createdBy); 069 070 if(description != null) { 071 offerControl.createOfferDescription(offer, language, description, createdBy); 072 } 073 } else { 074 handleExecutionError(DuplicateOfferNameException.class, eea, ExecutionErrors.DuplicateOfferName.name(), offerName); 075 } 076 077 return offer; 078 } 079 080 public Offer getOfferByName(final ExecutionErrorAccumulator eea, final String offerName, 081 final EntityPermission entityPermission) { 082 var offerControl = Session.getModelController(OfferControl.class); 083 var offer = offerControl.getOfferByName(offerName, entityPermission); 084 085 if(offer == null) { 086 handleExecutionError(UnknownOfferNameException.class, eea, ExecutionErrors.UnknownOfferName.name(), offerName); 087 } 088 089 return offer; 090 } 091 092 public Offer getOfferByName(final ExecutionErrorAccumulator eea, final String offerName) { 093 return getOfferByName(eea, offerName, EntityPermission.READ_ONLY); 094 } 095 096 public Offer getOfferByNameForUpdate(final ExecutionErrorAccumulator eea, final String offerName) { 097 return getOfferByName(eea, offerName, EntityPermission.READ_WRITE); 098 } 099 100 public Offer getOfferByUniversalSpec(final ExecutionErrorAccumulator eea, 101 final OfferUniversalSpec universalSpec, boolean allowDefault, final EntityPermission entityPermission) { 102 Offer offer = null; 103 var offerControl = Session.getModelController(OfferControl.class); 104 var offerName = universalSpec.getOfferName(); 105 var parameterCount = (offerName == null ? 0 : 1) + EntityInstanceLogic.getInstance().countPossibleEntitySpecs(universalSpec); 106 107 switch(parameterCount) { 108 case 0 -> { 109 if(allowDefault) { 110 offer = offerControl.getDefaultOffer(entityPermission); 111 112 if(offer == null) { 113 handleExecutionError(UnknownDefaultOfferException.class, eea, ExecutionErrors.UnknownDefaultOffer.name()); 114 } 115 } else { 116 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 117 } 118 } 119 case 1 -> { 120 if(offerName == null) { 121 var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, universalSpec, 122 ComponentVendors.ECHO_THREE.name(), EntityTypes.Offer.name()); 123 124 if(!eea.hasExecutionErrors()) { 125 offer = offerControl.getOfferByEntityInstance(entityInstance, entityPermission); 126 } 127 } else { 128 offer = getOfferByName(eea, offerName, entityPermission); 129 } 130 } 131 default -> 132 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 133 } 134 135 return offer; 136 } 137 138 public Offer getOfferByUniversalSpec(final ExecutionErrorAccumulator eea, 139 final OfferUniversalSpec universalSpec, boolean allowDefault) { 140 return getOfferByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY); 141 } 142 143 public Offer getOfferByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, 144 final OfferUniversalSpec universalSpec, boolean allowDefault) { 145 return getOfferByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE); 146 } 147 148 public void updateOfferFromValue(OfferDetailValue offerDetailValue, BasePK updatedBy) { 149 var offerControl = Session.getModelController(OfferControl.class); 150 151 if(offerDetailValue.getOfferItemSelectorPKHasBeenModified() && offerDetailValue.getOfferItemSelectorPK() != null) { 152 var offer = OfferFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE, offerDetailValue.getOfferPK()); 153 154 OfferItemLogic.getInstance().deleteOfferItemsByOffer(offer, updatedBy); 155 } else if(offerDetailValue.getOfferItemPriceFilterPKHasBeenModified() && offerDetailValue.getOfferItemPriceFilterPK() != null) { 156 var offerItemControl = Session.getModelController(OfferItemControl.class); 157 var offer = OfferFactory.getInstance().getEntityFromPK(EntityPermission.READ_WRITE, offerDetailValue.getOfferPK()); 158 159 var offerItems = offerItemControl.getOfferItemsByOffer(offer); 160 for(var offerItem : offerItems) { 161 var offerItemPrices = offerItemControl.getOfferItemPricesByOfferItemForUpdate(offerItem); 162 163 for(var offerItemPrice : offerItemPrices) { 164 offerItemControl.deleteOfferItemPrice(offerItemPrice, updatedBy); 165 } 166 } 167 } 168 169 offerControl.updateOfferFromValue(offerDetailValue, updatedBy); 170 } 171 172 public void deleteOffer(final ExecutionErrorAccumulator eea, final Offer offer, final BasePK deletedBy) { 173 var offerUseControl = Session.getModelController(OfferUseControl.class); 174 175 if(offerUseControl.countOfferUsesByOffer(offer) == 0) { 176 var offerControl = Session.getModelController(OfferControl.class); 177 178 offerControl.deleteOffer(offer, deletedBy); 179 } else { 180 handleExecutionError(CannotDeleteOfferInUseException.class, eea, ExecutionErrors.CannotDeleteOfferInUse.name()); 181 } 182 } 183 184}