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