diff --git a/Pipfile.lock b/Pipfile.lock
index 14ec9a11..1340ca7b 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -309,10 +309,11 @@
},
"django-hcaptcha": {
"hashes": [
- "sha256:2b80197c07bb8444249bcce3758b0472d369cca309fb02d7abcd0a856431b76b"
+ "sha256:18804fb38a01827b6c65d111bac31265c1b96fcf52d7a54c3e2d2cb1c62ddcde",
+ "sha256:b2519eaf0cc97865ac72f825301122c5cf61e1e4852d6895994160222acb6c1a"
],
"index": "pypi",
- "version": "==0.1.0"
+ "version": "==0.2.0"
},
"django-htmlmin": {
"hashes": [
@@ -362,11 +363,11 @@
},
"django-widget-tweaks": {
"hashes": [
- "sha256:19bcb66a4a9e68493ced04e7124882d753c5be517ed001556f9e35a40147f545",
- "sha256:d6c64fbf92cd2df9031f597c1374982233c05a1190d295c39d1c57ce007569c7"
+ "sha256:01b911a1b47629de0a3a3097774798dee4eb703b94d41666929f688d5f77c723",
+ "sha256:07674e32031eda81077f0b8e390ce78d1d415e700cedd0396ef0ce452e95b94d"
],
"index": "pypi",
- "version": "==1.4.9"
+ "version": "==1.4.11"
},
"envparse": {
"hashes": [
@@ -861,11 +862,11 @@
},
"sentry-sdk": {
"hashes": [
- "sha256:2a1757d6611e4bec7d672c2b7ef45afef79fed201d064f53994753303944f5a8",
- "sha256:e4cb107e305b2c1b919414775fa73a9997f996447417d22b98e7610ded1e9eb5"
+ "sha256:2cec50166bcb67e1965f8073541b2321e3864cd6fd42a526bcde9f0c4e4cc3f8",
+ "sha256:7bbaa32bba806ec629962f207b597e86831c7ee2c1f287c21ba7de7fea9a9c46"
],
"index": "pypi",
- "version": "==1.5.1"
+ "version": "==1.5.2"
},
"simplejson": {
"hashes": [
@@ -1538,11 +1539,11 @@
},
"pytest-reverse": {
"hashes": [
- "sha256:9f2a3b163378922dd332ed056a58af4cfd1ccc8ad4a76606f43ed43cfff2140b",
- "sha256:d878e28c785fb20291580aa816d566a21beac508e06a2c9eb4f934d49c31ce5c"
+ "sha256:1695b7c9e51b28db5af13d579b33b54a80958d86b886dfabd2a246bcad3e082e",
+ "sha256:6acfb50acd11caf3d222366f5e1458dea2351d47b6ca5b08ab408158636250ba"
],
"index": "pypi",
- "version": "==1.3.0"
+ "version": "==1.4.0"
},
"pytest-splinter": {
"hashes": [
diff --git a/RIGS/forms.py b/RIGS/forms.py
index 28c660ea..258928d0 100644
--- a/RIGS/forms.py
+++ b/RIGS/forms.py
@@ -8,6 +8,7 @@ from django.utils import timezone
from reversion import revisions as reversion
from RIGS import models
+from training.models import TrainingLevel
# Override the django form defaults to use the HTML date/time/datetime UI elements
forms.DateField.widget = forms.DateInput(attrs={'type': 'date'})
@@ -164,6 +165,9 @@ class EventRiskAssessmentForm(forms.ModelForm):
], attrs={'class': 'custom-control-input', 'required': 'true'})
def clean(self):
+ if self.cleaned_data.get('big_power'):
+ if not self.cleaned_data.get('power_mic').level_qualifications.filter(level__department=TrainingLevel.POWER).exists():
+ self.add_error('power_mic', forms.ValidationError("Your Power MIC must be a Power Technician.", code="power_tech_required"))
# Check expected values
unexpected_values = []
for field, value in models.RiskAssessment.expected_values.items():
diff --git a/RIGS/models.py b/RIGS/models.py
index 90b0c3d5..16e936b1 100644
--- a/RIGS/models.py
+++ b/RIGS/models.py
@@ -99,7 +99,7 @@ class RevisionMixin(object):
version = self.current_version
if version is None:
return None
- return "V{0} | R{1}".format(version.pk, version.revision.pk)
+ return f"V{version.pk} | R{version.revision.pk}"
class Person(models.Model, RevisionMixin):
@@ -207,7 +207,7 @@ class VatRate(models.Model, RevisionMixin):
get_latest_by = 'start_at'
def __str__(self):
- return self.comment + " " + str(self.start_at) + " @ " + str(self.as_percent) + "%"
+ return f"{self.comment} {self.start_at} @ {self.as_percent}%"
class Venue(models.Model, RevisionMixin):
@@ -347,10 +347,10 @@ class Event(models.Model, RevisionMixin):
if self.pk:
if self.is_rig:
return str("N%05d" % self.pk)
- else:
- return self.pk
- else:
- return "????"
+
+ return self.pk
+
+ return "????"
# Calculated values
"""
@@ -475,7 +475,7 @@ class Event(models.Model, RevisionMixin):
return reverse('event_detail', kwargs={'pk': self.pk})
def __str__(self):
- return "{}: {}".format(self.display_id, self.name)
+ return f"{self.display_id}: {self.name}"
def clean(self):
errdict = {}
@@ -521,11 +521,11 @@ class EventItem(models.Model, RevisionMixin):
ordering = ['order']
def __str__(self):
- return "{}.{}: {} | {}".format(self.event_id, self.order, self.event.name, self.name)
+ return f"{self.event_id}.{self.order}: {self.event.name} | {self.name}"
@property
def activity_feed_string(self):
- return str("item {}".format(self.name))
+ return f"item {self.name}"
@reversion.register
@@ -543,7 +543,7 @@ class EventAuthorisation(models.Model, RevisionMixin):
@property
def activity_feed_string(self):
- return "{} (requested by {})".format(self.event.display_id, self.sent_by.initials)
+ return f"{self.event.display_id} (requested by {self.sent_by.initials})"
class InvoiceManager(models.Manager):
@@ -671,7 +671,6 @@ class RiskAssessment(models.Model, RevisionMixin):
# Power
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,
verbose_name="Power MIC", on_delete=models.CASCADE, help_text="Who is the Power MIC? (if yes to the above question, this person must be a Power Technician or Power Supervisor)")
outside = models.BooleanField(help_text="Is the event outdoors?")
diff --git a/conftest.py b/conftest.py
index 3e5b278a..ac203464 100644
--- a/conftest.py
+++ b/conftest.py
@@ -2,9 +2,7 @@ from django.conf import settings
import django
import pytest
from django.core.management import call_command
-from RIGS.models import VatRate, Profile
-import random
-from django.db import connection
+from RIGS.models import VatRate
from PyRIGS.tests import pages
import os
from selenium import webdriver
diff --git a/training/forms.py b/training/forms.py
index 9cfcf368..9f4dbbf6 100644
--- a/training/forms.py
+++ b/training/forms.py
@@ -1,15 +1,8 @@
from django import forms
-from datetime import date
-
from training import models
from RIGS.models import Profile
-
-class SessionLogForm(forms.Form):
- pass
-
-
class QualificationForm(forms.ModelForm):
class Meta:
model = models.TrainingItemQualification
diff --git a/training/models.py b/training/models.py
index edea755a..558277fc 100644
--- a/training/models.py
+++ b/training/models.py
@@ -1,10 +1,8 @@
-from django.db import models
-
from RIGS.models import RevisionMixin, Profile
from reversion import revisions as reversion
+from django.db import models
from django.urls import reverse
-
-from django.utils.safestring import SafeData, mark_safe
+from django.utils.safestring import mark_safe
@reversion.register(for_concrete_model=False, fields=[], follow=["qualifications_obtained", "level_qualifications"])
@@ -105,13 +103,13 @@ class TrainingItemQualification(models.Model, RevisionMixin):
return str("{} in {}".format(self.get_depth_display(), self.item))
@classmethod
- def get_colour_from_depth(obj, depth):
+ def get_colour_from_depth(cls, obj, depth):
if depth == 0:
return "warning"
- elif depth == 1:
+ if depth == 1:
return "success"
- else:
- return "info"
+
+ return "info"
def get_absolute_url(self):
return reverse('trainee_item_detail', kwargs={'pk': self.trainee.pk})
@@ -157,16 +155,16 @@ class TrainingLevel(models.Model, RevisionMixin):
def department_colour(self):
if self.department == self.SOUND:
return "info"
- elif self.department == self.LIGHTING:
+ if self.department == self.LIGHTING:
return "dark"
- elif self.department == self.POWER:
+ if self.department == self.POWER:
return "danger"
- elif self.department == self.RIGGING:
+ if self.department == self.RIGGING:
return "warning"
- elif self.department == self.HAULAGE:
+ if self.department == self.HAULAGE:
return "light"
- else:
- return "primary"
+
+ return "primary"
def get_requirements_of_depth(self, depth):
return self.requirements.filter(depth=depth)
@@ -197,8 +195,8 @@ class TrainingLevel(models.Model, RevisionMixin):
if len(needed_qualifications) > 0:
return int(relavant_qualifications / float(len(needed_qualifications)) * 100)
- else:
- return 0
+
+ return 0
def user_has_requirements(self, user):
has_required_items = all(TrainingItem.user_has_qualification(req.item, user, req.depth) for req in self.requirements.all())
@@ -225,7 +223,7 @@ class TrainingLevel(models.Model, RevisionMixin):
@property
def get_icon(self):
if self.icon is not None:
- icon = "".format(self.icon)
+ icon = f""
else:
icon = "".join([w[0] for w in str(self).split()])
return mark_safe("{}".format(self.department_colour, str(self), icon))
@@ -260,14 +258,14 @@ class TrainingLevelQualification(models.Model, RevisionMixin):
return self.level.get_icon
def clean(self):
- if level.level >= TrainingLevel.SUPERVISOR and level.department != TrainingLevel.HAULAGE:
- trainee.is_supervisor = True
- trainee.save()
+ if self.level.level >= TrainingLevel.SUPERVISOR and self.level.department != TrainingLevel.HAULAGE:
+ self.trainee.is_supervisor = True
+ self.trainee.save()
def __str__(self):
if self.level.is_common_competencies:
- return "{} is qualified in the {}".format(self.trainee, self.level)
- return "{} is qualified as a {}".format(self.trainee, self.level)
+ return f"{self.trainee} is qualified in the {self.level}"
+ return f"{self.trainee} is qualified as a {self.level}"
class Meta:
unique_together = ["trainee", "level"]
diff --git a/training/views.py b/training/views.py
index 8f2f449e..dbf9cf26 100644
--- a/training/views.py
+++ b/training/views.py
@@ -1,14 +1,13 @@
import reversion
-from django.shortcuts import render
from django.urls import reverse_lazy
from django.views import generic
-from PyRIGS.views import OEmbedView, is_ajax, ModalURLMixin
-from training import models, forms
from django.utils import timezone
from django.db import transaction
-from django.db.models import Q, Count, OuterRef, F, Subquery, Window
+from django.db.models import Q, Count
+from PyRIGS.views import is_ajax, ModalURLMixin
+from training import models, forms
from users import views
@@ -98,12 +97,12 @@ class TraineeList(generic.ListView):
def get_queryset(self):
q = self.request.GET.get('q', "")
- filter = Q(first_name__icontains=q) | Q(last_name__icontains=q) | Q(initials__icontains=q)
+ fil = Q(first_name__icontains=q) | Q(last_name__icontains=q) | Q(initials__icontains=q)
# try and parse an int
try:
val = int(q)
- filter = filter | Q(pk=val)
+ fil = fil | Q(pk=val)
except: # noqa
# not an integer
pass
@@ -200,7 +199,7 @@ class RemoveRequirement(generic.DeleteView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- context["page_title"] = "Delete Requirement '{}' from Training Level {}?".format(self.object, self.object.level)
+ context["page_title"] = f"Delete Requirement '{self.object}' from Training Level {self.object.level}?"
return context
def get_success_url(self):