mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-18 05:52:15 +00:00
Autofire of traininglevelqualification basically works
This commit is contained in:
@@ -16,13 +16,21 @@ class QualificationForm(forms.ModelForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pk = kwargs.pop('pk', None)
|
||||
super().__init__()
|
||||
super(QualificationForm, self).__init__(*args, **kwargs)
|
||||
self.fields['trainee'].initial = Profile.objects.get(pk=pk)
|
||||
self.fields['date'].initial = date.today()
|
||||
|
||||
def clean_date(self):
|
||||
date = self.cleaned_data['date']
|
||||
if date > date.today():
|
||||
raise ValidationError('Qualification date may not be in the future')
|
||||
raise forms.ValidationError('Qualification date may not be in the future')
|
||||
return date
|
||||
|
||||
def clean_supervisor(self):
|
||||
supervisor = self.cleaned_data['supervisor']
|
||||
if supervisor.pk == self.cleaned_data['trainee'].pk:
|
||||
raise forms.ValidationError('One may not supervise oneself...')
|
||||
return supervisor # TODO also confirm that the supervisor is a Supervisor
|
||||
|
||||
class RequirementForm(forms.ModelForm):
|
||||
depth = forms.ChoiceField(choices=models.TrainingItemQualification.CHOICES)
|
||||
@@ -33,5 +41,5 @@ class RequirementForm(forms.ModelForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pk = kwargs.pop('pk', None)
|
||||
super().__init__()
|
||||
super(RequirementForm, self).__init__(*args, **kwargs)
|
||||
self.fields['level'].initial = models.TrainingLevel.objects.get(pk=pk)
|
||||
|
||||
24
training/migrations/0003_auto_20210716_0150.py
Normal file
24
training/migrations/0003_auto_20210716_0150.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 3.1.5 on 2021-07-16 00:50
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('training', '0002_auto_20210706_0053'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='traininglevelqualification',
|
||||
name='confirmed_by',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='confirmer', to='training.trainee'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='traininglevelqualification',
|
||||
name='confirmed_on',
|
||||
field=models.DateTimeField(null=True),
|
||||
),
|
||||
]
|
||||
@@ -26,6 +26,9 @@ class TrainingCategory(models.Model):
|
||||
reference_number = models.CharField(max_length=3)
|
||||
name = models.CharField(max_length=50)
|
||||
|
||||
def __str__(self):
|
||||
return "{}. {}".format(self.reference_number, self.name)
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = 'Training Categories'
|
||||
|
||||
@@ -67,9 +70,9 @@ class TrainingItemQualification(models.Model):
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save()
|
||||
for level in TrainingLevel.models.all(): # Mm yes efficiency
|
||||
for level in TrainingLevel.objects.all(): # Mm yes efficiency
|
||||
if level.user_has_requirements(self.trainee):
|
||||
level_qualification = models.TrainingLevelQualification.create(trainee=self.trainee, level=level)
|
||||
level_qualification = TrainingLevelQualification.objects.create(trainee=self.trainee, level=level)
|
||||
|
||||
|
||||
# Levels
|
||||
@@ -118,8 +121,7 @@ class TrainingLevel(models.Model, RevisionMixin):
|
||||
return 0
|
||||
|
||||
def user_has_requirements(self, user):
|
||||
return all(TrainingItem.user_has_qualification(req.item, user, req.depth) for req in self.requirements.all())
|
||||
|
||||
return all(TrainingItem.user_has_qualification(req.item, user, req.depth) for req in self.requirements.all())
|
||||
|
||||
def __str__(self):
|
||||
if self.department is None: # 2TA
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
{% load static %}
|
||||
{% load widget_tweaks %}
|
||||
{% load button from filters %}
|
||||
|
||||
{% block css %}
|
||||
{{ block.super }}
|
||||
@@ -23,26 +24,26 @@
|
||||
{% if form.errors %}
|
||||
{% include 'form_errors.html' %}
|
||||
{% endif %}
|
||||
<form id="item-form" action="{{ form.action|default:request.path }}" method="post">{% csrf_token %}
|
||||
<form role="form" action="{{ form.action|default:request.path }}" method="POST">{% csrf_token %}
|
||||
{% render_field form.trainee|attr:'hidden' value=form.trainee.initial %}
|
||||
<div class="form-group form-row">
|
||||
<label for="item_id" class="col-sm-2 col-form-label">Item</label>
|
||||
<select name="item" id="item_id" class="form-control selectpicker custom-select col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}" required>
|
||||
<select name="item" id="item_id" class="form-control selectpicker custom-select col-sm-4" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}" required>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<label for="depth" class="col-sm-2 col-form-label">Depth</label>
|
||||
{% render_field form.depth|add_class:'form-control custom-select selectpicker col-sm' %}
|
||||
{% render_field form.depth|add_class:'form-control custom-select col-sm-4' %}
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<label for="selectpicker" class="col-sm-2 col-form-label">Supervisor</label>
|
||||
<label for="supervisor" class="col-sm-2 col-form-label">Supervisor</label>
|
||||
<select name="supervisor" id="supervisor_id" class="form-control selectpicker custom-select col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<label for="date" class="col-sm-2 col-form-label">Training Date</label>
|
||||
<div class="col-sm-10">
|
||||
{% render_field form.date|add_class:'form-control'|attr:'type="date"' %}
|
||||
{% render_field form.date|add_class:'form-control'|attr:'type="date"' value=form.date.initial %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
@@ -52,6 +53,8 @@
|
||||
id="notes" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary">
|
||||
<div class="col-sm-12 text-right pr-0"}>
|
||||
{% button 'submit' %}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="card-body">
|
||||
<p>{{ level.description|truncatewords:30 }}</p>
|
||||
<div class="progress mb-2">
|
||||
{% percentage_complete level request.user as completion %}
|
||||
{% percentage_complete level object as completion %}
|
||||
|
||||
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: 25%" aria-valuenow="{{completion}}" aria-valuemin="0" aria-valuemax="100">{{completion}}% complete</div>
|
||||
</div>
|
||||
@@ -61,19 +61,17 @@
|
||||
</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>
|
||||
<div class="card-columns">
|
||||
{% for category in categories %}
|
||||
<div class="card mb-3">
|
||||
<h3 class="card-header">{{ category.name }}</h3>
|
||||
<h3 class="card-header">{{ category }}</h3>
|
||||
<div class="list-group list-group-flush">
|
||||
{% for depth in depths %}
|
||||
<li class="list-group-item {% if depth.0 == 0 %}list-group-item-warning{%elif depth.0 == 1%}list-group-item-success{%else%}list-group-item-info{%endif%}">{{depth.1}}</li>
|
||||
{% for q in object.qualifications_obtained.all %}
|
||||
{% if q.depth == depth.0 and q.item.category == category %}
|
||||
<li class="list-group-item">{{q.item}} ({{q.date}})</li>
|
||||
{% 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>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
@@ -62,16 +62,16 @@ class AddQualification(generic.CreateView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(AddQualification, self).get_context_data(**kwargs)
|
||||
# context["page_title"] = "Edit {}'s Training Record".format(self.object)
|
||||
context["depths"] = models.TrainingItemQualification.CHOICES
|
||||
if is_ajax(self.request):
|
||||
context['override'] = "base_ajax.html"
|
||||
else:
|
||||
context['override'] = 'base_rigs.html' # TODO
|
||||
context['override'] = 'base_training.html'
|
||||
context['page_title'] = "Add Qualification for {}".format(models.Trainee.objects.get(pk=self.kwargs['pk']))
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('trainee_detail')
|
||||
return reverse_lazy('trainee_detail', kwargs={"pk": self.object.pk })
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super(AddQualification, self).get_form_kwargs()
|
||||
|
||||
Reference in New Issue
Block a user