diff --git a/docs/workflows.md b/docs/workflows.md
index d6589c5..9b64206 100644
--- a/docs/workflows.md
+++ b/docs/workflows.md
@@ -21,7 +21,9 @@ Als bekannter Gast der ein defekten Geräte anmelden möchte,
- Die nächste Seite (S5) bestätigt mir die Anmeldung meines Gerätes.
- In meinem eMail Posteingang finde ich ebenfalls eine Bestätigung der Geräteanmeldung.
-## Organisator: Neues Gerät - akzeptieren für ausgewähltes Repair-Café
+## Organisator: Neues Gerät
+
+### Variante: Akzeptieren für ausgewähltes Repair-Café
Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wurde. Ich möchte dieses Gerät nun ansehen un die Eingangsüberprüfung durchführen.
- Ich öffne die RepApp im Browser
@@ -31,7 +33,7 @@ Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wu
- Ich klicke auf den Knopf "Details" für das neue Gerät, und mein Browser öffnet eine Seite in der ich die Details zu dem Gerät sehe. Auf der Seite sind Knöpfe: `Annehmen für gewähltes Repair-Café`, `Annehmen für anderes Repair-Café`, `Ablehnen` und `Rückfrage`. Alle notwendigen Informationen sind vorhanden und ich entscheide mich das Gerät für das ausgewählte Repair-Café zu akzeptieren. Der Klick auf `Annehmen für gewähltes Repair-Café` bringt mich zurück zum Hauptmenü.
- In der Liste der neuen Geräte ist das gerade bearbeitete Gerät nicht mehr sichtbar.
-## Organisator: Neues Gerät - akzeptieren für späteres Repair-Café
+### Variante: Akzeptieren für späteres Repair-Café
Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wurde. Ich möchte dieses Gerät nun ansehen un die Eingangsüberprüfung durchführen.
- Ich öffne die RepApp im Browser
@@ -41,7 +43,7 @@ Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wu
- Ich klicke auf den Knopf "Details" für das neue Gerät, und mein Browser öffnet eine Seite in der ich die Details zu dem Gerät sehe. Auf der Seite sind Knöpfe: `Annehmen für gewähltes Repair-Café`, `Annehmen für anderes Repair-Café`, `Ablehnen` und `Rückfrage`. Alle notwendigen Informationen sind vorhanden, aber da ich weiß dass im nächsten Repair-Café kein geeigneter Reparateur verfügbar ist entscheide ich mich das Gerät für ein späteres Repair-Café zu akzeptieren. Der Klick auf `Annehmen für anderes Repair-Café` bringt mich zurück zum Hauptmenü.
- In der Liste der neuen Geräte ist das gerade bearbeitete Gerät nicht mehr sichtbar.
-## Organisator: Neues Gerät - ablehnen
+### Variante: Ablehnen
Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wurde. Ich möchte dieses Gerät nun ansehen un die Eingangsüberprüfung durchführen.
- Ich öffne die RepApp im Browser
@@ -52,7 +54,7 @@ Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wu
- Auf der neuen Seite sehe ich ein Formular mit einem Textbereich der die Überschrift "Antwort an den Gast" trägt. Im Formular ist bereits ein Standard-Text zur Ablehnung eines Geräts. Ich passe den Text an um dem Gast mitzuteilen dass wir leider keinen geeigneten Reparateur haben und klicke auf den Knopf `Absenden`. Der Klick bringt mich zurück zum Hauptmenü.
- In der Liste der neuen Geräte ist das gerade bearbeitete Gerät nicht mehr sichtbar.
-## Organisator: Neues Gerät - Rückfrage
+### Variante: Rückfrage
Als Organisator habe ich eine eMail bekommen dass ein neues Gerät angemeldet wurde. Ich möchte dieses Gerät nun ansehen un die Eingangsüberprüfung durchführen.
- Ich öffne die RepApp im Browser
diff --git a/rc_hip/rc_hip/settings.py b/rc_hip/rc_hip/settings.py
index 78d64cf..a18ca3a 100644
--- a/rc_hip/rc_hip/settings.py
+++ b/rc_hip/rc_hip/settings.py
@@ -53,10 +53,13 @@ INSTALLED_APPS = [
"crispy_forms",
"crispy_bootstrap5",
"import_export",
+ "ckeditor",
+ "ckeditor_uploader",
]
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"
+CKEDITOR_UPLOAD_PATH = "uploads/"
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
@@ -166,7 +169,7 @@ AUTHENTICATION_BACKENDS = [
"repapp.backends.OneTimeLoginBackend",
]
-LOGIN_REDIRECT_URL = "/guest/profile/"
+LOGIN_REDIRECT_URL = "/guest/"
OIDC_RP_CLIENT_ID = "repapp"
OIDC_RP_CLIENT_SECRET = os.getenv("DJANGO_OIDC_RP_CLIENT_SECRET", None)
diff --git a/rc_hip/rc_hip/urls.py b/rc_hip/rc_hip/urls.py
index 9cd3412..7f57906 100644
--- a/rc_hip/rc_hip/urls.py
+++ b/rc_hip/rc_hip/urls.py
@@ -23,6 +23,8 @@ from django.conf.urls.static import static
urlpatterns = [
path("", include("repapp.urls")),
path('oidc/', include('mozilla_django_oidc.urls')),
- path('accounts/', include('django.contrib.auth.urls')),
+ # user management for guests not needed, use one-time-login only
+ # path('accounts/', include('django.contrib.auth.urls')),
+ path('ckeditor/', include('ckeditor_uploader.urls')),
path('admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/rc_hip/repapp/forms.py b/rc_hip/repapp/forms.py
index cc8650a..ec58ed3 100644
--- a/rc_hip/repapp/forms.py
+++ b/rc_hip/repapp/forms.py
@@ -3,7 +3,8 @@ Django forms for RepApp.
"""
from django import forms
from django.core.exceptions import ValidationError
-from crispy_forms.layout import Field
+from ckeditor.widgets import CKEditorWidget
+from .models import Question, Device
EMPTY_VALUES = (None, '')
@@ -16,7 +17,7 @@ class HoneypotWidget(forms.TextInput):
"""
is_hidden = True
- def __init__(self, attrs=None, html_comment=False, *args, **kwargs):
+ def __init__(self, *args, attrs=None, html_comment=False, **kwargs):
self.html_comment = html_comment
super(HoneypotWidget, self).__init__(attrs, *args, **kwargs)
if 'class' not in self.attrs:
@@ -113,3 +114,18 @@ class RegisterGuest(forms.Form):
max_length=200
)
accept_agb = HoneypotField(label="")
+
+
+class Mail(forms.Form):
+ """
+ Form for rejecting a device.
+ """
+ message = forms.CharField(widget=CKEditorWidget(), label="")
+
+
+class UpdateDeviceForm(forms.ModelForm):
+ class Meta:
+ model = Question
+ fields = ['question']
+ question = forms.CharField(widget=CKEditorWidget(
+ attrs={'style': 'width:100%;'}), label="Frage")
diff --git a/rc_hip/repapp/mail_interface.py b/rc_hip/repapp/mail_interface.py
index a5a22ec..dbf8492 100644
--- a/rc_hip/repapp/mail_interface.py
+++ b/rc_hip/repapp/mail_interface.py
@@ -48,6 +48,7 @@ def process_message(message: MailMessage, guest: Guest):
if question:
if question.device.guest.mail == message.from_:
question.answer = content
+ question.answered = True
question.save()
# TODO: save attachments and add to message
logger.info(
diff --git a/rc_hip/repapp/migrations/0005_device_status.py b/rc_hip/repapp/migrations/0005_device_status.py
new file mode 100644
index 0000000..d6c2964
--- /dev/null
+++ b/rc_hip/repapp/migrations/0005_device_status.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2023-05-29 10:39
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0004_alter_onetimelogin_secret'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='device',
+ name='status',
+ field=models.IntegerField(default=0, verbose_name='Status'),
+ ),
+ ]
diff --git a/rc_hip/repapp/migrations/0006_alter_question_answer.py b/rc_hip/repapp/migrations/0006_alter_question_answer.py
new file mode 100644
index 0000000..1f9d1e4
--- /dev/null
+++ b/rc_hip/repapp/migrations/0006_alter_question_answer.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2023-05-29 12:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0005_device_status'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='question',
+ name='answer',
+ field=models.TextField(null=True, verbose_name='Antwort'),
+ ),
+ ]
diff --git a/rc_hip/repapp/migrations/0007_question_open.py b/rc_hip/repapp/migrations/0007_question_open.py
new file mode 100644
index 0000000..c747947
--- /dev/null
+++ b/rc_hip/repapp/migrations/0007_question_open.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2023-05-29 12:55
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0006_alter_question_answer'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='question',
+ name='open',
+ field=models.BooleanField(default=True, verbose_name='offen'),
+ ),
+ ]
diff --git a/rc_hip/repapp/migrations/0008_question_sent.py b/rc_hip/repapp/migrations/0008_question_sent.py
new file mode 100644
index 0000000..f49e80a
--- /dev/null
+++ b/rc_hip/repapp/migrations/0008_question_sent.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2023-05-29 14:08
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0007_question_open'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='question',
+ name='sent',
+ field=models.BooleanField(default=False, verbose_name='gesendet'),
+ ),
+ ]
diff --git a/rc_hip/repapp/migrations/0009_question_answered.py b/rc_hip/repapp/migrations/0009_question_answered.py
new file mode 100644
index 0000000..b840470
--- /dev/null
+++ b/rc_hip/repapp/migrations/0009_question_answered.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2023-05-29 14:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0008_question_sent'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='question',
+ name='answered',
+ field=models.BooleanField(default=False, verbose_name='beantwortet'),
+ ),
+ ]
diff --git a/rc_hip/repapp/models.py b/rc_hip/repapp/models.py
index b78fce5..327bd13 100644
--- a/rc_hip/repapp/models.py
+++ b/rc_hip/repapp/models.py
@@ -113,6 +113,7 @@ class Device(models.Model):
type_plate_picture = models.FileField(
upload_to=device_directory_path, null=True, verbose_name=_("Foto vom Typenschild"))
confirmed = models.BooleanField(verbose_name=_("Bestätigung gesendet?"))
+ status = models.IntegerField(verbose_name=_("Status"), default=0)
guest = models.ForeignKey(
Guest, on_delete=models.CASCADE, null=True, verbose_name=_("Gast"))
cafe = models.ForeignKey(
@@ -123,7 +124,7 @@ class Device(models.Model):
verbose_name_plural = _('Geräte')
def __str__(self):
- return f'Gerät {self.device}'
+ return f'Gerät {self.device} - {self.manufacturer}'
class Appointment(models.Model):
@@ -153,7 +154,7 @@ class Question(models.Model):
A Question is a request for information form a Organisator or a Reparateur for a Device.
"""
question = models.TextField(verbose_name=_("Frage"))
- answer = models.TextField(verbose_name=_("Antwort"))
+ answer = models.TextField(verbose_name=_("Antwort"), null=True)
date = models.DateField(verbose_name=_(
"Erstellungsdatum"), default=django.utils.timezone.now)
organisator = models.ForeignKey(
@@ -162,6 +163,10 @@ class Question(models.Model):
Reparateur, on_delete=models.CASCADE, null=True, verbose_name=_("Reparateur"))
device = models.ForeignKey(
Device, on_delete=models.CASCADE, verbose_name=_("Gerät"))
+ open = models.BooleanField(verbose_name=_("offen"), default=True)
+ sent = models.BooleanField(verbose_name=_("gesendet"), default=False)
+ answered = models.BooleanField(
+ verbose_name=_("beantwortet"), default=False)
class Meta:
verbose_name = _('Frage')
diff --git a/rc_hip/repapp/static/repapp/css/repapp.css b/rc_hip/repapp/static/repapp/css/repapp.css
new file mode 100644
index 0000000..5a150b1
--- /dev/null
+++ b/rc_hip/repapp/static/repapp/css/repapp.css
@@ -0,0 +1,3 @@
+.django-ckeditor-widget {
+ display: block !important
+}
\ No newline at end of file
diff --git a/rc_hip/repapp/templates/repapp/base.html b/rc_hip/repapp/templates/repapp/base.html
index ac5b2a3..570ca00 100644
--- a/rc_hip/repapp/templates/repapp/base.html
+++ b/rc_hip/repapp/templates/repapp/base.html
@@ -15,6 +15,7 @@
{% endblock title %}
+
{% block head %}
{% endblock head %}
@@ -39,10 +40,6 @@
Mitglieder
diff --git a/rc_hip/repapp/templates/repapp/mail/mail_new_guest_text.html b/rc_hip/repapp/templates/repapp/mail/mail_new_guest_text.html
deleted file mode 100644
index 9e7beb6..0000000
--- a/rc_hip/repapp/templates/repapp/mail/mail_new_guest_text.html
+++ /dev/null
@@ -1,6 +0,0 @@
-Guten Tag,
-wir haben ein Benutzerkonto für Sie erstellt. Sie können sich im Web-Broswer unter {{ link }} um ihre Daten einzusehen und zu ändern.
-Ihr Anmeldedaten sind:
-Benutzername: {{ username }}
-Passwort: {{ password }}
-Herzliche Grüße sendet dir das Organisationsteam vom Repair-Café Hilpoltstein!
diff --git a/rc_hip/repapp/templates/repapp/mail/mail_one_time_login_text.html b/rc_hip/repapp/templates/repapp/mail/mail_one_time_login_text.html
deleted file mode 100644
index 4c28274..0000000
--- a/rc_hip/repapp/templates/repapp/mail/mail_one_time_login_text.html
+++ /dev/null
@@ -1,3 +0,0 @@
-Guten Tag,
-wir haben für Sie einen Einmal-Ammeldelink erstellt. Wenn sie {{ link }} im Web-Broswer öffnen können sie auf ihre Informationen zugreifen.
-Herzliche Grüße sendet dir das Organisationsteam vom Repair-Café Hilpoltstein!
diff --git a/rc_hip/repapp/templates/repapp/mail/mail_question_device_html.html b/rc_hip/repapp/templates/repapp/mail/mail_question_device_html.html
new file mode 100644
index 0000000..0a14009
--- /dev/null
+++ b/rc_hip/repapp/templates/repapp/mail/mail_question_device_html.html
@@ -0,0 +1,4 @@
+
Guten Tag,
+
Wir benötigen mehr Informationen zu ihrem Gerät {{ device.device }} - {{ device.manufacturer }}.
+
HIER FRAGE EINFÜGEN
+
Herzliche Grüße sendet dir das Organisationsteam vom Repair-Café Hilpoltstein!
diff --git a/rc_hip/repapp/templates/repapp/mail/mail_question_device_subject.html b/rc_hip/repapp/templates/repapp/mail/mail_question_device_subject.html
new file mode 100644
index 0000000..5516a71
--- /dev/null
+++ b/rc_hip/repapp/templates/repapp/mail/mail_question_device_subject.html
@@ -0,0 +1 @@
+Repair-Café Hilpoltstein - Q#{{ question.pk }}: Rückfrage zu {{ device.device }}
diff --git a/rc_hip/repapp/templates/repapp/mail/mail_register_device_text.html b/rc_hip/repapp/templates/repapp/mail/mail_register_device_text.html
deleted file mode 100644
index 775aa7e..0000000
--- a/rc_hip/repapp/templates/repapp/mail/mail_register_device_text.html
+++ /dev/null
@@ -1,8 +0,0 @@
-Guten Tag,
-dies ist eine automatische Nachricht, die du erhältst, nachdem du unser Anmeldeformular abgesendet hast und deine Angaben in unserer Datenbank gespeichert wurden.
-Vielen Dank für die Anmeldung des Geräts {{ device.device }} - {{ device.manufacturer }} zur Reparatur im Repair-Café am {{ cafe.event_date|date }}.
-Sie können die Daten zu ihrer Geräteanmeldung hier einsehen.
-Die Organisation unserer Repair-Cafés beginnt i.a. einige Tage vor dem jeweiligen Termin. Dann erstellen wir anhand der angemeldeten Geräte und der Spezialgebiete der anwesenden Reparateure einen Zeitplan.
-Sobald dieser Zeitplan fertig gestellt ist, erhältst du von einem Mitglied unseres Organisationsteams eine Mail. Diese beinhaltet im Normalfall den Reparaturtermin inkl. der Uhrzeit, für die die Reparatur vorgesehen ist. In Ausnahmefällen (z.B. wenn kein Spezialist für die Gerätegruppe anwesend sein wird oder überbucht ist) ist es aber auch möglich, dass wir deinen gewünschten Termin absagen und dir einen Alternativtermin vorschlagen müssen.
-Falls du in der Zwischenzeit Rückfragen hast oder deinen Wunschtermin doch nicht wahrnehmen kannst, antworte bitte einfach auf diese Nachricht.
-Herzliche Grüße sendet dir das Organisationsteam vom Repair-Café Hilpoltstein!
diff --git a/rc_hip/repapp/templates/repapp/mail/mail_reject_device_html.html b/rc_hip/repapp/templates/repapp/mail/mail_reject_device_html.html
new file mode 100644
index 0000000..c79ef97
--- /dev/null
+++ b/rc_hip/repapp/templates/repapp/mail/mail_reject_device_html.html
@@ -0,0 +1,6 @@
+
Guten Tag,
+
Leider können wir das Gerät {{ device.device }} - {{ device.manufacturer }} nicht annehmen.
+
+ In unserem Repair-Café gibt es leider keinen passenden Reparateur mit den notwenidgen Fähigkeiten um das Gerät zu reparieren.
+
+
Herzliche Grüße sendet dir das Organisationsteam vom Repair-Café Hilpoltstein!