Our custom ordering system
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

""" 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