Change to just using online auth for internal clients.

This effectively reverts 067e03b.
This commit is contained in:
Tom Price
2017-05-23 18:19:02 +01:00
parent 4d316c7a4a
commit c6b7bbc219
16 changed files with 123 additions and 183 deletions

View File

@@ -144,7 +144,7 @@ class EventForm(forms.ModelForm):
fields = ['is_rig', 'name', 'venue', 'start_time', 'end_date', 'start_date',
'end_time', 'meet_at', 'access_at', 'description', 'notes', 'mic',
'person', 'organisation', 'dry_hire', 'checked_in_by', 'status',
'collector']
'purchase_order', 'collector']
class BaseClientEventAuthorisationForm(forms.ModelForm):
@@ -171,15 +171,5 @@ class InternalClientEventAuthorisationForm(BaseClientEventAuthorisationForm):
fields = ('tos', 'name', 'amount', 'uni_id', 'account_code')
class ExternalClientEventAuthorisationForm(BaseClientEventAuthorisationForm):
def __init__(self, **kwargs):
super(ExternalClientEventAuthorisationForm, self).__init__(**kwargs)
self.fields['po'].required = True
class Meta:
model = models.EventAuthorisation
fields = ('tos', 'name', 'amount', 'po')
class EventAuthorisationRequestForm(forms.Form):
email = forms.EmailField(required=True, label='Authoriser Email')

View File

@@ -19,7 +19,6 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=255)),
('uni_id', models.CharField(max_length=10, null=True, verbose_name=b'University ID', blank=True)),
('account_code', models.CharField(max_length=50, null=True, blank=True)),
('po', models.CharField(max_length=255, null=True, verbose_name=b'purchase order', blank=True)),
('amount', models.DecimalField(verbose_name=b'authorisation amount', max_digits=10, decimal_places=2)),
('created_at', models.DateTimeField(auto_now_add=True)),
('event', models.ForeignKey(related_name='authroisations', to='RIGS.Event')),

View File

@@ -1,48 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db.models import F, Sum, DecimalField
def POs_forward(apps, schema_editor):
VatRate = apps.get_model('RIGS', 'VatRate')
Event = apps.get_model('RIGS', 'Event')
EventItem = apps.get_model('RIGS', 'EventItem')
EventAuthorisation = apps.get_model('RIGS', 'EventAuthorisation')
db_alias = schema_editor.connection.alias
for event in Event.objects.using(db_alias).filter(purchase_order__isnull=False):
sum_total = EventItem.objects.filter(event=event).aggregate(
sum_total=Sum(models.F('cost') * F('quantity'),
output_field=DecimalField(
max_digits=10,
decimal_places=2)
)
)['sum_total']
vat = VatRate.objects.using(db_alias).filter(start_at__lte=event.start_date).latest()
total = sum_total + sum_total * vat.rate
EventAuthorisation.objects.using(db_alias).create(event=event, name='LEGACY',
email='treasurer@nottinghamtec.co.uk',
amount=total,
po=event.purchase_order)
def POs_reverse(apps, schema_editor):
EventAuthorisation = apps.get_model('RIGS', 'EventAuthorisation')
db_alias = schema_editor.connection.alias
for auth in EventAuthorisation.objects.using(db_alias).filter(po__isnull=False):
auth.event.purchase_order = auth.po
auth.delete()
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0027_eventauthorisation_event_singular'),
]
operations = [
migrations.RunPython(POs_forward, POs_reverse),
migrations.RemoveField(model_name='event', name='purchase_order')
]

View File

