mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 05:22:16 +00:00
Add basic validation of item prerequisites
Currently throws the worlds most unhelpful error message...
This commit is contained in:
@@ -16,6 +16,13 @@ class QualificationForm(forms.ModelForm):
|
|||||||
self.fields['trainee'].initial = Profile.objects.get(pk=pk)
|
self.fields['trainee'].initial = Profile.objects.get(pk=pk)
|
||||||
self.fields['date'].widget.format = '%Y-%m-%d'
|
self.fields['date'].widget.format = '%Y-%m-%d'
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super().clean()
|
||||||
|
item = cleaned_data.get('item')
|
||||||
|
trainee = cleaned_data.get('trainee')
|
||||||
|
if not item.user_has_requirements(trainee):
|
||||||
|
self.add_error('item', 'Missing prerequisites')
|
||||||
|
|
||||||
def clean_date(self):
|
def clean_date(self):
|
||||||
date = self.cleaned_data['date']
|
date = self.cleaned_data['date']
|
||||||
if date > date.today():
|
if date > date.today():
|
||||||
|
|||||||
@@ -104,19 +104,19 @@ class Command(BaseCommand):
|
|||||||
obj, created = models.TrainingItem.objects.update_or_create(
|
obj, created = models.TrainingItem.objects.update_or_create(
|
||||||
pk=int(child.find('ID').text),
|
pk=int(child.find('ID').text),
|
||||||
reference_number=number,
|
reference_number=number,
|
||||||
name=name,
|
description=name,
|
||||||
category=category,
|
category=category,
|
||||||
active=active
|
active=active
|
||||||
)
|
)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
print("Training Item {}.{} {} has a duplicate reference number".format(category.reference_number, number, name))
|
print(f"Training Item {category.reference_number}.{number} {name} has a duplicate reference number")
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
tally[1] += 1
|
tally[1] += 1
|
||||||
else:
|
else:
|
||||||
tally[0] += 1
|
tally[0] += 1
|
||||||
|
|
||||||
print('Training Items - Updated: {}, Created: {}'.format(tally[0], tally[1]))
|
print(f'Training Items - Updated: {tally[0]}, Created: {tally[1]}')
|
||||||
|
|
||||||
def import_TrainingItemQualification(self):
|
def import_TrainingItemQualification(self):
|
||||||
tally = [0, 0, 0]
|
tally = [0, 0, 0]
|
||||||
@@ -129,9 +129,9 @@ class Command(BaseCommand):
|
|||||||
("Competency_Assessed", models.TrainingItemQualification.PASSED_OUT), ]
|
("Competency_Assessed", models.TrainingItemQualification.PASSED_OUT), ]
|
||||||
|
|
||||||
for (depth, depth_index) in depths:
|
for (depth, depth_index) in depths:
|
||||||
if child.find('{}_Date'.format(depth)) is not None:
|
if child.find(f'{depth}_Date') is not None:
|
||||||
if child.find('{}_Assessor_ID'.format(depth)) is None:
|
if child.find(f'{depth}_Assessor_ID') is None:
|
||||||
print("Training Record #{} had no supervisor. Assigning System User.".format(child.find('ID').text))
|
print(f"Training Record #{child.find('ID').text} had no supervisor. Assigning System User.")
|
||||||
supervisor = Profile.objects.get(first_name="God")
|
supervisor = Profile.objects.get(first_name="God")
|
||||||
continue
|
continue
|
||||||
supervisor = Profile.objects.get(pk=self.id_map[child.find('{}_Assessor_ID'.format(depth)).text])
|
supervisor = Profile.objects.get(pk=self.id_map[child.find('{}_Assessor_ID'.format(depth)).text])
|
||||||
|
|||||||
22
training/migrations/0005_auto_20220223_1535.py
Normal file
22
training/migrations/0005_auto_20220223_1535.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 3.2.12 on 2022-02-23 15:35
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('training', '0004_rename_name_trainingitem_description'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='trainingcategory',
|
||||||
|
options={'ordering': ['reference_number'], 'verbose_name_plural': 'Training Categories'},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='trainingitem',
|
||||||
|
name='prerequisites',
|
||||||
|
field=models.ManyToManyField(blank=True, to='training.TrainingItem'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -75,6 +75,7 @@ class TrainingCategory(models.Model):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'Training Categories'
|
verbose_name_plural = 'Training Categories'
|
||||||
|
ordering = ['reference_number']
|
||||||
|
|
||||||
|
|
||||||
class TrainingItemManager(QueryablePropertiesManager):
|
class TrainingItemManager(QueryablePropertiesManager):
|
||||||
@@ -92,6 +93,7 @@ class TrainingItem(models.Model):
|
|||||||
category = models.ForeignKey('TrainingCategory', related_name='items', on_delete=models.CASCADE)
|
category = models.ForeignKey('TrainingCategory', related_name='items', on_delete=models.CASCADE)
|
||||||
description = models.CharField(max_length=50)
|
description = models.CharField(max_length=50)
|
||||||
active = models.BooleanField(default=True)
|
active = models.BooleanField(default=True)
|
||||||
|
prerequisites = models.ManyToManyField('self', symmetrical=False, blank=True)
|
||||||
|
|
||||||
objects = TrainingItemManager()
|
objects = TrainingItemManager()
|
||||||
|
|
||||||
@@ -124,6 +126,13 @@ class TrainingItem(models.Model):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('item_list')
|
return reverse('item_list')
|
||||||
|
|
||||||
|
def has_prereqs(self):
|
||||||
|
return self.prerequisites.all().exists()
|
||||||
|
|
||||||
|
def user_has_requirements(self, user):
|
||||||
|
# Always true if there are no prerequisites, otherwise get a set of prerequsite IDs and check if they are a subset of the set of qualification IDs
|
||||||
|
return not self.has_prereqs() or set(self.prerequisites.values_list('pk', flat=True)).issubset(set(user.qualifications_obtained.values_list('item', flat=True)))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def user_has_qualification(item, user, depth):
|
def user_has_qualification(item, user, depth):
|
||||||
return user.qualifications_obtained.only('item', 'depth').filter(item=item, depth__gte=depth).exists()
|
return user.qualifications_obtained.only('item', 'depth').filter(item=item, depth__gte=depth).exists()
|
||||||
|
|||||||
@@ -13,11 +13,18 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
{% for item in category.items.all %}
|
{% for item in category.items.all %}
|
||||||
{% if item.active %}
|
<li class="list-group-item {% if not item.active%}text-warning{%endif%}">{{ item }}
|
||||||
<li class="list-group-item">{{ item }}</li>
|
{% if item.prerequisites.exists %}
|
||||||
{% elif request.user.is_superuser %}
|
<div class="ml-3 font-italic">
|
||||||
<li class="list-group-item text-warning">{{ item }}</li>
|
<p class="text-info mb-0">Prerequisites:</p>
|
||||||
|
<ul>
|
||||||
|
{% for p in item.prerequisites.all %}
|
||||||
|
<li>{{p}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user