Deal with cancelling memberships (#2130)

This commit is contained in:
Raphael Michel
2021-06-17 18:10:45 +02:00
committed by GitHub
parent 8ad53256c2
commit 1ef076bb9b
13 changed files with 153 additions and 2 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.3 on 2021-06-17 10:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0193_auto_20210611_1355'),
]
operations = [
migrations.AddField(
model_name='membership',
name='canceled',
field=models.BooleanField(default=False),
),
]

View File

@@ -118,6 +118,10 @@ class Membership(models.Model):
verbose_name=_('Test mode'),
default=False
)
canceled = models.BooleanField(
verbose_name=_('Canceled'),
default=False
)
customer = models.ForeignKey(
Customer,
related_name='memberships',

View File

@@ -599,6 +599,8 @@ class Order(LockModel, LoggedModel):
for gc in op.issued_gift_cards.all():
if gc.value != op.price:
return False
if op.granted_memberships.with_usages().filter(usages__gt=0):
return False
if self.user_cancel_deadline and now() > self.user_cancel_deadline:
return False
if self.status == Order.STATUS_PENDING:

View File

@@ -141,6 +141,11 @@ def validate_memberships_in_order(customer: Customer, positions: List[AbstractPo
_('You selected a membership that is connected to a different customer account.')
)
if m.canceled:
raise ValidationError(
_('You selected membership that has been canceled.')
)
if m.testmode != testmode:
raise ValidationError(
_('You can only use a test mode membership for test mode tickets.')

View File

@@ -177,6 +177,10 @@ def reactivate_order(order: Order, force: bool=False, user: User=None, auth=None
gc = GiftCard.objects.select_for_update().get(pk=gc.pk)
gc.transactions.create(value=position.price, order=order)
break
for m in position.granted_memberships.all():
m.canceled = False
m.save()
else:
raise OrderError(is_available)
@@ -410,6 +414,10 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
else:
gc.transactions.create(value=-position.price, order=order)
for m in position.granted_memberships.all():
m.canceled = True
m.save()
if cancellation_fee:
with order.event.lock():
for position in order.positions.all():
@@ -1768,7 +1776,26 @@ class OrderChangeManager:
else:
gc.transactions.create(value=-op.position.price, order=self.order)
for m in op.position.granted_memberships.with_usages().all():
m.canceled = True
m.save()
for opa in op.position.addons.all():
for gc in opa.issued_gift_cards.all():
gc = GiftCard.objects.select_for_update().get(pk=gc.pk)
if gc.value < opa.position.price:
raise OrderError(_(
'A position can not be canceled since the gift card {card} purchased in this order has '
'already been redeemed.').format(
card=gc.secret
))
else:
gc.transactions.create(value=-opa.position.price, order=self.order)
for m in opa.granted_memberships.with_usages().all():
m.canceled = True
m.save()
self.order.log_action('pretix.event.order.changed.cancel', user=self.user, auth=self.auth, data={
'position': opa.pk,
'positionid': opa.positionid,

View File

@@ -560,7 +560,7 @@ class MembershipUpdateForm(forms.ModelForm):
class Meta:
model = Membership
fields = ['testmode', 'membership_type', 'date_start', 'date_end', 'attendee_name_parts']
fields = ['testmode', 'membership_type', 'date_start', 'date_end', 'attendee_name_parts', 'canceled']
field_classes = {
'date_start': SplitDateTimeField,
'date_end': SplitDateTimeField,

View File

@@ -81,7 +81,9 @@
{% for m in memberships %}
<tr>
<td>
{% if m.canceled %}<del>{% endif %}
{{ m.membership_type.name }}
{% if m.canceled %}</del>{% endif %}
{% if m.testmode %}<span class="label label-warning">{% trans "TEST MODE" %}</span>{% endif %}
</td>
<td>

View File

@@ -1891,7 +1891,6 @@ class MembershipDeleteView(OrganizerDetailViewMixin, OrganizerPermissionRequired
template_name = 'pretixcontrol/organizers/customer_membership_delete.html'
permission = 'can_manage_customers'
context_object_name = 'membership'
form_class = MembershipUpdateForm
def get_object(self, queryset=None):
return get_object_or_404(

View File

@@ -376,6 +376,7 @@ class MembershipStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
memberships = list(self.cart_customer.memberships.with_usages().filter(
Q(Q(membership_type__max_usages__isnull=True) | Q(usages__lt=F('membership_type__max_usages'))),
canceled=False
).select_related('membership_type'))
for p in self.applicable_positions:

View File

@@ -58,7 +58,9 @@
{% for m in memberships %}
<tr>
<td>
{% if m.canceled %}<del>{% endif %}
{{ m.membership_type.name }}
{% if m.canceled %}</del>{% endif %}
{% if m.testmode %}<span class="label label-warning">{% trans "TEST MODE" %}</span>{% endif %}
</td>
<td>