mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 21:42:14 +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 RIGS import models
|
||||
from training import models as tmodels
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ class Trainee(Profile):
|
||||
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:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_records_of_depth(self, depth):
|
||||
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):
|
||||
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:
|
||||
unique_together = ["trainee", "item", "depth"]
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
{% load user_has_qualification from tags %}
|
||||
{% load percentage_complete from tags %}
|
||||
{% load user_level_if_present from tags %}
|
||||
{% load colour_from_depth from tags %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-sm-12 text-right">
|
||||
@@ -12,7 +13,14 @@
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<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">
|
||||
{% for level in levels %}
|
||||
<div class="card my-3">
|
||||
@@ -47,20 +55,20 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="card-footer text-right">
|
||||
{% user_level_if_present object level as level_qualification %}
|
||||
{% if level_qualification %}
|
||||
{% if level_qualification.confirmed_by is None %}
|
||||
{% 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>
|
||||
{% else %}
|
||||
<button class="btn btn-warning text-right" disabled>Awaiting Confirmation</button>
|
||||
<button class="btn btn-warning" disabled>Awaiting Confirmation</button>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<button class="btn btn-success active">Confirmed <small>by {{ level_qualification.confirmed_by }}</small></button>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<button class="btn btn-danger text-right" disabled>Incomplete</button>
|
||||
<button class="btn btn-danger" disabled>Incomplete</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,8 +76,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h2 class="col-12">Training Items</h2><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>
|
||||
<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/>
|
||||
<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">
|
||||
{% for category in categories %}
|
||||
<div class="card mb-3">
|
||||
@@ -77,7 +85,7 @@
|
||||
<div class="list-group list-group-flush">
|
||||
{% for q in object.qualifications_obtained.all %}
|
||||
{% 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 %}
|
||||
{% endfor %}
|
||||
</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>
|
||||
<th scope="col">Name<a href="?{% orderby request 'orderBy' 'name' %}"><span class="caret"></span></a></th>
|
||||
<th>Supervisor?</th>
|
||||
<th>-</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for object in object_list %}
|
||||
<tr id="row_item">
|
||||
<th scope="row" class="align-middle" id="cell_name">{{ object.name }}</th>
|
||||
<td>No</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>
|
||||
<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 {% 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>
|
||||
<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>
|
||||
{% empty %}
|
||||
<tr class="table-warning">
|
||||
|
||||
@@ -23,3 +23,6 @@ def user_level_if_present(user, level):
|
||||
def percentage_complete(level, 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/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>/item_record', views.TraineeItemDetail.as_view(), name='trainee_item_detail'),
|
||||
]
|
||||
|
||||
@@ -37,6 +37,19 @@ class TraineeDetail(views.ProfileDetail):
|
||||
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):
|
||||
model = models.Trainee
|
||||
template_name = 'trainee_list.html'
|
||||
|
||||
Reference in New Issue
Block a user