From 8957c2f1067a735c70c93ad7f8d413733a301faf Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 17 Feb 2020 13:15:49 +0100 Subject: [PATCH] Seating: Support custom row and seat labels --- .../migrations/0143_auto_20200217_1211.py | 28 +++++++++++++++++++ src/pretix/base/models/seating.py | 23 +++++++++++++-- src/pretix/base/services/seating.py | 4 +++ .../static/seating/seating-plan.schema.json | 10 ++++++- 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/pretix/base/migrations/0143_auto_20200217_1211.py diff --git a/src/pretix/base/migrations/0143_auto_20200217_1211.py b/src/pretix/base/migrations/0143_auto_20200217_1211.py new file mode 100644 index 0000000000..1fe1bd8d7b --- /dev/null +++ b/src/pretix/base/migrations/0143_auto_20200217_1211.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.4 on 2020-02-17 12:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0142_auto_20191215_1522'), + ] + + operations = [ + migrations.AddField( + model_name='seat', + name='row_label', + field=models.CharField(max_length=190, null=True), + ), + migrations.AddField( + model_name='seat', + name='seat_label', + field=models.CharField(max_length=190, null=True), + ), + migrations.AlterField( + model_name='giftcard', + name='secret', + field=models.CharField(db_index=True, max_length=190), + ), + ] diff --git a/src/pretix/base/models/seating.py b/src/pretix/base/models/seating.py index b2df8837be..83cafbc3f0 100644 --- a/src/pretix/base/models/seating.py +++ b/src/pretix/base/models/seating.py @@ -40,7 +40,7 @@ class SeatingPlan(LoggedModel): layout = models.TextField(validators=[SeatingPlanLayoutValidator()]) Category = namedtuple('Categrory', 'name') - RawSeat = namedtuple('Seat', 'name guid number row category zone sorting_rank') + RawSeat = namedtuple('Seat', 'name guid number row category zone sorting_rank row_label seat_label') def __str__(self): return self.name @@ -69,11 +69,17 @@ class SeatingPlan(LoggedModel): # optimization, because this way we do not need to update the rank of very seat if we change a plan a little. for zi, z in enumerate(self.layout_data['zones']): for ri, r in enumerate(z['rows']): + row_label = None + if r.get('row_label'): + row_label = r['row_label'].replace("%s", r.get('row_number', str(ri))) try: row_rank = int(r['row_number']) except ValueError: row_rank = ri for si, s in enumerate(r['seats']): + seat_label = None + if r.get('seat_label'): + seat_label = r['seat_label'].replace("%s", s.get('seat_number', str(si))) try: seat_rank = int(s['seat_number']) except ValueError: @@ -87,6 +93,8 @@ class SeatingPlan(LoggedModel): guid=s['seat_guid'], name='{} {}'.format(r['row_number'], s['seat_number']), # TODO: Zone? Variable scheme? row=r['row_number'], + row_label=row_label, + seat_label=seat_label, zone=z['name'], category=s['category'], sorting_rank=rank @@ -114,7 +122,9 @@ class Seat(models.Model): name = models.CharField(max_length=190) zone_name = models.CharField(max_length=190, blank=True, default="") row_name = models.CharField(max_length=190, blank=True, default="") + row_label = models.CharField(max_length=190, null=True) seat_number = models.CharField(max_length=190, blank=True, default="") + seat_label = models.CharField(max_length=190, null=True) seat_guid = models.CharField(max_length=190, db_index=True) product = models.ForeignKey('Item', null=True, blank=True, related_name='seats', on_delete=models.CASCADE) blocked = models.BooleanField(default=False) @@ -127,10 +137,17 @@ class Seat(models.Model): parts = [] if self.zone_name: parts.append(self.zone_name) - if self.row_name: + + if self.row_label: + parts.append(self.row_label) + elif self.row_name: parts.append(gettext('Row {number}').format(number=self.row_name)) - if self.seat_number: + + if self.seat_label: + parts.append(self.seat_label) + elif self.seat_number: parts.append(gettext('Seat {number}').format(number=self.seat_number)) + if not parts: return self.name return ', '.join(parts) diff --git a/src/pretix/base/services/seating.py b/src/pretix/base/services/seating.py index 093a51bc75..a735471b42 100644 --- a/src/pretix/base/services/seating.py +++ b/src/pretix/base/services/seating.py @@ -65,6 +65,8 @@ def generate_seats(event, subevent, plan, mapping): update(seat, 'seat_number', ss.number), update(seat, 'zone_name', ss.zone), update(seat, 'sorting_rank', ss.sorting_rank), + update(seat, 'row_label', ss.row_label), + update(seat, 'seat_label', ss.seat_label), ]) if updated: seat.save() @@ -78,6 +80,8 @@ def generate_seats(event, subevent, plan, mapping): seat_number=ss.number, zone_name=ss.zone, sorting_rank=ss.sorting_rank, + row_label=ss.row_label, + seat_label=ss.seat_label, product=p, )) diff --git a/src/pretix/static/seating/seating-plan.schema.json b/src/pretix/static/seating/seating-plan.schema.json index 3f81df0708..ce6282b871 100644 --- a/src/pretix/static/seating/seating-plan.schema.json +++ b/src/pretix/static/seating/seating-plan.schema.json @@ -29,7 +29,7 @@ "additionalProperties": false } }, - "required": ["zones", "name", "categories"], + "required": ["zones", "name", "categories", "size"], "additionalProperties": false, "definitions": { "zone": { @@ -69,6 +69,14 @@ "type": "string", "description": "Row number or name by which it can be identified" }, + "row_label": { + "type": ["string", "null"], + "description": "Human-readable name for the row. May include %s as a placeholder for the row_number value. Not used for rendering the plan, but for describing the seats in text." + }, + "seat_label": { + "type": ["string", "null"], + "description": "Human-readable name for the seats in this. May include %s as a placeholder for the seat_number values. Not used for rendering the plan, but for describing the seats in text." + }, "seats": { "type": "array", "description": "List of seats in this row",