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.item.server.command;
018
019import com.echothree.control.user.item.common.edit.ItemEdit;
020import com.echothree.control.user.item.common.edit.ItemEditFactory;
021import com.echothree.control.user.item.common.form.EditItemForm;
022import com.echothree.control.user.item.common.result.EditItemResult;
023import com.echothree.control.user.item.common.result.ItemResultFactory;
024import com.echothree.control.user.item.common.spec.ItemSpec;
025import com.echothree.model.control.accounting.server.control.AccountingControl;
026import com.echothree.model.control.cancellationpolicy.common.CancellationKinds;
027import com.echothree.model.control.cancellationpolicy.server.control.CancellationPolicyControl;
028import com.echothree.model.control.item.common.ItemConstants;
029import com.echothree.model.control.item.server.control.ItemControl;
030import com.echothree.model.control.party.common.PartyTypes;
031import com.echothree.model.control.returnpolicy.common.ReturnKinds;
032import com.echothree.model.control.returnpolicy.server.control.ReturnPolicyControl;
033import com.echothree.model.control.security.common.SecurityRoleGroups;
034import com.echothree.model.control.security.common.SecurityRoles;
035import com.echothree.model.control.vendor.server.control.VendorControl;
036import com.echothree.model.data.accounting.server.entity.ItemAccountingCategory;
037import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy;
038import com.echothree.model.data.item.server.entity.Item;
039import com.echothree.model.data.item.server.entity.ItemCategory;
040import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy;
041import com.echothree.model.data.user.common.pk.UserVisitPK;
042import com.echothree.model.data.vendor.server.entity.ItemPurchasingCategory;
043import com.echothree.util.common.command.EditMode;
044import com.echothree.util.common.message.ExecutionErrors;
045import com.echothree.util.common.validation.FieldDefinition;
046import com.echothree.util.common.validation.FieldType;
047import com.echothree.util.server.control.BaseAbstractEditCommand;
048import com.echothree.util.server.control.CommandSecurityDefinition;
049import com.echothree.util.server.control.PartyTypeDefinition;
050import com.echothree.util.server.control.SecurityRoleDefinition;
051import com.echothree.util.server.persistence.Session;
052import com.echothree.util.server.string.DateUtils;
053import java.util.Arrays;
054import java.util.Collections;
055import java.util.List;
056
057public class EditItemCommand
058        extends BaseAbstractEditCommand<ItemSpec, ItemEdit, EditItemResult, Item, Item> {
059    
060    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
061    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
062    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
063    
064    static {
065        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
066                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
067                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
068                        new SecurityRoleDefinition(SecurityRoleGroups.ItemCategory.name(), SecurityRoles.Edit.name())
069                        )))
070                )));
071
072        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
073                new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null)
074                ));
075        
076        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
077                new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null),
078                new FieldDefinition("ItemCategoryName", FieldType.ENTITY_NAME, true, null, null),
079                new FieldDefinition("ItemAccountingCategoryName", FieldType.ENTITY_NAME, false, null, null),
080                new FieldDefinition("ItemPurchasingCategoryName", FieldType.ENTITY_NAME, false, null, null),
081                new FieldDefinition("ShippingChargeExempt", FieldType.BOOLEAN, true, null, null),
082                new FieldDefinition("ShippingStartTime", FieldType.DATE_TIME, false, null, null),
083                new FieldDefinition("ShippingEndTime", FieldType.DATE_TIME, false, null, null),
084                new FieldDefinition("SalesOrderStartTime", FieldType.DATE_TIME, false, null, null),
085                new FieldDefinition("SalesOrderEndTime", FieldType.DATE_TIME, false, null, null),
086                new FieldDefinition("PurchaseOrderStartTime", FieldType.DATE_TIME, false, null, null),
087                new FieldDefinition("PurchaseOrderEndTime", FieldType.DATE_TIME, false, null, null),
088                new FieldDefinition("AllowClubDiscounts", FieldType.BOOLEAN, true, null, null),
089                new FieldDefinition("AllowCouponDiscounts", FieldType.BOOLEAN, true, null, null),
090                new FieldDefinition("AllowAssociatePayments", FieldType.BOOLEAN, true, null, null),
091                new FieldDefinition("CancellationPolicyName", FieldType.ENTITY_NAME, false, null, null),
092                new FieldDefinition("ReturnPolicyName", FieldType.ENTITY_NAME, false, null, null)
093                ));
094    }
095    
096    /** Creates a new instance of EditItemCommand */
097    public EditItemCommand(UserVisitPK userVisitPK, EditItemForm form) {
098        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
099    }
100
101    @Override
102    public EditItemResult getResult() {
103        return ItemResultFactory.getEditItemResult();
104    }
105
106    @Override
107    public ItemEdit getEdit() {
108        return ItemEditFactory.getItemEdit();
109    }
110
111    @Override
112    public Item getEntity(EditItemResult result) {
113        var itemControl = Session.getModelController(ItemControl.class);
114        Item item;
115        var itemName = spec.getItemName();
116
117        if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
118            item = itemControl.getItemByName(itemName);
119        } else { // EditMode.UPDATE
120            item = itemControl.getItemByNameForUpdate(itemName);
121        }
122
123        if(item != null) {
124            result.setItem(itemControl.getItemTransfer(getUserVisit(), item));
125        } else {
126            addExecutionError(ExecutionErrors.UnknownItemName.name(), itemName);
127        }
128
129        return item;
130    }
131
132    @Override
133    public Item getLockEntity(Item item) {
134        return item;
135    }
136
137    @Override
138    public void fillInResult(EditItemResult result, Item item) {
139        var itemControl = Session.getModelController(ItemControl.class);
140
141        result.setItem(itemControl.getItemTransfer(getUserVisit(), item));
142    }
143
144    @Override
145    public void doLock(ItemEdit edit, Item item) {
146        var dateUtils = DateUtils.getInstance();
147        var itemDetail = item.getLastDetail();
148        var userVisit = getUserVisit();
149        var preferredDateTimeFormat = getPreferredDateTimeFormat();
150
151        itemAccountingCategory = itemDetail.getItemAccountingCategory();
152        itemPurchasingCategory = itemDetail.getItemPurchasingCategory();
153        cancellationPolicy = itemDetail.getCancellationPolicy();
154        returnPolicy = itemDetail.getReturnPolicy();
155
156        edit.setItemName(itemDetail.getItemName());
157        edit.setItemName(edit.getItemName());
158        edit.setItemCategoryName(itemDetail.getItemCategory().getLastDetail().getItemCategoryName());
159        edit.setItemAccountingCategoryName(itemAccountingCategory == null? null: itemAccountingCategory.getLastDetail().getItemAccountingCategoryName());
160        edit.setItemPurchasingCategoryName(itemPurchasingCategory == null? null: itemPurchasingCategory.getLastDetail().getItemPurchasingCategoryName());
161        edit.setShippingChargeExempt(itemDetail.getShippingChargeExempt().toString());
162        edit.setShippingStartTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getShippingStartTime()));
163        edit.setShippingEndTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getShippingEndTime()));
164        edit.setSalesOrderStartTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getSalesOrderStartTime()));
165        edit.setSalesOrderEndTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getSalesOrderEndTime()));
166        edit.setPurchaseOrderStartTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getPurchaseOrderStartTime()));
167        edit.setPurchaseOrderEndTime(dateUtils.formatTypicalDateTime(userVisit, preferredDateTimeFormat, itemDetail.getPurchaseOrderEndTime()));
168        edit.setAllowClubDiscounts(itemDetail.getAllowClubDiscounts().toString());
169        edit.setAllowCouponDiscounts(itemDetail.getAllowCouponDiscounts().toString());
170        edit.setAllowAssociatePayments(itemDetail.getAllowAssociatePayments().toString());
171        edit.setCancellationPolicyName(cancellationPolicy == null? null: cancellationPolicy.getLastDetail().getCancellationPolicyName());
172        edit.setReturnPolicyName(returnPolicy == null? null: returnPolicy.getLastDetail().getReturnPolicyName());
173    }
174
175    ItemCategory itemCategory;
176    boolean isKit;
177    ItemAccountingCategory itemAccountingCategory;
178    ItemPurchasingCategory itemPurchasingCategory;
179    CancellationPolicy cancellationPolicy;
180    ReturnPolicy returnPolicy;
181
182    @Override
183    public void canUpdate(Item item) {
184        var itemControl = Session.getModelController(ItemControl.class);
185        var itemName = edit.getItemName();
186        var duplicateItem = itemControl.getItemByName(itemName);
187
188        if(duplicateItem == null || item.equals(duplicateItem)) {
189            var itemCategoryName = edit.getItemCategoryName();
190            var itemTypeName = item.getLastDetail().getItemType().getItemTypeName();
191
192            itemCategory = itemControl.getItemCategoryByName(itemCategoryName);
193
194            if(itemCategory != null) {
195                var itemAccountingCategoryName = edit.getItemAccountingCategoryName();
196
197                isKit = itemTypeName.equals(ItemConstants.ItemType_KIT);
198
199                if(isKit) {
200                    if(itemAccountingCategoryName != null) {
201                        addExecutionError(ExecutionErrors.NotPermittedItemAccountingCategory.name(), itemAccountingCategoryName);
202                    }
203                } else {
204                    var accountingControl = Session.getModelController(AccountingControl.class);
205
206                    itemAccountingCategory = itemAccountingCategoryName == null? null: accountingControl.getItemAccountingCategoryByName(itemAccountingCategoryName);
207
208                    if(itemAccountingCategoryName == null) {
209                        addExecutionError(ExecutionErrors.MissingItemAccountingCategoryName.name());
210                    } else if(itemAccountingCategory == null) {
211                        addExecutionError(ExecutionErrors.UnknownItemAccountingCategoryName.name(), itemAccountingCategoryName);
212                    }
213                }
214
215                if(!hasExecutionErrors()) {
216                    var itemPurchasingCategoryName = edit.getItemPurchasingCategoryName();
217
218                    if(isKit) {
219                        if(itemPurchasingCategoryName != null) {
220                            addExecutionError(ExecutionErrors.NotPermittedItemPurchasingCategory.name(), itemPurchasingCategoryName);
221                        }
222                    } else {
223                        var vendorControl = Session.getModelController(VendorControl.class);
224
225                        itemPurchasingCategory = itemPurchasingCategoryName == null? null: vendorControl.getItemPurchasingCategoryByName(itemPurchasingCategoryName);
226
227                        if(itemPurchasingCategoryName == null) {
228                            addExecutionError(ExecutionErrors.MissingItemPurchasingCategoryName.name());
229                        } else if(itemPurchasingCategory == null) {
230                            addExecutionError(ExecutionErrors.UnknownItemPurchasingCategoryName.name(), itemPurchasingCategoryName);
231                        }
232                    }
233
234                    if(!hasExecutionErrors()) {
235                        var cancellationPolicyName = edit.getCancellationPolicyName();
236
237                        if(cancellationPolicyName != null) {
238                            var cancellationPolicyControl = Session.getModelController(CancellationPolicyControl.class);
239                            var cancellationKind = cancellationPolicyControl.getCancellationKindByName(CancellationKinds.CUSTOMER_CANCELLATION.name());
240
241                            cancellationPolicy = cancellationPolicyControl.getCancellationPolicyByName(cancellationKind, cancellationPolicyName);
242                        }
243
244                        if(cancellationPolicyName == null || cancellationPolicy != null) {
245                            var returnPolicyName = edit.getReturnPolicyName();
246
247                            if(returnPolicyName != null) {
248                                var returnPolicyControl = Session.getModelController(ReturnPolicyControl.class);
249                                var returnKind = returnPolicyControl.getReturnKindByName(ReturnKinds.CUSTOMER_RETURN.name());
250
251                                returnPolicy = returnPolicyControl.getReturnPolicyByName(returnKind, returnPolicyName);
252                            }
253
254                            if(returnPolicyName != null && returnPolicy == null) {
255                                addExecutionError(ExecutionErrors.UnknownReturnPolicyName.name(), returnPolicyName);
256                            }
257                        } else {
258                            addExecutionError(ExecutionErrors.UnknownCancellationPolicyName.name(), cancellationPolicyName);
259                        }
260                    }
261                }
262            } else {
263                addExecutionError(ExecutionErrors.UnknownItemCategoryName.name(), itemCategoryName);
264            }
265        } else {
266            addExecutionError(ExecutionErrors.DuplicateItemName.name(), itemName);
267        }
268    }
269
270    @Override
271    public void doUpdate(Item item) {
272        var itemControl = Session.getModelController(ItemControl.class);
273        var partyPK = getPartyPK();
274        var itemDetailValue = itemControl.getItemDetailValueForUpdate(item);
275        var shippingChargeExempt = Boolean.valueOf(edit.getShippingChargeExempt());
276        var strShippingStartTime = edit.getShippingStartTime();
277        var shippingStartTime = strShippingStartTime == null? session.START_TIME_LONG: Long.valueOf(strShippingStartTime);
278        var strShippingEndTime = edit.getShippingEndTime();
279        var shippingEndTime = strShippingEndTime == null? null: Long.valueOf(strShippingEndTime);
280        var strSalesOrderStartTime = edit.getSalesOrderStartTime();
281        var salesOrderStartTime = strSalesOrderStartTime == null? session.START_TIME_LONG: Long.valueOf(strSalesOrderStartTime);
282        var strSalesOrderEndTime = edit.getSalesOrderEndTime();
283        var salesOrderEndTime = strSalesOrderEndTime == null? null: Long.valueOf(strSalesOrderEndTime);
284        var strPurchaseOrderStartTime = edit.getPurchaseOrderStartTime();
285        var purchaseOrderStartTime = isKit? null: strPurchaseOrderStartTime == null? session.START_TIME_LONG: Long.valueOf(strPurchaseOrderStartTime);
286        var strPurchaseOrderEndTime = edit.getPurchaseOrderEndTime();
287        var purchaseOrderEndTime = isKit? null: strPurchaseOrderEndTime == null? null: Long.valueOf(strPurchaseOrderEndTime);
288        var allowClubDiscounts = Boolean.valueOf(edit.getAllowClubDiscounts());
289        var allowCouponDiscounts = Boolean.valueOf(edit.getAllowCouponDiscounts());
290        var allowAssociatePayments = Boolean.valueOf(edit.getAllowAssociatePayments());
291
292        itemDetailValue.setItemName(edit.getItemName());
293        itemDetailValue.setItemCategoryPK(itemCategory.getPrimaryKey());
294        itemDetailValue.setItemAccountingCategoryPK(itemAccountingCategory == null? null: itemAccountingCategory.getPrimaryKey());
295        itemDetailValue.setItemPurchasingCategoryPK(itemPurchasingCategory == null? null: itemPurchasingCategory.getPrimaryKey());
296        itemDetailValue.setShippingChargeExempt(shippingChargeExempt);
297        itemDetailValue.setShippingStartTime(shippingStartTime);
298        itemDetailValue.setShippingEndTime(shippingEndTime);
299        itemDetailValue.setSalesOrderStartTime(salesOrderStartTime);
300        itemDetailValue.setSalesOrderEndTime(salesOrderEndTime);
301        itemDetailValue.setPurchaseOrderStartTime(purchaseOrderStartTime);
302        itemDetailValue.setPurchaseOrderEndTime(purchaseOrderEndTime);
303        itemDetailValue.setAllowClubDiscounts(allowClubDiscounts);
304        itemDetailValue.setAllowCouponDiscounts(allowCouponDiscounts);
305        itemDetailValue.setAllowAssociatePayments(allowAssociatePayments);
306        itemDetailValue.setCancellationPolicyPK(cancellationPolicy == null? null: cancellationPolicy.getPrimaryKey());
307        itemDetailValue.setReturnPolicyPK(returnPolicy == null? null: returnPolicy.getPrimaryKey());
308
309        itemControl.updateItemFromValue(itemDetailValue, partyPK);
310    }
311    
312}