paperwork: Add two stage definition/version selection in Certification admin

This commit is contained in:
Adam Goldsmith 2023-04-01 11:37:49 -04:00
parent 1e4fc52531
commit 3b61061e4c
5 changed files with 111 additions and 0 deletions

View File

@ -13,6 +13,7 @@ from .models import (
SpecialProgram,
Waiver,
)
from .forms import CertificationForm
from .certification_emails import all_certification_emails
@ -65,6 +66,7 @@ class CertificationDefinitionAdmin(admin.ModelAdmin):
@admin.register(Certification)
class CertificationAdmin(admin.ModelAdmin):
form = CertificationForm
search_fields = [
"name",
"certification_version__definition__certification_name",

View File

@ -0,0 +1,42 @@
from dal import autocomplete
from django.db.models.functions import Concat
from django.db.models import Q, Value, CharField
from .models import CertificationVersion
class CertificationVersionAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.has_perm("membershipworks.view_certification_version"):
return CertificationVersion.objects.none()
qs = CertificationVersion.objects.alias(
version_str=Concat(
"major",
Value("."),
"minor",
Value("."),
"patch",
output_field=CharField(),
),
)
certification_definition = self.forwarded.get("certification_definition", None)
if certification_definition:
qs = qs.filter(definition=certification_definition)
if self.q:
qs = qs.filter(
Q(version_str__istartswith=self.q)
| Q(prerelease__istartswith=self.q)
| Q(approval_date__istartswith=self.q)
)
return qs
def get_result_label(self, result: CertificationVersion) -> str:
return str(result.semantic_version())
def get_selected_result_label(self, result: CertificationVersion) -> str:
return str(result)

51
paperwork/forms.py Normal file
View File

@ -0,0 +1,51 @@
from dal import autocomplete
from django import forms
from django.core.exceptions import ValidationError
from .models import CertificationDefinition, Certification
class CertificationForm(forms.ModelForm):
certification_definition = forms.ModelChoiceField(
queryset=CertificationDefinition.objects.all()
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
instance = kwargs.get("instance")
if instance:
self.fields[
"certification_definition"
].initial = instance.certification_version.definition
def clean(self):
cleaned_data = super().clean()
certification_version = cleaned_data.get("certification_version")
certification_definition = cleaned_data.get("certification_definition")
if certification_version.definition != certification_definition:
raise ValidationError(
"Certification Version did not match Certification Definition!"
)
class Media:
js = ("paperwork/certification-form-clear-autocomplete.js",)
class Meta:
model = Certification
fields = [
"certification_definition",
"certification_version",
"name",
"member",
"certified_by",
"date",
"notes",
]
widgets = {
"certification_version": autocomplete.ModelSelect2(
url="paperwork:certification_version_autocomplete",
forward=["certification_definition"],
)
}

View File

@ -0,0 +1,10 @@
window.addEventListener('load', function() {
// Bind on certification_definition field change
django.jQuery(':input[name$=certification_definition]').on('change', function() {
// Get the field prefix, ie. if this comes from a formset form
var prefix = django.jQuery(this).getFormPrefix();
// Clear the autocomplete with the same prefix
django.jQuery(':input[name=' + prefix + 'certification_version]').val(null).trigger('change');
});
});

View File

@ -1,6 +1,7 @@
from django.urls import path
from . import views
from . import autocomplete_views
app_name = "paperwork"
@ -20,4 +21,9 @@ urlpatterns = [
views.certification_pdf,
name="certification_pdf",
),
path(
"certifications/version_autocomplete",
autocomplete_views.CertificationVersionAutocomplete.as_view(),
name="certification_version_autocomplete",
),
]