Add regular price history dialog for product view

This commit is contained in:
Lance Edgar 2020-01-08 08:04:48 -06:00
parent 910e82a795
commit 02649709aa
2 changed files with 146 additions and 30 deletions

View file

@ -6,23 +6,33 @@
% if not use_buefy and request.rattail_config.versioning_enabled() and master.has_perm('versions'): % if not use_buefy and request.rattail_config.versioning_enabled() and master.has_perm('versions'):
<script type="text/javascript"> <script type="text/javascript">
$(function() { function showPriceHistory(typ) {
var dialog = $('#' + typ + '-price-history-dialog');
$('#view-srp-history').on('click', function() { dialog.dialog({
$('#srp-history-dialog').dialog({ title: typ[0].toUpperCase() + typ.slice(1) + " Price History",
title: "SRP History", width: 500,
width: 550,
height: 300, height: 300,
modal: true, modal: true,
buttons: [ buttons: [
{ {
text: "Close", text: "Close",
click: function() { click: function() {
$(this).dialog('close'); dialog.dialog('close');
} }
} }
] ]
}); });
}
$(function() {
$('#view-regular-price-history').on('click', function() {
showPriceHistory('regular');
return false;
});
$('#view-suggested-price-history').on('click', function() {
showPriceHistory('suggested');
return false; return false;
}); });
@ -44,7 +54,10 @@
white-space: nowrap; white-space: nowrap;
} }
% else: % else:
#srp-history-dialog .grid { .price-history-dialog {
display: none;
}
.price-history-dialog .grid {
color: black; color: black;
} }
% endif % endif
@ -378,8 +391,11 @@
</div> </div>
% if request.rattail_config.versioning_enabled() and master.has_perm('versions'): % if request.rattail_config.versioning_enabled() and master.has_perm('versions'):
<div id="srp-history-dialog" style="display: none;"> <div class="price-history-dialog" id="regular-price-history-dialog">
${srp_history_grid.render_grid()|n} ${regular_price_history_grid.render_grid()|n}
</div>
<div class="price-history-dialog" id="suggested-price-history-dialog">
${suggested_price_history_grid.render_grid()|n}
</div> </div>
% endif % endif
% endif % endif

View file

@ -393,7 +393,7 @@ class ProductsView(MasterView):
f.remove_field('regular_price') f.remove_field('regular_price')
else: else:
f.set_readonly('regular_price') f.set_readonly('regular_price')
f.set_renderer('regular_price', self.render_price) f.set_renderer('regular_price', self.render_regular_price)
# current_price # current_price
if self.creating: if self.creating:
@ -473,14 +473,14 @@ class ProductsView(MasterView):
return "$ {:0.2f} / {}".format(price.pack_price, price.pack_multiple) return "$ {:0.2f} / {}".format(price.pack_price, price.pack_multiple)
return "" return ""
def add_srp_history_link(self, text): def add_price_history_link(self, text, typ):
if not self.rattail_config.versioning_enabled(): if not self.rattail_config.versioning_enabled():
return text return text
if not self.has_perm('versions'): if not self.has_perm('versions'):
return text return text
history = tags.link_to("(view history)", '#', history = tags.link_to("(view history)", '#',
id='view-srp-history') id='view-{}-price-history'.format(typ))
if not text: if not text:
return history return history
@ -488,11 +488,11 @@ class ProductsView(MasterView):
br = HTML.tag('br') br = HTML.tag('br')
return HTML.tag('div', c=[text, br, history]) return HTML.tag('div', c=[text, br, history])
def render_suggested_price(self, product, column): def render_regular_price(self, product, field):
text = self.render_price(product, column) text = self.render_price(product, field)
if text and self.rattail_config.versioning_enabled(): if text and self.rattail_config.versioning_enabled():
history = self.get_srp_history(product) history = self.get_regular_price_history(product)
if history: if history:
date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date() date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
text = "{} (as of {})".format(text, date) text = "{} (as of {})".format(text, date)
@ -501,7 +501,22 @@ class ProductsView(MasterView):
# TODO: should add history link here too... # TODO: should add history link here too...
return text return text
else: # not buefy else: # not buefy
return self.add_srp_history_link(text) return self.add_price_history_link(text, 'regular')
def render_suggested_price(self, product, column):
text = self.render_price(product, column)
if text and self.rattail_config.versioning_enabled():
history = self.get_suggested_price_history(product)
if history:
date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
text = "{} (as of {})".format(text, date)
if self.get_use_buefy():
# TODO: should add history link here too...
return text
else: # not buefy
return self.add_price_history_link(text, 'suggested')
def render_true_cost(self, product, field): def render_true_cost(self, product, field):
if not product.volatile: if not product.volatile:
@ -931,10 +946,12 @@ class ProductsView(MasterView):
if not kwargs.get('image_url'): if not kwargs.get('image_url'):
kwargs['image_url'] = self.request.static_url('tailbone:static/img/product.png') kwargs['image_url'] = self.request.static_url('tailbone:static/img/product.png')
# add SRP history, if user has access # add price history, if user has access
if self.rattail_config.versioning_enabled() and self.has_perm('versions'): if self.rattail_config.versioning_enabled() and self.has_perm('versions'):
data = self.get_srp_history(product)
grid = grids.Grid('products.srp_history', data, # regular price
data = self.get_regular_price_history(product)
grid = grids.Grid('products.regular_price_history', data,
request=self.request, request=self.request,
columns=[ columns=[
'price', 'price',
@ -944,7 +961,21 @@ class ProductsView(MasterView):
]) ])
grid.set_type('price', 'currency') grid.set_type('price', 'currency')
grid.set_type('changed', 'datetime') grid.set_type('changed', 'datetime')
kwargs['srp_history_grid'] = grid kwargs['regular_price_history_grid'] = grid
# suggested price
data = self.get_suggested_price_history(product)
grid = grids.Grid('products.suggested_price_history', data,
request=self.request,
columns=[
'price',
'since',
'changed',
'changed_by',
])
grid.set_type('price', 'currency')
grid.set_type('changed', 'datetime')
kwargs['suggested_price_history_grid'] = grid
kwargs['costs_label_preferred'] = "Pref." kwargs['costs_label_preferred'] = "Pref."
kwargs['costs_label_vendor'] = "Vendor" kwargs['costs_label_vendor'] = "Vendor"
@ -952,7 +983,76 @@ class ProductsView(MasterView):
kwargs['costs_label_case_size'] = "Case Size" kwargs['costs_label_case_size'] = "Case Size"
return kwargs return kwargs
def get_srp_history(self, product): def get_regular_price_history(self, product):
"""
Returns a sequence of "records" which corresponds to the given
product's regular price 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.regular_price_uuid != last_uuid:
changed = version.transaction.issued_at
if version.regular_price:
assert isinstance(version.regular_price, ProductPriceVersion)
price = version.regular_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.regular_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_REGULAR)\
.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 get_suggested_price_history(self, product):
""" """
Returns a sequence of "records" which corresponds to the given Returns a sequence of "records" which corresponds to the given
product's SRP history. product's SRP history.