forked from CGM_Public/pretix_original
Introduce Seat.sorting_rank (#1499)
* Introduce Seat.sorting_rank * Fix comments * Comments, for real
This commit is contained in:
18
src/pretix/base/migrations/0141_seat_sorting_rank.py
Normal file
18
src/pretix/base/migrations/0141_seat_sorting_rank.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 2.2.4 on 2019-11-22 11:42
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pretixbase', '0140_voucher_seat'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='seat',
|
||||||
|
name='sorting_rank',
|
||||||
|
field=models.BigIntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -40,7 +40,7 @@ class SeatingPlan(LoggedModel):
|
|||||||
layout = models.TextField(validators=[SeatingPlanLayoutValidator()])
|
layout = models.TextField(validators=[SeatingPlanLayoutValidator()])
|
||||||
|
|
||||||
Category = namedtuple('Categrory', 'name')
|
Category = namedtuple('Categrory', 'name')
|
||||||
RawSeat = namedtuple('Seat', 'name guid number row category zone')
|
RawSeat = namedtuple('Seat', 'name guid number row category zone sorting_rank')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -60,16 +60,36 @@ class SeatingPlan(LoggedModel):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def iter_all_seats(self):
|
def iter_all_seats(self):
|
||||||
for z in self.layout_data['zones']:
|
# This returns all seats in a plan and assignes each of them a rank. The rank is used for sorting lists of
|
||||||
for r in z['rows']:
|
# seats later. The rank does not say anything about the *quality* of a seat, and is only meant as a heuristic
|
||||||
for s in r['seats']:
|
# to make it easier for humas to process lists of seats. The current algorithm assumes that there are less
|
||||||
|
# than 10'000 zones, less than 10'000 rows in every zone and less than 10'000 seats in every row.
|
||||||
|
# Respectively, no row/seat numbers may be numeric with a value of 10'000 or more. The resulting ranks
|
||||||
|
# *will* have gaps. We chose this way over just sorting the seats and continuously enumerating them as an
|
||||||
|
# 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']):
|
||||||
|
try:
|
||||||
|
row_rank = int(r['row_number'])
|
||||||
|
except ValueError:
|
||||||
|
row_rank = ri
|
||||||
|
for si, s in enumerate(r['seats']):
|
||||||
|
try:
|
||||||
|
seat_rank = int(s['seat_number'])
|
||||||
|
except ValueError:
|
||||||
|
seat_rank = si
|
||||||
|
rank = (
|
||||||
|
10000 * 10000 * zi + 10000 * row_rank + seat_rank
|
||||||
|
)
|
||||||
|
|
||||||
yield self.RawSeat(
|
yield self.RawSeat(
|
||||||
number=s['seat_number'],
|
number=s['seat_number'],
|
||||||
guid=s['seat_guid'],
|
guid=s['seat_guid'],
|
||||||
name='{} {}'.format(r['row_number'], s['seat_number']), # TODO: Zone? Variable scheme?
|
name='{} {}'.format(r['row_number'], s['seat_number']), # TODO: Zone? Variable scheme?
|
||||||
row=r['row_number'],
|
row=r['row_number'],
|
||||||
zone=z['name'],
|
zone=z['name'],
|
||||||
category=s['category']
|
category=s['category'],
|
||||||
|
sorting_rank=rank
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -98,6 +118,10 @@ class Seat(models.Model):
|
|||||||
seat_guid = models.CharField(max_length=190, db_index=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)
|
product = models.ForeignKey('Item', null=True, blank=True, related_name='seats', on_delete=models.CASCADE)
|
||||||
blocked = models.BooleanField(default=False)
|
blocked = models.BooleanField(default=False)
|
||||||
|
sorting_rank = models.BigIntegerField(default=0)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['sorting_rank', 'seat_guid']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
parts = []
|
parts = []
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ def generate_seats(event, subevent, plan, mapping):
|
|||||||
update(seat, 'row_name', ss.row),
|
update(seat, 'row_name', ss.row),
|
||||||
update(seat, 'seat_number', ss.number),
|
update(seat, 'seat_number', ss.number),
|
||||||
update(seat, 'zone_name', ss.zone),
|
update(seat, 'zone_name', ss.zone),
|
||||||
|
update(seat, 'sorting_rank', ss.sorting_rank),
|
||||||
])
|
])
|
||||||
if updated:
|
if updated:
|
||||||
seat.save()
|
seat.save()
|
||||||
@@ -63,6 +64,7 @@ def generate_seats(event, subevent, plan, mapping):
|
|||||||
row_name=ss.row,
|
row_name=ss.row,
|
||||||
seat_number=ss.number,
|
seat_number=ss.number,
|
||||||
zone_name=ss.zone,
|
zone_name=ss.zone,
|
||||||
|
sorting_rank=ss.sorting_rank,
|
||||||
product=p,
|
product=p,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user