diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/azube/__init__.py b/azube/__init__.py old mode 100644 new mode 100755 diff --git a/azube/asgi.py b/azube/asgi.py old mode 100644 new mode 100755 diff --git a/azube/settings.py b/azube/settings.py old mode 100644 new mode 100755 diff --git a/azube/urls.py b/azube/urls.py old mode 100644 new mode 100755 diff --git a/azube/wsgi.py b/azube/wsgi.py old mode 100644 new mode 100755 diff --git a/core/__init__.py b/core/__init__.py old mode 100644 new mode 100755 diff --git a/core/admin.py b/core/admin.py old mode 100644 new mode 100755 diff --git a/core/apps.py b/core/apps.py old mode 100644 new mode 100755 diff --git a/core/azure_auth.py b/core/azure_auth.py old mode 100644 new mode 100755 index 2dee84e..3797d8a --- a/core/azure_auth.py +++ b/core/azure_auth.py @@ -1,17 +1,8 @@ -import datetime import json import base64 from core.models import Berichtsheft -from core.reports import DailyReport, WeeklyReport, choose_report_kind -import core.util -from enum import Enum - - -class Roles(Enum): - TRAINEE = "trainee" - MANAGER = "manager" - ADMIN = "admin" +from core.report_templates import ReportTemplates class AzureUser: @@ -42,32 +33,8 @@ class AzureUser: self.id = "anon" def reports(self): - return Berichtsheft.objects.filter(user=self.id).order_by("-year", "-week") + return Berichtsheft.objects.filter(user=self.id) - def get_report_kind(self): + def get_report_template(self): # TODO : Implement - return "weekly" - - def get_report_kind_form(self, request=None, files=None): - return choose_report_kind(self.get_report_kind(), request, files) - - def latest_report(self): - return self.reports().order_by("-year", "-week").first() - - def late_reports(self) -> int: - year_now, week_now, _ = datetime.datetime.today().isocalendar() - count = 0 - latest = self.latest_report() - - new_year, new_week = (latest.year, latest.week) - - while week_now != new_week or (week_now == new_week and year_now != new_year): - count += 1 - new_year, new_week = core.util.next_date(new_year, new_week) - - return count - - @property - def role(self) -> Roles: - # TODO : Implement - return Roles.TRAINEE + return ReportTemplates.get_template("weekly") diff --git a/core/doc_gen.py b/core/doc_gen.py old mode 100644 new mode 100755 index 7999cf8..e6b3040 --- a/core/doc_gen.py +++ b/core/doc_gen.py @@ -1,35 +1,12 @@ import json -from weasyprint import HTML, CSS -from io import BytesIO -from pdf2image import convert_from_bytes -from PIL import Image -from django.conf import settings -from django.template.loader import render_to_string -from .models import Berichtsheft -from io import BytesIO -def gen_doc_html(report: Berichtsheft): - return render_to_string(f"report_template/{report.kind}.html", report.vars()) +def gen_doc(template: str, vars: dict) -> str: + definition = json.loads(open(f"{template}.json").read()) + content = open(f"{template}.html").read() + for var in definition["vars"]: + var_r = var["name"].upper() + content = content.replace(f"[[{var_r}]]", vars[var["name"]]) -def gen_doc_pdf(report: Berichtsheft): - main_content = gen_doc_html(report) - - pdf_buffer = BytesIO() - HTML( - string=main_content, - ).write_pdf(pdf_buffer, stylesheets=[CSS(string="@page { size: A4; margin: 1cm }")]) - pdf_buffer.seek(0) - return pdf_buffer - - -def gen_doc_png(report: Berichtsheft): - pdf_buffer = gen_doc_pdf(report) - pages = convert_from_bytes(pdf_buffer.getvalue(), 300) - - for page in pages: - img_byte_array = BytesIO() - page.save(img_byte_array, format="PNG") - img_byte_array.seek(0) - return img_byte_array + return content diff --git a/core/forms.py b/core/forms.py new file mode 100755 index 0000000..be9c917 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,5 @@ +def extract_post_values(post, vars) -> dict: + res = {} + for var in vars: + res[var["name"]] = post.get(var["name"], "") + return res diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py old mode 100644 new mode 100755 index 7be4550..eaacbb1 --- a/core/migrations/0001_initial.py +++ b/core/migrations/0001_initial.py @@ -6,6 +6,7 @@ import django.db.models.deletion class Migration(migrations.Migration): + initial = True dependencies = [ diff --git a/core/migrations/0002_alter_berichtsheft_id.py b/core/migrations/0002_alter_berichtsheft_id.py old mode 100644 new mode 100755 index 2ccae28..21edbf1 --- a/core/migrations/0002_alter_berichtsheft_id.py +++ b/core/migrations/0002_alter_berichtsheft_id.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): + dependencies = [ ("core", "0001_initial"), ] diff --git a/core/migrations/0003_group_azureuser_alter_berichtsheft_user.py b/core/migrations/0003_group_azureuser_alter_berichtsheft_user.py old mode 100644 new mode 100755 index 8cc8a8e..6050d9c --- a/core/migrations/0003_group_azureuser_alter_berichtsheft_user.py +++ b/core/migrations/0003_group_azureuser_alter_berichtsheft_user.py @@ -8,6 +8,7 @@ import django.utils.timezone class Migration(migrations.Migration): + dependencies = [ ("auth", "0012_alter_user_first_name_max_length"), ("core", "0002_alter_berichtsheft_id"), diff --git a/core/migrations/0004_remove_berichtsheft_approved_by.py b/core/migrations/0004_remove_berichtsheft_approved_by.py old mode 100644 new mode 100755 index 78b4b3f..aa1f29b --- a/core/migrations/0004_remove_berichtsheft_approved_by.py +++ b/core/migrations/0004_remove_berichtsheft_approved_by.py @@ -4,6 +4,7 @@ from django.db import migrations class Migration(migrations.Migration): + dependencies = [ ("core", "0003_group_azureuser_alter_berichtsheft_user"), ] diff --git a/core/migrations/0005_user_alter_berichtsheft_user_delete_azureuser.py b/core/migrations/0005_user_alter_berichtsheft_user_delete_azureuser.py old mode 100644 new mode 100755 index f52a13b..cf368b3 --- a/core/migrations/0005_user_alter_berichtsheft_user_delete_azureuser.py +++ b/core/migrations/0005_user_alter_berichtsheft_user_delete_azureuser.py @@ -7,6 +7,7 @@ import django.utils.timezone class Migration(migrations.Migration): + dependencies = [ ("auth", "0012_alter_user_first_name_max_length"), ("core", "0004_remove_berichtsheft_approved_by"), diff --git a/core/migrations/0006_berichtsheft_num.py b/core/migrations/0006_berichtsheft_num.py old mode 100644 new mode 100755 index 4ab5e4d..985fc22 --- a/core/migrations/0006_berichtsheft_num.py +++ b/core/migrations/0006_berichtsheft_num.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): + dependencies = [ ("core", "0005_user_alter_berichtsheft_user_delete_azureuser"), ] diff --git a/core/migrations/0007_approval.py b/core/migrations/0007_approval.py deleted file mode 100644 index 1cb35ba..0000000 --- a/core/migrations/0007_approval.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 4.2.16 on 2024-12-03 12:41 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0006_berichtsheft_num"), - ] - - operations = [ - migrations.CreateModel( - name="Approval", - fields=[ - ("id", models.AutoField(primary_key=True, serialize=False)), - ("user", models.TextField()), - ( - "report", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="report", - to="core.berichtsheft", - ), - ), - ], - ), - ] diff --git a/core/migrations/0008_berichtsheft_needs_rewrite.py b/core/migrations/0008_berichtsheft_needs_rewrite.py deleted file mode 100644 index a67dc54..0000000 --- a/core/migrations/0008_berichtsheft_needs_rewrite.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.16 on 2024-12-03 12:44 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0007_approval"), - ] - - operations = [ - migrations.AddField( - model_name="berichtsheft", - name="needs_rewrite", - field=models.BooleanField(default=False), - ), - ] diff --git a/core/migrations/0009_berichtsheft_kind.py b/core/migrations/0009_berichtsheft_kind.py deleted file mode 100644 index 016887d..0000000 --- a/core/migrations/0009_berichtsheft_kind.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 4.2.16 on 2024-12-03 14:24 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0008_berichtsheft_needs_rewrite"), - ] - - operations = [ - migrations.AddField( - model_name="berichtsheft", - name="kind", - field=models.CharField( - choices=[("weekly", "Weekly"), ("daily", "Daily")], - default="weekly", - max_length=20, - ), - ), - ] diff --git a/core/migrations/0010_berichtsheft_department.py b/core/migrations/0010_berichtsheft_department.py deleted file mode 100644 index 57c931f..0000000 --- a/core/migrations/0010_berichtsheft_department.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.16 on 2024-12-03 15:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0009_berichtsheft_kind"), - ] - - operations = [ - migrations.AddField( - model_name="berichtsheft", - name="department", - field=models.CharField(default="", max_length=160), - ), - ] diff --git a/core/migrations/0011_berichtsheftdraft.py b/core/migrations/0011_berichtsheftdraft.py deleted file mode 100644 index 9f73ecf..0000000 --- a/core/migrations/0011_berichtsheftdraft.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.2.17 on 2024-12-05 10:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0010_berichtsheft_department"), - ] - - operations = [ - migrations.CreateModel( - name="BerichtsheftDraft", - fields=[ - ("user", models.TextField(primary_key=True, serialize=False)), - ("department", models.CharField(default="", max_length=160)), - ("content", models.JSONField()), - ], - ), - ] diff --git a/core/migrations/0012_berichtsheft_image.py b/core/migrations/0012_berichtsheft_image.py deleted file mode 100644 index b6e5aed..0000000 --- a/core/migrations/0012_berichtsheft_image.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.17 on 2024-12-06 09:38 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0011_berichtsheftdraft"), - ] - - operations = [ - migrations.AddField( - model_name="berichtsheft", - name="image", - field=models.BinaryField(blank=True, null=True), - ), - ] diff --git a/core/migrations/__init__.py b/core/migrations/__init__.py old mode 100644 new mode 100755 diff --git a/core/models.py b/core/models.py old mode 100644 new mode 100755 index 96df7f8..8a57865 --- a/core/models.py +++ b/core/models.py @@ -1,8 +1,6 @@ from django.db import models from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import Group as BuiltinGroup -from .util import get_week_range -import base64 class User(AbstractUser): @@ -23,66 +21,22 @@ class Group(BuiltinGroup): proxy = True -class ReportKind(models.TextChoices): - WEEKLY = "weekly" - DAILY = "daily" - - class Berichtsheft(models.Model): id = models.AutoField(primary_key=True) user = models.TextField() - kind = models.CharField( - max_length=20, choices=ReportKind.choices, default=ReportKind.WEEKLY - ) num = models.PositiveBigIntegerField(default=0) year = models.PositiveIntegerField() week = models.PositiveSmallIntegerField() - department = models.CharField(max_length=160, default="") content = models.JSONField() - needs_rewrite = models.BooleanField(default=False) created = models.DateTimeField(auto_now_add=True) - image = models.BinaryField(null=True, blank=True) def __str__(self): return f"Berichtsheft: {self.user}, Year: {self.year}, Week: {self.week}" - @property - def is_approved(self): - approvals = Approval.objects.filter(report=self.id) - return len(approvals) >= 2 - def vars(self): - start_date, end_date = get_week_range(self.year, self.week) - - vars = { - "user": self.user, - "kind": self.kind, - "num": self.num, - "year": self.year, - "week": self.week, - "department": self.department, - "start_date": start_date, - "end_date": end_date, - "image": base64.b64encode(self.image).decode("utf-8") - if self.image is not None - else None, - } - - for key, val in self.content.items(): - vars[key] = val - - return vars - - -class Approval(models.Model): +class Approval: id = models.AutoField(primary_key=True) user = models.TextField() report = models.ForeignKey( Berichtsheft, on_delete=models.CASCADE, related_name="report" ) - - -class BerichtsheftDraft(models.Model): - user = models.TextField(primary_key=True) - department = models.CharField(max_length=160, default="") - content = models.JSONField() diff --git a/core/report_templates.py b/core/report_templates.py new file mode 100755 index 0000000..a5f2073 --- /dev/null +++ b/core/report_templates.py @@ -0,0 +1,29 @@ +class ReportTemplates: + report_global = { + "vars": [ + {"name": "name", "display_name": "Name"}, + {"name": "num_doc", "display_name": "Berichtsheft Nummer"}, + {"name": "year", "display_name": "Jahr"}, + {"name": "week", "display_name": "Kalenderwoche"}, + {"name": "start_date", "display_name": "Von"}, + {"name": "end_date", "display_name": "bis"}, + {"name": "department", "display_name": "Abteilung"}, + ] + } + + def get_template(id) -> dict: + match id: + case "weekly": + weekly = { + "vars": [ + { + "name": "company_text", + "display_name": "Betriebliche Tätigkeiten", + }, + {"name": "week_topic", "display_name": "Thema der Woche"}, + {"name": "school_text", "display_name": "Berufsschule"}, + ] + } + + weekly["vars"].extend(ReportTemplates.report_global["vars"]) + return weekly diff --git a/core/reports.py b/core/reports.py deleted file mode 100644 index fa637af..0000000 --- a/core/reports.py +++ /dev/null @@ -1,196 +0,0 @@ -from django import forms - -from core.styles import label_span, STYLE - - -class WeeklyReport(forms.Form): - department = forms.CharField( - label=label_span("Abteilung"), - max_length=150, - widget=forms.TextInput( - attrs={ - "placeholder": "Abteilung", - "class": STYLE["text-input"], - } - ), - ) - company_text = forms.CharField( - label=label_span("Betriebliche Tätigkeiten"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Betriebliche Tätigkeiten", - } - ), - ) - week_topic = forms.CharField( - label=label_span("Thema der Woche"), - max_length=600, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 10, - "placeholder": "Thema der Woche", - } - ), - ) - school_text = forms.CharField( - label=label_span("Berufsschule"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Berufsschule", - } - ), - ) - img = forms.ImageField( - label=label_span("Bild"), - required=False, - widget=forms.ClearableFileInput( - attrs={ - "class": "block w-full p-2 text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400", - "accept": "image/*", - } - ), - ) - - @property - def display_names(self): - return { - "department": self.fields["department"].label, - "company_text": self.fields["company_text"].label, - "week_topic": self.fields["week_topic"].label, - "school_text": self.fields["school_text"].label, - } - - def content_values(self) -> dict: - if self.is_valid(): - return { - "company_text": self.cleaned_data["company_text"], - "week_topic": self.cleaned_data["week_topic"], - "school_text": self.cleaned_data["school_text"], - } - - -class DailyReport(forms.Form): - department = forms.CharField( - label=label_span("Abteilung"), - max_length=150, - widget=forms.TextInput( - attrs={ - "placeholder": "Abteilung", - "class": STYLE["text-input"], - } - ), - ) - week_topic = forms.CharField( - label=label_span("Thema der Woche"), - max_length=600, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Thema der Woche", - } - ), - ) - monday_text = forms.CharField( - label=label_span("Montag"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Montag", - } - ), - ) - tuesday_text = forms.CharField( - label=label_span("Dienstag"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Dienstag", - } - ), - ) - wednesday_text = forms.CharField( - label=label_span("Mittwoch"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Mittwoch,", - } - ), - ) - thursday_text = forms.CharField( - label=label_span("Donnerstag"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Donnerstag", - } - ), - ) - friday_text = forms.CharField( - label=label_span("Freitag"), - max_length=300, - widget=forms.Textarea( - attrs={ - "class": STYLE["text-input"], - "rows": 5, - "placeholder": "Freitag", - } - ), - ) - img = forms.ImageField( - label=label_span("Bild"), - required=False, - widget=forms.ClearableFileInput( - attrs={ - "class": "block w-full p-2 text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400", - "accept": "image/*", - } - ), - ) - - @property - def display_names(self) -> dict: - return { - "department": self.fields["department"].label, - "week_topic": self.fields["week_topic"].label, - "monday_text": self.fields["monday_text"].label, - "tuesday_text": self.fields["tuesday_text"].label, - "wednesday_text": self.fields["wednesday_text"].label, - "thursday_text": self.fields["thursday_text"].label, - "friday_text": self.fields["friday_text"].label, - } - - def content_values(self) -> dict: - if self.is_valid(): - return { - "week_topic": self.cleaned_data["week_topic"], - "monday_text": self.cleaned_data["monday_text"], - "tuesday_text": self.cleaned_data["tuesday_text"], - "wednesday_text": self.cleaned_data["wednesday_text"], - "thursday_text": self.cleaned_data["thursday_text"], - "friday_text": self.cleaned_data["friday_text"], - } - - -def choose_report_kind(kind, request=None, files=None): - match kind: - case "weekly": - return WeeklyReport(request, files) - case "daily": - return DailyReport(request, files) diff --git a/core/styles.py b/core/styles.py deleted file mode 100644 index 7f9ce5a..0000000 --- a/core/styles.py +++ /dev/null @@ -1,11 +0,0 @@ -# Tailwind Styles - -STYLE = { - "red_btn": "text-white bg-red-700 hover:bg-red-800 focus:outline-none focus:ring-4 focus:ring-red-300 font-medium rounded-full text-sm px-5 py-2.5 text-center me-2 mb-2 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900", - "card": "bg-white drop-shadow-md mx-auto mt-5 aspect-[2/3] hover:drop-shadow-xl hover:scale-[0.85] scale-[0.8] lg:hover:scale-[0.95] lg:scale-[0.9] transition-all duration-50 transform ease-in-out w-60 sm:w-80 flex items-center justify-center", - "text-input": "w-full p-2 border border-gray-300 rounded-lg focus:ring focus:ring-blue-400 mb-5", -} - - -def label_span(txt): - return f'{txt}' diff --git a/core/templates/component/report.html b/core/templates/component/report.html deleted file mode 100644 index 331469c..0000000 --- a/core/templates/component/report.html +++ /dev/null @@ -1,13 +0,0 @@ - - {% if report.is_approved %} -
- ✓ -
- {% endif %} - -
diff --git a/core/templates/head.html b/core/templates/head.html deleted file mode 100644 index e1d2240..0000000 --- a/core/templates/head.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/core/templates/htmx/reports.html b/core/templates/htmx/reports.html deleted file mode 100644 index aee0210..0000000 --- a/core/templates/htmx/reports.html +++ /dev/null @@ -1,12 +0,0 @@ -{% if reports|length != 0 %} - {% for report in reports %} - - {% include 'component/report.html' with report=report %} - - {% endfor %} - -
- - {% endif %} diff --git a/core/templates/index.html b/core/templates/index.html old mode 100644 new mode 100755 index 7655f66..ab7cf7f --- a/core/templates/index.html +++ b/core/templates/index.html @@ -1,45 +1,34 @@ - {{ title|safe }} + + + Azube + + + + {{ user.display_name }} - {% if late_reports > 1 %} - - - - {% endif %} +

