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.control.user.sales.server.command;
018
019import com.echothree.control.user.sales.common.edit.SalesEditFactory;
020import com.echothree.control.user.sales.common.edit.SalesOrderBatchEdit;
021import com.echothree.control.user.sales.common.form.EditSalesOrderBatchForm;
022import com.echothree.control.user.sales.common.result.EditSalesOrderBatchResult;
023import com.echothree.control.user.sales.common.result.SalesResultFactory;
024import com.echothree.control.user.sales.common.spec.SalesOrderBatchSpec;
025import com.echothree.model.control.accounting.server.control.AccountingControl;
026import com.echothree.model.control.order.server.control.OrderBatchControl;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.control.payment.server.control.PaymentMethodControl;
029import com.echothree.model.control.sales.server.control.SalesOrderBatchControl;
030import com.echothree.model.control.sales.server.logic.SalesOrderBatchLogic;
031import com.echothree.model.control.security.common.SecurityRoleGroups;
032import com.echothree.model.control.security.common.SecurityRoles;
033import com.echothree.model.data.accounting.server.entity.Currency;
034import com.echothree.model.data.batch.server.entity.Batch;
035import com.echothree.model.data.payment.server.entity.PaymentMethod;
036import com.echothree.model.data.user.common.pk.UserVisitPK;
037import com.echothree.util.common.command.EditMode;
038import com.echothree.util.common.message.ExecutionErrors;
039import com.echothree.util.common.validation.FieldDefinition;
040import com.echothree.util.common.validation.FieldType;
041import com.echothree.util.server.control.BaseAbstractEditCommand;
042import com.echothree.util.server.control.CommandSecurityDefinition;
043import com.echothree.util.server.control.PartyTypeDefinition;
044import com.echothree.util.server.control.SecurityRoleDefinition;
045import com.echothree.util.server.persistence.Session;
046import com.echothree.util.server.string.AmountUtils;
047import java.util.Arrays;
048import java.util.Collections;
049import java.util.List;
050import javax.enterprise.context.RequestScoped;
051
052@RequestScoped
053public class EditSalesOrderBatchCommand
054        extends BaseAbstractEditCommand<SalesOrderBatchSpec, SalesOrderBatchEdit, EditSalesOrderBatchResult, Batch, Batch> {
055
056    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
057    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
058    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
059
060    static {
061        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
062                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
063                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
064                        new SecurityRoleDefinition(SecurityRoleGroups.SalesOrderBatch.name(), SecurityRoles.Edit.name())
065                        )))
066                )));
067
068        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
069                new FieldDefinition("BatchName", FieldType.ENTITY_NAME, true, null, null)
070                ));
071
072        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
073                new FieldDefinition("CurrencyIsoName", FieldType.ENTITY_NAME, true, null, null),
074                new FieldDefinition("PaymentMethodName", FieldType.ENTITY_NAME, true, null, null),
075                new FieldDefinition("Count", FieldType.UNSIGNED_LONG, false, null, null),
076                new FieldDefinition("Amount:CurrencyIsoName,CurrencyIsoName", FieldType.UNSIGNED_PRICE_LINE, false, null, null)
077                ));
078    }
079
080    /** Creates a new instance of EditSalesOrderBatchCommand */
081    public EditSalesOrderBatchCommand() {
082        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
083    }
084
085    @Override
086    public EditSalesOrderBatchResult getResult() {
087        return SalesResultFactory.getEditSalesOrderBatchResult();
088    }
089
090    @Override
091    public SalesOrderBatchEdit getEdit() {
092        return SalesEditFactory.getSalesOrderBatchEdit();
093    }
094
095    @Override
096    public Batch getEntity(EditSalesOrderBatchResult result) {
097        Batch batch;
098        var batchName = spec.getBatchName();
099
100        if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
101            batch = SalesOrderBatchLogic.getInstance().getBatchByName(this, batchName);
102        } else { // EditMode.UPDATE
103            batch = SalesOrderBatchLogic.getInstance().getBatchByNameForUpdate(this, batchName);
104        }
105
106        if(!hasExecutionErrors()) {
107            var salesOrderBatchControl = Session.getModelController(SalesOrderBatchControl.class);
108            
109            result.setSalesOrderBatch(salesOrderBatchControl.getSalesOrderBatchTransfer(getUserVisit(), batch));
110        }
111
112        return batch;
113    }
114
115    @Override
116    public Batch getLockEntity(Batch batch) {
117        return batch;
118    }
119
120    @Override
121    public void fillInResult(EditSalesOrderBatchResult result, Batch batch) {
122        var salesOrderBatchControl = Session.getModelController(SalesOrderBatchControl.class);
123
124        result.setSalesOrderBatch(salesOrderBatchControl.getSalesOrderBatchTransfer(getUserVisit(), batch));
125    }
126
127    @Override
128    public void doLock(SalesOrderBatchEdit edit, Batch batch) {
129        var orderBatchControl = Session.getModelController(OrderBatchControl.class);
130        var salesOrderBatchControl = Session.getModelController(SalesOrderBatchControl.class);
131        var orderBatch = orderBatchControl.getOrderBatch(batch);
132        var salesOrderBatch = salesOrderBatchControl.getSalesOrderBatch(batch);
133        var count = orderBatch.getCount();
134
135        // TODO: currency and payment method should be editable only if the batch has no orders in it.
136        edit.setCurrencyIsoName(orderBatch.getCurrency().getCurrencyIsoName());
137        edit.setPaymentMethodName(salesOrderBatch.getPaymentMethod().getLastDetail().getPaymentMethodName());
138        edit.setCount(count == null ? null : count.toString());
139        edit.setAmount(AmountUtils.getInstance().formatCostUnit(orderBatch.getCurrency(), orderBatch.getAmount()));
140    }
141
142     Currency currency;
143     PaymentMethod paymentMethod;
144
145    @Override
146    public void canUpdate(Batch batch) {
147        // TODO: currency and payment method should be checked only if the batch has no orders in it.
148        var accountingControl = Session.getModelController(AccountingControl.class);
149        var currencyIsoName = edit.getCurrencyIsoName();
150
151        currency = accountingControl.getCurrencyByIsoName(currencyIsoName);
152
153        if(currency != null) {
154            var paymentMethodControl = Session.getModelController(PaymentMethodControl.class);
155            var paymentMethodName = edit.getPaymentMethodName();
156
157            paymentMethod = paymentMethodControl.getPaymentMethodByName(paymentMethodName);
158
159            if(paymentMethod == null) {
160                addExecutionError(ExecutionErrors.UnknownPaymentMethodName.name(), paymentMethodName);
161            }
162        } else {
163            addExecutionError(ExecutionErrors.UnknownCurrencyIsoName.name(), currencyIsoName);
164        }
165    }
166
167    @Override
168    public void doUpdate(Batch batch) {
169        var salesOrderBatchControl = Session.getModelController(SalesOrderBatchControl.class);
170        var orderBatchControl = Session.getModelController(OrderBatchControl.class);
171        var partyPK = getPartyPK();
172        var strCount = edit.getCount();
173        var count = strCount == null ? null : Long.valueOf(strCount);
174        var strAmount = edit.getAmount();
175        var amount = strAmount == null ? null : Long.valueOf(strAmount);
176        var orderBatchValue = orderBatchControl.getOrderBatchValueForUpdate(batch);
177        var salesOrderBatchValue = salesOrderBatchControl.getSalesOrderBatchValueForUpdate(batch);
178
179        if(currency != null) {
180            orderBatchValue.setCurrencyPK(currency.getPrimaryKey());
181        }
182        orderBatchValue.setCount(count);
183        orderBatchValue.setAmount(amount);
184        if(paymentMethod != null) {
185            salesOrderBatchValue.setPaymentMethodPK(paymentMethod.getPrimaryKey());
186        }
187
188        orderBatchControl.updateOrderBatchFromValue(orderBatchValue, partyPK);
189        salesOrderBatchControl.updateSalesOrderBatchFromValue(salesOrderBatchValue, partyPK);
190    }
191
192}