244 lines
9.4 KiB
Python
244 lines
9.4 KiB
Python
from django.shortcuts import render, get_object_or_404
|
|
from django.contrib.auth.decorators import login_required, user_passes_test
|
|
from django.http import JsonResponse
|
|
from django.core.serializers.json import DjangoJSONEncoder
|
|
import json
|
|
from .models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage
|
|
from abschnitte.utils import render_textabschnitte
|
|
|
|
from datetime import date
|
|
import parsedatetime
|
|
|
|
calendar=parsedatetime.Calendar()
|
|
|
|
|
|
def standard_list(request):
|
|
dokumente = Dokument.objects.select_related('dokumententyp').prefetch_related('vorgaben__thema').all()
|
|
return render(request, 'standards/standard_list.html',
|
|
{'dokumente': dokumente}
|
|
)
|
|
|
|
|
|
def standard_detail(request, nummer,check_date=""):
|
|
standard = get_object_or_404(Dokument, nummer=nummer)
|
|
|
|
if check_date:
|
|
check_date = calendar.parseDT(check_date)[0].date()
|
|
standard.history = True
|
|
else:
|
|
check_date = date.today()
|
|
standard.history = False
|
|
standard.check_date=check_date
|
|
vorgaben = list(standard.vorgaben.order_by("thema","nummer")
|
|
.select_related("thema","dokument")
|
|
.prefetch_related("relevanz", "referenzen",
|
|
"vorgabekurztext_set__abschnitttyp",
|
|
"vorgabelangtext_set__abschnitttyp")) # convert queryset to list so we can attach attributes
|
|
|
|
standard.geltungsbereich_html = render_textabschnitte(standard.geltungsbereich_set.order_by("order").select_related("abschnitttyp"))
|
|
standard.einleitung_html=render_textabschnitte(standard.einleitung_set.order_by("order"))
|
|
for vorgabe in vorgaben:
|
|
# Prepare Kurztext HTML
|
|
vorgabe.kurztext_html = render_textabschnitte(vorgabe.vorgabekurztext_set.order_by("order").select_related("abschnitttyp","abschnitt"))
|
|
vorgabe.langtext_html = render_textabschnitte(vorgabe.vorgabelangtext_set.order_by("order").select_related("abschnitttyp","abschnitt"))
|
|
vorgabe.long_status=vorgabe.get_status(check_date,verbose=True)
|
|
vorgabe.relevanzset=list(vorgabe.relevanz.all())
|
|
|
|
referenz_items = []
|
|
for r in vorgabe.referenzen.all():
|
|
referenz_items.append(r.Path())
|
|
vorgabe.referenzpfade = referenz_items
|
|
|
|
return render(request, 'standards/standard_detail.html', {
|
|
'standard': standard,
|
|
'vorgaben': vorgaben,
|
|
})
|
|
|
|
|
|
def standard_checkliste(request, nummer):
|
|
standard = get_object_or_404(Dokument, nummer=nummer)
|
|
vorgaben = list(standard.vorgaben.all())
|
|
return render(request, 'standards/standard_checkliste.html', {
|
|
'standard': standard,
|
|
'vorgaben': vorgaben,
|
|
})
|
|
|
|
|
|
def is_staff_user(user):
|
|
return user.is_staff
|
|
|
|
@login_required
|
|
@user_passes_test(is_staff_user)
|
|
def incomplete_vorgaben(request):
|
|
"""
|
|
Show table of all Vorgaben with completeness status:
|
|
- References (✓ or ✗)
|
|
- Stichworte (✓ or ✗)
|
|
- Text (✓ or ✗)
|
|
- Checklistenfragen (✓ or ✗)
|
|
"""
|
|
# Get all active Vorgaben
|
|
all_vorgaben = Vorgabe.objects.all().select_related('dokument', 'thema').prefetch_related(
|
|
'referenzen', 'stichworte', 'checklistenfragen', 'vorgabekurztext_set', 'vorgabelangtext_set'
|
|
)
|
|
|
|
# Build table data
|
|
vorgaben_data = []
|
|
for vorgabe in all_vorgaben:
|
|
has_references = vorgabe.referenzen.exists()
|
|
has_stichworte = vorgabe.stichworte.exists()
|
|
has_kurztext = vorgabe.vorgabekurztext_set.exists()
|
|
has_langtext = vorgabe.vorgabelangtext_set.exists()
|
|
has_text = has_kurztext or has_langtext
|
|
has_checklistenfragen = vorgabe.checklistenfragen.exists()
|
|
|
|
# Only include Vorgaben that are incomplete in at least one way
|
|
if not (has_references and has_stichworte and has_text and has_checklistenfragen):
|
|
vorgaben_data.append({
|
|
'vorgabe': vorgabe,
|
|
'has_references': has_references,
|
|
'has_stichworte': has_stichworte,
|
|
'has_text': has_text,
|
|
'has_checklistenfragen': has_checklistenfragen,
|
|
'is_complete': has_references and has_stichworte and has_text and has_checklistenfragen
|
|
})
|
|
|
|
# Sort by document number and Vorgabe number
|
|
vorgaben_data.sort(key=lambda x: (x['vorgabe'].dokument.nummer, x['vorgabe'].Vorgabennummer()))
|
|
|
|
return render(request, 'standards/incomplete_vorgaben.html', {
|
|
'vorgaben_data': vorgaben_data,
|
|
})
|
|
|
|
|
|
def standard_json(request, nummer):
|
|
"""
|
|
Export a single Dokument as JSON
|
|
"""
|
|
# Get the document with all related data
|
|
dokument = get_object_or_404(
|
|
Dokument.objects.prefetch_related(
|
|
'autoren', 'pruefende', 'vorgaben__thema',
|
|
'vorgaben__referenzen', 'vorgaben__stichworte',
|
|
'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set',
|
|
'vorgaben__vorgabelangtext_set', 'geltungsbereich_set',
|
|
'einleitung_set', 'changelog__autoren'
|
|
),
|
|
nummer=nummer
|
|
)
|
|
|
|
# Build document structure (reusing logic from export_json command)
|
|
doc_data = {
|
|
"Typ": dokument.dokumententyp.name if dokument.dokumententyp else "",
|
|
"Nummer": dokument.nummer,
|
|
"Name": dokument.name,
|
|
"Autoren": [autor.name for autor in dokument.autoren.all()],
|
|
"Pruefende": [pruefender.name for pruefender in dokument.pruefende.all()],
|
|
"Gueltigkeit": {
|
|
"Von": dokument.gueltigkeit_von.strftime("%Y-%m-%d") if dokument.gueltigkeit_von else "",
|
|
"Bis": dokument.gueltigkeit_bis.strftime("%Y-%m-%d") if dokument.gueltigkeit_bis else None
|
|
},
|
|
"SignaturCSO": dokument.signatur_cso,
|
|
"Geltungsbereich": {},
|
|
"Einleitung": {},
|
|
"Ziel": "",
|
|
"Grundlagen": "",
|
|
"Changelog": [],
|
|
"Anhänge": dokument.anhaenge,
|
|
"Verantwortlich": "Information Security Management BIT",
|
|
"Klassifizierung": None,
|
|
"Glossar": {},
|
|
"Vorgaben": []
|
|
}
|
|
|
|
# Process Geltungsbereich sections
|
|
geltungsbereich_sections = []
|
|
for gb in dokument.geltungsbereich_set.all().order_by('order'):
|
|
geltungsbereich_sections.append({
|
|
"typ": gb.abschnitttyp.abschnitttyp if gb.abschnitttyp else "text",
|
|
"inhalt": gb.inhalt
|
|
})
|
|
|
|
if geltungsbereich_sections:
|
|
doc_data["Geltungsbereich"] = {
|
|
"Abschnitt": geltungsbereich_sections
|
|
}
|
|
|
|
# Process Einleitung sections
|
|
einleitung_sections = []
|
|
for ei in dokument.einleitung_set.all().order_by('order'):
|
|
einleitung_sections.append({
|
|
"typ": ei.abschnitttyp.abschnitttyp if ei.abschnitttyp else "text",
|
|
"inhalt": ei.inhalt
|
|
})
|
|
|
|
if einleitung_sections:
|
|
doc_data["Einleitung"] = {
|
|
"Abschnitt": einleitung_sections
|
|
}
|
|
|
|
# Process Changelog entries
|
|
changelog_entries = []
|
|
for cl in dokument.changelog.all().order_by('-datum'):
|
|
changelog_entries.append({
|
|
"Datum": cl.datum.strftime("%Y-%m-%d"),
|
|
"Autoren": [autor.name for autor in cl.autoren.all()],
|
|
"Aenderung": cl.aenderung
|
|
})
|
|
|
|
doc_data["Changelog"] = changelog_entries
|
|
|
|
# Process Vorgaben for this document
|
|
vorgaben = dokument.vorgaben.all().order_by('order')
|
|
|
|
for vorgabe in vorgaben:
|
|
# Get Kurztext and Langtext sections
|
|
kurztext_sections = []
|
|
for kt in vorgabe.vorgabekurztext_set.all().order_by('order'):
|
|
kurztext_sections.append({
|
|
"typ": kt.abschnitttyp.abschnitttyp if kt.abschnitttyp else "text",
|
|
"inhalt": kt.inhalt
|
|
})
|
|
|
|
langtext_sections = []
|
|
for lt in vorgabe.vorgabelangtext_set.all().order_by('order'):
|
|
langtext_sections.append({
|
|
"typ": lt.abschnitttyp.abschnitttyp if lt.abschnitttyp else "text",
|
|
"inhalt": lt.inhalt
|
|
})
|
|
|
|
# Build text structures following Langtext pattern
|
|
kurztext = {
|
|
"Abschnitt": kurztext_sections if kurztext_sections else []
|
|
} if kurztext_sections else {}
|
|
langtext = {
|
|
"Abschnitt": langtext_sections if langtext_sections else []
|
|
} if langtext_sections else {}
|
|
|
|
# Get references and keywords
|
|
referenzen = [f"{ref.name_nummer}: {ref.name_text}" if ref.name_text else ref.name_nummer for ref in vorgabe.referenzen.all()]
|
|
stichworte = [stw.stichwort for stw in vorgabe.stichworte.all()]
|
|
|
|
# Get checklist questions
|
|
checklistenfragen = [cf.frage for cf in vorgabe.checklistenfragen.all()]
|
|
|
|
vorgabe_data = {
|
|
"Nummer": str(vorgabe.nummer),
|
|
"Titel": vorgabe.titel,
|
|
"Thema": vorgabe.thema.name if vorgabe.thema else "",
|
|
"Kurztext": kurztext,
|
|
"Langtext": langtext,
|
|
"Referenz": referenzen,
|
|
"Gueltigkeit": {
|
|
"Von": vorgabe.gueltigkeit_von.strftime("%Y-%m-%d") if vorgabe.gueltigkeit_von else "",
|
|
"Bis": vorgabe.gueltigkeit_bis.strftime("%Y-%m-%d") if vorgabe.gueltigkeit_bis else None
|
|
},
|
|
"Checklistenfragen": checklistenfragen,
|
|
"Stichworte": stichworte
|
|
}
|
|
|
|
doc_data["Vorgaben"].append(vorgabe_data)
|
|
|
|
# Return JSON response
|
|
return JsonResponse(doc_data, json_dumps_params={'indent': 2, 'ensure_ascii': False}, encoder=DjangoJSONEncoder)
|