mirror of
https://github.com/pretix/pretix.git
synced 2026-05-06 15:24:02 +00:00
Order import: Respect sales channel when validating seats (#4707)
This commit is contained in:
@@ -585,7 +585,7 @@ class SeatColumn(ImportColumn):
|
|||||||
raise ValidationError(_('Multiple matching seats were found.'))
|
raise ValidationError(_('Multiple matching seats were found.'))
|
||||||
except Seat.DoesNotExist:
|
except Seat.DoesNotExist:
|
||||||
raise ValidationError(_('No matching seat was found.'))
|
raise ValidationError(_('No matching seat was found.'))
|
||||||
if not value.is_available() or value in self._cached:
|
if not value.is_available(sales_channel=previous_values.get('sales_channel')) or value in self._cached:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_('The seat you selected has already been taken. Please select a different seat.'))
|
_('The seat you selected has already been taken. Please select a different seat.'))
|
||||||
self._cached.add(value)
|
self._cached.add(value)
|
||||||
@@ -754,11 +754,11 @@ def get_order_import_columns(event):
|
|||||||
AttendeeState(event),
|
AttendeeState(event),
|
||||||
Price(event),
|
Price(event),
|
||||||
Secret(event),
|
Secret(event),
|
||||||
|
Saleschannel(event),
|
||||||
SeatColumn(event),
|
SeatColumn(event),
|
||||||
ValidFrom(event),
|
ValidFrom(event),
|
||||||
ValidUntil(event),
|
ValidUntil(event),
|
||||||
Locale(event),
|
Locale(event),
|
||||||
Saleschannel(event),
|
|
||||||
CheckinAttentionColumn(event),
|
CheckinAttentionColumn(event),
|
||||||
CheckinTextColumn(event),
|
CheckinTextColumn(event),
|
||||||
Expires(event),
|
Expires(event),
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
c.assign(record.get(c.identifier), order, position, order._address)
|
c.assign(record.get(c.identifier), order, position, order._address)
|
||||||
|
|
||||||
if position.seat is not None:
|
if position.seat is not None:
|
||||||
lock_seats.append(position.seat)
|
lock_seats.append((order.sales_channel, position.seat))
|
||||||
except (ValidationError, ImportError) as e:
|
except (ValidationError, ImportError) as e:
|
||||||
raise DataImportError(
|
raise DataImportError(
|
||||||
_('Invalid data in row {row}: {message}').format(row=i, message=str(e))
|
_('Invalid data in row {row}: {message}').format(row=i, message=str(e))
|
||||||
@@ -128,9 +128,9 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# We don't support vouchers, quotas, or memberships here, so we only need to lock if seats are in use
|
# We don't support vouchers, quotas, or memberships here, so we only need to lock if seats are in use
|
||||||
if lock_seats:
|
if lock_seats:
|
||||||
lock_objects(lock_seats, shared_lock_objects=[event])
|
lock_objects([s for c, s in lock_seats], shared_lock_objects=[event])
|
||||||
for s in lock_seats:
|
for c, s in lock_seats:
|
||||||
if not s.is_available():
|
if not s.is_available(sales_channel=c):
|
||||||
raise DataImportError(_('The seat you selected has already been taken. Please select a different seat.'))
|
raise DataImportError(_('The seat you selected has already been taken. Please select a different seat.'))
|
||||||
|
|
||||||
save_transactions = []
|
save_transactions = []
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ def inputfile_factory(multiplier=1):
|
|||||||
'I': 'Foo',
|
'I': 'Foo',
|
||||||
'J': '2021-06-28 11:00:00',
|
'J': '2021-06-28 11:00:00',
|
||||||
'K': '06221/32177-50',
|
'K': '06221/32177-50',
|
||||||
'L': 'True'
|
'L': 'True',
|
||||||
|
'M': 'baz',
|
||||||
|
'N': 'Seat-1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'A': 'Daniel',
|
'A': 'Daniel',
|
||||||
@@ -87,6 +89,8 @@ def inputfile_factory(multiplier=1):
|
|||||||
'J': '2021-06-28 11:00:00',
|
'J': '2021-06-28 11:00:00',
|
||||||
'K': '+4962213217750',
|
'K': '+4962213217750',
|
||||||
'L': 'False',
|
'L': 'False',
|
||||||
|
'M': 'baz',
|
||||||
|
'N': 'Seat-2',
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
@@ -102,12 +106,14 @@ def inputfile_factory(multiplier=1):
|
|||||||
'J': '2021-06-28 11:00:00',
|
'J': '2021-06-28 11:00:00',
|
||||||
'K': '',
|
'K': '',
|
||||||
'L': '',
|
'L': '',
|
||||||
|
'M': 'baz',
|
||||||
|
'N': 'Seat-3',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
if multiplier > 1:
|
if multiplier > 1:
|
||||||
d = d * multiplier
|
d = d * multiplier
|
||||||
f = StringIO()
|
f = StringIO()
|
||||||
w = csv.DictWriter(f, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'], dialect=csv.excel)
|
w = csv.DictWriter(f, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'], dialect=csv.excel)
|
||||||
w.writeheader()
|
w.writeheader()
|
||||||
w.writerows(d)
|
w.writerows(d)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
@@ -663,20 +669,41 @@ def test_import_seat_required(user, event, item):
|
|||||||
def test_import_seat_blocked(user, event, item):
|
def test_import_seat_blocked(user, event, item):
|
||||||
settings = dict(DEFAULT_SETTINGS)
|
settings = dict(DEFAULT_SETTINGS)
|
||||||
settings['item'] = 'static:{}'.format(item.pk)
|
settings['item'] = 'static:{}'.format(item.pk)
|
||||||
settings['seat'] = 'csv:D'
|
settings['seat'] = 'csv:N'
|
||||||
|
|
||||||
event.seat_category_mappings.create(
|
event.seat_category_mappings.create(
|
||||||
layout_category='Stalls', product=item
|
layout_category='Stalls', product=item
|
||||||
)
|
)
|
||||||
event.seats.create(seat_number="Test", product=item, seat_guid="Test", blocked=True)
|
event.seats.create(seat_number="Seat-1", product=item, seat_guid="Seat-1", blocked=True)
|
||||||
|
event.seats.create(seat_number="Seat-2", product=item, seat_guid="Seat-2", blocked=True)
|
||||||
|
event.seats.create(seat_number="Seat-3", product=item, seat_guid="Seat-3", blocked=True)
|
||||||
with pytest.raises(DataImportError) as excinfo:
|
with pytest.raises(DataImportError) as excinfo:
|
||||||
import_orders.apply(
|
import_orders.apply(
|
||||||
args=(event.pk, inputfile_factory().id, settings, 'en', user.pk)
|
args=(event.pk, inputfile_factory().id, settings, 'en', user.pk)
|
||||||
).get()
|
).get()
|
||||||
assert 'Error while importing value "Test" for column "Seat ID" in line "1": The seat you selected has already ' \
|
assert 'Error while importing value "Seat-1" for column "Seat ID" in line "1": The seat you selected has already ' \
|
||||||
'been taken. Please select a different seat.' in str(excinfo.value)
|
'been taken. Please select a different seat.' in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@scopes_disabled()
|
||||||
|
def test_import_seat_blocked_sales_channel(user, event, item):
|
||||||
|
settings = dict(DEFAULT_SETTINGS)
|
||||||
|
settings['item'] = 'static:{}'.format(item.pk)
|
||||||
|
settings['seat'] = 'csv:N'
|
||||||
|
settings['sales_channel'] = 'csv:M'
|
||||||
|
event.settings.seating_allow_blocked_seats_for_channel = ["baz"]
|
||||||
|
event.seat_category_mappings.create(
|
||||||
|
layout_category='Stalls', product=item
|
||||||
|
)
|
||||||
|
event.seats.create(seat_number="Seat-1", product=item, seat_guid="Seat-1", blocked=True)
|
||||||
|
event.seats.create(seat_number="Seat-2", product=item, seat_guid="Seat-2", blocked=True)
|
||||||
|
event.seats.create(seat_number="Seat-3", product=item, seat_guid="Seat-3", blocked=True)
|
||||||
|
import_orders.apply(
|
||||||
|
args=(event.pk, inputfile_factory().id, settings, 'en', user.pk)
|
||||||
|
).get()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def test_import_seat_dbl(user, event, item):
|
def test_import_seat_dbl(user, event, item):
|
||||||
|
|||||||
Reference in New Issue
Block a user