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
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
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
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)
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
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)
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
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
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
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())
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())
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
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
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
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
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())
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())
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
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)
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 )
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()
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
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)
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
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