diff --git a/RIGS/finance.py b/RIGS/finance.py index be52b1f1..65fc3b07 100644 --- a/RIGS/finance.py +++ b/RIGS/finance.py @@ -94,6 +94,25 @@ class InvoiceVoid(generic.View): return HttpResponseRedirect(reverse_lazy('invoice_list')) return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': object.pk})) +class InvoiceDelete(generic.DeleteView): + model = models.Invoice + + def get(self, request, pk): + obj = self.get_object() + if obj.payment_set.all().count() > 0: + messages.info(self.request, 'To delete an invoice, delete the payments first.') + return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': obj.pk})) + return super(InvoiceDelete, self).get(pk) + + def post(self, request, pk): + obj = self.get_object() + if obj.payment_set.all().count() > 0: + messages.info(self.request, 'To delete an invoice, delete the payments first.') + return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': obj.pk})) + return super(InvoiceDelete, self).post(pk) + + def get_success_url(self): + return self.request.POST.get('next') class InvoiceArchive(generic.ListView): model = models.Invoice @@ -112,6 +131,7 @@ class InvoiceWaiting(generic.ListView): for obj in self.get_objects(): total += obj.sum_total context['total'] = total + context['count'] = len(self.get_objects()) return context def get_queryset(self): @@ -124,6 +144,7 @@ class InvoiceWaiting(generic.ListView): Q(start_date__lte=datetime.date.today(), end_date__isnull=True) | # Starts before with no end Q(end_date__lte=datetime.date.today()) # Has end date, finishes before ) & Q(invoice__isnull=True) # Has not already been invoiced + & Q(is_rig=True) # Is a rig (not non-rig) ).order_by('start_date') \ .select_related('person', diff --git a/RIGS/templates/RIGS/event_invoice.html b/RIGS/templates/RIGS/event_invoice.html index 0e56158f..cd080a74 100644 --- a/RIGS/templates/RIGS/event_invoice.html +++ b/RIGS/templates/RIGS/event_invoice.html @@ -15,75 +15,77 @@ {% block content %}
-

Events for Invoice ({{object_list|length}} Events, £ {{ total|floatformat:2 }})

+

Events for Invoice ({{count}} Events, £ {{ total|floatformat:2 }})

These events have happened, but paperwork has not yet been sent to treasury

