Compare commits

..

4 Commits

Author SHA1 Message Date
Matthew Smith
8ca55f2696 Added migration for name change 2020-01-22 03:06:29 +00:00
Matthew Smith
228592a0f3 Creating an invoice now appears in its history. Rudimentary tracking of payments is also implemented 2020-01-22 02:37:39 +00:00
Tom Price
1be1b1abd7 Add invoice versioning to templates. 2018-05-15 17:42:13 +01:00
Johnathan Graydon
42e1931e72 Add revision history to invoices & payments 2018-05-14 15:57:06 +01:00
29 changed files with 109 additions and 185 deletions

View File

@@ -1,12 +0,0 @@
FROM python:3.6
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt && \
python manage.py collectstatic --noinput
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

View File

@@ -11,7 +11,6 @@ https://docs.djangoproject.com/en/1.7/ref/settings/
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os import os
import raven import raven
import secrets
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) BASE_DIR = os.path.dirname(os.path.dirname(__file__))
@@ -234,7 +233,3 @@ USE_GRAVATAR = True
TERMS_OF_HIRE_URL = "http://www.nottinghamtec.co.uk/terms.pdf" TERMS_OF_HIRE_URL = "http://www.nottinghamtec.co.uk/terms.pdf"
AUTHORISATION_NOTIFICATION_ADDRESS = 'productions@nottinghamtec.co.uk' AUTHORISATION_NOTIFICATION_ADDRESS = 'productions@nottinghamtec.co.uk'
RISK_ASSESSMENT_URL = os.environ.get('RISK_ASSESSMENT_URL') if os.environ.get(
'RISK_ASSESSMENT_URL') else "http://example.com"
RISK_ASSESSMENT_SECRET = os.environ.get('RISK_ASSESSMENT_SECRET') if os.environ.get(
'RISK_ASSESSMENT_SECRET') else secrets.token_hex(15)

View File

@@ -77,13 +77,6 @@ python manage.py runserver
``` ```
Please refer to Django documentation for a full list of options available here. Please refer to Django documentation for a full list of options available here.
### Development using docker
```
docker build . -t pyrigs
docker run -it --rm -p=8000:8000 -v $(pwd):/app pyrigs
```
### Sample Data ### ### Sample Data ###
Sample data is available to aid local development and user acceptance testing. To load this data into your local database, first ensure the database is empty: Sample data is available to aid local development and user acceptance testing. To load this data into your local database, first ensure the database is empty:
``` ```

View File

@@ -1,25 +1,24 @@
from django.contrib import admin from django.contrib import admin
from RIGS import models, forms
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _
from reversion.admin import VersionAdmin
from django.contrib.admin import helpers
from django.template.response import TemplateResponse
from django.contrib import messages from django.contrib import messages
from django.db import transaction from django.contrib.admin import helpers
from django.contrib.auth.admin import UserAdmin
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.db.models import Count from django.db.models import Count
from django.forms import ModelForm from django.forms import ModelForm
from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from reversion import revisions as reversion from reversion import revisions as reversion
from reversion.admin import VersionAdmin
from RIGS import models, forms
# Register your models here. # Register your models here.
admin.site.register(models.VatRate, VersionAdmin) admin.site.register(models.VatRate, VersionAdmin)
admin.site.register(models.Event, VersionAdmin) admin.site.register(models.Event, VersionAdmin)
admin.site.register(models.EventItem, VersionAdmin) admin.site.register(models.EventItem, VersionAdmin)
admin.site.register(models.Invoice) admin.site.register(models.Invoice, VersionAdmin)
admin.site.register(models.Payment) admin.site.register(models.Payment, VersionAdmin)
@admin.register(models.Profile) @admin.register(models.Profile)

View File

