From e85cee22653531975619f27ee1da1dc8819febb5 Mon Sep 17 00:00:00 2001 From: Tom Irgang Date: Mon, 29 May 2023 16:58:36 +0200 Subject: [PATCH] accept, request or question new device --- rc_hip/rc_hip/settings.py | 5 +- rc_hip/rc_hip/urls.py | 4 +- rc_hip/repapp/forms.py | 20 +- rc_hip/repapp/mail_interface.py | 1 + .../repapp/migrations/0005_device_status.py | 18 + .../migrations/0006_alter_question_answer.py | 18 + .../repapp/migrations/0007_question_open.py | 18 + .../repapp/migrations/0008_question_sent.py | 18 + .../migrations/0009_question_answered.py | 18 + rc_hip/repapp/models.py | 9 +- rc_hip/repapp/templates/repapp/base.html | 9 +- .../repapp/mail/mail_new_guest_text.html | 6 - .../repapp/mail/mail_one_time_login_text.html | 3 - .../mail/mail_question_device_html.html | 4 + .../mail/mail_question_device_subject.html | 1 + .../mail/mail_register_device_text.html | 8 - .../repapp/mail/mail_reject_device_html.html | 6 + .../mail/mail_reject_device_subject.html | 1 + rc_hip/repapp/templates/repapp/orga/cafe.html | 2 +- .../repapp/orga/device_question.html | 23 ++ .../templates/repapp/orga/edit_question.html | 28 ++ .../repapp/templates/repapp/orga/guest.html | 4 +- rc_hip/repapp/templates/repapp/orga/main.html | 113 ++++++- .../templates/repapp/orga/question.html | 41 +++ .../templates/repapp/orga/review_device.html | 72 ++++ .../repapp/orga/review_device_reject.html | 23 ++ rc_hip/repapp/urls.py | 13 +- rc_hip/repapp/views.py | 318 ++++++++++++++++-- requirements_dev.txt | 2 + requirements_prod.txt | 2 + 30 files changed, 755 insertions(+), 53 deletions(-) create mode 100644 rc_hip/repapp/migrations/0005_device_status.py create mode 100644 rc_hip/repapp/migrations/0006_alter_question_answer.py create mode 100644 rc_hip/repapp/migrations/0007_question_open.py create mode 100644 rc_hip/repapp/migrations/0008_question_sent.py create mode 100644 rc_hip/repapp/migrations/0009_question_answered.py delete mode 100644 rc_hip/repapp/templates/repapp/mail/mail_new_guest_text.html delete mode 100644 rc_hip/repapp/templates/repapp/mail/mail_one_time_login_text.html create mode 100644 rc_hip/repapp/templates/repapp/mail/mail_question_device_html.html create mode 100644 rc_hip/repapp/templates/repapp/mail/mail_question_device_subject.html delete mode 100644 rc_hip/repapp/templates/repapp/mail/mail_register_device_text.html create mode 100644 rc_hip/repapp/templates/repapp/mail/mail_reject_device_html.html create mode 100644 rc_hip/repapp/templates/repapp/mail/mail_reject_device_subject.html create mode 100644 rc_hip/repapp/templates/repapp/orga/device_question.html create mode 100644 rc_hip/repapp/templates/repapp/orga/edit_question.html create mode 100644 rc_hip/repapp/templates/repapp/orga/question.html create mode 100644 rc_hip/repapp/templates/repapp/orga/review_device.html create mode 100644 rc_hip/repapp/templates/repapp/orga/review_device_reject.html 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/templates/repapp/base.html b/rc_hip/repapp/templates/repapp/base.html index 91436ab..a291bdb 100644 --- a/rc_hip/repapp/templates/repapp/base.html +++ b/rc_hip/repapp/templates/repapp/base.html @@ -15,6 +15,11 @@ {% endblock title %} + {% block head %} {% endblock head %} @@ -39,10 +44,6 @@ - {% else %} - {% endif %}