Refs #654 -- API: Writable item endpoints (#676)

* MKBDIGI-184: Basic create added for API items endpoint

* MKBDIGI-184: Starting endpoint for GET /api/v1/organizers/(organizer)/events/(event)/items/(id)/variations/

* MKBDIGI-184: endpoint for GET /api/v1/organizers/(organizer)/events/(event)/items/(id)/variations/

* MKBDIGI-184: Completed endpoint for variations

* MKBDIGI-184: Added endpoint for addons

* MKBDIGI-184: Added Item validation

* MKBDIGI-184: Added check for order/cart positions on item variation destroy.

* MKBDIGI-184: Fixed check for order/cart positions on item variation destroy.

* MKBDIGI-184: Updated tests, validation for addons

* MKBDIGI-184: Documentation feedback corrections

* MKBDIGI-184: Added documentation for item add-ons

* MKBDIGI-184: Code formatting fixes

* MKBDIGI-184: Feedback fixes

* MKBDIGI-184: Updated tests for delete item

* MKBDIGI-184: Cleaned up tests

* MKBDIGI-184: Added additional test URLs

* MKBDIGI-184: Documentation fixes

* MKBDIGI-184: Fixed read-only fields/Documentation

* MKBDIGI-184: Documentation fixes

* MKBDIGI-184: Added helper for dict merge for 3.4 compatibility

* MKBDIGI-184: Validation updates

* MKBDIGI-184: Fixed permissions test error. Changed to HTTP 404 for POST to addons endpoint

* MKBDIGI-184: Implemented nested variations and add-ons for POST on the item endpoint.
This commit is contained in:
Ture Gjørup
2018-02-01 15:43:51 +01:00
committed by Raphael Michel
parent f5dba45fa0
commit 8eaada992f
13 changed files with 1854 additions and 28 deletions

View File

@@ -10,6 +10,8 @@ Resources and endpoints
taxrules
categories
items
item_variations
item_add-ons
questions
quotas
orders

View File