Deine Berichtshefte

- {% if reports|length == 0 %} + {% if reports|length == 0 %} + + {% endif %} -

wau, such empty!

- - - {% else %} - -
{% for report in reports %} - - {% if forloop.first %} {% if report.week != week_now %} - - + - - {% endif %} {% endif %} - - {% include 'component/report.html' with report=report %} - - {% endfor %} - -
- - {% endif %} - -
-
+
+

{{ report }}

+
+ {% endfor %} + + + \ No newline at end of file diff --git a/core/templates/report.html b/core/templates/report.html deleted file mode 100644 index f47c82f..0000000 --- a/core/templates/report.html +++ /dev/null @@ -1,48 +0,0 @@ -{{ title|safe }} - -
-
-
-

- Berichtsheft {{ report.year }} / {{ report.week }} -

-

- Is Approved? - - {{ report.is_approved }} - -

-
- -
- -
-

Content:

-
-
-
- {% load access markdown %} - {% for key, value in report.content.items %} -
-

{{ form.display_names|access:key|safe }}

-
{{ value|markdown|safe }}
-
- {% endfor %} -
- - {% if report.image is not None %} - {% load b64 %} -
- -
- {% endif %} - -
-
-
-
diff --git a/core/templates/report_template/weekly.html b/core/templates/report_template/weekly.html deleted file mode 100644 index 6c05a5c..0000000 --- a/core/templates/report_template/weekly.html +++ /dev/null @@ -1,2464 +0,0 @@ -{% load markdown %} - - - - - - - - - - - - - - - - - - - - -
- -

 

