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.accounting.server.command;
018
019import com.echothree.control.user.accounting.common.edit.AccountingEditFactory;
020import com.echothree.control.user.accounting.common.edit.TransactionGlAccountCategoryEdit;
021import com.echothree.control.user.accounting.common.result.AccountingResultFactory;
022import com.echothree.control.user.accounting.common.result.EditTransactionGlAccountCategoryResult;
023import com.echothree.control.user.accounting.common.spec.TransactionGlAccountCategorySpec;
024import com.echothree.model.control.accounting.server.control.AccountingControl;
025import com.echothree.model.control.accounting.server.logic.GlAccountCategoryLogic;
026import com.echothree.model.control.accounting.server.logic.GlAccountLogic;
027import com.echothree.model.control.accounting.server.logic.TransactionGlAccountCategoryLogic;
028import com.echothree.model.control.party.common.PartyTypes;
029import com.echothree.model.control.security.common.SecurityRoleGroups;
030import com.echothree.model.control.security.common.SecurityRoles;
031import com.echothree.model.data.accounting.server.entity.GlAccount;
032import com.echothree.model.data.accounting.server.entity.GlAccountCategory;
033import com.echothree.model.data.accounting.server.entity.TransactionGlAccountCategory;
034import com.echothree.util.common.message.ExecutionErrors;
035import com.echothree.util.common.validation.FieldDefinition;
036import com.echothree.util.common.validation.FieldType;
037import com.echothree.util.server.control.BaseAbstractEditCommand;
038import com.echothree.util.server.control.CommandSecurityDefinition;
039import com.echothree.util.server.control.PartyTypeDefinition;
040import com.echothree.util.server.control.SecurityRoleDefinition;
041import java.util.List;
042import javax.enterprise.context.Dependent;
043import javax.inject.Inject;
044
045@Dependent
046public class EditTransactionGlAccountCategoryCommand
047        extends BaseAbstractEditCommand<TransactionGlAccountCategorySpec, TransactionGlAccountCategoryEdit, EditTransactionGlAccountCategoryResult, TransactionGlAccountCategory, TransactionGlAccountCategory> {
048
049    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
050    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
051    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
052
053    static {
054        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
055                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
056                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
057                        new SecurityRoleDefinition(SecurityRoleGroups.TransactionGlAccountCategory.name(), SecurityRoles.Edit.name())
058                ))
059        ));
060
061        SPEC_FIELD_DEFINITIONS = List.of(
062                new FieldDefinition("TransactionTypeName", FieldType.ENTITY_NAME, true, null, null),
063                new FieldDefinition("TransactionGlAccountCategoryName", FieldType.ENTITY_NAME, true, null, null)
064        );
065
066        EDIT_FIELD_DEFINITIONS = List.of(
067                new FieldDefinition("TransactionGlAccountCategoryName", FieldType.ENTITY_NAME, true, null, null),
068                new FieldDefinition("GlAccountCategoryName", FieldType.ENTITY_NAME, false, null, null),
069                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
070                new FieldDefinition("GlAccountName", FieldType.ENTITY_NAME, false, null, null),
071                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
072        );
073    }
074
075    @Inject
076    AccountingControl accountingControl;
077
078    @Inject
079    GlAccountCategoryLogic glAccountCategoryLogic;
080
081    @Inject
082    GlAccountLogic glAccountLogic;
083
084    @Inject
085    TransactionGlAccountCategoryLogic transactionGlAccountCategoryLogic;
086
087    /** Creates a new instance of EditTransactionGlAccountCategoryCommand */
088    public EditTransactionGlAccountCategoryCommand() {
089        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
090    }
091
092    @Override
093    public EditTransactionGlAccountCategoryResult getResult() {
094        return AccountingResultFactory.getEditTransactionGlAccountCategoryResult();
095    }
096
097    @Override
098    public TransactionGlAccountCategoryEdit getEdit() {
099        return AccountingEditFactory.getTransactionGlAccountCategoryEdit();
100    }
101
102    @Override
103    public TransactionGlAccountCategory getEntity(EditTransactionGlAccountCategoryResult result) {
104        return transactionGlAccountCategoryLogic.getTransactionGlAccountCategoryByName(this, spec.getTransactionTypeName(),
105                spec.getTransactionGlAccountCategoryName(), editModeToEntityPermission(editMode));
106    }
107
108    @Override
109    public TransactionGlAccountCategory getLockEntity(TransactionGlAccountCategory transactionGlAccountCategory) {
110        return transactionGlAccountCategory;
111    }
112
113    @Override
114    public void fillInResult(EditTransactionGlAccountCategoryResult result, TransactionGlAccountCategory transactionGlAccountCategory) {
115        result.setTransactionGlAccountCategory(accountingControl.getTransactionGlAccountCategoryTransfer(getUserVisit(), transactionGlAccountCategory));
116    }
117
118    private GlAccountCategory glAccountCategory;
119    private GlAccount glAccount;
120
121    @Override
122    public void doLock(TransactionGlAccountCategoryEdit edit, TransactionGlAccountCategory transactionGlAccountCategory) {
123        var transactionGlAccountCategoryDescription = accountingControl.getTransactionGlAccountCategoryDescription(transactionGlAccountCategory, getPreferredLanguage());
124        var transactionGlAccount = accountingControl.getTransactionGlAccount(transactionGlAccountCategory);
125        var transactionGlAccountCategoryDetail = transactionGlAccountCategory.getLastDetail();
126        var glAccountCategory = transactionGlAccountCategoryDetail.getGlAccountCategory();
127
128        edit.setTransactionGlAccountCategoryName(transactionGlAccountCategoryDetail.getTransactionGlAccountCategoryName());
129        edit.setGlAccountCategoryName(glAccountCategory == null? null: glAccountCategory.getLastDetail().getGlAccountCategoryName());
130        edit.setSortOrder(transactionGlAccountCategoryDetail.getSortOrder().toString());
131        edit.setGlAccountName(transactionGlAccount == null? null: transactionGlAccount.getGlAccount().getLastDetail().getGlAccountName());
132
133        if(transactionGlAccountCategoryDescription != null) {
134            edit.setDescription(transactionGlAccountCategoryDescription.getDescription());
135        }
136    }
137
138    @Override
139    public void canUpdate(TransactionGlAccountCategory transactionGlAccountCategory) {
140        var transactionType = transactionGlAccountCategory.getLastDetail().getTransactionType();
141        var transactionGlAccountCategoryName = edit.getTransactionGlAccountCategoryName();
142        var duplicateTransactionGlAccountCategory = accountingControl.getTransactionGlAccountCategoryByName(transactionType, transactionGlAccountCategoryName);
143
144        if(duplicateTransactionGlAccountCategory == null || transactionGlAccountCategory.equals(duplicateTransactionGlAccountCategory)) {
145            var glAccountCategoryName = edit.getGlAccountCategoryName();
146
147            glAccountCategory = glAccountCategoryName == null? null: glAccountCategoryLogic.getGlAccountCategoryByName(this, glAccountCategoryName);
148
149            if(!hasExecutionErrors()) {
150                var glAccountName = edit.getGlAccountName();
151
152                glAccount = glAccountName == null? null: glAccountLogic.getGlAccountByName(this, glAccountName);
153
154                if(!hasExecutionErrors()) {
155                    if(glAccountCategory != null && glAccount != null && !glAccountCategory.equals(glAccount.getLastDetail().getGlAccountCategory())) {
156                        addExecutionError(ExecutionErrors.InvalidGlAccountCategory.name());
157                    }
158                }
159            }
160        } else {
161            addExecutionError(ExecutionErrors.DuplicateTransactionGlAccountCategoryName.name(),
162                    transactionType.getLastDetail().getTransactionTypeName(), transactionGlAccountCategoryName);
163        }
164    }
165
166    @Override
167    public void doUpdate(TransactionGlAccountCategory transactionGlAccountCategory) {
168        var partyPK = getPartyPK();
169        var transactionGlAccountCategoryDetailValue = accountingControl.getTransactionGlAccountCategoryDetailValueForUpdate(transactionGlAccountCategory);
170        var transactionGlAccountCategoryDescription = accountingControl.getTransactionGlAccountCategoryDescriptionForUpdate(transactionGlAccountCategory, getPreferredLanguage());
171        var transactionGlAccount = accountingControl.getTransactionGlAccount(transactionGlAccountCategory);
172        var description = edit.getDescription();
173
174        transactionGlAccountCategoryDetailValue.setTransactionGlAccountCategoryName(edit.getTransactionGlAccountCategoryName());
175        transactionGlAccountCategoryDetailValue.setGlAccountCategoryPK(glAccountCategory == null? null: glAccountCategory.getPrimaryKey());
176        transactionGlAccountCategoryDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
177
178        accountingControl.updateTransactionGlAccountCategoryFromValue(transactionGlAccountCategoryDetailValue, partyPK);
179
180        if(transactionGlAccountCategoryDescription == null && description != null) {
181            accountingControl.createTransactionGlAccountCategoryDescription(transactionGlAccountCategory, getPreferredLanguage(), description, partyPK);
182        } else if(transactionGlAccountCategoryDescription != null && description == null) {
183            accountingControl.deleteTransactionGlAccountCategoryDescription(transactionGlAccountCategoryDescription, partyPK);
184        } else if(transactionGlAccountCategoryDescription != null && description != null) {
185            var transactionGlAccountCategoryDescriptionValue = accountingControl.getTransactionGlAccountCategoryDescriptionValue(transactionGlAccountCategoryDescription);
186
187            transactionGlAccountCategoryDescriptionValue.setDescription(description);
188            accountingControl.updateTransactionGlAccountCategoryDescriptionFromValue(transactionGlAccountCategoryDescriptionValue, partyPK);
189        }
190
191        if(transactionGlAccount == null && glAccount != null) {
192            accountingControl.createTransactionGlAccount(transactionGlAccountCategory, glAccount, partyPK);
193        } else if(transactionGlAccount != null && glAccount == null) {
194            accountingControl.deleteTransactionGlAccount(transactionGlAccount, partyPK);
195        } else if(transactionGlAccount != null && glAccount != null) {
196            var transactionGlAccountValue = accountingControl.getTransactionGlAccountValue(transactionGlAccount);
197
198            transactionGlAccountValue.setGlAccountPK(glAccount.getPrimaryKey());
199            accountingControl.updateTransactionGlAccountFromValue(transactionGlAccountValue, partyPK);
200        }
201    }
202
203}