From 4d723f57c3b3913c6a8b344005b395ee08bcaa10 Mon Sep 17 00:00:00 2001 From: Helge Jung <hej@c3pb.de> Date: Thu, 26 Dec 2024 16:43:02 +0100 Subject: [PATCH] Room: new location_state and location_data fields (like Assembly) --- src/core/admin.py | 8 +++- src/core/locale/de/LC_MESSAGES/django.po | 12 ++++++ src/core/locale/en/LC_MESSAGES/django.po | 12 ++++++ src/core/migrations/0174_room_location.py | 29 +++++++++++++++ src/core/models/rooms.py | 45 +++++++++++++++++++++++ 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 src/core/migrations/0174_room_location.py diff --git a/src/core/admin.py b/src/core/admin.py index c00e2f344..6f45d562b 100644 --- a/src/core/admin.py +++ b/src/core/admin.py @@ -770,9 +770,9 @@ class RoomShareAdmin(admin.ModelAdmin): class RoomAdmin(admin.ModelAdmin): - list_display = ['conference', 'assembly', 'name', 'room_type', 'blocked', 'official_room_order', 'id'] + list_display = ['conference', 'assembly', 'name', 'room_type', 'location_state', 'blocked', 'official_room_order', 'id'] list_display_links = ['name'] - list_filter = ['conference', 'room_type', 'backend_status', 'blocked', 'is_official', 'is_public_fahrplan'] + list_filter = ['conference', 'room_type', 'backend_status', 'location_state', 'blocked', 'is_official', 'is_public_fahrplan'] save_as = True search_fields = ['assembly__name', 'name', 'slug', 'id'] inlines = [RoomLinkInline, RoomShareInline, TagsInline] @@ -792,6 +792,10 @@ class RoomAdmin(admin.ModelAdmin): 'Data', {'fields': ['name', 'room_type', 'capacity', 'occupants', 'description']}, ), + ( + 'Location', + {'fields': ['location_state', 'location_data']}, + ), ( 'Backend', {'fields': ['backend_link', 'backend_link_branch', 'backend_status', 'backend_data', 'director_data']}, diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po index 54605f17f..5f859b6db 100644 --- a/src/core/locale/de/LC_MESSAGES/django.po +++ b/src/core/locale/de/LC_MESSAGES/django.po @@ -1763,6 +1763,18 @@ msgstr "Art des Raums" msgid "Room__type" msgstr "Typ" +msgid "Room__location_state__help" +msgstr "Qualität der ausgewählten Position auf der Karte" + +msgid "Room__location_state" +msgstr "Position (Karte) Status" + +msgid "Room__location_floor__help" +msgstr "Ebene, auf der sich der Raum befindet" + +msgid "Room__location_floor" +msgstr "Ebene" + msgid "Room__backend_link__help" msgstr "Referenz zu interner Quelle" diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po index d5c6b5e3d..a2be9e62b 100644 --- a/src/core/locale/en/LC_MESSAGES/django.po +++ b/src/core/locale/en/LC_MESSAGES/django.po @@ -1763,6 +1763,18 @@ msgstr "type of room" msgid "Room__type" msgstr "type" +msgid "Room__location_state__help" +msgstr "quality of the selected position, how to handle it?" + +msgid "Room__location_state" +msgstr "location state" + +msgid "Room__location_floor__help" +msgstr "floor, on which this room is placed" + +msgid "Room__location_floor" +msgstr "floor" + msgid "Room__backend_link__help" msgstr "reference to internal (backend) source" diff --git a/src/core/migrations/0174_room_location.py b/src/core/migrations/0174_room_location.py new file mode 100644 index 000000000..6b96922c1 --- /dev/null +++ b/src/core/migrations/0174_room_location.py @@ -0,0 +1,29 @@ +# Generated by Django 5.1.3 on 2024-12-26 13:10 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0173_lock_created_at'), + ] + + operations = [ + migrations.AddField( + model_name='room', + name='location_data', + field=models.JSONField(blank=True, null=True), + ), + migrations.AddField( + model_name='room', + name='location_floor', + field=models.ForeignKey(blank=True, help_text='Room__location_floor__help', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rooms', to='core.mapfloor', verbose_name='Room__location_floor'), + ), + migrations.AddField( + model_name='room', + name='location_state', + field=models.CharField(choices=[('none', 'Assembly__location_state-none'), ('draft', 'Assembly__location_state-draft'), ('rough', 'Assembly__location_state-rough'), ('preview', 'Assembly__location_state-preview'), ('final', 'Assembly__location_state-final')], default='none', help_text='Room__location_state__help', max_length=20, verbose_name='Room__location_state'), + ), + ] diff --git a/src/core/models/rooms.py b/src/core/models/rooms.py index cef75f46a..a0fdf8146 100644 --- a/src/core/models/rooms.py +++ b/src/core/models/rooms.py @@ -1,3 +1,4 @@ +import json import uuid from datetime import datetime from pathlib import Path @@ -153,6 +154,27 @@ class Room(BackendMixin, models.Model): room_type = models.CharField(max_length=20, choices=RoomType.choices, help_text=_('Room__type__help'), verbose_name=_('Room__type')) """Style of the room.""" + location_state = models.CharField( + max_length=20, + choices=Assembly.LocationState.choices, + default=Assembly.LocationState.NONE, + help_text=_('Room__location_state__help'), + verbose_name=_('Room__location_state'), + ) + location_floor = models.ForeignKey( + 'MapFloor', + blank=True, + null=True, + related_name='rooms', + on_delete=models.PROTECT, + help_text=_('Room__location_floor__help'), + verbose_name=_('Room__location_floor'), + ) + location_data = models.JSONField( + blank=True, + null=True, + ) + backend_link = models.URLField(blank=True, null=True, help_text=_('Room__backend_link__help'), verbose_name=_('Room__backend_link')) """Reference to integration/source system. For e.g. WorkAdventure this is the collection JSON URL.""" @@ -301,6 +323,29 @@ class Room(BackendMixin, models.Model): def generate_slug(self): self.slug = self.__create_slug() + def get_location_floor_index(self) -> int | None: + return self.location_floor.index if self.location_floor else None + + def get_location_point_xy(self) -> tuple[int, int] | None: + if self.location_data is None: + return None + if p := self.location_data.get('point'): + return p[0], p[1] + return None + + def get_location_point_as_json(self) -> str: + return json.dumps(self.get_location_point_xy() or '') + + def get_location_boundaries_xy(self) -> list[list[tuple[int, int]]] | None: + if self.location_data is None: + return None + if b := self.location_data.get('boundaries'): + return b + return None + + def get_location_boundaries_as_json(self) -> str: + return json.dumps(self.get_location_boundaries_xy() or '') + def clean(self): if self.room_type == self.RoomType.PROJECT: raise ValidationError(_('Room__type_project_not_allowed')) -- GitLab