Add views for PendingProduct model; also DepartmentWidget
This commit is contained in:
parent
7630f504b0
commit
5f9d311cdb
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2019 Lance Edgar
|
||||
# Copyright © 2010-2021 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -36,6 +36,7 @@ import colander
|
|||
from deform import widget as dfwidget
|
||||
from webhelpers2.html import tags, HTML
|
||||
|
||||
from tailbone.db import Session
|
||||
from tailbone.forms.types import ProductQuantity
|
||||
|
||||
|
||||
|
@ -278,3 +279,30 @@ class JQueryAutocompleteWidget(dfwidget.AutocompleteInputWidget):
|
|||
tmpl_values = self.get_template_values(field, cstruct, kw)
|
||||
template = readonly and self.readonly_template or self.template
|
||||
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)
|
||||
|
|
|
@ -739,9 +739,11 @@ class MasterView(View):
|
|||
if obj.emails:
|
||||
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.
|
||||
|
||||
nb. the ``field`` kwarg is ignored if present
|
||||
"""
|
||||
product_key = self.rattail_config.product_key()
|
||||
if product_key == 'upc':
|
||||
|
|
|
@ -1885,6 +1885,165 @@ class ProductView(MasterView):
|
|||
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):
|
||||
profile = request.params.get('profile')
|
||||
profile = Session.query(model.LabelProfile).get(profile) if profile else None
|
||||
|
@ -1920,3 +2079,4 @@ def includeme(config):
|
|||
renderer='json', permission='products.print_labels')
|
||||
|
||||
ProductView.defaults(config)
|
||||
PendingProductView.defaults(config)
|
||||
|
|
Loading…
Reference in a new issue