@@ -10,8 +10,9 @@ from django.template import RequestContext
from django.template.loader import get_template from django.template.loader import get_template
from django.views import generic from django.views import generic
from django.db.models import Q from django.db.models import Q
from django.db import transaction
from z3c.rml import rml2pdf from z3c.rml import rml2pdf
import reversion
from RIGS import models from RIGS import models
from django import forms from django import forms
@@ -101,14 +102,14 @@ class InvoiceDelete(generic.DeleteView):
def get(self, request, pk): def get(self, request, pk):
obj = self.get_object() obj = self.get_object()
if obj.payment_set.all().count() > 0: if obj.payments.all().count() > 0:
messages.info(self.request, 'To delete an invoice, delete the payments first.') messages.info(self.request, 'To delete an invoice, delete the payments first.')
return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': obj.pk})) return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': obj.pk}))
return super(InvoiceDelete, self).get(pk) return super(InvoiceDelete, self).get(pk)
def post(self, request, pk): def post(self, request, pk):
obj = self.get_object() obj = self.get_object()
if obj.payment_set.all().count() > 0: if obj.payments.all().count() > 0:
messages.info(self.request, 'To delete an invoice, delete the payments first.') messages.info(self.request, 'To delete an invoice, delete the payments first.')
return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': obj.pk})) return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': obj.pk}))
return super(InvoiceDelete, self).post(pk) return super(InvoiceDelete, self).post(pk)
@@ -159,7 +160,10 @@ class InvoiceWaiting(generic.ListView):
class InvoiceEvent(generic.View): class InvoiceEvent(generic.View):
@transaction.atomic()
@reversion.create_revision()
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
reversion.set_user(self.request.user)
epk = kwargs.get('pk') epk = kwargs.get('pk')
event = models.Event.objects.get(pk=epk) event = models.Event.objects.get(pk=epk)
invoice, created = models.Invoice.objects.get_or_create(event=event) invoice, created = models.Invoice.objects.get_or_create(event=event)
@@ -184,6 +188,13 @@ class PaymentCreate(generic.CreateView):
initial.update({'invoice': invoice}) initial.update({'invoice': invoice})
return initial return initial
@transaction.atomic()
@reversion.create_revision()
def form_valid(self, form, *args, **kwargs):
reversion.add_to_revision(form.cleaned_data['invoice'])
reversion.set_comment("Payment removed")
return super().form_valid(form, *args, **kwargs)
def get_success_url(self): def get_success_url(self):
messages.info(self.request, "location.reload()") messages.info(self.request, "location.reload()")
return reverse_lazy('closemodal') return reverse_lazy('closemodal')
@@ -192,5 +203,12 @@ class PaymentCreate(generic.CreateView):
class PaymentDelete(generic.DeleteView): class PaymentDelete(generic.DeleteView):
model = models.Payment model = models.Payment
@transaction.atomic()
@reversion.create_revision()
def delete(self, *args, **kwargs):
reversion.add_to_revision(self.get_object().invoice)
reversion.set_comment("Payment removed")
return super().delete(*args, **kwargs)
def get_success_url(self): def get_success_url(self):
return self.request.POST.get('next') return self.request.POST.get('next')

View File

@@ -33,12 +33,7 @@ class ProfileRegistrationFormUniqueEmail(RegistrationFormUniqueEmail):
return self.cleaned_data['initials'] return self.cleaned_data['initials']
# Embedded Login form - remove the autofocus # Login form
class EmbeddedAuthenticationForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].widget.attrs.pop('autofocus', None)
class PasswordReset(PasswordResetForm): class PasswordReset(PasswordResetForm):
captcha = ReCaptchaField(label='Captcha') captcha = ReCaptchaField(label='Captcha')

View File

