Пример #1
0
def test_sales_channels_qualify(env):
    event, order = env
    event.settings.set('invoice_generate', 'admin')

    # Orders with Total of 0 do never qualify
    assert invoice_qualified(order) is False

    order.total = Decimal('42.00')

    # Order with default Sales Channel (web)
    assert invoice_qualified(order) is True

    event.settings.set('invoice_generate_sales_channels', [])
    assert invoice_qualified(order) is False
Пример #2
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['order'] = self.order
        ctx['can_download'] = (
            self.request.event.settings.ticket_download
            and (
                self.request.event.settings.ticket_download_date is None
                or now() > self.request.event.settings.ticket_download_date
            ) and self.order.status == Order.STATUS_PAID
        )
        ctx['download_buttons'] = self.download_buttons
        ctx['cart'] = self.get_cart(
            answers=True,
            queryset=OrderPosition.objects.filter(order=self.order),
            payment_fee=self.order.payment_fee, payment_fee_tax_rate=self.order.payment_fee_tax_rate
        )
        ctx['invoices'] = list(self.order.invoices.all())
        ctx['can_generate_invoice'] = invoice_qualified(self.order) and (
            self.request.event.settings.invoice_generate == 'user'
        )

        if self.order.status == Order.STATUS_PENDING:
            ctx['payment'] = self.payment_provider.order_pending_render(self.request, self.order)
            ctx['can_retry'] = (
                self.payment_provider.order_can_retry(self.order)
                and self.payment_provider.is_enabled
                and self.order._can_be_paid()
            )
        elif self.order.status == Order.STATUS_PAID:
            ctx['payment'] = self.payment_provider.order_paid_render(self.request, self.order)
            ctx['can_retry'] = False
        return ctx
Пример #3
0
 def get_context_data(self, **kwargs):
     ctx = super().get_context_data(**kwargs)
     ctx['can_generate_invoice'] = invoice_qualified(self.order) and (
         self.request.event.settings.invoice_generate == 'admin' or
         self.request.event.settings.invoice_generate == 'user'
     )
     return ctx
Пример #4
0
    def create(self, request, *args, **kwargs):
        serializer = OrderCreateSerializer(
            data=request.data, context=self.get_serializer_context())
        serializer.is_valid(raise_exception=True)
        with transaction.atomic():
            self.perform_create(serializer)
            order = serializer.instance
            serializer = OrderSerializer(order, context=serializer.context)

            order.log_action(
                'pretix.event.order.placed',
                user=request.user if request.user.is_authenticated else None,
                auth=request.auth,
            )
        order_placed.send(self.request.event, order=order)

        gen_invoice = invoice_qualified(order) and (
            (order.event.settings.get('invoice_generate') == 'True') or
            (order.event.settings.get('invoice_generate') == 'paid' and
             order.status == Order.STATUS_PAID)) and not order.invoices.last()
        if gen_invoice:
            generate_invoice(order, trigger_pdf=True)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
Пример #5
0
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
                   email: str, locale: str, address: int, meta_info: dict=None):

    event = Event.objects.get(id=event)
    responses = register_payment_providers.send(event)
    pprov = None
    for rec, response in responses:
        provider = response(event)
        if provider.identifier == payment_provider:
            pprov = provider
    if not pprov:
        raise OrderError(error_messages['internal'])

    with event.lock() as now_dt:
        positions = list(CartPosition.objects.filter(
            id__in=position_ids).select_related('item', 'variation'))
        if len(positions) == 0:
            raise OrderError(error_messages['empty'])
        if len(position_ids) != len(positions):
            raise OrderError(error_messages['internal'])
        _check_positions(event, now_dt, positions)
        order = _create_order(event, email, positions, now_dt, pprov,
                              locale=locale, address=address, meta_info=meta_info)

    if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
        if not order.invoices.exists():
            generate_invoice(order)

    if order.total == Decimal('0.00'):
        mailtext = event.settings.mail_text_order_free
    else:
        mailtext = event.settings.mail_text_order_placed

    try:
        invoice_name = order.invoice_address.name
        invoice_company = order.invoice_address.company
    except InvoiceAddress.DoesNotExist:
        invoice_name = ""
        invoice_company = ""

    mail(
        order.email, _('Your order: %(code)s') % {'code': order.code},
        mailtext,
        {
            'total': LazyNumber(order.total),
            'currency': event.currency,
            'date': LazyDate(order.expires),
            'event': event.name,
            'url': build_absolute_uri(event, 'presale:event.order', kwargs={
                'order': order.code,
                'secret': order.secret
            }),
            'paymentinfo': str(pprov.order_pending_mail_render(order)),
            'invoice_name': invoice_name,
            'invoice_company': invoice_company,
        },
        event, locale=order.locale
    )

    return order.id
