From 4247804707b69e0fe6f2291e027307060c42696e Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 24 Oct 2023 19:17:36 -0500 Subject: [PATCH] Allow pending product fields to be required, for new custorder --- tailbone/templates/custorders/configure.mako | 44 +++++-- tailbone/templates/custorders/create.mako | 128 ++++++++++++------- tailbone/views/custorders/orders.py | 52 +++++++- 3 files changed, 167 insertions(+), 57 deletions(-) diff --git a/tailbone/templates/custorders/configure.mako b/tailbone/templates/custorders/configure.mako index ee1f06c5..3f7041d3 100644 --- a/tailbone/templates/custorders/configure.mako +++ b/tailbone/templates/custorders/configure.mako @@ -79,15 +79,6 @@ - - - Allow creating orders for "unknown" products - - - + +

Unknown Products

+
+ + + + Allow creating orders for "unknown" products + + + +
+ +

+ Require these fields for new product: +

+ +
+ % for field in pending_product_fields: + + + ${field} + + + % endfor +
+ +
+ +
diff --git a/tailbone/templates/custorders/create.mako b/tailbone/templates/custorders/create.mako index 7d3b367f..dbcd81b3 100644 --- a/tailbone/templates/custorders/create.mako +++ b/tailbone/templates/custorders/create.mako @@ -28,7 +28,7 @@ :disabled="submittingOrder" icon-pack="fas" icon-left="fas fa-upload"> - {{ submitOrderButtonText }} + {{ submittingOrder ? "Working, please wait..." : "Submit this Order" }} - + + % if 'description' in pending_product_required_fields: + :type="pendingProduct.description ? null : 'is-danger'" + % endif + > - + @@ -664,12 +675,20 @@ - + - + - - + + + + + + + + + + + + + + + + @@ -690,27 +736,24 @@ - - - - - - - - - - - + - - + + @@ -854,7 +897,7 @@ :disabled="itemDialogSaveDisabled" icon-pack="fas" icon-left="save"> - {{ itemDialogSaveButtonText }} + {{ itemDialogSaving ? "Working, please wait..." : (this.editingItem ? "Update Item" : "Add Item") }} @@ -1197,6 +1240,7 @@ % endif pendingProduct: {}, + pendingProductRequiredFields: ${json.dumps(pending_product_required_fields)|n}, departmentOptions: ${json.dumps(department_options)|n}, submittingOrder: false, @@ -1385,37 +1429,30 @@ % endif itemDialogSaveDisabled() { + if (this.itemDialogSaving) { return true } + if (this.productIsKnown) { if (!this.productUUID) { return true } + } else { - if (!this.pendingProduct.description) { - return true + for (let field of this.pendingProductRequiredFields) { + if (!this.pendingProduct[field]) { + return true + } } } + if (!this.productUOM) { return true } + return false }, - - itemDialogSaveButtonText() { - if (this.itemDialogSaving) { - return "Working, please wait..." - } - return this.editingItem ? "Update Item" : "Add Item" - }, - - submitOrderButtonText() { - if (this.submittingOrder) { - return "Working, please wait..." - } - return "Submit this Order" - }, }, mounted() { if (this.customerStatusType) { @@ -1925,11 +1962,14 @@ this.productIsKnown = !!row.product_uuid this.productUUID = row.product_uuid - this.pendingProduct = {} + + // nb. must construct new object before updating data + // (otherwise vue does not notice the changes?) + let pending = {} if (row.pending_product) { - this.copyPendingProductAttrs(row.pending_product, - this.pendingProduct) + this.copyPendingProductAttrs(row.pending_product, pending) } + this.pendingProduct = pending this.productDisplay = row.product_full_description this.productKey = row.product_key diff --git a/tailbone/views/custorders/orders.py b/tailbone/views/custorders/orders.py index 60949e8f..cc02f682 100644 --- a/tailbone/views/custorders/orders.py +++ b/tailbone/views/custorders/orders.py @@ -102,6 +102,19 @@ class CustomerOrderView(MasterView): 'flagged', ] + PENDING_PRODUCT_ENTRY_FIELDS = [ + 'key', + 'department_uuid', + 'brand_name', + 'description', + 'size', + 'vendor_name', + 'vendor_item_code', + 'unit_cost', + 'case_size', + 'regular_price_amount', + ] + def __init__(self, request): super(CustomerOrderView, self).__init__(request) self.batch_handler = self.get_batch_handler() @@ -361,6 +374,7 @@ class CustomerOrderView(MasterView): 'order_items': items, 'product_key_label': app.get_product_key_label(), 'allow_unknown_product': self.batch_handler.allow_unknown_product(), + 'pending_product_required_fields': self.get_pending_product_required_fields(), 'department_options': self.get_department_options(), 'default_uom_choices': self.batch_handler.uom_choices_for_product(None), 'default_uom': None, @@ -390,6 +404,17 @@ class CustomerOrderView(MasterView): 'value': department.uuid}) return options + def get_pending_product_required_fields(self): + required = [] + for field in self.PENDING_PRODUCT_ENTRY_FIELDS: + require = self.rattail_config.getbool('rattail.custorders', + f'unknown_product.fields.{field}.required') + if require is None and field == 'description': + require = True + if require: + required.append(field) + return required + def get_current_batch(self): user = self.request.user if not user: @@ -1044,7 +1069,7 @@ class CustomerOrderView(MasterView): } def configure_get_simple_settings(self): - return [ + settings = [ # customer handling {'section': 'rattail.custorders', @@ -1067,9 +1092,6 @@ class CustomerOrderView(MasterView): {'section': 'rattail.custorders', 'option': 'product_price_may_be_questionable', 'type': bool}, - {'section': 'rattail.custorders', - 'option': 'allow_unknown_product', - 'type': bool}, {'section': 'rattail.custorders', 'option': 'allow_item_discounts', 'type': bool}, @@ -1082,8 +1104,30 @@ class CustomerOrderView(MasterView): {'section': 'rattail.custorders', 'option': 'allow_past_item_reorder', 'type': bool}, + + # unknown products + {'section': 'rattail.custorders', + 'option': 'allow_unknown_product', + 'type': bool}, ] + for field in self.PENDING_PRODUCT_ENTRY_FIELDS: + setting = {'section': 'rattail.custorders', + 'option': f'unknown_product.fields.{field}.required', + 'type': bool} + if field == 'description': + setting['default'] = True + settings.append(setting) + + return settings + + def configure_get_context(self, **kwargs): + context = super().configure_get_context(**kwargs) + + context['pending_product_fields'] = self.PENDING_PRODUCT_ENTRY_FIELDS + + return context + @classmethod def defaults(cls, config): cls._order_defaults(config)