Skip to content
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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pretix_wallet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def get_or_create_wallet_membership_type(organizer):
organizer=organizer,
allow_parallel_usage=True,
transferable=False,
max_usages=False,
max_usages=None,
)


Expand Down
9 changes: 4 additions & 5 deletions pretix_wallet/payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ def _get_payment_info_data(self, wallet: CustomerWallet):
'retry': True
}




def execute_payment(self, request: HttpRequest, payment: OrderPayment, is_early_special_case=False) -> str:
# re-implemented as the original method does not allow for giftcards to have negative balance

Expand Down Expand Up @@ -128,7 +125,8 @@ def settings_form_fields(self):
('top_up_products', CharField(
label=_("Products used to charge wallet accounts"),
help_text=_(
"Comma separated list of English product names, Buying these products will charge a users wallet by their price. Remeber, to require the Wallet memberships for these products to force users to login."),
"Comma separated list of English product names, Buying these products will charge a users wallet by"
"their price. Remeber, to require the Wallet memberships for these products to force users to login."),
))
# ('top_up_products', MultipleChoiceField(
# widget=CheckboxSelectMultiple,
Expand All @@ -141,6 +139,7 @@ def settings_form_fields(self):
# choices=product_choices))
])


def _wallet_transaction(event, payment: OrderPayment, gift_card: GiftCard, sign=-1, amount=None):
with transaction.atomic():
if gift_card.currency != event.currency: # noqa - just a safeguard
Expand All @@ -153,4 +152,4 @@ def _wallet_transaction(event, payment: OrderPayment, gift_card: GiftCard, sign=
order=payment.order,
payment=payment,
acceptor=event.organizer,
)
)
50 changes: 48 additions & 2 deletions pretix_wallet/signals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
from django.core.exceptions import ImproperlyConfigured
from django.dispatch import receiver
from django.http import Http404
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _

from pretix.base.payment import PaymentException
from pretix.base.signals import register_payment_providers, order_paid
from pretix.helpers.http import redirect_to_url
from pretix.presale.checkoutflow import BaseCheckoutFlowStep, CartMixin, TemplateFlowStep
from pretix.presale.signals import checkout_flow_steps
from pretix.presale.views.cart import cart_session
from pretix_wallet.models import CustomerWallet

from pretix_wallet.payment import WalletPaymentProvider, _wallet_transaction
Expand All @@ -12,19 +20,57 @@ def register_payment_provider(sender, **kwargs):
return [WalletPaymentProvider]


@receiver(checkout_flow_steps, dispatch_uid="checkout_flow_steps_wallet")
def wallet_checkout_flow_steps(sender, **kwargs):
return MembershipGrantingCheckoutFlowStep


@receiver(order_paid, dispatch_uid="payment_wallet_order_paid")
def wallet_order_paid(sender, order, **kwargs):
top_up_positions = list(filter(lambda pos: position_is_top_up_product(pos), order.positions))
top_up_positions = list(filter(lambda pos: position_is_top_up_product(sender, pos), order.positions.all()))
if top_up_positions:
CustomerWallet.create_if_non_existent(sender.organizer, order.customer)
try:
top_up_value = sum(lambda pos: pos.price, top_up_positions)
top_up_value = sum(map(lambda pos: pos.price, top_up_positions))
_wallet_transaction(sender, order.payments.last(), order.customer.wallet.giftcard, sign=1,
amount=top_up_value)
except PaymentException as e:
raise e


class MembershipGrantingCheckoutFlowStep(CartMixin, BaseCheckoutFlowStep):
icon = 'user-plus'
identifier = 'wallet-membership-granting'

def label(self):
return _('Creating Wallet')

@cached_property
def priority(self):
# One less than MembershipStep
return 46

def get(self, request):
if request.event.organizer and request.customer:
CustomerWallet.create_if_non_existent(request.event.organizer, request.customer)
return redirect_to_url(self.get_next_url(request))
else:
raise ImproperlyConfigured('User reached the wallet creation step without signing in.'
'Have you created customer accounts and required membership'
'for the top-up product?')

def is_completed(self, request, warn=False):
if self.request.customer.wallet:
Copy link
Contributor

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

Copy link
Collaborator Author

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.

return True
return False

def is_applicable(self, request):
self.request = request
if not request.event.settings.get("payment_wallet_top_up_products"):
return False
return any(map(lambda pos: position_is_top_up_product(request.event, pos), self.positions))


def position_is_top_up_product(event, position):
top_up_products = event.settings.get("payment_wallet_top_up_products").lower().split(',')
product_name = position.item.name.localize('en').lower()
Expand Down
Loading