From 71851e1a05b1e5ce0649762d59630c27e51fd4e6 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 4 Jan 2023 21:23:57 -0600 Subject: [PATCH] Use product handler to normalize data for products API at least, as much as possible --- tailbone/api/products.py | 68 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/tailbone/api/products.py b/tailbone/api/products.py index 48a6e4aa..a1547cce 100644 --- a/tailbone/api/products.py +++ b/tailbone/api/products.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2022 Lance Edgar +# Copyright © 2010-2023 Lance Edgar # # This file is part of Rattail. # @@ -30,6 +30,8 @@ import six import sqlalchemy as sa from sqlalchemy import orm +from cornice import Service + from rattail.db import model from tailbone.api import APIMasterView @@ -44,20 +46,41 @@ class ProductView(APIMasterView): object_url_prefix = '/product' supports_autocomplete = True + def __init__(self, request, context=None): + super(ProductView, self).__init__(request, context=context) + app = self.get_rattail_app() + self.products_handler = app.get_products_handler() + def normalize(self, product): + + # get what we can from handler + data = self.products_handler.normalize_product(product, fields=[ + 'brand_name', + 'full_description', + 'department_name', + 'unit_price_display', + 'sale_price', + 'sale_price_display', + 'sale_ends', + 'sale_ends_display', + 'vendor_name', + 'costs', + 'image_url', + ]) + + # but must supplement cost = product.cost - return { - 'uuid': product.uuid, - '_str': six.text_type(product), + data.update({ 'upc': six.text_type(product.upc), 'scancode': product.scancode, 'item_id': product.item_id, 'item_type': product.item_type, - 'description': product.description, 'status_code': product.status_code, 'default_unit_cost': cost.unit_cost if cost else None, 'default_unit_cost_display': "${:0.2f}".format(cost.unit_cost) if cost and cost.unit_cost is not None else None, - } + }) + + return data def make_autocomplete_query(self, term): query = self.Session.query(model.Product)\ @@ -77,6 +100,39 @@ class ProductView(APIMasterView): def autocomplete_display(self, product): return product.full_description + def quick_lookup(self): + """ + View for handling "quick lookup" user input, for index page. + """ + data = self.request.GET + entry = data['entry'] + + product = self.products_handler.locate_product_for_entry(self.Session(), + entry) + if not product: + return {'error': "Product not found"} + + return {'ok': True, + 'product': self.normalize(product)} + + @classmethod + def defaults(cls, config): + cls._defaults(config) + cls._product_defaults(config) + + @classmethod + def _product_defaults(cls, config): + route_prefix = cls.get_route_prefix() + permission_prefix = cls.get_permission_prefix() + collection_url_prefix = cls.get_collection_url_prefix() + + # quick lookup + quick_lookup = Service(name='{}.quick_lookup'.format(route_prefix), + path='{}/quick-lookup'.format(collection_url_prefix)) + quick_lookup.add_view('GET', 'quick_lookup', klass=cls, + permission='{}.list'.format(permission_prefix)) + config.add_cornice_service(quick_lookup) + def defaults(config, **kwargs): base = globals()