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