From 9108cb3c4e264b38455b99c57b35deb0398912dc Mon Sep 17 00:00:00 2001 From: David Taylor Date: Sat, 4 Jun 2016 18:08:43 +0100 Subject: [PATCH 1/8] Fail! Hide non-rigs from waiting invoices --- RIGS/finance.py | 1 + 1 file changed, 1 insertion(+) diff --git a/RIGS/finance.py b/RIGS/finance.py index be52b1f1..1fd9b535 100644 --- a/RIGS/finance.py +++ b/RIGS/finance.py @@ -124,6 +124,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', From f92f418bc5cff671930a52bdab319cc8704553c1 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Mon, 6 Jun 2016 23:06:30 +0100 Subject: [PATCH 2/8] Fixed waiting invoice counter - closes #239 --- RIGS/finance.py | 1 + RIGS/templates/RIGS/event_invoice.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/RIGS/finance.py b/RIGS/finance.py index 1fd9b535..75de8bd9 100644 --- a/RIGS/finance.py +++ b/RIGS/finance.py @@ -112,6 +112,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): diff --git a/RIGS/templates/RIGS/event_invoice.html b/RIGS/templates/RIGS/event_invoice.html index 0e56158f..3136fe40 100644 --- a/RIGS/templates/RIGS/event_invoice.html +++ b/RIGS/templates/RIGS/event_invoice.html @@ -15,7 +15,7 @@ {% 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 %}
From 1163b117e4020421b0b4ce33f7abec330c8a5505 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 14 Jun 2016 19:23:40 +0100 Subject: [PATCH 3/8] Fixed #240 --- RIGS/templates/RIGS/invoice_list.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RIGS/templates/RIGS/invoice_list.html b/RIGS/templates/RIGS/invoice_list.html index f833b89a..7b080897 100644 --- a/RIGS/templates/RIGS/invoice_list.html +++ b/RIGS/templates/RIGS/invoice_list.html @@ -31,10 +31,10 @@ N{{ object.event.pk|stringformat:"05d" }}: {{ object.event.name }}
{{ object.event.get_status_display }} - {% if object.organisation %} + {% if object.event.organisation %} {{ object.event.organisation.name }}
- {{ object.organisation.union_account|yesno:'Internal,External' }} + {{ object.event.organisation.union_account|yesno:'Internal,External' }} {% else %} {{ object.event.person.name }}
From f265da2f1d9277a404c849d1004fb7a2907c6df0 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 14 Jun 2016 19:45:45 +0100 Subject: [PATCH 4/8] Fixed #241 and #244 --- RIGS/templates/RIGS/event_invoice.html | 124 +++++++++++++------------ RIGS/templates/RIGS/invoice_list.html | 82 ++++++++-------- 2 files changed, 105 insertions(+), 101 deletions(-) diff --git a/RIGS/templates/RIGS/event_invoice.html b/RIGS/templates/RIGS/event_invoice.html index 3136fe40..05b351aa 100644 --- a/RIGS/templates/RIGS/event_invoice.html +++ b/RIGS/templates/RIGS/event_invoice.html @@ -22,68 +22,70 @@ {% 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/invoice_list.html b/RIGS/templates/RIGS/invoice_list.html index 7b080897..2c77d352 100644 --- a/RIGS/templates/RIGS/invoice_list.html +++ b/RIGS/templates/RIGS/invoice_list.html @@ -12,47 +12,49 @@ {% paginator %}
{% endif %} - - - - - - - - - - - - - - {% for object in object_list %} - - - - - - - - - +
+
#EventClientEvent DateInvoice DateBalance
{{ 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 }} - - - -
+ + + + + + + + + - {% endfor %} - -
#EventClientEvent DateInvoice DateBalance
+ + + {% for object in object_list %} + + {{ 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 }} + + + + + + + {% endfor %} + + + {% if is_paginated %}
{% paginator %} From a7247c273edaf26e73a520cc753807f671f8177f Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 14 Jun 2016 19:50:35 +0100 Subject: [PATCH 5/8] Fixed #245 --- RIGS/templates/RIGS/event_table.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 %} "> - +
# 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 %} From e1578eb0d47b8d5a17a57b23b828e32b61a265cc Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 15 Jun 2016 13:00:14 +0100 Subject: [PATCH 6/8] Fixed responsive table fail --- RIGS/templates/RIGS/event_invoice.html | 2 +- RIGS/templates/RIGS/invoice_list.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RIGS/templates/RIGS/event_invoice.html b/RIGS/templates/RIGS/event_invoice.html index 05b351aa..cd080a74 100644 --- a/RIGS/templates/RIGS/event_invoice.html +++ b/RIGS/templates/RIGS/event_invoice.html @@ -22,7 +22,7 @@ {% paginator %} {% endif %} -
+
diff --git a/RIGS/templates/RIGS/invoice_list.html b/RIGS/templates/RIGS/invoice_list.html index 2c77d352..5bd7ef70 100644 --- a/RIGS/templates/RIGS/invoice_list.html +++ b/RIGS/templates/RIGS/invoice_list.html @@ -12,7 +12,7 @@ {% paginator %} {% endif %} -
+
From 67624eea6f2bae4f44f5c7ae179182d67aed1949 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 15 Jun 2016 23:18:46 +0100 Subject: [PATCH 7/8] Allow deleting invoices, if there are no payments yet --- RIGS/finance.py | 19 ++++++++++ .../RIGS/invoice_confirm_delete.html | 35 +++++++++++++++++++ RIGS/templates/RIGS/invoice_detail.html | 4 +++ RIGS/urls.py | 3 ++ 4 files changed, 61 insertions(+) create mode 100644 RIGS/templates/RIGS/invoice_confirm_delete.html diff --git a/RIGS/finance.py b/RIGS/finance.py index 75de8bd9..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 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 @@
+ + + 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'), From 667b0c80ca7bc7e8fd2eae8839f969d61c46dcd1 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 16 Jun 2016 01:44:59 +0100 Subject: [PATCH 8/8] Added tests for invoice deleting --- RIGS/test_unit.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) 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