Compare commits

...

657 Commits

Author SHA1 Message Date
Raphael Michel
581f3c3d58 Release 1.8.1 2017-11-25 19:07:42 +01:00
Raphael Michel
6600c430ab [SECURITY] Respect session timeout in API 2017-11-25 19:06:46 +01:00
Raphael Michel
807eb2ea7f [SECURITY] Fix handling of session timeouts 2017-11-25 19:06:03 +01:00
Raphael Michel
7dea6fc1b7 Bump version number 2017-10-07 20:38:12 +02:00
Raphael Michel
bd306e9400 Best-effort backwards compatibility of isolated cart IDs 2017-10-07 20:37:12 +02:00
Raphael Michel
3e686211e1 Update translations 2017-10-07 18:42:02 +02:00
Raphael Michel
6d1b4b0a39 Re-order travis matrix for better productivity 2017-10-07 18:16:36 +02:00
Sanket Dasgupta
58938fc07c Fix #531 -- Make placeholders replace in subject (#594)
Placeholders in subject were not being replaced because there was
no `.format()` called on the subject.

This commit creates a context dict that is used for both the body
and the subject. It is then replaced using `.format_map()`

Fixes https://github.com/pretix/pretix/issues/531
2017-10-07 18:16:13 +02:00
Raphael Michel
96dd4e02f3 Add tests for style generation and propagated settings 2017-10-07 18:13:06 +02:00
Raphael Michel
411c537438 UI for settings propagation 2017-10-07 18:13:06 +02:00
Raphael Michel
bbd112280a Propagate setting and add organizer display settings page 2017-10-07 18:13:06 +02:00
Marvin Sipp
28d074366e added organizer color field 2017-10-07 18:13:06 +02:00
Haroon Sheikh
11d76656de Fix #538 -- Remove pyvenv from docs (#633) 2017-10-07 16:50:14 +02:00
Raphael Michel
1c96bc31d5 Re-calculate quotas for all events with recent logs 2017-10-06 11:43:08 +02:00
Raphael Michel
0030064f55 Form UX: Better label in sendmail form 2017-10-06 11:23:21 +02:00
Raphael Michel
4726f5c136 Fix i18n for confirm_text 2017-10-06 11:14:42 +02:00
Raphael Michel
c7fafedc51 Checkout UX: Pre-select payment provider if there is only one 2017-10-06 11:08:00 +02:00
Raphael Michel
3eeb70ae36 Form UX: Add more helpful placeholders 2017-10-06 11:05:24 +02:00
Raphael Michel
29b1a3dca3 Do not send navigation singals for authentication pages 2017-10-06 10:35:24 +02:00
Raphael Michel
caf844b5fb Fix wrong signal name in documentation 2017-10-05 11:55:09 +02:00
Raphael Michel
6b7bdf8c4f Item creation UX: Clearer placeholders, defaults 2017-10-05 10:47:46 +02:00
Raphael Michel
aad433a3bc Welcome wizard UX: Use primary color for button 2017-10-05 10:32:14 +02:00
Raphael Michel
3f1bb56826 Event creation UX: Show clearer that the event is now created 2017-10-05 10:31:25 +02:00
Raphael Michel
b2b3add616 Form UX: Display units for more number inputs 2017-10-05 10:21:00 +02:00
Raphael Michel
2d484d4a8e Event creation UX: Label changes 2017-10-05 10:20:00 +02:00
Raphael Michel
2f252f19c9 Form UX: Use splitted date/time widgets 2017-10-05 10:17:17 +02:00
Raphael Michel
a27f372785 Event creation UX: Pre-choose organizer if there is only one 2017-10-05 08:01:22 +02:00
Raphael Michel
f074e642ec Display quotas in event list 2017-10-04 11:25:51 +02:00
Raphael Michel
217ed905d4 Contract columns in event list table 2017-10-04 10:12:46 +02:00
Raphael Michel
b920efc955 Add database cache for quotas 2017-10-04 09:45:37 +02:00
Raphael Michel
330fadbea9 Fix wrong execution order 2017-10-04 09:43:14 +02:00
Raphael Michel
50c595e3d6 Fix migration error (unique app configuragion keys) 2017-10-02 17:40:31 +02:00
Raphael Michel
26f258c6cf Isolate cart sessions 2017-10-02 17:00:35 +02:00
Raphael Michel
f15a72e59d Fix mail_text_download_reminder email preview 2017-10-02 15:44:32 +02:00
Raphael Michel
8accaae6b1 New signal: allow_ticket_download 2017-10-02 15:07:23 +02:00
Raphael Michel
d4259501af Remove legacy ordering code 2017-10-02 14:59:01 +02:00
Jakob Schnell
fd5d5ae98e Fix #628 -- Sorting of filtered order list (#631)
* fix sorting of filtered order list

fixes #628

