Add regular price history dialog for product view
This commit is contained in:
parent
910e82a795
commit
02649709aa
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue