summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Hagander2025-06-03 13:38:52 +0000
committerMagnus Hagander2025-06-03 13:38:52 +0000
commit2d4eae94f0bc06f271225ad5444e6fb2cd14efbb (patch)
tree9fe084fae2f3e0cb6a813ababd185a71623832b9
parentc7dfd89c9ba2910f81f8c371d2842d6227ee8c00 (diff)
Add support for sponsors requesting explicit contract at click-through levels
Click-through contracts makes it easier for most, but some sponsor organisations require an actual contract at these levels as well. To handle this, add an option during contract/address verification to request an explicit contract, which can then be either manual or digital, and will both prevent the clickthrough contract and invoice to be sent until thsi contract has been completed.
-rw-r--r--postgresqleu/confsponsor/migrations/0035_sponsor_explicitcontract.py18
-rw-r--r--postgresqleu/confsponsor/models.py1
-rw-r--r--postgresqleu/confsponsor/util.py2
-rw-r--r--postgresqleu/confsponsor/views.py13
-rw-r--r--template/confsponsor/admin_dashboard.html2
-rw-r--r--template/confsponsor/admin_sponsor.html6
-rw-r--r--template/confsponsor/admin_sponsor_details.html2
-rw-r--r--template/confsponsor/signupform.html14
-rw-r--r--template/confsponsor/sponsor.html4
9 files changed, 49 insertions, 13 deletions
diff --git a/postgresqleu/confsponsor/migrations/0035_sponsor_explicitcontract.py b/postgresqleu/confsponsor/migrations/0035_sponsor_explicitcontract.py
new file mode 100644
index 00000000..7b53b368
--- /dev/null
+++ b/postgresqleu/confsponsor/migrations/0035_sponsor_explicitcontract.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.11 on 2025-06-03 13:17
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('confsponsor', '0034_rename_instantbuy'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='sponsor',
+ name='explicitcontract',
+ field=models.BooleanField(default=False, verbose_name='Requested explicit contract'),
+ ),
+ ]
diff --git a/postgresqleu/confsponsor/models.py b/postgresqleu/confsponsor/models.py
index d6d9b404..1e56c985 100644
--- a/postgresqleu/confsponsor/models.py
+++ b/postgresqleu/confsponsor/models.py
@@ -166,6 +166,7 @@ class Sponsor(models.Model):
signmethod = models.IntegerField(null=False, blank=False, default=1, choices=((0, 'Digital signatures'), (1, 'Manual signatures')), verbose_name='Signing method')
autoapprovesigned = models.BooleanField(null=False, blank=False, default=True, verbose_name="Approve on signing", help_text="Automatically approve once digital signatures are completed")
contract = models.OneToOneField(DigisignDocument, null=True, blank=True, help_text="Contract, when using digital signatures", on_delete=models.SET_NULL)
+ explicitcontract = models.BooleanField(null=False, blank=False, default=False, verbose_name='Requested explicit contract')
def __str__(self):
return self.name
diff --git a/postgresqleu/confsponsor/util.py b/postgresqleu/confsponsor/util.py
index f9daeafa..9e87617d 100644
--- a/postgresqleu/confsponsor/util.py
+++ b/postgresqleu/confsponsor/util.py
@@ -175,7 +175,7 @@ def get_pdf_fields_for_conference(conference, sponsor=None, overrides={}):
fields.append(
('static:euvat', sponsor.vatnumber if sponsor else overrides.get('static:euvat', 'Sponsor EU VAT number')),
)
- if sponsor and sponsor.level.contractlevel == 1:
+ if sponsor and sponsor.level.contractlevel == 1 and not sponsor.explicitcontract:
# Only add clickthrough contract fields if it's a clickthrough level (or a preview, with no sponsor yet)
fields.extend([
('static:clickthrough', overrides.get('static:clickthrough', 'Click-through agreement')),
diff --git a/postgresqleu/confsponsor/views.py b/postgresqleu/confsponsor/views.py
index 09701e70..5b7cdae0 100644
--- a/postgresqleu/confsponsor/views.py
+++ b/postgresqleu/confsponsor/views.py
@@ -389,7 +389,7 @@ def _generate_and_send_sponsor_contract(sponsor):
send_sponsor_manager_email(
sponsor,
'Your contract for {}'.format(conference.conferencename),
- 'confsponsor/mail/{}.txt'.format('sponsor_contract_instant' if level.contractlevel == 1 else 'sponsor_contract_manual'),
+ 'confsponsor/mail/{}.txt'.format('sponsor_contract_instant' if (level.contractlevel == 1 and not sponsor.explicitcontract) else 'sponsor_contract_manual'),
{
'conference': conference,
'sponsor': sponsor,
@@ -455,7 +455,7 @@ def sponsor_signup(request, confurlname, levelurlname):
# Stage 2 = contract choice. When submitted, sign up.
# If there is no contract needed on this level, or there is no choice
# of contract because only one available, we bypass stage 1.
- if stage == '1' and (level.contractlevel != 2 or not conference.contractprovider or not conference.manualcontracts):
+ if stage == '1' and ((level.contractlevel != 2 and request.POST.get('explicitcontract', '') != '1') or not conference.contractprovider or not conference.manualcontracts):
stage = '2'
def _render_contract_choices():
@@ -480,6 +480,7 @@ def sponsor_signup(request, confurlname, levelurlname):
'form': form,
'noform': 1,
'contractchoices': contractchoices,
+ 'explicitcontract': request.POST.get('explicitcontract', '') == '1',
})
if stage == '0':
@@ -507,7 +508,7 @@ def sponsor_signup(request, confurlname, levelurlname):
# 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':
- if request.POST.get('contractchoice', '') not in ('0', '1') and level.contractlevel == 2:
+ if request.POST.get('contractchoice', '') not in ('0', '1') and (level.contractlevel == 2 or request.POST.get('explicitcontract', '') == '1'):
return _render_contract_choices()
social = {
@@ -525,8 +526,9 @@ def sponsor_signup(request, confurlname, levelurlname):
level=level,
social=social,
invoiceaddr=form.cleaned_data['address'],
- signmethod=1 if request.POST.get('contractchoice', '') == '1' or not conference.contractprovider or level.contractlevel < 2 else 0,
+ signmethod=1 if request.POST.get('contractchoice', '') == '1' or not conference.contractprovider or level.contractlevel < 2 or request.POST.get('explicitcontract', '') == '1' else 0,
autoapprovesigned=conference.autocontracts,
+ explicitcontract=request.POST.get('explicitcontract', '') == '1',
)
if settings.EU_VAT:
sponsor.vatstatus = int(form.cleaned_data['vatstatus'])
@@ -539,7 +541,7 @@ def sponsor_signup(request, confurlname, levelurlname):
error = None
- if level.contractlevel < 2:
+ if level.contractlevel < 2 and request.POST.get('explicitcontract', '') != '1':
# No contract or click-through contract
if level.contractlevel == 1:
# Click-through contract
@@ -548,6 +550,7 @@ def sponsor_signup(request, confurlname, levelurlname):
mailstr += "Level does not require a signed contract. Verify the details and approve\nthe sponsorship using:\n\n{0}/events/sponsor/admin/{1}/{2}/".format(
settings.SITEBASE, conference.urlname, sponsor.id)
else:
+ # Contract required!
contractid, error = _generate_and_send_sponsor_contract(sponsor)
if sponsor.signmethod == 1:
diff --git a/template/confsponsor/admin_dashboard.html b/template/confsponsor/admin_dashboard.html
index 8fa6f119..e7d0ae89 100644
--- a/template/confsponsor/admin_dashboard.html
+++ b/template/confsponsor/admin_dashboard.html
@@ -88,7 +88,7 @@ sponsor manually, you may want to confirm them manually as well...
{%else%}
<span class="label label-success">Invoiced</span>
{%endif%}
- {%elif s.level.contractlevel < 2 %}
+ {%elif s.level.contractlevel < 2 and not s.explicitcontract %}
<span class="label label-warning" title="Sponsor details for {%if s.level.contractlevel == 1 %}click-through{%else%}no{%endif%} contract levels have to be verified before invoice is issued">Pending organizer verification</span>
{%else%}
{%if s.signmethod == 0 and s.contract %}
diff --git a/template/confsponsor/admin_sponsor.html b/template/confsponsor/admin_sponsor.html
index 99b3caf7..75ae0a83 100644
--- a/template/confsponsor/admin_sponsor.html
+++ b/template/confsponsor/admin_sponsor.html
@@ -140,7 +140,7 @@
<p>
This sponsorship is awaiting an <a href="/invoiceadmin/{{sponsor.invoice.pk}}/">invoice</a> to be paid.
</p>
-{%if sponsor.level.contractlevel == 2 %}
+{%if sponsor.level.contractlevel == 2 or sponsor.explicitcontract %}
{%comment%}Only full contract sponsorships should be manually confirmed{%endcomment%}
<p>
<b>Iff</b> there is a signed <i>and</i> countersigned contract available
@@ -161,7 +161,7 @@ for this sponsor, it can be confirmed before the invoice is paid.
{%else%}
{%comment%}Sponsor has no invoice{%endcomment%}
{%if sponsor.level.levelcost %}
-{%if sponsor.level.contractlevel < 2%}
+{%if sponsor.level.contractlevel < 2 and not sponsor.explicitcontract %}
<p>
This sponsorship has not yet been issued an invoice. This is a
{%if sponsor.level.contractlevel == 1 %}click-through{%else%}no{%endif%}
@@ -192,7 +192,7 @@ This sponsorship has not yet been issued an invoice. Once the contract
has been received, go ahead and generate the invoice.
</p>
{%endif%}{%comment%}Digital contracts{%endcomment%}
-{%endif%}{%comment%}contractlevel < 2{%endcomment%}
+{%endif%}{%comment%}contractlevel < 2 and not explicitcontract{%endcomment%}
{%else%}{%comment%}levelcost != 0 {%endcomment%}
<p>
This sponsorship has zero cost, which means payment is handled manually.
diff --git a/template/confsponsor/admin_sponsor_details.html b/template/confsponsor/admin_sponsor_details.html
index dac8b191..deacbc8c 100644
--- a/template/confsponsor/admin_sponsor_details.html
+++ b/template/confsponsor/admin_sponsor_details.html
@@ -41,7 +41,7 @@
<td>
{%if sponsor.level.contractlevel == 0 %}
No contract needed for this level.
- {%elif sponsor.level.contractlevel == 1 %}
+ {%elif sponsor.level.contractlevel == 1 and not sponsor.explicitcontract %}
Click-through contract completed. {%if not sponsor.confirmed%}<form class="inline-block-form" method="post" action="resendcontract/">{% csrf_token %}<input type="submit" class="btn btn-sm btn-default confirm-btn" value="Re-send contract anyway" data-confirm="Are you sure you want to re-send a new contract to this sponsor?{%if sponsor.signmethod == 0%} {{conference.contractprovider.implementation.resendprompt}}{%endif%}"></form>{%endif%}
{%else%}{%comment%}Full contract{%endcomment%}
{%if sponsor.signmethod == 0%}
diff --git a/template/confsponsor/signupform.html b/template/confsponsor/signupform.html
index 689e4d1b..684a37dc 100644
--- a/template/confsponsor/signupform.html
+++ b/template/confsponsor/signupform.html
@@ -65,6 +65,19 @@ the invoice cannot be changed.
step. If anything about it is incorrect please click <i>Continue
editing</i> and correct it <i>before</i> proceeding.
</p>
+
+{% if level.contractlevel == 1 %}
+<h4>Contract options</h4>
+<p>
+ As this level uses a click-thruogh contract, no specific contract signature is
+ required. However, if your organization requires a signed contract, you can
+ explicitly request one here.
+</p>
+<p>
+ <input type="checkbox" name="explicitcontract" value="1"> Request explicit contract
+</p>
+{% endif %}
+
{%endif%}
<h4>Invoice address preview</h4>
@@ -97,6 +110,7 @@ the invoice cannot be changed.
</dl>
<input type="hidden" name="stage" value="2">
+{%if explicitcontract %}<input type="hidden" name="explicitcontract" value="1">{%endif%}
{%endif%}{# contractchoices #}
{%if level.contractlevle == 2 and not noform %}
diff --git a/template/confsponsor/sponsor.html b/template/confsponsor/sponsor.html
index 9f11f934..6a4679ae 100644
--- a/template/confsponsor/sponsor.html
+++ b/template/confsponsor/sponsor.html
@@ -40,7 +40,7 @@
<td>
{% if sponsor.level.contractlevel == 0 %}
This level requires no contract.
-{% elif sponsor.level.contractlevel == 1 %}
+{% elif sponsor.level.contractlevel == 1 and not sponsor.explicitcontract %}
Click-through contract agreed to. <a href="contractview/" class="btn btn-outline-dark btn-sm">View copy of contract</a>
{% else %}
{%if sponsor.signmethod == 0%}
@@ -75,7 +75,7 @@ Manual contract signed.
{%endwith%}
{%else%}
{%comment%}No invoice generated{%endcomment%}
-{%if sponsor.level.contractlevel < 2 %}
+{%if sponsor.level.contractlevel < 2 and not sponsor.explicitcontract %}
{%comment%}No invoice generated but clickthrough contract or no contract, so awaiting admin approval{%endcomment%}
<p>
Your sponsorship request has been submitted, and is currently awaiting confirmation