diff --git a/src/core/admin.py b/src/core/admin.py index c00e2f344b16a5603d58bd58a4a1ca6cb4c48b4d..6f45d562bfa6f2860dea297ee05701d75e0dc1e2 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 54605f17f955c3b137a75835b2e6c296b318595e..5f859b6dbd58c8f833ba236dd80a63ccaa6c2602 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 d5c6b5e3d29d407e90a308af459a86bdf22ae8f1..a2be9e62b7a53bc5502bfd2de34bbe866affb35d 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 0000000000000000000000000000000000000000..6b96922c16b62a4f8018c676a3f13394a5201e77 --- /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 cef75f46a77b2b89f46a675ac1a6e2c22217d303..a0fdf814675cb8975719fedd00b62d88bca31869 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'))