Esempio n. 1
0
    def post(self, request, *args, **kwargs):
        self.request = request
        for p in self.provider_forms:
            if p['provider'].identifier == request.POST.get('payment', ''):
                request.session['payment'] = p['provider'].identifier
                request.session['payment_change_{}'.format(self.order.pk)] = '1'

                with transaction.atomic():
                    old_fee, new_fee, fee, newpayment = change_payment_provider(self.order, p['provider'], None)

                resp = p['provider'].payment_prepare(request, newpayment)
                if isinstance(resp, str):
                    return redirect(resp)
                elif resp is True:
                    return redirect(self.get_confirm_url(newpayment))
                else:
                    return self.get(request, *args, **kwargs)
        messages.error(self.request, _("Please select a payment method."))
        return self.get(request, *args, **kwargs)
Esempio n. 2
0
    def post(self, request, *args, **kwargs):
        self.request = request
        oldtotal = self.order.total
        for p in self.provider_forms:
            if p['provider'].identifier == request.POST.get('payment', ''):
                request.session['payment'] = p['provider'].identifier
                request.session['payment_change_{}'.format(
                    self.order.pk)] = '1'

                with transaction.atomic():
                    old_fee, new_fee, fee = change_payment_provider(
                        self.order, p['provider'], None)
                    newpayment = self.order.payments.create(
                        state=OrderPayment.PAYMENT_STATE_CREATED,
                        provider=p['provider'].identifier,
                        amount=self.order.pending_sum,
                        fee=fee)
                    self.order.log_action(
                        'pretix.event.order.payment.changed'
                        if self.open_payment else
                        'pretix.event.order.payment.started', {
                            'fee': new_fee,
                            'old_fee': old_fee,
                            'provider': newpayment.provider,
                            'payment': newpayment.pk,
                            'local_id': newpayment.local_id,
                        })
                    i = self.order.invoices.filter(
                        is_cancellation=False).last()
                    if i and self.order.total != oldtotal:
                        generate_cancellation(i)
                        generate_invoice(self.order)

                resp = p['provider'].payment_prepare(request, newpayment)
                if isinstance(resp, str):
                    return redirect(resp)
                elif resp is True:
                    return redirect(self.get_confirm_url(newpayment))
                else:
                    return self.get(request, *args, **kwargs)
        messages.error(self.request, _("Please select a payment method."))
        return self.get(request, *args, **kwargs)
Esempio n. 3
0
    def post(self, request, *args, **kwargs):
        self.request = request
        oldtotal = self.order.total
        for p in self.provider_forms:
            if p['provider'].identifier == request.POST.get('payment', ''):
                request.session['payment'] = p['provider'].identifier
                request.session['payment_change_{}'.format(self.order.pk)] = '1'

                with transaction.atomic():
                    old_fee, new_fee, fee = change_payment_provider(self.order, p['provider'], None)
                    newpayment = self.order.payments.create(
                        state=OrderPayment.PAYMENT_STATE_CREATED,
                        provider=p['provider'].identifier,
                        amount=self.order.pending_sum,
                        fee=fee
                    )
                    self.order.log_action(
                        'pretix.event.order.payment.changed' if self.open_payment else 'pretix.event.order.payment.started',
                        {
                            'fee': new_fee,
                            'old_fee': old_fee,
                            'provider': newpayment.provider,
                            'payment': newpayment.pk,
                            'local_id': newpayment.local_id,
                        }
                    )
                    i = self.order.invoices.filter(is_cancellation=False).last()
                    if i and self.order.total != oldtotal:
                        generate_cancellation(i)
                        generate_invoice(self.order)

                resp = p['provider'].payment_prepare(request, newpayment)
                if isinstance(resp, str):
                    return redirect(resp)
                elif resp is True:
                    return redirect(self.get_confirm_url(newpayment))
                else:
                    return self.get(request, *args, **kwargs)
        messages.error(self.request, _("Please select a payment method."))
        return self.get(request, *args, **kwargs)
