Defer fetching price, cost history when viewing product details
user can ask for that history if they need it, but it's too expensive to always fetch by default for initial page load
This commit is contained in:
parent
f2b5e2302a
commit
cc96d9877b
|
@ -32,7 +32,8 @@
|
||||||
|
|
||||||
let ThisPage = {
|
let ThisPage = {
|
||||||
template: '#this-page-template',
|
template: '#this-page-template',
|
||||||
methods: {}
|
computed: {},
|
||||||
|
methods: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
let ThisPageData = {
|
let ThisPageData = {
|
||||||
|
|
|
@ -305,7 +305,7 @@
|
||||||
<p class="panel-heading">
|
<p class="panel-heading">
|
||||||
Vendor Sources
|
Vendor Sources
|
||||||
% if request.rattail_config.versioning_enabled() and master.has_perm('versions'):
|
% if request.rattail_config.versioning_enabled() and master.has_perm('versions'):
|
||||||
<a href="#" @click.prevent="showingCostHistory = true">
|
<a href="#" @click.prevent="showCostHistory()">
|
||||||
(view cost history)
|
(view cost history)
|
||||||
</a>
|
</a>
|
||||||
% endif
|
% endif
|
||||||
|
@ -380,7 +380,7 @@
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<section class="modal-card-body">
|
<section class="modal-card-body">
|
||||||
${regular_price_history_grid.render_buefy_table_element(data_prop='regularPriceHistoryData')|n}
|
${regular_price_history_grid.render_buefy_table_element(data_prop='regularPriceHistoryData', loading='regularPriceHistoryLoading')|n}
|
||||||
</section>
|
</section>
|
||||||
<footer class="modal-card-foot">
|
<footer class="modal-card-foot">
|
||||||
<b-button @click="showingPriceHistory_regular = false">
|
<b-button @click="showingPriceHistory_regular = false">
|
||||||
|
@ -399,7 +399,7 @@
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<section class="modal-card-body">
|
<section class="modal-card-body">
|
||||||
${current_price_history_grid.render_buefy_table_element(data_prop='currentPriceHistoryData')|n}
|
${current_price_history_grid.render_buefy_table_element(data_prop='currentPriceHistoryData', loading='currentPriceHistoryLoading')|n}
|
||||||
</section>
|
</section>
|
||||||
<footer class="modal-card-foot">
|
<footer class="modal-card-foot">
|
||||||
<b-button @click="showingPriceHistory_current = false">
|
<b-button @click="showingPriceHistory_current = false">
|
||||||
|
@ -418,7 +418,7 @@
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<section class="modal-card-body">
|
<section class="modal-card-body">
|
||||||
${suggested_price_history_grid.render_buefy_table_element(data_prop='suggestedPriceHistoryData')|n}
|
${suggested_price_history_grid.render_buefy_table_element(data_prop='suggestedPriceHistoryData', loading='suggestedPriceHistoryLoading')|n}
|
||||||
</section>
|
</section>
|
||||||
<footer class="modal-card-foot">
|
<footer class="modal-card-foot">
|
||||||
<b-button @click="showingPriceHistory_suggested = false">
|
<b-button @click="showingPriceHistory_suggested = false">
|
||||||
|
@ -437,7 +437,7 @@
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<section class="modal-card-body">
|
<section class="modal-card-body">
|
||||||
${cost_history_grid.render_buefy_table_element(data_prop='costHistoryData')|n}
|
${cost_history_grid.render_buefy_table_element(data_prop='costHistoryData', loading='costHistoryLoading')|n}
|
||||||
</section>
|
</section>
|
||||||
<footer class="modal-card-foot">
|
<footer class="modal-card-foot">
|
||||||
<b-button @click="showingCostHistory = false">
|
<b-button @click="showingCostHistory = false">
|
||||||
|
@ -539,16 +539,121 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
ThisPageData.showingPriceHistory_regular = false
|
ThisPageData.showingPriceHistory_regular = false
|
||||||
ThisPageData.regularPriceHistoryData = ${json.dumps(regular_price_history_grid.get_buefy_data()['data'])|n}
|
ThisPageData.regularPriceHistoryDataRaw = ${json.dumps(regular_price_history_grid.get_buefy_data()['data'])|n}
|
||||||
|
ThisPageData.regularPriceHistoryLoading = false
|
||||||
|
|
||||||
|
ThisPage.computed.regularPriceHistoryData = function() {
|
||||||
|
let data = []
|
||||||
|
this.regularPriceHistoryDataRaw.forEach(raw => {
|
||||||
|
data.push({
|
||||||
|
price: raw.price_display,
|
||||||
|
since: raw.since,
|
||||||
|
changed: raw.changed_display_html,
|
||||||
|
changed_by: raw.changed_by_display,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.showPriceHistory_regular = function() {
|
||||||
|
this.showingPriceHistory_regular = true
|
||||||
|
this.regularPriceHistoryLoading = true
|
||||||
|
|
||||||
|
let url = '${url("products.price_history", uuid=instance.uuid)}'
|
||||||
|
let params = {'type': 'regular'}
|
||||||
|
this.$http.get(url, {params: params}).then(response => {
|
||||||
|
this.regularPriceHistoryDataRaw = response.data
|
||||||
|
this.regularPriceHistoryLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
ThisPageData.showingPriceHistory_current = false
|
ThisPageData.showingPriceHistory_current = false
|
||||||
ThisPageData.currentPriceHistoryData = ${json.dumps(current_price_history_grid.get_buefy_data()['data'])|n}
|
ThisPageData.currentPriceHistoryDataRaw = ${json.dumps(current_price_history_grid.get_buefy_data()['data'])|n}
|
||||||
|
ThisPageData.currentPriceHistoryLoading = false
|
||||||
|
|
||||||
|
ThisPage.computed.currentPriceHistoryData = function() {
|
||||||
|
let data = []
|
||||||
|
this.currentPriceHistoryDataRaw.forEach(raw => {
|
||||||
|
data.push({
|
||||||
|
price: raw.price_display,
|
||||||
|
price_type: raw.price_type,
|
||||||
|
since: raw.since,
|
||||||
|
changed: raw.changed_display_html,
|
||||||
|
changed_by: raw.changed_by_display,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.showPriceHistory_current = function() {
|
||||||
|
this.showingPriceHistory_current = true
|
||||||
|
this.currentPriceHistoryLoading = true
|
||||||
|
|
||||||
|
let url = '${url("products.price_history", uuid=instance.uuid)}'
|
||||||
|
let params = {'type': 'current'}
|
||||||
|
this.$http.get(url, {params: params}).then(response => {
|
||||||
|
this.currentPriceHistoryDataRaw = response.data
|
||||||
|
this.currentPriceHistoryLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
ThisPageData.showingPriceHistory_suggested = false
|
ThisPageData.showingPriceHistory_suggested = false
|
||||||
ThisPageData.suggestedPriceHistoryData = ${json.dumps(suggested_price_history_grid.get_buefy_data()['data'])|n}
|
ThisPageData.suggestedPriceHistoryDataRaw = ${json.dumps(suggested_price_history_grid.get_buefy_data()['data'])|n}
|
||||||
|
ThisPageData.suggestedPriceHistoryLoading = false
|
||||||
|
|
||||||
|
ThisPage.computed.suggestedPriceHistoryData = function() {
|
||||||
|
let data = []
|
||||||
|
this.suggestedPriceHistoryDataRaw.forEach(raw => {
|
||||||
|
data.push({
|
||||||
|
price: raw.price_display,
|
||||||
|
since: raw.since,
|
||||||
|
changed: raw.changed_display_html,
|
||||||
|
changed_by: raw.changed_by_display,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.showPriceHistory_suggested = function() {
|
||||||
|
this.showingPriceHistory_suggested = true
|
||||||
|
this.suggestedPriceHistoryLoading = true
|
||||||
|
|
||||||
|
let url = '${url("products.price_history", uuid=instance.uuid)}'
|
||||||
|
let params = {'type': 'suggested'}
|
||||||
|
this.$http.get(url, {params: params}).then(response => {
|
||||||
|
this.suggestedPriceHistoryDataRaw = response.data
|
||||||
|
this.suggestedPriceHistoryLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
ThisPageData.showingCostHistory = false
|
ThisPageData.showingCostHistory = false
|
||||||
ThisPageData.costHistoryData = ${json.dumps(cost_history_grid.get_buefy_data()['data'])|n}
|
ThisPageData.costHistoryDataRaw = ${json.dumps(cost_history_grid.get_buefy_data()['data'])|n}
|
||||||
|
ThisPageData.costHistoryLoading = false
|
||||||
|
|
||||||
|
ThisPage.computed.costHistoryData = function() {
|
||||||
|
let data = []
|
||||||
|
this.costHistoryDataRaw.forEach(raw => {
|
||||||
|
data.push({
|
||||||
|
cost: raw.cost_display,
|
||||||
|
vendor: raw.vendor,
|
||||||
|
since: raw.since,
|
||||||
|
changed: raw.changed_display_html,
|
||||||
|
changed_by: raw.changed_by_display,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.showCostHistory = function() {
|
||||||
|
this.showingCostHistory = true
|
||||||
|
this.costHistoryLoading = true
|
||||||
|
|
||||||
|
let url = '${url("products.cost_history", uuid=instance.uuid)}'
|
||||||
|
this.$http.get(url).then(response => {
|
||||||
|
this.costHistoryDataRaw = response.data
|
||||||
|
this.costHistoryLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -483,7 +483,7 @@ class ProductsView(MasterView):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
if self.get_use_buefy():
|
if self.get_use_buefy():
|
||||||
kwargs = {'@click.prevent': 'showingPriceHistory_{} = true'.format(typ)}
|
kwargs = {'@click.prevent': 'showPriceHistory_{}()'.format(typ)}
|
||||||
else:
|
else:
|
||||||
kwargs = {'id': 'view-{}-price-history'.format(typ)}
|
kwargs = {'id': 'view-{}-price-history'.format(typ)}
|
||||||
history = tags.link_to("(view history)", '#', **kwargs)
|
history = tags.link_to("(view history)", '#', **kwargs)
|
||||||
|
@ -494,10 +494,17 @@ 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 show_price_effective_dates(self):
|
||||||
|
if not self.rattail_config.versioning_enabled():
|
||||||
|
return False
|
||||||
|
return self.rattail_config.getbool(
|
||||||
|
'tailbone', 'products.show_effective_price_dates',
|
||||||
|
default=True)
|
||||||
|
|
||||||
def render_regular_price(self, product, field):
|
def render_regular_price(self, product, field):
|
||||||
text = self.render_price(product, field)
|
text = self.render_price(product, field)
|
||||||
|
|
||||||
if text and self.rattail_config.versioning_enabled():
|
if text and self.show_price_effective_dates():
|
||||||
history = self.get_regular_price_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()
|
||||||
|
@ -508,7 +515,7 @@ class ProductsView(MasterView):
|
||||||
def render_current_price(self, product, field):
|
def render_current_price(self, product, field):
|
||||||
text = self.render_price(product, field)
|
text = self.render_price(product, field)
|
||||||
|
|
||||||
if text and self.rattail_config.versioning_enabled():
|
if text and self.show_price_effective_dates():
|
||||||
history = self.get_current_price_history(product)
|
history = self.get_current_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()
|
||||||
|
@ -526,7 +533,7 @@ class ProductsView(MasterView):
|
||||||
def render_suggested_price(self, product, column):
|
def render_suggested_price(self, product, column):
|
||||||
text = self.render_price(product, column)
|
text = self.render_price(product, column)
|
||||||
|
|
||||||
if text and self.rattail_config.versioning_enabled():
|
if text and self.show_price_effective_dates():
|
||||||
history = self.get_suggested_price_history(product)
|
history = self.get_suggested_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()
|
||||||
|
@ -973,8 +980,63 @@ class ProductsView(MasterView):
|
||||||
return ""
|
return ""
|
||||||
return pretty_quantity(value)
|
return pretty_quantity(value)
|
||||||
|
|
||||||
|
def price_history(self):
|
||||||
|
"""
|
||||||
|
AJAX view for fetching various types of price history for a product.
|
||||||
|
"""
|
||||||
|
product = self.get_instance()
|
||||||
|
|
||||||
|
typ = self.request.params.get('type', 'regular')
|
||||||
|
assert typ in ('regular', 'current', 'suggested')
|
||||||
|
|
||||||
|
getter = getattr(self, 'get_{}_price_history'.format(typ))
|
||||||
|
data = getter(product)
|
||||||
|
|
||||||
|
# make some data JSON-friendly
|
||||||
|
jsdata = []
|
||||||
|
for history in data:
|
||||||
|
history = dict(history)
|
||||||
|
price = history['price']
|
||||||
|
history['price'] = float(price)
|
||||||
|
history['price_display'] = "${:0.2f}".format(price)
|
||||||
|
changed = localtime(self.rattail_config, history['changed'], from_utc=True)
|
||||||
|
history['changed'] = six.text_type(changed)
|
||||||
|
history['changed_display_html'] = raw_datetime(self.rattail_config, changed)
|
||||||
|
user = history.pop('changed_by')
|
||||||
|
history['changed_by_uuid'] = user.uuid
|
||||||
|
history['changed_by_display'] = six.text_type(user)
|
||||||
|
jsdata.append(history)
|
||||||
|
return jsdata
|
||||||
|
|
||||||
|
def cost_history(self):
|
||||||
|
"""
|
||||||
|
AJAX view for fetching cost history for a product.
|
||||||
|
"""
|
||||||
|
product = self.get_instance()
|
||||||
|
data = self.get_cost_history(product)
|
||||||
|
|
||||||
|
# make some data JSON-friendly
|
||||||
|
jsdata = []
|
||||||
|
for history in data:
|
||||||
|
history = dict(history)
|
||||||
|
cost = history['cost']
|
||||||
|
if cost is not None:
|
||||||
|
history['cost'] = float(cost)
|
||||||
|
history['cost_display'] = "${:0.2f}".format(cost)
|
||||||
|
else:
|
||||||
|
history['cost_display'] = None
|
||||||
|
changed = localtime(self.rattail_config, history['changed'], from_utc=True)
|
||||||
|
history['changed'] = six.text_type(changed)
|
||||||
|
history['changed_display_html'] = raw_datetime(self.rattail_config, changed)
|
||||||
|
user = history.pop('changed_by')
|
||||||
|
history['changed_by_uuid'] = user.uuid
|
||||||
|
history['changed_by_display'] = six.text_type(user)
|
||||||
|
jsdata.append(history)
|
||||||
|
return jsdata
|
||||||
|
|
||||||
def template_kwargs_view(self, **kwargs):
|
def template_kwargs_view(self, **kwargs):
|
||||||
product = kwargs['instance']
|
product = kwargs['instance']
|
||||||
|
use_buefy = self.get_use_buefy()
|
||||||
|
|
||||||
# TODO: pretty sure this is no longer needed? guess we'll find out
|
# TODO: pretty sure this is no longer needed? guess we'll find out
|
||||||
# kwargs['image'] = False
|
# kwargs['image'] = False
|
||||||
|
@ -998,7 +1060,10 @@ class ProductsView(MasterView):
|
||||||
if self.rattail_config.versioning_enabled() and self.has_perm('versions'):
|
if self.rattail_config.versioning_enabled() and self.has_perm('versions'):
|
||||||
|
|
||||||
# regular price
|
# regular price
|
||||||
data = self.get_regular_price_history(product)
|
if use_buefy:
|
||||||
|
data = [] # defer fetching until user asks for it
|
||||||
|
else:
|
||||||
|
data = self.get_regular_price_history(product)
|
||||||
grid = grids.Grid('products.regular_price_history', data,
|
grid = grids.Grid('products.regular_price_history', data,
|
||||||
request=self.request,
|
request=self.request,
|
||||||
columns=[
|
columns=[
|
||||||
|
@ -1012,7 +1077,10 @@ class ProductsView(MasterView):
|
||||||
kwargs['regular_price_history_grid'] = grid
|
kwargs['regular_price_history_grid'] = grid
|
||||||
|
|
||||||
# current price
|
# current price
|
||||||
data = self.get_current_price_history(product)
|
if use_buefy:
|
||||||
|
data = [] # defer fetching until user asks for it
|
||||||
|
else:
|
||||||
|
data = self.get_current_price_history(product)
|
||||||
grid = grids.Grid('products.current_price_history', data,
|
grid = grids.Grid('products.current_price_history', data,
|
||||||
request=self.request,
|
request=self.request,
|
||||||
columns=[
|
columns=[
|
||||||
|
@ -1030,7 +1098,10 @@ class ProductsView(MasterView):
|
||||||
kwargs['current_price_history_grid'] = grid
|
kwargs['current_price_history_grid'] = grid
|
||||||
|
|
||||||
# suggested price
|
# suggested price
|
||||||
data = self.get_suggested_price_history(product)
|
if use_buefy:
|
||||||
|
data = [] # defer fetching until user asks for it
|
||||||
|
else:
|
||||||
|
data = self.get_suggested_price_history(product)
|
||||||
grid = grids.Grid('products.suggested_price_history', data,
|
grid = grids.Grid('products.suggested_price_history', data,
|
||||||
request=self.request,
|
request=self.request,
|
||||||
columns=[
|
columns=[
|
||||||
|
@ -1044,7 +1115,10 @@ class ProductsView(MasterView):
|
||||||
kwargs['suggested_price_history_grid'] = grid
|
kwargs['suggested_price_history_grid'] = grid
|
||||||
|
|
||||||
# cost history
|
# cost history
|
||||||
data = self.get_cost_history(product)
|
if use_buefy:
|
||||||
|
data = [] # defer fetching until user asks for it
|
||||||
|
else:
|
||||||
|
data = self.get_cost_history(product)
|
||||||
grid = grids.Grid('products.cost_history', data,
|
grid = grids.Grid('products.cost_history', data,
|
||||||
request=self.request,
|
request=self.request,
|
||||||
columns=[
|
columns=[
|
||||||
|
@ -1654,6 +1728,7 @@ class ProductsView(MasterView):
|
||||||
rattail_config = config.registry.settings.get('rattail_config')
|
rattail_config = config.registry.settings.get('rattail_config')
|
||||||
route_prefix = cls.get_route_prefix()
|
route_prefix = cls.get_route_prefix()
|
||||||
url_prefix = cls.get_url_prefix()
|
url_prefix = cls.get_url_prefix()
|
||||||
|
instance_url_prefix = cls.get_instance_url_prefix()
|
||||||
template_prefix = cls.get_template_prefix()
|
template_prefix = cls.get_template_prefix()
|
||||||
permission_prefix = cls.get_permission_prefix()
|
permission_prefix = cls.get_permission_prefix()
|
||||||
model_title = cls.get_model_title()
|
model_title = cls.get_model_title()
|
||||||
|
@ -1684,6 +1759,20 @@ class ProductsView(MasterView):
|
||||||
config.add_route('products.image', '/products/{uuid}/image')
|
config.add_route('products.image', '/products/{uuid}/image')
|
||||||
config.add_view(cls, attr='image', route_name='products.image')
|
config.add_view(cls, attr='image', route_name='products.image')
|
||||||
|
|
||||||
|
# price history
|
||||||
|
config.add_route('{}.price_history'.format(route_prefix), '{}/price-history'.format(instance_url_prefix),
|
||||||
|
request_method='GET')
|
||||||
|
config.add_view(cls, attr='price_history', route_name='{}.price_history'.format(route_prefix),
|
||||||
|
renderer='json',
|
||||||
|
permission='{}.versions'.format(permission_prefix))
|
||||||
|
|
||||||
|
# cost history
|
||||||
|
config.add_route('{}.cost_history'.format(route_prefix), '{}/cost-history'.format(instance_url_prefix),
|
||||||
|
request_method='GET')
|
||||||
|
config.add_view(cls, attr='cost_history', route_name='{}.cost_history'.format(route_prefix),
|
||||||
|
renderer='json',
|
||||||
|
permission='{}.versions'.format(permission_prefix))
|
||||||
|
|
||||||
# mobile quick lookup
|
# mobile quick lookup
|
||||||
if legacy_mobile:
|
if legacy_mobile:
|
||||||
config.add_route('mobile.products.quick_lookup', '/mobile/products/quick-lookup')
|
config.add_route('mobile.products.quick_lookup', '/mobile/products/quick-lookup')
|
||||||
|
|
Loading…
Reference in a new issue