@@ -8,7 +8,7 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0028_migrate_purchase_order'),
('RIGS', '0027_eventauthorisation_event_singular'),
]
operations = [

View File

@@ -329,6 +329,7 @@ class Event(models.Model, RevisionMixin):
# Monies
payment_method = models.CharField(max_length=255, blank=True, null=True)
payment_received = models.CharField(max_length=255, blank=True, null=True)
purchase_order = models.CharField(max_length=255, blank=True, null=True, verbose_name='PO')
collector = models.CharField(max_length=255, blank=True, null=True, verbose_name='collected by')
# Authorisation request details
@@ -388,7 +389,7 @@ class Event(models.Model, RevisionMixin):
@property
def authorised(self):
return self.authorisation.amount == self.total
return not self.internal and self.purchase_order or self.authorisation.amount == self.total
@property
def has_start_time(self):
@@ -450,6 +451,10 @@ class Event(models.Model, RevisionMixin):
else:
return endDate
@property
def internal(self):
return self.organisation and self.organisation.union_account
objects = EventManager()
def get_absolute_url(self):
@@ -513,7 +518,6 @@ class EventAuthorisation(models.Model, RevisionMixin):
name = models.CharField(max_length=255)
uni_id = models.CharField(max_length=10, blank=True, null=True, verbose_name="University ID")
account_code = models.CharField(max_length=50, blank=True, null=True)
po = models.CharField(max_length=255, blank=True, null=True, verbose_name="purchase order")
amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="authorisation amount")
sent_by = models.ForeignKey('RIGS.Profile')

View File

@@ -137,6 +137,7 @@ class EventDuplicate(EventUpdate):
old = super(EventDuplicate, self).get_object(queryset) # Get the object (the event you're duplicating)
new = copy.copy(old) # Make a copy of the object in memory
new.based_on = old # Make the new event based on the old event
new.purchase_order = None
# Remove all the authorisation information from the new event
new.auth_request_to = None
@@ -256,20 +257,12 @@ class EventAuthorise(generic.UpdateView):
return getattr(self.event, 'authorisation', None)
def get_form_class(self):
if self.event.organisation is not None and self.event.organisation.union_account:
return forms.InternalClientEventAuthorisationForm
else:
return forms.ExternalClientEventAuthorisationForm
return forms.InternalClientEventAuthorisationForm
def get_context_data(self, **kwargs):
context = super(EventAuthorise, self).get_context_data(**kwargs)
context['event'] = self.event
if self.get_form_class() is forms.InternalClientEventAuthorisationForm:
context['internal'] = True
else:
context['internal'] = False
context['tos_url'] = settings.TERMS_OF_HIRE_URL
return context
@@ -304,6 +297,7 @@ class EventAuthorise(generic.UpdateView):
"This URL is invalid. Please ask your TEC contact for a new URL")
return super(EventAuthorise, self).dispatch(request, *args, **kwargs)
class EventAuthorisationRequest(generic.FormView, generic.detail.SingleObjectMixin):
model = models.Event
form_class = forms.EventAuthorisationRequestForm

View File

@@ -71,7 +71,7 @@
</div>
{% endif %}
{% if event.is_rig %}
{% if event.is_rig and event.internal %}
<div class="panel panel-default">
<div class="panel-heading">Client Authorisation</div>
<div class="panel-body">
@@ -183,17 +183,23 @@
{% if event.is_rig %}
<dd>&nbsp;</dd>
<dt>Authorisation Request</dt>
<dd>{{ object.auth_request_to|yesno:"Yes,No" }}</dd>
{% if object.internal %}
<dt>Authorisation Request</dt>
<dd>{{ object.auth_request_to|yesno:"Yes,No" }}</dd>
<dt>By</dt>
<dd>{{ object.auth_request_by }}</dd>
<dt>By</dt>
<dd>{{ object.auth_request_by }}</dd>
<dt>At</dt>
<dd>{{ object.auth_request_at|date:"D d M Y H:i"|default:"" }}</dd>
<dt>At</dt>
<dd>{{ object.auth_request_at|date:"D d M Y H:i"|default:"" }}</dd>
<dt>To</dt>
<dd>{{ object.auth_request_to }}</dd>
<dt>To</dt>
<dd>{{ object.auth_request_to }}</dd>
{% else %}
<dt>PO</dt>
<dd>{{ object.purchase_order }}</dd>
{% endif %}
{% endif %}
</dl>
</div>

View File

