"""File containing member forms.""" from django import forms from django.utils import timezone from django.utils.translation import ugettext_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_email(self): email = self.cleaned_data['email'] if Member.objects.filter(email=email).exists(): raise forms.ValidationError('Member with email "{}" already exists.'.format(email), code='exists') return email 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(',') 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']