forked from CGM_Public/pretix_original
Change API to accomodate for invoice numbers
This commit is contained in:
@@ -11,7 +11,7 @@ The invoice resource contains the following public fields:
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
invoice_no string Invoice number (without prefix)
|
||||
number string Invoice number (with prefix)
|
||||
order string Order code of the order this invoice belongs to
|
||||
is_cancellation boolean ``True``, if this invoice is the cancellation of a
|
||||
different invoice.
|
||||
@@ -35,6 +35,13 @@ lines list of objects The actual invo
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
.. versionchanged:: 1.6
|
||||
|
||||
The attribute ``invoice_no`` has been dropped in favor of ``number`` which includes the number including the prefix,
|
||||
since the prefix can now vary. Also, invoices now need to be identified by their ``number`` instead of the raw
|
||||
number.
|
||||
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -64,7 +71,7 @@ Endpoints
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"invoice_no": "00001",
|
||||
"number": "SAMPLECONF-00001",
|
||||
"order": "ABC12",
|
||||
"is_cancellation": false,
|
||||
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
|
||||
@@ -95,14 +102,14 @@ Endpoints
|
||||
:query string refers: If set, only invoices refering to the given invoice will be returned.
|
||||
:query string locale: If set, only invoices with the given locale will be returned.
|
||||
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``date`` and
|
||||
``invoice_no``. Default: ``invoice_no``
|
||||
``nr`` (equals to ``number``). Default: ``nr``
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(invoice_no)/
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/
|
||||
|
||||
Returns information on one invoice, identified by its invoice number.
|
||||
|
||||
@@ -110,7 +117,7 @@ Endpoints
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/invoices/00001/ HTTP/1.1
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/invoices/SAMPLECONF-00001/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
|
||||
@@ -123,7 +130,7 @@ Endpoints
|
||||
Content-Type: text/javascript
|
||||
|
||||
{
|
||||
"invoice_no": "00001",
|
||||
"number": "SAMPLECONF-00001",
|
||||
"order": "ABC12",
|
||||
"is_cancellation": false,
|
||||
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
|
||||
|
||||
@@ -115,5 +115,5 @@ class InvoiceSerializer(I18nAwareModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = ('order', 'invoice_no', 'is_cancellation', 'invoice_from', 'invoice_to', 'date', 'refers', 'locale',
|
||||
fields = ('order', 'number', 'is_cancellation', 'invoice_from', 'invoice_to', 'date', 'refers', 'locale',
|
||||
'introductory_text', 'additional_text', 'payment_provider_text', 'footer_text', 'lines')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import django_filters
|
||||
from django.db.models import Q
|
||||
from django.db.models.functions import Concat
|
||||
from django.http import FileResponse
|
||||
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||
from rest_framework import viewsets
|
||||
@@ -137,12 +138,21 @@ class OrderPositionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
|
||||
|
||||
class InvoiceFilter(FilterSet):
|
||||
refers = django_filters.CharFilter(name='refers', lookup_expr='invoice_no__iexact')
|
||||
refers = django_filters.CharFilter(method='refers_qs')
|
||||
number = django_filters.CharFilter(method='nr_qs')
|
||||
order = django_filters.CharFilter(name='order', lookup_expr='code__iexact')
|
||||
|
||||
def refers_qs(self, queryset, name, value):
|
||||
return queryset.annotate(
|
||||
refers_nr=Concat('refers__prefix', 'refers__invoice_no')
|
||||
).filter(refers_nr__iexact=value)
|
||||
|
||||
def nr_qs(self, queryset, name, value):
|
||||
return queryset.filter(nr__iexact=value)
|
||||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = ['order', 'invoice_no', 'is_cancellation', 'refers', 'locale']
|
||||
fields = ['order', 'number', 'is_cancellation', 'refers', 'locale']
|
||||
|
||||
|
||||
class RetryException(APIException):
|
||||
@@ -155,15 +165,17 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = InvoiceSerializer
|
||||
queryset = Invoice.objects.none()
|
||||
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||
ordering = ('invoice_no',)
|
||||
ordering_fields = ('invoice_no', 'date')
|
||||
ordering = ('nr',)
|
||||
ordering_fields = ('nr', 'date')
|
||||
filter_class = InvoiceFilter
|
||||
lookup_field = 'invoice_no'
|
||||
lookup_url_kwarg = 'invoice_no'
|
||||
permission = 'can_view_orders'
|
||||
lookup_url_kwarg = 'number'
|
||||
lookup_field = 'nr'
|
||||
|
||||
def get_queryset(self):
|
||||
return self.request.event.invoices.prefetch_related('lines').select_related('order')
|
||||
return self.request.event.invoices.prefetch_related('lines').select_related('order', 'refers').annotate(
|
||||
nr=Concat('prefix', 'invoice_no')
|
||||
)
|
||||
|
||||
@detail_route()
|
||||
def download(self, request, **kwargs):
|
||||
|
||||
@@ -256,7 +256,7 @@ def invoice(order):
|
||||
|
||||
TEST_INVOICE_RES = {
|
||||
"order": "FOO",
|
||||
"invoice_no": "00001",
|
||||
"number": "DUMMY-00001",
|
||||
"is_cancellation": False,
|
||||
"invoice_from": "",
|
||||
"invoice_to": "Sample company",
|
||||
@@ -291,10 +291,10 @@ def test_invoice_list(token_client, organizer, event, order, invoice):
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?order=BAR'.format(organizer.slug, event.slug))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?invoice_no={}'.format(
|
||||
organizer.slug, event.slug, invoice.invoice_no))
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?number={}'.format(
|
||||
organizer.slug, event.slug, invoice.number))
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?invoice_no=XXX'.format(
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?number=XXX'.format(
|
||||
organizer.slug, event.slug))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
@@ -313,15 +313,15 @@ def test_invoice_list(token_client, organizer, event, order, invoice):
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?is_cancellation=true'.format(
|
||||
organizer.slug, event.slug))
|
||||
assert len(resp.data['results']) == 1
|
||||
assert resp.data['results'][0]['invoice_no'] == ic.invoice_no
|
||||
assert resp.data['results'][0]['number'] == ic.number
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?refers={}'.format(
|
||||
organizer.slug, event.slug, invoice.invoice_no))
|
||||
organizer.slug, event.slug, invoice.number))
|
||||
assert len(resp.data['results']) == 1
|
||||
assert resp.data['results'][0]['invoice_no'] == ic.invoice_no
|
||||
assert resp.data['results'][0]['number'] == ic.number
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?refers={}'.format(
|
||||
organizer.slug, event.slug, ic.invoice_no))
|
||||
organizer.slug, event.slug, ic.number))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
|
||||
@@ -330,6 +330,6 @@ def test_invoice_detail(token_client, organizer, event, invoice):
|
||||
res = dict(TEST_INVOICE_RES)
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/{}/'.format(organizer.slug, event.slug,
|
||||
invoice.invoice_no))
|
||||
invoice.number))
|
||||
assert resp.status_code == 200
|
||||
assert res == resp.data
|
||||
|
||||
Reference in New Issue
Block a user