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
					
				
					 3 changed files with 213 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -32,7 +32,8 @@
 | 
			
		|||
 | 
			
		||||
    let ThisPage = {
 | 
			
		||||
        template: '#this-page-template',
 | 
			
		||||
        methods: {}
 | 
			
		||||
        computed: {},
 | 
			
		||||
        methods: {},
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let ThisPageData = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -305,7 +305,7 @@
 | 
			
		|||
        <p class="panel-heading">
 | 
			
		||||
          Vendor Sources
 | 
			
		||||
          % 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)
 | 
			
		||||
              </a>
 | 
			
		||||
          % endif
 | 
			
		||||
| 
						 | 
				
			
			@ -380,7 +380,7 @@
 | 
			
		|||
            </p>
 | 
			
		||||
          </header>
 | 
			
		||||
          <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>
 | 
			
		||||
          <footer class="modal-card-foot">
 | 
			
		||||
            <b-button @click="showingPriceHistory_regular = false">
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +399,7 @@
 | 
			
		|||
            </p>
 | 
			
		||||
          </header>
 | 
			
		||||
          <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>
 | 
			
		||||
          <footer class="modal-card-foot">
 | 
			
		||||
            <b-button @click="showingPriceHistory_current = false">
 | 
			
		||||
| 
						 | 
				
			
			@ -418,7 +418,7 @@
 | 
			
		|||
            </p>
 | 
			
		||||
          </header>
 | 
			
		||||
          <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>
 | 
			
		||||
          <footer class="modal-card-foot">
 | 
			
		||||
            <b-button @click="showingPriceHistory_suggested = false">
 | 
			
		||||
| 
						 | 
				
			
			@ -437,7 +437,7 @@
 | 
			
		|||
            </p>
 | 
			
		||||
          </header>
 | 
			
		||||
          <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>
 | 
			
		||||
          <footer class="modal-card-foot">
 | 
			
		||||
            <b-button @click="showingCostHistory = false">
 | 
			
		||||
| 
						 | 
				
			
			@ -539,16 +539,121 @@
 | 
			
		|||
      <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
        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.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.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.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>
 | 
			
		||||
  % endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -483,7 +483,7 @@ class ProductsView(MasterView):
 | 
			
		|||
            return text
 | 
			
		||||
 | 
			
		||||
        if self.get_use_buefy():
 | 
			
		||||
            kwargs = {'@click.prevent': 'showingPriceHistory_{} = true'.format(typ)}
 | 
			
		||||
            kwargs = {'@click.prevent': 'showPriceHistory_{}()'.format(typ)}
 | 
			
		||||
        else:
 | 
			
		||||
            kwargs = {'id': 'view-{}-price-history'.format(typ)}
 | 
			
		||||
        history = tags.link_to("(view history)", '#', **kwargs)
 | 
			
		||||
| 
						 | 
				
			
			@ -494,10 +494,17 @@ class ProductsView(MasterView):
 | 
			
		|||
        br = HTML.tag('br')
 | 
			
		||||
        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):
 | 
			
		||||
        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)
 | 
			
		||||
            if history:
 | 
			
		||||
                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):
 | 
			
		||||
        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)
 | 
			
		||||
            if history:
 | 
			
		||||
                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):
 | 
			
		||||
        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)
 | 
			
		||||
            if history:
 | 
			
		||||
                date = localtime(self.rattail_config, history[0]['changed'], from_utc=True).date()
 | 
			
		||||
| 
						 | 
				
			
			@ -973,8 +980,63 @@ class ProductsView(MasterView):
 | 
			
		|||
            return ""
 | 
			
		||||
        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):
 | 
			
		||||
        product = kwargs['instance']
 | 
			
		||||
        use_buefy = self.get_use_buefy()
 | 
			
		||||
 | 
			
		||||
        # TODO: pretty sure this is no longer needed?  guess we'll find out
 | 
			
		||||
        # kwargs['image'] = False
 | 
			
		||||
| 
						 | 
				
			
			@ -998,6 +1060,9 @@ class ProductsView(MasterView):
 | 
			
		|||
        if self.rattail_config.versioning_enabled() and self.has_perm('versions'):
 | 
			
		||||
 | 
			
		||||
            # regular price
 | 
			
		||||
            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,
 | 
			
		||||
                              request=self.request,
 | 
			
		||||
| 
						 | 
				
			
			@ -1012,6 +1077,9 @@ class ProductsView(MasterView):
 | 
			
		|||
            kwargs['regular_price_history_grid'] = grid
 | 
			
		||||
 | 
			
		||||
            # current price
 | 
			
		||||
            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,
 | 
			
		||||
                              request=self.request,
 | 
			
		||||
| 
						 | 
				
			
			@ -1030,6 +1098,9 @@ class ProductsView(MasterView):
 | 
			
		|||
            kwargs['current_price_history_grid'] = grid
 | 
			
		||||
 | 
			
		||||
            # suggested price
 | 
			
		||||
            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,
 | 
			
		||||
                              request=self.request,
 | 
			
		||||
| 
						 | 
				
			
			@ -1044,6 +1115,9 @@ class ProductsView(MasterView):
 | 
			
		|||
            kwargs['suggested_price_history_grid'] = grid
 | 
			
		||||
 | 
			
		||||
            # cost history
 | 
			
		||||
            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,
 | 
			
		||||
                              request=self.request,
 | 
			
		||||
| 
						 | 
				
			
			@ -1654,6 +1728,7 @@ class ProductsView(MasterView):
 | 
			
		|||
        rattail_config = config.registry.settings.get('rattail_config')
 | 
			
		||||
        route_prefix = cls.get_route_prefix()
 | 
			
		||||
        url_prefix = cls.get_url_prefix()
 | 
			
		||||
        instance_url_prefix = cls.get_instance_url_prefix()
 | 
			
		||||
        template_prefix = cls.get_template_prefix()
 | 
			
		||||
        permission_prefix = cls.get_permission_prefix()
 | 
			
		||||
        model_title = cls.get_model_title()
 | 
			
		||||
| 
						 | 
				
			
			@ -1684,6 +1759,20 @@ class ProductsView(MasterView):
 | 
			
		|||
        config.add_route('products.image', '/products/{uuid}/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
 | 
			
		||||
        if legacy_mobile:
 | 
			
		||||
            config.add_route('mobile.products.quick_lookup', '/mobile/products/quick-lookup')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue