Do not remove unavailable addons when changing order (Z#23150855) (#4086)

This commit is contained in:
Raphael Michel
2024-04-29 18:11:20 +02:00
committed by GitHub
parent 11a038feb3
commit 247c4c6c9c
2 changed files with 55 additions and 1 deletions

View File

@@ -2013,6 +2013,20 @@ class OrderChangeManager:
for a in current_addons[cp][k][:current_num - input_num]:
if a.canceled:
continue
is_unavailable = (
# If an item is no longer available due to time, it should usually also be no longer
# user-removable, because e.g. the stock has already been ordered.
# We always pass has_voucher=True because if a product now requires a voucher, it usually does
# not mean it should be unremovable for others.
# This also prevents accidental removal through the UI because a hidden product will no longer
# be part of the input.
(a.variation and a.variation.unavailability_reason(has_voucher=True, subevent=a.subevent))
or (a.variation and self.order.sales_channel not in a.variation.sales_channels)
or a.item.unavailability_reason(has_voucher=True, subevent=a.subevent)
or self.order.sales_channel not in item.sales_channels
)
if is_unavailable:
continue
if a.checkins.filter(list__consider_tickets_used=True).exists():
raise OrderError(
error_messages['addon_already_checked_in'] % {

View File

@@ -993,6 +993,47 @@ class OrderChangeAddonsTest(BaseOrdersTest):
self.order.refresh_from_db()
assert self.order.total == Decimal('23.00')
def test_do_not_remove_unavailable_on_adding(self):
self.iao.max_count = 2
self.iao.save()
self.workshop1.available_until = now() - datetime.timedelta(days=1)
self.workshop1.save()
with scopes_disabled():
OrderPosition.objects.create(
order=self.order,
item=self.workshop1,
variation=None,
price=Decimal("12"),
addon_to=self.ticket_pos,
attendee_name_parts={'full_name': "Peter"}
)
self.order.total += Decimal("12")
self.order.save()
response = self.client.get(
'/%s/%s/order/%s/%s/change' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret)
)
assert response.status_code == 200
assert 'Workshop 1' not in response.content.decode()
response = self.client.post(
'/%s/%s/order/%s/%s/change' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret),
{
f'cp_{self.ticket_pos.pk}_variation_{self.workshop2.pk}_{self.workshop2a.pk}': '1'
},
follow=True
)
doc = BeautifulSoup(response.content.decode(), "lxml")
form_data = extract_form_fields(doc.select('.main-box form')[0])
form_data['confirm'] = 'true'
response = self.client.post(
'/%s/%s/order/%s/%s/change' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret), form_data, follow=True
)
assert 'alert-success' in response.content.decode()
with scopes_disabled():
assert self.ticket_pos.addons.count() == 2
def test_remove_addon_checked_in(self):
with scopes_disabled():
self.event.settings.change_allow_user_if_checked_in = True
@@ -1578,7 +1619,6 @@ class OrderChangeAddonsTest(BaseOrdersTest):
},
follow=True
)
print(response.content.decode())
assert 'alert-danger' not in response.content.decode()
response = self.client.post(