mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 05:22:16 +00:00
Change to just using online auth for internal clients.
This effectively reverts 067e03b.
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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')),
|
||||
|
||||
@@ -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')
|
||||
]
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
@@ -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,6 +183,7 @@
|
||||
{% if event.is_rig %}
|
||||
<dd> </dd>
|
||||
|
||||
{% if object.internal %}
|
||||
<dt>Authorisation Request</dt>
|
||||
<dd>{{ object.auth_request_to|yesno:"Yes,No" }}</dd>
|
||||
|
||||
@@ -194,6 +195,11 @@
|
||||
|
||||
<dt>To</dt>
|
||||
<dd>{{ object.auth_request_to }}</dd>
|
||||
|
||||
{% else %}
|
||||
<dt>PO</dt>
|
||||
<dd>{{ object.purchase_order }}</dd>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
class="glyphicon glyphicon-duplicate"></span> <span
|
||||
class="hidden-xs">Duplicate</span></a>
|
||||
{% if event.is_rig %}
|
||||
{% if event.internal %}
|
||||
<a class="btn btn-default item-add modal-href event-authorise-request
|
||||
{% if event.authorised %}
|
||||
btn-success
|
||||
@@ -34,6 +35,8 @@
|
||||
{% 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 %}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
<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>
|
||||
|
||||
@@ -249,13 +249,12 @@
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
{% if object.authorised %}
|
||||
{% 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>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
$('form').on('submit', function() {
|
||||
$('form').on('submit', function () {
|
||||
$('#loading-modal').modal({
|
||||
backdrop: 'static',
|
||||
show: true
|
||||
@@ -54,7 +54,6 @@
|
||||
{% 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
|
||||
@@ -64,7 +63,6 @@
|
||||
I can authorise this event.
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="col-sm-12 form-group" data-toggle="tooltip"
|
||||
@@ -77,7 +75,6 @@
|
||||
</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 }}"
|
||||
@@ -86,11 +83,9 @@
|
||||
{% render_field form.uni_id class+="form-control" %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</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 }}"
|
||||
@@ -99,16 +94,6 @@
|
||||
{% render_field form.account_code class+="form-control" %}
|
||||
</div>
|
||||
</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 class="col-sm-12 form-group" data-toggle="tooltip"
|
||||
title="The full amount chargable for this event as displayed above, including VAT.">
|
||||
|
||||
@@ -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>Authorised amount</dt>
|
||||
<dd>£ {{ object.amount|floatformat:2 }}</dd>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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.')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user