From 9dff1bbd0ffe4ba3b18bd6bcf6a4c11deef06607 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Tue, 6 Nov 2018 13:56:13 +0100 Subject: [PATCH] Add a step for previewing sponsor invoice addresses Due to the number of sponsors that got it wrong, make a separate step where they get to proview the sponsor address exactly as it's going to look on the invoice before proceeding. It won't help with the ones who actually put the wrong company name in, but at least for things like VAT numbers and duplicated (almost the same but not quite) company names etc. --- postgresqleu/confsponsor/forms.py | 3 +- postgresqleu/confsponsor/invoicehandler.py | 13 ++-- postgresqleu/confsponsor/views.py | 84 +++++++++++++--------- template/confsponsor/signupform.html | 24 +++++++ 4 files changed, 82 insertions(+), 42 deletions(-) diff --git a/postgresqleu/confsponsor/forms.py b/postgresqleu/confsponsor/forms.py index fe3c73f..59394cb 100644 --- a/postgresqleu/confsponsor/forms.py +++ b/postgresqleu/confsponsor/forms.py @@ -26,12 +26,11 @@ def _int_with_default(s, default): class SponsorSignupForm(forms.Form): name = forms.CharField(label="Company name *", min_length=3, max_length=100, help_text="This name is used on invoices and in internal communication") displayname = forms.CharField(label="Display name *", min_length=3, max_length=100, help_text="This name is displayed on websites and in public communication") - address = forms.CharField(label="Company invoice address *", min_length=10, max_length=500, widget=forms.Textarea) + address = forms.CharField(label="Company invoice address *", min_length=10, max_length=500, widget=forms.Textarea, help_text="The sponsor name is automatically included at beginning of address. The VAT number is automatically included at end of address.") vatstatus = forms.ChoiceField(label="Company VAT status", choices=vat_status_choices) vatnumber = forms.CharField(label="EU VAT Number", min_length=5, max_length=50, help_text="Enter EU VAT Number to be included on invoices if assigned one. Leave empty if outside the EU or without assigned VAT number.", required=False) url = forms.URLField(label="Company URL *") twittername = forms.CharField(label="Company twitter", min_length=0, max_length=100, required=False, validators=[TwitterValidator, ]) - confirm = forms.BooleanField(help_text="Check this box to that you have read and agree to the terms in the contract") def __init__(self, conference, *args, **kwargs): self.conference = conference diff --git a/postgresqleu/confsponsor/invoicehandler.py b/postgresqleu/confsponsor/invoicehandler.py index 98cc022..3436140 100644 --- a/postgresqleu/confsponsor/invoicehandler.py +++ b/postgresqleu/confsponsor/invoicehandler.py @@ -109,6 +109,12 @@ class InvoiceProcessor(object): return "%s/events/sponsor/%s/" % (settings.SITEBASE, sponsor.id) +def get_sponsor_invoice_address(name, invoiceaddr, vatnumber): + if settings.EU_VAT and vatnumber: + return u"{0}\n{1}\n\nVAT: {2}".format(name, invoiceaddr, vatnumber) + else: + return u"{0}\n{1}".format(name, invoiceaddr) + # Generate an invoice for sponsorship def create_sponsor_invoice(user, sponsor): conference = sponsor.conference @@ -163,18 +169,13 @@ def create_sponsor_invoice(user, sponsor): # to 30 days from now. duedate = datetime.now() + timedelta(days=30) - if settings.EU_VAT and sponsor.vatnumber: - addrstr = u"{0}\n{1}\n\nVAT: {2}".format(sponsor.name, sponsor.invoiceaddr, sponsor.vatnumber) - else: - addrstr = u"{0}\n{1}".format(sponsor.name, sponsor.invoiceaddr) - manager = InvoiceManager() processor = invoicemodels.InvoiceProcessor.objects.get(processorname="confsponsor processor") i = manager.create_invoice( user, user.email, user.first_name + ' ' + user.last_name, - addrstr, + get_sponsor_invoice_address(sponsor.name, sponsor.invoiceaddr, sponsor.vatnumber), '%s sponsorship' % conference.conferencename, datetime.now(), duedate, diff --git a/postgresqleu/confsponsor/views.py b/postgresqleu/confsponsor/views.py index ef40739..e290d3d 100644 --- a/postgresqleu/confsponsor/views.py +++ b/postgresqleu/confsponsor/views.py @@ -24,7 +24,7 @@ from models import PurchasedVoucher from forms import SponsorSignupForm, SponsorSendEmailForm from forms import PurchaseVouchersForm, PurchaseDiscountForm from benefits import get_benefit_class -from invoicehandler import create_sponsor_invoice, confirm_sponsor +from invoicehandler import create_sponsor_invoice, confirm_sponsor, get_sponsor_invoice_address from invoicehandler import create_voucher_invoice from vatutil import validate_eu_vat_number @@ -260,41 +260,57 @@ def sponsor_signup(request, confurlname, levelurlname): if request.method == 'POST': form = SponsorSignupForm(conference, data=request.POST) - if form.is_valid(): - # Create a new sponsorship record always - sponsor = Sponsor(conference=conference, - signupat=datetime.now(), - name=form.cleaned_data['name'], - displayname=form.cleaned_data['displayname'], - url=form.cleaned_data['url'], - level=level, - twittername = form.cleaned_data.get('twittername', ''), - invoiceaddr = form.cleaned_data['address']) - if settings.EU_VAT: - sponsor.vatstatus = int(form.cleaned_data['vatstatus']) - sponsor.vatnumber = form.cleaned_data['vatnumber'] - sponsor.save() - sponsor.managers.add(request.user) - sponsor.save() - - mailstr = "Sponsor %s signed up for conference\n%s at level %s.\n\n" % (sponsor.name, conference, level.levelname) - - if level.instantbuy: - # Create the invoice, so it can be paid right away! - sponsor.invoice = create_sponsor_invoice(request.user, sponsor) - sponsor.invoice.save() + if not request.POST.get('confirm', '0') == '1': + if form.is_valid(): + # Confirm not set, but form valid: show the address verification. + return render(request, 'confsponsor/signupform.html', { + 'user_name': user_name, + 'conference': conference, + 'level': level, + 'form': form, + 'previewaddr': get_sponsor_invoice_address(form.cleaned_data['name'], + form.cleaned_data['address'], + settings.EU_VAT and form.cleaned_data['vatnumber'] or None) + }) + # Else fall through to re-render the full form + # If form not valid, fall through to error below + elif form.is_valid(): + # Confirm is set, but if the Continue editing button is selected we should go back + # to just rendering the normal form. Otherwise, go ahead and create the record. + if request.POST.get('submit', '') != 'Continue editing': + sponsor = Sponsor(conference=conference, + signupat=datetime.now(), + name=form.cleaned_data['name'], + displayname=form.cleaned_data['displayname'], + url=form.cleaned_data['url'], + level=level, + twittername = form.cleaned_data.get('twittername', ''), + invoiceaddr = form.cleaned_data['address']) + if settings.EU_VAT: + sponsor.vatstatus = int(form.cleaned_data['vatstatus']) + sponsor.vatnumber = form.cleaned_data['vatnumber'] + sponsor.save() + sponsor.managers.add(request.user) sponsor.save() - mailstr += "An invoice (#%s) has automatically been generated\nand is awaiting payment." % sponsor.invoice.pk - else: - mailstr += "No invoice has been generated as for this level\na signed contract is required first. The sponsor\nhas been instructed to sign and send the contract." - send_simple_mail(conference.sponsoraddr, - conference.sponsoraddr, - "Sponsor %s signed up for %s" % (sponsor.name, conference), - mailstr, - sendername=conference.conferencename) - # Redirect back to edit the actual sponsorship entry - return HttpResponseRedirect('/events/sponsor/%s/' % sponsor.id) + mailstr = "Sponsor %s signed up for conference\n%s at level %s.\n\n" % (sponsor.name, conference, level.levelname) + + if level.instantbuy: + # Create the invoice, so it can be paid right away! + sponsor.invoice = create_sponsor_invoice(request.user, sponsor) + sponsor.invoice.save() + sponsor.save() + mailstr += "An invoice (#%s) has automatically been generated\nand is awaiting payment." % sponsor.invoice.pk + else: + mailstr += "No invoice has been generated as for this level\na signed contract is required first. The sponsor\nhas been instructed to sign and send the contract." + + send_simple_mail(conference.sponsoraddr, + conference.sponsoraddr, + "Sponsor %s signed up for %s" % (sponsor.name, conference), + mailstr, + sendername=conference.conferencename) + # Redirect back to edit the actual sponsorship entry + return HttpResponseRedirect('/events/sponsor/%s/' % sponsor.id) else: form = SponsorSignupForm(conference) diff --git a/template/confsponsor/signupform.html b/template/confsponsor/signupform.html index b2e0efb..7d1d3fd 100644 --- a/template/confsponsor/signupform.html +++ b/template/confsponsor/signupform.html @@ -5,6 +5,12 @@ tr.error { background-color: #ffb6b6; } +div#addresspreview { + border: 1px solid black; + border-radius: 5px; + padding: 3px; + margin-bottom: 2em; +} {%endblock%} {%block content%} @@ -29,6 +35,7 @@ agree with the contents in it. {%endif%}
{% csrf_token %} +
@@ -45,6 +52,20 @@ Please double-check all the fields with an asterisk in the form above, as they are what will be included on the invoice when it's generated. Once generated, the invoice cannot be changed.

+ +{%if previewaddr%} +

Invoice address preview

+

+ Please verify that the address below is correct. Please note that it will + not be possible to modify the invoice once + generated, so make sure you verify the contents of the address + against any requirements of your organisation. +

+
+{{previewaddr|linebreaks}} +
+ +{%endif%} {%if not level.instantbuy%}

@@ -57,6 +78,9 @@ instructions. {%endif%} +{%if previewaddr%} + +{%endif%}
-- 2.39.5

Level{{level}}
Contact name *{{user_name}}