Пример #6
0
 def get_context_data(self, **kwargs):
     ctx = super().get_context_data(**kwargs)
     ctx['can_generate_invoice'] = invoice_qualified(self.order) and (
         self.request.event.settings.invoice_generate == 'admin' or
         self.request.event.settings.invoice_generate == 'user'
     )
     return ctx
Пример #7
0
    def create_invoice(self, request, **kwargs):
        order = self.get_object()
        has_inv = order.invoices.exists() and not (
            order.status in (Order.STATUS_PAID, Order.STATUS_PENDING)
            and order.invoices.filter(is_cancellation=True).count() >=
            order.invoices.filter(is_cancellation=False).count())
        if self.request.event.settings.get('invoice_generate') not in (
                'admin', 'user', 'paid',
                'True') or not invoice_qualified(order):
            return Response(
                {
                    'detail':
                    _('You cannot generate an invoice for this order.')
                },
                status=status.HTTP_400_BAD_REQUEST)
        elif has_inv:
            return Response(
                {'detail': _('An invoice for this order already exists.')},
                status=status.HTTP_400_BAD_REQUEST)

        inv = generate_invoice(order)
        order.log_action('pretix.event.order.invoice.generated',
                         user=self.request.user,
                         auth=self.request.auth,
                         data={'invoice': inv.pk})
        return Response(InvoiceSerializer(inv).data,
                        status=status.HTTP_201_CREATED)
Пример #8
0
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
                   email: str, locale: str, address: int, meta_info: dict=None):

    event = Event.objects.get(id=event)
    pprov = event.get_payment_providers().get(payment_provider)
    if not pprov:
        raise OrderError(error_messages['internal'])

    with event.lock() as now_dt:
        positions = list(CartPosition.objects.filter(
            id__in=position_ids).select_related('item', 'variation', 'subevent'))
        if len(positions) == 0:
            raise OrderError(error_messages['empty'])
        if len(position_ids) != len(positions):
            raise OrderError(error_messages['internal'])
        _check_positions(event, now_dt, positions)
        order = _create_order(event, email, positions, now_dt, pprov,
                              locale=locale, address=address, meta_info=meta_info)

    if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
        if not order.invoices.exists():
            generate_invoice(order)

    if order.total == Decimal('0.00'):
        email_template = event.settings.mail_text_order_free
        log_entry = 'pretix.event.order.email.order_free'
    else:
        email_template = event.settings.mail_text_order_placed
        log_entry = 'pretix.event.order.email.order_placed'

    try:
        invoice_name = order.invoice_address.name
        invoice_company = order.invoice_address.company
    except InvoiceAddress.DoesNotExist:
        invoice_name = ""
        invoice_company = ""
    email_context = {
        'total': LazyNumber(order.total),
        'currency': event.currency,
        'date': LazyDate(order.expires),
        'event': event.name,
        'url': build_absolute_uri(event, 'presale:event.order', kwargs={
            'order': order.code,
            'secret': order.secret
        }),
        'payment_info': str(pprov.order_pending_mail_render(order)),
        'invoice_name': invoice_name,
        'invoice_company': invoice_company,
    }
    email_subject = _('Your order: %(code)s') % {'code': order.code}
    try:
        order.send_mail(
            email_subject, email_template, email_context,
            log_entry
        )
    except SendMailException:
        logger.exception('Order received email could not be sent')

    return order.id
Пример #9
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['order'] = self.order

        can_download = all([r for rr, r in allow_ticket_download.send(self.request.event, order=self.order)])
        if self.request.event.settings.ticket_download_date:
            ctx['ticket_download_date'] = self.order.ticket_download_date
        ctx['can_download'] = can_download and self.order.ticket_download_available
        ctx['download_buttons'] = self.download_buttons
        ctx['cart'] = self.get_cart(
            answers=True, downloads=ctx['can_download'],
            queryset=self.order.positions.select_related('tax_rule'),
            order=self.order
        )
        ctx['can_download_multi'] = any([b['multi'] for b in self.download_buttons]) and (
            self.request.event.settings.ticket_download_nonadm or
            [p.item.admission for p in ctx['cart']['positions']].count(True) > 1
        )
        ctx['invoices'] = list(self.order.invoices.all())
        can_generate_invoice = (
            self.request.event.settings.get('invoice_generate') in ('user', 'True')
            or (
                self.request.event.settings.get('invoice_generate') == 'paid'
                and self.order.status == Order.STATUS_PAID
            )
        )
        ctx['can_generate_invoice'] = invoice_qualified(self.order) and can_generate_invoice
        ctx['url'] = build_absolute_uri(
            self.request.event, 'presale:event.order', kwargs={
                'order': self.order.code,
                'secret': self.order.secret
            }
        )

        if self.order.status == Order.STATUS_PENDING:
            ctx['pending_sum'] = self.order.pending_sum

            lp = self.order.payments.last()
            ctx['can_pay'] = False

            for provider in self.request.event.get_payment_providers().values():
                if provider.is_enabled and provider.order_change_allowed(self.order):
                    ctx['can_pay'] = True
                    break

            if lp and lp.state not in (OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED):
                ctx['last_payment'] = self.order.payments.last()

                pp = lp.payment_provider
                ctx['last_payment_info'] = pp.payment_pending_render(self.request, ctx['last_payment'])

                if lp.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.abort_pending_allowed:
                    ctx['can_pay'] = False

            ctx['can_pay'] = ctx['can_pay'] and self.order._can_be_paid() is True

        elif self.order.status == Order.STATUS_PAID:
            ctx['can_pay'] = False
        return ctx
