From 0e4b33be96174c15e04e5829bbc2dc7154d319b5 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 16 Jan 2020 11:56:33 -0600 Subject: [PATCH] Add "cost history" dialog for product view older jquery theme only, for now --- tailbone/templates/products/view.mako | 35 +++++++++++++- tailbone/views/products.py | 70 +++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/tailbone/templates/products/view.mako b/tailbone/templates/products/view.mako index 35095a1d..1c36c63c 100644 --- a/tailbone/templates/products/view.mako +++ b/tailbone/templates/products/view.mako @@ -10,7 +10,25 @@ var dialog = $('#' + typ + '-price-history-dialog'); dialog.dialog({ title: typ[0].toUpperCase() + typ.slice(1) + " Price History", - width: 500, + width: 600, + height: 300, + modal: true, + buttons: [ + { + text: "Close", + click: function() { + dialog.dialog('close'); + } + } + ] + }); + } + + function showCostHistory() { + var dialog = $('#cost-history-dialog'); + dialog.dialog({ + title: "Cost History", + width: 600, height: 300, modal: true, buttons: [ @@ -41,6 +59,11 @@ return false; }); + $('#view-cost-history').on('click', function() { + showCostHistory(); + return false; + }); + }); @@ -286,7 +309,12 @@ % else:
-

Vendor Sources

+

+ Vendor Sources + % if request.rattail_config.versioning_enabled() and master.has_perm('versions'): + (view cost history) + % endif +

${self.sources_grid()}
% endif @@ -405,6 +433,9 @@
${suggested_price_history_grid.render_grid()|n}
+
+ ${cost_history_grid.render_grid()|n} +
% endif % endif diff --git a/tailbone/views/products.py b/tailbone/views/products.py index 3ce27e87..14e17247 100644 --- a/tailbone/views/products.py +++ b/tailbone/views/products.py @@ -1030,6 +1030,24 @@ class ProductsView(MasterView): grid.set_type('changed', 'datetime') kwargs['suggested_price_history_grid'] = grid + # cost history + data = self.get_cost_history(product) + grid = grids.Grid('products.cost_history', data, + request=self.request, + columns=[ + 'cost', + 'vendor', + 'since', + 'changed', + 'changed_by', + ], + labels={ + 'price_type': "Type", + }) + grid.set_type('cost', 'currency') + grid.set_type('changed', 'datetime') + kwargs['cost_history_grid'] = grid + kwargs['costs_label_preferred'] = "Pref." kwargs['costs_label_vendor'] = "Vendor" kwargs['costs_label_code'] = "Order Code" @@ -1289,6 +1307,58 @@ class ProductsView(MasterView): return list(final_history.values()) + def get_cost_history(self, product): + """ + Returns a sequence of "records" which corresponds to the given + product's cost history. + """ + Transaction = continuum.transaction_class(model.Product) + ProductVersion = continuum.version_class(model.Product) + ProductCostVersion = continuum.version_class(model.ProductCost) + now = make_utc() + history = [] + + # we just find all relevant (preferred!) ProductCostVersion records + versions = self.Session.query(ProductCostVersion)\ + .join(Transaction, + Transaction.id == ProductCostVersion.transaction_id)\ + .filter(ProductCostVersion.product_uuid == product.uuid)\ + .filter(ProductCostVersion.preference == 1)\ + .order_by(Transaction.issued_at, + Transaction.id)\ + .all() + + last_cost = None + last_vendor_uuid = None + for version in versions: + + changed = False + if version.unit_cost != last_cost: + changed = True + elif version.vendor_uuid != last_vendor_uuid: + changed = True + + if changed: + changed = version.transaction.issued_at + history.append({ + 'transaction_id': version.transaction.id, + 'cost': version.unit_cost, + 'vendor': version.vendor.name, + 'since': humanize.naturaltime(now - changed), + 'changed': changed, + 'changed_by': version.transaction.user, + }) + + last_cost = version.unit_cost + last_vendor_uuid = version.vendor_uuid + + final_history = OrderedDict() + for hist in sorted(history, key=lambda h: h['changed'], reverse=True): + if hist['transaction_id'] not in final_history: + final_history[hist['transaction_id']] = hist + + return list(final_history.values()) + def edit(self): # TODO: Should add some more/better hooks, so don't have to duplicate # so much code here.