You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
6.9 KiB
230 lines
6.9 KiB
""" Schemas for form input and validation """ |
|
|
|
import deform |
|
import colander |
|
|
|
from .base import CSRFSchema |
|
from ..models import UserRole, OrderStatus, OrderCategory |
|
|
|
CATEGORIES = [(c.name, c.name.capitalize()) for c in OrderCategory] |
|
STATI = [(s.name, s.name.capitalize()) for s in OrderStatus] |
|
|
|
|
|
class OrderStatus(colander.Schema): |
|
""" schema for editing order status |
|
|
|
parital schema, used in EditOrderSchema |
|
""" |
|
|
|
status = colander.SchemaNode( |
|
colander.String(), |
|
widget=deform.widget.SelectWidget( |
|
values=STATI, |
|
css_class="custom-select col-sm-9", |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label", |
|
), |
|
) |
|
|
|
|
|
class OrderItem(colander.Schema): |
|
""" schema for editing order information |
|
|
|
parital schema, used in NewOrderSchema and EditOrderSchema |
|
""" |
|
|
|
cas_description = colander.SchemaNode( |
|
colander.String(), |
|
widget=deform.widget.TextInputWidget( |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
css_class="col-sm-9", |
|
), |
|
) |
|
category = colander.SchemaNode( |
|
colander.String(), |
|
widget=deform.widget.SelectWidget( |
|
values=CATEGORIES, |
|
css_class="custom-select col-sm-9", |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label", |
|
), |
|
) |
|
catalog_nr = colander.SchemaNode( |
|
colander.String(), |
|
widget=deform.widget.TextInputWidget( |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
css_class="col-sm-9", |
|
), |
|
) |
|
vendor = colander.SchemaNode( |
|
colander.String(), |
|
widget=deform.widget.TextInputWidget( |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
css_class="col-sm-9 o3-vendor", |
|
attributes={"data-url": ""}, # noqa: E231 |
|
), |
|
) |
|
package_size = colander.SchemaNode( |
|
colander.String(), |
|
widget=deform.widget.TextInputWidget( |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
css_class="col-sm-9", |
|
), |
|
) |
|
|
|
|
|
class MoneyInputSchema(colander.Schema): |
|
""" custom schema for structured money and currency input """ |
|
|
|
amount = colander.SchemaNode( |
|
colander.Decimal(), |
|
widget=deform.widget.MoneyInputWidget( |
|
readonly_template="textinput_disabled.pt", |
|
css_class="moneyinput amount", |
|
col_css_class="col-sm-7", |
|
), |
|
) |
|
currency = colander.SchemaNode( |
|
colander.String(), |
|
default="EUR", |
|
widget=deform.widget.TextInputWidget( |
|
readonly_template="textinput_disabled.pt", |
|
css_class="moneyinput currency", |
|
col_css_class="col-sm-2", |
|
), |
|
) |
|
|
|
def __init__(self, *args, **kwargs): |
|
""" define the custom schema templates """ |
|
if "widget" not in kwargs: |
|
readonly = kwargs.pop("readonly", False) |
|
kwargs["widget"] = deform.widget.MappingWidget( |
|
category="default", |
|
template="money_mapping.pt", |
|
readonly_template="money_mapping_disabled.pt", |
|
item_template="money_mapping_item.pt", |
|
item_readonly_template="money_mapping_item_diabled.pt", |
|
readonly=readonly, |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
item_css_class="row", |
|
) |
|
super().__init__(*args, **kwargs) |
|
|
|
|
|
class OrderPricing(colander.Schema): |
|
""" schema for editing price information |
|
|
|
parital schema, used in NewOrderSchema and EditOrderSchema |
|
""" |
|
|
|
quantity = colander.SchemaNode( |
|
colander.Integer(), |
|
validator=colander.Range(min=1), |
|
widget=deform.widget.TextInputWidget( |
|
css_class="number col-sm-9", |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
), |
|
default=1, |
|
) |
|
unit_price = MoneyInputSchema( |
|
readonly=False, label_css_class="col-sm-3 col-form-label o3-form-copy" |
|
) |
|
total_price = MoneyInputSchema( |
|
readonly=True, label_css_class="col-sm-3 col-form-label o3-form-copy" |
|
) |
|
|
|
|
|
class OrderOptionals(colander.Schema): |
|
""" schema for editing optional information |
|
|
|
parital schema, used in NewOrderSchema and EditOrderSchema |
|
""" |
|
|
|
account = colander.SchemaNode( |
|
colander.String(), |
|
required=False, |
|
missing="", |
|
widget=deform.widget.TextInputWidget( |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
css_class="col-sm-9", |
|
), |
|
) |
|
comment = colander.SchemaNode( |
|
colander.String(), |
|
missing="", |
|
widget=deform.widget.TextAreaWidget( |
|
rows=7, |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label o3-form-copy", |
|
css_class="col-sm-9", |
|
), |
|
) |
|
|
|
|
|
class EditOrderSchema(CSRFSchema): |
|
""" edit an order """ |
|
|
|
status = OrderStatus() |
|
item = OrderItem() |
|
pricing = OrderPricing() |
|
optional = OrderOptionals() |
|
|
|
@classmethod |
|
def as_form(cls, request, **override): |
|
""" returns the schema as a form """ |
|
vendor_autocorrect_url = override.pop("autocorrect_url") |
|
|
|
settings = { |
|
"buttons": ("Save Changes", "Cancel"), |
|
"css_class": "deform o3-col-form o3-order-form", |
|
} |
|
settings.update(override) |
|
form = super().as_form(request, **settings) |
|
|
|
# disable the status field, if the current user is not a purchaser |
|
if UserRole.PURCHASER.principal not in request.user.principals: |
|
form["status"]["status"].widget = deform.widget.TextInputWidget( |
|
template="textinput_disabled.pt", |
|
item_css_class="row", |
|
label_css_class="col-sm-3 col-form-label", |
|
css_class="col-sm-9", |
|
) |
|
|
|
# set the url for vendor check |
|
vendor_widget = form["item"]["vendor"].widget |
|
vendor_widget.attributes["data-url"] = vendor_autocorrect_url |
|
|
|
return form |
|
|
|
|
|
class AddOrderSchema(CSRFSchema): |
|
""" add an order """ |
|
|
|
item = OrderItem() |
|
pricing = OrderPricing() |
|
optional = OrderOptionals() |
|
|
|
@classmethod |
|
def as_form(cls, request, **override): |
|
""" returns the schema as a form """ |
|
vendor_autocorrect_url = override.pop("autocorrect_url") |
|
|
|
settings = { |
|
"buttons": ("Place Order", "Cancel"), |
|
"css_class": "deform o3-col-form o3-order-form", |
|
} |
|
settings.update(override) |
|
form = super().as_form(request, **settings) |
|
|
|
# set the url for vendor check |
|
vendor_url = vendor_autocorrect_url |
|
vendor_widget = form["item"]["vendor"].widget |
|
vendor_widget.attributes["data-url"] = vendor_url |
|
|
|
return form
|
|
|