Пример #10
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['order'] = self.order

        can_download = all([
            r for rr, r in allow_ticket_download.send(self.request.event,
                                                      order=self.order)
        ])
        if self.request.event.settings.ticket_download_date:
            ctx['ticket_download_date'] = self.order.ticket_download_date
        ctx['can_download'] = (
            can_download and self.request.event.settings.ticket_download
            and (self.request.event.settings.ticket_download_date is None
                 or now() > self.order.ticket_download_date)
            and self.order.status == Order.STATUS_PAID)
        ctx['download_buttons'] = self.download_buttons
        ctx['cart'] = self.get_cart(
            answers=True,
            downloads=ctx['can_download'],
            queryset=self.order.positions.select_related('tax_rule'),
            order=self.order)
        ctx['can_download_multi'] = any([
            b['multi'] for b in self.download_buttons
        ]) and (self.request.event.settings.ticket_download_nonadm
                or [p.item.admission
                    for p in ctx['cart']['positions']].count(True) > 1)
        ctx['invoices'] = list(self.order.invoices.all())
        ctx['can_generate_invoice'] = invoice_qualified(
            self.order) and (self.request.event.settings.invoice_generate
                             == 'user')
        ctx['url'] = build_absolute_uri(self.request.event,
                                        'presale:event.order',
                                        kwargs={
                                            'order': self.order.code,
                                            'secret': self.order.secret
                                        })

        if self.order.status == Order.STATUS_PENDING:
            ctx['payment'] = self.payment_provider.order_pending_render(
                self.request, self.order)
            ctx['can_retry'] = (self.payment_provider.order_can_retry(
                self.order) and self.payment_provider.is_enabled
                                and self.order._can_be_paid())

            ctx['can_change_method'] = False
            for provider in self.request.event.get_payment_providers().values(
            ):
                if (provider.identifier != self.order.payment_provider
                        and provider.is_enabled
                        and provider.order_change_allowed(self.order)):
                    ctx['can_change_method'] = True
                    break

        elif self.order.status == Order.STATUS_PAID:
            ctx['payment'] = self.payment_provider.order_paid_render(
                self.request, self.order)
            ctx['can_retry'] = False
        return ctx
Пример #11
0
 def post(self, request, *args, **kwargs):
     if self.request.event.settings.get("invoice_generate") != "user" or not invoice_qualified(self.order):
         messages.error(self.request, _("You cannot generate an invoice for this order."))
     elif self.order.invoices.exists():
         messages.error(self.request, _("An invoice for this order already exists."))
     else:
         i = generate_invoice(self.order)
         self.order.log_action("pretix.event.order.invoice.generated", data={"invoice": i.pk})
         messages.success(self.request, _("The invoice has been generated."))
     return redirect(self.get_order_url())
Пример #12
0
 def post(self, request, *args, **kwargs):
     if self.request.event.settings.get('invoice_generate') != 'user' or not invoice_qualified(self.order):
         messages.error(self.request, _('You cannot generate an invoice for this order.'))
     elif self.order.invoices.exists():
         messages.error(self.request, _('An invoice for this order already exists.'))
     else:
         i = generate_invoice(self.order)
         self.order.log_action('pretix.event.order.invoice.generated', data={
             'invoice': i.pk
         })
         messages.success(self.request, _('The invoice has been generated.'))
     return redirect(self.get_order_url())
Пример #13
0
 def post(self, request, *args, **kwargs):
     if self.request.event.settings.get('invoice_generate') != 'user' or not invoice_qualified(self.order):
         messages.error(self.request, _('You cannot generate an invoice for this order.'))
     elif self.order.invoices.exists():
         messages.error(self.request, _('An invoice for this order already exists.'))
     else:
         i = generate_invoice(self.order)
         self.order.log_action('pretix.event.order.invoice.generated', data={
             'invoice': i.pk
         })
         messages.success(self.request, _('The invoice has been generated.'))
     return redirect(self.get_order_url())
Пример #14
0
def can_generate_invoice(event, order, ignore_payments=False):
    v = (order.sales_channel
         in event.settings.get('invoice_generate_sales_channels')
         and (event.settings.get('invoice_generate') in ('user', 'True') or
              (event.settings.get('invoice_generate') == 'paid'
               and order.status == Order.STATUS_PAID))
         and (invoice_qualified(order)))
    if not ignore_payments:
        v = v and not (not order.payments.exclude(state__in=[
            OrderPayment.PAYMENT_STATE_CANCELED,
            OrderPayment.PAYMENT_STATE_FAILED
        ]).exists() and order.status == Order.STATUS_PENDING)
    return v
