97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
from django import forms
|
|
from django.utils.safestring import mark_safe
|
|
from django.urls import reverse
|
|
from .models import SustainerOrder
|
|
|
|
MONTH_MINIMUM = 10
|
|
YEAR_MINIMUM = 120
|
|
|
|
class SustainerFormRenderer(forms.renderers.DjangoTemplates):
|
|
# Customised layout with labels on own row
|
|
field_template_name = 'supporters/field.html'
|
|
|
|
|
|
class ButtonRadioSelect(forms.widgets.RadioSelect):
|
|
"""Radio button styled like a button. BYO CSS."""
|
|
# Extra <span> wrappers to support CSS
|
|
option_template_name = 'supporters/buttonradio_option.html'
|
|
use_fieldset = False
|
|
|
|
class Media:
|
|
css = {
|
|
'all': ['css/buttonradio.css'],
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.attrs['class'] = 'button-select'
|
|
|
|
|
|
class SustainerForm(forms.ModelForm):
|
|
# Used to pre-fill the price selector
|
|
amount_option = forms.CharField(required=False)
|
|
|
|
template_name = 'supporters/sustainer_form.html'
|
|
|
|
MONTH_OPTIONS = [12, 25, 50, 100]
|
|
YEAR_OPTIONS = [128, 250, 500, 1000]
|
|
|
|
class Meta:
|
|
model = SustainerOrder
|
|
fields = [
|
|
'recurring',
|
|
'amount',
|
|
'name',
|
|
'email',
|
|
'acknowledge_publicly',
|
|
'add_to_mailing_list',
|
|
'tshirt_size',
|
|
'street',
|
|
'city',
|
|
'state',
|
|
'zip_code',
|
|
'country',
|
|
]
|
|
widgets = {
|
|
'recurring': ButtonRadioSelect(attrs={
|
|
'x-model': 'recurring',
|
|
# Reset the amount field and option when changing monthly/annually.
|
|
'x-on:change': '$refs.amount.value = null; amount_option = null',
|
|
}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.renderer = SustainerFormRenderer()
|
|
|
|
self.fields['recurring'].label = ''
|
|
self.fields['amount'].initial = self.YEAR_OPTIONS[0]
|
|
# So we can write to this field easily from Alpine JS.
|
|
self.fields['amount'].widget.attrs['x-ref'] = 'amount'
|
|
self.fields['amount'].widget.attrs['style'] = 'width: 5rem'
|
|
self.fields['email'].help_text = 'For your payment receipt'
|
|
self.fields['tshirt_size'].help_text = mark_safe("""Sizing chart: <a href="/videos/women-2017-to-2020-t-shirt-sizing.jpg" target="_blank" class="black-60">Women's</a>, <a href="/videos/men-2017-to-2020-t-shirt-sizing.jpg" target="_blank" class="black-60">Men's</a>""")
|
|
self.fields['tshirt_size'].widget.attrs['x-model'] = 'tshirt_size'
|
|
|
|
def clean(self):
|
|
super().clean()
|
|
recurring = self.cleaned_data.get('recurring', '')
|
|
amount = self.cleaned_data.get('amount', 0)
|
|
minimum = MONTH_MINIMUM if recurring == 'month' else YEAR_MINIMUM
|
|
donate_url = reverse('donate')
|
|
if amount < minimum:
|
|
self.add_error(
|
|
'',
|
|
mark_safe(f'${minimum:d} is a minimum for Conservancy Sustainers. <a href="{donate_url}">Donate smaller amounts here</a>.')
|
|
)
|
|
tshirt_size = self.cleaned_data.get('tshirt_size')
|
|
if tshirt_size and not all([
|
|
self.cleaned_data.get('street'),
|
|
self.cleaned_data.get('city'),
|
|
self.cleaned_data.get('country')
|
|
]):
|
|
self.add_error(
|
|
'street',
|
|
'No address provided'
|
|
)
|