diff --git a/src/pretix/base/migrations/0130_auto_20190729_1311.py b/src/pretix/base/migrations/0130_auto_20190729_1311.py new file mode 100644 index 0000000000..47f973faad --- /dev/null +++ b/src/pretix/base/migrations/0130_auto_20190729_1311.py @@ -0,0 +1,31 @@ +# Generated by Django 2.2.1 on 2019-07-29 13:11 + +import django.db.models.deletion +from django.db import migrations, models + +import pretix.base.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0129_auto_20190724_1548'), + ] + + operations = [ + migrations.AddField( + model_name='seat', + name='row_name', + field=models.CharField(default='', max_length=190), + ), + migrations.AddField( + model_name='seat', + name='seat_number', + field=models.CharField(default='', max_length=190), + ), + migrations.AddField( + model_name='seat', + name='zone_name', + field=models.CharField(default='', max_length=190), + ), + ] diff --git a/src/pretix/base/models/seating.py b/src/pretix/base/models/seating.py index a62923fec4..bc56004155 100644 --- a/src/pretix/base/models/seating.py +++ b/src/pretix/base/models/seating.py @@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError from django.db import models from django.utils.deconstruct import deconstructible from django.utils.timezone import now -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext, ugettext_lazy as _ from pretix.base.models import Event, Item, LoggedModel, Organizer, SubEvent @@ -39,7 +39,7 @@ class SeatingPlan(LoggedModel): layout = models.TextField(validators=[SeatingPlanLayoutValidator()]) Category = namedtuple('Categrory', 'name') - RawSeat = namedtuple('Seat', 'name guid number row category') + RawSeat = namedtuple('Seat', 'name guid number row category zone') def __str__(self): return self.name @@ -67,6 +67,7 @@ class SeatingPlan(LoggedModel): guid=s['seat_guid'], name='{} {}'.format(r['row_number'], s['seat_number']), # TODO: Zone? Variable scheme? row=r['row_number'], + zone=z['name'], category=s['category'] ) @@ -90,12 +91,24 @@ class Seat(models.Model): event = models.ForeignKey(Event, related_name='seats', on_delete=models.CASCADE) subevent = models.ForeignKey(SubEvent, null=True, blank=True, related_name='seats', on_delete=models.CASCADE) 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="") + seat_number = models.CharField(max_length=190, blank=True, default="") 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) def __str__(self): - return self.name + parts = [] + if self.zone_name: + parts.append(self.zone_name) + if self.row_name: + parts.append(gettext('Row {number}').format(number=self.row_name)) + if self.seat_number: + parts.append(gettext('Seat {number}').format(number=self.seat_number)) + if not parts: + return self.name + return ', '.join(parts) def is_available(self, ignore_cart=None, ignore_orderpos=None): from .orders import Order diff --git a/src/pretix/base/pdf.py b/src/pretix/base/pdf.py index 29024e2841..72bfd5d7cc 100644 --- a/src/pretix/base/pdf.py +++ b/src/pretix/base/pdf.py @@ -239,10 +239,25 @@ DEFAULT_VARIABLES = OrderedDict(( ) if ev.date_admission else "" }), ("seat", { - "label": _("Seat name"), - "editor_sample": _("3, 4-5"), + "label": _("Seat: Full name"), + "editor_sample": _("Ground floor, Row 3, Seat 4"), "evaluate": lambda op, order, ev: str(op.seat if op.seat else _('General admission')) }), + ("seat_zone", { + "label": _("Seat: zone"), + "editor_sample": _("Ground floor"), + "evaluate": lambda op, order, ev: str(op.seat.zone_name if op.seat else _('General admission')) + }), + ("seat_row", { + "label": _("Seat: row"), + "editor_sample": "3", + "evaluate": lambda op, order, ev: str(op.seat.row_name if op.seat else "") + }), + ("seat_number", { + "label": _("Seat: seat number"), + "editor_sample": 4, + "evaluate": lambda op, order, ev: str(op.seat.number if op.seat else "") + }), )) diff --git a/src/pretix/base/services/seating.py b/src/pretix/base/services/seating.py index 1526c4e2a7..bd2b457410 100644 --- a/src/pretix/base/services/seating.py +++ b/src/pretix/base/services/seating.py @@ -29,14 +29,27 @@ def generate_seats(event, subevent, plan, mapping): s.seat_guid: s for s in event.seats.select_related('product').annotate(has_op=Count('orderposition')).filter(subevent=subevent) } + + def update(o, a, v): + if getattr(o, a) != v: + setattr(o, a, v) + return True + return False + create_seats = [] if plan: for ss in plan.iter_all_seats(): p = mapping.get(ss.category) if ss.guid in current_seats: seat = current_seats.pop(ss.guid) - if seat.product != p: - seat.product = p + updated = any([ + update(seat, 'product', p), + update(seat, 'name', ss.name), + update(seat, 'row_name', ss.row), + update(seat, 'seat_number', ss.number), + update(seat, 'zone_name', ss.zone), + ]) + if updated: seat.save() else: create_seats.append(Seat( @@ -44,6 +57,9 @@ def generate_seats(event, subevent, plan, mapping): subevent=subevent, seat_guid=ss.guid, name=ss.name, + row_name=ss.row, + seat_number=ss.number, + zone_name=ss.zone, product=p, ))