* implement comments on pr
2017-10-02 14:55:02 +02:00
Raphael Michel
457901ff82 Fix flake8 error 2017-10-01 17:43:51 +02:00
Raphael Michel
e201be1c65 Clarify payment fee / shipping fee relation 2017-09-29 17:08:04 +02:00
Raphael Michel
acde14372d PDF editor: Change default text 2017-09-29 17:01:13 +02:00
Raphael Michel
79988a2325 New signal order_fee_type_name 2017-09-29 16:54:27 +02:00
Raphael Michel
784f6e703c CSP: Exclude PDF editor (just doesn't work in FF) 2017-09-28 18:44:12 +02:00
Raphael Michel
29b157f287 CSP: Add reporting endpoint 2017-09-28 18:43:45 +02:00
Raphael Michel
c030bd35ca Make PDF ticket cover more extensible 2017-09-27 18:32:50 +02:00
Raphael Michel
06fe076ce2 Add request argument to pretix.control.signals.order_info 2017-09-27 18:19:47 +02:00
Raphael Michel
ae6cba067c Fix issue created in 1f889be0 2017-09-27 14:40:15 +02:00
Raphael Michel
72ae19a95d Update translation 2017-09-27 13:24:03 +02:00
Raphael Michel
1f889be07a Refactor and add signal layout_text_variables 2017-09-27 13:15:18 +02:00
Raphael Michel
39061b659a PDF Editor: More extensible implementation 2017-09-26 13:05:51 +02:00
Raphael Michel
d38f29ac7c Add signal pretix.control.signals.order_info 2017-09-26 11:47:46 +02:00
Raphael Michel
1a8e67f4de Allow clicking on typeahead results 2017-09-25 22:03:25 +02:00
Raphael Michel
8265c302ad Fix missing required=False 2017-09-25 13:33:41 +02:00
Raphael Michel
110d7c6acf Allow to enter a custom text that needs to be confirmed during checkout 2017-09-25 12:48:31 +02:00
Tobias Kunze
244b767f8f Allow markdown rendering in transaction comments. (#621)
This commit allows transaction comments to display newlines and URLs in
a useful way, helping when additional data (such as a reference to a
ticket system or a longer discussion) is required.
This PR also prevents pretix from having to bring its own chat system ;)
2017-09-25 12:25:32 +03:00
Raphael Michel
f40950efc9 Adjust to newer sentry version 2017-09-25 10:46:47 +02:00
Raphael Michel
0e0534c273 Fix incorrect timezones on event dashboard 2017-09-25 10:25:22 +02:00
Raphael Michel
9b3ea3656f PDF Output: Prevent subsequent exception on permission errors 2017-09-25 10:22:09 +02:00
Raphael Michel
62b2a367ff PDF Output: Fix AttributeError with undefined used meta data 2017-09-25 10:20:46 +02:00
Raphael Michel
ab9dd32902 Add font-src to default CSP header 2017-09-25 10:19:36 +02:00
Raphael Michel
43fc498297 Prevent some pages from search indexing 2017-09-25 10:04:37 +02:00
Raphael Michel
ef3eee7873 ContactForm: Prevent TypeError during validation 2017-09-25 09:38:35 +02:00
Raphael Michel
9f0deea9dd Rich text: Do not rewrite mailto: URLs 2017-09-25 09:37:17 +02:00
Abhiraj Hinge
e3798600ed Fixed typo in Concepts.rst (#624) 2017-09-14 16:16:56 +03:00
Raphael Michel
00834cd5e0 Fix test_checkoutflow 2017-09-13 18:29:08 +02:00
Raphael Michel
ed35c4f74e Add new signal logentry_object_link 2017-09-13 17:36:13 +02:00
Raphael Michel
9cd3e2d494 Require payment even if total consists only of fees 2017-09-13 16:42:00 +02:00
Raphael Michel
3345f48986 nav_event_settings should be an EventPluginSignal 2017-09-13 16:21:14 +02:00
Raphael Michel
b611d63975 ModelRelativeDateTimeField: Deal with None values 2017-09-13 16:20:54 +02:00
Raphael Michel
fb3866aa1a Fix TypError in PDF preview 2017-09-13 14:59:19 +02:00
Raphael Michel
a9f131b645 Make PDF download more prominent 2017-09-12 19:06:02 +02:00
Raphael Michel
e5728662c5 Allow to extend expired order even if waiting list entries exist 2017-09-12 18:50:13 +02:00
Raphael Michel
94a97fb0fd Fix broken toggling script 2017-09-09 11:09:03 +02:00
Raphael Michel
b5bea6fe7a Do not disable core modules' URLs 2017-09-08 17:50:50 +02:00
Raphael Michel
fb9d677d76 CSP: Allow blob: URLs for images in PDFs 2017-09-07 23:29:21 +02:00
Raphael Michel
7c4fc7bd0d New signals: fee_calculation_for_cart, order_fee_calculation 2017-09-07 18:59:21 +02:00
Raphael Michel
de992cecf3 New signal checkout_confirm_page_content 2017-09-07 18:15:36 +02:00
Raphael Michel
cd94549606 Fix export of answered files with binary content 2017-09-07 12:38:39 +02:00
Raphael Michel
214a6eb5ce Database field for RelativeDateTime 2017-09-06 11:25:12 +02:00
Raphael Michel
db5f0aa02d Fix #156 -- Plug-in settings navigation hook 2017-09-06 09:31:33 +02:00
Raphael Michel
ba48ab3659 Re-do squashed migration 2017-09-05 15:34:40 +02:00
Raphael Michel
d1538e07d3 Bump version 2017-09-05 12:47:10 +02:00
Raphael Michel
fe0c033b2d Bump version 2017-09-05 12:46:08 +02:00
Raphael Michel
2e58dca048 Order overview: Deterministic ordering of fees 2017-09-05 12:45:25 +02:00
Raphael Michel
d38ab8a439 Correctly set OrderFee type for new orders 2017-09-05 12:32:39 +02:00
Raphael Michel
acd7b9ba8c Squash migrations 2017-09-05 12:32:20 +02:00
Raphael Michel
56f72b225c Improve pretixdroid UI 2017-09-05 12:10:33 +02:00
Raphael Michel
8bfaf7425a Update translation 2017-09-05 11:48:01 +02:00
Raphael Michel
77a8726a03 Fix #615 -- Incorrect defaults for email texts 2017-09-05 11:46:33 +02:00
luto
119fea3379 Fix #619 -- Check format of stripe API keys in settings (#620)
* stripe tests: add settings URL to fixture, as it will be needed later

* Fix #619 -- Stripe: add basic validation for secret and publishable keys
2017-09-05 10:26:03 +03:00
Raphael Michel
e54e0d6511 New concept for fee handling (#610)
* New concept for fee handling

* More usages

* Remove all usages, make all tests pass

* API changes

* Small fixes

* Fix order of invoice lines

* Rebase migration
2017-09-05 10:11:26 +03:00
Raphael Michel
a2a88cfafa Fix tests after meta-data merge 2017-09-04 22:09:30 +02:00
Raphael Michel
5ff53d08ed Fix #586 -- Fix folded subnavigation in order detail view 2017-09-04 21:13:54 +02:00
Raphael Michel
0ddda4a668 Fix #617 -- Purge ticket cache after ticket settings/layout changes 2017-09-04 21:09:08 +02:00
Raphael Michel
d3a76e9f2f Fix #614 -- Warning message if ticket output is active but no provider 2017-09-04 21:03:17 +02:00
Raphael Michel
ea7ec2b5fc Fix #585 -- Creating invoices for refunded orders 2017-09-04 20:36:19 +02:00
Raphael Michel
b9b4ccb180 Change order of user docs pages 2017-09-04 20:13:38 +02:00
Raphael Michel
2f15d410fe Add optional timeouts for backend sessions 2017-09-04 19:50:32 +02:00
Raphael Michel
88f5af3e77 Add event meta-data 2017-09-04 19:50:32 +02:00
Martin Gross
454ca27c54 Fix #613 -- Minor typo in last change date (#616)
* Fix #556 - Max. redemptions instead of amount of vouchers

* Update Translation for Dashboard-Tile

* Fix #613 - Minor typo in last change date
2017-09-04 10:42:21 +03:00
Raphael Michel
f536cb3536 Fix grammar error 2017-08-30 18:30:59 +02:00
Raphael Michel
e6ba7379eb Display free tickets as "FREE" instead of "0.00" 2017-08-30 18:24:25 +02:00
Raphael Michel
f6b01b6e02 Improve margin arount product picture 2017-08-30 18:24:25 +02:00
Raphael Michel
ce27f8e89c Fix product list in template 2017-08-30 18:24:25 +02:00
Raphael Michel
a52635f940 Fix typo 2017-08-30 18:24:25 +02:00
Martin Gross
b608125545 Fix Dashboard-Tile Translation (number of orders) (#612)
* Fix #556 - Max. redemptions instead of amount of vouchers

* Update Translation for Dashboard-Tile
2017-08-30 15:47:03 +03:00
Raphael Michel
631cded0d6 New pretixdroid configuration system 2017-08-29 23:19:02 +02:00
Raphael Michel
43b5140754 New handling of plugin URLs (#609) 2017-08-29 10:01:50 +03:00
Raphael Michel
557a05135e Allow connect-src to media domain 2017-08-28 09:19:42 +02:00
Tobias Kunze
618416d0d2 Update translation, closes #604 (#608) 2017-08-27 10:45:13 +03:00
Tobias Preuss
9a4ee3db69 Improve reading flow. (#603) 2017-08-27 10:41:55 +03:00
Raphael Michel
999dde3fa4 Fix exception in pretixdroid API 2017-08-25 16:32:12 +02:00
Raphael Michel
1171cce550 Predictable order of question forms 2017-08-25 16:23:16 +02:00
Raphael Michel
77e13338ad Fix inconsistencies in pretixdroid API views 2017-08-25 16:22:53 +02:00
Raphael Michel
fd35b5ea72 Add "attention" flag to products 2017-08-25 15:14:54 +02:00
Raphael Michel
f98f25fb6b Improve MT940 import 2017-08-25 14:51:25 +02:00
Raphael Michel
511a49041f Add item and variation ID to pretixdroid API 2017-08-25 13:01:05 +02:00
Raphael Michel
74be5cfe96 Fix test (again) 2017-08-24 21:31:27 +02:00
Raphael Michel
1f54b36ece Fix failing test of calendar page 2017-08-24 19:32:12 +02:00
Raphael Michel
d12b77b572 Remove unneeded space 2017-08-24 18:32:31 +02:00
Raphael Michel
4928234785 Banktransfer: Allow mt940 files to have the .sta extension 2017-08-24 18:13:26 +02:00
Raphael Michel
208e3c9933 Update translation 2017-08-24 18:11:47 +02:00
Raphael Michel
d697381d8b List and calendar for all organizers 2017-08-24 17:13:22 +02:00
Raphael Michel
cd6b1a2327 Allow subevent filtering in dashboard 2017-08-24 16:12:50 +02:00
Raphael Michel
ff21380099 Improve typeahead on dashboard page 2017-08-24 14:21:30 +02:00
Raphael Michel
a773531003 Statistics: Add subevent selection 2017-08-24 12:53:59 +02:00
Raphael Michel
23ecd43885 Better dashboard layout 2017-08-24 12:36:48 +02:00
Raphael Michel
3415bf5cd3 Event list: Correct handling of event series 2017-08-24 10:44:22 +02:00
Raphael Michel
45b9f1190f Case insensitivity when validating repreated email addresses 2017-08-24 10:19:11 +02:00
Raphael Michel
ef1b09671a pretixdroid: Let attendee_name fall back to invoice address name 2017-08-24 10:17:32 +02:00
Raphael Michel
ee282af53e Add invoice address fields to ticket PDF editor 2017-08-24 09:53:31 +02:00
Raphael Michel
455a95d46c Add column ordering to more lists 2017-08-24 09:36:24 +02:00
Raphael Michel
76666b0d22 Update and fix trove classifiers 2017-08-23 17:47:13 +02:00
Raphael Michel
45fd43682a Docs: Add missing RST file 2017-08-23 15:13:20 +02:00
Raphael Michel
fd801e3323 Delete cache in migration 2017-08-23 15:09:47 +02:00
Raphael Michel
429c6ebb1b Fix TaxRule.__str__ 2017-08-23 15:07:01 +02:00
Raphael Michel
ea2f24fe23 Fix problem in migration 2017-08-23 14:49:08 +02:00
Raphael Michel
db4a2cfaac Docs: Add missing screenshots 2017-08-23 14:22:08 +02:00
Raphael Michel
583223f454 Update translation 2017-08-23 14:21:47 +02:00
Raphael Michel
f9fcc16f54 Do not rely on CSP nonce support (breaks safari) 2017-08-23 13:36:35 +02:00
Raphael Michel
50ca6ee63d Support custom fonts 2017-08-23 13:35:47 +02:00
Raphael Michel
56338be13e Tax rules and reverse charge (#559)
Tax rules and reverse charge
2017-08-23 13:13:16 +03:00
Raphael Michel
b9ec5ea83c Documentation on event creation 2017-08-23 10:15:51 +02:00
Raphael Michel
389585c47a Fix translation errors 2017-08-22 12:35:39 +02:00
Raphael Michel
e9583087eb Fix logic of multi downloads 2017-08-22 10:55:32 +02:00
Raphael Michel
57e2090d70 Fix date display in event list 2017-08-22 10:10:10 +02:00
Raphael Michel
5fbf26b8cb Make additional font styles optional 2017-08-22 10:09:46 +02:00
Raphael Michel
447c728557 [SECURITY] Rewrite all links in rich texts 2017-08-21 15:14:45 +02:00
Raphael Michel
a3ca4c81ae [SECURITY] Fix XSS vulnerability in typeahead.js 2017-08-21 15:14:45 +02:00
Raphael Michel
fb398a5520 [SECURITY] Fix XSS vulnerability in Lightbox caption 2017-08-21 15:14:45 +02:00
Raphael Michel
9a9bb92f91 [SECURITY] Support custom media URLs in CSP middleware 2017-08-21 15:14:45 +02:00
Raphael Michel
e23a5c24d6 [SECURITY] Add warning for download of unsafe files 2017-08-21 15:14:45 +02:00
Raphael Michel
1a42a54d98 [SECURITY] Tokens for downloading answer attachments 2017-08-21 15:14:45 +02:00
Raphael Michel
5c91352bae [SECURITY] Do not allow SVG files for logos 2017-08-21 15:14:45 +02:00
Raphael Michel
3428ea2f18 [SECURITY] Fix XSS injection vulnerabilities in question answers, event, quota and product names 2017-08-21 15:14:45 +02:00
Raphael Michel
24e5d337a6 [SECURITY] Update to morris.js master to fix a XSS vulnerability 2017-08-21 15:14:44 +02:00
Raphael Michel
a2c1413036 [SECURITY] Use defusedcsv for exports 2017-08-21 15:14:44 +02:00
Tobias Kunze
bab092f04b Do not override the Reply-To header (#597) 2017-08-20 13:50:48 +03:00
Tobias Kunze
2bf4e6c5c6 Fix import of celery app in documentation (#596) 2017-08-20 12:41:37 +03:00
Raphael Michel
584add97a3 Fix counting bug for global order search 2017-08-11 12:42:47 +02:00
Raphael Michel
57143a434e Add new signal voucher_form_validation 2017-08-10 17:06:16 +02:00
Raphael Michel
e31bd7600c Add bcc to mail_send 2017-08-09 16:22:14 +02:00
Raphael Michel
f02ec8b24b Improve Stripe.js loading 2017-08-09 13:56:52 +02:00
Raphael Michel
b8704f980f Only validate form of the selected payment 2017-08-09 13:56:52 +02:00
Raphael Michel
3accf74687 Fix KeyError in form submission 2017-08-09 13:56:52 +02:00
Tobias Kunze
a213ca746c Only mention an order in the mail if one is associated (#592) 2017-08-09 10:42:52 +02:00
Raphael Michel
349e306d38 Fix #576 yet again 2017-08-08 23:08:34 +02:00
Raphael Michel
ca1b1032eb Allow mails without HTML 2017-08-08 22:28:27 +02:00
Raphael Michel
a6c9fb0f8b Fix #576 again 2017-08-08 22:24:53 +02:00
Raphael Michel
c8230c55ee Update translation 2017-08-08 21:06:54 +02:00
Raphael Michel
55f77613d4 Fix #576 -- linebreaks in bank details in HTML mails 2017-08-08 20:37:01 +02:00
Raphael Michel
c9a1ff45c7 Fix import order 2017-08-07 19:31:20 +02:00
Raphael Michel
c209f66d49 Fix #590 -- Combined Ticket-PDFs are not invalidated when rotating secrets 2017-08-07 18:34:04 +02:00
Raphael Michel
3efa02eb81 Fixes to the download reminder 2017-08-07 17:10:04 +02:00
Raphael Michel
8506f66236 Show if team members have 2FA enabled 2017-08-07 16:15:32 +02:00
Sanket Dasgupta
cb2826f171 Fix #293 -- Add ticket downloading reminder (#567)
Closes https://github.com/pretix/pretix/issues/293
2017-08-07 16:15:27 +02:00
Raphael Michel
0990c9cc3d Fix AttributeError in voucher creation 2017-08-07 14:12:16 +02:00
Raphael Michel
4aa9594a61 Fix voucher redemption problem with subevents 2017-08-07 14:09:12 +02:00
Raphael Michel
ed208cf433 Optimize OrderFilterForm query 2017-08-07 14:04:16 +02:00
Raphael Michel
428faeb756 Add a minimal length for voucher codes 2017-08-07 12:11:48 +02:00
Raphael Michel
e858edd85c Do not allow vouchers to create negative prices 2017-08-07 12:11:48 +02:00
Raphael Michel
e4ab27a292 Fix missing file 2017-08-01 21:02:15 +02:00
Raphael Michel
eece5793d6 Fix travis after bbed8e5f 2017-08-01 20:43:28 +02:00
Nicole Klünder
3df737a94f fix missing space in german translation (#587) 2017-08-01 20:39:39 +02:00
Nicole Klünder
0e4c414c2e fix wrong stripe version in setup.py (#588) 2017-08-01 20:39:25 +02:00
Raphael Michel
326304db54 Fix #583 -- Wrongly documented option 2017-07-31 23:00:48 +02:00
Raphael Michel
c8e54524a3 Only use SQLite config during tests if it exists 2017-07-31 21:36:46 +02:00
Raphael Michel
d671060a47 Add sphinxcontrib-images to doc dependencies 2017-07-31 21:14:00 +02:00
Raphael Michel
93dab76da2 Complete docs page 2017-07-31 21:12:30 +02:00
Nicole Klünder
bbed8e5fae throw exception if PRETIX_CONFIG_FILE can not be opened (#581)
If the environment variable PRETIX_CONFIG_FILE is set but the file can not be read because it does not exists or permission is denied, pretix just runs with default settings. When setting up a new installation this can be confusing and difficult to debug.

I think it is safe to assume that someone who sets PRETIX_CONFIG_FILE aims to point it at a readable file, so raising with a more understandable exception is expected or at least helpful. Otherwise, the user will usually get a DisallowedHost exception because the [pretix]url config variable is not set which is not as helpful.
2017-07-31 18:33:16 +02:00
Raphael Michel
e16f8fc7e9 Add some user documentation 2017-07-31 18:31:20 +02:00
Raphael Michel
86f17094bb Hide quota options when creating a product with variations 2017-07-31 13:52:50 +02:00
Raphael Michel
b1b49758b1 Fix reversal bug 2017-07-31 12:54:57 +02:00
Raphael Michel
4790665759 bump version 2017-07-31 12:54:57 +02:00
Tobias Kunze
8ede492cba Add optional help_text to Question objects. Closes #574. (#579) 2017-07-31 10:54:57 +02:00
Raphael Michel
5f607cc034 Bump version 2017-07-30 20:36:45 +02:00
Raphael Michel
3b9f508be9 Create squash migration 2017-07-30 20:11:23 +02:00
Raphael Michel
89e381b7ea Update translations 2017-07-30 19:44:11 +02:00
Tobias Kunze
57869b2145 Wording fixes (#577) 2017-07-30 19:29:17 +02:00
Raphael Michel
46976900d7 Add documentation on mail methods 2017-07-27 15:47:22 +02:00
Raphael Michel
a1535da117 Subevent creation: Layout issue 2017-07-27 15:18:25 +02:00
Raphael Michel
f43d782b5c Hide quota options during product creation for event series 2017-07-27 15:14:28 +02:00
Daniel
5c443e2f93 Ref #569 -- Include other email to history (#570)
Log all other order-specified emails and include them into
email history.
2017-07-27 15:09:06 +02:00
Raphael Michel
54f01f63f7 Update translation 2017-07-27 11:53:14 +02:00
Raphael Michel
c64b4473e4 Add organizer_info_text 2017-07-27 11:43:35 +02:00
Raphael Michel
d413a37c1f Translation improvements 2017-07-27 11:21:28 +02:00
Raphael Michel
202fb12008 Order payment providers by name 2017-07-27 11:17:29 +02:00
Raphael Michel
59dea63870 Add product description to ticket editor 2017-07-27 10:13:55 +02:00
Raphael Michel
9a18f2b553 Small JS improvements 2017-07-26 13:41:53 +02:00
Clint
4293ec3805 Fix #475 -- add to existing quota / add new quota from product form (#562)
* added fields and logic for adding quota in creation of product

* added section for selecting quota option

* logic for hiding quota selections when needed

* fixed logic for quota selection

* formatting, removed print statements

* styling

* tests for adding quotas in product form

* cleaned up

* added divs

* reworked to include translatable text, readable values for quota options

* quota_add_existing form assignment to str(q.pk)

* made changes for radio buttons, added in sliding animation

* moved string constants for quota options, changed quota options to RadioSelect from Select
2017-07-26 13:41:23 +02:00
Raphael Michel
f3b616e495 Add exporter to output all tickets 2017-07-26 13:18:35 +02:00
Raphael Michel
003ea24990 Fix Stripe test 2017-07-25 16:52:37 +02:00
Raphael Michel
92d4566a54 Make stripe refund call optional, add request parameter to order_control_refund_render 2017-07-25 16:11:42 +02:00
Raphael Michel
70a933edc1 Hide min_per_order=1 2017-07-24 09:54:33 +02:00
Raphael Michel
d2d77f28aa Fix wrongly displayed download buttons 2017-07-24 09:14:54 +02:00
Raphael Michel
39179971c5 Fix stripe tests 2017-07-23 13:33:43 +02:00
Raphael Michel
c06f36e8c2 Do not render time before JS locale file is loaded 2017-07-23 13:06:07 +02:00
Raphael Michel
1d2d9d8b99 PayPal: Event-independent webhooks 2017-07-23 12:38:41 +02:00
Raphael Michel
5f529817ef Stripe: Event-independent webhooks 2017-07-23 12:22:48 +02:00
Raphael Michel
7c91bc2f37 Respect primary browser language 2017-07-20 11:31:34 +02:00
Raphael Michel
ef022f5a6d Add new dependencies to setup.py 2017-07-19 17:42:07 +02:00
Raphael Michel
54ce00c8b9 Update translation 2017-07-19 14:17:23 +02:00
Raphael Michel
baabbfb1ea Check for required invoice information in other steps 2017-07-19 14:10:04 +02:00
Raphael Michel
28e676ac9a Allow to only require the name in the invoice address 2017-07-19 14:07:18 +02:00
Raphael Michel
21fac9ec7a Auto-toggle form fields for business/individual customers 2017-07-19 12:26:50 +02:00
Raphael Michel
335955820b Fix a counting bug 2017-07-19 12:10:35 +02:00
Raphael Michel
d2b0e7209f Use a choice field for invoice address countries 2017-07-19 12:08:18 +02:00
Johan von Forstner
f8ed21c819 Fix #130 -- Mark required question fields at checkout (#564)
* Fix #130: Mark required question fields at checkout

* Add legend
2017-07-19 11:02:07 +02:00
Tobias Kunze
9c2143effe Clarify mail subject prefix. (#520) 2017-07-19 10:42:34 +02:00
Raphael Michel
8a3fa6aff6 Show category descriptions if redeeming a voucher 2017-07-18 16:47:18 +02:00
Daniel
7e304bb231 Fix #565 -- OrderList ordering request handling (#566)
Fix missed out ordering get request handling.
2017-07-18 16:16:51 +02:00
Raphael Michel
99d614289e Link order from change pages, compat for old logs 2017-07-18 11:46:21 +02:00
Daniel
b90894c20f Fix #543 -- Allow send mail from order (#550)
- Add send email directly for order
- Add email history (from mass and custom) to each specific order
2017-07-18 11:45:30 +02:00
Johan von Forstner
921834c917 Fix os.chown call on Windows (#563) 2017-07-18 11:42:30 +02:00
Raphael Michel
83df4451e6 Fix #491 -- Search order by invoice number 2017-07-18 11:14:51 +02:00
Raphael Michel
2ad9e1bb43 Change API to accomodate for invoice numbers 2017-07-18 10:37:32 +02:00
Raphael Michel
c9990e5ca4 Update translation 2017-07-18 10:04:24 +02:00
Raphael Michel
c95e61db09 Add new external plugins to list 2017-07-17 23:32:41 +02:00
Raphael Michel
7bb12ff0ec Configurable invoice prefixes 2017-07-17 23:03:20 +02:00
Raphael Michel
670bfa18de Slug widget 2017-07-17 20:54:39 +02:00
Raphael Michel
130f619b05 Fix raven integration 2017-07-17 20:29:56 +02:00
Raphael Michel
f900c842cb Improve "copy from above" 2017-07-17 16:12:33 +02:00
Tobias Kunze
c2844a8f35 Add custom_header block to <head> (#561) 2017-07-17 14:52:20 +02:00
Raphael Michel
a864dabbaf Refs #552 -- Expand all panels that contain validation errors 2017-07-17 12:49:45 +02:00
Daniel
02786f4801 Fix #552 -- Add icon to expansible panels (#560)
* Ref #552 -- Add icon to expansible panels

Offer informative feedback to user by showing icons to indicate
expansible panels.

* Fix wrongly removed JavaScript line
2017-07-17 12:29:47 +02:00
Raphael Michel
5a4fe266c6 Fix usage of wrong settings key 2017-07-16 22:17:02 +02:00
Raphael Michel
b30a4db0b8 Update translation 2017-07-16 20:15:48 +02:00
Raphael Michel
2e76e07764 Show end date on front page 2017-07-16 20:11:59 +02:00
Raphael Michel
1be92f5078 Really fix 2050c0b7 issue 2017-07-16 19:37:18 +02:00
Raphael Michel
8afff29cd4 Make microdata XSS-safe and subevent-aware 2017-07-16 17:52:08 +02:00
Raphael Michel
9c6090a355 Fix translation sytax error 2017-07-16 17:49:31 +02:00
Joepriesto
27b73227ed Fix #30 -- Event microdata information (#546)
* Addition of all basics required for microdata

Microdata for event added to the head of the base event html template.

* Fixed flake8 errors & included settings checks

Fixed the flake8 too many blank line errors and changed the date and time section to refer to settings before including the time and/or the date_to.

* Typo in last commit

Fixed typo in last commit

* Fixed bracket mistake and flake8 error

Fixed tab between { and % in template tag. Removed extra lines. Removed unnecessary str() call.
Corrected binary & to [and] operator.

* Added testing for microdata

Testing added to the presale.test_event tests to cover the 4 branches and basic microdata functionality.
2017-07-16 17:42:46 +02:00
Raphael Michel
9582f8380f Fix translation syntax 2017-07-16 17:31:35 +02:00
Raphael Michel
bfeac7e70b Fix bogus translation 2017-07-16 17:21:07 +02:00
Raphael Michel
2050c0b7a8 Fix TypeError 2017-07-16 17:05:46 +02:00
Raphael Michel
144f9bed69 Fix URL in iCal test 2017-07-15 16:38:14 +02:00
Raphael Michel
f2b642d944 Fix iCal URL 2017-07-14 18:26:18 +02:00
Raphael Michel
bcdc75953e Add SubEvent.frontpage_text 2017-07-14 18:14:24 +02:00
Raphael Michel
1fabe5a7cf Disable button "add to cart" with no selection 2017-07-14 18:10:49 +02:00
Raphael Michel
fe9a4b7aa3 Allow word wrapping inside .dl-horizontal dt 2017-07-14 18:10:18 +02:00
Raphael Michel
56735dc1c6 Make PDF ticket output subevent-compatible 2017-07-14 18:09:48 +02:00
Raphael Michel
42287b92f1 Allow ticket output methods to opt-out from ZIP generation 2017-07-14 17:32:16 +02:00
Raphael Michel
7d9e642f24 Useful default date for admission field 2017-07-14 17:21:41 +02:00
Raphael Michel
b20e10585f Include Event.is_public in Event.copy_data_from 2017-07-14 17:11:52 +02:00
Raphael Michel
8438b211a6 Fix iCal test failing due to new UID format 2017-07-14 14:55:08 +02:00
Raphael Michel
f94314afec Generate organizer-level iCal files 2017-07-14 14:25:05 +02:00
Martin Gross
4584d23434 Fix #556 - Max. redemptions instead of amount of vouchers (#558) 2017-07-14 12:11:34 +02:00
Raphael Michel
2791501781 Fix #557 -- Drop unused CSS file 2017-07-14 12:11:20 +02:00
Raphael Michel
6ea798e55b Allow to exclude free products from invoices 2017-07-14 12:11:20 +02:00
Martin Gross
0ab6ac569e Fix #553 -- Order by position first in order_overview (#554) 2017-07-14 10:22:26 +02:00
Raphael Michel
f91d7352a4 Fix AttributeError in test 2017-07-13 22:04:34 +02:00
Raphael Michel
d644b8fe01 Fix detection of core modules after ae910eb7 2017-07-13 20:33:08 +02:00
Raphael Michel
5a8042cc10 Fix relative dates in payment method availability field 2017-07-13 17:37:07 +02:00
Raphael Michel
ae910eb731 Fix EventPluginSignal to recognize Django apps with custom app labels 2017-07-12 19:14:28 +02:00
Raphael Michel
c1158c3175 Allow to mark add-ons as "included" in price 2017-07-12 18:42:09 +02:00
Raphael Michel
79562e7ad9 Add logdisplay for charge.pending 2017-07-12 18:02:56 +02:00
Raphael Michel
e3388bea96 Fix Stripe webhooks 2017-07-12 17:37:05 +02:00
Daniel
a3b4a7ef1d Fix #516 -- Prevent gaps in plugin list (#551)
Use flexbox to fix misalignment when column height is imbalanced.
2017-07-12 17:30:01 +02:00
Raphael Michel
947b06cd61 Update translation 2017-07-12 17:20:09 +02:00
Raphael Michel
a3f3561f02 Fix import in stripe tests 2017-07-12 16:56:01 +02:00
Raphael Michel
48095d38be Fix #407 -- Integrate more Stripe payment methods 2017-07-12 16:42:44 +02:00
Raphael Michel
1c6858653a Avoid relative URLs in stripe plugin 2017-07-11 22:53:15 +02:00
Raphael Michel
648797325e Allow to copy across events with and w/o subevents 2017-07-11 22:45:41 +02:00
Raphael Michel
af3fa88d67 Typos and translation 2017-07-11 18:47:39 +02:00
Raphael Michel
8123effa65 Add sub-events and relative date settings (#503)
* Data model

* little crud

* SubEventItemForm etc

* Drop SubEventItem.active, quota editor

* Fix failing tests

* First frontend stuff

* Addons form stuff

* Quota calculation

* net price display on EventIndex

* Add tests, solve some bugs

* Correct quota selection in more places, consolidate pricing logic

* Fix failing quota tests

* Fix TypeError

* Add tests for checkout

* Fixed a bug in QuotaForm

* Prevent immutable cart if a quota was removed from an item

* Add tests for pricing

* Handle waiting list

* Filter in check-in list

* Fixed import lost in rebase

* Fix waiting list widget

* Voucher management

* Voucher redemption

* Fix broken tests

* Add subevents to OrderChangeManager

* Create a subevent during event creation

* Fix bulk voucher creation

* Introduce subevent.active

* Copy from for subevents

* Show active in list

* ICal download for subevents

* Check start and end of presale

* Failing tests / show cart logic

* Test

* Rebase migrations

* REST API integration of sub-events

* Integrate quota calculation into the traditional quota form

* Make subevent argument to add_position optional

* Log-display foo

* pretixdroid and subevents

* Filter by subevent

* Add more tests

* Some mor tests

* Rebase fixes

* More tests

* Relative dates

* Restrict selection in relative datetime widgets

* Filter subevent list

* Re-label has_subevents

* Rebase fixes, subevents in calendar view

* Performance and caching issues

* Refactor calendar templates

* Permission tests

* Calendar fixes and month selection

* subevent selection

* Rename subevents to dates

* Add tests for calendar views
2017-07-11 13:56:00 +02:00
Raphael Michel
554800c06f Add 3DS support to Stripe plugin 2017-07-10 21:36:59 +02:00
Raphael Michel
687ce29366 Fix #547 -- Switch to Stripe Elements 2017-07-10 20:00:03 +02:00
Raphael Michel
c70301572c Fix bug in invoice rendering 2017-07-10 14:43:37 +02:00
Raphael Michel
714f58e2c5 Update translation 2017-07-10 14:29:53 +02:00
Raphael Michel
9bf9dca88a Invoice exporter: open in binary mode 2017-07-10 14:25:26 +02:00
Daniel
0663f25208 Fix #541 -- Allow delete waitinglist entries (#544)
Add new action "delete" for each waiting list entries
2017-07-09 15:19:30 +02:00
Raphael Michel
275d162b81 List of events: Optional calendar view 2017-07-08 22:50:48 +02:00
Raphael Michel
675956a7c4 Update translations 2017-07-07 11:37:09 +02:00
Raphael Michel
cf1602c0af Add short form to event list 2017-07-07 11:32:53 +02:00
Raphael Michel
35979ed332 Add internal comment to events 2017-07-07 11:31:33 +02:00
Raphael Michel
6e65ae5306 Swappable invoice renderers 2017-07-07 11:16:07 +02:00
Raphael Michel
95e716b8ce Improve help texts 2017-07-07 10:11:39 +02:00
Raphael Michel
554284ac67 Link new plugins 2017-07-06 18:07:03 +02:00
Raphael Michel
fa6102bbad Allow to override sender for mail 2017-07-06 18:06:07 +02:00
Raphael Michel
f28d5f19a7 Ignore spaces in bank transfer references 2017-07-06 17:39:32 +02:00
Raphael Michel
34d59c7741 Add "Go to shop" in mobile view 2017-07-06 17:36:01 +02:00
Raphael Michel
21d432a3ca Make cancel notifications optional 2017-07-06 12:04:35 +02:00
Daniel
d444935140 Fix #391 -- Send email on cancelled order (#540)
Send a notification email to user when
order is cancelled.
2017-07-06 11:59:48 +02:00
Raphael Michel
9de9d96e35 Do not expose "Deutsch (Du)" in name-local 2017-07-06 09:26:26 +02:00
Michele Fattoruso
5932558ca2 Fix #300 - Feature/remove flag as language (#542)
* don't use flags to indicate languages #300

* cleaned code

* removed the filter and moved the logic to context.py

* cleaned code

* show the text in the local language

* cleaned code

* changed loop for list comprehension

* fix indentation

* ordered import
2017-07-06 09:13:57 +02:00
Raphael Michel
7b22adb72e Allow to manually generate invoice if invoice mode is "on payment" 2017-07-05 13:34:07 +02:00
Raphael Michel
0db5d062be Add a file upload type to questions (#534)
* Initial stuff

* More features
2017-07-03 14:22:31 +02:00
Sanket Dasgupta
678d510e29 config.rst: Include environment variable in list of paths (#539)
Closes https://github.com/pretix/pretix/issues/528
2017-07-03 12:52:36 +02:00
Raphael Michel
1fc3307d22 Add signal question_form_fields 2017-07-02 19:45:26 +02:00
Raphael Michel
45c17ba949 Fix syntax error in setup.py 2017-07-02 18:57:55 +02:00
Raphael Michel
15bd1d9006 Fix missing dependencies in setup.py 2017-07-02 18:44:25 +02:00
Tydon K
b4715f0931 Fix #517 -- Changed navpills to navtabs in email template editor (#533)
* Changed navpills to navtabs in email template editor

* Issue 517 - Added border radius to email template tabs and removed excess bottom margin.
2017-07-02 17:51:41 +02:00
Raphael Michel
6f24a2a88c Fix import in unit test 2017-07-02 17:36:12 +02:00
Raphael Michel
fcbecf895a Bump version to 1.6.0.dev0 2017-07-02 17:32:02 +02:00
Raphael Michel
5abe8a109c Bump release to 1.5.0 2017-07-02 17:29:55 +02:00
Raphael Michel
ee6d0af795 Update translations 2017-07-02 17:26:32 +02:00
Raphael Michel
0dc82b6a28 Add answers to REST API 2017-07-02 16:34:55 +02:00
Raphael Michel
a530eda9fc Add CSRF_TRUSTED_ORIGINS to settings.py 2017-06-30 11:55:59 +02:00
Raphael Michel
3fa39798e5 Fix test failures 2017-06-29 18:03:16 +02:00
Raphael Michel
b7f8832633 Fix test_order_list 2017-06-29 12:11:20 +02:00
Raphael Michel
2add8d671a Unify all calls to register_payment_providers 2017-06-29 12:09:48 +02:00
Raphael Michel
d5d1fcf331 Add PaymentProvider.public_name 2017-06-29 11:44:27 +02:00
Raphael Michel
9007501d81 Collappse payment provider settings by default 2017-06-29 11:40:17 +02:00
Raphael Michel
fc12a8f549 Relabel button. 2017-06-28 18:57:50 +02:00
Raphael Michel
86f03b3399 Fix #532: Ticket editor, moving element groups 2017-06-28 18:55:33 +02:00
Raphael Michel
80ad0e7f68 PDF editor: share source code 2017-06-28 18:36:45 +02:00
Raphael Michel
ea970be6f2 Allow to generate random slugs 2017-06-28 18:20:06 +02:00
Raphael Michel
4bd0b96a2d Order list of events descending 2017-06-28 17:59:07 +02:00
Raphael Michel
c7f0436ec0 Filter list of events 2017-06-28 17:57:15 +02:00
Raphael Michel
ecc788fd79 Invoice name in order list 2017-06-28 17:37:53 +02:00
Raphael Michel
8ea9d5685d Use FilterForm for list of orders 2017-06-28 17:28:30 +02:00
Raphael Michel
c2bd2f0672 Add filters to the order search 2017-06-28 12:52:48 +02:00
Raphael Michel
424b7964b4 Move some links to their own templates 2017-06-27 18:22:27 +02:00
Raphael Michel
98394fdc63 Fix test failing on MySQL 2017-06-27 16:56:10 +02:00
Raphael Michel
625e90518e Add banktransfer API 2017-06-27 12:31:56 +02:00
Raphael Michel
d446191cf4 Organizer-level bank import 2017-06-27 12:31:45 +02:00
Raphael Michel
ea2557274f Show "create team" button to everyone who can 2017-06-27 08:58:54 +02:00
Raphael Michel
1bcca566ab Remove SVG from supported files for invoice generation 2017-06-26 19:15:13 +02:00
Raphael Michel
cf365635ef Correct pluralization for addon help texts 2017-06-26 17:29:39 +02:00
Raphael Michel
df6a93da5f Update translation 2017-06-26 17:08:52 +02:00
Raphael Michel
433512a256 Optionally ask for email addresses twice 2017-06-26 17:06:20 +02:00
Raphael Michel
e0fe78b82e Fix typocheck problem 2017-06-26 17:00:16 +02:00
Raphael Michel
d3a84690f2 Add QuotaListExporter 2017-06-26 16:50:16 +02:00
Raphael Michel
3df4b4dc57 Update translations 2017-06-22 16:24:29 +02:00
Raphael Michel
b2801f3a40 EU legislation note 2017-06-22 15:53:30 +02:00
Raphael Michel
e1bdfd7e4e Allow headlines with markdown 2017-06-22 15:53:30 +02:00
Tydon K
5584c12d0a Fixed typo in Helptext (#530) 2017-06-22 10:35:56 +02:00
Raphael Michel
91bd02157c Avoid word wrap inside event date 2017-06-21 15:44:42 +02:00
Raphael Michel
02d2b88a54 Extend validator blacklist 2017-06-19 17:47:13 +02:00
Raphael Michel
6ae5c5e6ce Fix tests failing after last commit 2017-06-19 16:17:08 +02:00
Raphael Michel
123d2f6120 Allow to add positions to an existing order 2017-06-19 15:22:57 +02:00
Raphael Michel
3ada10c3f4 Fix broken ReST markup 2017-06-19 13:58:45 +02:00
Raphael Michel
b21a928028 Add API endpoint for Quota.availability 2017-06-19 13:57:58 +02:00
Raphael Michel
374cf08086 Mention offending item in QuotaExceededException message 2017-06-19 13:23:37 +02:00
Raphael Michel
15a85bb873 Commit style docs 2017-06-19 12:02:12 +02:00
Raphael Michel
4b12678fa4 Various docs improvements 2017-06-19 12:01:00 +02:00
Raphael Michel
b2d4bea1d0 Refs #314 -- Read-only REST API (#513)
* initial commit

* API auth

* Hierarchical URLs

* Add session auth

* Strong hierarchy

* Add filters

* Add i18n fields, questions

* More viewsets and serializers

* Ticket download

* Add OrderPosition serializer

* View-level permissions

* More tests

* More tests

* Add basic API docs

* Add REST API to docs frontpage

* Tests for order endpoints

* Add invoice tests

* Voucher and waitinglist tests

* Doc draft

* order docs

* Docs on all viewsets

* Disable DRF docs, style sphinx, style browsable API

* Fix tests

* deprecated imports

* Test foo

* Attendee names

* Fix migration problems

* Remove browsable API, plugin integration

* Doc fixes
2017-06-19 11:16:04 +02:00
Tobias Kunze
6df3a7d4b5 Order vouchers by code by default (#525) 2017-06-18 18:31:54 +02:00
Raphael Michel
6964bf7c8a Revert accidental deletion of translations 2017-06-18 18:31:09 +02:00
Tobias Kunze
965424799d Highlight voucher nav element when in detail view (#524) 2017-06-18 18:31:02 +02:00
Tobias Kunze
f7de2ead40 Allow to pass prefix to generate_code, too (#523) 2017-06-18 18:30:38 +02:00
Tobias Kunze
260ba19e44 Typo fix and translation update (#519) 2017-06-18 18:22:57 +02:00
Raphael Michel
5caff5d28e Remove validation error on valid input 2017-06-16 23:21:49 +02:00
Tobias Kunze
8fa490c938 Allow to add a prefix when generating voucher codes (#518) 2017-06-16 23:21:23 +02:00
Raphael Michel
8e3cc0df0c Fix readthedocs CSS issue 2017-06-16 22:37:51 +02:00
Raphael Michel
1a5a4cf72d Fix sphinx-related problems 2017-06-16 22:29:19 +02:00
Raphael Michel
6c5b7bbed0 Custom docs front page 2017-06-16 22:16:45 +02:00
Raphael Michel
f9eee6a864 Add custom Sphinx theme 2017-06-16 22:16:45 +02:00
Raphael Michel
4ad0fe5653 Voucher form validation order 2017-06-12 12:50:06 +02:00
Raphael Michel
a02823ca38 Add global order search 2017-06-05 20:50:06 +02:00
Raphael Michel
513f8e66f5 Display full name in event typeahead 2017-06-05 19:37:40 +02:00
Raphael Michel
0cecc168b6 Autocompletion in event selection 2017-06-05 19:28:52 +02:00
Raphael Michel
6f7281b0f5 Add organizer domain 2017-06-05 18:07:18 +02:00
Raphael Michel
c7022bd285 Truncate name of current event 2017-06-05 17:51:21 +02:00
Raphael Michel
e89e3d2e1b Fix Go to shop button for non-live events with subdomain 2017-06-02 17:58:44 +02:00
noelroy
574fb6804f Fix #445 - Added go to shop button (#512) 2017-06-02 17:48:11 +02:00
AV-room
caf75fafdf Fix #454 -- Email field is now required on user settings page (#511) 2017-06-02 17:42:42 +02:00
Raphael Michel
bc74fb63d1 Base Dockerfile on python:3.6 2017-06-01 22:28:24 +02:00
Raphael Michel
b576a87d61 mark mimetypes as stdlib 2017-06-01 16:20:52 +02:00
Raphael Michel
6e81d8acec isort show diff 2017-06-01 15:44:11 +02:00
Raphael Michel
c67a53d156 Travis: Check style on 3.6 2017-06-01 14:54:52 +02:00
Raphael Michel
bf5ea81b40 Ignore style in tests, change import order 2017-06-01 13:28:11 +02:00
Raphael Michel
1261b8670f Bump version to 1.5.0.dev0 2017-06-01 13:00:37 +02:00
Raphael Michel
17dad33f8b Bump version to 1.4.0 2017-06-01 12:57:29 +02:00
Raphael Michel
1d5c160e1d Document contact_form_fields 2017-06-01 12:57:11 +02:00
Raphael Michel
f04b7fa365 Update translations 2017-06-01 12:56:53 +02:00
Raphael Michel
fa011fbdce Update django-redis 2017-05-31 07:51:16 +02:00
Raphael Michel
759c5374d9 Fix chardet pinning in setup.py 2017-05-30 19:22:28 +02:00
Raphael Michel
f631acdf18 Force chardet update 2017-05-30 19:12:44 +02:00
Raphael Michel
b2dfd8ab11 Bankimport: Force re-annotation for badly parsed files 2017-05-30 18:43:53 +02:00
Raphael Michel
43f4803da7 Fix name being used instead of email in CSV files 2017-05-30 18:00:21 +02:00
Raphael Michel
019d8220b8 Fix wrong text with banktransfer orders manually marked as paid 2017-05-30 17:57:50 +02:00
Raphael Michel
b946010bdb Add event date range to ticket editor 2017-05-30 17:18:03 +02:00
Raphael Michel
c3097b12c3 Fix typo 2017-05-30 17:14:17 +02:00
Raphael Michel
12a53710c3 Fix test_csvparser case that changed with newer chardet 2017-05-27 14:28:39 +02:00
Raphael Michel
983326e610 Stop pinning chardet/setuptools versions 2017-05-27 12:50:18 +02:00
Claudio Luck
b4eb707b38 bump required mt940 to v4.7 2017-05-27 11:59:21 +02:00
Claudio Luck
e44f34f0a9 mt940: also consider non-SWIFT field NS 2017-05-27 11:59:21 +02:00
Claudio Luck
3c762adbf4 mt940: payer is not always available 2017-05-27 11:59:21 +02:00
Raphael Michel
ebabd20d09 [Django 1.11] Refs #481 -- Explicit sorting of NULLs 2017-05-26 09:44:11 +02:00
Raphael Michel
8694e1901a [Django 1.11] Port AddOnVariationField 2017-05-26 09:44:11 +02:00
Tobias Kunze
0f2875e89a [Django 1.11] Upgrade to Django 1.11 2017-05-26 09:44:11 +02:00
Raphael Michel
74d9921be1 Fix error 500 during building error 400 responses 2017-05-26 09:37:48 +02:00
Tobias Kunze
41e56adfdb Make checkin lists available by default (#508) 2017-05-25 16:47:09 +02:00
Raphael Michel
4ff1d302d9 Fix missing argument 2017-05-25 14:55:04 +02:00
Raphael Michel
d6e213d51a Disable inline pdfs again due to Safari issues 2017-05-25 14:43:31 +02:00
Raphael Michel
2a4deeba55 List commercial plugins 2017-05-24 14:34:20 +02:00
Raphael Michel
24b1d2afcb Disable CssAbsoluteFilter 2017-05-24 14:34:20 +02:00
Leah Oswald
5cea3d824a Fix some typos in the backup and monitoring documentation (#506)
* fix missing word typo in backup and monitoring documentation

* fix another typo in backup and monitoring documentation
2017-05-24 13:40:12 +02:00
Raphael Michel
78a8a7d744 Add Order.meta_info_data 2017-05-23 12:38:00 +02:00
Raphael Michel
a3bf85754a Add signal contact_form_fields 2017-05-23 11:43:05 +02:00
Raphael Michel
006b6fd5e8 Add support for image icons in navigation 2017-05-23 11:42:42 +02:00
Raphael Michel
8ff2c42070 Fix order changing with zero-priced products 2017-05-22 21:13:05 +02:00
Raphael Michel
c5d18c6884 Clear settings cache after migration 2017-05-22 14:17:52 +02:00
Heok Hong Low
48b3621f1e Fix #499 -- Refactor paymentinfo to payment_info (#501)
* Refactor paymentinfo to payment_info, resolve #499

* Fix calling of object attribute on tuple

* Minor update to setup documentation

* Do not use short words for typochecks

* Text clarification

* Refactor paymentinfo to payment_info, resolve #499

* Include data migration for existing event settings, resolve #499
2017-05-22 14:06:19 +02:00
Raphael Michel
fb716eb498 Add add-ons to ticket editor 2017-05-22 14:04:14 +02:00
Tobias Kunze
5d8e294350 Fix typo 2017-05-22 09:25:15 +02:00
Raphael Michel
8a96d8c24e Text clarification 2017-05-21 10:47:12 +02:00
Raphael Michel
6396d2f922 Do not use short words for typochecks 2017-05-21 10:47:12 +02:00
lhhong
ed7e90451b Minor update to setup documentation 2017-05-21 10:29:56 +02:00
lhhong
f5990dd5c4 Fix calling of object attribute on tuple 2017-05-21 10:26:58 +02:00
Knuth
f29f615aec added a missing string and translation for it 2017-05-18 11:57:36 +02:00
Raphael Michel
f1300badb8 Bump version 2017-05-18 11:17:06 +02:00
Raphael Michel
88a1cddb23 Add release config for GitLab CI 2017-05-18 09:50:51 +02:00
Raphael Michel
d53fbc52d1 Fix #322 -- Do not use ManifestStaticFileStorage during testing 2017-05-17 18:20:13 +02:00
Raphael Michel
ec9511c17a Smaller documentation updates 2017-05-17 18:19:28 +02:00
Raphael Michel
3f2bb3beae Add date to the metadata section 2017-05-17 18:06:19 +02:00
Raphael Michel
c8b96696b0 Update/fix German translation 2017-05-17 18:06:19 +02:00
Raphael Michel
0bb6b53ebc Change client-side TIME_FORMAT for locale en as well 2017-05-17 18:06:19 +02:00
Raphael Michel
7400c2373b Remove debugging output 2017-05-17 18:06:19 +02:00
Knuth
635329f102 added missing spaces in DE and DE_informal 2017-05-17 17:05:49 +02:00
scabux
b5a2123d1c Added configurable text for organizer page (#494) 2017-05-17 15:53:30 +02:00
Raphael Michel
396c558b25 Fix critical bug in item creation 2017-05-17 15:47:35 +02:00
Ian Williams
60e178d821 Fix #443 -- Show private key in 2FA wizard (#490)
* Syncing fork to upstream (#1)

Sync master with master of pretix/pretix@300f8f6

* Automatically sort new products to the end

* Drop "squash your commits" from the dev guide

* Add variation descriptions and allow to order addons

* Link to Django's runserver options in dev docs

* Allow <br> tags in rich text

* Copy from event: deal with deleted items

* Make validate_cart useful together with addons

* Fix collapsing panels in the addon choice step

* Button text change if addons are present

* Update translations

* Squash migrations and bump version

* Ticket PDFs: Do not hide attendee name if code is hidden

* Add a user guide on payments

* Link PayPal and Stripe documentation in the respective forms

* Hide payment fees if they are all equal to 0.00

* Refs #39 -- New concept of "teams" (#478)

* New models

* CRUD UI

* UI for adding/removing team members

* Log display for teams

* Fix invitations, move frontend

* Drop old models (incomplete)

* Drop more old stuff

* Drop even more old stuff

* Fix tests

* Fix permission test

* flake8 fix

* Add tests fore the new code

* Rebase migrations

* Fix typo in method name

* Update translations

* Force ordering of events on dashboard

* Fix typos in events

* Prepare the pretixdroid API for an async mode in the app

* Pretixdroid tests: Ignore microseconds (chopped by mysql)

* pretixdroid API: Add related lookups

* Add idempotenty nonces to pretixdroid API

* pretixdroid: force-accepting unpaids and time display

* Marked webfonts as binary files (#487)

Webfonts now listed as binary in `.gitattributes`.
Works on pretix/pretix#486

* Fix #456 -- Allow products to be excluded from ticket-generation (#483)

* Added non-admission setting to event

`ticket_download_nonadm` now setting in storage. Still need logic for
order page/PDF generation.
Works on pretix/pretix#456.

* Download button considers `ticket_download_nonadm`

Modified Django tags to look at item admission attribute and
`ticket_download_nonadm` setting.
Works on pretix/pretix#456.

* Ticket output for non-admission disabled

PDFs/etc. will only be permitted/generated for items with the
`admission` attribute, or if the `ticket_download_nonadm` event setting
is true. Applies to single and whole-order ticket downloads.
Works on pretix/pretix#456.

* Fixed product exclusion in PDF output

Forgot PDF output was a plugin, now includes same check as base
`BaseTicketOutput.generate_order`.
Works on pretix/pretix#456

* Mail signature (#485)

* added signature field -- no function yet

* added mail signature feature

* fixed style issue

* fixed problem with signature default

* added unit test for mail signatures

* added unit test for mail signatures

* [WIP] Fix #447 -- Sendmail plugin: Create new mail based on an old one (#476)

* send old email content to the new one

* error key event

* test commit

* query bad ID

* query bad ID

* query bad ID

* query bad ID

* Update pretixdroid API version

* Refs #447 -- Extend copying old mails to subject and receipients

* Fixed bugs and added test for date range rendering (#488)

* fixed bug for same dates, added unit check for daterange

* fixed local language override in unit test

* Fix #297 -- pretixdroid: Show metrics in the control panel (#481)

* add checkin status page

add dashboard widget
add checkin page under orders

* modify checkin logic

added new fields in checkin page
added filter items

* add tests for checkins & minor improvement

* support addin_product & noadm setting logic

* remove name ordering check test case

* Fix #379 -- Add logo to event organizers (#431)

* [WIP] Add logo to event organizers.

* Fix indentation issues.

* Refactor code

Refactor code

Refactor code

* Add new migration

* Take files into account for organizer sform (settings form)

* Fix grammer

* Make bootstrap form errors specific to each fieldset

* Display logo on organizer's page

* Fix PR issues

Fix PR issues

Fix PR issues

* Reorder imports

* Remove conflicting migration

* Fix rebase conflict

* Fix #41 -- Drag-and-drop ticket editor

Undo/redo

Useful toolbox

Font selection

Add text content

Use hex for colors

JS-side dump and load

Save

Load layout, proper undo/redo

First steps to Python rendering

More PDF rendering

Copy and paste

Buttons for keyboard actions

Splash Screen

Block unbeforeunload in dirty state

Remove debugging output

Preview

Upload new PDFs via the editor

Fix bugs during PDF reload, link in settings form

New default ticket

Add OpenSans BI

Custom fonts, fix tests

* Added bootstrap-colorpicker

* Allow inline PDF display in CSP header

* Add fontpack to list of plugins

* Update German translation

* Add ticketoutputpdf's assets to MANIFEST.i

* Fix migration of old ticket styles

* Fix iCal download URL

* Multi-line location field, new field for admission time

* Admission date and time in editor

* Remove icon from "add to calendar"

* Try to fix PDF display problems in Safari

* Proxy cachedfiles that are used as editor previews

* Check Event.presale_is_running in more places

* Fix CSS generation with an empty color field

* Fix missing placeholders and reformat the sendmail view

* Fix bug that lead to wrong payment amount when switching payment method to PayPal later

* Update translation

* Revert "Syncing fork to upstream (#1)"

This reverts commit 847d409a00.
Merged wrong, my bad.

* Formatted OTP secret

New variable `secretGrouped` in `2fa_confirm_totp.html`, user-friendly
version of OTP secret (split every 4 characters).
Works on pretix/pretix#443.

* Adds manual secret entry OTP setup screen

`secretGrouped` exposed in user-friendly fashion. Includes short
instructions, copy-to-clipboard button, and js to hide instructions
unless user clicks on "Can't scan the barcode?" link.
Works on pretix/pretix#443.

* Minor indentation issuer

Fixed indentation issue (L40).
Works on pretix/pretix#443.

* Minor spacing issues

L265 of `user.py` failing flake8 tests, minor spacing fixes.

* Fixes indentation in `2fa_confirm_totp.html`

Per https://github.com/pretix/pretix/pull/490#discussion_r116165041,
fixes an issue with indentation.
Works on pretix/pretix#443, member of pretix/pretix#490.

* Removed `aria-*` attributes

Per https://github.com/pretix/pretix/pull/490#discussion_r116165115,
removes `aria` attributes from sub-tutorial.
Works on pretix/pretix#443, member of pretix/pretix#490.

* Pretix capitalization issue

Per https://github.com/pretix/pretix/pull/490#discussion_r116165193,
fixes an issue with capitalization of pretix.
Works on pretix/pretix#443, member of pretix/pretix#490.
2017-05-17 09:31:28 +02:00
Raphael Michel
7769aaccea Fix #492 -- Force deterministic ordering of some signals 2017-05-15 13:09:23 +02:00
Raphael Michel
5ff6d0b014 Auto-detect common typos in email addresses 2017-05-15 11:33:18 +02:00
Raphael Michel
7d9a1b5e0c Update translation 2017-05-11 12:15:23 +02:00
Raphael Michel
127086a50e Fix bug that lead to wrong payment amount when switching payment method to PayPal later 2017-05-10 19:12:55 +02:00
Raphael Michel
90d14c004f Fix missing placeholders and reformat the sendmail view 2017-05-10 15:14:23 +02:00
Raphael Michel
8c457c057e Fix CSS generation with an empty color field 2017-05-10 15:09:07 +02:00
Raphael Michel
36215a989a Check Event.presale_is_running in more places 2017-05-10 15:04:01 +02:00
Raphael Michel
74259bd4c6 Proxy cachedfiles that are used as editor previews 2017-05-10 15:02:54 +02:00
Raphael Michel
4561b7dce2 Try to fix PDF display problems in Safari 2017-05-10 15:02:28 +02:00
Raphael Michel
89d6166dbe Remove icon from "add to calendar" 2017-05-10 13:28:07 +02:00
Raphael Michel
f451977a04 Admission date and time in editor 2017-05-10 13:16:39 +02:00
Raphael Michel
aac05727ed Multi-line location field, new field for admission time 2017-05-10 12:58:57 +02:00
Raphael Michel
c9ae65a9a8 Fix iCal download URL 2017-05-10 12:57:59 +02:00
Raphael Michel
f4a9dbb546 Fix migration of old ticket styles 2017-05-09 17:23:17 +02:00
Raphael Michel
3eec791584 Add ticketoutputpdf's assets to MANIFEST.i 2017-05-09 11:55:25 +02:00
Raphael Michel
57473da182 Update German translation 2017-05-09 11:21:42 +02:00
Raphael Michel
fd90752a12 Add fontpack to list of plugins 2017-05-09 11:10:10 +02:00
Raphael Michel
0d3f5e0c32 Fix #41 -- Drag-and-drop ticket editor
Undo/redo

Useful toolbox

Font selection

Add text content

Use hex for colors

JS-side dump and load

Save

Load layout, proper undo/redo

First steps to Python rendering

More PDF rendering

Copy and paste

Buttons for keyboard actions

Splash Screen

Block unbeforeunload in dirty state

Remove debugging output

Preview

Upload new PDFs via the editor

Fix bugs during PDF reload, link in settings form

New default ticket

Add OpenSans BI

Custom fonts, fix tests
2017-05-09 11:10:10 +02:00
Raphael Michel
c98b0aac90 Added bootstrap-colorpicker 2017-05-09 11:10:10 +02:00
Raphael Michel
3de85975d6 Allow inline PDF display in CSP header 2017-05-09 11:10:10 +02:00
Bolutife Lawrence
962cdef69a Fix #379 -- Add logo to event organizers (#431)
* [WIP] Add logo to event organizers.

* Fix indentation issues.

* Refactor code

Refactor code

Refactor code

* Add new migration

* Take files into account for organizer sform (settings form)

* Fix grammer

* Make bootstrap form errors specific to each fieldset

* Display logo on organizer's page

* Fix PR issues

Fix PR issues

Fix PR issues

* Reorder imports

* Remove conflicting migration

* Fix rebase conflict
2017-05-08 17:46:35 +02:00
jlwt90
b301d20488 Fix #297 -- pretixdroid: Show metrics in the control panel (#481)
* add checkin status page

add dashboard widget
add checkin page under orders

* modify checkin logic

added new fields in checkin page
added filter items

* add tests for checkins & minor improvement

* support addin_product & noadm setting logic

* remove name ordering check test case
2017-05-08 17:31:37 +02:00
scabux
1b2895b0ca Fixed bugs and added test for date range rendering (#488)
* fixed bug for same dates, added unit check for daterange

* fixed local language override in unit test
2017-05-07 10:40:36 +02:00
Raphael Michel
d6943bb1dd Refs #447 -- Extend copying old mails to subject and receipients 2017-05-06 15:13:53 +02:00
Raphael Michel
51d74503ae Update pretixdroid API version 2017-05-06 14:40:28 +02:00
asv-hungvt
5eac3cf9cf [WIP] Fix #447 -- Sendmail plugin: Create new mail based on an old one (#476)
* send old email content to the new one

* error key event

* test commit

* query bad ID

* query bad ID

* query bad ID

* query bad ID
2017-05-06 14:39:48 +02:00
scabux
27d6f24c3c Mail signature (#485)
* added signature field -- no function yet

* added mail signature feature

* fixed style issue

* fixed problem with signature default

* added unit test for mail signatures

* added unit test for mail signatures
2017-05-06 11:12:38 +02:00
Ian Williams
d929b163db Fix #456 -- Allow products to be excluded from ticket-generation (#483)
* Added non-admission setting to event

`ticket_download_nonadm` now setting in storage. Still need logic for
order page/PDF generation.
Works on pretix/pretix#456.

* Download button considers `ticket_download_nonadm`

Modified Django tags to look at item admission attribute and
`ticket_download_nonadm` setting.
Works on pretix/pretix#456.

* Ticket output for non-admission disabled

PDFs/etc. will only be permitted/generated for items with the
`admission` attribute, or if the `ticket_download_nonadm` event setting
is true. Applies to single and whole-order ticket downloads.
Works on pretix/pretix#456.

* Fixed product exclusion in PDF output

Forgot PDF output was a plugin, now includes same check as base
`BaseTicketOutput.generate_order`.
Works on pretix/pretix#456
2017-05-06 11:11:11 +02:00
Ian Williams
571b3fbfa8 Marked webfonts as binary files (#487)
Webfonts now listed as binary in `.gitattributes`.
Works on pretix/pretix#486
2017-05-06 10:50:47 +02:00
Raphael Michel
db05f8eaa3 pretixdroid: force-accepting unpaids and time display 2017-05-04 11:57:29 +02:00
Raphael Michel
d8eba81efc Add idempotenty nonces to pretixdroid API 2017-05-04 09:32:36 +02:00
Raphael Michel
429ef67bbf pretixdroid API: Add related lookups 2017-05-03 19:17:37 +02:00
Raphael Michel
e5d9e69e3e Pretixdroid tests: Ignore microseconds (chopped by mysql) 2017-05-03 18:51:16 +02:00
Raphael Michel
dc32bdc474 Prepare the pretixdroid API for an async mode in the app 2017-05-03 18:06:32 +02:00
Raphael Michel
c45b709d54 Fix typos in events 2017-05-03 18:04:41 +02:00
Raphael Michel
e1be084d98 Force ordering of events on dashboard 2017-05-03 18:02:10 +02:00
Raphael Michel
20b8aafe11 Update translations 2017-05-03 17:23:44 +02:00
Raphael Michel
c719adf235 Fix typo in method name 2017-05-03 17:11:55 +02:00
Raphael Michel
d08a0bdb00 Refs #39 -- New concept of "teams" (#478)
* New models

* CRUD UI

* UI for adding/removing team members

* Log display for teams

* Fix invitations, move frontend

* Drop old models (incomplete)

* Drop more old stuff

* Drop even more old stuff

* Fix tests

* Fix permission test

* flake8 fix

* Add tests fore the new code

* Rebase migrations
2017-05-03 16:55:37 +02:00
Raphael Michel
8294391ebc Hide payment fees if they are all equal to 0.00 2017-05-02 19:12:42 +02:00
Raphael Michel
394c206133 Link PayPal and Stripe documentation in the respective forms 2017-05-02 19:07:19 +02:00
Raphael Michel
2fcd561ff7 Add a user guide on payments 2017-05-02 18:59:18 +02:00
Raphael Michel
f95b77fd7a Ticket PDFs: Do not hide attendee name if code is hidden 2017-05-02 17:07:09 +02:00
Raphael Michel
7509bf69ca Squash migrations and bump version 2017-05-02 11:07:15 +02:00
Raphael Michel
d9adec88c8 Update translations 2017-05-02 11:01:48 +02:00
Raphael Michel
938a1bca0d Button text change if addons are present 2017-05-02 10:57:40 +02:00
Raphael Michel
ab757c502c Fix collapsing panels in the addon choice step 2017-05-02 10:51:43 +02:00
Raphael Michel
6b17388bd8 Make validate_cart useful together with addons 2017-05-02 10:20:28 +02:00
Raphael Michel
48a933b757 Copy from event: deal with deleted items 2017-05-02 09:58:26 +02:00
Raphael Michel
6c02bf73b5 Allow <br> tags in rich text 2017-05-02 09:52:46 +02:00
Raphael Michel
960d0bcdf2 Link to Django's runserver options in dev docs 2017-05-02 00:15:39 +02:00
Raphael Michel
d389e4390f Add variation descriptions and allow to order addons 2017-05-02 00:12:22 +02:00
Raphael Michel
55ce83a642 Drop "squash your commits" from the dev guide 2017-05-02 00:04:38 +02:00
Raphael Michel
300f8f666d Automatically sort new products to the end 2017-05-01 22:57:29 +02:00
Raphael Michel
5d6083dce4 Add-On product refinements 2017-04-30 13:23:03 +02:00
Raphael Michel
82f9f5027f Fix incorrect heading of CSV file 2017-04-27 18:23:16 +02:00
Raphael Michel
4f015f1d96 Replace organizer_edit_tabs by nav_organizer 2017-04-27 10:00:09 +02:00
Raphael Michel
bbe272c35c Fix #372 -- Plugin hook for "Copy from event" 2017-04-26 15:24:16 +02:00
Raphael Michel
39513448f3 Add signal nav_global 2017-04-26 14:34:48 +02:00
Raphael Michel
bee61bf398 Allow creating KnownDomains in the interface 2017-04-26 14:34:48 +02:00
Tobias Kunze
010c31cf10 Fix type annotation 2017-04-25 09:10:45 +02:00
Raphael Michel
d1643b4506 Refs #471 -- Additional event filter on quota calculation 2017-04-22 11:47:25 +02:00
Raphael Michel
623307b348 Do not override the selected category when copying from a different product 2017-04-22 10:37:28 +02:00
Raphael Michel
09e8fca132 Do not allow adding add-ons to add-ons 2017-04-21 15:12:16 +02:00
Raphael Michel
2c96a26d91 Fix missing attributes in copying products 2017-04-21 15:07:32 +02:00
Raphael Michel
f639d2aa57 Include category in ItemCreateForm 2017-04-21 14:35:45 +02:00
Raphael Michel
5a68eb345f Fix broken language field filtering in payment settings 2017-04-21 14:26:19 +02:00
Raphael Michel
603a3d78fc Properly initialize lightbox 2017-04-19 17:10:32 +02:00
Raphael Michel
cafc6a7226 Add the new widget dependencies to the event creation form 2017-04-18 20:32:12 +02:00
Raphael Michel
0b068f6d79 Copy add-ons during event cloning 2017-04-18 20:31:16 +02:00
Raphael Michel
ec73c916b7 Change style of admin log entries 2017-04-17 22:04:25 +02:00
Raphael Michel
110ccb5587 Update FontAwesome 2017-04-17 22:00:58 +02:00
Raphael Michel
d224ae3eb0 Fix broken aggregation in orders per product statistics 2017-04-17 21:52:17 +02:00
Raphael Michel
dd9c0b3a01 Add dependencies between form fields 2017-04-17 21:37:25 +02:00
Raphael Michel
d2d711c1f8 Fix datetimepicker annoyances 2017-04-17 21:12:52 +02:00
Raphael Michel
3dd2492926 Fix a broken import 2017-04-17 17:13:18 +02:00
Raphael Michel
bc1520ec35 Even more wording corrections 2017-04-17 17:10:47 +02:00
Raphael Michel
3033a82c92 Update wording and translation 2017-04-17 16:34:46 +02:00
Raphael Michel
bb75be7e8e Update docs and version number 2017-04-17 15:19:45 +02:00
Raphael Michel
b52f2f5a9e Improve add-on products 2017-04-17 14:54:15 +02:00
Raphael Michel
5bcfb958f0 Simpler API for cart removal 2017-04-17 14:54:15 +02:00
Raphael Michel
5f52963ce0 Add add-on products 2017-04-17 14:54:15 +02:00
Raphael Michel
3f76be2287 Fix docker plugin installation documentation 2017-04-17 13:27:49 +02:00
Raphael Michel
92aa65a839 Small refinements on the previous commit 2017-04-14 18:05:02 +02:00
Alexey Kislitsin
bd5337a2c2 Fix #448 -- Add PlaceholderValidator (#465)
* Integrated PlaceholderValidator to MailForm at plugins/sendmail

* Integrated PlaceholderValidator to MailForm and MailSettingsForm

* Typo
2017-04-14 18:04:30 +02:00
Raphael Michel
990d5815f2 Fix #468 -- Long event slugs on invoices 2017-04-14 18:00:20 +02:00
Raphael Michel
c1d51cc196 Improve help text 2017-04-14 17:37:38 +02:00
Raphael Michel
f5b871f8f5 Unify design of the different mail previews 2017-04-14 11:51:27 +02:00
jlwt90
bc6b84f900 Fix #308 -- Preview for email templates (#438)
* add ajax and dummy api response

* add preview <p> blocks

* finalise order_placed setup

- use <pre> for mail preview
- create dummy data in backend

* fix i18n text conversion

* create fragment template for mail preview

* support i18n in mail preview view

* apply mail fragment in all mail settings

fix mistake in input[lang=en] flag style
add dummy data for all placeholders
apply fragment template to all fields
add exclude option to fragment template

* remove migration file

* add translation mapping & fix field label

remove hardcoded field label
add transblock for translation file

* add test for mail setting preview

* fix code style in preview class

* bug fix in mail preview view

- fixed localised date values
- added locale index mapping
- added tests on multi-language event
- enhanced dummy data
2017-04-14 11:19:58 +02:00
Raphael Michel
5ee79c8148 Update German translations 2017-04-13 23:16:03 +02:00
Raphael Michel
e4706dd3ba Add attendee email field (#466)
* Add attendee email field

* exports, tests
2017-04-13 22:59:54 +02:00
Raphael Michel
3c59a870e7 Add new option Item.min_per_order 2017-04-13 14:16:23 +02:00
Raphael Michel
ae6ad8870d Fix order view in test cases 2017-04-11 14:25:13 +02:00
Raphael Michel
07fed0acce Use async actions for order export 2017-04-11 12:12:40 +02:00
Raphael Michel
7dd99f3d18 Fix locale formatting in PDF exporter 2017-04-11 11:38:49 +02:00
Raphael Michel
03d8cfb401 Cosmetic changes to locale change form 2017-04-11 10:54:12 +02:00
Jahongir
ccb981e6ce Issue #449: Display and change order locale (#459)
* Add more security headers (#458)

* Include some missing security headers

This change adds the following security headers:
* X-Content-Type-Options to prevent content type sniffing
* Referrer-Policy to prevent leaking referrer information when navigating away from the instance

* Migrate from Docker sample to manual configuration

Migrate the additional security headers from the Docker configuration sample to the manual configuration guide.

Add DS_Store to gitingore

* Show order locale in order details

* Add OrderLocaleChange view and OrderLocaleForm

Refactor OrderLocaleForm. Add test
2017-04-11 10:45:46 +02:00
Raphael Michel
984d5c716b Integrate hierarkey package (#460) 2017-04-10 18:11:21 +02:00
Raphael Michel
43121a08bd Add consistent ordering to pretixdroid API 2017-04-10 16:34:58 +02:00
Jan Felix Wiebe
54c7f16c4c Added missing semicolon to docker nginx config (#462) 2017-04-10 15:11:40 +02:00
Jan Felix Wiebe
6cd2674f2a Switched checkbox order (#461)
The boxes vor adding and editing vouchers were switched for new users.
2017-04-10 10:25:21 +02:00
BenBE
602947a3d7 Add more security headers (#458)
* Include some missing security headers

This change adds the following security headers:
* X-Content-Type-Options to prevent content type sniffing
* Referrer-Policy to prevent leaking referrer information when navigating away from the instance

* Migrate from Docker sample to manual configuration

Migrate the additional security headers from the Docker configuration sample to the manual configuration guide.
2017-04-06 17:30:26 +02:00
Raphael Michel
5048963aa2 Fix trailing whitespace 2017-04-06 15:04:31 +02:00
morrme
8d16e2b59b Fix #444 -- Add alternative text to the top-right navigation (#457)
* Update base.html

* Update base.html

* Update signals.py
2017-04-06 14:13:12 +02:00
Matthew Emerson
4accbef6a9 Fix #446 -- Choices for Event.currenxy attribute (#452)
* Change event currency to a choice attribute

* Added pycountry to requirements for currency list

* Fixed issues from flake8

* Added tests for event currency and added pycountry to setup.py

* Removed whitespace from test/control/test_events.py
2017-04-06 12:08:55 +02:00
Raphael Michel
2e9d95b96a Update minimal django version 2017-04-05 11:10:49 +02:00
Raphael Michel
03dfd1b96f Ignore database errors during rebuild 2017-04-02 22:27:53 +02:00
Raphael Michel
ee1ccb7f01 Do not actually call the pretix server during tests 2017-04-02 22:12:14 +02:00
Raphael Michel
a6a3544628 Bump version number 2017-04-01 16:19:57 +02:00
Raphael Michel
ca762083b6 Update translations 2017-04-01 15:55:31 +02:00
alainrk
550ab7de18 Added python3-dev package to External Dependencies (#451) 2017-04-01 15:40:46 +02:00
Raphael Michel
4919f8991c Automatic update checks (#434)
* Basic update checks

* Fix issues pointed out by @rixx

* First test

* Add tests

* Even more tests
2017-04-01 15:34:34 +02:00
Raphael Michel
867a8132aa Add error messages to forms 2017-04-01 15:23:11 +02:00
Raphael Michel
c661122bb6 Increase margin in emails 2017-04-01 15:22:40 +02:00
Raphael Michel
80bd8d2039 Fix TypeError introduced in 9dacea11 2017-03-31 11:49:25 +02:00
Raphael Michel
7267496367 Fix small UI glitches 2017-03-31 11:11:40 +02:00
Raphael Michel
9dacea11dd Improve wording 2017-03-31 09:54:07 +02:00
Raphael Michel
91c48c50e5 Fix unclear labels and validations 2017-03-30 23:34:28 +02:00
Raphael Michel
67e5ecb931 Add IcePay to list of plugins 2017-03-30 16:45:01 +02:00
Raphael Michel
887152a0e2 Fix retry logic for failed order downloads 2017-03-29 14:36:09 +02:00
Raphael Michel
c1a76c4c18 HTML Sanitizer: Allow the class attribute 2017-03-28 10:54:08 +02:00
Raphael Michel
8dacbe0fc6 Add docs for metrics and FakeRedis.pipeline 2017-03-27 23:07:33 +02:00
Raphael Michel
a4ead5bd07 Metrics: Pipeline redis commands 2017-03-27 22:31:20 +02:00
Raphael Michel
2f6e36c504 Metrics: Replace redundant metrics by aliases 2017-03-27 22:24:35 +02:00
Raphael Michel
bcdb4fd000 Metrics: Count model instances in database 2017-03-27 21:58:38 +02:00
Raphael Michel
99395c722d Run CommonMiddleware before metrics (because of APPEND_SLASH) 2017-03-27 21:52:00 +02:00
Raphael Michel
e28030576a Metrics: Follow conventions (thanks @cherti) 2017-03-27 21:43:11 +02:00
Raphael Michel
455b0f2015 Add documentation on backups and monitoring 2017-03-25 22:54:39 +01:00
Raphael Michel
6da0125b7d Metrics: Add empty line at end 2017-03-25 22:21:22 +01:00
Raphael Michel
48912bdf55 Healthcheck: Check redis and cache 2017-03-25 22:21:07 +01:00
Raphael Michel
ba70ddfb76 Metrics: Fix key output 2017-03-25 22:12:36 +01:00
Raphael Michel
f828fcdcab Fix and extend metrics tests 2017-03-25 22:08:44 +01:00
Raphael Michel
c1403207de Metrics: Store all metrics within a redis hash 2017-03-25 22:08:15 +01:00
Raphael Michel
4514bd7e53 Add metrics for view/task time 2017-03-25 21:38:42 +01:00
Raphael Michel
f2378168c1 Metrics: Implement histograms 2017-03-25 21:38:04 +01:00
Raphael Michel
e0e3a72268 Add metrics for request/task counting 2017-03-25 21:17:12 +01:00
Raphael Michel
c932892dbd Fix bugs in metrics tooling 2017-03-25 21:16:07 +01:00
Raphael Michel
f03ad7c68f Revert 36d6b6f9, pass language to async tasks 2017-03-25 11:32:29 +01:00
Raphael Michel
d3a26d8022 Display checkbox for items with max_per_order == 1 2017-03-24 17:30:37 +01:00
Raphael Michel
446698d52f Update German translation 2017-03-24 17:17:09 +01:00
Raphael Michel
69faab01b2 Add constraint for a maximum number of a ticket per order 2017-03-24 17:11:48 +01:00
Raphael Michel
36d6b6f9ab Support LazyI18nString arguments for LazyLocaleException 2017-03-24 17:03:41 +01:00
Raphael Michel
ea70b5fa46 Remove double negative 2017-03-24 15:44:23 +01:00
Raphael Michel
927e21e5d1 Fix display error on variations with required vouchers 2017-03-20 16:01:09 +01:00
Raphael Michel
259c0cca69 Explicit position ordering in invoice tests 2017-03-19 15:04:21 +01:00
Raphael Michel
11ce4c2078 Add default ordering for Invoice and OrderPosition 2017-03-19 14:47:30 +01:00
Raphael Michel
76ec402fc5 Fix #436 -- Fix test cases broken in aed78c2d 2017-03-19 13:58:08 +01:00
Raphael Michel
df956816b4 Refs #436 -- Try to fix travis script 2017-03-19 13:47:58 +01:00
Flavia Bastos
5d431b3843 Add test for sendmail plugin (#417)
* add test for sendmail plugin

* add post request

* failing get request

* test sendmail simple case

* add tests for sendmail plugin

* add tests to sendmail plugin - adjust test name

* fix multi_locales test for sendmail plugin
2017-03-17 11:03:43 +01:00
Raphael Michel
91ca4f2184 Fix untranslated titles of export providers 2017-03-16 23:46:42 +01:00
Raphael Michel
b00a0eccc6 Add names to AUTHORS file 2017-03-16 23:46:20 +01:00
Raphael Michel
d675ad18e0 Absolute URLs in HTML mails 2017-03-16 09:59:54 +01:00
Raphael Michel
031ed8f3cd Add new template tag abseventurl 2017-03-16 09:59:54 +01:00
Raphael Michel
aed78c2d69 Show "sold out" if all quota is blocked by orders, even unpaid ones 2017-03-13 18:02:45 +01:00
jlwt90
af3e811f94 Fix #428 -- Timezone handling on event creation/update (#432)
* add event timezone during event creation

* add timezone handling in EventUpdate

* added event creation test cases & form cleaning bug fix
2017-03-13 16:44:05 +01:00
Raphael Michel
811c498080 Fix typo 2017-03-12 23:09:11 +01:00
Raphael Michel
e6d58b3b0d Show warnings about development mode and DEBUG mode 2017-03-12 23:03:03 +01:00
Raphael Michel
b7dc671028 Move global settings to a distinct URL 2017-03-12 20:17:55 +01:00
Raphael Michel
8418eb2c6b Add basic tests for event creation 2017-03-12 17:23:39 +01:00
Raphael Michel
5a882a0fae Fix broken i18nfield style 2017-03-12 11:11:13 +01:00
Raphael Michel
be1cbfeb91 Integrate cartshare tests (#425) 2017-03-12 00:32:33 +01:00
Raphael Michel
96c61a073c Fix wrong email subject 2017-03-11 20:03:10 +01:00
Raphael Michel
64ef293ce2 Move "Add to calendar" button down 2017-03-09 21:41:18 +01:00
jlwt90
55953d5b4e Fix #389 -- Add event ical download feature (#413)
* added event ical download feature

* handle event settings and timezone

* add test cases for ical download

* fix failed test case for timezone settings

* using vobject lib to generate ical

* customised UID & add vobject dependency
2017-03-09 21:13:08 +01:00
Raphael Michel
c63e69db5f Remove version pin of html5lib and update bleach 2017-03-08 18:26:52 +01:00
Raphael Michel
f9646d9325 Do casual reads only on Galera 2017-03-08 18:15:39 +01:00
Raphael Michel
6bbdbddfaa Reorder meta tags 2017-03-08 17:54:55 +01:00
Raphael Michel
177d46ab8d New signal: html_footer 2017-03-08 14:38:25 +01:00
Raphael Michel
ecd90da554 Fix syntax fuckup 2017-03-07 23:37:37 +01:00
Raphael Michel
2302dbade6 Even slightly more CSP refactoring 2017-03-07 22:30:15 +01:00
Raphael Michel
cbf735487f Improved merging of CSP headers 2017-03-07 21:48:59 +01:00
Tobias Kunze
a10090b1fb Set autofocus on search/filter field (#427) 2017-03-06 14:19:14 +01:00
Raphael Michel
babf76371e Sendmail plugin: Fix usage of old argument 2017-03-05 17:23:16 +01:00
jlwt90
1baac6bb21 add voucher code in success message (#426)
* add voucher code in success message

* change voucher message
2017-03-05 09:32:56 +01:00
Raphael Michel
b1c60065b2 Bump version number 2017-03-02 23:10:31 +01:00
Raphael Michel
af4a2c7184 Run tests on multiple Python versions and databases (#424)
* Test against more python versions

* Add testing on MySQL

* Add testing on PostgreSQL
2017-03-02 11:59:09 +01:00
Tobias Kunze
b6f42ecd6d Update translations. (#423)
(Including adding a missing whitespace.)
2017-03-02 08:19:34 +01:00
Raphael Michel
8b7d2314b8 Use django-i18nfield library (#418) 2017-02-27 21:16:28 +01:00
Tobias Kunze
81adbb3813 Expand Question docstring (#420) 2017-02-26 13:11:37 +01:00
Raphael Michel
684198fc08 Docker: fix build on docker hub 2017-02-26 12:40:57 +01:00
Raphael Michel
a86431bb6d Docker: Move static files 2017-02-26 11:55:19 +01:00
Raphael Michel
767e3ac659 Docker: Use stable version in docs 2017-02-26 11:32:23 +01:00
Raphael Michel
910d6831bf Docker: Ignore local pretix.cfg on build host 2017-02-26 11:31:24 +01:00
Jakob Schnell
c251a48e31 Fix #248 -- Failed Payment error handling (#333)
* [WIP] Failed Payment error handling

When finished, this should fix #248

* rename PaymentFailedException to PaymentException\nimported Exception where neccessary

* comments fixed

* minor style fixes

* Fixed a name error
2017-02-24 14:11:41 +01:00
Raphael Michel
8e4b71eb19 Display a small pretix logo next to changes performed by superusers 2017-02-23 20:36:19 +01:00
Raphael Michel
a2cb219d9b Remove GenericRelation to prevent cascade deletion of logs 2017-02-23 17:52:48 +01:00
Raphael Michel
f722d4e83e Update translations 2017-02-22 17:31:13 +01:00
Raphael Michel
ed04f3124f Introduce a setting to show net prices (#415)
* Introduce a setting to show net prices in the frontend

* Show net prices in the backend as well
2017-02-22 16:59:54 +01:00
Raphael Michel
08e7a29623 MySQL Galera workaround (#416) 2017-02-22 16:59:23 +01:00
Raphael Michel
09020143e7 Refactoring of cart services (#414) 2017-02-21 17:15:43 +01:00
Raphael Michel
33e7a10bea Fix editing organizers (now for real) 2017-02-20 16:46:48 +01:00
Raphael Michel
5e64f6ac88 Update German translation 2017-02-20 15:41:41 +01:00
Raphael Michel
f16aabc136 Add signal for required pre-checkout confirmations 2017-02-20 15:40:55 +01:00
Raphael Michel
2d00563088 Code style fix 2017-02-20 15:11:03 +01:00
Raphael Michel
124c3a99e6 Fix possible TypeError 2017-02-20 15:11:03 +01:00
Raphael Michel
7e135be012 Add tests and remove redundant checks 2017-02-17 16:19:03 +01:00
Raphael Michel
d94c67bc7a Adjust test to previous change 2017-02-17 09:58:52 +01:00
Raphael Michel
3636bbbf3f Fix invoice logos with transparency 2017-02-17 09:51:06 +01:00
Raphael Michel
7c687ee397 Fix dashboard widgets to show correct waiting list numbers 2017-02-17 09:45:05 +01:00
Raphael Michel
c3fb033d33 Update .codecov.yml 2017-02-16 10:33:08 +01:00
Raphael Michel
8b2257161f Fix voucher redemption and event index after c4bf73c 2017-02-15 19:17:42 +01:00
Raphael Michel
c4bf73c8d6 Refs #340 -- Allow order changes for paid orders if they don't change the total 2017-02-15 18:42:46 +01:00
Raphael Michel
0db927407d Clarify help texts 2017-02-15 18:07:40 +01:00
Tobias Kunze
9b7223c0e8 Enforce a sane last payment date (#412) 2017-02-15 16:37:10 +01:00
Flavia Bastos
7b33fc6633 Fix #409 -- false success message on sendmail plugin (#410)
* Fix false success message on sendmail plugin
#409

* remove unnecessary else statement when fixing false success message on sendmail
#409
2017-02-11 21:49:10 +01:00
Raphael Michel
8310597944 Waitinglist: Improve waitinglist and logging 2017-02-10 11:19:22 +01:00
Raphael Michel
c03ac624fc Update translation 2017-02-10 11:19:05 +01:00
Raphael Michel
323beb1ab0 Add word wrapping to Invoice from/to/event 2017-02-10 10:38:45 +01:00
Raphael Michel
73490d2923 Add custom rich_text template filter 2017-02-10 10:38:45 +01:00
Jan Felix Wiebe
a8e630d271 corrected typo in pdf ticket generator help text (#408)
* Corrected small typo

* corrected same typo in informal language file
2017-02-10 08:36:05 +01:00
Raphael Michel
e3e8a162bd Fix KeyError in sendmail history 2017-02-08 12:06:11 +01:00
Raphael Michel
824ca54478 Refs #386 -- Add unit test 2017-02-08 10:24:50 +01:00
Adam K. Sumner
8661bfe4a4 Fix #386 -- Allow to copy products (#396)
* add copy item info functionality

* fix formatting

* Revert "fix formatting"

This reverts commit 779bd79e8b.

* Revert "add copy item info functionality"

This reverts commit dbec76bf5a.

* add copy functionality

* copy questions from item

* add copy functionality

* copy questions from item

* add copy functionality

* copy questions from item
2017-02-08 10:16:18 +01:00
Raphael Michel
4c2c302bfd Fix organizer team changes 2017-02-07 10:50:20 +01:00
Raphael Michel
c83f539bba Add waiting list 2017-02-07 10:03:30 +01:00
Raphael Michel
8f5849a90c Test on SQLite if not configured otherwise 2017-02-07 10:03:30 +01:00
Raphael Michel
b7df5eff19 Move asynctask/asyncdownload to base 2017-02-07 10:03:30 +01:00
Raphael Michel
eb4ba70be8 Codecov config 2017-02-07 08:39:31 +01:00
Raphael Michel
136094caf9 Updated README (thanks Dr. h.c. pun. @rixx) 2017-02-07 00:09:35 +01:00
Raphael Michel
1fa0256363 Switch from coveralls to codecov 2017-02-07 00:04:28 +01:00
Ahrdie
6de44aee02 Small Typo correction (#404) 2017-02-06 22:04:12 +01:00
Marc-Pascal Clement
43facbecda Fix path in cronjob of smallscale deployment guide (#401) 2017-02-04 14:10:41 +01:00
Raphael Michel
0dfca824e2 Fix install docs, thanks @buenaventure 2017-02-04 14:09:04 +01:00
Raphael Michel
70ee678fef Fix language classifiers 2017-02-03 15:58:38 +01:00
629 changed files with 153846 additions and 11879 deletions

35
.codecov.yml Normal file
View File

@@ -0,0 +1,35 @@
codecov:
notify:
require_ci_to_pass: yes
coverage:
precision: 2
round: down
range: "60...100"
status:
project:
default:
target: auto
threshold: 2%
base: auto
patch:
default:
target: auto
threshold: 2%
base: auto
changes: no
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
comment:
require_changes: yes
layout: "header, diff, files"
behavior: default
require_changes: no

14
.gitattributes vendored
View File

@@ -3,4 +3,18 @@ src/static/lightbox/* linguist-vendored
src/static/typeahead/* linguist-vendored
src/static/moment/* linguist-vendored
src/static/datetimepicker/* linguist-vendored
src/static/colorpicker/* linguist-vendored
src/static/fileupload/* linguist-vendored
src/static/charts/* linguist-vendored
src/pretix/plugins/ticketoutputpdf/static/pretixplugins/ticketoutputpdf/fabric.* linguist-vendored
src/pretix/plugins/ticketoutputpdf/static/pretixplugins/ticketoutputpdf/pdf.* linguist-vendored
# Denote all files that are truly binary and should not be modified.
*.eot binary
*.otf binary
*.ttf binary
*.woff binary
*.zip binary
*.png binary
*.gif binary
*.jpg binary

2
.gitignore vendored
View File

@@ -21,4 +21,6 @@ pretixeu/
local/
.project
.pydevproject
.DS_Store

View File

@@ -2,11 +2,31 @@ before_script:
tests:
stage: test
script:
- virtualenv-3.4 env
- virtualenv env
- source env/bin/activate
- pip install -U pip wheel setuptools
- XDG_CACHE_HOME=/cache bash .travis.sh style
- XDG_CACHE_HOME=/cache bash .travis.sh tests
- XDG_CACHE_HOME=/cache bash .travis.sh doctests
tags:
- python3
pypi:
stage: release
script:
- cp /keys/.pypirc ~/.pypirc
- virtualenv env
- source env/bin/activate
- pip install -U pip wheel setuptools
- XDG_CACHE_HOME=/cache pip3 install -Ur src/requirements.txt -r src/requirements/dev.txt -r src/requirements/py34.txt
- cd src
- python setup.py sdist upload
- python setup.py bdist_wheel upload
tags:
- python3
only:
- release
artifacts:
paths:
- src/dist/
stages:
- test
- build
- release

View File

@@ -4,11 +4,21 @@ set -x
echo "Executing job $1"
if [ "$PRETIX_CONFIG_FILE" == "tests/travis_mysql.cfg" ]; then
mysql -u root -e 'CREATE DATABASE pretix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
pip3 install -Ur src/requirements/mysql.txt
fi
if [ "$PRETIX_CONFIG_FILE" == "tests/travis_postgres.cfg" ]; then
psql -c 'create database travis_ci_test;' -U postgres
pip3 install -Ur src/requirements/postgres.txt
fi
if [ "$1" == "style" ]; then
XDG_CACHE_HOME=/cache pip3 install -Ur src/requirements.txt -r src/requirements/dev.txt -r src/requirements/py34.txt
cd src
flake8 .
isort -c -rc .
isort -c -rc -df .
fi
if [ "$1" == "doctests" ]; then
XDG_CACHE_HOME=/cache pip3 install -Ur doc/requirements.txt -r src/requirements/py34.txt
@@ -20,12 +30,27 @@ if [ "$1" == "tests" ]; then
cd src
python manage.py check
make all compress
coverage run -m py.test --rerun 5 tests && coverage report
py.test --rerun 5 tests
fi
if [ "$1" == "tests-cov" ]; then
pip3 install -r src/requirements.txt -Ur src/requirements/dev.txt -r src/requirements/py34.txt
cd src
python manage.py check
make all compress
coverage run -m py.test --rerun 5 tests && coveralls
coverage run -m py.test --rerun 5 tests && codecov
fi
if [ "$1" == "plugins" ]; then
pip3 install -r src/requirements.txt -Ur src/requirements/dev.txt -r src/requirements/py34.txt
cd src
python setup.py develop
make all compress
pushd ~
git clone --depth 1 https://github.com/pretix/pretix-cartshare.git
cd pretix-cartshare
python setup.py develop
make
py.test --rerun 5 tests
popd
fi

View File

@@ -1,15 +1,40 @@
language: python
sudo: false
python:
- "3.4"
install:
- pip install -U pip wheel setuptools==28.6.1
- pip install -U pip wheel setuptools==28.6.1
script:
- bash .travis.sh $JOB
- bash .travis.sh $JOB
cache:
directories:
- $HOME/.cache/pip
env:
- JOB=style
- JOB=doctests
- JOB=tests-cov
directories:
- $HOME/.cache/pip
services:
- mysql
- postgresql
matrix:
include:
- python: 3.6
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_sqlite.cfg
- python: 3.6
env: JOB=tests-cov
- python: 3.6
env: JOB=style
- python: 3.4
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_sqlite.cfg
- python: 3.5
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_sqlite.cfg
- python: 3.4
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_mysql.cfg
- python: 3.5
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_mysql.cfg
- python: 3.6
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_mysql.cfg
- python: 3.4
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_postgres.cfg
- python: 3.5
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_postgres.cfg
- python: 3.6
env: JOB=tests PRETIX_CONFIG_FILE=tests/travis_postgres.cfg
- python: 3.6
env: JOB=plugins
addons:
postgresql: "9.4"

17
AUTHORS
View File

@@ -3,18 +3,31 @@ 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>
Ben Oswald
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>
Jason Estibeiro <jasonestibeiro@live.com>
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

View File

@@ -1,11 +1,9 @@
FROM debian:jessie
FROM python:3.6
RUN apt-get update && \
apt-get install -y python3 git python3-pip \
libxml2-dev libxslt1-dev python-dev python-virtualenv locales libffi-dev \
build-essential python3-dev zlib1g-dev libssl-dev gettext \
libpq-dev libmysqlclient-dev libmemcached-dev libjpeg-dev \
aqbanking-tools supervisor nginx sudo \
apt-get install -y git libxml2-dev libxslt1-dev python-dev python-virtualenv locales \
libffi-dev build-essential python3-dev zlib1g-dev libssl-dev gettext libpq-dev \
libmysqlclient-dev libmemcached-dev libjpeg-dev supervisor nginx sudo \
--no-install-recommends && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
@@ -31,11 +29,11 @@ RUN chmod +x /usr/local/bin/pretix && \
rm /etc/nginx/sites-enabled/default && \
pip3 install -U pip wheel setuptools && \
cd /pretix/src && \
rm -f pretix.cfg && \
pip3 install -r requirements.txt -r requirements/mysql.txt -r requirements/postgres.txt \
-r requirements/memcached.txt -r requirements/redis.txt \
-r requirements/py34.txt gunicorn && \
-r requirements/memcached.txt -r requirements/redis.txt gunicorn && \
mkdir -p data && \
chown -R pretixuser:pretixuser /static /pretix /data data && \
chown -R pretixuser:pretixuser /pretix /data data && \
sudo -u pretixuser make production
USER pretixuser

View File

@@ -10,11 +10,12 @@ pretix
.. image:: https://travis-ci.org/pretix/pretix.svg?branch=master
:target: https://travis-ci.org/pretix/pretix
.. image:: https://coveralls.io/repos/github/pretix/pretix/badge.svg?branch=master
:target: https://coveralls.io/r/pretix/pretix
.. image:: https://codecov.io/gh/pretix/pretix/branch/master/graph/badge.svg
:target: https://codecov.io/gh/pretix/pretix
Reinventing ticket presales, one bit at a time.
Reinventing ticket presales, one ticket at a time.
Project status & release cycle
------------------------------

View File

@@ -22,9 +22,11 @@ http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
add_header X-Content-Type-Options nosniff;
access_log /var/log/nginx/access.log private;
error_log /var/log/nginx/error.log;
add_header Referrer-Policy same-origin;
gzip on;
gzip_disable "msie6";
@@ -57,7 +59,7 @@ http {
return 404;
}
location /static/ {
alias /static/;
alias /pretix/src/pretix/static.dist/;
access_log off;
expires 365d;
add_header Cache-Control "public";

View File

@@ -1,5 +1,4 @@
from pretix.settings import *
LOGGING['handlers']['mail_admins']['include_html'] = True
STATIC_ROOT = '/static'
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

160
doc/_templates/index.html vendored Normal file
View File

@@ -0,0 +1,160 @@
{% extends "layout.html" %}
{% set title = 'Overview' %}
{% block body %}
<h1>Welcome to pretix' documentation!</h1>
<p>
We work hard to make this website contain all information that you need to use, run, understand, and improve
pretix. Of course, this documentation will never be perfect or complete, but if there is anything unclear
or anything specific that you miss here, that's a bug and we'd be happy if you'd
<a href="https://github.com/pretix/pretix/issues/new">let us know</a>.
</p>
<h2>Documentation structure</h2>
<div class="sectionbox">
<div class="icon">
<a href="user/index.html">
<span class="fa fa-user fa-fw"></span>
</a>
</div>
<div class="text">
<a href="user/index.html">
<strong>User Guide</strong>
</a>
<p>Go here to find information on how to configure and use pretix as an event organizer.</p>
</div>
</div>
<div class="sectionbox">
<div class="icon">
<a href="admin/index.html">
<span class="fa fa-server fa-fw"></span>
</a>
</div>
<div class="text">
<a href="admin/index.html">
<strong>Administrator docs</strong>
</a>
<p>Find out how to install pretix on your own server and how to maintain an installation of pretix.</p>
</div>
</div>
<div class="clearfix"></div>
<div class="sectionbox">
<div class="icon">
<a href="api/index.html">
<span class="fa fa-plug fa-fw"></span>
</a>
</div>
<div class="text">
<a href="api/index.html">
<strong>REST API</strong>
</a>
<p>
Documentation and reference of the RESTful API exposed by pretix for interaction with external
components.
</p>
</div>
</div>
<div class="sectionbox">
<div class="icon">
<a href="development/index.html">
<span class="fa fa-wrench fa-fw"></span>
</a>
</div>
<div class="text">
<a href="development/index.html">
<strong>Developer docs</strong>
</a>
<p>Get information on how to contribute to pretix itself and how to build plugins that interact with
pretix.</p>
</div>
</div>
<div class="clearfix"></div>
<div class="sectionbox">
<div class="icon">
<a href="plugins/index.html">
<span class="fa fa-puzzle-piece fa-fw"></span>
</a>
</div>
<div class="text">
<a href="plugins/index.html">
<strong>Plugin docs</strong>
</a>
<p>Documentation and details on plugins that ship with pretix or are officially supported.</p>
</div>
</div>
<div class="sectionbox">
<div class="icon">
<a href="contents.html">
<span class="fa fa-list fa-fw"></span>
</a>
</div>
<div class="text">
<a href="contents.html">
<strong>Table of contents</strong>
</a>
<p>Detailled overview of everything contained in this documentation.</p>
</div>
</div>
<div class="clearfix"></div>
<h2>Useful links</h2>
<div class="sectionbox">
<div class="icon">
<a href="https://pretix.eu" target="_blank">
<span class="fa fa-globe fa-fw"></span>
</a>
</div>
<div class="text">
<a href="https://pretix.eu" target="_blank">
<strong>Project website</strong>
</a>
<p>pretix.eu is the central entry-point to the pretix project and also the home of the commercial hosting
service available.</p>
</div>
</div>
<div class="sectionbox">
<div class="icon">
<a href="https://github.com/pretix/pretix" target="_blank">
<span class="fa fa-github fa-fw"></span>
</a>
</div>
<div class="text">
<a href="https://github.com/pretix/pretix" target="_blank">
<strong>GitHub repository</strong>
</a>
<p>Our main source code repository contains all code that is part of pretix as well as some plugins and the
source for this documentation.</p>
</div>
</div>
<div class="clearfix"></div>
<div class="sectionbox">
<div class="icon">
<a href="https://pretix.eu/about/en/blog/" target="_blank">
<span class="fa fa-newspaper-o fa-fw"></span>
</a>
</div>
<div class="text">
<a href="https://pretix.eu/about/en/blog/" target="_blank">
<strong>Project blog</strong>
</a>
<p>This important information source contains all release notes for all stable releases of pretix as well as
general news on pretix as a project.</p>
</div>
</div>
<div class="sectionbox">
<div class="icon">
<a href="https://twitter.com/pretixeu" target="_blank">
<span class="fa fa-twitter fa-fw"></span>
</a>
</div>
<div class="text">
<a href="https://twitter.com/pretixeu" target="_blank">
<strong>Twitter</strong>
</a>
<p>Keep in touch and stay up to date by following our project account on Twitter.</p>
</div>
</div>
<div class="clearfix"></div>
{% endblock %}

16
doc/_themes/pretix_theme/__init__.py vendored Normal file
View File

@@ -0,0 +1,16 @@
"""pretix sphinx theme.
Based on sphinx-rtd-theme
Based on https://github.com/ryan-roemer/sphinx-bootstrap-theme.
"""
import os
__version__ = '0.1.0'
__version_full__ = __version__
def get_html_theme_path():
"""Return list of HTML theme paths."""
cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
return cur_dir

View File

@@ -0,0 +1,82 @@
{# Support for Sphinx 1.3+ page_source_suffix, but don't break old builds. #}
{% if page_source_suffix %}
{% set suffix = page_source_suffix %}
{% else %}
{% set suffix = source_suffix %}
{% endif %}
{% if meta is defined and meta is not none %}
{% set check_meta = True %}
{% else %}
{% set check_meta = False %}
{% endif %}
{% if check_meta and 'github_url' in meta %}
{% set display_github = True %}
{% endif %}
{% if check_meta and 'bitbucket_url' in meta %}
{% set display_bitbucket = True %}
{% endif %}
{% if check_meta and 'gitlab_url' in meta %}
{% set display_gitlab = True %}
{% endif %}
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
{% block breadcrumbs %}
<li><a href="{{ pathto(master_doc) }}">{{ _('Docs') }}</a> &raquo;</li>
{% for doc in parents %}
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
{% endfor %}
<li>{{ title }}</li>
{% endblock %}
{% block breadcrumbs_aside %}
<li class="wy-breadcrumbs-aside">
{% if pagename != "search" %}
{% if display_github %}
{% if check_meta and 'github_url' in meta %}
<!-- User defined GitHub URL -->
<a href="{{ meta['github_url'] }}" class="fa fa-github"> {{ _('Edit on GitHub') }}</a>
{% else %}
<a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-github"> {{ _('Edit on GitHub') }}</a>
{% endif %}
{% elif display_bitbucket %}
{% if check_meta and 'bitbucket_url' in meta %}
<!-- User defined Bitbucket URL -->
<a href="{{ meta['bitbucket_url'] }}" class="fa fa-bitbucket"> {{ _('Edit on Bitbucket') }}</a>
{% else %}
<a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-bitbucket"> {{ _('Edit on Bitbucket') }}</a>
{% endif %}
{% elif display_gitlab %}
{% if check_meta and 'gitlab_url' in meta %}
<!-- User defined GitLab URL -->
<a href="{{ meta['gitlab_url'] }}" class="fa fa-gitlab"> {{ _('Edit on GitLab') }}</a>
{% else %}
<a href="https://{{ gitlab_host|default("gitlab.com") }}/{{ gitlab_user }}/{{ gitlab_repo }}/blob/{{ gitlab_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-gitlab"> {{ _('Edit on GitLab') }}</a>
{% endif %}
{% elif show_source and source_url_prefix %}
<a href="{{ source_url_prefix }}{{ pagename }}{{ suffix }}">{{ _('View page source') }}</a>
{% elif show_source and has_source and sourcename %}
<a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> {{ _('View page source') }}</a>
{% endif %}
{% endif %}
</li>
{% endblock %}
</ul>
{% if (theme_prev_next_buttons_location == 'top' or theme_prev_next_buttons_location == 'both') and (next or prev) %}
<div class="rst-breadcrumbs-buttons" role="navigation" aria-label="breadcrumb navigation">
{% if next %}
<a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
{% endif %}
{% if prev %}
<a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
{% endif %}
</div>
{% endif %}
<hr/>
</div>

52
doc/_themes/pretix_theme/footer.html vendored Normal file
View File

@@ -0,0 +1,52 @@
<footer>
{% if (theme_prev_next_buttons_location == 'bottom' or theme_prev_next_buttons_location == 'both') and (next or prev) %}
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
{% if next %}
<a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n" rel="next">{{ _('Next') }} <span class="fa fa-arrow-circle-right"></span></a>
{% endif %}
{% if prev %}
<a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> {{ _('Previous') }}</a>
{% endif %}
</div>
{% endif %}
<hr/>
<div role="contentinfo">
<p>
{%- if show_copyright %}
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- endif %}
{%- if build_id and build_url %}
{% trans build_url=build_url, build_id=build_id %}
<span class="build">
Build
<a href="{{ build_url }}">{{ build_id }}</a>.
</span>
{% endtrans %}
{%- elif commit %}
{% trans commit=commit %}
<span class="commit">
Revision <code>{{ commit }}</code>.
</span>
{% endtrans %}
{%- elif last_updated %}
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
{%- endif %}
</p>
</div>
{%- if show_sphinx %}
<small>{% trans %}Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a theme that is based on a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}.</small>
{%- endif %}
{%- block extrafooter %} {% endblock %}
</footer>

211
doc/_themes/pretix_theme/layout.html vendored Normal file
View File

@@ -0,0 +1,211 @@
{# TEMPLATE VAR SETTINGS #}
{%- set url_root = pathto('', 1) %}
{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
{%- if not embedded and docstitle %}
{%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
{%- else %}
{%- set titlesuffix = "" %}
{%- endif %}
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
{{ metatags }}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% block htmltitle %}
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
{% endblock %}
{# FAVICON #}
{% if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{% endif %}
{# CANONICAL URL #}
{% if theme_canonical_url %}
<link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html"/>
{% endif %}
{# CSS #}
{# OPENSEARCH #}
{% if not embedded %}
{% if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml" title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}" href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{% endif %}
{% endif %}
{# RTD hosts this file, so just load on non RTD builds #}
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
{% for cssfile in css_files %}
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
{% endfor %}
{% for cssfile in extra_css_files %}
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
{% endfor %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}"
href="{{ pathto('about') }}"/>
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}"
href="{{ pathto('genindex') }}"/>
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}"/>
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}"/>
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}"/>
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"/>
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"/>
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"/>
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
{# Keep modernizr in head - http://modernizr.com/docs/#installing #}
<script src="{{ pathto('_static/js/modernizr.min.js', 1) }}"></script>
</head>
<body class="wy-body-for-nav" role="document">
{% block extrabody %} {% endblock %}
<div class="wy-grid-for-nav">
{# SIDE NAV, TOGGLES ON MOBILE #}
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
{% block sidebartitle %}
{% if logo and theme_logo_only %}
<a href="{{ pathto('index') }}">
{% else %}
<a href="{{ pathto('index') }}" class="icon icon-home"> {{ project }}
{% endif %}
{% if logo %}
{# Not strictly valid HTML, but it's the only way to display/scale it properly, without weird scripting or heaps of work #}
<img src="{{ pathto('_static/' + logo, 1) }}" class="logo" />
{% endif %}
</a>
{% include "searchbox.html" %}
{% endblock %}
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
{% block menu %}
{#
The singlehtml builder doesn't handle this toctree call when the
toctree is empty. Skip building this for now.
#}
{% if 'singlehtml' not in builder %}
{% set global_toc = toctree(maxdepth=theme_navigation_depth|int, collapse=theme_collapse_navigation, includehidden=True) %}
{% endif %}
{% if global_toc %}
{{ global_toc }}
{% else %}
<!-- Local TOC -->
<div class="local-toc">{{ toc }}</div>
{% endif %}
{% endblock %}
</div>
{% if theme_display_version %}
{%- set nav_version = version %}
{% if READTHEDOCS and current_version %}
{%- set nav_version = current_version %}
{% endif %}
{% if nav_version %}
<div class="version">
{{ nav_version }}
</div>
{% endif %}
{% endif %}
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
{# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
{% block mobile_nav %}
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="{{ pathto('index') }}">{{ project }}</a>
{% endblock %}
</nav>
{# PAGE CONTENT #}
<div class="wy-nav-content">
<div class="rst-content">
{% include "breadcrumbs.html" %}
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
{% block body %}{% endblock %}
</div>
<div class="articleComments">
{% block comments %}{% endblock %}
</div>
</div>
{% include "footer.html" %}
</div>
</div>
</section>
</div>
{% include "versions.html" %}
{% if not embedded %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'{{ url_root }}',
VERSION:'{{ release|e }}',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
HAS_SOURCE: {{ has_source|lower }},
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{% endif %}
{# RTD hosts this file, so just load on non RTD builds #}
{% if not READTHEDOCS %}
<script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
{% endif %}
{# STICKY NAVIGATION #}
{% if theme_sticky_navigation %}
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
});
</script>
{% endif %}
{%- block footer %} {% endblock %}
</body>
</html>

209
doc/_themes/pretix_theme/layout_old.html vendored Normal file
View File

@@ -0,0 +1,209 @@
{#
basic/layout.html
~~~~~~~~~~~~~~~~~
Master layout template for Sphinx themes.
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- block doctype -%}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
{%- endblock %}
{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and
(sidebars != []) %}
{%- set url_root = pathto('', 1) %}
{# XXX necessary? #}
{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
{%- if not embedded and docstitle %}
{%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
{%- else %}
{%- set titlesuffix = "" %}
{%- endif %}
{%- macro relbar() %}
<div class="related">
<h3>{{ _('Navigation') }}</h3>
<ul>
{%- for rellink in rellinks %}
<li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
{%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
{%- endfor %}
{%- block rootrellink %}
<li><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}</li>
{%- endblock %}
{%- for parent in parents %}
<li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
{%- endfor %}
{%- block relbaritems %} {% endblock %}
</ul>
</div>
{%- endmacro %}
{%- macro sidebar() %}
{%- if render_sidebar %}
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
{%- if logo %}
<p class="logo"><a href="{{ pathto(master_doc) }}">
<img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
</a></p>
{%- endif %}
{%- endblock %}
{%- if sidebars != None %}
{#- new style sidebar: explicitly include/exclude templates #}
{%- for sidebartemplate in sidebars %}
{%- include sidebartemplate %}
{%- endfor %}
{%- else %}
{#- old style sidebars: using blocks -- should be deprecated #}
{%- block sidebartoc %}
{%- include "localtoc.html" %}
{%- endblock %}
{%- block sidebarrel %}
{%- include "relations.html" %}
{%- endblock %}
{%- block sidebarsourcelink %}
{%- include "sourcelink.html" %}
{%- endblock %}
{%- if customsidebar %}
{%- include customsidebar %}
{%- endif %}
{%- block sidebarsearch %}
{%- include "searchbox.html" %}
{%- endblock %}
{%- endif %}
</div>
</div>
{%- endif %}
{%- endmacro %}
{%- macro script() %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ url_root }}',
VERSION: '{{ release|e }}',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
HAS_SOURCE: {{ has_source|lower }},
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{%- endmacro %}
{%- macro css() %}
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
{%- for cssfile in css_files %}
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
{%- endfor %}
{%- endmacro %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset={{ encoding }}" />
{{ metatags }}
{%- block htmltitle %}
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
{%- endblock %}
{{ css() }}
{%- if not embedded %}
{{ script() }}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
{%- if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{%- endif %}
{%- if theme_canonical_url %}
<link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
<body>
{%- block header %}{% endblock %}
{%- block relbar1 %}{{ relbar() }}{% endblock %}
{%- block content %}
{%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
<div class="document">
{%- block document %}
<div class="documentwrapper">
{%- if render_sidebar %}
<div class="bodywrapper">
{%- endif %}
<div class="body">
{% block body %} {% endblock %}
</div>
{%- if render_sidebar %}
</div>
{%- endif %}
</div>
{%- endblock %}
{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
<div class="clearer"></div>
</div>
{%- endblock %}
{%- block relbar2 %}{{ relbar() }}{% endblock %}
{%- block footer %}
<div class="footer">
{%- if show_copyright %}
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- endif %}
{%- if last_updated %}
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
{%- endif %}
{%- if show_sphinx %}
{% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
{%- endif %}
</div>
<p>asdf asdf asdf asdf 22</p>
{%- endblock %}
</body>
</html>

50
doc/_themes/pretix_theme/search.html vendored Normal file
View File

@@ -0,0 +1,50 @@
{#
basic/search.html
~~~~~~~~~~~~~~~~~
Template for the search page.
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- extends "layout.html" %}
{% set title = _('Search') %}
{% set script_files = script_files + ['_static/searchtools.js'] %}
{% block footer %}
<script type="text/javascript">
jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
</script>
{# this is used when loading the search index using $.ajax fails,
such as on Chrome for documents on localhost #}
<script type="text/javascript" id="searchindexloader"></script>
{{ super() }}
{% endblock %}
{% block body %}
<noscript>
<div id="fallback" class="admonition warning">
<p class="last">
{% trans %}Please activate JavaScript to enable the search
functionality.{% endtrans %}
</p>
</div>
</noscript>
{% if search_performed %}
<h2>{{ _('Search Results') }}</h2>
{% if not search_results %}
<p>{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}</p>
{% endif %}
{% endif %}
<div id="search-results">
{% if search_results %}
<ul>
{% for href, caption, context in search_results %}
<li>
<a href="{{ pathto(item.href) }}">{{ caption }}</a>
<p class="context">{{ context|e }}</p>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,9 @@
{%- if builder != 'singlehtml' %}
<div role="search">
<form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" placeholder="{{ _('Search docs') }}" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
{%- endif %}

View File

@@ -0,0 +1,2 @@
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
/*# sourceMappingURL=badge_only.css.map */

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,169 @@
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"sphinx-rtd-theme":[function(require,module,exports){
var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
// Sphinx theme nav state
function ThemeNav () {
var nav = {
navBar: null,
win: null,
winScroll: false,
winResize: false,
linkScroll: false,
winPosition: 0,
winHeight: null,
docHeight: null,
isRunning: false
};
nav.enable = function () {
var self = this;
if (!self.isRunning) {
self.isRunning = true;
jQuery(function ($) {
self.init($);
self.reset();
self.win.on('hashchange', self.reset);
// Set scroll monitor
self.win.on('scroll', function () {
if (!self.linkScroll) {
self.winScroll = true;
}
});
setInterval(function () { if (self.winScroll) self.onScroll(); }, 25);
// Set resize monitor
self.win.on('resize', function () {
self.winResize = true;
});
setInterval(function () { if (self.winResize) self.onResize(); }, 25);
self.onResize();
});
};
};
nav.init = function ($) {
var doc = $(document),
self = this;
this.navBar = $('div.wy-side-scroll:first');
this.win = $(window);
// Set up javascript UX bits
$(document)
// Shift nav in mobile when clicking the menu.
.on('click', "[data-toggle='wy-nav-top']", function() {
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
})
// Nav menu link click operations
.on('click', ".wy-menu-vertical .current ul li a", function() {
var target = $(this);
// Close menu when you click a link.
$("[data-toggle='wy-nav-shift']").removeClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
// Handle dynamic display of l3 and l4 nav lists
self.toggleCurrent(target);
self.hashChange();
})
.on('click', "[data-toggle='rst-current-version']", function() {
$("[data-toggle='rst-versions']").toggleClass("shift-up");
})
// Make tables responsive
$("table.docutils:not(.field-list)")
.wrap("<div class='wy-table-responsive'></div>");
// Add expand links to all parents of nested ul
$('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
var link = $(this);
expand = $('<span class="toctree-expand"></span>');
expand.on('click', function (ev) {
self.toggleCurrent(link);
ev.stopPropagation();
return false;
});
link.prepend(expand);
});
};
nav.reset = function () {
// Get anchor from URL and open up nested nav
var anchor = encodeURI(window.location.hash);
if (anchor) {
try {
var link = $('.wy-menu-vertical')
.find('[href="' + anchor + '"]');
// If we didn't find a link, it may be because we clicked on
// something that is not in the sidebar (eg: when using
// sphinxcontrib.httpdomain it generates headerlinks but those
// aren't picked up and placed in the toctree). So let's find
// the closest header in the document and try with that one.
if (link.length === 0) {
var doc_link = $('.document a[href="' + anchor + '"]');
var closest_section = doc_link.closest('div.section');
// Try again with the closest section entry.
link = $('.wy-menu-vertical')
.find('[href="#' + closest_section.attr("id") + '"]');
}
$('.wy-menu-vertical li.toctree-l1 li.current')
.removeClass('current');
link.closest('li.toctree-l2').addClass('current');
link.closest('li.toctree-l3').addClass('current');
link.closest('li.toctree-l4').addClass('current');
}
catch (err) {
console.log("Error expanding nav for anchor", err);
}
}
};
nav.onScroll = function () {
this.winScroll = false;
var newWinPosition = this.win.scrollTop(),
winBottom = newWinPosition + this.winHeight,
navPosition = this.navBar.scrollTop(),
newNavPosition = navPosition + (newWinPosition - this.winPosition);
if (newWinPosition < 0 || winBottom > this.docHeight) {
return;
}
this.navBar.scrollTop(newNavPosition);
this.winPosition = newWinPosition;
};
nav.onResize = function () {
this.winResize = false;
this.winHeight = this.win.height();
this.docHeight = $(document).height();
};
nav.hashChange = function () {
this.linkScroll = true;
this.win.one('hashchange', function () {
this.linkScroll = false;
});
};
nav.toggleCurrent = function (elem) {
var parent_li = elem.closest('li');
parent_li.siblings('li.current').removeClass('current');
parent_li.siblings().find('li.current').removeClass('current');
parent_li.find('> ul li.current').removeClass('current');
parent_li.toggleClass('current');
}
return nav;
};
module.exports.ThemeNav = ThemeNav();
if (typeof(window) != 'undefined') {
window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };
}
},{"jquery":"jquery"}]},{},["sphinx-rtd-theme"]);

14
doc/_themes/pretix_theme/theme.conf vendored Normal file
View File

@@ -0,0 +1,14 @@
[theme]
inherit = basic
stylesheet = css/pretix.css
[options]
typekit_id = hiw1hhg
analytics_id =
sticky_navigation = False
logo_only =
collapse_navigation = False
display_version = True
navigation_depth = 4
prev_next_buttons_location = bottom
canonical_url =

37
doc/_themes/pretix_theme/versions.html vendored Normal file
View File

@@ -0,0 +1,37 @@
{% if READTHEDOCS %}
{# Add rst-badge after rst-versions for small badge style. #}
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Read the Docs</span>
v: {{ current_version }}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<dl>
<dt>{{ _('Versions') }}</dt>
{% for slug, url in versions %}
<dd><a href="{{ url }}">{{ slug }}</a></dd>
{% endfor %}
</dl>
<dl>
<dt>{{ _('Downloads') }}</dt>
{% for type, url in downloads %}
<dd><a href="{{ url }}">{{ type }}</a></dd>
{% endfor %}
</dl>
<dl>
<dt>{{ _('On Read the Docs') }}</dt>
<dd>
<a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">{{ _('Project Home') }}</a>
</dd>
<dd>
<a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">{{ _('Builds') }}</a>
</dd>
</dl>
<hr/>
{% trans %}Free document hosting provided by <a href="http://www.readthedocs.org">Read the Docs</a>.{% endtrans %}
</div>
</div>
{% endif %}

View File

@@ -10,9 +10,10 @@ at the following locations. It will try to read the file from the specified path
the following order. The file that is found *last* will override the settings from
the files found before.
1. ``/etc/pretix/pretix.cfg``
2. ``~/.pretix.cfg``
3. ``pretix.cfg`` in the current working directory
1. ``PREFIX_CONFIG_FILE`` environment variable
2. ``/etc/pretix/pretix.cfg``
3. ``~/.pretix.cfg``
4. ``pretix.cfg`` in the current working directory
The file is expected to be in the INI format as specified in the `Python documentation`_.
@@ -59,6 +60,14 @@ Example::
``password_reset``
Enables or disables password reset. Defaults to ``on``.
``long_sessions``
Enables or disables the "keep me logged in" button. Defaults to ``on``.
``ecb_rates``
By default, pretix periodically downloads a XML file from the European Central Bank to retrieve exchange rates
that are used to print tax amounts in the customer currency on invoices for some currencies. Set to ``off`` to
disable this feature. Defaults to ``on``.
Locale settings
---------------
@@ -102,6 +111,10 @@ Example::
``user``, ``password``, ``host``, ``port``
Connection details for the database connection. Empty by default.
``galera``
Indicates if the database backend is a MySQL/MariaDB Galera cluster and
turns on some optimizations/special case handlers. Default: ``False``
URLs
----
@@ -151,20 +164,17 @@ Example::
``admins``
Comma-separated list of email addresses that should receive a report about every error code 500 thrown by pretix.
.. _`django-settings`:
Django settings
---------------
Example::
[django]
hosts=localhost
secret=j1kjps5a5&4ilpn912s7a1!e2h!duz^i3&idu@_907s$wrz@x-
debug=off
``hosts``
Comma-separated list of allowed host names for this installation.
Default: ``localhost``
``secret``
The secret to be used by Django for signing and verification purposes. If this
setting is not provided, pretix will generate a random secret on the first start
@@ -175,6 +185,11 @@ Example::
.. WARNING:: Never set this to ``True`` in production!
``profile``
Enable code profiling for a random subset of requests. Disabled by default, see
:ref:`perf-monitoring` for details.
.. _`metrics-settings`:
Metrics
-------

View File

@@ -1,12 +1,13 @@
.. _`admindocs`:
Administrator documentation
===========================
This documentation is for everyone who wants to install pretix on a server.
Contents:
.. toctree::
:maxdepth: 2
installation/index
config
maintainance

View File

@@ -141,9 +141,9 @@ See :ref:`email configuration <mail-settings>` to learn more about configuring m
Docker image and service
------------------------
First of all, download the latest pretix image by running::
First of all, download the latest stable pretix image by running::
$ docker pull pretix/standalone:latest
$ docker pull pretix/standalone:stable
We recommend starting the docker container using systemd to make sure it runs correctly after a reboot. Create a file
named ``/etc/systemd/system/pretix.service`` with the following content::
@@ -222,6 +222,8 @@ Yay, you are done! You should now be able to reach pretix at https://pretix.your
*admin@localhost* with a password of *admin*. Don't forget to change that password! Create an organizer first, then
create an event and start selling tickets!
You should probably read :ref:`maintainance` next.
Updates
-------
@@ -229,11 +231,13 @@ Updates
Updates are fairly simple, but require at least a short downtime::
# docker pull pretix/standalone
# docker pull pretix/standalone:stable
# systemctl restart pretix.service
# docker exec -it pretix.service pretix upgrade
Restarting the service can take a few seconds, especially if the update requires changes to the database.
Replace ``stable`` above with a specific version number like ``1.0`` or with ``latest`` for the development
version, if you want to.
Install a plugin
----------------
@@ -242,11 +246,11 @@ To install a plugin, you need to build your own docker image. To do so, create a
named ``Dockerfile`` in it. The Dockerfile could look like this (replace ``pretix-passbook`` with the plugins of your
choice)::
FROM pretix/standalone
FROM pretix/standalone:stable
USER root
RUN pip3 install pretix-passbook
USER pretixuser
RUN make production
RUN cd /pretix/src && make production
Then, go to that directory and build the image::

View File

@@ -5,7 +5,7 @@ General remarks
Requirements
------------
To use pretix, you wull need the following things:
To use pretix, you will need the following things:
* **pretix** and the python packages it depends on

View File

@@ -190,7 +190,7 @@ Cronjob
You need to set up a cronjob that runs the management command ``runperiodic``. The exact interval is not important
but should be something between every minute and every hour. You could for example configure cron like this::
15,45 * * * * export PATH=/var/pretix/venv/bin:$PATH && cd /var/pretix/source/src && python -m pretix runperiodic
15,45 * * * * export PATH=/var/pretix/venv/bin:$PATH && cd /var/pretix && python -m pretix runperiodic
The cronjob should run as the ``pretix`` user (``crontab -e -u pretix``).
@@ -213,6 +213,9 @@ The following snippet is an example on how to configure a nginx proxy for pretix
ssl_certificate /path/to/cert.chain.pem;
ssl_certificate_key /path/to/key.pem;
add_header Referrer-Options same-origin;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://localhost:8345/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -236,13 +239,15 @@ The following snippet is an example on how to configure a nginx proxy for pretix
}
location /static/ {
alias /var/pretix/source/src/pretix/static.dist/;
alias /var/pretix/venv/lib/python3.5/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
above with your python version.
We recommend reading about setting `strong encryption settings`_ for your web server.
@@ -253,6 +258,8 @@ Yay, you are done! You should now be able to reach pretix at https://pretix.your
*admin@localhost* with a password of *admin*. Don't forget to change that password! Create an organizer first, then
create an event and start selling tickets!
You should probably read :ref:`maintainance` next.
Updates
-------

View File

@@ -0,0 +1,99 @@
.. highlight:: ini
.. _`maintainance`:
Backups and Monitoring
======================
If you host your own pretix instance, you also need to care about the availability
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
-------
There are essentially two things which you should create backups of:
Database
Your SQL database (MySQL or PostgreSQL). This is critical and you should **absolutely
always create automatic backups of your database**. There are tons of tutorials on the
internet on how to do this, and the exact process depends on the choice of your database.
For MySQL, see ``mysqldump`` and for PostgreSQL, see the ``pg_dump`` tool. You probably
want to create a cronjob that does the backups for you on a regular schedule.
Data directory
The data directory of your pretix configuration might contain some things that you should
back up. If you did not specify a secret in your config file, back up the ``.secret`` text
file in the data directory. If you lose your secret, all currently active user sessions,
password reset links and similar things will be rendered invalid. Also, you probably want
to backup the ``media`` subdirectory of the data directory which contains all user-uploaded
and generated files. This includes files you could in theory regenerate (ticket downloads)
but also files that you might be legally required to keep (invoice PDFs) or files that you
would need to re-upload (event logos, product pictures, etc.). It is up to you if you
create regular backups of this data, but we strongly advise you to do so. You can create
backups e.g. using ``rsync``. There is a lot of information on the internet on how to create
backups of folders on a Linux machine.
There is no need to create backups of the redis database, if you use it. We only use it for
non-critical, temporary or cached data.
Uptime monitoring
-----------------
To monitor whether your pretix instance is running, you can issue a GET request to
``https://pretix.mydomain.com/healthcheck/``. This endpoint tests if the connection to the
database, to the configured cache and to redis (if used) is working correctly. If everything
appears to work fine, an empty response with status code ``200`` is returned.
If there is a problem, a status code in the ``5xx`` range will be returned.
.. _`perf-monitoring`:
Performance monitoring
----------------------
If you want to generate detailed performance statistics of your pretix installation, there is an
endpoint at ``https://pretix.mydomain.com/metrics`` (no slash at the end) which returns a
number of values in the text format understood by monitoring tools like Prometheus_. This data
is only collected and exposed if you enable it in the :ref:`metrics-settings` section of your
pretix configuration. You can also configure basic auth credentials there to protect your
statistics against unauthorized access. The data is temporarily collected in redis, so the
performance impact of this feature depends on the connection to your redis database.
Currently, mostly response times of HTTP requests and background tasks are exposed.
If you want to go even further, you can set the ``profile`` option in the :ref:`django-settings`
section to a value between 0 and 1. If you set it for example to 0.1, then 10% of your requests
(randomly selected) will be run with cProfile_ activated. The profiling results will be saved
to your data directory. As this might impact performance significantly and writes a lot of data
to disk, we recommend to only enable it for a small number of requests -- and only if you are
really interested in the results.
Available metrics
^^^^^^^^^^^^^^^^^
The metrics available in pretix follow the standard `metric types`_ from the Prometheus world.
Currently, the following metrics are exported:
pretix_view_requests_total
Counter. Counts requests to Django views, labeled with the resolved ``url_name``, the used
HTTP ``method`` and the ``status_code`` returned.
pretix_view_durations_seconds
Histogram. Measures duration of requests to Django views, labeled with the resolved
``url_name``, the used HTTP ``method`` and the ``status_code`` returned.
pretix_task_runs_total
Counter. Counts executions of background tasks, labeled with the ``task_name`` and the
``status``. The latter can be ``success``, ``error`` or ``expected-error``.
pretix_task_duration_seconds
Histogram. Measures duration of successful background task executions, labeled with the
``task_name``.
pretix_model_instances
Gauge. Measures number of instances of a certain model within the database, labeled with
the ``model`` name.
.. _metric types: https://prometheus.io/docs/concepts/metric_types/
.. _Prometheus: https://prometheus.io/
.. _cProfile: https://docs.python.org/3/library/profile.html

149
doc/api/fundamentals.rst Normal file
View File

@@ -0,0 +1,149 @@
Basic concepts
==============
This page describes basic concepts and definition that you need to know to interact
with pretix' REST API, such as authentication, pagination and similar definitions.
.. _`rest-auth`:
Obtaining an API token
----------------------
To authenticate your API requests, you need to obtain an API token. You can create a
token in the pretix web interface on the level of organizer teams. Create a new team
or choose an existing team that has the level of permissions the token should have and
create a new token using the form below the list of team members:
.. image:: img/token_form.png
:class: screenshot
You can enter a description for the token to distinguish from other tokens later on.
Once you click "Add", you will be provided with an API token in the success message.
Copy this token, as you won't be able to retrieve it again.
.. image:: img/token_success.png
:class: screenshot
Authentication
--------------
You need to include the API token with every request to pretix' API in the ``Authorization`` header
like the following:
.. sourcecode:: http
:emphasize-lines: 3
GET /api/v1/organizers/ HTTP/1.1
Host: pretix.eu
Authorization: Token e1l6gq2ye72thbwkacj7jbri7a7tvxe614ojv8ybureain92ocub46t5gab5966k
.. note:: The API currently also supports authentication via browser sessions, i.e. the
same way that you authenticate with pretix when using the browser interface.
Using this type of authentication is *not* officially supported for use by
third-party clients and might change or be removed at any time. We plan on
adding OAuth2 support in the future for user-level authentication. If you want
to use session authentication, be sure to comply with Django's `CSRF policies`_.
Compatibility
-------------
We currently see pretix' API as a beta-stage feature. We therefore do not give any guarantees
for compatibility between feature releases of pretix (such as 1.5 and 1.6). However, as always,
we try not to break things when we don't need to. Any backwards-incompatible changes will be
prominently noted in the release notes.
We treat the following types of changes as *backwards-compatible* so we ask you to make sure
that your clients can deal with them properly:
* Support of new API endpoints
* Support of new HTTP methods for a given API endpoint
* Support of new query parameters for a given API endpoint
* New fields contained in API responses
We treat the following types of changes as *backwards-incompatible*:
* Type changes of fields in API responses
* New required input fields for an API endpoint
* New required type for input fields of an API endpoint
* Removal of endpoints, API methods or fields
Pagination
----------
Most lists of objects returned by pretix' API will be paginated. The response will take
the form of:
.. sourcecode:: javascript
{
"count": 117,
"next": "https://pretix.eu/api/v1/organizers/?page=2",
"previous": null,
"results": [],
}
As you can see, the response contains the total number of results in the field ``count``.
The fields ``next`` and ``previous`` contain links to the next and previous page of results,
respectively, or ``null`` if there is no such page. You can use those URLs to retrieve the
respective page.
The field ``results`` contains a list of objects representing the first results. For most
objects, every page contains 50 results.
Errors
------
Error responses (of type 400-499) are returned in one of the following forms, depending on
the type of error. General errors look like:
.. sourcecode:: http
HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 42
{"detail": "Method 'DELETE' not allowed."}
Field specific input errors include the name of the offending fields as keys in the response:
.. sourcecode:: http
HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 94
{"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}
Data types
----------
All structured API responses are returned in JSON format using standard JSON data types such
as integers, floating point numbers, strings, lists, objects and booleans. Most fields can
be ``null`` as well.
The following table shows some data types that have no native JSON representation and how
we serialize them to JSON.
===================== ============================ ===================================
Internal pretix type JSON representation Examples
===================== ============================ ===================================
Datetime String in ISO 8601 format ``"2017-12-27T10:00:00Z"``
with timezone (normally UTC) ``"2017-12-27T10:00:00.596934Z"``,
``"2017-12-27T10:00:00+02:00"``
Date String in ISO 8601 format ``2017-12-27``
Multi-lingual string Object of strings ``{"en": "red", "de": "rot", "de_Informal": "rot"}``
Money String with decimal number ``"23.42"``
Currency String with ISO 4217 code ``"EUR"``, ``"USD"``
===================== ============================ ===================================
Query parameters
^^^^^^^^^^^^^^^^
Most list endpoints allow a filtering of the results using query parameters. In this case, booleans should be passed
as the string values ``true`` and ``false``.
If the ``ordering`` parameter is documented for a resource, you can use it to sort the result set by one of the allowed
fields. Prepend a ``-`` to the field name to reverse the sort order.
.. _CSRF policies: https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax

BIN
doc/api/img/token_form.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

17
doc/api/index.rst Normal file
View File

@@ -0,0 +1,17 @@
.. _`rest-api`:
REST API
========
This part of the documentation contains information about the REST-style API
exposed by pretix since version 1.5 that can be used by third-party programs
to interact with pretix and its data structures.
Currently, the API provides mostly read-only capabilities, but it will be extended
in functionality over time.
.. toctree::
:maxdepth: 2
fundamentals
resources/index

View File

@@ -0,0 +1,108 @@
Item categories
===============
Resource description
--------------------
Categories provide grouping for items (better known as products).
The category resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the category
name multi-lingual string The category's visible name
description multi-lingual string A public description (might include markdown, can
be ``null``)
position integer An integer, used for sorting the categories
is_addon boolean If ``True``, items within this category are not on sale
on their own but the category provides a source for
defining add-ons for other products.
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/categories/
Returns a list of all categories within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/categories/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": {"en": "Tickets"},
"description": {"en": "Tickets are what you need to get in."},
"position": 1,
"is_addon": false
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query boolean is_addon: If set to ``true`` or ``false``, only categories with this value for the field ``is_addon`` will be
returned.
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``.
Default: ``position``
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/categories/(id)/
Returns information on one category, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/categories/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: text/javascript
{
"id": 1,
"name": {"en": "Tickets"},
"description": {"en": "Tickets are what you need to get in."},
"position": 1,
"is_addon": false
}
: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 category to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.

View File

@@ -0,0 +1,128 @@
Events
======
Resource description
--------------------
The event resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
name multi-lingual string The event's full name
slug string A short form of the name, used e.g. in URLs.
live boolean If ``true``, the event ticket shop is publicly
available.
currency string The currency this event is handled in.
date_from datetime The event's start date
date_to datetime The event's end date (or ``null``)
date_admission datetime The event's admission date (or ``null``)
is_public boolean If ``true``, the event shows up in places like the
organizer's public list of events
presale_start datetime The date at which the ticket shop opens (or ``null``)
presale_end datetime The date at which the ticket shop closes (or ``null``)
location multi-lingual string The event location (or ``null``)
has_subevents boolean ``True`` if the event series feature is active for this
event
meta_data dict Values set for organizer-specific meta data parameters.
===================================== ========================== =======================================================
.. versionchanged:: 1.7
The ``meta_data`` field has been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/
Returns a list of all events within a given organizer the authenticated user/token has access to.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"name": {"en": "Sample Conference"},
"slug": "sampleconf",
"live": false,
"currency": "EUR",
"date_from": "2017-12-27T10:00:00Z",
"date_to": null,
"date_admission": null,
"is_public": null,
"presale_start": null,
"presale_end": null,
"location": null,
"has_subevents": false,
"meta_data": {}
}
]
}
: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
: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)/
Returns information on one event, identified by its slug.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"name": {"en": "Sample Conference"},
"slug": "sampleconf",
"live": false,
"currency": "EUR",
"date_from": "2017-12-27T10:00:00Z",
"date_to": null,
"date_admission": null,
"is_public": false,
"presale_start": null,
"presale_end": null,
"location": null,
"has_subevents": false,
"meta_data": {}
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view it.

View File

@@ -0,0 +1,18 @@
Resources and endpoints
=======================
.. toctree::
:maxdepth: 2
organizers
events
subevents
taxrules
categories
items
questions
quotas
orders
invoices
vouchers
waitinglist

View File

@@ -0,0 +1,217 @@
Invoices
========
Resource description
--------------------
The invoice resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
number string Invoice number (with prefix)
order string Order code of the order this invoice belongs to
is_cancellation boolean ``True``, if this invoice is the cancellation of a
different invoice.
invoice_from string Sender address
invoice_to string Receiver address
date date Invoice date
refers string Invoice number of an invoice this invoice refers to
(for example a cancellation refers to the invoice it
cancels) or ``null``.
locale string Invoice locale
introductory_text string Text to be printed above the product list
additional_text string Text to be printed below the product list
payment_provider_text string Text to be printed below the product list with
payment information
footer_text string Text to be printed in the page footer area
lines list of objects The actual invoice contents
├ description string Text representing the invoice line (e.g. product name)
├ gross_value money (string) Price including taxes
├ tax_value money (string) Tax amount included
├ tax_name string Name of used tax rate (e.g. "VAT")
└ tax_rate decimal (string) Used tax rate
foreign_currency_display string If the invoice should also show the total and tax
amount in a different currency, this contains the
currency code (``null`` otherwise).
foreign_currency_rate decimal (string) If ``foreign_currency_rate`` is set and the system
knows the exchange rate to the event currency at
invoicing time, it is stored here.
foreign_currency_rate_date date If ``foreign_currency_rate`` is set, this signifies the
date at which the currency rate was obtained.
===================================== ========================== =======================================================
.. versionchanged:: 1.6
The attribute ``invoice_no`` has been dropped in favor of ``number`` which includes the number including the prefix,
since the prefix can now vary. Also, invoices now need to be identified by their ``number`` instead of the raw
number.
.. versionchanged:: 1.7
The attributes ``lines.tax_name``, ``foreign_currency_display``, ``foreign_currency_rate``, and
``foreign_currency_rate_date`` have been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/
Returns a list of all invoices within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/invoices/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"number": "SAMPLECONF-00001",
"order": "ABC12",
"is_cancellation": false,
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT ID: EU123456789",
"date": "2017-12-01",
"refers": null,
"locale": "en",
"introductory_text": "thank you for your purchase of the following items:",
"additional_text": "We are looking forward to see you on our conference!",
"payment_provider_text": "Please transfer the money to our account ABC…",
"footer_text": "Big Events LLC - Registration No. 123456 - VAT ID: EU0987654321",
"lines": [
{
"description": "Budget Ticket",
"gross_value": "23.00",
"tax_value": "0.00",
"tax_name": "VAT",
"tax_rate": "0.00"
}
],
"foreign_currency_display": "PLN",
"foreign_currency_rate": "4.2408",
"foreign_currency_rate_date": "2017-07-24"
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query boolean is_cancellation: If set to ``true`` or ``false``, only invoices with this value for the field
``is_cancellation`` will be returned.
:query string order: If set, only invoices belonging to the order with the given order code will be returned.
:query string refers: If set, only invoices refering to the given invoice will be returned.
:query string locale: If set, only invoices with the given locale will be returned.
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``date`` and
``nr`` (equals to ``number``). Default: ``nr``
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/
Returns information on one invoice, identified by its invoice number.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/invoices/SAMPLECONF-00001/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"number": "SAMPLECONF-00001",
"order": "ABC12",
"is_cancellation": false,
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT ID: EU123456789",
"date": "2017-12-01",
"refers": null,
"locale": "en",
"introductory_text": "thank you for your purchase of the following items:",
"additional_text": "We are looking forward to see you on our conference!",
"payment_provider_text": "Please transfer the money to our account ABC…",
"footer_text": "Big Events LLC - Registration No. 123456 - VAT ID: EU0987654321",
"lines": [
{
"description": "Budget Ticket",
"gross_value": "23.00",
"tax_value": "0.00",
"tax_name": "VAT",
"tax_rate": "0.00"
}
],
"foreign_currency_display": "PLN",
"foreign_currency_rate": "4.2408",
"foreign_currency_rate_date": "2017-07-24"
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param invoice_no: The ``invoice_no`` field of the invoice to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(invoice_no)/download/
Download an invoice in PDF format.
Note that in some cases the PDF file might not yet have been created. In that case, you will receive a status
code :http:statuscode:`409` and you are expected to retry the request after a short period of waiting.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/invoices/00001/download/ 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 invoice_no: The ``invoice_no`` field of the invoice to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
:statuscode 409: The file is not yet ready and will now be prepared. Retry the request after waiting vor a few
seconds.

241
doc/api/resources/items.rst Normal file
View File

@@ -0,0 +1,241 @@
Items
=====
Resource description
--------------------
Items (better known as products) are the things that can be sold using pretix.
The item resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the item
name multi-lingual string The item's visible name
default_price money (string) The item price that is applied if the price is not
overwritten by variations or other options.
category integer The ID of the category this item belongs to
(or ``null``).
active boolean If ``False``, the item is hidden from all public lists
and will not be sold.
description multi-lingual string A public description of the item. May contain Markdown
syntax or can be ``null``.
free_price boolean If ``True``, customers can change the price at which
they buy the product (however, the price can't be set
lower than the price defined by ``default_price`` or
otherwise).
tax_rate decimal (string) The VAT rate to be applied for this item.
tax_rule integer The internal ID of the applied tax rule (or ``null``).
admission boolean ``True`` for items that grant admission to the event
(such as primary tickets) and ``False`` for others
(such as add-ons or merchandise).
position integer An integer, used for sorting
picture string A product picture to be displayed in the shop
available_from datetime The first date time at which this item can be bought
(or ``null``).
available_until datetime The last date time at which this item can be bought
(or ``null``).
require_voucher boolean If ``True``, this item can only be bought using a
voucher that is specifically assigned to this item.
hide_without_voucher boolean If ``True``, this item is only shown during the voucher
redemption process, but not in the normal shop
frontend.
allow_cancel boolean If ``False``, customers cannot cancel orders containing
this item.
min_per_order integer This product can only be bought if it is included at
least this many times in the order (or ``null`` for no
limitation).
max_per_order integer This product can only be bought if it is included at
most this many times in the order (or ``null`` for no
limitation).
checkin_attention boolean If ``True``, the check-in app should show a warning
that this ticket requires special attention if such
a product is being scanned.
has_variations boolean Shows whether or not this item has variations
(read-only).
variations list of objects A list with one object for each variation of this item.
Can be empty.
├ id integer Internal ID of the variation
├ default_price money (string) The price set directly for this variation or ``null``
├ price money (string) The price used for this variation. This is either the
same as ``default_price`` if that value is set or equal
to the item's ``default_price``.
├ active boolean If ``False``, this variation will not be sold or shown.
├ description multi-lingual string A public description of the variation. May contain
Markdown syntax or can be ``null``.
└ position integer An integer, used for sorting
addons list of objects Definition of add-ons that can be chosen for this item
├ addon_category integer Internal ID of the item category the add-on can be
chosen from.
├ min_count integer The minimal number of add-ons that need to be chosen.
├ max_count integer The maxima number of add-ons that can be chosen.
└ position integer An integer, used for sorting
===================================== ========================== =======================================================
.. versionchanged:: 1.7
The attribute ``tax_rule`` has been added. ``tax_rate`` is kept for compatibility. The attribute
``checkin_attention`` has been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/items/
Returns a list of all items within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/items/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": {"en": "Standard ticket"},
"default_price": "23.00",
"category": null,
"active": true,
"description": null,
"free_price": false,
"tax_rate": "0.00",
"tax_rule": 1,
"admission": false,
"position": 0,
"picture": null,
"available_from": null,
"available_until": null,
"require_voucher": false,
"hide_without_voucher": false,
"allow_cancel": true,
"min_per_order": null,
"max_per_order": null,
"checkin_attention": false,
"has_variations": false,
"variations": [
{
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
},
{
"value": {"en": "Regular"},
"default_price": null,
"price": "23.00",
"active": true,
"description": null,
"position": 1
}
],
"addons": []
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query boolean active: If set to ``true`` or ``false``, only items with this value for the field ``active`` will be
returned.
:query integer category: If set to the ID of a category, only items within that category will be returned.
:query boolean admission: If set to ``true`` or ``false``, only items with this value for the field ``admission``
will be returned.
:query string tax_rate: If set to a decimal value, only items with this tax rate will be returned.
:query boolean free_price: If set to ``true`` or ``false``, only items with this value for the field ``free_price``
will be returned.
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``.
Default: ``position``
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/items/(id)/
Returns information on one item, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/items/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"id": 1,
"name": {"en": "Standard ticket"},
"default_price": "23.00",
"category": null,
"active": true,
"description": null,
"free_price": false,
"tax_rate": "0.00",
"tax_rule": 1,
"admission": false,
"position": 0,
"picture": null,
"available_from": null,
"available_until": null,
"require_voucher": false,
"hide_without_voucher": false,
"allow_cancel": true,
"min_per_order": null,
"max_per_order": null,
"checkin_attention": false,
"has_variations": false,
"variations": [
{
"value": {"en": "Student"},
"default_price": "10.00",
"price": "10.00",
"active": true,
"description": null,
"position": 0
},
{
"value": {"en": "Regular"},
"default_price": null,
"price": "23.00",
"active": true,
"description": null,
"position": 1
}
],
"addons": []
}
: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 item to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.

View File

@@ -0,0 +1,563 @@
Orders
======
Order resource
--------------
The order resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
code string Order code
status string Order status, one of:
* ``n`` pending
* ``p`` paid
* ``e`` expired
* ``c`` canceled
* ``r`` refunded
secret string The secret contained in the link sent to the customer
email string The customer email address
locale string The locale used for communication with this customer
datetime datetime Time of order creation
expires datetime The order will expire, if it is still pending by this time
payment_date date Date of payment receival
payment_provider string Payment provider used for this order
payment_fee money (string) Payment fee included in this order's total
payment_fee_tax_rate decimal (string) Tax rate applied to the payment fee
payment_fee_tax_value money (string) Tax value included in the payment fee
payment_fee_tax_rule integer The ID of the used tax rule (or ``null``)
total money (string) Total value of this order
comment string Internal comment on this order
invoice_address object Invoice address information (can be ``null``)
├ last_modified datetime Last modification date of the address
├ company string Customer company name
├ is_business boolean Business or individual customers (always ``False``
for orders created before pretix 1.7, do not rely on
it).
├ name string Customer name
├ street string Customer street
├ zipcode string Customer ZIP code
├ city string Customer city
├ country string Customer country
├ vat_id string Customer VAT ID
└ vat_id_validated string ``True``, if the VAT ID has been validated against the
EU VAT service and validation was successful. This only
happens in rare cases.
position list of objects List of order positions (see below)
fees list of objects List of fees included in the order total (i.e.
payment fees)
├ fee_type string Type of fee (currently ``payment``, ``passbook``,
``other``)
├ value money (string) Fee amount
├ description string Human-readable string with more details (can be empty)
├ internal_type string Internal string (i.e. ID of the payment provider),
can be empty
├ tax_rate decimal (string) VAT rate applied for this fee
├ tax_value money (string) VAT included in this fee
└ tax_rule integer The ID of the used tax rule (or ``null``)
downloads list of objects List of ticket download options for order-wise ticket
downloading. This might be a multi-page PDF or a ZIP
file of tickets for outputs that do not support
multiple tickets natively. See also order position
download options.
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
└ url string Download URL
===================================== ========================== =======================================================
.. versionchanged:: 1.6
The ``invoice_address.country`` attribute contains a two-letter country code for all new orders. For old orders,
a custom text might still be returned.
.. versionchanged:: 1.7
The attributes ``invoice_address.vat_id_validated`` and ``invoice_address.is_business`` have been added.
The attributes ``order.payment_fee``, ``order.payment_fee_tax_rate`` and ``order.payment_fee_tax_value`` have been
deprecated in favour of the new ``fees`` attribute but will still be served and removed in 1.9.
Order position resource
-----------------------
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the order positon
code string Order code of the order the position belongs to
positionid integer Number of the position within the order
item integer ID of the purchased item
variation integer ID of the purchased variation (or ``null``)
price money (string) Price of this position
attendee_name string Specified attendee name for this position (or ``null``)
attendee_email string Specified attendee email address for this position (or ``null``)
voucher integer Internal ID of the voucher used for this position (or ``null``)
tax_rate decimal (string) VAT rate applied for this position
tax_value money (string) VAT included in this position
tax_rule integer The ID of the used tax rule (or ``null``)
secret string Secret code printed on the tickets for validation
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``).
checkins list of objects List of check-ins with this ticket
└ datetime datetime Time of check-in
downloads list of objects List of ticket download options
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
└ url string Download URL
answers list of objects Answers to user-defined questions
├ question integer Internal ID of the answered question
├ answer string Text representation of the answer
└ options list of integers Internal IDs of selected option(s)s (only for choice types)
===================================== ========================== =======================================================
.. versionchanged:: 1.7
The attribute ``tax_rule`` has been added.
Order endpoints
---------------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orders/
Returns a list of all orders within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orders/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"code": "ABC12",
"status": "p",
"secret": "k24fiuwvu8kxz3y1",
"email": "tester@example.org",
"locale": "en",
"datetime": "2017-12-01T10:00:00Z",
"expires": "2017-12-10T10:00:00Z",
"payment_date": "2017-12-05",
"payment_provider": "banktransfer",
"fees": [],
"total": "23.00",
"comment": "",
"invoice_address": {
"last_modified": "2017-12-01T10:00:00Z",
"is_business": True,
"company": "Sample company",
"name": "John Doe",
"street": "Test street 12",
"zipcode": "12345",
"city": "Testington",
"country": "Testikistan",
"vat_id": "EU123456789",
"vat_id_validated": False
},
"positions": [
{
"id": 23442,
"order": "ABC12",
"positionid": 1,
"item": 1345,
"variation": null,
"price": "23.00",
"attendee_name": "Peter",
"attendee_email": null,
"voucher": null,
"tax_rate": "0.00",
"tax_value": "0.00",
"tax_rule": null,
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null,
"subevent": null,
"checkins": [
{
"datetime": "2017-12-25T12:45:23Z"
}
],
"answers": [
{
"question": 12,
"answer": "Foo",
"options": []
}
],
"downloads": [
{
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
}
],
"downloads": [
{
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/download/pdf/"
}
]
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``datetime``, ``code`` and
``status``. Default: ``datetime``
:query string code: Only return orders that match the given order code
:query string status: Only return orders in the given order status (see above)
:query string email: Only return orders created with the given email address
:query string locale: Only return orders with the given customer locale
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/
Returns information on one order, identified by its order code.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"code": "ABC12",
"status": "p",
"secret": "k24fiuwvu8kxz3y1",
"email": "tester@example.org",
"locale": "en",
"datetime": "2017-12-01T10:00:00Z",
"expires": "2017-12-10T10:00:00Z",
"payment_date": "2017-12-05",
"payment_provider": "banktransfer",
"fees": [],
"total": "23.00",
"comment": "",
"invoice_address": {
"last_modified": "2017-12-01T10:00:00Z",
"company": "Sample company",
"is_business": True,
"name": "John Doe",
"street": "Test street 12",
"zipcode": "12345",
"city": "Testington",
"country": "Testikistan",
"vat_id": "EU123456789",
"vat_id_validated": False
},
"positions": [
{
"id": 23442,
"order": "ABC12",
"positionid": 1,
"item": 1345,
"variation": null,
"price": "23.00",
"attendee_name": "Peter",
"attendee_email": null,
"voucher": null,
"tax_rate": "0.00",
"tax_rule": null,
"tax_value": "0.00",
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null,
"subevent": null,
"checkins": [
{
"datetime": "2017-12-25T12:45:23Z"
}
],
"answers": [
{
"question": 12,
"answer": "Foo",
"options": []
}
],
"downloads": [
{
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
}
],
"downloads": [
{
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/download/pdf/"
}
]
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param code: The ``code`` field of the order to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/download/(output)/
Download tickets for an order, identified by its order code. Depending on the chosen output, the response might
be a ZIP file, PDF file or something else. The order details response contains a list of output options for this
partictular order.
Tickets can be only downloaded if the order is paid and if ticket downloads are active. Note that in some cases the
ticket file might not yet have been created. In that case, you will receive a status code :http:statuscode:`409` and
you are expected to retry the request after a short period of waiting.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/download/pdf/ 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 code: The ``code`` field of the order to fetch
:param output: The internal name of the output provider to use
: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
**or** downlodas are not available for this order at this time. The response content will
contain more details.
:statuscode 409: The file is not yet ready and will now be prepared. Retry the request after waiting vor a few
seconds.
Order position endpoints
------------------------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/
Returns a list of all order positions within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 23442,
"order": "ABC12",
"positionid": 1,
"item": 1345,
"variation": null,
"price": "23.00",
"attendee_name": "Peter",
"attendee_email": null,
"voucher": null,
"tax_rate": "0.00",
"tax_rule": null,
"tax_value": "0.00",
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null,
"subevent": null,
"checkins": [
{
"datetime": "2017-12-25T12:45:23Z"
}
],
"answers": [
{
"question": 12,
"answer": "Foo",
"options": []
}
],
"downloads": [
{
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/"
}
]
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``order__code``,
``order__datetime``, ``positionid``, ``attendee_name``, and ``order__status``. Default:
``order__datetime,positionid``
:query string order: Only return positions of the order with the given order code
:query integer item: Only return positions with the purchased item matching the given ID.
:query integer variation: Only return positions with the purchased item variation matching the given ID.
:query string attendee_name: Only return positions with the given value in the attendee_name field. Also, add-on
products positions are shown if they refer to an attendee with the given name.
:query string secret: Only return positions with the given ticket secret.
:query string order__status: Only return positions with the given order status.
:query bollean has_checkin: If set to ``true`` or ``false``, only return positions that have or have not been
checked in already.
:query integer subevent: Only return positions of the sub-event with the given ID
:query integer addon_to: Only return positions that are add-ons to the position with the given ID.
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/
Returns information on one order position, identified by its internal ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"id": 23442,
"order": "ABC12",
"positionid": 1,
"item": 1345,
"variation": null,
"price": "23.00",
"attendee_name": "Peter",
"attendee_email": null,
"voucher": null,
"tax_rate": "0.00",
"tax_rule": null,
"tax_value": "0.00",
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null,
"subevent": null,
"checkins": [
{
"datetime": "2017-12-25T12:45:23Z"
}
],
"answers": [
{
"question": 12,
"answer": "Foo",
"options": []
}
],
"downloads": [
{
"output": "pdf",
"url": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/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: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/download/(output)/
Download tickets for one order position, identified by its internal ID.
Depending on the chosen output, the response might be a ZIP file, PDF file or something else. The order details
response contains a list of output options for this partictular order position.
Tickets can be only downloaded if the order is paid and if ticket downloads are active. Also, depending on event
configuration downloads might be only unavailable for add-on products or non-admission products.
Note that in some cases the ticket file might not yet have been created. In that case, you will receive a status
code :http:statuscode:`409` and you are expected to retry the request after a short period of waiting.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/pdf/ 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
:param output: The internal name of the output provider to use
: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
**or** downlodas are not available for this order position at this time. The response content will
contain more details.
:statuscode 409: The file is not yet ready and will now be prepared. Retry the request after waiting vor a few
seconds.

View File

@@ -0,0 +1,90 @@
Organizers
==========
Resource description
--------------------
An organizers is an entity running any number of events. In pretix, every event belongs to one
organizer and various settings, such as teams and permissions, are managed on organizer level.
The organizer resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
name string The organizer's full name, i.e. the name of an
organization or company.
slug string A short form of the name, used e.g. in URLs.
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/
Returns a list of all organizers the authenticated user/token has access to.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"name": "Big Events LLC",
"slug": "Big Events",
}
]
}
:query page: The page number in case of a multi-page result set, default is 1
:statuscode 200: no error
:statuscode 401: Authentication failure
.. http:get:: /api/v1/organizers/(organizer)/
Returns information on one organizer account, identified by its slug.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"name": "Big Events LLC",
"slug": "Big Events",
}
: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 it.

View File

@@ -0,0 +1,146 @@
Questions
=========
Resource description
--------------------
Questions define additional fields that need to be filled out by customers during checkout.
The question resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the question
question multi-lingual string The field label shown to the customer
type string The expected type of answer. Valid options:
* ``N`` number
* ``S`` one-line string
* ``T`` multi-line string
* ``B`` boolean
* ``C`` choice from a list
* ``M`` multiple choice from a list
* ``F`` file upload
required boolean If ``True``, the question needs to be filled out.
position integer An integer, used for sorting
items list of integers List of item IDs this question is assigned to.
options list of objects In case of question type ``C`` or ``M``, this lists the
available objects.
├ id integer Internal ID of the option
└ answer multi-lingual string The displayed value of this option
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/questions/
Returns a list of all questions within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/questions/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"question": {"en": "T-Shirt size"},
"type": "C",
"required": false,
"items": [1, 2],
"position": 1,
"options": [
{
"id": 1,
"answer": {"en": "S"}
},
{
"id": 2,
"answer": {"en": "M"}
},
{
"id": 3,
"answer": {"en": "L"}
}
]
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``.
Default: ``position``
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/questions/(id)/
Returns information on one question, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/questions/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: text/javascript
{
"id": 1,
"question": {"en": "T-Shirt size"},
"type": "C",
"required": false,
"items": [1, 2],
"position": 1,
"options": [
{
"id": 1,
"answer": {"en": "S"}
},
{
"id": 2,
"answer": {"en": "M"}
},
{
"id": 3,
"answer": {"en": "L"}
}
]
}
: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 question to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.

View File

@@ -0,0 +1,147 @@
Quotas
======
Resource description
--------------------
Questions define how many times an item can be sold.
The quota resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the quota
name string The internal name of the quota
size integer The size of the quota or ``null`` for unlimited
items list of integers List of item IDs this quota acts on.
variations list of integers List of item variation IDs this quota acts on.
subevent integer ID of the date inside an event series this quota belongs to (or ``null``).
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/quotas/
Returns a list of all quotas within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/quotas/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "Ticket Quota",
"size": 200,
"items": [1, 2],
"variations": [1, 4, 5, 7],
"subevent": null
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``.
Default: ``position``
:query integer subevent: Only return quotas of the sub-event with the given ID
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/quotas/(id)/
Returns information on one quota, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/quotas/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: text/javascript
{
"id": 1,
"name": "Ticket Quota",
"size": 200,
"items": [1, 2],
"variations": [1, 4, 5, 7],
"subevent": null
}
: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
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/quotas/(id)/availability/
Returns availability information on one quota, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/quotas/1/availability/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"available": true,
"available_number": 419,
"total_size": 1000,
"pending_orders": 25,
"paid_orders": 423,
"cart_positions": 7,
"blocking_vouchers": 126,
"waiting_list": 0
}
Note that ``total_size`` and ``available_number`` are ``null`` in case of unlimited quotas.
: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
: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.

View File

@@ -0,0 +1,144 @@
Event series dates / Sub-events
===============================
Resource description
--------------------
Events can represent whole event series if the ``has_subevents`` property of the event is active.
In this case, many other resources are additionally connected to an event date (also called sub-event).
The sub-event resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the sub-event
name multi-lingual string The sub-event's full name
active boolean If ``true``, the sub-event ticket shop is publicly
available.
date_from datetime The sub-event's start date
date_to datetime The sub-event's end date (or ``null``)
date_admission datetime The sub-event's admission date (or ``null``)
presale_start datetime The sub-date at which the ticket shop opens (or ``null``)
presale_end datetime The sub-date at which the ticket shop closes (or ``null``)
location multi-lingual string The sub-event location (or ``null``)
item_price_overrides list of objects List of items for which this sub-event overrides the
default price
├ item integer The internal item ID
└ price money (string) The price or ``null`` for the default price
variation_price_overrides list of objects List of variations for which this sub-event overrides
the default price
├ variation integer The internal variation ID
└ price money (string) The price or ``null`` for the default price
meta_data dict Values set for organizer-specific meta data parameters.
===================================== ========================== =======================================================
.. versionchanged:: 1.7
The ``meta_data`` field has been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/subevents/
Returns a list of all sub-events of an event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/subevents/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": {"en": "First Sample Conference"},
"active": false,
"date_from": "2017-12-27T10:00:00Z",
"date_to": null,
"date_admission": null,
"presale_start": null,
"presale_end": null,
"location": null,
"item_price_overrides": [
{
"item": 2,
"price": "12.00"
}
],
"variation_price_overrides": [],
"meta_data": {}
}
]
}
: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)/subevents/(id)/
Returns information on one sub-event, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/subevents/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: text/javascript
{
"id": 1,
"name": {"en": "First Sample Conference"},
"active": false,
"date_from": "2017-12-27T10:00:00Z",
"date_to": null,
"date_admission": null,
"presale_start": null,
"presale_end": null,
"location": null,
"item_price_overrides": [
{
"item": 2,
"price": "12.00"
}
],
"variation_price_overrides": [],
"meta_data": {}
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param id: The ``slug`` field of the sub-event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view it.

View File

@@ -0,0 +1,109 @@
Tax rules
=========
Resource description
--------------------
Tax rules specify how tax should be calculated for specific products.
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the tax rule
name multi-lingual string The tax rules' name
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
===================================== ========================== =======================================================
.. versionchanged:: 1.7
This resource has been added.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/taxrules/
Returns a list of all tax rules configured for an event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/taxrules/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": {"en": "VAT"},
"rate": "19.00",
"price_includes_tax": true,
"eu_reverse_charge": false,
"home_country": "DE"
}
]
}
: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)/taxrules/(id)/
Returns information on one tax rule, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/taxrules/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: text/javascript
{
"id": 1,
"name": {"en": "VAT"},
"rate": "19.00",
"price_includes_tax": true,
"eu_reverse_charge": false,
"home_country": "DE"
}
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:param id: The ``slug`` field of the sub-event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view it.

View File

@@ -0,0 +1,164 @@
Vouchers
========
Resource description
--------------------
The voucher resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the voucher
code string The voucher code that is required to redeem the voucher
max_usages integer The maximum number of times this voucher can be
redeemed (default: 1).
redeemed integer The number of times this voucher already has been
redeemed.
valid_until datetime The voucher expiration date (or ``null``).
block_quota boolean If ``True``, quota is blocked for this voucher.
allow_ignore_quota boolean If ``True``, this voucher can be redeemed even if a
product is sold out and even if quota is not blocked
for this voucher.
price_mode string Determines how this voucher affects product prices.
Possible values:
* ``none`` No effect on price
* ``set`` The product price is set to the given ``value``
* ``subtract`` The product price is determined by the original price *minus* the given ``value``
* ``percent`` The product price is determined by the original price reduced by the percentage given in ``value``
value decimal (string) The value (see ``price_mode``)
item integer An ID of an item this voucher is restricted to (or ``null``)
variation integer An ID of a variation this voucher is restricted to (or ``null``)
quota integer An ID of a quota this voucher is restricted to (or
``null``). This is an exclusive alternative to
``item`` and ``variation``: A voucher can be
attached either to a specific product or to all
products within one quota or it can be available
for all items without restriction.
tag string A string that is used for grouping vouchers
comment string An internal comment on the voucher
subevent integer ID of the date inside an event series this voucher belongs to (or ``null``).
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/vouchers/
Returns a list of all vouchers within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/vouchers/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"code": "43K6LKM37FBVR2YG",
"max_usages": 1,
"redeemed": 0,
"valid_until": null,
"block_quota": false,
"allow_ignore_quota": false,
"price_mode": "set",
"value": "12.00",
"item": 1,
"variation": null,
"quota": null,
"tag": "testvoucher",
"comment": "",
"subevent": null
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query string code: Only show the voucher with the given voucher code.
:query integer max_usages: Only show vouchers with the given maximal number of usages.
:query integer redeemed: Only show vouchers with the given number of redemptions. Note that this doesn't tell you if
the voucher can still be redeemed, as this also depends on ``max_usages``. See the
``active`` query parameter as well.
:query boolean block_quota: If set to ``true`` or ``false``, only vouchers with this value in the field
``block_quota`` will be shown.
:query boolean allow_ignore_quota: If set to ``true`` or ``false``, only vouchers with this value in the field
``allow_ignore_quota`` will be shown.
:query string price_mode: If set, only vouchers with this value in the field ``price_mode`` will be shown (see
above).
:query string value: If set, only vouchers with this value in the field ``value`` will be shown.
:query integer item: If set, only vouchers attached to the item with the given ID will be shown.
:query integer variation: If set, only vouchers attached to the variation with the given ID will be shown.
:query integer quota: If set, only vouchers attached to the quota with the given ID will be shown.
:query string tag: If set, only vouchers with the given tag will be shown.
:query integer subevent: Only return vouchers of the sub-event with the given ID
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id``, ``code``,
``max_usages``, ``valid_until``, and ``value``. Default: ``id``
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/vouchers/(id)/
Returns information on one voucher, identified by its internal ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/vouchers/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: text/javascript
{
"id": 1,
"code": "43K6LKM37FBVR2YG",
"max_usages": 1,
"redeemed": 0,
"valid_until": null,
"block_quota": false,
"allow_ignore_quota": false,
"price_mode": "set",
"value": "12.00",
"item": 1,
"variation": null,
"quota": null,
"tag": "testvoucher",
"comment": "",
"subevent": null
}
: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 voucher to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.

View File

@@ -0,0 +1,123 @@
Waiting list entries
====================
Resource description
--------------------
The waiting list entry resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal ID of the waiting list entry
created datetime Creation date of the waiting list entry
email string Email address of the user on the waiting list
voucher integer Internal ID of the voucher sent to this user. If
this field is set, the user has been sent a voucher
and is no longer waiting. If it is ``null``, the
user is still waiting.
item integer An ID of an item the user is waiting to be available
again
variation integer An ID of a variation the user is waiting to be
available again (or ``null``)
locale string Locale of the waiting user
subevent integer ID of the date inside an event series this entry belongs to (or ``null``).
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/waitinglistentries/
Returns a list of all waiting list entries within a given event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/waitinglistentries/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"created": "2017-12-01T10:00:00Z",
"email": "waiting@example.org",
"voucher": null,
"item": 2,
"variation": null,
"locale": "en",
"subevent": null
}
]
}
:query integer page: The page number in case of a multi-page result set, default is 1
:query string email: Only show waiting list entries created with the given email address.
:query string locale: Only show waiting list entries created with the given locale.
:query boolean has_voucher: If set to ``true`` or ``false``, only waiting list entries are returned that have or
have not been sent a voucher.
:query integer item: If set, only entries of users waiting for the item with the given ID will be shown.
:query integer variation: If set, only entries of users waiting for the variation with the given ID will be shown.
:query integer subevent: Only return entries of the sub-event with the given ID
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id``, ``created``,
``email``, ``item``. Default: ``created``
:param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/waitinglistentries/(id)/
Returns information on one waiting list entry, identified by its internal ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/waitinglistentries/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: text/javascript
{
"id": 1,
"created": "2017-12-01T10:00:00Z",
"email": "waiting@example.org",
"voucher": null,
"item": 2,
"variation": null,
"locale": "en",
"subevent": null
}
: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 waiting list entry to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.

View File

@@ -13,16 +13,22 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
from sphinx.util import compat
compat.make_admonition = BaseAdmonition # See https://github.com/spinus/sphinxcontrib-images/issues/41
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
from datetime import date
sys.path.insert(0, os.path.abspath('../src'))
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pretix.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pretix.testutils.settings")
django.setup()
# -- General configuration ------------------------------------------------
@@ -36,9 +42,9 @@ django.setup()
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinxcontrib.httpdomain',
'sphinxcontrib.images',
]
# Add any paths that contain templates here, relative to this directory.
@@ -51,20 +57,21 @@ source_suffix = '.rst'
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
master_doc = 'contents'
# General information about the project.
project = 'pretix'
copyright = '2014-2016, Raphael Michel'
copyright = '2014-{}, Raphael Michel'.format(date.today().year)
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.0.0'
from pretix import __version__
version = '.'.join(__version__.split('.')[:2])
# The full version, including alpha/beta/rc tags.
release = '0.0.0'
release = __version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -114,7 +121,9 @@ pygments_style = 'sphinx'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
html_theme_options = {
'logo_only': True,
}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
@@ -128,7 +137,7 @@ pygments_style = 'sphinx'
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
html_logo = 'images/logo-white.svg'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
@@ -138,7 +147,11 @@ pygments_style = 'sphinx'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = [
'_static',
os.path.abspath('../src/pretix/static/fonts/'),
os.path.abspath('../src/pretix/static/fontawesome/fonts/'),
]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
@@ -158,7 +171,9 @@ html_static_path = ['_static']
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
html_additional_pages = {
'index': 'index.html'
}
# If false, no module index is generated.
html_domain_indices = False
@@ -170,7 +185,7 @@ html_use_index = False
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
@@ -189,11 +204,8 @@ html_use_index = False
# Output file base name for HTML help builder.
htmlhelp_basename = 'pretixdoc'
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_theme = 'pretix_theme'
html_theme_path = [os.path.abspath('_themes')]
# -- Options for LaTeX output ---------------------------------------------
@@ -213,7 +225,7 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'pretix.tex', 'pretix Documentation',
('contents', 'pretix.tex', 'pretix Documentation',
'Raphael Michel', 'manual'),
]
@@ -273,3 +285,8 @@ texinfo_documents = [
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
images_config = {
'default_image_width': '250px'
}

12
doc/contents.rst Normal file
View File

@@ -0,0 +1,12 @@
Table of contents
=================
.. toctree::
:maxdepth: 3
user/index
admin/index
api/index
development/index
plugins/index

View File

@@ -60,7 +60,85 @@ your views::
def admin_view(request, organizer, event):
...
Similarly, there is ``organizer_permission_required`` and ``OrganizerPermissionRequiredMixin``.
Similarly, there is ``organizer_permission_required`` and ``OrganizerPermissionRequiredMixin``. In case of
event-related views, there is also a signal that allows you to add the view to the event navigation like this::
from django.core.urlresolvers import resolve, reverse
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _
from pretix.control.signals import nav_event
@receiver(nav_event, dispatch_uid='friends_tickets_nav')
def navbar_info(sender, request, **kwargs):
url = resolve(request.path_info)
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_vouchers'):
return []
return [{
'label': _('My plugin view'),
'icon': 'heart',
'url': reverse('plugins:myplugin:index', kwargs={
'event': request.event.slug,
'organizer': request.organizer.slug,
}),
'active': url.namespace == 'plugins:myplugin' and url.url_name == 'review',
}]
Event settings view
-------------------
A special case of a control panel view is a view hooked into the event settings page. For this case, there is a
special navigation signal::
@receiver(nav_event_settings, dispatch_uid='friends_tickets_nav_settings')
def navbar_settings(sender, request, **kwargs):
url = resolve(request.path_info)
return [{
'label': _('My settings'),
'url': reverse('plugins:myplugin:settings', kwargs={
'event': request.event.slug,
'organizer': request.organizer.slug,
}),
'active': url.namespace == 'plugins:myplugin' and url.url_name == 'settings',
}]
Also, your view should inherit from ``EventSettingsViewMixin`` and your template from ``pretixcontrol/event/settings_base.html``
for good integration. If you just want to display a form, you could do it like the following::
class MySettingsView(EventSettingsViewMixin, EventSettingsFormView):
model = Event
permission = 'can_change_settings'
form_class = MySettingsForm
template_name = 'my_plugin/settings.html'
def get_success_url(self, **kwargs):
return reverse('plugins:myplugin:settings', kwargs={
'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug,
})
With this template::
{% extends "pretixcontrol/event/settings_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %} {% trans "Friends Tickets Settings" %} {% endblock %}
{% block inside %}
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
<fieldset>
<legend>{% trans "Friends Tickets Settings" %}</legend>
{% bootstrap_form form layout="horizontal" %}
</fieldset>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
</div>
</form>
{% endblock %}
Frontend views
--------------
@@ -68,31 +146,79 @@ Frontend views
Including a custom view into the participant-facing frontend is a little bit different as there is
no path prefix like ``control/``.
First, define your URL in your ``urls.py``, but this time in the ``event_patterns`` section::
First, define your URL in your ``urls.py``, but this time in the ``event_patterns`` section and wrapped by
``event_url``::
from django.conf.urls import url
from pretix.multidomain import event_url
from . import views
event_patterns = [
url(r'^mypluginname/', views.frontend_view, name='frontend'),
event_url(r'^mypluginname/', views.frontend_view, name='frontend'),
]
You can then implement a view as you would normally do, but you need to apply a decorator to your
view if you want pretix's default behavior::
from pretix.presale.utils import event_view
@event_view
def some_event_view(request, *args, **kwargs):
...
This decorator will check the URL arguments for their ``event`` and ``organizer`` parameters and
correctly ensure that:
You can then implement a view as you would normally do. It will be automatically ensured that:
* The requested event exists
* The requested event is activated (can be overridden by decorating with ``@event_view(require_live=False)``)
* The requested event is active (you can disable this check using ``event_url(…, require_live=True)``)
* The event is accessed via the domain it should be accessed
* The ``request.event`` attribute contains the correct ``Event`` object
* The ``request.organizer`` attribute contains the correct ``Organizer`` object
* Your plugin is enabled
* The locale is set correctly
.. versionchanged:: 1.7
The ``event_url()`` wrapper has been added in 1.7 to replace the former ``@event_view`` decorator. The
``event_url()`` wrapper is optional and using ``url()`` still works, but you will not be able to set the
``require_live`` setting any more via the decorator. The ``@event_view`` decorator is now deprecated and
does nothing.
REST API viewsets
-----------------
Our REST API is built upon `Django REST Framework`_ (DRF). DRF has two important concepts that are different from
standard Django request handling: There are `ViewSets`_ to group related views in a single class and `Routers`_ to
automatically build URL configurations from them.
To integrate a custom viewset with pretix' REST API, you can just register with one of our routers within the
``urls.py`` module of your plugin::
from pretix.api.urls import event_router, router, orga_router
router.register('global_viewset', MyViewSet)
orga_router.register('orga_level_viewset', MyViewSet)
event_router.register('event_level_viewset', MyViewSet)
Routes registered with ``router`` are inserted into the global API space at ``/api/v1/``. Routes registered with
``orga_router`` will be included at ``/api/v1/organizers/(organizer)/`` and routes registered with ``event_router``
will be included at ``/api/v1/organizers/(organizer)/events/(event)/``.
In case of ``orga_router`` and ``event_router``, permission checking is done for you similarly as with custom views
in the control panel. However, you need to make sure on your own only to return the correct subset of data! ``request
.event`` and ``request.organizer`` are available as usual.
To require a special permission like ``can_view_orders``, you do not need to inherit from a special ViewSet base
class, you can just set the ``permission`` attribute on your viewset::
class MyViewSet(ModelViewSet):
permission = 'can_view_orders'
...
If you want to check the permission only for some methods of your viewset, you have to do it yourself. Note here that
API authentications can be done via user sessions or API tokens and you should therefore check something like the
following::
perm_holder = (request.auth if isinstance(request.auth, TeamAPIToken) else request.user)
if perm_holder.has_event_permission(request.event.organizer, request.event, 'can_view_orders'):
...
.. warning:: It is important that you do this in the ``yourplugin.urls`` module, otherwise pretix will not find your
routes early enough during system startup.
.. _Django REST Framework: http://www.django-rest-framework.org/
.. _ViewSets: http://www.django-rest-framework.org/api-guide/viewsets/
.. _Routers: http://www.django-rest-framework.org/api-guide/routers/

View File

@@ -11,7 +11,7 @@ Core
----
.. automodule:: pretix.base.signals
:members: periodic_task, event_live_issues
:members: periodic_task, event_live_issues, event_copy_data
Order events
""""""""""""
@@ -19,13 +19,13 @@ Order events
There are multiple signals that will be sent out in the ordering cycle:
.. automodule:: pretix.base.signals
:members: validate_cart, order_paid, order_placed
:members: validate_cart, order_fee_calculation, order_paid, order_placed, order_fee_type_name, allow_ticket_download
Frontend
--------
.. automodule:: pretix.presale.signals
:members: html_head, footer_links, front_page_top, front_page_bottom
:members: html_head, html_footer, footer_links, front_page_top, front_page_bottom, fee_calculation_for_cart, contact_form_fields, question_form_fields, checkout_confirm_messages, checkout_confirm_page_content
.. automodule:: pretix.presale.signals
@@ -47,20 +47,26 @@ Backend
-------
.. automodule:: pretix.control.signals
:members: nav_event, html_head, quota_detail_html, nav_topbar, organizer_edit_tabs
:members: nav_event, html_head, quota_detail_html, nav_topbar, nav_global, nav_organizer, nav_event_settings, order_info
.. automodule:: pretix.base.signals
:members: logentry_display, requiredaction_display
:members: logentry_display, logentry_object_link, requiredaction_display
Vouchers
""""""""
.. automodule:: pretix.control.signals
:members: voucher_form_class, voucher_form_html
:members: voucher_form_class, voucher_form_html, voucher_form_validation
Dashboards
""""""""""
.. automodule:: pretix.control.signals
:members: event_dashboard_widgets, user_dashboard_widgets
Ticket designs
""""""""""""""
.. automodule:: pretix.plugins.ticketoutputpdf.signals
:members: layout_text_variables

View File

@@ -1,5 +1,5 @@
Plugin hooks
============
Plugin development
==================
Contents:
@@ -10,5 +10,6 @@ Contents:
exporter
ticketoutput
payment
invoice
customview
general

View File

@@ -0,0 +1,95 @@
.. highlight:: python
:linenothreshold: 5
Writing an invoice renderer plugin
==================================
An invoice renderer controls how invoice files are built.
The creation of such a plugin is very similar to creating an export output.
Please read :ref:`Creating a plugin <pluginsetup>` first, if you haven't already.
Output registration
-------------------
The invoice renderer API does not make a lot of usage from signals, however, it
does use a signal to get a list of all available ticket outputs. Your plugin
should listen for this signal and return the subclass of ``pretix.base.invoice.BaseInvoiceRenderer``
that we'll provide in this plugin::
from django.dispatch import receiver
from pretix.base.signals import register_invoice_renderers
@receiver(register_invoice_renderers, dispatch_uid="output_custom")
def register_infoice_renderers(sender, **kwargs):
from .invoice import MyInvoiceRenderer
return MyInvoiceRenderer
The renderer class
------------------
.. class:: pretix.base.invoice.BaseInvoiceRenderer
The central object of each invoice renderer is the subclass of ``BaseInvoiceRenderer``.
.. py:attribute:: BaseInvoiceRenderer.event
The default constructor sets this property to the event we are currently
working for.
.. autoattribute:: identifier
This is an abstract attribute, you **must** override this!
.. autoattribute:: verbose_name
This is an abstract attribute, you **must** override this!
.. automethod:: generate
Helper class for reportlab-base renderers
-----------------------------------------
All PDF rendering that ships with pretix is based on reportlab. We recommend to read the
`reportlab User Guide`_ to understand all the concepts used here.
If you want to implement a renderer that also uses report lab, this helper class might be
convenient to you:
.. class:: pretix.base.invoice.BaseReportlabInvoiceRenderer
.. py:attribute:: BaseReportlabInvoiceRenderer.pagesize
.. py:attribute:: BaseReportlabInvoiceRenderer.left_margin
.. py:attribute:: BaseReportlabInvoiceRenderer.right_margin
.. py:attribute:: BaseReportlabInvoiceRenderer.top_margin
.. py:attribute:: BaseReportlabInvoiceRenderer.bottom_margin
.. py:attribute:: BaseReportlabInvoiceRenderer.doc_template_class
.. py:attribute:: BaseReportlabInvoiceRenderer.invoice
.. automethod:: _init
.. automethod:: _get_stylesheet
.. automethod:: _register_fonts
.. automethod:: _on_first_page
.. automethod:: _on_other_page
.. automethod:: _get_first_page_frames
.. automethod:: _get_other_page_frames
.. automethod:: _build_doc
.. _reportlab User Guide: https://www.reportlab.com/docs/reportlab-userguide.pdf

View File

@@ -1,8 +1,10 @@
.. highlight:: python
:linenothreshold: 5
Plugin basics
=============
.. _`pluginsetup`:
Creating a plugin
=================
It is possible to extend pretix with custom Python code using the official plugin
API. Every plugin has to be implemented as an independent Django 'app' living
@@ -14,10 +16,15 @@ The communication between pretix and the plugins happens mostly using Django's
``pretix.control`` and ``pretix.presale`` expose a number of signals which are documented
on the next pages.
.. _`pluginsetup`:
To create a new plugin, create a new python package which must be a valid `Django app`_
and must contain plugin metadata, as described below.
There is some boilerplate that you will need for every plugin to get started. To save your
time, we created a `cookiecutter`_ template that you can use like this::
$ pip install cookiecutter
$ cookiecutter https://github.com/pretix/pretix-plugin-cookiecutter
This will ask you some questions and then create a project folder for your plugin.
The following pages go into detail about the several types of plugins currently
supported. While these instructions don't assume that you know a lot about pretix,
@@ -30,35 +37,29 @@ Plugin metadata
The plugin metadata lives inside a ``PretixPluginMeta`` class inside your app's
configuration class. The metadata class must define the following attributes:
``name`` (``str``):
The human-readable name of your plugin
.. rst-class:: rest-resource-table
``author`` (``str``):
Your name
``version`` (``str``):
A human-readable version code of your plugin
``description`` (``str``):
A more verbose description of what your plugin does.
``visible`` (``bool``):
``True`` by default, can hide a plugin so it cannot be normally activated.
``restricted`` (``bool``):
``False`` by default, restricts a plugin such that it can only be enabled for an event
by system administrators / superusers.
================== ==================== ===========================================================
Attribute Type Description
================== ==================== ===========================================================
name string The human-readable name of your plugin
author string Your name
version string A human-readable version code of your plugin
description string A more verbose description of what your plugin does.
visible boolean (optional) ``True`` by default, can hide a plugin so it cannot be normally activated.
restricted boolean (optional) ``False`` by default, restricts a plugin such that it can only be enabled
for an event by system administrators / superusers.
================== ==================== ===========================================================
A working example would be::
# file: pretix/plugins/timerestriction/__init__.py
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class PaypalApp(AppConfig):
name = 'pretix.plugins.paypal'
verbose_name = _("Stripe")
name = 'pretix_paypal'
verbose_name = _("PayPal")
class PretixPluginMeta:
name = _("PayPal")
@@ -69,8 +70,7 @@ A working example would be::
description = _("This plugin allows you to receive payments via PayPal")
default_app_config = 'pretix.plugins.paypal.PaypalApp'
default_app_config = 'pretix_paypal.PaypalApp'
The ``AppConfig`` class may implement a property ``compatiblity_errors``, that checks
whether the pretix installation meets all requirements of the plugin. If so,
@@ -87,11 +87,10 @@ make use of the `entry point`_ feature of setuptools. To register a plugin that
in a separate python package, your ``setup.py`` should contain something like this::
setup(
args...,
entry_points="""
[pretix.plugin]
sampleplugin=sampleplugin:PretixPluginMeta
pretix_paypal=pretix_paypal:PretixPluginMeta
"""
)
@@ -109,12 +108,25 @@ pages. We suggest that you put your signal receivers into a ``signals`` submodul
of your plugin. You should extend your ``AppConfig`` (see above) by the following
method to make your receivers available::
class TimeRestrictionApp(AppConfig):
class PaypalApp(AppConfig):
def ready(self):
from . import signals # NOQA
You can optionally specify code that is executed when your plugin is activated for an event
in the ``installed`` method::
class PaypalApp(AppConfig):
def installed(self, event):
pass # Your code here
Note that ``installed`` will *not* be called if the plugin in indirectly activated for an event
because the event is created with settings copied from another event.
Views
-----
@@ -131,3 +143,4 @@ your Django app label.
.. _signal dispatcher: https://docs.djangoproject.com/en/1.7/topics/signals/
.. _namespace packages: http://legacy.python.org/dev/peps/pep-0420/
.. _entry point: https://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins
.. _cookiecutter: https://cookiecutter.readthedocs.io/en/latest/

View File

@@ -58,6 +58,8 @@ The output class
.. autoattribute:: is_enabled
.. autoattribute:: multi_download_enabled
.. autoattribute:: settings_form_fields
.. automethod:: settings_content_render

View File

@@ -1,18 +1,16 @@
Implementation concepts
=======================
Basic terminology
-----------------
Concepts and Terminology
========================
The components
^^^^^^^^^^^^^^
The project pretix is split into several components. The main three of them are:
The project pretix is split into several components. The main components are:
**base**
This is the foundation below all other components. It is primarily
responsible for the data structures and database communication. It also hosts
several utilities which are used by multiple other components.
several utilities which are used by multiple other components and important parts of
the business logic.
**control**
This is the web-based backend software which allows organizers to
@@ -20,7 +18,13 @@ The project pretix is split into several components. The main three of them are:
**presale**
This is the ticket-shop itself, containing all of the parts visible to the
end user.
end user. Also called "frontend" in parts of this documentation.
**api**
A RESTful API exposed to integrate with third-party software.
**plugins**
A set of pretix plugins that ship bundled with pretix.
Users and events
^^^^^^^^^^^^^^^^
@@ -55,12 +59,13 @@ If an item is assigned to multiple quotas, it can only be bought if *all of them
If multiple items are assigned to the same quota, the quota will be counted as sold out as soon as the
*sum* of the two items exceeds the quota limit.
The availability of a quota is currently calculated by substracting the following numbers from the quota
The availability of a quota is currently calculated by subtracting the following numbers from the quota
limit:
* The number of orders placed for an item that are either already paid or within their granted payment period
* The number of non-expired items currently in the shopping cart of users
* The number of vouchers defined as "quota blocking" (see blow)
* The number of people on the waiting list
The quota system tries very hard to be as friendly as possible to your event attendees while still making sure
your limit is never exceeded. For example, when the payment period of an order expires without the order being

View File

@@ -9,7 +9,8 @@ constructive and friendly feedback on your changes.
First of all, you'll need pretix running locally on your machine. Head over to :ref:`devsetup` to learn how to do this.
If you run into any problems on your way, please do not hesitate to ask us anytime!
Please note that we have a :ref:`coc` in place that applies to all communication around the project.
Please note that we bound ourselves to a :ref:`coc` that applies to all communication around the project. You can be
assured that we will not tolerate any form of harassment.
Sending a patch
---------------
@@ -18,8 +19,9 @@ If you improved pretix in any way, we'd be very happy if you contribute it
back to the main code base! The easiest way to do so is to `create a pull request`_
on our `GitHub repository`_.
Before you do so, please `squash all your changes`_ into one single commit. Please
use the test suite to check whether your changes break any existing features and run
We recommend that you create a feature branch for every issue you work on so the changes can
be reviewed individually.
Please use the test suite to check whether your changes break any existing features and run
the code style checks to confirm you are consistent with pretix's coding style. You'll
find instructions on this in the :ref:`checksandtests` section of the development setup guide.
@@ -34,4 +36,3 @@ Again: If you get stuck, do not hesitate to contact any of us, or Raphael person
.. _create a pull request: https://help.github.com/articles/creating-a-pull-request/
.. _GitHub repository: https://github.com/pretix/pretix
.. _squash all your changes: https://davidwalsh.name/squash-commits-git

View File

@@ -1,5 +1,5 @@
Contribution guide
==================
Contributing to pretix
======================
.. toctree::
:maxdepth: 2

View File

@@ -1,39 +1,33 @@
Coding style
============
Coding style and quality
========================
Python 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`
for more information. Use four spaces for indentation.
* Basically: Follow `PEP 8`_.
* We sort our imports by a certain schema, but you don't have to do this by hand. Again, ``setup.cfg`` contains
some definitions that allow the command ``isort -rc <directory>`` to automatically sort the imports in your source
files.
Use `flake8`_ to check for conformance problems. The project includes a setup.cfg file
with a default configuration for flake8 that excludes migrations and other non-relevant
code parts. It also silences a few checks, e.g. ``N802`` (function names should be lowercase)
and increases the maximum line length to more than 79 characters. **However** you should
still name all your functions lowercase [#f1]_ and keep your lines short when possible.
* For templates and models, please take a look at the `Django Coding Style`_. We like Django's `class-based views`_ and
kindly ask you to use them where appropriate.
* Our build server will reject all code violating other flake8 checks than the following:
* Please remember to always mark all strings ever displayed to any user for `translation`_.
* E123: closing bracket does not match indentation of opening brackets line
* F403: ``from module import *`` used; unable to detect undefined names
* F401: module imported but unused
* N802: function names should be lowercase
* We expect all new code to come with proper tests. When writing new tests, please write them using `pytest-style`_
test functions and raw ``assert`` statements. Use `fixtures`_ to prevent repetitive code. Some old parts of pretix'
test suite are in the style of Python's unit test module. If you extend those files, you might continue in this style,
but please use pytest style for any new test files.
So please make sure that you *always* follow all other rules and break these rules *only when
it makes sense*.
* Use ``isort -rc pretix`` in the source directory to order your imports.
* Indent your code with four spaces.
* For templates and models, follow the `Django Coding Style`_.
* Use Django's class-based views
* Always mark all strings ever displayed to any user for translation.
* 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``.
.. _PEP 8: http://legacy.python.org/dev/peps/pep-0008/
.. _flake8: https://pypi.python.org/pypi/flake8
.. _Django Coding Style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
.. [#f1] But Python's very own ``unittest`` module forces us to use ``setUp`` as a method name...
.. _translation: https://docs.djangoproject.com/en/1.11/topics/i18n/translation/
.. _class-based views: https://docs.djangoproject.com/en/1.11/topics/class-based-views/
.. _pytest-style: https://docs.pytest.org/en/latest/assert.html
.. _fixtures: https://docs.pytest.org/en/latest/fixture.html

View File

@@ -14,7 +14,7 @@ Implementing a task
A common pattern for implementing asynchronous tasks can be seen a lot in ``pretix.base.services``
and looks like this::
from pretix.celery import app
from pretix.celery_app import app
@app.task
def my_task(argument1, argument2):

View File

@@ -2,6 +2,9 @@ Sending Email
=============
pretix allows event organizers to configure how they want to send emails to their users in multiple ways.
Therefore, all emails should be sent through the following function:
Therefore, all emails should be sent through the following function.
If the email you send is related to an order, you should also take a look at the
:py:meth:`~pretix.base.models.Order.send_mail` of the order model.
.. autofunction:: pretix.base.services.mail.mail

View File

@@ -6,116 +6,18 @@ One of pretix's major selling points is its multi-language capability. We make h
way to translate *user-generated content*. In our case, we need to translate strings like product names
or event descriptions, so we need event organizers to be able to fill in all fields in multiple languages.
.. note:: Implementing object-level translation in a relational database is a task that requires some difficult
trade-off. We decided for a design that is not elegant on the database level (as it violates the `1NF`_) and
makes searching in the respective database fields very hard, but allows for a simple design on the ORM level
and adds only minimal performance overhead.
For this purpose, we use ``django-i18nfield`` which started out as part of pretix and then got refactored into
its own library. It has comprehensive documentation on how to work with its `strings`_, `database fields`_ and
`forms`_.
All classes and functions introduced in this document are located in ``pretix.base.i18n`` if not stated otherwise.
Database storage
----------------
pretix provides two custom model field types that allow you to work with localized strings: ``I18nCharField`` and
``I18nTextField``. Both of them are stored in the database as a ``TextField`` internally, they only differ in the
default form widget that is used by ``ModelForm``.
As pretix does not use these fields in places that need to be searched, the negative performance impact when searching
and indexing these fields in negligible, as mentioned above. Lookups are currently not even implemented on these
fields. In the database, the strings will be stored as a JSON-encoded mapping of language codes to strings.
Whenever you interact with those fields, you will either provide or receive an instance of the following class:
.. autoclass:: pretix.base.i18n.LazyI18nString
:members: __init__, localize, __str__
Usage
-----
The following examples are given to illustrate how you can work with ``LazyI18nString``.
.. testsetup:: *
from pretix.base.i18n import LazyI18nString, language
To create a LazyI18nString, we can cast a simple string:
.. doctest::
>>> naive = LazyI18nString('Naive untranslated string')
>>> naive
<LazyI18nString: 'Naive untranslated string'>
Or we can provide a dictionary with multiple translations:
.. doctest::
>>> translated = LazyI18nString({'en': 'English String', 'de': 'Deutscher String'})
We can use ``localize`` to get the string in a specific language:
.. doctest::
>>> translated.localize('de')
'Deutscher String'
>>> translated.localize('en')
'English String'
If we try a locale that does not exist for the string, we might get a it either in a similar locale or in the system's default language:
.. doctest::
>>> translated.localize('de-AT')
'Deutscher String'
>>> translated.localize('zh')
'English String'
>>> naive.localize('de')
'Naive untranslated string'
If we cast a ``LazyI18nString`` to ``str``, ``localize`` will be called with the currently active language:
.. doctest::
>>> from django.utils import translation
>>> str(translated)
'English String'
>>> translation.activate('de')
>>> str(translated)
'Deutscher String'
You can also use our handy context manager to set the locale temporarily:
.. doctest::
>>> translation.activate('en')
>>> with language('de'):
... str(translated)
'Deutscher String'
>>> str(translated)
'English String'
Forms
-----
We provide i18n-aware versions of the respective form fields and widgets: ``I18nFormField`` with the ``I18nTextInput``
and ``I18nTextarea`` widgets. They transparently allow you to use ``LazyI18nString`` values in forms and render text
inputs for multiple languages.
.. autoclass:: pretix.base.i18n.I18nFormField
To easily limit the displayed languages to the languages relevant to an event, there is a custom ``ModelForm`` subclass
that deals with this for you:
.. autoclass:: pretix.base.forms.I18nModelForm
There are equivalents for ``BaseModelFormSet`` and ``BaseInlineFormSet``:
.. autoclass:: pretix.base.forms.I18nFormSet
.. autoclass:: pretix.base.forms.I18nInlineFormSet
For backwards-compatibility with older parts of pretix' code base and older plugins, ``pretix.base.forms`` still
contains a number of forms that are equivalent in name and usage to their counterparts in ``i18nfield.forms`` with
the difference that they take an ``event`` keyword argument and then set the ``locales`` argument based on
``event.settings.get('locales')``.
Useful utilities
----------------
@@ -135,4 +37,6 @@ action that causes the mail to be sent.
.. _translation features: https://docs.djangoproject.com/en/1.9/topics/i18n/translation/
.. _GNU gettext: https://www.gnu.org/software/gettext/
.. _1NF: https://en.wikipedia.org/wiki/First_normal_form
.. _strings: https://django-i18nfield.readthedocs.io/en/latest/strings.html
.. _database fields: https://django-i18nfield.readthedocs.io/en/latest/quickstart.html
.. _forms: https://django-i18nfield.readthedocs.io/en/latest/forms.html

View File

@@ -20,18 +20,27 @@ Organizers and events
.. autoclass:: pretix.base.models.Organizer
:members:
.. autoclass:: pretix.base.models.OrganizerPermission
:members:
.. autoclass:: pretix.base.models.Event
:members:
:members: get_date_from_display, get_time_from_display, get_date_to_display, get_date_range_display, presale_has_ended, presale_is_running, get_cache, lock, get_plugins, get_mail_backend, payment_term_last, get_payment_providers, get_invoice_renderers, active_subevents, invoice_renderer, settings
.. autoclass:: pretix.base.models.EventPermission
.. autoclass:: pretix.base.models.SubEvent
:members: get_date_from_display, get_time_from_display, get_date_to_display, get_date_range_display, presale_has_ended, presale_is_running
.. autoclass:: pretix.base.models.Team
:members:
.. autoclass:: pretix.base.models.RequiredAction
:members:
.. autoclass:: pretix.base.models.EventMetaProperty
:members:
.. autoclass:: pretix.base.models.EventMetaValue
:members:
.. autoclass:: pretix.base.models.SubEventMetaValue
:members:
Items
-----
@@ -45,6 +54,15 @@ Items
.. autoclass:: pretix.base.models.ItemVariation
:members:
.. autoclass:: pretix.base.models.SubEventItem
:members:
.. autoclass:: pretix.base.models.SubEventItemVariation
:members:
.. autoclass:: pretix.base.models.ItemAddOn
:members:
.. autoclass:: pretix.base.models.Question
:members:
@@ -67,7 +85,7 @@ Carts and Orders
:members:
.. autoclass:: pretix.base.models.QuestionAnswer
:members:
:members:
.. autoclass:: pretix.base.models.Checkin
:members:
@@ -92,5 +110,3 @@ Vouchers
.. autoclass:: pretix.base.models.Voucher
:members:
.. _cleanerversion: https://github.com/swisscom/cleanerversion

View File

@@ -2,7 +2,10 @@ Settings storage
================
pretix is highly configurable and therefore needs to store a lot of per-event and per-organizer settings.
Those settings are stored in the database and accessed through a ``SettingsProxy`` instance. You can obtain
For this purpose, we use `django-hierarkey`_ which started out as part of pretix and then got refactored into
its own library. It has a comprehensive `documentation`_ which you should read if you work with settings in pretix.
The settings are stored in the database and accessed through a ``HierarkeyProxy`` instance. You can obtain
such an instance from any event or organizer model instance by just accessing ``event.settings`` or
``organizer.settings``, respectively.
@@ -17,12 +20,10 @@ includes serializers for serializing the following types:
In code, we recommend to always use the ``.get()`` method on the settings object to access a value, but for
convenience in templates you can also access settings values at ``settings[name]`` and ``settings.name``.
.. autoclass:: pretix.base.settings.SettingsProxy
:members: get, set, delete, freeze
See the hierarkey `documentation`_ for more information.
To avoid naming conflicts, plugins are requested to prefix all settings they use with the name of the plugin
or something unique, e.g. ``payment.paypal.api_key``. To reduce redundant typing of this prefix, we provide
or something unique, e.g. ``payment_paypal_api_key``. To reduce redundant typing of this prefix, we provide
another helper class:
.. autoclass:: pretix.base.settings.SettingsSandbox
@@ -33,10 +34,10 @@ you will just be passed a sandbox object with a prefix generated from your provi
Forms
-----
We also provide a base class for forms that allow the modification of settings:
Hierarkey also provides a base class for forms that allow the modification of settings. pretix contains a
subclass that also adds suport for internationalized fields:
.. autoclass:: pretix.base.forms.SettingsForm
:members: save
You can simply use it like this::
@@ -51,3 +52,17 @@ You can simply use it like this::
help_text=_("The number of days after placing an order the user has to pay to "
"preserve his reservation."),
)
Defaults in plugins
-------------------
Plugins can add custom hardcoded defaults in the following way::
from pretix.base.settings import settings_hierarkey
settings_hierarkey.add_default('key', 'value', type)
Make sure that you include this code in a module that is imported at app loading time.
.. _django-hierarkey: https://github.com/raphaelm/django-hierarkey
.. _documentation: https://django-hierarkey.readthedocs.io/en/latest/

View File

@@ -1,17 +1,12 @@
Developer documentation
=======================
Contents:
.. toctree::
:maxdepth: 2
concepts
setup
structure
contribution/index
implementation/index
api/index
.. TODO::
Document settings objects, ItemVariation objects, form fields.
structure

View File

@@ -1,7 +1,11 @@
.. _`devsetup`:
The development setup
=====================
Development setup
=================
This tutorial helps you to get started hacking with pretix on your own computer. You need this to
be able to contribute to pretix, but it might also be helpful if you want to write your own plugins.
If you want to install pretix on a server for actual usage, go to the :ref:`admindocs` instead.
Obtain a copy of the source code
--------------------------------
@@ -12,9 +16,11 @@ You can just clone our git repository::
External Dependencies
---------------------
Your should install the following on your system:
* Python 3.4 or newer
* ``pip`` for Python 3 (Debian package: ``python3-pip``)
* ``pyvenv`` for Python 3 (Debian package: ``python3-venv``)
* ``python-dev`` for Python 3 (Debian package: ``python3-dev``)
* ``libffi`` (Debian package: ``libffi-dev``)
* ``libssl`` (Debian package: ``libssl-dev``)
* ``libxml2`` (Debian package ``libxml2-dev``)
@@ -30,7 +36,7 @@ Please execute ``python -V`` or ``python3 -V`` to make sure you have Python 3.4
execute ``pip3 -V`` to check. Then use Python's internal tools to create a virtual
environment and activate it for your current session::
pyvenv env
python3 -m venv env
source env/bin/activate
You should now see a ``(env)`` prepended to your shell prompt. You have to do this
@@ -39,7 +45,7 @@ automatically). If you are working on Ubuntu or Debian, we strongly recommend up
your pip and setuptools installation inside the virtual environment, otherwise some of
the dependencies might fail::
pip3 install -U pip setuptools==28.6.1
pip3 install -U pip setuptools
Working with the code
---------------------
@@ -48,7 +54,7 @@ The first thing you need are all the main application's dependencies::
cd src/
pip3 install -r requirements.txt -r requirements/dev.txt
If you are working with Python 3.4, you will also need (you can skip this for Python 3.5)::
If you are working with Python 3.4, you will also need (you can skip this for Python 3.5+)::
pip3 install -r requirements/py34.txt
@@ -80,17 +86,28 @@ and head to http://localhost:8000/
As we did not implement an overall front page yet, you need to go directly to
http://localhost:8000/control/ for the admin view or, if you imported the test
data as suggested above, to the event page at http://localhost:8000/bigevents/2017/
data as suggested above, to the event page at http://localhost:8000/bigevents/2018/
.. note:: If you want the development server to listen on a different interface or
port (for example because you develop on `pretixdroid`_), you can check
`Django's documentation`_ for more options.
.. _`checksandtests`:
Code checks and unit tests
^^^^^^^^^^^^^^^^^^^^^^^^^^
Before you check in your code into git, always run the static checkers and unit tests::
Before you check in your code into git, always run static checkers and linters. If any of these commands fail,
your pull request will not be merged into pretix. If you have trouble figuring out *why* they fail, create your
pull request nevertheless and ask us for help, we are happy to assist you.
Execute the following commands to check for code style errors::
flake8 .
isort -c -rc .
python manage.py check
Execute the following command to run pretix' test suite (might take a coumple of minutes)::
py.test
.. note:: If you have multiple CPU cores and want to speed up the test suite, you can install the python
@@ -102,9 +119,10 @@ for example::
#!/bin/sh
cd $GIT_DIR/../src
source ../env/bin/activate
flake8 --ignore=E123,E128,F403,F401,N802,W503 .
flake8 . || exit 1
isort -q -rc -c . || exit 1
This keeps you from accidentally creating commits violating the sdtyle guide.
Working with mails
^^^^^^^^^^^^^^^^^^
@@ -146,4 +164,14 @@ To build the documentation, run the following command from the ``doc/`` director
make html
You will now find the generated documentation in the ``doc/_build/html/`` subdirectory.
You will now find the generated documentation in the ``doc/_build/html/`` subdirectory. If you work
with the documentation a lot, you might find it useful to use sphinx-autobuild::
pip3 install sphinx-autobuild
sphinx-autobuild . _build/html -p 8081
Then, go to http://localhost:8081 for a version of the documentation that automatically re-builds
whenever you change a source file.
.. _Django's documentation: https://docs.djangoproject.com/en/1.11/ref/django-admin/#runserver
.. _pretixdroid: https://github.com/pretix/pretixdroid

View File

@@ -1,13 +1,10 @@
Project structure
=================
Python source code
------------------
Directory structure
===================
All the source code lives in ``src/``, which has several subdirectories.
pretix/
This directory contains nearly all source code.
This directory contains nearly all source code that belongs to pretix.
base/
This is the Django app containing all the models and methods which are
@@ -19,57 +16,31 @@ pretix/
presale/
This is the Django app containing the front end for users buying tickets.
api/
This is the Django app containing all views and serializers for pretix'
:ref:`rest-api`.
helpers/
Helpers contain a very few modules providing workarounds for low-level flaws in
Django or installed 3rd-party packages.
locale/
Contains translation file for pretix
multidomain/
Additional code implementing our customized :ref:`URL handling <urlconf>`.
static/
Contains all static files (CSS, JavaScript, images)
static/
Contains all static files (CSS/SASS, JavaScript, images) of pretix' core
We use libsass as a preprocessor for CSS. Our own sass code is built in the same
step as Bootstrap and FontAwesome, so their mixins etc. are fully available.
testutils/
Contains helper methods that are useful to write the test suite for pretix or test
suites for pretix plugins.
tests/
This is the root directory for all test codes. It includes subdirectories ``base``,
``control``, ``presale``, ``helpers`` and ``plugins`` to mirror the structure of the
``pretix`` source code as well as ``testdummy``, which is a pretix plugin used during
This is the root directory for all test codes. It includes subdirectories ``api``, ``base``,
``control``, ``presale``, ``helpers`, ``multidomain`` and ``plugins`` to mirror the structure
of the pretix source code as well as ``testdummy``, which is a pretix plugin used during
testing.
Language files
--------------
The language files live in ``locale/*/LC_MESSAGES/``.
Static files
------------
Sass source code
^^^^^^^^^^^^^^^^
We use libsass as a preprocessor for CSS. Our own sass code is built in the same
step as Bootstrap and FontAwesome, so their mixins etc. are fully available.
pretix.control
pretixcontrol has two main SCSS files, ``pretix/control/static/pretixcontrol/scss/main.scss`` and
``pretix/control/static/pretixcontrol/scss/auth.scss``, importing everything else.
pretix.presale
pretixpresale has one main SCSS files, ``pretix/control/static/pretix/presale/scss/main.scss``,
importing everything else.
3rd-party assets
^^^^^^^^^^^^^^^^
Bootstrap
Bootstrap lives vendored at ``static/bootstrap/``
Font Awesome
Font Awesome lives vendored at ``static/fontawesome/``
jQuery
jQuery lives as a single JavaScript file in ``static/jquery/js/``
jQuery plugin: Django formsets
Our own modified version of `django-formset-js`_ is available as an independent
django app and installed via ``pip``.
.. _django-formset-js: https://github.com/pretix/django-formset-js

69
doc/images/logo-white.svg Normal file
View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="254.15625"
height="109.59375"
viewBox="0 0 254.15625 109.59375"
version="1.1"
id="svg5"
sodipodi:docname="logo-white.svg"
inkscape:version="0.92.1 r"><metadata
id="metadata9">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1364"
inkscape:window-height="676"
id="namedview7"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="1"
inkscape:cx="56.462442"
inkscape:cy="54.796875"
inkscape:window-x="0"
inkscape:window-y="72"
inkscape:window-maximized="0"
inkscape:current-layer="svg5" />
id=&quot;svg2&quot;
version=&quot;1.1&quot;&gt;
<defs
id="defs4" />
<g
id="layer1"
transform="translate(-277.78125,-568.75)">
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
d="m 20,20 v 34.09375 c 11.43679,0 20.71875,9.28196 20.71875,20.71875 C 40.71875,86.24928 31.43679,95.5 20,95.5 v 34.09375 h 146.6875 v -9.5 h 3 v 9.5 H 274.15625 V 95.5 c -0.0105,2e-5 -0.0208,0 -0.0312,0 -11.43678,0 -20.71875,-9.25072 -20.71875,-20.6875 0,-11.43679 9.28197,-20.71875 20.71875,-20.71875 0.0105,0 0.0208,-2e-5 0.0312,0 V 20 H 169.6875 v 9.09375 h -3 V 20 Z m 146.6875,16.09375 h 3 v 14 h -3 z m 41.44141,12.833984 c 2.79067,0 5.02343,1.92774 5.02343,4.3125 0,2.38476 -2.23276,4.363282 -5.02343,4.363282 -2.73994,0 -4.97266,-1.978522 -4.97266,-4.363282 0,-2.38476 2.23272,-4.3125 4.97266,-4.3125 z m -13.22852,4.210938 v 8.017578 h 3.95899 v 6.291016 h -3.95899 v 12.279296 c 0,2.02959 0.71015,2.791016 2.13086,2.791016 0.71035,0 1.06703,-0.10181 1.82813,-0.40625 v 5.935547 c -0.71036,0.40591 -2.38661,0.964844 -4.61915,0.964844 -6.13949,0 -8.98046,-3.753876 -8.98046,-8.472657 V 67.447266 h -2.8418 V 61.15625 h 2.8418 V 55.574219 Z M 166.6875,57.09375 h 3 v 14 h -3 z m -74.568359,3.554688 c 8.473509,0 14.207029,4.515688 14.207029,14.105468 0,8.62573 -5.02336,14.105469 -12.07617,14.105469 -1.72514,0 -3.147072,-0.20329 -3.857422,-0.40625 V 99.414062 H 80.751953 V 62.728516 c 2.58772,-1.21775 6.090268,-2.080081 11.367188,-2.080078 z m 49.863279,0 c 8.57499,0 12.63436,5.935363 12.12696,15.220703 l -15.93165,2.234375 c 0.60888,2.94289 2.18061,4.414062 5.68165,4.414062 3.24732,0 5.78445,-0.711556 7.30664,-1.472656 l 2.13086,5.886719 c -2.38476,1.16701 -5.58034,2.080078 -10.6543,2.080078 -8.93017,0 -13.64844,-6.037993 -13.64844,-14.257813 0,-8.21981 4.41329,-14.105468 12.98828,-14.105468 z m -17.92187,0.0059 c 0.8928,0.01358 1.82795,0.04496 2.80468,0.0957 l -1.67578,6.697266 c -1.77589,-0.86257 -3.50104,-0.913692 -4.76953,-0.457032 v 21.513672 h -9.64062 v -25.77539 c 2.79702,-1.376314 7.03166,-2.16926 13.28125,-2.074219 z m 79.24804,0.501953 h 9.64063 v 27.347656 h -9.64063 z m 13.23438,0 h 10.04687 l 3.29883,6.849609 h 0.10156 l 3.60157,-6.849609 h 8.98047 l -7.96485,12.632812 8.72656,14.714844 H 232.67969 L 229.17773,80.9434 h -0.10156 l -3.65234,7.560547 h -9.74219 l 8.57422,-14.105468 z m -74.9668,5.023438 c -2.84142,0 -4.41381,2.585948 -4.10937,7.355468 l 7.76367,-1.166015 c 0,-4.16064 -1.2188,-6.189454 -3.6543,-6.189453 z m -49.507811,0.09961 c -0.71035,0 -1.219131,0.101686 -1.675781,0.253906 v 16.439453 c 0.35517,0.15221 0.863828,0.253906 1.523438,0.253906 3.4503,0 4.871093,-2.840514 4.871093,-8.421874 0,-5.733571 -1.21772,-8.525391 -4.71875,-8.525391 z M 166.6875,78.09375 h 3 v 14 h -3 z m 0,21 h 3 v 14 h -3 z"
transform="translate(257.78125,548.75)"
id="rect3888"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,12 +0,0 @@
Welcome to pretix's documentation!
==================================
Contents:
.. toctree::
:maxdepth: 2
admin/index
development/index
plugins/index

View File

@@ -0,0 +1,201 @@
Bank transfer HTTP API
======================
The banktransfer plugin provides a HTTP API that `pretix-banktool`_ uses to send bank
transactions to the pretix server. This API is integrated with the regular :ref:`rest-api`
and therefore follows the conventions listed there.
Bank import job resource
^^^^^^^^^^^^^^^^^^^^^^^^
Resource description
--------------------
The bank import job resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Internal job ID
event string Slug of the event this job was uploaded for or ``null``
created datetime Job creation time
state string Job state, one of ``pending``, ``running``,
``error`` or ``completed``
transactions list of objects Transactions included in this job (will only appear
after the job has started processing).
├ state string Transaction state, one of ``imported``, ``nomatch``,
``invalid``, ``error``, ``valid``, ``discarded``,
``already`` (already paid)
├ message string Error message (if any)
├ checksum string Checksum computed from payer, reference, amount and
date
├ payer string Payment source
├ reference string Payment reference
├ amount string Payment amount
├ date string Payment date (in **user-inputted** format)
├ order string Associated order code (or ``null``)
└ comment string Internal comment
===================================== ========================== =======================================================
Note that the ``payer`` and ``reference`` fields are set to empty as soon as the payment is matched to an order or
discarded to avoid storing sensitive data when not necessary. The ``checksum`` persists to implement deduplication.
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/bankimportjobs/
Returns a list of all bank import jobs within a given organizer the authenticated user/token has access to.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/bankimportjobs/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"state": "completed",
"created": "2017-06-27T08:00:29Z",
"event": "sampleconf",
"transactions": [
{
"amount": "57.00",
"comment": "",
"date": "26.06.2017",
"payer": "John Doe",
"order": null,
"checksum": "5de03a601644dfa63420dacfd285565f8375a8f2",
"reference": "GUTSCHRIFT\r\nSAMPLECONF-NAB12 EREF: SAMPLECONF-NAB12\r\nIBAN: DE1234556…",
"state": "nomatch",
"message": ""
}
]
}
]
}
:query page: The page number in case of a multi-page result set, default is 1
:query event: Return only jobs for the event with the given slug
:query state: Return only jobs with the given state
:param organizer: The ``slug`` field of a valid organizer
: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)/bankimportjobs/(id)/
Returns information on one job, identified by its ID.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/bankimportjobs/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: text/javascript
{
"id": 1,
"state": "completed",
"created": "2017-06-27T08:00:29Z",
"event": "sampleconf",
"transactions": [
{
"amount": "57.00",
"comment": "",
"date": "26.06.2017",
"payer": "John Doe",
"order": null,
"checksum": "5de03a601644dfa63420dacfd285565f8375a8f2",
"reference": "GUTSCHRIFT\r\nSAMPLECONF-NAB12 EREF: SAMPLECONF-NAB12\r\nIBAN: DE1234556…",
"state": "nomatch",
"message": ""
}
]
}
:param organizer: The ``slug`` field of the organizer to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view it.
.. http:post:: /api/v1/organizers/(organizer)/bankimportjobs/
Upload a new job and execute it.
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/bigevents/bankimportjobs/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content-Type: application/json
{
"event": "sampleconf",
"transactions": [
{
"payer": "Foo",
"reference": "SAMPLECONF-173AS",
"amount": "23.00",
"date": "2017-06-26"
}
]
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 201 Created
Vary: Accept
Content-Type: text/javascript
{
"id": 1,
"state": "pending",
"created": "2017-06-27T08:00:29Z",
"event": "sampleconf",
"transactions": []
}
.. note:: Depending on the server configuration, the job might be executed immediately, leading to a longer API
response time but a response with state ``completed`` or ``error``, or the job might be put into a
background queue, leading to an immediate response of state ``pending`` with an empty list of
transactions.
:param organizer: The ``slug`` field of a valid organizer
:statuscode 201: no error
:statuscode 400: Invalid input
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to perform this action.
.. _pretix-banktool: https://github.com/pretix/pretix-banktool

View File

@@ -11,3 +11,4 @@ If you want to **create** a plugin, please go to the
list
pretixdroid
banktransfer

View File

@@ -15,20 +15,42 @@ ways that pretix itself is:
* PDF ticket output
The following plugins are not shipped with pretix but are maintained by the
same team:
same team. We update them regularly to make them compatible with the latest
pretix releases:
* `SEPA direct debit`_
* `Wirecard payment`_
* `Pages`_
* `Passbook/Wallet ticket output`_
* `Cartshare`_
* `Fontpack Free fonts`_
* `Mailing list subscription`_
The following closed-source plugins are available to customers of the hosted pretix.eu platform.
Please get in touch with the pretix team if you want to have them for your self-hosted
pretix installation:
* Campaign tracking
* Integration with Google Analytics and Facebook Pixel
* Integration with Slack
* Integration with MailChimp
The following plugins are from independent third-party authors, so we can make
no statements about their stability:
no statements about their functionality, security, stability or compatibility:
* `esPass ticket output`_
* `IcePay integration`_
* `Average price chart`_
* `Pay in cash upon arrival`_
.. _SEPA direct debit: https://github.com/pretix/pretix-sepadebit
.. _Passbook/Wallet ticket output: https://github.com/pretix/pretix-passbook
.. _Cartshare: https://github.com/pretix/pretix-cartshare
.. _Pages: https://github.com/pretix/pretix-pages
.. _esPass ticket output: https://github.com/esPass/pretix-espass
.. _IcePay integration: https://github.com/chotee/pretix-icepay
.. _Fontpack Free fonts: https://github.com/pretix/pretix-fontpack-free
.. _Wirecard payment: https://github.com/pretix/pretix-wirecard
.. _Mailing list subscription: https://github.com/pretix/pretix-newsletter-ml
.. _Average price chart: https://github.com/rixx/pretix-avgchart
.. _Pay in cash upon arrival: https://github.com/pc-coholic/pretix-cashpayment

View File

@@ -4,6 +4,11 @@ pretixdroid HTTP API
The pretixdroid plugin provides a HTTP API that the `pretixdroid Android app`_
uses to communicate with the pretix server.
.. warning:: This API is intended **only** to serve the pretixdroid Android app. There are no backwards compatibility
guarantees on this API. We will not add features that are not required for the Android App. There is a
general-purpose :ref:`rest-api` that not yet provides all features that this API provides, but will do
so in the future.
.. http:post:: /pretixdroid/api/(organizer)/(event)/redeem/
Redeems a ticket, i.e. checks the user in.
@@ -19,6 +24,16 @@ uses to communicate with the pretix server.
secret=az9u4mymhqktrbupmwkvv6xmgds5dk3
You can optionally include the additional parameter ``datetime`` in the body containing an ISO8601-encoded
datetime of the entry attempt. If you don't, the current date and time will be used.
You can optionally include the additional parameter ``force`` to indicate that the request should be logged
regardless of previous check-ins for the same ticket. This might be useful if you made the entry decision offline.
You can optionally include the additional parameter ``nonce`` with a globally unique random value to identify this
check-in. This is meant to be used to prevent duplicate check-ins when you are just retrying after a connection
failure.
**Example successful response**:
.. sourcecode:: http
@@ -51,9 +66,9 @@ uses to communicate with the pretix server.
* ``unknown_ticket`` - Secret does not match a ticket in the database
:query key: Secret API key
:statuscode 200: Valid request
:statuscode 404: Unknown organizer or event
:statuscode 403: Invalid authorization key
:statuscode 200: Valid request
:statuscode 404: Unknown organizer or event
:statuscode 403: Invalid authorization key
.. http:get:: /pretixdroid/api/(organizer)/(event)/search/
@@ -84,6 +99,7 @@ uses to communicate with the pretix server.
"variation": null,
"attendee_name": "Peter Higgs",
"redeemed": false,
"attention": false,
"paid": true
},
...
@@ -92,10 +108,51 @@ uses to communicate with the pretix server.
}
:query query: Search query
:query key: Secret API key
:statuscode 200: Valid request
:statuscode 404: Unknown organizer or event
:statuscode 403: Invalid authorization key
:query key: Secret API key
:statuscode 200: Valid request
:statuscode 404: Unknown organizer or event
:statuscode 403: Invalid authorization key
.. http:get:: /pretixdroid/api/(organizer)/(event)/download/
Download data for all tickets.
**Example request**:
.. sourcecode:: http
GET /pretixdroid/api/demoorga/democon/download/?key=ABCDEF HTTP/1.1
Host: demo.pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: text/json
{
"results": [
{
"secret": "az9u4mymhqktrbupmwkvv6xmgds5dk3",
"order": "ABCE6",
"item": "Standard ticket",
"variation": null,
"attendee_name": "Peter Higgs",
"redeemed": false,
"attention": false,
"paid": true
},
...
],
"version": 2
}
:query key: Secret API key
:statuscode 200: Valid request
:statuscode 404: Unknown organizer or event
:statuscode 403: Invalid authorization key
.. http:get:: /pretixdroid/api/(organizer)/(event)/status/

View File

@@ -2,3 +2,4 @@
sphinx
sphinx-rtd-theme
sphinxcontrib-httpdomain
sphinxcontrib-images

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,97 @@
Creating an event
=================
After you have created an organizer account, the next step is to create your event. An event is the basic object in
pretix that everything is organized around. One event corresponds to one ticket shop with all its products, quotas,
orders and settings.
To create an event, you can click the "Create a new event" tile on your dashboard or the button above the list of
events. You will then be presented with the first step of event creation:
.. thumbnail:: ../../screens/event/create_step1.png
:align: center
:class: screenshot
Here, you first need to decide for the organizer the event belongs to. You will not be able to change this
association later. This will determine default settings for the event, as well as access control to the event's
settings.
Second, you need to select the languages that the ticket shop should be available in. You can change this setting
later, but if you select it correctly now, it will automatically ask you for all descriptions in the respective
languages starting from the next step.
Last on this page, you can decide if this event represents an event series. In this cases, the event will turn into
multiple events included in once, meaning that you will get one combined ticket shop for multiple actual events. This
is useful if you have a large number of events that are very similar to each other and that should be sold together
(i.e. users should be able to buy tickets for multiple events at the same time). Those single events can differ in
available products, quotas, prices and some meta information, but most settings need to be the same for all of them.
We recommend to use this feature only if you really know that you need it and if you really run a lot of events, not if
you run e.g. a yearly conference.
Once you set these values, you can procede to the next step:
.. thumbnail:: ../../screens/event/create_step2.png
:align: center
:class: screenshot
In this step, you will be asked more detailled questions about your event. In particular, you can fill in the
following fields:
Name
This is the public name of your event. It should be descriptive and tell both you and the user which event you are
dealing with, but should still be concise. You probably know how your event is named already ;)
Short form
This will be used in multiple places. For example, the URL of your ticket shop will include this short form of
your event name, but it will also be the default prefix e.g. for invoice numbers. We recommend to use some natural
abbreviation of your event name, maybe together with a date, of no more than 10 characters. This is the only value
on this page that can't be changed later.
Event start time
The date and time that your event starts at. You can later configure settings to hide the time, if you don't want
to show that.
Event end time
The date and time your event ends at. You can later configure settings to hide this value completely -- or you can
just leave it empty. It's optional!
Location
This is the location of your event in a human-readable format. We will show this on the ticket shop frontpage, but
it might also be used e.g. in Wallet tickets.
Event currency
This is the currency all prices and payments in your shop will be handled in.
Sales tax rate
If you need to pay a form of sales tax (also known as VAT in many countries) on your products, you can set a tax rate
in percent here that will be used as a default later. After creating your event, you can also create multiple tax
rates or fine-tune the tax settings.
Default language
If you selected multiple supported languages in the previous step, you can now decide which one should be
displayed by default.
Start of presale
If you set this date, no ticket will be sold before this date. We normally recommend not to set this date during
event creation because it will make testing your shop harder.
End of presale
If you set this date, no ticket will be sold after this date.
If all of this is set, you can proceed to the next step. If this is your first event, there will not be a next step
and you are done! If you have already created events before, you will be asked if you want to copy settings from one
of them:
.. thumbnail:: ../../screens/event/create_step3.png
:align: center
:class: screenshot
If you do so, all products, categories, quotas and most settings of the other event will be taken over. You should
still review them if they make sense for your new event, but it could save you a lot of work. After this step, your
event is created successfully:
.. thumbnail:: ../../screens/event/create_step4.png
:align: center
:class: screenshot
You can now fine-tune all settings to your liking, publish your event and start selling tickets!

109
doc/user/events/taxes.rst Normal file
View File

@@ -0,0 +1,109 @@
Tax rules
=========
In most countries, you will be required to pay some form of sales tax for your event tickets. If you don't know about
the exact rules, you should consult a professional tax consultant right now.
To implement those taxes in pretix, you can create one or multiple "tax rules". A tax rule specifies when and at what
rate should be calculated on a product price. Taxes will then be correctly displayed in the product list, order
details and on invoices.
At the time of this writing, every product can be assigned exactly one tax rule. To view and change the tax rules of
your event, go to the respective section in your event's settings:
.. thumbnail:: ../../screens/event/tax_list.png
:align: center
:class: screenshot
On this page, you can create, edit and delete your tax rules. Clicking on the name of a tax rule will take you to its
detailled settings:
.. thumbnail:: ../../screens/event/tax_detail.png
:align: center
:class: screenshot
Here, you can tune the following parameters:
Name
What is the (short) name of this tax? This is probably "VAT" in English and should be very short as it will be
displayed in lots of places.
Rate
This is the tax rate in percent.
The configured product prices include the tax amount
If this setting is enabled (the default), then a product configured to a price of 10.00 EUR will, at a tax rate of
19.00 %, be interpreted as a product with a total gross price of 10.00 EUR including 1.60 EUR taxes, leading to a
net price of 8.40 EUR. If you disable this setting, the price will be interpreted as a net price of 10.00 EUR,
leading to a total price to pay of 11.90 EUR.
Use EU reverse charge taxation rules
This enables reverse charge taxation (see section below).
Merchant country
This is probably your country of residence, but in some cases it could also be the country your event is
located in. This is the place of taxation in the sense of EU reverse charge rules (see section below).
EU reverse charge
-----------------
.. warning:: Everything contained in this section is not legal advice. Please consult a tax consultant
before making decisions. We are not responsible for the correct handling of taxes in your
ticket shop.
"Reverse charge" is a rule in European VAT legislation that specifies how taxes are paid
if you provide goods to a buyer in a different European country than you reside in yourself.
If the buyer is a VAT-paying business in their country, you charge them only the net price without
taxes and state that the buyer is responsible for paying the correct taxes themselves.
.. warning:: We firmly believe that reverse charge rules are **not applicable** for most events handled
with pretix and therefore **strongly recommend not to enable this feature** if you do not have
a specific reason to do so. The reasoning behind this is that according to article 52 of the
`VAT directive`_ (page 17), the place of supply is always the location of your event and
therefore the tax rate of the event country always has to be paid regardless of the location
of the visitor.
If you enable the reverse charge feature and specify your merchant country, then the following process
will be performed during order creation:
* The user will first be presented with the "normal" prices (net or gross, as configured).
* The user adds a product to their cart. The cart will at this point always show gross prices *with*
taxes.
* In the next step, the user can enter an invoice address. Tax will be removed from the price if one of the
following statements is true:
* The invoice address is in a non-EU country.
* The invoice address is a business address in an EU-country different from the merchant country and has a valid VAT ID.
* In the second case, a reverse charge note will be added to the invoice.
VAT IDs are validated against the EUs validation web service. Should that service be unavailable, the user
needs to pay VAT tax and reclaim the taxes at a later point in time with their government.
If you and the buyer are residing in EU countries that use different currencies, the invoice will show
the total and VAT amount also in the local currency of the buyer, if the system was able to obtain a
conversion rate from the European Central Bank's webservice within the last 7 days.
For existing orders, a change of the invoice address will not result in a change of taxes automatically.
You can trigger this manually in the backend by going to the order's detail view. There, first click
the "Check" button next to the VAT ID. Then, go to "Change products" and select the option "Recalculate
taxes" at the end of the page.
.. note:: In the invoicing settings, you should turn the setting "Ask for VAT ID" on for this to work.
.. note:: During back-and-forth modification of taxation status, unfortunately there can be rounding
errors of usually up to one cent from the intended price. This is unavoidable due to the
flexible nature in which prices are being calculated.
Taxation of payment fees
------------------------
In the payment part of your event settings, you can choose the tax rule that needs to be applied for
payment method fees. This works in the same way as product prices, with the small difference that the
"configured product prices include the tax amount" settings is ignored and payment fees will always be
treated as gross values.
.. _VAT directive: http://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:32006L0112&from=EN

13
doc/user/index.rst Normal file
View File

@@ -0,0 +1,13 @@
User Guide
==========
This section of our documentation is dedicated to show you the way around pretix if you are an event organizer
wanting to use pretix to sell tickets.
.. toctree::
:maxdepth: 2
organizers/index
events/create
events/taxes
payments/index

View File

@@ -0,0 +1,112 @@
Organizer accounts and teams
============================
Organizer account
-----------------
The basis of all your operations within pretix is your organizer account. It represents an entity that is running
events, for example a company, yourself or any other institution.
Every event belongs to one organizer account and events within the same organizer account are assumed to belong together
in some sense, whereas events in different organizer accounts are completely isolated.
If you want to use the hosted pretix service, you can create an organizer account on our `Get started`_ page. Otherwise,
ask your pretix administrator for access to an organizer account.
You can find out all organizer accounts you have access to by going to your global dashboard (click on the pretix logo
in the top-left corner) and then select "Organizers" from the navigation bar on the left side. Then, choose one of the
organizer accounts presented, if there are multiple of them:
.. thumbnail:: ../../screens/organizer/list.png
:align: center
:class: screenshot
This overview shows you all event that belong to the organizer and you have access to:
.. thumbnail:: ../../screens/organizer/event_list.png
:align: center
:class: screenshot
With the "Edit" button at the top, next to the organizer account name, you can modify properties of the organizer
account such as its name and display settings for the public profile page of the organizer account:
.. thumbnail:: ../../screens/organizer/edit.png
:align: center
:class: screenshot
.. tip::
The profile page will be shown as ``https://pretix.eu/slug/`` where ``slug`` is to be replaced by the short form of
the organizer name that you entered during account creation and ``pretix.eu`` is to be replaced by your
installation's domain name if you are not using our hosted service.
Instead, you can also use a custom domain for the profile page and your events, for example
``https://tickets.example.com/`` if ``example.com`` is a domain that you own. In this case, please contact the pretix
hosted support or your system administrator to set up the custom domain.
Teams
-----
We don't expect you to work on your events all by yourself and therefore, pretix comes with ways to invite your fellow
team members to access your pretix organizer account. To manage teams, click on the "Teams" link on your organizer
settings page (see above how to find it). This shows you a list of teams that should contain at least one team already:
.. thumbnail:: ../../screens/organizer/team_list.png
:align: center
:class: screenshot
If you click on a team name, you get to a page that shows you the current members of the team:
.. thumbnail:: ../../screens/organizer/team_detail.png
:align: center
:class: screenshot
You see that there is a list of pretix user accounts (i.e. email addresses), who are part of the team. To add a user to
the team, just enter their email address in the text box next to the "Add" button. If the user already has an account
in the pretix system they will instantly get access to the team. Otherwise, they will be sent an email with an invitation
link that can be used to create an account. This account will then instantly have access to the team. Users can be part
of as many teams as you want.
In the section below, you can also create access tokens for our :ref:`rest-api`. You can read more on this topic in the
section :ref:`rest-auth` of the API documentation.
Next to the team name, you again see a button called "Edit" that allows you to modify the permissions of the team.
Permissions separate into two areas:
* **Organizer permissions** allow actions on the level of an organizer account, in particular:
* Can create events To create a new event under this organizer account, users need to have this permission
* 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.
* Can change organizer settings This permission is required to perform changes to the settings of the organizer
account, e.g. its name or display settings.
* **Event permissions** allow actions on the level of an event. You can give the team access to all events of the
organizer (including future ones that are not yet created) or just a selected set of events. The specific permissions to choose from are:
* Can change event settings This permission gives access to most areas of the control panel that are not controlled
by one of the other event permissions, especially those that are related to setting up and configuring the event.
* Can change product settings This permission allows to create and modify products and objects that are closely
related to products, such as product categories, quotas, and questions.
* Can view orders This permission allows viewing the list of orders and allindividual order details, but not
changing anything about it. This also includes the various exports offered.
* Can change orders This permission allows all actions that involve changing an order, such as changing the products
in an order, marking an order as paid or refunden, importing banking data, etc. This only works properly if the
same users also have the "Can view orders" permission.
* Can view vouchers This permission allows viewing the list of vouchers including the voucher codes themselves and
their redemption status.
* Can change vouchers This permission allows to create and modify vouchers in all their details. It only works
properly if the same users also have the "Can view vouchers" permission.
.. thumbnail:: ../../screens/organizer/team_edit.png
:align: center
:class: screenshot
.. _Get started: https://pretix.eu/about/en/setup

View File

@@ -0,0 +1,32 @@
.. _`banktransfer`:
Bank transfer
=============
To accept payments with bank transfer, you only need to fill out one important field in pretix' settings: In "Bank
account details" you should specify everything one needs to know to transfer money to you, e.g. your IBAN and BIC,
the name of your bank and for international transfers, preferably also your address and the bank's address.
pretix will automatically tell the user to include the order code in the payment reference so incoming transfers can
automatically be matched to payments.
Importing payment data
----------------------
The easiest way to import payment data is to download a CSV file from your online banking. Most banks provide a CSV
export of some sort. You can go to "Import bank data" in pretix to upload a new file:
.. image:: img/bank1.png
:class: screenshot
If you upload a file for the first time, pretix will not know what information is contained in which column as every
bank builds completely different CSV files. Therefore, pretix will ask you for that information. It will show you the
data of the file you imported and ask you to define the column's meanings. You can select one column that contains
the payment date and one that contains the paid amount. You can select multiple columns that contain information
about the payer or the payment reference. All other columns will be ignored.
Once you continue, pretix will try to match the payments to the respective orders automatically. It will tell you how
many orders could be processed correctly and how many could not. You can then go back to the upload page to see all
transfers from your bank statement that are not yet matched to an order. Using the input field and the buttons on the
left of each transaction, you can manually enter an order code to match it to or just discard it from the list, e.g.
if the transaction is not related to the event at all.

View File

@@ -0,0 +1,58 @@
Payment method fees
===================
Most external payment providers like PayPal or Stripe charge substantial fees for your service. In general, you have
two options to deal with this:
1. Pay the fees yourself
2. Add the fees to your customer's total
The choice totally depends on you and what your customers expect from you. Option two might be appropriate if you
offer different payment methods and want to encourage your customers to use the ones that come you cheaper, but you
might also decide to go for option one to make it easier for customers who don't have the option.
.. warning:: Please note that EU Directive 2015/2366 bans surcharging payment fees for most common payment
methods within the European Union. Depending on the payment method, this might affect
selling to consumers only or to business customers as well. Depending on your country, this
legislation might already be in place or become relevant from January 2018 the latest. This is not
legal advice. If in doubt, consult a lawyer or refrain from charging payment fees.
If you go for the second option, you can configure pretix to charge the payment method fees to your user. You can
define both an absolute fee as well as a percental fee based on the order total. If you do so, there are two
different ways in which pretix can calculate the fee. Normally, it is fine to just go with the default setting, but
in case you are interested, here are all the details:
Payment fee calculation
-----------------------
If you configure a fee for a payment method, there are two possible ways for us to calculate this. Let's
assume that your payment provider, e.g. PayPal, charges you 5 % fees and you want to charge your users the
same 5 %, such that for a ticket with a list price of 100 € you will get your full 100 €.
**Method A: Calculate the fee from the subtotal and add it to the bill.**
For a ticket price of 100 €, this will lead to the following calculation:
============================================== ============
Ticket price 100.00 €
pretix calculates the fee as 5 % of 100 € +5.00 €
Subtotal that will be paid by the customer 105.00 €
PayPal calculates its fee as 5 % of 105 € -5.25 €
End total that is on your bank account **99.75 €**
============================================== ============
**Method B (default): Calculate the fee from the total value including the fee.**
For a ticket price of 100 €, this will lead to the following calculation:
===================================================== =============
Ticket price 100.00 €
pretix calculates the fee as 100/(100 - 5) % of 100 € +5.26 €
Subtotal that will be paid by the customer 105.26 €
PayPal calculates its fee as 5 % of 105 € -5.26 €
End total that is on your bank account **100.00 €**
===================================================== =============
Due to the various rounding steps performed by pretix and by the payment provider, the end total on
your bank account might stil vary by one cent.

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Some files were not shown because too many files have changed in this diff Show More