@@ -11,29 +11,32 @@
class="glyphicon glyphicon-duplicate"></span> <span
class="hidden-xs">Duplicate</span></a>
{% if event.is_rig %}
<a class="btn btn-default item-add modal-href event-authorise-request
{% if event.authorised %}
btn-success
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
btn-warning
{% elif event.auth_request_to %}
btn-info
{% endif %}
"
href="{% url 'event_authorise_request' object.pk %}">
<span class="glyphicon glyphicon-send"></span>
<span class="hidden-xs">
{% if event.authorised %}
Authorised
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
Authorisation Issue
{% elif event.auth_request_to %}
Awaiting Authorisation
{% else %}
Request Authorisation
{% endif %}
</span>
</a>
{% if event.internal %}
<a class="btn btn-default item-add modal-href event-authorise-request
{% if event.authorised %}
btn-success
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
btn-warning
{% elif event.auth_request_to %}
btn-info
{% endif %}
"
href="{% url 'event_authorise_request' object.pk %}">
<span class="glyphicon glyphicon-send"></span>
<span class="hidden-xs">
{% if event.authorised %}
Authorised
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
Authorisation Issue
{% elif event.auth_request_to %}
Awaiting Authorisation
{% else %}
Request Authorisation
{% endif %}
</span>
</a>
{% endif %}
{% if perms.RIGS.add_invoice %}
<a id="invoiceDropdownLabel" href="{% url 'invoice_event' event.pk %}" class="btn
{% if event.invoice and event.invoice.is_closed %}

View File

@@ -398,6 +398,15 @@
{% render_field form.collector class+="form-control" %}
</div>
</div>
<div class="form-group" data-toggle="tooltip" title="The purchase order number (for external clients)">
<label for="{{ form.purchase_order.id_for_label }}"
class="col-sm-4 control-label">{{ form.purchase_order.label }}</label>
<div class="col-sm-8">
{% render_field form.purchase_order class+="form-control" %}
</div>
</div>
</div>
</div>
</div>

View File

@@ -61,21 +61,14 @@
{% endif %}
</td>
<td>
{% if object.organisation %}
{{ object.organisation.name }}
<br>
<span class="text-muted">{{ object.organisation.union_account|yesno:'Internal,External' }}</span>
{% else %}
{{ object.person.name }}
<br>
<span class="text-muted">External</span>
{% endif %}
{{ object.organisation.name }}
<br>
<span class="text-muted">{{ object.internal|yesno:'Internal,External' }}</span>
</td>
<td>
{{ object.sum_total|floatformat:2 }}
<br />
<span class="text-muted">{{ object.authorisation.po }}</span>
<span class="text-muted">{% if not object.internal %}{{ object.purchase_order }}{% endif %}</span>
</td>
<td class="text-center">
{% if object.mic %}
@@ -86,7 +79,10 @@
{% endif %}
</td>
<td class="text-right">
<a href="{% url 'invoice_event' object.pk %}" class="btn btn-default" data-toggle="tooltip" title="'Invoice' this event - click this when paperwork has been sent to treasury">
<a href="{% url 'invoice_event' object.pk %}"
class="btn btn-default"
data-toggle="tooltip"
title="'Invoice' this event - click this when paperwork has been sent to treasury">
<span class="glyphicon glyphicon-gbp"></span>
</a>
</td>

View File

@@ -249,13 +249,12 @@
<tr>
<td>
{% if object.authorised %}
<para>
Event authorised online by {{ object.authorisation.name }} ({{ object.authorisation.email }}) at
{{ object.authorisation.last_edited_at }}.
</para>
{% if object.internal and object.authorised %}
<para>
Event authorised online by {{ object.authorisation.name }} ({{ object.authorisation.email }}) at
{{ object.authorisation.last_edited_at }}.
</para>
{% if object.organisation.union_account %}
<blockTable colWidths="165,165,165">
<tr>
<td><para><b>University ID</b></para></td>
@@ -268,19 +267,18 @@
<td>£ {{ object.authorisation.amount|floatformat:2 }}</td>
</tr>
</blockTable>
{% else %}
{% elif not object.internal and object.purchase_order %}
<blockTable colWidths="247,248">
<tr>
<td></td>
<td><para><b>Purchase Order</b></para></td>
<td><para><b>Authorised Amount</b></para></td>
</tr>
<tr>
<td>{{ object.authorisation.po }}</td>
<td>£ {{ object.authorisation.amount|floatformat:2 }}</td>
<td></td>
<td>{{ object.purchase_order }}</td>
</tr>
</blockTable>
{% endif %}
{% endif %}
</td>
</tr>
</blockTable>

