Files
@ 38cdb8aa6330
Branch filter:
Location: symposion_app/registrasion/forms.py - annotation
38cdb8aa6330
4.3 KiB
text/x-python
Makes invoice model, controller, and test changes to match issue #15 design doc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | 1b7d8a60c119 1b7d8a60c119 1b7d8a60c119 1b7d8a60c119 1b7d8a60c119 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 745f6db444fa 0ae005a5f541 3562772c13cc 0ae005a5f541 0ae005a5f541 0ae005a5f541 745f6db444fa 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 745f6db444fa 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 fc279b1922d3 745f6db444fa 0ae005a5f541 0ae005a5f541 0ae005a5f541 745f6db444fa 0ae005a5f541 3562772c13cc 0ae005a5f541 812cc0b9c834 8e95bb746990 8e95bb746990 8e95bb746990 8e95bb746990 812cc0b9c834 812cc0b9c834 745f6db444fa 0ae005a5f541 0ae005a5f541 0ae005a5f541 0b7ccfc82719 0ae005a5f541 0ae005a5f541 745f6db444fa 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 745f6db444fa 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 0ae005a5f541 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 0ae005a5f541 0ae005a5f541 745f6db444fa 3562772c13cc 3562772c13cc db332da9584d db332da9584d 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 3562772c13cc 745f6db444fa 3562772c13cc 0ae005a5f541 2d6b28c5a6da 236c61eefa0d 2d6b28c5a6da 2d6b28c5a6da 2d6b28c5a6da 2d6b28c5a6da d50d6bac482c 2d6b28c5a6da | import models as rego
from django import forms
# Products forms -- none of these have any fields: they are to be subclassed
# and the fields added as needs be.
class _ProductsForm(forms.Form):
PRODUCT_PREFIX = "product_"
''' Base class for product entry forms. '''
def __init__(self, *a, **k):
if "product_quantities" in k:
initial = self.initial_data(k["product_quantities"])
k["initial"] = initial
del k["product_quantities"]
super(_ProductsForm, self).__init__(*a, **k)
@classmethod
def field_name(cls, product):
return cls.PRODUCT_PREFIX + ("%d" % product.id)
@classmethod
def set_fields(cls, category, products):
''' Sets the base_fields on this _ProductsForm to allow selecting
from the provided products. '''
pass
@classmethod
def initial_data(cls, product_quantites):
''' Prepares initial data for an instance of this form.
product_quantities is a sequence of (product,quantity) tuples '''
return {}
def product_quantities(self):
''' Yields a sequence of (product, quantity) tuples from the
cleaned form data. '''
return iter([])
class _QuantityBoxProductsForm(_ProductsForm):
''' Products entry form that allows users to enter quantities
of desired products. '''
@classmethod
def set_fields(cls, category, products):
for product in products:
if product.description:
help_text = "$%d each -- %s" % (
product.price,
product.description,
)
else:
help_text = "$%d each" % product.price
field = forms.IntegerField(
label=product.name,
help_text=help_text,
min_value=0,
)
cls.base_fields[cls.field_name(product)] = field
@classmethod
def initial_data(cls, product_quantities):
initial = {}
for product, quantity in product_quantities:
initial[cls.field_name(product)] = quantity
return initial
def product_quantities(self):
for name, value in self.cleaned_data.items():
if name.startswith(self.PRODUCT_PREFIX):
product_id = int(name[len(self.PRODUCT_PREFIX):])
yield (product_id, value, name)
class _RadioButtonProductsForm(_ProductsForm):
''' Products entry form that allows users to enter quantities
of desired products. '''
FIELD = "chosen_product"
@classmethod
def set_fields(cls, category, products):
choices = []
for product in products:
choice_text = "%s -- $%d" % (product.name, product.price)
choices.append((product.id, choice_text))
cls.base_fields[cls.FIELD] = forms.TypedChoiceField(
label=category.name,
widget=forms.RadioSelect,
choices=choices,
empty_value=0,
coerce=int,
)
@classmethod
def initial_data(cls, product_quantities):
initial = {}
for product, quantity in product_quantities:
if quantity > 0:
initial[cls.FIELD] = product.id
break
return initial
def product_quantities(self):
ours = self.cleaned_data[self.FIELD]
choices = self.fields[self.FIELD].choices
for choice_value, choice_display in choices:
yield (
choice_value,
1 if ours == choice_value else 0,
self.FIELD,
)
def ProductsForm(category, products):
''' Produces an appropriate _ProductsForm subclass for the given render
type. '''
# Each Category.RENDER_TYPE value has a subclass here.
RENDER_TYPES = {
rego.Category.RENDER_TYPE_QUANTITY: _QuantityBoxProductsForm,
rego.Category.RENDER_TYPE_RADIO: _RadioButtonProductsForm,
}
# Produce a subclass of _ProductsForm which we can alter the base_fields on
class ProductsForm(RENDER_TYPES[category.render_type]):
pass
ProductsForm.set_fields(category, products)
return ProductsForm
class VoucherForm(forms.Form):
voucher = forms.CharField(
label="Voucher code",
help_text="If you have a voucher code, enter it here",
required=False,
)
|