- -

 

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

 

-
-

 

-
-

Name: {{ user }}

-
-

Ausbildungsnachweis Nr. {{ num }}

-
-

 

-
-

 

-
-

 

-
-

 

-
-

Ausbildungsjahr: {{ year }}

-
-

Firma:

-
-

Ausbildungsabteilung: {{ department }}

-
-

 

-
-

 

-
-

 

-
-

 

-
-

CANCOM GmbH

-
-

 

-
-

Woche: {{ week }}

-
-

Messerschmittstr. 20

-
-

 

-
-

 

-
-

89343 Jettingen-Scheppach

-
-

 

-
-

 

-
-

 

-
-

 

-
-

vom: {{ start_date }} bis: {{ end_date }}

-
-

 

-
-

 

-
-

 

-
-

Betriebliche - Tätigkeit (bitte - Ausbildungsverlauf mit der zeitlichen und sachlichen Gliederung abgleichen):

-

 

-

 

-

{{ company_text|markdown|safe }}        

-

 

-

 

-

 

-
-

Stunden

-
-

Thema der Woche:

-

  {{ week_topic|markdown|safe }}

-

 

-

 

-

 

-
-

 

-
-

 

-
-

 

-
-

Berufsschule (Themen des - Unterrichts)

-

 

-

{{ school_text|markdown|safe }}