View File

@@ -9,11 +9,11 @@
$('[data-toggle="tooltip"]').tooltip();
});
$('form').on('submit', function() {
$('#loading-modal').modal({
backdrop: 'static',
show: true
});
$('form').on('submit', function () {
$('#loading-modal').modal({
backdrop: 'static',
show: true
});
});
</script>
{% endblock %}
@@ -54,17 +54,15 @@
{% csrf_token %}
{% include 'form_errors.html' %}
<div class="row">
{% if internal %}
<div class="col-sm-12">
<p>
I agree that I am authorised to approve this event. I agree that I am the
<strong>President/Treasurer or account holder</strong> of the hirer, or that I
have the written permission of the
<strong>President/Treasurer or account holder</strong> of the hirer stating that
I can authorise this event.
</p>
</div>
{% endif %}
<div class="col-sm-12">
<p>
I agree that I am authorised to approve this event. I agree that I am the
<strong>President/Treasurer or account holder</strong> of the hirer, or that I
have the written permission of the
<strong>President/Treasurer or account holder</strong> of the hirer stating that
I can authorise this event.
</p>
</div>
<div class="col-sm-12 col-md-6">
<div class="col-sm-12 form-group" data-toggle="tooltip"
@@ -77,38 +75,25 @@
</div>
</div>
{% if internal %}
<div class="col-sm-12 form-group" data-toggle="tooltip"
title="Your Student ID or Staff username as the person authorising the event.">
<label for="{{ form.uni_id.id_for_label }}"
class="col-sm-4 control-label">{{ form.uni_id.label }}</label>
<div class="col-sm-8">
{% render_field form.uni_id class+="form-control" %}
</div>
<div class="col-sm-12 form-group" data-toggle="tooltip"
title="Your Student ID or Staff username as the person authorising the event.">
<label for="{{ form.uni_id.id_for_label }}"
class="col-sm-4 control-label">{{ form.uni_id.label }}</label>
<div class="col-sm-8">
{% render_field form.uni_id class+="form-control" %}
</div>
{% endif %}
</div>
</div>
<div class="col-sm-12 col-md-6">
{% if internal %}
<div class="col-sm-12 form-group" data-toggle="tooltip"
title="The Students' Union account code you wish this event to be charged to.">
<label for="{{ form.account_code.id_for_label }}"
class="col-sm-4 control-label">{{ form.account_code.label }}</label>
<div class="col-sm-8">
{% render_field form.account_code class+="form-control" %}
</div>
<div class="col-sm-12 form-group" data-toggle="tooltip"
title="The Students' Union account code you wish this event to be charged to.">
<label for="{{ form.account_code.id_for_label }}"
class="col-sm-4 control-label">{{ form.account_code.label }}</label>
<div class="col-sm-8">
{% render_field form.account_code class+="form-control" %}
</div>
{% else %}
<div class="col-sm-12 form-group" data-toggle="tooltip"
title="Your Purchase Order reference for this event.">
<label for="{{ form.po.id_for_label }}"
class="col-sm-4 control-label">{{ form.po.label }}</label>
<div class="col-sm-8">
{% render_field form.po class+="form-control" %}
</div>
</div>
{% endif %}
</div>
<div class="col-sm-12 form-group" data-toggle="tooltip"
title="The full amount chargable for this event as displayed above, including VAT.">

View File

@@ -49,13 +49,8 @@
<div class="col-sm-12 col-md-6">
<dl class="dl-horizontal">
{% if internal %}
<dt>Account code</dt>
<dd>{{ object.account_code }}</dd>
{% else %}
<dt>PO</dt>
<dd>{{ object.po }}</dd>
{% endif %}
<dt>Account code</dt>
<dd>{{ object.account_code }}</dd>
<dt>Authorised amount</dt>
<dd>£ {{ object.amount|floatformat:2 }}</dd>

View File

@@ -89,7 +89,7 @@
{% endif %}
</dd>
{% if object.event.organisation.union_account %}
{% if object.event.internal %}
{# internal #}
<dt>Uni ID</dt>
<dd>{{ object.event.authorisation.uni_id }}</dd>
@@ -98,7 +98,7 @@
<dd>{{ object.event.authorisation.account_code }}</dd>
{% else %}
<dt>PO</dt>
<dd>{{ object.event.authorisation.po }}</dd>
<dd>{{ object.event.purchase_order }}</dd>
{% endif %}
<dt>Authorised at</dt>

View File

@@ -50,7 +50,7 @@
<td>{% if object.event.organisation %}
{{ object.event.organisation.name }}
<br>
<span class="text-muted">{{ object.event.organisation.union_account|yesno:'Internal,External' }}</span>
<span class="text-muted">{{ object.event.internal|yesno:'Internal,External' }}</span>
{% else %}
{{ object.event.person.name }}
<br>
@@ -62,7 +62,7 @@
<td>
{{ object.balance|floatformat:2 }}
<br />
<span class="text-muted">{{ object.event.authorisation.po }}</span>
<span class="text-muted">{{ object.event.purchase_order }}</span>
</td>
<td class="text-right">
<a href="{% url 'invoice_detail' object.pk %}" class="btn btn-default">

View File

@@ -496,6 +496,7 @@ class EventTest(LiveServerTestCase):
testEvent = models.Event.objects.create(name="TE E1", status=models.Event.PROVISIONAL,
start_date=date.today() + timedelta(days=6),
description="start future no end",
purchase_order='TESTPO',
auth_request_by=self.profile,
auth_request_at=self.create_datetime(2015, 06, 04, 10, 00),
auth_request_to="some@email.address")
@@ -570,6 +571,10 @@ class EventTest(LiveServerTestCase):
self.assertIn("Test Item 3", table.text)
infoPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Event Info")]/..')
self.assertIn("N0000%d" % testEvent.pk,
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
# Check the PO hasn't carried through
self.assertNotIn("TESTPO", infoPanel.find_element_by_xpath('//dt[text()="PO"]/following-sibling::dd[1]').text)
self.assertIn("N%05d"%testEvent.pk, infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
@@ -578,6 +583,10 @@ class EventTest(LiveServerTestCase):
#Check that based-on hasn't crept into the old event
infoPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Event Info")]/..')
self.assertNotIn("N0000%d" % testEvent.pk,
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
# Check the PO remains on the old event
self.assertIn("TESTPO", infoPanel.find_element_by_xpath('//dt[text()="PO"]/following-sibling::dd[1]').text)
self.assertNotIn("N%05d"%testEvent.pk, infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
@@ -1108,7 +1117,7 @@ class ClientEventAuthorisationTest(TestCase):
self.assertContains(response, "Terms of Hire")
response = self.client.post(self.url)
self.assertContains(response, "This field is required.", 4)
self.assertContains(response, "This field is required.", 5)
data = self.auth_data
data['amount'] = self.event.total + 1
@@ -1142,7 +1151,7 @@ class ClientEventAuthorisationTest(TestCase):
def test_duplicate_warning(self):
auth = models.EventAuthorisation.objects.create(event=self.event, name='Test ABC', email='dupe@functional.test',
po='ABC12345', amount=self.event.total, sent_by=self.profile)
amount=self.event.total, sent_by=self.profile)
response = self.client.get(self.url)
self.assertContains(response, 'This event has already been authorised.')