@@ -47,24 +47,25 @@ class ManualPaymentForm(forms.ModelForm):
# Products forms -- none of these have any fields: they are to be subclassed
# and the fields added as needs be. ProductsForm (the function) is responsible
# for the subclassing.
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 = {
inventory.Category.RENDER_TYPE_QUANTITY: _QuantityBoxProductsForm,
inventory.Category.RENDER_TYPE_RADIO: _RadioButtonProductsForm,
inventory.Category.RENDER_TYPE_ITEM_QUANTITY: _ItemQuantityProductsForm,
}
# 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 _HasProductsFields(object):
@@ -143,25 +144,24 @@ class _QuantityBoxProductsForm(_ProductsForm):
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))
if not category.required:
choices.append((0, "No selection"))
cls.base_fields[cls.FIELD] = forms.TypedChoiceField(
label=category.name,
widget=forms.RadioSelect,
choices=choices,
empty_value=0,
coerce=int,
@@ -181,19 +181,76 @@ class _RadioButtonProductsForm(_ProductsForm):
def product_quantities(self):
ours = self.cleaned_data[self.FIELD]
choices = self.fields[self.FIELD].choices
for choice_value, choice_display in choices:
if choice_value == 0:
continue
yield (
choice_value,
1 if ours == choice_value else 0,
self.FIELD,
)
class _ItemQuantityProductsForm(_ProductsForm):
''' Products entry form that allows users to select a product type, and
enter a quantity of that product. This version _only_ allows a specific
product type to be purchased.'''
CHOICE_FIELD = "choice"
QUANTITY_FIELD = "quantity"
choice_text = "%s -- $%d each" % (product.name, product.price)
cls.base_fields[cls.CHOICE_FIELD] = forms.TypedChoiceField(
widget=forms.Select,
cls.base_fields[cls.QUANTITY_FIELD] = forms.IntegerField(
label="Quantity", # TODO: internationalise
min_value=0,
max_value=500, # Issue #19. We should figure out real limit.
def initial_data(cls, product_quantities):
initial = {}
for product, quantity in product_quantities:
if quantity > 0:
initial[cls.CHOICE_FIELD] = product.id
initial[cls.QUANTITY_FIELD] = quantity
break
return initial
our_choice = self.cleaned_data[self.CHOICE_FIELD]
our_quantity = self.cleaned_data[self.QUANTITY_FIELD]
choices = self.fields[self.CHOICE_FIELD].choices
our_quantity if our_choice == choice_value else 0,
self.CHOICE_FIELD,
class VoucherForm(forms.Form):
voucher = forms.CharField(
label="Voucher code",
help_text="If you have a voucher code, enter it here",
required=False,