Пример #15
0
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
                   email: str, locale: str, address: int):

    event = Event.objects.get(id=event)
    responses = register_payment_providers.send(event)
    pprov = None
    for rec, response in responses:
        provider = response(event)
        if provider.identifier == payment_provider:
            pprov = provider
    if not pprov:
        raise OrderError(error_messages['internal'])

    with event.lock() as now_dt:
        positions = list(CartPosition.objects.filter(
            id__in=position_ids).select_related('item', 'variation'))
        if len(position_ids) != len(positions):
            raise OrderError(error_messages['internal'])
        _check_positions(event, now_dt, positions)
        order = _create_order(event, email, positions, now_dt, pprov,
                              locale=locale, address=address)

    if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
        if not order.invoices.exists():
            generate_invoice(order)

    with language(order.locale):
        if order.total == Decimal('0.00'):
            mailtext = event.settings.mail_text_order_free
        else:
            mailtext = event.settings.mail_text_order_placed
        mail(
            order.email, _('Your order: %(code)s') % {'code': order.code},
            mailtext,
            {
                'total': LazyNumber(order.total),
                'currency': event.currency,
                'date': LazyDate(order.expires),
                'event': event.name,
                'url': build_absolute_uri(event, 'presale:event.order', kwargs={
                    'order': order.code,
                    'secret': order.secret
                }),
                'paymentinfo': str(pprov.order_pending_mail_render(order))
            },
            event, locale=order.locale
        )

    return order.id
Пример #16
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['order'] = self.order

        if self.request.event.settings.ticket_download_date:
            ctx['ticket_download_date'] = self.order.ticket_download_date
        ctx['can_download'] = (
            self.request.event.settings.ticket_download
            and (
                self.request.event.settings.ticket_download_date is None
                or now() > self.order.ticket_download_date
            ) and self.order.status == Order.STATUS_PAID
        )
        ctx['download_buttons'] = self.download_buttons
        ctx['cart'] = self.get_cart(
            answers=True, downloads=ctx['can_download'],
            queryset=self.order.positions.all(),
            payment_fee=self.order.payment_fee, payment_fee_tax_rate=self.order.payment_fee_tax_rate
        )
        ctx['can_download_multi'] = any([b['multi'] for b in self.download_buttons]) and (
            self.request.event.settings.ticket_download_nonadm or
            any([p.item.admission for p in ctx['cart']['positions']])
        )
        ctx['invoices'] = list(self.order.invoices.all())
        ctx['can_generate_invoice'] = invoice_qualified(self.order) and (
            self.request.event.settings.invoice_generate == 'user'
        )

        if self.order.status == Order.STATUS_PENDING:
            ctx['payment'] = self.payment_provider.order_pending_render(self.request, self.order)
            ctx['can_retry'] = (
                self.payment_provider.order_can_retry(self.order)
                and self.payment_provider.is_enabled
                and self.order._can_be_paid()
            )

            ctx['can_change_method'] = False
            for provider in self.request.event.get_payment_providers().values():
                if (provider.identifier != self.order.payment_provider and provider.is_enabled
                        and provider.order_change_allowed(self.order)):
                    ctx['can_change_method'] = True
                    break

        elif self.order.status == Order.STATUS_PAID:
            ctx['payment'] = self.payment_provider.order_paid_render(self.request, self.order)
            ctx['can_retry'] = False
        return ctx
Пример #17
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx["order"] = self.order
        ctx["can_download"] = (
            self.request.event.settings.ticket_download
            and (
                self.request.event.settings.ticket_download_date is None
                or now() > self.request.event.settings.ticket_download_date
            )
            and self.order.status == Order.STATUS_PAID
        )
        ctx["download_buttons"] = self.download_buttons
        ctx["cart"] = self.get_cart(
            answers=True,
            queryset=OrderPosition.objects.filter(order=self.order),
            payment_fee=self.order.payment_fee,
            payment_fee_tax_rate=self.order.payment_fee_tax_rate,
        )
        ctx["invoices"] = list(self.order.invoices.all())
        ctx["can_generate_invoice"] = invoice_qualified(self.order) and (
            self.request.event.settings.invoice_generate == "user"
        )

        if self.order.status == Order.STATUS_PENDING:
            ctx["payment"] = self.payment_provider.order_pending_render(self.request, self.order)
            ctx["can_retry"] = (
                self.payment_provider.order_can_retry(self.order)
                and self.payment_provider.is_enabled
                and self.order._can_be_paid()
            )

            ctx["can_change_method"] = False
            responses = register_payment_providers.send(self.request.event)
            for receiver, response in responses:
                provider = response(self.request.event)
                if (
                    provider.identifier != self.order.payment_provider
                    and provider.is_enabled
                    and provider.order_change_allowed(self.order)
                ):
                    ctx["can_change_method"] = True
                    break

        elif self.order.status == Order.STATUS_PAID:
            ctx["payment"] = self.payment_provider.order_paid_render(self.request, self.order)
            ctx["can_retry"] = False
        return ctx
