Use clientele handler to populate customer dropdown widget

This commit is contained in:
Lance Edgar 2023-12-01 19:50:07 -06:00
parent faeb2cb7e2
commit 3e4bbf7092
3 changed files with 41 additions and 18 deletions

View file

@ -0,0 +1,6 @@
``tailbone.forms.widgets``
==========================
.. automodule:: tailbone.forms.widgets
:members:

View file

@ -46,6 +46,7 @@ Package API:
api/api/batch/ordering api/api/batch/ordering
api/diffs api/diffs
api/forms api/forms
api/forms.widgets
api/grids api/grids
api/grids.core api/grids.core
api/progress api/progress

View file

@ -40,6 +40,7 @@ class ReadonlyWidget(dfwidget.HiddenWidget):
readonly = True readonly = True
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
if cstruct in (colander.null, None): if cstruct in (colander.null, None):
cstruct = '' cstruct = ''
# TODO: is this hacky? # TODO: is this hacky?
@ -77,15 +78,17 @@ class PercentInputWidget(dfwidget.TextInputWidget):
autocomplete = 'off' autocomplete = 'off'
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
if cstruct not in (colander.null, None): if cstruct not in (colander.null, None):
# convert "traditional" value to "human-friendly" # convert "traditional" value to "human-friendly"
value = decimal.Decimal(cstruct) * 100 value = decimal.Decimal(cstruct) * 100
value = value.quantize(decimal.Decimal('0.001')) value = value.quantize(decimal.Decimal('0.001'))
cstruct = str(value) cstruct = str(value)
return super(PercentInputWidget, self).serialize(field, cstruct, **kw) return super().serialize(field, cstruct, **kw)
def deserialize(self, field, pstruct): def deserialize(self, field, pstruct):
pstruct = super(PercentInputWidget, self).deserialize(field, pstruct) """ """
pstruct = super().deserialize(field, pstruct)
if pstruct is colander.null: if pstruct is colander.null:
return colander.null return colander.null
# convert "human-friendly" value to "traditional" # convert "human-friendly" value to "traditional"
@ -108,6 +111,7 @@ class CasesUnitsWidget(dfwidget.Widget):
one_amount_only = False one_amount_only = False
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
if cstruct in (colander.null, None): if cstruct in (colander.null, None):
cstruct = '' cstruct = ''
readonly = kw.get('readonly', self.readonly) readonly = kw.get('readonly', self.readonly)
@ -118,6 +122,7 @@ class CasesUnitsWidget(dfwidget.Widget):
return field.renderer(template, **values) return field.renderer(template, **values)
def deserialize(self, field, pstruct): def deserialize(self, field, pstruct):
""" """
from tailbone.forms.types import ProductQuantity from tailbone.forms.types import ProductQuantity
if pstruct is colander.null: if pstruct is colander.null:
@ -166,7 +171,7 @@ class CustomSelectWidget(dfwidget.SelectWidget):
self.extra_template_values.update(kw) self.extra_template_values.update(kw)
def get_template_values(self, field, cstruct, kw): def get_template_values(self, field, cstruct, kw):
values = super(CustomSelectWidget, self).get_template_values(field, cstruct, kw) values = super().get_template_values(field, cstruct, kw)
if hasattr(self, 'extra_template_values'): if hasattr(self, 'extra_template_values'):
values.update(self.extra_template_values) values.update(self.extra_template_values)
return values return values
@ -209,6 +214,7 @@ class JQueryDateWidget(dfwidget.DateInputWidget):
) )
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
if cstruct in (colander.null, None): if cstruct in (colander.null, None):
cstruct = '' cstruct = ''
readonly = kw.get('readonly', self.readonly) readonly = kw.get('readonly', self.readonly)
@ -243,12 +249,14 @@ class FalafelDateTimeWidget(dfwidget.DateTimeInputWidget):
template = 'datetime_falafel' template = 'datetime_falafel'
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
readonly = kw.get('readonly', self.readonly) readonly = kw.get('readonly', self.readonly)
values = self.get_template_values(field, cstruct, kw) values = self.get_template_values(field, cstruct, kw)
template = self.readonly_template if readonly else self.template template = self.readonly_template if readonly else self.template
return field.renderer(template, **values) return field.renderer(template, **values)
def deserialize(self, field, pstruct): def deserialize(self, field, pstruct):
""" """
if pstruct == '': if pstruct == '':
return colander.null return colander.null
return pstruct return pstruct
@ -261,6 +269,7 @@ class FalafelTimeWidget(dfwidget.TimeInputWidget):
template = 'time_falafel' template = 'time_falafel'
def deserialize(self, field, pstruct): def deserialize(self, field, pstruct):
""" """
if pstruct == '': if pstruct == '':
return colander.null return colander.null
return pstruct return pstruct
@ -288,6 +297,7 @@ class JQueryAutocompleteWidget(dfwidget.AutocompleteInputWidget):
options = None options = None
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
if 'delay' in kw or getattr(self, 'delay', None): if 'delay' in kw or getattr(self, 'delay', None):
raise ValueError( raise ValueError(
'AutocompleteWidget does not support *delay* parameter ' 'AutocompleteWidget does not support *delay* parameter '
@ -324,6 +334,7 @@ class MultiFileUploadWidget(dfwidget.FileUploadWidget):
requirements = () requirements = ()
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
if cstruct in (colander.null, None): if cstruct in (colander.null, None):
cstruct = [] cstruct = []
@ -339,6 +350,7 @@ class MultiFileUploadWidget(dfwidget.FileUploadWidget):
return field.renderer(template, **values) return field.renderer(template, **values)
def deserialize(self, field, pstruct): def deserialize(self, field, pstruct):
""" """
if pstruct is colander.null: if pstruct is colander.null:
return colander.null return colander.null
@ -359,6 +371,7 @@ class MultiFileUploadWidget(dfwidget.FileUploadWidget):
return files_data return files_data
def deserialize_upload(self, upload): def deserialize_upload(self, upload):
""" """
# nb. this logic was copied from parent class and adapted # nb. this logic was copied from parent class and adapted
# to allow for multiple files. needs some more love. # to allow for multiple files. needs some more love.
@ -428,11 +441,13 @@ def make_customer_widget(request, **kwargs):
class CustomerAutocompleteWidget(JQueryAutocompleteWidget): class CustomerAutocompleteWidget(JQueryAutocompleteWidget):
""" """
Autocomplete widget for a Customer reference field. Autocomplete widget for a
:class:`~rattail:rattail.db.model.customers.Customer` reference
field.
""" """
def __init__(self, request, *args, **kwargs): def __init__(self, request, *args, **kwargs):
super(CustomerAutocompleteWidget, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.request = request self.request = request
model = self.request.rattail_config.get_model() model = self.request.rattail_config.get_model()
@ -452,7 +467,7 @@ class CustomerAutocompleteWidget(JQueryAutocompleteWidget):
self.input_callback = input_handler self.input_callback = input_handler
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
# fetch customer to provide button label, if we have a value # fetch customer to provide button label, if we have a value
if cstruct: if cstruct:
model = self.request.rattail_config.get_model() model = self.request.rattail_config.get_model()
@ -460,18 +475,21 @@ class CustomerAutocompleteWidget(JQueryAutocompleteWidget):
if customer: if customer:
self.field_display = str(customer) self.field_display = str(customer)
return super(CustomerAutocompleteWidget, self).serialize( return super().serialize(
field, cstruct, **kw) field, cstruct, **kw)
class CustomerDropdownWidget(dfwidget.SelectWidget): class CustomerDropdownWidget(dfwidget.SelectWidget):
""" """
Dropdown widget for a Customer reference field. Dropdown widget for a
:class:`~rattail:rattail.db.model.customers.Customer` reference
field.
""" """
def __init__(self, request, *args, **kwargs): def __init__(self, request, *args, **kwargs):
super(CustomerDropdownWidget, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.request = request self.request = request
app = self.request.rattail_config.get_app()
# must figure out dropdown values, if they weren't given # must figure out dropdown values, if they weren't given
if 'values' not in kwargs: if 'values' not in kwargs:
@ -483,10 +501,8 @@ class CustomerDropdownWidget(dfwidget.SelectWidget):
customers = customers() customers = customers()
else: # default customer list else: # default customer list
model = self.request.rattail_config.get_model() customers = app.get_clientele_handler()\
customers = Session.query(model.Customer)\ .get_all_customers(Session())
.order_by(model.Customer.name)\
.all()
# convert customer list to option values # convert customer list to option values
self.values = [(c.uuid, c.name) self.values = [(c.uuid, c.name)
@ -517,7 +533,7 @@ class DepartmentWidget(dfwidget.SelectWidget):
values.insert(0, ('', "(none)")) values.insert(0, ('', "(none)"))
kwargs['values'] = values kwargs['values'] = values
super(DepartmentWidget, self).__init__(**kwargs) super().__init__(**kwargs)
def make_vendor_widget(request, **kwargs): def make_vendor_widget(request, **kwargs):
@ -548,7 +564,7 @@ class VendorAutocompleteWidget(JQueryAutocompleteWidget):
""" """
def __init__(self, request, *args, **kwargs): def __init__(self, request, *args, **kwargs):
super(VendorAutocompleteWidget, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.request = request self.request = request
model = self.request.rattail_config.get_model() model = self.request.rattail_config.get_model()
@ -568,7 +584,7 @@ class VendorAutocompleteWidget(JQueryAutocompleteWidget):
# self.input_callback = input_handler # self.input_callback = input_handler
def serialize(self, field, cstruct, **kw): def serialize(self, field, cstruct, **kw):
""" """
# fetch vendor to provide button label, if we have a value # fetch vendor to provide button label, if we have a value
if cstruct: if cstruct:
model = self.request.rattail_config.get_model() model = self.request.rattail_config.get_model()
@ -576,7 +592,7 @@ class VendorAutocompleteWidget(JQueryAutocompleteWidget):
if vendor: if vendor:
self.field_display = str(vendor) self.field_display = str(vendor)
return super(VendorAutocompleteWidget, self).serialize( return super().serialize(
field, cstruct, **kw) field, cstruct, **kw)
@ -586,7 +602,7 @@ class VendorDropdownWidget(dfwidget.SelectWidget):
""" """
def __init__(self, request, *args, **kwargs): def __init__(self, request, *args, **kwargs):
super(VendorDropdownWidget, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.request = request self.request = request
# must figure out dropdown values, if they weren't given # must figure out dropdown values, if they weren't given