diff --git a/tailbone/templates/products/view.mako b/tailbone/templates/products/view.mako
index 6ca39c28..35095a1d 100644
--- a/tailbone/templates/products/view.mako
+++ b/tailbone/templates/products/view.mako
@@ -31,6 +31,11 @@
return false;
});
+ $('#view-current-price-history').on('click', function() {
+ showPriceHistory('current');
+ return false;
+ });
+
$('#view-suggested-price-history').on('click', function() {
showPriceHistory('suggested');
return false;
@@ -394,6 +399,9 @@
${regular_price_history_grid.render_grid()|n}
+
+ ${current_price_history_grid.render_grid()|n}
+
${suggested_price_history_grid.render_grid()|n}
diff --git a/tailbone/views/products.py b/tailbone/views/products.py
index 43b6d93e..3ce27e87 100644
--- a/tailbone/views/products.py
+++ b/tailbone/views/products.py
@@ -403,7 +403,7 @@ class ProductsView(MasterView):
f.remove_field('current_price')
else:
f.set_readonly('current_price')
- f.set_renderer('current_price', self.render_price)
+ f.set_renderer('current_price', self.render_current_price)
# current_price_ends
if self.creating:
@@ -506,6 +506,21 @@ class ProductsView(MasterView):
else: # not buefy
return self.add_price_history_link(text, 'regular')
+ def render_current_price(self, product, field):
+ text = self.render_price(product, field)
+
+ if text and self.rattail_config.versioning_enabled():
+ history = self.get_current_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, 'current')
+
def warn_if_regprice_more_than_srp(self, product, text):
sugprice = product.suggested_price.price if product.suggested_price else None
regprice = product.regular_price.price if product.regular_price else None
@@ -983,6 +998,24 @@ class ProductsView(MasterView):
grid.set_type('changed', 'datetime')
kwargs['regular_price_history_grid'] = grid
+ # current price
+ data = self.get_current_price_history(product)
+ grid = grids.Grid('products.current_price_history', data,
+ request=self.request,
+ columns=[
+ 'price',
+ 'price_type',
+ 'since',
+ 'changed',
+ 'changed_by',
+ ],
+ labels={
+ 'price_type': "Type",
+ })
+ grid.set_type('price', 'currency')
+ grid.set_type('changed', 'datetime')
+ kwargs['current_price_history_grid'] = grid
+
# suggested price
data = self.get_suggested_price_history(product)
grid = grids.Grid('products.suggested_price_history', data,
@@ -1066,7 +1099,122 @@ class ProductsView(MasterView):
last_price = version.price
final_history = OrderedDict()
- for hist in reversed(history):
+ 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 get_current_price_history(self, product):
+ """
+ Returns a sequence of "records" which corresponds to the given
+ product's current 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_current_uuid = None
+ last_regular_uuid = None
+ for version in versions:
+
+ changed = False
+ if version.current_price_uuid != last_current_uuid:
+ changed = True
+ elif not version.current_price_uuid and version.regular_price_uuid != last_regular_uuid:
+ changed = True
+
+ if changed:
+ changed = version.transaction.issued_at
+ if version.current_price:
+ assert isinstance(version.current_price, ProductPriceVersion)
+ price = version.current_price.price
+ price_type = self.enum.PRICE_TYPE.get(version.current_price.type)
+ elif version.regular_price:
+ price = version.regular_price.price
+ price_type = self.enum.PRICE_TYPE.get(version.regular_price.type)
+ else:
+ price = None
+ price_type = None
+ history.append({
+ 'transaction_id': version.transaction.id,
+ 'price': price,
+ 'price_type': price_type,
+ 'since': humanize.naturaltime(now - changed),
+ 'changed': changed,
+ 'changed_by': version.transaction.user,
+ })
+
+ last_current_uuid = version.current_price_uuid
+ last_regular_uuid = version.regular_price_uuid
+
+ # next we find all relevant *SALE* 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_SALE)\
+ .order_by(Transaction.issued_at,
+ Transaction.id)\
+ .all()
+
+ last_price = None
+ for version in versions:
+ # only include this version if it was "current" at the time
+ if version.uuid == version.product.current_price_uuid:
+ if version.price != last_price:
+ changed = version.transaction.issued_at
+ price = version.price
+ history.append({
+ 'transaction_id': version.transaction.id,
+ 'price': version.price,
+ 'price_type': self.enum.PRICE_TYPE[version.type],
+ 'since': humanize.naturaltime(now - changed),
+ 'changed': changed,
+ 'changed_by': version.transaction.user,
+ })
+ last_price = version.price
+
+ # next we find all relevant *TPR* 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_TPR)\
+ .order_by(Transaction.issued_at,
+ Transaction.id)\
+ .all()
+
+ last_price = None
+ for version in versions:
+ # only include this version if it was "current" at the time
+ if version.uuid == version.product.current_price_uuid:
+ if version.price != last_price:
+ changed = version.transaction.issued_at
+ price = version.price
+ history.append({
+ 'transaction_id': version.transaction.id,
+ 'price': version.price,
+ 'price_type': self.enum.PRICE_TYPE[version.type],
+ 'since': humanize.naturaltime(now - changed),
+ 'changed': changed,
+ 'changed_by': version.transaction.user,
+ })
+ last_price = version.price
+
+ 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
@@ -1135,7 +1283,7 @@ class ProductsView(MasterView):
last_price = version.price
final_history = OrderedDict()
- for hist in reversed(history):
+ 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