Add "full lookup" product search modal for new custorder page
This commit is contained in:
parent
025cabd1ad
commit
072f5da69d
4 changed files with 403 additions and 13 deletions
|
@ -179,9 +179,10 @@ class ProductView(MasterView):
|
|||
'tailbone', 'products.print_labels', default=False)
|
||||
|
||||
app = self.get_rattail_app()
|
||||
self.product_handler = app.get_products_handler()
|
||||
# TODO: deprecate / remove this
|
||||
self.handler = self.product_handler
|
||||
self.products_handler = app.get_products_handler()
|
||||
# TODO: deprecate / remove these
|
||||
self.product_handler = self.products_handler
|
||||
self.handler = self.products_handler
|
||||
|
||||
def query(self, session):
|
||||
user = self.request.user
|
||||
|
@ -535,7 +536,7 @@ class ProductView(MasterView):
|
|||
if not product.not_for_sale:
|
||||
price = product[field]
|
||||
if price:
|
||||
return self.product_handler.render_price(price)
|
||||
return self.products_handler.render_price(price)
|
||||
|
||||
def render_current_price_for_grid(self, product, field):
|
||||
text = self.render_price(product, field) or ""
|
||||
|
@ -1173,7 +1174,7 @@ class ProductView(MasterView):
|
|||
key = self.rattail_config.product_key()
|
||||
kwargs['product_key_field'] = self.product_key_fields.get(key, key)
|
||||
|
||||
kwargs['image_url'] = self.product_handler.get_image_url(product)
|
||||
kwargs['image_url'] = self.products_handler.get_image_url(product)
|
||||
|
||||
# add price history, if user has access
|
||||
if self.rattail_config.versioning_enabled() and self.has_perm('versions'):
|
||||
|
@ -1743,6 +1744,105 @@ class ProductView(MasterView):
|
|||
return {'ok': True}
|
||||
|
||||
def search(self):
|
||||
"""
|
||||
Perform a product search across multiple fields, and return
|
||||
the results as JSON suitable for row data for a Buefy
|
||||
``<b-table>`` component.
|
||||
"""
|
||||
if 'term' not in self.request.GET:
|
||||
# TODO: deprecate / remove this? not sure if/where it is used
|
||||
return self.search_v1()
|
||||
|
||||
term = self.request.GET.get('term')
|
||||
if not term:
|
||||
return {'ok': True, 'results': []}
|
||||
|
||||
supported_fields = [
|
||||
'product_key',
|
||||
'vendor_code',
|
||||
'alt_code',
|
||||
'brand_name',
|
||||
'description',
|
||||
]
|
||||
|
||||
search_fields = []
|
||||
for field in supported_fields:
|
||||
key = 'search_{}'.format(field)
|
||||
if self.request.GET.get(key) == 'true':
|
||||
search_fields.append(field)
|
||||
|
||||
final_results = []
|
||||
session = self.Session()
|
||||
model = self.model
|
||||
|
||||
lookup_fields = []
|
||||
if 'product_key' in search_fields:
|
||||
lookup_fields.append('_product_key_')
|
||||
if 'vendor_code' in search_fields:
|
||||
lookup_fields.append('vendor_code')
|
||||
if 'alt_code' in search_fields:
|
||||
lookup_fields.append('alt_code')
|
||||
if lookup_fields:
|
||||
product = self.products_handler.locate_product_for_entry(
|
||||
session, term, lookup_fields=lookup_fields)
|
||||
if product:
|
||||
final_results.append(self.search_normalize_result(product))
|
||||
|
||||
# base wildcard query
|
||||
query = session.query(model.Product)
|
||||
if 'brand_name' in search_fields:
|
||||
query = query.outerjoin(model.Brand)
|
||||
|
||||
# now figure out wildcard criteria
|
||||
criteria = []
|
||||
for word in term.split():
|
||||
if 'brand_name' in search_fields and 'description' in search_fields:
|
||||
criteria.append(sa.or_(
|
||||
model.Brand.name.ilike('%{}%'.format(word)),
|
||||
model.Product.description.ilike('%{}%'.format(word))))
|
||||
elif 'brand_name' in search_fields:
|
||||
criteria.append(model.Brand.name.ilike('%{}%'.format(word)))
|
||||
elif 'description' in search_fields:
|
||||
criteria.append(model.Product.description.ilike('%{}%'.format(word)))
|
||||
|
||||
# execute wildcard query if applicable
|
||||
max_results = 30 # TODO: make conifgurable?
|
||||
elided = 0
|
||||
if criteria:
|
||||
query = query.filter(sa.and_(*criteria))
|
||||
count = query.count()
|
||||
if count > max_results:
|
||||
elided = count - max_results
|
||||
for product in query[:max_results]:
|
||||
final_results.append(self.search_normalize_result(product))
|
||||
|
||||
return {'ok': True, 'results': final_results, 'elided': elided}
|
||||
|
||||
def search_normalize_result(self, product, **kwargs):
|
||||
return self.products_handler.normalize_product(product, fields=[
|
||||
'product_key',
|
||||
'url',
|
||||
'image_url',
|
||||
'brand_name',
|
||||
'description',
|
||||
'size',
|
||||
'full_description',
|
||||
'department_name',
|
||||
'unit_price',
|
||||
'unit_price_display',
|
||||
'sale_price',
|
||||
'sale_price_display',
|
||||
'sale_ends_display',
|
||||
'vendor_name',
|
||||
# TODO: should be case_size
|
||||
'case_quantity',
|
||||
'case_price',
|
||||
'case_price_display',
|
||||
'uom_choices',
|
||||
])
|
||||
|
||||
# TODO: deprecate / remove this? not sure if/where it is used
|
||||
def search_v1(self):
|
||||
"""
|
||||
Locate a product(s) by UPC.
|
||||
|
||||
|
@ -2027,10 +2127,10 @@ class ProductView(MasterView):
|
|||
renderer='{}/batch.mako'.format(template_prefix),
|
||||
permission='{}.make_batch'.format(permission_prefix))
|
||||
|
||||
# search (by upc)
|
||||
# search
|
||||
config.add_route('products.search', '/products/search')
|
||||
config.add_view(cls, attr='search', route_name='products.search',
|
||||
renderer='json', permission='products.view')
|
||||
renderer='json', permission='products.list')
|
||||
|
||||
# product image
|
||||
config.add_route('products.image', '/products/{uuid}/image')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue