diff --git a/PyRIGS/tests/base.py b/PyRIGS/tests/base.py
index 79005757..0d056978 100644
--- a/PyRIGS/tests/base.py
+++ b/PyRIGS/tests/base.py
@@ -22,21 +22,12 @@ def create_datetime(year, month, day, hour, minute):
def create_browser():
- browser = env('BROWSER', default="chrome")
- if browser == "firefox":
- options = webdriver.FirefoxOptions()
- options.headless = True
- driver = webdriver.Firefox(options=options)
- driver.set_window_position(0, 0)
- # Firefox is pissy about out of bounds otherwise
- driver.set_window_size(3840, 2160)
- else:
- options = webdriver.ChromeOptions()
- options.add_argument("--window-size=1920,1080")
- options.add_argument("--headless")
- if settings.CI:
- options.add_argument("--no-sandbox")
- driver = webdriver.Chrome(options=options)
+ options = webdriver.ChromeOptions()
+ options.add_argument("--window-size=1920,1080")
+ options.add_argument("--headless")
+ if settings.CI:
+ options.add_argument("--no-sandbox")
+ driver = webdriver.Chrome(options=options)
return driver
diff --git a/RIGS/finance.py b/RIGS/finance.py
index f88881fd..9486b8ee 100644
--- a/RIGS/finance.py
+++ b/RIGS/finance.py
@@ -10,7 +10,7 @@ from django.http import Http404, HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.template.loader import get_template
-from django.urls import reverse_lazy
+from django.urls import reverse
from django.views import generic
from z3c.rml import rml2pdf
@@ -92,8 +92,8 @@ class InvoiceVoid(generic.View):
object.save()
if object.void:
- return HttpResponseRedirect(reverse_lazy('invoice_list'))
- return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': object.pk}))
+ return HttpResponseRedirect(reverse('invoice_list'))
+ return HttpResponseRedirect(reverse('invoice_detail', kwargs={'pk': object.pk}))
class InvoiceDelete(generic.DeleteView):
@@ -104,14 +104,14 @@ class InvoiceDelete(generic.DeleteView):
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 HttpResponseRedirect(reverse('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 HttpResponseRedirect(reverse('invoice_detail', kwargs={'pk': obj.pk}))
return super(InvoiceDelete, self).post(pk)
def get_success_url(self):
@@ -210,7 +210,7 @@ class InvoiceEvent(generic.View):
invoice.save()
messages.warning(self.request, 'Invoice voided')
- return HttpResponseRedirect(reverse_lazy('invoice_detail', kwargs={'pk': invoice.pk}))
+ return HttpResponseRedirect(reverse('invoice_detail', kwargs={'pk': invoice.pk}))
class PaymentCreate(generic.CreateView):
@@ -236,7 +236,7 @@ class PaymentCreate(generic.CreateView):
def get_success_url(self):
messages.info(self.request, "location.reload()")
- return reverse_lazy('closemodal')
+ return reverse('closemodal')
class PaymentDelete(generic.DeleteView):
diff --git a/RIGS/migrations/0037_approve_legacy.py b/RIGS/migrations/0037_approve_legacy.py
index 72348b3f..d38c1b66 100644
--- a/RIGS/migrations/0037_approve_legacy.py
+++ b/RIGS/migrations/0037_approve_legacy.py
@@ -1,5 +1,5 @@
# Generated by Django 2.0.13 on 2020-01-11 18:29
-# This migration ensures that legacy Profiles from before approvals were implemented are automatically approved
+# This migration ensures that legacy Profiles from before approvals were implemented are automatically approved
from django.db import migrations
def approve_legacy(apps, schema_editor):
@@ -15,5 +15,5 @@ class Migration(migrations.Migration):
]
operations = [
- migrations.RunPython(approve_legacy)
+ migrations.RunPython(approve_legacy, migrations.RunPython.noop)
]
diff --git a/RIGS/migrations/0041_auto_20210208_1603.py b/RIGS/migrations/0041_auto_20210208_1603.py
new file mode 100644
index 00000000..94795ad2
--- /dev/null
+++ b/RIGS/migrations/0041_auto_20210208_1603.py
@@ -0,0 +1,199 @@
+# Generated by Django 3.1.5 on 2021-02-08 16:03
+
+import RIGS.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('RIGS', '0040_profile_dark_theme'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='event',
+ name='auth_request_to',
+ field=models.EmailField(blank=True, default='', max_length=254),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='collector',
+ field=models.CharField(blank=True, default='', max_length=255, verbose_name='collected by'),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='description',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='meet_info',
+ field=models.CharField(blank=True, default='', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='notes',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='payment_method',
+ field=models.CharField(blank=True, default='', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='payment_received',
+ field=models.CharField(blank=True, default='', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='event',
+ name='purchase_order',
+ field=models.CharField(blank=True, default='', max_length=255, verbose_name='PO'),
+ ),
+ migrations.AlterField(
+ model_name='eventauthorisation',
+ name='account_code',
+ field=models.CharField(blank=True, default='', max_length=50),
+ ),
+ migrations.AlterField(
+ model_name='eventauthorisation',
+ name='uni_id',
+ field=models.CharField(blank=True, default='', max_length=10, verbose_name='University ID'),
+ ),
+ migrations.AlterField(
+ model_name='eventchecklist',
+ name='extinguishers_location',
+ field=models.CharField(blank=True, default='', help_text='Location of fire extinguishers', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='eventchecklist',
+ name='hs_location',
+ field=models.CharField(blank=True, default='', help_text='Location of Safety Bag/Box', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='eventchecklist',
+ name='w1_description',
+ field=models.CharField(blank=True, default='', help_text='Description', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='eventchecklist',
+ name='w2_description',
+ field=models.CharField(blank=True, default='', help_text='Description', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='eventchecklist',
+ name='w3_description',
+ field=models.CharField(blank=True, default='', help_text='Description', max_length=255),
+ ),
+ migrations.AlterField(
+ model_name='eventitem',
+ name='description',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='organisation',
+ name='address',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='organisation',
+ name='email',
+ field=models.EmailField(blank=True, default='', max_length=254),
+ ),
+ migrations.AlterField(
+ model_name='organisation',
+ name='notes',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='organisation',
+ name='phone',
+ field=models.CharField(blank=True, default='', max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='payment',
+ name='method',
+ field=models.CharField(blank=True, choices=[('C', 'Cash'), ('I', 'Internal'), ('E', 'External'), ('SU', 'SU Core'), ('T', 'TEC Adjustment')], default='', max_length=2),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='address',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='email',
+ field=models.EmailField(blank=True, default='', max_length=254),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='notes',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone',
+ field=models.CharField(blank=True, default='', max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='profile',
+ name='api_key',
+ field=models.CharField(blank=True, default='', editable=False, max_length=40),
+ ),
+ migrations.AlterField(
+ model_name='profile',
+ name='phone',
+ field=models.CharField(default='', max_length=13, null=True),
+ ),
+ migrations.AlterField(
+ model_name='riskassessment',
+ name='general_notes',
+ field=models.TextField(blank=True, default='', help_text='Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?'),
+ ),
+ migrations.AlterField(
+ model_name='riskassessment',
+ name='persons_responsible_structures',
+ field=models.TextField(blank=True, default='', help_text='Who are the persons on site responsible for their use?'),
+ ),
+ migrations.AlterField(
+ model_name='riskassessment',
+ name='power_notes',
+ field=models.TextField(blank=True, default='', help_text='Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?'),
+ ),
+ migrations.AlterField(
+ model_name='riskassessment',
+ name='power_plan',
+ field=models.URLField(blank=True, default='', help_text="Upload your power plan to the Sharepoint and submit a link", validators=[RIGS.models.validate_url]),
+ ),
+ migrations.AlterField(
+ model_name='riskassessment',
+ name='rigging_plan',
+ field=models.URLField(blank=True, default='', help_text="Upload your rigging plan to the Sharepoint and submit a link", validators=[RIGS.models.validate_url]),
+ ),
+ migrations.AlterField(
+ model_name='riskassessment',
+ name='sound_notes',
+ field=models.TextField(blank=True, default='', help_text='Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?'),
+ ),
+ migrations.AlterField(
+ model_name='venue',
+ name='address',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='venue',
+ name='email',
+ field=models.EmailField(blank=True, default='', max_length=254),
+ ),
+ migrations.AlterField(
+ model_name='venue',
+ name='notes',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='venue',
+ name='phone',
+ field=models.CharField(blank=True, default='', max_length=15),
+ ),
+ ]
diff --git a/RIGS/models.py b/RIGS/models.py
index 03a35c46..e7050947 100644
--- a/RIGS/models.py
+++ b/RIGS/models.py
@@ -12,7 +12,7 @@ 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.urls import reverse
from django.utils import timezone
from django.utils.functional import cached_property
from reversion import revisions as reversion
@@ -21,11 +21,11 @@ from reversion.models import Version
class Profile(AbstractUser):
initials = models.CharField(max_length=5, unique=True, null=True, blank=False)
- phone = models.CharField(max_length=13, null=True, blank=True)
- api_key = models.CharField(max_length=40, blank=True, editable=False, null=True)
+ phone = models.CharField(max_length=13, null=True, default='')
+ api_key = models.CharField(max_length=40, blank=True, editable=False, default='')
is_approved = models.BooleanField(default=False)
- last_emailed = models.DateTimeField(blank=True,
- null=True) # Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that...
+ # Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that...
+ last_emailed = models.DateTimeField(blank=True, null=True)
dark_theme = models.BooleanField(default=False)
@classmethod
@@ -103,12 +103,12 @@ class RevisionMixin(object):
class Person(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
- phone = models.CharField(max_length=15, blank=True, null=True)
- email = models.EmailField(blank=True, null=True)
+ phone = models.CharField(max_length=15, blank=True, default='')
+ email = models.EmailField(blank=True, default='')
- address = models.TextField(blank=True, null=True)
+ address = models.TextField(blank=True, default='')
- notes = models.TextField(blank=True, null=True)
+ notes = models.TextField(blank=True, default='')
def __str__(self):
string = self.name
@@ -134,17 +134,17 @@ class Person(models.Model, RevisionMixin):
return self.event_set.order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic')
def get_absolute_url(self):
- return reverse_lazy('person_detail', kwargs={'pk': self.pk})
+ return reverse('person_detail', kwargs={'pk': self.pk})
class Organisation(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
- phone = models.CharField(max_length=15, blank=True, null=True)
- email = models.EmailField(blank=True, null=True)
+ phone = models.CharField(max_length=15, blank=True, default='')
+ email = models.EmailField(blank=True, default='')
- address = models.TextField(blank=True, null=True)
+ address = models.TextField(blank=True, default='')
- notes = models.TextField(blank=True, null=True)
+ notes = models.TextField(blank=True, default='')
union_account = models.BooleanField(default=False)
def __str__(self):
@@ -171,7 +171,7 @@ class Organisation(models.Model, RevisionMixin):
return self.event_set.order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic')
def get_absolute_url(self):
- return reverse_lazy('organisation_detail', kwargs={'pk': self.pk})
+ return reverse('organisation_detail', kwargs={'pk': self.pk})
class VatManager(models.Manager):
@@ -211,12 +211,12 @@ class VatRate(models.Model, RevisionMixin):
class Venue(models.Model, RevisionMixin):
name = models.CharField(max_length=255)
- phone = models.CharField(max_length=15, blank=True, null=True)
- email = models.EmailField(blank=True, null=True)
+ phone = models.CharField(max_length=15, blank=True, default='')
+ email = models.EmailField(blank=True, default='')
three_phase_available = models.BooleanField(default=False)
- notes = models.TextField(blank=True, null=True)
+ notes = models.TextField(blank=True, default='')
- address = models.TextField(blank=True, null=True)
+ address = models.TextField(blank=True, default='')
def __str__(self):
string = self.name
@@ -229,7 +229,7 @@ class Venue(models.Model, RevisionMixin):
return self.event_set.order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic')
def get_absolute_url(self):
- return reverse_lazy('venue_detail', kwargs={'pk': self.pk})
+ return reverse('venue_detail', kwargs={'pk': self.pk})
class EventManager(models.Manager):
@@ -298,8 +298,8 @@ class Event(models.Model, RevisionMixin):
person = models.ForeignKey('Person', null=True, blank=True, on_delete=models.CASCADE)
organisation = models.ForeignKey('Organisation', blank=True, null=True, on_delete=models.CASCADE)
venue = models.ForeignKey('Venue', blank=True, null=True, on_delete=models.CASCADE)
- description = models.TextField(blank=True, null=True)
- notes = models.TextField(blank=True, null=True)
+ description = models.TextField(blank=True, default='')
+ notes = models.TextField(blank=True, default='')
status = models.IntegerField(choices=EVENT_STATUS_CHOICES, default=PROVISIONAL)
dry_hire = models.BooleanField(default=False)
is_rig = models.BooleanField(default=True)
@@ -313,7 +313,7 @@ class Event(models.Model, RevisionMixin):
end_time = models.TimeField(blank=True, null=True)
access_at = models.DateTimeField(blank=True, null=True)
meet_at = models.DateTimeField(blank=True, null=True)
- meet_info = models.CharField(max_length=255, blank=True, null=True)
+ meet_info = models.CharField(max_length=255, blank=True, default='')
# Crew management
checked_in_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='event_checked_in', blank=True, null=True,
@@ -322,15 +322,15 @@ class Event(models.Model, RevisionMixin):
verbose_name="MIC", on_delete=models.CASCADE)
# 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')
+ payment_method = models.CharField(max_length=255, blank=True, default='')
+ payment_received = models.CharField(max_length=255, blank=True, default='')
+ purchase_order = models.CharField(max_length=255, blank=True, default='', verbose_name='PO')
+ collector = models.CharField(max_length=255, blank=True, default='', verbose_name='collected by')
# Authorisation request details
auth_request_by = models.ForeignKey('Profile', null=True, blank=True, on_delete=models.CASCADE)
auth_request_at = models.DateTimeField(null=True, blank=True)
- auth_request_to = models.EmailField(null=True, blank=True)
+ auth_request_to = models.EmailField(blank=True, default='')
@property
def display_id(self):
@@ -456,7 +456,7 @@ class Event(models.Model, RevisionMixin):
objects = EventManager()
def get_absolute_url(self):
- return reverse_lazy('event_detail', kwargs={'pk': self.pk})
+ return reverse('event_detail', kwargs={'pk': self.pk})
def __str__(self):
return "{}: {}".format(self.display_id, self.name)
@@ -490,7 +490,7 @@ class Event(models.Model, RevisionMixin):
class EventItem(models.Model, RevisionMixin):
event = models.ForeignKey('Event', related_name='items', blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
- description = models.TextField(blank=True, null=True)
+ description = models.TextField(blank=True, default='')
quantity = models.IntegerField()
cost = models.DecimalField(max_digits=10, decimal_places=2)
order = models.IntegerField()
@@ -505,7 +505,7 @@ class EventItem(models.Model, RevisionMixin):
ordering = ['order']
def __str__(self):
- return str(self.event.pk) + "." + str(self.order) + ": " + self.event.name + " | " + self.name
+ return "{}.{}: {} | {}".format(self.event_id, self.order, self.event.name, self.name)
@property
def activity_feed_string(self):
@@ -517,13 +517,13 @@ class EventAuthorisation(models.Model, RevisionMixin):
event = models.OneToOneField('Event', related_name='authorisation', on_delete=models.CASCADE)
email = models.EmailField()
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)
+ uni_id = models.CharField(max_length=10, blank=True, default='', verbose_name="University ID")
+ account_code = models.CharField(max_length=50, default='', blank=True)
amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="authorisation amount")
sent_by = models.ForeignKey('Profile', on_delete=models.CASCADE)
def get_absolute_url(self):
- return reverse_lazy('event_detail', kwargs={'pk': self.event.pk})
+ return reverse('event_detail', kwargs={'pk': self.event_id})
@property
def activity_feed_string(self):
@@ -562,11 +562,11 @@ class Invoice(models.Model, RevisionMixin):
return self.balance == 0 or self.void
def get_absolute_url(self):
- return reverse_lazy('invoice_detail', kwargs={'pk': self.pk})
+ return reverse('invoice_detail', kwargs={'pk': self.pk})
@property
def activity_feed_string(self):
- return "#{} for Event {}".format(self.display_id, "N%05d" % self.event.pk)
+ return "#{} for Event {}".format(self.display_id, self.event.display_id)
def __str__(self):
return "%i: %s (%.2f)" % (self.pk, self.event, self.balance)
@@ -597,7 +597,7 @@ class Payment(models.Model, RevisionMixin):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE)
date = models.DateField()
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, default='', blank=True)
reversion_hide = True
@@ -632,10 +632,9 @@ class RiskAssessment(models.Model, RevisionMixin):
contractors = models.BooleanField(help_text="Are you using any external contractors?
i.e. Freelancers/Crewing Companies")
other_companies = models.BooleanField(help_text="Are TEC working with any other companies on site?
e.g. TEC is providing the lighting while another company does sound")
crew_fatigue = models.BooleanField(help_text="Is crew fatigue likely to be a risk at any point during this event?")
- general_notes = models.TextField(blank=True, null=True, help_text="Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?")
+ general_notes = models.TextField(blank=True, default='', help_text="Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?")
# Power
- # event_size = models.IntegerField(blank=True, null=True, choices=SIZES)
big_power = models.BooleanField(help_text="Does the event require larger power supplies than 13A or 16A single phase wall sockets, or draw more than 20A total current?")
# If yes to the above two, you must answer...
power_mic = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='power_mic', blank=True, null=True,
@@ -645,12 +644,12 @@ class RiskAssessment(models.Model, RevisionMixin):
other_companies_power = models.BooleanField(help_text="Will TEC be supplying power to any other companies?")
nonstandard_equipment_power = models.BooleanField(help_text="Does the power plan require the use of any power equipment (distros, dimmers, motor controllers, etc.) that does not belong to TEC?")
multiple_electrical_environments = models.BooleanField(help_text="Will the electrical installation occupy more than one electrical environment?")
- power_notes = models.TextField(blank=True, null=True, help_text="Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?")
- power_plan = models.URLField(blank=True, null=True, help_text="Upload your power plan to the Sharepoint and submit a link", validators=[validate_url])
+ power_notes = models.TextField(blank=True, default='', help_text="Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?")
+ power_plan = models.URLField(blank=True, default='', help_text="Upload your power plan to the Sharepoint and submit a link", validators=[validate_url])
# Sound
noise_monitoring = models.BooleanField(help_text="Does the event require noise monitoring or any non-standard procedures in order to comply with health and safety legislation or site rules?")
- sound_notes = models.TextField(blank=True, null=True, help_text="Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?")
+ sound_notes = models.TextField(blank=True, default='', help_text="Did you have to consult a supervisor about any of the above? If so who did you consult and what was the outcome?")
# Site
known_venue = models.BooleanField(help_text="Is this venue new to you (the MIC) or new to TEC?")
@@ -663,8 +662,8 @@ class RiskAssessment(models.Model, RevisionMixin):
# Structures
special_structures = models.BooleanField(help_text="Does the event require use of winch stands, motors, MPT Towers, or staging?")
suspended_structures = models.BooleanField(help_text="Are any structures (excluding projector screens and IWBs) being suspended from TEC's structures?")
- persons_responsible_structures = models.TextField(blank=True, null=True, help_text="Who are the persons on site responsible for their use?")
- rigging_plan = models.URLField(blank=True, null=True, help_text="Upload your rigging plan to the Sharepoint and submit a link", validators=[validate_url])
+ persons_responsible_structures = models.TextField(blank=True, default='', help_text="Who are the persons on site responsible for their use?")
+ rigging_plan = models.URLField(blank=True, default='', help_text="Upload your rigging plan to the Sharepoint and submit a link", validators=[validate_url])
# Blimey that was a lot of options
@@ -723,7 +722,7 @@ class RiskAssessment(models.Model, RevisionMixin):
return str(self.event)
def get_absolute_url(self):
- return reverse_lazy('ra_detail', kwargs={'pk': self.pk})
+ return reverse('ra_detail', kwargs={'pk': self.pk})
def __str__(self):
return "%i - %s" % (self.pk, self.event)
@@ -746,8 +745,8 @@ class EventChecklist(models.Model, RevisionMixin):
trip_hazard = models.BooleanField(blank=True, null=True, help_text="Appropriate barriers around kit and cabling secured?")
warning_signs = models.BooleanField(blank=True, help_text="Warning signs in place?
(strobe, smoke, power etc.)")
ear_plugs = models.BooleanField(blank=True, null=True, help_text="Ear plugs issued to crew where needed?")
- hs_location = models.CharField(blank=True, null=True, max_length=255, help_text="Location of Safety Bag/Box")
- extinguishers_location = models.CharField(blank=True, null=True, max_length=255, help_text="Location of fire extinguishers")
+ hs_location = models.CharField(blank=True, default='', max_length=255, help_text="Location of Safety Bag/Box")
+ extinguishers_location = models.CharField(blank=True, default='', max_length=255, help_text="Location of fire extinguishers")
# Small Electrical Checks
rcds = models.BooleanField(blank=True, null=True, help_text="RCDs installed where needed and tested?")
@@ -768,15 +767,15 @@ class EventChecklist(models.Model, RevisionMixin):
fd_earth_fault = models.IntegerField(blank=True, null=True, verbose_name="Earth Fault Loop Impedance", help_text="Earth Fault Loop Impedance (ZS)")
fd_pssc = models.IntegerField(blank=True, null=True, verbose_name="PSCC", help_text="Prospective Short Circuit Current")
# Worst case points
- w1_description = models.CharField(blank=True, null=True, max_length=255, help_text="Description")
+ w1_description = models.CharField(blank=True, default='', max_length=255, help_text="Description")
w1_polarity = models.BooleanField(blank=True, null=True, help_text="Polarity Checked?")
w1_voltage = models.IntegerField(blank=True, null=True, help_text="Voltage")
w1_earth_fault = models.IntegerField(blank=True, null=True, help_text="Earth Fault Loop Impedance (ZS)")
- w2_description = models.CharField(blank=True, null=True, max_length=255, help_text="Description")
+ w2_description = models.CharField(blank=True, default='', max_length=255, help_text="Description")
w2_polarity = models.BooleanField(blank=True, null=True, help_text="Polarity Checked?")
w2_voltage = models.IntegerField(blank=True, null=True, help_text="Voltage")
w2_earth_fault = models.IntegerField(blank=True, null=True, help_text="Earth Fault Loop Impedance (ZS)")
- w3_description = models.CharField(blank=True, null=True, max_length=255, help_text="Description")
+ w3_description = models.CharField(blank=True, default='', max_length=255, help_text="Description")
w3_polarity = models.BooleanField(blank=True, null=True, help_text="Polarity Checked?")
w3_voltage = models.IntegerField(blank=True, null=True, help_text="Voltage")
w3_earth_fault = models.IntegerField(blank=True, null=True, help_text="Earth Fault Loop Impedance (ZS)")
@@ -801,7 +800,7 @@ class EventChecklist(models.Model, RevisionMixin):
return str(self.event)
def get_absolute_url(self):
- return reverse_lazy('ec_detail', kwargs={'pk': self.pk})
+ return reverse('ec_detail', kwargs={'pk': self.pk})
def __str__(self):
return "%i - %s" % (self.pk, self.event)
diff --git a/RIGS/rigboard.py b/RIGS/rigboard.py
index 6d07e4f6..7e6cc388 100644
--- a/RIGS/rigboard.py
+++ b/RIGS/rigboard.py
@@ -153,7 +153,7 @@ class EventDuplicate(EventUpdate):
new.checked_in_by = None
# Remove all the authorisation information from the new event
- new.auth_request_to = None
+ new.auth_request_to = ''
new.auth_request_by = None
new.auth_request_at = None
diff --git a/RIGS/templatetags/filters.py b/RIGS/templatetags/filters.py
index 5e2eca0a..097e4678 100644
--- a/RIGS/templatetags/filters.py
+++ b/RIGS/templatetags/filters.py
@@ -4,7 +4,7 @@ from django.forms.forms import NON_FIELD_ERRORS
from django.forms.utils import ErrorDict
from django.template.defaultfilters import stringfilter
from django.template.defaultfilters import yesno, title, truncatewords
-from django.urls import reverse_lazy
+from django.urls import reverse
from django.utils.html import escape
from django.utils.safestring import SafeData, mark_safe
from django.utils.text import normalize_newlines
@@ -173,7 +173,7 @@ def title_spaced(string):
@register.filter(needs_autoescape=True)
def namewithnotes(obj, url, autoescape=True):
if hasattr(obj, 'notes') and obj.notes is not None and len(obj.notes) > 0:
- return mark_safe(obj.name + " ".format(reverse_lazy(url, kwargs={'pk': obj.pk})))
+ return mark_safe(obj.name + " ".format(reverse(url, kwargs={'pk': obj.pk})))
else:
return obj.name
diff --git a/RIGS/tests/test_interaction.py b/RIGS/tests/test_interaction.py
index d03d86f4..f67927c9 100644
--- a/RIGS/tests/test_interaction.py
+++ b/RIGS/tests/test_interaction.py
@@ -311,7 +311,7 @@ class TestEventDuplicate(BaseRigboardTest):
# TODO Rewrite when EventDetail page is implemented
newEvent = models.Event.objects.latest('pk')
- self.assertEqual(newEvent.auth_request_to, None)
+ assert newEvent.auth_request_to == ''
self.assertEqual(newEvent.auth_request_by, None)
self.assertEqual(newEvent.auth_request_at, None)
@@ -449,7 +449,7 @@ class TestEventDetail(BaseRigboardTest):
self.assertIn("N%05d | %s" % (self.testEvent.pk, self.testEvent.name), self.page.event_name)
self.assertEqual(self.client.name, self.page.name)
self.assertEqual(self.client.email, self.page.email)
- self.assertEqual(self.client.phone, None)
+ assert self.client.phone == ''
@screenshot_failure_cls
diff --git a/assets/migrations/0019_fix_cabletype.py b/assets/migrations/0019_fix_cabletype.py
new file mode 100644
index 00000000..57e63976
--- /dev/null
+++ b/assets/migrations/0019_fix_cabletype.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.5 on 2021-02-08 16:02
+
+from django.db import migrations
+
+
+def add_default(apps, schema_editor):
+ CableType = apps.get_model('assets', 'CableType')
+ Connector = apps.get_model('assets', 'Connector')
+ for cable_type in CableType.objects.all():
+ if cable_type.plug is None:
+ cable_type.plug = Connector.first()
+ if cable_type.socket is None:
+ cable_type.socket = Connector.first()
+ cable_type.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('assets', '0018_auto_20200415_1940'),
+ ]
+
+ operations = [
+ migrations.RunPython(add_default, migrations.RunPython.noop)
+ ]
diff --git a/assets/migrations/0020_auto_20210208_1603.py b/assets/migrations/0020_auto_20210208_1603.py
new file mode 100644
index 00000000..c040462a
--- /dev/null
+++ b/assets/migrations/0020_auto_20210208_1603.py
@@ -0,0 +1,50 @@
+# Generated by Django 3.1.5 on 2021-02-08 16:03
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('assets', '0019_fix_cabletype'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='assetstatus',
+ name='display_class',
+ field=models.CharField(blank=True, default='', help_text='HTML class to be appended to alter display of assets with this status, such as in the list.', max_length=80),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='cabletype',
+ name='plug',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='plug', to='assets.connector'),
+ ),
+ migrations.AlterField(
+ model_name='cabletype',
+ name='socket',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='socket', to='assets.connector'),
+ ),
+ migrations.AlterField(
+ model_name='supplier',
+ name='address',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='supplier',
+ name='email',
+ field=models.EmailField(blank=True, default='', max_length=254),
+ ),
+ migrations.AlterField(
+ model_name='supplier',
+ name='notes',
+ field=models.TextField(blank=True, default=''),
+ ),
+ migrations.AlterField(
+ model_name='supplier',
+ name='phone',
+ field=models.CharField(blank=True, default='', max_length=15),
+ ),
+ ]
diff --git a/assets/models.py b/assets/models.py
index cc532780..0b783865 100644
--- a/assets/models.py
+++ b/assets/models.py
@@ -10,44 +10,44 @@ from RIGS.models import RevisionMixin, Profile
class AssetCategory(models.Model):
+ name = models.CharField(max_length=80)
+
class Meta:
verbose_name = 'Asset Category'
verbose_name_plural = 'Asset Categories'
ordering = ['name']
- name = models.CharField(max_length=80)
-
def __str__(self):
return self.name
class AssetStatus(models.Model):
+ name = models.CharField(max_length=80)
+ should_show = models.BooleanField(
+ default=True, help_text="Should this be shown by default in the asset list.")
+ display_class = models.CharField(max_length=80, blank=True, help_text="HTML class to be appended to alter display of assets with this status, such as in the list.")
+
class Meta:
verbose_name = 'Asset Status'
verbose_name_plural = 'Asset Statuses'
ordering = ['name']
- name = models.CharField(max_length=80)
- should_show = models.BooleanField(
- default=True, help_text="Should this be shown by default in the asset list.")
- display_class = models.CharField(max_length=80, blank=True, null=True, help_text="HTML class to be appended to alter display of assets with this status, such as in the list.")
-
def __str__(self):
return self.name
@reversion.register
class Supplier(models.Model, RevisionMixin):
+ name = models.CharField(max_length=80)
+ phone = models.CharField(max_length=15, blank=True, default="")
+ email = models.EmailField(blank=True, default="")
+ address = models.TextField(blank=True, default="")
+
+ notes = models.TextField(blank=True, default="")
+
class Meta:
ordering = ['name']
- name = models.CharField(max_length=80)
- phone = models.CharField(max_length=15, blank=True, null=True)
- email = models.EmailField(blank=True, null=True)
- address = models.TextField(blank=True, null=True)
-
- notes = models.TextField(blank=True, null=True)
-
def get_absolute_url(self):
return reverse('supplier_list')
@@ -65,17 +65,16 @@ class Connector(models.Model):
return self.description
-# Things are nullable that shouldn't be because I didn't properly fix the data structure when moving this to its own model...
class CableType(models.Model):
- class Meta:
- ordering = ['plug', 'socket', '-circuits']
-
circuits = models.IntegerField(default=1)
cores = models.IntegerField(default=3)
plug = models.ForeignKey(Connector, on_delete=models.CASCADE,
- related_name='plug', null=True)
+ related_name='plug')
socket = models.ForeignKey(Connector, on_delete=models.CASCADE,
- related_name='socket', null=True)
+ related_name='socket')
+
+ class Meta:
+ ordering = ['plug', 'socket', '-circuits']
def __str__(self):
if self.plug and self.socket:
@@ -104,12 +103,6 @@ def get_available_asset_id(wanted_prefix=""):
@reversion.register
class Asset(models.Model, RevisionMixin):
- class Meta:
- ordering = ['asset_id_prefix', 'asset_id_number']
- permissions = [
- ('asset_finance', 'Can see financial data for assets')
- ]
-
parent = models.ForeignKey(to='self', related_name='asset_parent',
blank=True, null=True, on_delete=models.SET_NULL)
asset_id = models.CharField(max_length=15, unique=True)
@@ -143,12 +136,18 @@ class Asset(models.Model, RevisionMixin):
reversion_perm = 'assets.asset_finance'
- def get_absolute_url(self):
- return reverse('asset_detail', kwargs={'pk': self.asset_id})
+ class Meta:
+ ordering = ['asset_id_prefix', 'asset_id_number']
+ permissions = [
+ ('asset_finance', 'Can see financial data for assets')
+ ]
def __str__(self):
return "{} | {}".format(self.asset_id, self.description)
+ def get_absolute_url(self):
+ return reverse('asset_detail', kwargs={'pk': self.asset_id})
+
def clean(self):
errdict = {}
if self.date_sold and self.date_acquired > self.date_sold:
diff --git a/versioning/tests/test_models.py b/versioning/tests/test_models.py
index 09787c4b..453ad901 100644
--- a/versioning/tests/test_models.py
+++ b/versioning/tests/test_models.py
@@ -43,7 +43,7 @@ class RIGSVersionTestCase(TestCase):
# Check the prev version is loaded correctly
previousVersion = current_version.parent
- self.assertEqual(previousVersion._object_version.object.notes, None)
+ assert previousVersion._object_version.object.notes == ''
# Check that finding the parent of the first version fails gracefully
self.assertFalse(previousVersion.parent)