diff --git a/schoolapps/static/common/style.css b/schoolapps/static/common/style.css index 2e9d91a3dab402b21ab8401a1f4a76d5af44c0aa..b79d6c6de218d114e4d4c02710fa2701f501cd00 100644 --- a/schoolapps/static/common/style.css +++ b/schoolapps/static/common/style.css @@ -249,7 +249,7 @@ table.substitutions td, table.substitutions th { } .lesson-card a, .substitutions a { - color: black; + color: inherit; } /*.timetable-time {*/ @@ -312,10 +312,11 @@ table.substitutions td, table.substitutions th { /* Table*/ -table.striped > tbody > tr:nth-child(odd) { +table.striped > tbody > tr:nth-child(odd), table tr.striped { background-color: rgba(208, 208, 208, 0.5); } + /*+++++++*/ /* Print */ /*+++++++*/ diff --git a/schoolapps/static/css/paper.css b/schoolapps/static/css/paper.css new file mode 100644 index 0000000000000000000000000000000000000000..9e5b66db1a7f87dca6123920a4b03bb54e0270a6 --- /dev/null +++ b/schoolapps/static/css/paper.css @@ -0,0 +1,134 @@ +/* MIT © Tsutomu Kawamura */ +/* Edited by SchoolApps Team */ + +@page { + margin: 0 +} + +body { + margin: 0 +} + +.sheet { + margin: 0; + overflow: hidden; + position: relative; + box-sizing: border-box; + page-break-after: always; +} + +/** Paper sizes **/ +body.A3 .sheet { + width: 297mm; + height: 419mm +} + +body.A3.landscape .sheet { + width: 420mm; + height: 296mm +} + +body.A4 .sheet { + width: 210mm; + height: 296mm +} + +body.A4.landscape .sheet { + width: 297mm; + height: 209mm +} + +body.A5 .sheet { + width: 148mm; + height: 209mm +} + +body.A5.landscape .sheet { + width: 210mm; + height: 147mm +} + +body.letter .sheet { + width: 216mm; + height: 279mm +} + +body.letter.landscape .sheet { + width: 280mm; + height: 215mm +} + +body.legal .sheet { + width: 216mm; + height: 356mm +} + +body.legal.landscape .sheet { + width: 357mm; + height: 215mm +} + +.sheet.infinitive { + height: auto !important; +} + +/** Padding area **/ +.sheet.padding-10mm { + padding: 10mm +} + +.sheet.padding-15mm { + padding: 15mm +} + +.sheet.padding-20mm { + padding: 20mm +} + +.sheet.padding-25mm { + padding: 25mm +} + +/** For screen preview **/ +@media screen { + body { + background: #e0e0e0 + } + + .sheet { + background: white; + box-shadow: 0 .5mm 2mm rgba(0, 0, 0, .3); + margin: 5mm auto; + } +} + +/** Fix for Chrome issue #273306 **/ +@media print { + body.A3.landscape { + width: 420mm + } + + body.A3, body.A4.landscape { + width: 297mm + } + + body.A4, body.A5.landscape { + width: 210mm + } + + body.A5 { + width: 148mm + } + + body.letter, body.legal { + width: 216mm + } + + body.letter.landscape { + width: 280mm + } + + body.legal.landscape { + width: 357mm + } +} diff --git a/schoolapps/templates/partials/paper/footer.html b/schoolapps/templates/partials/paper/footer.html new file mode 100755 index 0000000000000000000000000000000000000000..1dc3a88b8281509e4eb8d18212b4513d32189845 --- /dev/null +++ b/schoolapps/templates/partials/paper/footer.html @@ -0,0 +1,32 @@ +{% load static %} +<footer> + <div class="left"> + Katharineum zu Lübeck + </div> + + <div class="right"> + Umsetzung: {{ COPYRIGHT_SHORT }} + </div> +</footer> +</div> +</td> +</tr> +</tbody> +<tfoot> +<tr class="no-border"> + <td> + <div class="footer-space"> </div> + </td> +</tr> +</tfoot> +</table> +</main> + +<!----------------> +<!-- JavaScript (jquery v. 3.4.1.slim)--> +<!----------------> +<script src="{% static 'common/manup.min.js' %}"></script> +<script src="{% static 'js/materialize.min.js' %}"></script> +<script src="{% static 'common/helper.js' %}"></script> +</body> +</html> diff --git a/schoolapps/templates/partials/paper/header.html b/schoolapps/templates/partials/paper/header.html new file mode 100755 index 0000000000000000000000000000000000000000..4b92397ddc86886771e811b1ec34ad72e2c776e2 --- /dev/null +++ b/schoolapps/templates/partials/paper/header.html @@ -0,0 +1,146 @@ +{% load static %} +{% load pwa %} +{% load url_name %} + +<!DOCTYPE html> +<html lang="de"> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <meta name="description" content="Selbst programmierte Anwendungen für den Schullaltag am Katharineum zu Lübeck"> + <title>SchoolApps – Katharineum zu Lübeck</title> + + <!---------> + <!-- CSS --> + <!---------> + <link href="{% static 'css/materialdesignicons-webfont/material-icons.css' %}" rel="stylesheet"> + <link rel="stylesheet" type="text/css" href="{% static 'css/materialize.min.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'css/paper.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'common/style.css' %}"> + <script src="{% static 'js/jquery/jquery-3.3.1.min.js' %}"></script> + + + <style> + body { + font-family: Cabin, sans-serif; + } + + @page { + size: A4; + padding: 30mm; + } + + header { + display: block; + width: 190mm; + } + + + #print-header { + display: block !important; + border-bottom: 1px solid; + margin-bottom: 0; + height: 22mm; + background: white; + } + + header, main, footer { + margin: 0; + } + + #print-header .col.right-align { + padding: 15px; + } + + .sheet { + padding: 10mm; + } + + + .header-space, .footer-space { + height: 0; + } + + .print-layout-table td { + padding: 0; + } + + .print-layout-table .no-border { + border: 0; + } + + + footer { + margin-top: 5mm; + text-align: center; + width: 190mm; + + } + + header .row, header .col { + padding: 0 !important; + margin: 0 !important; + } + + @media print { + .header-space { + height: 32mm; + } + + .footer-space { + height: 20mm + } + + header, footer { + height: 22mm; + } + + header { + position: fixed; + top: 10mm; + } + + footer { + position: fixed; + bottom: 0; + } + + @page { + @bottom-center { + content: "Seite " counter(page) " von " counter(pages); + } + } + } + </style> +</head> +<body class="A4"> + + +<div style="margin-top: -10mm;"></div> +<main class="sheet infinitive"> + <table class="print-layout-table"> + <thead> + <tr class="no-border"> + <td> + <div class="header-space"> </div> + </td> + </tr> + </thead> + <tbody> + <tr class="no-border"> + <td> + <div class="content"> + <header> + <div id="print-header" class="row"> + <div class="col s6 logo"> + <img src="{% static 'common/logo.png' %}"> + </div> + <div class="col s6 right-align"> + <h5>SchoolApps</h5> + {% now "j. F Y H:i" %} + </div> + </div> + </header> + + diff --git a/schoolapps/timetable/templates/timetable/hintsinsubprint.html b/schoolapps/timetable/templates/timetable/hintsinsubprint.html new file mode 100644 index 0000000000000000000000000000000000000000..d39760fac1dd3843c4f286c252c8088193443c91 --- /dev/null +++ b/schoolapps/timetable/templates/timetable/hintsinsubprint.html @@ -0,0 +1,16 @@ +{% load martortags %} +{% if c.hints %} + {% for hint in c.hints %} + <div class="alert primary"> + <div> + <strong> + {{ hint.classes_formatted }}{% if hint.teachers and hint.classes.all %}, Lehrkräfte{% endif %}: + </strong> + + <i class="material-icons left">announcement</i> + + {{ hint.text|safe_markdown }} + </div> + </div> + {% endfor %} +{% endif %} diff --git a/schoolapps/timetable/templates/timetable/substitutionprint.html b/schoolapps/timetable/templates/timetable/substitutionprint.html new file mode 100755 index 0000000000000000000000000000000000000000..39363d68a5b46e52b00d3099716362fb8aa9784e --- /dev/null +++ b/schoolapps/timetable/templates/timetable/substitutionprint.html @@ -0,0 +1,110 @@ +{% load common %} +{% include 'partials/paper/header.html' %} + +<script type="text/javascript"> + var dest = "/timetable/substitutions/"; +</script> + +<style> + table.substitutions td, table.substitutions th { + padding: 0 2px; + } + + span.badge.new { + font-size: 0.9rem; + line-height: 20px; + height: 20px; + margin: 2px; + letter-spacing: 0.3pt; + } +</style> + +{% for c in days %} + <h4>Vertretungen {{ c.date|date:"l, j. F Y" }}</h4> + + + {% include "timetable/hintsinsubprint.html" %} + + <div style="margin-bottom: 20px"> + {% if c.header_info.is_box_needed %} + {% for row in c.header_info.rows %} + <div class="row no-margin"> + <div class="col s3 no-padding"> + <strong>{{ row.0 }}</strong> + </div> + <div class="col s9 no-padding"> + {{ row.1 }} + </div> + </div> + {% endfor %} + {% endif %} + </div> + + <table class="substitutions"> + <thead> + <tr> + <th><i class="material-icons">people</i></th> + <th><i class="material-icons">access_time</i></th> + <th>Lehrer</th> + <th>Fach</th> + <th>Raum</th> + <th>Hinweis</th> + <th></th> + </tr> + </thead> + <tbody> + {% if not c.sub_table %} + <td colspan="7"> + <p class="flow-text center"> + Keine Vertretungen vorhanden + </p> + </td> + {% endif %} + + {% set color_background = 1 %} + {% set last_classes = "" %} + + {% for sub in c.sub_table %} + + {# Color groups of classes in grey/white #} + {% if last_classes != sub.classes %} + {% if color_background %}{% set color_background = 0 %} + {% else %}{% set color_background = 1 %} + {% endif %} + {% endif %} + {% set last_classes = sub.classes %} + + + <tr class="{{ sub.color }}-text {% if color_background %}striped{% endif %}"> + <td> + {{ sub.classes }} + </td> + <td> + <strong> + {{ sub.lesson }} + </strong> + </td> + <td> + {% include "timetable/subs/teacher.html" %} + </td> + <td> + {% include "timetable/subs/subject.html" %} + </td> + <td> + {% include "timetable/subs/room.html" %} + </td> + <td> + {% if sub.badge %} + <span class="badge new green">{{ sub.badge }}</span> + {% endif %} + <em>{{ sub.text|default:"" }}</em> + </td> + </tr> + {% endfor %} + </tbody> + </table> + +{% endfor %} + + +{% include 'partials/paper/footer.html' %} diff --git a/schoolapps/timetable/urls.py b/schoolapps/timetable/urls.py index 704099725ade72bee9057fd52bec6f6de3126cfd..610ffb897ded39e7aa399ba6f326d15b3fe51881 100755 --- a/schoolapps/timetable/urls.py +++ b/schoolapps/timetable/urls.py @@ -23,6 +23,10 @@ try: path('substitutions/', views.substitutions, name='timetable_substitutions'), path('substitutions/<int:year>/<int:month>/<int:day>/', views.substitutions, name='timetable_substitutions_date'), + path('substitutions/<int:year>/<int:month>/<int:day>/print/', views.substitutions_print, + name='timetable_substitutions_date_print'), + path('substitutions/print/', views.substitutions_print, + name='timetable_substitutions_print'), path('aktuell.pdf', views.sub_pdf, name="timetable_substitutions_pdf"), path('<str:plan_date>-aktuell.pdf', views.sub_pdf, name="timetable_substitutions_pdf_date") ] @@ -47,5 +51,10 @@ except (Terms.DoesNotExist, Schoolyear.DoesNotExist, ProgrammingError, Operation path('substitutions/', fallback_view.fallback, name='timetable_substitutions'), path('substitutions/<int:year>/<int:month>/<int:day>/', fallback_view.fallback, name='timetable_substitutions_date'), - path('aktuell.pdf', fallback_view.fallback, name="timetable_substitutions_pdf") + path('substitutions/<int:year>/<int:month>/<int:day>/<str:print_view>/', fallback_view.fallback, + name='timetable_substitutions_date_print'), + path('substitutions/<str:print_view>/', fallback_view.fallback, + name='timetable_substitutions_print'), + path('aktuell.pdf', fallback_view.fallback, name="timetable_substitutions_pdf"), + path('<str:plan_date>-aktuell.pdf', fallback_view.fallback, name="timetable_substitutions_pdf_date") ] diff --git a/schoolapps/timetable/views.py b/schoolapps/timetable/views.py index c716d63dc3f0ed51e93e273ffc3c5d501b6d0c57..16d7ef2d35a7e1fdca49e601813cd3f05dcfdd86 100755 --- a/schoolapps/timetable/views.py +++ b/schoolapps/timetable/views.py @@ -328,19 +328,7 @@ def sub_pdf(request, plan_date=None): return FileResponse(file, content_type="application/pdf") -@login_required -@permission_required("timetable.show_plan") -@cache_page(SUBS_VIEW_CACHE.expiration_time) -def substitutions(request, year=None, month=None, day=None): - """Show substitutions in a classic view""" - - date, time = find_out_what_is_today(year, month, day) - - # Get next weekday if it is a weekend - next_weekday = get_next_weekday_with_time(date, time) - if next_weekday != date: - return redirect("timetable_substitutions_date", next_weekday.year, next_weekday.month, next_weekday.day) - +def get_subs_context(request, date): # Get subs and generate table events = get_all_events_by_date(date) subs = get_substitutions_by_date(date) @@ -354,7 +342,7 @@ def substitutions(request, year=None, month=None, day=None): header_info = get_header_information(subs, date, events) hints = list(get_all_hints_by_time_period(date, date)) - context = { + return { "subs": subs, "sub_table": sub_table, "date": date, @@ -363,7 +351,51 @@ def substitutions(request, year=None, month=None, day=None): "hints": hints, } - return render(request, 'timetable/substitution.html', context) + +@login_required +@permission_required("timetable.show_plan") +@cache_page(SUBS_VIEW_CACHE.expiration_time) +def substitutions(request, year=None, month=None, day=None): + """Show substitutions in a classic view""" + + date, time = find_out_what_is_today(year, month, day) + + # Get next weekday if it is a weekend + next_weekday = get_next_weekday_with_time(date, time) + if next_weekday != date: + return redirect("timetable_substitutions_date", next_weekday.year, next_weekday.month, next_weekday.day) + + context = get_subs_context(request, date) + + template_name = 'timetable/substitution.html' + + return render(request, template_name, context) + + +@login_required +@permission_required("timetable.show_plan") +@cache_page(SUBS_VIEW_CACHE.expiration_time) +def substitutions_print(request, year=None, month=None, day=None): + """Show substitutions in a classic view""" + + date, time = find_out_what_is_today(year, month, day) + + # Get next weekday if it is a weekend + next_weekday = get_next_weekday_with_time(date, time) + if next_weekday != date: + return redirect("timetable_substitutions_date_print", next_weekday.year, next_weekday.month, next_weekday.day) + + second_date = get_next_weekday(date + datetime.timedelta(days=1)) + context1 = get_subs_context(request, date) + context2 = get_subs_context(request, second_date) + + context = { + "days": [context1, context2] + } + + template_name = 'timetable/substitutionprint.html' + + return render(request, template_name, context) ###################