-

 

-

 

-

 

-
-

 

-
-

 

-
-

 

-
-

8

-
-

Gesamtstunden

-
-

40

-
-

 

-
-

 

-
-

 

-
-

Für - die

-
-

                   

-
-

 

-
-

 

-
-

 

-
-

Richtigkeit

-
-

____________________

-
-

____________________

-
-

____________________

-
-

____________________

-
-

 

-
-

Datum

-
-

Auszubildender

-
-

Datum

-
-

Ausbilder

-
-

 

-
-

 

-
-

 

-
- -
- -

 

- -
- - - - diff --git a/core/templates/settings.html b/core/templates/settings.html deleted file mode 100644 index 9d14eb4..0000000 --- a/core/templates/settings.html +++ /dev/null @@ -1,8 +0,0 @@ -{{ title|safe }} - -

- Benutzer: -

- -

{{ user.display_name }}

-

{{ user.role.value|capfirst }}

diff --git a/core/templates/shell.html b/core/templates/shell.html deleted file mode 100644 index a4402a5..0000000 --- a/core/templates/shell.html +++ /dev/null @@ -1,70 +0,0 @@ - - - {{ title }} - {% include 'head.html' %} - - - - -
-
- - -

{{ title }}

-
- - -
- -
- -
- - -
- {{ main_content|safe }} -
-
-
- - - - - - diff --git a/core/templates/test.html b/core/templates/test.html new file mode 100755 index 0000000..31ea0fc --- /dev/null +++ b/core/templates/test.html @@ -0,0 +1,384 @@ + + + Test + + + + + + + +

