mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-25 01:12:16 +00:00
Add a view for a trainee's item record
This commit is contained in:
@@ -10,7 +10,6 @@ from django.utils.safestring import SafeData, mark_safe
|
|||||||
from django.utils.text import normalize_newlines
|
from django.utils.text import normalize_newlines
|
||||||
|
|
||||||
from RIGS import models
|
from RIGS import models
|
||||||
from training import models as tmodels
|
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class Trainee(Profile):
|
|||||||
for level_qualification in self.levels.select_related('level').all():
|
for level_qualification in self.levels.select_related('level').all():
|
||||||
if level_qualification.confirmed_on is not None and level_qualification.level.level >= TrainingLevel.SUPERVISOR:
|
if level_qualification.confirmed_on is not None and level_qualification.level.level >= TrainingLevel.SUPERVISOR:
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_records_of_depth(self, depth):
|
def get_records_of_depth(self, depth):
|
||||||
return self.qualifications_obtained.filter(depth=depth).select_related('item', 'trainee', 'supervisor')
|
return self.qualifications_obtained.filter(depth=depth).select_related('item', 'trainee', 'supervisor')
|
||||||
@@ -75,6 +76,15 @@ class TrainingItemQualification(models.Model):
|
|||||||
if level.user_has_requirements(self.trainee):
|
if level.user_has_requirements(self.trainee):
|
||||||
level_qualification = TrainingLevelQualification.objects.get_or_create(trainee=self.trainee, level=level)
|
level_qualification = TrainingLevelQualification.objects.get_or_create(trainee=self.trainee, level=level)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_colour_from_depth(obj, depth):
|
||||||
|
if depth == 0:
|
||||||
|
return "warning"
|
||||||
|
elif depth == 1:
|
||||||
|
return "success"
|
||||||
|
else:
|
||||||
|
return "info"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ["trainee", "item", "depth"]
|
unique_together = ["trainee", "item", "depth"]
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
{% load user_has_qualification from tags %}
|
{% load user_has_qualification from tags %}
|
||||||
{% load percentage_complete from tags %}
|
{% load percentage_complete from tags %}
|
||||||
{% load user_level_if_present from tags %}
|
{% load user_level_if_present from tags %}
|
||||||
|
{% load colour_from_depth from tags %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-sm-12 text-right">
|
<div class="col-sm-12 text-right">
|
||||||
@@ -12,7 +13,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<h2 class="col-12">Training Levels</h2>
|
<h2 class="col-12">Training Levels</h2>
|
||||||
<div class="alert alert-info" role="alert">Technical Assistant is conferred automatically when the item requirements are met. Technician status is also automatic, but notification of status should be made at the next general meeting, at which point 'approval' should be granted on the system. Supervisor status is <em>not automatic</em> and until signed off at a general meeting, does not count.<sup>Correct as of 7th July 2021, check the Training Policy.</sup></div>
|
<div class="alert alert-info" role="alert">
|
||||||
|
<ul>
|
||||||
|
<li>Technical Assistant is conferred automatically when the item requirements are met.</li>
|
||||||
|
<li>Technician status is also automatic, but notification of status should be made at the next general meeting, at which point 'approval' should be granted on the system.</li>
|
||||||
|
<li>Supervisor status is <em>not automatic</em> and until signed off at a general meeting, does not count.</li>
|
||||||
|
</ul>
|
||||||
|
<sup>Correct as of 7th July 2021, check the Training Policy.</sup>
|
||||||
|
</div>
|
||||||
<div class="card-columns">
|
<div class="card-columns">
|
||||||
{% for level in levels %}
|
{% for level in levels %}
|
||||||
<div class="card my-3">
|
<div class="card my-3">
|
||||||
@@ -47,20 +55,20 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer text-right">
|
||||||
{% user_level_if_present object level as level_qualification %}
|
{% user_level_if_present object level as level_qualification %}
|
||||||
{% if level_qualification %}
|
{% if level_qualification %}
|
||||||
{% if level_qualification.confirmed_by is None %}
|
{% if level_qualification.confirmed_by is None %}
|
||||||
{% if request.user.is_supervisor or request.user.is_superuser %}
|
{% if request.user.is_supervisor or request.user.is_superuser %}
|
||||||
<a class="btn btn-info" href="{% url 'confirm_level' object.pk level.pk %}">Confirm</a>
|
<a class="btn btn-info" href="{% url 'confirm_level' object.pk level.pk %}">Confirm</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-warning text-right" disabled>Awaiting Confirmation</button>
|
<button class="btn btn-warning" disabled>Awaiting Confirmation</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-success active">Confirmed <small>by {{ level_qualification.confirmed_by }}</small></button>
|
<button class="btn btn-success active">Confirmed <small>by {{ level_qualification.confirmed_by }}</small></button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-danger text-right" disabled>Incomplete</button>
|
<button class="btn btn-danger" disabled>Incomplete</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,8 +76,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2 class="col-12">Training Items</h2><br>
|
<h2 class="col-10">Training Items</h2><a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info col-2"><span class="fas fa-info-circle"></span> View Detailed Record</a><br/>
|
||||||
<h3 class="col-12">Key: <span class="badge badge-warning">Training Started</span> <span class="badge badge-success">Training Complete</span> <span class="badge badge-info">Passed Out</span></h3>
|
<div class="alert alert-info" role="alert"><h3 class="col-12">Key: <span class="badge badge-warning">Training Started</span> <span class="badge badge-success">Training Complete</span> <span class="badge badge-info">Passed Out</span></h3></div>
|
||||||
<div class="card-deck">
|
<div class="card-deck">
|
||||||
{% for category in categories %}
|
{% for category in categories %}
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
@@ -77,7 +85,7 @@
|
|||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
{% for q in object.qualifications_obtained.all %}
|
{% for q in object.qualifications_obtained.all %}
|
||||||
{% if q.item.category == category %}
|
{% if q.item.category == category %}
|
||||||
<li class="list-group-item {% if q.depth == 0 %}list-group-item-warning{%elif q.depth == 1%}list-group-item-success{%else%}list-group-item-info{%endif%}">{{q.item}} ({{q.date}})</li>
|
<li class="list-group-item list-group-item-{% colour_from_depth q.depth %}">{{q.item}} ({{q.date}})</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
42
training/templates/trainee_item_list.html
Normal file
42
training/templates/trainee_item_list.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{% extends 'base_training.html' %}
|
||||||
|
|
||||||
|
{% load url_replace from filters %}
|
||||||
|
{% load paginator from filters %}
|
||||||
|
{% load linkornone from filters %}
|
||||||
|
{% load button from filters %}
|
||||||
|
{% load colour_from_depth from tags %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Training Item</th>
|
||||||
|
<th>Depth</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Supervisor</th>
|
||||||
|
<th>Notes</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for object in object_list %}
|
||||||
|
<tr id="row_item">
|
||||||
|
<th scope="row" class="align-middle" id="cell_name">{{ object.item }}</th>
|
||||||
|
<td class="table-{% colour_from_depth object.depth %}">{{ object.get_depth_display }}</td>
|
||||||
|
<td>{{ object.date }}</td>
|
||||||
|
<td>{{ object.supervisor }}</td>
|
||||||
|
<td>{{ object.notes }}</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr class="table-warning">
|
||||||
|
<td colspan="6" class="text-center">Nothing found</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -15,15 +15,18 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="col">Name<a href="?{% orderby request 'orderBy' 'name' %}"><span class="caret"></span></a></th>
|
<th scope="col">Name<a href="?{% orderby request 'orderBy' 'name' %}"><span class="caret"></span></a></th>
|
||||||
<th>Supervisor?</th>
|
<th>Supervisor?</th>
|
||||||
<th>-</th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<tr id="row_item">
|
<tr id="row_item">
|
||||||
<th scope="row" class="align-middle" id="cell_name">{{ object.name }}</th>
|
<th scope="row" class="align-middle" id="cell_name">{{ object.name }} {% if request.user.pk == object.pk %}<span class="fas fa-user text-success"></span>{%endif%}</th>
|
||||||
<td>No</td>
|
<td {% if object.is_supervisor %}class="table-success"{%endif%}>{{ object.is_supervisor|yesno|title }}</td>
|
||||||
<td><a class="btn btn-info" href="{% url 'trainee_detail' pk=object.pk %}"><span class="fas fa-eye"></span> View Training Record</a></td>
|
<td>
|
||||||
|
<a class="btn btn-info" href="{% url 'trainee_detail' pk=object.pk %}"><span class="fas fa-eye"></span> View Training Record</a>
|
||||||
|
<a href="{% url 'trainee_item_detail' pk=object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr class="table-warning">
|
<tr class="table-warning">
|
||||||
|
|||||||
@@ -23,3 +23,6 @@ def user_level_if_present(user, level):
|
|||||||
def percentage_complete(level, user):
|
def percentage_complete(level, user):
|
||||||
return level.percentage_complete(user)
|
return level.percentage_complete(user)
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def colour_from_depth(depth):
|
||||||
|
return models.TrainingItemQualification.get_colour_from_depth(depth)
|
||||||
|
|||||||
@@ -20,4 +20,5 @@ urlpatterns = [
|
|||||||
path('level/<int:pk>/add_requirement/', views.AddLevelRequirement.as_view(), name='add_requirement'),
|
path('level/<int:pk>/add_requirement/', views.AddLevelRequirement.as_view(), name='add_requirement'),
|
||||||
path('level/remove_requirement/<int:pk>/', views.RemoveRequirement.as_view(), name='remove_requirement'),
|
path('level/remove_requirement/<int:pk>/', views.RemoveRequirement.as_view(), name='remove_requirement'),
|
||||||
path('trainee/<int:pk>/level/<int:level_pk>/confirm', views.ConfirmLevel.as_view(), name='confirm_level'),
|
path('trainee/<int:pk>/level/<int:level_pk>/confirm', views.ConfirmLevel.as_view(), name='confirm_level'),
|
||||||
|
path('trainee/<int:pk>/item_record', views.TraineeItemDetail.as_view(), name='trainee_item_detail'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -37,6 +37,19 @@ class TraineeDetail(views.ProfileDetail):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class TraineeItemDetail(generic.ListView):
|
||||||
|
model = models.TrainingItemQualification
|
||||||
|
template_name = 'trainee_item_list.html'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return models.Trainee.objects.get(pk=self.kwargs['pk']).qualifications_obtained.all()
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["page_title"] = "Detailed Training Record for {}".format(models.Trainee.objects.get(pk=self.kwargs['pk']))
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class TraineeList(generic.ListView):
|
class TraineeList(generic.ListView):
|
||||||
model = models.Trainee
|
model = models.Trainee
|
||||||
template_name = 'trainee_list.html'
|
template_name = 'trainee_list.html'
|
||||||
|
|||||||
Reference in New Issue
Block a user