diff --git a/rc_hip/repapp/migrations/0011_reparateur_cafe_alter_device_guest.py b/rc_hip/repapp/migrations/0011_reparateur_cafe_alter_device_guest.py
new file mode 100644
index 0000000..926e49b
--- /dev/null
+++ b/rc_hip/repapp/migrations/0011_reparateur_cafe_alter_device_guest.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.2 on 2023-06-18 07:46
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0010_customuser_notifications'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='reparateur',
+ name='cafe',
+ field=models.ManyToManyField(to='repapp.cafe'),
+ ),
+ migrations.AlterField(
+ model_name='device',
+ name='guest',
+ field=models.ForeignKey(choices=[(-1, 'abgelehnt'), (0, 'neu'), (1, 'in Orga Rückfrage'), (2, 'in Orga Rückfrage beantwortet'), (3, 'in der Warteliste')], null=True, on_delete=django.db.models.deletion.CASCADE, to='repapp.guest', verbose_name='Gast'),
+ ),
+ ]
diff --git a/rc_hip/repapp/migrations/0012_remove_reparateur_cafe_cafe_reparateur.py b/rc_hip/repapp/migrations/0012_remove_reparateur_cafe_cafe_reparateur.py
new file mode 100644
index 0000000..3afb04a
--- /dev/null
+++ b/rc_hip/repapp/migrations/0012_remove_reparateur_cafe_cafe_reparateur.py
@@ -0,0 +1,22 @@
+# Generated by Django 4.2 on 2023-06-18 13:59
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0011_reparateur_cafe_alter_device_guest'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='reparateur',
+ name='cafe',
+ ),
+ migrations.AddField(
+ model_name='cafe',
+ name='reparateur',
+ field=models.ManyToManyField(to='repapp.reparateur'),
+ ),
+ ]
diff --git a/rc_hip/repapp/migrations/0013_device_reparateur.py b/rc_hip/repapp/migrations/0013_device_reparateur.py
new file mode 100644
index 0000000..d54efee
--- /dev/null
+++ b/rc_hip/repapp/migrations/0013_device_reparateur.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2023-06-18 14:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('repapp', '0012_remove_reparateur_cafe_cafe_reparateur'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='device',
+ name='reparateur',
+ field=models.ManyToManyField(to='repapp.reparateur'),
+ ),
+ ]
diff --git a/rc_hip/repapp/models.py b/rc_hip/repapp/models.py
index 7117d19..4cf763a 100644
--- a/rc_hip/repapp/models.py
+++ b/rc_hip/repapp/models.py
@@ -30,6 +30,21 @@ class CustomUser(AbstractUser):
return f'{self.email}'
+class Reparateur(models.Model):
+ """
+ A Reparateur is a member of the Repair-Café who supports guests with fixing their devices.
+ """
+ name = models.CharField(max_length=200, verbose_name=_("Name"))
+ mail = models.CharField(max_length=200, verbose_name=_("eMail"))
+
+ class Meta:
+ verbose_name = _('Reparateur')
+ verbose_name_plural = _('Reparateure')
+
+ def __str__(self):
+ return f'Reparateur {self.name} (eMail: {self.mail})'
+
+
class Cafe(models.Model):
"""
A Cafe is a "Repair-Café event.
@@ -39,6 +54,7 @@ class Cafe(models.Model):
address = models.CharField(
max_length=200, verbose_name=_("Adresse"))
event_date = models.DateField(verbose_name=_("Datum"))
+ reparateur = models.ManyToManyField(Reparateur)
class Meta:
verbose_name = _('Repair-Café')
@@ -48,22 +64,6 @@ class Cafe(models.Model):
return f'Repair-Café am {self.event_date} (Ort: {self.location})'
-class Reparateur(models.Model):
- """
- A Reparateur is a member of the Repair-Café who supports guests with fixing their devices.
- """
- name = models.CharField(max_length=200, verbose_name=_("Name"))
- mail = models.CharField(max_length=200, verbose_name=_("eMail"))
- cafe = models.ManyToManyField(Cafe)
-
- class Meta:
- verbose_name = _('Reparateur')
- verbose_name_plural = _('Reparateure')
-
- def __str__(self):
- return f'Reparateur {self.name} (eMail: {self.mail})'
-
-
class Organisator(models.Model):
"""
A Organisator is a member of the Repair-Café who arranges repair appointments with guests.
@@ -108,12 +108,16 @@ class Device(models.Model):
STATUS_ORGA_QUESTION = 1
STATUS_ORGA_QUESTION_ANSWERED = 2
STATUS_WAITING_LIST = 3
+ STATUS_REPA_QUESTION = 4
+ STATUS_REPA_QUESTION_ANSWERED = 5
STATUS = (
(STATUS_REJECTED, 'abgelehnt'),
(STATUS_NEW, 'neu'),
(STATUS_ORGA_QUESTION, 'in Orga Rückfrage'),
(STATUS_ORGA_QUESTION_ANSWERED, 'in Orga Rückfrage beantwortet'),
(STATUS_WAITING_LIST, 'in der Warteliste'),
+ (STATUS_REPA_QUESTION, 'in Repa Rückfrage'),
+ (STATUS_REPA_QUESTION_ANSWERED, 'in Repa Rückfrage beantwortet'),
)
identifier = models.CharField(max_length=200, verbose_name=_("ID"))
@@ -134,6 +138,7 @@ class Device(models.Model):
Guest, on_delete=models.CASCADE, null=True, verbose_name=_("Gast"), choices=STATUS)
cafe = models.ForeignKey(
Cafe, on_delete=models.CASCADE, null=False, verbose_name=_("Repair-Café"))
+ reparateur = models.ManyToManyField(Reparateur)
class Meta:
verbose_name = _('Gerät')
diff --git a/rc_hip/repapp/templates/repapp/base.html b/rc_hip/repapp/templates/repapp/base.html
index 570ca00..b9783b3 100644
--- a/rc_hip/repapp/templates/repapp/base.html
+++ b/rc_hip/repapp/templates/repapp/base.html
@@ -52,7 +52,8 @@
background-repeat: no-repeat;
background-size: cover;
background-position: center;
- max-width:1920px;>
+ max-width:1920px;
+ margin-bottom:10px">
| {{ cafe.location }} |
- Nein |
- teilnehmen
+ {% if cafe.accepted %}
+ Ja
+ {% else %}
+ Nein
+ {% endif %}
+ |
+
+ {% if cafe.accepted %}
+ absagen
+ {% else %}
+ teilnehmen
+ {% endif %}
|
{% empty %}
@@ -47,6 +57,7 @@
Hersteller & Modell/Typ |
Repair-Café |
Ort |
+ mir zugeordnet? |
|
@@ -58,7 +69,14 @@
{{ device.cafe.event_date|date:"l" }}, {{ device.cafe.event_date|date }} |
{{ device.cafe.location }} |
- Details
+ {% if device.assigned %}
+ Ja
+ {% else %}
+ Nein
+ {% endif %}
+ |
+
+ Details
|
{% empty %}
diff --git a/rc_hip/repapp/templates/repapp/repa/view_device.html b/rc_hip/repapp/templates/repapp/repa/view_device.html
new file mode 100644
index 0000000..408e82b
--- /dev/null
+++ b/rc_hip/repapp/templates/repapp/repa/view_device.html
@@ -0,0 +1,75 @@
+{% extends "repapp/base.html" %}
+{% load crispy_forms_tags %}
+{% block title %}
+ - Gerät
+{% endblock title %}
+{% block page_title %}
+ Gerät
+{% endblock page_title %}
+{% block content %}
+
+ Zurück
+ {% if assigned %}
+ Gerät ablehnen
+ Rückfrage
+ {% else %}
+ Gerät mir zuordnen
+ {% endif %}
+
+
+
Gerät
+
+
+
+ | Art des Geräts |
+ {{ device.device }} |
+
+
+ | Hersteller & Modell/Typ |
+ {{ device.manufacturer }} |
+
+
+ | Fehlerbeschreibung |
+ {{ device.error }} |
+
+
+ | Folgetermin |
+
+ {% if device.follow_up %}
+ Ja
+ {% else %}
+ Nein
+ {% endif %}
+ |
+
+
+ | Foto vom Gerät |
+
+ {% if device.device_picture %}
+
+ {% else %}
+ kein Bild
+ {% endif %}
+ |
+
+
+ | Foto vom Typenschild |
+
+ {% if device.device_picture %}
+
+ {% else %}
+ kein Bild
+ {% endif %}
+ |
+
+
+
+{% endblock content %}
diff --git a/rc_hip/repapp/urls.py b/rc_hip/repapp/urls.py
index 3a89fa5..535373a 100644
--- a/rc_hip/repapp/urls.py
+++ b/rc_hip/repapp/urls.py
@@ -44,6 +44,15 @@ urlpatterns = [
path("member/question/",
views.questions, name="device_questions"),
path("repa/", views.repa, name="repa"),
+ path("repa/
/accept", views.repa_cafe_accept, name="repa_cafe_accept"),
+ path("repa//decline",
+ views.repa_cafe_decline, name="repa_cafe_decline"),
+ path("repa//",
+ views.repa_view_device, name="repa_view_device"),
+ path("repa//assign",
+ views.repa_device_assign, name="repa_device_assign"),
+ path("repa//unassign",
+ views.repa_device_unassign, name="repa_device_unassign"),
path("cafe/", views.CafeView.as_view(), name="cafe"),
path("cafe/create", views.CafeCreateView.as_view(), name="create_cafe"),
path("cafe//edit", views.CafeUpdateView.as_view(), name="edit_cafe"),
diff --git a/rc_hip/repapp/views.py b/rc_hip/repapp/views.py
index 0f3f88e..73f1eeb 100644
--- a/rc_hip/repapp/views.py
+++ b/rc_hip/repapp/views.py
@@ -618,7 +618,7 @@ class QuestionDeviceFormView(LoginRequiredMixin, UserPassesTestMixin, generic.ed
login_url = reverse_lazy('member')
def test_func(self):
- return is_organisator(self.request.user)
+ return is_member(self.request.user)
def form_valid(self, form):
device = self.kwargs['device']
@@ -628,23 +628,31 @@ class QuestionDeviceFormView(LoginRequiredMixin, UserPassesTestMixin, generic.ed
message = form.cleaned_data['message']
mail = self.request.user.email
organisator = Organisator.objects.filter(mail=mail).first()
+ reparateur = Reparateur.objects.filter(mail=mail).first()
if organisator:
question = Question(
question=message,
organisator=organisator,
device=device
)
+
+ send_device_question_mail(question, self.request)
+ device.status = Device.STATUS_ORGA_QUESTION
+ elif reparateur:
+ question = Question(
+ question=message,
+ reparateur=reparateur,
+ device=device
+ )
+
+ device.status = Device.STATUS_REPA_QUESTION
else:
raise PermissionDenied('Not valid member found!')
question.save()
-
- send_device_question_mail(question, self.request)
-
- device.status = Device.STATUS_ORGA_QUESTION
device.save()
return HttpResponseRedirect(
- reverse_lazy('orga')
+ reverse_lazy('member')
)
def get_initial(self, **kwargs):
@@ -782,8 +790,21 @@ def repa(request):
logger.warning('The user %s is no reparateur!', str(request.user))
raise PermissionDenied('Not reparateur!')
- cafes = Cafe.objects.filter(event_date__gte=datetime.date.today())
- devices = Device.objects.filter(status=Device.STATUS_WAITING_LIST)
+ devices = []
+ for device in Device.objects.filter(status__gte=Device.STATUS_WAITING_LIST):
+ if device.reparateur.filter(mail=request.user.email).count() > 0:
+ device.assigned = True
+ else:
+ device.assigned = False
+ devices.append(device)
+
+ cafes = []
+ for cafe in Cafe.objects.filter(event_date__gte=datetime.date.today()):
+ if cafe.reparateur.filter(mail=request.user.email).count() > 0:
+ cafe.accepted = True
+ else:
+ cafe.accepted = False
+ cafes.append(cafe)
return render(
request,
@@ -977,3 +998,81 @@ class MemberSettingsFormView(LoginRequiredMixin, UserPassesTestMixin, generic.ed
def test_func(self):
return is_member(self.request.user)
+
+
+@login_required(login_url=reverse_lazy('member'))
+def repa_cafe_accept(request, cafe):
+ if not is_reparateur(request.user):
+ raise PermissionDenied('Not a reparateur!')
+
+ cafe = get_object_or_404(Cafe, pk=cafe)
+ reparateur = get_object_or_404(Reparateur, mail=request.user.email)
+ cafe.reparateur.add(reparateur)
+ cafe.save()
+
+ return HttpResponseRedirect(reverse_lazy('repa'))
+
+
+@login_required(login_url=reverse_lazy('member'))
+def repa_cafe_decline(request, cafe):
+ if not is_reparateur(request.user):
+ raise PermissionDenied('Not a reparateur!')
+
+ cafe = get_object_or_404(Cafe, pk=cafe)
+ reparateur = get_object_or_404(Reparateur, mail=request.user.email)
+ cafe.reparateur.remove(reparateur)
+ cafe.save()
+
+ return HttpResponseRedirect(reverse_lazy('repa'))
+
+
+@login_required(login_url=reverse_lazy('member'))
+def repa_view_device(request, device):
+ """
+ View device details.
+ """
+ # TODO: test
+ if not is_reparateur(request.user):
+ raise PermissionDenied('Not reparateur!')
+
+ device = get_object_or_404(Device, pk=device)
+ assigned = device.reparateur.filter(mail=request.user.email).count() > 0
+
+ return render(
+ request,
+ "repapp/repa/view_device.html",
+ {
+ 'device': device,
+ 'assigned': assigned,
+ }
+ )
+
+
+@login_required(login_url=reverse_lazy('member'))
+def repa_device_assign(request, device):
+ if not is_reparateur(request.user):
+ raise PermissionDenied('Not a reparateur!')
+
+ device = get_object_or_404(Device, pk=device)
+ reparateur = get_object_or_404(Reparateur, mail=request.user.email)
+ device.reparateur.add(reparateur)
+ device.save()
+
+ return HttpResponseRedirect(reverse_lazy('repa_view_device', kwargs={
+ 'device': device.id
+ }))
+
+
+@login_required(login_url=reverse_lazy('member'))
+def repa_device_unassign(request, device):
+ if not is_reparateur(request.user):
+ raise PermissionDenied('Not a reparateur!')
+
+ device = get_object_or_404(Device, pk=device)
+ reparateur = get_object_or_404(Reparateur, mail=request.user.email)
+ device.reparateur.remove(reparateur)
+ device.save()
+
+ return HttpResponseRedirect(reverse_lazy('repa_view_device', kwargs={
+ 'device': device.id
+ }))