Deine Berichtshefte

+ + + + + + \ No newline at end of file diff --git a/core/templates/write.html b/core/templates/write.html old mode 100644 new mode 100755 index 3ec6783..7d3ccbe --- a/core/templates/write.html +++ b/core/templates/write.html @@ -1,127 +1,50 @@ -
- - {{ title|safe }} - -
-

{{ user.display_name }}

-

- Berichtsheft {{ year }} / {{ week }} -

-

- Von: {{ start_date|date:"d.m.Y" }} bis: {{ end_date|date:"d.m.Y" }} -

-
+ + + Neues Berichtsheft + + +

Neues Berichtsheft

-
+

Berichtsheft {{ year }} / {{ week }}

- {% load access set_content %} - - {% for field in form %} -
- - - {% if field.id_for_label == "id_department" %} - - {% if draft is not None %} - {{ field|set_content:draft.department }} - {% else %} - {{ field }} + + {% for var in definition.vars %} +
+ + {{ field.errors|join:", " }}

- {% endif %} + {% if var.name == "year" %} + value = "{{ year }}" + {% endif %} + + {% if var.name == "start_date" %} + value = "{{ start_date|date:"d.m.Y" }}" + {% endif %} + + {% if var.name == "end_date" %} + value = "{{ end_date|date:"d.m.Y" }}" + {% endif %} + + {% if var.name == "num_doc" %} + value = "{{ current_num }}" + {% endif %} + + {% if var.name == "name" %} + value = "{{ user.display_name }}" + {% endif %} + + >
- {% endfor %} + {% endfor %} + + {% csrf_token %} - - - + - - -
+ + diff --git a/core/templatetags/access.py b/core/templatetags/access.py deleted file mode 100644 index 1cd9369..0000000 --- a/core/templatetags/access.py +++ /dev/null @@ -1,13 +0,0 @@ -from django import template - -register = template.Library() - - -@register.filter(name="access") -def access(value, arg): - if value == None: - return "" - try: - return value[arg] - except: - return "" diff --git a/core/templatetags/add_attr.py b/core/templatetags/add_attr.py deleted file mode 100644 index 51e77b7..0000000 --- a/core/templatetags/add_attr.py +++ /dev/null @@ -1,25 +0,0 @@ -from django import template - -register = template.Library() - - -@register.filter(name="add_attr") -def add_attr(field, css): - """Adds custom attributes (like class) to form fields without overwriting existing attributes.""" - # Retrieve existing attributes (if any) - attrs = field.field.widget.attrs.copy() - - # Split the CSS string into key-value pairs - definition = css.split(",") - - for d in definition: - if ":" not in d: - # If no key-value pair is provided, default to 'class' - attrs["class"] = f"{attrs.get('class', '')} {d}".strip() - else: - # If a key-value pair is provided (e.g., 'data-test:123'), add it - key, val = d.split(":") - attrs[key.strip()] = val.strip() - - # Return the widget with the updated attributes - return field.as_widget(attrs=attrs) diff --git a/core/templatetags/b64.py b/core/templatetags/b64.py deleted file mode 100644 index 6c82718..0000000 --- a/core/templatetags/b64.py +++ /dev/null @@ -1,11 +0,0 @@ -from django import template -import base64 - -register = template.Library() - - -@register.filter(name="b64") -def b64(value): - if value is None: - return "" - return base64.b64encode(value).decode("utf-8") diff --git a/core/templatetags/markdown.py b/core/templatetags/markdown.py deleted file mode 100644 index 3728b52..0000000 --- a/core/templatetags/markdown.py +++ /dev/null @@ -1,12 +0,0 @@ -from django import template -import markdown -import bleach - -register = template.Library() - - -@register.filter(name="markdown") -def markdown_tag(value): - return markdown.markdown( - bleach.clean(value, tags=[], attributes=[]), extensions=["nl2br"] - ) diff --git a/core/templatetags/set_content.py b/core/templatetags/set_content.py deleted file mode 100644 index 0c5dc22..0000000 --- a/core/templatetags/set_content.py +++ /dev/null @@ -1,27 +0,0 @@ -from django import template -from django import forms - -register = template.Library() - - -@register.filter(name="set_content") -def set_content(field, content): - """Sets the content of input and textarea fields, and custom attributes like class, without overwriting existing attributes.""" - - # Retrieve existing attributes (if any) - attrs = field.field.widget.attrs.copy() - - # Check if the field is a text input or textarea - is_input_or_textarea = isinstance( - field.field.widget, (forms.widgets.TextInput, forms.widgets.Textarea) - ) - - # If the field is an input or textarea, set the content as value or text - if is_input_or_textarea: - attrs["value"] = content.strip() # Set the value to the provided content - - if isinstance(field.field.widget, forms.widgets.Textarea): - field.initial = content.strip() - - # Return the widget with the updated attributes - return field.as_widget(attrs=attrs) diff --git a/core/tests.py b/core/tests.py old mode 100644 new mode 100755 diff --git a/core/urls.py b/core/urls.py old mode 100644 new mode 100755 index 4e7c018..6a9c653 --- a/core/urls.py +++ b/core/urls.py @@ -4,11 +4,5 @@ from . import views urlpatterns = [ path("", views.index, name="index"), path("write", views.write_new_report, name="write"), - path("report/", views.report_detail_page, name="report_detail"), - path("report//pdf", views.report_pdf_route, name="report_pdf"), - path("report//html", views.report_html_route, name="report_html"), - path("report//png", views.report_png_route, name="report_png"), - path("reports", views.reports_list, name="reports_list"), - path("draft", views.report_draft_update, name="report_draft_update"), - path("settings", views.settings_page, name="settings"), + path("test", views.test, name="test"), ] diff --git a/core/util.py b/core/util.py old mode 100644 new mode 100755 index b383732..c93ebe8 --- a/core/util.py +++ b/core/util.py @@ -1,9 +1,5 @@ import datetime -from django.template.loader import render_to_string -from django.shortcuts import render -from django.http import HttpResponse - def next_date(year: int, week: int) -> (int, int): if week >= 52: @@ -34,35 +30,3 @@ def get_week_range(p_year, p_week): ).date() lastdayofweek = firstdayofweek + datetime.timedelta(days=6.9) return firstdayofweek, lastdayofweek - - -def is_htmx_request(request) -> bool: - return request.headers.get("HX-Request") is not None - - -def title(t): - return f""" - - """ - - -def htmx_request(request, content_template, vars, page_title): - vars["title"] = title(page_title) - vars["htmx"] = is_htmx_request(request) - - main_content = render_to_string(content_template, vars, request=request) - - if is_htmx_request(request): - return HttpResponse(main_content, content_type="text/html") - else: - return render( - request, - "shell.html", - { - "title": page_title, - "main_content": main_content, - }, - ) diff --git a/core/views.py b/core/views.py old mode 100644 new mode 100755 index a477744..7f760ec --- a/core/views.py +++ b/core/views.py @@ -1,17 +1,11 @@ -from django.http import HttpResponse -from django.shortcuts import get_object_or_404, redirect, render +from django.shortcuts import redirect, render +from core.forms import extract_post_values +from core.report_templates import ReportTemplates from core.util import get_week_range, next_date from .azure_auth import AzureUser from .models import Berichtsheft -from django.core.paginator import Paginator -from django.template.loader import render_to_string -from core.styles import STYLE -from .util import is_htmx_request, title, htmx_request -from .reports import choose_report_kind -from .doc_gen import gen_doc_html, gen_doc_pdf, gen_doc_png import datetime -import json # Create your views here. @@ -26,45 +20,34 @@ def write_new_report(request): def write_new_report_post(request): user = AzureUser(request) - report_form = user.get_report_kind_form(request.POST, request.FILES) + definition = user.get_report_template() - if not report_form.is_valid(): - return HttpResponse("Bad Request", status=400) + values = extract_post_values(request.POST, definition["vars"]) - # TODO : Implement values - - current_year, current_week, _, _, current_num = get_current_report_values( - user.reports().order_by("-year", "-week").first() - ) - - upload = report_form.cleaned_data["img"] - img = upload.read() if upload is not None else None + # TODO : Input Validation report = Berichtsheft( user=user.id, - kind=user.get_report_kind(), - num=int(current_num), - year=int(current_year), - week=int(current_week), - department=report_form.cleaned_data["department"], - content=report_form.content_values(), - image=img, + num=int(values.pop("num_doc", "")), + year=int(values.pop("year", "")), + week=int(values.pop("week", "")), + content=values, ) report.save() - - # Clear draft - BerichtsheftDraft.objects.filter(user=user.id).delete() - return redirect("/") -def get_current_report_values(latest): - year_now, week_now, _ = datetime.datetime.today().isocalendar() +def write_new_report_get(request): + user = AzureUser(request) + definition = user.get_report_template() + + # Get the latest year and week + latest = user.reports().order_by("-year", "-week").first() if latest is not None: current_year, current_week = next_date(latest.year, latest.week) else: - current_year, current_week = year_now, week_now + current_year, current_week, _ = datetime.datetime.today().isocalendar() start_date, end_date = get_week_range(current_year, current_week) @@ -73,37 +56,9 @@ def get_current_report_values(latest): else: current_num = 1 - return current_year, current_week, start_date, end_date, current_num + # TODO : Cookies for persistent saves - -def write_new_report_get(request): - user = AzureUser(request) - - report_kind = user.get_report_kind() - - # Get the latest year and week - latest = user.latest_report() - - year_now, week_now, _ = datetime.datetime.today().isocalendar() - - # Report for this week already exists - if latest is not None: - if latest.year == year_now and latest.week == week_now: - return redirect(f"/report/{latest.id}") - - ( - current_year, - current_week, - start_date, - end_date, - current_num, - ) = get_current_report_values(latest) - - draft = BerichtsheftDraft.objects.filter(user=user.id).first() - - form = user.get_report_kind_form() - - return htmx_request( + return render( request, "write.html", { @@ -113,11 +68,8 @@ def write_new_report_get(request): "start_date": start_date, "end_date": end_date, "current_num": current_num, - "report_kind": report_kind, - "form": form, - "draft": draft, + "definition": definition, }, - "Neues Berichtsheft", ) @@ -125,145 +77,10 @@ def index(request): user = AzureUser(request) # Get all berichtshefte - reports = Paginator(user.reports(), 30).get_page(1) + all_reports = user.reports() - year_now, week_now, _ = datetime.datetime.today().isocalendar() - - return htmx_request( - request, - "index.html", - { - "user": user, - "reports": reports, - "week_now": week_now, - "late_reports": user.late_reports(), - "style": STYLE, - }, - "Berichtshefte", - ) + return render(request, "index.html", {"user": user, "reports": all_reports}) -def reports_list(request): - user = AzureUser(request) - - p = Paginator(user.reports(), 30) - - try: - page_num = int(request.GET.get("page")) - except: - return HttpResponse("Page should be a number", 400) - - if p.num_pages >= page_num: - objs = p.get_page(page_num) - else: - objs = [] - - return render( - request, - "htmx/reports.html", - {"reports": objs, "next": page_num + 1, "style": STYLE}, - ) - - -def report_detail_page(request, report_id): - user = AzureUser(request) - - report = get_object_or_404(Berichtsheft, id=report_id) - form = choose_report_kind(report.kind) - - if report.user != user.id: - return HttpResponse("Nah", status=401) - - return htmx_request( - request, - "report.html", - {"report": report, "form": form, "STYLE": STYLE}, - f"Berichtsheft {report.num}", - ) - - -from django.shortcuts import get_object_or_404 -from django.http import JsonResponse -from .models import BerichtsheftDraft - - -def report_draft_update(request): - if request.method == "POST": - user = AzureUser(request) - - data = json.loads(request.body) - - department = "" - content = {} - - for key, val in data.items(): - if key == "id_department": - department = val - continue - content[key] = val - - draft, created = BerichtsheftDraft.objects.update_or_create( - user=user.id, defaults={"department": department, "content": content} - ) - - return JsonResponse( - { - "status": "success", - "message": "Draft updated" if not created else "Draft created", - } - ) - - return JsonResponse({"error": "Invalid request method"}, status=400) - - -def settings_page(request): - user = AzureUser(request) - - return htmx_request( - request, - "settings.html", - {"user": user}, - "Einstellungen", - ) - - -def report_pdf_route(request, report_id): - user = AzureUser(request) - - report = get_object_or_404(Berichtsheft, id=report_id) - form = choose_report_kind(report.kind) - - if report.user != user.id: - return HttpResponse("Nah", status=401) - - pdf_buffer = gen_doc_pdf(report) - response = HttpResponse(pdf_buffer, content_type="application/pdf") - return response - - -def report_html_route(request, report_id): - user = AzureUser(request) - - report = get_object_or_404(Berichtsheft, id=report_id) - form = choose_report_kind(report.kind) - - if report.user != user.id: - return HttpResponse("Nah", status=401) - - html = gen_doc_html(report) - response = HttpResponse(html) - return response - - -def report_png_route(request, report_id): - user = AzureUser(request) - - report = get_object_or_404(Berichtsheft, id=report_id) - form = choose_report_kind(report.kind) - - if report.user != user.id: - return HttpResponse("Nah", status=401) - - png = gen_doc_png(report) - response = HttpResponse(png, content_type="image/png") - return response +def test(request): + return render(request, "test.html", {}) diff --git a/manage.py b/manage.py old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 index 5b5aab3..7a4844b --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,2 @@ Django~=4.2.11 -psycopg2 -markdown -bleach -pillow -weasyprint -pdf2image \ No newline at end of file +psycopg2 \ No newline at end of file