Compare commits

...

2 Commits

Author SHA1 Message Date
900002bf71 Modalise training item qualification edit
Also fixed some stuff
2022-03-06 18:30:03 +00:00
2869c9fcc3 FIX(T): 500 error editing training item qualifications
For the second time with this piece of functionality...how did that ever work?
2022-03-06 17:30:11 +00:00
7 changed files with 64 additions and 19 deletions

View File

@@ -3,20 +3,20 @@ import datetime
from django import forms from django import forms
from training import models from training import models
from RIGS.models import Profile
def validate_user_can_train_in(supervisor, item): def validate_user_can_train_in(self, supervisor, item):
if item.category.training_level: if item.category.training_level:
if not supervisor.level_qualifications.filter(level=item.category.training_level): if not supervisor.level_qualifications.filter(level=item.category.training_level):
raise forms.ValidationError('Selected supervising person is missing requisite training level to train in this department') self.add_error('supervisor', 'Selected supervising person is missing requisite training level to train in this department')
elif not supervisor.is_supervisor: elif not supervisor.is_supervisor:
raise forms.ValidationError('Selected supervisor must actually *be* a supervisor...') self.add_error('supervisor', 'Selected supervisor must actually *be* a supervisor...')
class QualificationForm(forms.ModelForm): class QualificationForm(forms.ModelForm):
related_models = { related_models = {
'item': models.TrainingItem 'item': models.TrainingItem,
'supervisor': models.Trainee
} }
class Meta: class Meta:
@@ -27,29 +27,35 @@ class QualificationForm(forms.ModelForm):
cleaned_data = super().clean() cleaned_data = super().clean()
item = cleaned_data.get('item') item = cleaned_data.get('item')
trainee = cleaned_data.get('trainee') trainee = cleaned_data.get('trainee')
supervisor = cleaned_data.get('supervisor')
if supervisor:
validate_user_can_train_in(self, supervisor, item)
if not item.user_has_requirements(trainee): if not item.user_has_requirements(trainee):
self.add_error('item', 'Missing prerequisites') self.add_error('item', 'Missing prerequisites')
def clean_date(self): def clean_date(self):
date = self.cleaned_data['date'] date = self.cleaned_data.get('date')
if date > date.today(): if date > date.today():
raise forms.ValidationError('Qualification date may not be in the future') raise forms.ValidationError('Qualification date may not be in the future')
return date return date
def clean_supervisor(self): def clean_supervisor(self):
supervisor = self.cleaned_data['supervisor'] supervisor = self.cleaned_data.get('supervisor')
item = self.cleaned_data['item'] if supervisor.pk == self.cleaned_data.get('trainee').pk:
if supervisor.pk == self.cleaned_data['trainee'].pk:
raise forms.ValidationError('One may not supervise oneself...') raise forms.ValidationError('One may not supervise oneself...')
validate_user_can_train_in(supervisor, item)
return supervisor return supervisor
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['date'].widget.format = '%Y-%m-%d'
class AddQualificationForm(QualificationForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
pk = kwargs.pop('pk', None) pk = kwargs.pop('pk', None)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if pk: if pk:
self.fields['trainee'].initial = Profile.objects.get(pk=pk) self.fields['trainee'].initial = models.Trainee.objects.get(pk=pk)
self.fields['date'].widget.format = '%Y-%m-%d'
class RequirementForm(forms.ModelForm): class RequirementForm(forms.ModelForm):
@@ -91,5 +97,5 @@ class SessionLogForm(forms.Form):
raise forms.ValidationError('One may not supervise oneself...') raise forms.ValidationError('One may not supervise oneself...')
for depth in models.TrainingItemQualification.CHOICES: for depth in models.TrainingItemQualification.CHOICES:
for item in self.cleaned_data.get('items_{depth.0}', []): for item in self.cleaned_data.get('items_{depth.0}', []):
validate_user_can_train_in(supervisor, item) validate_user_can_train_in(self, supervisor, item)
return supervisor return supervisor

View File

@@ -198,7 +198,7 @@ class TrainingItemQualification(models.Model, RevisionMixin):
return "info" return "info"
def get_absolute_url(self): def get_absolute_url(self):
return reverse('trainee_item_detail', kwargs={'pk': self.trainee.pk}) return reverse('edit_qualification', kwargs={'pk': self.pk})
class Meta: class Meta:
unique_together = ["trainee", "item", "depth"] unique_together = ["trainee", "item", "depth"]

View File

@@ -2,7 +2,7 @@
<label for="item_id" class="col col-form-label">Item</label> <label for="item_id" class="col col-form-label">Item</label>
<select name="item" id="item_id" class="selectpicker col-sm-10 px-0" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}?fields=display_id,description&filters=active" required> <select name="item" id="item_id" class="selectpicker col-sm-10 px-0" data-live-search="true" data-sourceurl="{% url 'api_secure' model='training_item' %}?fields=display_id,description&filters=active" required>
{% if item %} {% if item %}
<option value="{{form.item.pk}}" selected>{{item}}</option> <option value="{{form.item.value}}" selected>{{item}}</option>
{% endif %} {% endif %}
</select> </select>
</div> </div>

