From d504da19c5197ee0d6d2c37c09bbc1e94470f264 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 7 Aug 2023 12:36:07 -0500 Subject: [PATCH 001/530] Add common logic to validate employee reference field --- tailbone/views/master.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tailbone/views/master.py b/tailbone/views/master.py index e0c42e6e..eeae4dae 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -856,6 +856,13 @@ class MasterView(View): url = self.request.route_url('stores.view', uuid=store.uuid) return tags.link_to(text, url) + def valid_employee_uuid(self, node, value): + if value: + model = self.model + employee = self.Session.get(model.Employee, value) + if not employee: + node.raise_invalid("Employee not found") + def render_product(self, obj, field): product = getattr(obj, field) if not product: From f2915afda4dd94ad95facd4c23e2f100e9e94909 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 8 Aug 2023 14:11:54 -0500 Subject: [PATCH 002/530] Fix HTML rendering for UOM choice options also avoid deprecated config methods --- tailbone/templates/deform/select_dynamic.pt | 2 +- tailbone/views/custorders/orders.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tailbone/templates/deform/select_dynamic.pt b/tailbone/templates/deform/select_dynamic.pt index a0ee1daf..712830d1 100644 --- a/tailbone/templates/deform/select_dynamic.pt +++ b/tailbone/templates/deform/select_dynamic.pt @@ -26,7 +26,7 @@ diff --git a/tailbone/views/custorders/orders.py b/tailbone/views/custorders/orders.py index 563739ea..cdf765a6 100644 --- a/tailbone/views/custorders/orders.py +++ b/tailbone/views/custorders/orders.py @@ -341,7 +341,7 @@ class CustomerOrderView(MasterView): 'allow_contact_info_choice': self.batch_handler.allow_contact_info_choice(), 'allow_contact_info_create': self.batch_handler.allow_contact_info_creation(), 'order_items': items, - 'product_key_label': self.rattail_config.product_key_title(), + 'product_key_label': app.get_product_key_label(), 'allow_unknown_product': self.batch_handler.allow_unknown_product(), 'department_options': self.get_department_options(), 'default_uom_choices': self.batch_handler.uom_choices_for_product(None), @@ -767,7 +767,7 @@ class CustomerOrderView(MasterView): if self.batch_handler.product_price_may_be_questionable(): data['price_needs_confirmation'] = row.price_needs_confirmation - key = self.rattail_config.product_key() + key = app.get_product_key_field() if key == 'upc': data['product_key'] = data['product_upc_pretty'] elif key == 'item_id': From 845b5cda1a6730fe27028d180b246e2c221b3f40 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 8 Aug 2023 18:06:22 -0500 Subject: [PATCH 003/530] Fix custom cell click handlers in main buefy grid tables just used for editing catalog/invoice cost in receiving thus far.. --- tailbone/templates/grids/buefy.mako | 20 +++++++++++++++++--- tailbone/templates/receiving/view.mako | 3 ++- tailbone/views/purchasing/receiving.py | 9 +++------ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/tailbone/templates/grids/buefy.mako b/tailbone/templates/grids/buefy.mako index d96358d5..42451597 100644 --- a/tailbone/templates/grids/buefy.mako +++ b/tailbone/templates/grids/buefy.mako @@ -180,18 +180,21 @@ % endif :checkable="checkable" + % if grid.checkboxes: :checked-rows.sync="checkedRows" % if grid.clicking_row_checks_box: @click="rowClick" % endif % endif + % if grid.check_handler: @check="${grid.check_handler}" % endif % if grid.check_all_handler: @check-all="${grid.check_all_handler}" % endif + % if isinstance(grid.checkable, str): :is-row-checkable="${grid.row_checkable}" % elif grid.checkable: @@ -204,6 +207,10 @@ @sort="onSort" % endif + % if grid.click_handlers: + @cellclick="cellClick" + % endif + :paginated="paginated" :per-page="perPage" :current-page="currentPage" @@ -227,9 +234,6 @@ searchable % endif cell-class="c_${column['field']}" - % if grid.has_click_handler(column['field']): - @click.native="${grid.click_handlers[column['field']]}" - % endif :visible="${json.dumps(column['visible'])}"> % if column['field'] in grid.raw_renderers: ${grid.raw_renderers[column['field']]()} @@ -392,6 +396,16 @@ methods: { + % if grid.click_handlers: + cellClick(row, column, rowIndex, columnIndex) { + % for key in grid.click_handlers: + if (column._props.field == '${key}') { + ${grid.click_handlers[key]}(row) + } + % endfor + }, + % endif + copyDirectLink() { if (navigator.clipboard) { diff --git a/tailbone/templates/receiving/view.mako b/tailbone/templates/receiving/view.mako index 463fdf6c..b4de37f1 100644 --- a/tailbone/templates/receiving/view.mako +++ b/tailbone/templates/receiving/view.mako @@ -103,7 +103,8 @@ ref="input" v-show="editing" @keydown.native="inputKeyDown" - @blur="inputBlur"> + @blur="inputBlur" + style="width: 6rem;"> diff --git a/tailbone/views/purchasing/receiving.py b/tailbone/views/purchasing/receiving.py index d4bed60a..35e1d6b4 100644 --- a/tailbone/views/purchasing/receiving.py +++ b/tailbone/views/purchasing/receiving.py @@ -968,19 +968,16 @@ class ReceivingBatchView(PurchasingBatchView): g.filters['vendor_code'].default_verb = 'contains' # catalog_unit_cost - if (self.handler.has_purchase_order(batch) - or self.handler.has_invoice_file(batch)): - g.remove('catalog_unit_cost') - elif self.allow_edit_catalog_unit_cost(batch): + if self.allow_edit_catalog_unit_cost(batch): g.set_raw_renderer('catalog_unit_cost', self.render_catalog_unit_cost) g.set_click_handler('catalog_unit_cost', - 'catalogUnitCostClicked(props.row)') + 'this.catalogUnitCostClicked') # invoice_unit_cost if self.allow_edit_invoice_unit_cost(batch): g.set_raw_renderer('invoice_unit_cost', self.render_invoice_unit_cost) g.set_click_handler('invoice_unit_cost', - 'invoiceUnitCostClicked(props.row)') + 'this.invoiceUnitCostClicked') # nb. only show PO *or* invoice cost; prefer the latter unless # we have a PO and no invoice From 4ecea891b3347a878b710569e3a07c120a5a922a Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 8 Aug 2023 18:42:50 -0500 Subject: [PATCH 004/530] Update changelog --- CHANGES.rst | 10 ++++++++++ tailbone/_version.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 08bff3b8..f43e669b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,16 @@ CHANGELOG ========= +0.9.41 (2023-08-08) +------------------- + +* Add common logic to validate employee reference field. + +* Fix HTML rendering for UOM choice options. + +* Fix custom cell click handlers in main buefy grid tables. + + 0.9.40 (2023-08-03) ------------------- diff --git a/tailbone/_version.py b/tailbone/_version.py index 6d32d447..07ccc0e9 100644 --- a/tailbone/_version.py +++ b/tailbone/_version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8; -*- -__version__ = '0.9.40' +__version__ = '0.9.41' From 90075b3b6539d554ccca6915fe6fcab14b7df7fe Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 9 Aug 2023 18:04:51 -0500 Subject: [PATCH 005/530] When bulk-deleting, skip objects which are not "deletable" whatever that means in context --- tailbone/views/master.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tailbone/views/master.py b/tailbone/views/master.py index eeae4dae..107870cd 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -1728,7 +1728,8 @@ class MasterView(View): def bulk_delete_objects(self, session, objects, progress=None): def delete(obj, i): - self.delete_instance(obj) + if self.deletable_instance(obj): + self.delete_instance(obj) if i % 1000 == 0: session.flush() From a007606863ab386578018c765a388f50a9bf8d0f Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 17 Aug 2023 18:12:42 -0500 Subject: [PATCH 006/530] Declare "from PO" receiving workflow if applicable, in API --- tailbone/api/batch/receiving.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tailbone/api/batch/receiving.py b/tailbone/api/batch/receiving.py index 9a6864db..b02215d2 100644 --- a/tailbone/api/batch/receiving.py +++ b/tailbone/api/batch/receiving.py @@ -77,9 +77,15 @@ class ReceivingBatchViews(APIBatchView): def create_object(self, data): data = dict(data) + + # all about receiving mode here data['mode'] = self.enum.PURCHASE_BATCH_MODE_RECEIVING - batch = super(ReceivingBatchViews, self).create_object(data) - return batch + + # assume "receive from PO" if given a PO key + if data['purchase_key']: + data['receiving_workflow'] = 'from_po' + + return super().create_object(data) def auto_receive(self): """ From b2aea57da6933d84b79d049f10c07dff20d56579 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 18 Aug 2023 15:04:52 -0500 Subject: [PATCH 007/530] Auto-select text when editing costs for receiving --- tailbone/templates/receiving/view.mako | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tailbone/templates/receiving/view.mako b/tailbone/templates/receiving/view.mako index b4de37f1..77560ac1 100644 --- a/tailbone/templates/receiving/view.mako +++ b/tailbone/templates/receiving/view.mako @@ -103,6 +103,7 @@ ref="input" v-show="editing" @keydown.native="inputKeyDown" + @focus="selectAll" @blur="inputBlur" style="width: 6rem;"> @@ -189,6 +190,12 @@ }, methods: { + selectAll() { + // nb. must traverse into the element + let trueInput = this.$refs.input.$el.firstChild + trueInput.select() + }, + startEdit() { this.inputValue = this.value this.editing = true From 8be7dac33b7020b3ae59db15ace1c74a9b9524cb Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 24 Aug 2023 22:00:11 -0500 Subject: [PATCH 008/530] Include shopper history from parent customer account perspective ..right? or should this be hidden? configurable etc.? --- tailbone/views/people.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tailbone/views/people.py b/tailbone/views/people.py index 8dc96037..54d00ca7 100644 --- a/tailbone/views/people.py +++ b/tailbone/views/people.py @@ -1283,6 +1283,22 @@ class PersonView(MasterView): .filter(cls.account_holder_uuid == person.uuid) versions.extend(query.all()) + # CustomerShopper (from Customer perspective) + cls = continuum.version_class(model.CustomerShopper) + query = self.Session.query(cls)\ + .join(model.Customer, model.Customer.uuid == cls.customer_uuid)\ + .filter(model.Customer.account_holder_uuid == person.uuid) + versions.extend(query.all()) + + # CustomerShopperHistory (from Customer perspective) + cls = continuum.version_class(model.CustomerShopperHistory) + query = self.Session.query(cls)\ + .join(model.CustomerShopper, + model.CustomerShopper.uuid == cls.shopper_uuid)\ + .join(model.Customer)\ + .filter(model.Customer.account_holder_uuid == person.uuid) + versions.extend(query.all()) + # CustomerShopper (from Shopper perspective) cls = continuum.version_class(model.CustomerShopper) query = self.Session.query(cls)\ From bc8b5a8d324b3d30410ef8222e068714cdb7b84a Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 25 Aug 2023 09:08:33 -0500 Subject: [PATCH 009/530] Link to product record, for New Product batch row also fix a typo --- tailbone/templates/products/configure.mako | 2 +- tailbone/views/batch/newproduct.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tailbone/templates/products/configure.mako b/tailbone/templates/products/configure.mako index a8caeac7..10f3c0e5 100644 --- a/tailbone/templates/products/configure.mako +++ b/tailbone/templates/products/configure.mako @@ -50,7 +50,7 @@

Handling

- + Date: Fri, 25 Aug 2023 10:41:20 -0500 Subject: [PATCH 010/530] Fix profile history to show when a CustomerShopperHistory is deleted --- tailbone/views/people.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tailbone/views/people.py b/tailbone/views/people.py index 54d00ca7..48391f63 100644 --- a/tailbone/views/people.py +++ b/tailbone/views/people.py @@ -1307,10 +1307,10 @@ class PersonView(MasterView): # CustomerShopperHistory (from Shopper perspective) cls = continuum.version_class(model.CustomerShopperHistory) + standin = continuum.version_class(model.CustomerShopper) query = self.Session.query(cls)\ - .join(model.CustomerShopper, - model.CustomerShopper.uuid == cls.shopper_uuid)\ - .filter(model.CustomerShopper.person_uuid == person.uuid) + .join(standin, standin.uuid == cls.shopper_uuid)\ + .filter(standin.person_uuid == person.uuid) versions.extend(query.all()) # PersonNote From 844c629a6a013ce57ff01f896fa9cce442cd6426 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 25 Aug 2023 13:59:58 -0500 Subject: [PATCH 011/530] Fix profile history to show when a CustomerShopperHistory is deleted --- tailbone/views/people.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tailbone/views/people.py b/tailbone/views/people.py index 48391f63..d7f84849 100644 --- a/tailbone/views/people.py +++ b/tailbone/views/people.py @@ -1292,10 +1292,10 @@ class PersonView(MasterView): # CustomerShopperHistory (from Customer perspective) cls = continuum.version_class(model.CustomerShopperHistory) + standin = continuum.version_class(model.CustomerShopper) query = self.Session.query(cls)\ - .join(model.CustomerShopper, - model.CustomerShopper.uuid == cls.shopper_uuid)\ - .join(model.Customer)\ + .join(standin, standin.uuid == cls.shopper_uuid)\ + .join(model.Customer, model.Customer.uuid == standin.customer_uuid)\ .filter(model.Customer.account_holder_uuid == person.uuid) versions.extend(query.all()) From 12e477909305a1f2ed4b7e4ba2b421ab727c782e Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 28 Aug 2023 20:43:31 -0500 Subject: [PATCH 012/530] Fairly massive overhaul of the Profile view; standardize tabs etc. much cleaner and more consistent interface now, between the main ProfileInfo component, and various *Tab components also cleaner interface between client-side JS and server view methods to my knowledge this is complete and breaks nothing..we'll see! --- tailbone/templates/members/configure.mako | 14 + tailbone/templates/page.mako | 7 +- .../templates/people/view_profile_buefy.mako | 1830 +++++++++-------- tailbone/views/members.py | 5 + tailbone/views/people.py | 397 ++-- 5 files changed, 1234 insertions(+), 1019 deletions(-) diff --git a/tailbone/templates/members/configure.mako b/tailbone/templates/members/configure.mako index c0e0355d..465bf611 100644 --- a/tailbone/templates/members/configure.mako +++ b/tailbone/templates/members/configure.mako @@ -36,6 +36,20 @@
+ +

Relationships

+
+ + + + Limit one (1) Member account per Person + + + +
<%def name="modify_this_page_vars()"> diff --git a/tailbone/templates/page.mako b/tailbone/templates/page.mako index b5ac8773..bf799440 100644 --- a/tailbone/templates/page.mako +++ b/tailbone/templates/page.mako @@ -38,7 +38,12 @@ }, computed: {}, watch: {}, - methods: {}, + methods: { + + changeContentTitle(newTitle) { + this.$emit('change-content-title', newTitle) + }, + }, } let ThisPageData = { diff --git a/tailbone/templates/people/view_profile_buefy.mako b/tailbone/templates/people/view_profile_buefy.mako index e1da8661..5574088e 100644 --- a/tailbone/templates/people/view_profile_buefy.mako +++ b/tailbone/templates/people/view_profile_buefy.mako @@ -119,17 +119,17 @@