Add dialog for viewing product SRP history

only old jquery theme is supported, for now
This commit is contained in:
Lance Edgar 2020-01-02 06:55:02 -06:00
parent 8947a4d14f
commit 7dce154cc3
2 changed files with 163 additions and 17 deletions

View file

@ -1,10 +1,41 @@
## -*- coding: utf-8; -*-
<%inherit file="/master/view.mako" />
<%def name="extra_javascript()">
${parent.extra_javascript()}
% if not use_buefy and request.rattail_config.versioning_enabled() and master.has_perm('versions'):
<script type="text/javascript">
$(function() {
$('#view-srp-history').on('click', function() {
$('#srp-history-dialog').dialog({
title: "SRP History",
width: 550,
height: 300,
modal: true,
buttons: [
{
text: "Close",
click: function() {
$(this).dialog('close');
}
}
]
});
return false;
});
});
</script>
% endif
</%def>
<%def name="extra_styles()">
${parent.extra_styles()}
% if use_buefy:
<style type="text/css">
% if use_buefy:
#main-product-panel {
margin-right: 2em;
margin-top: 1em;
@ -12,8 +43,12 @@
#pricing-panel .field-wrapper .field {
white-space: nowrap;
}
</style>
% else:
#srp-history-dialog .grid {
color: black;
}
% endif
</style>
</%def>
<%def name="render_main_fields(form)">
@ -341,6 +376,12 @@
</div>
</div>
% if request.rattail_config.versioning_enabled() and master.has_perm('versions'):
<div id="srp-history-dialog" style="display: none;">
${srp_history_grid.render_grid()|n}
</div>
% endif
% endif
% if buttons:

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2018 Lance Edgar
# Copyright © 2010-2020 Lance Edgar
#
# This file is part of Rattail.
#
@ -30,16 +30,19 @@ import re
import logging
import six
import humanize
import sqlalchemy as sa
from sqlalchemy import orm
import sqlalchemy_continuum as continuum
from rattail import enum, pod, sil
from rattail.db import model, api, auth, Session as RattailSession
from rattail.gpc import GPC
from rattail.threads import Thread
from rattail.exceptions import LabelPrintingError
from rattail.util import load_object, pretty_quantity
from rattail.util import load_object, pretty_quantity, OrderedDict
from rattail.batch import get_batch_handler
from rattail.time import localtime, make_utc
import colander
from deform import widget as dfwidget
@ -383,7 +386,7 @@ class ProductsView(MasterView):
f.remove_field('suggested_price')
else:
f.set_readonly('suggested_price')
f.set_renderer('suggested_price', self.render_price)
f.set_renderer('suggested_price', self.render_suggested_price)
# regular_price
if self.creating:
@ -445,11 +448,11 @@ class ProductsView(MasterView):
def render_cost(self, product, field):
cost = getattr(product, field)
if cost:
if cost.unit_cost:
if not cost:
return ""
if cost.unit_cost is None:
return ""
return "${:0.2f}".format(cost.unit_cost)
else:
return "TODO: does this item have a cost?"
def render_price(self, product, column):
price = product[column]
@ -470,13 +473,31 @@ class ProductsView(MasterView):
return "$ {:0.2f} / {}".format(price.pack_price, price.pack_multiple)
return ""
def render_cost(self, product, column):
cost = product.cost
if not cost:
return ""
if cost.unit_cost is None:
return ""
return "${:0.2f}".format(cost.unit_cost)
def add_srp_history_link(self, text):
if not self.rattail_config.versioning_enabled():
return text
if not self.has_perm('versions'):
return text
history = tags.link_to("(view history)", '#',
id='view-srp-history')
if not text:
return history
text = HTML.tag('span', c=text)
br = HTML.tag('br')
return HTML.tag('div', c=[text, br, history])
def render_suggested_price(self, product, column):
text = self.render_price(product, column)
if text and self.rattail_config.versioning_enabled():
history = self.get_srp_history(product)
if history:
date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
text = "{} (as of {})".format(text, date)
return self.add_srp_history_link(text)
def render_true_cost(self, product, field):
if not product.volatile:
@ -906,12 +927,96 @@ class ProductsView(MasterView):
if not kwargs.get('image_url'):
kwargs['image_url'] = self.request.static_url('tailbone:static/img/product.png')
# add SRP history, if user has access
if self.rattail_config.versioning_enabled() and self.has_perm('versions'):
data = self.get_srp_history(product)
grid = grids.Grid('products.srp_history', data,
request=self.request,
columns=[
'price',
'since',
'changed',
'changed_by',
])
grid.set_type('price', 'currency')
grid.set_type('changed', 'datetime')
kwargs['srp_history_grid'] = grid
kwargs['costs_label_preferred'] = "Pref."
kwargs['costs_label_vendor'] = "Vendor"
kwargs['costs_label_code'] = "Order Code"
kwargs['costs_label_case_size'] = "Case Size"
return kwargs
def get_srp_history(self, product):
"""
Returns a sequence of "records" which corresponds to the given
product's SRP history.
"""
Transaction = continuum.transaction_class(model.Product)
ProductVersion = continuum.version_class(model.Product)
ProductPriceVersion = continuum.version_class(model.ProductPrice)
now = make_utc()
history = []
# first we find all relevant ProductVersion records
versions = self.Session.query(ProductVersion)\
.join(Transaction,
Transaction.id == ProductVersion.transaction_id)\
.filter(ProductVersion.uuid == product.uuid)\
.order_by(Transaction.issued_at,
Transaction.id)\
.all()
last_uuid = None
for version in versions:
if version.suggested_price_uuid != last_uuid:
changed = version.transaction.issued_at
if version.suggested_price:
assert isinstance(version.suggested_price, ProductPriceVersion)
price = version.suggested_price.price
else:
price = None
history.append({
'transaction_id': version.transaction.id,
'price': price,
'since': humanize.naturaltime(now - changed),
'changed': changed,
'changed_by': version.transaction.user,
})
last_uuid = version.suggested_price_uuid
# next we find all relevant ProductPriceVersion records
versions = self.Session.query(ProductPriceVersion)\
.join(Transaction,
Transaction.id == ProductPriceVersion.transaction_id)\
.filter(ProductPriceVersion.product_uuid == product.uuid)\
.filter(ProductPriceVersion.type == self.enum.PRICE_TYPE_MFR_SUGGESTED)\
.order_by(Transaction.issued_at,
Transaction.id)\
.all()
last_price = None
for version in versions:
if version.price != last_price:
changed = version.transaction.issued_at
price = version.price
history.append({
'transaction_id': version.transaction.id,
'price': version.price,
'since': humanize.naturaltime(now - changed),
'changed': changed,
'changed_by': version.transaction.user,
})
last_price = version.price
final_history = OrderedDict()
for hist in reversed(history):
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.