View File

@@ -1,6 +1,6 @@
<label for="supervisor" 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="selectpicker col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required> <select name="supervisor" id="supervisor_id" class="selectpicker col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required>
{% if supervisor %} {% if supervisor %}
<option value="{{form.supervisor.value}}" selected="selected">{{ supervisor }}</option> <option value="{{form.supervisor.value}}" selected>{{ supervisor }}</option>
{% endif %} {% endif %}
</select> </select>

View File

@@ -5,6 +5,41 @@
{% load linkornone from filters %} {% load linkornone from filters %}
{% load button from filters %} {% load button from filters %}
{% load colour_from_depth from tags %} {% load colour_from_depth from tags %}
{% load static %}
{% block css %}
<link rel="stylesheet" type="text/css" href="{% static 'css/selects.css' %}"/>
{% endblock %}
{% block preload_js %}
<script src="{% static 'js/selects.js' %}"></script>
{% endblock %}
{% block js %}
<script src="{% static 'js/tooltip.js' %}"></script>
<script>
$('document').ready(function(){
$('#edit').click(function (e) {
e.preventDefault();
var url = $(this).attr("href");
$.ajax({
url: url,
success: function(){
$link = $(this);
// Anti modal inception
if ($link.parents('#modal').length === 0) {
modaltarget = $link.data('target');
modalobject = "";
$('#modal').load(url, function (e) {
$('#modal').modal();
});
}
}
});
});
});
</script>
{% endblock %}
{% block content %} {% block content %}
<p class="text-muted text-right">Search by supervisor name, item name or item ID</p>{% include 'partials/list_search.html' %} <p class="text-muted text-right">Search by supervisor name, item name or item ID</p>{% include 'partials/list_search.html' %}
@@ -33,7 +68,7 @@
<td><a href="{{ object.supervisor.get_absolute_url}}">{{ object.supervisor }}</a></td> <td><a href="{{ object.supervisor.get_absolute_url}}">{{ object.supervisor }}</a></td>
<td>{{ object.notes }}</td> <td>{{ object.notes }}</td>
{% if request.user.is_supervisor or perms.training.change_trainingitemqualification %} {% if request.user.is_supervisor or perms.training.change_trainingitemqualification %}
<td>{% button 'edit' 'edit_qualification' object.pk %}</td> <td>{% button 'edit' 'edit_qualification' object.pk id="edit" %}</td>
{% endif %} {% endif %}
</tr> </tr>
{% empty %} {% empty %}

View File

@@ -17,6 +17,7 @@ def test_add_qualification(admin_client, trainee, admin_user, training_item):
assertFormError(response, 'form', 'date', 'Qualification date may not be in the future') assertFormError(response, 'form', 'date', 'Qualification date may not be in the future')
assertFormError(response, 'form', 'supervisor', 'One may not supervise oneself...') assertFormError(response, 'form', 'supervisor', 'One may not supervise oneself...')
response = admin_client.post(url, {'date': date, 'trainee': trainee.pk, 'supervisor': admin_user.pk, 'item': training_item.pk}) response = admin_client.post(url, {'date': date, 'trainee': trainee.pk, 'supervisor': admin_user.pk, 'item': training_item.pk})
print(response.content)
assertFormError(response, 'form', 'supervisor', 'Selected supervisor must actually *be* a supervisor...') assertFormError(response, 'form', 'supervisor', 'Selected supervisor must actually *be* a supervisor...')

View File

@@ -103,7 +103,7 @@ class TraineeList(generic.ListView):
class AddQualification(generic.CreateView, ModalURLMixin): class AddQualification(generic.CreateView, ModalURLMixin):
template_name = "edit_training_record.html" template_name = "edit_training_record.html"
model = models.TrainingItemQualification model = models.TrainingItemQualification
form_class = forms.QualificationForm form_class = forms.AddQualificationForm
def form_valid(self, form, *args, **kwargs): def form_valid(self, form, *args, **kwargs):
reversion.add_to_revision(form.cleaned_data['trainee']) reversion.add_to_revision(form.cleaned_data['trainee'])
@@ -130,7 +130,7 @@ class AddQualification(generic.CreateView, ModalURLMixin):
return kwargs return kwargs
class EditQualification(generic.UpdateView): class EditQualification(generic.UpdateView, ModalURLMixin):
template_name = 'edit_training_record.html' template_name = 'edit_training_record.html'
model = models.TrainingItemQualification model = models.TrainingItemQualification
form_class = forms.QualificationForm form_class = forms.QualificationForm
@@ -148,6 +148,9 @@ class EditQualification(generic.UpdateView):
reversion.add_to_revision(form.cleaned_data['trainee']) reversion.add_to_revision(form.cleaned_data['trainee'])
return super().form_valid(form, *args, **kwargs) return super().form_valid(form, *args, **kwargs)
def get_success_url(self):
return self.get_close_url('edit_qualification', 'trainee_item_detail')
class AddLevelRequirement(generic.CreateView, ModalURLMixin): class AddLevelRequirement(generic.CreateView, ModalURLMixin):
template_name = "add_level_requirement.html" template_name = "add_level_requirement.html"