@@ -0,0 +1,19 @@
# Generated by Django 2.0.13 on 2020-01-22 03:05
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0033_auto_20180325_0016'),
]
operations = [
migrations.AlterField(
model_name='payment',
name='invoice',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='payments', to='RIGS.Invoice'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 2.0.5 on 2019-07-28 21:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0033_auto_20180325_0016'),
]
operations = [
migrations.AddField(
model_name='event',
name='risk_assessment_edit_url',
field=models.CharField(blank=True, max_length=255, null=True),
),
]

View File

@@ -1,24 +1,21 @@
from collections import Counter
import datetime import datetime
import hashlib import hashlib
import datetime
import pytz import pytz
import random
from django.db import models import string
from django.contrib.auth.models import AbstractUser from decimal import Decimal
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from django.utils.functional import cached_property
from reversion import revisions as reversion from reversion import revisions as reversion
from reversion.models import Version from reversion.models import Version
import string
import random
from collections import Counter
from decimal import Decimal
from django.core.exceptions import ValidationError
from django.urls import reverse_lazy
# Create your models here. # Create your models here.
@@ -338,9 +335,6 @@ class Event(models.Model, RevisionMixin):
auth_request_at = models.DateTimeField(null=True, blank=True) auth_request_at = models.DateTimeField(null=True, blank=True)
auth_request_to = models.EmailField(null=True, blank=True) auth_request_to = models.EmailField(null=True, blank=True)
# Risk assessment info
risk_assessment_edit_url = models.CharField(verbose_name="risk assessment", max_length=255, blank=True, null=True)
# Calculated values # Calculated values
""" """
EX Vat EX Vat
@@ -533,8 +527,9 @@ class EventAuthorisation(models.Model, RevisionMixin):
return str("N%05d" % self.event.pk + ' (requested by ' + self.sent_by.initials + ')') return str("N%05d" % self.event.pk + ' (requested by ' + self.sent_by.initials + ')')
@reversion.register(follow=['payments'])
@python_2_unicode_compatible @python_2_unicode_compatible
class Invoice(models.Model): class Invoice(models.Model, RevisionMixin):
event = models.OneToOneField('Event', on_delete=models.CASCADE) event = models.OneToOneField('Event', on_delete=models.CASCADE)
invoice_date = models.DateField(auto_now_add=True) invoice_date = models.DateField(auto_now_add=True)
void = models.BooleanField(default=False) void = models.BooleanField(default=False)
@@ -549,7 +544,7 @@ class Invoice(models.Model):
@property @property
def payment_total(self): def payment_total(self):
total = self.payment_set.aggregate(total=models.Sum('amount'))['total'] total = self.payments.aggregate(total=models.Sum('amount'))['total']
if total: if total:
return total return total
return Decimal("0.00") return Decimal("0.00")
@@ -587,7 +582,7 @@ class Payment(models.Model):
(ADJUSTMENT, 'TEC Adjustment'), (ADJUSTMENT, 'TEC Adjustment'),
) )
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE) invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE, related_name="payments")
date = models.DateField() date = models.DateField()
amount = models.DecimalField(max_digits=10, decimal_places=2, help_text='Please use ex. VAT') amount = models.DecimalField(max_digits=10, decimal_places=2, help_text='Please use ex. VAT')
method = models.CharField(max_length=2, choices=METHODS, null=True, blank=True) method = models.CharField(max_length=2, choices=METHODS, null=True, blank=True)

View File

