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.warehouse.server.logic;
018
019import com.echothree.control.user.core.common.spec.UniversalEntitySpec;
020import com.echothree.control.user.warehouse.common.spec.WarehouseUniversalSpec;
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.logic.EntityInstanceLogic;
025import com.echothree.model.control.party.common.PartyTypes;
026import com.echothree.model.control.party.common.exception.UnknownPartyNameException;
027import com.echothree.model.control.party.server.control.PartyControl;
028import com.echothree.model.control.party.server.logic.PartyLogic;
029import com.echothree.model.control.warehouse.common.exception.DuplicateWarehouseNameException;
030import com.echothree.model.control.warehouse.common.exception.UnknownDefaultWarehouseException;
031import com.echothree.model.control.warehouse.common.exception.UnknownWarehouseNameException;
032import com.echothree.model.control.warehouse.server.control.WarehouseControl;
033import com.echothree.model.data.accounting.server.entity.Currency;
034import com.echothree.model.data.party.server.entity.DateTimeFormat;
035import com.echothree.model.data.party.server.entity.Language;
036import com.echothree.model.data.party.server.entity.Party;
037import com.echothree.model.data.party.server.entity.TimeZone;
038import com.echothree.model.data.warehouse.server.entity.Warehouse;
039import com.echothree.model.data.warehouse.server.entity.WarehouseType;
040import com.echothree.model.data.warehouse.server.value.WarehouseValue;
041import com.echothree.util.common.message.ExecutionErrors;
042import com.echothree.util.common.persistence.BasePK;
043import com.echothree.util.server.control.BaseLogic;
044import com.echothree.util.server.message.ExecutionErrorAccumulator;
045import com.echothree.util.server.persistence.EntityPermission;
046import javax.enterprise.context.ApplicationScoped;
047import javax.inject.Inject;
048
049@ApplicationScoped
050public class WarehouseLogic
051        extends BaseLogic {
052
053    @Inject
054    PartyControl partyControl;
055
056    @Inject
057    WarehouseControl warehouseControl;
058
059    @Inject
060    EntityInstanceLogic entityInstanceLogic;
061
062    @Inject
063    PartyLogic partyLogic;
064
065    protected WarehouseLogic() {
066        super();
067    }
068
069    public Warehouse createWarehouse(final ExecutionErrorAccumulator eea, final String warehouseName, final WarehouseType warehouseType,
070            final Language preferredLanguage, final Currency preferredCurrency, final TimeZone preferredTimeZone,
071            final DateTimeFormat preferredDateTimeFormat, final String name, final Boolean isDefault, final Integer sortOrder,
072            final BasePK createdBy) {
073        var warehouse = warehouseControl.getWarehouseByName(warehouseName);
074
075        if(warehouse == null) {
076            var partyType = partyControl.getPartyTypeByName(PartyTypes.WAREHOUSE.name());
077            var party = partyControl.createParty(null, partyType, preferredLanguage, preferredCurrency,
078                    preferredTimeZone, preferredDateTimeFormat, createdBy);
079
080            if(name != null) {
081                partyControl.createPartyGroup(party, name, createdBy);
082            }
083
084            warehouse = warehouseControl.createWarehouse(party, warehouseName, warehouseType, isDefault, sortOrder, createdBy);
085        } else {
086            handleExecutionError(DuplicateWarehouseNameException.class, eea, ExecutionErrors.DuplicateWarehouseName.name(), warehouseName);
087        }
088
089        return warehouse;
090    }
091
092    public Warehouse getWarehouseByName(final ExecutionErrorAccumulator eea, final String warehouseName, final String partyName,
093            final UniversalEntitySpec universalEntitySpec, final boolean allowDefault, final EntityPermission entityPermission) {
094        Warehouse warehouse = null;
095        var parameterCount = (warehouseName == null ? 0 : 1) + (partyName == null ? 0 : 1) +
096                entityInstanceLogic.countPossibleEntitySpecs(universalEntitySpec);
097
098        switch(parameterCount) {
099            case 0 -> {
100                if(allowDefault) {
101                    warehouse = warehouseControl.getDefaultWarehouse(entityPermission);
102
103                    if(warehouse == null) {
104                        handleExecutionError(UnknownDefaultWarehouseException.class, eea, ExecutionErrors.UnknownDefaultWarehouse.name());
105                    }
106                } else {
107                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
108                }
109            }
110            case 1 -> {
111                if(warehouseName != null) {
112                    warehouse = warehouseControl.getWarehouseByName(warehouseName, entityPermission);
113
114                    if(warehouse == null) {
115                        handleExecutionError(UnknownWarehouseNameException.class, eea, ExecutionErrors.UnknownWarehouseName.name(), warehouseName);
116                    }
117                } else if(partyName != null) {
118                    var party = partyControl.getPartyByName(partyName);
119
120                    if(party != null) {
121                        partyLogic.checkPartyType(eea, party, PartyTypes.WAREHOUSE.name());
122
123                        warehouse = warehouseControl.getWarehouse(party, entityPermission);
124                    } else {
125                        handleExecutionError(UnknownPartyNameException.class, eea, ExecutionErrors.UnknownPartyName.name(), partyName);
126                    }
127                } else if(universalEntitySpec != null){
128                    var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalEntitySpec,
129                            ComponentVendors.ECHO_THREE.name(), EntityTypes.Party.name());
130
131                    if(eea == null || !eea.hasExecutionErrors()) {
132                        var party = partyControl.getPartyByEntityInstance(entityInstance);
133
134                        partyLogic.checkPartyType(eea, party, PartyTypes.WAREHOUSE.name());
135
136                        warehouse = warehouseControl.getWarehouse(party, entityPermission);
137                    }
138                }
139            }
140            default ->
141                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
142        }
143
144        return warehouse;
145    }
146
147    public Warehouse getWarehouseByName(final ExecutionErrorAccumulator eea, final String warehouseName, final String partyName,
148            final UniversalEntitySpec universalEntitySpec, final boolean allowDefault) {
149        return getWarehouseByName(eea, warehouseName, partyName, universalEntitySpec, allowDefault, EntityPermission.READ_ONLY);
150    }
151
152    public Warehouse getWarehouseByNameForUpdate(final ExecutionErrorAccumulator eea, final String warehouseName, final String partyName,
153            final UniversalEntitySpec universalEntitySpec, final boolean allowDefault) {
154        return getWarehouseByName(eea, warehouseName, partyName, universalEntitySpec, allowDefault, EntityPermission.READ_WRITE);
155    }
156
157    public Warehouse getWarehouseByUniversalSpec(final ExecutionErrorAccumulator eea, final WarehouseUniversalSpec universalSpec,
158            final boolean allowDefault, final EntityPermission entityPermission) {
159        return getWarehouseByName(eea, universalSpec.getWarehouseName(), universalSpec.getPartyName(), universalSpec, allowDefault, entityPermission);
160    }
161
162    public Warehouse getWarehouseByUniversalSpec(final ExecutionErrorAccumulator eea, final WarehouseUniversalSpec universalSpec,
163            final boolean allowDefault) {
164        return getWarehouseByName(eea, universalSpec.getWarehouseName(), universalSpec.getPartyName(), universalSpec, allowDefault);
165    }
166
167    public Warehouse getWarehouseByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final WarehouseUniversalSpec universalSpec,
168            final boolean allowDefault) {
169        return getWarehouseByNameForUpdate(eea, universalSpec.getWarehouseName(), universalSpec.getPartyName(), universalSpec, allowDefault);
170    }
171
172    public Party getWarehouseParty(final ExecutionErrorAccumulator eea, final String partyName,
173            final String warehouseName) {
174        var warehouse = getWarehouseByName(eea, warehouseName, partyName, null, false);
175
176        return warehouse == null ? null : warehouse.getParty();
177    }
178
179    public void updateWarehouseFromValue(final ExecutionErrorAccumulator eea, final WarehouseValue warehouseValue,
180            final BasePK updatedBy) {
181        warehouseControl.updateWarehouseFromValue(warehouseValue, updatedBy);
182    }
183
184    public void deleteWarehouse(final ExecutionErrorAccumulator eea, final Warehouse warehouse, final BasePK deletedBy) {
185        // TODO: Verify warehouse is empty
186
187        warehouseControl.deleteWarehouse(warehouse, deletedBy);
188    }
189
190}