Пример #18
0
 def post(self, request, *args, **kwargs):
     can_generate_invoice = (
         self.request.event.settings.get('invoice_generate')
         in ('user', 'True')
         or (self.request.event.settings.get('invoice_generate') == 'paid'
             and self.order.status == Order.STATUS_PAID))
     if not can_generate_invoice or not invoice_qualified(self.order):
         messages.error(self.request,
                        _('You cannot generate an invoice for this order.'))
     elif self.order.invoices.exists():
         messages.error(self.request,
                        _('An invoice for this order already exists.'))
     else:
         i = generate_invoice(self.order)
         self.order.log_action('pretix.event.order.invoice.generated',
                               data={'invoice': i.pk})
         messages.success(self.request,
                          _('The invoice has been generated.'))
     return redirect(self.get_order_url())
Пример #19
0
 def post(self, request, *args, **kwargs):
     can_generate_invoice = (
         self.request.event.settings.get('invoice_generate') in ('user', 'True')
         or (
             self.request.event.settings.get('invoice_generate') == 'paid'
             and self.order.status == Order.STATUS_PAID
         )
     )
     if not can_generate_invoice or not invoice_qualified(self.order):
         messages.error(self.request, _('You cannot generate an invoice for this order.'))
     elif self.order.invoices.exists():
         messages.error(self.request, _('An invoice for this order already exists.'))
     else:
         i = generate_invoice(self.order)
         self.order.log_action('pretix.event.order.invoice.generated', data={
             'invoice': i.pk
         })
         messages.success(self.request, _('The invoice has been generated.'))
     return redirect(self.get_order_url())
Пример #20
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['order'] = self.order
        ctx['can_download'] = (
            self.request.event.settings.ticket_download
            and (self.request.event.settings.ticket_download_date is None
                 or now() > self.request.event.settings.ticket_download_date)
            and self.order.status == Order.STATUS_PAID)
        ctx['download_buttons'] = self.download_buttons
        ctx['cart'] = self.get_cart(
            answers=True,
            downloads=ctx['can_download'],
            queryset=OrderPosition.objects.filter(order=self.order),
            payment_fee=self.order.payment_fee,
            payment_fee_tax_rate=self.order.payment_fee_tax_rate)
        ctx['invoices'] = list(self.order.invoices.all())
        ctx['can_generate_invoice'] = invoice_qualified(
            self.order) and (self.request.event.settings.invoice_generate
                             == 'user')

        if self.order.status == Order.STATUS_PENDING:
            ctx['payment'] = self.payment_provider.order_pending_render(
                self.request, self.order)
            ctx['can_retry'] = (self.payment_provider.order_can_retry(
                self.order) and self.payment_provider.is_enabled
                                and self.order._can_be_paid())

            ctx['can_change_method'] = False
            responses = register_payment_providers.send(self.request.event)
            for receiver, response in responses:
                provider = response(self.request.event)
                if (provider.identifier != self.order.payment_provider
                        and provider.is_enabled
                        and provider.order_change_allowed(self.order)):
                    ctx['can_change_method'] = True
                    break

        elif self.order.status == Order.STATUS_PAID:
            ctx['payment'] = self.payment_provider.order_paid_render(
                self.request, self.order)
            ctx['can_retry'] = False
        return ctx
Пример #21
0
    def create(self, request, *args, **kwargs):
        serializer = OrderCreateSerializer(data=request.data, context=self.get_serializer_context())
        serializer.is_valid(raise_exception=True)
        with transaction.atomic():
            self.perform_create(serializer)
            order = serializer.instance
            serializer = OrderSerializer(order, context=serializer.context)

            order.log_action(
                'pretix.event.order.placed',
                user=request.user if request.user.is_authenticated else None,
                auth=request.auth,
            )
        order_placed.send(self.request.event, order=order)

        gen_invoice = invoice_qualified(order) and (
            (order.event.settings.get('invoice_generate') == 'True') or
            (order.event.settings.get('invoice_generate') == 'paid' and order.status == Order.STATUS_PAID)
        ) and not order.invoices.last()
        if gen_invoice:
            generate_invoice(order, trigger_pdf=True)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Пример #22
