"""File containing member forms.""" from django import forms from django.utils import timezone from django.utils.translation import gettext_lazy as _ from members.models import Member, Payment, Request import csv import logging from dal import autocomplete class CSVValidationError(Exception): def __init__(self, form_errors): self.form_errors = form_errors class MemberForm(forms.ModelForm): """Member model form.""" class Meta: """Meta for Member model form.""" model = Member fields = ["first_name", "last_name", "email", "POR", "AYY", "jas"] class ImportResult: def __init__(self, members, payments): self.members = members self.payments = payments def _clean_boolean_field(self, key): value = self.data.get(key, None) if value in ["1", "0"]: return bool(int(value)) else: return value == "on" def clean_jas(self): return self._clean_boolean_field("jas") def clean_AYY(self): return self._clean_boolean_field("AYY") @staticmethod def csv_to_models(data, payment_source="AYY", delimiter=","): clean_data = data.strip().split("\n") clean_data = [row.rstrip(",").rstrip("\r").strip() for row in clean_data] csv_reader = csv.DictReader( clean_data, fieldnames=MemberForm.Meta.fields, delimiter=delimiter, quoting=csv.QUOTE_NONE, ) members = [] payments = [] for line in csv_reader: try: for key, value in line.items(): line[key] = value.strip() except AttributeError as ex: logging.error('Invalid line in CSV: "{}"'.format(line)) logging.error("Delimiter: {}".format(delimiter)) raise email = line["email"] member_exists = False if Member.objects.filter(email=email).exists(): member_exists = True if not member_exists: form = MemberForm(line) if not form.is_valid(): raise CSVValidationError(form.errors) model = form.save(commit=False) members.append(model) else: member = Member.objects.get(email=email) payment_data = { "source": payment_source, "member": member.id, "date": timezone.now(), } form = PaymentForm(payment_data) if not form.is_valid(): raise CSVValidationError(form.errors) model = form.save(commit=False) payments.append(model) return MemberForm.ImportResult(members, payments) class PaymentForm(forms.ModelForm): """Payment model form.""" member = forms.ModelChoiceField( queryset=Member.objects.all(), widget=autocomplete.ModelSelect2(url="member-autocomplete"), ) class Meta: """Meta for Payment model form.""" model = Payment fields = ["date", "source", "member"] labels = {"member": _("Member")} class ApplicationForm(forms.ModelForm): """Member application model form.""" class Meta: """Meta for application model form.""" model = Request fields = ["first_name", "last_name", "email", "AYY", "jas", "POR"] def __init__(self, *args, **kwargs): super(ApplicationForm, self).__init__(*args, **kwargs) self.fields["AYY"].label = _("I'm a member of AYY") self.fields["jas"].label = _("I want to receive a weekly newsletter") class UploadFileForm(forms.Form): file = forms.FileField()