mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Add multi-sheet export for invoices
This commit is contained in:
@@ -154,7 +154,7 @@ class MultiSheetListExporter(ListExporter):
|
|||||||
@property
|
@property
|
||||||
def export_form_fields(self) -> dict:
|
def export_form_fields(self) -> dict:
|
||||||
choices = [
|
choices = [
|
||||||
('xlsx', _('Excel (.xlsx)')),
|
('xlsx', _('Combined Excel (.xlsx)')),
|
||||||
]
|
]
|
||||||
for s, l in self.sheets:
|
for s, l in self.sheets:
|
||||||
choices += [
|
choices += [
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ from decimal import Decimal
|
|||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db.models import DateTimeField, Max, OuterRef, Subquery, Sum
|
from django.db.models import DateTimeField, F, Max, OuterRef, Subquery, Sum
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.formats import localize
|
from django.utils.formats import date_format, localize
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
|
|
||||||
from pretix.base.models import InvoiceAddress, Order, OrderPosition
|
from pretix.base.models import (
|
||||||
|
InvoiceAddress, InvoiceLine, Order, OrderPosition,
|
||||||
|
)
|
||||||
from pretix.base.models.orders import OrderFee, OrderPayment, OrderRefund
|
from pretix.base.models.orders import OrderFee, OrderPayment, OrderRefund
|
||||||
from pretix.base.settings import PERSON_NAME_SCHEMES
|
from pretix.base.settings import PERSON_NAME_SCHEMES
|
||||||
|
|
||||||
from ..exporter import ListExporter
|
from ..exporter import ListExporter, MultiSheetListExporter
|
||||||
from ..signals import register_data_exporters
|
from ..signals import register_data_exporters
|
||||||
|
|
||||||
|
|
||||||
@@ -208,7 +210,7 @@ class PaymentListExporter(ListExporter):
|
|||||||
|
|
||||||
headers = [
|
headers = [
|
||||||
_('Order'), _('Payment ID'), _('Creation date'), _('Completion date'), _('Status'),
|
_('Order'), _('Payment ID'), _('Creation date'), _('Completion date'), _('Status'),
|
||||||
_('Amount'), _('Payment method')
|
_('Status code'), _('Amount'), _('Payment method')
|
||||||
]
|
]
|
||||||
yield headers
|
yield headers
|
||||||
|
|
||||||
@@ -225,6 +227,7 @@ class PaymentListExporter(ListExporter):
|
|||||||
obj.created.astimezone(tz).date().strftime('%Y-%m-%d'),
|
obj.created.astimezone(tz).date().strftime('%Y-%m-%d'),
|
||||||
d2,
|
d2,
|
||||||
obj.get_state_display(),
|
obj.get_state_display(),
|
||||||
|
obj.state,
|
||||||
localize(obj.amount * (-1 if isinstance(obj, OrderRefund) else 1)),
|
localize(obj.amount * (-1 if isinstance(obj, OrderRefund) else 1)),
|
||||||
provider_names.get(obj.provider, obj.provider)
|
provider_names.get(obj.provider, obj.provider)
|
||||||
]
|
]
|
||||||
@@ -263,6 +266,172 @@ class QuotaListExporter(ListExporter):
|
|||||||
return '{}_quotas'.format(self.event.slug)
|
return '{}_quotas'.format(self.event.slug)
|
||||||
|
|
||||||
|
|
||||||
|
class InvoiceDataExporter(MultiSheetListExporter):
|
||||||
|
identifier = 'invoicedata'
|
||||||
|
verbose_name = ugettext_lazy('Invoice data')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sheets(self):
|
||||||
|
return (
|
||||||
|
('invoices', _('Invoices')),
|
||||||
|
('lines', _('Invoice lines')),
|
||||||
|
)
|
||||||
|
|
||||||
|
def iterate_sheet(self, form_data, sheet):
|
||||||
|
if sheet == 'invoices':
|
||||||
|
yield [
|
||||||
|
_('Invoice number'),
|
||||||
|
_('Date'),
|
||||||
|
_('Order code'),
|
||||||
|
_('E-mail address'),
|
||||||
|
_('Invoice type'),
|
||||||
|
_('Cancellation of'),
|
||||||
|
_('Language'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Name'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Address'),
|
||||||
|
_('Invoice sender:') + ' ' + _('ZIP code'),
|
||||||
|
_('Invoice sender:') + ' ' + _('City'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Country'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Tax ID'),
|
||||||
|
_('Invoice sender:') + ' ' + _('VAT ID'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Company'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Name'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Street address'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('ZIP code'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('City'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Country'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('VAT ID'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Beneficiary'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Internal reference'),
|
||||||
|
_('Reverse charge'),
|
||||||
|
_('Shown foreign currency'),
|
||||||
|
_('Foreign currency rate'),
|
||||||
|
_('Total value (with taxes)'),
|
||||||
|
_('Total value (without taxes)'),
|
||||||
|
]
|
||||||
|
qs = self.event.invoices.order_by('full_invoice_no').select_related(
|
||||||
|
'order', 'refers'
|
||||||
|
).annotate(
|
||||||
|
total_gross=Subquery(
|
||||||
|
InvoiceLine.objects.filter(
|
||||||
|
invoice=OuterRef('pk')
|
||||||
|
).order_by().values('invoice').annotate(
|
||||||
|
s=Sum('gross_value')
|
||||||
|
).values('s')
|
||||||
|
),
|
||||||
|
total_net=Subquery(
|
||||||
|
InvoiceLine.objects.filter(
|
||||||
|
invoice=OuterRef('pk')
|
||||||
|
).order_by().values('invoice').annotate(
|
||||||
|
s=Sum(F('gross_value') - F('tax_value'))
|
||||||
|
).values('s')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for i in qs:
|
||||||
|
yield [
|
||||||
|
i.full_invoice_no,
|
||||||
|
date_format(i.date, "SHORT_DATE_FORMAT"),
|
||||||
|
i.order.code,
|
||||||
|
i.order.email,
|
||||||
|
_('Cancellation') if i.is_cancellation else _('Invoice'),
|
||||||
|
i.refers.full_invoice_no if i.refers else '',
|
||||||
|
i.locale,
|
||||||
|
i.invoice_from_name,
|
||||||
|
i.invoice_from,
|
||||||
|
i.invoice_from_zipcode,
|
||||||
|
i.invoice_from_city,
|
||||||
|
i.invoice_from_country,
|
||||||
|
i.invoice_from_tax_id,
|
||||||
|
i.invoice_from_vat_id,
|
||||||
|
i.invoice_to_company,
|
||||||
|
i.invoice_to_name,
|
||||||
|
i.invoice_to_street or i.invoice_to,
|
||||||
|
i.invoice_to_zipcode,
|
||||||
|
i.invoice_to_city,
|
||||||
|
i.invoice_to_country,
|
||||||
|
i.invoice_to_vat_id,
|
||||||
|
i.invoice_to_beneficiary,
|
||||||
|
i.internal_reference,
|
||||||
|
_('Yes') if i.reverse_charge else _('No'),
|
||||||
|
i.foreign_currency_display,
|
||||||
|
i.foreign_currency_rate,
|
||||||
|
i.total_gross,
|
||||||
|
Decimal(i.total_net).quantize(Decimal('0.01')),
|
||||||
|
]
|
||||||
|
elif sheet == 'lines':
|
||||||
|
yield [
|
||||||
|
_('Invoice number'),
|
||||||
|
_('Line number'),
|
||||||
|
_('Description'),
|
||||||
|
_('Gross price'),
|
||||||
|
_('Net price'),
|
||||||
|
_('Tax value'),
|
||||||
|
_('Tax rate'),
|
||||||
|
_('Tax name'),
|
||||||
|
|
||||||
|
_('Date'),
|
||||||
|
_('Order code'),
|
||||||
|
_('E-mail address'),
|
||||||
|
_('Invoice type'),
|
||||||
|
_('Cancellation of'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Name'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Address'),
|
||||||
|
_('Invoice sender:') + ' ' + _('ZIP code'),
|
||||||
|
_('Invoice sender:') + ' ' + _('City'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Country'),
|
||||||
|
_('Invoice sender:') + ' ' + _('Tax ID'),
|
||||||
|
_('Invoice sender:') + ' ' + _('VAT ID'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Company'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Name'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Street address'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('ZIP code'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('City'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Country'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('VAT ID'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Beneficiary'),
|
||||||
|
_('Invoice recipient:') + ' ' + _('Internal reference'),
|
||||||
|
]
|
||||||
|
qs = InvoiceLine.objects.order_by('invoice__full_invoice_no', 'position').select_related(
|
||||||
|
'invoice', 'invoice__order', 'invoice__refers'
|
||||||
|
)
|
||||||
|
for l in qs:
|
||||||
|
i = l.invoice
|
||||||
|
yield [
|
||||||
|
i.full_invoice_no,
|
||||||
|
l.position + 1,
|
||||||
|
l.description.replace("<br />", " - "),
|
||||||
|
l.gross_value,
|
||||||
|
l.net_value,
|
||||||
|
l.tax_value,
|
||||||
|
l.tax_rate,
|
||||||
|
l.tax_name,
|
||||||
|
date_format(i.date, "SHORT_DATE_FORMAT"),
|
||||||
|
i.order.code,
|
||||||
|
i.order.email,
|
||||||
|
_('Cancellation') if i.is_cancellation else _('Invoice'),
|
||||||
|
i.refers.full_invoice_no if i.refers else '',
|
||||||
|
i.invoice_from_name,
|
||||||
|
i.invoice_from,
|
||||||
|
i.invoice_from_zipcode,
|
||||||
|
i.invoice_from_city,
|
||||||
|
i.invoice_from_country,
|
||||||
|
i.invoice_from_tax_id,
|
||||||
|
i.invoice_from_vat_id,
|
||||||
|
i.invoice_to_company,
|
||||||
|
i.invoice_to_name,
|
||||||
|
i.invoice_to_street or i.invoice_to,
|
||||||
|
i.invoice_to_zipcode,
|
||||||
|
i.invoice_to_city,
|
||||||
|
i.invoice_to_country,
|
||||||
|
i.invoice_to_vat_id,
|
||||||
|
i.invoice_to_beneficiary,
|
||||||
|
i.internal_reference,
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_filename(self):
|
||||||
|
return '{}_payments'.format(self.event.slug)
|
||||||
|
|
||||||
|
|
||||||
@receiver(register_data_exporters, dispatch_uid="exporter_orderlist")
|
@receiver(register_data_exporters, dispatch_uid="exporter_orderlist")
|
||||||
def register_orderlist_exporter(sender, **kwargs):
|
def register_orderlist_exporter(sender, **kwargs):
|
||||||
return OrderListExporter
|
return OrderListExporter
|
||||||
@@ -276,3 +445,8 @@ def register_paymentlist_exporter(sender, **kwargs):
|
|||||||
@receiver(register_data_exporters, dispatch_uid="exporter_quotalist")
|
@receiver(register_data_exporters, dispatch_uid="exporter_quotalist")
|
||||||
def register_quotalist_exporter(sender, **kwargs):
|
def register_quotalist_exporter(sender, **kwargs):
|
||||||
return QuotaListExporter
|
return QuotaListExporter
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(register_data_exporters, dispatch_uid="exporter_invoicedata")
|
||||||
|
def register_invoicedata_exporter(sender, **kwargs):
|
||||||
|
return InvoiceDataExporter
|
||||||
|
|||||||
Reference in New Issue
Block a user