0
    def create_invoice(self, request, **kwargs):
        order = self.get_object()
        has_inv = order.invoices.exists() and not (
            order.status in (Order.STATUS_PAID, Order.STATUS_PENDING)
            and order.invoices.filter(is_cancellation=True).count() >= order.invoices.filter(is_cancellation=False).count()
        )
        if self.request.event.settings.get('invoice_generate') not in ('admin', 'user', 'paid', 'True') or not invoice_qualified(order):
            return Response(
                {'detail': _('You cannot generate an invoice for this order.')},
                status=status.HTTP_400_BAD_REQUEST
            )
        elif has_inv:
            return Response(
                {'detail': _('An invoice for this order already exists.')},
                status=status.HTTP_400_BAD_REQUEST
            )

        inv = generate_invoice(order)
        order.log_action(
            'pretix.event.order.invoice.generated',
            user=self.request.user,
            auth=self.request.auth,
            data={
                'invoice': inv.pk
            }
        )
        return Response(
            InvoiceSerializer(inv).data,
            status=status.HTTP_201_CREATED
        )
Пример #23
0
def import_orders(event: Event, fileid: str, settings: dict, locale: str,
                  user) -> None:
    # TODO: quotacheck?
    cf = CachedFile.objects.get(id=fileid)
    user = User.objects.get(pk=user)
    with language(locale, event.settings.region):
        cols = get_all_columns(event)
        parsed = parse_csv(cf.file)
        orders = []
        order = None
        data = []

        # Run validation
        for i, record in enumerate(parsed):
            if not any(record.values()):
                continue
            values = {}
            for c in cols:
                val = c.resolve(settings, record)
                if isinstance(val, str):
                    val = val.strip()
                try:
                    values[c.identifier] = c.clean(val, values)
                except ValidationError as e:
                    raise DataImportError(
                        _('Error while importing value "{value}" for column "{column}" in line "{line}": {message}'
                          ).format(value=val if val is not None else '',
                                   column=c.verbose_name,
                                   line=i + 1,
                                   message=e.message))
            data.append(values)

        # Prepare model objects. Yes, this might consume lots of RAM, but allows us to make the actual SQL transaction
        # shorter. We'll see what works better in reality…
        for i, record in enumerate(data):
            try:
                if order is None or settings['orders'] == 'many':
                    order = Order(
                        event=event,
                        testmode=settings['testmode'],
                    )
                    order.meta_info = {}
                    order._positions = []
                    order._address = InvoiceAddress()
                    order._address.name_parts = {
                        '_scheme': event.settings.name_scheme
                    }
                    orders.append(order)

                position = OrderPosition(positionid=len(order._positions) + 1)
                position.attendee_name_parts = {
                    '_scheme': event.settings.name_scheme
                }
                position.meta_info = {}
                order._positions.append(position)
                position.assign_pseudonymization_id()

                for c in cols:
                    c.assign(record.get(c.identifier), order, position,
                             order._address)

            except ImportError as e:
                raise ImportError(
                    _('Invalid data in row {row}: {message}').format(
                        row=i, message=str(e)))

        # quota check?
        with event.lock():
            with transaction.atomic():
                save_transactions = []
                for o in orders:
                    o.total = sum([c.price for c in o._positions
                                   ])  # currently no support for fees
                    if o.total == Decimal('0.00'):
                        o.status = Order.STATUS_PAID
                        o.save()
                        OrderPayment.objects.create(
                            local_id=1,
                            order=o,
                            amount=Decimal('0.00'),
                            provider='free',
                            info='{}',
                            payment_date=now(),
                            state=OrderPayment.PAYMENT_STATE_CONFIRMED)
                    elif settings['status'] == 'paid':
                        o.status = Order.STATUS_PAID
                        o.save()
                        OrderPayment.objects.create(
                            local_id=1,
                            order=o,
                            amount=o.total,
                            provider='manual',
                            info='{}',
                            payment_date=now(),
                            state=OrderPayment.PAYMENT_STATE_CONFIRMED)
                    else:
                        o.status = Order.STATUS_PENDING
                        o.save()
                    for p in o._positions:
                        p.order = o
                        p.save()
                    o._address.order = o
                    o._address.save()
                    for c in cols:
                        c.save(o)
                    o.log_action('pretix.event.order.placed',
                                 user=user,
                                 data={'source': 'import'})
                    save_transactions += o.create_transactions(
                        is_new=True,
                        fees=[],
                        positions=o._positions,
                        save=False)
                Transaction.objects.bulk_create(save_transactions)

            for o in orders:
                with language(o.locale, event.settings.region):
                    order_placed.send(event, order=o)
                    if o.status == Order.STATUS_PAID:
                        order_paid.send(event, order=o)

                    gen_invoice = invoice_qualified(o) and (
                        (event.settings.get('invoice_generate') == 'True') or
                        (event.settings.get('invoice_generate') == 'paid'
                         and o.status
                         == Order.STATUS_PAID)) and not o.invoices.last()
                    if gen_invoice:
                        generate_invoice(o, trigger_pdf=True)
    cf.delete()