Esempio n. 4
0
def _handle_transaction(trans: BankTransaction,
                        matches: tuple,
                        event: Event = None,
                        organizer: Organizer = None):
    orders = []
    if event:
        for slug, code in matches:
            order = _find_order_for_code(event.orders, code)
            if order and order.code not in {o.code for o in orders}:
                orders.append(order)
    else:
        qs = Order.objects.filter(event__organizer=organizer)
        for slug, code in matches:
            order = _find_order_for_code(qs.filter(event__slug__iexact=slug),
                                         code)
            if order and order.code not in {o.code for o in orders}:
                orders.append(order)

    if not orders:
        # No match
        trans.state = BankTransaction.STATE_NOMATCH
        trans.save()
        return
    else:
        trans.order = orders[0]

    for o in orders:
        if o.status == Order.STATUS_PAID and o.pending_sum <= Decimal('0.00'):
            trans.state = BankTransaction.STATE_DUPLICATE
            trans.save()
            return
        elif o.status == Order.STATUS_CANCELED:
            trans.state = BankTransaction.STATE_ERROR
            trans.message = gettext_noop(
                'The order has already been canceled.')
            trans.save()
            return

    if len(orders) > 1:
        # Multi-match! Can we split this automatically?
        order_pending_sum = sum(o.pending_sum for o in orders)
        if order_pending_sum != trans.amount:
            # we can't :( this needs to be dealt with by a human
            trans.state = BankTransaction.STATE_NOMATCH
            trans.message = gettext_noop(
                'Automatic split to multiple orders not possible.')
            trans.save()
            return

        # we can!
        splits = [(o, o.pending_sum) for o in orders]
    else:
        splits = [(orders[0], trans.amount)]

    trans.state = BankTransaction.STATE_VALID
    for order, amount in splits:
        try:
            p, created = order.payments.get_or_create(
                amount=amount,
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED,
                           OrderPayment.PAYMENT_STATE_PENDING),
                defaults={
                    'state': OrderPayment.PAYMENT_STATE_CREATED,
                })
        except OrderPayment.MultipleObjectsReturned:
            created = False
            p = order.payments.filter(
                amount=amount,
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED,
                           OrderPayment.PAYMENT_STATE_PENDING),
            ).last()

        p.info_data = {
            'reference': trans.reference,
            'date':
            trans.date_parsed.isoformat() if trans.date_parsed else trans.date,
            'payer': trans.payer,
            'iban': trans.iban,
            'bic': trans.bic,
            'full_amount': str(trans.amount),
            'trans_id': trans.pk
        }

        if created:
            # We're perform a payment method switching on-demand here
            old_fee, new_fee, fee, p = change_payment_provider(
                order,
                p.payment_provider,
                p.amount,
                new_payment=p,
                create_log=False)  # noqa
            if fee:
                p.fee = fee
                p.save(update_fields=['fee'])

        try:
            p.confirm()
        except Quota.QuotaExceededException:
            # payment confirmed but order status could not be set, no longer problem of this plugin
            cancel_old_payments(order)
        except SendMailException:
            # payment confirmed but order status could not be set, no longer problem of this plugin
            cancel_old_payments(order)
        else:
            cancel_old_payments(order)

            order.refresh_from_db()
            if order.pending_sum > Decimal(
                    '0.00') and order.status == Order.STATUS_PENDING:
                notify_incomplete_payment(order)

    trans.save()
