diff --git a/RIGS/templatetags/filters.py b/RIGS/templatetags/filters.py
index 07263d67..078ea459 100644
--- a/RIGS/templatetags/filters.py
+++ b/RIGS/templatetags/filters.py
@@ -10,6 +10,7 @@ from django.utils.safestring import SafeData, mark_safe
from django.utils.text import normalize_newlines
from RIGS import models
+from training import models as tmodels
register = template.Library()
@@ -190,6 +191,17 @@ def linkornone(target, namespace=None, autoescape=True):
return "None"
+@register.simple_tag
+def user_has_qualification(user, item, depth):
+ if tmodels.TrainingItem.user_has_qualification(item, user, depth) is not None:
+ return mark_safe("")
+ else:
+ return mark_safe("")
+
+@register.simple_tag
+def percentage_complete(level, user):
+ return level.percentage_complete(user)
+
@register.inclusion_tag('partials/button.html')
def button(type, url=None, pk=None, clazz="", icon=None, text="", id=None, style=None):
if type == 'edit':
diff --git a/training/forms.py b/training/forms.py
index c7e3028f..7fab1883 100644
--- a/training/forms.py
+++ b/training/forms.py
@@ -1,30 +1,37 @@
from django import forms
+from datetime import date
+
from training import models
from RIGS.models import Profile
class SessionLogForm(forms.Form):
pass
-# TODO Validation that dates cannot be in the future
+
class QualificationForm(forms.ModelForm):
class Meta:
model = models.TrainingItemQualification
fields = '__all__'
- # exclude = ['trainee']
def __init__(self, *args, **kwargs):
pk = kwargs.pop('pk', None)
- super(QualificationForm, self).__init__(*args, **kwargs)
+ super().__init__()
self.fields['trainee'].initial = Profile.objects.get(pk=pk)
+ def clean_date(self):
+ date = self.cleaned_data['date']
+ if date > date.today():
+ raise ValidationError('Qualification date may not be in the future')
class RequirementForm(forms.ModelForm):
+ depth = forms.ChoiceField(choices=models.TrainingItemQualification.CHOICES)
+
class Meta:
model = models.TrainingLevelRequirement
fields = '__all__'
def __init__(self, *args, **kwargs):
pk = kwargs.pop('pk', None)
- super(RequirementForm, self).__init__(*args, **kwargs)
+ super().__init__()
self.fields['level'].initial = models.TrainingLevel.objects.get(pk=pk)
diff --git a/training/models.py b/training/models.py
index ba49f91c..a63cab16 100644
--- a/training/models.py
+++ b/training/models.py
@@ -27,6 +27,11 @@ class TrainingItem(models.Model):
def __str__(self):
return "{}.{} {}".format(self.category.reference_number, self.reference_number, self.name)
+ def user_has_qualification(self, user, depth):
+ for q in user.qualifications_obtained.all():
+ if q.item == self and q.depth > depth:
+ return True
+
class TrainingItemQualification(models.Model):
STARTED = 0
@@ -86,12 +91,21 @@ class TrainingLevel(models.Model, RevisionMixin):
def passed_out_requirements(self):
return self.get_requirements_of_depth(TrainingItemQualification.PASSED_OUT)
+ def percentage_complete(self, user): # FIXME
+ needed_qualifications = self.requirements.all()
+ relavant_qualifications = [x for x in user.qualifications_obtained.all() if x in self.requirements.all()]
+ if len(needed_qualifications) > 0:
+ return round(len(relavant_qualifications) / len(needed_qualifications))
+ else:
+ return 0
+
def __str__(self):
if self.department is None: # 2TA
return self.get_level_display()
else:
return "{} {}".format(self.get_department_display(), self.get_level_display())
+
class TrainingLevelRequirement(models.Model):
level = models.ForeignKey('TrainingLevel', related_name='requirements', on_delete=models.RESTRICT)
item = models.ForeignKey('TrainingItem', on_delete=models.RESTRICT)
diff --git a/training/templates/base_training.html b/training/templates/base_training.html
new file mode 100644
index 00000000..f57bf1fa
--- /dev/null
+++ b/training/templates/base_training.html
@@ -0,0 +1 @@
+{% extends 'base_rigs.html' %}
diff --git a/training/templates/edit_training_level.html b/training/templates/edit_training_level.html
index 8fcf2e4c..4f529493 100644
--- a/training/templates/edit_training_level.html
+++ b/training/templates/edit_training_level.html
@@ -1,4 +1,4 @@
-{% extends 'base_rigs.html' %}
+{% extends 'base_training.html' %}
{% load static %}
{% load widget_tweaks %}
@@ -32,7 +32,7 @@
- {% render_field form.depth|add_class:'form-control custom-select selectpicker col-sm'|attr:'required' %}
+ {% render_field form.depth|add_class:'form-control custom-select col-sm'|attr:'required' %}
diff --git a/training/templates/level_detail.html b/training/templates/level_detail.html
new file mode 100644
index 00000000..ec5b5a00
--- /dev/null
+++ b/training/templates/level_detail.html
@@ -0,0 +1,44 @@
+{% extends 'base_training.html' %}
+
+{% block content %}
+{% if edit or True %}
+
+{% endif %}
+
+
+
+
{{ object.description }}
+
+
+
+
+
Users with this level...{% lorem %}
+
+
+
+
+
+
+
+
+ | Training Started |
+ Training Complete |
+ Passed Out |
+
+
+
+
+ {% for req in object.started_requirements %}- {{ req.item }}
{% endfor %} |
+ {% for req in object.complete_requirements %}- {{ req.item }}
{% endfor %} |
+ {% for req in object.passed_out_requirements %}- {{ req.item }}
{% endfor %} |
+
+
+
+
+
+{% include 'partials/last_edited.html' with target="traininglevel_history" %}
+{% endblock %}
diff --git a/training/templates/trainee_detail.html b/training/templates/trainee_detail.html
index 652cebdc..5dee7551 100644
--- a/training/templates/trainee_detail.html
+++ b/training/templates/trainee_detail.html
@@ -1,9 +1,12 @@
{% extends 'base_rigs.html' %}
+{% load user_has_qualification from filters %}
+{% load percentage_complete from filters %}
+
{% block content %}
-
+
@@ -11,13 +14,16 @@
{% for level in levels %}
-
+
+
{{ level.description|truncatewords:30 }}
-
25% complete
+ {% percentage_complete level request.user as completion %}
+
+
{{completion}}% complete
-
{{ level.description }}
-