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.tax.server.command;
018
019import com.echothree.control.user.tax.common.edit.TaxClassificationEdit;
020import com.echothree.control.user.tax.common.edit.TaxEditFactory;
021import com.echothree.control.user.tax.common.form.EditTaxClassificationForm;
022import com.echothree.control.user.tax.common.result.EditTaxClassificationResult;
023import com.echothree.control.user.tax.common.result.TaxResultFactory;
024import com.echothree.control.user.tax.common.spec.TaxClassificationSpec;
025import com.echothree.model.control.core.common.MimeTypeUsageTypes;
026import com.echothree.model.control.core.server.logic.MimeTypeLogic;
027import com.echothree.model.control.geo.server.control.GeoControl;
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.control.tax.server.control.TaxControl;
032import com.echothree.model.data.core.server.entity.MimeType;
033import com.echothree.model.data.geo.server.entity.GeoCode;
034import com.echothree.model.data.geo.server.entity.GeoCodeDetail;
035import com.echothree.model.data.tax.server.entity.TaxClassification;
036import com.echothree.model.data.tax.server.entity.TaxClassificationDetail;
037import com.echothree.model.data.tax.server.entity.TaxClassificationTranslation;
038import com.echothree.model.data.tax.server.value.TaxClassificationDetailValue;
039import com.echothree.model.data.tax.server.value.TaxClassificationTranslationValue;
040import com.echothree.model.data.user.common.pk.UserVisitPK;
041import com.echothree.util.common.message.ExecutionErrors;
042import com.echothree.util.common.validation.FieldDefinition;
043import com.echothree.util.common.validation.FieldType;
044import com.echothree.util.common.command.EditMode;
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 java.util.Arrays;
051import java.util.Collections;
052import java.util.List;
053
054public class EditTaxClassificationCommand
055        extends BaseAbstractEditCommand<TaxClassificationSpec, TaxClassificationEdit, EditTaxClassificationResult, TaxClassification, TaxClassification> {
056
057    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
058    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
059    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
060
061    static {
062        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
063                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
064                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
065                        new SecurityRoleDefinition(SecurityRoleGroups.TaxClassification.name(), SecurityRoles.Edit.name())
066                        )))
067                )));
068
069        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
070                new FieldDefinition("CountryName", FieldType.ENTITY_NAME, true, null, null),
071                new FieldDefinition("TaxClassificationName", FieldType.ENTITY_NAME, true, null, null)
072                ));
073
074        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
075                new FieldDefinition("TaxClassificationName", FieldType.ENTITY_NAME, true, null, null),
076                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
077                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
078                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L),
079                new FieldDefinition("OverviewMimeTypeName", FieldType.MIME_TYPE, false, null, null),
080                new FieldDefinition("Overview", FieldType.STRING, false, null, null)
081                ));
082    }
083
084    /** Creates a new instance of EditTaxClassificationCommand */
085    public EditTaxClassificationCommand(UserVisitPK userVisitPK, EditTaxClassificationForm form) {
086        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
087    }
088
089    @Override
090    public EditTaxClassificationResult getResult() {
091        return TaxResultFactory.getEditTaxClassificationResult();
092    }
093
094    @Override
095    public TaxClassificationEdit getEdit() {
096        return TaxEditFactory.getTaxClassificationEdit();
097    }
098
099    GeoCode countryGeoCode;
100
101    @Override
102    public TaxClassification getEntity(EditTaxClassificationResult result) {
103        var geoControl = Session.getModelController(GeoControl.class);
104        TaxClassification taxClassification = null;
105        String countryName = spec.getCountryName();
106
107        countryGeoCode = geoControl.getCountryByAlias(countryName);
108
109        if(countryGeoCode != null) {
110            var taxControl = Session.getModelController(TaxControl.class);
111            String taxClassificationName = spec.getTaxClassificationName();
112
113            if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
114                taxClassification = taxControl.getTaxClassificationByName(countryGeoCode, taxClassificationName);
115            } else { // EditMode.UPDATE
116                taxClassification = taxControl.getTaxClassificationByNameForUpdate(countryGeoCode, taxClassificationName);
117            }
118
119            if(taxClassification == null) {
120                addExecutionError(ExecutionErrors.UnknownTaxClassificationName.name(), countryName, taxClassificationName);
121            }
122        } else {
123            addExecutionError(ExecutionErrors.UnknownGeoCodeName.name(), countryName);
124        }
125
126        return taxClassification;
127    }
128
129    @Override
130    public TaxClassification getLockEntity(TaxClassification taxClassification) {
131        return taxClassification;
132    }
133
134    @Override
135    public void fillInResult(EditTaxClassificationResult result, TaxClassification taxClassification) {
136        var taxControl = Session.getModelController(TaxControl.class);
137
138        result.setTaxClassification(taxControl.getTaxClassificationTransfer(getUserVisit(), taxClassification));
139    }
140
141    MimeType overviewMimeType;
142    
143    @Override
144    public void doLock(TaxClassificationEdit edit, TaxClassification taxClassification) {
145        var taxControl = Session.getModelController(TaxControl.class);
146        TaxClassificationTranslation taxClassificationTranslation = taxControl.getTaxClassificationTranslation(taxClassification, getPreferredLanguage());
147        TaxClassificationDetail taxClassificationDetail = taxClassification.getLastDetail();
148
149        edit.setTaxClassificationName(taxClassificationDetail.getTaxClassificationName());
150        edit.setIsDefault(taxClassificationDetail.getIsDefault().toString());
151        edit.setSortOrder(taxClassificationDetail.getSortOrder().toString());
152
153        if(taxClassificationTranslation != null) {
154            overviewMimeType = taxClassificationTranslation.getOverviewMimeType();
155            
156            edit.setDescription(taxClassificationTranslation.getDescription());
157            edit.setOverviewMimeTypeName(overviewMimeType == null? null: overviewMimeType.getLastDetail().getMimeTypeName());
158            edit.setOverview(taxClassificationTranslation.getOverview());
159        }
160    }
161    
162    @Override
163    public void canUpdate(TaxClassification taxClassification) {
164        var taxControl = Session.getModelController(TaxControl.class);
165        GeoCodeDetail geoCodeDetail = countryGeoCode.getLastDetail();
166        String taxClassificationName = edit.getTaxClassificationName();
167        TaxClassification duplicateTaxClassification = taxControl.getTaxClassificationByName(countryGeoCode, taxClassificationName);
168
169        if(duplicateTaxClassification != null && !taxClassification.equals(duplicateTaxClassification)) {
170            addExecutionError(ExecutionErrors.DuplicateTaxClassificationName.name(), geoCodeDetail.getGeoCodeName(), taxClassificationName);
171        } else {
172            String overviewMimeTypeName = edit.getOverviewMimeTypeName();
173            String overview = edit.getOverview();
174
175            overviewMimeType = MimeTypeLogic.getInstance().checkMimeType(this, overviewMimeTypeName, overview, MimeTypeUsageTypes.TEXT.name(),
176                    ExecutionErrors.MissingRequiredOverviewMimeTypeName.name(), ExecutionErrors.MissingRequiredOverview.name(),
177                    ExecutionErrors.UnknownOverviewMimeTypeName.name(), ExecutionErrors.UnknownOverviewMimeTypeUsage.name());
178        }
179    }
180
181    @Override
182    public void doUpdate(TaxClassification taxClassification) {
183        var taxControl = Session.getModelController(TaxControl.class);
184        var partyPK = getPartyPK();
185        TaxClassificationDetailValue taxClassificationDetailValue = taxControl.getTaxClassificationDetailValueForUpdate(taxClassification);
186        TaxClassificationTranslation taxClassificationTranslation = taxControl.getTaxClassificationTranslationForUpdate(taxClassification, getPreferredLanguage());
187        String description = edit.getDescription();
188        String overview = edit.getOverview();
189
190        taxClassificationDetailValue.setTaxClassificationName(edit.getTaxClassificationName());
191        taxClassificationDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
192        taxClassificationDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
193
194        taxControl.updateTaxClassificationFromValue(taxClassificationDetailValue, partyPK);
195
196        if(taxClassificationTranslation == null && (description != null || overview != null)) {
197            taxControl.createTaxClassificationTranslation(taxClassification, getPreferredLanguage(), description, overviewMimeType, overview, partyPK);
198        } else if(taxClassificationTranslation != null && (description == null && overview == null)) {
199            taxControl.deleteTaxClassificationTranslation(taxClassificationTranslation, partyPK);
200        } else if(taxClassificationTranslation != null && (description != null || overview != null)) {
201            TaxClassificationTranslationValue taxClassificationTranslationValue = taxControl.getTaxClassificationTranslationValue(taxClassificationTranslation);
202
203            taxClassificationTranslationValue.setDescription(description);
204            taxClassificationTranslationValue.setOverviewMimeTypePK(overviewMimeType == null? null: overviewMimeType.getPrimaryKey());
205            taxClassificationTranslationValue.setOverview(overview);
206            taxControl.updateTaxClassificationTranslationFromValue(taxClassificationTranslationValue, partyPK);
207        }
208    }
209
210}