-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Top Up Products #12
base: main
Are you sure you want to change the base?
Top Up Products #12
Conversation
What's still left todo: How to integrate this into the front end?
|
def get_or_create_wallet_membership_type(organizer): | ||
membership_type = organizer.membership_types.filter(name=membership_type_name_for_organizer(organizer)).first() | ||
|
||
if membership_type is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.filter(...).exists() is the prettier sytnax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I read the docs correctly, that doesn't give me the object (which I want to return, because I use it in lines 49 and 53). But in line 49, I can use exists
. I've changed that.
try: | ||
gc = GiftCard.objects.select_for_update(of=OF_SELF).get(pk=gcpk) | ||
except GiftCard.DoesNotExist: | ||
raise PaymentException(_("This gift card does not support this currency.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exception text is wrong (not your fault)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should it say?
payment.info_data['transaction_id'] = trans.pk | ||
payment.confirm(send_mail=not is_early_special_case, generate_invoice=not is_early_special_case) | ||
try: | ||
gc = GiftCard.objects.select_for_update(of=OF_SELF).get(pk=gcpk) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.get() evaluates the queryset, which activates the lock. if you want to keep it locked, the evaluation needs to happen inside the same transaction as the other operations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason to keep the lock? Shouldn't the lock around the write part be enough? Ore are you worried about the gift card changing owners?
pretix_wallet/signals.py
Outdated
|
||
@receiver(order_paid, dispatch_uid="payment_wallet_order_paid") | ||
def wallet_order_paid(sender, order, **kwargs): | ||
CustomerWallet.create_if_non_existent(sender.organizer, order.customer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all of this should only happen if there is a topup product
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -115,3 +108,11 @@ def create(self, request, *args, **kwargs): | |||
serializer.is_valid(raise_exception=True) | |||
self.perform_create(serializer) | |||
return Response(WalletSerializer(self.wallet).data, status=HTTP_201_CREATED) | |||
|
|||
|
|||
class WalletRequiredRedirectView(CustomerRequiredMixin, WalletRequiredMixin, View): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll keep this until we've verified the checkout step actually works. If that's the case, we can remove it.
'for the top-up product?') | ||
|
||
def is_completed(self, request, warn=False): | ||
if self.request.customer.wallet: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC this raises if not existent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should never happen (see get
). This I intended this to raise as this ever happening is a bug. Then, some of our central assumptions must be pretty wrong.
By marking a pretix products as "top up", buying them will charge a users wallet by their value. This PR also introduces a wallet membership type, automatically creates and assigns it to wallet users. You can use this to ensure users buying top up products are forced to sign in.
It also introduces a redirect url route using which you can funnel users through the wallet login and them redirect them to an arbitrary target. This is useful for linking users to top-up shops since it ensures the correct data (user, wallet, membership type, membership) are created before the user enters the shop.