@@ -18,7 +18,6 @@ from django.core.exceptions import SuspiciousOperation
from django.db.models import Q from django.db.models import Q
from django.contrib import messages from django.contrib import messages
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from z3c.rml import rml2pdf from z3c.rml import rml2pdf
from PyPDF2 import PdfFileMerger, PdfFileReader from PyPDF2 import PdfFileMerger, PdfFileReader
import simplejson import simplejson
@@ -81,24 +80,6 @@ class EventEmbed(EventDetail):
template_name = 'RIGS/event_embed.html' template_name = 'RIGS/event_embed.html'
class EventRA(generic.base.RedirectView):
permanent = False
def get_redirect_url(self, *args, **kwargs):
event = get_object_or_404(models.Event, pk=kwargs['pk'])
if event.risk_assessment_edit_url:
return event.risk_assessment_edit_url
params = {
'entry.708610078': f'N{event.pk:05}',
'entry.905899507': event.name,
'entry.139491562': event.venue.name if event.venue else '',
'entry.1689826056': event.start_date.strftime('%Y-%m-%d') + ((' - ' + event.end_date.strftime('%Y-%m-%d')) if event.end_date else ''),
'entry.902421165': event.mic.name if event.mic else ''
}
return settings.RISK_ASSESSMENT_URL + "?" + urllib.parse.urlencode(params)
class EventCreate(generic.CreateView): class EventCreate(generic.CreateView):
model = models.Event model = models.Event
form_class = forms.EventForm form_class = forms.EventForm
@@ -405,26 +386,3 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView):
}) })
context['to_name'] = self.request.GET.get('to_name', None) context['to_name'] = self.request.GET.get('to_name', None)
return context return context
@method_decorator(csrf_exempt, name='dispatch')
class LogRiskAssessment(generic.View):
http_method_names = ["post"]
def post(self, request, **kwargs):
data = request.POST
shared_secret = data.get("secret")
edit_url = data.get("editUrl")
rig_number = data.get("rigNum")
if shared_secret is None or edit_url is None or rig_number is None:
return HttpResponse(status=422)
if shared_secret != settings.RISK_ASSESSMENT_SECRET:
return HttpResponse(status=403)
rig_number = int(re.sub("[^0-9]", "", rig_number))
event = get_object_or_404(models.Event, pk=rig_number)
event.risk_assessment_edit_url = edit_url
event.save()
return HttpResponse(status=200)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -149,19 +149,16 @@ ins {
} }
html.embedded{ html.embedded{
display: flex; min-height:100%;
flex-direction: column; display: table;
width: 100%; width: 100%;
height: 100%;
max-height: 100%;
overflow: hidden;
justify-content: center;
body{ body{
padding:0; padding:0;
display: table-cell;
vertical-align: middle;
width:100%; width:100%;
background:none; background:none;
overflow: scroll;
} }
.embed_container{ .embed_container{

View File

@@ -3,17 +3,6 @@
class="glyphicon glyphicon-edit"></span> <span class="glyphicon glyphicon-edit"></span> <span
class="hidden-xs">Edit</span></a> class="hidden-xs">Edit</span></a>
{% if event.is_rig %} {% if event.is_rig %}
{% if not event.dry_hire %}
<a href="{% url 'event_ra' event.pk %}" class="btn btn-default
{% if event.risk_assessment_edit_url %}
btn-success
{% else %}
btn-warning
{% endif %}
"><span
class="glyphicon glyphicon-paperclip"></span> <span
class="hidden-xs">RA</span></a>
{% endif %}
<a href="{% url 'event_print' event.pk %}" target="_blank" class="btn btn-default"><span <a href="{% url 'event_print' event.pk %}" target="_blank" class="btn btn-default"><span
class="glyphicon glyphicon-print"></span> <span class="glyphicon glyphicon-print"></span> <span
class="hidden-xs">Print</span></a> class="hidden-xs">Print</span></a>

View File

@@ -264,7 +264,7 @@
</para> </para>
</td> </td>
</tr> </tr>
{% for payment in object.invoice.payment_set.all %} {% for payment in object.invoice.payments.all %}
<tr> <tr>
<td>{{ payment.get_method_display }}</td> <td>{{ payment.get_method_display }}</td>
<td>{{ payment.date }}</td> <td>{{ payment.date }}</td>

View File

@@ -27,7 +27,7 @@
<a class="list-group-item" href="//members.nottinghamtec.co.uk/wiki" target="_blank"><span class="glyphicon glyphicon-link"></span> TEC Wiki</a> <a class="list-group-item" href="//members.nottinghamtec.co.uk/wiki" target="_blank"><span class="glyphicon glyphicon-link"></span> TEC Wiki</a>
<a class="list-group-item" href="http://members.nottinghamtec.co.uk/wiki/images/2/22/Event_Risk_Assesment.pdf" target="_blank"><span class="glyphicon glyphicon-link"></span> Pre-Event Risk Assessment</a> <a class="list-group-item" href="http://members.nottinghamtec.co.uk/wiki/images/2/22/Event_Risk_Assesment.pdf" target="_blank"><span class="glyphicon glyphicon-link"></span> Pre-Event Risk Assessment</a>
<a class="list-group-item" href="//members.nottinghamtec.co.uk/price" target="_blank"><span class="glyphicon glyphicon-link"></span> Price List</a> <a class="list-group-item" href="//members.nottinghamtec.co.uk/price" target="_blank"><span class="glyphicon glyphicon-link"></span> Price List</a>
<a class="list-group-item" href="https://goo.gl/forms/jdPWov8PCNPoXtbn2" target="_blank"><span class="glyphicon glyphicon-link"></span> Subhire Insurance Form</a> <a class="list-group-item" href="https://form.jotformeu.com/62203600438344" target="_blank"><span class="glyphicon glyphicon-link"></span> Subhire Insurance Form</a>
</div> </div>
</div> </div>

View File

@@ -19,7 +19,8 @@
<span class="glyphicon glyphicon-ban-circle"></span> <span <span class="glyphicon glyphicon-ban-circle"></span> <span
class="hidden-xs">Void</span> class="hidden-xs">Void</span>
</a> </a>
<a href="{% url 'invoice_print' object.pk %}" target="_blank" title="Print Invoice" class="btn btn-default"><span <a href="{% url 'invoice_print' object.pk %}" target="_blank" title="Print Invoice"
class="btn btn-default"><span
class="glyphicon glyphicon-print"></span> <span class="glyphicon glyphicon-print"></span> <span
class="hidden-xs">Print</span></a> class="hidden-xs">Print</span></a>
</div> </div>
@@ -85,7 +86,9 @@
<dd> <dd>
{% if object.event.authorised %} {% if object.event.authorised %}
{{ object.event.authorisation.name }} {{ object.event.authorisation.name }}
(<a href="mailto:{{ object.event.authorisation.email }}">{{ object.event.authorisation.email }}</a>) (
<a href="mailto:{{ object.event.authorisation.email }}">{{ object.event.authorisation.email }}</a>
)
{% endif %} {% endif %}
</dd> </dd>
@@ -140,7 +143,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for payment in object.payment_set.all %} {% for payment in object.payments.all %}
<tr> <tr>
<td>{{ payment.date }}</td> <td>{{ payment.date }}</td>
<td>{{ payment.amount|floatformat:2 }}</td> <td>{{ payment.amount|floatformat:2 }}</td>
@@ -172,6 +175,13 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="col-sm-12 text-right">
<div>
<a href="{% url 'invoice_history' object.pk %}" title="View Revision History">
Last edited at {{ object.last_edited_at }} by {{ object.last_edited_by.name }}
</a>
</div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,12 @@
from django.conf.urls import url from django.conf.urls import url
from django.contrib.auth.views import password_reset
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from RIGS import models, views, rigboard, finance, ical, versioning, forms from django.contrib.auth.views import password_reset
from django.views.generic import RedirectView
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import RedirectView
from PyRIGS.decorators import permission_required_with_403
from PyRIGS.decorators import api_key_required from PyRIGS.decorators import api_key_required
from PyRIGS.decorators import permission_required_with_403
from RIGS import models, views, rigboard, finance, ical, versioning, forms
urlpatterns = [ urlpatterns = [
# Examples: # Examples:
@@ -101,9 +100,6 @@ urlpatterns = [
url(r'^event/(?P<pk>\d+)/print/$', url(r'^event/(?P<pk>\d+)/print/$',
permission_required_with_403('RIGS.view_event')(rigboard.EventPrint.as_view()), permission_required_with_403('RIGS.view_event')(rigboard.EventPrint.as_view()),
name='event_print'), name='event_print'),
url(r'^event/(?P<pk>\d+)/ra/$',
permission_required_with_403('RIGS.change_event')(rigboard.EventRA.as_view()),
name='event_ra'),
url(r'^event/create/$', url(r'^event/create/$',
permission_required_with_403('RIGS.add_event')(rigboard.EventCreate.as_view()), permission_required_with_403('RIGS.add_event')(rigboard.EventCreate.as_view()),
name='event_create'), name='event_create'),
@@ -147,6 +143,10 @@ urlpatterns = [
url(r'^invoice/(?P<pk>\d+)/delete/$', url(r'^invoice/(?P<pk>\d+)/delete/$',
permission_required_with_403('RIGS.change_invoice')(finance.InvoiceDelete.as_view()), permission_required_with_403('RIGS.change_invoice')(finance.InvoiceDelete.as_view()),
name='invoice_delete'), name='invoice_delete'),
url(r'^invoice/(?P<pk>\d+)/history/$',
permission_required_with_403('RIGS.view_invoice')(versioning.VersionHistory.as_view()),
name='invoice_history', kwargs={'model': models.Invoice}),
url(r'^payment/create/$', url(r'^payment/create/$',
permission_required_with_403('RIGS.add_payment')(finance.PaymentCreate.as_view()), permission_required_with_403('RIGS.add_payment')(finance.PaymentCreate.as_view()),
name='payment_create'), name='payment_create'),
@@ -188,9 +188,6 @@ urlpatterns = [
url(r'^api/(?P<model>\w+)/(?P<pk>\d+)/$', login_required(views.SecureAPIRequest.as_view()), url(r'^api/(?P<model>\w+)/(?P<pk>\d+)/$', login_required(views.SecureAPIRequest.as_view()),
name="api_secure"), name="api_secure"),
# Risk assessment API
url(r'^log_risk_assessment/$', rigboard.LogRiskAssessment.as_view(), name='log_risk_assessment'),
# Legacy URL's # Legacy URL's
url(r'^rig/show/(?P<pk>\d+)/$', url(r'^rig/show/(?P<pk>\d+)/$',
RedirectView.as_view(permanent=True, pattern_name='event_detail')), RedirectView.as_view(permanent=True, pattern_name='event_detail')),

View File

@@ -27,8 +27,6 @@ class FieldComparison(object):
def display_value(self, value): def display_value(self, value):
if isinstance(self.field, IntegerField) and len(self.field.choices) > 0: if isinstance(self.field, IntegerField) and len(self.field.choices) > 0:
return [x[1] for x in self.field.choices if x[0] == value][0] return [x[1] for x in self.field.choices if x[0] == value][0]
if self.field.name == "risk_assessment_edit_url":
return "completed" if value else ""
return value return value
@property @property

View File

@@ -62,7 +62,7 @@ def login_embed(request, **kwargs):
messages.warning(request, 'Cookies do not seem to be enabled. Try logging in using a new tab.') messages.warning(request, 'Cookies do not seem to be enabled. Try logging in using a new tab.')
request.method = 'GET' # Render the page without trying to login request.method = 'GET' # Render the page without trying to login
return login(request, template_name="registration/login_embed.html", authentication_form=forms.EmbeddedAuthenticationForm) return login(request, template_name="registration/login_embed.html")
""" """

View File

@@ -49,6 +49,5 @@
{ {
"url": "heroku/python" "url": "heroku/python"
} }
], ]
"stack": "heroku-18"
} }

View File

@@ -3,7 +3,7 @@ contextlib2==0.5.5
diff-match-patch==20121119 diff-match-patch==20121119
dj-database-url==0.5.0 dj-database-url==0.5.0
dj-static==0.0.6 dj-static==0.0.6
Django==2.0.13 Django==2.0.5
django-debug-toolbar==1.9.1 django-debug-toolbar==1.9.1
django-ical==1.4 django-ical==1.4
django-recaptcha==1.4.0 django-recaptcha==1.4.0
@@ -21,12 +21,12 @@ Pillow==5.1.0
psycopg2==2.7.4 psycopg2==2.7.4
Pygments==2.2.0 Pygments==2.2.0
PyPDF2==1.26.0 PyPDF2==1.26.0
python-dateutil==2.7.3 python-dateutil==2.7.2
pytz==2018.4 pytz==2018.4
raven==6.8.0 raven==6.7.0
reportlab==3.4.0 reportlab==3.4.0
selenium==3.12.0 selenium==3.12.0
simplejson==3.15.0 simplejson==3.14.0
six==1.11.0 six==1.11.0
sqlparse==0.2.4 sqlparse==0.2.4
static3==0.7.0 static3==0.7.0