Validation of power reqs

This commit is contained in:
2020-08-30 12:15:04 +01:00
parent bfe80db85e
commit f3c2ce2519
10 changed files with 281 additions and 53 deletions

View File

@@ -173,6 +173,12 @@ class EventRiskAssessmentForm(forms.ModelForm):
class EventChecklistForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(EventChecklistForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
if field.__class__ == forms.NullBooleanField:
# Only display yes/no to user, the 'none' is only ever set in the background
field.widget = forms.CheckboxInput()
# Parsed from incoming form data by clean, then saved into models when the form is saved
items = {}
@@ -231,6 +237,7 @@ class EventChecklistForm(forms.ModelForm):
# Remove all existing, to be recreated from the form
checklist.vehicles.all().delete()
checklist.crew.all().delete()
checklist.save()
for key in self.items:
item = self.items[key]
@@ -240,8 +247,6 @@ class EventChecklistForm(forms.ModelForm):
item.full_clean()
item.save()
checklist.save()
self.items.clear()
return checklist

View File

@@ -0,0 +1,73 @@
# Generated by Django 3.1 on 2020-08-30 10:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0050_auto_20200830_1048'),
]
operations = [
migrations.AlterField(
model_name='eventchecklist',
name='all_rcds_tested',
field=models.BooleanField(blank=True, help_text='All circuit RCDs tested?<small>(using test button)</small>'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_earth_fault',
field=models.IntegerField(blank=True, help_text='Earth Fault Loop Impedance (Z<small>S</small>)', verbose_name='Earth Fault Loop Impedance'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_phase_rotation',
field=models.BooleanField(blank=True, help_text='Phase Rotation<br><small>(if required)</small>', verbose_name='Phase Rotation'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_pssc',
field=models.IntegerField(blank=True, help_text='Prospective Short Circuit Current', verbose_name='PSCC'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_voltage_l1',
field=models.IntegerField(blank=True, help_text='L1 - N', verbose_name='First Distro Voltage L1-N'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_voltage_l2',
field=models.IntegerField(blank=True, help_text='L2 - N', verbose_name='First Distro Voltage L2-N'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_voltage_l3',
field=models.IntegerField(blank=True, help_text='L3 - N', verbose_name='First Distro Voltage L3-N'),
),
migrations.AlterField(
model_name='eventchecklist',
name='labelling',
field=models.BooleanField(blank=True, help_text='Appropriate and clear labelling on distribution and cabling?'),
),
migrations.AlterField(
model_name='eventchecklist',
name='public_sockets_tested',
field=models.BooleanField(blank=True, help_text='Public/Performer accessible circuits tested?<small>(using socket tester)</small>'),
),
migrations.AlterField(
model_name='eventchecklist',
name='rcds',
field=models.BooleanField(blank=True, help_text='RCDs installed where needed and tested?'),
),
migrations.AlterField(
model_name='eventchecklist',
name='source_rcd',
field=models.BooleanField(blank=True, help_text='Source RCD protected?<br><small>(if cable is more than 3m long) </small>'),
),
migrations.AlterField(
model_name='eventchecklist',
name='supply_test',
field=models.BooleanField(blank=True, help_text='Electrical supplies tested?<br><small>(using socket tester)</small>'),
),
]

View File

@@ -0,0 +1,73 @@
# Generated by Django 3.1 on 2020-08-30 10:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0051_auto_20200830_1115'),
]
operations = [
migrations.AlterField(
model_name='eventchecklist',
name='all_rcds_tested',
field=models.BooleanField(blank=True, help_text='All circuit RCDs tested?<small>(using test button)</small>', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_earth_fault',
field=models.IntegerField(blank=True, help_text='Earth Fault Loop Impedance (Z<small>S</small>)', null=True, verbose_name='Earth Fault Loop Impedance'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_phase_rotation',
field=models.BooleanField(blank=True, help_text='Phase Rotation<br><small>(if required)</small>', null=True, verbose_name='Phase Rotation'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_pssc',
field=models.IntegerField(blank=True, help_text='Prospective Short Circuit Current', null=True, verbose_name='PSCC'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_voltage_l1',
field=models.IntegerField(blank=True, help_text='L1 - N', null=True, verbose_name='First Distro Voltage L1-N'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_voltage_l2',
field=models.IntegerField(blank=True, help_text='L2 - N', null=True, verbose_name='First Distro Voltage L2-N'),
),
migrations.AlterField(
model_name='eventchecklist',
name='fd_voltage_l3',
field=models.IntegerField(blank=True, help_text='L3 - N', null=True, verbose_name='First Distro Voltage L3-N'),
),
migrations.AlterField(
model_name='eventchecklist',
name='labelling',
field=models.BooleanField(blank=True, help_text='Appropriate and clear labelling on distribution and cabling?', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='public_sockets_tested',
field=models.BooleanField(blank=True, help_text='Public/Performer accessible circuits tested?<small>(using socket tester)</small>', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='rcds',
field=models.BooleanField(blank=True, help_text='RCDs installed where needed and tested?', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='source_rcd',
field=models.BooleanField(blank=True, help_text='Source RCD protected?<br><small>(if cable is more than 3m long) </small>', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='supply_test',
field=models.BooleanField(blank=True, help_text='Electrical supplies tested?<br><small>(using socket tester)</small>', null=True),
),
]

View File

@@ -654,8 +654,8 @@ class EventChecklist(models.Model, RevisionMixin):
extinguishers_location = models.CharField(max_length=255, help_text="Location of fire extinguishers")
# Small Electrical Checks
rcds = models.BooleanField(help_text="RCDs installed where needed and tested?")
supply_test = models.BooleanField(help_text="Electrical supplies tested?<br><small>(using socket tester)</small>")
rcds = models.BooleanField(blank=True,null=True,help_text="RCDs installed where needed and tested?")
supply_test = models.BooleanField(blank=True,null=True,help_text="Electrical supplies tested?<br><small>(using socket tester)</small>")
# Shared electrical checks
earthing = models.BooleanField(help_text="Equipment appropriately earthed?<br><small>(truss, stage, generators etc)</small>")
@@ -663,18 +663,27 @@ class EventChecklist(models.Model, RevisionMixin):
medium_event = models.BooleanField()
# Medium Electrical Checks
source_rcd = models.BooleanField(help_text="Source RCD protected?<br><small>(if cable is more than 3m long) </small>")
labelling = models.BooleanField(help_text="Appropriate and clear labelling on distribution and cabling?")
source_rcd = models.BooleanField(blank=True,null=True,help_text="Source RCD protected?<br><small>(if cable is more than 3m long) </small>")
labelling = models.BooleanField(blank=True,null=True, help_text="Appropriate and clear labelling on distribution and cabling?")
# First Distro
fd_voltage_l1 = models.IntegerField(verbose_name="First Distro Voltage L1-N", help_text="L1 - N")
fd_voltage_l2 = models.IntegerField(verbose_name="First Distro Voltage L2-N", help_text="L2 - N")
fd_voltage_l3 = models.IntegerField(verbose_name="First Distro Voltage L3-N", help_text="L3 - N")
fd_phase_rotation = models.BooleanField(verbose_name="Phase Rotation", help_text="Phase Rotation<br><small>(if required)</small>")
fd_earth_fault = models.IntegerField(verbose_name="Earth Fault Loop Impedance", help_text="Earth Fault Loop Impedance (Z<small>S</small>)")
fd_pssc = models.IntegerField(verbose_name="PSCC", help_text="Prospective Short Circuit Current")
fd_voltage_l1 = models.IntegerField(blank=True,null=True, verbose_name="First Distro Voltage L1-N", help_text="L1 - N")
fd_voltage_l2 = models.IntegerField(blank=True,null=True,verbose_name="First Distro Voltage L2-N", help_text="L2 - N")
fd_voltage_l3 = models.IntegerField(blank=True,null=True,verbose_name="First Distro Voltage L3-N", help_text="L3 - N")
fd_phase_rotation = models.BooleanField(blank=True,null=True,verbose_name="Phase Rotation", help_text="Phase Rotation<br><small>(if required)</small>")
fd_earth_fault = models.IntegerField(blank=True,null=True,verbose_name="Earth Fault Loop Impedance", help_text="Earth Fault Loop Impedance (Z<small>S</small>)")
fd_pssc = models.IntegerField(blank=True,null=True,verbose_name="PSCC", help_text="Prospective Short Circuit Current")
all_rcds_tested = models.BooleanField(help_text="All circuit RCDs tested?<small>(using test button)</small>")
public_sockets_tested = models.BooleanField(help_text="Public/Performer accessible circuits tested?<small>(using socket tester)</small>")
all_rcds_tested = models.BooleanField(blank=True,null=True,help_text="All circuit RCDs tested?<br><small>(using test button)</small>")
public_sockets_tested = models.BooleanField(blank=True,null=True,help_text="Public/Performer accessible circuits tested?<br><small>(using socket tester)</small>")
def clean(self):
errdict = {}
if self.earthing == None or self.pat == None:
raise ValidationError('Fill out the electrical checks')
if self.medium_event and (self.source_rcd == None or self.labelling == None or self.all_rcds_tested == None or self.public_sockets_tested == None):
raise ValidationError('Fill out the medium event electrical checks')
elif self.rcds == None or self.supply_test == None:
raise ValidationError('Fill out the small event electrical checks')
@property
def activity_feed_string(self):

View File

@@ -91,12 +91,75 @@
</table>
</div>
<div class="card card-default mb-3">
<div class="card-header">Power</div>
<div class="card-header">Power {% if object.medium_event %}<span class="badge badge-warning p-2 my-3">Medium Event</span>{%else%}<span class="badge badge-success p-2 my-3">Small Event</span>{%endif%}</div>
<div class="card-body">
{% if object.medium_event %}
<span class="badge badge-warning p-2 my-3">Medium Event</span>
<dl class="row">
<dt class="col-10">{{ object|help_text:'source_rcd'|safe }}</dt>
<dd class="col-2">
{{ object.source_rcd|yesno|title }}
</dd>
<dt class="col-10">{{ object|help_text:'labelling'|safe }}</dt>
<dd class="col-2">
{{ object.labelling|yesno|title }}
</dd>
<dt class="col-10">{{ object|help_text:'earthing'|safe }}</dt>
<dd class="col-2">
{{ object.earthing|yesno|title }}
</dd>
<dt class="col-10">{{ object|help_text:'pat'|safe }}</dt>
<dd class="col-2">
{{ object.pat|yesno|title }}
</dd>
</dl>
<hr>
<p>Tests at first distro</p>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" class="text-center">Test</th>
<th scope="col" colspan="3" class="text-center">Value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" rowspan="2">Voltage<br><small>(cube meter)</small></th>
<th>{{ object|help_text:'fd_voltage_l1' }}</th>
<th>{{ object|help_text:'fd_voltage_l2' }}</th>
<th>{{ object|help_text:'fd_voltage_l3' }}</th>
</tr>
<tr>
<td>{{ object.fd_voltage_l1 }}</td>
<td>{{ object.fd_voltage_l2 }}</td>
<td>{{ object.fd_voltage_l3 }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_phase_rotation'|safe }}</th>
<td colspan="3">{{ object.fd_phase_rotation|yesno|title }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_earth_fault'|safe}}</th>
<td colspan="3">{{ object.fd_earth_fault }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_pssc'}}</th>
<td colspan="3">{{ object.fd_pssc }}</td>
</tr>
</tbody>
</table>
<hr>
<dl class="row">
<dt class="col-10">{{ object|help_text:'all_rcds_tested'|safe }}</dt>
<dd class="col-2">
{{ object.all_rcds_tested|yesno|title }}
</dd>
<dt class="col-10">{{ object|help_text:'public_sockets_tested'|safe }}</dt>
<dd class="col-2">
{{ object.public_sockets_tested|yesno|title }}
</dd>
</dl>
{% include 'partials/ec_power_info.html' %}
{% else %}
<span class="badge badge-success p-2 my-3">Small Event</span>
<dl class="row">
<dt class="col-10">{{ object|help_text:'rcds'|safe }}</dt>
<dd class="col-2">
@@ -119,13 +182,13 @@
</div>
</div>
</div>
</div>
<div class="col-12 text-right">
<a href="{% url 'ec_edit' object.pk %}" class="btn btn-warning my-3"><span class="fas fa-edit"></span> <span
class="hidden-xs">Edit</span></a>
</div>
<div class="col-12 text-right">
{% include 'partials/last_edited.html' with target="eventchecklist_history" %}
<div class="col-12 text-right">
<a href="{% url 'ec_edit' object.pk %}" class="btn btn-warning my-3"><span class="fas fa-edit"></span> <span
class="hidden-xs">Edit</span></a>
</div>
<div class="col-12 text-right">
{% include 'partials/last_edited.html' with target="eventchecklist_history" %}
</div>
</div>
</div>
{% endblock %}

View File

@@ -49,10 +49,14 @@
$('#{{form.medium_event.auto_id}}').prop('checked', true);
$('#small-event').slideUp();
$('#medium-event').slideDown();
//$('#medium-event').find('select,input').attr('required', 'true');
//$('#small-event').find('select,input').removeAttr('required');
} else {
$('#{{form.medium_event.auto_id}}').prop('checked', false);
$('#small-event').slideDown();
$('#medium-event').slideUp();
//('#small-event').find('select,input').attr('required', 'true');
//('#medium-event').find('select,input').removeAttr('required');
}
});
$('button[data-action=add]').on('click', function (event) {
@@ -118,7 +122,7 @@
<label for="{{ form.power_mic.id_for_label }}"
class="col-4 control-label">{{ form.power_mic.help_text }}</label>
<div class="col-8">
<select id="{{ form.power_mic.id_for_label }}" name="{{ form.power_mic.name }}" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials">
<select id="{{ form.power_mic.id_for_label }}" name="{{ form.power_mic.name }}" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required="true">
{% if object.power_mic %}
<option value="{{object.power_mic.pk}}" selected="selected">{{ object.power_mic.name }}</option>
{% endif %}
@@ -261,27 +265,24 @@
<div class="card-header">Electrical Checks <small>for Medium TEC Events </small></div>
<div class="card-body">
{% include 'partials/checklist_checkbox.html' with formitem=form.source_rcd %}
{% include 'partials/checklist_checkbox.html' with formitem=form.clear_labelling %}
{% include 'partials/checklist_checkbox.html' with formitem=form.labelling %}
{% include 'partials/checklist_checkbox.html' with formitem=form.earthing %}
{% include 'partials/checklist_checkbox.html' with formitem=form.pat %}
<hr>
<p>Tests at first distro</p>
<table class="table">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Test</th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col" class="text-center">Test</th>
<th scope="col" colspan="3" class="text-center">Value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" rowspan="2">Voltage<br><small>(cube meter)</small></th>
<th>{{object|help_text:'fd_voltage_l1'}}</th>
<th>{{object|help_text:'fd_voltage_l2'}}</th>
<th>{{object|help_text:'fd_voltage_l3'}}</th>
<th>{{ form.fd_voltage_l1.help_text }}</th>
<th>{{ form.fd_voltage_l2.help_text }}</th>
<th>{{ form.fd_voltage_l3.help_text }}</th>
</tr>
<tr>
<td>{% render_field form.fd_voltage_l1 class+="form-control" %}</td>
@@ -289,15 +290,15 @@
<td>{% render_field form.fd_voltage_l3 class+="form-control" %}</td>
</tr>
<tr>
<th scope="row">{{object|help_text:'fd_phase_rotation'|safe}}</th>
<td colspan="3">{% render_field form.fd_phase_rotation %}</td>
<th scope="row">{{form.fd_phase_rotation.help_text|safe}}</th>
<td colspan="3">{% include 'partials/checklist_checkbox.html' with formitem=form.fd_phase_rotation %}</td>
</tr>
<tr>
<th scope="row">{{object|help_text:'fd_earth_fault'|safe}}</th>
<th scope="row">{{form.fd_earth_fault.help_text|safe}}</th>
<td colspan="3">{% render_field form.fd_earth_fault class+="form-control" %}</td>
</tr>
<tr>
<th scope="row">{{object|help_text:'fd_pssc'|safe}}</th>
<th scope="row">{{form.fd_pssc.help_text|safe}}</th>
<td colspan="3">{% render_field form.fd_pssc class+="form-control" %}</td>
</tr>
</tbody>

View File

@@ -1,6 +1,6 @@
{% load widget_tweaks %}
{% load help_text from filters %}
<div class="form-check">
{% render_field formitem|attr:'required=true' class+="form-check-input" %}
{% render_field formitem class+="form-check-input" %}
<label class="form-check-label" for="{{ formitem.id_for_label }}">{{formitem.help_text|safe}}</label>
</div>

View File

@@ -1,10 +1,12 @@
<label for="{{ formitem.id_for_label }}"
class="col-sm-8 control-label">{{ formitem.help_text|safe }}</label>
<div class="col-4 pb-3">
{% for radio in formitem %}
<div class="custom-control custom-radio">
{{ radio.tag }}
<label class="custom-control-label" for="{{ radio.id_for_label }}">{{ radio.choice_label }}</label>
</div>
{% endfor %}
<div class="row">
<label for="{{ formitem.id_for_label }}"
class="col-8 control-label">{{ formitem.help_text|safe }}</label>
<div class="col-4 pb-3">
{% for radio in formitem %}
<div class="custom-control custom-radio">
{{ radio.tag }}
<label class="custom-control-label" for="{{ radio.id_for_label }}">{{ radio.choice_label }}</label>
</div>
{% endfor %}
</div>
</div>

View File

@@ -114,10 +114,11 @@ def orderby(request, field, attr):
return dict_.urlencode()
# Used for accessing outside of a form, i.e. in detail views of RiskAssessment and EventChecklist
@register.filter
def help_text(obj, field):
return obj._meta.get_field(field).help_text
if hasattr(obj, '_meta'):
return obj._meta.get_field(field).help_text
@register.filter

View File

@@ -117,17 +117,17 @@ class ModelComparison(object):
@cached_property
def item_changes(self):
# Recieves two event version objects and compares their items, returns an array of ItemCompare objects
item_type = ContentType.objects.get_for_model(self.version.object)
old_item_versions = self.version.parent.revision.version_set.exclude(content_type=item_type)
new_item_versions = self.version.revision.version_set.exclude(content_type=item_type)
comparisonParams = {'excluded_keys': ['id', 'event', 'order']}
comparisonParams = {'excluded_keys': ['id', 'event', 'order', 'checklist']}
# Build some dicts of what we have
item_dict = {} # build a list of items, key is the item_pk
# FIXME Removing the if checks makes things REALLY slow...
for version in old_item_versions: # put all the old versions in a list
print(version)
# if version.field_dict["event_id"] == int(self.new.pk):
compare = ModelComparison(old=version._object_version.object, **comparisonParams)
item_dict[version.object_id] = compare
@@ -179,6 +179,7 @@ class RIGSVersion(Version):
objects = RIGSVersionManager.as_manager()
# Gets the most recent previous version
@cached_property
def parent(self):
thisId = self.object_id