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.chain.server.logic;
018
019import com.echothree.model.control.chain.common.exception.UnknownChainEntityRoleTypeNameException;
020import com.echothree.model.control.chain.common.exception.UnknownChainKindNameException;
021import com.echothree.model.control.chain.common.exception.UnknownChainTypeNameException;
022import com.echothree.model.control.chain.server.control.ChainControl;
023import com.echothree.model.control.customer.server.control.CustomerControl;
024import com.echothree.model.control.offer.server.control.OfferControl;
025import com.echothree.model.control.sequence.common.SequenceTypes;
026import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
027import com.echothree.model.data.chain.server.entity.Chain;
028import com.echothree.model.data.chain.server.entity.ChainActionSet;
029import com.echothree.model.data.chain.server.entity.ChainEntityRoleType;
030import com.echothree.model.data.chain.server.entity.ChainInstance;
031import com.echothree.model.data.chain.server.entity.ChainInstanceEntityRole;
032import com.echothree.model.data.chain.server.entity.ChainKind;
033import com.echothree.model.data.chain.server.entity.ChainType;
034import com.echothree.model.data.core.server.entity.EntityInstance;
035import com.echothree.model.data.customer.server.entity.Customer;
036import com.echothree.model.data.offer.server.entity.OfferChainType;
037import com.echothree.model.data.offer.server.entity.OfferUse;
038import com.echothree.model.data.party.server.entity.Party;
039import com.echothree.model.data.sequence.server.entity.Sequence;
040import com.echothree.util.common.message.ExecutionErrors;
041import com.echothree.util.common.persistence.BasePK;
042import com.echothree.util.server.control.BaseLogic;
043import com.echothree.util.server.message.ExecutionErrorAccumulator;
044import com.echothree.util.server.persistence.Session;
045import java.util.HashSet;
046import java.util.List;
047import java.util.Set;
048
049public class BaseChainLogic
050        extends BaseLogic {
051    
052    protected BaseChainLogic() {
053        super();
054    }
055    
056    public ChainKind getChainKindByName(final ExecutionErrorAccumulator eea, final String chainKindName) {
057        var chainControl = Session.getModelController(ChainControl.class);
058        ChainKind chainKind = chainControl.getChainKindByName(chainKindName);
059
060        if(chainKind == null) {
061            handleExecutionError(UnknownChainKindNameException.class, eea, ExecutionErrors.UnknownChainKindName.name(), chainKindName);
062        }
063
064        return chainKind;
065    }
066
067    public ChainType getChainTypeByName(final ExecutionErrorAccumulator eea, final ChainKind chainKind, final String chainTypeName) {
068        var chainControl = Session.getModelController(ChainControl.class);
069        ChainType chainType = chainControl.getChainTypeByName(chainKind, chainTypeName);
070
071        if(chainType == null) {
072            handleExecutionError(UnknownChainTypeNameException.class, eea, ExecutionErrors.UnknownChainTypeName.name(), chainKind.getLastDetail().getChainKindName(),
073                    chainTypeName);
074        }
075        
076        return chainType;
077    }
078    
079   public ChainType getChainTypeByName(final ExecutionErrorAccumulator eea, final String chainKindName, final String chainTypeName) {
080        ChainKind chainKind = getChainKindByName(eea, chainKindName);
081        ChainType chainType = null;
082        
083        if(chainKind != null) {
084            chainType = getChainTypeByName(eea, chainKind, chainTypeName);
085        }
086        
087        return chainType;
088    }
089    
090    public ChainEntityRoleType getChainEntityRoleTypeByName(final ExecutionErrorAccumulator eea, final ChainType chainType, final String chainEntityRoleTypeName) {
091        var chainControl = Session.getModelController(ChainControl.class);
092        ChainEntityRoleType chainEntityRoleType = chainControl.getChainEntityRoleTypeByName(chainType, chainEntityRoleTypeName);
093
094        if(chainEntityRoleType == null) {
095            handleExecutionError(UnknownChainEntityRoleTypeNameException.class, eea, ExecutionErrors.UnknownChainEntityRoleTypeName.name(),
096                    chainType.getLastDetail().getChainTypeName(), chainEntityRoleTypeName);
097        }
098        
099        return chainEntityRoleType;
100    }
101    
102    protected long countChainInstanceEntityRolesByChainEntityRoleType(final ChainEntityRoleType chainEntityRoleType) {
103        var chainControl = Session.getModelController(ChainControl.class);
104        
105        return chainControl.countChainInstanceEntityRolesByChainEntityRoleType(chainEntityRoleType);
106    }
107
108    protected long countChainInstanceEntityRolesByEntityInstance(final EntityInstance entityInstance) {
109        var chainControl = Session.getModelController(ChainControl.class);
110        
111        return chainControl.countChainInstanceEntityRolesByEntityInstance(entityInstance);
112    }
113
114    protected long countChainInstanceEntityRoles(final ChainEntityRoleType chainEntityRoleType, final EntityInstance entityInstance) {
115        var chainControl = Session.getModelController(ChainControl.class);
116        
117        return chainControl.countChainInstanceEntityRoles(chainEntityRoleType, entityInstance);
118    }
119
120    protected Long countChainInstanceEntityRoles(final ExecutionErrorAccumulator eea, final ChainType chainType, final String chainEntityRoleTypeName,
121            final EntityInstance entityInstance) {
122        ChainEntityRoleType chainEntityRoleType = getChainEntityRoleTypeByName(eea, chainType, chainEntityRoleTypeName);
123        
124        return chainEntityRoleType == null ? null : countChainInstanceEntityRoles(chainEntityRoleType, entityInstance);
125    }
126    
127    protected Chain getChain(final ExecutionErrorAccumulator eea, final ChainType chainType, final Party party) {
128        var chainControl = Session.getModelController(ChainControl.class);
129        var offerControl = Session.getModelController(OfferControl.class);
130        var customerControl = Session.getModelController(CustomerControl.class);
131        Customer customer = customerControl.getCustomer(party);
132        OfferUse initialOfferUse = customer == null ? null : customer.getInitialOfferUse();
133        OfferChainType offerChainType = initialOfferUse == null ? null : offerControl.getOfferChainType(initialOfferUse.getLastDetail().getOffer(), chainType);
134
135        return offerChainType == null ? chainControl.getDefaultChain(chainType) : offerChainType.getChain();
136    }
137
138    protected ChainInstance createChainInstance(final ExecutionErrorAccumulator eea, final Chain chain, final BasePK createdBy) {
139        var chainControl = Session.getModelController(ChainControl.class);
140        ChainActionSet defaultChainActionSet = chainControl.getDefaultChainActionSet(chain);
141        ChainInstance chainInstance = null;
142        
143        // The lack of a defaultChainActionSet is not a reportable error - it just silently avoids creating a Chain Instance.
144        if(defaultChainActionSet != null) {
145            Sequence sequence = chain.getLastDetail().getChainInstanceSequence();
146
147            if(sequence == null) {
148                sequence = SequenceGeneratorLogic.getInstance().getDefaultSequence(eea, SequenceTypes.CHAIN_INSTANCE.name());
149            }
150
151            if(!hasExecutionErrors(eea)) {
152                chainInstance = chainControl.createChainInstance(SequenceGeneratorLogic.getInstance().getNextSequenceValue(sequence), defaultChainActionSet, createdBy);
153            }
154        }
155        
156        return chainInstance;
157    }
158    
159    protected ChainInstance createChainInstance(final ExecutionErrorAccumulator eea, final ChainType chainType, final Party party, final BasePK createdBy) {
160        Chain chain = getChain(eea, chainType, party);
161        ChainInstance chainInstance = null;
162
163        if(chain != null) {
164            chainInstance = createChainInstance(eea, chain, createdBy);
165        }
166
167        return chainInstance;
168    }
169    
170    protected ChainInstance createChainInstance(final ExecutionErrorAccumulator eea, final String chainKindName, final String chainTypeName, final Party party,
171            final BasePK createdBy) {
172        ChainType chainType = getChainTypeByName(eea, chainKindName, chainTypeName);
173        ChainInstance chainInstance = null;
174
175        if(!hasExecutionErrors(eea)) {
176            chainInstance = createChainInstance(eea, chainType, party, createdBy);
177        }
178
179        return chainInstance;
180    }
181    
182    protected void deleteChainInstancedByChainEntityRoleTypeAndEntityInstance(final ChainEntityRoleType chainEntityRoleType, final EntityInstance entityInstance,
183            final BasePK deletedBy) {
184        var chainControl = Session.getModelController(ChainControl.class);
185        List<ChainInstanceEntityRole> chainInstanceEntityRoles = chainControl.getChainInstanceEntityRoles(chainEntityRoleType, entityInstance);
186        Set<ChainInstance> chainInstances = new HashSet<>();
187        
188        chainInstanceEntityRoles.forEach((chainInstanceEntityRole) -> {
189            chainInstances.add(chainInstanceEntityRole.getChainInstanceForUpdate());
190        });
191        
192        chainControl.deleteChainInstances(chainInstances, deletedBy);
193    }
194    
195}