{% if is_paginated %}
{% paginator %}
{% endif %} - - - - - - - - - - - - - - {% for object in object_list %} - - - - - - - - +
+
#Start DateEvent NameClientCost
{{ object.start_date }}{{ object.name }} - {% if object.organisation %} - {{ object.organisation.name }} -
- {{ object.organisation.union_account|yesno:'Internal,External' }} - {% else %} - {{ object.person.name }} -
- External - {% endif %} - -
{{ object.sum_total|floatformat:2 }} - {% if object.mic %} - {{ object.mic.initials }}
- - {% else %} - - {% endif %} -
- - - -
+ + + + + + + + + - {% endfor %} - -
#Start DateEvent NameClientCostMIC
+ + + {% for object in object_list %} + + N{{ object.pk|stringformat:"05d" }}
+ {{ object.get_status_display }} + {{ object.start_date }} + {{ object.name }} + + {% if object.organisation %} + {{ object.organisation.name }} +
+ {{ object.organisation.union_account|yesno:'Internal,External' }} + {% else %} + {{ object.person.name }} +
+ External + {% endif %} + + + {{ object.sum_total|floatformat:2 }} + + {% if object.mic %} + {{ object.mic.initials }}
+ + {% else %} + + {% endif %} + + + + + + + + {% endfor %} + + +
{% if is_paginated %}
{% paginator %} diff --git a/RIGS/templates/RIGS/event_table.html b/RIGS/templates/RIGS/event_table.html index 1868f2dd..949c710a 100644 --- a/RIGS/templates/RIGS/event_table.html +++ b/RIGS/templates/RIGS/event_table.html @@ -1,7 +1,7 @@
- + @@ -23,7 +23,7 @@ danger {% endif %} "> - + + + {% for object in object_list %} + + + + + + + + + + + {% endfor %} + +
# Event Date Event Details Event Timings{{ event.pk }}
{{ event.start_date|date:"D d/m/Y" }}
{% if event.end_date and event.end_date != event.start_date %} diff --git a/RIGS/templates/RIGS/invoice_confirm_delete.html b/RIGS/templates/RIGS/invoice_confirm_delete.html new file mode 100644 index 00000000..fe295ed6 --- /dev/null +++ b/RIGS/templates/RIGS/invoice_confirm_delete.html @@ -0,0 +1,35 @@ +{% extends 'base.html' %} + +{% block title %}Delete payment on invoice {{ object.invoice.pk }}{% endblock %} + +{% block content %} +
+ +
+{% endblock %} \ No newline at end of file diff --git a/RIGS/templates/RIGS/invoice_detail.html b/RIGS/templates/RIGS/invoice_detail.html index ad177ba4..27b4c514 100644 --- a/RIGS/templates/RIGS/invoice_detail.html +++ b/RIGS/templates/RIGS/invoice_detail.html @@ -11,6 +11,10 @@
{{ object.pk }}N{{ object.event.pk|stringformat:"05d" }}: {{ object.event.name }}
+ {{ object.event.get_status_display }}
{% if object.event.organisation %} + {{ object.event.organisation.name }} +
+ {{ object.event.organisation.union_account|yesno:'Internal,External' }} + {% else %} + {{ object.event.person.name }} +
+ External + {% endif %} +
{{ object.event.start_date }}{{ object.invoice_date }}{{ object.balance|floatformat:2 }} + + + +
+
{% if is_paginated %}
{% paginator %} diff --git a/RIGS/test_unit.py b/RIGS/test_unit.py index 75fcca5a..c51874f4 100644 --- a/RIGS/test_unit.py +++ b/RIGS/test_unit.py @@ -155,3 +155,57 @@ class TestAdminMergeObjects(TestCase): if event.organisation == self.organisations[3]: # The one we left in place continue self.assertEqual(updatedEvent.organisation, self.organisations[1]) + +class TestInvoiceDelete(TestCase): + @classmethod + def setUpTestData(cls): + cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True, is_active=True, is_staff=True) + + cls.events = { + 1: models.Event.objects.create(name="TE E1", start_date=date.today()), + 2: models.Event.objects.create(name="TE E2", start_date=date.today()) + } + + cls.invoices = { + 1: models.Invoice.objects.create(event=cls.events[1]), + 2: models.Invoice.objects.create(event=cls.events[2]) + } + + cls.payments = { + 1: models.Payment.objects.create(invoice=cls.invoices[1], date=date.today(), amount=12.34, method=models.Payment.CASH) + } + + def setUp(self): + self.profile.set_password('testuser') + self.profile.save() + self.assertTrue(self.client.login(username=self.profile.username, password='testuser')) + + def test_invoice_delete_allowed(self): + request_url = reverse('invoice_delete', kwargs={'pk':self.invoices[2].pk}) + + response = self.client.get(request_url, follow=True) + self.assertContains(response, "Are you sure") + + # Check the invoice still exists + self.assertTrue(models.Invoice.objects.get(pk=self.invoices[2].pk)) + + # Actually delete it + response = self.client.post(request_url, follow=True) + + # Check the invoice is deleted + self.assertRaises(ObjectDoesNotExist, models.Invoice.objects.get, pk=self.invoices[2].pk) + + def test_invoice_delete_not_allowed(self): + request_url = reverse('invoice_delete', kwargs={'pk':self.invoices[1].pk}) + + response = self.client.get(request_url, follow=True) + self.assertContains(response, "To delete an invoice, delete the payments first.") + + # Check the invoice still exists + self.assertTrue(models.Invoice.objects.get(pk=self.invoices[1].pk)) + + # Try to actually delete it + response = self.client.post(request_url, follow=True) + + # Check this didn't work + self.assertTrue(models.Invoice.objects.get(pk=self.invoices[1].pk)) \ No newline at end of file diff --git a/RIGS/urls.py b/RIGS/urls.py index 4338df08..ee949ff8 100644 --- a/RIGS/urls.py +++ b/RIGS/urls.py @@ -127,6 +127,9 @@ urlpatterns = patterns('', url(r'^invoice/(?P\d+)/void/$', permission_required_with_403('RIGS.change_invoice')(finance.InvoiceVoid.as_view()), name='invoice_void'), + url(r'^invoice/(?P\d+)/delete/$', + permission_required_with_403('RIGS.change_invoice')(finance.InvoiceDelete.as_view()), + name='invoice_delete'), url(r'^payment/create/$', permission_required_with_403('RIGS.add_payment')(finance.PaymentCreate.as_view()), name='payment_create'),