Compare commits
1021 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a362f4ad3b | ||
|
|
6f30c347c0 | ||
|
|
3596fa9c5a | ||
|
|
e3c7cd7c6d | ||
|
|
194042dca5 | ||
|
|
3be6e83f33 | ||
|
|
4262bce2b5 | ||
|
|
73ab962e16 | ||
|
|
13a86fc6f3 | ||
|
|
9d6f11718a | ||
|
|
c9d3428996 | ||
|
|
d4ef16b31a | ||
|
|
6a35e7d3cd | ||
|
|
463443d606 | ||
|
|
6f0da5c2ca | ||
|
|
c1344422a5 | ||
|
|
c2bd3dde44 | ||
|
|
9e51736232 | ||
|
|
5b27ce1265 | ||
|
|
0757542f4f | ||
|
|
12be98c888 | ||
|
|
51e6b02aa9 | ||
|
|
acc4a167b1 | ||
|
|
dd9429bbfa | ||
|
|
768bb8c106 | ||
|
|
cbdafac999 | ||
|
|
96f694cf61 | ||
|
|
5576829ebf | ||
|
|
b0d67e92ac | ||
|
|
63e28723d2 | ||
|
|
cc0656f169 | ||
|
|
849c8e719a | ||
|
|
a3ec2a4061 | ||
|
|
00a7187a7a | ||
|
|
701c4f768e | ||
|
|
cf751d38d2 | ||
|
|
888402a4bf | ||
|
|
1134f610fd | ||
|
|
8ae4304c7d | ||
|
|
357092ec44 | ||
|
|
70a5c76d79 | ||
|
|
7a4db8ea23 | ||
|
|
223b160c0c | ||
|
|
30c1771d29 | ||
|
|
b3b7b9bbab | ||
|
|
be040cd6ea | ||
|
|
c6665ec2e6 | ||
|
|
fd16ef1e4d | ||
|
|
39557fc452 | ||
|
|
408397a639 | ||
|
|
d4a2500204 | ||
|
|
e74d9e56cf | ||
|
|
f3767ab4ac | ||
|
|
5d13f5f885 | ||
|
|
451d3fce05 | ||
|
|
ccb61e0f56 | ||
|
|
b6273adc57 | ||
|
|
0bf7bba6ba | ||
|
|
7090e0bae2 | ||
|
|
c75cb0b8e3 | ||
|
|
3dbf22f670 | ||
|
|
f26cbdc257 | ||
|
|
6b4adccee5 | ||
|
|
c2a8286022 | ||
|
|
4145887a9b | ||
|
|
9f4b834abc | ||
|
|
8fcc314f09 | ||
|
|
94a7d02ab1 | ||
|
|
ad2943263c | ||
|
|
5210ac3a78 | ||
|
|
0e9600a7bf | ||
|
|
eccba09452 | ||
|
|
c8a830ecde | ||
|
|
aed64d16f6 | ||
|
|
d16f6167f6 | ||
|
|
77d59248e5 | ||
|
|
a0e05f8af6 | ||
|
|
9b8a47c8b8 | ||
|
|
b3d692276c | ||
|
|
55543e12f6 | ||
|
|
1e16185c02 | ||
|
|
cd900e24bd | ||
|
|
0dbedc07ce | ||
|
|
f71877b7fc | ||
|
|
f69e270e4d | ||
|
|
533939cae4 | ||
|
|
91ec5fd78c | ||
|
|
0056fb447b | ||
|
|
20c4d12e98 | ||
|
|
e13c567e84 | ||
|
|
9fef97a7c6 | ||
|
|
e68a995376 | ||
|
|
6abdb40ef5 | ||
|
|
43cc06b0a1 | ||
|
|
d17476cd75 | ||
|
|
5c3bfd2a71 | ||
|
|
033b8d70e7 | ||
|
|
bd22c2afc9 | ||
|
|
b355733f53 | ||
|
|
e1f924c4ce | ||
|
|
8038f4e173 | ||
|
|
5c55219d45 | ||
|
|
bfd37af467 | ||
|
|
b2509e120c | ||
|
|
e2339acd09 | ||
|
|
c15b4fa03c | ||
|
|
c4aa2e0484 | ||
|
|
361eeb7159 | ||
|
|
0109e1806f | ||
|
|
30aadac099 | ||
|
|
0458f1b2dc | ||
|
|
e006ca3feb | ||
|
|
1f31ee2ea1 | ||
|
|
2d37b0df77 | ||
|
|
4133e5ac4d | ||
|
|
0fd3d0fe71 | ||
|
|
d0685e99ad | ||
|
|
c6fd5bc864 | ||
|
|
9fa935099f | ||
|
|
83b5a325e3 | ||
|
|
97e12c5003 | ||
|
|
e6db8340f2 | ||
|
|
3cf9caa5d3 | ||
|
|
2ffd68ace7 | ||
|
|
0231be63b4 | ||
|
|
fae8bc254e | ||
|
|
1d5c700fa2 | ||
|
|
e61775d5c1 | ||
|
|
e767c6a68d | ||
|
|
832235411f | ||
|
|
1f0f7b752f | ||
|
|
3117eceb72 | ||
|
|
c1b39782fd | ||
|
|
860cfc3227 | ||
|
|
45859a07dd | ||
|
|
04fb8efc0d | ||
|
|
fdb8a3720b | ||
|
|
5638d68894 | ||
|
|
f64042280a | ||
|
|
50060cdc8d | ||
|
|
4499f58e3d | ||
|
|
918e4a5a89 | ||
|
|
15a86fd796 | ||
|
|
4126d20f1c | ||
|
|
ea3edf83f8 | ||
|
|
9a42819b56 | ||
|
|
3e4ba28700 | ||
|
|
9014ffcc28 | ||
|
|
48f4bcf88c | ||
|
|
b7dfb3697e | ||
|
|
475a5be351 | ||
|
|
8254d8f5cc | ||
|
|
6f0f4755ef | ||
|
|
910a35dedc | ||
|
|
e694bd8c21 | ||
|
|
29cf384c28 | ||
|
|
492288f437 | ||
|
|
34e4f7e0fc | ||
|
|
f6f3bbcce6 | ||
|
|
16054893ed | ||
|
|
f6038d2c39 | ||
|
|
8d13b51271 | ||
|
|
83e1f365c2 | ||
|
|
146e1aeb67 | ||
|
|
f9b2920984 | ||
|
|
2c01b214a7 | ||
|
|
fdab45e5ce | ||
|
|
9d2cf18543 | ||
|
|
2206ab1d35 | ||
|
|
ecd2c80dce | ||
|
|
3387df491a | ||
|
|
b6974e0c77 | ||
|
|
31751cbd79 | ||
|
|
993da5a392 | ||
|
|
72455209bb | ||
|
|
803aa0b70d | ||
|
|
954d86337c | ||
|
|
38a58d62f3 | ||
|
|
e67b39a57b | ||
|
|
148b67ac3f | ||
|
|
d261cb3b6b | ||
|
|
169a6c51b4 | ||
|
|
245ad644ff | ||
|
|
4fdce0d126 | ||
|
|
a542bc7a5a | ||
|
|
3164919923 | ||
|
|
8085311eb6 | ||
|
|
3887a65961 | ||
|
|
b229c6156a | ||
|
|
c45298544e | ||
|
|
7bb9d3fc3d | ||
|
|
8607df5a9c | ||
|
|
c4150473fc | ||
|
|
172b2f74e0 | ||
|
|
9586f71dc2 | ||
|
|
25692d180f | ||
|
|
ae047037dc | ||
|
|
265106034b | ||
|
|
dd0a4df914 | ||
|
|
b0ae40c264 | ||
|
|
ad95815043 | ||
|
|
f68522ec0d | ||
|
|
b831e57351 | ||
|
|
51166786ee | ||
|
|
909e7906ff | ||
|
|
e185d5f0e7 | ||
|
|
ce8edf621b | ||
|
|
e58b512876 | ||
|
|
d1754f6d1b | ||
|
|
ff2f1b7424 | ||
|
|
fb1838a2f0 | ||
|
|
d7b05063a4 | ||
|
|
f64a42d61a | ||
|
|
c1994e89a5 | ||
|
|
f37de1ad2f | ||
|
|
e1ff6f8590 | ||
|
|
a5dd22eb4d | ||
|
|
19cde63505 | ||
|
|
754d4f4f62 | ||
|
|
e433230573 | ||
|
|
f8927396d3 | ||
|
|
60be99fbb2 | ||
|
|
0c508c5ba4 | ||
|
|
ea6067ab3f | ||
|
|
9d0fa84277 | ||
|
|
a6835d3b14 | ||
|
|
9ff565f772 | ||
|
|
5d41b20bae | ||
|
|
03de0d5d2e | ||
|
|
2937acdc66 | ||
|
|
6fd09e99e2 | ||
|
|
290e14689d | ||
|
|
89c937089b | ||
|
|
0e02febe76 | ||
|
|
771f822e5f | ||
|
|
e8936551c0 | ||
|
|
ea0f6dfc54 | ||
|
|
abeddd360e | ||
|
|
c209d195bf | ||
|
|
35c46d320c | ||
|
|
30621568ab | ||
|
|
403c4f4499 | ||
|
|
884bba0088 | ||
|
|
2b52edd5b7 | ||
|
|
a4aed96784 | ||
|
|
4bdfd56264 | ||
|
|
31f0b07325 | ||
|
|
3f08f3a7f4 | ||
|
|
93263e7567 | ||
|
|
69cf62d2ca | ||
|
|
bb353e5fde | ||
|
|
2dceff1218 | ||
|
|
5ea8a8ef82 | ||
|
|
03a7a3303c | ||
|
|
2beb0b20ca | ||
|
|
24eea02e0d | ||
|
|
15ab9c72d3 | ||
|
|
c957d77fe0 | ||
|
|
7697018ca4 | ||
|
|
3980a7b2a7 | ||
|
|
035bb56386 | ||
|
|
837b03fff3 | ||
|
|
d3dec72831 | ||
|
|
3d78f68d94 | ||
|
|
faa43d4df8 | ||
|
|
78917afa1a | ||
|
|
4b53d39e3e | ||
|
|
02db07cd25 | ||
|
|
19fb6c8c34 | ||
|
|
0c25b2df92 | ||
|
|
6a543e4557 | ||
|
|
846527546a | ||
|
|
c8cdb2b311 | ||
|
|
96ff3d532d | ||
|
|
8ebba9de86 | ||
|
|
c4e71011ee | ||
|
|
e71ad4bfba | ||
|
|
05a5a69128 | ||
|
|
bb83cd2f39 | ||
|
|
df26171ff1 | ||
|
|
da937dc4e3 | ||
|
|
bb9508ad96 | ||
|
|
41fed7d6a2 | ||
|
|
f441e9984d | ||
|
|
05c6155f37 | ||
|
|
3c096325bd | ||
|
|
d06a352df5 | ||
|
|
ba7b1bb89e | ||
|
|
3dcfa57b70 | ||
|
|
cc13ca1c3f | ||
|
|
aac67ebf83 | ||
|
|
b51e1cfc6f | ||
|
|
f0508cdcc3 | ||
|
|
9ed2dc7b46 | ||
|
|
0e568a3fca | ||
|
|
7f3606ee81 | ||
|
|
b22d43860a | ||
|
|
0f9b339f01 | ||
|
|
cd1e9c1740 | ||
|
|
aec1ce53fc | ||
|
|
aae129be6a | ||
|
|
b906fe0fc3 | ||
|
|
f0f1537e9c | ||
|
|
7b7e77d497 | ||
|
|
9ac705cd88 | ||
|
|
01d9574ddf | ||
|
|
8121167d5e | ||
|
|
dde4e12ce1 | ||
|
|
6cd32400ae | ||
|
|
8fa71ccad4 | ||
|
|
0f47bff5cd | ||
|
|
f459f1f12d | ||
|
|
65167cc290 | ||
|
|
bc7300c393 | ||
|
|
d8450202fe | ||
|
|
41d2bcc34f | ||
|
|
0e1589013a | ||
|
|
39f81617e1 | ||
|
|
b394ef6de1 | ||
|
|
177906e2ac | ||
|
|
59f6b20129 | ||
|
|
51998e820d | ||
|
|
e803b56716 | ||
|
|
fa8b1c176b | ||
|
|
2598787602 | ||
|
|
003fa62996 | ||
|
|
798c21955e | ||
|
|
fe6185af4b | ||
|
|
7bacefa442 | ||
|
|
04e187c297 | ||
|
|
9f2ffc3276 | ||
|
|
a9a4cf6fca | ||
|
|
a563316e22 | ||
|
|
4b6f55c31d | ||
|
|
21a8fad17a | ||
|
|
7586df9d3f | ||
|
|
1d4afa5d27 | ||
|
|
720d9b924e | ||
|
|
9f56669f2a | ||
|
|
fc541016c6 | ||
|
|
5eefe9ad1e | ||
|
|
1d065a7672 | ||
|
|
101f5f7781 | ||
|
|
af7c6d360f | ||
|
|
8751e6e5ba | ||
|
|
93004a8125 | ||
|
|
adf40e1d56 | ||
|
|
364cfe0131 | ||
|
|
1514527ef3 | ||
|
|
680024234d | ||
|
|
2a3660f2d1 | ||
|
|
2041d1213a | ||
|
|
42a1fe9bd1 | ||
|
|
002469d523 | ||
|
|
5be4af1305 | ||
|
|
0b241438e1 | ||
|
|
61649ab2b8 | ||
|
|
848ea999c5 | ||
|
|
dfa82870fb | ||
|
|
e05ac7ef34 | ||
|
|
ad2334bffc | ||
|
|
17adde99fa | ||
|
|
4789d82c4e | ||
|
|
0567e2d22b | ||
|
|
2e0592b0a6 | ||
|
|
7f6d234b4c | ||
|
|
0436de316b | ||
|
|
e16d643d2a | ||
|
|
bdec22cf3b | ||
|
|
b38df27dce | ||
|
|
b95f556d8f | ||
|
|
851a4c977c | ||
|
|
7bffd461d1 | ||
|
|
9a3b4f7863 | ||
|
|
673a38ddc8 | ||
|
|
a27b8bf213 | ||
|
|
36e6f10b37 | ||
|
|
fde10d7f55 | ||
|
|
6b44b2f429 | ||
|
|
5e9018e0fd | ||
|
|
185f8066ae | ||
|
|
6388f7b29c | ||
|
|
4aa2c9d51d | ||
|
|
ef9256f0b0 | ||
|
|
28d78e40f9 | ||
|
|
89554a82eb | ||
|
|
ae99e82ad1 | ||
|
|
5ea3d01b8d | ||
|
|
aa2bd79b99 | ||
|
|
44ee35b885 | ||
|
|
22b79a8c22 | ||
|
|
65bbd537e6 | ||
|
|
34387d7bc0 | ||
|
|
ca38204313 | ||
|
|
b7083eca2e | ||
|
|
6bb8b428dc | ||
|
|
677142d0c9 | ||
|
|
d1b66e365a | ||
|
|
50154c02ce | ||
|
|
04375d4fcf | ||
|
|
9c1ff296bb | ||
|
|
0b3acb06b5 | ||
|
|
b2cdccedd6 | ||
|
|
7ebefa7b85 | ||
|
|
c7b5baa185 | ||
|
|
6d08e7a8b0 | ||
|
|
0da2b12646 | ||
|
|
a0693483dc | ||
|
|
29826a9f08 | ||
|
|
36a045020f | ||
|
|
40c2b774aa | ||
|
|
8422b2b4aa | ||
|
|
ae334c4860 | ||
|
|
722f36121d | ||
|
|
529092a4ed | ||
|
|
e7068020d5 | ||
|
|
08acecf37b | ||
|
|
b200ca5ad5 | ||
|
|
e564952148 | ||
|
|
f4ad2a2293 | ||
|
|
854bbf26c2 | ||
|
|
ec5a670ea6 | ||
|
|
276add9163 | ||
|
|
de977f4818 | ||
|
|
a4827fc992 | ||
|
|
9a002bf172 | ||
|
|
9a7f3e2d8a | ||
|
|
e7546a7575 | ||
|
|
434719285b | ||
|
|
5bc9ba4641 | ||
|
|
74dd13abd5 | ||
|
|
ead755aa86 | ||
|
|
1f46a8b91b | ||
|
|
eb77c2f6f6 | ||
|
|
c5fe615be5 | ||
|
|
f5504e11ac | ||
|
|
e88a1a52f9 | ||
|
|
b86d54ea9f | ||
|
|
b6e2ed14db | ||
|
|
c513868afa | ||
|
|
3f7664f743 | ||
|
|
e654b951ed | ||
|
|
b5c7556abe | ||
|
|
53e3619140 | ||
|
|
e191988b81 | ||
|
|
bb7fd9423b | ||
|
|
c10c6ee28d | ||
|
|
3c64733e93 | ||
|
|
08cb045f2e | ||
|
|
7bf854fe0b | ||
|
|
f2a1e11b85 | ||
|
|
9b07912b7f | ||
|
|
e1cec9882a | ||
|
|
1ff9c1a84b | ||
|
|
0035825f33 | ||
|
|
1ec73b1b33 | ||
|
|
ed83f4558e | ||
|
|
b18ec7605a | ||
|
|
f96bc0776d | ||
|
|
629bdcd55d | ||
|
|
829fd907a1 | ||
|
|
d7fe321f36 | ||
|
|
517432319e | ||
|
|
edef9f1b23 | ||
|
|
617730ab76 | ||
|
|
7c17d041f4 | ||
|
|
9295abb80e | ||
|
|
4c3192f116 | ||
|
|
9c6a2eb85a | ||
|
|
bcbc8a542f | ||
|
|
a915442efc | ||
|
|
103631a14b | ||
|
|
e9d7a24cbf | ||
|
|
cc977e441a | ||
|
|
add9bae018 | ||
|
|
77d157ab8e | ||
|
|
e42bc94329 | ||
|
|
b4bf5f998e | ||
|
|
dc785e9dac | ||
|
|
8f5f95b04e | ||
|
|
c86839ed41 | ||
|
|
8b6e0f0de7 | ||
|
|
a65243e4bb | ||
|
|
ac028be84e | ||
|
|
efd5b5b1da | ||
|
|
4be618bc93 | ||
|
|
7b6d5a0cc9 | ||
|
|
f367d5e675 | ||
|
|
f9b7894c4d | ||
|
|
354bbb485b | ||
|
|
8dc5dbd547 | ||
|
|
e04793d2eb | ||
|
|
db65c14733 | ||
|
|
f10c8b229f | ||
|
|
4655d8237f | ||
|
|
78f4f35ca3 | ||
|
|
3a01a05a08 | ||
|
|
1738c710cb | ||
|
|
d07783a453 | ||
|
|
1ce331f163 | ||
|
|
586f95bc6d | ||
|
|
5620aec5f2 | ||
|
|
c1dfec20f6 | ||
|
|
7fef81bdef | ||
|
|
0f2e905672 | ||
|
|
a57a4e7350 | ||
|
|
b57a6e982a | ||
|
|
39736ef0d4 | ||
|
|
f7e5f0b567 | ||
|
|
b6078d5272 | ||
|
|
1ed1cd33e8 | ||
|
|
a4a2500725 | ||
|
|
3fb44ec9dd | ||
|
|
2a96575b4d | ||
|
|
dcf29ec63e | ||
|
|
a743605bd3 | ||
|
|
75dc80eb09 | ||
|
|
ac16d9d900 | ||
|
|
736d26c232 | ||
|
|
8985dfc5eb | ||
|
|
bb80ef067a | ||
|
|
bdd9751f0e | ||
|
|
965aac6ad5 | ||
|
|
e3858373d1 | ||
|
|
fcdfae88d7 | ||
|
|
7d5a85e26f | ||
|
|
b8b2c2eba3 | ||
|
|
c6a3280d69 | ||
|
|
7f9368c415 | ||
|
|
add764e3f0 | ||
|
|
a3431cd51e | ||
|
|
9772d43235 | ||
|
|
2e29e369f5 | ||
|
|
9f6ce81229 | ||
|
|
d67954de3f | ||
|
|
d04f93d45c | ||
|
|
ef70209ba8 | ||
|
|
f127cfc46a | ||
|
|
ec444e5bf3 | ||
|
|
32f690e9d0 | ||
|
|
9089b630ed | ||
|
|
0c6971ff5f | ||
|
|
59e92245de | ||
|
|
9894954233 | ||
|
|
6e7505abd5 | ||
|
|
9df381ec4c | ||
|
|
be726183cb | ||
|
|
be5e2d8c33 | ||
|
|
9da7321a19 | ||
|
|
cc7d95b805 | ||
|
|
5376dbffc0 | ||
|
|
cddefd98d3 | ||
|
|
5ae0e55f7e | ||
|
|
856c36b85a | ||
|
|
a3bc717a5b | ||
|
|
6fa198a175 | ||
|
|
9596f48fed | ||
|
|
11b1c81633 | ||
|
|
212f33afee | ||
|
|
3fab15d086 | ||
|
|
2f1dd79162 | ||
|
|
e00ab01235 | ||
|
|
60f0e297e3 | ||
|
|
93c791e16f | ||
|
|
6da8caaa2b | ||
|
|
38ffd7d6ba | ||
|
|
ff4f56392d | ||
|
|
618b67ca2f | ||
|
|
a856a3ef6f | ||
|
|
573284c480 | ||
|
|
d4712266ff | ||
|
|
e4f542b060 | ||
|
|
1b68e8bf0e | ||
|
|
c8d464ded7 | ||
|
|
12ab5ace9c | ||
|
|
a2126c7b15 | ||
|
|
cba2ad5333 | ||
|
|
8700c41f5e | ||
|
|
a88fed283a | ||
|
|
130ffddf48 | ||
|
|
f84b612d7b | ||
|
|
e1ac22067a | ||
|
|
60c3b76ee9 | ||
|
|
fa8552e86f | ||
|
|
ecf1a40a5e | ||
|
|
ecfeae6ad9 | ||
|
|
3544c3f5b8 | ||
|
|
d8f3a3f5be | ||
|
|
d6849c45fe | ||
|
|
eaf663794e | ||
|
|
dbbd4fe47f | ||
|
|
abab7dc874 | ||
|
|
11ddfc511b | ||
|
|
3e50f3dd33 | ||
|
|
bf5becad82 | ||
|
|
f191ce823a | ||
|
|
b03fed979f | ||
|
|
91de41b782 | ||
|
|
ff1cfe269f | ||
|
|
2641a40142 | ||
|
|
584d869729 | ||
|
|
8b9b86a68d | ||
|
|
b7f5631ad0 | ||
|
|
038413be88 | ||
|
|
4508745feb | ||
|
|
f9fa1733b0 | ||
|
|
d50dff4a6e | ||
|
|
2852722b50 | ||
|
|
1ef076bb9b | ||
|
|
8ad53256c2 | ||
|
|
f51155a5df | ||
|
|
75f9824095 | ||
|
|
9678ef3dd4 | ||
|
|
4d945cf1e3 | ||
|
|
8f05de7004 | ||
|
|
72388abd57 | ||
|
|
5801c8602e | ||
|
|
eb77f67d28 | ||
|
|
ba895270fa | ||
|
|
cd88659351 | ||
|
|
eabead4768 | ||
|
|
9cb0cf210a | ||
|
|
d181241a63 | ||
|
|
b3edb82ffd | ||
|
|
eb5ed2bdf9 | ||
|
|
c132ccd141 | ||
|
|
fb2827e9ab | ||
|
|
bb89bf68ef | ||
|
|
97d67d58d5 | ||
|
|
3235f90876 | ||
|
|
227b2513b4 | ||
|
|
5952fdccb8 | ||
|
|
4874748aa2 | ||
|
|
030ea269b0 | ||
|
|
d187a497f9 | ||
|
|
efc2efac84 | ||
|
|
3378744a5c | ||
|
|
71ac461929 | ||
|
|
039da531c4 | ||
|
|
91e080d962 | ||
|
|
b78cf9f2c5 | ||
|
|
af68053195 | ||
|
|
2dd1e567cf | ||
|
|
33400ed7cc | ||
|
|
fe2e01938a | ||
|
|
fccd119a1f | ||
|
|
b1dee5ae7c | ||
|
|
3e178a7293 | ||
|
|
193407d819 | ||
|
|
25419dc8e8 | ||
|
|
cec27d7a44 | ||
|
|
881f0e04a0 | ||
|
|
5ee51c8f9a | ||
|
|
050f3990c3 | ||
|
|
b11ae9e5dd | ||
|
|
c7ef79be90 | ||
|
|
9c3fc69176 | ||
|
|
18df9d66bb | ||
|
|
a43625c5e8 | ||
|
|
a4d9d7041c | ||
|
|
96eabebc15 | ||
|
|
3819df57d8 | ||
|
|
0fee7b0613 | ||
|
|
1a17f54354 | ||
|
|
750231eb3c | ||
|
|
1bb84b7296 | ||
|
|
6d9ef397ee | ||
|
|
64d07a2811 | ||
|
|
e4949b6491 | ||
|
|
71e7df3038 | ||
|
|
47df6fe2bc | ||
|
|
ec08faf205 | ||
|
|
76e86cbdd1 | ||
|
|
f1b072b9a4 | ||
|
|
e792e8fd1e | ||
|
|
bc8b3f504c | ||
|
|
0bcbfda276 | ||
|
|
db029882ec | ||
|
|
a1cc17094d | ||
|
|
1c763ccce3 | ||
|
|
36fd5e7d01 | ||
|
|
66cf9c1ac7 | ||
|
|
0b9b67d603 | ||
|
|
520fb62088 | ||
|
|
d7e26ce930 | ||
|
|
bf3c7545c9 | ||
|
|
3cc92bc9a8 | ||
|
|
086fd5e335 | ||
|
|
20b912d586 | ||
|
|
9691a95ea6 | ||
|
|
e074590140 | ||
|
|
bbbeea3948 | ||
|
|
5f42b8581e | ||
|
|
e1bfd5af9b | ||
|
|
d7fbaa2eac | ||
|
|
f3cf6a6892 | ||
|
|
18623c5dc3 | ||
|
|
85b9e4eb94 | ||
|
|
85dbc0551b | ||
|
|
438ff3f5ea | ||
|
|
39dd8a1a64 | ||
|
|
7e0fa33661 | ||
|
|
6ed7a3d44d | ||
|
|
2c5d544391 | ||
|
|
398f264dbc | ||
|
|
8337d0cbda | ||
|
|
3b312855fc | ||
|
|
68beccfc42 | ||
|
|
c3367fa074 | ||
|
|
f58b1fd210 | ||
|
|
634aee14b5 | ||
|
|
b857c83193 | ||
|
|
4415f98568 | ||
|
|
b27feba3bd | ||
|
|
6a9df1538f | ||
|
|
be430c912c | ||
|
|
6927c8d795 | ||
|
|
2adbf75658 | ||
|
|
ce020fe5f0 | ||
|
|
99d0e46c91 | ||
|
|
c5986e5edb | ||
|
|
c3460430e7 | ||
|
|
00f5bc4c8e | ||
|
|
99a9530495 | ||
|
|
c0af75ab48 | ||
|
|
f40c35baf1 | ||
|
|
93da4801db | ||
|
|
49a9b71ea3 | ||
|
|
ab30129fc2 | ||
|
|
ffc41605f9 | ||
|
|
067a546ab6 | ||
|
|
a48cb2a844 | ||
|
|
ae10c7f79c | ||
|
|
9e6fa1e37d | ||
|
|
91e3b04b0a | ||
|
|
8086462940 | ||
|
|
be5f147937 | ||
|
|
5029213bc5 | ||
|
|
cb42457683 | ||
|
|
179a450ae5 | ||
|
|
3fee298045 | ||
|
|
e510a2c121 | ||
|
|
72f4b77603 | ||
|
|
236967da52 | ||
|
|
8fa0d55e17 | ||
|
|
c05d03437c | ||
|
|
57763f4a2f | ||
|
|
9a941fb89d | ||
|
|
6d2d011b33 | ||
|
|
55977057f0 | ||
|
|
1631bfcca1 | ||
|
|
aafd921aba | ||
|
|
e66540f91c | ||
|
|
ea514948b5 | ||
|
|
538dd933fb | ||
|
|
2f724592e0 | ||
|
|
9f7be4e267 | ||
|
|
a8f2cbdf76 | ||
|
|
41acf2c1ab | ||
|
|
a519310fb8 | ||
|
|
8955efc890 | ||
|
|
442bd90237 | ||
|
|
7535a9bd15 | ||
|
|
b4d8252183 | ||
|
|
b1dfa71035 | ||
|
|
f7a32784f2 | ||
|
|
56bde88460 | ||
|
|
26668707b9 | ||
|
|
e1efa80b04 | ||
|
|
dbddd44234 | ||
|
|
0cb84bac15 | ||
|
|
2df40ceb08 | ||
|
|
f3abddeb9c | ||
|
|
3059aa4de8 | ||
|
|
5ded6a3912 | ||
|
|
435ecf10ac | ||
|
|
1ca523847b | ||
|
|
dcf00c8772 | ||
|
|
3f7fe09a45 | ||
|
|
c230436108 | ||
|
|
545628e5cd | ||
|
|
1439594806 | ||
|
|
5d5601a8bb | ||
|
|
40fa881486 | ||
|
|
0348b0985c | ||
|
|
732bfba19b | ||
|
|
b00da8b002 | ||
|
|
c191db524d | ||
|
|
1503bf4014 | ||
|
|
9773867f92 | ||
|
|
9809b88b52 | ||
|
|
670389c8ae | ||
|
|
94632e5514 | ||
|
|
587c4f5a81 | ||
|
|
ac4e4a2578 | ||
|
|
f20ac78586 | ||
|
|
35c6975270 | ||
|
|
b3e14be6ed | ||
|
|
ad3f6e9077 | ||
|
|
e19d79a2bf | ||
|
|
f19a74990f | ||
|
|
04dd2a6cf0 | ||
|
|
9d524febf5 | ||
|
|
aa1fc42628 | ||
|
|
7111548a9a | ||
|
|
4bcb810140 | ||
|
|
44b1aaa440 | ||
|
|
1c4eeb3cf4 | ||
|
|
ffa80989d3 | ||
|
|
111d674c8f | ||
|
|
d6c1c1bd41 | ||
|
|
8c07fa75e4 | ||
|
|
cf9fd47d2b | ||
|
|
1d7d2de482 | ||
|
|
7ab2132502 | ||
|
|
5764a05581 | ||
|
|
7a658dd61c | ||
|
|
235a49b9c0 | ||
|
|
36a460bf48 | ||
|
|
d65f3254f0 | ||
|
|
cb31aba79e | ||
|
|
c4c2b4c563 | ||
|
|
8bfed06ac8 | ||
|
|
44bedd77bd | ||
|
|
2c664df5d8 | ||
|
|
d94fd6bbec | ||
|
|
6042b55af2 | ||
|
|
f534064d5c | ||
|
|
4144ac413b | ||
|
|
bd7a38ea3f | ||
|
|
5b0d3c9ff1 | ||
|
|
5a33e76965 | ||
|
|
233a119289 | ||
|
|
5398d24b32 | ||
|
|
31a7194119 | ||
|
|
9254a559ef | ||
|
|
51c8ad16c1 | ||
|
|
972f4646fa | ||
|
|
ce2da4ee99 | ||
|
|
0f73f5bc5e | ||
|
|
389228bfe8 | ||
|
|
ab0fadc0fe | ||
|
|
07a11e4df2 | ||
|
|
5e9865379d | ||
|
|
d9da2da690 | ||
|
|
2d63d5a6e7 | ||
|
|
0a220eb0d6 | ||
|
|
4cbec46f3e | ||
|
|
a4ccf07bfb | ||
|
|
2e8253fa7b | ||
|
|
403b8191e4 | ||
|
|
0a7a3537eb | ||
|
|
706f330a6e | ||
|
|
b5e41f4c62 | ||
|
|
366395278e | ||
|
|
b5fdba796b | ||
|
|
fb8ddc9cb6 | ||
|
|
52bf6dced3 | ||
|
|
3af1efb750 | ||
|
|
a9af2dc902 | ||
|
|
a050a341b6 | ||
|
|
b7ac16402d | ||
|
|
905d37f768 | ||
|
|
a81695533c | ||
|
|
e4b27ef7b4 | ||
|
|
d8bd9dd4fe | ||
|
|
e114555a1f | ||
|
|
65d1e41b0e | ||
|
|
d915447624 | ||
|
|
dedd77e4be | ||
|
|
62f85d2160 | ||
|
|
d7625b0157 | ||
|
|
8e6925c037 | ||
|
|
23a9ce30d3 | ||
|
|
7f0a6d08cf | ||
|
|
324919881f | ||
|
|
9ab61f3e27 | ||
|
|
1fcc406030 | ||
|
|
338c9b240e | ||
|
|
aa589d4739 | ||
|
|
f4964fe7b1 | ||
|
|
5db17dac87 | ||
|
|
1a2cc457f3 | ||
|
|
0a71308f97 | ||
|
|
00a25a2e3d | ||
|
|
95adfc9f54 | ||
|
|
06bd731e3f | ||
|
|
145ddff1ab | ||
|
|
6c838b774d | ||
|
|
21e8dde13e | ||
|
|
4c3e716b88 | ||
|
|
a5d9844ddb | ||
|
|
4911cbb46b | ||
|
|
bb57b7cde8 | ||
|
|
d695b8e576 | ||
|
|
d0d80290b8 | ||
|
|
63007b34ed | ||
|
|
083c257915 | ||
|
|
8c101dc64c | ||
|
|
6820044461 | ||
|
|
63cfef43e4 | ||
|
|
f2e2b5cb86 | ||
|
|
4796616578 | ||
|
|
9634555798 | ||
|
|
f97cd59162 | ||
|
|
d900faf5c8 | ||
|
|
44245b4053 | ||
|
|
879507c0e1 | ||
|
|
8e79eb570e | ||
|
|
62e412bbc0 | ||
|
|
c4189db548 | ||
|
|
cd0e287403 | ||
|
|
d5a0facb92 | ||
|
|
2b5a704412 | ||
|
|
36ac2b1e52 | ||
|
|
02ce2fb5cf | ||
|
|
ecd97fc6ce | ||
|
|
79b113ef57 | ||
|
|
3b585d15cd | ||
|
|
a3dc562d08 | ||
|
|
b17706410a | ||
|
|
5ecbd5c8d8 | ||
|
|
4e35385a27 | ||
|
|
8ba76ec542 | ||
|
|
a9ec581421 | ||
|
|
da762a3fa9 | ||
|
|
5a02f110a4 | ||
|
|
84a07ec998 | ||
|
|
e526847704 | ||
|
|
527fa58ee4 | ||
|
|
735bc74146 | ||
|
|
55c1edaa03 | ||
|
|
552d13ef6c | ||
|
|
a45f4cce4f | ||
|
|
4acf660906 | ||
|
|
6447201f9f | ||
|
|
c9e7dfe953 | ||
|
|
aae3faed44 | ||
|
|
a0b3c70e2a | ||
|
|
8921ccb8c1 | ||
|
|
2cd67d6036 | ||
|
|
9f9d18b17f | ||
|
|
a0a3967ceb | ||
|
|
762fbe0cf6 | ||
|
|
dafee9ad72 | ||
|
|
967c641e14 | ||
|
|
2c033e67a9 | ||
|
|
a230df33f6 | ||
|
|
07a3623c13 | ||
|
|
8c7774e5e3 | ||
|
|
16538972a3 | ||
|
|
9ae23217f2 | ||
|
|
2b18063f9f | ||
|
|
24d29febc4 | ||
|
|
18fdaa0647 | ||
|
|
8e05d52f42 | ||
|
|
96e31c15e6 | ||
|
|
70fbc48295 | ||
|
|
b6e9e64ff9 | ||
|
|
b148253997 | ||
|
|
7585f8b7d2 | ||
|
|
d635610546 | ||
|
|
f4b7d02361 | ||
|
|
7dfd6480bd | ||
|
|
dd99095bef | ||
|
|
65ce678a20 | ||
|
|
3a7bde4980 | ||
|
|
0488336b1f | ||
|
|
10d41cd6ee | ||
|
|
99bc133540 | ||
|
|
caa61a463e | ||
|
|
1314cdc7b7 | ||
|
|
7942c4112f | ||
|
|
b482d84c3c | ||
|
|
97dbef9778 | ||
|
|
0576cb013c | ||
|
|
6064b14563 | ||
|
|
c2de0ca9b0 | ||
|
|
5faf2019e8 | ||
|
|
9f9d047293 | ||
|
|
35fbefe2bd | ||
|
|
bd34dd44a0 | ||
|
|
7d1aeeb6dd | ||
|
|
24bccf8b9c | ||
|
|
638b856f42 | ||
|
|
5fa3a3bf85 | ||
|
|
6309582593 | ||
|
|
1844a1fe6d | ||
|
|
bc1641a97e | ||
|
|
3831ddec93 | ||
|
|
f2a6f751ac | ||
|
|
95d19dc656 | ||
|
|
3ea1a92716 | ||
|
|
7c07a6581e | ||
|
|
fa48e55f0f | ||
|
|
294cb65388 | ||
|
|
16cd6598b3 | ||
|
|
1b41fa1f3b | ||
|
|
0719213155 | ||
|
|
7555bf422d | ||
|
|
08d68a764b | ||
|
|
90056c5dca | ||
|
|
92bf93ca0a | ||
|
|
d48e2bc084 | ||
|
|
2a9d133922 | ||
|
|
a96023af01 | ||
|
|
a93287207b | ||
|
|
ce834d7028 | ||
|
|
0a6b53b63b | ||
|
|
3044b9346a | ||
|
|
aaafbea77a | ||
|
|
b2e28dcd1c | ||
|
|
d635448db4 | ||
|
|
69e8613896 | ||
|
|
1275995575 | ||
|
|
9d7d59f030 | ||
|
|
847190e0fe | ||
|
|
1a9769ea8c | ||
|
|
59299fdecb | ||
|
|
f1f09d5c34 | ||
|
|
94d6ac855a |
5
.clabot
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"contributors": "https://crm.rami.io/cla/check/?project=pretix&checkContributor=",
|
||||
"message": "Hey there! :) Thank you very much for offering a contribution to pretix! For legal reasons, we need you to sign a Contributor License Agreement in order to be able to merge the code. Sorry for the hassle :( Please download the agreement from https://pretix.eu/about/en/cla and send a signed copy to support@pretix.eu. Feel free to also contact us there or via comments here if you have any questions!",
|
||||
"label": "cla-signed"
|
||||
}
|
||||
1
.gitattributes
vendored
@@ -6,6 +6,7 @@ src/pretix/static/datetimepicker/* linguist-vendored
|
||||
src/pretix/static/colorpicker/* linguist-vendored
|
||||
src/pretix/static/fileupload/* linguist-vendored
|
||||
src/pretix/static/vuejs/* linguist-vendored
|
||||
src/pretix/static/d3/* linguist-vendored
|
||||
src/pretix/static/select2/* linguist-vendored
|
||||
src/pretix/static/charts/* linguist-vendored
|
||||
src/pretix/static/rrule/* linguist-vendored
|
||||
|
||||
15
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/src"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/src/pretix/static/npm_dir"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
3
.github/workflows/docs.yml
vendored
@@ -33,7 +33,8 @@ jobs:
|
||||
- name: Install system packages
|
||||
run: sudo apt update && sudo apt install enchant hunspell aspell-en
|
||||
- name: Install Dependencies
|
||||
run: pip3 install -Ur doc/requirements.txt
|
||||
run: pip3 install -Ur requirements.txt
|
||||
working-directory: ./doc
|
||||
- name: Spellcheck docs
|
||||
run: make spelling
|
||||
working-directory: ./doc
|
||||
|
||||
6
.github/workflows/strings.yml
vendored
@@ -31,7 +31,8 @@ jobs:
|
||||
- name: Install system packages
|
||||
run: sudo apt update && sudo apt install gettext
|
||||
- name: Install Dependencies
|
||||
run: pip3 install -Ur src/requirements.txt
|
||||
run: pip3 install -e ".[dev]"
|
||||
working-directory: ./src
|
||||
- name: Compile messages
|
||||
run: python manage.py compilemessages
|
||||
working-directory: ./src
|
||||
@@ -56,7 +57,8 @@ jobs:
|
||||
- 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 -Ur src/requirements/dev.txt
|
||||
run: pip3 install -e ".[dev]"
|
||||
working-directory: ./src
|
||||
- name: Spellcheck translations
|
||||
run: potypo
|
||||
working-directory: ./src
|
||||
|
||||
23
.github/workflows/style.yml
vendored
@@ -29,7 +29,8 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install Dependencies
|
||||
run: pip3 install -Ur src/requirements/dev.txt
|
||||
run: pip3 install -e ".[dev]" mysqlclient psycopg2-binary
|
||||
working-directory: ./src
|
||||
- name: Run isort
|
||||
run: isort -c .
|
||||
working-directory: ./src
|
||||
@@ -49,7 +50,25 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install Dependencies
|
||||
run: pip3 install -r src/requirements.txt -Ur src/requirements/dev.txt
|
||||
run: pip3 install -e ".[dev]" mysqlclient psycopg2-binary
|
||||
working-directory: ./src
|
||||
- name: Run flake8
|
||||
run: flake8 .
|
||||
working-directory: ./src
|
||||
licenseheader:
|
||||
name: licenseheaders
|
||||
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
|
||||
- name: Install Dependencies
|
||||
run: pip3 install licenseheaders
|
||||
- name: Run licenseheaders
|
||||
run: licenseheaders -t ../.licenseheader -E .py -x "*/migrations/*.py"
|
||||
working-directory: ./src
|
||||
- name: Check for changes
|
||||
run: git diff --exit-code
|
||||
working-directory: ./src
|
||||
|
||||
17
.github/workflows/tests.yml
vendored
@@ -18,17 +18,17 @@ jobs:
|
||||
name: Tests
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
python-version: ["3.7", "3.8", "3.9"]
|
||||
database: [sqlite, postgres, mysql]
|
||||
exclude:
|
||||
- database: mysql
|
||||
python-version: 3.7
|
||||
- database: sqlite
|
||||
python-version: 3.7
|
||||
python-version: "3.8"
|
||||
- database: mysql
|
||||
python-version: 3.6
|
||||
python-version: "3.9"
|
||||
- database: sqlite
|
||||
python-version: 3.6
|
||||
python-version: "3.7"
|
||||
- database: sqlite
|
||||
python-version: "3.8"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: getong/mariadb-action@v1.1
|
||||
@@ -55,9 +55,10 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Install system dependencies
|
||||
run: sudo apt update && sudo apt install gettext mysql-client
|
||||
run: sudo apt update && sudo apt install gettext mariadb-client
|
||||
- name: Install Python dependencies
|
||||
run: pip3 install -r src/requirements.txt -Ur src/requirements/dev.txt mysqlclient psycopg2-binary
|
||||
run: pip3 install -e ".[dev]" mysqlclient psycopg2-binary
|
||||
working-directory: ./src
|
||||
- name: Run checks
|
||||
run: python manage.py check
|
||||
working-directory: ./src
|
||||
|
||||
@@ -5,8 +5,8 @@ tests:
|
||||
- virtualenv env
|
||||
- source env/bin/activate
|
||||
- pip install -U pip wheel setuptools
|
||||
- XDG_CACHE_HOME=/cache pip3 install -r src/requirements.txt --no-use-pep517 -Ur src/requirements/dev.txt
|
||||
- cd src
|
||||
- XDG_CACHE_HOME=/cache pip3 install -e ".[dev]"
|
||||
- python manage.py check
|
||||
- make all compress
|
||||
- py.test --reruns 3 -n 3 tests
|
||||
@@ -21,14 +21,14 @@ pypi:
|
||||
- virtualenv env
|
||||
- source env/bin/activate
|
||||
- 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
|
||||
- XDG_CACHE_HOME=/cache pip3 install -e ".[dev]"
|
||||
- python setup.py sdist
|
||||
- make npminstall
|
||||
- pip install dist/pretix-*.tar.gz
|
||||
- python -m pretix migrate
|
||||
- python -m pretix check
|
||||
- check-manifest
|
||||
- make npminstall
|
||||
- python setup.py sdist bdist_wheel
|
||||
- twine check dist/*
|
||||
- twine upload dist/*
|
||||
|
||||
19
.licenseheader
Normal file
@@ -0,0 +1,19 @@
|
||||
This file is part of pretix (Community Edition).
|
||||
|
||||
Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
|
||||
ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
this file, see <https://pretix.eu/about/en/license>.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
37
AUTHORS
@@ -1,37 +0,0 @@
|
||||
Here is an inevitably incomplete list of much-appreciated contributors --
|
||||
people who have submitted patches, reported bugs, added translations, helped
|
||||
answer newbie questions, improved the documentation, and generally made pretix
|
||||
an awesome project. Thank you all!
|
||||
|
||||
Adam K. Sumner <asumner101@gmail.com>
|
||||
Ahrdie <robert.deppe@me.com>
|
||||
Alexander Brock <Brock.Alexander@web.de>
|
||||
Brandon Pineda
|
||||
Bolutife Lawrence
|
||||
Christian Franke <nobody@nowhere.ws>
|
||||
Christopher Dambamuromo <me@chridam.com>
|
||||
chotee <chotee@openended.eu>
|
||||
Cpt. Foo
|
||||
Daniel Rosenblüh
|
||||
Enrique Saez
|
||||
Flavia Bastos
|
||||
informancer <informancer@web.de>
|
||||
Jakob Schnell <github@ezelo.de>
|
||||
Jan Felix Wiebe <git@jfwie.be>
|
||||
Jan Weiß
|
||||
Jason Estibeiro <jasonestibeiro@live.com>
|
||||
jlwt90
|
||||
Jonas Große Sundrup <cherti@letopolis.de>
|
||||
Kevin Nelson
|
||||
Leah Oswald
|
||||
Lukas Martini
|
||||
Nathan Mattes
|
||||
Nicole Klünder
|
||||
Marc-Pascal Clement
|
||||
Martin Gross <martin@pc-coholic.de>
|
||||
Raphael Michel <mail@raphaelmichel.de>
|
||||
Team MRMCD
|
||||
Tobias Kunze <rixx@cutebit.de>
|
||||
Oliver Knapp <github@oliverknapp.de>
|
||||
Vishal Sodani <vishalsodani@rediffmail.com>
|
||||
Jan Felix Wiebe <git@jfwie.be>
|
||||
@@ -3,9 +3,9 @@ Contributing to pretix
|
||||
|
||||
Hey there and welcome to pretix!
|
||||
|
||||
We've got a contributors guide in [our documentation](https://docs.pretix.eu/en/latest/development/contribution/)
|
||||
together with notes on the [development setup](https://docs.pretix.eu/en/latest/development/setup.html).
|
||||
* We've got a contributors guide in [our documentation](https://docs.pretix.eu/en/latest/development/contribution/) together with notes on the [development setup](https://docs.pretix.eu/en/latest/development/setup.html).
|
||||
|
||||
Please note that we have a [Code of Conduct](https://docs.pretix.eu/en/latest/development/contribution/codeofconduct.html)
|
||||
in place that applies to all project contributions, including issues, pull requests, etc.
|
||||
* Please note that we have a [Code of Conduct](https://docs.pretix.eu/en/latest/development/contribution/codeofconduct.html) in place that applies to all project contributions, including issues, pull requests, etc.
|
||||
|
||||
* Before we can accept a PR from you we'll need you to sign [our CLA](https://pretix.eu/about/en/cla). You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/en/latest/license/faq.html#) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
|
||||
|
||||
|
||||
32
COPYRIGHT
@@ -1,32 +0,0 @@
|
||||
Copyright 2014-2016 Raphael Michel
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
This project includes the work of others, namely:
|
||||
|
||||
* Django, (c) Django Software Foundation and contributors, BSD License
|
||||
* Font Awesome, (c) Dave Gandy, SIL Open Font License and MIT License
|
||||
* Bootstrap, (c) Twitter, Inc., MIT License
|
||||
* jQuery, (c) jQuery Foundation and contributors, MIT License
|
||||
* django-formset-js, (c) Ionata Web Solutions, BSD License
|
||||
* CleanerVersion, (c) Jean-Christophe Zulian, Brian King, Andrea Marcacci, Manuel Jeckelmann, Apache License
|
||||
* django-bootstrap3, (c) Dylan Verheul, Apache License
|
||||
* pytz, (c) Stuart Bishop, MIT License
|
||||
* python-dateutil, (c) Yaron de Leeuw, BSD License
|
||||
* startbootstrap-sb-admin-2, (c) Iron Summit Media Strategies, LLC, Apache License
|
||||
* metismenu, (c) Osman Nuri Okumus, MIT License
|
||||
* easy-thumbnails, (c) Chris Beaven and contributors
|
||||
* reportlab, (c) ReportLab Europe Ltd, BSD License
|
||||
* django-compressor, (c) Jannis Leidel and contributors, MIT License
|
||||
* static3, (c) Roman Mohr and contributors, LGPL License
|
||||
* Lightbox, (c) Lokesh Dhakar, MIT License
|
||||
19
Dockerfile
@@ -1,9 +1,9 @@
|
||||
FROM python:3.8
|
||||
FROM python:3.9-bullseye
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
default-libmysqlclient-dev \
|
||||
libmariadb-dev \
|
||||
gettext \
|
||||
git \
|
||||
libffi-dev \
|
||||
@@ -15,8 +15,7 @@ RUN apt-get update && \
|
||||
libxslt1-dev \
|
||||
locales \
|
||||
nginx \
|
||||
python-dev \
|
||||
python-virtualenv \
|
||||
python3-virtualenv \
|
||||
python3-dev \
|
||||
sudo \
|
||||
supervisor \
|
||||
@@ -41,17 +40,14 @@ ENV LC_ALL=C.UTF-8 \
|
||||
DJANGO_SETTINGS_MODULE=production_settings
|
||||
|
||||
# To copy only the requirements files needed to install from PIP
|
||||
COPY src/requirements /pretix/src/requirements
|
||||
COPY src/requirements.txt /pretix/src
|
||||
COPY src/setup.py /pretix/src/setup.py
|
||||
RUN pip3 install -U \
|
||||
pip \
|
||||
setuptools \
|
||||
wheel && \
|
||||
cd /pretix/src && \
|
||||
pip3 install \
|
||||
-r requirements.txt \
|
||||
-r requirements/memcached.txt \
|
||||
-r requirements/mysql.txt \
|
||||
PRETIX_DOCKER_BUILD=TRUE pip3 install \
|
||||
-e ".[memcached,mysql]" \
|
||||
gunicorn django-extensions ipython && \
|
||||
rm -rf ~/.cache/pip
|
||||
|
||||
@@ -60,10 +56,11 @@ COPY deployment/docker/supervisord /etc/supervisord
|
||||
COPY deployment/docker/supervisord.all.conf /etc/supervisord.all.conf
|
||||
COPY deployment/docker/supervisord.web.conf /etc/supervisord.web.conf
|
||||
COPY deployment/docker/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY deployment/docker/nginx-max-body-size.conf /etc/nginx/conf.d/nginx-max-body-size.conf
|
||||
COPY deployment/docker/production_settings.py /pretix/src/production_settings.py
|
||||
COPY src /pretix/src
|
||||
|
||||
RUN cd /pretix/src && pip3 install .
|
||||
RUN cd /pretix/src && python setup.py install
|
||||
|
||||
RUN chmod +x /usr/local/bin/pretix && \
|
||||
rm /etc/nginx/sites-enabled/default && \
|
||||
|
||||
@@ -52,11 +52,9 @@ including issues, pull requests, etc.
|
||||
|
||||
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. See the AUTHORS file for a list of all
|
||||
the awesome folks who contributed to this project.
|
||||
The code in this repository is covered by different licenses. Most of it is available to everyone under the terms of
|
||||
the GNU AGPL license v3 with additional terms. See the LICENSE file for the complete license details.
|
||||
|
||||
.. _installation guide: https://docs.pretix.eu/en/latest/admin/installation/index.html
|
||||
.. _developer documentation: https://docs.pretix.eu/en/latest/development/index.html
|
||||
|
||||
1
deployment/docker/nginx-max-body-size.conf
Normal file
@@ -0,0 +1 @@
|
||||
client_max_body_size 100M;
|
||||
@@ -16,7 +16,6 @@ http {
|
||||
charset utf-8;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
client_max_body_size 100M;
|
||||
|
||||
log_format private '[$time_local] $host "$request" $status $body_bytes_sent';
|
||||
|
||||
@@ -33,7 +32,7 @@ http {
|
||||
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml image/svg+xml;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml image/svg+xml;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
@@ -66,9 +65,18 @@ http {
|
||||
access_log off;
|
||||
expires 365d;
|
||||
add_header Cache-Control "public";
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
gzip on;
|
||||
}
|
||||
location / {
|
||||
proxy_pass http://unix:/tmp/pretix.sock:/;
|
||||
# Very important:
|
||||
# proxy_pass http://unix:/tmp/pretix.sock:;
|
||||
# is not the same as
|
||||
# proxy_pass http://unix:/tmp/pretix.sock:/;
|
||||
# In the latter case, nginx will apply its URL parsing, in the former it doesn't.
|
||||
# There are situations in which pretix' API will deal with "file names" containing %2F%2F, which
|
||||
# nginx will normalize to %2F, which can break ticket validation.
|
||||
proxy_pass http://unix:/tmp/pretix.sock:;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
|
||||
202
doc/LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -282,7 +282,7 @@ You can use an existing memcached server as pretix's caching backend::
|
||||
``location``
|
||||
The location of memcached, either a host:port combination or a socket file.
|
||||
|
||||
If no memcached is configured, pretix will use Django's built-in local-memory caching method.
|
||||
If no memcached is configured, pretix will use redis for caching. If neither is configured, pretix will not use any caching.
|
||||
|
||||
.. note:: If you use memcached and you deploy pretix across multiple servers, you should use *one*
|
||||
shared memcached instance, not multiple ones, because cache invalidations would not be
|
||||
@@ -297,6 +297,12 @@ to speed up various operations::
|
||||
[redis]
|
||||
location=redis://127.0.0.1:6379/1
|
||||
sessions=false
|
||||
sentinels=[
|
||||
["sentinel_host_1", 26379],
|
||||
["sentinel_host_2", 26379],
|
||||
["sentinel_host_3", 26379]
|
||||
]
|
||||
password=password
|
||||
|
||||
``location``
|
||||
The location of redis, as a URL of the form ``redis://[:password]@localhost:6379/0``
|
||||
@@ -305,13 +311,34 @@ to speed up various operations::
|
||||
``session``
|
||||
When this is set to ``True``, redis will be used as the session storage.
|
||||
|
||||
``sentinels``
|
||||
Configures redis sentinels to use.
|
||||
If you don't want to use redis sentinels, you should omit this option.
|
||||
If this is set, redis via sentinels will be used instead of plain redis.
|
||||
In this case the location should be of the form ``redis://my_master/0``.
|
||||
The ``sentinels`` variable should be a json serialized list of sentinels,
|
||||
each being a list with the two elements hostname and port.
|
||||
You cannot provide a password within the location when using sentinels.
|
||||
Note that the configuration format requires you to either place the entire
|
||||
value on one line or make sure all values are indented by at least one space.
|
||||
|
||||
``password``
|
||||
If your redis setup doesn't require a password or you already specified it in the location you can omit this option.
|
||||
If this is set it will be passed to redis as the connection option PASSWORD.
|
||||
|
||||
If redis is not configured, pretix will store sessions and locks in the database. If memcached
|
||||
is configured, memcached will be used for caching instead of redis.
|
||||
|
||||
Translations
|
||||
------------
|
||||
|
||||
pretix comes with a number of translations. Some of them are marked as "incubating", which means
|
||||
pretix comes with a number of translations. All languages are enabled by default. If you want to limit
|
||||
the languages available in your installation, you can enable a set of languages like this::
|
||||
|
||||
[languages]
|
||||
enabled=en,de
|
||||
|
||||
Some of the languages them are marked as "incubating", which means
|
||||
they can usually only be selected in development mode. If you want to use them nevertheless, you
|
||||
can activate them like this::
|
||||
|
||||
@@ -337,11 +364,22 @@ an AMQP server (e.g. RabbitMQ) as a broker and redis or your database as a resul
|
||||
[celery]
|
||||
broker=amqp://guest:guest@localhost:5672//
|
||||
backend=redis://localhost/0
|
||||
broker_transport_options="{}"
|
||||
backend_transport_options="{}"
|
||||
|
||||
RabbitMQ might be the better choice if you have a complex, multi-server, high-performance setup,
|
||||
but as you already should have a redis instance ready for session and lock storage, we recommend
|
||||
redis for convenience. See the `Celery documentation`_ for more details.
|
||||
|
||||
The two ``transport_options`` entries can be omitted in most cases.
|
||||
If they are present they need to be a valid JSON dictionary.
|
||||
For possible entries in that dictionary see the `Celery documentation`_.
|
||||
|
||||
To use redis with sentinels set the broker or backend to ``sentinel://sentinel_host_1:26379;sentinal_host_2:26379/0``
|
||||
and the respective transport_options to ``{"master_name":"mymaster"}``.
|
||||
If your redis instances behind the sentinel have a password use ``sentinel://:my_password@sentinel_host_1:26379;sentinal_host_2:26379/0``.
|
||||
If your redis sentinels themselves have a password set the transport_options to ``{"master_name":"mymaster","sentinel_kwargs":{"password":"my_password"}}``.
|
||||
|
||||
Sentry
|
||||
------
|
||||
|
||||
@@ -350,10 +388,18 @@ application. If you want to use sentry, you need to set a DSN in the configurati
|
||||
|
||||
[sentry]
|
||||
dsn=https://<key>:<secret>@sentry.io/<project>
|
||||
traces_sample_rate=0.5
|
||||
traces_sample_token=xyz
|
||||
|
||||
``dsn``
|
||||
You will be given this value by your sentry installation.
|
||||
|
||||
``traces_sample_rate``
|
||||
Sample rate for performance monitoring.
|
||||
|
||||
``traces_sample_token``
|
||||
If this token is found in a query string, a trace will always be sampled.
|
||||
|
||||
|
||||
Caching
|
||||
-------
|
||||
@@ -388,3 +434,21 @@ pretix can make use of some external tools if they are installed. Currently, the
|
||||
|
||||
.. _Python documentation: https://docs.python.org/3/library/configparser.html?highlight=configparser#supported-ini-file-structure
|
||||
.. _Celery documentation: http://docs.celeryproject.org/en/latest/userguide/configuration.html
|
||||
|
||||
Maximum upload file sizes
|
||||
-------------------------
|
||||
|
||||
You can configure the maximum file size for uploading various files::
|
||||
|
||||
[pretix_file_upload]
|
||||
; Max upload size for images in MiB, defaults to 10 MiB
|
||||
max_size_image = 12
|
||||
; Max upload size for favicons in MiB, defaults to 1 MiB
|
||||
max_size_favicon = 2
|
||||
; Max upload size for email attachments of manually sent emails in MiB, defaults to 10 MiB
|
||||
max_size_email_attachment = 15
|
||||
; Max upload size for email attachments of automatically sent emails in MiB, defaults to 1 MiB
|
||||
max_size_email_auto_attachment = 2
|
||||
; Max upload size for other files in MiB, defaults to 10 MiB
|
||||
; This includes all file upload type order questions
|
||||
max_size_other = 100
|
||||
|
||||
40
doc/admin/errors.rst
Normal file
@@ -0,0 +1,40 @@
|
||||
.. _`admin-errors`:
|
||||
|
||||
Dealing with errors
|
||||
===================
|
||||
|
||||
If you encounter an error in pretix, please follow the following steps to debug it:
|
||||
|
||||
* If the error message is shown on a **white page** and the last line of the error includes "nginx", the error is not with pretix
|
||||
directly but with your nginx webserver. This might mean that pretix is not running, but it could also be something else.
|
||||
Please first check your nginx error log. The default location is ``/var/log/nginx/error.log``.
|
||||
|
||||
* If it turns out pretix is not running, check the output of ``docker logs pretix`` for a docker installation and
|
||||
``journalctl -u pretix-web.service`` for a manual installation.
|
||||
|
||||
* If the error message is an "**Internal Server Error**" in purple pretix design, please check pretix' log file which by default is at
|
||||
``/var/pretix-data/logs/pretix.log`` if you installed with docker and ``/var/pretix/data/logs/pretix.log`` otherwise. If you don't
|
||||
know how to interpret it, open a discussion on GitHub with the relevant parts of the log file.
|
||||
|
||||
* If the error message includes ``/usr/bin/env: ‘node’: No such file or directory``, you forgot to install ``node.js``
|
||||
|
||||
* If the error message includes ``OfflineGenerationError``, you might have forgot to run the ``rebuild`` step after a pretix update
|
||||
or plugin installation.
|
||||
|
||||
* If the error message mentions your database server or redis server, make sure these are running and accessible.
|
||||
|
||||
* If pretix loads fine but certain actions (creating carts, orders, or exports, downloading tickets, sending emails) **take forever**,
|
||||
``pretix-worker`` is not running. Check the output of ``docker logs pretix`` for a docker installation and
|
||||
``journalctl -u pretix-worker.service`` for a manual installation.
|
||||
|
||||
* If the page loads but all **styles are missing**, you probably forgot to update your nginx configuration file after an upgrade of your
|
||||
operating system's python version.
|
||||
|
||||
|
||||
If you are unable to debug the issue any further, please open a **discussion** on GitHub in our `Q&A Forum`_. Do **not** open an issue
|
||||
right away, since most things turn out not to be a bug in pretix but a mistake in your server configuration. Make sure to include
|
||||
relevant log excerpts in your question.
|
||||
|
||||
If you're a pretix Enterprise customer, you can also reach out to support@pretix.eu with your issue right away.
|
||||
|
||||
.. _Q&A Forum: https://github.com/pretix/pretix/discussions/categories/q-a
|
||||
@@ -9,7 +9,9 @@ This documentation is for everyone who wants to install pretix on a server.
|
||||
:maxdepth: 2
|
||||
|
||||
installation/index
|
||||
updates
|
||||
config
|
||||
maintainance
|
||||
scaling
|
||||
errors
|
||||
indexes
|
||||
|
||||
@@ -45,10 +45,12 @@ Here is the currently recommended set of commands::
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_order_comment
|
||||
ON pretixbase_order
|
||||
USING gin (upper("comment") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_order_event_date
|
||||
ON public.pretixbase_order (event_id, datetime);
|
||||
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
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_secret
|
||||
ON pretixbase_orderposition
|
||||
USING gin (upper("secret") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_email
|
||||
@@ -64,6 +66,10 @@ Here is the currently recommended set of commands::
|
||||
ON public.pretixbase_orderposition (upper((attendee_email)::text));
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_voucher_code_upper
|
||||
ON public.pretixbase_voucher (upper((code)::text));
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_logentry_event_date
|
||||
ON public.pretixbase_logentry (event_id, datetime);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_logentry_event_cid_date
|
||||
ON public.pretixbase_logentry (event_id, content_type_id, datetime);
|
||||
|
||||
|
||||
Also, if you use our ``pretix-shipping`` plugin::
|
||||
|
||||
@@ -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`_ 9.5+, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `PostgreSQL`_ 9.6+, `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
|
||||
@@ -39,6 +39,10 @@ Linux and firewalls, we recommend that you start with `ufw`_.
|
||||
.. warning:: We recommend **PostgreSQL**. If you go for MySQL, make sure you run **MySQL 5.7 or newer** or
|
||||
**MariaDB 10.2.7 or newer**.
|
||||
|
||||
.. warning:: By default, using `ufw` in conjunction will not have any effect. Please make sure to either bind the exposed
|
||||
ports of your docker container explicitly to 127.0.0.1 or configure docker to respect any set up firewall
|
||||
rules.
|
||||
|
||||
On this guide
|
||||
-------------
|
||||
|
||||
@@ -58,7 +62,12 @@ Database
|
||||
--------
|
||||
|
||||
Next, we need a database and a database user. We can create these with any kind of database managing tool or directly on
|
||||
our database's shell. For PostgreSQL, we would do::
|
||||
our database's shell. Please make sure that UTF8 is used as encoding for the best compatibility. You can check this with
|
||||
the following command::
|
||||
|
||||
# sudo -u postgres psql -c 'SHOW SERVER_ENCODING'
|
||||
|
||||
For PostgreSQL database creation, we would do::
|
||||
|
||||
# sudo -u postgres createuser -P pretix
|
||||
# sudo -u postgres createdb -O pretix pretix
|
||||
@@ -178,7 +187,7 @@ named ``/etc/systemd/system/pretix.service`` with the following content::
|
||||
TimeoutStartSec=0
|
||||
ExecStartPre=-/usr/bin/docker kill %n
|
||||
ExecStartPre=-/usr/bin/docker rm %n
|
||||
ExecStart=/usr/bin/docker run --name %n -p 8345:80 \
|
||||
ExecStart=/usr/bin/docker run --name %n -p 127.0.0.1:8345:80 \
|
||||
-v /var/pretix-data:/data \
|
||||
-v /etc/pretix:/etc/pretix \
|
||||
-v /var/run/redis:/var/run/redis \
|
||||
@@ -228,7 +237,7 @@ The following snippet is an example on how to configure a nginx proxy for pretix
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8345/;
|
||||
proxy_pass http://localhost:8345;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Host $http_host;
|
||||
@@ -247,6 +256,8 @@ create an event and start selling tickets!
|
||||
|
||||
You should probably read :ref:`maintainance` next.
|
||||
|
||||
.. _`docker_updates`:
|
||||
|
||||
Updates
|
||||
-------
|
||||
|
||||
@@ -262,6 +273,8 @@ Restarting the service can take a few seconds, especially if the update requires
|
||||
Replace ``stable`` above with a specific version number like ``1.0`` or with ``latest`` for the development
|
||||
version, if you want to.
|
||||
|
||||
Make sure to also read :ref:`update_notes` and the release notes of the version you are updating to.
|
||||
|
||||
.. _`docker_plugininstall`:
|
||||
|
||||
Install a plugin
|
||||
|
||||
@@ -23,8 +23,9 @@ 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`_ 9.5+, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `PostgreSQL`_ 9.6+, `MySQL`_ 5.7+, or MariaDB 10.2.7+ database server
|
||||
* A `redis`_ server
|
||||
* A `nodejs`_ installation
|
||||
|
||||
We also recommend that you use a firewall, although this is not a pretix-specific recommendation. If you're new to
|
||||
Linux and firewalls, we recommend that you start with `ufw`_.
|
||||
@@ -50,7 +51,12 @@ Database
|
||||
--------
|
||||
|
||||
Having the database server installed, we still need a database and a database user. We can create these with any kind
|
||||
of database managing tool or directly on our database's shell. For PostgreSQL, we would do::
|
||||
of database managing tool or directly on our database's shell. Please make sure that UTF8 is used as encoding for the
|
||||
best compatibility. You can check this with the following command::
|
||||
|
||||
# sudo -u postgres psql -c 'SHOW SERVER_ENCODING'
|
||||
|
||||
For PostgreSQL database creation, we would do::
|
||||
|
||||
# sudo -u postgres createuser pretix
|
||||
# sudo -u postgres createdb -O pretix pretix
|
||||
@@ -66,7 +72,7 @@ To build and run pretix, you will need the following debian packages::
|
||||
|
||||
# apt-get install git build-essential python-dev python3-venv python3 python3-pip \
|
||||
python3-dev libxml2-dev libxslt1-dev libffi-dev zlib1g-dev libssl-dev \
|
||||
gettext libpq-dev libmariadbclient-dev libjpeg-dev libopenjp2-7-dev
|
||||
gettext libpq-dev libmariadb-dev libjpeg-dev libopenjp2-7-dev
|
||||
|
||||
Config file
|
||||
-----------
|
||||
@@ -128,12 +134,15 @@ python installation::
|
||||
$ source /var/pretix/venv/bin/activate
|
||||
(venv)$ pip3 install -U pip setuptools wheel
|
||||
|
||||
We now install pretix, its direct dependencies and gunicorn. Replace ``postgres`` with ``mysql`` in the following
|
||||
command if you're running MySQL::
|
||||
We now install pretix, its direct dependencies and gunicorn::
|
||||
|
||||
(venv)$ pip3 install "pretix[postgres]" gunicorn
|
||||
(venv)$ pip3 install pretix gunicorn
|
||||
|
||||
Note that you need Python 3.6 or newer. You can find out your Python version using ``python -V``.
|
||||
If you're running MySQL, also install the client library::
|
||||
|
||||
(venv)$ pip3 install mysqlclient
|
||||
|
||||
Note that you need Python 3.7 or newer. You can find out your Python version using ``python -V``.
|
||||
|
||||
We also need to create a data directory::
|
||||
|
||||
@@ -228,7 +237,7 @@ The following snippet is an example on how to configure a nginx proxy for pretix
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8345/;
|
||||
proxy_pass http://localhost:8345;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Host $http_host;
|
||||
@@ -250,14 +259,14 @@ The following snippet is an example on how to configure a nginx proxy for pretix
|
||||
}
|
||||
|
||||
location /static/ {
|
||||
alias /var/pretix/venv/lib/python3.5/site-packages/pretix/static.dist/;
|
||||
alias /var/pretix/venv/lib/python3.10/site-packages/pretix/static.dist/;
|
||||
access_log off;
|
||||
expires 365d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
}
|
||||
|
||||
.. note:: Remember to replace the ``python3.5`` in the ``/static/`` path in the config
|
||||
.. note:: Remember to replace the ``python3.10`` in the ``/static/`` path in the config
|
||||
above with your python version.
|
||||
|
||||
We recommend reading about setting `strong encryption settings`_ for your web server.
|
||||
@@ -271,21 +280,23 @@ create an event and start selling tickets!
|
||||
|
||||
You should probably read :ref:`maintainance` next.
|
||||
|
||||
.. _`manual_updates`:
|
||||
|
||||
Updates
|
||||
-------
|
||||
|
||||
.. warning:: While we try hard not to break things, **please perform a backup before every upgrade**.
|
||||
|
||||
To upgrade to a new pretix release, pull the latest code changes and run the following commands (again, replace
|
||||
``postgres`` with ``mysql`` if necessary)::
|
||||
To upgrade to a new pretix release, pull the latest code changes and run the following commands::
|
||||
|
||||
$ source /var/pretix/venv/bin/activate
|
||||
(venv)$ pip3 install -U pretix[postgres] gunicorn
|
||||
(venv)$ pip3 install -U --upgrade-strategy eager pretix gunicorn
|
||||
(venv)$ python -m pretix migrate
|
||||
(venv)$ python -m pretix rebuild
|
||||
(venv)$ python -m pretix updatestyles
|
||||
# systemctl restart pretix-web pretix-worker
|
||||
|
||||
Make sure to also read :ref:`update_notes` and the release notes of the version you are updating to.
|
||||
|
||||
.. _`manual_plugininstall`:
|
||||
|
||||
@@ -312,3 +323,4 @@ example::
|
||||
.. _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/
|
||||
.. _nodejs: https://github.com/nodesource/distributions/blob/master/README.md#deb
|
||||
|
||||
@@ -9,6 +9,8 @@ If you host your own pretix instance, you also need to care about the availabili
|
||||
of your service and the safety of your data yourself. This page gives you some
|
||||
information that you might need to do so properly.
|
||||
|
||||
.. _`backups`:
|
||||
|
||||
Backups
|
||||
-------
|
||||
|
||||
|
||||
51
doc/admin/updates.rst
Normal file
@@ -0,0 +1,51 @@
|
||||
.. _`update_notes`:
|
||||
|
||||
Update notes
|
||||
============
|
||||
|
||||
pretix receives regular feature and bugfix updates and we highly encourage you to always update to
|
||||
the latest version for maximum quality and security. Updates are announces on our `blog`_. There are
|
||||
usually 10 feature updates in a year, so you can expect a new release almost every month.
|
||||
|
||||
Pure bugfix releases are only issued in case of very critical bugs or security vulnerabilities. In these
|
||||
case, we'll publish bugfix releases for the last three stable release branches.
|
||||
|
||||
Compatibility to plugins and in very rare cases API clients may break. For in-depth details on the
|
||||
API changes of every version, please refer to the release notes published on our blog.
|
||||
|
||||
Upgrade steps
|
||||
-------------
|
||||
|
||||
For the actual upgrade, you can usually just follow the steps from the installation guide for :ref:`manual installations <manual_updates>`
|
||||
or :ref:`docker installations <docker_updates>` respectively.
|
||||
Generally, it is always strongly recommended to perform a :ref:`backup <backups>` first.
|
||||
It is possible to skip versions during updates, although we recommend not skipping over major version numbers
|
||||
(i.e. if you want to go from 2.4 to 4.4, first upgrade to 3.0, then upgrade to 4.0, then to 4.4).
|
||||
|
||||
In addition to these standard update steps, the following list issues steps that should be taken when you upgrade
|
||||
to specific versions for pretix. If you're skipping versions, please read the instructions for every version in
|
||||
between as well.
|
||||
|
||||
Upgrade to 3.17.0 or newer
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
pretix 3.17 introduces a dependency on ``nodejs``, so you should install it on your system::
|
||||
|
||||
# apt install nodejs npm
|
||||
|
||||
Upgrade to 4.4.0 or newer
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
pretix 4.4 introduces a new data structure to store historical financial data. If you already have existing
|
||||
data in your database, you will need to back-fill this data or you might get incorrect reports! This is not
|
||||
done automatically as part of the usual update steps since it can take a while on large databases and you might
|
||||
want to do it in parallel while the system is already running again. Please execute the following command::
|
||||
|
||||
(venv)$ python -m pretix create_order_transactions
|
||||
|
||||
Or, with a docker installation::
|
||||
|
||||
$ docker exec -it pretix.service pretix create_order_transactions
|
||||
|
||||
|
||||
.. _blog: https://pretix.eu/about/en/blog/
|
||||
@@ -87,7 +87,8 @@ respectively, or ``null`` if there is no such page. You can use those URLs to re
|
||||
respective page.
|
||||
|
||||
The field ``results`` contains a list of objects representing the first results. For most
|
||||
objects, every page contains 50 results.
|
||||
objects, every page contains 50 results. You can specify a lower pagination size using the
|
||||
``page_size`` query parameter, but no more than 50.
|
||||
|
||||
Conditional fetching
|
||||
--------------------
|
||||
@@ -213,13 +214,16 @@ Please note that this also goes for most error responses. For example, if we ret
|
||||
error and you retry with the same ``X-Idempotency-Key``, you will get the same error again, even if you were granted
|
||||
permission in the meantime! This includes internal server errors on our side that might have been fixed in the meantime.
|
||||
|
||||
There are only three exceptions to the rule:
|
||||
There are only the following exceptions to the rule:
|
||||
|
||||
* Responses with status code ``409 Conflict`` are not cached. If you send the request again, it will be executed as a
|
||||
new request, since these responses are intended to be retried.
|
||||
|
||||
* Rate-limited responses with status code ``429 Too Many Requests`` are not cached and you can safely retry them.
|
||||
|
||||
* Responses with status code ``500 Internal Server Error`` are not cached and you can retry them. This is not guaranteed
|
||||
to be safe in all theoretical cases, but 500 by definition is an unforeseen situation and we need to have some way out.
|
||||
|
||||
* Responses with status code ``503 Service Unavailable`` are not cached and you can safely retry them.
|
||||
|
||||
If you send a request with an ``X-Idempotency-Key`` header that we have seen before but that has not yet received a
|
||||
|
||||
@@ -97,7 +97,8 @@ For example, if you want users to be redirected to ``https://example.org/order/r
|
||||
either enter ``https://example.org`` or ``https://example.org/order/``.
|
||||
|
||||
The user will be redirected back to your page instead of pretix' order confirmation page after the payment,
|
||||
**regardless of whether it was successful or not**. Make sure you use our API to check if the payment actually
|
||||
**regardless of whether it was successful or not**. We will append an ``error=…`` query parameter with an error
|
||||
message, but you should not rely on that and instead make sure you use our API to check if the payment actually
|
||||
worked! Your final URL could look like this::
|
||||
|
||||
https://test.pretix.eu/democon/3vjrh/order/NSLEZ/ujbrnsjzbq4dzhck/pay/123/?return_url=https%3A%2F%2Fexample.org%2Forder%2Freturn%3Ftx_id%3D1234
|
||||
|
||||
@@ -243,6 +243,99 @@ Cart position endpoints
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to create this
|
||||
order.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/cartpositions/bulk_create/
|
||||
|
||||
Creates multiple new cart position. This operation is deliberately not atomic, so each cart position can succeed
|
||||
or fail individually, so the response code of the response is not the only thing to look at!
|
||||
|
||||
.. warning:: This endpoint is considered **experimental**. It might change at any time without prior notice.
|
||||
|
||||
.. warning:: The same limitations as with the regular creation endpoint apply.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/cartpositions/bulk_create/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
{
|
||||
"item": 1,
|
||||
"variation": null,
|
||||
"price": "23.00",
|
||||
"attendee_name_parts": {
|
||||
"given_name": "Peter",
|
||||
"family_name": "Miller"
|
||||
},
|
||||
"attendee_email": null,
|
||||
"answers": [
|
||||
{
|
||||
"question": 1,
|
||||
"answer": "23",
|
||||
"options": []
|
||||
}
|
||||
],
|
||||
"subevent": null
|
||||
},
|
||||
{
|
||||
"item": 1,
|
||||
"variation": null,
|
||||
"price": "23.00",
|
||||
"attendee_name_parts": {
|
||||
"given_name": "Maria",
|
||||
"family_name": "Miller"
|
||||
},
|
||||
"attendee_email": null,
|
||||
"answers": [
|
||||
{
|
||||
"question": 1,
|
||||
"answer": "23",
|
||||
"options": []
|
||||
}
|
||||
],
|
||||
"subevent": null
|
||||
}
|
||||
]
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"success": true,
|
||||
"errors": null,
|
||||
"data": {
|
||||
"id": 1,
|
||||
...
|
||||
},
|
||||
},
|
||||
{
|
||||
"success": "false",
|
||||
"errors": {
|
||||
"non_field_errors": ["There is not enough quota available on quota \"Tickets\" to perform the operation."]
|
||||
},
|
||||
"data": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer of the event to create positions for
|
||||
:param event: The ``slug`` field of the event to create positions for
|
||||
:statuscode 200: See response for success
|
||||
:statuscode 400: Your input could not be parsed
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to create this
|
||||
order.
|
||||
|
||||
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/cartpositions/(id)/
|
||||
|
||||
Deletes a cart position, identified by its internal ID.
|
||||
|
||||
@@ -362,6 +362,42 @@ Endpoints
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/checkinlists/(list)/failed_checkins/
|
||||
|
||||
Stores a failed check-in. Only necessary for statistical purposes if you perform scan validation offline.
|
||||
|
||||
:<json boolean error_reason: One of ``canceled``, ``invalid``, ``unpaid``, ``product``, ``rules``, ``revoked``,
|
||||
``incomplete``, ``already_redeemed``, or ``error``. Required.
|
||||
:<json raw_barcode: The raw barcode you scanned. Required.
|
||||
:<json datetime: Date and time of the scan. Optional.
|
||||
:<json type: Type of scan, defaults to ``"entry"``.
|
||||
:<json position: Internal ID of an order position you matched. Optional.
|
||||
:<json raw_item: Internal ID of an item you matched. Optional.
|
||||
:<json raw_variation: Internal ID of an item variation you matched. Optional.
|
||||
:<json raw_subevent: Internal ID of an event series date you matched. Optional.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/checkinlists/1/failed_checkins/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
|
||||
{
|
||||
"raw_barcode": "Pvrk50vUzQd0DhdpNRL4I4OcXsvg70uA",
|
||||
"error_reason": "canceled"
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:param list: The ID of the check-in list to save for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: Invalid request
|
||||
: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 position or check-in list does not exist.
|
||||
|
||||
|
||||
Order position endpoints
|
||||
------------------------
|
||||
@@ -424,6 +460,9 @@ Order position endpoints
|
||||
"checkins": [
|
||||
{
|
||||
"list": 1,
|
||||
"type": "entry",
|
||||
"gate": null,
|
||||
"device": 2,
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": true
|
||||
}
|
||||
@@ -494,8 +533,6 @@ Order position endpoints
|
||||
* If ``attendee_name`` is empty, it will automatically fall back to values from a parent product or from invoice
|
||||
addresses.
|
||||
|
||||
**Instead of an ID, you can also use the ``secret`` field as the lookup parameter.**
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
@@ -537,6 +574,9 @@ Order position endpoints
|
||||
{
|
||||
"list": 1,
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"type": "entry",
|
||||
"gate": null,
|
||||
"device": 2,
|
||||
"auto_checked_in": true
|
||||
}
|
||||
],
|
||||
@@ -564,12 +604,14 @@ Order position endpoints
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||
:statuscode 404: The requested order position or check-in list does not exist.
|
||||
|
||||
.. _`rest-checkin-redeem`:
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/checkinlists/(list)/positions/(id)/redeem/
|
||||
|
||||
Tries to redeem an order position, identified by its internal ID, i.e. checks the attendee in. This endpoint
|
||||
accepts a number of optional requests in the body.
|
||||
|
||||
**Instead of an ID, you can also use the ``secret`` field as the lookup parameter.**
|
||||
**Tip:** Instead of an ID, you can also use the ``secret`` field as the lookup parameter.
|
||||
|
||||
:<json boolean questions_supported: When this parameter is set to ``true``, handling of questions is supported. If
|
||||
you do not implement question handling in your user interface, you **must**
|
||||
@@ -578,8 +620,9 @@ Order position endpoints
|
||||
:<json boolean canceled_supported: When this parameter is set to ``true``, the response code ``canceled`` may be
|
||||
returned. Otherwise, canceled orders will return ``unpaid``.
|
||||
:<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 boolean force: Specifies that the check-in should succeed regardless of revoked barcode, previous check-ins or required
|
||||
questions that have not been filled. This is usually used to upload offline scans that already happened,
|
||||
because there's no point in validating them since they happened whether they are valid or not. 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
|
||||
@@ -697,6 +740,9 @@ Order position endpoints
|
||||
* ``product`` - Tickets with this product may not be scanned at this device
|
||||
* ``rules`` - Check-in prevented by a user-defined rule
|
||||
|
||||
In case of reason ``rules``, there might be an additional response field ``reason_explanation`` with a human-readable
|
||||
description of the violated rules. However, that field can also be missing or be ``null``.
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:param list: The ID of the check-in list to look for
|
||||
|
||||
238
doc/api/resources/customers.rst
Normal file
@@ -0,0 +1,238 @@
|
||||
.. _`rest-customers`:
|
||||
|
||||
Customers
|
||||
=========
|
||||
|
||||
Resource description
|
||||
--------------------
|
||||
|
||||
The customer resource contains the following public fields:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
identifier string Internal ID of the customer
|
||||
email string Customer email address
|
||||
name string Name of this customer (or ``null``)
|
||||
name_parts object of strings Decomposition of name (i.e. given name, family name)
|
||||
is_active boolean Whether this account is active
|
||||
is_verified boolean Whether the email address of this account has been
|
||||
verified
|
||||
last_login datetime Date and time of last login
|
||||
date_joined datetime Date and time of registration
|
||||
locale string Preferred language of the customer
|
||||
last_modified datetime Date and time of modification of the record
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
.. versionadded:: 4.0
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/customers/
|
||||
|
||||
Returns a list of all customers registered with a given organizer.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/customers/ 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": [
|
||||
{
|
||||
"identifier": "8WSAJCJ",
|
||||
"email": "customer@example.org",
|
||||
"name": "John Doe",
|
||||
"name_parts": {
|
||||
"_scheme": "full",
|
||||
"full_name": "John Doe"
|
||||
},
|
||||
"is_active": true,
|
||||
"is_verified": false,
|
||||
"last_login": null,
|
||||
"date_joined": "2021-04-06T13:44:22.809216Z",
|
||||
"locale": "de",
|
||||
"last_modified": "2021-04-06T13:44:22.809377Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query string email: Only fetch customers with this email address
|
||||
: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)/customers/(identifier)/
|
||||
|
||||
Returns information on one customer, identified by its identifier.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/customers/8WSAJCJ/ 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
|
||||
|
||||
{
|
||||
"identifier": "8WSAJCJ",
|
||||
"email": "customer@example.org",
|
||||
"name": "John Doe",
|
||||
"name_parts": {
|
||||
"_scheme": "full",
|
||||
"full_name": "John Doe"
|
||||
},
|
||||
"is_active": true,
|
||||
"is_verified": false,
|
||||
"last_login": null,
|
||||
"date_joined": "2021-04-06T13:44:22.809216Z",
|
||||
"locale": "de",
|
||||
"last_modified": "2021-04-06T13:44:22.809377Z"
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param identifier: The ``identifier`` field of the customer 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)/customers/
|
||||
|
||||
Creates a new customer
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/customers/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "test@example.org"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"identifier": "8WSAJCJ",
|
||||
"email": "test@example.org",
|
||||
...
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to create a customer for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The customer 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)/customers/(identifier)/
|
||||
|
||||
Update a customer. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide all fields of
|
||||
the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the fields that you
|
||||
want to change.
|
||||
|
||||
You can change all fields of the resource except the ``identifier``, ``last_login``, ``date_joined``, ``name``,
|
||||
and ``last_modified`` fields.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /api/v1/organizers/bigevents/customers/8WSAJCJ/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 94
|
||||
|
||||
{
|
||||
"email": "test@example.org"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"identifier": "8WSAJCJ",
|
||||
"email": "test@example.org",
|
||||
…
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
:param identifier: The ``identifier`` field of the customer to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The customer 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.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/customers/(identifier)/anonymize/
|
||||
|
||||
Anonymize a customer. Deletes personal data and disconnects from existing orders.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/customers/8WSAJCJ/anonymize/ 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
|
||||
|
||||
{
|
||||
"identifier": "8WSAJCJ",
|
||||
"email": null,
|
||||
…
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
:param identifier: The ``identifier`` field of the customer to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The customer 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.
|
||||
@@ -80,6 +80,16 @@ Endpoints
|
||||
|
||||
The events resource can now be filtered by meta data attributes.
|
||||
|
||||
.. versionchanged:: 4.0
|
||||
|
||||
The ``clone_from`` parameter has been added to the event creation endpoint.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
The ``with_availability_for`` parameter has been added.
|
||||
|
||||
The ``search`` query parameter has been added to filter events by their slug, name, or location in any language.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/
|
||||
|
||||
Returns a list of all events within a given organizer the authenticated user/token has access to.
|
||||
@@ -158,6 +168,11 @@ Endpoints
|
||||
events having set their ``Format`` meta data to ``Seminar``, ``?attr[Format]=`` only those, that have no value
|
||||
set. Please note that this filter will respect default values set on organizer level.
|
||||
:query sales_channel: If set to a sales channel identifier, only events allowed to be sold on the specified sales channel are returned.
|
||||
:query with_availability_for: If set to a sales channel identifier, the response will contain a special ``best_availability_state``
|
||||
attribute with values of 100 for "tickets available", values less than 100 for "tickets sold out or reserved",
|
||||
and ``null`` for "status unknown". These values might be served from a cache. This parameter can make the response
|
||||
slow.
|
||||
:query search: Only return events matching a given search query.
|
||||
:param organizer: The ``slug`` field of a valid organizer
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
@@ -321,6 +336,9 @@ Endpoints
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer of the event to create.
|
||||
:query clone_from: Set to ``event_slug`` to clone data (settings, products, …) from an event with this slug in the
|
||||
same organizer or to ``organizer_slug/event_slug`` to clone from an event within a different
|
||||
organizer.
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The event could not be created due to invalid submitted data.
|
||||
:statuscode 401: Authentication failure
|
||||
@@ -335,7 +353,8 @@ Endpoints
|
||||
If the ``plugins``, ``has_subevents`` and/or ``is_public`` fields are present in the post body this will determine their
|
||||
value. Otherwise their value will be copied from the existing event.
|
||||
|
||||
Please note that you can only copy from events under the same organizer.
|
||||
Please note that you can only copy from events under the same organizer this way. Use the ``clone_from`` parameter
|
||||
when creating a new event for this instead.
|
||||
|
||||
Permission required: "Can create events"
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ Resources and endpoints
|
||||
vouchers
|
||||
checkinlists
|
||||
waitinglist
|
||||
customers
|
||||
membershiptypes
|
||||
memberships
|
||||
giftcards
|
||||
carts
|
||||
teams
|
||||
@@ -28,5 +31,6 @@ Resources and endpoints
|
||||
webhooks
|
||||
seatingplans
|
||||
exporters
|
||||
sendmail_rules
|
||||
billing_invoices
|
||||
billing_var
|
||||
|
||||
@@ -58,6 +58,21 @@ lines list of objects The actual invo
|
||||
created before this field was introduced as well as for
|
||||
all lines not created by a product (e.g. a shipping or
|
||||
cancellation fee).
|
||||
├ subevent integer Event series date ID used to create this line. Note that everything
|
||||
about the subevent might have changed since the creation
|
||||
of the invoice. Can be ``null`` for all invoice lines
|
||||
created before this field was introduced as well as for
|
||||
all lines not created by a product (e.g. a shipping or
|
||||
cancellation fee) as well as for all events that are not a series.
|
||||
├ fee_type string Fee type, e.g. ``shipping``, ``service``, ``payment``,
|
||||
``cancellation``, ``giftcard``, or ``other. Can be ``null`` for
|
||||
all invoice lines
|
||||
created before this field was introduced as well as for
|
||||
all lines not created by a fee (e.g. a product).
|
||||
├ fee_internal_type string Additional fee type, e.g. type of payment provider. Can be ``null``
|
||||
for all invoice lines
|
||||
created before this field was introduced as well as for
|
||||
all lines not created by a fee (e.g. a product).
|
||||
├ event_date_from datetime Start date of the (sub)event this line was created for as it
|
||||
was set during invoice creation. Can be ``null`` for all invoice
|
||||
lines created before this was introduced as well as for lines in
|
||||
@@ -69,6 +84,12 @@ lines list of objects The actual invo
|
||||
an event series not created by a product (e.g. shipping or
|
||||
cancellation fees) as well as whenever the respective (sub)event
|
||||
has no end date set.
|
||||
├ event_location string Location of the (sub)event this line was created for as it
|
||||
was set during invoice creation. Can be ``null`` for all invoice
|
||||
lines created before this was introduced as well as for lines in
|
||||
an event series not created by a product (e.g. shipping or
|
||||
cancellation fees) as well as whenever the respective (sub)event
|
||||
has no location set.
|
||||
├ attendee_name string Attendee name at time of invoice creation. Can be ``null`` if no
|
||||
name was set or if names are configured to not be added to invoices.
|
||||
├ gross_value money (string) Price including taxes
|
||||
@@ -97,6 +118,18 @@ internal_reference string Customer's refe
|
||||
``lines.event_date_to``, and ``lines.attendee_name`` have been added.
|
||||
``refers`` now returns an invoice number including the prefix.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
The attributes ``fee_type`` and ``fee_internal_type`` have been added.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
The attribute ``lines.event_location`` has been added.
|
||||
|
||||
.. versionchanged:: 4.6
|
||||
|
||||
The attribute ``lines.subevent`` has been added.
|
||||
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
@@ -162,8 +195,12 @@ Endpoints
|
||||
"description": "Budget Ticket",
|
||||
"item": 1234,
|
||||
"variation": 245,
|
||||
"subevent": null,
|
||||
"fee_type": null,
|
||||
"fee_internal_type": null,
|
||||
"event_date_from": "2017-12-27T10:00:00Z",
|
||||
"event_date_to": null,
|
||||
"event_location": "Heidelberg",
|
||||
"attendee_name": null,
|
||||
"gross_value": "23.00",
|
||||
"tax_value": "0.00",
|
||||
@@ -248,8 +285,12 @@ Endpoints
|
||||
"description": "Budget Ticket",
|
||||
"item": 1234,
|
||||
"variation": 245,
|
||||
"subevent": null,
|
||||
"fee_type": null,
|
||||
"fee_internal_type": null,
|
||||
"event_date_from": "2017-12-27T10:00:00Z",
|
||||
"event_date_to": null,
|
||||
"event_location": "Heidelberg",
|
||||
"attendee_name": null,
|
||||
"gross_value": "23.00",
|
||||
"tax_value": "0.00",
|
||||
|
||||
@@ -24,6 +24,25 @@ active boolean If ``false``, t
|
||||
description multi-lingual string A public description of the variation. May contain
|
||||
Markdown syntax or can be ``null``.
|
||||
position integer An integer, used for sorting
|
||||
require_approval boolean If ``true``, orders with this variation will need to be
|
||||
approved by the event organizer before they can be
|
||||
paid.
|
||||
require_membership boolean If ``true``, booking this variation requires an active membership.
|
||||
require_membership_hidden boolean If ``true`` and ``require_membership`` is set, this variation will
|
||||
be hidden from users without a valid membership.
|
||||
require_membership_types list of integers Internal IDs of membership types valid if ``require_membership`` is ``true``
|
||||
sales_channels list of strings Sales channels this variation is available on, such as
|
||||
``"web"`` or ``"resellers"``. Defaults to all existing sales channels.
|
||||
The item-level list takes precedence, i.e. a sales
|
||||
channel needs to be on both lists for the item to be
|
||||
available.
|
||||
available_from datetime The first date time at which this variation can be bought
|
||||
(or ``null``).
|
||||
available_until datetime The last date time at which this variation can be bought
|
||||
(or ``null``).
|
||||
hide_without_voucher boolean If ``true``, this variation is only shown during the voucher
|
||||
redemption process, but not in the normal shop
|
||||
frontend.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
Endpoints
|
||||
@@ -60,6 +79,14 @@ Endpoints
|
||||
"en": "S"
|
||||
},
|
||||
"active": true,
|
||||
"require_approval": false,
|
||||
"require_membership": false,
|
||||
"require_membership_hidden": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": {
|
||||
"en": "Test2"
|
||||
},
|
||||
@@ -74,6 +101,10 @@ Endpoints
|
||||
"en": "L"
|
||||
},
|
||||
"active": true,
|
||||
"require_approval": false,
|
||||
"require_membership": false,
|
||||
"require_membership_hidden": false,
|
||||
"require_membership_types": [],
|
||||
"description": {},
|
||||
"position": 1,
|
||||
"default_price": null,
|
||||
@@ -121,6 +152,14 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_approval": false,
|
||||
"require_membership": false,
|
||||
"require_membership_hidden": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
}
|
||||
@@ -150,6 +189,14 @@ Endpoints
|
||||
"value": {"en": "Student"},
|
||||
"default_price": "10.00",
|
||||
"active": true,
|
||||
"require_approval": false,
|
||||
"require_membership": false,
|
||||
"require_membership_hidden": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
}
|
||||
@@ -169,6 +216,14 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_approval": false,
|
||||
"require_membership": false,
|
||||
"require_membership_hidden": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
}
|
||||
@@ -219,6 +274,14 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": false,
|
||||
"require_approval": false,
|
||||
"require_membership": false,
|
||||
"require_membership_hidden": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 1
|
||||
}
|
||||
|
||||
@@ -69,6 +69,18 @@ require_approval boolean If ``true``, or
|
||||
approved by the event organizer before they can be
|
||||
paid.
|
||||
require_bundling boolean If ``true``, this item is only available as part of bundles.
|
||||
require_membership boolean If ``true``, booking this item requires an active membership.
|
||||
require_membership_hidden boolean If ``true`` and ``require_membership`` is set, this product will
|
||||
be hidden from users without a valid membership.
|
||||
require_membership_types list of integers Internal IDs of membership types valid if ``require_membership`` is ``true``
|
||||
grant_membership_type integer If set to the internal ID of a membership type, purchasing this item will
|
||||
create a membership of the given type.
|
||||
grant_membership_duration_like_event boolean If ``true``, the membership created through ``grant_membership_type`` will derive
|
||||
its term from ``date_from`` to ``date_to`` of the purchased (sub)event.
|
||||
grant_membership_duration_days integer If ``grant_membership_duration_like_event`` is ``false``, this sets the number of
|
||||
days for the membership.
|
||||
grant_membership_duration_months integer If ``grant_membership_duration_like_event`` is ``false``, this sets the number of
|
||||
calendar months for the membership.
|
||||
generate_tickets boolean If ``false``, tickets are never generated for this
|
||||
product, regardless of other settings. If ``true``,
|
||||
tickets are generated even if this is a
|
||||
@@ -94,7 +106,23 @@ variations list of objects A list with one
|
||||
for price calculations (or ``null``).
|
||||
├ active boolean If ``false``, this variation will not be sold or shown.
|
||||
├ description multi-lingual string A public description of the variation. May contain
|
||||
├ require_membership boolean If ``true``, booking this variation requires an active membership.
|
||||
├ require_membership_hidden boolean If ``true`` and ``require_membership`` is set, this variation will
|
||||
be hidden from users without a valid membership.
|
||||
├ require_membership_types list of integers Internal IDs of membership types valid if ``require_membership`` is ``true``
|
||||
Markdown syntax or can be ``null``.
|
||||
├ sales_channels list of strings Sales channels this variation is available on, such as
|
||||
``"web"`` or ``"resellers"``. Defaults to all existing sales channels.
|
||||
The item-level list takes precedence, i.e. a sales
|
||||
channel needs to be on both lists for the item to be
|
||||
available.
|
||||
├ available_from datetime The first date time at which this variation can be bought
|
||||
(or ``null``).
|
||||
├ available_until datetime The last date time at which this variation can be bought
|
||||
(or ``null``).
|
||||
├ hide_without_voucher boolean If ``true``, this variation is only shown during the voucher
|
||||
redemption process, but not in the normal shop
|
||||
frontend.
|
||||
└ position integer An integer, used for sorting
|
||||
addons list of objects Definition of add-ons that can be chosen for this item.
|
||||
Only writable during creation,
|
||||
@@ -126,6 +154,15 @@ meta_data object Values set for
|
||||
|
||||
The attribute ``multi_allowed`` has been added to ``addons``.
|
||||
|
||||
.. versionchanged:: 4.0
|
||||
|
||||
The attributes ``require_membership``, ``require_membership_types``, ``grant_membership_type``, ``grant_membership_duration_like_event``,
|
||||
``grant_membership_duration_days`` and ``grant_membership_duration_months`` have been added.
|
||||
|
||||
.. versionchanged:: 4.4
|
||||
|
||||
The attributes ``require_membership_hidden`` attribute has been added.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
@@ -198,6 +235,12 @@ Endpoints
|
||||
"show_quota_left": null,
|
||||
"require_approval": false,
|
||||
"require_bundling": false,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"grant_membership_type": null,
|
||||
"grant_membership_duration_like_event": true,
|
||||
"grant_membership_duration_days": 0,
|
||||
"grant_membership_duration_months": 0,
|
||||
"variations": [
|
||||
{
|
||||
"value": {"en": "Student"},
|
||||
@@ -205,6 +248,12 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
},
|
||||
@@ -214,6 +263,12 @@ Endpoints
|
||||
"price": "23.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 1
|
||||
}
|
||||
@@ -294,6 +349,12 @@ Endpoints
|
||||
"has_variations": false,
|
||||
"require_approval": false,
|
||||
"require_bundling": false,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"grant_membership_type": null,
|
||||
"grant_membership_duration_like_event": true,
|
||||
"grant_membership_duration_days": 0,
|
||||
"grant_membership_duration_months": 0,
|
||||
"variations": [
|
||||
{
|
||||
"value": {"en": "Student"},
|
||||
@@ -301,7 +362,13 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"description": null,
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"position": 0
|
||||
},
|
||||
{
|
||||
@@ -310,6 +377,12 @@ Endpoints
|
||||
"price": "23.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 1
|
||||
}
|
||||
@@ -370,6 +443,12 @@ Endpoints
|
||||
"checkin_attention": false,
|
||||
"require_approval": false,
|
||||
"require_bundling": false,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"grant_membership_type": null,
|
||||
"grant_membership_duration_like_event": true,
|
||||
"grant_membership_duration_days": 0,
|
||||
"grant_membership_duration_months": 0,
|
||||
"variations": [
|
||||
{
|
||||
"value": {"en": "Student"},
|
||||
@@ -377,6 +456,12 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
},
|
||||
@@ -386,6 +471,12 @@ Endpoints
|
||||
"price": "23.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 1
|
||||
}
|
||||
@@ -435,6 +526,12 @@ Endpoints
|
||||
"has_variations": true,
|
||||
"require_approval": false,
|
||||
"require_bundling": false,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"grant_membership_type": null,
|
||||
"grant_membership_duration_like_event": true,
|
||||
"grant_membership_duration_days": 0,
|
||||
"grant_membership_duration_months": 0,
|
||||
"variations": [
|
||||
{
|
||||
"value": {"en": "Student"},
|
||||
@@ -442,6 +539,12 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
},
|
||||
@@ -451,6 +554,12 @@ Endpoints
|
||||
"price": "23.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 1
|
||||
}
|
||||
@@ -531,6 +640,12 @@ Endpoints
|
||||
"has_variations": true,
|
||||
"require_approval": false,
|
||||
"require_bundling": false,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"grant_membership_type": null,
|
||||
"grant_membership_duration_like_event": true,
|
||||
"grant_membership_duration_days": 0,
|
||||
"grant_membership_duration_months": 0,
|
||||
"variations": [
|
||||
{
|
||||
"value": {"en": "Student"},
|
||||
@@ -538,6 +653,12 @@ Endpoints
|
||||
"price": "10.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 0
|
||||
},
|
||||
@@ -547,6 +668,12 @@ Endpoints
|
||||
"price": "23.00",
|
||||
"original_price": null,
|
||||
"active": true,
|
||||
"require_membership": false,
|
||||
"require_membership_types": [],
|
||||
"sales_channels": ["web"],
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"hide_without_voucher": false,
|
||||
"description": null,
|
||||
"position": 1
|
||||
}
|
||||
|
||||
216
doc/api/resources/memberships.rst
Normal file
@@ -0,0 +1,216 @@
|
||||
Memberships
|
||||
===========
|
||||
|
||||
Resource description
|
||||
--------------------
|
||||
|
||||
The membership resource contains the following public fields:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
id integer Internal ID of the membership
|
||||
customer string Identifier of the customer associated with this membership (can't be changed)
|
||||
testmode boolean Whether this is a test membership
|
||||
membership_type integer Internal ID of the membership type
|
||||
date_start datetime Start of validity
|
||||
date_end datetime End of validity
|
||||
attendee_name_parts object JSON representation of components of an attendee name (configuration dependent)
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/memberships/
|
||||
|
||||
Returns a list of all memberships within a given organizer.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/memberships/ 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": 2,
|
||||
"customer": "EGR9SYT",
|
||||
"membership_type": 1,
|
||||
"testmode": false,
|
||||
"date_start": "2021-04-19T00:00:00+02:00",
|
||||
"date_end": "2021-04-20T00:00:00+02:00",
|
||||
"attendee_name_parts": {
|
||||
"_scheme": "title_given_family",
|
||||
"family_name": "Doe",
|
||||
"given_name": "John",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query string customer: A customer identifier to filter for
|
||||
:query integer membership_type: A membership type ID to filter for
|
||||
:query boolean testmode: Filter for memberships that are (not) in test mode.
|
||||
: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)/memberships/(id)/
|
||||
|
||||
Returns information on one membership, identified by its ID.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/memberships/2/ 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": 2,
|
||||
"customer": "EGR9SYT",
|
||||
"membership_type": 1,
|
||||
"testmode": false,
|
||||
"date_start": "2021-04-19T00:00:00+02:00",
|
||||
"date_end": "2021-04-20T00:00:00+02:00",
|
||||
"attendee_name_parts": {
|
||||
"_scheme": "title_given_family",
|
||||
"family_name": "Doe",
|
||||
"given_name": "John",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param id: The ``id`` field of the membership 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)/memberships/
|
||||
|
||||
Creates a new membership
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/memberships/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"membership_type": 2,
|
||||
"customer": "EGR9SYT",
|
||||
"testmode": false,
|
||||
"date_start": "2021-04-19T00:00:00+02:00",
|
||||
"date_end": "2021-04-20T00:00:00+02:00",
|
||||
"attendee_name_parts": {
|
||||
"_scheme": "title_given_family",
|
||||
"family_name": "Doe",
|
||||
"given_name": "John",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 3,
|
||||
"membership_type": 2,
|
||||
"customer": "EGR9SYT",
|
||||
"testmode": false,
|
||||
"date_start": "2021-04-19T00:00:00+02:00",
|
||||
"date_end": "2021-04-20T00:00:00+02:00",
|
||||
"attendee_name_parts": {
|
||||
"_scheme": "title_given_family",
|
||||
"family_name": "Doe",
|
||||
"given_name": "John",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to create a membership for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The membership 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)/memberships/(id)/
|
||||
|
||||
Update a membership. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide all fields of
|
||||
the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the fields that you
|
||||
want to change.
|
||||
|
||||
You can change all fields of the resource except the ``id``, ``customer``, and ``testmode`` fields.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /api/v1/organizers/bigevents/memberships/1/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 94
|
||||
|
||||
{
|
||||
"membership_type": 3
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"membership_type": 3,
|
||||
…
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
:param id: The ``id`` field of the membership to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The membership 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.
|
||||
|
||||
227
doc/api/resources/membershiptypes.rst
Normal file
@@ -0,0 +1,227 @@
|
||||
Membership types
|
||||
================
|
||||
|
||||
Resource description
|
||||
--------------------
|
||||
|
||||
The membership type resource contains the following public fields:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
id integer Internal ID of the membership type
|
||||
name multi-lingual string Human-readable name of the type
|
||||
transferable boolean Whether a membership of this type can be used by
|
||||
multiple persons
|
||||
allow_parallel_usage boolean Whether a membership of this type can be used for
|
||||
multiple parallel tickets
|
||||
max_usages integer Maximum number of times a membership of this type can be
|
||||
used.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/membershiptypes/
|
||||
|
||||
Returns a list of all membership types within a given organizer.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/membershiptypes/ 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": 2,
|
||||
"name": {
|
||||
"de": "Wochenkarte",
|
||||
"en": "Week pass"
|
||||
},
|
||||
"transferable": false,
|
||||
"allow_parallel_usage": false,
|
||||
"max_usages": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
: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)/membershiptypes/(id)/
|
||||
|
||||
Returns information on one membership type, identified by its ID.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/membershiptypes/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,
|
||||
"name": {
|
||||
"de": "Wochenkarte",
|
||||
"en": "Week pass"
|
||||
},
|
||||
"transferable": false,
|
||||
"allow_parallel_usage": false,
|
||||
"max_usages": 7
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param id: The ``id`` field of the membership type 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)/membershiptypes/
|
||||
|
||||
Creates a new membership type
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/membershiptypes/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": {
|
||||
"de": "Wochenkarte",
|
||||
"en": "Week pass"
|
||||
},
|
||||
"transferable": false,
|
||||
"allow_parallel_usage": false,
|
||||
"max_usages": 7
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 3,
|
||||
"name": {
|
||||
"de": "Wochenkarte",
|
||||
"en": "Week pass"
|
||||
},
|
||||
"transferable": false,
|
||||
"allow_parallel_usage": false,
|
||||
"max_usages": 7
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to create a membership type for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The membership type 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)/membershiptypes/(id)/
|
||||
|
||||
Update a membership type. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide all fields of
|
||||
the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the fields that you
|
||||
want to change.
|
||||
|
||||
You can change all fields of the resource except the ``id`` field.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
PATCH /api/v1/organizers/bigevents/membershiptypes/2/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 94
|
||||
|
||||
{
|
||||
"max_usages": 3
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 2,
|
||||
"name": {
|
||||
"de": "Wochenkarte",
|
||||
"en": "Week pass"
|
||||
},
|
||||
"transferable": false,
|
||||
"allow_parallel_usage": false,
|
||||
"max_usages": 3
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
:param id: The ``id`` field of the membership type to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The membership 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.
|
||||
|
||||
.. http:delete:: /api/v1/organizers/(organizer)/membershiptypes/(id)/
|
||||
|
||||
Delete a membership type. You can not delete types which have already been used.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
DELETE /api/v1/organizers/bigevents/membershiptype/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 id: The ``id`` field of the type to delete
|
||||
:statuscode 204: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to delete this resource **or** the membership type is currently in use.
|
||||
@@ -31,6 +31,7 @@ testmode boolean If ``true``, th
|
||||
secret string The secret contained in the link sent to the customer
|
||||
email string The customer email address
|
||||
phone string The customer phone number
|
||||
customer string The customer account identifier (or ``null``)
|
||||
locale string The locale used for communication with this customer
|
||||
sales_channel string Channel this sale was created through, such as
|
||||
``"web"``.
|
||||
@@ -40,6 +41,7 @@ payment_date date **DEPRECATED AN
|
||||
payment_provider string **DEPRECATED AND INACCURATE** Payment provider used for this order
|
||||
total money (string) Total value of this order
|
||||
comment string Internal comment on this order
|
||||
custom_followup_at date Internal date for a custom follow-up action
|
||||
checkin_attention boolean If ``true``, the check-in app should show a warning
|
||||
that this ticket requires special attention if a ticket
|
||||
of this order is scanned.
|
||||
@@ -118,6 +120,22 @@ last_modified datetime Last modificati
|
||||
|
||||
The ``phone`` attribute has been added.
|
||||
|
||||
.. versionchanged:: 4.0
|
||||
|
||||
The ``customer`` attribute has been added.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
The ``custom_followup_at`` attribute has been added.
|
||||
|
||||
.. versionchanged:: 4.4
|
||||
|
||||
The ``item`` and ``variation`` query parameters have been added.
|
||||
|
||||
.. versionchanged:: 4.6
|
||||
|
||||
The ``subevent`` query parameters has been added.
|
||||
|
||||
|
||||
.. _order-position-resource:
|
||||
|
||||
@@ -155,11 +173,13 @@ secret string Secret code pri
|
||||
addon_to integer Internal ID of the position this position is an add-on for (or ``null``)
|
||||
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
|
||||
checkins list of objects List of **successful** 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``)
|
||||
├ gate integer Internal ID of the gate. Can be ``null``.
|
||||
├ device integer Internal ID of the device. Can be ``null``.
|
||||
└ 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``)
|
||||
@@ -289,6 +309,7 @@ List of all orders
|
||||
"url": "https://test.pretix.eu/dummy/dummy/order/ABC12/k24fiuwvu8kxz3y1/",
|
||||
"email": "tester@example.org",
|
||||
"phone": "+491234567",
|
||||
"customer": null,
|
||||
"locale": "en",
|
||||
"sales_channel": "web",
|
||||
"datetime": "2017-12-01T10:00:00Z",
|
||||
@@ -299,6 +320,7 @@ List of all orders
|
||||
"fees": [],
|
||||
"total": "23.00",
|
||||
"comment": "",
|
||||
"custom_followup_at": null,
|
||||
"checkin_attention": false,
|
||||
"require_approval": false,
|
||||
"invoice_address": {
|
||||
@@ -349,6 +371,8 @@ List of all orders
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"gate": null,
|
||||
"device": 2,
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -399,6 +423,8 @@ List of all orders
|
||||
: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 integer item: Only return orders with a position that contains this item ID. *Warning:* Result will also include orders if they contain mixed items, and it will even return orders where the item is only contained in a canceled position.
|
||||
:query integer variation: Only return orders with a position that contains this variation ID. *Warning:* Result will also include orders if they contain mixed items and variations, and it will even return orders where the variation is only contained in a canceled position.
|
||||
: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.
|
||||
@@ -411,6 +437,7 @@ 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 integer subevent: Only return orders with a position that contains this subevent ID. *Warning:* Result will also include orders if they contain mixed subevents, and it will even return orders where the subevent is only contained in a canceled position.
|
||||
:query datetime subevent_after: Only return orders that contain a ticket for a subevent taking place after the given date. This is an exclusive after, and it considers the **end** of the subevent (or its start, if the end is not set).
|
||||
:query datetime subevent_before: Only return orders that contain a ticket for a subevent taking place after the given date. This is an exclusive before, and it considers the **start** of the subevent.
|
||||
: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.
|
||||
@@ -457,6 +484,7 @@ Fetching individual orders
|
||||
"url": "https://test.pretix.eu/dummy/dummy/order/ABC12/k24fiuwvu8kxz3y1/",
|
||||
"email": "tester@example.org",
|
||||
"phone": "+491234567",
|
||||
"customer": null,
|
||||
"locale": "en",
|
||||
"sales_channel": "web",
|
||||
"datetime": "2017-12-01T10:00:00Z",
|
||||
@@ -467,6 +495,7 @@ Fetching individual orders
|
||||
"fees": [],
|
||||
"total": "23.00",
|
||||
"comment": "",
|
||||
"custom_followup_at": null,
|
||||
"checkin_attention": false,
|
||||
"require_approval": false,
|
||||
"invoice_address": {
|
||||
@@ -517,6 +546,8 @@ Fetching individual orders
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"gate": null,
|
||||
"device": 2,
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -631,6 +662,8 @@ Updating order fields
|
||||
|
||||
* ``comment``
|
||||
|
||||
* ``custom_followup_at``
|
||||
|
||||
* ``invoice_address`` (you always need to supply the full object, or ``null`` to delete the current address)
|
||||
|
||||
**Example request**:
|
||||
@@ -775,6 +808,8 @@ Creating orders
|
||||
|
||||
* does not support redeeming gift cards
|
||||
|
||||
* does not support or validate memberships
|
||||
|
||||
You can supply the following fields of the resource:
|
||||
|
||||
* ``code`` (optional)
|
||||
@@ -783,6 +818,7 @@ Creating orders
|
||||
or in state ``confirmed``, depending on this value. If you create a paid order, the ``order_paid`` signal will
|
||||
**not** be sent out to plugins and no email will be sent. If you want that behavior, create an unpaid order and
|
||||
then call the ``mark_paid`` API method.
|
||||
* ``customer`` (optional) – Customer identifier or ``null``
|
||||
* ``testmode`` (optional) – Defaults to ``false``
|
||||
* ``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
|
||||
@@ -801,6 +837,7 @@ Creating orders
|
||||
charge will be created), this is just informative in case you *handled the payment already*.
|
||||
* ``payment_date`` (optional) – Date and time of the completion of the payment.
|
||||
* ``comment`` (optional)
|
||||
* ``custom_followup_at`` (optional)
|
||||
* ``checkin_attention`` (optional)
|
||||
* ``invoice_address`` (optional)
|
||||
|
||||
@@ -1411,6 +1448,8 @@ List of all order positions
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"gate": null,
|
||||
"device": 2,
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -1517,6 +1556,8 @@ Fetching individual positions
|
||||
{
|
||||
"list": 44,
|
||||
"type": "entry",
|
||||
"gate": null,
|
||||
"device": 2,
|
||||
"datetime": "2017-12-25T12:45:23Z",
|
||||
"auto_checked_in": false
|
||||
}
|
||||
@@ -1629,7 +1670,8 @@ Manipulating individual positions
|
||||
* ``answers``: If specified, you will need to provide **all** answers for this order position.
|
||||
Validation is handled the same way as when creating orders through the API. You are therefore
|
||||
expected to provide ``question``, ``answer``, and possibly ``options``. ``question_identifier``
|
||||
and ``option_identifiers`` will be ignored.
|
||||
and ``option_identifiers`` will be ignored. As a special case, you can submit the magic value
|
||||
``"file:keep"`` as the answer to a file question to keep the current value without re-uploading it.
|
||||
|
||||
**Example request**:
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ valid_date_min date Minimum value f
|
||||
valid_date_max date Maximum value for date questions (optional)
|
||||
valid_datetime_min datetime Minimum value for date and time questions (optional)
|
||||
valid_datetime_max datetime Maximum value for date and time questions (optional)
|
||||
valid_file_portrait boolean Turn on file validation for portrait photos
|
||||
dependency_question integer Internal ID of a different question. The current
|
||||
question will only be shown if the question given in
|
||||
this attribute is set to the value given in
|
||||
@@ -83,6 +84,10 @@ dependency_value string An old version
|
||||
|
||||
The attributes ``valid_*`` have been added.
|
||||
|
||||
.. versionchanged:: 3.18
|
||||
|
||||
The attribute ``valid_file_portrait`` have been added.
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -134,6 +139,7 @@ Endpoints
|
||||
"valid_date_max": null,
|
||||
"valid_datetime_min": null,
|
||||
"valid_datetime_max": null,
|
||||
"valid_file_portrait": false,
|
||||
"dependency_question": null,
|
||||
"dependency_value": null,
|
||||
"dependency_values": [],
|
||||
@@ -211,6 +217,7 @@ Endpoints
|
||||
"valid_date_max": null,
|
||||
"valid_datetime_min": null,
|
||||
"valid_datetime_max": null,
|
||||
"valid_file_portrait": false,
|
||||
"dependency_question": null,
|
||||
"dependency_value": null,
|
||||
"dependency_values": [],
|
||||
@@ -311,6 +318,7 @@ Endpoints
|
||||
"valid_date_max": null,
|
||||
"valid_datetime_min": null,
|
||||
"valid_datetime_max": null,
|
||||
"valid_file_portrait": false,
|
||||
"options": [
|
||||
{
|
||||
"id": 1,
|
||||
@@ -392,6 +400,7 @@ Endpoints
|
||||
"valid_date_max": null,
|
||||
"valid_datetime_min": null,
|
||||
"valid_datetime_max": null,
|
||||
"valid_file_portrait": false,
|
||||
"options": [
|
||||
{
|
||||
"id": 1,
|
||||
|
||||
@@ -28,12 +28,22 @@ closed boolean Whether the quo
|
||||
field).
|
||||
release_after_exit boolean Whether the quota regains capacity as soon as some tickets
|
||||
have been scanned at an exit.
|
||||
available boolean Whether this quota is available. Only returned if ``with_availability=true``
|
||||
is set on the request. Do not rely on this value for critical operations, it may be
|
||||
slightly out of date.
|
||||
available_number integer Number of available tickets. Only returned if ``with_availability=true``
|
||||
is set on the request. Do not rely on this value for critical operations, it may be
|
||||
slightly out of date. ``null`` means unlimited.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
|
||||
The attribute ``release_after_exit`` has been added.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
The ``with_availability`` query parameter has been added.
|
||||
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
@@ -80,6 +90,7 @@ Endpoints
|
||||
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``.
|
||||
Default: ``position``
|
||||
:query integer subevent: Only return quotas of the sub-event with the given ID
|
||||
:query string with_availability: Set to ``true`` to get availability information. Can lead to increased answer 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
|
||||
@@ -120,6 +131,7 @@ Endpoints
|
||||
: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 quota to fetch
|
||||
:query string with_availability: Set to ``true`` to get availability information. Can lead to increased answer times.
|
||||
: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.
|
||||
|
||||
281
doc/api/resources/sendmail_rules.rst
Normal file
@@ -0,0 +1,281 @@
|
||||
Automated email rules
|
||||
=====================
|
||||
|
||||
Resource description
|
||||
--------------------
|
||||
|
||||
Automated email rules that specify emails that the system will send automatically at a specific point in time, e.g.
|
||||
the day of the event.
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
===================================== ========================== =======================================================
|
||||
Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
id integer Internal ID of the rule
|
||||
enabled boolean If ``false``, the rule is ignored
|
||||
subject multi-lingual string The subject of the email
|
||||
template multi-lingual string The body of the email
|
||||
all_products boolean If ``true``, the email is sent to buyers of all products
|
||||
limit_products list of integers List of product IDs, if ``all_products`` is not set
|
||||
include_pending boolean If ``true``, the email is sent to pending orders. If ``false``,
|
||||
only paid orders are considered.
|
||||
date_is_absolute boolean If ``true``, the email is set at a specific point in time.
|
||||
send_date datetime If ``date_is_absolute`` is set: Date and time to send the email.
|
||||
send_offset_days integer If ``date_is_absolute`` is not set, this is the number of days
|
||||
before/after the email is sent.
|
||||
send_offset_time time If ``date_is_absolute`` is not set, this is the time of day the
|
||||
email is sent on the day specified by ``send_offset_days``.
|
||||
offset_to_event_end boolean If ``true``, ``send_offset_days`` is relative to the event end
|
||||
date. Otherwise it is relative to the event start date.
|
||||
offset_is_after boolean If ``true``, ``send_offset_days`` is the number of days **after**
|
||||
the event start or end date. Otherwise it is the number of days
|
||||
**before**.
|
||||
send_to string Can be ``"orders"`` if the email should be sent to customers
|
||||
(one email per order),
|
||||
``"attendees"`` if the email should be sent to every attendee,
|
||||
or ``"both"``.
|
||||
date. Otherwise it is relative to the event start date.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/sendmail_rules/
|
||||
|
||||
Returns a list of all rules configured for an event.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/sendmail_rules/ 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,
|
||||
"enabled": true,
|
||||
"subject": {"en": "See you tomorrow!"},
|
||||
"template": {"en": "Don't forget your tickets, download them at {url}"},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"send_date": null,
|
||||
"send_offset_days": 1,
|
||||
"send_offset_time": "18:00",
|
||||
"date_is_absolute": false,
|
||||
"offset_to_event_end": false,
|
||||
"offset_is_after": false,
|
||||
"send_to": "orders"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
: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 does not exist **or** you have no permission to view it.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/sendmail_rules/(id)/
|
||||
|
||||
Returns information on one rule, identified by its ID.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/sendmail_rules/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,
|
||||
"enabled": true,
|
||||
"subject": {"en": "See you tomorrow!"},
|
||||
"template": {"en": "Don't forget your tickets, download them at {url}"},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"send_date": null,
|
||||
"send_offset_days": 1,
|
||||
"send_offset_time": "18:00",
|
||||
"date_is_absolute": false,
|
||||
"offset_to_event_end": false,
|
||||
"offset_is_after": false,
|
||||
"send_to": "orders"
|
||||
}
|
||||
|
||||
: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 rule to fetch
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event/rule does not exist **or** you have no permission to view it.
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/sendmail_rules/
|
||||
|
||||
Create a new rule.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/sendmail_rules/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 166
|
||||
|
||||
{
|
||||
"enabled": true,
|
||||
"subject": {"en": "See you tomorrow!"},
|
||||
"template": {"en": "Don't forget your tickets, download them at {url}"},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"send_date": null,
|
||||
"send_offset_days": 1,
|
||||
"send_offset_time": "18:00",
|
||||
"date_is_absolute": false,
|
||||
"offset_to_event_end": false,
|
||||
"offset_is_after": false,
|
||||
"send_to": "orders"
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"enabled": true,
|
||||
"subject": {"en": "See you tomorrow!"},
|
||||
"template": {"en": "Don't forget your tickets, download them at {url}"},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"send_date": null,
|
||||
"send_offset_days": 1,
|
||||
"send_offset_time": "18:00",
|
||||
"date_is_absolute": false,
|
||||
"offset_to_event_end": false,
|
||||
"offset_is_after": false,
|
||||
"send_to": "orders"
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to create a rule for
|
||||
:param event: The ``slug`` field of the event to create a rule for
|
||||
:statuscode 201: no error
|
||||
:statuscode 400: The rule 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 rules.
|
||||
|
||||
|
||||
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/sendmail_rules/(id)/
|
||||
|
||||
Update a rule. 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/sendmail_rules/1/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
Content-Length: 34
|
||||
|
||||
{
|
||||
"enabled": false,
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: text/javascript
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"enabled": false,
|
||||
"subject": {"en": "See you tomorrow!"},
|
||||
"template": {"en": "Don't forget your tickets, download them at {url}"},
|
||||
"all_products": true,
|
||||
"limit_products": [],
|
||||
"include_pending": false,
|
||||
"send_date": null,
|
||||
"send_offset_days": 1,
|
||||
"send_offset_time": "18:00",
|
||||
"date_is_absolute": false,
|
||||
"offset_to_event_end": false,
|
||||
"offset_is_after": false,
|
||||
"send_to": "orders"
|
||||
}
|
||||
|
||||
: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 rule to modify
|
||||
:statuscode 200: no error
|
||||
:statuscode 400: The rule could not be modified due to invalid submitted data.
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event/rule does not exist **or** you have no permission to change it.
|
||||
|
||||
|
||||
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/sendmail_rules/(id)/
|
||||
|
||||
Delete a rule.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
DELETE /api/v1/organizers/bigevents/events/sampleconf/sendmail_rules/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 rule to delete
|
||||
:statuscode 204: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event/rule does not exist **or** you have no permission to change it **or** this rule cannot be deleted since it is currently in use.
|
||||
@@ -38,14 +38,18 @@ location multi-lingual string The sub-event l
|
||||
geo_lat float Latitude of the location (or ``null``)
|
||||
geo_lon float Longitude of the location (or ``null``)
|
||||
item_price_overrides list of objects List of items for which this sub-event overrides the
|
||||
default price
|
||||
default price or settings
|
||||
├ item integer The internal item ID
|
||||
├ disabled boolean If ``true``, item should not be available for this sub-event
|
||||
├ available_from datetime Start of availability (or ``null``)
|
||||
├ available_until datetime End of availability (or ``null``)
|
||||
└ 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
|
||||
the default price or settings
|
||||
├ variation integer The internal variation ID
|
||||
├ disabled boolean If ``true``, variation should not be available for this sub-event
|
||||
├ available_from datetime Start of availability (or ``null``)
|
||||
├ available_until datetime End of availability (or ``null``)
|
||||
└ 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
|
||||
@@ -67,6 +71,10 @@ last_modified datetime Last modificati
|
||||
|
||||
The ``last_modified`` attribute has been added.
|
||||
|
||||
.. versionchanged:: 3.18
|
||||
|
||||
The ``available_from``/``available_until`` attributes have been added to ``item_price_overrides`` and ``variation_price_overrides``.
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -74,6 +82,10 @@ Endpoints
|
||||
|
||||
The sub-events resource can now be filtered by meta data attributes.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
The ``with_availability_for`` parameter has been added.
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/subevents/
|
||||
|
||||
Returns a list of all sub-events of an event.
|
||||
@@ -119,6 +131,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -142,6 +156,10 @@ Endpoints
|
||||
only those sub-events having set their ``Format`` meta data to ``Seminar``, ``?attr[Format]=`` only those, that
|
||||
have no value set. Please note that this filter will respect default values set on
|
||||
organizer or event level.
|
||||
:query with_availability_for: If set to a sales channel identifier, the response will contain a special ``best_availability_state``
|
||||
attribute with values of 100 for "tickets available", values less than 100 for "tickets sold out or reserved",
|
||||
and ``null`` for "status unknown". These values might be served from a cache. This parameter can make the response
|
||||
slow.
|
||||
:statuscode 200: no error
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to view it.
|
||||
@@ -179,6 +197,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -214,6 +234,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -270,6 +292,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
@@ -307,6 +331,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "23.42"
|
||||
}
|
||||
],
|
||||
@@ -340,6 +366,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "23.42"
|
||||
}
|
||||
],
|
||||
@@ -429,6 +457,8 @@ Endpoints
|
||||
{
|
||||
"item": 2,
|
||||
"disabled": false,
|
||||
"available_from": null,
|
||||
"available_until": null,
|
||||
"price": "12.00"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -16,15 +16,22 @@ Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
id integer Internal ID of the tax rule
|
||||
name multi-lingual string The tax rules' name
|
||||
internal_name string An optional name that is only used in the backend
|
||||
rate decimal (string) Tax rate in percent
|
||||
price_includes_tax boolean If ``true`` (default), tax is assumed to be included in
|
||||
the specified product price
|
||||
eu_reverse_charge boolean If ``true``, EU reverse charge rules are applied
|
||||
home_country string Merchant country (required for reverse charge), can be
|
||||
``null`` or empty string
|
||||
keep_gross_if_rate_changes boolean If ``true``, changes of the tax rate based on custom
|
||||
rules keep the gross price constant (default is ``false``)
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
.. versionchanged:: 4.6
|
||||
|
||||
The ``internal_name`` and ``keep_gross_if_rate_changes`` attributes have been added.
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
@@ -56,9 +63,11 @@ Endpoints
|
||||
{
|
||||
"id": 1,
|
||||
"name": {"en": "VAT"},
|
||||
"internal_name": "VAT",
|
||||
"rate": "19.00",
|
||||
"price_includes_tax": true,
|
||||
"eu_reverse_charge": false,
|
||||
"keep_gross_if_rate_changes": false,
|
||||
"home_country": "DE"
|
||||
}
|
||||
]
|
||||
@@ -94,9 +103,11 @@ Endpoints
|
||||
{
|
||||
"id": 1,
|
||||
"name": {"en": "VAT"},
|
||||
"internal_name": "VAT",
|
||||
"rate": "19.00",
|
||||
"price_includes_tax": true,
|
||||
"eu_reverse_charge": false,
|
||||
"keep_gross_if_rate_changes": false,
|
||||
"home_country": "DE"
|
||||
}
|
||||
|
||||
@@ -140,9 +151,11 @@ Endpoints
|
||||
{
|
||||
"id": 1,
|
||||
"name": {"en": "VAT"},
|
||||
"internal_name": "VAT",
|
||||
"rate": "19.00",
|
||||
"price_includes_tax": true,
|
||||
"eu_reverse_charge": false,
|
||||
"keep_gross_if_rate_changes": false,
|
||||
"home_country": "DE"
|
||||
}
|
||||
|
||||
@@ -185,9 +198,11 @@ Endpoints
|
||||
{
|
||||
"id": 1,
|
||||
"name": {"en": "VAT"},
|
||||
"internal_name": "VAT",
|
||||
"rate": "20.00",
|
||||
"price_includes_tax": true,
|
||||
"eu_reverse_charge": false,
|
||||
"keep_gross_if_rate_changes": false,
|
||||
"home_country": "DE"
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ limit_events list List of event s
|
||||
can_create_events boolean
|
||||
can_change_teams boolean
|
||||
can_change_organizer_settings boolean
|
||||
can_manage_customers boolean
|
||||
can_manage_gift_cards boolean
|
||||
can_change_event_settings boolean
|
||||
can_change_items boolean
|
||||
|
||||
@@ -9,4 +9,5 @@ Table of contents
|
||||
api/index
|
||||
development/index
|
||||
plugins/index
|
||||
license/faq
|
||||
|
||||
|
||||
28
doc/development/algorithms/checkin.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
.. spelling: libpretixsync
|
||||
|
||||
Check-in algorithms
|
||||
===================
|
||||
|
||||
When a ticket is scanned at the entrance or exit of an event, we follow a series of steps to determine whether
|
||||
the check-in is allowed or not. To understand some of the terms in the following diagrams, you should also check
|
||||
out the documentation of the :ref:`ticket redemption API endpoint <rest-checkin-redeem>`.
|
||||
|
||||
Server-side
|
||||
-----------
|
||||
|
||||
The following diagram shows the series of checks executed on the server when a ticket is redeemed through the API.
|
||||
Some simplifications have been made, for example the deduplication mechanism based on the ``nonce`` parameter
|
||||
to prevent re-uploads of the same scan is not shown.
|
||||
|
||||
.. image:: /images/checkin_online.png
|
||||
|
||||
Client-side
|
||||
-----------
|
||||
|
||||
The process of verifying tickets offline is a little different. There are two different approaches,
|
||||
depending on whether we have information about all tickets in the local database. The following diagram shows
|
||||
the algorithm as currently implemented in recent versions of `libpretixsync`_.
|
||||
|
||||
.. image:: /images/checkin_offline.png
|
||||
|
||||
.. _libpretixsync: https://github.com/pretix/libpretixsync
|
||||
13
doc/development/algorithms/index.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
Algorithms
|
||||
==========
|
||||
|
||||
The business logic inside pretix is full of complex algorithms making decisions based on all the hundreds of settings
|
||||
and input parameters available. Some of them are documented here as graphs, either because fully understanding them is very important
|
||||
when working on features close to them, or because they also need to be re-implemented by client-side components like our
|
||||
ticket scanning apps and we want to ensure the implementations are as similar as possible to avoid confusion.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
checkin
|
||||
layouts
|
||||
15
doc/development/algorithms/layouts.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
.. spelling: pretixPOS
|
||||
|
||||
Ticket layout
|
||||
=============
|
||||
|
||||
When a ticket is exported to PDF, the system needs to decide which of multiple PDF layouts to use. The
|
||||
following diagram shows the steps of the decision, showing both the implementation in pretix itself as
|
||||
well as the implementation in `pretixPOS`_.
|
||||
|
||||
The process can be influenced by plugins, which is demonstrated with the example of the shipping plugin.
|
||||
|
||||
.. image:: /images/ticket_layouts.png
|
||||
|
||||
|
||||
.. _pretixPOS: https://pretix.eu/about/en/pos
|
||||
119
doc/development/api/cookieconsent.rst
Normal file
@@ -0,0 +1,119 @@
|
||||
.. highlight:: python
|
||||
:linenothreshold: 5
|
||||
|
||||
.. _`cookieconsent`:
|
||||
|
||||
Handling cookie consent
|
||||
=======================
|
||||
|
||||
pretix includes an optional feature to handle cookie consent explicitly to comply with EU regulations.
|
||||
If your plugin sets non-essential cookies or includes a third-party service that does so, you should
|
||||
integrate with this feature.
|
||||
|
||||
Server-side integration
|
||||
-----------------------
|
||||
|
||||
First, you need to declare that you are using non-essential cookies by responding to the following
|
||||
signal:
|
||||
|
||||
.. automodule:: pretix.presale.signals
|
||||
:members: register_cookie_providers
|
||||
|
||||
You are expected to return a list of ``CookieProvider`` objects instantiated from the following class:
|
||||
|
||||
.. class:: pretix.presale.cookies.CookieProvider
|
||||
|
||||
.. py:attribute:: CookieProvider.identifier
|
||||
|
||||
A short and unique identifier used to distinguish this cookie provider form others (required).
|
||||
|
||||
.. py:attribute:: CookieProvider.provider_name
|
||||
|
||||
A human-readable name of the entity of feature responsible for setting the cookie (required).
|
||||
|
||||
.. py:attribute:: CookieProvider.usage_classes
|
||||
|
||||
A list of enum values from the ``pretix.presale.cookies.UsageClass`` enumeration class, such as
|
||||
``UsageClass.ANALYTICS``, ``UsageClass.MARKETING``, or ``UsageClass.SOCIAL`` (required).
|
||||
|
||||
.. py:attribute:: CookieProvider.privacy_url
|
||||
|
||||
A link to a privacy policy (optional).
|
||||
|
||||
Here is an example of such a receiver:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@receiver(register_cookie_providers)
|
||||
def recv_cookie_providers(sender, request, **kwargs):
|
||||
return [
|
||||
CookieProvider(
|
||||
identifier='google_analytics',
|
||||
provider_name='Google Analytics',
|
||||
usage_classes=[UsageClass.ANALYTICS],
|
||||
)
|
||||
]
|
||||
|
||||
JavaScript-side integration
|
||||
---------------------------
|
||||
|
||||
The server-side integration only causes the cookie provider to show up in the cookie dialog. You still
|
||||
need to care about actually enforcing the consent state.
|
||||
|
||||
You can access the consent state through the ``window.pretix.cookie_consent`` variable. Whenever the
|
||||
value changes, a ``pretix:cookie-consent:change`` event is fired on the ``document`` object.
|
||||
|
||||
The variable will generally have one of the following states:
|
||||
|
||||
.. rst-class:: rest-resource-table
|
||||
|
||||
================================================================ =====================================================
|
||||
State Interpretation
|
||||
================================================================ =====================================================
|
||||
``pretix === undefined || pretix.cookie_consent === undefined`` Your JavaScript has loaded before the cookie consent
|
||||
script. Wait for the event to be fired, then try again,
|
||||
do not yet set a cookie.
|
||||
``pretix.cookie_consent === null`` The cookie consent mechanism has not been enabled. This
|
||||
usually means that you can set cookies however you like.
|
||||
``pretix.cookie_consent[identifier] === undefined`` The cookie consent mechanism is loaded, but has no data
|
||||
on your cookie yet, wait for the event to be fired, do not
|
||||
yet set a cookie.
|
||||
``pretix.cookie_consent[identifier] === true`` The user has consented to your cookie.
|
||||
``pretix.cookie_consent[identifier] === false`` The user has actively rejected your cookie.
|
||||
================================================================ =====================================================
|
||||
|
||||
If you are integrating e.g. a tracking provider with native cookie consent support such
|
||||
as Facebook's Pixel, you can integrate it like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var consent = (window.pretix || {}).cookie_consent;
|
||||
if (consent !== null && !(consent || {}).facebook) {
|
||||
fbq('consent', 'revoke');
|
||||
}
|
||||
fbq('init', ...);
|
||||
document.addEventListener('pretix:cookie-consent:change', function (e) {
|
||||
fbq('consent', (e.detail || {}).facebook ? 'grant' : 'revoke');
|
||||
})
|
||||
|
||||
If you have a JavaScript function that you only want to load if consent for a specific ``identifier``
|
||||
is given, you can wrap it like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var consent_identifier = "youridentifier";
|
||||
var consent = (window.pretix || {}).cookie_consent;
|
||||
if (consent === null || (consent || {})[consent_identifier] === true) {
|
||||
// Cookie consent tool is either disabled or consent is given
|
||||
addScriptElement(src);
|
||||
return;
|
||||
}
|
||||
|
||||
// Either cookie consent tool has not loaded yet or consent is not given
|
||||
document.addEventListener('pretix:cookie-consent:change', function onChange(e) {
|
||||
var consent = e.detail || {};
|
||||
if (consent === null || consent[consent_identifier] === true) {
|
||||
addScriptElement(src);
|
||||
document.removeEventListener('pretix:cookie-consent:change', onChange);
|
||||
}
|
||||
})
|
||||
@@ -17,6 +17,7 @@ Contents:
|
||||
shredder
|
||||
import
|
||||
customview
|
||||
cookieconsent
|
||||
auth
|
||||
general
|
||||
quality
|
||||
|
||||
@@ -62,6 +62,8 @@ The provider class
|
||||
|
||||
.. autoattribute:: public_name
|
||||
|
||||
.. autoattribute:: confirm_button_name
|
||||
|
||||
.. autoattribute:: is_enabled
|
||||
|
||||
.. autoattribute:: priority
|
||||
|
||||
@@ -94,7 +94,7 @@ F. Functionality
|
||||
|
||||
#. Refunds are implemented, if possible.
|
||||
|
||||
#. In case of overpayment or external refunds, a "required action" is created to notify the event organizer.
|
||||
#. In case of overpayment or external refunds, an external refund is properly created.
|
||||
|
||||
#. If the plugin adds steps to the checkout process, it has been tested in combination with the pretix widget.
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
.. spelling:: Rebase rebasing
|
||||
|
||||
Coding style and quality
|
||||
========================
|
||||
|
||||
Code
|
||||
----
|
||||
|
||||
* Basically, we want all python code to follow the `PEP 8`_ standard. There are a few exceptions where
|
||||
we see things differently or just aren't that strict. The ``setup.cfg`` file in the project's source
|
||||
folder contains definitions that allow `flake8`_ to check for violations automatically. See :ref:`checksandtests`
|
||||
@@ -20,8 +25,62 @@ Coding style and quality
|
||||
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.
|
||||
|
||||
* 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``.
|
||||
Commits and Pull Requests
|
||||
-------------------------
|
||||
|
||||
|
||||
|
||||
Most commits should start as pull requests, therefore this applies to the titles of pull requests as well since
|
||||
the pull request title will become the commit message on merge. We prefer merging with GitHub's "Squash and merge"
|
||||
feature if the PR contains multiple commits that do not carry value to keep. If there is value in keeping the
|
||||
individual commits, we use "Rebase and merge" instead. Merge commits should be avoided.
|
||||
|
||||
* The commit message should start with a single subject line and can optionally be followed by a commit message body.
|
||||
|
||||
* The subject line should be the shortest possible representation of what the commit changes. Someone who reviewed
|
||||
the commit should able to immediately remember the commit in a couple of weeks based on the subject line and tell
|
||||
it apart from other commits.
|
||||
|
||||
* If there's additional useful information that we should keep, such as reasoning behind the commit, you can
|
||||
add a longer body, separated from the first line by a blank line.
|
||||
|
||||
* The body should explain **what** you changed and more importantly **why** you changed it. There's no need to iterate
|
||||
**how** you changed something.
|
||||
|
||||
* The subject line should be capitalized ("Add new feature" instead of "add new feature") and should not end with a period
|
||||
("Add new feature" instead of "Add new feature.")
|
||||
|
||||
* The subject line should be written in imperative mood, as if you were giving a command what the computer should do if the
|
||||
commit is applied. This is how generated commit messages by git itself are already written ("Merge branch …", "Revert …")
|
||||
and makes for short and consistent messages.
|
||||
|
||||
* Good: "Fix typo in template"
|
||||
* Good: "Add Chinese translation"
|
||||
* Good: "Remove deprecated method"
|
||||
* Good: "Bump version to 4.4.0"
|
||||
* Bad: "Fixed bug with …"
|
||||
* Bad: "Fixes bug with …"
|
||||
* Bad: "Fixing bug …"
|
||||
|
||||
* If all changes in your commit are in context of a single feature or e.g. a bundled plugin, it makes sense to prefix the
|
||||
subject line with the name of that feature. Examples:
|
||||
|
||||
* "API: Add support for PATCH on customers"
|
||||
* "Docs: Add chapter on alpaca feeding"
|
||||
* "Stripe: Fix duplicate payments"
|
||||
* "Order change form: Fix incorrect validation"
|
||||
|
||||
* If your commit references a GitHub issue that is fully resolved by your commit, start your subject line with the issue
|
||||
ID in the form of "Fix #1234 -- Crash in order list". In this case, you can omit the verb "Fix" at the beginning of the
|
||||
second part of the message to avoid repetition of the word "fix". If your commit only partially resolves the issue, use
|
||||
"Refs #1234 -- Crash in order list" instead.
|
||||
|
||||
* Applies to pretix employees only: If your commit references a sentry issue, please put it in parentheses at the end
|
||||
of the subject line or inside the body ("Fix crash in order list (PRETIXEU-ABC)"). If your commit references a support
|
||||
ticket, please put it in parentheses at the end of the subject line with a "Z#" prefix ("Fix crash in order list (Z#12345)").
|
||||
|
||||
* If your PR was open for a while and might cause conflicts on merge, please prefer rebasing it (``git rebase -i master``)
|
||||
over merging ``master`` into your branch unless it is prohibitively complicated.
|
||||
|
||||
|
||||
.. _PEP 8: https://legacy.python.org/dev/peps/pep-0008/
|
||||
|
||||
@@ -34,9 +34,6 @@ Organizers and events
|
||||
.. autoclass:: pretix.base.models.TeamAPIToken
|
||||
:members:
|
||||
|
||||
.. autoclass:: pretix.base.models.RequiredAction
|
||||
:members:
|
||||
|
||||
.. autoclass:: pretix.base.models.EventMetaProperty
|
||||
:members:
|
||||
|
||||
@@ -95,6 +92,9 @@ Carts and Orders
|
||||
.. autoclass:: pretix.base.models.OrderRefund
|
||||
:members:
|
||||
|
||||
.. autoclass:: pretix.base.models.Transaction
|
||||
:members:
|
||||
|
||||
.. autoclass:: pretix.base.models.CartPosition
|
||||
:members:
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ Developer documentation
|
||||
setup
|
||||
contribution/index
|
||||
implementation/index
|
||||
translation/index
|
||||
algorithms/index
|
||||
api/index
|
||||
structure
|
||||
translation/index
|
||||
|
||||
@@ -26,7 +26,7 @@ Your should install the following on your system:
|
||||
* ``libssl`` (Debian package: ``libssl-dev``)
|
||||
* ``libxml2`` (Debian package ``libxml2-dev``)
|
||||
* ``libxslt`` (Debian package ``libxslt1-dev``)
|
||||
* ``libenchant1c2a`` (Debian package ``libenchant1c2a``)
|
||||
* ``libenchant-2-2`` (Debian package ``libenchant-2-2``)
|
||||
* ``msgfmt`` (Debian package ``gettext``)
|
||||
* ``git``
|
||||
|
||||
@@ -51,10 +51,15 @@ the dependencies might fail::
|
||||
|
||||
Working with the code
|
||||
---------------------
|
||||
The first thing you need are all the main application's dependencies::
|
||||
If you do not have a recent installation of ``nodejs``, install it now::
|
||||
|
||||
curl -sL https://deb.nodesource.com/setup_17.x | sudo -E bash -
|
||||
sudo apt install nodejs
|
||||
|
||||
To make sure it is on your path variable, close and reopen your terminal. Now, install the Python-level dependencies of pretix::
|
||||
|
||||
cd src/
|
||||
pip3 install -r requirements.txt -r requirements/dev.txt
|
||||
pip3 install -e ".[dev]"
|
||||
|
||||
Next, you need to copy the SCSS files from the source folder to the STATIC_ROOT directory::
|
||||
|
||||
|
||||
BIN
doc/images/checkin_offline.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
146
doc/images/checkin_offline.puml
Normal file
@@ -0,0 +1,146 @@
|
||||
@startuml
|
||||
|
||||
|
||||
partition "data-based check" {
|
||||
"Check based on local database" --> "Is the order in status PAID or PENDING\nand is the position not canceled?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error CANCELED"
|
||||
else
|
||||
-down->[yes] "Is the product part of the check-in list?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error PRODUCT"
|
||||
else
|
||||
-down->[yes] "Is the subevent part of the check-in list?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error INVALID"
|
||||
note bottom: TODO\ninconsistent\nwith online\ncheck
|
||||
else
|
||||
-down->[yes] "Is the order in status PAID?"
|
||||
--> if "" then
|
||||
-right->[no] "Does the check-in list include pending orders?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error UNPAID "
|
||||
else
|
||||
-down->[yes] "Is ignore_unpaid set?\n(Has the operator confirmed\nthe checkin?)"
|
||||
--> if "" then
|
||||
-right->[no] "Return error UNPAID "
|
||||
else
|
||||
-down->[yes] "Is this an entry or exit?"
|
||||
endif
|
||||
endif
|
||||
else
|
||||
-down->[yes] "Is this an entry or exit?"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
"Is this an entry or exit?" --> if "" then
|
||||
-right->[entry] Evaluate custom logic (rules)
|
||||
--> if "" then
|
||||
-right->[error] "Return error RULES"
|
||||
else
|
||||
-down->[ok] "Are all required questions answered?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error INCOMPLETE"
|
||||
else
|
||||
-down->[yes] "Does the check-in list allow multi-entry?"
|
||||
endif
|
||||
endif
|
||||
else
|
||||
-->[exit] "Return OK "
|
||||
endif
|
||||
|
||||
"Does the check-in list allow multi-entry?" --> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Is this the first checkin\nfor this ticket on this list?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Are all previous checkins\nfor this ticket on this list exits?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Does the check-in list\n allow entry after exit\nand is the last checkin\nan exit?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Return error ALREADY_REDEEMED"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
}
|
||||
|
||||
partition "dataless check" {
|
||||
"Check based on secret content" --> "Does the secret decode with\nany supported scheme\nand has a valid signature?"
|
||||
|
||||
--> if "" then
|
||||
-down->[yes] "Is the ticket secret on the revocation list?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return error REVOKED"
|
||||
else
|
||||
-down->[no] "Is the product part of the check-in list? "
|
||||
--> if "" then
|
||||
-right->[no] "Return error PRODUCT "
|
||||
else
|
||||
-down->[yes] "Is the subevent part of the check-in list? "
|
||||
--> if "" then
|
||||
-right->[no] "Return error INVALID "
|
||||
note bottom: TODO\ninconsistent\nwith online\ncheck
|
||||
else
|
||||
--> "Is this an entry or exit? "
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
else
|
||||
-right>[no] "Return error INVALID "
|
||||
endif
|
||||
|
||||
"Is this an entry or exit? " --> if "" then
|
||||
-right->[entry] "Evaluate custom logic (rules) "
|
||||
--> if "" then
|
||||
-right->[error] "Return error RULES "
|
||||
else
|
||||
-down->[ok] "Are all required questions answered? "
|
||||
--> if "" then
|
||||
-right->[no] "Return error INCOMPLETE "
|
||||
else
|
||||
-down->[yes] "Does the check-in list allow multi-entry? "
|
||||
endif
|
||||
endif
|
||||
else
|
||||
-->[exit] " Return OK "
|
||||
endif
|
||||
|
||||
"Does the check-in list allow multi-entry? " --> if "" then
|
||||
-right->[yes] " Return OK "
|
||||
else
|
||||
-down->[no] "Are any locally queued checkins for\nthis ticket of this list known?"
|
||||
--> if "" then
|
||||
-right->[no] " Return OK "
|
||||
else
|
||||
-down->[yes] "Are all locally queued checkins\nfor this ticket on this list exits? "
|
||||
--> if "" then
|
||||
-right->[yes] " Return OK "
|
||||
else
|
||||
-down->[no] "Does the check-in list\n allow entry after exit\nand is the last locally\nqueued checkin\nan exit? "
|
||||
--> if "" then
|
||||
-right->[yes] " Return OK "
|
||||
else
|
||||
-down->[no] "Return error ALREADY_REDEEMED "
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
}
|
||||
|
||||
(*) --> "Check if order position with\nscanned ticket secret exists"
|
||||
--> if "" then
|
||||
-down->[yes] "Check based on local database"
|
||||
else
|
||||
-->[no] "Check based on secret content"
|
||||
endif
|
||||
|
||||
@enduml
|
||||
BIN
doc/images/checkin_online.png
Normal file
|
After Width: | Height: | Size: 147 KiB |
92
doc/images/checkin_online.puml
Normal file
@@ -0,0 +1,92 @@
|
||||
@startuml
|
||||
|
||||
(*) --> "Check if order position with\nscanned ticket secret exists"
|
||||
--> if "" then
|
||||
-down->[yes] ===CHECK===
|
||||
else
|
||||
-->[no] "Check if secret exists\nin revocation list"
|
||||
--> if "" then
|
||||
--> "Is this a forced upload?"
|
||||
--> if "" then
|
||||
-->[yes] ===CHECK===
|
||||
else
|
||||
-right->[no] "Return error REVOKED"
|
||||
endif
|
||||
else
|
||||
-right->[no] "Return error INVALID"
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
===CHECK=== -down-> "Is the order in status PAID or PENDING\nand is the position not canceled?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error CANCELED"
|
||||
else
|
||||
-down->[yes] "Is the product part of the check-in list?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error PRODUCT"
|
||||
else
|
||||
-down->[yes] "Is the subevent part of the check-in list?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error PRODUCT "
|
||||
else
|
||||
-down->[yes] "Is the order in status PAID\nor is this a forced upload?"
|
||||
--> if "" then
|
||||
-right->[no] "Does the check-in list include pending orders?"
|
||||
--> if "" then
|
||||
-right->[no] "Return error UNPAID "
|
||||
else
|
||||
-down->[yes] "Is ignore_unpaid set?\n(Has the operator confirmed\nthe checkin?)"
|
||||
--> if "" then
|
||||
-right->[no] "Return error UNPAID "
|
||||
else
|
||||
-down->[yes] "Is this an entry or exit?\nIs the upload forced?"
|
||||
endif
|
||||
endif
|
||||
else
|
||||
-down->[yes] "Is this an entry or exit?\nIs the upload forced?"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
"Is this an entry or exit?\nIs the upload forced?" --> if "" then
|
||||
-right->[entry && not force] Evaluate custom logic (rules)
|
||||
--> if "" then
|
||||
-right->[error] "Return error RULES"
|
||||
else
|
||||
-down->[ok] "Are all required questions answered?"
|
||||
--> if "" then
|
||||
-right->[no && questions_supported] "Return error INCOMPLETE"
|
||||
else
|
||||
-down->[yes || not questions_supported] "Does the check-in list allow multi-entry?"
|
||||
endif
|
||||
endif
|
||||
else
|
||||
-->[exit || force=true] "Return OK "
|
||||
endif
|
||||
|
||||
"Does the check-in list allow multi-entry?" --> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Is this the first checkin\nfor this ticket on this list?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Are all previous checkins\nfor this ticket on this list exits?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Does the check-in list\n allow entry after exit\nand is the last checkin\nan exit?"
|
||||
--> if "" then
|
||||
-right->[yes] "Return OK"
|
||||
else
|
||||
-down->[no] "Return error ALREADY_REDEEMED"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@enduml
|
||||
BIN
doc/images/ticket_layouts.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
52
doc/images/ticket_layouts.puml
Normal file
@@ -0,0 +1,52 @@
|
||||
@startuml
|
||||
|
||||
(*) --> "Which implementation?"
|
||||
--> if "" then
|
||||
-down->[pretixPOS] "Check for TicketLayoutItem with\nsales_channel=pretixpos [libpretixsync]"
|
||||
--> if "" then
|
||||
--> (*)
|
||||
else
|
||||
-->[not found] "Check for TicketLayoutItem with\nsales_channel=web [libpretixsync]"
|
||||
--> if "" then
|
||||
--> (*)
|
||||
else
|
||||
-->[not found] "Use event default [libpretixsync]"
|
||||
--> (*)
|
||||
endif
|
||||
endif
|
||||
|
||||
else
|
||||
-right->[pretix] "Check for TicketLayoutItem with\nsales_channel=order.sales_channel"
|
||||
--> if "" then
|
||||
-right-> "Run override_layout plugin signal on result"
|
||||
else
|
||||
-down->[not found] "Check for TicketLayoutItem with\nsales_channel=web"
|
||||
--> if "" then
|
||||
--> "Run override_layout plugin signal on result"
|
||||
else
|
||||
-->[not found] "Use event default"
|
||||
--> "Run override_layout plugin signal on result"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
"Run override_layout plugin signal on result" -> (*)
|
||||
|
||||
|
||||
partition pretix_shipping {
|
||||
"Run override_layout plugin signal on result" --> "Check for ShippingLayoutItem with\nmethod=order.shipping_method"
|
||||
--> if "" then
|
||||
--> (*)
|
||||
else
|
||||
-down->[not found] "Check for ShippingMethod.layout"
|
||||
--> if "" then
|
||||
--> (*)
|
||||
else
|
||||
-down->[not found] "Keep original layout"
|
||||
--> (*)
|
||||
endif
|
||||
endif
|
||||
}
|
||||
|
||||
@enduml
|
||||
177
doc/license/faq.rst
Normal file
@@ -0,0 +1,177 @@
|
||||
.. spelling::
|
||||
|
||||
AGPL
|
||||
AGPLv3
|
||||
GPL
|
||||
LGPL
|
||||
Apache
|
||||
BSD
|
||||
MIT
|
||||
CLA
|
||||
django
|
||||
i18nfields
|
||||
hierarkey
|
||||
rami.io
|
||||
rami
|
||||
io
|
||||
GmbH
|
||||
|
||||
License FAQ
|
||||
===========
|
||||
|
||||
.. warning::
|
||||
|
||||
This FAQ tries to explain in simpler terms what the license of the pretix open source project does and does not
|
||||
allow. It is based on our interpretation of the license and is not legal advice. The contents of this page are not
|
||||
legally binding, only the original text of the license in the `license file`_ is legally binding.
|
||||
|
||||
How is pretix licensed?
|
||||
-----------------------
|
||||
|
||||
pretix follows the popular dual licensing model. It is available under the `GNU Affero General Public License 3`_ (AGPL)
|
||||
plus some additional terms, as well as under a proprietary license ("pretix Enterprise license") on request.
|
||||
|
||||
How can it be AGPL if there are additional terms?
|
||||
-------------------------------------------------
|
||||
|
||||
Even though it is fairly unknown, the AGPL's section 7 is titled "Additional Terms" and outlines specific conditions
|
||||
under which additional terms can be imposed on an AGPL-licensed work. In our case, we add three additional terms.
|
||||
|
||||
The first additional term for pretix is an additional **permission**. It allows you to do something that the AGPL would
|
||||
generally not allow. As it doesn't restrict your freedoms granted by AGPL, if you don't like it, you can ignore it, and
|
||||
if you distribute pretix further, you can remove it.
|
||||
|
||||
The second and third additional term for pretix are additional terms that restrict or specify other provisions of the
|
||||
license. AGPL specifically requires that these terms can only restrict or specify very specific things and we believe
|
||||
our additional terms are in compliance with that and are thus valid and may not be removed.
|
||||
|
||||
Why did you choose this license model?
|
||||
--------------------------------------
|
||||
|
||||
pretix was born in the open source community and we're deeply committed to building the best open source ticketing
|
||||
solution in the world. It is important to us that pretix is available with a comprehensive feature set under term that
|
||||
are compatible with the `Open Source Definition`_. This enables event organizers from all industries and regions
|
||||
to have access to a self-hosted, privacy-friendly and secure option to host their events.
|
||||
|
||||
However, developing and maintaining pretix is a lot of work. Between 2014 and 2021, we've received external
|
||||
contributions from more than 150 individuals. Not counting translations over 90 % of the development was
|
||||
done by staff engineers of rami.io GmbH, the company that started pretix. While we're very happy to receive many more
|
||||
contributions in the future, we also want to ensure that we continue to be able to pay people working on pretix
|
||||
full-time.
|
||||
|
||||
We believe our model creates a good balance between ensuring pretix is available freely as well as protecting our
|
||||
business interests. Unlike licenses chosen by other projects recently, such as the Server-Side Public License, our
|
||||
choice does not restrict using pretix for any possible use case, it just sets a few rules that you have to play by
|
||||
if you do.
|
||||
|
||||
What do I need to do if I use pretix unmodified?
|
||||
------------------------------------------------
|
||||
|
||||
If you use pretix without any modifications or plugins, you can use it for whatever you want, as long as you keep
|
||||
all copyright notices (including the link to pretix at the bottom of the site) intact.
|
||||
|
||||
You are also allowed to make copies of the unmodified source code and distribute them to others as long as you keep
|
||||
all copyright and license information intact.
|
||||
|
||||
If you install **plugins**, you must follow the same terms as when using a **modified** version (see below).
|
||||
|
||||
What do I need to do if I modify pretix?
|
||||
----------------------------------------
|
||||
|
||||
If you want to modify pretix, you have the right to do so. However, you need to follow the following rules:
|
||||
|
||||
* If you **run it for your own events** (events run by you or your company as well as companies from the same
|
||||
corporate groups) our additional permission allows you to do so **without needing to share your source code
|
||||
modifications** as long as you keep the link to pretix at the bottom of the site intact.
|
||||
|
||||
* If you **run it for others**, for example as part of a Software-as-a-Service offering or a managed hosting service
|
||||
you **must** make the source code **including all your modifications and all installed plugins** available under the
|
||||
same license as pretix to every visitor of your site. You need to do so in a prominent place such as a link at the bottom of the
|
||||
site. You also **must** keep the existing link intact.
|
||||
You **may not** add additional restrictions on the result as a whole. You **may** add additional permissions, but
|
||||
only on the parts you added. You **must** make clear which changes you made and you must not give the impression that
|
||||
your modified version is an official version of pretix.
|
||||
|
||||
* If you **distribute** the modified version, for example as a source code or software package, you **must** license it
|
||||
under the AGPL license with the same additional terms. You **may not** add additional restrictions on the result as a
|
||||
whole. You **may** add additional permissions, but only on the parts you added. You **must** make clear which changes
|
||||
you made and you must not give the impression that your modified version is an official version of pretix.
|
||||
|
||||
Does the AGPL copyleft mechanism extend to plugins?
|
||||
---------------------------------------------------
|
||||
|
||||
Yes. pretix plugins are tightly integrated with pretix, so when running pretix together with a plugin in the same
|
||||
environment they form a `combined work`_ and the copyleft mechanism of AGPL applies.
|
||||
|
||||
Can I create proprietary or secret plugins?
|
||||
-------------------------------------------
|
||||
|
||||
Yes, you can create a proprietary or secret plugin, but it may only ever be **used** in an environment that is covered
|
||||
by the additional permission from our license. As soon as the plugin is installed in an installation that is not covered
|
||||
by our additional permission (e.g. when it is used in a SaaS environment) or covered by an active pretix Enterprise
|
||||
license it **must** be released to the visitors of the site under the same license as pretix (like a modified version
|
||||
of pretix).
|
||||
|
||||
What licenses can plugins use?
|
||||
------------------------------
|
||||
|
||||
Technically, you can distribute a plugin under any free or proprietary license as long as it is distributed separately.
|
||||
However, once it is either **distributed together with pretix or used in an environment not covered by our
|
||||
additional permission** or an active pretix Enterprise license, you **must** release it to all recipients of the
|
||||
distribution or all visitors of your site under the same license as pretix (like a modified version of pretix).
|
||||
|
||||
If you release a plugin publicly, it is therefore most practical to use a license that is `compatible to AGPL`_.
|
||||
This includes most open source licenses such as AGPL, GPL, Apache, 3-clause BSD or MIT.
|
||||
|
||||
Note however that when you license a plugin with pure AGPL, it will be incompatible with our additional permission.
|
||||
Therefore, if you want to use an AGPL-licensed plugin, you'll need to publish the source code of **all** your plugins
|
||||
under AGPL terms **even if you only use it for your own events**. A plugin would add its `own additional permission`_
|
||||
to its license to allow combining it with pretix for this use case.
|
||||
|
||||
To make things less complicated, if you want to distribute a plugin freely, we therefore recommend distributing the
|
||||
plugin under **Apache License 2.0**, like we do for most plugins we distribute as open source.
|
||||
|
||||
What do I need to do if I want to contribute my changes back?
|
||||
-------------------------------------------------------------
|
||||
|
||||
In order to retain the possibility for us to offer pretix in a dual licensing model, we unfortunately need you to sign
|
||||
a Contributor License Agreement (CLA) that gives us permission to use your contribution in all present and future
|
||||
distributions of pretix. We know the bureaucracy sucks. Sorry.
|
||||
|
||||
What if I want to re-use a minor part of pretix in my project?
|
||||
--------------------------------------------------------------
|
||||
|
||||
This is the main part we dislike about AGPL: If you see a specific thing in pretix that you'd like to use in another
|
||||
project, you'll need to distribute your other project under AGPL terms as well which is often not practical.
|
||||
|
||||
In this case, feel free to get in touch with us! We're happy to grant you special permission or pull the component
|
||||
out into a separately, permissively licensed repository. We already did that with `django-hierarkey`_ and
|
||||
`django-i18nfield`_ which have previously been parts of pretix.
|
||||
|
||||
What can I use the name "pretix" for?
|
||||
-------------------------------------
|
||||
|
||||
The name pretix is a registered trademark by rami.io GmbH.
|
||||
|
||||
* You **may** use it to **indicate copyright**, such as in the "powered by pretix" or "based on pretix" line, or when
|
||||
indicating that a distribution is based on pretix.
|
||||
|
||||
* You **may** use it to **indicate compatibility**, for example you are allowed to name your plugin "<name> for pretix"
|
||||
or you may state that an external service is compatible with pretix.
|
||||
|
||||
* You **may not** give the impression that your modified version, plugin or compatible service is official or authorized
|
||||
by rami.io GmbH or pretix unless we specifically allowed you to do so.
|
||||
|
||||
* You **may not** use it to name your modified version of pretix. End-users must be able to easily identify whether
|
||||
a version of pretix is distributed by us.
|
||||
|
||||
* You **may not** use any variations of the name, such as "MyPretix".
|
||||
|
||||
.. _license file: https://github.com/pretix/pretix/blob/master/LICENSE
|
||||
.. _GNU Affero General Public License 3: https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
.. _compatible to AGPL: https://www.gnu.org/licenses/license-list.en.html#GPLCompatibleLicenses
|
||||
.. _Open Source Definition: https://opensource.org/osd
|
||||
.. _combined work: https://www.gnu.org/licenses/gpl-faq.html#GPLPlugins
|
||||
.. _own additional permission: https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs
|
||||
.. _django-hierarkey: https://github.com/raphaelm/django-hierarkey
|
||||
.. _django-i18nfield: https://github.com/raphaelm/django-i18nfield
|
||||
64
doc/plugins/certificates.rst
Normal file
@@ -0,0 +1,64 @@
|
||||
Certificates of attendance
|
||||
==========================
|
||||
|
||||
The certificates plugin provides a HTTP API that allows you to download the certificate for a specific attendee.
|
||||
|
||||
|
||||
Certificate download
|
||||
--------------------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/certificate/
|
||||
|
||||
Downloads the certificate for one order position, identified by its internal ID. Download is a two-step
|
||||
process. You will always get a :http:statuscode:`303` response with a ``Location`` header to a different
|
||||
URL. In the background, our server starts preparing the PDF file.
|
||||
|
||||
If you then do a ``GET`` to the URL you were given, you will either receive a :http:statuscode:`409` response
|
||||
indicating to retry after a few seconds, or a :http:statuscode:`200` response with the PDF file.
|
||||
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/certificate/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 303 See Other
|
||||
Location: /api/v1/organizers/democon/events/3vjrh/orderpositions/426/certificate/?result=1f550651-ae7b-4911-a76c-2be8f348aaa5
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/certificate/?result=1f550651-ae7b-4911-a76c-2be8f348aaa5 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/pdf
|
||||
|
||||
...
|
||||
|
||||
: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 order position to fetch
|
||||
:statuscode 200: File ready for download
|
||||
:statuscode 303: Processing started
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource
|
||||
**or** downloads are not available for this order position at this time. The response content will
|
||||
contain more details.
|
||||
:statuscode 404: The requested order position or download provider does not exist.
|
||||
:statuscode 409: The file is not yet ready and will now be prepared. Retry the request after waiting for a few
|
||||
seconds.
|
||||
@@ -15,5 +15,6 @@ If you want to **create** a plugin, please go to the
|
||||
ticketoutputpdf
|
||||
badges
|
||||
campaigns
|
||||
certificates
|
||||
digital
|
||||
webinar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-r ../src/requirements.txt
|
||||
-e ../src/
|
||||
sphinx==2.3.*
|
||||
sphinx-rtd-theme
|
||||
sphinxcontrib-httpdomain
|
||||
|
||||
BIN
doc/screens/event/seasontickets_issue.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
doc/screens/event/seasontickets_membershiptype.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
doc/screens/event/seasontickets_orgsettings.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
doc/screens/event/seasontickets_require.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
doc/screens/event/seasontickets_rules.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
@@ -17,10 +17,12 @@ bic
|
||||
BIC
|
||||
boolean
|
||||
booleans
|
||||
bugfix
|
||||
cancelled
|
||||
casted
|
||||
Ceph
|
||||
checkbox
|
||||
checkins
|
||||
checksum
|
||||
config
|
||||
contenttypes
|
||||
@@ -76,13 +78,16 @@ mixin
|
||||
mixins
|
||||
multi
|
||||
multidomain
|
||||
multiplicator
|
||||
namespace
|
||||
namespaced
|
||||
namespaces
|
||||
namespacing
|
||||
natively
|
||||
nginx
|
||||
nodejs
|
||||
NotificationType
|
||||
npm
|
||||
ons
|
||||
optimizations
|
||||
overpayment
|
||||
|
||||
@@ -203,4 +203,4 @@ Then, please contact support@pretix.eu and we will enable DKIM for your domain o
|
||||
|
||||
|
||||
.. _Sender Policy Framework: https://en.wikipedia.org/wiki/Sender_Policy_Framework
|
||||
.. _SPF specification: http://www.openspf.org/SPF_Record_Syntax
|
||||
.. _SPF specification: http://www.open-spf.org/SPF_Record_Syntax
|
||||
|
||||
20
doc/user/events/guides/earlybird_dates.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
Use case: Early-bird tiers based on dates
|
||||
-----------------------------------------
|
||||
|
||||
Let's say you run a conference that has the following pricing scheme:
|
||||
|
||||
* 12 to 6 months before the event: € 450
|
||||
* 6 to 3 months before the event: € 550
|
||||
* closer than 3 months to the event: € 650
|
||||
|
||||
Of course, you could just set up one product and change its price at the given dates manually, but if you want to set
|
||||
this up automatically, here's how:
|
||||
|
||||
Create three products (e.g. "super early bird", "early bird", "regular ticket") with the respective prices and one shared
|
||||
quota of your total event capacity. Then, set the **available from** and **available until** configuration fields of
|
||||
the products to automatically turn them on and off based on the current date.
|
||||
|
||||
If you're in an event series, this will likely not help you since these dates would need to be the same for all dates
|
||||
in your series. As an alternative, you can go to the "Dates" section of your event series, select one or more dates,
|
||||
and scroll down to the "product settings" section. Here, you can also define availability times for individual products
|
||||
just for this date individually.
|
||||
47
doc/user/events/guides/earlybird_numbers.rst
Normal file
@@ -0,0 +1,47 @@
|
||||
Use case: Early-bird tiers based on ticket numbers
|
||||
--------------------------------------------------
|
||||
|
||||
Let's say you run a conference with 400 tickets that has the following pricing scheme:
|
||||
|
||||
* First 100 tickets ("super early bird"): € 450
|
||||
* Next 100 tickets ("early bird"): € 550
|
||||
* Remaining tickets ("regular"): € 650
|
||||
|
||||
First of all, create three products:
|
||||
|
||||
* "Super early bird ticket"
|
||||
* "Early bird ticket"
|
||||
* "Regular ticket"
|
||||
|
||||
Then, create three quotas:
|
||||
|
||||
* "Super early bird" with a **size of 100** and the "Super early bird ticket" product selected. At "Advanced options",
|
||||
select the box "Close this quota permanently once it is sold out".
|
||||
|
||||
* "Early bird and lower" with a **size of 200** and both of the "Super early bird ticket" and "Early bird ticket"
|
||||
products selected. At "Advanced options", select the box "Close this quota permanently once it is sold out".
|
||||
|
||||
* "All participants" with a **size of 400**, all three products selected and **no additional options**.
|
||||
|
||||
Next, modify the product "Regular ticket". In the section "Availability", you should look for the option "Only show
|
||||
after sellout of" and select your quota "Early bird and lower". Do the same for the "Early bird ticket" with the quota
|
||||
"Super early bird ticket".
|
||||
|
||||
This will ensure the following things:
|
||||
|
||||
* Each ticket level is only visible after the previous level is sold out.
|
||||
|
||||
* As soon as one level is really sold out, it's not coming back, because the quota "closes", i.e. locks in place.
|
||||
|
||||
* By creating a total quota of 400 with all tickets included, you can still make sure to sell the maximum number of
|
||||
tickets, even if e.g. early-bird tickets are canceled.
|
||||
|
||||
Optionally, if you want to hide the early bird prices once they are sold out, go to "Settings", then "Display" and
|
||||
select "Hide all products that are sold out". Of course, it might be a nice idea to keep showing the prices to remind
|
||||
people to buy earlier next time ;)
|
||||
|
||||
Please note that there might be short time intervals where the prices switch back and forth: When the last early bird
|
||||
tickets are in someone's cart (but not yet sold!), the early bird tickets will show as "Reserved" and the regular
|
||||
tickets start showing up. However, if the customers holding the reservations do not complete their order,
|
||||
the early bird tickets will become available again. This is not avoidable if we want to prevent malicious users
|
||||
from blocking all the cheap tickets without an actual sale happening.
|
||||
20
doc/user/events/guides/groups.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
Use case: Group discounts
|
||||
-------------------------
|
||||
|
||||
Often times, you want to give discounts for whole groups attending your event. pretix can't automatically discount based on volume, but there's still some ways you can set up group tickets.
|
||||
|
||||
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
|
||||
"""""""""""""""""
|
||||
|
||||
If you want to sell group tickets in fixed sizes, e.g. a table of eight at your gala dinner, you can use product bundles. Assuming you already set up a ticket for admission of single persons, you then set up a second product **Table (8 persons)** with a discounted full price. Then, head to the **Bundled products** tab of that product and add one bundle configuration to include the single admission product **eight times**. Next, create an unlimited quota mapped to the new product.
|
||||
|
||||
This way, the purchase of a table will automatically create eight tickets, leading to a correct calculation of your total quota and, as expected, eight persons on your check-in list. You can even ask for the individual names of the persons during checkout.
|
||||
22
doc/user/events/guides/mixed_taxation.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
Use case: Mixed taxation
|
||||
------------------------
|
||||
|
||||
Let's say you are a charitable organization in Germany and are allowed to charge a reduced tax rate of 7% for your educational event. However, your event includes a significant amount of food, you might need to charge a 19% tax rate on that portion. For example, your desired tax structure might then look like this:
|
||||
|
||||
* Conference ticket price: € 450 (incl. € 150 for food)
|
||||
|
||||
* incl. € 19.63 VAT at 7%
|
||||
* incl. € 23.95 VAT at 19%
|
||||
|
||||
You can implement this in pretix using product bundles. In order to do so, you should create the following two products:
|
||||
|
||||
* Conference ticket at € 450 with a 7% tax rule
|
||||
* Conference food at € 150 with a 19% tax rule and the option "**Only sell this product as part of a bundle**" set
|
||||
|
||||
In addition to your normal conference quota, you need to create an unlimited quota for the food product.
|
||||
|
||||
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:
|
||||
78
doc/user/events/guides/packages.rst
Normal file
@@ -0,0 +1,78 @@
|
||||
Use case: Discounted packages
|
||||
-----------------------------
|
||||
|
||||
Imagine you run a trade show that opens on three consecutive days and you want to have the following pricing:
|
||||
|
||||
* Single day: € 10
|
||||
* Any two days: € 17
|
||||
* All three days: € 25
|
||||
|
||||
In this case, there are multiple different ways you could set this up with pretix.
|
||||
|
||||
Option A: Combination products
|
||||
""""""""""""""""""""""""""""""
|
||||
|
||||
With this option, you just set up all the different combinations someone could by as a separate product. In this case, you would need 7 products:
|
||||
|
||||
* Day 1 pass
|
||||
* Day 2 pass
|
||||
* Day 3 pass
|
||||
* Day 1+2 pass
|
||||
* Day 2+3 pass
|
||||
* Day 1+3 pass
|
||||
* All-day pass
|
||||
|
||||
Then, you create three quotas, each one with the maximum capacity of your venue on any given day:
|
||||
|
||||
* Day 1 quota, linked to "Day 1 pass", "Day 1+2 pass", "Day 1+3 pass", and "All-day pass"
|
||||
* Day 2 quota, linked to "Day 2 pass", "Day 1+2 pass", "Day 2+3 pass", and "All-day pass"
|
||||
* Day 3 quota, linked to "Day 3 pass", "Day 2+3 pass", "Day 1+3 pass", and "All-day pass"
|
||||
|
||||
This way, every person gets exactly one ticket that they can use for all days that they attend. You can later set up check-in lists appropriately to make sure only tickets valid for a certain day can be scanned on that day.
|
||||
|
||||
The benefit of this option is that your product structure and order structure stays very simple. However, the two-day packages scale badly when you need many products.
|
||||
|
||||
We recommend this setup for most setups in which the number of possible combinations does not exceed the number of parts (here: number of days) by much.
|
||||
|
||||
Option B: Add-ons and bundles
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
We can combine the two features "product add-ons" and "product bundles" to set this up in a different way. Here, you would create the following five products:
|
||||
|
||||
* Day 1 pass in a category called "Day passes"
|
||||
* Day 2 pass in a category called "Day passes"
|
||||
* Day 3 pass in a category called "Day passes"
|
||||
* Two-day pass
|
||||
* All-day pass
|
||||
|
||||
This time, you will need five quotas:
|
||||
|
||||
* Day 1 quota, linked to "Day 1 pass"
|
||||
* Day 2 quota, linked to "Day 2 pass"
|
||||
* Day 3 quota, linked to "Day 3 pass"
|
||||
* Two-day pass quota, linked to "Two-day pass" (can be unlimited)
|
||||
* All-day pass quota, linked to "All-day pass" (can be unlimited)
|
||||
|
||||
Then, you open the "Add-On" tab in the settings of the **Two-day pass** product and create a new add-on configuration specifying the following options:
|
||||
|
||||
* Category: "Day passes"
|
||||
* Minimum number: 2
|
||||
* Maximum number: 2
|
||||
* Add-Ons are included in the price: Yes
|
||||
|
||||
This way, when buying a two-day pass, the user will be able to select *exactly* two days for free, which will then be added to the cart. Depending on your specific configuration, the user will now receive *two separate* tickets, one for each day.
|
||||
|
||||
For the all-day pass, you open the "Bundled products" tab in the settings of the **All-day pass** product and add **three** new bundled items with the following options:
|
||||
|
||||
* Bundled product: "Day 1/2/3"
|
||||
* Bundled variation: None
|
||||
* Count: 1
|
||||
* Designated price: 0
|
||||
|
||||
This way, when buying an all-day pass, three free day passes will *automatically* be added to the cart. Depending on your specific configuration, the user will now receive *three separate* tickets, one for each day.
|
||||
|
||||
This approach makes your order data more complicated, since e.g. someone who buys an all-day pass now technically bought **four products**. However, this option allows for more flexibility when you have lots of options to choose from.
|
||||
|
||||
.. tip::
|
||||
|
||||
Depending on the packages you offer, you **might not need both the add-on and the bundle feature**, i.e. you only need the add-on feature for the two-day pass and only the bundle feature for the all-day pass. You could also set up the two-day pass like we showed here, but the all-day pass like in option A!
|
||||
13
doc/user/events/guides/pricelevels.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
Use case: Multiple price levels
|
||||
-------------------------------
|
||||
|
||||
Imagine you're running a concert with general admission that sells a total of 200 tickets for two prices:
|
||||
|
||||
* Regular: € 25.00
|
||||
* Students: € 19.00
|
||||
|
||||
You can either set up two different products called e.g. "Regular ticket" and "Student ticket" with the respective prices, or two variations within the same product. In this simple case, it really doesn't matter.
|
||||
|
||||
In addition, you will need quotas. If you do not care how many of your tickets are sold to students, you should set up just **one quota** of 200 called e.g. "General admission" that you link to **both products**.
|
||||
|
||||
If you want to limit the number of student tickets to 50 to ensure a certain minimum revenue, but do not want to limit the number of regular tickets artificially, we suggest you to create the same quota of 200 that is linked to both products, and then create a **second quota** of 50 that is only linked to the student ticket. This way, the system will reduce both quotas whenever a student ticket is sold and only the larger quota when a regular ticket is sold.
|
||||
28
doc/user/events/guides/restricted_audience.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
Use case: Restricted audience
|
||||
-----------------------------
|
||||
|
||||
Not all events are for everyone. Sometimes, there is a good reason to restrict access to your event or parts of your event only to a specific, invited group. There's two ways to implement this with pretix:
|
||||
|
||||
Option A: Required voucher codes
|
||||
""""""""""""""""""""""""""""""""
|
||||
|
||||
If you check the option "**This product can only be bought using a voucher**" of one or multiple products, only people holding an applicable voucher code will be able to buy the product.
|
||||
|
||||
You can then generate voucher codes for the respective product and send them out to the group of possible attendees. If the recipients should still be able to choose between different products, you can create an additional quota and map the voucher to that quota instead of the products themselves.
|
||||
|
||||
There's also the second option "**This product will only be shown if a voucher matching the product is redeemed**". In this case, the existence of the product won't even be shown before a voucher code is entered – useful for a VIP option in a shop where you also sell other products to the general public. Please note that this option does **not** work with vouchers assigned to a quota, only with vouchers assigned directly to the product.
|
||||
|
||||
This option is appropriate if you know the group of people beforehand, e.g. members of a club, and you can mail them their access codes.
|
||||
|
||||
Option B: Order approvals
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
If you do not know your audience already, but still want to restrict it to a certain group, e.g. people with a given profession, you can check the "**Buying this product requires approval**" in the settings of your product. If a customer tries to buy such a product, they will be able to place their order but can not proceed to payment. Instead, you will be asked to approve or deny the order and only if you approve it, we will send a payment link to the customer.
|
||||
|
||||
This requires the customer to interact with the ticket shop twice (once for the order, once for the payment) which adds a little more friction, but gives you full control over who attends the event.
|
||||
|
||||
Option C: Registered customers & memberships
|
||||
""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
You can also do this by requiring that customers have a customer account and an active membership. You can find more
|
||||
information on this mechanism in the :ref:`seasontickets` article.
|
||||
92
doc/user/events/guides/season_tickets.rst
Normal file
@@ -0,0 +1,92 @@
|
||||
.. _seasontickets:
|
||||
|
||||
Use case: Season tickets
|
||||
========================
|
||||
|
||||
Season tickets and similar time-based tickets are popular for swimming pools, sports clubs, theaters and lots of other
|
||||
types of venues. In this article, we show you different ways to set them up with pretix. Of course, other types of
|
||||
tickets such as week tickets, month tickets or tickets of ten can be created with the same mechanism.
|
||||
|
||||
There is a big difference between the two ways we show below.
|
||||
|
||||
With **Option A**, a customer who purchases a season ticket creates an account with their email address and a password
|
||||
and the season ticket will be saved in that account. If the customer wants to use the season ticket, they need to buy
|
||||
an additional free ticket for the specific event they want to visit. This makes sense for all events or venues with
|
||||
**limited capacity** or **reserved seating**, because it still allows you to set an upper limit of people showing up
|
||||
for a specific event or time slot.
|
||||
|
||||
With **Option B**, a customer who purchases a season ticket receives a single ticket with a single QR code that can be
|
||||
used an unlimited number of times. This makes sense if the capacity of your venue is virtually unlimited and you do not
|
||||
need to know in advance how many season ticket holders will show up.
|
||||
|
||||
Option A: Memberships and multiple tickets
|
||||
""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Since this approach requires customers to be identified with a customer account, you first need to enable the customer
|
||||
accounts feature in your organizer settings in the "Customer accounts" tab.
|
||||
|
||||
.. thumbnail:: ../../../screens/event/seasontickets_orgsettings.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
After doing so, a new menu item "Customer accounts" will also show up in the main menu of your organizer account on
|
||||
the left. Open it's menu and click on "Membership types". Then, select to "create a new membership type".
|
||||
|
||||
You can name the membership type in a way that clearly explains where it is valid, e.g. "season pass main location"
|
||||
or "season pass all locations". There are a few details you can configure on this page, such as whether the season pass
|
||||
can be used by multiple different persons, or if the season pass can be used for multiple tickets for the same time
|
||||
slot. You can also define a maximum number of usages, which is useful if you e.g. use this feature to add a "ticket of
|
||||
ten".
|
||||
|
||||
.. thumbnail:: ../../../screens/event/seasontickets_membershiptype.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Next, you need a way of selling these season passes. Theoretically this can be done through the same event series that
|
||||
you usually use, but it's probably cleaner and easier to find for customers if you create a **new event** that you only
|
||||
use to sell season passes. The start and end date of the new event should correspond to the dates of your season.
|
||||
|
||||
Inside the new event, you only need to create a single product which you can call "season ticket". Inside that product's
|
||||
settings, head to the "Additional settings" section and look for the option "This product creates a membership of type".
|
||||
Select the membership type you just created. By default, the checkbox "The duration of the membership is the same as the
|
||||
duration of the event or event series date" is active, which is fine for our season ticket example, but you might need
|
||||
to unset it and provide custom timing for other ticket types such as week passes.
|
||||
|
||||
.. thumbnail:: ../../../screens/event/seasontickets_issue.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
To prevent confusion, it might be useful to turn off ticket downloading at "Settings" → "Tickets" for your new event.
|
||||
That's it, you are now ready to sell season tickets!
|
||||
|
||||
We can now deal with how to use the season tickets. Move back to your existing event and create a new product
|
||||
**or** product variation of your regular product which you call "ticket for season ticket holders" and assign a price
|
||||
of zero. In the "Availability" section of the product or variation settings, check the option "Require a valid
|
||||
membership" and again select the membership type you created. You can of course repeat this with all events the season
|
||||
ticket holder should have access to.
|
||||
|
||||
.. thumbnail:: ../../../screens/event/seasontickets_require.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
|
||||
Option B: All-access in a single pass
|
||||
"""""""""""""""""""""""""""""""""""""
|
||||
|
||||
If you have only a single event series with many time slots and you do not care how many season ticket holders show up,
|
||||
there's a solution that does not require your customers to set up accounts and book a new ticket on every visit.
|
||||
|
||||
Instead, you can just create an additional product "Season ticket" that you enable either in a "special" date of your
|
||||
event series just created for this purpose, or in all of your dates so it can be easily found by customers.
|
||||
|
||||
Then, you can set up your check-in lists with custom logic in the "Advanced" tab of your check-in list settings.
|
||||
The logic needs to ensure the following requirements:
|
||||
|
||||
* Regular ticket holders can only get in during their assigned time frame **and** when they haven't used their ticket before.
|
||||
|
||||
* Season ticket holders can always get in.
|
||||
|
||||
Here's an example on how to set this up:
|
||||
|
||||
.. thumbnail:: ../../../screens/event/seasontickets_rules.png
|
||||
:align: center
|
||||
:class: screenshot
|
||||
24
doc/user/events/guides/terminology.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
Terminology
|
||||
-----------
|
||||
|
||||
Products
|
||||
A product is a basic entity that can be bought. You can think of it as a ticket type, but it can be more things than just a ticket, it can also be a piece of merchandise, a parking slot, etc.
|
||||
You might find some places where they are called "items" instead, but we're trying to get rid of that.
|
||||
|
||||
Product categories
|
||||
Products can be sorted into categories. Each product can only be in one category. Category are mostly used for grouping related products together to make your event page easier to read for buyers. However, we'll need categories as well to set up some of the structures outlined below.
|
||||
|
||||
Product variations
|
||||
During creation of a product, you can decide that your product should have multiple variations. Variations of a product can differ in price, description, and availability, but are otherwise the same. You could use this e.g. for differentiating between a regular ticket and a discounted ticket for students, or when selling merchandise to differentiate the different sizes of a t-shirt.
|
||||
|
||||
Product add-ons
|
||||
Add-ons are products that are sold together with another product (which we will call the base product in this case). For example, you could have a base product "Conference ticket" and then define multiple workshops that can be chosen as an add-on.
|
||||
|
||||
Product bundles
|
||||
Bundles work very similarly to add-ons, but are different in the way that they are always automatically included with the base product and cannot be optional. In contrast to add-on products, the same product can be included multiple times in a bundle.
|
||||
|
||||
Quotas
|
||||
Quotas define the availability of products. A quota has a size (i.e. the number of products in the inventory) and is mapped to one or multiple products or variations.
|
||||
|
||||
Questions
|
||||
Questions are user-defined form fields that buyers will need to fill out when purchasing a product.
|
||||
17
doc/user/events/guides/upselling.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
Use case: Up-selling of ticket extras
|
||||
-------------------------------------
|
||||
|
||||
Let's assume you're putting up a great music festival, and to save trouble with handling payments on-site, you want to sell parking spaces together with your ticket. By using our add-on feature, you can prompt all users to book the parking space (to make sure they see it) and ensure that only people with a ticket can book a parking space. You can set it up like this:
|
||||
|
||||
* Create a base product "Festival admission"
|
||||
* Create a quota for the base product
|
||||
* Create a category "Ticket extras" and check "Products in this category are add-on products"
|
||||
* Create a product "Parking space" within that category
|
||||
* Create a quota for the parking space product
|
||||
* Go to the base product and select the tab "Add-Ons" at the top. Click "Add a new add-on" and choose the "Ticket extras" category. You can keep the numbers at 0 and 1.
|
||||
|
||||
During checkout, all buyers of the base product will now be prompted if they want to add the parking space.
|
||||
|
||||
.. tip::
|
||||
|
||||
You can also use add-on products for free things, just to keep tabs on capacity.
|
||||
77
doc/user/events/guides/workshops.rst
Normal file
@@ -0,0 +1,77 @@
|
||||
Use case: Conference with workshops
|
||||
-----------------------------------
|
||||
|
||||
When running a conference, you might also organize a number of workshops with smaller capacity. To be able to plan, it would be great to know which workshops an attendee plans to attend.
|
||||
|
||||
Option A: Questions
|
||||
"""""""""""""""""""
|
||||
|
||||
Your first and simplest option is to just create a multiple-choice question. This has the upside of making it easy for users to change their mind later on, but will not allow you to restrict the number of attendees signing up for a given workshop – or even charge extra for a given workshop.
|
||||
|
||||
Option B: Add-on products with fixed time slots
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
The usually better option is to go with add-on products. Let's take for example the following conference schedule, in which the lecture can be attended by anyone, but the workshops only have space for 20 persons each:
|
||||
|
||||
==================== =================================== ===================================
|
||||
Time Room A Room B
|
||||
==================== =================================== ===================================
|
||||
Wednesday morning Lecture
|
||||
Wednesday afternoon Workshop A Workshop B
|
||||
Thursday morning Workshop C Workshop D (20 € extra charge)
|
||||
==================== =================================== ===================================
|
||||
|
||||
Assuming you already created one or more products for your general conference admission, we suggest that you additionally create:
|
||||
|
||||
* A category called "Workshops" with the checkbox "Products in this category are add-on products" activated
|
||||
|
||||
* A free product called "Wednesday afternoon" within the category "Workshops" and with two variations:
|
||||
|
||||
* Workshop A
|
||||
|
||||
* Workshop B
|
||||
|
||||
* A free product called "Thursday morning" within the category "Workshops" and with two variations:
|
||||
|
||||
* Workshop C
|
||||
|
||||
* Workshop D with a price of 20 €
|
||||
|
||||
* Four quotas for each of the workshops
|
||||
|
||||
* One add-on configuration on your base product that allows users to choose between 0 and 2 products from the category "Workshops"
|
||||
|
||||
Option C: Add-on products with variable time slots
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
The above option only works if your conference uses fixed time slots and every workshop uses exactly one time slot. If
|
||||
your schedule looks like this, it's not going to work great:
|
||||
|
||||
+-------------+------------+-----------+
|
||||
| Time | Room A | Room B |
|
||||
+=============+============+===========+
|
||||
| 09:00-11:00 | Talk 1 | Long |
|
||||
+-------------+------------+ Workshop 1|
|
||||
| 11:00-13:00 | Talk 2 | |
|
||||
+-------------+------------+-----------+
|
||||
| 14:00-16:00 | Long | Talk 3 |
|
||||
+-------------+ workshop 2 +-----------+
|
||||
| 16:00-18:00 | | Talk 4 |
|
||||
+-------------+------------+-----------+
|
||||
|
||||
In this case, we recommend that you go to *Settings*, then *Plugins* and activate the plugin **Agenda constraints**.
|
||||
|
||||
Then, create a product (without variations) for every single part that should be bookable (talks 1-4 and long workshops
|
||||
1 and 2) as well as appropriate quotas for each of them.
|
||||
|
||||
All of these products should be part of the same category. In your base product (e.g. your conference ticket), you
|
||||
can then create an add-on product configuration allowing users to add products from this category.
|
||||
|
||||
If you edit these products, you will be able to enter the "Start date" and "End date" of the talk or workshop close
|
||||
to the bottom of the page. If you fill in these values, pretix will automatically ensure no overlapping talks are
|
||||
booked.
|
||||
|
||||
.. note::
|
||||
|
||||
This option is currently only available on pretix Hosted. If you are interested in using it with pretix Enterprise,
|
||||
please contact sales@pretix.eu.
|
||||
@@ -6,353 +6,18 @@ However, it is easy to get lost in the process or to get started with building y
|
||||
Often times, there are multiple ways to do something that come with different advantages and disadvantages.
|
||||
This guide will walk you through a number of typical examples of pretix event structures and will explain how to set them up – feel free to just skip ahead to a section relevant for you.
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
|
||||
Products
|
||||
A product is a basic entity that can be bought. You can think of it as a ticket type, but it can be more things than just a ticket, it can also be a piece of merchandise, a parking slot, etc.
|
||||
You might find some places where they are called "items" instead, but we're trying to get rid of that.
|
||||
|
||||
Product categories
|
||||
Products can be sorted into categories. Each product can only be in one category. Category are mostly used for grouping related products together to make your event page easier to read for buyers. However, we'll need categories as well to set up some of the structures outlined below.
|
||||
|
||||
Product variations
|
||||
During creation of a product, you can decide that your product should have multiple variations. Variations of a product can differ in price, description, and availability, but are otherwise the same. You could use this e.g. for differentiating between a regular ticket and a discounted ticket for students, or when selling merchandise to differentiate the different sizes of a t-shirt.
|
||||
|
||||
Product add-ons
|
||||
Add-ons are products that are sold together with another product (which we will call the base product in this case). For example, you could have a base product "Conference ticket" and then define multiple workshops that can be chosen as an add-on.
|
||||
|
||||
Product bundles
|
||||
Bundles work very similarly to add-ons, but are different in the way that they are always automatically included with the base product and cannot be optional. In contrast to add-on products, the same product can be included multiple times in a bundle.
|
||||
|
||||
Quotas
|
||||
Quotas define the availability of products. A quota has a size (i.e. the number of products in the inventory) and is mapped to one or multiple products or variations.
|
||||
|
||||
Questions
|
||||
Questions are user-defined form fields that buyers will need to fill out when purchasing a product.
|
||||
|
||||
Use case: Multiple price levels
|
||||
-------------------------------
|
||||
|
||||
Imagine you're running a concert with general admission that sells a total of 200 tickets for two prices:
|
||||
|
||||
* Regular: € 25.00
|
||||
* Students: € 19.00
|
||||
|
||||
You can either set up two different products called e.g. "Regular ticket" and "Student ticket" with the respective prices, or two variations within the same product. In this simple case, it really doesn't matter.
|
||||
|
||||
In addition, you will need quotas. If you do not care how many of your tickets are sold to students, you should set up just **one quota** of 200 called e.g. "General admission" that you link to **both products**.
|
||||
|
||||
If you want to limit the number of student tickets to 50 to ensure a certain minimum revenue, but do not want to limit the number of regular tickets artificially, we suggest you to create the same quota of 200 that is linked to both products, and then create a **second quota** of 50 that is only linked to the student ticket. This way, the system will reduce both quotas whenever a student ticket is sold and only the larger quota when a regular ticket is sold.
|
||||
|
||||
Use case: Early-bird tiers based on dates
|
||||
-----------------------------------------
|
||||
|
||||
Let's say you run a conference that has the following pricing scheme:
|
||||
|
||||
* 12 to 6 months before the event: € 450
|
||||
* 6 to 3 months before the event: € 550
|
||||
* closer than 3 months to the event: € 650
|
||||
|
||||
Of course, you could just set up one product and change its price at the given dates manually, but if you want to set this up automatically, here's how:
|
||||
|
||||
Create three products (e.g. "super early bird", "early bird", "regular ticket") with the respective prices and one shared quota of your total event capacity. Then, set the **available from** and **available until** configuration fields of the products to automatically turn them on and off based on the current date.
|
||||
|
||||
Use case: Early-bird tiers based on ticket numbers
|
||||
--------------------------------------------------
|
||||
|
||||
Let's say you run a conference with 400 tickets that has the following pricing scheme:
|
||||
|
||||
* First 100 tickets ("super early bird"): € 450
|
||||
* Next 100 tickets ("early bird"): € 550
|
||||
* Remaining tickets ("regular"): € 650
|
||||
|
||||
First of all, create three products:
|
||||
|
||||
* "Super early bird ticket"
|
||||
* "Early bird ticket"
|
||||
* "Regular ticket"
|
||||
|
||||
Then, create three quotas:
|
||||
|
||||
* "Super early bird" with a **size of 100** and the "Super early bird ticket" product selected. At "Advanced options",
|
||||
select the box "Close this quota permanently once it is sold out".
|
||||
|
||||
* "Early bird and lower" with a **size of 200** and both of the "Super early bird ticket" and "Early bird ticket"
|
||||
products selected. At "Advanced options", select the box "Close this quota permanently once it is sold out".
|
||||
|
||||
* "All participants" with a **size of 400**, all three products selected and **no additional options**.
|
||||
|
||||
Next, modify the product "Regular ticket". In the section "Availability", you should look for the option "Only show
|
||||
after sellout of" and select your quota "Early bird and lower". Do the same for the "Early bird ticket" with the quota
|
||||
"Super early bird ticket".
|
||||
|
||||
This will ensure the following things:
|
||||
|
||||
* Each ticket level is only visible after the previous level is sold out.
|
||||
|
||||
* As soon as one level is really sold out, it's not coming back, because the quota "closes", i.e. locks in place.
|
||||
|
||||
* By creating a total quota of 400 with all tickets included, you can still make sure to sell the maximum number of
|
||||
tickets, even if e.g. early-bird tickets are canceled.
|
||||
|
||||
Optionally, if you want to hide the early bird prices once they are sold out, go to "Settings", then "Display" and
|
||||
select "Hide all products that are sold out". Of course, it might be a nice idea to keep showing the prices to remind
|
||||
people to buy earlier next time ;)
|
||||
|
||||
Please note that there might be short time intervals where the prices switch back and forth: When the last early bird
|
||||
tickets are in someone's cart (but not yet sold!), the early bird tickets will show as "Reserved" and the regular
|
||||
tickets start showing up. However, if the customers holding the reservations do not complete their order,
|
||||
the early bird tickets will become available again. This is not avoidable if we want to prevent malicious users
|
||||
from blocking all the cheap tickets without an actual sale happening.
|
||||
|
||||
Use case: Up-selling of ticket extras
|
||||
-------------------------------------
|
||||
|
||||
Let's assume you're putting up a great music festival, and to save trouble with handling payments on-site, you want to sell parking spaces together with your ticket. By using our add-on feature, you can prompt all users to book the parking space (to make sure they see it) and ensure that only people with a ticket can book a parking space. You can set it up like this:
|
||||
|
||||
* Create a base product "Festival admission"
|
||||
* Create a quota for the base product
|
||||
* Create a category "Ticket extras" and check "Products in this category are add-on products"
|
||||
* Create a product "Parking space" within that category
|
||||
* Create a quota for the parking space product
|
||||
* Go to the base product and select the tab "Add-Ons" at the top. Click "Add a new add-on" and choose the "Ticket extras" category. You can keep the numbers at 0 and 1.
|
||||
|
||||
During checkout, all buyers of the base product will now be prompted if they want to add the parking space.
|
||||
|
||||
.. tip::
|
||||
|
||||
You can also use add-on products for free things, just to keep tabs on capacity.
|
||||
|
||||
Use case: Conference with workshops
|
||||
-----------------------------------
|
||||
|
||||
When running a conference, you might also organize a number of workshops with smaller capacity. To be able to plan, it would be great to know which workshops an attendee plans to attend.
|
||||
|
||||
Option A: Questions
|
||||
"""""""""""""""""""
|
||||
|
||||
Your first and simplest option is to just create a multiple-choice question. This has the upside of making it easy for users to change their mind later on, but will not allow you to restrict the number of attendees signing up for a given workshop – or even charge extra for a given workshop.
|
||||
|
||||
Option B: Add-on products with fixed time slots
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
The usually better option is to go with add-on products. Let's take for example the following conference schedule, in which the lecture can be attended by anyone, but the workshops only have space for 20 persons each:
|
||||
|
||||
==================== =================================== ===================================
|
||||
Time Room A Room B
|
||||
==================== =================================== ===================================
|
||||
Wednesday morning Lecture
|
||||
Wednesday afternoon Workshop A Workshop B
|
||||
Thursday morning Workshop C Workshop D (20 € extra charge)
|
||||
==================== =================================== ===================================
|
||||
|
||||
Assuming you already created one or more products for your general conference admission, we suggest that you additionally create:
|
||||
|
||||
* A category called "Workshops" with the checkbox "Products in this category are add-on products" activated
|
||||
|
||||
* A free product called "Wednesday afternoon" within the category "Workshops" and with two variations:
|
||||
|
||||
* Workshop A
|
||||
|
||||
* Workshop B
|
||||
|
||||
* A free product called "Thursday morning" within the category "Workshops" and with two variations:
|
||||
|
||||
* Workshop C
|
||||
|
||||
* Workshop D with a price of 20 €
|
||||
|
||||
* Four quotas for each of the workshops
|
||||
|
||||
* One add-on configuration on your base product that allows users to choose between 0 and 2 products from the category "Workshops"
|
||||
|
||||
Option C: Add-on products with variable time slots
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
The above option only works if your conference uses fixed time slots and every workshop uses exactly one time slot. If
|
||||
your schedule looks like this, it's not going to work great:
|
||||
|
||||
+-------------+------------+-----------+
|
||||
| Time | Room A | Room B |
|
||||
+=============+============+===========+
|
||||
| 09:00-11:00 | Talk 1 | Long |
|
||||
+-------------+------------+ Workshop 1|
|
||||
| 11:00-13:00 | Talk 2 | |
|
||||
+-------------+------------+-----------+
|
||||
| 14:00-16:00 | Long | Talk 3 |
|
||||
+-------------+ workshop 2 +-----------+
|
||||
| 16:00-18:00 | | Talk 4 |
|
||||
+-------------+------------+-----------+
|
||||
|
||||
In this case, we recommend that you go to *Settings*, then *Plugins* and activate the plugin **Agenda constraints**.
|
||||
|
||||
Then, create a product (without variations) for every single part that should be bookable (talks 1-4 and long workshops
|
||||
1 and 2) as well as appropriate quotas for each of them.
|
||||
|
||||
All of these products should be part of the same category. In your base product (e.g. your conference ticket), you
|
||||
can then create an add-on product configuration allowing users to add products from this category.
|
||||
|
||||
If you edit these products, you will be able to enter the "Start date" and "End date" of the talk or workshop close
|
||||
to the bottom of the page. If you fill in these values, pretix will automatically ensure no overlapping talks are
|
||||
booked.
|
||||
|
||||
.. note::
|
||||
|
||||
This option is currently only available on pretix Hosted. If you are interested in using it with pretix Enterprise,
|
||||
please contact sales@pretix.eu.
|
||||
|
||||
|
||||
Use case: Discounted packages
|
||||
-----------------------------
|
||||
|
||||
Imagine you run a trade show that opens on three consecutive days and you want to have the following pricing:
|
||||
|
||||
* Single day: € 10
|
||||
* Any two days: € 17
|
||||
* All three days: € 25
|
||||
|
||||
In this case, there are multiple different ways you could set this up with pretix.
|
||||
|
||||
Option A: Combination products
|
||||
""""""""""""""""""""""""""""""
|
||||
|
||||
With this option, you just set up all the different combinations someone could by as a separate product. In this case, you would need 7 products:
|
||||
|
||||
* Day 1 pass
|
||||
* Day 2 pass
|
||||
* Day 3 pass
|
||||
* Day 1+2 pass
|
||||
* Day 2+3 pass
|
||||
* Day 1+3 pass
|
||||
* All-day pass
|
||||
|
||||
Then, you create three quotas, each one with the maximum capacity of your venue on any given day:
|
||||
|
||||
* Day 1 quota, linked to "Day 1 pass", "Day 1+2 pass", "Day 1+3 pass", and "All-day pass"
|
||||
* Day 2 quota, linked to "Day 2 pass", "Day 1+2 pass", "Day 2+3 pass", and "All-day pass"
|
||||
* Day 3 quota, linked to "Day 3 pass", "Day 2+3 pass", "Day 1+3 pass", and "All-day pass"
|
||||
|
||||
This way, every person gets exactly one ticket that they can use for all days that they attend. You can later set up check-in lists appropriately to make sure only tickets valid for a certain day can be scanned on that day.
|
||||
|
||||
The benefit of this option is that your product structure and order structure stays very simple. However, the two-day packages scale badly when you need many products.
|
||||
|
||||
We recommend this setup for most setups in which the number of possible combinations does not exceed the number of parts (here: number of days) by much.
|
||||
|
||||
Option B: Add-ons and bundles
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
We can combine the two features "product add-ons" and "product bundles" to set this up in a different way. Here, you would create the following five products:
|
||||
|
||||
* Day 1 pass in a category called "Day passes"
|
||||
* Day 2 pass in a category called "Day passes"
|
||||
* Day 3 pass in a category called "Day passes"
|
||||
* Two-day pass
|
||||
* All-day pass
|
||||
|
||||
This time, you will need five quotas:
|
||||
|
||||
* Day 1 quota, linked to "Day 1 pass"
|
||||
* Day 2 quota, linked to "Day 2 pass"
|
||||
* Day 3 quota, linked to "Day 3 pass"
|
||||
* Two-day pass quota, linked to "Two-day pass" (can be unlimited)
|
||||
* All-day pass quota, linked to "All-day pass" (can be unlimited)
|
||||
|
||||
Then, you open the "Add-On" tab in the settings of the **Two-day pass** product and create a new add-on configuration specifying the following options:
|
||||
|
||||
* Category: "Day passes"
|
||||
* Minimum number: 2
|
||||
* Maximum number: 2
|
||||
* Add-Ons are included in the price: Yes
|
||||
|
||||
This way, when buying a two-day pass, the user will be able to select *exactly* two days for free, which will then be added to the cart. Depending on your specific configuration, the user will now receive *two separate* tickets, one for each day.
|
||||
|
||||
For the all-day pass, you open the "Bundled products" tab in the settings of the **All-day pass** product and add **three** new bundled items with the following options:
|
||||
|
||||
* Bundled product: "Day 1/2/3"
|
||||
* Bundled variation: None
|
||||
* Count: 1
|
||||
* Designated price: 0
|
||||
|
||||
This way, when buying an all-day pass, three free day passes will *automatically* be added to the cart. Depending on your specific configuration, the user will now receive *three separate* tickets, one for each day.
|
||||
|
||||
This approach makes your order data more complicated, since e.g. someone who buys an all-day pass now technically bought **four products**. However, this option allows for more flexibility when you have lots of options to choose from.
|
||||
|
||||
.. tip::
|
||||
|
||||
Depending on the packages you offer, you **might not need both the add-on and the bundle feature**, i.e. you only need the add-on feature for the two-day pass and only the bundle feature for the all-day pass. You could also set up the two-day pass like we showed here, but the all-day pass like in option A!
|
||||
|
||||
Use case: Group discounts
|
||||
-------------------------
|
||||
|
||||
Often times, you want to give discounts for whole groups attending your event. pretix can't automatically discount based on volume, but there's still some ways you can set up group tickets.
|
||||
|
||||
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
|
||||
"""""""""""""""""
|
||||
|
||||
If you want to sell group tickets in fixed sizes, e.g. a table of eight at your gala dinner, you can use product bundles. Assuming you already set up a ticket for admission of single persons, you then set up a second product **Table (8 persons)** with a discounted full price. Then, head to the **Bundled products** tab of that product and add one bundle configuration to include the single admission product **eight times**. Next, create an unlimited quota mapped to the new product.
|
||||
|
||||
This way, the purchase of a table will automatically create eight tickets, leading to a correct calculation of your total quota and, as expected, eight persons on your check-in list. You can even ask for the individual names of the persons during checkout.
|
||||
|
||||
Use case: Restricted audience
|
||||
-----------------------------
|
||||
|
||||
Not all events are for everyone. Sometimes, there is a good reason to restrict access to your event or parts of your event only to a specific, invited group. There's two ways to implement this with pretix:
|
||||
|
||||
Option A: Required voucher codes
|
||||
""""""""""""""""""""""""""""""""
|
||||
|
||||
If you check the option "**This product can only be bought using a voucher**" of one or multiple products, only people holding an applicable voucher code will be able to buy the product.
|
||||
|
||||
You can then generate voucher codes for the respective product and send them out to the group of possible attendees. If the recipients should still be able to choose between different products, you can create an additional quota and map the voucher to that quota instead of the products themselves.
|
||||
|
||||
There's also the second option "**This product will only be shown if a voucher matching the product is redeemed**". In this case, the existence of the product won't even be shown before a voucher code is entered – useful for a VIP option in a shop where you also sell other products to the general public. Please note that this option does **not** work with vouchers assigned to a quota, only with vouchers assigned directly to the product.
|
||||
|
||||
This option is appropriate if you know the group of people beforehand, e.g. members of a club, and you can mail them their access codes.
|
||||
|
||||
Option B: Order approvals
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
If you do not know your audience already, but still want to restrict it to a certain group, e.g. people with a given profession, you can check the "**Buying this product requires approval**" in the settings of your product. If a customer tries to buy such a product, they will be able to place their order but can not proceed to payment. Instead, you will be asked to approve or deny the order and only if you approve it, we will send a payment link to the customer.
|
||||
|
||||
This requires the customer to interact with the ticket shop twice (once for the order, once for the payment) which adds a little more friction, but gives you full control over who attends the event.
|
||||
|
||||
Use case: Mixed taxation
|
||||
------------------------
|
||||
|
||||
Let's say you are a charitable organization in Germany and are allowed to charge a reduced tax rate of 7% for your educational event. However, your event includes a significant amount of food, you might need to charge a 19% tax rate on that portion. For example, your desired tax structure might then look like this:
|
||||
|
||||
* Conference ticket price: € 450 (incl. € 150 for food)
|
||||
|
||||
* incl. € 19.63 VAT at 7%
|
||||
* incl. € 23.95 VAT at 19%
|
||||
|
||||
You can implement this in pretix using product bundles. In order to do so, you should create the following two products:
|
||||
|
||||
* Conference ticket at € 450 with a 7% tax rule
|
||||
* Conference food at € 150 with a 19% tax rule and the option "**Only sell this product as part of a bundle**" set
|
||||
|
||||
In addition to your normal conference quota, you need to create an unlimited quota for the food product.
|
||||
|
||||
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/terminology
|
||||
guides/pricelevels
|
||||
guides/earlybird_dates
|
||||
guides/earlybird_numbers
|
||||
guides/upselling
|
||||
guides/workshops
|
||||
guides/packages
|
||||
guides/groups
|
||||
guides/restricted_audience
|
||||
guides/timeslots
|
||||
guides/season_tickets
|
||||
guides/mixed_taxation
|
||||
|
||||
@@ -4,8 +4,7 @@ Embeddable Widget
|
||||
=================
|
||||
|
||||
If you want to show your ticket shop on your event website or blog, you can use our JavaScript widget. This way,
|
||||
users will not need to leave your site to buy their ticket in most cases. The widget will still open a new tab
|
||||
for the checkout if the user is on a mobile device.
|
||||
users will not need to leave your site to buy their ticket in most cases.
|
||||
|
||||
To obtain the correct HTML code for embedding your event into your website, we recommend that you go to the "Widget"
|
||||
tab of your event's settings. You can specify some optional settings there (for example the language of the widget)
|
||||
@@ -310,6 +309,10 @@ Currently, the following attributes are understood by pretix itself:
|
||||
always be modified. Note that this is not a security feature and can easily be overridden by users, so do not rely
|
||||
on this for authentication.
|
||||
|
||||
* If ``data-consent="…"`` is given, the cookie consent mechanism will be initialized with consent for the given cookie
|
||||
providers. All other providers will be disabled, no consent dialog will be shown. This is useful if you already
|
||||
asked the user for consent and don't want them to be asked again. Example: ``data-consent="facebook,google_analytics"``
|
||||
|
||||
Any configured pretix plugins might understand more data fields. For example, if the appropriate plugins on pretix
|
||||
Hosted or pretix Enterprise are active, you can pass the following fields:
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ going to develop around pretix, for example connect to pretix through our API, y
|
||||
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
|
||||
| |:de:| Wertgutschein
|
||||
- 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.
|
||||
@@ -104,13 +104,18 @@ going to develop around pretix, for example connect to pretix through our API, y
|
||||
* - | |:gb:| **Order code**
|
||||
| |:de:| Bestellnummer
|
||||
- An order code is the unique identifier of an order, usually consisting of 5 numbers and letters.
|
||||
* - | |:gb:| **Customer**
|
||||
| |:de:| Kund\*in
|
||||
- A customer is the person who buys a ticket, regardless of who will be using it later. A customer can be defined
|
||||
just by an email address or a name, or can have a persistent **customer account** they can log in to.
|
||||
* - | |: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:| **Attendee**
|
||||
| |:de:| Teilnehmer\*in
|
||||
- An attendee is the person designated to use a specific order position to access the event. It may be the same
|
||||
or a different person as the customer.
|
||||
* - | |: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,
|
||||
@@ -121,9 +126,14 @@ going to develop around pretix, for example connect to pretix through our API, y
|
||||
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:| **Membership**
|
||||
| |:de:| Mitgliedschaft
|
||||
- A membership is a status attached customer, granting that customer a special right for a limited amount of time.
|
||||
This special right could for example be the right to purchase a specific product. Memberships can be sold through
|
||||
pretix as well.
|
||||
* - | |: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.
|
||||
- A check-in is the event of someone's ticket being 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
|
||||
@@ -151,7 +161,7 @@ going to develop around pretix, for example connect to pretix through our API, y
|
||||
- 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.
|
||||
- A user is anyone who can sign into the backend interface of pretix. Not to be confused with *Customer*.
|
||||
* - | |: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.
|
||||
|
||||
@@ -33,6 +33,8 @@ Permissions separate into two areas:
|
||||
|
||||
* Can create events – To create a new event under this organizer account, users need to have this permission
|
||||
|
||||
* Can manage customer accounts – This permission is required to view and change organizer-level customer accounts.
|
||||
|
||||
* Can change teams and permissions – This permission is required to perform the kind of action you are doing right now.
|
||||
Anyone with this permission can assign arbitrary other permissions to themselves, so this is the most powerful
|
||||
permission there is to give.
|
||||
|
||||
2
src/.gitignore
vendored
@@ -9,4 +9,4 @@ dist/
|
||||
*.bak
|
||||
pretix/static/jsi18n/
|
||||
node_modules/
|
||||
|
||||
.eggs/
|
||||
|
||||
@@ -34,5 +34,7 @@ git push
|
||||
# Unlock Weblate
|
||||
for c in $COMPONENTS; do
|
||||
wlc unlock $c;
|
||||
done
|
||||
for c in $COMPONENTS; do
|
||||
wlc pull $c;
|
||||
done
|
||||
|
||||
@@ -26,3 +26,5 @@ recursive-include pretix/plugins/badges/templates *
|
||||
recursive-include pretix/plugins/badges/static *
|
||||
recursive-include pretix/plugins/returnurl/templates *
|
||||
recursive-include pretix/plugins/returnurl/static *
|
||||
recursive-include pretix/plugins/webcheckin/templates *
|
||||
recursive-include pretix/plugins/webcheckin/static *
|
||||
|
||||
@@ -1,4 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
@@ -1 +1,22 @@
|
||||
__version__ = "3.17.0"
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
__version__ = "4.6.0.dev0"
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PretixApiConfig(AppConfig):
|
||||
name = 'pretix.api'
|
||||
label = 'pretixapi'
|
||||
|
||||
def ready(self):
|
||||
from . import signals, webhooks # noqa
|
||||
|
||||
|
||||
default_app_config = 'pretix.api.PretixApiConfig'
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
30
src/pretix/api/apps.py
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PretixApiConfig(AppConfig):
|
||||
name = 'pretix.api'
|
||||
label = 'pretixapi'
|
||||
|
||||
def ready(self):
|
||||
from . import signals, webhooks # noqa
|
||||
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django_scopes import scopes_disabled
|
||||
from rest_framework import exceptions
|
||||
|
||||
@@ -1,4 +1,26 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class FullAccessSecurityProfile:
|
||||
@@ -37,6 +59,7 @@ class PretixScanSecurityProfile(AllowListSecurityProfile):
|
||||
('GET', 'api-v1:badgeitem-list'),
|
||||
('GET', 'api-v1:checkinlist-list'),
|
||||
('GET', 'api-v1:checkinlist-status'),
|
||||
('POST', 'api-v1:checkinlist-failed_checkins'),
|
||||
('GET', 'api-v1:checkinlistpos-list'),
|
||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
||||
('GET', 'api-v1:revokedsecrets-list'),
|
||||
@@ -47,9 +70,9 @@ class PretixScanSecurityProfile(AllowListSecurityProfile):
|
||||
)
|
||||
|
||||
|
||||
class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
|
||||
class PretixScanNoSyncNoSearchSecurityProfile(AllowListSecurityProfile):
|
||||
identifier = 'pretixscan_online_kiosk'
|
||||
verbose_name = _('pretixSCAN (kiosk mode, online only)')
|
||||
verbose_name = _('pretixSCAN (kiosk mode, no order sync, no search)')
|
||||
allowlist = (
|
||||
('GET', 'api-v1:version'),
|
||||
('GET', 'api-v1:device.eventselection'),
|
||||
@@ -67,6 +90,37 @@ class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
|
||||
('GET', 'api-v1:badgeitem-list'),
|
||||
('GET', 'api-v1:checkinlist-list'),
|
||||
('GET', 'api-v1:checkinlist-status'),
|
||||
('POST', 'api-v1:checkinlist-failed_checkins'),
|
||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
||||
('GET', 'api-v1:revokedsecrets-list'),
|
||||
('GET', 'api-v1:orderposition-pdf_image'),
|
||||
('GET', 'api-v1:event.settings'),
|
||||
('POST', 'api-v1:upload'),
|
||||
)
|
||||
|
||||
|
||||
class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
|
||||
identifier = 'pretixscan_online_noorders'
|
||||
verbose_name = _('pretixSCAN (online only, no order sync)')
|
||||
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:checkinlist-failed_checkins'),
|
||||
('GET', 'api-v1:checkinlistpos-list'),
|
||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
||||
('GET', 'api-v1:revokedsecrets-list'),
|
||||
('GET', 'api-v1:orderposition-pdf_image'),
|
||||
@@ -101,12 +155,18 @@ class PretixPosSecurityProfile(AllowListSecurityProfile):
|
||||
('POST', 'api-v1:order-list'),
|
||||
('GET', 'api-v1:order-detail'),
|
||||
('DELETE', 'api-v1:orderposition-detail'),
|
||||
('PATCH', 'api-v1:orderposition-detail'),
|
||||
('GET', 'api-v1:orderposition-answer'),
|
||||
('GET', 'api-v1:orderposition-pdf_image'),
|
||||
('POST', 'api-v1:order-mark_canceled'),
|
||||
('POST', 'api-v1:order-mark-canceled'),
|
||||
('POST', 'api-v1:orderpayment-list'),
|
||||
('POST', 'api-v1:orderrefund-list'),
|
||||
('POST', 'api-v1:orderrefund-done'),
|
||||
('POST', 'api-v1:cartposition-list'),
|
||||
('POST', 'api-v1:cartposition-bulk-create'),
|
||||
('GET', 'api-v1:checkinlist-list'),
|
||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
||||
('POST', 'plugins:pretix_posbackend:order.posprintlog'),
|
||||
('DELETE', 'api-v1:cartposition-detail'),
|
||||
('GET', 'api-v1:giftcard-list'),
|
||||
('POST', 'api-v1:giftcard-transact'),
|
||||
@@ -131,6 +191,7 @@ DEVICE_SECURITY_PROFILES = {
|
||||
FullAccessSecurityProfile,
|
||||
PretixScanSecurityProfile,
|
||||
PretixScanNoSyncSecurityProfile,
|
||||
PretixScanNoSyncNoSearchSecurityProfile,
|
||||
PretixPosSecurityProfile,
|
||||
)
|
||||
}
|
||||
|
||||