@@ -0,0 +1,246 @@
Item add-ons
=====
Resource description
--------------------
With add-ons, you can specify products that can be bought as an addition to this specific product. For example, if you
host a conference with a base conference ticket and a number of workshops, you could define the workshops as add-ons to
the conference ticket. With this configuration, the workshops cannot be bought on their own but only in combination with
a conference ticket. You can here specify categories of products that can be used as add-ons to this product. You can
also specify the minimum and maximum number of add-ons of the given category that can or need to be chosen. The user can
buy every add-on from the category at most once. If an add-on product has multiple variations, only one of them can be
bought.
The add-ons resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the add-on
addon_category integer Internal ID of the item category the add-on can be
chosen from.
min_count integer The minimal number of add-ons that need to be chosen.
max_count integer The maximal number of add-ons that can be chosen.
position integer An integer, used for sorting
price_included boolean Adding this add-on to the item is free
===================================== ========================== =======================================================
.. versionchanged:: 1.12
This resource has been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/addons/
Returns a list of all add-ons for a given item.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/items/11/addons/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 3,
"addon_category": 1,
"min_count": 0,
"max_count": 10,
"position": 0,
"price_included": true
},
{
"id": 4,
"addon_category": 2,
"min_count": 0,
"max_count": 10,
"position": 1,
"price_included": true
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param item: The ``id`` field of the item to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event/item does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/addons/(id)/
Returns information on one add-on, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/items/1/addons/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 3,
"addon_category": 1,
"min_count": 0,
"max_count": 10,
"position": 1,
"price_included": true
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param item: The ``id`` field of the item to fetch
:param id: The ``id`` field of the add-on 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:post:: /api/v1/organizers/bigevents/events/sampleconf/items/1/addons/
Creates a new add-on
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/(organizer)/events/(event)/items/(item)/addons/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content: application/json
{
"addon_category": 1,
"min_count": 0,
"max_count": 10,
"position": 1,
"price_included": true
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 3,
"addon_category": 1,
"min_count": 0,
"max_count": 10,
"position": 1,
"price_included": true
}
:param organizer: The ``slug`` field of the organizer of the event/item to create a add-on for
:param event: The ``slug`` field of the event to create a add-on for
:param item: The ``id`` field of the item to create a add-on for
:statuscode 201: no error
:statuscode 400: The add-on could not be created due to invalid submitted data.
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to create this resource.
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/addon/(id)/
Update an add-on. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide all fields of
the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the fields that you
want to change.
You can change all fields of the resource except the ``id`` field.
**Example request**:
.. sourcecode:: http
PATCH /api/v1/organizers/bigevents/events/sampleconf/items/1/addons/3/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content-Type: application/json
Content-Length: 94
{
"min_count": 0,
"max_count": 10,
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 3,
"addon_category": 1,
"min_count": 0,
"max_count": 10,
"position": 1,
"price_included": true
}
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param item: The ``id`` field of the item to modify
:param id: The ``id`` field of the add-on to modify
:statuscode 200: no error
:statuscode 400: The add-on could not be modified due to invalid submitted data
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to change this resource.
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/items/(id)/addons/(id)/
Delete an add-on.
**Example request**:
.. sourcecode:: http
DELETE /api/v1/organizers/bigevents/events/sampleconf/items/1/addons/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 204 No Content
Vary: Accept
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param id: The ``id`` field of the item to modify
:param id: The ``id`` field of the add-on to delete
:statuscode 204: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.

View File

@@ -0,0 +1,258 @@
Item variations
=====
Resource description
--------------------
Variations of items can be use for products (items) that are available in different sizes, colors or other variations
of the same product.
The addons resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the variation
default_price money (string) The price set directly for this variation or ``null``
price money (string) The price used for this variation. This is either the
same as ``default_price`` if that value is set or equal
to the item's ``default_price`` (read-only).
active boolean If ``False``, this variation will not be sold or shown.
description multi-lingual string A public description of the variation. May contain
Markdown syntax or can be ``null``.
position integer An integer, used for sorting
===================================== ========================== =======================================================
.. versionchanged:: 1.12
This resource has been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/variations/
Returns a list of all variations for a given item.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/items/11/variations/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"value": {
"en": "S"
},
"active": true,
"description": {
"en": "Test2"
},
"position": 0,
"default_price": "223.00",
"price": 223.0
},
{
"id": 3,
"value": {
"en": "L"
},
"active": true,
"description": {},
"position": 1,
"default_price": null,
"price": 15.0
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query boolean active: If set to ``true`` or ``false``, only items with this value for the field ``active`` will be
returned.
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param item: The ``id`` field of the item to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event/item does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/variations/(id)/
Returns information on one variation, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/items/1/variations/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 3,
"value": {
"en": "Student"
},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param item: The ``id`` field of the item to fetch
:param id: The ``id`` field of the variation 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:post:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/variations/
Creates a new variation
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/bigevents/events/sampleconf/items/1/variations/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content: application/json
{
"value": {"en": "Student"},
"default_price": "10.00",
"active": true,
"description": null,
"position": 0
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 1,
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
}
:param organizer: The ``slug`` field of the organizer of the event/item to create a variation for
:param event: The ``slug`` field of the event to create a variation for
:param item: The ``id`` field of the item to create a variation for
:statuscode 201: no error
:statuscode 400: The variation could not be created due to invalid submitted data.
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to create this resource.
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/variations/(id)/
Update a variation. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide all fields of
the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the fields that you
want to change.
You can change all fields of the resource except the ``id`` and the ``price`` field.
**Example request**:
.. sourcecode:: http
PATCH /api/v1/organizers/bigevents/events/sampleconf/items/1/variations/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content-Type: application/json
Content-Length: 94
{
"active": false,
"position": 1
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 1,
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": false,
"description": null,
"position": 1
}
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param id: The ``id`` field of the item to modify
:param id: The ``id`` field of the variation to modify
:statuscode 200: no error
:statuscode 400: The variation could not be modified due to invalid submitted data
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to change this resource.
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/items/(id)/variations/(id)/
Delete a variation.
**Example request**:
.. sourcecode:: http
DELETE /api/v1/organizers/bigevents/events/sampleconf/items/1/variations/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 204 No Content
Vary: Accept
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param id: The ``id`` field of the item to modify
:param id: The ``id`` field of the variation to delete
:statuscode 204: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.

View File

@@ -33,6 +33,7 @@ admission boolean ``True`` for it
(such as add-ons or merchandise).
position integer An integer, used for sorting
picture string A product picture to be displayed in the shop
(read-only).
available_from datetime The first date time at which this item can be bought
(or ``null``).
available_until datetime The last date time at which this item can be bought
@@ -53,10 +54,9 @@ max_per_order integer This product ca
checkin_attention boolean If ``True``, the check-in app should show a warning
that this ticket requires special attention if such
a product is being scanned.
has_variations boolean Shows whether or not this item has variations
(read-only).
has_variations boolean Shows whether or not this item has variations.
variations list of objects A list with one object for each variation of this item.
Can be empty.
Can be empty. Only writable on POST.
├ id integer Internal ID of the variation
├ default_price money (string) The price set directly for this variation or ``null``
├ price money (string) The price used for this variation. This is either the
@@ -66,12 +66,14 @@ variations list of objects A list with one
├ description multi-lingual string A public description of the variation. May contain
Markdown syntax or can be ``null``.
└ position integer An integer, used for sorting
addons list of objects Definition of add-ons that can be chosen for this item
addons list of objects Definition of add-ons that can be chosen for this item.
Only writable on POST.
├ addon_category integer Internal ID of the item category the add-on can be
chosen from.
├ min_count integer The minimal number of add-ons that need to be chosen.
├ max_count integer The maximal number of add-ons that can be chosen.
└ position integer An integer, used for sorting
└ price_included boolean Adding this add-on to the item is free
===================================== ========================== =======================================================
.. versionchanged:: 1.7
@@ -79,6 +81,20 @@ addons list of objects Definition of a
The attribute ``tax_rule`` has been added. ``tax_rate`` is kept for compatibility. The attribute
``checkin_attention`` has been added.
.. versionchanged:: 1.12
The write operations ``POST``, ``PATCH``, ``PUT``, and ``DELETE`` have been added.
The attribute ``price_included`` has been added to ``addons``.
Notes
-----
Please note that an item either always has variations or never has. Once created with variations the item can never
change to an item without and vice versa. To create an item with variations ensure that you POST an item with at least
one variation.
Also note that ``variations`` and ``addons`` are only supported on ``POST``. To update/delete variations and add-ons please
use the dedicated nested endpoints. By design this endpoint does not support ``PATCH`` and ``PUT`` with nested
``variations`` and/or ``addons``.
Endpoints
---------
@@ -239,3 +255,226 @@ Endpoints
: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:post:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/
Creates a new item
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/bigevents/events/sampleconf/items/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content: application/json
{
"id": 1,
"name": {"en": "Standard ticket"},
"default_price": "23.00",
"category": null,
"active": true,
"description": null,
"free_price": false,
"tax_rate": "0.00",
"tax_rule": 1,
"admission": false,
"position": 0,
"picture": null,
"available_from": null,
"available_until": null,
"require_voucher": false,
"hide_without_voucher": false,
"allow_cancel": true,
"min_per_order": null,
"max_per_order": null,
"checkin_attention": false,
"variations": [
{
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
},
{
"value": {"en": "Regular"},
"default_price": null,
"price": "23.00",
"active": true,
"description": null,
"position": 1
}
],
"addons": []
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 1,
"name": {"en": "Standard ticket"},
"default_price": "23.00",
"category": null,
"active": true,
"description": null,
"free_price": false,
"tax_rate": "0.00",
"tax_rule": 1,
"admission": false,
"position": 0,
"picture": null,
"available_from": null,
"available_until": null,
"require_voucher": false,
"hide_without_voucher": false,
"allow_cancel": true,
"min_per_order": null,
"max_per_order": null,
"checkin_attention": false,
"has_variations": true,
"variations": [
{
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
},
{
"value": {"en": "Regular"},
"default_price": null,
"price": "23.00",
"active": true,
"description": null,
"position": 1
}
],
"addons": []
}
:param organizer: The ``slug`` field of the organizer of the event to create an item for
:param event: The ``slug`` field of the event to create an item for
:statuscode 201: no error
:statuscode 400: The item could not be created due to invalid submitted data.
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to create this resource.
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/items/(item)/
Update an item. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide all fields of
the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the fields that you
want to change.
You can change all fields of the resource except the ``has_variations``, ``variations`` and the ``addon`` field. If
you need to update/delete variations or add-ons please use the nested dedicated endpoints.
**Example request**:
.. sourcecode:: http
PATCH /api/v1/organizers/bigevents/events/sampleconf/items/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content-Type: application/json
Content-Length: 94
{
"name": {"en": "Ticket"},
"default_price": "25.00"
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 1,
"name": {"en": "Ticket"},
"default_price": "25.00",
"category": null,
"active": true,
"description": null,
"free_price": false,
"tax_rate": "0.00",
"tax_rule": 1,
"admission": false,
"position": 0,
"picture": null,
"available_from": null,
"available_until": null,
"require_voucher": false,
"hide_without_voucher": false,
"allow_cancel": true,
"min_per_order": null,
"max_per_order": null,
"checkin_attention": false,
"has_variations": true,
"variations": [
{
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
},
{
"value": {"en": "Regular"},
"default_price": null,
"price": "23.00",
"active": true,
"description": null,
"position": 1
}
],
"addons": []
}
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param id: The ``id`` field of the item to modify
:statuscode 200: no error
:statuscode 400: The item could not be modified due to invalid submitted data
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to change this resource.
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/items/(id)/
Delete an item.
**Example request**:
.. sourcecode:: http
DELETE /api/v1/organizers/bigevents/events/sampleconf/items/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 204 No Content
Vary: Accept
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param id: The ``id`` field of the item to delete
:statuscode 204: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.