Пример #24
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['cart'] = self.get_cart(
            answers=True,
            downloads=ctx['can_download'],
            queryset=self.order.positions.select_related('tax_rule'),
            order=self.order)
        ctx['can_download_multi'] = any([
            b['multi'] for b in self.download_buttons
        ]) and ([p.generate_ticket
                 for p in ctx['cart']['positions']].count(True) > 1)
        ctx['invoices'] = list(self.order.invoices.all())
        can_generate_invoice = (
            self.order.sales_channel in self.request.event.settings.get(
                'invoice_generate_sales_channels')
            and (self.request.event.settings.get('invoice_generate')
                 in ('user', 'True') or
                 (self.request.event.settings.get('invoice_generate') == 'paid'
                  and self.order.status == Order.STATUS_PAID)))
        ctx['can_generate_invoice'] = invoice_qualified(
            self.order) and can_generate_invoice
        ctx['url'] = build_absolute_uri(self.request.event,
                                        'presale:event.order',
                                        kwargs={
                                            'order': self.order.code,
                                            'secret': self.order.secret
                                        })
        ctx['invoice_address_asked'] = self.request.event.settings.invoice_address_asked and (
            self.order.total != Decimal('0.00')
            or not self.request.event.settings.invoice_address_not_asked_free)

        if self.order.status == Order.STATUS_PENDING:
            ctx['pending_sum'] = self.order.pending_sum

            lp = self.order.payments.last()
            ctx['can_pay'] = False

            for provider in self.request.event.get_payment_providers().values(
            ):
                if provider.is_enabled and provider.order_change_allowed(
                        self.order):
                    ctx['can_pay'] = True
                    break

            if lp and lp.state not in (OrderPayment.PAYMENT_STATE_CONFIRMED,
                                       OrderPayment.PAYMENT_STATE_REFUNDED):
                ctx['last_payment'] = self.order.payments.last()

                pp = lp.payment_provider
                ctx['last_payment_info'] = pp.payment_pending_render(
                    self.request, ctx['last_payment'])

                if lp.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.abort_pending_allowed:
                    ctx['can_pay'] = False

            ctx['can_pay'] = ctx['can_pay'] and self.order._can_be_paid(
            ) is True

        elif self.order.status == Order.STATUS_PAID:
            ctx['can_pay'] = False

        ctx['refunds'] = self.order.refunds.filter(
            state__in=(OrderRefund.REFUND_STATE_DONE,
                       OrderRefund.REFUND_STATE_TRANSIT,
                       OrderRefund.REFUND_STATE_CREATED))

        return ctx
Пример #25
0
    def create(self, request, *args, **kwargs):
        serializer = OrderCreateSerializer(
            data=request.data, context=self.get_serializer_context())
        serializer.is_valid(raise_exception=True)
        with transaction.atomic():
            self.perform_create(serializer)
            send_mail = serializer._send_mail
            order = serializer.instance
            serializer = OrderSerializer(order, context=serializer.context)

            order.log_action(
                'pretix.event.order.placed',
                user=request.user if request.user.is_authenticated else None,
                auth=request.auth,
            )
        order_placed.send(self.request.event, order=order)

        gen_invoice = invoice_qualified(order) and (
            (order.event.settings.get('invoice_generate') == 'True') or
            (order.event.settings.get('invoice_generate') == 'paid' and
             order.status == Order.STATUS_PAID)) and not order.invoices.last()
        invoice = None
        if gen_invoice:
            invoice = generate_invoice(order, trigger_pdf=True)

        if send_mail:
            payment = order.payments.last()
            free_flow = (payment and order.total == Decimal('0.00')
                         and order.status == Order.STATUS_PAID
                         and not order.require_approval
                         and payment.provider == "free")
            if free_flow:
                email_template = request.event.settings.mail_text_order_free
                log_entry = 'pretix.event.order.email.order_free'
                email_attendees = request.event.settings.mail_send_order_free_attendee
                email_attendees_template = request.event.settings.mail_text_order_free_attendee
            else:
                email_template = request.event.settings.mail_text_order_placed
                log_entry = 'pretix.event.order.email.order_placed'
                email_attendees = request.event.settings.mail_send_order_placed_attendee
                email_attendees_template = request.event.settings.mail_text_order_placed_attendee

            _order_placed_email(request.event, order,
                                payment.payment_provider if payment else None,
                                email_template, log_entry, invoice, payment)
            if email_attendees:
                for p in order.positions.all():
                    if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
                        _order_placed_email_attendee(request.event, order, p,
                                                     email_attendees_template,
                                                     log_entry)

            if not free_flow and order.status == Order.STATUS_PAID and payment:
                payment._send_paid_mail(invoice, None, '')
                if self.request.event.settings.mail_send_order_paid_attendee:
                    for p in order.positions.all():
                        if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
                            payment._send_paid_mail_attendee(p, None)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
