Add views for PendingProduct model; also DepartmentWidget

This commit is contained in:
Lance Edgar 2021-11-10 12:39:51 -06:00
parent 7630f504b0
commit 5f9d311cdb
3 changed files with 192 additions and 2 deletions

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2019 Lance Edgar # Copyright © 2010-2021 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -36,6 +36,7 @@ import colander
from deform import widget as dfwidget from deform import widget as dfwidget
from webhelpers2.html import tags, HTML from webhelpers2.html import tags, HTML
from tailbone.db import Session
from tailbone.forms.types import ProductQuantity from tailbone.forms.types import ProductQuantity
@ -278,3 +279,30 @@ class JQueryAutocompleteWidget(dfwidget.AutocompleteInputWidget):
tmpl_values = self.get_template_values(field, cstruct, kw) tmpl_values = self.get_template_values(field, cstruct, kw)
template = readonly and self.readonly_template or self.template template = readonly and self.readonly_template or self.template
return field.renderer(template, **tmpl_values) return field.renderer(template, **tmpl_values)
class DepartmentWidget(dfwidget.SelectWidget):
"""
Custom select widget for a Department reference field.
Constructor accepts the normal ``values`` kwarg but if not
provided then the widget will fetch department list from Rattail
DB.
Constructor also accepts ``required`` kwarg, which defaults to
true unless specified.
"""
def __init__(self, request, **kwargs):
if 'values' not in kwargs:
model = request.rattail_config.get_model()
departments = Session.query(model.Department)\
.order_by(model.Department.number)
values = [(dept.uuid, six.text_type(dept))
for dept in departments]
if not kwargs.pop('required', True):
values.insert(0, ('', "(none)"))
kwargs['values'] = values
super(DepartmentWidget, self).__init__(**kwargs)

View file

@ -739,9 +739,11 @@ class MasterView(View):
if obj.emails: if obj.emails:
return obj.emails[0].address return obj.emails[0].address
def render_product_key_value(self, obj): def render_product_key_value(self, obj, field=None):
""" """
Render the "canonical" product key value for the given object. Render the "canonical" product key value for the given object.
nb. the ``field`` kwarg is ignored if present
""" """
product_key = self.rattail_config.product_key() product_key = self.rattail_config.product_key()
if product_key == 'upc': if product_key == 'upc':

View file

@ -1885,6 +1885,165 @@ class ProductView(MasterView):
permission='{}.versions'.format(permission_prefix)) permission='{}.versions'.format(permission_prefix))
class PendingProductView(MasterView):
"""
Master view for the Pending Product class.
"""
model_class = model.PendingProduct
route_prefix = 'pending_products'
url_prefix = '/products/pending'
labels = {
'regular_price_amount': "Regular Price",
'status_code': "Status",
'user': "Created by",
}
grid_columns = [
'_product_key_',
'department_name',
'brand_name',
'description',
'size',
'created',
'user',
'status_code',
]
form_fields = [
'_product_key_',
'department_name',
'department',
'brand_name',
'brand',
'description',
'size',
'case_size',
'regular_price_amount',
'special_order',
'notes',
'created',
'user',
'status_code',
]
def configure_grid(self, g):
super(PendingProductView, self).configure_grid(g)
# product key
if '_product_key_' in g.columns:
key = self.rattail_config.product_key()
g.replace('_product_key_', key)
g.set_label(key, self.rattail_config.product_key_title(key))
g.set_link(key)
g.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
g.set_sort_defaults('created', 'desc')
g.set_link('description')
def configure_form(self, f):
super(PendingProductView, self).configure_form(f)
model = self.model
pending = f.model_instance
# product key
if '_product_key_' in f:
key = self.rattail_config.product_key()
f.replace('_product_key_', key)
f.set_label(key, self.rattail_config.product_key_title(key))
f.set_renderer(key, self.render_product_key_value)
# department
if self.creating or self.editing:
if 'department' in f:
f.remove('department_name')
f.replace('department', 'department_uuid')
f.set_widget('department_uuid', forms.widgets.DepartmentWidget(self.request, required=False))
f.set_label('department_uuid', "Department")
else:
f.set_renderer('department', self.render_department)
if pending.department:
f.remove('department_name')
# brand
if self.creating or self.editing:
f.remove('brand_name')
f.replace('brand', 'brand_uuid')
f.set_label('brand_uuid', "Brand")
f.set_node('brand_uuid', colander.String(), missing=colander.null)
brand_display = ""
if self.request.method == 'POST':
if self.request.POST.get('brand_uuid'):
brand = self.Session.query(model.Brand).get(self.request.POST['brand_uuid'])
if brand:
brand_display = six.text_type(brand)
elif self.editing:
brand_display = six.text_type(pending.brand or '')
brands_url = self.request.route_url('brands.autocomplete')
f.set_widget('brand_uuid', forms.widgets.JQueryAutocompleteWidget(
field_display=brand_display, service_url=brands_url))
else:
f.set_renderer('brand', self.render_brand)
if pending.brand:
f.remove('brand_name')
# description
f.set_required('description')
# case_size
f.set_type('case_size', 'quantity')
# regular_price_amount
f.set_type('regular_price_amount', 'currency')
# notes
f.set_type('notes', 'text')
# created
if self.creating:
f.remove('created')
else:
f.set_readonly('created')
# user
if self.creating:
f.remove('user')
else:
f.set_readonly('user')
f.set_renderer('user', self.render_user)
# status_code
if self.creating:
f.remove('status_code')
else:
# f.set_readonly('status_code')
f.set_enum('status_code', self.enum.PENDING_PRODUCT_STATUS)
def objectify(self, form, data=None):
if data is None:
data = form.validated
pending = super(PendingProductView, self).objectify(form, data)
if not pending.user:
pending.user = self.request.user
self.Session.add(pending)
self.Session.flush()
self.Session.refresh(pending)
if pending.department:
pending.department_name = pending.department.name
if pending.brand:
pending.brand_name = pending.brand.name
return pending
def print_labels(request): def print_labels(request):
profile = request.params.get('profile') profile = request.params.get('profile')
profile = Session.query(model.LabelProfile).get(profile) if profile else None profile = Session.query(model.LabelProfile).get(profile) if profile else None
@ -1920,3 +2079,4 @@ def includeme(config):
renderer='json', permission='products.print_labels') renderer='json', permission='products.print_labels')
ProductView.defaults(config) ProductView.defaults(config)
PendingProductView.defaults(config)