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.contact.server.logic;
018
019import com.echothree.control.user.contact.common.spec.ContactMechanismUniversalSpec;
020import com.echothree.model.control.contact.common.exception.CannotDeleteContactMechanismInUseException;
021import com.echothree.model.control.contact.common.exception.UnknownContactMechanismNameException;
022import com.echothree.model.control.contact.server.control.ContactControl;
023import com.echothree.model.control.core.common.ComponentVendors;
024import com.echothree.model.control.core.common.EntityTypes;
025import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
026import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
027import com.echothree.model.control.payment.server.control.PartyPaymentMethodControl;
028import com.echothree.model.data.contact.server.entity.ContactMechanism;
029import com.echothree.model.data.party.common.pk.PartyPK;
030import com.echothree.util.common.message.ExecutionErrors;
031import com.echothree.util.server.control.BaseLogic;
032import com.echothree.util.server.message.ExecutionErrorAccumulator;
033import com.echothree.util.server.persistence.EntityPermission;
034import javax.enterprise.context.ApplicationScoped;
035import javax.enterprise.inject.spi.CDI;
036import javax.inject.Inject;
037
038@ApplicationScoped
039public class ContactMechanismLogic
040    extends BaseLogic {
041
042    @Inject
043    ContactControl contactControl;
044
045    @Inject
046    PartyPaymentMethodControl partyPaymentMethodControl;
047
048    @Inject
049    EntityInstanceLogic entityInstanceLogic;
050
051    protected ContactMechanismLogic() {
052        super();
053    }
054
055    public static ContactMechanismLogic getInstance() {
056        return CDI.current().select(ContactMechanismLogic.class).get();
057    }
058
059    public ContactMechanism getContactMechanismByName(final ExecutionErrorAccumulator eea, final String contactMechanismName,
060            final EntityPermission entityPermission) {
061        var contactMechanism = contactControl.getContactMechanismByName(contactMechanismName, entityPermission);
062
063        if(contactMechanism == null) {
064            handleExecutionError(UnknownContactMechanismNameException.class, eea, ExecutionErrors.UnknownContactMechanismName.name(), contactMechanismName);
065        }
066
067        return contactMechanism;
068    }
069
070    public ContactMechanism getContactMechanismByName(final ExecutionErrorAccumulator eea, final String contactMechanismName) {
071        return getContactMechanismByName(eea, contactMechanismName, EntityPermission.READ_ONLY);
072    }
073
074    public ContactMechanism getContactMechanismByNameForUpdate(final ExecutionErrorAccumulator eea, final String contactMechanismName) {
075        return getContactMechanismByName(eea, contactMechanismName, EntityPermission.READ_WRITE);
076    }
077
078    public ContactMechanism getContactMechanismByUniversalSpec(final ExecutionErrorAccumulator eea,
079            final ContactMechanismUniversalSpec universalSpec, final EntityPermission entityPermission) {
080        ContactMechanism contactMechanism = null;
081        var contactMechanismName = universalSpec.getContactMechanismName();
082        var parameterCount = (contactMechanismName == null ? 0 : 1) + entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
083
084        switch(parameterCount) {
085            case 1 -> {
086                if(contactMechanismName == null) {
087                    var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
088                            ComponentVendors.ECHO_THREE.name(), EntityTypes.ContactMechanism.name());
089
090                    if(eea == null || !eea.hasExecutionErrors()) {
091                        contactMechanism = contactControl.getContactMechanismByEntityInstance(entityInstance, entityPermission);
092                    }
093                } else {
094                    contactMechanism = getContactMechanismByName(eea, contactMechanismName, entityPermission);
095                }
096            }
097            default ->
098                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
099        }
100
101        return contactMechanism;
102    }
103
104    public ContactMechanism getContactMechanismByUniversalSpec(final ExecutionErrorAccumulator eea,
105            final ContactMechanismUniversalSpec universalSpec) {
106        return getContactMechanismByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY);
107    }
108
109    public ContactMechanism getContactMechanismByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea,
110            final ContactMechanismUniversalSpec universalSpec) {
111        return getContactMechanismByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE);
112    }
113
114    public void deleteContactMechanism(final ExecutionErrorAccumulator eea, final ContactMechanism contactMechanism,
115            final PartyPK deletedBy) {
116        var cannotDeleteContactMechanismInUse = false;
117
118        // Check if the ContactMechanism is in-use by any PartyPaymentMethodCreditCard.
119        var partyContactMechanisms = contactControl.getPartyContactMechanismsByContactMechanism(contactMechanism);
120        for(var partyContactMechanism : partyContactMechanisms) {
121            if(partyPaymentMethodControl.countPartyPaymentMethodCreditCardsByIssuerPartyContactMechanism(partyContactMechanism) != 0
122                    || partyPaymentMethodControl.countPartyPaymentMethodCreditCardsByBillingPartyContactMechanism(partyContactMechanism) != 0) {
123                cannotDeleteContactMechanismInUse = true;
124                break;
125            }
126        }
127
128        if(cannotDeleteContactMechanismInUse) {
129            handleExecutionError(CannotDeleteContactMechanismInUseException.class, eea, ExecutionErrors.CannotDeleteContactMechanismInUse.name(),
130                    contactMechanism.getLastDetail().getContactMechanismName());
131        }
132
133        if(eea == null || !eea.hasExecutionErrors()) {
134            contactControl.deleteContactMechanism(contactMechanism, deletedBy);
135        }
136    }
137
138    public void deleteContactMechanism(final ExecutionErrorAccumulator eea, final String contactMechanismName,
139            final PartyPK deletedBy) {
140        var contactMechanism = getContactMechanismByNameForUpdate(eea, contactMechanismName);
141
142        if(eea == null || !eea.hasExecutionErrors()) {
143            deleteContactMechanism(eea, contactMechanism, deletedBy);
144        }
145    }
146
147}