Compare commits
965 Commits
release/3.
...
v3.12.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f965edc22 | ||
|
|
508538aa76 | ||
|
|
4511963aca | ||
|
|
2c9277d11b | ||
|
|
93ee5450ec | ||
|
|
e1b3e20148 | ||
|
|
880e3fd93e | ||
|
|
cea201af16 | ||
|
|
93252e1645 | ||
|
|
65f8b68634 | ||
|
|
db0aaf58b7 | ||
|
|
ae07e433d4 | ||
|
|
4fed690209 | ||
|
|
6ca6f7f3ef | ||
|
|
2cceb4f056 | ||
|
|
bfa9b380bb | ||
|
|
65d9640dbc | ||
|
|
b0221b0e92 | ||
|
|
1233dd64a8 | ||
|
|
9a5d17f14a | ||
|
|
65b0df056f | ||
|
|
997f56f758 | ||
|
|
f30541e465 | ||
|
|
efb6a25387 | ||
|
|
4a65828275 | ||
|
|
9627d77a9d | ||
|
|
c2069663f3 | ||
|
|
5ca1366fad | ||
|
|
b0bdae33c1 | ||
|
|
3ced206d04 | ||
|
|
539ee2d9db | ||
|
|
8ed9684b5d | ||
|
|
882b1b6a80 | ||
|
|
48b6c90a17 | ||
|
|
c4f6468579 | ||
|
|
b7cbe6054b | ||
|
|
b38af13032 | ||
|
|
142386cb9e | ||
|
|
d932aecc22 | ||
|
|
7fe68140fd | ||
|
|
fdf69c4695 | ||
|
|
d57ac92676 | ||
|
|
9578fa73ef | ||
|
|
fcb68cb551 | ||
|
|
8b84aad39e | ||
|
|
b698c8380c | ||
|
|
f7b5f4744b | ||
|
|
a999dd01d1 | ||
|
|
a77a9d6891 | ||
|
|
b3bb3cb9a0 | ||
|
|
1009ce52b2 | ||
|
|
db420a56e1 | ||
|
|
cefdb9f65c | ||
|
|
b7037b9432 | ||
|
|
4f8de4e1fc | ||
|
|
987597b298 | ||
|
|
bb38e2216b | ||
|
|
3865063b12 | ||
|
|
8037a8ce7f | ||
|
|
a0dd8f74e4 | ||
|
|
38e067da9c | ||
|
|
3b6ce19959 | ||
|
|
2b8e6aab39 | ||
|
|
bc7444d7d9 | ||
|
|
0436064d31 | ||
|
|
1c6984fc2d | ||
|
|
050b0888fb | ||
|
|
1c1bca2dd3 | ||
|
|
e499780414 | ||
|
|
74b11305e9 | ||
|
|
4f0562e845 | ||
|
|
22c0209bed | ||
|
|
d4c26d00be | ||
|
|
ab40b3b06b | ||
|
|
dac0252326 | ||
|
|
9453f07059 | ||
|
|
74cac2a914 | ||
|
|
563886b901 | ||
|
|
7ef319fb35 | ||
|
|
bc11e85e42 | ||
|
|
5d9cb2dc0d | ||
|
|
9ad00b7ce6 | ||
|
|
02460fc648 | ||
|
|
70a2ebe830 | ||
|
|
522dbfe1c5 | ||
|
|
4e202f523d | ||
|
|
0bad8d70c8 | ||
|
|
1cf0fc9f96 | ||
|
|
7b46292da3 | ||
|
|
0482920a01 | ||
|
|
07bd47d934 | ||
|
|
8241ddf5be | ||
|
|
a62c7939ae | ||
|
|
9e4dc344a4 | ||
|
|
d673a43130 | ||
|
|
92d7268945 | ||
|
|
8e318dd95d | ||
|
|
50a8063fd3 | ||
|
|
6f41b039b4 | ||
|
|
12ca4552dd | ||
|
|
4f780031f7 | ||
|
|
9fe2b31620 | ||
|
|
93db33515f | ||
|
|
b06e849363 | ||
|
|
95b001e109 | ||
|
|
52b940b0bf | ||
|
|
d28fec544a | ||
|
|
7ca09cc73b | ||
|
|
1f151c4a84 | ||
|
|
1473845f33 | ||
|
|
659d166c02 | ||
|
|
e3d9b3546d | ||
|
|
ffde521fcb | ||
|
|
ed0e28eee5 | ||
|
|
22bba28bea | ||
|
|
6e20f33ef5 | ||
|
|
4ef95346a7 | ||
|
|
fcd0c65567 | ||
|
|
7c212ba79d | ||
|
|
0a1a9fcf88 | ||
|
|
bfabed5b44 | ||
|
|
8883e2642a | ||
|
|
460b5ee588 | ||
|
|
c74d8bb126 | ||
|
|
07c62f4362 | ||
|
|
bb59cbca75 | ||
|
|
fef3ebcb91 | ||
|
|
dfc7483b5d | ||
|
|
b80ed9079b | ||
|
|
6801b027cd | ||
|
|
f7e0c76f0f | ||
|
|
02c59f85d9 | ||
|
|
6257b8cb54 | ||
|
|
fec682dddb | ||
|
|
ff74f13fce | ||
|
|
d0d84f2a13 | ||
|
|
bf59ce2661 | ||
|
|
b4a7729cb5 | ||
|
|
f2e5e89970 | ||
|
|
4fd773caf6 | ||
|
|
6402f0d86e | ||
|
|
f5d93eaffa | ||
|
|
3f40a8e6fa | ||
|
|
b947467589 | ||
|
|
810f3d7d31 | ||
|
|
e8f3ad633a | ||
|
|
301849f771 | ||
|
|
ee6a595e26 | ||
|
|
980296e38a | ||
|
|
0a62ee0e33 | ||
|
|
afc1013d69 | ||
|
|
16cf3cec76 | ||
|
|
0105b9642d | ||
|
|
3ec15fa529 | ||
|
|
703eebab47 | ||
|
|
3aec3a52fc | ||
|
|
fd93cac8cf | ||
|
|
e139924696 | ||
|
|
da725c0bff | ||
|
|
dca61447cf | ||
|
|
f54bf3f1ea | ||
|
|
3cef9bac26 | ||
|
|
4f20849e4b | ||
|
|
758981fc1b | ||
|
|
9b671d6370 | ||
|
|
3bfaf55094 | ||
|
|
3708dab656 | ||
|
|
14ad7716bd | ||
|
|
985d3c3993 | ||
|
|
fa2222e629 | ||
|
|
13eabdd7f4 | ||
|
|
4fd748e6d9 | ||
|
|
f48ded0165 | ||
|
|
903ea09140 | ||
|
|
fadc610b8e | ||
|
|
ac4b8a392b | ||
|
|
22d986a709 | ||
|
|
bca34145f1 | ||
|
|
97af6f7311 | ||
|
|
67156a67aa | ||
|
|
4ed872d4ef | ||
|
|
5cd6cba0a2 | ||
|
|
72bb5bd177 | ||
|
|
d392e14a96 | ||
|
|
d7459b3b83 | ||
|
|
b4778b5845 | ||
|
|
5a09759cb9 | ||
|
|
2fbaa90d76 | ||
|
|
93f10d33a9 | ||
|
|
e9a972ad60 | ||
|
|
a31f0c1bc8 | ||
|
|
1b0c2f3bb7 | ||
|
|
766428c469 | ||
|
|
d85583f70a | ||
|
|
ee801bd717 | ||
|
|
af0e8ec992 | ||
|
|
bc3325c1cb | ||
|
|
753c331887 | ||
|
|
cfc9055ec1 | ||
|
|
c131a2ac3a | ||
|
|
17fe3355d1 | ||
|
|
0381d42d41 | ||
|
|
b73db911e9 | ||
|
|
1f3d4a2810 | ||
|
|
3cbcf663e5 | ||
|
|
ae0637a3d6 | ||
|
|
a6a9c08a0a | ||
|
|
f3b3d0b8f7 | ||
|
|
9490f20a6c | ||
|
|
4555a917b2 | ||
|
|
951e99d0da | ||
|
|
d0b002cf0c | ||
|
|
4fb0b948ec | ||
|
|
2384478b45 | ||
|
|
f3a2d0cb03 | ||
|
|
1b11d88442 | ||
|
|
954951ddfa | ||
|
|
c01b96bdfc | ||
|
|
c78e88a1ba | ||
|
|
4cb18218b2 | ||
|
|
450d017c32 | ||
|
|
655977e33d | ||
|
|
0cb0620df0 | ||
|
|
c8bf069650 | ||
|
|
e65087fd68 | ||
|
|
d67d389b9d | ||
|
|
0e805e50f9 | ||
|
|
a4d133731e | ||
|
|
c74e7fd4fb | ||
|
|
0e405d2327 | ||
|
|
035c707427 | ||
|
|
787e7ec993 | ||
|
|
09a9b4a456 | ||
|
|
e2547c2761 | ||
|
|
c7b2baf40f | ||
|
|
59595c9db8 | ||
|
|
2f8baecd68 | ||
|
|
a76f74b161 | ||
|
|
f2518101ef | ||
|
|
ec667545e8 | ||
|
|
afb789226c | ||
|
|
bca7a6db93 | ||
|
|
429ad4da37 | ||
|
|
cd6e6004af | ||
|
|
e9d5665a3d | ||
|
|
4cbc30a7ea | ||
|
|
2b0388c2ee | ||
|
|
06b8826e57 | ||
|
|
7c6f0f45a3 | ||
|
|
93399f51b3 | ||
|
|
87bd54b233 | ||
|
|
3fb237f434 | ||
|
|
d7640d25f5 | ||
|
|
1669d3f5c7 | ||
|
|
5aa3f3e772 | ||
|
|
b7a2f0257f | ||
|
|
5c0f29f959 | ||
|
|
59655dca82 | ||
|
|
af2b4ebb4b | ||
|
|
d5b3528f92 | ||
|
|
0a1b41235b | ||
|
|
8ca544064b | ||
|
|
1e2b305376 | ||
|
|
bfa20e995a | ||
|
|
e7fd0f116b | ||
|
|
e836da09cd | ||
|
|
22c6553a48 | ||
|
|
ea5fc3df40 | ||
|
|
7977b6dc15 | ||
|
|
59df5fe052 | ||
|
|
c4e00e7601 | ||
|
|
b3fd515652 | ||
|
|
6ee54f6cc1 | ||
|
|
403dc9cf98 | ||
|
|
eb462b1950 | ||
|
|
cb6d50e570 | ||
|
|
32a2a99b7b | ||
|
|
7859985ff0 | ||
|
|
7b7cf76028 | ||
|
|
4fda9b2205 | ||
|
|
ede93f1669 | ||
|
|
4af4dbd9cf | ||
|
|
820f6d52a5 | ||
|
|
8d04974caa | ||
|
|
8021c9e865 | ||
|
|
874ea6750b | ||
|
|
8f2c125435 | ||
|
|
2f21dc8c3c | ||
|
|
05135c779c | ||
|
|
f08f06ddff | ||
|
|
9c28537d1c | ||
|
|
95b1a4a434 | ||
|
|
019801e9dc | ||
|
|
3e97fd87d1 | ||
|
|
8bcc0e4641 | ||
|
|
878becfee9 | ||
|
|
273c34999c | ||
|
|
3f4f9d98de | ||
|
|
d703eeb770 | ||
|
|
b7754d8737 | ||
|
|
ed62ecaccb | ||
|
|
5c3ef3f2b9 | ||
|
|
f3282807e2 | ||
|
|
52944ff3a3 | ||
|
|
23a9018988 | ||
|
|
936c771d5e | ||
|
|
d064a7affa | ||
|
|
4b894eb433 | ||
|
|
6c7ef89779 | ||
|
|
e8f3a66a8e | ||
|
|
d999971249 | ||
|
|
fb701f25f4 | ||
|
|
913596459a | ||
|
|
04e9ea1ae7 | ||
|
|
5dc09019ff | ||
|
|
7c3671b383 | ||
|
|
b91c16538e | ||
|
|
9ba517109d | ||
|
|
5f86fbc21d | ||
|
|
fae35cc56f | ||
|
|
78c5eb4516 | ||
|
|
860f4c36a4 | ||
|
|
311dcfaab0 | ||
|
|
83a6041a32 | ||
|
|
a2f9bb73ad | ||
|
|
fb92c9dd64 | ||
|
|
aa1910fd70 | ||
|
|
f66c266ff7 | ||
|
|
7cc5179e85 | ||
|
|
f633cc3103 | ||
|
|
5e212c83e4 | ||
|
|
2d5768aa20 | ||
|
|
8ea66bc05b | ||
|
|
eba17e22fb | ||
|
|
620c956ef8 | ||
|
|
35debba865 | ||
|
|
a635ea527e | ||
|
|
6e76db40ed | ||
|
|
7956074d8b | ||
|
|
7a3418e32f | ||
|
|
0bfc436970 | ||
|
|
b6fc02255d | ||
|
|
a06f94fde1 | ||
|
|
d5073f416c | ||
|
|
b32ea0dec4 | ||
|
|
932851cf96 | ||
|
|
4513cd7ec3 | ||
|
|
261878b3fe | ||
|
|
31590f7e6c | ||
|
|
ebe7560f14 | ||
|
|
c5b722ebc1 | ||
|
|
5ea961819d | ||
|
|
983d734c6a | ||
|
|
c1bca2f207 | ||
|
|
118f0f55e9 | ||
|
|
d1146add38 | ||
|
|
fc18788cb8 | ||
|
|
a2eb4444b4 | ||
|
|
606d13e303 | ||
|
|
d90fcee5e1 | ||
|
|
e9a4c3845a | ||
|
|
018fac2361 | ||
|
|
41dd71879e | ||
|
|
738e5d07aa | ||
|
|
a22451140b | ||
|
|
6759506838 | ||
|
|
82bb3f3b6e | ||
|
|
cdb8a92a47 | ||
|
|
7597344897 | ||
|
|
c94d384e86 | ||
|
|
b2357b7e29 | ||
|
|
c7d1e5d069 | ||
|
|
754d498938 | ||
|
|
ec7fc05108 | ||
|
|
bbba0df6c4 | ||
|
|
65e87455ec | ||
|
|
e6d09baacc | ||
|
|
fbd38fef58 | ||
|
|
253f944951 | ||
|
|
7f30f753d7 | ||
|
|
8789a42dc1 | ||
|
|
e7740b1735 | ||
|
|
586da71a64 | ||
|
|
68697f0c6a | ||
|
|
a2e1bc9c20 | ||
|
|
89a82d75a9 | ||
|
|
a2414081af | ||
|
|
c812d39b39 | ||
|
|
c6f3fdd8e4 | ||
|
|
30e0f5ebc7 | ||
|
|
f767f2f644 | ||
|
|
750c3c5201 | ||
|
|
7d9220ae3e | ||
|
|
69879bdae0 | ||
|
|
0e245b41ee | ||
|
|
2839ee1ffd | ||
|
|
d72a03c434 | ||
|
|
b6f47f6f4a | ||
|
|
ca2dd0d6b6 | ||
|
|
c4415beb8c | ||
|
|
35c8684cd4 | ||
|
|
9bb5c57792 | ||
|
|
1c8699662d | ||
|
|
9b367cb28b | ||
|
|
896ba5b06b | ||
|
|
8f3dbba859 | ||
|
|
bf5b92c465 | ||
|
|
aef09003d9 | ||
|
|
9d22e833a6 | ||
|
|
1e121c0f75 | ||
|
|
373755a502 | ||
|
|
6f694b60ca | ||
|
|
77f76195c8 | ||
|
|
355dd4463b | ||
|
|
c0c39223aa | ||
|
|
db7f8d9658 | ||
|
|
c15344ced2 | ||
|
|
0f3f15a736 | ||
|
|
478f6e3029 | ||
|
|
4c77e2f16e | ||
|
|
80b6a3d27d | ||
|
|
89e8d3d12f | ||
|
|
baf8a4ae18 | ||
|
|
2cdaf07c46 | ||
|
|
cf76a2e24d | ||
|
|
559b4a8e66 | ||
|
|
59bf11b98d | ||
|
|
5b3551fb60 | ||
|
|
72a5008513 | ||
|
|
c5ace8447d | ||
|
|
28b82841c2 | ||
|
|
fbe10a981b | ||
|
|
21c22aa63a | ||
|
|
fb4116012f | ||
|
|
53fe4a32cd | ||
|
|
ff066898d4 | ||
|
|
cbb848b3fa | ||
|
|
98dfdd8b01 | ||
|
|
0e95a7863f | ||
|
|
0913f5bc18 | ||
|
|
d1eb4c4cce | ||
|
|
4a0a3aff59 | ||
|
|
83908fde45 | ||
|
|
143ac10991 | ||
|
|
413cbec4b9 | ||
|
|
b168516d78 | ||
|
|
d0ccc42aff | ||
|
|
7aa793f4f7 | ||
|
|
1b48b519e3 | ||
|
|
5f502776b1 | ||
|
|
985e1ac9bf | ||
|
|
df1014d62f | ||
|
|
062afc42d3 | ||
|
|
1fb861a117 | ||
|
|
0a2346778d | ||
|
|
605a21a0cf | ||
|
|
1cfec9cc99 | ||
|
|
0a97b0ce67 | ||
|
|
60eee25cd1 | ||
|
|
779ec6c3f6 | ||
|
|
988eb85c05 | ||
|
|
556cb7c46d | ||
|
|
86e3c30633 | ||
|
|
6276f213b9 | ||
|
|
524f6c9975 | ||
|
|
125a14c8e9 | ||
|
|
c7f0e6f652 | ||
|
|
1e58ef6f9e | ||
|
|
41127ce978 | ||
|
|
99b42d201e | ||
|
|
265da6c746 | ||
|
|
d58c8559fc | ||
|
|
b5dca762f0 | ||
|
|
a310c33497 | ||
|
|
fc5c3caf66 | ||
|
|
bff1041878 | ||
|
|
2626259492 | ||
|
|
18415c62bb | ||
|
|
85f546a3a6 | ||
|
|
829b0041fc | ||
|
|
4968a6d995 | ||
|
|
033deb7cf2 | ||
|
|
e23e88f5c3 | ||
|
|
c3745e792b | ||
|
|
735d4564f8 | ||
|
|
b305ac012c | ||
|
|
7bd9a01f5e | ||
|
|
8bebea61f1 | ||
|
|
6714ab24ee | ||
|
|
a54dbc0110 | ||
|
|
19fa2fb016 | ||
|
|
12b5d6663e | ||
|
|
ca4db5f628 | ||
|
|
b6a343a623 | ||
|
|
dc451cdeea | ||
|
|
6732d13439 | ||
|
|
5bf67ba613 | ||
|
|
8885b50972 | ||
|
|
940566ab93 | ||
|
|
e7b9c49620 | ||
|
|
c8ef825de5 | ||
|
|
5b25a68599 | ||
|
|
e26a07d44d | ||
|
|
6842127802 | ||
|
|
3c5948d2e0 | ||
|
|
ed3542e219 | ||
|
|
e439b20618 | ||
|
|
5c1fe6f68c | ||
|
|
e4e91523a0 | ||
|
|
00827700de | ||
|
|
0a87225a9a | ||
|
|
9371d221bf | ||
|
|
08a3c846b6 | ||
|
|
1c84de9ab2 | ||
|
|
980f4012bc | ||
|
|
591d70eabe | ||
|
|
2c4609604d | ||
|
|
30c2b8b03f | ||
|
|
a685af6433 | ||
|
|
f179a220bc | ||
|
|
b61893e3b1 | ||
|
|
d3282a1acb | ||
|
|
c585946e72 | ||
|
|
b6245b97ca | ||
|
|
51720c3afe | ||
|
|
4746b8e456 | ||
|
|
b2401f7641 | ||
|
|
b4cd11ef94 | ||
|
|
33682e1b38 | ||
|
|
e10e3300ba | ||
|
|
4f0eadfd6e | ||
|
|
0f9ec2ce7d | ||
|
|
93e3cf1d99 | ||
|
|
3affaa8c85 | ||
|
|
fddf134755 | ||
|
|
568398e4e7 | ||
|
|
fc08531639 | ||
|
|
bd25ce238d | ||
|
|
c88ce8a9a8 | ||
|
|
004403e2c8 | ||
|
|
0cde5288ac | ||
|
|
e585da2901 | ||
|
|
f369fca091 | ||
|
|
e0e638ac8c | ||
|
|
4abe906511 | ||
|
|
855a47776f | ||
|
|
c63c499a95 | ||
|
|
f06a23ae95 | ||
|
|
2b68a22aad | ||
|
|
86d42cc524 | ||
|
|
6e8040ac9d | ||
|
|
c742c9979b | ||
|
|
15f3880fcd | ||
|
|
6bf5d8cb5e | ||
|
|
27d772f52f | ||
|
|
6e9d921af6 | ||
|
|
1c9a1b5e02 | ||
|
|
640c05729b | ||
|
|
fc9e5166da | ||
|
|
b1eb5bb3df | ||
|
|
f690d74be7 | ||
|
|
c52fdc95a7 | ||
|
|
039ca36233 | ||
|
|
9920a47580 | ||
|
|
74acfbe2fd | ||
|
|
b0b8f32cb9 | ||
|
|
066cf510e3 | ||
|
|
aca963d960 | ||
|
|
582c7b50f7 | ||
|
|
d6b185193e | ||
|
|
fb92d500be | ||
|
|
27ed9ae4fd | ||
|
|
06fbf56c04 | ||
|
|
d843fc1545 | ||
|
|
cf2af3c94d | ||
|
|
5f50aa95eb | ||
|
|
626e332886 | ||
|
|
507e1a5b83 | ||
|
|
0d1aa2f96e | ||
|
|
df6038e39b | ||
|
|
922f12f55e | ||
|
|
fdea190d72 | ||
|
|
34fe34d50a | ||
|
|
3412c1d2a9 | ||
|
|
6f58f30d92 | ||
|
|
19b5610503 | ||
|
|
55670b92a8 | ||
|
|
e5cc15ffac | ||
|
|
249e6978ea | ||
|
|
a223d57124 | ||
|
|
2a5c24482e | ||
|
|
868292f9b3 | ||
|
|
5c24fd966a | ||
|
|
61490a9ee8 | ||
|
|
3c3333c485 | ||
|
|
4c19002be6 | ||
|
|
2c49eaeef8 | ||
|
|
481e29c3b2 | ||
|
|
0aebde62eb | ||
|
|
49e44f68ba | ||
|
|
84dc9f241d | ||
|
|
07b05f4a44 | ||
|
|
d1c1aed1f2 | ||
|
|
de9f7248cc | ||
|
|
0d45706608 | ||
|
|
016dd88e8b | ||
|
|
6362c27cba | ||
|
|
7396f29b82 | ||
|
|
ff9f6b6a36 | ||
|
|
7359b5543d | ||
|
|
74a0cafa0f | ||
|
|
16472e915d | ||
|
|
ec6844f900 | ||
|
|
e6455f8204 | ||
|
|
4c48fcd861 | ||
|
|
adfd7834fb | ||
|
|
a4b8315487 | ||
|
|
8594fecad4 | ||
|
|
61979f0c40 | ||
|
|
df5f8a340b | ||
|
|
651e797264 | ||
|
|
d40010fab6 | ||
|
|
89c3d59e6d | ||
|
|
b30569a941 | ||
|
|
fe230fe56d | ||
|
|
0b20d3f6f8 | ||
|
|
e895c13b28 | ||
|
|
5cc0bd5d36 | ||
|
|
569379e508 | ||
|
|
d975a68641 | ||
|
|
c992de341f | ||
|
|
11cc27dbd6 | ||
|
|
90e70eae25 | ||
|
|
9eacd38ec7 | ||
|
|
d1c96aa77c | ||
|
|
99e02bde36 | ||
|
|
e7da2aec53 | ||
|
|
d0c6f0f0e9 | ||
|
|
3ae148956f | ||
|
|
e0436039d2 | ||
|
|
29510b8617 | ||
|
|
2d88da3a67 | ||
|
|
fbb88602d4 | ||
|
|
7d7820a4ee | ||
|
|
8001063347 | ||
|
|
0c3a200355 | ||
|
|
ebb1cc1be7 | ||
|
|
45f120b0c3 | ||
|
|
bae0e45d00 | ||
|
|
057fd95706 | ||
|
|
597d4aa206 | ||
|
|
7f9b245eb5 | ||
|
|
42490c6dec | ||
|
|
60c0b7da12 | ||
|
|
7d41922274 | ||
|
|
fc7fbf31c5 | ||
|
|
da5433325c | ||
|
|
939a38d53b | ||
|
|
a57280004e | ||
|
|
ce896cec8f | ||
|
|
effc9723f1 | ||
|
|
cd5f6b66a1 | ||
|
|
0d35064d21 | ||
|
|
314ce5467f | ||
|
|
d97ef380a4 | ||
|
|
d3498c419d | ||
|
|
0d90ae9d53 | ||
|
|
796d6f92ef | ||
|
|
73faecaa39 | ||
|
|
e04e8e8ca6 | ||
|
|
89a9148073 | ||
|
|
205faafc57 | ||
|
|
db8ed065df | ||
|
|
c84ae364ba | ||
|
|
55a57dced2 | ||
|
|
62db01e353 | ||
|
|
e435e7140c | ||
|
|
f4d38965cc | ||
|
|
5d080a4ab2 | ||
|
|
7895729c38 | ||
|
|
3b003d0baa | ||
|
|
69a4a16793 | ||
|
|
cf3412d54d | ||
|
|
03bcfc7c5a | ||
|
|
a6c1c85591 | ||
|
|
1c8468c21b | ||
|
|
dcc54a0204 | ||
|
|
435b32a6b8 | ||
|
|
9e93560f7c | ||
|
|
e12e7a5dd3 | ||
|
|
e822ba5430 | ||
|
|
b1ee355663 | ||
|
|
ca40ddc39b | ||
|
|
1b85911a76 | ||
|
|
27b56b5aea | ||
|
|
5147508ef9 | ||
|
|
39ae22b8b2 | ||
|
|
65b612eabd | ||
|
|
48d2f98815 | ||
|
|
5dd5ff8a7c | ||
|
|
059bdc629e | ||
|
|
36532e5bbb | ||
|
|
ed318791fb | ||
|
|
4d61ec4d86 | ||
|
|
cc2f8ac3da | ||
|
|
770293e8ec | ||
|
|
0ab11a8134 | ||
|
|
7e56100c21 | ||
|
|
6fecb42e26 | ||
|
|
4c063272d4 | ||
|
|
029f113b06 | ||
|
|
7827b026fd | ||
|
|
bd4ccf4507 | ||
|
|
f95d2972d3 | ||
|
|
e642098a5f | ||
|
|
bf11dea798 | ||
|
|
9e47f37097 | ||
|
|
149c25e609 | ||
|
|
fccd7a5499 | ||
|
|
d16acf0bfd | ||
|
|
71c915f5f7 | ||
|
|
f1c29daa42 | ||
|
|
fec31823ee | ||
|
|
c056db46b6 | ||
|
|
640b9c876d | ||
|
|
25ad2ea475 | ||
|
|
d2dfbca913 | ||
|
|
7287a16711 | ||
|
|
c6e969b7fe | ||
|
|
c03c278ecd | ||
|
|
140f041cc1 | ||
|
|
de9c450648 | ||
|
|
6a4c81ff3c | ||
|
|
e117545b3f | ||
|
|
feb7f419d3 | ||
|
|
ea04c85486 | ||
|
|
094450564a | ||
|
|
66d3c4516f | ||
|
|
4b01c42f31 | ||
|
|
c0972ef39d | ||
|
|
4d1cbd8248 | ||
|
|
07eb71400a | ||
|
|
f6f72d4b7f | ||
|
|
08d89acffd | ||
|
|
28831d674f | ||
|
|
65f1c20af0 | ||
|
|
5b2b3d71ec | ||
|
|
15bdcb9973 | ||
|
|
1a1afcddc6 | ||
|
|
219c82b028 | ||
|
|
19e2158f19 | ||
|
|
23055cfe09 | ||
|
|
790f248388 | ||
|
|
ef8d9bdb93 | ||
|
|
0d9b534cee | ||
|
|
b1b303e598 | ||
|
|
b4f3a665af | ||
|
|
f71153db4a | ||
|
|
1643005a4b | ||
|
|
0ee2f674bc | ||
|
|
d142a09ad3 | ||
|
|
68c13aaa3c | ||
|
|
556c77a54b | ||
|
|
5b689e5fd2 | ||
|
|
57f5fbc131 | ||
|
|
7e80ec93d5 | ||
|
|
ee1928aeed | ||
|
|
5c62f2b852 | ||
|
|
ad8be705fd | ||
|
|
4635d9b5f7 | ||
|
|
ace32f3fc4 | ||
|
|
88a235da30 | ||
|
|
4ec24fc884 | ||
|
|
e2b9fe8e71 | ||
|
|
6f1c29581d | ||
|
|
9bf0a6dfcd | ||
|
|
3e6e324027 | ||
|
|
912e6816df | ||
|
|
d00aa2f3ad | ||
|
|
41fecf366c | ||
|
|
f7f751bda7 | ||
|
|
7b68614de3 | ||
|
|
c0fc259d17 | ||
|
|
d6cad265fc | ||
|
|
bb1882aca5 | ||
|
|
b887c2c43d | ||
|
|
c05bf779bd | ||
|
|
68ff001bb6 | ||
|
|
3c6fdd15af | ||
|
|
16957eec33 | ||
|
|
1bcf1ec26a | ||
|
|
d224b5387d | ||
|
|
27d6e49c4a | ||
|
|
50bb66a32b | ||
|
|
207149f681 | ||
|
|
e0ed25a1d3 | ||
|
|
c0c177d755 | ||
|
|
f2844ac686 | ||
|
|
d9fd4b33a0 | ||
|
|
d2415f46df | ||
|
|
ad7c745465 | ||
|
|
b260cca412 | ||
|
|
82c84a0fdc | ||
|
|
d703c4de7a | ||
|
|
ff5fbf1c15 | ||
|
|
41ff4bca7f | ||
|
|
37f45de8a5 | ||
|
|
71f01c17bd | ||
|
|
43b1df572f | ||
|
|
ecda905ceb | ||
|
|
4e59b02bb1 | ||
|
|
234bf093ff | ||
|
|
ae9bd1b6ba | ||
|
|
b84b51250f | ||
|
|
d0dd2116ca | ||
|
|
945218035e | ||
|
|
89f8436e9a | ||
|
|
4992b17966 | ||
|
|
f7d057f9fa | ||
|
|
96ba32b1bb | ||
|
|
02792e3ae8 | ||
|
|
a87fe3ef41 | ||
|
|
bb673e0cc9 | ||
|
|
0b02bcea8b | ||
|
|
1d8668aaf1 | ||
|
|
0783add3b9 | ||
|
|
2030aaf12e | ||
|
|
7ce4c30922 | ||
|
|
f1e772c829 | ||
|
|
31d1fc31cd | ||
|
|
597211d83a | ||
|
|
17679d4304 | ||
|
|
0fb70c78a9 | ||
|
|
e254e90e49 | ||
|
|
9c6e5f025d | ||
|
|
3c86532218 | ||
|
|
3834ae566f | ||
|
|
6766b2b19e | ||
|
|
b6d2f67c7c | ||
|
|
e70f593a94 | ||
|
|
ed5726fc0c | ||
|
|
5400d26c60 | ||
|
|
0bb6104532 | ||
|
|
16aa403735 | ||
|
|
1c279a92a7 | ||
|
|
35985dcb11 | ||
|
|
b0dcbe31fa | ||
|
|
b3c3ee3b22 | ||
|
|
aab340fd87 | ||
|
|
1871324ef4 | ||
|
|
d799d560b7 | ||
|
|
01e2851a76 | ||
|
|
ef2a4244ed | ||
|
|
55539dc8e5 | ||
|
|
ef303bfcc4 | ||
|
|
fff9ac04a9 | ||
|
|
76d27fbfaa | ||
|
|
2b1123b487 | ||
|
|
3607d8706d | ||
|
|
31fdf8721b | ||
|
|
128a1f349a | ||
|
|
7d432f0639 | ||
|
|
1ffc799c4d | ||
|
|
25dd8f2e2f | ||
|
|
b121596e4b | ||
|
|
cf835df62e | ||
|
|
7a3b7d4f02 | ||
|
|
b151d8f455 | ||
|
|
06de74d877 | ||
|
|
2ae9e3e0d9 | ||
|
|
0c0fe58bbf | ||
|
|
7b1e1a48ef | ||
|
|
c7dd50de0d | ||
|
|
a1caa65776 | ||
|
|
260973345d | ||
|
|
2c9b2620ea | ||
|
|
909c80e710 | ||
|
|
5a218ae6a9 | ||
|
|
b498d45621 | ||
|
|
b02196434b | ||
|
|
c0edce7760 | ||
|
|
cc46d55f5e | ||
|
|
ea8abb8dab | ||
|
|
f765d094b4 | ||
|
|
86f222870d | ||
|
|
19b5270d76 | ||
|
|
db76b9b0ef | ||
|
|
d23e53873f | ||
|
|
c116a4b998 | ||
|
|
2471d4bca5 | ||
|
|
8e04dbdcca | ||
|
|
0928358396 | ||
|
|
23f783c15c | ||
|
|
edae96c84f | ||
|
|
242ebdfae9 | ||
|
|
0ee502abec | ||
|
|
29cb1e93d8 | ||
|
|
c89242855c | ||
|
|
61a1368ed2 | ||
|
|
ac3e00fa03 | ||
|
|
d9d0f7b6f3 | ||
|
|
ad5e2df3be | ||
|
|
ec34561815 | ||
|
|
e1540b1648 | ||
|
|
a6b265455d | ||
|
|
8a6334bd86 | ||
|
|
173a23722a | ||
|
|
ab8eb2a34d | ||
|
|
30dcda616b | ||
|
|
3eafec9d6e | ||
|
|
a5910016fd | ||
|
|
0a49b93b26 | ||
|
|
7449bea836 | ||
|
|
0fc4478332 | ||
|
|
0df4a6e7ed | ||
|
|
a37cd380c8 | ||
|
|
11b2bd8887 | ||
|
|
8986db0975 | ||
|
|
2921611cb1 | ||
|
|
785fb29513 | ||
|
|
81c3d7fa17 | ||
|
|
8ff963698d | ||
|
|
6da63e0169 | ||
|
|
f84903ae27 | ||
|
|
a0a7859b33 | ||
|
|
af23d6e4bf | ||
|
|
7e9c9beace | ||
|
|
ac2fc2de5c | ||
|
|
45e548873e | ||
|
|
f484eb65df | ||
|
|
027a785ab5 | ||
|
|
25b80cbb57 | ||
|
|
589fa0f9de | ||
|
|
6d2989d15a | ||
|
|
5bb27b29ae | ||
|
|
d17f8a71e6 | ||
|
|
b664cc712a | ||
|
|
d61e8a9204 | ||
|
|
f00012a63e | ||
|
|
bd238f76ce | ||
|
|
703ae97820 | ||
|
|
1a60c5ea64 | ||
|
|
1d3ac5f02f | ||
|
|
8d23d75dfd | ||
|
|
9a32668ee1 | ||
|
|
ca0407a133 | ||
|
|
1de77b0784 | ||
|
|
d0907d3dcf | ||
|
|
81cc4bd768 | ||
|
|
262639e063 | ||
|
|
dedd93fb89 | ||
|
|
45f94aee03 | ||
|
|
d36e7d033f | ||
|
|
b94bd277bf | ||
|
|
e5095185d9 | ||
|
|
d76ce47597 | ||
|
|
58717850c2 | ||
|
|
29d52d4fe5 | ||
|
|
34c9c40ddc | ||
|
|
39d05a6c40 | ||
|
|
b664222c62 | ||
|
|
1ee48a10b5 | ||
|
|
2431a8b767 | ||
|
|
af84354e51 | ||
|
|
b04de880fc |
42
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- 'src/pretix/locale/**'
|
||||
- 'src/pretix/static/**'
|
||||
- 'src/tests/**'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- 'src/pretix/locale/**'
|
||||
- 'src/pretix/static/**'
|
||||
- 'src/tests/**'
|
||||
|
||||
jobs:
|
||||
spelling:
|
||||
name: Spellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install system packages
|
||||
run: sudo apt update && sudo apt install enchant hunspell aspell-en
|
||||
- name: Install Dependencies
|
||||
run: pip3 install --no-use-pep517 -Ur doc/requirements.txt
|
||||
- name: Spellcheck docs
|
||||
run: make spelling
|
||||
working-directory: ./doc
|
||||
- name:
|
||||
run: '[ ! -s _build/spelling/output.txt ]'
|
||||
working-directory: ./doc
|
||||
62
.github/workflows/strings.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Strings
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
- 'doc/**'
|
||||
- 'src/pretix/locale/**'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
- 'doc/**'
|
||||
- 'src/pretix/locale/**'
|
||||
|
||||
jobs:
|
||||
compile:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check gettext syntax
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install system packages
|
||||
run: sudo apt update && sudo apt install gettext
|
||||
- name: Install Dependencies
|
||||
run: pip3 install --no-use-pep517 -Ur src/requirements.txt
|
||||
- name: Compile messages
|
||||
run: python manage.py compilemessages
|
||||
working-directory: ./src
|
||||
- name: Compile jsi18n
|
||||
run: python manage.py compilejsi18n
|
||||
working-directory: ./src
|
||||
spelling:
|
||||
runs-on: ubuntu-latest
|
||||
name: Spellcheck
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install system packages
|
||||
run: sudo apt update && sudo apt install enchant hunspell hunspell-de-de aspell-en aspell-de
|
||||
- name: Install Dependencies
|
||||
run: pip3 install --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
- name: Spellcheck translations
|
||||
run: potypo
|
||||
working-directory: ./src
|
||||
55
.github/workflows/style.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
name: Code Style
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- 'src/pretix/locale/**'
|
||||
- 'src/pretix/static/**'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- 'src/pretix/locale/**'
|
||||
- 'src/pretix/static/**'
|
||||
|
||||
jobs:
|
||||
isort:
|
||||
name: isort
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install Dependencies
|
||||
run: pip3 install --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
- name: Run isort
|
||||
run: isort -c .
|
||||
working-directory: ./src
|
||||
flake:
|
||||
name: flake8
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install Dependencies
|
||||
run: pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
- name: Run flake8
|
||||
run: flake8 .
|
||||
working-directory: ./src
|
||||
75
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'src/pretix/locale/**'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'src/pretix/locale/**'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Tests
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
database: [sqlite, postgres, mysql]
|
||||
exclude:
|
||||
- database: mysql
|
||||
python-version: 3.7
|
||||
- database: sqlite
|
||||
python-version: 3.7
|
||||
- database: mysql
|
||||
python-version: 3.6
|
||||
- database: sqlite
|
||||
python-version: 3.6
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: getong/mariadb-action@v1.1
|
||||
with:
|
||||
mariadb version: '10.4'
|
||||
mysql database: 'pretix'
|
||||
mysql root password: ''
|
||||
if: matrix.database == 'mysql'
|
||||
- uses: harmon758/postgresql-action@v1
|
||||
with:
|
||||
postgresql version: '11'
|
||||
postgresql db: 'pretix'
|
||||
postgresql user: 'postgres'
|
||||
postgresql password: 'postgres'
|
||||
if: matrix.database == 'postgres'
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install system dependencies
|
||||
run: sudo apt update && sudo apt install gettext mysql-client
|
||||
- name: Install Python dependencies
|
||||
run: pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt mysqlclient psycopg2-binary
|
||||
- name: Run checks
|
||||
run: python manage.py check
|
||||
working-directory: ./src
|
||||
- name: Compile
|
||||
working-directory: ./src
|
||||
run: make all compress
|
||||
- name: Run tests
|
||||
working-directory: ./src
|
||||
run: PRETIX_CONFIG_FILE=tests/travis_${{ matrix.database }}.cfg py.test -n 3 -p no:sugar --cov=./ --cov-report=xml --reruns 3 tests --maxfail=100
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: src/coverage.xml
|
||||
fail_ci_if_error: true
|
||||
if: matrix.database == 'postgres' && matrix.python-version == '3.8'
|
||||
@@ -5,7 +5,11 @@ tests:
|
||||
- virtualenv env
|
||||
- source env/bin/activate
|
||||
- pip install -U pip wheel setuptools
|
||||
- XDG_CACHE_HOME=/cache bash .travis.sh tests
|
||||
- XDG_CACHE_HOME=/cache pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
- cd src
|
||||
- python manage.py check
|
||||
- make all compress
|
||||
- py.test --reruns 3 -n 3 tests
|
||||
tags:
|
||||
- python3
|
||||
except:
|
||||
@@ -16,15 +20,17 @@ pypi:
|
||||
- cp /keys/.pypirc ~/.pypirc
|
||||
- virtualenv env
|
||||
- source env/bin/activate
|
||||
- pip install -U pip wheel setuptools
|
||||
- pip install -U pip wheel setuptools check-manifest twine
|
||||
- XDG_CACHE_HOME=/cache pip3 install -Ur src/requirements.txt -r src/requirements/dev.txt
|
||||
- cd src
|
||||
- python setup.py sdist
|
||||
- pip install dist/pretix-*.tar.gz
|
||||
- python -m pretix migrate
|
||||
- python -m pretix check
|
||||
- python setup.py sdist upload
|
||||
- python setup.py bdist_wheel upload
|
||||
- check-manifest
|
||||
- python setup.py sdist bdist_wheel
|
||||
- twine check dist/*
|
||||
- twine upload dist/*
|
||||
tags:
|
||||
- python3
|
||||
only:
|
||||
|
||||
68
.travis.sh
@@ -1,68 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
echo "Executing job $1"
|
||||
|
||||
if [ "$PRETIX_CONFIG_FILE" == "tests/travis_mysql.cfg" ]; then
|
||||
mysql -u root -e 'CREATE DATABASE pretix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
|
||||
pip3 install -Ur src/requirements/mysql.txt
|
||||
fi
|
||||
|
||||
if [ "$PRETIX_CONFIG_FILE" == "tests/travis_postgres.cfg" ]; then
|
||||
psql -c 'create database travis_ci_test;' -U postgres
|
||||
fi
|
||||
|
||||
if [ "$1" == "style" ]; then
|
||||
XDG_CACHE_HOME=/cache pip3 install --no-use-pep517 -Ur src/requirements.txt -r src/requirements/dev.txt
|
||||
cd src
|
||||
flake8 .
|
||||
isort -c -rc -df .
|
||||
fi
|
||||
if [ "$1" == "doctests" ]; then
|
||||
XDG_CACHE_HOME=/cache pip3 install --no-use-pep517 -Ur doc/requirements.txt
|
||||
cd doc
|
||||
make doctest
|
||||
fi
|
||||
if [ "$1" == "doc-spelling" ]; then
|
||||
XDG_CACHE_HOME=/cache pip3 install --no-use-pep517 -Ur doc/requirements.txt
|
||||
cd doc
|
||||
make spelling
|
||||
if [ -s _build/spelling/output.txt ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ "$1" == "translation-spelling" ]; then
|
||||
XDG_CACHE_HOME=/cache pip3 install --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
cd src
|
||||
potypo
|
||||
fi
|
||||
if [ "$1" == "tests" ]; then
|
||||
pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
cd src
|
||||
python manage.py check
|
||||
make all compress
|
||||
py.test --reruns 5 -n 3 tests
|
||||
fi
|
||||
if [ "$1" == "tests-cov" ]; then
|
||||
pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
cd src
|
||||
python manage.py check
|
||||
make all compress
|
||||
coverage run -m py.test --reruns 5 tests && codecov
|
||||
fi
|
||||
if [ "$1" == "plugins" ]; then
|
||||
pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
cd src
|
||||
python setup.py develop
|
||||
make all compress
|
||||
|
||||
pushd ~
|
||||
git clone --depth 1 https://github.com/pretix/pretix-cartshare.git
|
||||
cd pretix-cartshare
|
||||
python setup.py develop
|
||||
make
|
||||
py.test --reruns 5 tests
|
||||
popd
|
||||
|
||||
fi
|
||||
45
.travis.yml
@@ -1,45 +0,0 @@
|
||||
language: python
|
||||
dist: xenial
|
||||
sudo: false
|
||||
install:
|
||||
- pip install -U pip wheel setuptools
|
||||
script:
|
||||
- bash .travis.sh $JOB
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
matrix:
|
||||
include:
|
||||
- python: 3.7
|
||||
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_sqlite.cfg
|
||||
- python: 3.7
|
||||
env: JOB=tests-cov PRETIX_CONFIG_FILE=tests/travis_postgres.cfg
|
||||
- python: 3.7
|
||||
env: JOB=style
|
||||
- python: 3.7
|
||||
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_mysql.cfg
|
||||
- python: 3.7
|
||||
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_postgres.cfg
|
||||
- python: 3.5
|
||||
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_postgres.cfg
|
||||
- python: 3.7
|
||||
env: JOB=doc-spelling
|
||||
- python: 3.7
|
||||
env: JOB=translation-spelling
|
||||
addons:
|
||||
postgresql: "9.4"
|
||||
mariadb: '10.3'
|
||||
apt:
|
||||
packages:
|
||||
- enchant
|
||||
- myspell-de-de
|
||||
- aspell-en
|
||||
- sqlite3
|
||||
sources:
|
||||
- travis-ci/sqlite3
|
||||
branches:
|
||||
except:
|
||||
- /^weblate-.*/
|
||||
@@ -29,7 +29,7 @@ RUN apt-get update && \
|
||||
mkdir /etc/pretix && \
|
||||
mkdir /data && \
|
||||
useradd -ms /bin/bash -d /pretix -u 15371 pretixuser && \
|
||||
echo 'pretixuser ALL=(ALL) NOPASSWD: /usr/bin/supervisord' >> /etc/sudoers && \
|
||||
echo 'pretixuser ALL=(ALL) NOPASSWD:SETENV: /usr/bin/supervisord' >> /etc/sudoers && \
|
||||
mkdir /static
|
||||
|
||||
ENV LC_ALL=C.UTF-8 \
|
||||
|
||||
24
README.rst
@@ -4,11 +4,10 @@ pretix
|
||||
.. image:: https://img.shields.io/pypi/v/pretix.svg
|
||||
:target: https://pypi.python.org/pypi/pretix
|
||||
|
||||
.. image:: https://readthedocs.org/projects/pretix/badge/?version=latest
|
||||
.. image:: https://github.com/pretix/pretix/workflows/Documentation/badge.svg
|
||||
:target: https://docs.pretix.eu/en/latest/
|
||||
|
||||
.. image:: https://travis-ci.org/pretix/pretix.svg?branch=master
|
||||
:target: https://travis-ci.org/pretix/pretix
|
||||
.. image:: https://github.com/pretix/pretix/workflows/Tests/badge.svg
|
||||
|
||||
.. image:: https://codecov.io/gh/pretix/pretix/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/pretix/pretix
|
||||
@@ -20,9 +19,8 @@ Reinventing ticket presales, one ticket at a time.
|
||||
Project status & release cycle
|
||||
------------------------------
|
||||
|
||||
While there is always a lot to do and improve on, pretix by now has been in use for more than a dozen
|
||||
conferences that sold over ten thousand tickets combined without major problems. We therefore think of
|
||||
pretix as being stable and ready to use.
|
||||
While there is always a lot to do and improve on, pretix by now has been in use for thousands of events
|
||||
conferences that sold millions of tickets combined. We therefore think of pretix as being stable and ready to use.
|
||||
|
||||
If you want to use or extend pretix, we strongly recommend to follow our `blog`_. We will announce all
|
||||
releases there. You can always find the latest stable version on PyPI or in the ``release/X.Y`` branch of
|
||||
@@ -31,9 +29,13 @@ the sense that it does not break your data, but its APIs might change without p
|
||||
|
||||
To get started using pretix on your own server, look at the `installation guide`_ in our documentation.
|
||||
|
||||
This project is 100 percent free and open source software. If you are interested in commercial support,
|
||||
hosting services or supporting this project financially, please go to `pretix.eu`_ or contact us at
|
||||
support@pretix.eu.
|
||||
Support
|
||||
-------
|
||||
|
||||
This project is 100 percent free and open source software. You are welcome to ask questions in the GitHub
|
||||
repository. Private support via email or phone is only offered to customers of our pretix Hosted or pretix
|
||||
Enterprise offerings. If you are interested in commercial support, hosting services or supporting this project
|
||||
financially, please go to `pretix.eu`_ or contact us at support@pretix.eu.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
@@ -53,8 +55,8 @@ License
|
||||
The code in this repository is published under the terms of the Apache License.
|
||||
See the LICENSE file for the complete license text.
|
||||
|
||||
This project is maintained by Raphael Michel <mail@raphaelmichel.de>. See the
|
||||
AUTHORS file for a list of all the awesome folks who contributed to this project.
|
||||
This project is maintained by Raphael Michel. See the AUTHORS file for a list of all
|
||||
the awesome folks who contributed to this project.
|
||||
|
||||
.. _installation guide: https://docs.pretix.eu/en/latest/admin/installation/index.html
|
||||
.. _developer documentation: https://docs.pretix.eu/en/latest/development/index.html
|
||||
|
||||
@@ -19,7 +19,7 @@ fi
|
||||
python3 -m pretix migrate --noinput
|
||||
|
||||
if [ "$1" == "all" ]; then
|
||||
exec sudo /usr/bin/supervisord -n -c /etc/supervisord.conf
|
||||
exec sudo -E /usr/bin/supervisord -n -c /etc/supervisord.conf
|
||||
fi
|
||||
|
||||
if [ "$1" == "webworker" ]; then
|
||||
@@ -33,8 +33,8 @@ if [ "$1" == "webworker" ]; then
|
||||
fi
|
||||
|
||||
if [ "$1" == "taskworker" ]; then
|
||||
export C_FORCE_ROOT=True
|
||||
exec celery -A pretix.celery_app worker -l info
|
||||
shift
|
||||
exec celery -A pretix.celery_app worker -l info "$@"
|
||||
fi
|
||||
|
||||
if [ "$1" == "shell" ]; then
|
||||
@@ -45,5 +45,4 @@ if [ "$1" == "upgrade" ]; then
|
||||
exec python3 -m pretix updatestyles
|
||||
fi
|
||||
|
||||
echo "Specify argument: all|cron|webworker|taskworker|shell|upgrade"
|
||||
exit 1
|
||||
exec python3 -m pretix "$@"
|
||||
|
||||
@@ -6099,3 +6099,6 @@ img.screenshot, a.screenshot img {
|
||||
.versionchanged p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.rst-content td > .line-block {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
@@ -92,9 +92,14 @@ Example::
|
||||
|
||||
``trust_x_forwarded_proto``
|
||||
Specifies whether the ``X-Forwarded-Proto`` header can be trusted. Only set to ``on`` if you have a reverse
|
||||
proxy that actively removes and re-adds the header to make sure the correct client IP is the first value.
|
||||
proxy that actively removes and re-adds the header to make sure the correct value is set.
|
||||
Defaults to ``off``.
|
||||
|
||||
``csp_log``
|
||||
Log violations of the Content Security Policy (CSP). Defaults to ``on``.
|
||||
|
||||
``loglevel``
|
||||
Set console and file log level (``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` or ``CRITICAL``). Defaults to ``INFO``.
|
||||
|
||||
Locale settings
|
||||
---------------
|
||||
@@ -337,6 +342,15 @@ application. If you want to use sentry, you need to set a DSN in the configurati
|
||||
You will be given this value by your sentry installation.
|
||||
|
||||
|
||||
Caching
|
||||
-------
|
||||
|
||||
You can adjust some caching settings to control how much storage pretix uses::
|
||||
|
||||
[cache]
|
||||
tickets=48 ; Number of hours tickets (PDF, passbook, …) are cached
|
||||
|
||||
|
||||
Secret length
|
||||
-------------
|
||||
|
||||
|
||||
@@ -12,3 +12,4 @@ This documentation is for everyone who wants to install pretix on a server.
|
||||
config
|
||||
maintainance
|
||||
scaling
|
||||
indexes
|
||||
|
||||
73
doc/admin/indexes.rst
Normal file
@@ -0,0 +1,73 @@
|
||||
Additional database indices
|
||||
===========================
|
||||
|
||||
If you have a large pretix database, some features such as search for orders or events might turn pretty slow.
|
||||
For PostgreSQL, we have compiled a list of additional database indexes that you can add to speed things up.
|
||||
Just like any index, they in turn make write operations insignificantly slower and cause the database to use
|
||||
more disk space.
|
||||
|
||||
The indexes aren't automatically created by pretix since Django does not allow us to do so only on PostgreSQL
|
||||
(and they won't work on other databases). Also, they're really not necessary if you're not having tens of
|
||||
thousands of records in your database.
|
||||
|
||||
However, this also means they won't automatically adapt if some of the referred fields change in future updates of pretix
|
||||
and you might need to re-check this page and change them manually.
|
||||
|
||||
Here is the currently recommended set of commands::
|
||||
|
||||
CREATE EXTENSION pg_trgm;
|
||||
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_event_slug
|
||||
ON pretixbase_event
|
||||
USING gin (upper("slug") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_event_name
|
||||
ON pretixbase_event
|
||||
USING gin (upper("name") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_order_code
|
||||
ON pretixbase_order
|
||||
USING gin (upper("code") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_voucher_code
|
||||
ON pretixbase_voucher
|
||||
USING gin (upper("code") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_invoice_nu1
|
||||
ON "pretixbase_invoice" (UPPER("invoice_no"));
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_invoice_nu2
|
||||
ON "pretixbase_invoice" (UPPER("full_invoice_no"));
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_organizer_name
|
||||
ON pretixbase_organizer
|
||||
USING gin (upper("name") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_organizer_slug
|
||||
ON pretixbase_organizer
|
||||
USING gin (upper("slug") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_order_email
|
||||
ON pretixbase_order
|
||||
USING gin (upper("email") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_order_comment
|
||||
ON pretixbase_order
|
||||
USING gin (upper("comment") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_name
|
||||
ON pretixbase_orderposition
|
||||
USING gin (upper("attendee_name_cached") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_scret
|
||||
ON pretixbase_orderposition
|
||||
USING gin (upper("secret") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_email
|
||||
ON pretixbase_orderposition
|
||||
USING gin (upper("attendee_email") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_ia_name
|
||||
ON pretixbase_invoiceaddress
|
||||
USING gin (upper("name_cached") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_ia_company
|
||||
ON pretixbase_invoiceaddress
|
||||
USING gin (upper("company") gin_trgm_ops);
|
||||
|
||||
|
||||
Also, if you use our ``pretix-shipping`` plugin::
|
||||
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_sa_name
|
||||
ON pretix_shipping_shippingaddress
|
||||
USING gin (upper("name") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_sa_company
|
||||
ON pretix_shipping_shippingaddress
|
||||
USING gin (upper("company") gin_trgm_ops);
|
||||
|
||||
@@ -26,7 +26,7 @@ installation guides):
|
||||
* `Docker`_
|
||||
* A SMTP server to send out mails, e.g. `Postfix`_ on your machine or some third-party server you have credentials for
|
||||
* A HTTP reverse proxy, e.g. `nginx`_ or Apache to allow HTTPS connections
|
||||
* A `PostgreSQL`_, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `PostgreSQL`_ 9.5+, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `redis`_ server
|
||||
|
||||
We also recommend that you use a firewall, although this is not a pretix-specific recommendation. If you're new to
|
||||
@@ -182,7 +182,7 @@ named ``/etc/systemd/system/pretix.service`` with the following content::
|
||||
-v /var/pretix-data:/data \
|
||||
-v /etc/pretix:/etc/pretix \
|
||||
-v /var/run/redis:/var/run/redis \
|
||||
--sysctl net.core.somaxconn=4096
|
||||
--sysctl net.core.somaxconn=4096 \
|
||||
pretix/standalone:stable all
|
||||
ExecStop=/usr/bin/docker stop %n
|
||||
|
||||
@@ -290,7 +290,7 @@ to re-build your custom image after you pulled ``pretix/standalone`` if you want
|
||||
.. _Let's Encrypt: https://letsencrypt.org/
|
||||
.. _pretix.eu: https://pretix.eu/
|
||||
.. _MySQL: https://dev.mysql.com/doc/refman/5.7/en/linux-installation-apt-repo.html
|
||||
.. _PostgreSQL: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-9-4-on-debian-8
|
||||
.. _PostgreSQL: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-20-04
|
||||
.. _redis: https://blog.programster.org/debian-8-install-redis-server/
|
||||
.. _ufw: https://en.wikipedia.org/wiki/Uncomplicated_Firewall
|
||||
.. _redis website: https://redis.io/topics/security
|
||||
|
||||
@@ -12,7 +12,7 @@ solution with many things readily set-up, look at :ref:`dockersmallscale`.
|
||||
get it right. If you're not feeling comfortable managing a Linux server, check out our hosting and service
|
||||
offers at `pretix.eu`_.
|
||||
|
||||
We tested this guide on the Linux distribution **Debian 8.0** but it should work very similar on other
|
||||
We tested this guide on the Linux distribution **Debian 10.0** but it should work very similar on other
|
||||
modern distributions, especially on all systemd-based ones.
|
||||
|
||||
Requirements
|
||||
@@ -23,7 +23,7 @@ installation guides):
|
||||
|
||||
* A SMTP server to send out mails, e.g. `Postfix`_ on your machine or some third-party server you have credentials for
|
||||
* A HTTP reverse proxy, e.g. `nginx`_ or Apache to allow HTTPS connections
|
||||
* A `PostgreSQL`_, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `PostgreSQL`_ 9.5+, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `redis`_ server
|
||||
|
||||
We also recommend that you use a firewall, although this is not a pretix-specific recommendation. If you're new to
|
||||
@@ -133,7 +133,7 @@ command if you're running MySQL::
|
||||
|
||||
(venv)$ pip3 install "pretix[postgres]" gunicorn
|
||||
|
||||
Note that you need Python 3.5 or newer. You can find out your Python version using ``python -V``.
|
||||
Note that you need Python 3.6 or newer. You can find out your Python version using ``python -V``.
|
||||
|
||||
We also need to create a data directory::
|
||||
|
||||
@@ -308,7 +308,7 @@ example::
|
||||
.. _Let's Encrypt: https://letsencrypt.org/
|
||||
.. _pretix.eu: https://pretix.eu/
|
||||
.. _MySQL: https://dev.mysql.com/doc/refman/5.7/en/linux-installation-apt-repo.html
|
||||
.. _PostgreSQL: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-9-4-on-debian-8
|
||||
.. _PostgreSQL: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-20-04
|
||||
.. _redis: https://blog.programster.org/debian-8-install-redis-server/
|
||||
.. _ufw: https://en.wikipedia.org/wiki/Uncomplicated_Firewall
|
||||
.. _strong encryption settings: https://mozilla.github.io/server-side-tls/ssl-config-generator/
|
||||
|
||||
@@ -92,7 +92,8 @@ pretix_task_duration_seconds
|
||||
|
||||
pretix_model_instances
|
||||
Gauge. Measures number of instances of a certain model within the database, labeled with
|
||||
the ``model`` name.
|
||||
the ``model`` name. Starting with pretix 3.11, these numbers might only be approximate for
|
||||
most tables when running on PostgreSQL to mitigate performance impact.
|
||||
|
||||
.. _metric types: https://prometheus.io/docs/concepts/metric_types/
|
||||
.. _Prometheus: https://prometheus.io/
|
||||
|
||||
@@ -49,11 +49,15 @@ information on your device as well as your API token:
|
||||
"device_id": 5,
|
||||
"unique_serial": "HHZ9LW9JWP390VFZ",
|
||||
"api_token": "1kcsh572fonm3hawalrncam4l1gktr2rzx25a22l8g9hx108o9oi0rztpcvwnfnd",
|
||||
"name": "Bar"
|
||||
"name": "Bar",
|
||||
"gate": {
|
||||
"id": 3,
|
||||
"name": "South entrance"
|
||||
}
|
||||
}
|
||||
|
||||
Please make sure that you store this ``api_token`` value. We also recommend storing your device ID, your assigned
|
||||
``unique_serial``, and the ``organizer`` you have access to, but that's up to you.
|
||||
``unique_serial``, and the ``organizer`` you have access to, but that's up to you. ``gate`` might be ``null``.
|
||||
|
||||
In case of an error, the response will look like this:
|
||||
|
||||
@@ -98,6 +102,8 @@ following endpoint:
|
||||
"software_version": "4.1.0"
|
||||
}
|
||||
|
||||
You will receive a response equivalent to the response of your initialization request.
|
||||
|
||||
Creating a new API key
|
||||
----------------------
|
||||
|
||||
@@ -126,12 +132,65 @@ invalidate your API key. There is no way to reverse this operation.
|
||||
|
||||
This can also be done by the user through the web interface.
|
||||
|
||||
Permissions
|
||||
-----------
|
||||
Permissions & security profiles
|
||||
-------------------------------
|
||||
|
||||
Device authentication is currently hardcoded to grant the following permissions:
|
||||
|
||||
* View event meta data and products etc.
|
||||
* View and change orders
|
||||
* View orders
|
||||
* Change orders
|
||||
* Manage gift cards
|
||||
|
||||
Devices cannot change events or products and cannot access vouchers.
|
||||
|
||||
Additionally, when creating a device through the user interface or API, a user can specify a "security profile" for
|
||||
the device. These include an allow list of specific API calls that may be made by the device. pretix ships with security
|
||||
policies for official pretix apps like pretixSCAN and pretixPOS.
|
||||
|
||||
Removing a device
|
||||
-----------------
|
||||
|
||||
If you want implement a way to to deprovision a device in your software, you can call the ``revoke`` endpoint to
|
||||
invalidate your API key. There is no way to reverse this operation.
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/device/revoke HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Authorization: Device 1kcsh572fonm3hawalrncam4l1gktr2rzx25a22l8g9hx108o9oi0rztpcvwnfnd
|
||||
|
||||
This can also be done by the user through the web interface.
|
||||
|
||||
Event selection
|
||||
---------------
|
||||
|
||||
In most cases, your application should allow the user to select the event and check-in list they work with manually
|
||||
from a list. However, in some cases it is required to automatically configure the device for the correct event, for
|
||||
example in a kiosk-like situation where nobody is operating the device. In this case, the app can query the server
|
||||
for a suggestion which event should be used. You can also submit the configuration that is currently in use via
|
||||
query parameters:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/device/eventselection?current_event=democon¤t_subevent=42¤t_checkinlist=542 HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Authorization: Device 1kcsh572fonm3hawalrncam4l1gktr2rzx25a22l8g9hx108o9oi0rztpcvwnfnd
|
||||
|
||||
You can get three response codes:
|
||||
|
||||
* ``304`` The server things you already selected a good event
|
||||
* ``404`` The server has not found a suggestion for you
|
||||
* ``200`` The server suggests a new event (body see below)
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"event": "democon",
|
||||
"subevent": 23,
|
||||
"checkinlist": 5
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,6 @@ This part of the documentation contains information about the REST-style API
|
||||
exposed by pretix since version 1.5 that can be used by third-party programs
|
||||
to interact with pretix and its data structures.
|
||||
|
||||
Currently, the API provides mostly read-only capabilities, but it will be extended
|
||||
in functionality over time.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Obtaining an authorization grant
|
||||
--------------------------------
|
||||
|
||||
To authorize a new user, link or redirect them to the ``authorize`` endpoint, passing your client ID as a query
|
||||
parameter. Additionally, you can pass a scope (currently either ``read``, ``write``, or ``read write``)
|
||||
parameter. Additionally, you can pass a scope (currently either ``read``, ``write``, ``read write`` or ``profile``)
|
||||
and an URL the user should be redirected to after successful or failed authorization. You also need to pass the
|
||||
``response_type`` parameter with a value of ``code``. Example::
|
||||
|
||||
@@ -47,11 +47,9 @@ You will need this ``code`` parameter to perform the next step.
|
||||
|
||||
On a failed registration, a query string like ``?error=access_denied`` will be appended to the redirection URL.
|
||||
|
||||
.. note:: In this step, the user is allowed to restrict your access to certain organizer accounts. If you try to
|
||||
re-authenticate the user later, the user might be instantly redirected back to you if authorization is already
|
||||
given and would therefore be unable to review their organizer restriction settings. You can append the
|
||||
``approval_prompt=force`` query parameter if you want to make sure the user actively needs to confirm the
|
||||
authorization.
|
||||
.. note:: By default, the user is asked to give permission on every call to this URL. If you **only** request the
|
||||
``profile`` scope, i.e. no access to organizer data, you can pass the ``approval_prompt=auto`` parameter
|
||||
to skip user interaction on subsequent calls.
|
||||
|
||||
Getting an access token
|
||||
-----------------------
|
||||
@@ -193,10 +191,11 @@ If you need the user's meta data, you can fetch it here:
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
email: "admin@localhost",
|
||||
fullname: "John Doe",
|
||||
locale: "de",
|
||||
timezone: "Europe/Berlin"
|
||||
"email": "admin@localhost",
|
||||
"fullname": "John Doe",
|
||||
"locale": "de",
|
||||
"is_staff": false,
|
||||
"timezone": "Europe/Berlin"
|
||||
}
|
||||
|
||||
:statuscode 200: no error
|
||||
|
||||
@@ -30,6 +30,10 @@ position_count integer Number of ticke
|
||||
checkin_count integer Number of check-ins performed on this list (read-only).
|
||||
include_pending boolean If ``true``, the check-in list also contains tickets from orders in pending state.
|
||||
auto_checkin_sales_channels list of strings All items on the check-in list will be automatically marked as checked-in when purchased through any of the listed sales channels.
|
||||
allow_multiple_entries boolean If ``true``, subsequent scans of a ticket on this list should not show a warning but instead be stored as an additional check-in.
|
||||
allow_entry_after_exit boolean If ``true``, subsequent scans of a ticket on this list are valid if the last scan of the ticket was an exit scan.
|
||||
rules object Custom check-in logic. The contents of this field are currently not considered a stable API and modifications through the API are highly discouraged.
|
||||
exit_all_at datetime Automatically check out (i.e. perform an exit scan) at this point in time. After this happened, this property will automatically be set exactly one day into the future. Note that this field is considered "internal configuration" and if you pull the list with ``If-Modified-Since``, the daily change in this field will not trigger a response.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
.. versionchanged:: 1.10
|
||||
@@ -48,6 +52,19 @@ auto_checkin_sales_channels list of strings All items on th
|
||||
|
||||
The ``auto_checkin_sales_channels`` field has been added.
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
|
||||
The ``subevent`` attribute may now be ``null`` inside event series. The ``allow_multiple_entries``,
|
||||
``allow_entry_after_exit``, and ``rules`` attributes have been added.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
|
||||
The ``subevent_match`` and ``exclude`` query parameters have been added.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The ``exit_all_at`` attribute has been added.
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -89,6 +106,10 @@ Endpoints
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"subevent": null,
|
||||
"allow_multiple_entries": false,
|
||||
"allow_entry_after_exit": true,
|
||||
"exit_all_at": null,
|
||||
"rules": {},
|
||||
"auto_checkin_sales_channels": [
|
||||
"pretixpos"
|
||||
]
|
||||
@@ -98,6 +119,8 @@ Endpoints
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query integer subevent: Only return check-in lists of the sub-event with the given ID
|
||||
:query integer subevent_match: Only return check-in lists that are valid for the sub-event with the given ID (i.e. also lists valid for all subevents)
|
||||
:query string exclude: Exclude a field from the output, e.g. ``checkin_count``. Can be used as a performance optimization. Can be passed multiple times.
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:statuscode 200: no error
|
||||
@@ -133,6 +156,10 @@ Endpoints
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"subevent": null,
|
||||
"allow_multiple_entries": false,
|
||||
"allow_entry_after_exit": true,
|
||||
"exit_all_at": null,
|
||||
"rules": {},
|
||||
"auto_checkin_sales_channels": [
|
||||
"pretixpos"
|
||||
]
|
||||
@@ -168,6 +195,7 @@ Endpoints
|
||||
{
|
||||
"checkin_count": 17,
|
||||
"position_count": 42,
|
||||
"inside_count": 12,
|
||||
"event": {
|
||||
"name": "Demo Conference"
|
||||
},
|
||||
@@ -229,6 +257,8 @@ Endpoints
|
||||
"all_products": false,
|
||||
"limit_products": [1, 2],
|
||||
"subevent": null,
|
||||
"allow_multiple_entries": false,
|
||||
"allow_entry_after_exit": true,
|
||||
"auto_checkin_sales_channels": [
|
||||
"pretixpos"
|
||||
]
|
||||
@@ -251,6 +281,8 @@ Endpoints
|
||||
"limit_products": [1, 2],
|
||||
"include_pending": false,
|
||||
"subevent": null,
|
||||
"allow_multiple_entries": false,
|
||||
"allow_entry_after_exit": true,
|
||||
"auto_checkin_sales_channels": [
|
||||
"pretixpos"
|
||||
]
|
||||
@@ -303,6 +335,8 @@ Endpoints
|
||||
"limit_products": [1, 2],
|
||||
"include_pending": false,
|
||||
"subevent": null,
|
||||
"allow_multiple_entries": false,
|
||||
"allow_entry_after_exit": true,
|
||||
"auto_checkin_sales_channels": [
|
||||
"pretixpos"
|
||||
]
|
||||
@@ -582,6 +616,7 @@ Order position endpoints
|
||||
:<json datetime datetime: Specifies the datetime of the check-in. If not supplied, the current time will be used.
|
||||
:<json boolean force: Specifies that the check-in should succeed regardless of previous check-ins or required
|
||||
questions that have not been filled. Defaults to ``false``.
|
||||
:<json string type: Send ``"exit"`` for an exit and ``"entry"`` (default) for an entry.
|
||||
:<json boolean ignore_unpaid: Specifies that the check-in should succeed even if the order is in pending state.
|
||||
Defaults to ``false`` and only works when ``include_pending`` is set on the check-in
|
||||
list.
|
||||
@@ -696,6 +731,7 @@ Order position endpoints
|
||||
``canceled_supported`` to ``true``, otherwise these orders return ``unpaid``.
|
||||
* ``already_redeemed`` - Ticket already has been redeemed
|
||||
* ``product`` - Tickets with this product may not be scanned at this device
|
||||
* ``rules`` - Check-in prevented by a user-defined rule
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
|
||||
224
doc/api/resources/devices.rst
Normal file
@@ -0,0 +1,224 @@
|
||||
.. spelling:: fullname
|
||||
|
||||
.. _`rest-devices`:
|
||||
|
||||
Devices
|
||||
=======
|
||||
|
||||
See also :ref:`rest-deviceauth`.
|
||||
|
||||
Device resource
|
||||
----------------
|
||||
|
||||
The device resource contains the following public fields:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
device_id integer Internal ID of the device within this organizer
|
||||
unique_serial string Unique identifier of this device
|
||||
name string Device name
|
||||
all_events boolean Whether this device has access to all events
|
||||
limit_events list List of event slugs this device has access to
|
||||
hardware_brand string Device hardware manufacturer (read-only)
|
||||
hardware_model string Device hardware model (read-only)
|
||||
software_brand string Device software product (read-only)
|
||||
software_version string Device software version (read-only)
|
||||
created datetime Creation time
|
||||
initialized datetime Time of initialization (or ``null``)
|
||||
initialization_token string Token for initialization
|
||||
revoked boolean Whether this device no longer has access
|
||||
security_profile string The name of a supported security profile restricting API access
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
Device endpoints
|
||||
----------------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/devices/
|
||||
|
||||
Returns a list of all devices within a given organizer.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/devices/ 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": 1,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"device_id": 1,
|
||||
"unique_serial": "UOS3GNZ27O39V3QS",
|
||||
"initialization_token": "frkso3m2w58zuw70",
|
||||
"all_events": false,
|
||||
"limit_events": [
|
||||
"museum"
|
||||
],
|
||||
"revoked": false,
|
||||
"name": "Scanner",
|
||||
"created": "2020-09-18T14:17:40.971519Z",
|
||||
"initialized": "2020-09-18T14:17:44.190021Z",
|
||||
"security_profile": "full",
|
||||
"hardware_brand": "Zebra",
|
||||
"hardware_model": "TC25",
|
||||
"software_brand": "pretixSCAN",
|
||||
"software_version": "1.5.1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
: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
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to view this resource.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/devices/(device_id)/
|
||||
|
||||
Returns information on one device, identified by its ID.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/devices/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
|
||||
|
||||
{
|
||||
"device_id": 1,
|
||||
"unique_serial": "UOS3GNZ27O39V3QS",
|
||||
"initialization_token": "frkso3m2w58zuw70",
|
||||
"all_events": false,
|
||||
"limit_events": [
|
||||
"museum"
|
||||
],
|
||||
"revoked": false,
|
||||
"name": "Scanner",
|
||||
"created": "2020-09-18T14:17:40.971519Z",
|
||||
"initialized": "2020-09-18T14:17:44.190021Z",
|
||||
"security_profile": "full",
|
||||
"hardware_brand": "Zebra",
|
||||
"hardware_model": "TC25",
|
||||
"software_brand": "pretixSCAN",
|
||||
"software_version": "1.5.1"
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param device_id: The ``device_id`` field of the device to fetch
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to view this resource.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/devices/
|
||||
|
||||
Creates a new device
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/devices/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "Scanner",
|
||||
"all_events": true,
|
||||
"limit_events": [],
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"device_id": 1,
|
||||
"unique_serial": "UOS3GNZ27O39V3QS",
|
||||
"initialization_token": "frkso3m2w58zuw70",
|
||||
"all_events": true,
|
||||
"limit_events": [],
|
||||
"revoked": false,
|
||||
"name": "Scanner",
|
||||
"created": "2020-09-18T14:17:40.971519Z",
|
||||
"security_profile": "full",
|
||||
"initialized": null
|
||||
"hardware_brand": null,
|
||||
"hardware_model": null,
|
||||
"software_brand": null,
|
||||
"software_version": null
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to create a device for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The device could not be created due to invalid submitted data.
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to create this resource.
|
||||
|
||||
.. http:patch:: /api/v1/organizers/(organizer)/devices/(device_id)/
|
||||
|
||||
Update a device.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /api/v1/organizers/bigevents/devices/1/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 94
|
||||
|
||||
{
|
||||
"name": "Foo"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Foo",
|
||||
...
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
:param device_id: The ``device_id`` field of the device to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The device could not be modified due to invalid submitted data
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to change this resource.
|
||||
|
||||
@@ -44,6 +44,9 @@ seat_category_mapping object An object mappi
|
||||
(strings) to items in the event (integers or ``null``).
|
||||
timezone string Event timezone name
|
||||
item_meta_properties object Item-specific meta data parameters and default values.
|
||||
valid_keys object Cryptographic keys for non-default signature schemes.
|
||||
For performance reason, value is omitted in lists and
|
||||
only contained in detail views. Value can be cached.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
@@ -84,6 +87,10 @@ item_meta_properties object Item-specific m
|
||||
|
||||
The attribute ``item_meta_properties`` has been added.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The attribute ``valid_keys`` has been added.
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -144,7 +151,7 @@ Endpoints
|
||||
"pretix.plugins.stripe"
|
||||
"pretix.plugins.paypal"
|
||||
"pretix.plugins.ticketoutputpdf"
|
||||
]
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -216,7 +223,12 @@ Endpoints
|
||||
"pretix.plugins.stripe"
|
||||
"pretix.plugins.paypal"
|
||||
"pretix.plugins.ticketoutputpdf"
|
||||
]
|
||||
],
|
||||
"valid_keys": {
|
||||
"pretix_sig1": [
|
||||
"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQTdBRDcvdkZBMzNFc1k0ejJQSHI3aVpQc1o4bjVkaDBhalA4Z3l6Tm1tSXM9Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo="
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
@@ -472,7 +484,7 @@ Endpoints
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to create this resource.
|
||||
|
||||
|
||||
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/items/(id)/
|
||||
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/
|
||||
|
||||
Delete an event. Note that events with orders cannot be deleted to ensure data integrity.
|
||||
|
||||
@@ -526,7 +538,7 @@ information about the properties.
|
||||
|
||||
Get current values of event settings.
|
||||
|
||||
Permission required: "Can change event settings"
|
||||
Permission required: "Can change event settings" (Exception: with device auth, *some* settings can always be *read*.)
|
||||
|
||||
**Example request**:
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ secret string Gift card code
|
||||
value money (string) Current gift card value
|
||||
currency string Currency of the value (can not be modified later)
|
||||
testmode boolean Whether this is a test gift card
|
||||
expires datetime Expiry date (or ``null``)
|
||||
conditions string Special terms and conditions for this card (or ``null``)
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
Endpoints
|
||||
@@ -53,6 +55,8 @@ Endpoints
|
||||
"secret": "HLBYVELFRC77NCQY",
|
||||
"currency": "EUR",
|
||||
"testmode": false,
|
||||
"expires": null,
|
||||
"conditions": null,
|
||||
"value": "13.37"
|
||||
}
|
||||
]
|
||||
@@ -92,6 +96,8 @@ Endpoints
|
||||
"secret": "HLBYVELFRC77NCQY",
|
||||
"currency": "EUR",
|
||||
"testmode": false,
|
||||
"expires": null,
|
||||
"conditions": null,
|
||||
"value": "13.37"
|
||||
}
|
||||
|
||||
@@ -134,6 +140,8 @@ Endpoints
|
||||
"secret": "HLBYVELFRC77NCQY",
|
||||
"testmode": false,
|
||||
"currency": "EUR",
|
||||
"expires": null,
|
||||
"conditions": null,
|
||||
"value": "13.37"
|
||||
}
|
||||
|
||||
@@ -180,6 +188,8 @@ Endpoints
|
||||
"secret": "HLBYVELFRC77NCQY",
|
||||
"testmode": false,
|
||||
"currency": "EUR",
|
||||
"expires": null,
|
||||
"conditions": null,
|
||||
"value": "14.00"
|
||||
}
|
||||
|
||||
@@ -199,14 +209,15 @@ Endpoints
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /api/v1/organizers/bigevents/giftcards/1/transact/ HTTP/1.1
|
||||
POST /api/v1/organizers/bigevents/giftcards/1/transact/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 94
|
||||
Content-Length: 79
|
||||
|
||||
{
|
||||
"value": "2.00"
|
||||
"value": "2.00",
|
||||
"text": "Optional value explaining the transaction"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@@ -222,6 +233,8 @@ Endpoints
|
||||
"secret": "HLBYVELFRC77NCQY",
|
||||
"currency": "EUR",
|
||||
"testmode": false,
|
||||
"expires": null,
|
||||
"conditions": null,
|
||||
"value": "15.37"
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ Resources and endpoints
|
||||
giftcards
|
||||
carts
|
||||
teams
|
||||
devices
|
||||
webhooks
|
||||
seatingplans
|
||||
billing_invoices
|
||||
|
||||
@@ -24,6 +24,7 @@ addon_category integer Internal ID of
|
||||
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
|
||||
multi_allowed boolean Adding the same item multiple times is allowed
|
||||
price_included boolean Adding this add-on to the item is free
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
@@ -65,6 +66,7 @@ Endpoints
|
||||
"min_count": 0,
|
||||
"max_count": 10,
|
||||
"position": 0,
|
||||
"multi_allowed": false,
|
||||
"price_included": true
|
||||
},
|
||||
{
|
||||
@@ -73,6 +75,7 @@ Endpoints
|
||||
"min_count": 0,
|
||||
"max_count": 10,
|
||||
"position": 1,
|
||||
"multi_allowed": false,
|
||||
"price_included": true
|
||||
}
|
||||
]
|
||||
@@ -112,6 +115,7 @@ Endpoints
|
||||
"min_count": 0,
|
||||
"max_count": 10,
|
||||
"position": 1,
|
||||
"multi_allowed": false,
|
||||
"price_included": true
|
||||
}
|
||||
|
||||
@@ -141,6 +145,7 @@ Endpoints
|
||||
"min_count": 0,
|
||||
"max_count": 10,
|
||||
"position": 1,
|
||||
"multi_allowed": false,
|
||||
"price_included": true
|
||||
}
|
||||
|
||||
@@ -158,6 +163,7 @@ Endpoints
|
||||
"min_count": 0,
|
||||
"max_count": 10,
|
||||
"position": 1,
|
||||
"multi_allowed": false,
|
||||
"price_included": true
|
||||
}
|
||||
|
||||
@@ -206,6 +212,7 @@ Endpoints
|
||||
"min_count": 0,
|
||||
"max_count": 10,
|
||||
"position": 1,
|
||||
"multi_allowed": false,
|
||||
"price_included": true
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ addons list of objects Definition of a
|
||||
├ 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
|
||||
├ multi_allowed boolean Adding the same item multiple times is allowed
|
||||
└ price_included boolean Adding this add-on to the item is free
|
||||
bundles list of objects Definition of bundles that are included in this item.
|
||||
Only writable during creation,
|
||||
@@ -159,6 +160,10 @@ meta_data object Values set for
|
||||
|
||||
The attribute ``meta_data`` has been added.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
|
||||
The attribute ``multi_allowed`` has been added to ``addons``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
|
||||
@@ -151,6 +151,18 @@ last_modified datetime Last modificati
|
||||
|
||||
The ``order.fees.canceled`` attribute has been added.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
|
||||
The ``reactivate`` operation has been added.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
|
||||
The ``search`` query parameter has been added.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
|
||||
The ``exclude`` and ``subevent_after`` query parameter has been added.
|
||||
|
||||
|
||||
.. _order-position-resource:
|
||||
|
||||
@@ -173,6 +185,13 @@ price money (string) Price of this p
|
||||
attendee_name string Specified attendee name for this position (or ``null``)
|
||||
attendee_name_parts object of strings Decomposition of attendee name (i.e. given name, family name)
|
||||
attendee_email string Specified attendee email address for this position (or ``null``)
|
||||
company string Attendee company name (or ``null``)
|
||||
street string Attendee street (or ``null``)
|
||||
zipcode string Attendee ZIP code (or ``null``)
|
||||
city string Attendee city (or ``null``)
|
||||
country string Attendee country code (or ``null``)
|
||||
state string Attendee state (ISO 3166-2 code). Only supported in
|
||||
AU, BR, CA, CN, MY, MX, and US, otherwise ``null``.
|
||||
voucher integer Internal ID of the voucher used for this position (or ``null``)
|
||||
tax_rate decimal (string) VAT rate applied for this position
|
||||
tax_value money (string) VAT included in this position
|
||||
@@ -182,8 +201,10 @@ addon_to integer Internal ID of
|
||||
subevent integer ID of the date inside an event series this position belongs to (or ``null``).
|
||||
pseudonymization_id string A random ID, e.g. for use in lead scanning apps
|
||||
checkins list of objects List of check-ins with this ticket
|
||||
├ id integer Internal ID of the check-in event
|
||||
├ list integer Internal ID of the check-in list
|
||||
├ datetime datetime Time of check-in
|
||||
├ type string Type of scan (defaults to ``entry``)
|
||||
└ auto_checked_in boolean Indicates if this check-in been performed automatically by the system
|
||||
downloads list of objects List of ticket download options
|
||||
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
|
||||
@@ -236,6 +257,14 @@ pdf_data object Data object req
|
||||
|
||||
The attribute ``canceled`` has been added.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
|
||||
The attributes ``company``, ``street``, ``zipcode``, ``city``, ``country``, and ``state`` have been added.
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
|
||||
The ``checkin.type`` attribute has been added.
|
||||
|
||||
.. _order-payment-resource:
|
||||
|
||||
Order payment resource
|
||||
@@ -380,6 +409,12 @@ List of all orders
|
||||
"full_name": "Peter",
|
||||
},
|
||||
"attendee_email": null,
|
||||
"company": "Sample company",
|
||||
"street": "Test street 12",
|
||||
"zipcode": "12345",
|
||||
"city": "Testington",
|
||||
"country": "DE",
|
||||
"state": null,
|
||||
"voucher": null,
|
||||
"tax_rate": "0.00",
|
||||
"tax_value": "0.00",
|
||||
@@ -392,6 +427,7 @@ List of all orders
|
||||
"checkins": [
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -441,6 +477,7 @@ List of all orders
|
||||
``last_modified``, and ``status``. Default: ``datetime``
|
||||
:query string code: Only return orders that match the given order code
|
||||
:query string status: Only return orders in the given order status (see above)
|
||||
:query string search: Only return orders matching a given search query
|
||||
:query boolean testmode: Only return orders with ``testmode`` set to ``true`` or ``false``
|
||||
:query boolean require_approval: If set to ``true`` or ``false``, only categories with this value for the field
|
||||
``require_approval`` will be returned.
|
||||
@@ -453,6 +490,8 @@ List of all orders
|
||||
recommend using this in combination with ``testmode=false``, since test mode orders can vanish at any time and
|
||||
you will not notice it using this method.
|
||||
:query datetime created_since: Only return orders that have been created since the given date.
|
||||
:query datetime subevent_after: Only return orders that contain a ticket for a subevent taking place after the given date.
|
||||
:query string exclude: Exclude a field from the output, e.g. ``fees`` or ``positions.downloads``. Can be used as a performance optimization. Can be passed multiple times.
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:resheader X-Page-Generated: The server time at the beginning of the operation. If you're using this API to fetch
|
||||
@@ -536,6 +575,12 @@ Fetching individual orders
|
||||
"full_name": "Peter",
|
||||
},
|
||||
"attendee_email": null,
|
||||
"company": "Sample company",
|
||||
"street": "Test street 12",
|
||||
"zipcode": "12345",
|
||||
"city": "Testington",
|
||||
"country": "DE",
|
||||
"state": null,
|
||||
"voucher": null,
|
||||
"tax_rate": "0.00",
|
||||
"tax_rule": null,
|
||||
@@ -548,6 +593,7 @@ Fetching individual orders
|
||||
"checkins": [
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -816,9 +862,9 @@ Creating orders
|
||||
* ``consume_carts`` (optional) – A list of cart IDs. All cart positions with these IDs will be deleted if the
|
||||
order creation is successful. Any quotas or seats that become free by this operation will be credited to your order
|
||||
creation.
|
||||
* ``email``
|
||||
* ``email`` (optional)
|
||||
* ``locale``
|
||||
* ``sales_channel``
|
||||
* ``sales_channel`` (optional)
|
||||
* ``payment_provider`` (optional) – The identifier of the payment provider set for this order. This needs to be an
|
||||
existing payment provider. You should use ``"free"`` for free orders, and we strongly advise to use ``"manual"``
|
||||
for all orders you create as paid. This field is optional when the order status is ``"n"`` or the order total is
|
||||
@@ -851,15 +897,21 @@ Creating orders
|
||||
|
||||
* ``positionid`` (optional, see below)
|
||||
* ``item``
|
||||
* ``variation``
|
||||
* ``variation`` (optional)
|
||||
* ``price`` (optional, if set to ``null`` or missing the price will be computed from the given product)
|
||||
* ``seat`` (The ``seat_guid`` attribute of a seat. Required when the specified ``item`` requires a seat, otherwise must be ``null``.)
|
||||
* ``attendee_name`` **or** ``attendee_name_parts``
|
||||
* ``attendee_name`` **or** ``attendee_name_parts`` (optional)
|
||||
* ``voucher`` (optional, the ``code`` attribute of a valid voucher)
|
||||
* ``attendee_email``
|
||||
* ``attendee_email`` (optional)
|
||||
* ``company`` (optional)
|
||||
* ``street`` (optional)
|
||||
* ``zipcode`` (optional)
|
||||
* ``city`` (optional)
|
||||
* ``country`` (optional)
|
||||
* ``state`` (optional)
|
||||
* ``secret`` (optional)
|
||||
* ``addon_to`` (optional, see below)
|
||||
* ``subevent``
|
||||
* ``subevent`` (optional)
|
||||
* ``answers``
|
||||
|
||||
* ``question``
|
||||
@@ -883,7 +935,8 @@ Creating orders
|
||||
during order generation and is not respected automatically when the order changes later.)
|
||||
|
||||
* ``force`` (optional). If set to ``true``, quotas will be ignored.
|
||||
* ``send_mail`` (optional). If set to ``true``, the same emails will be sent as for a regular order. Defaults to
|
||||
* ``send_mail`` (optional). If set to ``true``, the same emails will be sent as for a regular order, regardless of
|
||||
whether these emails are enabled for certain sales channels. Defaults to
|
||||
``false``.
|
||||
|
||||
If you want to use add-on products, you need to set the ``positionid`` fields of all positions manually
|
||||
@@ -977,6 +1030,10 @@ Creating orders
|
||||
Order state operations
|
||||
----------------------
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The ``mark_paid`` operation now takes a ``send_email`` parameter.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/mark_paid/
|
||||
|
||||
Marks a pending or expired order as successfully paid.
|
||||
@@ -988,6 +1045,11 @@ Order state operations
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/mark_paid/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"send_email": true
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
@@ -1057,6 +1119,42 @@ Order state operations
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||
:statuscode 404: The requested order does not exist.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/reactivate/
|
||||
|
||||
Reactivates a canceled order. This will set the order to pending or paid state. Only possible if all products are
|
||||
still available.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/reactivate/ 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
|
||||
|
||||
{
|
||||
"code": "ABC12",
|
||||
"status": "n",
|
||||
...
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
:param event: The ``slug`` field of the event to modify
|
||||
:param code: The ``code`` field of the order to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The order cannot be reactivated
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||
:statuscode 404: The requested order does not exist.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/mark_pending/
|
||||
|
||||
Marks a paid order as unpaid.
|
||||
@@ -1402,6 +1500,7 @@ List of all order positions
|
||||
"checkins": [
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -1507,6 +1606,7 @@ Fetching individual positions
|
||||
"checkins": [
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -1632,6 +1732,10 @@ Order payment endpoints
|
||||
|
||||
Payments can now be created through the API.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The ``confirm`` operation now takes a ``send_email`` parameter.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/payments/
|
||||
|
||||
Returns a list of all payments for an order.
|
||||
@@ -1732,7 +1836,10 @@ Order payment endpoints
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{"force": false}
|
||||
{
|
||||
"send_email": true,
|
||||
"force": false
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
@@ -2156,3 +2263,57 @@ Order refund endpoints
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||
:statuscode 404: The requested order or refund does not exist.
|
||||
|
||||
Revoked ticket secrets
|
||||
----------------------
|
||||
|
||||
With some non-default ticket secret generation methods, a list of revoked ticket secrets is required for proper validation.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
Added revocation lists.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/revokedsecrets/
|
||||
|
||||
Returns a list of all revoked secrets within a given event.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/revokedsecrets/ 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
|
||||
X-Page-Generated: 2017-12-01T10:00:00Z
|
||||
|
||||
{
|
||||
"count": 1,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1234,
|
||||
"secret": "k24fiuwvu8kxz3y1",
|
||||
"created": "2017-12-01T10:00:00Z",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``secret`` and ``created``. Default: ``-created``
|
||||
:query datetime created_since: Only return revocations that have been created since the given date.
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:resheader X-Page-Generated: The server time at the beginning of the operation. If you're using this API to fetch
|
||||
differences, this is the value you want to use as ``created_since`` in your next call.
|
||||
: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.
|
||||
|
||||
@@ -26,6 +26,8 @@ close_when_sold_out boolean If ``true``, th
|
||||
again.
|
||||
closed boolean Whether the quota is currently closed (see above
|
||||
field).
|
||||
release_after_exit boolean Whether the quota regains capacity as soon as some tickets
|
||||
have been scanned at an exit.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
.. versionchanged:: 1.10
|
||||
@@ -36,6 +38,10 @@ closed boolean Whether the quo
|
||||
|
||||
The attributes ``close_when_sold_out`` and ``closed`` have been added.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
|
||||
The attribute ``release_after_exit`` has been added.
|
||||
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
@@ -283,6 +289,7 @@ Endpoints
|
||||
"total_size": 1000,
|
||||
"pending_orders": 25,
|
||||
"paid_orders": 423,
|
||||
"exited_orders": 0,
|
||||
"cart_positions": 7,
|
||||
"blocking_vouchers": 126,
|
||||
"waiting_list": 0
|
||||
|
||||
@@ -39,16 +39,19 @@ geo_lon float Longitude of th
|
||||
item_price_overrides list of objects List of items for which this sub-event overrides the
|
||||
default price
|
||||
├ item integer The internal item ID
|
||||
├ disabled boolean If ``true``, item should not be available for this sub-event
|
||||
└ price money (string) The price or ``null`` for the default price
|
||||
variation_price_overrides list of objects List of variations for which this sub-event overrides
|
||||
the default price
|
||||
├ variation integer The internal variation ID
|
||||
├ disabled boolean If ``true``, variation should not be available for this sub-event
|
||||
└ price money (string) The price or ``null`` for the default price
|
||||
meta_data object Values set for organizer-specific meta data parameters.
|
||||
seating_plan integer If reserved seating is in use, the ID of a seating
|
||||
plan. Otherwise ``null``.
|
||||
seat_category_mapping object An object mapping categories of the seating plan
|
||||
(strings) to items in the event (integers or ``null``).
|
||||
last_modified datetime Last modification of this object
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
.. versionchanged:: 1.7
|
||||
@@ -74,6 +77,14 @@ seat_category_mapping object An object mappi
|
||||
|
||||
The attributes ``geo_lat`` and ``geo_lon`` have been added.
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
|
||||
The ``disabled`` attribute has been added to ``item_price_overrides`` and ``variation_price_overrides``.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
|
||||
The ``last_modified`` attribute has been added.
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -125,6 +136,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -141,6 +153,8 @@ Endpoints
|
||||
:query ends_after: If set to a date and time, only events that happen during of after the given time are returned.
|
||||
:param organizer: The ``slug`` field of a valid organizer
|
||||
:param event: The ``slug`` field of the main event
|
||||
:query datetime modified_since: Only return objects that have changed since the given date. Be careful: This does not
|
||||
allow you to know if a subevent was deleted.
|
||||
:query array attr[meta_data_key]: By providing the key and value of a meta data attribute, the list of sub-events
|
||||
will only contain the sub-events matching the set criteria. Providing ``?attr[Format]=Seminar`` would return
|
||||
only those sub-events having set their ``Format`` meta data to ``Seminar``, ``?attr[Format]=`` only those, that
|
||||
@@ -182,6 +196,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -216,6 +231,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -271,6 +287,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -307,6 +324,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "23.42"
|
||||
}
|
||||
],
|
||||
@@ -339,6 +357,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "23.42"
|
||||
}
|
||||
],
|
||||
@@ -427,6 +446,7 @@ Endpoints
|
||||
"item_price_overrides": [
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -70,6 +70,9 @@ and ``checkin_list``.
|
||||
only include the minimum amount of data necessary for you to fetch the changed objects from our
|
||||
:ref:`rest-api` in an authenticated way.
|
||||
|
||||
.. warning:: In very rare cases, you could receive the same webhook notification twice. We try to avoid it, but we
|
||||
prefer it over missing a notification.
|
||||
|
||||
If you want to further prevent others from accessing your webhook URL, you can also use `Basic authentication`_ and
|
||||
supply the URL to us in the format of ``https://username:password@domain.com/path/``.
|
||||
We recommend that you use HTTPS for your webhook URL and might require it in the future. If HTTPS is used, we require
|
||||
|
||||
@@ -52,6 +52,7 @@ extensions = [
|
||||
'sphinx.ext.coverage',
|
||||
'sphinxcontrib.httpdomain',
|
||||
'sphinxcontrib.images',
|
||||
'sphinxemoji.sphinxemoji',
|
||||
]
|
||||
if HAS_PYENCHANT:
|
||||
extensions.append('sphinxcontrib.spelling')
|
||||
|
||||
@@ -66,7 +66,7 @@ event-related views, there is also a signal that allows you to add the view to t
|
||||
|
||||
from django.urls import resolve, reverse
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from pretix.control.signals import nav_event
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,22 @@ that we'll provide in this plugin::
|
||||
from .exporter import MyExporter
|
||||
return MyExporter
|
||||
|
||||
Some exporters might also prove to be useful, when provided on an organizer-level. In order to declare your
|
||||
exporter as capable of providing exports spanning multiple events, your plugin should listen for this signal
|
||||
and return the subclass of ``pretix.base.exporter.BaseExporter`` that we'll provide in this plugin::
|
||||
|
||||
from django.dispatch import receiver
|
||||
|
||||
from pretix.base.signals import register_multievent_data_exporters
|
||||
|
||||
|
||||
@receiver(register_multievent_data_exporters, dispatch_uid="multieventexporter_myexporter")
|
||||
def register_multievent_data_exporter(sender, **kwargs):
|
||||
from .exporter import MyExporter
|
||||
return MyExporter
|
||||
|
||||
If your exporter supports both event-level and multi-event level exports, you will need to listen for both
|
||||
signals.
|
||||
|
||||
The exporter class
|
||||
------------------
|
||||
|
||||
@@ -12,7 +12,8 @@ Core
|
||||
|
||||
.. automodule:: pretix.base.signals
|
||||
:members: periodic_task, event_live_issues, event_copy_data, email_filter, register_notification_types,
|
||||
item_copy_data, register_sales_channels, register_global_settings, quota_availability, global_email_filter
|
||||
item_copy_data, register_sales_channels, register_global_settings, quota_availability, global_email_filter,
|
||||
register_ticket_secret_generators
|
||||
|
||||
Order events
|
||||
""""""""""""
|
||||
@@ -20,7 +21,7 @@ Order events
|
||||
There are multiple signals that will be sent out in the ordering cycle:
|
||||
|
||||
.. automodule:: pretix.base.signals
|
||||
:members: validate_cart, validate_cart_addons, validate_order, order_fee_calculation, order_paid, order_placed, order_canceled, order_expired, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download, order_split, order_gracefully_delete, invoice_line_text
|
||||
:members: validate_cart, validate_cart_addons, validate_order, order_fee_calculation, order_paid, order_placed, order_canceled, order_reactivated, order_expired, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download, order_split, order_gracefully_delete, invoice_line_text
|
||||
|
||||
Check-ins
|
||||
"""""""""
|
||||
@@ -33,11 +34,11 @@ Frontend
|
||||
--------
|
||||
|
||||
.. automodule:: pretix.presale.signals
|
||||
:members: html_head, html_footer, footer_link, front_page_top, front_page_bottom, front_page_bottom_widget, fee_calculation_for_cart, contact_form_fields, question_form_fields, checkout_confirm_messages, checkout_confirm_page_content, checkout_all_optional, html_page_header, sass_preamble, sass_postamble, render_seating_plan, checkout_flow_steps, position_info, item_description
|
||||
:members: html_head, html_footer, footer_link, front_page_top, front_page_bottom, front_page_bottom_widget, fee_calculation_for_cart, contact_form_fields, question_form_fields, contact_form_fields_overrides, question_form_fields_overrides, checkout_confirm_messages, checkout_confirm_page_content, checkout_all_optional, html_page_header, sass_preamble, sass_postamble, render_seating_plan, checkout_flow_steps, position_info, position_info_top, item_description, global_html_head, global_html_footer, global_html_page_header
|
||||
|
||||
|
||||
.. automodule:: pretix.presale.signals
|
||||
:members: order_info, order_meta_from_request
|
||||
:members: order_info, order_info_top, order_meta_from_request
|
||||
|
||||
Request flow
|
||||
""""""""""""
|
||||
@@ -66,19 +67,13 @@ Vouchers
|
||||
""""""""
|
||||
|
||||
.. automodule:: pretix.control.signals
|
||||
:members: item_forms
|
||||
|
||||
Vouchers
|
||||
""""""""
|
||||
|
||||
.. automodule:: pretix.control.signals
|
||||
:members: voucher_form_class, voucher_form_html, voucher_form_validation
|
||||
:members: item_forms, voucher_form_class, voucher_form_html, voucher_form_validation
|
||||
|
||||
Dashboards
|
||||
""""""""""
|
||||
|
||||
.. automodule:: pretix.control.signals
|
||||
:members: event_dashboard_widgets, user_dashboard_widgets
|
||||
:members: event_dashboard_widgets, user_dashboard_widgets, event_dashboard_top
|
||||
|
||||
Ticket designs
|
||||
""""""""""""""
|
||||
|
||||
@@ -126,6 +126,8 @@ The provider class
|
||||
|
||||
.. autoattribute:: test_mode_message
|
||||
|
||||
.. autoattribute:: requires_invoice_immediately
|
||||
|
||||
|
||||
Additional views
|
||||
----------------
|
||||
|
||||
@@ -61,7 +61,7 @@ A working example would be::
|
||||
from pretix.base.plugins import PluginConfig
|
||||
except ImportError:
|
||||
raise RuntimeError("Please use pretix 2.7 or above to run this plugin!")
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class PaypalApp(PluginConfig):
|
||||
@@ -136,7 +136,7 @@ in the ``installed`` method::
|
||||
pass # Your code here
|
||||
|
||||
|
||||
Note that ``installed`` will *not* be called if the plugin in indirectly activated for an event
|
||||
Note that ``installed`` will *not* be called if the plugin is indirectly activated for an event
|
||||
because the event is created with settings copied from another event.
|
||||
|
||||
Views
|
||||
@@ -151,8 +151,8 @@ your Django app label.
|
||||
with checking that the calling user is logged in, has appropriate permissions,
|
||||
etc. We plan on providing native support for this in a later version.
|
||||
|
||||
.. _Django app: https://docs.djangoproject.com/en/1.7/ref/applications/
|
||||
.. _signal dispatcher: https://docs.djangoproject.com/en/1.7/topics/signals/
|
||||
.. _namespace packages: http://legacy.python.org/dev/peps/pep-0420/
|
||||
.. _Django app: https://docs.djangoproject.com/en/3.0/ref/applications/
|
||||
.. _signal dispatcher: https://docs.djangoproject.com/en/3.0/topics/signals/
|
||||
.. _namespace packages: https://legacy.python.org/dev/peps/pep-0420/
|
||||
.. _entry point: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#locating-plugins
|
||||
.. _cookiecutter: https://cookiecutter.readthedocs.io/en/latest/
|
||||
|
||||
@@ -72,6 +72,10 @@ The output class
|
||||
|
||||
.. autoattribute:: download_button_icon
|
||||
|
||||
.. autoattribute:: multi_download_button_text
|
||||
|
||||
.. autoattribute:: long_download_button_text
|
||||
|
||||
.. autoattribute:: preview_allowed
|
||||
|
||||
.. autoattribute:: javascript_required
|
||||
|
||||
@@ -7,7 +7,7 @@ Coding style and quality
|
||||
for more information. Use four spaces for indentation.
|
||||
|
||||
* We sort our imports by a certain schema, but you don't have to do this by hand. Again, ``setup.cfg`` contains
|
||||
some definitions that allow the command ``isort -rc <directory>`` to automatically sort the imports in your source
|
||||
some definitions that allow the command ``isort <directory>`` to automatically sort the imports in your source
|
||||
files.
|
||||
|
||||
* For templates and models, please take a look at the `Django Coding Style`_. We like Django's `class-based views`_ and
|
||||
@@ -18,7 +18,7 @@ Coding style and quality
|
||||
* We expect all new code to come with proper tests. When writing new tests, please write them using `pytest-style`_
|
||||
test functions and raw ``assert`` statements. Use `fixtures`_ to prevent repetitive code. Some old parts of pretix'
|
||||
test suite are in the style of Python's unit test module. If you extend those files, you might continue in this style,
|
||||
but please use pytest style for any new test files.
|
||||
but please use ``pytest`` style for any new test files.
|
||||
|
||||
* Please keep the first line of your commit messages short. When referencing an issue, please phrase it like
|
||||
``Fix #123 -- Problems with order creation`` or ``Refs #123 -- Fix this part of that bug``.
|
||||
|
||||
@@ -69,7 +69,7 @@ We now need a way to translate the action codes like ``pretix.event.changed`` in
|
||||
strings. The :py:attr:`pretix.base.signals.logentry_display` signals allows you to do so. A simple
|
||||
implementation could look like::
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import gettext as _
|
||||
from pretix.base.signals import logentry_display
|
||||
|
||||
@receiver(signal=logentry_display)
|
||||
|
||||
@@ -98,7 +98,7 @@ pull request nevertheless and ask us for help, we are happy to assist you.
|
||||
Execute the following commands to check for code style errors::
|
||||
|
||||
flake8 .
|
||||
isort -c -rc .
|
||||
isort -c .
|
||||
python manage.py check
|
||||
|
||||
Execute the following command to run pretix' test suite (might take a couple of minutes)::
|
||||
@@ -117,11 +117,11 @@ for example, to check for any errors in any staged files when committing::
|
||||
export GIT_WORK_TREE=../
|
||||
export GIT_DIR=../.git
|
||||
source ../env/bin/activate # Adjust to however you activate your virtual environment
|
||||
for file in $(git diff --cached --name-only | grep -E '\.py$' | grep -Ev "migrations|mt940\.py|pretix/settings\.py|make_testdata\.py|testutils/settings\.py|tests/settings\.py|pretix/base/models/__init__\.py")
|
||||
for file in $(git diff --cached --name-only | grep -E '\.py$' | grep -Ev "migrations|mt940\.py|pretix/settings\.py|make_testdata\.py|testutils/settings\.py|tests/settings\.py|pretix/base/models/__init__\.py|.*_pb2\.py")
|
||||
do
|
||||
echo $file
|
||||
git show ":$file" | flake8 - --stdin-display-name="$file" || exit 1 # we only want to lint the staged changes, not any un-staged changes
|
||||
git show ":$file" | isort -df --check-only - | grep ERROR && exit 1 || true
|
||||
git show ":$file" | isort -c - | grep ERROR && exit 1 || true
|
||||
done
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ transactions list of objects Transactions in
|
||||
├ payer string Payment source
|
||||
├ reference string Payment reference
|
||||
├ amount string Payment amount
|
||||
├ iban string Payment IBAN
|
||||
├ bic string Payment BIC
|
||||
├ date string Payment date (in **user-inputted** format)
|
||||
├ order string Associated order code (or ``null``)
|
||||
└ comment string Internal comment
|
||||
@@ -83,6 +85,8 @@ Endpoints
|
||||
"date": "26.06.2017",
|
||||
"payer": "John Doe",
|
||||
"order": null,
|
||||
"iban": "",
|
||||
"bic": "",
|
||||
"checksum": "5de03a601644dfa63420dacfd285565f8375a8f2",
|
||||
"reference": "GUTSCHRIFT\r\nSAMPLECONF-NAB12 EREF: SAMPLECONF-NAB12\r\nIBAN: DE1234556…",
|
||||
"state": "nomatch",
|
||||
@@ -132,6 +136,8 @@ Endpoints
|
||||
"comment": "",
|
||||
"date": "26.06.2017",
|
||||
"payer": "John Doe",
|
||||
"iban": "",
|
||||
"bic": "",
|
||||
"order": null,
|
||||
"checksum": "5de03a601644dfa63420dacfd285565f8375a8f2",
|
||||
"reference": "GUTSCHRIFT\r\nSAMPLECONF-NAB12 EREF: SAMPLECONF-NAB12\r\nIBAN: DE1234556…",
|
||||
|
||||
356
doc/plugins/digital.rst
Normal file
@@ -0,0 +1,356 @@
|
||||
Digital content
|
||||
===============
|
||||
|
||||
URL interpolation and JWT authentication
|
||||
----------------------------------------
|
||||
|
||||
In the simplest case, you can use the digital content module to point users to a specific piece of content on some
|
||||
platform after their ticket purchase, or show them an embedded video or live stream. However, the full power of the
|
||||
module can be utilized by passing additional information to the target system to automatically authenticate the user
|
||||
or pre-fill some fields with their data. For example, you could use an URL like this::
|
||||
|
||||
https://webinars.example.com/join?as={attendee_name}&userid={order_code}-{positionid}
|
||||
|
||||
While this is already useful, it does not provide much security – anyone could guess a valid combination for that URL.
|
||||
Therefore, the module allows you to pass information as a `JSON Web Token`_, which isn't encrypted, but signed with a
|
||||
shared secret such that nobody can create their own tokens or modify the contents. To use a token, set up a URL like this::
|
||||
|
||||
https://webinars.example.com/join?with_token={token}
|
||||
|
||||
Additionally, you will need to set a JWT secret and a token template, either through the pretix interface or through the
|
||||
API (see below). pretix currently only supports tokens signed with ``HMAC-SHA256`` (``HS256``). Your token template can contain
|
||||
whatever JSON you'd like to pass on based on the same variables, for example::
|
||||
|
||||
{
|
||||
"iss": "pretix.eu",
|
||||
"aud": "webinars.example.com",
|
||||
"user": {
|
||||
"id": "{order_code}-{positionid}",
|
||||
"product": "{product_id}",
|
||||
"variation": "{variation_id}",
|
||||
"name": "{attendee_name}"
|
||||
}
|
||||
}
|
||||
|
||||
Variables can only be used in strings inside the JSON structure.
|
||||
pretix will automatically add an ``iat`` claim with the current timestamp and an ``exp`` claim with an expiration timestamp
|
||||
based on your configuration.
|
||||
|
||||
|
||||
List of variables
|
||||
"""""""""""""""""
|
||||
|
||||
The following variables are currently supported:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
=================================== ====================================================================
|
||||
Variable Description
|
||||
=================================== ====================================================================
|
||||
``order_code`` Order code (alphanumerical, unique per order, not per ticket)
|
||||
``positionid`` ID of the ticket within the order (integer, starting at 1)
|
||||
``order_email`` E-mail address of the ticket purchaser
|
||||
``product_id`` Internal ID of the purchased product
|
||||
``product_variation`` Internal ID of the purchased product variation (or empty)
|
||||
``attendee_name`` Full name of the ticket holder (or empty)
|
||||
``attendee_name_*`` Name parts of the ticket holder, depending on configuration, e.g. ``attendee_name_given_name`` or ``attendee_name_family_name``
|
||||
``attendee_email`` E-mail address of the ticket holder (or empty)
|
||||
``attendee_company`` Company of the ticket holder (or empty)
|
||||
``attendee_street`` Street of the ticket holder's address (or empty)
|
||||
``attendee_zipcode`` ZIP code of the ticket holder's address (or empty)
|
||||
``attendee_city`` City of the ticket holder's address (or empty)
|
||||
``attendee_country`` Country code of the ticket holder's address (or empty)
|
||||
``attendee_state`` State of the ticket holder's address (or empty)
|
||||
``answer[XYZ]`` Answer to the custom question with identifier ``XYZ``
|
||||
``invoice_name`` Full name of the invoice address (or empty)
|
||||
``invoice_name_*`` Name parts of the invoice address, depending on configuration, e.g. ``invoice_name_given_name`` or ``invoice_name_family_name``
|
||||
``invoice_company`` Company of the invoice address (or empty)
|
||||
``invoice_street`` Street of the invoice address (or empty)
|
||||
``invoice_zipcode`` ZIP code of the invoice address (or empty)
|
||||
``invoice_city`` City of the invoice address (or empty)
|
||||
``invoice_country`` Country code of the invoice address (or empty)
|
||||
``invoice_state`` State of the invoice address (or empty)
|
||||
``meta_XYZ`` Value of the event's ``XYZ`` meta property
|
||||
``token`` Signed JWT (only to be used in URLs, not in tokens)
|
||||
=================================== ====================================================================
|
||||
|
||||
|
||||
API Resource description
|
||||
-------------------------
|
||||
|
||||
The digital content plugin provides a HTTP API that allows you to create new digital content for your ticket holders,
|
||||
such as live streams, videos, or material downloads.
|
||||
|
||||
The digital content resource contains the following public fields:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
id integer Internal content ID
|
||||
title multi-lingual string The content title (required)
|
||||
content_type string The type of content, valid values are ``webinar``, ``video``, ``livestream``, ``link``, ``file``
|
||||
url string The location of the digital content
|
||||
description multi-lingual string A public description of the item. May contain Markdown
|
||||
syntax and is not required.
|
||||
available_from datetime The first date time at which this content will be shown
|
||||
(or ``null``).
|
||||
available_until datetime The last date time at which this content will b e shown
|
||||
(or ``null``).
|
||||
all_products boolean If ``true``, the content is available to all buyers of tickets for this event. The ``limit_products`` field is ignored in this case.
|
||||
limit_products list of integers List of product/item IDs. This content is only shown to buyers of these ticket types.
|
||||
position integer An integer, used for sorting
|
||||
subevent integer Date in an event series this content should be shown for. Should be ``null`` if this is not an event series or if this should be shown to all customers.
|
||||
jwt_template string Template for JWT token generation
|
||||
jwt_secret string Secret for JWT token generation
|
||||
jwt_validity integer JWT validity in days
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
API Endpoints
|
||||
-------------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/digitalcontents/
|
||||
|
||||
Returns a list of all digital content configured for an event.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/digitalcontents/ 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": 1,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": 1,
|
||||
"subevent": null,
|
||||
"title": {
|
||||
"en": "Concert livestream"
|
||||
},
|
||||
"content_type": "link",
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||
"description": {
|
||||
"en": "Watch our event live here on YouTube!"
|
||||
},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"available_from": "2020-03-22T23:00:00Z",
|
||||
"available_until": null,
|
||||
"position": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
:query page: The page number in case of a multi-page result set, default is 1
|
||||
:param organizer: The ``slug`` field of a valid organizer
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer or event does not exist **or** you have no permission to view it.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/digitalcontents/(id)/
|
||||
|
||||
Returns information on one content item, identified by its ID.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/digitalcontents/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": 1,
|
||||
"subevent": null,
|
||||
"title": {
|
||||
"en": "Concert livestream"
|
||||
},
|
||||
"content_type": "link",
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||
"description": {
|
||||
"en": "Watch our event live here on YouTube!"
|
||||
},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"available_from": "2020-03-22T23:00:00Z",
|
||||
"available_until": null,
|
||||
"position": 1
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:param id: The ``id`` field of the content to fetch
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event/content does not exist **or** you have no permission to view it.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/digitalcontents/
|
||||
|
||||
Create a new digital content.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/digitalcontents/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 166
|
||||
|
||||
{
|
||||
"subevent": null,
|
||||
"title": {
|
||||
"en": "Concert livestream"
|
||||
},
|
||||
"content_type": "link",
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||
"description": {
|
||||
"en": "Watch our event live here on YouTube!"
|
||||
},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"available_from": "2020-03-22T23:00:00Z",
|
||||
"available_until": null,
|
||||
"position": 1
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 2,
|
||||
"subevent": null,
|
||||
"title": {
|
||||
"en": "Concert livestream"
|
||||
},
|
||||
"content_type": "link",
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||
"description": {
|
||||
"en": "Watch our event live here on YouTube!"
|
||||
},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"available_from": "2020-03-22T23:00:00Z",
|
||||
"available_until": null,
|
||||
"position": 1
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to create new content for
|
||||
:param event: The ``slug`` field of the event to create new content for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The content 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 digital contents.
|
||||
|
||||
|
||||
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/digitalcontents/(id)/
|
||||
|
||||
Update a content. 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.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /api/v1/organizers/bigevents/events/sampleconf/digitalcontents/1/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 34
|
||||
|
||||
{
|
||||
"url": "https://mywebsite.com"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: text/javascript
|
||||
|
||||
{
|
||||
"id": 2,
|
||||
"subevent": null,
|
||||
"title": {
|
||||
"en": "Concert livestream"
|
||||
},
|
||||
"content_type": "link",
|
||||
"url": "https://mywebsite.com",
|
||||
"description": {
|
||||
"en": "Watch our event live here on YouTube!"
|
||||
},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"available_from": "2020-03-22T23:00:00Z",
|
||||
"available_until": 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 content to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The content could not be modified due to invalid submitted data.
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event/content does not exist **or** you have no permission to change it.
|
||||
|
||||
|
||||
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/digitalcontents/(id)/
|
||||
|
||||
Delete a digital content.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
DELETE /api/v1/organizers/bigevents/events/sampleconf/digitalcontents/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 content to delete
|
||||
:statuscode 204: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event/content does not exist **or** you have no permission to change it
|
||||
|
||||
.. _JSON Web Token: https://en.wikipedia.org/wiki/JSON_Web_Token
|
||||
@@ -15,3 +15,5 @@ If you want to **create** a plugin, please go to the
|
||||
ticketoutputpdf
|
||||
badges
|
||||
campaigns
|
||||
digital
|
||||
webinar
|
||||
|
||||
43
doc/plugins/webinar.rst
Normal file
@@ -0,0 +1,43 @@
|
||||
pretix Webinar
|
||||
==============
|
||||
|
||||
Fetch host URLs
|
||||
---------------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/webinars/
|
||||
|
||||
Returns a list of all currently available webinar calls configured for an event.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/webinars/ 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
|
||||
|
||||
[
|
||||
{
|
||||
"name": "Webinar B – Sept. 8th, 2020",
|
||||
"hosturl": "http://pretix.eu/demo/museum/webinar/host/a9aded3d7bd4df60/30611a34f9fee5d3/"
|
||||
},
|
||||
{
|
||||
"name": "Webinar A – Sept. 8, 2020",
|
||||
"hosturl": "http://pretix.eu/demo/museum/webinar/host/e714x7d4a4a36a04/b9cc444665xxx757/"
|
||||
}
|
||||
]
|
||||
|
||||
:query subevent: Limit the result to the webinar(s) for a specific subevent.
|
||||
:param organizer: The ``slug`` field of a valid organizer
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer or event does not exist **or** you have no permission to view it.
|
||||
@@ -3,7 +3,8 @@ sphinx==2.3.*
|
||||
sphinx-rtd-theme
|
||||
sphinxcontrib-httpdomain
|
||||
sphinxcontrib-images
|
||||
sphinxcontrib-spelling
|
||||
sphinxcontrib-spelling==4.*
|
||||
sphinxemoji
|
||||
pygments-markdown-lexer
|
||||
# See https://github.com/rfk/pyenchant/pull/130
|
||||
git+https://github.com/raphaelm/pyenchant.git@patch-1#egg=pyenchant
|
||||
|
||||
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 70 KiB |
BIN
doc/screens/event/tax_add.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 53 KiB |
BIN
doc/screens/event/timeslots_checkinlists.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
doc/screens/event/timeslots_create.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
doc/screens/event/timeslots_create_2.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
doc/screens/event/timeslots_create_3.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
doc/screens/event/timeslots_presale.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
doc/screens/event/timeslots_settings_1.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 55 KiB |
@@ -10,7 +10,11 @@ availabilities
|
||||
backend
|
||||
backends
|
||||
banktransfer
|
||||
barcode
|
||||
barcodes
|
||||
Bcc
|
||||
bic
|
||||
BIC
|
||||
boolean
|
||||
booleans
|
||||
cancelled
|
||||
@@ -47,13 +51,19 @@ gunicorn
|
||||
guid
|
||||
hardcoded
|
||||
hostname
|
||||
iban
|
||||
IBAN
|
||||
ics
|
||||
idempotency
|
||||
iframe
|
||||
incrementing
|
||||
inofficial
|
||||
invalidations
|
||||
iOS
|
||||
iterable
|
||||
Jimdo
|
||||
jwt
|
||||
JWT
|
||||
libpretixprint
|
||||
libsass
|
||||
linters
|
||||
@@ -88,7 +98,9 @@ prepending
|
||||
preprocessor
|
||||
presale
|
||||
pretix
|
||||
pretixSCAN
|
||||
pretixdroid
|
||||
pretixPOS
|
||||
pretixpresale
|
||||
prometheus
|
||||
proxied
|
||||
|
||||
@@ -26,6 +26,9 @@ Sender address
|
||||
we strongly recommend to use the SMTP settings below as well, otherwise your e-mails might be detected as spam
|
||||
due to the `Sender Policy Framework`_ and similar mechanisms.
|
||||
|
||||
Sender name
|
||||
This is the name associated with the sender address. By default, this is your event name.
|
||||
|
||||
Signature
|
||||
This text will be appended to all e-mails in form of a signature. This might be useful e.g. to add your contact
|
||||
details or any legal information that needs to be included with the e-mails.
|
||||
@@ -33,6 +36,15 @@ Signature
|
||||
Bcc address
|
||||
This email address will receive a copy of every event-related email.
|
||||
|
||||
Attach calendar files
|
||||
With this option, every order confirmation mail will include an ics file with name, date and location of
|
||||
your event. It can be imported into many digital calendars.
|
||||
|
||||
Sales Channels for Checkout Emails
|
||||
When you are using multiple sales channel, you may want to decide that mails for order and payment confirmation
|
||||
are only to be sent for some sales channels. For orders created through the default online shop, these emails
|
||||
must always be send. A similar option is available for ticket download reminders.
|
||||
|
||||
E-mail design
|
||||
-------------
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
Warengutschein
|
||||
Wertgutschein
|
||||
|
||||
.. _giftcards:
|
||||
|
||||
Gift cards
|
||||
==========
|
||||
|
||||
|
||||
94
doc/user/events/guides/timeslots.rst
Normal file
@@ -0,0 +1,94 @@
|
||||
.. _timeslots:
|
||||
|
||||
Use case: Time slots
|
||||
====================
|
||||
|
||||
A more advanced use case of pretix is using pretix for time-slot-based access to an area with a limited visitor
|
||||
capacity, such as a museum or other attraction. This guide will show you the quickest way to set up such an event
|
||||
with pretix.
|
||||
|
||||
First of all, when creating your event, you need to select that your event represents an "event series":
|
||||
|
||||
|
||||
.. thumbnail:: ../../../screens/event/create_step1.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
You can click :ref:`here <subevents>` for a more general description of event series with pretix, but everything you
|
||||
need to know is in this chapter as well.
|
||||
|
||||
General event setup
|
||||
-------------------
|
||||
|
||||
Before you go further, set up your products that you want to sell for each time slot, such as different types of entry.
|
||||
|
||||
Creating slots
|
||||
--------------
|
||||
|
||||
To create the time slots, you need to create a number of "dates" in the event series. Select "Dates" in the navigation
|
||||
menu on the left side and click "Create many new dates". Then, first enter the pattern of your opening days. In the
|
||||
example, the museum is open week Tuesday to Sunday. We recommend to create the slots for a few weeks at a time, but not
|
||||
e.g. for a full year, since it will be more complicated to change things later.
|
||||
|
||||
.. thumbnail:: ../../../screens/event/timeslots_create.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Then, scroll to the times section and create your time slots. You can do any interval you like. If you have different
|
||||
opening times on different week days, you will need to go through the creation process multiple times.
|
||||
|
||||
.. thumbnail:: ../../../screens/event/timeslots_create_2.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Scroll further down and create one or multiple quotas that define how many people can book a ticket for that time slot.
|
||||
In this example, 50 people in total are allowed to enter within every slot:
|
||||
|
||||
.. thumbnail:: ../../../screens/event/timeslots_create_3.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Do **not** create a check-in list at this point. We will deal with this further below in the guide.
|
||||
Now, press "Save" to create your slots.
|
||||
|
||||
.. warning:: If you create a lot of time slots at once, the server might need a few minutes to create them all in our
|
||||
system. If you receive an error page because it took too long, please do not try again immediately but wait
|
||||
for a few minutes. Most likely, the slots will be created successfully even though you saw an error.
|
||||
|
||||
Event settings
|
||||
--------------
|
||||
|
||||
We recommend that you navigate to "Settings" > "General" > "Display" and set the settings "Default overview style"
|
||||
to "Week calendar":
|
||||
|
||||
.. thumbnail:: ../../../screens/event/timeslots_settings_1.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Now, your ticket shop should give users a nice weekly overview over all time slots and their availability:
|
||||
|
||||
.. thumbnail:: ../../../screens/event/timeslots_presale.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Check-in
|
||||
--------
|
||||
|
||||
If you want to scan people at the entrance of your event and only admit them at their designated time, we recommend
|
||||
the following setup: Go to "Check-in" in the main navigation on the left and create a new check-in list. Give it a name
|
||||
and do *not* choose a specific data. We will use one check-in list for all dates. Then, go to the "Advanced" tab at
|
||||
the top and set up two restrictions to make sure people can only get in during the time slot they registered for.
|
||||
You can create the rules exactly like shown in the following screenshot:
|
||||
|
||||
.. thumbnail:: ../../../screens/event/timeslots_checkinlists.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
If you want, you can enter a tolerance of e.g. "10" if you want to be a little bit more relaxed and admit people up to
|
||||
10 minutes before or after their time slot.
|
||||
|
||||
Now, download our `Android or Desktop app`_ and register it to your account. The app will ask you to select one the
|
||||
time slots, but it does not matter, you can select any one of them and then select your newly created check-in list.
|
||||
That's it, you're good to go!
|
||||
|
||||
.. _Android or Desktop app: https://pretix.eu/about/en/scan
|
||||
@@ -292,6 +292,8 @@ Flexible group sizes
|
||||
|
||||
If you want to give out discounted tickets to groups starting at a given size, but still billed per person, you can do so by creating a special **Group ticket** at the per-person price and set the **Minimum amount per order** option of the ticket to the minimal group size.
|
||||
|
||||
For more complex use cases, you can also use add-on products that can be chosen multiple times.
|
||||
|
||||
This way, your ticket can be bought an arbitrary number of times – but no less than the given minimal amount per order.
|
||||
|
||||
Fixed group sizes
|
||||
@@ -344,3 +346,13 @@ In addition to your normal conference quota, you need to create an unlimited quo
|
||||
Then, head to the **Bundled products** tab of the "conference ticket" and add the "conference food" as a bundled product with a **designated price** of € 150.
|
||||
|
||||
Once a customer tries to buy the € 450 conference ticket, a sub-product will be added and the price will automatically be split into the two components, leading to a correct computation of taxes.
|
||||
|
||||
You can find more use cases in these specialized guides:
|
||||
|
||||
More use cases
|
||||
--------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
guides/timeslots
|
||||
|
||||
93
doc/user/events/ticket_secrets.rst
Normal file
@@ -0,0 +1,93 @@
|
||||
Ticket secret generators
|
||||
========================
|
||||
|
||||
pretix allows you to change the way in which ticket secrets (also known as "ticket codes", "barcodes", …)
|
||||
are generated. This affects the value of the QR code in any tickets issued by pretix, regardless of ticket
|
||||
format.
|
||||
|
||||
.. note:: This is intended for highly advanced use cases, usually when huge numbers of tickets (> 25k per event)
|
||||
are involved. **If you don't know whether you need this, you probably don't.**
|
||||
|
||||
Default: Random secrets
|
||||
-----------------------
|
||||
|
||||
By default, pretix generates a random code for every ticket, consisting of 32 lower case characters and
|
||||
numbers. The characters ``oO1il`` are avoided to reduce confusion when ticket codes are printed and need to
|
||||
be typed in manually.
|
||||
|
||||
Choosing random codes has a number of advantages:
|
||||
|
||||
* Ticket codes are short, which makes QR codes easier to scan. At the same time, it is absolutely impossible to
|
||||
guess or forge a valid ticket code.
|
||||
|
||||
* The code does not need to change if the ticket changes. For example, if an attendee is re-booked to a
|
||||
different product or date, they can keep their ticket and it is just mapped to the new product in the
|
||||
database.
|
||||
|
||||
This approach works really well for 99 % or events running with pretix.
|
||||
The big caveat is that the scanner needs to access a database of all ticket codes in order to know whether a ticket
|
||||
code is valid and what kind of ticket it represents.
|
||||
|
||||
When scanning online this is no problem at all, since the pretix server always has such a database. In case your local
|
||||
internet connection is interrupted or the pretix server goes down, though, there needs to be a database locally on the
|
||||
scanner.
|
||||
|
||||
Therefore, our pretixSCAN apps by default download the database of all valid tickets onto the device itself. This makes
|
||||
it possible to seamlessly switch into offline mode when the connection is lost and continue scanning with the maximum
|
||||
possible feature set.
|
||||
|
||||
There are a few situations in which this approach is not ideal:
|
||||
|
||||
* When running a single event with 25k or more valid tickets, downloading all ticket data onto the scanner may just
|
||||
take too much time and resources.
|
||||
|
||||
* When the risk of losing sensible data by losing one of the scanner devices is not acceptable.
|
||||
|
||||
* When offline mode needs to be used regularly and newly-purchased tickets need to be valid immediately after purchase,
|
||||
without being able to tolerate a few minutes of delay.
|
||||
|
||||
Signature schemes
|
||||
-----------------
|
||||
|
||||
The alternative approach that is included with pretix is to choose a signature-based ticket code generation scheme.
|
||||
These secrets include the most important information that is required for verifying their validity and use modern
|
||||
cryptography to make sure they cannot be forged.
|
||||
|
||||
Currently, pretix ships with one such scheme ("pretix signature scheme 1") which encodes the product, the product
|
||||
variation, and the date (if inside an event series) into the ticket code and signs the code with a `EdDSA`_ signature.
|
||||
This allows to verify whether a ticket is allowed to enter without any database or connection to the server, but has
|
||||
a few important drawbacks:
|
||||
|
||||
* Whenever the product, variation or date of a ticket changes or the ticket is canceled, the ticket code needs to be
|
||||
changed and the old code needs to be put on a revocation list. This revocation list again needs to be downloaded by
|
||||
all scanning devices (but is usually much smaller than the ticket database). The main downside is that the attendee
|
||||
needs to download their new ticket and can no longer use the old one.
|
||||
|
||||
* Scanning in offline mode is much more limited, since the scanner has no information about previous usages of the
|
||||
ticket, attendee names, seating information, etc.
|
||||
|
||||
Comparison of scanning behavior
|
||||
-------------------------------
|
||||
|
||||
=============================================== =================================== =================================== =================================== ================================= =====================================
|
||||
Scan mode Online Offline
|
||||
----------------------------------------------- ----------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Synchronization setting any Synchronize orders Don't synchronize orders
|
||||
----------------------------------------------- ----------------------------------- ----------------------------------------------------------------------- -----------------------------------------------------------------------
|
||||
Ticket secrets any Random Signed Random Signed
|
||||
=============================================== =================================== =================================== =================================== ================================= =====================================
|
||||
Scenario supported on platforms Android, Desktop, iOS Android, Desktop, iOS Android, Desktop Android, Desktop Android, Desktop
|
||||
Synchronization speed for large data sets slow slow fast fast
|
||||
Tickets can be scanned yes yes yes no yes
|
||||
Ticket is valid after sale immediately next sync (~5 minutes) immediately never immediately
|
||||
Same ticket can be scanned multiple times no yes, before data is synced yes, before data is synced n/a yes, always
|
||||
Custom check-in rules yes yes yes (limited directly after sale) n/a yes, but only based on product,
|
||||
variation and date, not on previous
|
||||
scans
|
||||
Name and seat visible on scanner yes yes yes (except directly after sale) n/a no
|
||||
Order-specific check-in attention flag yes yes yes (except directly after sale) n/a no
|
||||
Ticket search by order code or name yes yes yes (except directly after sale) no no
|
||||
Check-in statistics on scanner yes yes mostly accurate no no
|
||||
=============================================== =================================== =================================== =================================== ================================= =====================================
|
||||
|
||||
.. _EdDSA: https://en.wikipedia.org/wiki/EdDSA#Ed25519
|
||||
@@ -9,26 +9,33 @@ At "Settings" → "Tickets", you can configure the ticket download options that
|
||||
|
||||
The top of this page shows a short list of options relevant for all download formats:
|
||||
|
||||
Use feature
|
||||
Allow users to download tickets
|
||||
This can be used to completely enable or disable ticket downloads all over your ticket shop.
|
||||
|
||||
Generate tickets for add-on products
|
||||
By default, tickets can not be downloaded for order positions which are only an add-on to other order positions. If
|
||||
you enable this, this behavior will be changed and add-on products will get their own tickets as well. If disabled,
|
||||
you can still print a list of chosen add-ons e.g. on the PDF tickets.
|
||||
|
||||
Generate tickets for all products
|
||||
By default, tickets will only be generated for products that are marked as admission products. Enable this option to
|
||||
generate tickets for all products instead.
|
||||
|
||||
Generate tickets for pending orders
|
||||
By default, ticket download is only possible for paid orders. If you run an event where people usually pay only after
|
||||
the event, you can check this box to enable ticket download even before.
|
||||
|
||||
Download date
|
||||
If you set a date here, no ticket download will be offered before this date. If no date is set, tickets can be
|
||||
downloaded immediately after the payment for an order has been received.
|
||||
|
||||
Offer to download tickets separately for add-on products
|
||||
By default, tickets can not be downloaded for order positions which are only an add-on to other order positions. If
|
||||
you enable this, this behavior will be changed and add-on products will get their own tickets as well. If disabled,
|
||||
you can still print a list of chosen add-ons e.g. on the PDF tickets.
|
||||
|
||||
Generate tickets for non-admission products
|
||||
By default, tickets will only be generated for products that are marked as admission products. Enable this option to
|
||||
generate tickets for all products instead.
|
||||
|
||||
Offer to download tickets even before an order is paid
|
||||
By default, ticket download is only possible for paid orders. If you run an event where people usually pay only after
|
||||
the event, you can check this box to enable ticket download even before.
|
||||
|
||||
Below these settings, the detail settings for the various ticket file formats are offered. They differ from format to
|
||||
format and only share the common "Enable" setting that can be used to turn them on. By default, pretix ships with
|
||||
a PDF output plugin that you can configure through a visual design editor.
|
||||
a PDF output plugin that you can configure through a visual design editor.
|
||||
|
||||
**Advanced topics:**
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
ticket_secrets
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _widget:
|
||||
|
||||
Embeddable Widget
|
||||
=================
|
||||
|
||||
@@ -136,10 +138,15 @@ If you want to include all your public events, you can just reference your organ
|
||||
|
||||
<pretix-widget event="https://pretix.eu/demo/"></pretix-widget>
|
||||
|
||||
There is an optional ``style`` parameter that let's you choose between a calendar view and a list view. If you do not set it, the choice will be taken from your organizer settings::
|
||||
There is an optional ``style`` parameter that let's you choose between a monthly calendar view, a week view and a list
|
||||
view. If you do not set it, the choice will be taken from your organizer settings::
|
||||
|
||||
<pretix-widget event="https://pretix.eu/demo/series/" style="list"></pretix-widget>
|
||||
<pretix-widget event="https://pretix.eu/demo/series/" style="calendar"></pretix-widget>
|
||||
<pretix-widget event="https://pretix.eu/demo/series/" style="week"></pretix-widget>
|
||||
|
||||
If you have more than 100 events, the system might refuse to show a list view and always show a calendar for performance
|
||||
reasons instead.
|
||||
|
||||
You can see an example here:
|
||||
|
||||
|
||||
@@ -58,28 +58,6 @@ method without creating a new order. If payment deadlines were dependent on the
|
||||
forth could either allow someone to extend their deadline forever, or render someones order invalid by moving the date
|
||||
back in the past.
|
||||
|
||||
How can I revert a check-in?
|
||||
----------------------------
|
||||
|
||||
Neither our apps nor our web interface can currently undo the check-in of a tickets. We know that this is
|
||||
inconvenient for some of you, but we have a good reason for it:
|
||||
|
||||
Our Desktop and Android apps both support an asynchronous mode in which they can scan tickets while staying
|
||||
independent of their internet connection. When scanning with multiple devices, it can of course happen that two
|
||||
devices scan the same ticket without knowing of the other scan. As soon as one of the devices regains connectivity, it
|
||||
will upload its activity and the server marks the ticket as checked in -- regardless of the order in which the two
|
||||
scans were made and uploaded (which could be two different orders).
|
||||
|
||||
If we'd provide a "check out" feature, it would not only be used to fix an accidental scan, but scan at entry and
|
||||
exit to count the current number of people inside etc. In this case, the order of operations matters very much for them
|
||||
to make sense and provide useful results. This makes implementing an asynchronous mode much more complicated.
|
||||
|
||||
In this trade off, we chose offline-capabilities over the check out feature. We plan on solving this problem in the
|
||||
future, but we're not there yet.
|
||||
|
||||
If you're just *testing* the check-in capabilities and want to clean out everything for the real process, you can just
|
||||
delete and re-create the check-in list.
|
||||
|
||||
Why does pretix not support any 1D (linear) bar codes?
|
||||
------------------------------------------------------
|
||||
|
||||
|
||||
181
doc/user/glossary.rst
Normal file
@@ -0,0 +1,181 @@
|
||||
Glossary
|
||||
========
|
||||
|
||||
This page gives definitions of domain-specific terms that we use a lot inside pretix and that might be used slightly
|
||||
differently elsewhere, as well as their official translations to other languages. In some cases, things have a different
|
||||
name internally, which is noted with a |:wrench:| symbol. If you only use pretix, you'll never see these, but if you're
|
||||
going to develop around pretix, for example connect to pretix through our API, you need to know these as well.
|
||||
|
||||
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
.. list-table:: Glossary
|
||||
:widths: 15 30
|
||||
:header-rows: 1
|
||||
|
||||
* - Term
|
||||
- Definition
|
||||
* - | |:gb:| **Organizer**
|
||||
| |:de:| Veranstalter
|
||||
- An organizer represents the entity using pretix, usually the company or institution running one or multiple events.
|
||||
In terms of navigation in the system, organizers are the "middle layer" between the system itself and the specific
|
||||
events.
|
||||
Multiple organizers on the same pretix system are fully separated from each other with very few exceptions.
|
||||
* - | |:gb:| **Event**
|
||||
| |:de:| Veranstaltung
|
||||
- An event is the central entity in pretix that you and your customers interact with all the time. An event
|
||||
represents one **shop** in which things like tickets can be bought. Since the introduction of event series (see
|
||||
below), this might include multiple events in the real world.
|
||||
|
||||
Every purchase needs to be connected to an event, and most things are completely separate between different
|
||||
events, i.e. most actions and configurations in pretix are done per-event.
|
||||
* - | |:gb:| **Event series**
|
||||
| |:de:| Veranstaltungsreihe
|
||||
- An event series is one of two types of events. Unlike a non-series event, an event series groups together
|
||||
multiple real-world events into one pretix shop. Examples are time-slot-based booking for a museum, a band on
|
||||
tour, a theater group playing the same play multiple times, etc.
|
||||
* - | |:gb:| **Date**
|
||||
| |:de:| Termin
|
||||
| |:wrench:| Subevent
|
||||
- A date represents a single real-world event inside an event series. Dates can differ from each other in name,
|
||||
date, time, location, pricing, capacity, and seating plans, but otherwise share the same configuration.
|
||||
* - | |:gb:| **Product**
|
||||
| |:de:| Produkt
|
||||
| |:wrench:| Item
|
||||
- A product is anything that can be sold, such as a specific type of ticket or merchandise.
|
||||
* - | |:gb:| **Admission product**
|
||||
| |:de:| Zutrittsprodukt
|
||||
- A product is considered an **admission product** if its purchase represents a person being granted access to your
|
||||
event. This applies to most ticketing products, but not e.g. to merchandise.
|
||||
* - | |:gb:| **Variation**
|
||||
| |:de:| Variante
|
||||
| |:wrench:| Item variation
|
||||
- Some products come in multiple variations that can differ in description, price and capacity. Examples would
|
||||
include "Adult" and "Child" in case of a concert ticket, or "S", "M", "L", … in case of a t-shirt product.
|
||||
* - | |:gb:| **Category**
|
||||
| |:de:| Kategorie
|
||||
- Products can be grouped together in categories. This is mostly to organize them cleanly in the frontend if you
|
||||
have lots of them.
|
||||
* - | |:gb:| **Quota**
|
||||
| |:de:| Kontingent
|
||||
- A quota is a capacity pool that defines how many times a product can be sold. A quota can be connected to multiple
|
||||
products, in which case all of them are counted together. This is useful e.g. if you have full-price and reduced
|
||||
tickets and only want to sell a certain number of tickets in total. The same way, multiple quotas can be connected
|
||||
to the same product, in which case the ticket will be available as long as all of them have capacity left.
|
||||
* - | |:gb:| **Add-on product**
|
||||
| |:de:| Zusatzprodukt
|
||||
- An add-on product is a product that is purchased as an upgrade or optional addition to a different product.
|
||||
Examples would be include a conference ticket that optionally allows to buy a public transport ticket for the
|
||||
same day, or a family ticket for 4 persons that allows you to add additional persons at a small cost, or a
|
||||
"two workshops" package that allows you to select two of a larger number of workshops at a discounted price.
|
||||
In all cases, there is a "main product" (the conference ticket, the family ticket) and a number of "add-on products"
|
||||
that can be chosen from.
|
||||
* - | |:gb:| **Bundled product**
|
||||
| |:de:| Enthaltenes Produkt
|
||||
- A bundled product is a product that is automatically put into the cart when another product is purchased. It's
|
||||
similar to an add-on product, except that the customer has no choice between whether it is added or which of a
|
||||
set of product is added.
|
||||
* - | |:gb:| **Question**
|
||||
| |:de:| Frage
|
||||
- A question is a custom field that customers need to fill in when purchasing a specific product.
|
||||
* - | |:gb:| **Voucher**
|
||||
| |:de:| Gutschein
|
||||
- A voucher is a code that can be used for multiple purposes: To grant a discount to specific customers, to only
|
||||
show certain products to certain customers, or to keep a seat open for someone specific even though you are
|
||||
sold out. If a voucher is used to apply a discount, the price of the purchased product is reduced by the
|
||||
discounted amount. Vouchers are connected to a specific event.
|
||||
* - | |:gb:| **Gift card**
|
||||
| |:de:| Geschenkgutschein
|
||||
- A :ref:`gift card <giftcards>` is a coupon representing an exact amount of money that can be used for purchases
|
||||
of any kind. Gift cards can be sold, created manually, or used as a method to refund your customer without paying
|
||||
them back directly.
|
||||
Unlike a voucher, it does not reduce the price of the purchased products when redeemed, but instead works as a
|
||||
payment method to lower the amount that needs to be paid through other methods. Gift cards are specific to an
|
||||
organizer by default but can even by shared between organizers.
|
||||
* - | |:gb:| **Cart**
|
||||
| |:de:| Warenkorb
|
||||
- A cart is a collection of products that are reserved by a customer who is currently completing the checkout
|
||||
process, but has not yet finished it.
|
||||
* - | |:gb:| **Order**
|
||||
| |:de:| Bestellung
|
||||
- An order is a purchase by a client, containing multiple different products. An order goes through various
|
||||
states and can change during its lifetime.
|
||||
* - | |:gb:| **Order code**
|
||||
| |:de:| Bestellnummer
|
||||
- An order code is the unique identifier of an order, usually consisting of 5 numbers and letters.
|
||||
* - | |:gb:| **Order position**
|
||||
| |:de:| Bestellposition
|
||||
- An order position is a single line inside an order, representing the purchase of one specific product. If the
|
||||
product is an admission product, this represents an attendee.
|
||||
* - | |:gb:| **Attendees**
|
||||
| |:de:| Teilnehmende
|
||||
- An attendee is the person designated to use a specific order position to access the event.
|
||||
* - | |:gb:| **Fee**
|
||||
| |:de:| Gebühr
|
||||
- A fee is an additional type of line inside an order that represents a cost that needs to be paid by the customer,
|
||||
but is not related to a specific product. A typical example is a shipping fee.
|
||||
* - | |:gb:| **Invoice** and **Cancellation**
|
||||
| |:de:| Rechnung und Rechnungskorrektur
|
||||
- An invoice refers to a legal document created to document a purchase for tax purposes. Invoices have individual
|
||||
numbers and no longer change after they have been issued. Every invoice is connected to an order, but an order
|
||||
can have multiple invoices: If an order changes, a cancellation document is created for the old invoice and a
|
||||
new invoice is created.
|
||||
* - | |:gb:| **Check-in**
|
||||
| |:de:| Check-in
|
||||
- A check-in is the event of someone being successfully scanned at an entry or exit of the event.
|
||||
* - | |:gb:| **Check-in list**
|
||||
| |:de:| Check-in-Liste
|
||||
- A check-in list is used to configure who can be scanned at a specific entry or exit of the event. Check-in lists
|
||||
are isolated from each other, so by default each ticket is valid once on every check-in list individually. They
|
||||
are therefore often used to represent *parts* of an event, either time-wise (e.g. conference days) or space-wise
|
||||
(e.g. rooms).
|
||||
* - | |:gb:| **Plugin**
|
||||
| |:de:| Erweiterung
|
||||
- A plugin is an optional software module that contains additional functionality and can be turned on and off per
|
||||
event. If you host pretix on your own server, most plugins need to be installed separately.
|
||||
* - | |:gb:| **Tax rule**
|
||||
| |:de:| Steuer-Regel
|
||||
- A tax rule defines how sales taxes are calculated for a product, possibly depending on type and country of the
|
||||
customer.
|
||||
* - | |:gb:| **Ticket**
|
||||
| |:de:| Ticket
|
||||
- A ticket usually refers to the actual file presented to the customer to be used at check-in, i.e. the PDF or
|
||||
Passbook file carrying the QR code. In some cases, "ticket" may also be used to refer to an order position,
|
||||
especially in case of admission products.
|
||||
* - | |:gb:| **Ticket secret**
|
||||
| |:de:| Ticket-Code
|
||||
- The ticket secret (sometimes "ticket code") is what's contained in the QR code on the ticket.
|
||||
* - | |:gb:| **Badge**
|
||||
| |:de:| Badge
|
||||
- A badge refers to the file used as a name tag for an attendee of your event.
|
||||
* - | |:gb:| **User**
|
||||
| |:de:| Benutzer
|
||||
- A user is anyone who can sign into the backend interface of pretix.
|
||||
* - | |:gb:| **Team**
|
||||
| |:de:| Team
|
||||
- A :ref:`team <user-teams>` is a collection of users who are granted some level of access to a set of events.
|
||||
* - | |:gb:| **Device**
|
||||
| |:de:| Gerät
|
||||
- A device is something that talks to pretix but does not run on a server. Usually a device refers to an
|
||||
installation of pretixSCAN, pretixPOS or some compatible third-party app on one of your computing devices.
|
||||
* - | |:gb:| **Gate**
|
||||
| |:de:| Station
|
||||
- A gate is a location at your event where people are being scanned, e.g. an entry or exit door. You can configure
|
||||
gates in pretix to group multiple devices together that are used in the same location, mostly for statistical
|
||||
purposes.
|
||||
* - | |:gb:| **Widget**
|
||||
| |:de:| Widget
|
||||
- The :ref:`widget` is a JavaScript component that can be used to embed the shop of an event or a list of events
|
||||
into a third-party web page.
|
||||
* - | |:gb:| **Sales channel**
|
||||
| |:de:| Verkaufskanal
|
||||
- A sales channel refers to the type in which a purchase arrived in the system, e.g. through pretix' web shop itself,
|
||||
or through other channels like box office or reseller sales.
|
||||
* - | |:gb:| **Box office**
|
||||
| |:de:| Abendkasse
|
||||
- Box office purchases refer to all purchases made in-person from the organizer directly, through a point of sale
|
||||
system like pretixPOS.
|
||||
* - | |:gb:| **Reseller**
|
||||
| |:de:| Vorverkaufsstelle
|
||||
- Resellers are third-party entities offering in-person sales of events to customers.
|
||||
@@ -15,3 +15,4 @@ wanting to use pretix to sell tickets.
|
||||
events/giftcards
|
||||
faq
|
||||
markdown
|
||||
glossary
|
||||
|
||||
@@ -14,30 +14,23 @@ and with pretix, you can do this. On this page, you find out the necessary steps
|
||||
With the pretix.eu hosted service
|
||||
---------------------------------
|
||||
|
||||
Step 1: DNS Configuration
|
||||
#########################
|
||||
Go to "Organizers" in the backend and select your organizer account. Then, go to "Settings" and "Custom Domain".
|
||||
|
||||
This page will show you instructions on how to set up your own domain. Basically, it works like this:
|
||||
|
||||
Go to the website of the provider you registered your domain name with. Look for the "DNS" settings page in their
|
||||
interface. Unfortunately, we can't tell you exactly how that is named and how it looks, since it is different for every
|
||||
domain provider.
|
||||
|
||||
Use this interface to add a new subdomain record, e.g. ``tickets`` of the type ``CNAME`` (might also be called "alias").
|
||||
The value of the record should be ``www.pretix.eu``.
|
||||
|
||||
Step 2: Wait for the DNS entry to propagate
|
||||
###########################################
|
||||
The value of the record should be the one shown on the "Custom Domain" page in pretix' backend.
|
||||
|
||||
Submit your changes and wait a bit, it can regularly take up to three hours for DNS changes to propagate to the caches
|
||||
of all DNS servers. You can try checking by accessing your new subdomain, ``http://tickets.awesomepartycorp.com``.
|
||||
If DNS was changed successfully, you should see a SSL certificate error. If you ignore the error and access the page
|
||||
anyways, you should get a pretix-themed error page with the headline "Unknown domain".
|
||||
|
||||
Step 3: Tell us
|
||||
###############
|
||||
|
||||
Write an email to support@pretix.eu, naming your new domain and your organizer account. We will then generate a SSL
|
||||
certificate for you (for free!) and configure the domain.
|
||||
|
||||
Now, tell us about your domain on the "Custom Domain" page to get started.
|
||||
|
||||
With a custom pretix installation
|
||||
---------------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
General settings
|
||||
================
|
||||
|
||||
At "Settings" → "Payment", you can configure every aspect related to the payments you want to accept. The upper part
|
||||
of the page shows a number of general settings that affect all payment methods:
|
||||
At "Settings" → "Payment", you can configure every aspect related to the payments you want to accept. The "Deadline"
|
||||
and "Advanced" tabs of the page show a number of general settings that affect all payment methods:
|
||||
|
||||
.. thumbnail:: ../../screens/event/settings_payment.png
|
||||
:align: center
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
include LICENSE
|
||||
include README.rst
|
||||
global-include *.proto
|
||||
recursive-include pretix/static *
|
||||
recursive-include pretix/static.dist *
|
||||
recursive-include pretix/locale *
|
||||
recursive-include pretix/helpers/locale *
|
||||
recursive-include pretix/base/templates *
|
||||
recursive-include pretix/control/templates *
|
||||
recursive-include pretix/presale/templates *
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "3.7.0"
|
||||
__version__ = "3.12.1"
|
||||
|
||||
@@ -3,6 +3,9 @@ from django_scopes import scopes_disabled
|
||||
from rest_framework import exceptions
|
||||
from rest_framework.authentication import TokenAuthentication
|
||||
|
||||
from pretix.api.auth.devicesecurity import (
|
||||
DEVICE_SECURITY_PROFILES, FullAccessSecurityProfile,
|
||||
)
|
||||
from pretix.base.models import Device
|
||||
|
||||
|
||||
@@ -25,3 +28,11 @@ class DeviceTokenAuthentication(TokenAuthentication):
|
||||
raise exceptions.AuthenticationFailed('Device access has been revoked.')
|
||||
|
||||
return AnonymousUser(), device
|
||||
|
||||
def authenticate(self, request):
|
||||
r = super().authenticate(request)
|
||||
if r and isinstance(r[1], Device):
|
||||
profile = DEVICE_SECURITY_PROFILES.get(r[1].security_profile, FullAccessSecurityProfile)
|
||||
if not profile.is_allowed(request):
|
||||
raise exceptions.PermissionDenied('Request denied by device security profile.')
|
||||
return r
|
||||
|
||||
121
src/pretix/api/auth/devicesecurity.py
Normal file
@@ -0,0 +1,121 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class FullAccessSecurityProfile:
|
||||
identifier = 'full'
|
||||
verbose_name = _('Full device access (reading and changing orders and gift cards, reading of products and settings)')
|
||||
|
||||
def is_allowed(self, request):
|
||||
return True
|
||||
|
||||
|
||||
class AllowListSecurityProfile:
|
||||
allowlist = tuple()
|
||||
|
||||
def is_allowed(self, request):
|
||||
key = (request.method, f"{request.resolver_match.namespace}:{request.resolver_match.url_name}")
|
||||
return key in self.allowlist
|
||||
|
||||
|
||||
class PretixScanSecurityProfile(AllowListSecurityProfile):
|
||||
identifier = 'pretixscan'
|
||||
verbose_name = _('pretixSCAN')
|
||||
allowlist = (
|
||||
('GET', 'api-v1:version'),
|
||||
('GET', 'api-v1:device.eventselection'),
|
||||
('POST', 'api-v1:device.update'),
|
||||
('POST', 'api-v1:device.revoke'),
|
||||
('POST', 'api-v1:device.roll'),
|
||||
('GET', 'api-v1:event-list'),
|
||||
('GET', 'api-v1:event-detail'),
|
||||
('GET', 'api-v1:subevent-list'),
|
||||
('GET', 'api-v1:subevent-detail'),
|
||||
('GET', 'api-v1:itemcategory-list'),
|
||||
('GET', 'api-v1:item-list'),
|
||||
('GET', 'api-v1:question-list'),
|
||||
('GET', 'api-v1:badgelayout-list'),
|
||||
('GET', 'api-v1:badgeitem-list'),
|
||||
('GET', 'api-v1:checkinlist-list'),
|
||||
('GET', 'api-v1:checkinlist-status'),
|
||||
('GET', 'api-v1:checkinlistpos-list'),
|
||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
||||
('GET', 'api-v1:revokedsecrets-list'),
|
||||
('GET', 'api-v1:order-list'),
|
||||
('GET', 'api-v1:event.settings'),
|
||||
)
|
||||
|
||||
|
||||
class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
|
||||
identifier = 'pretixscan_online_kiosk'
|
||||
verbose_name = _('pretixSCAN (kiosk mode, online only)')
|
||||
allowlist = (
|
||||
('GET', 'api-v1:version'),
|
||||
('GET', 'api-v1:device.eventselection'),
|
||||
('POST', 'api-v1:device.update'),
|
||||
('POST', 'api-v1:device.revoke'),
|
||||
('POST', 'api-v1:device.roll'),
|
||||
('GET', 'api-v1:event-list'),
|
||||
('GET', 'api-v1:event-detail'),
|
||||
('GET', 'api-v1:subevent-list'),
|
||||
('GET', 'api-v1:subevent-detail'),
|
||||
('GET', 'api-v1:itemcategory-list'),
|
||||
('GET', 'api-v1:item-list'),
|
||||
('GET', 'api-v1:question-list'),
|
||||
('GET', 'api-v1:badgelayout-list'),
|
||||
('GET', 'api-v1:badgeitem-list'),
|
||||
('GET', 'api-v1:checkinlist-list'),
|
||||
('GET', 'api-v1:checkinlist-status'),
|
||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
||||
('GET', 'api-v1:revokedsecrets-list'),
|
||||
('GET', 'api-v1:event.settings'),
|
||||
)
|
||||
|
||||
|
||||
class PretixPosSecurityProfile(AllowListSecurityProfile):
|
||||
identifier = 'pretixpos'
|
||||
verbose_name = _('pretixPOS')
|
||||
allowlist = (
|
||||
('GET', 'api-v1:version'),
|
||||
('GET', 'api-v1:device.eventselection'),
|
||||
('POST', 'api-v1:device.update'),
|
||||
('POST', 'api-v1:device.revoke'),
|
||||
('POST', 'api-v1:device.roll'),
|
||||
('GET', 'api-v1:event-list'),
|
||||
('GET', 'api-v1:event-detail'),
|
||||
('GET', 'api-v1:subevent-list'),
|
||||
('GET', 'api-v1:subevent-detail'),
|
||||
('GET', 'api-v1:itemcategory-list'),
|
||||
('GET', 'api-v1:item-list'),
|
||||
('GET', 'api-v1:question-list'),
|
||||
('GET', 'api-v1:quota-list'),
|
||||
('GET', 'api-v1:taxrule-list'),
|
||||
('GET', 'api-v1:ticketlayout-list'),
|
||||
('GET', 'api-v1:ticketlayoutitem-list'),
|
||||
('GET', 'api-v1:order-list'),
|
||||
('POST', 'api-v1:order-list'),
|
||||
('GET', 'api-v1:order-detail'),
|
||||
('DELETE', 'api-v1:orderposition-detail'),
|
||||
('POST', 'api-v1:order-mark_canceled'),
|
||||
('POST', 'api-v1:orderrefund-list'),
|
||||
('POST', 'api-v1:orderrefund-done'),
|
||||
('POST', 'api-v1:cartposition-list'),
|
||||
('DELETE', 'api-v1:cartposition-detail'),
|
||||
('GET', 'api-v1:giftcard-list'),
|
||||
('POST', 'api-v1:giftcard-transact'),
|
||||
('POST', 'plugins:pretix_posbackend:posreceipt-list'),
|
||||
('POST', 'plugins:pretix_posbackend:posclosing-list'),
|
||||
('POST', 'plugins:pretix_posbackend:posdebugdump-list'),
|
||||
('POST', 'plugins:pretix_posbackend:stripeterminal.token'),
|
||||
('GET', 'api-v1:revokedsecrets-list'),
|
||||
('GET', 'api-v1:event.settings'),
|
||||
)
|
||||
|
||||
|
||||
DEVICE_SECURITY_PROFILES = {
|
||||
k.identifier: k() for k in (
|
||||
FullAccessSecurityProfile,
|
||||
PretixScanSecurityProfile,
|
||||
PretixScanNoSyncSecurityProfile,
|
||||
PretixPosSecurityProfile,
|
||||
)
|
||||
}
|
||||
@@ -84,3 +84,15 @@ class EventCRUDPermission(EventPermission):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class ProfilePermission(BasePermission):
|
||||
|
||||
def has_permission(self, request, view):
|
||||
if not request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
if isinstance(request.auth, OAuthAccessToken):
|
||||
if not (request.auth.allow_scopes(['read']) or request.auth.allow_scopes(['profile'])) and request.method in SAFE_METHODS:
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -3,7 +3,7 @@ from datetime import timedelta
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from oauth2_provider.generators import (
|
||||
generate_client_id, generate_client_secret,
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ from oauth2_provider.settings import oauth2_settings
|
||||
class Validator(OAuth2Validator):
|
||||
|
||||
def save_authorization_code(self, client_id, code, request, *args, **kwargs):
|
||||
if not getattr(request, 'organizers', None):
|
||||
if not getattr(request, 'organizers', None) and request.scopes != ['profile']:
|
||||
raise FatalClientError('No organizers selected.')
|
||||
|
||||
expires = timezone.now() + timedelta(
|
||||
@@ -18,7 +18,8 @@ class Validator(OAuth2Validator):
|
||||
expires=expires, redirect_uri=request.redirect_uri,
|
||||
scope=" ".join(request.scopes))
|
||||
g.save()
|
||||
g.organizers.add(*request.organizers.all())
|
||||
if request.scopes != ['profile']:
|
||||
g.organizers.add(*request.organizers.all())
|
||||
|
||||
def validate_code(self, client_id, code, client, request, *args, **kwargs):
|
||||
try:
|
||||
@@ -34,12 +35,14 @@ class Validator(OAuth2Validator):
|
||||
return False
|
||||
|
||||
def _create_access_token(self, expires, request, token, source_refresh_token=None):
|
||||
if not getattr(request, 'organizers', None) and not getattr(source_refresh_token, 'access_token'):
|
||||
if not getattr(request, 'organizers', None) and not getattr(source_refresh_token, 'access_token', None) and token["scope"] != 'profile':
|
||||
raise FatalClientError('No organizers selected.')
|
||||
if hasattr(request, 'organizers'):
|
||||
orgs = list(request.organizers.all())
|
||||
else:
|
||||
orgs = list(source_refresh_token.access_token.organizers.all())
|
||||
if token['scope'] != 'profile':
|
||||
if hasattr(request, 'organizers'):
|
||||
orgs = list(request.organizers.all())
|
||||
else:
|
||||
orgs = list(source_refresh_token.access_token.organizers.all())
|
||||
access_token = super()._create_access_token(expires, request, token, source_refresh_token=None)
|
||||
access_token.organizers.add(*orgs)
|
||||
if token['scope'] != 'profile':
|
||||
access_token.organizers.add(*orgs)
|
||||
return access_token
|
||||
|
||||
@@ -2,7 +2,7 @@ from datetime import timedelta
|
||||
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.utils.translation import gettext_lazy
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
@@ -56,7 +56,7 @@ class CartPositionCreateSerializer(I18nAwareModelSerializer):
|
||||
else validated_data.get('item').quotas.filter(subevent=validated_data.get('subevent')))
|
||||
if len(new_quotas) == 0:
|
||||
raise ValidationError(
|
||||
ugettext_lazy('The product "{}" is not assigned to a quota.').format(
|
||||
gettext_lazy('The product "{}" is not assigned to a quota.').format(
|
||||
str(validated_data.get('item'))
|
||||
)
|
||||
)
|
||||
@@ -64,8 +64,8 @@ class CartPositionCreateSerializer(I18nAwareModelSerializer):
|
||||
avail = quota.availability()
|
||||
if avail[0] != Quota.AVAILABILITY_OK or (avail[1] is not None and avail[1] < 1):
|
||||
raise ValidationError(
|
||||
ugettext_lazy('There is not enough quota available on quota "{}" to perform '
|
||||
'the operation.').format(
|
||||
gettext_lazy('There is not enough quota available on quota "{}" to perform '
|
||||
'the operation.').format(
|
||||
quota.name
|
||||
)
|
||||
)
|
||||
@@ -88,7 +88,7 @@ class CartPositionCreateSerializer(I18nAwareModelSerializer):
|
||||
else:
|
||||
validated_data['seat'] = seat
|
||||
if not seat.is_available(sales_channel=validated_data.get('sales_channel', 'web')):
|
||||
raise ValidationError(ugettext_lazy('The selected seat "{seat}" is not available.').format(seat=seat.name))
|
||||
raise ValidationError(gettext_lazy('The selected seat "{seat}" is not available.').format(seat=seat.name))
|
||||
elif seated:
|
||||
raise ValidationError('The specified product requires to choose a seat.')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
@@ -14,7 +14,19 @@ class CheckinListSerializer(I18nAwareModelSerializer):
|
||||
class Meta:
|
||||
model = CheckinList
|
||||
fields = ('id', 'name', 'all_products', 'limit_products', 'subevent', 'checkin_count', 'position_count',
|
||||
'include_pending', 'auto_checkin_sales_channels')
|
||||
'include_pending', 'auto_checkin_sales_channels', 'allow_multiple_entries', 'allow_entry_after_exit',
|
||||
'rules', 'exit_all_at')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
for exclude_field in self.context['request'].query_params.getlist('exclude'):
|
||||
p = exclude_field.split('.')
|
||||
if p[0] in self.fields:
|
||||
if len(p) == 1:
|
||||
del self.fields[p[0]]
|
||||
elif len(p) == 2:
|
||||
self.fields[p[0]].child.fields.pop(p[1])
|
||||
|
||||
def validate(self, data):
|
||||
data = super().validate(data)
|
||||
@@ -28,9 +40,7 @@ class CheckinListSerializer(I18nAwareModelSerializer):
|
||||
raise ValidationError(_('One or more items do not belong to this event.'))
|
||||
|
||||
if event.has_subevents:
|
||||
if not full_data.get('subevent'):
|
||||
raise ValidationError(_('Subevent cannot be null for event series.'))
|
||||
if event != full_data.get('subevent').event:
|
||||
if full_data.get('subevent') and event != full_data.get('subevent').event:
|
||||
raise ValidationError(_('The subevent does not belong to this event.'))
|
||||
else:
|
||||
if full_data.get('subevent'):
|
||||
|
||||