Mercurial > sat_legacy_website
view sat_website/forms.py @ 72:ac83544a7645
display an ugly menu in <noscript> when JS is disabled
author | souliane <souliane@mailoo.org> |
---|---|
date | Wed, 27 May 2015 19:24:28 +0200 |
parents | 64977f537e9b |
children | 651c4049f32b |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- """ SàT website: Salut à Toi's presentation website Copyright (C) 2012 Jérôme Poisson (goffi@goffi.org) This file is part of SàT website. SàT website is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Foobar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Foobar. If not, see <http://www.gnu.org/licenses/>. """ from django.utils.translation import ugettext_lazy as _, ugettext, string_concat, get_language from django.core.mail import send_mail from django import forms from django.conf import settings from collections import OrderedDict import unicodecsv import utils import re ## Fields ## class Section(forms.Field): def __init__(self, *args, **kwargs): kwargs['required'] = False super(Section, self).__init__(*args, **kwargs) class BooleanField(forms.BooleanField): def __init__(self, *args, **kwargs): super(BooleanField, self).__init__(*args, **kwargs) class CharField(forms.CharField): def __init__(self, label=None, *args, **kwargs): try: placeholder = kwargs.pop('placeholder') except KeyError: placeholder = label super(CharField, self).__init__(*args, **kwargs) self.widget.attrs.update({'class': "form-control", 'placeholder': placeholder}) class EmailField(forms.EmailField): def __init__(self, *args, **kwargs): super(EmailField, self).__init__(*args, **kwargs) self.widget.attrs.update({'class': "form-control", 'placeholder': self.label}) class ChoiceField(forms.ChoiceField): def __init__(self, *args, **kwargs): super(ChoiceField, self).__init__(*args, **kwargs) self.widget.attrs.update({'class': "form-control"}) def choice_label(self, value): """Return the label corresponding to the given value. @param value (unicode): a choice value @return: unicode """ for current_value, label in self.choices: if unicode(current_value) == unicode(value): return unicode(label) return u'' ## Forms ## class RegistrationForm(forms.Form): section_1 = Section(label=_(u'Identity')) name = CharField(label=_(u'Given name')) surname = CharField(label=_(u'Family name')) address = CharField(label=_(u"Address, postal code, municipality"), widget=forms.Textarea(attrs={'rows': 3})) section_2 = Section(label=_(u'Contacts')) email = EmailField(label=_(u'Email address')) email_confirmation = EmailField(label=_(u'Email address confirmation')) jid = EmailField(required=False, label=_(u'Jabber ID (for example your SàT login)')) section_3 = Section(label=_(u'Subscription')) subscription_amount = ChoiceField(choices=[(amount, u"%s €" % amount) for amount in utils.get_asso_subscr_amounts()]) section_3b = Section(label="") payment_method = ChoiceField(choices=[(u"transfer", _(u"Bank transfer")), (u"card", _(u"Credit or debit card"))], help_text=_(u'Choose "Bank transfer" to proceed manually with the association\'s IBAN/BIC numbers. Choose "Credit or debit card" to pay via CB, Visa or Mastercard using a secure banking service. For both methods, we will first send you an email containing all the details.'), widget=forms.RadioSelect) section_5 = Section(label=_(u'Reference')) reference = CharField(required=False, label=_(u"Reference"), placeholder=_(u"Adherent number in case of a renewal")) section_6 = Section(label=_(u'Comment')) comment = CharField(required=False, label=_(u"Comment"), placeholder="", widget=forms.Textarea(attrs={'rows': 3})) newsletter = BooleanField(required=False, label=_(u'I would like to receive the newsletter.')) def html_link(url, label): return string_concat('<a target="#" href="', url, '">', label, '</a>') agreement_label = [_(u"I read the "), html_link(settings.ASSO_URL_STATUTES, _(u"Statutes")), _(u" and "), html_link(settings.ASSO_URL_RULES, _(u"Rules")), _(u" of the association, and agree to both of them."), ] agreement_confirmation = BooleanField(label=string_concat(*agreement_label)) def sections(self): """Get the fields grouped in sections. @return: OrderedDict binding section name to a list of fields """ sections = OrderedDict() current_section = None for field in self: if isinstance(field.field, Section): current_section = sections.setdefault(field.label, []) else: current_section.append(field) return sections def clean(self): cleaned_data = super(RegistrationForm, self).clean() email = cleaned_data.get("email") email_confirmation = cleaned_data.get("email_confirmation") if email and email_confirmation and email != email_confirmation: msg = _(u"Passwords don't match.") self.add_error('email_confirmation', msg) def results(self, user_readable=True): """Get the results submitted by the user as a list. @param user_readable: (bool) set to True to prefer the fields' labels to their names, also filter out the empty fields. @return: list of couple (name, value) or (label, value) """ if not self.is_valid(): return None results = [] for field in self: if isinstance(field.field, Section): continue # filter out section fields if field.name in ('email_confirmation', 'agreement_confirmation'): continue # filter out confirmation fields if user_readable and not field.value(): continue # filter out empty value if user_readable and field.name == "payment_method" and self['subscription_amount'].value() == "0": continue # filter out fields that are not pertinent for the user key = field.name if isinstance(field.field, BooleanField) and user_readable: value = ugettext(u"yes") if field.value() else ugettext(u"no") else: value = re.sub(r"[\n\r]+", ", ", unicode(field.value())) if user_readable: if isinstance(field.field, BooleanField): key = key.capitalize() # to get Newsletter instead of "Please add me..." else: key = field.label if isinstance(field.field, ChoiceField): value = field.field.choice_label(value) results.append((key, value)) if user_readable: results.append((_(u'Language'), utils.get_language_name_local(get_language()))) else: results.append(('lang', get_language())) return results def result_as_dict(self, user_readable=True): """Get the results submitted by the user as an OrderedDict. @param user_readable (bool): set to True to prefer the field labels to their names @return: dict {name: value} or {label: value} """ return {key: value for key, value in self.results(user_readable)} def result_as_string(self, user_readable=True): """Get the result as a string to be sent for example via email. @param user_readable (bool): set to True to prefer the field labels to their names @return: unicode """ return '\n'.join([name + ': ' + value for name, value in self.results(user_readable)]) def prepareResultForUser(self): """Get the email body to send to the subscriber. @return: unicode """ ref = self['reference'].value() data = {'name': self['name'].value(), 'surname': self['surname'].value(), 'amount': self['subscription_amount'].value(), 'ref_info': '(ref. {ref})'.format(ref=ref) if ref else '', 'iban': settings.ASSO_IBAN, 'bic': settings.ASSO_BIC, 'result': self.result_as_string(True) } HEADER = ugettext(u"""Thank you, {name}! We received your submission and we are happy to count you in the members of the association. """) PAYMENT = ugettext(u"""You chose to support Salut à Toi with a subscription of {amount} euros. Please complete your adhesion with a bank transfer to: Payee: Salut à Toi IBAN: {iban} BIC: {bic} Reason: subscription of {name} {surname} {ref_info} Or, if you prefer, you can proceed with a credit or debit card: https://www.apayer.fr/salut-a-toi """) FOOTER = ugettext(u"""Below a copy of the information we received: {result} If you have any question, feel free to contact us. Association Salut à Toi http://salut-a-toi.org""") return (HEADER + (PAYMENT if int(data['amount']) > 0 else "") + FOOTER).format(**data) def prepareResultForAdmin(self): """Get the email body to send to the admins. @return: unicode """ data = {'name': self['name'].value(), 'result': self.result_as_string(False) } MSG = ugettext(u"""New subscription received! {result} An email has been automatically sent to {name}, no additional action is required from your side.""") return MSG.format(**data) def writeResultToCSV(self): result = [unicode(value) for key, value in self.results(False)] with open(settings.ASSO_SUBSCR_CSV, 'a+') as csvfile: writer = unicodecsv.UnicodeWriter(csvfile, delimiter=';') writer.writerow(result) def process_submitted_data(self): """Send emails to the subscriber and the admins.""" if not self.is_valid(): return # send email to user send_mail(_(u'Subscription to Salut à Toi'), self.prepareResultForUser(), settings.FORM_FROM_EMAIL, [self['email'].value()], fail_silently=False) # send email to admins send_mail(_(u'Subscription to Salut à Toi'), self.prepareResultForAdmin(), settings.FORM_FROM_EMAIL, settings.FORM_TO_EMAILS, fail_silently=False) # save to a CSV file self.writeResultToCSV()