Пример #26
0
def mark_order_paid(order: Order, provider: str=None, info: str=None, date: datetime=None, manual: bool=None,
                    force: bool=False, send_mail: bool=True, user: User=None, mail_text='') -> Order:
    """
    Marks an order as paid. This sets the payment provider, info and date and returns
    the order object.

    :param provider: The payment provider that marked this as paid
    :type provider: str
    :param info: The information to store in order.payment_info
    :type info: str
    :param date: The date the payment was received (if you pass ``None``, the current
                 time will be used).
    :type date: datetime
    :param force: Whether this payment should be marked as paid even if no remaining
                  quota is available (default: ``False``).
    :type force: boolean
    :param send_mail: Whether an email should be sent to the user about this event (default: ``True``).
    :type send_mail: boolean
    :param user: The user that performed the change
    :param mail_text: Additional text to be included in the email
    :type mail_text: str
    :raises Quota.QuotaExceededException: if the quota is exceeded and ``force`` is ``False``
    """
    if order.status == Order.STATUS_PAID:
        return order

    with order.event.lock() as now_dt:
        can_be_paid = order._can_be_paid()
        if not force and can_be_paid is not True:
            raise Quota.QuotaExceededException(can_be_paid)
        order.payment_provider = provider or order.payment_provider
        order.payment_info = info or order.payment_info
        order.payment_date = date or now_dt
        if manual is not None:
            order.payment_manual = manual
        order.status = Order.STATUS_PAID
        order.save()

    order.log_action('pretix.event.order.paid', {
        'provider': provider,
        'info': info,
        'date': date or now_dt,
        'manual': manual,
        'force': force
    }, user=user)
    order_paid.send(order.event, order=order)

    if order.event.settings.get('invoice_generate') in ('True', 'paid') and invoice_qualified(order):
        if not order.invoices.exists():
            generate_invoice(order)

    if send_mail:
        with language(order.locale):
            try:
                invoice_name = order.invoice_address.name
                invoice_company = order.invoice_address.company
            except InvoiceAddress.DoesNotExist:
                invoice_name = ""
                invoice_company = ""
            mail(
                order.email, _('Payment received for your order: %(code)s') % {'code': order.code},
                order.event.settings.mail_text_order_paid,
                {
                    'event': order.event.name,
                    'url': build_absolute_uri(order.event, 'presale:event.order', kwargs={
                        'order': order.code,
                        'secret': order.secret
                    }),
                    'downloads': order.event.settings.get('ticket_download', as_type=bool),
                    'invoice_name': invoice_name,
                    'invoice_company': invoice_company,
                    'payment_info': mail_text
                },
                order.event, locale=order.locale
            )
    return order
Пример #27
0
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['cart'] = self.get_cart(
            answers=True, downloads=ctx['can_download'],
            queryset=self.order.positions.select_related('tax_rule'),
            order=self.order
        )
        ctx['can_download_multi'] = any([b['multi'] for b in self.download_buttons]) and (
            [p.generate_ticket for p in ctx['cart']['positions']].count(True) > 1
        )
        ctx['invoices'] = list(self.order.invoices.all())
        can_generate_invoice = (
            self.order.sales_channel in self.request.event.settings.get('invoice_generate_sales_channels')
            and (
                self.request.event.settings.get('invoice_generate') in ('user', 'True')
                or (
                    self.request.event.settings.get('invoice_generate') == 'paid'
                    and self.order.status == Order.STATUS_PAID
                )
            )
        )
        ctx['can_generate_invoice'] = invoice_qualified(self.order) and can_generate_invoice
        ctx['url'] = build_absolute_uri(
            self.request.event, 'presale:event.order', kwargs={
                'order': self.order.code,
                'secret': self.order.secret
            }
        )
        ctx['invoice_address_asked'] = self.request.event.settings.invoice_address_asked and (
            self.order.total != Decimal('0.00') or not self.request.event.settings.invoice_address_not_asked_free
        )

        if self.order.status == Order.STATUS_PENDING:
            ctx['pending_sum'] = self.order.pending_sum

            lp = self.order.payments.last()
            ctx['can_pay'] = False

            for provider in self.request.event.get_payment_providers().values():
                if provider.is_enabled and provider.order_change_allowed(self.order):
                    ctx['can_pay'] = True
                    break

            if lp and lp.state not in (OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED):
                ctx['last_payment'] = self.order.payments.last()

                pp = lp.payment_provider
                ctx['last_payment_info'] = pp.payment_pending_render(self.request, ctx['last_payment'])

                if lp.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.abort_pending_allowed:
                    ctx['can_pay'] = False

            ctx['can_pay'] = ctx['can_pay'] and self.order._can_be_paid() is True

        elif self.order.status == Order.STATUS_PAID:
            ctx['can_pay'] = False

        ctx['refunds'] = self.order.refunds.filter(
            state__in=(OrderRefund.REFUND_STATE_DONE, OrderRefund.REFUND_STATE_TRANSIT, OrderRefund.REFUND_STATE_CREATED)
        )

        return ctx