Esempio n. 5
0
def _handle_transaction(trans: BankTransaction, code: str, event: Event=None, organizer: Organizer=None,
                        slug: str=None):
    if event:
        try:
            trans.order = event.orders.get(code=code)
        except Order.DoesNotExist:
            normalized_code = Order.normalize_code(code)
            try:
                trans.order = event.orders.get(code=normalized_code)
            except Order.DoesNotExist:
                trans.state = BankTransaction.STATE_NOMATCH
                trans.save()
                return
    else:
        qs = Order.objects.filter(event__organizer=organizer)
        if slug:
            qs = qs.filter(event__slug__iexact=slug)
        try:
            trans.order = qs.get(code=code)
        except Order.DoesNotExist:
            normalized_code = Order.normalize_code(code)
            try:
                trans.order = qs.get(code=normalized_code)
            except Order.DoesNotExist:
                trans.state = BankTransaction.STATE_NOMATCH
                trans.save()
                return

    if trans.order.status == Order.STATUS_PAID and trans.order.pending_sum <= Decimal('0.00'):
        trans.state = BankTransaction.STATE_DUPLICATE
    elif trans.order.status == Order.STATUS_CANCELED:
        trans.state = BankTransaction.STATE_ERROR
        trans.message = ugettext_noop('The order has already been canceled.')
    else:
        try:
            p, created = trans.order.payments.get_or_create(
                amount=trans.amount,
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
                defaults={
                    'state': OrderPayment.PAYMENT_STATE_CREATED,
                }
            )
        except OrderPayment.MultipleObjectsReturned:
            created = False
            p = trans.order.payments.filter(
                amount=trans.amount,
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).last()

        p.info_data = {
            'reference': trans.reference,
            'date': trans.date,
            'payer': trans.payer,
            'trans_id': trans.pk
        }

        if created:
            # We're perform a payment method switchign on-demand here
            old_fee, new_fee, fee = change_payment_provider(trans.order, p.payment_provider, p.amount, new_payment=p)  # noqa
            if fee:
                p.fee = fee
                p.save(update_fields=['fee'])

        try:
            p.confirm()
        except Quota.QuotaExceededException:
            trans.state = BankTransaction.STATE_VALID
            trans.order.payments.filter(
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).update(state=OrderPayment.PAYMENT_STATE_CANCELED)
        except SendMailException:
            trans.state = BankTransaction.STATE_VALID
            trans.order.payments.filter(
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).update(state=OrderPayment.PAYMENT_STATE_CANCELED)
        else:
            trans.state = BankTransaction.STATE_VALID
            trans.order.payments.filter(
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).update(state=OrderPayment.PAYMENT_STATE_CANCELED)

            o = trans.order
            o.refresh_from_db()
            if o.pending_sum > Decimal('0.00') and o.status == Order.STATUS_PENDING:
                notify_incomplete_payment(o)

    trans.save()
Esempio n. 6
0
def _handle_transaction(trans: BankTransaction, code: str, event: Event=None, organizer: Organizer=None,
                        slug: str=None):
    if event:
        try:
            trans.order = event.orders.get(code=code)
        except Order.DoesNotExist:
            normalized_code = Order.normalize_code(code)
            try:
                trans.order = event.orders.get(code=normalized_code)
            except Order.DoesNotExist:
                trans.state = BankTransaction.STATE_NOMATCH
                trans.save()
                return
    else:
        qs = Order.objects.filter(event__organizer=organizer)
        if slug:
            qs = qs.filter(event__slug__iexact=slug)
        try:
            trans.order = qs.get(code=code)
        except Order.DoesNotExist:
            normalized_code = Order.normalize_code(code)
            try:
                trans.order = qs.get(code=normalized_code)
            except Order.DoesNotExist:
                trans.state = BankTransaction.STATE_NOMATCH
                trans.save()
                return

    if trans.order.status == Order.STATUS_PAID and trans.order.pending_sum <= Decimal('0.00'):
        trans.state = BankTransaction.STATE_DUPLICATE
    elif trans.order.status == Order.STATUS_CANCELED:
        trans.state = BankTransaction.STATE_ERROR
        trans.message = ugettext_noop('The order has already been canceled.')
    else:
        try:
            p, created = trans.order.payments.get_or_create(
                amount=trans.amount,
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
                defaults={
                    'state': OrderPayment.PAYMENT_STATE_CREATED,
                }
            )
        except OrderPayment.MultipleObjectsReturned:
            created = False
            p = trans.order.payments.filter(
                amount=trans.amount,
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).last()

        p.info_data = {
            'reference': trans.reference,
            'date': trans.date,
            'payer': trans.payer,
            'trans_id': trans.pk
        }

        if created:
            # We're perform a payment method switchign on-demand here
            old_fee, new_fee, fee = change_payment_provider(trans.order, p.payment_provider, p.amount, new_payment=p)  # noqa
            if fee:
                p.fee = fee
                p.save(update_fields=['fee'])

        try:
            p.confirm()
        except Quota.QuotaExceededException:
            trans.state = BankTransaction.STATE_VALID
            trans.order.payments.filter(
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).update(state=OrderPayment.PAYMENT_STATE_CANCELED)
        except SendMailException:
            trans.state = BankTransaction.STATE_VALID
            trans.order.payments.filter(
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).update(state=OrderPayment.PAYMENT_STATE_CANCELED)
        else:
            trans.state = BankTransaction.STATE_VALID
            trans.order.payments.filter(
                provider='banktransfer',
                state__in=(OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING),
            ).update(state=OrderPayment.PAYMENT_STATE_CANCELED)

            o = trans.order
            o.refresh_from_db()
            if o.pending_sum > Decimal('0.00') and o.status == Order.STATUS_PENDING:
                notify_incomplete_payment(o)

    trans.save()