This repository has been archived on 2026-03-30. You can view files and clone it, but cannot push or open issues or pull requests.
RepApp/rc_hip/repapp/models.py

255 lines
8.9 KiB
Python
Raw Normal View History

"""
This module implements the models of RepApp.
"""
2023-04-24 06:27:18 +00:00
import django.utils.timezone
2023-04-16 11:01:31 +00:00
from django.db import models
from django.utils.translation import gettext_lazy as _
2023-04-24 16:02:43 +00:00
from django.contrib.auth.models import AbstractUser
def device_directory_path(instance, filename):
"""
device_directory_path generates a device-specific storage path for file uploads.
"""
return f'device_{instance.identifier}/{filename}'
2023-04-16 11:01:31 +00:00
2023-04-16 17:55:54 +00:00
2023-04-25 07:14:26 +00:00
class CustomUser(AbstractUser):
"""
Custom user object with unique email.
"""
email = models.EmailField(unique=True, verbose_name=_("eMail Adresse"))
2023-06-18 07:01:14 +00:00
notifications = models.BooleanField(
verbose_name=_("Benachrichtigungen"), default=True)
2023-04-25 07:14:26 +00:00
class Meta:
verbose_name = _('Benutzer')
verbose_name_plural = _('Benutzer')
def __str__(self):
return f'{self.email}'
2023-04-16 17:55:54 +00:00
class Cafe(models.Model):
"""
A Cafe is a "Repair-Café event.
"""
location = models.CharField(
max_length=200, verbose_name=_("Ort"))
2023-04-21 16:24:31 +00:00
address = models.CharField(
max_length=200, verbose_name=_("Adresse"))
event_date = models.DateField(verbose_name=_("Datum"))
class Meta:
verbose_name = _('Repair-Café')
verbose_name_plural = _('Repair-Cafés')
2023-04-16 17:55:54 +00:00
def __str__(self):
return f'Repair-Café am {self.event_date} (Ort: {self.location})'
2023-04-16 17:55:54 +00:00
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"))
2023-06-18 07:44:53 +00:00
cafe = models.ManyToManyField(Cafe)
class Meta:
verbose_name = _('Reparateur')
verbose_name_plural = _('Reparateure')
2023-04-16 17:55:54 +00:00
def __str__(self):
return f'Reparateur {self.name} (eMail: {self.mail})'
2023-04-16 17:55:54 +00:00
class Organisator(models.Model):
"""
A Organisator is a member of the Repair-Café who arranges repair appointments with guests.
"""
name = models.CharField(max_length=200, verbose_name=_("Name"))
mail = models.CharField(max_length=200, verbose_name=_("eMail"))
class Meta:
verbose_name = _('Organisator')
verbose_name_plural = _('Organisatoren')
2023-04-16 17:55:54 +00:00
def __str__(self):
return f'Organisator {self.name} (eMail: {self.mail})'
2023-04-16 17:55:54 +00:00
class Guest(models.Model):
"""
A guest is a owner of a broken device who wants support in context of a Repair-Café.
"""
identifier = models.CharField(max_length=200, verbose_name=_("ID"))
name = models.CharField(max_length=200, verbose_name=_("Name"))
2023-04-16 19:17:11 +00:00
phone = models.CharField(max_length=200, verbose_name=_("Telefonnummer"))
residence = models.CharField(max_length=200, verbose_name=_("Wohnort"))
mail = models.CharField(max_length=200, verbose_name=_("eMail"))
2023-04-25 07:14:26 +00:00
user = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, null=True, verbose_name=_("Benutzer"))
class Meta:
verbose_name = _('Gast')
verbose_name_plural = _('Gäste')
def __str__(self):
return f'Gast {self.name} (eMail: {self.mail})'
class Device(models.Model):
"""
A Device is a broken device owned by a guest which shall be repaired during a Repair-Café.
"""
2023-06-18 07:44:53 +00:00
STATUS_REJECTED = -1
STATUS_NEW = 0
STATUS_ORGA_QUESTION = 1
STATUS_ORGA_QUESTION_ANSWERED = 2
STATUS_WAITING_LIST = 3
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'),
)
identifier = models.CharField(max_length=200, verbose_name=_("ID"))
2023-04-25 11:56:12 +00:00
date = models.DateField(verbose_name=_(
"Erstellungsdatum"), default=django.utils.timezone.now)
2023-04-21 16:24:31 +00:00
device = models.CharField(max_length=200, verbose_name=_("Art des Geräts"))
manufacturer = models.CharField(
max_length=200, verbose_name=_("Hersteller & Modell/Typ"))
error = models.TextField(verbose_name=_("Fehlerbeschreibung"))
follow_up = models.BooleanField(verbose_name=_("Folgetermin"))
2023-04-21 16:24:31 +00:00
device_picture = models.FileField(
upload_to=device_directory_path, null=True, verbose_name=_("Foto vom Gerät"))
type_plate_picture = models.FileField(
upload_to=device_directory_path, null=True, verbose_name=_("Foto vom Typenschild"))
2023-04-25 11:56:12 +00:00
confirmed = models.BooleanField(verbose_name=_("Bestätigung gesendet?"))
2023-05-29 14:58:36 +00:00
status = models.IntegerField(verbose_name=_("Status"), default=0)
guest = models.ForeignKey(
2023-06-18 07:44:53 +00:00
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é"))
class Meta:
verbose_name = _('Gerät')
verbose_name_plural = _('Geräte')
2023-04-16 17:55:54 +00:00
def __str__(self):
2023-05-29 14:58:36 +00:00
return f'Gerät {self.device} - {self.manufacturer}'
2023-04-16 17:55:54 +00:00
class Appointment(models.Model):
"""
A Appointment is a match of a broken Device and a Reparateur during a Repair-Café
with a defined time slot.
"""
time = models.TimeField(verbose_name=_("Zeit"))
confirmed = models.BooleanField(verbose_name=_("bestätigt"))
cafe = models.ForeignKey(
Cafe, on_delete=models.CASCADE, verbose_name=_("Repair-Café"))
reparateur = models.ForeignKey(
Reparateur, on_delete=models.CASCADE, verbose_name=_("Reparateur"))
device = models.ForeignKey(
Device, on_delete=models.CASCADE, null=True, verbose_name=_("Gerät"))
class Meta:
verbose_name = _('Termin')
verbose_name_plural = _('Termine')
def __str__(self):
return f'Termin {self.cafe.event_date} {self.time} für Gerät {self.device.device}'
2023-04-16 17:55:54 +00:00
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"))
2023-05-29 14:58:36 +00:00
answer = models.TextField(verbose_name=_("Antwort"), null=True)
2023-04-24 06:27:18 +00:00
date = models.DateField(verbose_name=_(
"Erstellungsdatum"), default=django.utils.timezone.now)
organisator = models.ForeignKey(
Organisator, on_delete=models.CASCADE, null=True, verbose_name=_("Organisator"))
reparateur = models.ForeignKey(
Reparateur, on_delete=models.CASCADE, null=True, verbose_name=_("Reparateur"))
device = models.ForeignKey(
Device, on_delete=models.CASCADE, verbose_name=_("Gerät"))
2023-05-29 14:58:36 +00:00
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')
verbose_name_plural = _('Fragen')
def __str__(self):
return f'Frage vom {self.date} zum Gerät {self.device.device}'
2023-04-21 16:24:31 +00:00
class Candidate(models.Model):
"""
A Candidate is a match of a broken Device and a Repair-Café without a fixed timeslot
or pre-assigned Reparateur.
"""
confirmed = models.BooleanField(verbose_name=_("bestätigt"))
cafe = models.ForeignKey(
Cafe, on_delete=models.CASCADE, verbose_name=_("Repair-Café"))
device = models.ForeignKey(
Device, on_delete=models.CASCADE, null=True, verbose_name=_("Gerät"))
class Meta:
verbose_name = _('Kandidat')
verbose_name_plural = _('Kandidaten')
def __str__(self):
return f'Kandidat {self.cafe.event_date} für Gerät {self.device.device}'
2023-04-24 16:02:43 +00:00
class OneTimeLogin(models.Model):
"""
A OneTimeLogin is a secret which can be used once to login a user.
"""
secret = models.CharField(max_length=200, verbose_name=_(
2023-04-25 11:56:12 +00:00
"Geheimnis"), unique=True, null=False)
2023-04-24 16:02:43 +00:00
url = models.CharField(max_length=200, verbose_name=_("URL"))
created = models.DateField(verbose_name=_(
"Erstellungsdatum"), default=django.utils.timezone.now)
login_used = models.BooleanField(
verbose_name=_("Login benutzt?"), default=False)
login_date = models.DateField(verbose_name=_(
"Login Datum"), null=True)
2023-04-25 11:56:12 +00:00
user = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, null=False, verbose_name=_("Benutzer"))
2023-04-24 16:02:43 +00:00
class Meta:
verbose_name = _('Einmal-Login')
verbose_name_plural = _('Einmal-Login')
def __str__(self):
return f'Einmal-Login {self.user.email}'
2023-04-24 17:25:29 +00:00
class Message(models.Model):
"""
A Message is a request from a guest.
"""
message = models.TextField(verbose_name=_("Nachricht"))
answer = models.TextField(verbose_name=_("Antwort"))
date = models.DateField(verbose_name=_(
"Erstellungsdatum"), default=django.utils.timezone.now)
guest = models.ForeignKey(
Guest, on_delete=models.CASCADE, null=True, verbose_name=_("Gast"))
class Meta:
verbose_name = _('Nachricht')
verbose_name_plural = _('Nachrichten')
def __str__(self):
return f'Nachricht vom {self.date} von {self.guest.mail}'