forked from CGM_Public/pretix_original
Compare commits
126
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4da34d2977 | ||
|
|
2e6eb167e1 | ||
|
|
495bc3ecc9 | ||
|
|
8bb3a95ce6 | ||
|
|
c6c2c90908 | ||
|
|
d4ae7df2ec | ||
|
|
79dd7fb596 | ||
|
|
5ed87cd019 | ||
|
|
ccdcbe0cc5 | ||
|
|
4f8607a9db | ||
|
|
57ecaa2676 | ||
|
|
96fd2b1a95 | ||
|
|
5cf24fb6a6 | ||
|
|
1d2ea35a39 | ||
|
|
ac98ae7941 | ||
|
|
a0d055e202 | ||
|
|
27ec5ca006 | ||
|
|
9d2edc405d | ||
|
|
fb95fe7cf6 | ||
|
|
5b5360ef8b | ||
|
|
129d10ca35 | ||
|
|
093a705ff9 | ||
|
|
6130ae4630 | ||
|
|
11a8ed6c7a | ||
|
|
f6392592c5 | ||
|
|
ecb9ad28ea | ||
|
|
45a506fd37 | ||
|
|
3b16e6356b | ||
|
|
9583a50c4e | ||
|
|
6e6d6b2746 | ||
|
|
7266d90c6b | ||
|
|
5e4e88c91d | ||
|
|
e74d12e8b8 | ||
|
|
a5c39271dd | ||
|
|
3170744c56 | ||
|
|
9ec161561b | ||
|
|
aff4f4b8f8 | ||
|
|
75addfe9f4 | ||
|
|
4b05ce5835 | ||
|
|
34c247f423 | ||
|
|
3aad6852cb | ||
|
|
5cdb07bce6 | ||
|
|
6cb2d68948 | ||
|
|
4a7a6273c6 | ||
|
|
ebe343458a | ||
|
|
f9a93b765c | ||
|
|
5aba1f9a23 | ||
|
|
a4eed87396 | ||
|
|
08879d0d55 | ||
|
|
c276a19bcc | ||
|
|
1e3c6e0b68 | ||
|
|
4e283eb560 | ||
|
|
52a1983630 | ||
|
|
3d85d9d865 | ||
|
|
4ca9a43890 | ||
|
|
d8bac7db65 | ||
|
|
91de0f93e6 | ||
|
|
901565203b | ||
|
|
14c6c9c0d7 | ||
|
|
6de6cf6c08 | ||
|
|
29306b3a4d | ||
|
|
ca69996611 | ||
|
|
16419b6ae4 | ||
|
|
d6258b9b54 | ||
|
|
6f75608196 | ||
|
|
6ef88e009b | ||
|
|
957100a195 | ||
|
|
112ef0908f | ||
|
|
91aaff7359 | ||
|
|
8ab61e2c38 | ||
|
|
c8ba5cc427 | ||
|
|
5ebad31b7d | ||
|
|
0429377f7d | ||
|
|
76e4b797a1 | ||
|
|
5f0009c996 | ||
|
|
de63a4be01 | ||
|
|
f3432139cb | ||
|
|
0b82ac9115 | ||
|
|
eb685b5141 | ||
|
|
5f7f0bd8f1 | ||
|
|
9fcef2dcaa | ||
|
|
fc3b186b93 | ||
|
|
a406884575 | ||
|
|
57ccd5f289 | ||
|
|
f4ac7e7f65 | ||
|
|
81d7045b31 | ||
|
|
f9502a3212 | ||
|
|
a31f624417 | ||
|
|
3f99e0bece | ||
|
|
7e64f2b38a | ||
|
|
ee2bc93608 | ||
|
|
fb4bed9d0d | ||
|
|
aec75e4d0c | ||
|
|
e7e41470fb | ||
|
|
0aa9dda90a | ||
|
|
d97c983b6f | ||
|
|
6c957f31ca | ||
|
|
8e6b4b3ec7 | ||
|
|
b24de62f73 | ||
|
|
cdbd220a12 | ||
|
|
2f11aee512 | ||
|
|
8ea475ce39 | ||
|
|
b29bc9db96 | ||
|
|
6bd6694132 | ||
|
|
110e6e248e | ||
|
|
985f4d969d | ||
|
|
826bd07b01 | ||
|
|
3e4e86742a | ||
|
|
ef5fcde5d9 | ||
|
|
8f1d53d016 | ||
|
|
9ca1573fcf | ||
|
|
5795aa6492 | ||
|
|
6e0613a2af | ||
|
|
b43ed38483 | ||
|
|
f0fedf0001 | ||
|
|
19373b8f91 | ||
|
|
45fd13786a | ||
|
|
ae5111ee7e | ||
|
|
d8bf3065d0 | ||
|
|
54f077665c | ||
|
|
482a66c546 | ||
|
|
e4cef6e46b | ||
|
|
cbee1b71fe | ||
|
|
0cd1290624 | ||
|
|
565f5e2ea7 | ||
|
|
b46c0eba0c |
@@ -38,7 +38,7 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: sudo apt update && sudo apt install gettext unzip
|
run: sudo apt update && sudo apt install -y gettext unzip
|
||||||
- name: Install Python dependencies
|
- name: Install Python dependencies
|
||||||
run: pip3 install -U setuptools build pip check-manifest
|
run: pip3 install -U setuptools build pip check-manifest
|
||||||
- name: Run check-manifest
|
- name: Run check-manifest
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
- name: Install system packages
|
- name: Install system packages
|
||||||
run: sudo apt update && sudo apt install enchant-2 hunspell aspell-en
|
run: sudo apt update && sudo apt install -y enchant-2 hunspell aspell-en
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pip3 install -Ur requirements.txt
|
run: pip3 install -Ur requirements.txt
|
||||||
working-directory: ./doc
|
working-directory: ./doc
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
- name: Install system packages
|
- name: Install system packages
|
||||||
run: sudo apt update && sudo apt install gettext
|
run: sudo apt update && sudo apt -y install gettext
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pip3 install -e ".[dev]"
|
run: pip3 install uv && uv pip install --system -e ".[dev]"
|
||||||
- name: Compile messages
|
- name: Compile messages
|
||||||
run: python manage.py compilemessages
|
run: python manage.py compilemessages
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
- name: Install system packages
|
- name: Install system packages
|
||||||
run: sudo apt update && sudo apt install enchant-2 hunspell hunspell-de-de aspell-en aspell-de
|
run: sudo apt update && sudo apt install enchant-2 hunspell hunspell-de-de aspell-en aspell-de
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pip3 install -e ".[dev]"
|
run: pip3 install uv && uv pip install --system -e ".[dev]"
|
||||||
- name: Spellcheck translations
|
- name: Spellcheck translations
|
||||||
run: potypo
|
run: potypo
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pip3 install -e ".[dev]" psycopg2-binary
|
run: pip3 install uv && uv pip install --system -e ".[dev]" psycopg2-binary
|
||||||
- name: Run isort
|
- name: Run isort
|
||||||
run: isort -c .
|
run: isort -c .
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pip3 install -e ".[dev]" psycopg2-binary
|
run: pip3 install uv && uv pip install --system -e ".[dev]" psycopg2-binary
|
||||||
- name: Run flake8
|
- name: Run flake8
|
||||||
run: flake8 .
|
run: flake8 .
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
|
|||||||
+19
-14
@@ -22,7 +22,6 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
name: Tests
|
name: Tests
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.9", "3.10", "3.11"]
|
python-version: ["3.9", "3.10", "3.11"]
|
||||||
database: [sqlite, postgres]
|
database: [sqlite, postgres]
|
||||||
@@ -31,15 +30,21 @@ jobs:
|
|||||||
python-version: "3.9"
|
python-version: "3.9"
|
||||||
- database: sqlite
|
- database: sqlite
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15
|
||||||
|
env:
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_DB: pretix
|
||||||
|
options: >-
|
||||||
|
--health-cmd "pg_isready -U postgres -d pretix"
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: harmon758/postgresql-action@v1
|
|
||||||
with:
|
|
||||||
postgresql version: '15'
|
|
||||||
postgresql db: 'pretix'
|
|
||||||
postgresql user: 'postgres'
|
|
||||||
postgresql password: 'postgres'
|
|
||||||
if: matrix.database == 'postgres'
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
@@ -51,9 +56,9 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: sudo apt update && sudo apt install gettext
|
run: sudo apt update && sudo apt install -y gettext
|
||||||
- name: Install Python dependencies
|
- name: Install Python dependencies
|
||||||
run: pip3 install --ignore-requires-python -e ".[dev]" psycopg2-binary # We ignore that flake8 needs newer python as we don't run flake8 during tests
|
run: pip3 install uv && uv pip install --system -e ".[dev]" psycopg2-binary
|
||||||
- name: Run checks
|
- name: Run checks
|
||||||
run: python manage.py check
|
run: python manage.py check
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
@@ -65,15 +70,15 @@ jobs:
|
|||||||
run: make all compress
|
run: make all compress
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
run: PRETIX_CONFIG_FILE=tests/travis_${{ matrix.database }}.cfg py.test -vv -n 3 -p no:sugar --cov=./ --cov-report=xml --reruns 3 tests --maxfail=100
|
run: PRETIX_CONFIG_FILE=tests/ci_${{ matrix.database }}.cfg py.test -n 3 -p no:sugar --cov=./ --cov-report=xml tests --maxfail=100
|
||||||
- name: Run concurrency tests
|
- name: Run concurrency tests
|
||||||
working-directory: ./src
|
working-directory: ./src
|
||||||
run: PRETIX_CONFIG_FILE=tests/travis_${{ matrix.database }}.cfg py.test tests/concurrency_tests/ --reruns 0 --reuse-db
|
run: PRETIX_CONFIG_FILE=tests/ci_${{ matrix.database }}.cfg py.test tests/concurrency_tests/ --reuse-db
|
||||||
if: matrix.database == 'postgres'
|
if: matrix.database == 'postgres'
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: src/coverage.xml
|
file: src/coverage.xml
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: false
|
||||||
if: matrix.database == 'postgres' && matrix.python-version == '3.11'
|
if: matrix.database == 'postgres' && matrix.python-version == '3.11'
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ tests:
|
|||||||
- cd src
|
- cd src
|
||||||
- python manage.py check
|
- python manage.py check
|
||||||
- make all compress
|
- make all compress
|
||||||
- PRETIX_CONFIG_FILE=tests/travis_sqlite.cfg py.test --reruns 3 -n 3 tests --maxfail=100
|
- PRETIX_CONFIG_FILE=tests/ci_sqlite.cfg py.test -n 3 tests --maxfail=100
|
||||||
except:
|
except:
|
||||||
- pypi
|
- pypi
|
||||||
pypi:
|
pypi:
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ Endpoints
|
|||||||
"mode": "placed",
|
"mode": "placed",
|
||||||
"all_sales_channels": false,
|
"all_sales_channels": false,
|
||||||
"limit_sales_channels": ["web"],
|
"limit_sales_channels": ["web"],
|
||||||
"all_products": False,
|
"all_products": false,
|
||||||
"limit_products": [2, 3],
|
"limit_products": [2, 3],
|
||||||
"limit_variations": [456],
|
"limit_variations": [456],
|
||||||
"all_payment_methods": true,
|
"all_payment_methods": true,
|
||||||
@@ -113,7 +113,7 @@ Endpoints
|
|||||||
"mode": "placed",
|
"mode": "placed",
|
||||||
"all_sales_channels": false,
|
"all_sales_channels": false,
|
||||||
"limit_sales_channels": ["web"],
|
"limit_sales_channels": ["web"],
|
||||||
"all_products": False,
|
"all_products": false,
|
||||||
"limit_products": [2, 3],
|
"limit_products": [2, 3],
|
||||||
"limit_variations": [456],
|
"limit_variations": [456],
|
||||||
"all_payment_methods": true,
|
"all_payment_methods": true,
|
||||||
@@ -146,7 +146,7 @@ Endpoints
|
|||||||
"mode": "placed",
|
"mode": "placed",
|
||||||
"all_sales_channels": false,
|
"all_sales_channels": false,
|
||||||
"limit_sales_channels": ["web"],
|
"limit_sales_channels": ["web"],
|
||||||
"all_products": False,
|
"all_products": false,
|
||||||
"limit_products": [2, 3],
|
"limit_products": [2, 3],
|
||||||
"limit_variations": [456],
|
"limit_variations": [456],
|
||||||
"all_payment_methods": true,
|
"all_payment_methods": true,
|
||||||
@@ -167,7 +167,7 @@ Endpoints
|
|||||||
"mode": "placed",
|
"mode": "placed",
|
||||||
"all_sales_channels": false,
|
"all_sales_channels": false,
|
||||||
"limit_sales_channels": ["web"],
|
"limit_sales_channels": ["web"],
|
||||||
"all_products": False,
|
"all_products": false,
|
||||||
"limit_products": [2, 3],
|
"limit_products": [2, 3],
|
||||||
"limit_variations": [456],
|
"limit_variations": [456],
|
||||||
"all_payment_methods": true,
|
"all_payment_methods": true,
|
||||||
@@ -216,7 +216,7 @@ Endpoints
|
|||||||
"mode": "placed",
|
"mode": "placed",
|
||||||
"all_sales_channels": false,
|
"all_sales_channels": false,
|
||||||
"limit_sales_channels": ["web"],
|
"limit_sales_channels": ["web"],
|
||||||
"all_products": False,
|
"all_products": false,
|
||||||
"limit_products": [2, 3],
|
"limit_products": [2, 3],
|
||||||
"limit_variations": [456],
|
"limit_variations": [456],
|
||||||
"all_payment_methods": true,
|
"all_payment_methods": true,
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ subevent integer ID of the date
|
|||||||
position_count integer Number of tickets that match this list (read-only).
|
position_count integer Number of tickets that match this list (read-only).
|
||||||
checkin_count integer Number of check-ins performed on this list (read-only).
|
checkin_count integer Number of check-ins performed on this list (read-only).
|
||||||
include_pending boolean If ``true``, the check-in list also contains tickets from orders in pending state.
|
include_pending boolean If ``true``, the check-in list also contains tickets from orders in pending state.
|
||||||
auto_checkin_sales_channels list of strings All items on the check-in list will be automatically marked as checked-in when purchased through any of the listed sales channels.
|
|
||||||
**Deprecated, will be removed in pretix 2024.10.** Use :ref:`rest-autocheckinrules`: instead.
|
|
||||||
allow_multiple_entries boolean If ``true``, subsequent scans of a ticket on this list should not show a warning but instead be stored as an additional check-in.
|
allow_multiple_entries boolean If ``true``, subsequent scans of a ticket on this list should not show a warning but instead be stored as an additional check-in.
|
||||||
allow_entry_after_exit boolean If ``true``, subsequent scans of a ticket on this list are valid if the last scan of the ticket was an exit scan.
|
allow_entry_after_exit boolean If ``true``, subsequent scans of a ticket on this list are valid if the last scan of the ticket was an exit scan.
|
||||||
rules object Custom check-in logic. The contents of this field are currently not considered a stable API and modifications through the API are highly discouraged.
|
rules object Custom check-in logic. The contents of this field are currently not considered a stable API and modifications through the API are highly discouraged.
|
||||||
@@ -91,10 +89,7 @@ Endpoints
|
|||||||
"allow_entry_after_exit": true,
|
"allow_entry_after_exit": true,
|
||||||
"exit_all_at": null,
|
"exit_all_at": null,
|
||||||
"rules": {},
|
"rules": {},
|
||||||
"addon_match": false,
|
"addon_match": false
|
||||||
"auto_checkin_sales_channels": [
|
|
||||||
"pretixpos"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -146,10 +141,7 @@ Endpoints
|
|||||||
"allow_entry_after_exit": true,
|
"allow_entry_after_exit": true,
|
||||||
"exit_all_at": null,
|
"exit_all_at": null,
|
||||||
"rules": {},
|
"rules": {},
|
||||||
"addon_match": false,
|
"addon_match": false
|
||||||
"auto_checkin_sales_channels": [
|
|
||||||
"pretixpos"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to fetch
|
:param organizer: The ``slug`` field of the organizer to fetch
|
||||||
@@ -246,10 +238,7 @@ Endpoints
|
|||||||
"subevent": null,
|
"subevent": null,
|
||||||
"allow_multiple_entries": false,
|
"allow_multiple_entries": false,
|
||||||
"allow_entry_after_exit": true,
|
"allow_entry_after_exit": true,
|
||||||
"addon_match": false,
|
"addon_match": false
|
||||||
"auto_checkin_sales_channels": [
|
|
||||||
"pretixpos"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
**Example response**:
|
**Example response**:
|
||||||
@@ -271,10 +260,7 @@ Endpoints
|
|||||||
"subevent": null,
|
"subevent": null,
|
||||||
"allow_multiple_entries": false,
|
"allow_multiple_entries": false,
|
||||||
"allow_entry_after_exit": true,
|
"allow_entry_after_exit": true,
|
||||||
"addon_match": false,
|
"addon_match": false
|
||||||
"auto_checkin_sales_channels": [
|
|
||||||
"pretixpos"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer of the event/item to create a list for
|
:param organizer: The ``slug`` field of the organizer of the event/item to create a list for
|
||||||
@@ -326,10 +312,7 @@ Endpoints
|
|||||||
"subevent": null,
|
"subevent": null,
|
||||||
"allow_multiple_entries": false,
|
"allow_multiple_entries": false,
|
||||||
"allow_entry_after_exit": true,
|
"allow_entry_after_exit": true,
|
||||||
"addon_match": false,
|
"addon_match": false
|
||||||
"auto_checkin_sales_channels": [
|
|
||||||
"pretixpos"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to modify
|
:param organizer: The ``slug`` field of the organizer to modify
|
||||||
@@ -342,7 +325,7 @@ Endpoints
|
|||||||
|
|
||||||
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/checkinlist/(id)/
|
.. http:delete:: /api/v1/organizers/(organizer)/events/(event)/checkinlist/(id)/
|
||||||
|
|
||||||
Delete a check-in list. Note that this also deletes the information on all check-ins performed via this list.
|
Delete a check-in list. **Note that this also deletes the information on all check-ins performed via this list.**
|
||||||
|
|
||||||
**Example request**:
|
**Example request**:
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ url string The full URL to
|
|||||||
payments list of objects List of payment processes (see below)
|
payments list of objects List of payment processes (see below)
|
||||||
refunds list of objects List of refund processes (see below)
|
refunds list of objects List of refund processes (see below)
|
||||||
last_modified datetime Last modification of this object
|
last_modified datetime Last modification of this object
|
||||||
|
cancellation_date datetime Time of order cancellation (or ``null``). **Note**:
|
||||||
|
Will not be set for partial cancellations and is not
|
||||||
|
reliable for orders that have been cancelled,
|
||||||
|
reactivated and cancelled again.
|
||||||
===================================== ========================== =======================================================
|
===================================== ========================== =======================================================
|
||||||
|
|
||||||
|
|
||||||
@@ -151,6 +155,9 @@ last_modified datetime Last modificati
|
|||||||
|
|
||||||
The ``expires`` attribute can now be passed during order creation.
|
The ``expires`` attribute can now be passed during order creation.
|
||||||
|
|
||||||
|
.. versionchanged:: 2024.11
|
||||||
|
|
||||||
|
The ``cancellation_date`` attribute has been added and can also be used as an ordering key.
|
||||||
|
|
||||||
.. _order-position-resource:
|
.. _order-position-resource:
|
||||||
|
|
||||||
@@ -206,6 +213,17 @@ checkins list of objects List of **succe
|
|||||||
├ device integer Internal ID of the device. Can be ``null``. **Deprecated**, since this ID is not otherwise used in the API and is therefore not very useful.
|
├ device integer Internal ID of the device. Can be ``null``. **Deprecated**, since this ID is not otherwise used in the API and is therefore not very useful.
|
||||||
├ device_id integer Attribute ``device_id`` of the device. Can be ``null``.
|
├ device_id integer Attribute ``device_id`` of the device. Can be ``null``.
|
||||||
└ auto_checked_in boolean Indicates if this check-in been performed automatically by the system
|
└ auto_checked_in boolean Indicates if this check-in been performed automatically by the system
|
||||||
|
print_logs list of objects List of print jobs recorded e.g. by the pretix apps
|
||||||
|
├ id integer Internal ID of the print job
|
||||||
|
├ successful boolean Whether the print job successfully resulted in a print.
|
||||||
|
This is not expected to be 100 % reliable information (since
|
||||||
|
printer feedback is never perfect) and there is no guarantee
|
||||||
|
that unsuccessful jobs will be logged.
|
||||||
|
├ device_id integer Attribute ``device_id`` of the device that recorded the print. Can be ``null``.
|
||||||
|
├ datetime datetime Time of printing
|
||||||
|
├ source string Source of print job, e.g. name of the app used.
|
||||||
|
├ type string Type of print (currently ``badge``, ``ticket``, ``certificate``, or ``other``)
|
||||||
|
└ info object Additional data with client-dependent structure.
|
||||||
downloads list of objects List of ticket download options
|
downloads list of objects List of ticket download options
|
||||||
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
|
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
|
||||||
└ url string Download URL
|
└ url string Download URL
|
||||||
@@ -233,6 +251,10 @@ pdf_data object Data object req
|
|||||||
|
|
||||||
The attributes ``blocked``, ``valid_from`` and ``valid_until`` have been added.
|
The attributes ``blocked``, ``valid_from`` and ``valid_until`` have been added.
|
||||||
|
|
||||||
|
.. versionchanged:: 2024.9
|
||||||
|
|
||||||
|
The attribute ``print_logs`` has been added.
|
||||||
|
|
||||||
.. _order-payment-resource:
|
.. _order-payment-resource:
|
||||||
|
|
||||||
Order payment resource
|
Order payment resource
|
||||||
@@ -399,10 +421,21 @@ List of all orders
|
|||||||
"type": "entry",
|
"type": "entry",
|
||||||
"gate": null,
|
"gate": null,
|
||||||
"device": 2,
|
"device": 2,
|
||||||
|
"device_id": 1,
|
||||||
"datetime": "2017-12-25T12:45:23Z",
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
"auto_checked_in": false
|
"auto_checked_in": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"print_logs": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "badge",
|
||||||
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
|
"device_id": 1,
|
||||||
|
"source": "pretixSCAN",
|
||||||
|
"info": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
@@ -438,14 +471,15 @@ List of all orders
|
|||||||
"provider": "banktransfer"
|
"provider": "banktransfer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"refunds": []
|
"refunds": [],
|
||||||
|
"cancellation_date": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
: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``,
|
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``datetime``, ``code``,
|
||||||
``last_modified``, and ``status``. Default: ``datetime``
|
``last_modified``, ``status`` and ``cancellation_date``. Default: ``datetime``
|
||||||
:query string code: Only return orders that match the given order code
|
: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 status: Only return orders in the given order status (see above)
|
||||||
:query string search: Only return orders matching a given search query (matching for names, email addresses, and company names)
|
:query string search: Only return orders matching a given search query (matching for names, email addresses, and company names)
|
||||||
@@ -626,10 +660,22 @@ Fetching individual orders
|
|||||||
"type": "entry",
|
"type": "entry",
|
||||||
"gate": null,
|
"gate": null,
|
||||||
"device": 2,
|
"device": 2,
|
||||||
|
"device_id": 1,
|
||||||
"datetime": "2017-12-25T12:45:23Z",
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
"auto_checked_in": false
|
"auto_checked_in": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"print_logs": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "badge",
|
||||||
|
"successful": true,
|
||||||
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
|
"device_id": 1,
|
||||||
|
"source": "pretixSCAN",
|
||||||
|
"info": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
@@ -665,7 +711,8 @@ Fetching individual orders
|
|||||||
"provider": "banktransfer"
|
"provider": "banktransfer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"refunds": []
|
"refunds": [],
|
||||||
|
"cancellation_date": null
|
||||||
}
|
}
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to fetch
|
:param organizer: The ``slug`` field of the organizer to fetch
|
||||||
@@ -977,8 +1024,8 @@ Creating orders
|
|||||||
* ``internal_reference``
|
* ``internal_reference``
|
||||||
* ``vat_id``
|
* ``vat_id``
|
||||||
* ``vat_id_validated`` (optional) – If you need support for reverse charge (rarely the case), you need to check
|
* ``vat_id_validated`` (optional) – If you need support for reverse charge (rarely the case), you need to check
|
||||||
yourself if the passed VAT ID is a valid EU VAT ID. In that case, set this to ``true``. Only valid VAT IDs will
|
yourself if the passed VAT ID is a valid EU VAT ID. In that case, set this to ``true``. Only valid VAT IDs will
|
||||||
trigger reverse charge taxation. Don't forget to set ``is_business`` as well!
|
trigger reverse charge taxation. Don't forget to set ``is_business`` as well!
|
||||||
|
|
||||||
* ``positions``
|
* ``positions``
|
||||||
|
|
||||||
@@ -1581,10 +1628,22 @@ List of all order positions
|
|||||||
"type": "entry",
|
"type": "entry",
|
||||||
"gate": null,
|
"gate": null,
|
||||||
"device": 2,
|
"device": 2,
|
||||||
|
"device_id": 1,
|
||||||
"datetime": "2017-12-25T12:45:23Z",
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
"auto_checked_in": false
|
"auto_checked_in": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"print_logs": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "badge",
|
||||||
|
"successful": true,
|
||||||
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
|
"device_id": 1,
|
||||||
|
"source": "pretixSCAN",
|
||||||
|
"info": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
@@ -1695,10 +1754,22 @@ Fetching individual positions
|
|||||||
"type": "entry",
|
"type": "entry",
|
||||||
"gate": null,
|
"gate": null,
|
||||||
"device": 2,
|
"device": 2,
|
||||||
|
"device_id": 1,
|
||||||
"datetime": "2017-12-25T12:45:23Z",
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
"auto_checked_in": false
|
"auto_checked_in": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"print_logs": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "badge",
|
||||||
|
"successful": true,
|
||||||
|
"datetime": "2017-12-25T12:45:23Z",
|
||||||
|
"device_id": 1,
|
||||||
|
"source": "pretixSCAN",
|
||||||
|
"info": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"question": 12,
|
"question": 12,
|
||||||
@@ -1795,6 +1866,10 @@ Manipulating individual positions
|
|||||||
|
|
||||||
The endpoints to manage blocks have been added.
|
The endpoints to manage blocks have been added.
|
||||||
|
|
||||||
|
.. versionchanged:: 2024.9
|
||||||
|
|
||||||
|
The API now supports logging ticket and badge prints.
|
||||||
|
|
||||||
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/
|
.. http:patch:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/
|
||||||
|
|
||||||
Updates specific fields on an order position. Currently, only the following fields are supported:
|
Updates specific fields on an order position. Currently, only the following fields are supported:
|
||||||
@@ -2054,6 +2129,59 @@ Manipulating individual positions
|
|||||||
:statuscode 401: Authentication failure
|
:statuscode 401: Authentication failure
|
||||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to update this order position.
|
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to update this order position.
|
||||||
|
|
||||||
|
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/printlog/
|
||||||
|
|
||||||
|
Creates a print log, stating that this ticket has been printed.
|
||||||
|
|
||||||
|
**Example request**:
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
POST /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/printlog/ HTTP/1.1
|
||||||
|
Host: pretix.eu
|
||||||
|
Accept: application/json, text/javascript
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"datetime": "2024-09-19T13:37:00+02:00",
|
||||||
|
"source": "pretixPOS",
|
||||||
|
"type": "badge",
|
||||||
|
"info": {
|
||||||
|
"cashier": 1234
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
**Example response**:
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 201 Created
|
||||||
|
Vary: Accept
|
||||||
|
Content-Type: application/pdf
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": 1234,
|
||||||
|
"device_id": null,
|
||||||
|
"datetime": "2024-09-19T13:37:00+02:00",
|
||||||
|
"source": "pretixPOS",
|
||||||
|
"type": "badge",
|
||||||
|
"info": {
|
||||||
|
"cashier": 1234
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:param organizer: The ``slug`` field of the organizer to create a log for
|
||||||
|
:param event: The ``slug`` field of the event to create a log for
|
||||||
|
:param id: The ``id`` field of the order position to create a log for
|
||||||
|
:statuscode 201: 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** downloads are not available for this order position at this time. The response content will
|
||||||
|
contain more details.
|
||||||
|
:statuscode 404: The requested order position or download provider does not exist.
|
||||||
|
:statuscode 409: The file is not yet ready and will now be prepared. Retry the request after waiting for a few
|
||||||
|
seconds.
|
||||||
|
|
||||||
Changing order contents
|
Changing order contents
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ Endpoints for event exports
|
|||||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.
|
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.
|
||||||
|
|
||||||
Endpoints for organizer exports
|
Endpoints for organizer exports
|
||||||
---------------------------
|
-------------------------------
|
||||||
|
|
||||||
.. http:get:: /api/v1/organizers/(organizer)/scheduled_exports/
|
.. http:get:: /api/v1/organizers/(organizer)/scheduled_exports/
|
||||||
|
|
||||||
@@ -553,4 +553,4 @@ Endpoints for organizer exports
|
|||||||
:statuscode 403: The requested organizer does not exist **or** you have no permission to delete this resource.
|
:statuscode 403: The requested organizer does not exist **or** you have no permission to delete this resource.
|
||||||
|
|
||||||
|
|
||||||
.. _RFC 5545: https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.5.3
|
.. _RFC 5545: https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.5.3
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. _`rest-reusablemedia`:
|
.. _`rest-seats`:
|
||||||
|
|
||||||
Seats
|
Seats
|
||||||
=====
|
=====
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ First, you need to declare that you are using non-essential cookies by respondin
|
|||||||
signal:
|
signal:
|
||||||
|
|
||||||
.. automodule:: pretix.presale.signals
|
.. automodule:: pretix.presale.signals
|
||||||
|
:no-index:
|
||||||
:members: register_cookie_providers
|
:members: register_cookie_providers
|
||||||
|
|
||||||
You are expected to return a list of ``CookieProvider`` objects instantiated from the following class:
|
You are expected to return a list of ``CookieProvider`` objects instantiated from the following class:
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ Order events
|
|||||||
There are multiple signals that will be sent out in the ordering cycle:
|
There are multiple signals that will be sent out in the ordering cycle:
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: validate_cart, validate_cart_addons, validate_order, order_valid_if_pending, order_fee_calculation, order_paid, order_placed, order_canceled, order_reactivated, order_expired, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download, order_split, order_gracefully_delete, invoice_line_text
|
:members: validate_cart, validate_cart_addons, validate_order, order_valid_if_pending, order_fee_calculation, order_paid, order_placed, order_canceled, order_reactivated, order_expired, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download, order_split, order_gracefully_delete, invoice_line_text
|
||||||
|
|
||||||
Check-ins
|
Check-ins
|
||||||
"""""""""
|
"""""""""
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: checkin_created
|
:members: checkin_created
|
||||||
|
|
||||||
|
|
||||||
@@ -39,18 +41,21 @@ Frontend
|
|||||||
|
|
||||||
|
|
||||||
.. automodule:: pretix.presale.signals
|
.. automodule:: pretix.presale.signals
|
||||||
|
:no-index:
|
||||||
:members: order_info, order_info_top, order_meta_from_request, order_api_meta_from_request
|
:members: order_info, order_info_top, order_meta_from_request, order_api_meta_from_request
|
||||||
|
|
||||||
Request flow
|
Request flow
|
||||||
""""""""""""
|
""""""""""""
|
||||||
|
|
||||||
.. automodule:: pretix.presale.signals
|
.. automodule:: pretix.presale.signals
|
||||||
|
:no-index:
|
||||||
:members: process_request, process_response
|
:members: process_request, process_response
|
||||||
|
|
||||||
Vouchers
|
Vouchers
|
||||||
""""""""
|
""""""""
|
||||||
|
|
||||||
.. automodule:: pretix.presale.signals
|
.. automodule:: pretix.presale.signals
|
||||||
|
:no-index:
|
||||||
:members: voucher_redeem_info
|
:members: voucher_redeem_info
|
||||||
|
|
||||||
Backend
|
Backend
|
||||||
@@ -62,24 +67,28 @@ Backend
|
|||||||
item_formsets, order_search_filter_q, order_search_forms
|
item_formsets, order_search_filter_q, order_search_forms
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: logentry_display, logentry_object_link, requiredaction_display, timeline_events, orderposition_blocked_display, customer_created, customer_signed_in
|
:members: logentry_display, logentry_object_link, requiredaction_display, timeline_events, orderposition_blocked_display, customer_created, customer_signed_in
|
||||||
|
|
||||||
Vouchers
|
Vouchers
|
||||||
""""""""
|
""""""""
|
||||||
|
|
||||||
.. automodule:: pretix.control.signals
|
.. automodule:: pretix.control.signals
|
||||||
|
:no-index:
|
||||||
:members: item_forms, voucher_form_class, voucher_form_html, voucher_form_validation
|
:members: item_forms, voucher_form_class, voucher_form_html, voucher_form_validation
|
||||||
|
|
||||||
Dashboards
|
Dashboards
|
||||||
""""""""""
|
""""""""""
|
||||||
|
|
||||||
.. automodule:: pretix.control.signals
|
.. automodule:: pretix.control.signals
|
||||||
|
:no-index:
|
||||||
:members: event_dashboard_widgets, user_dashboard_widgets, event_dashboard_top
|
:members: event_dashboard_widgets, user_dashboard_widgets, event_dashboard_top
|
||||||
|
|
||||||
Ticket designs
|
Ticket designs
|
||||||
""""""""""""""
|
""""""""""""""
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: layout_text_variables, layout_image_variables
|
:members: layout_text_variables, layout_image_variables
|
||||||
|
|
||||||
.. automodule:: pretix.plugins.ticketoutputpdf.signals
|
.. automodule:: pretix.plugins.ticketoutputpdf.signals
|
||||||
@@ -89,4 +98,9 @@ API
|
|||||||
---
|
---
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: validate_event_settings, api_event_settings_fields
|
:members: validate_event_settings, api_event_settings_fields
|
||||||
|
|
||||||
|
.. automodule:: pretix.api.signals
|
||||||
|
:no-index:
|
||||||
|
:members: register_device_security_profile
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ that we'll provide in this plugin:
|
|||||||
Similar signals exist for other objects:
|
Similar signals exist for other objects:
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: voucher_import_columns
|
:members: voucher_import_columns
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,6 @@ convenient to you:
|
|||||||
|
|
||||||
.. automethod:: _register_fonts
|
.. automethod:: _register_fonts
|
||||||
|
|
||||||
.. automethod:: _register_event_fonts
|
|
||||||
|
|
||||||
.. automethod:: _on_first_page
|
.. automethod:: _on_first_page
|
||||||
|
|
||||||
.. automethod:: _on_other_page
|
.. automethod:: _on_other_page
|
||||||
|
|||||||
@@ -86,7 +86,10 @@ Signals
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: register_text_placeholders
|
:members: register_text_placeholders
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
|
:no-index:
|
||||||
:members: register_mail_placeholders
|
:members: register_mail_placeholders
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
KulturPass
|
KulturPass
|
||||||
=========
|
==========
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ expects and - more importantly - supports.
|
|||||||
for a sample configuration in an academic context.
|
for a sample configuration in an academic context.
|
||||||
|
|
||||||
Note, that you can have multiple attributes with the same ``friendlyName``
|
Note, that you can have multiple attributes with the same ``friendlyName``
|
||||||
but different ``name``s. This is often used in systems, where the same
|
but different ``name`` value. This is often used in systems, where the same
|
||||||
information (for example a persons name) is saved in different fields -
|
information (for example a persons name) is saved in different fields -
|
||||||
for example because one institution is returning SAML 1.0 and other
|
for example because one institution is returning SAML 1.0 and other
|
||||||
institutions are returning SAML 2.0 style attributes. Typically, this only
|
institutions are returning SAML 2.0 style attributes. Typically, this only
|
||||||
|
|||||||
+8
-10
@@ -29,7 +29,7 @@ dependencies = [
|
|||||||
"arabic-reshaper==3.0.0", # Support for Arabic in reportlab
|
"arabic-reshaper==3.0.0", # Support for Arabic in reportlab
|
||||||
"babel",
|
"babel",
|
||||||
"BeautifulSoup4==4.12.*",
|
"BeautifulSoup4==4.12.*",
|
||||||
"bleach==5.0.*",
|
"bleach==6.2.*",
|
||||||
"celery==5.4.*",
|
"celery==5.4.*",
|
||||||
"chardet==5.2.*",
|
"chardet==5.2.*",
|
||||||
"cryptography>=3.4.2",
|
"cryptography>=3.4.2",
|
||||||
@@ -43,7 +43,7 @@ dependencies = [
|
|||||||
"django-formset-js-improved==0.5.0.3",
|
"django-formset-js-improved==0.5.0.3",
|
||||||
"django-formtools==2.5.1",
|
"django-formtools==2.5.1",
|
||||||
"django-hierarkey==1.2.*",
|
"django-hierarkey==1.2.*",
|
||||||
"django-hijack==3.6.*",
|
"django-hijack==3.7.*",
|
||||||
"django-i18nfield==1.9.*,>=1.9.4",
|
"django-i18nfield==1.9.*,>=1.9.4",
|
||||||
"django-libsass==0.9",
|
"django-libsass==0.9",
|
||||||
"django-localflavor==4.0",
|
"django-localflavor==4.0",
|
||||||
@@ -74,26 +74,25 @@ dependencies = [
|
|||||||
"paypal-checkout-serversdk==1.0.*",
|
"paypal-checkout-serversdk==1.0.*",
|
||||||
"PyJWT==2.9.*",
|
"PyJWT==2.9.*",
|
||||||
"phonenumberslite==8.13.*",
|
"phonenumberslite==8.13.*",
|
||||||
"Pillow==10.4.*",
|
"Pillow==11.0.*",
|
||||||
"pretix-plugin-build",
|
"pretix-plugin-build",
|
||||||
"protobuf==5.28.*",
|
"protobuf==5.28.*",
|
||||||
"psycopg2-binary",
|
"psycopg2-binary",
|
||||||
"pycountry",
|
"pycountry",
|
||||||
"pycparser==2.22",
|
"pycparser==2.22",
|
||||||
"pycryptodome==3.21.*",
|
"pycryptodome==3.21.*",
|
||||||
"pypdf==5.0.*",
|
"pypdf==5.1.*",
|
||||||
"python-bidi==0.6.*", # Support for Arabic in reportlab
|
"python-bidi==0.6.*", # Support for Arabic in reportlab
|
||||||
"python-dateutil==2.9.*",
|
"python-dateutil==2.9.*",
|
||||||
"pytz",
|
"pytz",
|
||||||
"pytz-deprecation-shim==0.1.*",
|
"pytz-deprecation-shim==0.1.*",
|
||||||
"pyuca",
|
"pyuca",
|
||||||
"qrcode==8.0",
|
"qrcode==8.0",
|
||||||
"redis==5.1.*",
|
"redis==5.2.*",
|
||||||
"reportlab==4.2.*",
|
"reportlab==4.2.*",
|
||||||
"requests==2.31.*",
|
"requests==2.31.*",
|
||||||
"sentry-sdk==2.17.*",
|
"sentry-sdk==2.18.*",
|
||||||
"sepaxml==2.6.*",
|
"sepaxml==2.6.*",
|
||||||
"slimit",
|
|
||||||
"stripe==7.9.*",
|
"stripe==7.9.*",
|
||||||
"text-unidecode==1.*",
|
"text-unidecode==1.*",
|
||||||
"tlds>=2020041600",
|
"tlds>=2020041600",
|
||||||
@@ -102,7 +101,7 @@ dependencies = [
|
|||||||
"vat_moss_forked==2020.3.20.0.11.0",
|
"vat_moss_forked==2020.3.20.0.11.0",
|
||||||
"vobject==0.9.*",
|
"vobject==0.9.*",
|
||||||
"webauthn==2.2.*",
|
"webauthn==2.2.*",
|
||||||
"zeep==4.2.*"
|
"zeep==4.3.*"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
@@ -117,12 +116,11 @@ dev = [
|
|||||||
"isort==5.13.*",
|
"isort==5.13.*",
|
||||||
"pep8-naming==0.14.*",
|
"pep8-naming==0.14.*",
|
||||||
"potypo",
|
"potypo",
|
||||||
"pytest-asyncio",
|
"pytest-asyncio>=0.24",
|
||||||
"pytest-cache",
|
"pytest-cache",
|
||||||
"pytest-cov",
|
"pytest-cov",
|
||||||
"pytest-django==4.*",
|
"pytest-django==4.*",
|
||||||
"pytest-mock==3.14.*",
|
"pytest-mock==3.14.*",
|
||||||
"pytest-rerunfailures==14.*",
|
|
||||||
"pytest-sugar",
|
"pytest-sugar",
|
||||||
"pytest-xdist==3.6.*",
|
"pytest-xdist==3.6.*",
|
||||||
"pytest==8.3.*",
|
"pytest==8.3.*",
|
||||||
|
|||||||
@@ -19,4 +19,4 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
__version__ = "2024.10.0.dev0"
|
__version__ = "2024.11.0.dev0"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from rest_framework import exceptions
|
|||||||
from rest_framework.authentication import TokenAuthentication
|
from rest_framework.authentication import TokenAuthentication
|
||||||
|
|
||||||
from pretix.api.auth.devicesecurity import (
|
from pretix.api.auth.devicesecurity import (
|
||||||
DEVICE_SECURITY_PROFILES, FullAccessSecurityProfile,
|
FullAccessSecurityProfile, get_all_security_profiles,
|
||||||
)
|
)
|
||||||
from pretix.base.models import Device
|
from pretix.base.models import Device
|
||||||
|
|
||||||
@@ -58,7 +58,8 @@ class DeviceTokenAuthentication(TokenAuthentication):
|
|||||||
def authenticate(self, request):
|
def authenticate(self, request):
|
||||||
r = super().authenticate(request)
|
r = super().authenticate(request)
|
||||||
if r and isinstance(r[1], Device):
|
if r and isinstance(r[1], Device):
|
||||||
profile = DEVICE_SECURITY_PROFILES.get(r[1].security_profile, FullAccessSecurityProfile)
|
profiles = get_all_security_profiles()
|
||||||
|
profile = profiles.get(r[1].security_profile, FullAccessSecurityProfile())
|
||||||
if not profile.is_allowed(request):
|
if not profile.is_allowed(request):
|
||||||
raise exceptions.PermissionDenied('Request denied by device security profile.')
|
raise exceptions.PermissionDenied('Request denied by device security profile.')
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -20,13 +20,40 @@
|
|||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import logging
|
import logging
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from django.dispatch import receiver
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from pretix.api.signals import register_device_security_profile
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
_ALL_PROFILES = None
|
||||||
|
|
||||||
|
|
||||||
class FullAccessSecurityProfile:
|
class BaseSecurityProfile:
|
||||||
|
@property
|
||||||
|
def identifier(self) -> str:
|
||||||
|
"""
|
||||||
|
Unique identifier for this profile.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def verbose_name(self) -> str:
|
||||||
|
"""
|
||||||
|
Human-readable name (can be a ``gettext_lazy`` object).
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def is_allowed(self, request) -> bool:
|
||||||
|
"""
|
||||||
|
Return whether a given request should be allowed.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class FullAccessSecurityProfile(BaseSecurityProfile):
|
||||||
identifier = 'full'
|
identifier = 'full'
|
||||||
verbose_name = _('Full device access (reading and changing orders and gift cards, reading of products and settings)')
|
verbose_name = _('Full device access (reading and changing orders and gift cards, reading of products and settings)')
|
||||||
|
|
||||||
@@ -34,7 +61,7 @@ class FullAccessSecurityProfile:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class AllowListSecurityProfile:
|
class AllowListSecurityProfile(BaseSecurityProfile):
|
||||||
allowlist = ()
|
allowlist = ()
|
||||||
|
|
||||||
def is_allowed(self, request):
|
def is_allowed(self, request):
|
||||||
@@ -77,6 +104,7 @@ class PretixScanSecurityProfile(AllowListSecurityProfile):
|
|||||||
('GET', 'api-v1:blockedsecrets-list'),
|
('GET', 'api-v1:blockedsecrets-list'),
|
||||||
('GET', 'api-v1:order-list'),
|
('GET', 'api-v1:order-list'),
|
||||||
('GET', 'api-v1:orderposition-pdf_image'),
|
('GET', 'api-v1:orderposition-pdf_image'),
|
||||||
|
('POST', 'api-v1:orderposition-printlog'),
|
||||||
('GET', 'api-v1:event.settings'),
|
('GET', 'api-v1:event.settings'),
|
||||||
('POST', 'api-v1:upload'),
|
('POST', 'api-v1:upload'),
|
||||||
('POST', 'api-v1:checkinrpc.redeem'),
|
('POST', 'api-v1:checkinrpc.redeem'),
|
||||||
@@ -112,6 +140,7 @@ class PretixScanNoSyncNoSearchSecurityProfile(AllowListSecurityProfile):
|
|||||||
('GET', 'api-v1:revokedsecrets-list'),
|
('GET', 'api-v1:revokedsecrets-list'),
|
||||||
('GET', 'api-v1:blockedsecrets-list'),
|
('GET', 'api-v1:blockedsecrets-list'),
|
||||||
('GET', 'api-v1:orderposition-pdf_image'),
|
('GET', 'api-v1:orderposition-pdf_image'),
|
||||||
|
('POST', 'api-v1:orderposition-printlog'),
|
||||||
('GET', 'api-v1:event.settings'),
|
('GET', 'api-v1:event.settings'),
|
||||||
('POST', 'api-v1:upload'),
|
('POST', 'api-v1:upload'),
|
||||||
('POST', 'api-v1:checkinrpc.redeem'),
|
('POST', 'api-v1:checkinrpc.redeem'),
|
||||||
@@ -147,6 +176,7 @@ class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
|
|||||||
('GET', 'api-v1:revokedsecrets-list'),
|
('GET', 'api-v1:revokedsecrets-list'),
|
||||||
('GET', 'api-v1:blockedsecrets-list'),
|
('GET', 'api-v1:blockedsecrets-list'),
|
||||||
('GET', 'api-v1:orderposition-pdf_image'),
|
('GET', 'api-v1:orderposition-pdf_image'),
|
||||||
|
('POST', 'api-v1:orderposition-printlog'),
|
||||||
('GET', 'api-v1:event.settings'),
|
('GET', 'api-v1:event.settings'),
|
||||||
('POST', 'api-v1:upload'),
|
('POST', 'api-v1:upload'),
|
||||||
('POST', 'api-v1:checkinrpc.redeem'),
|
('POST', 'api-v1:checkinrpc.redeem'),
|
||||||
@@ -154,87 +184,28 @@ class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PretixPosSecurityProfile(AllowListSecurityProfile):
|
def get_all_security_profiles():
|
||||||
identifier = 'pretixpos'
|
global _ALL_PROFILES
|
||||||
verbose_name = _('pretixPOS')
|
|
||||||
allowlist = (
|
if _ALL_PROFILES:
|
||||||
('GET', 'api-v1:version'),
|
return _ALL_PROFILES
|
||||||
('GET', 'api-v1:device.eventselection'),
|
|
||||||
('GET', 'api-v1:idempotency.query'),
|
types = OrderedDict()
|
||||||
('GET', 'api-v1:device.info'),
|
for recv, ret in register_device_security_profile.send(None):
|
||||||
('POST', 'api-v1:device.update'),
|
if isinstance(ret, (list, tuple)):
|
||||||
('POST', 'api-v1:device.revoke'),
|
for r in ret:
|
||||||
('POST', 'api-v1:device.roll'),
|
types[r.identifier] = r
|
||||||
('GET', 'api-v1:event-list'),
|
else:
|
||||||
('GET', 'api-v1:event-detail'),
|
types[ret.identifier] = ret
|
||||||
('GET', 'api-v1:subevent-list'),
|
_ALL_PROFILES = types
|
||||||
('GET', 'api-v1:subevent-detail'),
|
return types
|
||||||
('GET', 'api-v1:itemcategory-list'),
|
|
||||||
('GET', 'api-v1:item-list'),
|
|
||||||
('GET', 'api-v1:question-list'),
|
|
||||||
('GET', 'api-v1:quota-list'),
|
|
||||||
('GET', 'api-v1:taxrule-list'),
|
|
||||||
('GET', 'api-v1:ticketlayout-list'),
|
|
||||||
('GET', 'api-v1:ticketlayoutitem-list'),
|
|
||||||
('GET', 'api-v1:badgelayout-list'),
|
|
||||||
('GET', 'api-v1:badgeitem-list'),
|
|
||||||
('GET', 'api-v1:voucher-list'),
|
|
||||||
('GET', 'api-v1:voucher-detail'),
|
|
||||||
('GET', 'api-v1:order-list'),
|
|
||||||
('POST', 'api-v1:order-list'),
|
|
||||||
('GET', 'api-v1:order-detail'),
|
|
||||||
('DELETE', 'api-v1:orderposition-detail'),
|
|
||||||
('PATCH', 'api-v1:orderposition-detail'),
|
|
||||||
('GET', 'api-v1:orderposition-list'),
|
|
||||||
('GET', 'api-v1:orderposition-answer'),
|
|
||||||
('GET', 'api-v1:orderposition-pdf_image'),
|
|
||||||
('POST', 'api-v1:order-mark-canceled'),
|
|
||||||
('POST', 'api-v1:orderpayment-list'),
|
|
||||||
('POST', 'api-v1:orderrefund-list'),
|
|
||||||
('POST', 'api-v1:orderrefund-done'),
|
|
||||||
('POST', 'api-v1:cartposition-list'),
|
|
||||||
('POST', 'api-v1:cartposition-bulk-create'),
|
|
||||||
('GET', 'api-v1:checkinlist-list'),
|
|
||||||
('POST', 'api-v1:checkinlistpos-redeem'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:order.posprintlog'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:order.poslock'),
|
|
||||||
('DELETE', 'plugins:pretix_posbackend:order.poslock'),
|
|
||||||
('DELETE', 'api-v1:cartposition-detail'),
|
|
||||||
('GET', 'api-v1:giftcard-list'),
|
|
||||||
('POST', 'api-v1:giftcard-transact'),
|
|
||||||
('PATCH', 'api-v1:giftcard-detail'),
|
|
||||||
('GET', 'plugins:pretix_posbackend:posclosing-list'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:posreceipt-list'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:posclosing-list'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:posdebugdump-list'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:posdebuglogentry-list'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:posdebuglogentry-bulk-create'),
|
|
||||||
('GET', 'plugins:pretix_posbackend:poscashier-list'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:stripeterminal.token'),
|
|
||||||
('POST', 'plugins:pretix_posbackend:stripeterminal.paymentintent'),
|
|
||||||
('PUT', 'plugins:pretix_posbackend:file.upload'),
|
|
||||||
('GET', 'api-v1:revokedsecrets-list'),
|
|
||||||
('GET', 'api-v1:blockedsecrets-list'),
|
|
||||||
('GET', 'api-v1:event.settings'),
|
|
||||||
('GET', 'plugins:pretix_seating:event.event'),
|
|
||||||
('GET', 'plugins:pretix_seating:event.event.subevent'),
|
|
||||||
('GET', 'plugins:pretix_seating:event.plan'),
|
|
||||||
('GET', 'plugins:pretix_seating:selection.simple'),
|
|
||||||
('POST', 'api-v1:upload'),
|
|
||||||
('POST', 'api-v1:checkinrpc.redeem'),
|
|
||||||
('GET', 'api-v1:checkinrpc.search'),
|
|
||||||
('POST', 'api-v1:reusablemedium-lookup'),
|
|
||||||
('GET', 'api-v1:reusablemedium-list'),
|
|
||||||
('POST', 'api-v1:reusablemedium-list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
DEVICE_SECURITY_PROFILES = {
|
@receiver(register_device_security_profile, dispatch_uid="base_register_default_security_profiles")
|
||||||
k.identifier: k() for k in (
|
def register_default_webhook_events(sender, **kwargs):
|
||||||
FullAccessSecurityProfile,
|
return (
|
||||||
PretixScanSecurityProfile,
|
FullAccessSecurityProfile(),
|
||||||
PretixScanNoSyncSecurityProfile,
|
PretixScanSecurityProfile(),
|
||||||
PretixScanNoSyncNoSearchSecurityProfile,
|
PretixScanNoSyncSecurityProfile(),
|
||||||
PretixPosSecurityProfile,
|
PretixScanNoSyncNoSearchSecurityProfile(),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ class CartPositionCreateSerializer(BaseCartPositionCreateSerializer):
|
|||||||
return cid
|
return cid
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
validated_data.pop('sales_channel')
|
validated_data.pop('sales_channel', None)
|
||||||
addons_data = validated_data.pop('addons', None)
|
addons_data = validated_data.pop('addons', None)
|
||||||
bundled_data = validated_data.pop('bundled', None)
|
bundled_data = validated_data.pop('bundled', None)
|
||||||
|
|
||||||
|
|||||||
@@ -26,31 +26,22 @@ from rest_framework.exceptions import ValidationError
|
|||||||
from pretix.api.serializers.event import SubEventSerializer
|
from pretix.api.serializers.event import SubEventSerializer
|
||||||
from pretix.api.serializers.i18n import I18nAwareModelSerializer
|
from pretix.api.serializers.i18n import I18nAwareModelSerializer
|
||||||
from pretix.base.media import MEDIA_TYPES
|
from pretix.base.media import MEDIA_TYPES
|
||||||
from pretix.base.models import Checkin, CheckinList, SalesChannel
|
from pretix.base.models import Checkin, CheckinList
|
||||||
|
|
||||||
|
|
||||||
class CheckinListSerializer(I18nAwareModelSerializer):
|
class CheckinListSerializer(I18nAwareModelSerializer):
|
||||||
checkin_count = serializers.IntegerField(read_only=True)
|
checkin_count = serializers.IntegerField(read_only=True)
|
||||||
position_count = serializers.IntegerField(read_only=True)
|
position_count = serializers.IntegerField(read_only=True)
|
||||||
auto_checkin_sales_channels = serializers.SlugRelatedField(
|
|
||||||
slug_field="identifier",
|
|
||||||
queryset=SalesChannel.objects.none(),
|
|
||||||
required=False,
|
|
||||||
allow_empty=True,
|
|
||||||
many=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CheckinList
|
model = CheckinList
|
||||||
fields = ('id', 'name', 'all_products', 'limit_products', 'subevent', 'checkin_count', 'position_count',
|
fields = ('id', 'name', 'all_products', 'limit_products', 'subevent', 'checkin_count', 'position_count',
|
||||||
'include_pending', 'auto_checkin_sales_channels', 'allow_multiple_entries', 'allow_entry_after_exit',
|
'include_pending', 'allow_multiple_entries', 'allow_entry_after_exit',
|
||||||
'rules', 'exit_all_at', 'addon_match', 'ignore_in_statistics', 'consider_tickets_used')
|
'rules', 'exit_all_at', 'addon_match', 'ignore_in_statistics', 'consider_tickets_used')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.fields['auto_checkin_sales_channels'].child_relation.queryset = self.context['event'].organizer.sales_channels.all()
|
|
||||||
|
|
||||||
if 'subevent' in self.context['request'].query_params.getlist('expand'):
|
if 'subevent' in self.context['request'].query_params.getlist('expand'):
|
||||||
self.fields['subevent'] = SubEventSerializer(read_only=True)
|
self.fields['subevent'] = SubEventSerializer(read_only=True)
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ from pretix.base.models import (
|
|||||||
)
|
)
|
||||||
from pretix.base.models.orders import (
|
from pretix.base.models.orders import (
|
||||||
BlockedTicketSecret, CartPosition, OrderFee, OrderPayment, OrderRefund,
|
BlockedTicketSecret, CartPosition, OrderFee, OrderPayment, OrderRefund,
|
||||||
RevokedTicketSecret,
|
PrintLog, RevokedTicketSecret,
|
||||||
)
|
)
|
||||||
from pretix.base.pdf import get_images, get_variables
|
from pretix.base.pdf import get_images, get_variables
|
||||||
from pretix.base.services.cart import error_messages
|
from pretix.base.services.cart import error_messages
|
||||||
@@ -284,6 +284,26 @@ class CheckinSerializer(I18nAwareModelSerializer):
|
|||||||
fields = ('id', 'datetime', 'list', 'auto_checked_in', 'gate', 'device', 'device_id', 'type')
|
fields = ('id', 'datetime', 'list', 'auto_checked_in', 'gate', 'device', 'device_id', 'type')
|
||||||
|
|
||||||
|
|
||||||
|
class PrintLogSerializer(serializers.ModelSerializer):
|
||||||
|
device_id = serializers.SlugRelatedField(
|
||||||
|
source='device',
|
||||||
|
slug_field='device_id',
|
||||||
|
read_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = PrintLog
|
||||||
|
fields = (
|
||||||
|
"id",
|
||||||
|
"successful",
|
||||||
|
"datetime",
|
||||||
|
"source",
|
||||||
|
"type",
|
||||||
|
"device_id",
|
||||||
|
"info",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FailedCheckinSerializer(I18nAwareModelSerializer):
|
class FailedCheckinSerializer(I18nAwareModelSerializer):
|
||||||
error_reason = serializers.ChoiceField(choices=Checkin.REASONS, required=True, allow_null=False)
|
error_reason = serializers.ChoiceField(choices=Checkin.REASONS, required=True, allow_null=False)
|
||||||
raw_barcode = serializers.CharField(required=True, allow_null=False)
|
raw_barcode = serializers.CharField(required=True, allow_null=False)
|
||||||
@@ -476,6 +496,7 @@ class OrderPositionListSerializer(serializers.ListSerializer):
|
|||||||
|
|
||||||
class OrderPositionSerializer(I18nAwareModelSerializer):
|
class OrderPositionSerializer(I18nAwareModelSerializer):
|
||||||
checkins = CheckinSerializer(many=True, read_only=True)
|
checkins = CheckinSerializer(many=True, read_only=True)
|
||||||
|
print_logs = PrintLogSerializer(many=True, read_only=True)
|
||||||
answers = AnswerSerializer(many=True)
|
answers = AnswerSerializer(many=True)
|
||||||
downloads = PositionDownloadsField(source='*', read_only=True)
|
downloads = PositionDownloadsField(source='*', read_only=True)
|
||||||
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
|
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
|
||||||
@@ -490,7 +511,7 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
|
|||||||
fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts',
|
fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts',
|
||||||
'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount',
|
'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount',
|
||||||
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
||||||
'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled',
|
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled',
|
||||||
'valid_from', 'valid_until', 'blocked', 'voucher_budget_use')
|
'valid_from', 'valid_until', 'blocked', 'voucher_budget_use')
|
||||||
read_only_fields = (
|
read_only_fields = (
|
||||||
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
|
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
|
||||||
@@ -577,9 +598,9 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
|
|||||||
fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts',
|
fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts',
|
||||||
'company', 'street', 'zipcode', 'city', 'country', 'state',
|
'company', 'street', 'zipcode', 'city', 'country', 'state',
|
||||||
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
||||||
'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'require_attention',
|
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat',
|
||||||
'order__status', 'order__valid_if_pending', 'order__require_approval', 'valid_from', 'valid_until',
|
'require_attention', 'order__status', 'order__valid_if_pending', 'order__require_approval',
|
||||||
'blocked')
|
'valid_from', 'valid_until', 'blocked')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@@ -732,12 +753,12 @@ class OrderSerializer(I18nAwareModelSerializer):
|
|||||||
'code', 'event', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date',
|
'code', 'event', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date',
|
||||||
'payment_provider', 'fees', 'total', 'comment', 'custom_followup_at', 'invoice_address', 'positions', 'downloads',
|
'payment_provider', 'fees', 'total', 'comment', 'custom_followup_at', 'invoice_address', 'positions', 'downloads',
|
||||||
'checkin_attention', 'checkin_text', 'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel',
|
'checkin_attention', 'checkin_text', 'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel',
|
||||||
'url', 'customer', 'valid_if_pending', 'api_meta'
|
'url', 'customer', 'valid_if_pending', 'api_meta', 'cancellation_date'
|
||||||
)
|
)
|
||||||
read_only_fields = (
|
read_only_fields = (
|
||||||
'code', 'status', 'testmode', 'secret', 'datetime', 'expires', 'payment_date',
|
'code', 'status', 'testmode', 'secret', 'datetime', 'expires', 'payment_date',
|
||||||
'payment_provider', 'fees', 'total', 'positions', 'downloads', 'customer',
|
'payment_provider', 'fees', 'total', 'positions', 'downloads', 'customer',
|
||||||
'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel'
|
'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel', 'cancellation_date'
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -1494,6 +1515,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
|
|||||||
pos.answers = answers
|
pos.answers = answers
|
||||||
pos.pseudonymization_id = "PREVIEW"
|
pos.pseudonymization_id = "PREVIEW"
|
||||||
pos.checkins = []
|
pos.checkins = []
|
||||||
|
pos.print_logs = []
|
||||||
pos_map[pos.positionid] = pos
|
pos_map[pos.positionid] = pos
|
||||||
else:
|
else:
|
||||||
if pos.voucher:
|
if pos.voucher:
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError
|
||||||
|
|
||||||
|
from pretix.api.auth.devicesecurity import get_all_security_profiles
|
||||||
from pretix.api.serializers import AsymmetricField
|
from pretix.api.serializers import AsymmetricField
|
||||||
from pretix.api.serializers.i18n import I18nAwareModelSerializer
|
from pretix.api.serializers.i18n import I18nAwareModelSerializer
|
||||||
from pretix.api.serializers.order import CompatibleJSONField
|
from pretix.api.serializers.order import CompatibleJSONField
|
||||||
@@ -297,6 +298,7 @@ class DeviceSerializer(serializers.ModelSerializer):
|
|||||||
revoked = serializers.BooleanField(read_only=True)
|
revoked = serializers.BooleanField(read_only=True)
|
||||||
initialized = serializers.DateTimeField(read_only=True)
|
initialized = serializers.DateTimeField(read_only=True)
|
||||||
initialization_token = serializers.DateTimeField(read_only=True)
|
initialization_token = serializers.DateTimeField(read_only=True)
|
||||||
|
security_profile = serializers.ChoiceField(choices=[], required=False, default="full")
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Device
|
model = Device
|
||||||
@@ -306,6 +308,10 @@ class DeviceSerializer(serializers.ModelSerializer):
|
|||||||
'os_name', 'os_version', 'software_brand', 'software_version', 'security_profile'
|
'os_name', 'os_version', 'software_brand', 'software_version', 'security_profile'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['security_profile'].choices = [(k, v.verbose_name) for k, v in get_all_security_profiles().items()]
|
||||||
|
|
||||||
|
|
||||||
class TeamInviteSerializer(serializers.ModelSerializer):
|
class TeamInviteSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@@ -32,10 +32,17 @@ from pretix.helpers.periodic import minimum_interval
|
|||||||
register_webhook_events = Signal()
|
register_webhook_events = Signal()
|
||||||
"""
|
"""
|
||||||
This signal is sent out to get all known webhook events. Receivers should return an
|
This signal is sent out to get all known webhook events. Receivers should return an
|
||||||
instance of a subclass of pretix.api.webhooks.WebhookEvent or a list of such
|
instance of a subclass of ``pretix.api.webhooks.WebhookEvent`` or a list of such
|
||||||
instances.
|
instances.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
register_device_security_profile = Signal()
|
||||||
|
"""
|
||||||
|
This signal is sent out to get all known device security_profiles. Receivers should
|
||||||
|
return an instance of a subclass of ``pretix.api.auth.devicesecurity.BaseSecurityProfile``
|
||||||
|
or a list of such instances.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@receiver(periodic_task)
|
@receiver(periodic_task)
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ from pretix.base.models import (
|
|||||||
CachedFile, Checkin, CheckinList, Device, Event, Order, OrderPosition,
|
CachedFile, Checkin, CheckinList, Device, Event, Order, OrderPosition,
|
||||||
Question, ReusableMedium, RevokedTicketSecret, TeamAPIToken,
|
Question, ReusableMedium, RevokedTicketSecret, TeamAPIToken,
|
||||||
)
|
)
|
||||||
|
from pretix.base.models.orders import PrintLog
|
||||||
from pretix.base.services.checkin import (
|
from pretix.base.services.checkin import (
|
||||||
CheckInError, RequiredQuestionsError, SQLLogic, perform_checkin,
|
CheckInError, RequiredQuestionsError, SQLLogic, perform_checkin,
|
||||||
)
|
)
|
||||||
@@ -115,7 +116,7 @@ class CheckinListViewSet(viewsets.ModelViewSet):
|
|||||||
if 'subevent' in self.request.query_params.getlist('expand'):
|
if 'subevent' in self.request.query_params.getlist('expand'):
|
||||||
qs = qs.prefetch_related(
|
qs = qs.prefetch_related(
|
||||||
'subevent', 'subevent__event', 'subevent__subeventitem_set', 'subevent__subeventitemvariation_set',
|
'subevent', 'subevent__event', 'subevent__subeventitem_set', 'subevent__subeventitemvariation_set',
|
||||||
'subevent__seat_category_mappings', 'subevent__meta_values', 'auto_checkin_sales_channels'
|
'subevent__seat_category_mappings', 'subevent__meta_values',
|
||||||
)
|
)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
@@ -142,7 +143,9 @@ class CheckinListViewSet(viewsets.ModelViewSet):
|
|||||||
data=self.request.data
|
data=self.request.data
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
def perform_destroy(self, instance):
|
def perform_destroy(self, instance):
|
||||||
|
instance.checkins.all().delete()
|
||||||
instance.log_action(
|
instance.log_action(
|
||||||
'pretix.event.checkinlist.deleted',
|
'pretix.event.checkinlist.deleted',
|
||||||
user=self.request.user,
|
user=self.request.user,
|
||||||
@@ -365,8 +368,9 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
|||||||
qs = qs.prefetch_related(
|
qs = qs.prefetch_related(
|
||||||
Prefetch(
|
Prefetch(
|
||||||
lookup='checkins',
|
lookup='checkins',
|
||||||
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists])
|
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists]).select_related('device')
|
||||||
),
|
),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
'answers', 'answers__options', 'answers__question',
|
'answers', 'answers__options', 'answers__question',
|
||||||
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation')),
|
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation')),
|
||||||
Prefetch('order', Order.objects.select_related('invoice_address').prefetch_related(
|
Prefetch('order', Order.objects.select_related('invoice_address').prefetch_related(
|
||||||
@@ -378,6 +382,7 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
|||||||
'positions',
|
'positions',
|
||||||
OrderPosition.objects.prefetch_related(
|
OrderPosition.objects.prefetch_related(
|
||||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
'item', 'variation', 'answers', 'answers__options', 'answers__question',
|
'item', 'variation', 'answers', 'answers__options', 'answers__question',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -389,8 +394,9 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
|||||||
qs = qs.prefetch_related(
|
qs = qs.prefetch_related(
|
||||||
Prefetch(
|
Prefetch(
|
||||||
lookup='checkins',
|
lookup='checkins',
|
||||||
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists])
|
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists]).select_related('device')
|
||||||
),
|
),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
'answers', 'answers__options', 'answers__question',
|
'answers', 'answers__options', 'answers__question',
|
||||||
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation'))
|
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation'))
|
||||||
).select_related('item', 'variation', 'order', 'addon_to', 'order__invoice_address', 'order', 'seat')
|
).select_related('item', 'variation', 'order', 'addon_to', 'order__invoice_address', 'order', 'seat')
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import base64
|
import base64
|
||||||
|
import copy
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from cryptography.hazmat.backends.openssl.backend import Backend
|
from cryptography.hazmat.backends.openssl.backend import Backend
|
||||||
@@ -146,6 +147,8 @@ class InitializeView(APIView):
|
|||||||
permission_classes = ()
|
permission_classes = ()
|
||||||
|
|
||||||
def post(self, request, format=None):
|
def post(self, request, format=None):
|
||||||
|
from pretix.base.signals import device_info_updated
|
||||||
|
|
||||||
serializer = InitializationRequestSerializer(data=request.data)
|
serializer = InitializationRequestSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
@@ -160,6 +163,8 @@ class InitializeView(APIView):
|
|||||||
if device.revoked:
|
if device.revoked:
|
||||||
raise ValidationError({'token': ['This initialization token has been revoked.']})
|
raise ValidationError({'token': ['This initialization token has been revoked.']})
|
||||||
|
|
||||||
|
old_instance = copy.copy(device)
|
||||||
|
|
||||||
device.initialized = now()
|
device.initialized = now()
|
||||||
device.hardware_brand = serializer.validated_data.get('hardware_brand')
|
device.hardware_brand = serializer.validated_data.get('hardware_brand')
|
||||||
device.hardware_model = serializer.validated_data.get('hardware_model')
|
device.hardware_model = serializer.validated_data.get('hardware_model')
|
||||||
@@ -174,6 +179,10 @@ class InitializeView(APIView):
|
|||||||
|
|
||||||
device.log_action('pretix.device.initialized', data=serializer.validated_data, auth=device)
|
device.log_action('pretix.device.initialized', data=serializer.validated_data, auth=device)
|
||||||
|
|
||||||
|
device_info_updated.send(
|
||||||
|
sender=Device, old_device=old_instance, new_device=device
|
||||||
|
)
|
||||||
|
|
||||||
serializer = DeviceSerializer(device)
|
serializer = DeviceSerializer(device)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
@@ -182,9 +191,12 @@ class UpdateView(APIView):
|
|||||||
authentication_classes = (DeviceTokenAuthentication,)
|
authentication_classes = (DeviceTokenAuthentication,)
|
||||||
|
|
||||||
def post(self, request, format=None):
|
def post(self, request, format=None):
|
||||||
|
from pretix.base.signals import device_info_updated
|
||||||
|
|
||||||
serializer = UpdateRequestSerializer(data=request.data)
|
serializer = UpdateRequestSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
device = request.auth
|
device = request.auth
|
||||||
|
old_instance = copy.copy(device)
|
||||||
device.hardware_brand = serializer.validated_data.get('hardware_brand')
|
device.hardware_brand = serializer.validated_data.get('hardware_brand')
|
||||||
device.hardware_model = serializer.validated_data.get('hardware_model')
|
device.hardware_model = serializer.validated_data.get('hardware_model')
|
||||||
device.os_name = serializer.validated_data.get('os_name')
|
device.os_name = serializer.validated_data.get('os_name')
|
||||||
@@ -200,9 +212,8 @@ class UpdateView(APIView):
|
|||||||
device.save()
|
device.save()
|
||||||
device.log_action('pretix.device.updated', data=serializer.validated_data, auth=device)
|
device.log_action('pretix.device.updated', data=serializer.validated_data, auth=device)
|
||||||
|
|
||||||
from ...base.signals import device_info_updated
|
|
||||||
device_info_updated.send(
|
device_info_updated.send(
|
||||||
sender=Device, old_device=request.auth, new_device=device
|
sender=Device, old_device=old_instance, new_device=device
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = DeviceSerializer(device)
|
serializer = DeviceSerializer(device)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ from pretix.base.models import (
|
|||||||
Checkin, GiftCard, GiftCardAcceptance, GiftCardTransaction, OrderPosition,
|
Checkin, GiftCard, GiftCardAcceptance, GiftCardTransaction, OrderPosition,
|
||||||
ReusableMedium,
|
ReusableMedium,
|
||||||
)
|
)
|
||||||
|
from pretix.base.models.orders import PrintLog
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
from pretix.helpers.dicts import merge_dicts
|
from pretix.helpers.dicts import merge_dicts
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ class ReusableMediaViewSet(viewsets.ModelViewSet):
|
|||||||
'order', 'order__event', 'order__event__organizer', 'seat',
|
'order', 'order__event', 'order__event__organizer', 'seat',
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
'answers', 'answers__options', 'answers__question',
|
'answers', 'answers__options', 'answers__question',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ from pretix.api.serializers.order import (
|
|||||||
OrderPaymentCreateSerializer, OrderPaymentSerializer,
|
OrderPaymentCreateSerializer, OrderPaymentSerializer,
|
||||||
OrderPositionSerializer, OrderRefundCreateSerializer,
|
OrderPositionSerializer, OrderRefundCreateSerializer,
|
||||||
OrderRefundSerializer, OrderSerializer, PriceCalcSerializer,
|
OrderRefundSerializer, OrderSerializer, PriceCalcSerializer,
|
||||||
RevokedTicketSecretSerializer, SimulatedOrderSerializer,
|
PrintLogSerializer, RevokedTicketSecretSerializer,
|
||||||
|
SimulatedOrderSerializer,
|
||||||
)
|
)
|
||||||
from pretix.api.serializers.orderchange import (
|
from pretix.api.serializers.orderchange import (
|
||||||
BlockNameSerializer, OrderChangeOperationSerializer,
|
BlockNameSerializer, OrderChangeOperationSerializer,
|
||||||
@@ -75,7 +76,7 @@ from pretix.base.models import (
|
|||||||
TeamAPIToken, generate_secret,
|
TeamAPIToken, generate_secret,
|
||||||
)
|
)
|
||||||
from pretix.base.models.orders import (
|
from pretix.base.models.orders import (
|
||||||
BlockedTicketSecret, QuestionAnswer, RevokedTicketSecret,
|
BlockedTicketSecret, PrintLog, QuestionAnswer, RevokedTicketSecret,
|
||||||
)
|
)
|
||||||
from pretix.base.payment import PaymentException
|
from pretix.base.payment import PaymentException
|
||||||
from pretix.base.pdf import get_images
|
from pretix.base.pdf import get_images
|
||||||
@@ -214,7 +215,7 @@ class OrderViewSetMixin:
|
|||||||
queryset = Order.objects.none()
|
queryset = Order.objects.none()
|
||||||
filter_backends = (DjangoFilterBackend, TotalOrderingFilter)
|
filter_backends = (DjangoFilterBackend, TotalOrderingFilter)
|
||||||
ordering = ('datetime',)
|
ordering = ('datetime',)
|
||||||
ordering_fields = ('datetime', 'code', 'status', 'last_modified')
|
ordering_fields = ('datetime', 'code', 'status', 'last_modified', 'cancellation_date')
|
||||||
filterset_class = OrderFilter
|
filterset_class = OrderFilter
|
||||||
lookup_field = 'code'
|
lookup_field = 'code'
|
||||||
|
|
||||||
@@ -259,6 +260,7 @@ class OrderViewSetMixin:
|
|||||||
'positions',
|
'positions',
|
||||||
opq.all().prefetch_related(
|
opq.all().prefetch_related(
|
||||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'), to_attr='meta_values_cached')
|
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'), to_attr='meta_values_cached')
|
||||||
)),
|
)),
|
||||||
@@ -280,6 +282,7 @@ class OrderViewSetMixin:
|
|||||||
'positions',
|
'positions',
|
||||||
opq.all().prefetch_related(
|
opq.all().prefetch_related(
|
||||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
'item', 'variation',
|
'item', 'variation',
|
||||||
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options', 'question').order_by('question__position')),
|
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options', 'question').order_by('question__position')),
|
||||||
'seat',
|
'seat',
|
||||||
@@ -1093,6 +1096,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
|||||||
)
|
)
|
||||||
qs = qs.prefetch_related(
|
qs = qs.prefetch_related(
|
||||||
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'),
|
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'),
|
||||||
to_attr='meta_values_cached')
|
to_attr='meta_values_cached')
|
||||||
@@ -1136,6 +1140,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
|||||||
else:
|
else:
|
||||||
qs = qs.prefetch_related(
|
qs = qs.prefetch_related(
|
||||||
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
||||||
|
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
|
||||||
'answers', 'answers__options', 'answers__question',
|
'answers', 'answers__options', 'answers__question',
|
||||||
).select_related(
|
).select_related(
|
||||||
'item', 'order', 'order__event', 'order__event__organizer', 'seat'
|
'item', 'order', 'order__event', 'order__event__organizer', 'seat'
|
||||||
@@ -1254,6 +1259,34 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
|||||||
)
|
)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
@action(detail=True, url_name="printlog", url_path="printlog", methods=["POST"])
|
||||||
|
def printlog(self, request, **kwargs):
|
||||||
|
pos = self.get_object()
|
||||||
|
serializer = PrintLogSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
serializer.save(
|
||||||
|
position=pos,
|
||||||
|
device=request.auth if isinstance(request.auth, Device) else None,
|
||||||
|
user=request.user if request.user.is_authenticated else None,
|
||||||
|
api_token=request.auth if isinstance(request.auth, TeamAPIToken) else None,
|
||||||
|
oauth_application=request.auth.application if isinstance(request.auth, OAuthAccessToken) else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
pos.order.log_action(
|
||||||
|
"pretix.event.order.print",
|
||||||
|
data={
|
||||||
|
"position": pos.pk,
|
||||||
|
"positionid": pos.positionid,
|
||||||
|
**serializer.validated_data,
|
||||||
|
},
|
||||||
|
auth=request.auth,
|
||||||
|
user=request.user,
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
@action(detail=True, url_name='pdf_image', url_path=r'pdf_image/(?P<key>[^/]+)')
|
@action(detail=True, url_name='pdf_image', url_path=r'pdf_image/(?P<key>[^/]+)')
|
||||||
def pdf_image(self, request, key, **kwargs):
|
def pdf_image(self, request, key, **kwargs):
|
||||||
pos = self.get_object()
|
pos = self.get_object()
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ class BaseReportlabInvoiceRenderer(BaseInvoiceRenderer):
|
|||||||
def _clean_text(self, text, tags=None):
|
def _clean_text(self, text, tags=None):
|
||||||
return self._normalize(bleach.clean(
|
return self._normalize(bleach.clean(
|
||||||
text,
|
text,
|
||||||
tags=tags or []
|
tags=set(tags) if tags else set()
|
||||||
).strip().replace('<br>', '<br />').replace('\n', '<br />\n'))
|
).strip().replace('<br>', '<br />').replace('\n', '<br />\n'))
|
||||||
|
|
||||||
|
|
||||||
@@ -461,7 +461,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
def _draw_event(self, canvas):
|
def _draw_event(self, canvas):
|
||||||
def shorten(txt):
|
def shorten(txt):
|
||||||
txt = str(txt)
|
txt = str(txt)
|
||||||
txt = bleach.clean(txt, tags=[]).strip()
|
txt = bleach.clean(txt, tags=set()).strip()
|
||||||
p = Paragraph(self._normalize(txt.strip().replace('\n', '<br />\n')), style=self.stylesheet['Normal'])
|
p = Paragraph(self._normalize(txt.strip().replace('\n', '<br />\n')), style=self.stylesheet['Normal'])
|
||||||
p_size = p.wrap(self.event_width, self.event_height)
|
p_size = p.wrap(self.event_width, self.event_height)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2024-09-19 10:41
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
|
||||||
|
("pretixbase", "0271_itemcategory_cross_selling"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="PrintLog",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True, primary_key=True, serialize=False
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("datetime", models.DateTimeField(default=django.utils.timezone.now)),
|
||||||
|
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
||||||
|
("successful", models.BooleanField(default=True)),
|
||||||
|
("source", models.CharField(max_length=255)),
|
||||||
|
("type", models.CharField(max_length=255)),
|
||||||
|
("info", models.JSONField(default=dict)),
|
||||||
|
(
|
||||||
|
"api_token",
|
||||||
|
models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="pretixbase.teamapitoken",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"device",
|
||||||
|
models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="print_logs",
|
||||||
|
to="pretixbase.device",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"oauth_application",
|
||||||
|
models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"position",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="print_logs",
|
||||||
|
to="pretixbase.orderposition",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="print_logs",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"ordering": ("-datetime",),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2024-10-29 15:03
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_autocheckin(apps, schema_editor):
|
||||||
|
CheckinList = apps.get_model("pretixbase", "CheckinList")
|
||||||
|
AutoCheckinRule = apps.get_model("autocheckin", "AutoCheckinRule")
|
||||||
|
|
||||||
|
for cl in CheckinList.objects.filter(auto_checkin_sales_channels__isnull=False).select_related("event", "event__organizer"):
|
||||||
|
sales_channels = cl.auto_checkin_sales_channels.all()
|
||||||
|
all_sales_channels = cl.event.organizer.sales_channels.all()
|
||||||
|
|
||||||
|
if "pretix.plugins.autocheckin" not in cl.event.plugins:
|
||||||
|
cl.event.plugins = cl.event.plugins + ",pretix.plugins.autocheckin"
|
||||||
|
cl.event.save()
|
||||||
|
|
||||||
|
r = AutoCheckinRule.objects.get_or_create(
|
||||||
|
list=cl,
|
||||||
|
event=cl.event,
|
||||||
|
all_products=True,
|
||||||
|
all_payment_methods=True,
|
||||||
|
defaults=dict(
|
||||||
|
mode="placed",
|
||||||
|
all_sales_channels=len(sales_channels) == len(all_sales_channels),
|
||||||
|
)
|
||||||
|
)[0]
|
||||||
|
if len(sales_channels) != len(all_sales_channels):
|
||||||
|
r.limit_sales_channels.set(sales_channels)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("pretixbase", "0272_printlog"),
|
||||||
|
("autocheckin", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(
|
||||||
|
migrate_autocheckin,
|
||||||
|
migrations.RunPython.noop,
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="checkinlist",
|
||||||
|
name="auto_checkin_sales_channels",
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -256,6 +256,9 @@ class SubeventColumnMixin:
|
|||||||
]
|
]
|
||||||
|
|
||||||
def clean(self, value, previous_values):
|
def clean(self, value, previous_values):
|
||||||
|
if not value:
|
||||||
|
return None
|
||||||
|
|
||||||
if value in self._subevent_cache:
|
if value in self._subevent_cache:
|
||||||
return self._subevent_cache[value]
|
return self._subevent_cache[value]
|
||||||
|
|
||||||
|
|||||||
@@ -99,14 +99,6 @@ class CheckinList(LoggedModel):
|
|||||||
verbose_name=_('Automatically check out everyone at'),
|
verbose_name=_('Automatically check out everyone at'),
|
||||||
null=True, blank=True
|
null=True, blank=True
|
||||||
)
|
)
|
||||||
auto_checkin_sales_channels = models.ManyToManyField(
|
|
||||||
"SalesChannel",
|
|
||||||
verbose_name=_('Sales channels to automatically check in'),
|
|
||||||
help_text=_('This option is deprecated and will be removed in the next months. As a replacement, our new plugin '
|
|
||||||
'"Auto check-in" can be used. When we remove this option, we will automatically migrate your event '
|
|
||||||
'to use the new plugin.'),
|
|
||||||
blank=True,
|
|
||||||
)
|
|
||||||
rules = models.JSONField(default=dict, blank=True)
|
rules = models.JSONField(default=dict, blank=True)
|
||||||
|
|
||||||
objects = ScopedManager(organizer='event__organizer')
|
objects = ScopedManager(organizer='event__organizer')
|
||||||
@@ -141,7 +133,7 @@ class CheckinList(LoggedModel):
|
|||||||
return self.positions_query(ignore_status=False)
|
return self.positions_query(ignore_status=False)
|
||||||
|
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def positions_inside_query(self, ignore_status=False, at_time=None):
|
def _filter_positions_inside(self, qs, at_time=None):
|
||||||
if at_time is None:
|
if at_time is None:
|
||||||
c_q = []
|
c_q = []
|
||||||
else:
|
else:
|
||||||
@@ -149,7 +141,7 @@ class CheckinList(LoggedModel):
|
|||||||
|
|
||||||
if "postgresql" not in settings.DATABASES["default"]["ENGINE"]:
|
if "postgresql" not in settings.DATABASES["default"]["ENGINE"]:
|
||||||
# Use a simple approach that works on all databases
|
# Use a simple approach that works on all databases
|
||||||
qs = self.positions_query(ignore_status=ignore_status).annotate(
|
qs = qs.annotate(
|
||||||
last_entry=Subquery(
|
last_entry=Subquery(
|
||||||
Checkin.objects.filter(
|
Checkin.objects.filter(
|
||||||
*c_q,
|
*c_q,
|
||||||
@@ -202,7 +194,7 @@ class CheckinList(LoggedModel):
|
|||||||
.values("position_id", "type", "datetime", "cnt_exists_after")
|
.values("position_id", "type", "datetime", "cnt_exists_after")
|
||||||
.query.sql_with_params()
|
.query.sql_with_params()
|
||||||
)
|
)
|
||||||
return self.positions_query(ignore_status=ignore_status).filter(
|
return qs.filter(
|
||||||
pk__in=RawSQL(
|
pk__in=RawSQL(
|
||||||
f"""
|
f"""
|
||||||
SELECT "position_id"
|
SELECT "position_id"
|
||||||
@@ -214,6 +206,10 @@ class CheckinList(LoggedModel):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@scopes_disabled()
|
||||||
|
def positions_inside_query(self, ignore_status=False, at_time=None):
|
||||||
|
return self._filter_positions_inside(self.positions_query(ignore_status=ignore_status), at_time=at_time)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def positions_inside(self):
|
def positions_inside(self):
|
||||||
return self.positions_inside_query(None)
|
return self.positions_inside_query(None)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ from django.utils.crypto import get_random_string
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_scopes import ScopedManager, scopes_disabled
|
from django_scopes import ScopedManager, scopes_disabled
|
||||||
|
|
||||||
from pretix.api.auth.devicesecurity import DEVICE_SECURITY_PROFILES
|
|
||||||
from pretix.base.models import LoggedModel
|
from pretix.base.models import LoggedModel
|
||||||
|
|
||||||
|
|
||||||
@@ -161,7 +160,6 @@ class Device(LoggedModel):
|
|||||||
)
|
)
|
||||||
security_profile = models.CharField(
|
security_profile = models.CharField(
|
||||||
max_length=190,
|
max_length=190,
|
||||||
choices=[(k, v.verbose_name) for k, v in DEVICE_SECURITY_PROFILES.items()],
|
|
||||||
default='full',
|
default='full',
|
||||||
null=True,
|
null=True,
|
||||||
blank=False
|
blank=False
|
||||||
|
|||||||
@@ -1024,10 +1024,9 @@ class Event(EventMixin, LoggedModel):
|
|||||||
|
|
||||||
checkin_list_map = {}
|
checkin_list_map = {}
|
||||||
for cl in other.checkin_lists.filter(subevent__isnull=True).prefetch_related(
|
for cl in other.checkin_lists.filter(subevent__isnull=True).prefetch_related(
|
||||||
'limit_products', 'auto_checkin_sales_channels'
|
'limit_products'
|
||||||
):
|
):
|
||||||
items = list(cl.limit_products.all())
|
items = list(cl.limit_products.all())
|
||||||
auto_checkin_sales_channels = list(cl.auto_checkin_sales_channels.all())
|
|
||||||
checkin_list_map[cl.pk] = cl
|
checkin_list_map[cl.pk] = cl
|
||||||
cl.pk = None
|
cl.pk = None
|
||||||
cl._prefetched_objects_cache = {}
|
cl._prefetched_objects_cache = {}
|
||||||
@@ -1039,8 +1038,6 @@ class Event(EventMixin, LoggedModel):
|
|||||||
cl.log_action('pretix.object.cloned')
|
cl.log_action('pretix.object.cloned')
|
||||||
for i in items:
|
for i in items:
|
||||||
cl.limit_products.add(item_map[i.pk])
|
cl.limit_products.add(item_map[i.pk])
|
||||||
if auto_checkin_sales_channels:
|
|
||||||
cl.auto_checkin_sales_channels.set(self.organizer.sales_channels.filter(identifier__in=[s.identifier for s in auto_checkin_sales_channels]))
|
|
||||||
|
|
||||||
if other.seating_plan:
|
if other.seating_plan:
|
||||||
if other.seating_plan.organizer_id == self.organizer_id:
|
if other.seating_plan.organizer_id == self.organizer_id:
|
||||||
|
|||||||
@@ -1118,13 +1118,12 @@ class ItemVariation(models.Model):
|
|||||||
:param original_price: The item's "original" price. Will not be used for any calculations, will just be shown.
|
:param original_price: The item's "original" price. Will not be used for any calculations, will just be shown.
|
||||||
:type original_price: decimal.Decimal
|
:type original_price: decimal.Decimal
|
||||||
:param require_approval: If set to ``True``, orders containing this variation can only be processed and paid after
|
:param require_approval: If set to ``True``, orders containing this variation can only be processed and paid after
|
||||||
approval by an administrator
|
approval by an administrator
|
||||||
:type require_approval: bool
|
:type require_approval: bool
|
||||||
:param all_sales_channels: A flag indicating that this variation is available on all channels and limit_sales_channels will be ignored.
|
:param all_sales_channels: A flag indicating that this variation is available on all channels and limit_sales_channels will be ignored.
|
||||||
:type all_sales_channels: bool
|
:type all_sales_channels: bool
|
||||||
:param limit_sales_channels: A list of sales channel identifiers, that this variation is available for sale on.
|
:param limit_sales_channels: A list of sales channel identifiers, that this variation is available for sale on.
|
||||||
:type limit_sales_channels: list
|
:type limit_sales_channels: list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
item = models.ForeignKey(
|
item = models.ForeignKey(
|
||||||
Item,
|
Item,
|
||||||
|
|||||||
@@ -3391,6 +3391,74 @@ class BlockedTicketSecret(models.Model):
|
|||||||
unique_together = (('event', 'secret'),)
|
unique_together = (('event', 'secret'),)
|
||||||
|
|
||||||
|
|
||||||
|
class PrintLog(models.Model):
|
||||||
|
"""
|
||||||
|
A print log object is created when a ticket or badge is printed with our apps.
|
||||||
|
"""
|
||||||
|
TYPE_BADGE = 'badge'
|
||||||
|
TYPE_TICKET = 'ticket'
|
||||||
|
TYPE_CERTIFICATE = 'certificate'
|
||||||
|
TYPE_OTHER = 'other'
|
||||||
|
PRINT_TYPES = (
|
||||||
|
(TYPE_BADGE, _('Badge')),
|
||||||
|
(TYPE_TICKET, _('Ticket')),
|
||||||
|
(TYPE_CERTIFICATE, _('Certificate')),
|
||||||
|
(TYPE_OTHER, _('Other')),
|
||||||
|
)
|
||||||
|
|
||||||
|
position = models.ForeignKey(
|
||||||
|
'pretixbase.OrderPosition',
|
||||||
|
related_name='print_logs',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
)
|
||||||
|
successful = models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Datetime of checkin, might be different from created if past scans are uploaded
|
||||||
|
datetime = models.DateTimeField(default=now)
|
||||||
|
|
||||||
|
# Datetime of creation on server
|
||||||
|
created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
|
||||||
|
|
||||||
|
# Who printed?
|
||||||
|
device = models.ForeignKey('Device', related_name='print_logs', null=True, blank=True, on_delete=models.PROTECT)
|
||||||
|
user = models.ForeignKey('User', related_name='print_logs', null=True, blank=True, on_delete=models.PROTECT)
|
||||||
|
api_token = models.ForeignKey('TeamAPIToken', null=True, blank=True, on_delete=models.PROTECT)
|
||||||
|
oauth_application = models.ForeignKey('pretixapi.OAuthApplication', null=True, blank=True, on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
# Source = Tag field with undefined values, e.g. name of app ("pretixscan")
|
||||||
|
source = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
# Type = Type of object printed ("badge", "ticket")
|
||||||
|
type = models.CharField(max_length=255, choices=PRINT_TYPES)
|
||||||
|
|
||||||
|
info = models.JSONField(default=dict)
|
||||||
|
|
||||||
|
objects = ScopedManager(organizer='position__order__event__organizer')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = (('-datetime'),)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<PrintLog: pos {} at {} from {}>".format(
|
||||||
|
self.position, self.datetime, self.source
|
||||||
|
)
|
||||||
|
|
||||||
|
def save(self, **kwargs):
|
||||||
|
super().save(**kwargs)
|
||||||
|
if self.position:
|
||||||
|
self.position.order.touch()
|
||||||
|
|
||||||
|
def delete(self, **kwargs):
|
||||||
|
super().delete(**kwargs)
|
||||||
|
self.position.order.touch()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_late_upload(self):
|
||||||
|
return self.created and abs(self.created - self.datetime) > timedelta(minutes=2)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=CachedTicket)
|
@receiver(post_delete, sender=CachedTicket)
|
||||||
def cachedticket_delete(sender, instance, **kwargs):
|
def cachedticket_delete(sender, instance, **kwargs):
|
||||||
if instance.file:
|
if instance.file:
|
||||||
|
|||||||
@@ -53,6 +53,30 @@ class SeatingPlanLayoutValidator:
|
|||||||
e = str(e).replace('%', '%%')
|
e = str(e).replace('%', '%%')
|
||||||
raise ValidationError(_('Your layout file is not a valid seating plan. Error message: {}').format(e))
|
raise ValidationError(_('Your layout file is not a valid seating plan. Error message: {}').format(e))
|
||||||
|
|
||||||
|
try:
|
||||||
|
seat_guids = set()
|
||||||
|
for z in val["zones"]:
|
||||||
|
for r in z["rows"]:
|
||||||
|
for s in r["seats"]:
|
||||||
|
if not s.get("seat_guid"):
|
||||||
|
raise ValidationError(
|
||||||
|
_("Seat with zone {zone}, row {row}, and number {number} has no seat ID.").format(
|
||||||
|
zone=z["name"],
|
||||||
|
row=r["row_number"],
|
||||||
|
number=s["seat_number"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif s["seat_guid"] in seat_guids:
|
||||||
|
raise ValidationError(
|
||||||
|
_("Multiple seats have the same ID: {id}").format(
|
||||||
|
id=s["seat_guid"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
seat_guids.add(s["seat_guid"])
|
||||||
|
except ValidationError as e:
|
||||||
|
raise ValidationError(_('Your layout file is not a valid seating plan. Error message: {}').format(", ".join(e.message for e in e.error_list)))
|
||||||
|
|
||||||
|
|
||||||
class SeatingPlan(LoggedModel):
|
class SeatingPlan(LoggedModel):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -343,11 +343,13 @@ class CartManager:
|
|||||||
err = error_messages['some_subevent_not_started']
|
err = error_messages['some_subevent_not_started']
|
||||||
cp.addons.all().delete()
|
cp.addons.all().delete()
|
||||||
cp.delete()
|
cp.delete()
|
||||||
|
continue
|
||||||
|
|
||||||
if cp.subevent and cp.subevent.presale_end and time_machine_now(self.real_now_dt) > cp.subevent.presale_end:
|
if cp.subevent and cp.subevent.presale_end and time_machine_now(self.real_now_dt) > cp.subevent.presale_end:
|
||||||
err = error_messages['some_subevent_ended']
|
err = error_messages['some_subevent_ended']
|
||||||
cp.addons.all().delete()
|
cp.addons.all().delete()
|
||||||
cp.delete()
|
cp.delete()
|
||||||
|
continue
|
||||||
|
|
||||||
if cp.subevent:
|
if cp.subevent:
|
||||||
tlv = self.event.settings.get('payment_term_last', as_type=RelativeDateWrapper)
|
tlv = self.event.settings.get('payment_term_last', as_type=RelativeDateWrapper)
|
||||||
@@ -360,6 +362,7 @@ class CartManager:
|
|||||||
err = error_messages['some_subevent_ended']
|
err = error_messages['some_subevent_ended']
|
||||||
cp.addons.all().delete()
|
cp.addons.all().delete()
|
||||||
cp.delete()
|
cp.delete()
|
||||||
|
continue
|
||||||
return err
|
return err
|
||||||
|
|
||||||
def _update_subevents_cache(self, se_ids: List[int]):
|
def _update_subevents_cache(self, se_ids: List[int]):
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ from pretix.base.models import (
|
|||||||
Checkin, CheckinList, Device, Event, Gate, Item, ItemVariation, Order,
|
Checkin, CheckinList, Device, Event, Gate, Item, ItemVariation, Order,
|
||||||
OrderPosition, QuestionOption,
|
OrderPosition, QuestionOption,
|
||||||
)
|
)
|
||||||
from pretix.base.signals import checkin_created, order_placed, periodic_task
|
from pretix.base.signals import checkin_created, periodic_task
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
from pretix.helpers.jsonlogic import Logic
|
from pretix.helpers.jsonlogic import Logic
|
||||||
from pretix.helpers.jsonlogic_boolalg import convert_to_dnf
|
from pretix.helpers.jsonlogic_boolalg import convert_to_dnf
|
||||||
@@ -1154,23 +1154,6 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@receiver(order_placed, dispatch_uid="legacy_autocheckin_order_placed")
|
|
||||||
def order_placed(sender, **kwargs):
|
|
||||||
order = kwargs['order']
|
|
||||||
event = sender
|
|
||||||
|
|
||||||
cls = list(event.checkin_lists.filter(auto_checkin_sales_channels=order.sales_channel).prefetch_related(
|
|
||||||
'limit_products'))
|
|
||||||
if not cls:
|
|
||||||
return
|
|
||||||
for op in order.positions.all():
|
|
||||||
for cl in cls:
|
|
||||||
if cl.all_products or op.item_id in {i.pk for i in cl.limit_products.all()}:
|
|
||||||
if not cl.subevent_id or cl.subevent_id == op.subevent_id:
|
|
||||||
ci = Checkin.objects.create(position=op, list=cl, auto_checked_in=True, type=Checkin.TYPE_ENTRY)
|
|
||||||
checkin_created.send(event, checkin=ci)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(periodic_task, dispatch_uid="autocheckout_exit_all")
|
@receiver(periodic_task, dispatch_uid="autocheckout_exit_all")
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def process_exit_all(sender, **kwargs):
|
def process_exit_all(sender, **kwargs):
|
||||||
|
|||||||
@@ -550,7 +550,7 @@ DEFAULTS = {
|
|||||||
'serializer_class': serializers.BooleanField,
|
'serializer_class': serializers.BooleanField,
|
||||||
'type': bool,
|
'type': bool,
|
||||||
'form_kwargs': dict(
|
'form_kwargs': dict(
|
||||||
label=_("Require a business addresses"),
|
label=_("Require a business address"),
|
||||||
help_text=_('This will require users to enter a company name.'),
|
help_text=_('This will require users to enter a company name.'),
|
||||||
widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_invoice_address_required'}),
|
widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_invoice_address_required'}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ validate_cart_addons = EventPluginSignal()
|
|||||||
Arguments: ``addons``, ``base_position``, ``iao``
|
Arguments: ``addons``, ``base_position``, ``iao``
|
||||||
|
|
||||||
This signal is sent when a user tries to select a combination of addons. In contrast to
|
This signal is sent when a user tries to select a combination of addons. In contrast to
|
||||||
``validate_cart``, this is executed before the cart is actually modified. You are passed
|
``validate_cart``, this is executed before the cart is actually modified. You are passed
|
||||||
an argument ``addons`` containing a dict of ``(item, variation or None) → count`` tuples as well
|
an argument ``addons`` containing a dict of ``(item, variation or None) → count`` tuples as well
|
||||||
as the ``ItemAddOn`` object as the argument ``iao`` and the base cart position as
|
as the ``ItemAddOn`` object as the argument ``iao`` and the base cart position as
|
||||||
``base_position``.
|
``base_position``.
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ from tlds import tld_set
|
|||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
ALLOWED_TAGS_SNIPPET = [
|
ALLOWED_TAGS_SNIPPET = {
|
||||||
'a',
|
'a',
|
||||||
'abbr',
|
'abbr',
|
||||||
'acronym',
|
'acronym',
|
||||||
@@ -68,8 +68,8 @@ ALLOWED_TAGS_SNIPPET = [
|
|||||||
'strike',
|
'strike',
|
||||||
's',
|
's',
|
||||||
# Update doc/user/markdown.rst if you change this!
|
# Update doc/user/markdown.rst if you change this!
|
||||||
]
|
}
|
||||||
ALLOWED_TAGS = ALLOWED_TAGS_SNIPPET + [
|
ALLOWED_TAGS = ALLOWED_TAGS_SNIPPET | {
|
||||||
'blockquote',
|
'blockquote',
|
||||||
'li',
|
'li',
|
||||||
'ol',
|
'ol',
|
||||||
@@ -91,7 +91,7 @@ ALLOWED_TAGS = ALLOWED_TAGS_SNIPPET + [
|
|||||||
'h6',
|
'h6',
|
||||||
'pre',
|
'pre',
|
||||||
# Update doc/user/markdown.rst if you change this!
|
# Update doc/user/markdown.rst if you change this!
|
||||||
]
|
}
|
||||||
|
|
||||||
ALLOWED_ATTRIBUTES = {
|
ALLOWED_ATTRIBUTES = {
|
||||||
'a': ['href', 'title', 'class'],
|
'a': ['href', 'title', 'class'],
|
||||||
@@ -106,7 +106,7 @@ ALLOWED_ATTRIBUTES = {
|
|||||||
# Update doc/user/markdown.rst if you change this!
|
# Update doc/user/markdown.rst if you change this!
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOWED_PROTOCOLS = ['http', 'https', 'mailto', 'tel']
|
ALLOWED_PROTOCOLS = {'http', 'https', 'mailto', 'tel'}
|
||||||
|
|
||||||
URL_RE = SimpleLazyObject(lambda: build_url_re(tlds=sorted(tld_set, key=len, reverse=True)))
|
URL_RE = SimpleLazyObject(lambda: build_url_re(tlds=sorted(tld_set, key=len, reverse=True)))
|
||||||
|
|
||||||
@@ -211,9 +211,9 @@ class CleanPostprocessor(Postprocessor):
|
|||||||
def run(self, text):
|
def run(self, text):
|
||||||
return bleach.clean(
|
return bleach.clean(
|
||||||
text,
|
text,
|
||||||
tags=self.tags,
|
tags=set(self.tags),
|
||||||
attributes=self.attributes,
|
attributes=self.attributes,
|
||||||
protocols=self.protocols,
|
protocols=set(self.protocols),
|
||||||
strip=self.strip
|
strip=self.strip
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ def markdown_compile_email(source, allowed_tags=ALLOWED_TAGS, allowed_attributes
|
|||||||
EmailNl2BrExtension(),
|
EmailNl2BrExtension(),
|
||||||
LinkifyAndCleanExtension(
|
LinkifyAndCleanExtension(
|
||||||
linker,
|
linker,
|
||||||
tags=allowed_tags,
|
tags=set(allowed_tags),
|
||||||
attributes=allowed_attributes,
|
attributes=allowed_attributes,
|
||||||
protocols=ALLOWED_PROTOCOLS,
|
protocols=ALLOWED_PROTOCOLS,
|
||||||
strip=False,
|
strip=False,
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ from django_scopes.forms import (
|
|||||||
from pretix.base.forms.widgets import SplitDateTimePickerWidget
|
from pretix.base.forms.widgets import SplitDateTimePickerWidget
|
||||||
from pretix.base.models import Gate
|
from pretix.base.models import Gate
|
||||||
from pretix.base.models.checkin import Checkin, CheckinList
|
from pretix.base.models.checkin import Checkin, CheckinList
|
||||||
from pretix.control.forms import (
|
from pretix.control.forms import ItemMultipleChoiceField
|
||||||
ItemMultipleChoiceField, SalesChannelCheckboxSelectMultiple,
|
|
||||||
)
|
|
||||||
from pretix.control.forms.widgets import Select2
|
from pretix.control.forms.widgets import Select2
|
||||||
|
|
||||||
|
|
||||||
@@ -67,10 +65,6 @@ class CheckinListForm(forms.ModelForm):
|
|||||||
kwargs.pop('locales', None)
|
kwargs.pop('locales', None)
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.fields['limit_products'].queryset = self.event.items.all()
|
self.fields['limit_products'].queryset = self.event.items.all()
|
||||||
self.fields['auto_checkin_sales_channels'].queryset = self.event.organizer.sales_channels.all()
|
|
||||||
self.fields['auto_checkin_sales_channels'].widget = SalesChannelCheckboxSelectMultiple(
|
|
||||||
self.event, choices=self.fields['auto_checkin_sales_channels'].widget.choices
|
|
||||||
)
|
|
||||||
|
|
||||||
if not self.event.organizer.gates.exists():
|
if not self.event.organizer.gates.exists():
|
||||||
del self.fields['gates']
|
del self.fields['gates']
|
||||||
@@ -102,7 +96,6 @@ class CheckinListForm(forms.ModelForm):
|
|||||||
'limit_products',
|
'limit_products',
|
||||||
'subevent',
|
'subevent',
|
||||||
'include_pending',
|
'include_pending',
|
||||||
'auto_checkin_sales_channels',
|
|
||||||
'allow_multiple_entries',
|
'allow_multiple_entries',
|
||||||
'allow_entry_after_exit',
|
'allow_entry_after_exit',
|
||||||
'rules',
|
'rules',
|
||||||
@@ -125,7 +118,6 @@ class CheckinListForm(forms.ModelForm):
|
|||||||
'limit_products': ItemMultipleChoiceField,
|
'limit_products': ItemMultipleChoiceField,
|
||||||
'gates': SafeModelMultipleChoiceField,
|
'gates': SafeModelMultipleChoiceField,
|
||||||
'subevent': SafeModelChoiceField,
|
'subevent': SafeModelChoiceField,
|
||||||
'auto_checkin_sales_channels': SafeModelMultipleChoiceField,
|
|
||||||
'exit_all_at': NextTimeField,
|
'exit_all_at': NextTimeField,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1967,7 +1967,7 @@ class CheckinListAttendeeFilterForm(FilterForm):
|
|||||||
if s == '1':
|
if s == '1':
|
||||||
qs = qs.filter(last_entry__isnull=False)
|
qs = qs.filter(last_entry__isnull=False)
|
||||||
elif s == '2':
|
elif s == '2':
|
||||||
qs = qs.filter(pk__in=self.list.positions_inside.values_list('pk'))
|
qs = self.list._filter_positions_inside(qs)
|
||||||
elif s == '3':
|
elif s == '3':
|
||||||
qs = qs.filter(last_entry__isnull=False).filter(
|
qs = qs.filter(last_entry__isnull=False).filter(
|
||||||
Q(last_exit__isnull=False) & Q(last_exit__gte=F('last_entry'))
|
Q(last_exit__isnull=False) & Q(last_exit__gte=F('last_entry'))
|
||||||
|
|||||||
@@ -609,6 +609,49 @@ class OrderFeeChangeForm(forms.Form):
|
|||||||
change_decimal_field(self.fields['value'], instance.order.event.currency)
|
change_decimal_field(self.fields['value'], instance.order.event.currency)
|
||||||
|
|
||||||
|
|
||||||
|
class OrderFeeAddForm(forms.Form):
|
||||||
|
fee_type = forms.ChoiceField(choices=OrderFee.FEE_TYPES)
|
||||||
|
value = forms.DecimalField(
|
||||||
|
max_digits=13, decimal_places=2,
|
||||||
|
localize=True,
|
||||||
|
label=_('Price'),
|
||||||
|
help_text=_("including all taxes"),
|
||||||
|
)
|
||||||
|
tax_rule = forms.ModelChoiceField(
|
||||||
|
TaxRule.objects.none(),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
description = forms.CharField(required=False)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
order = kwargs.pop('order')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['tax_rule'].queryset = order.event.tax_rules.all()
|
||||||
|
change_decimal_field(self.fields['value'], order.event.currency)
|
||||||
|
|
||||||
|
|
||||||
|
class OrderFeeAddFormset(forms.BaseFormSet):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.order = kwargs.pop('order', None)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _construct_form(self, i, **kwargs):
|
||||||
|
kwargs['order'] = self.order
|
||||||
|
return super()._construct_form(i, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def empty_form(self):
|
||||||
|
form = self.form(
|
||||||
|
auto_id=self.auto_id,
|
||||||
|
prefix=self.add_prefix('__prefix__'),
|
||||||
|
empty_permitted=True,
|
||||||
|
use_required_attribute=False,
|
||||||
|
order=self.order,
|
||||||
|
)
|
||||||
|
self.add_fields(form, None)
|
||||||
|
return form
|
||||||
|
|
||||||
|
|
||||||
class OrderContactForm(forms.ModelForm):
|
class OrderContactForm(forms.ModelForm):
|
||||||
regenerate_secrets = forms.BooleanField(required=False, label=_('Invalidate secrets'),
|
regenerate_secrets = forms.BooleanField(required=False, label=_('Invalidate secrets'),
|
||||||
help_text=_('Regenerates the order and ticket secrets. You will '
|
help_text=_('Regenerates the order and ticket secrets. You will '
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ from i18nfield.strings import LazyI18nString
|
|||||||
from phonenumber_field.formfields import PhoneNumberField
|
from phonenumber_field.formfields import PhoneNumberField
|
||||||
from pytz import common_timezones
|
from pytz import common_timezones
|
||||||
|
|
||||||
|
from pretix.api.auth.devicesecurity import get_all_security_profiles
|
||||||
from pretix.api.models import WebHook
|
from pretix.api.models import WebHook
|
||||||
from pretix.api.webhooks import get_all_webhook_events
|
from pretix.api.webhooks import get_all_webhook_events
|
||||||
from pretix.base.customersso.oidc import oidc_validate_and_complete_config
|
from pretix.base.customersso.oidc import oidc_validate_and_complete_config
|
||||||
@@ -311,6 +312,11 @@ class DeviceForm(forms.ModelForm):
|
|||||||
'-has_subevents', '-date_from'
|
'-has_subevents', '-date_from'
|
||||||
)
|
)
|
||||||
self.fields['gate'].queryset = organizer.gates.all()
|
self.fields['gate'].queryset = organizer.gates.all()
|
||||||
|
self.fields['security_profile'] = forms.ChoiceField(
|
||||||
|
label=self.fields['security_profile'].label,
|
||||||
|
help_text=self.fields['security_profile'].help_text,
|
||||||
|
choices=[(k, v.verbose_name) for k, v in get_all_security_profiles().items()],
|
||||||
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
d = super().clean()
|
d = super().clean()
|
||||||
@@ -344,6 +350,11 @@ class DeviceBulkEditForm(forms.ModelForm):
|
|||||||
'-has_subevents', '-date_from'
|
'-has_subevents', '-date_from'
|
||||||
)
|
)
|
||||||
self.fields['gate'].queryset = organizer.gates.all()
|
self.fields['gate'].queryset = organizer.gates.all()
|
||||||
|
self.fields['security_profile'] = forms.ChoiceField(
|
||||||
|
label=self.fields['security_profile'].label,
|
||||||
|
help_text=self.fields['security_profile'].help_text,
|
||||||
|
choices=[(k, v.verbose_name) for k, v in get_all_security_profiles().items()],
|
||||||
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
d = super().clean()
|
d = super().clean()
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ from pretix.base.models import (
|
|||||||
Checkin, CheckinList, Event, ItemVariation, LogEntry, OrderPosition,
|
Checkin, CheckinList, Event, ItemVariation, LogEntry, OrderPosition,
|
||||||
TaxRule,
|
TaxRule,
|
||||||
)
|
)
|
||||||
|
from pretix.base.models.orders import PrintLog
|
||||||
from pretix.base.signals import logentry_display, orderposition_blocked_display
|
from pretix.base.signals import logentry_display, orderposition_blocked_display
|
||||||
from pretix.base.templatetags.money import money_filter
|
from pretix.base.templatetags.money import money_filter
|
||||||
|
|
||||||
@@ -612,7 +613,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
|
|||||||
|
|
||||||
if logentry.action_type == 'pretix.event.order.consent':
|
if logentry.action_type == 'pretix.event.order.consent':
|
||||||
return _('The user confirmed the following message: "{}"').format(
|
return _('The user confirmed the following message: "{}"').format(
|
||||||
bleach.clean(logentry.parsed_data.get('msg'), tags=[], strip=True)
|
bleach.clean(logentry.parsed_data.get('msg'), tags=set(), strip=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
if logentry.action_type == 'pretix.event.order.canceled':
|
if logentry.action_type == 'pretix.event.order.canceled':
|
||||||
@@ -639,6 +640,16 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
|
|||||||
if sender and logentry.action_type.startswith('pretix.event.checkin'):
|
if sender and logentry.action_type.startswith('pretix.event.checkin'):
|
||||||
return _display_checkin(sender, logentry)
|
return _display_checkin(sender, logentry)
|
||||||
|
|
||||||
|
if logentry.action_type == 'pretix.event.order.print':
|
||||||
|
return _('Position #{posid} has been printed at {datetime} with type "{type}".').format(
|
||||||
|
posid=data.get('positionid'),
|
||||||
|
datetime=date_format(
|
||||||
|
dateutil.parser.parse(data["datetime"]).astimezone(sender.timezone),
|
||||||
|
"SHORT_DATETIME_FORMAT"
|
||||||
|
),
|
||||||
|
type=dict(PrintLog.PRINT_TYPES)[data["type"]],
|
||||||
|
)
|
||||||
|
|
||||||
if logentry.action_type == 'pretix.control.views.checkin':
|
if logentry.action_type == 'pretix.control.views.checkin':
|
||||||
# deprecated
|
# deprecated
|
||||||
dt = dateutil.parser.parse(data.get('datetime'))
|
dt = dateutil.parser.parse(data.get('datetime'))
|
||||||
|
|||||||
@@ -132,16 +132,6 @@ def get_event_navigation(request: HttpRequest):
|
|||||||
'icon': 'wrench',
|
'icon': 'wrench',
|
||||||
'children': event_settings
|
'children': event_settings
|
||||||
})
|
})
|
||||||
if request.event.has_subevents:
|
|
||||||
nav.append({
|
|
||||||
'label': pgettext_lazy('subevent', 'Dates'),
|
|
||||||
'url': reverse('control:event.subevents', kwargs={
|
|
||||||
'event': request.event.slug,
|
|
||||||
'organizer': request.event.organizer.slug,
|
|
||||||
}),
|
|
||||||
'active': ('event.subevent' in url.url_name),
|
|
||||||
'icon': 'calendar',
|
|
||||||
})
|
|
||||||
|
|
||||||
if 'can_change_items' in request.eventpermset:
|
if 'can_change_items' in request.eventpermset:
|
||||||
nav.append({
|
nav.append({
|
||||||
@@ -197,6 +187,18 @@ def get_event_navigation(request: HttpRequest):
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if 'can_change_event_settings' in request.eventpermset:
|
||||||
|
if request.event.has_subevents:
|
||||||
|
nav.append({
|
||||||
|
'label': pgettext_lazy('subevent', 'Dates'),
|
||||||
|
'url': reverse('control:event.subevents', kwargs={
|
||||||
|
'event': request.event.slug,
|
||||||
|
'organizer': request.event.organizer.slug,
|
||||||
|
}),
|
||||||
|
'active': ('event.subevent' in url.url_name),
|
||||||
|
'icon': 'calendar',
|
||||||
|
})
|
||||||
|
|
||||||
if 'can_view_orders' in request.eventpermset:
|
if 'can_view_orders' in request.eventpermset:
|
||||||
children = [
|
children = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,7 +67,6 @@
|
|||||||
{% bootstrap_field form.allow_entry_after_exit layout="control" %}
|
{% bootstrap_field form.allow_entry_after_exit layout="control" %}
|
||||||
{% bootstrap_field form.addon_match layout="control" %}
|
{% bootstrap_field form.addon_match layout="control" %}
|
||||||
{% bootstrap_field form.exit_all_at layout="control" %}
|
{% bootstrap_field form.exit_all_at layout="control" %}
|
||||||
{% bootstrap_field form.auto_checkin_sales_channels layout="control" %}
|
|
||||||
{% if form.gates %}
|
{% if form.gates %}
|
||||||
{% bootstrap_field form.gates layout="control" %}
|
{% bootstrap_field form.gates layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -101,7 +101,6 @@
|
|||||||
<a href="?{% url_replace request 'ordering' 'subevent' %}"><i class="fa fa-caret-up"></i></a>
|
<a href="?{% url_replace request 'ordering' 'subevent' %}"><i class="fa fa-caret-up"></i></a>
|
||||||
</th>
|
</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<th class="iconcol">{% trans "Automated check-in" %}</th>
|
|
||||||
<th>{% trans "Products" %}</th>
|
<th>{% trans "Products" %}</th>
|
||||||
<th class="action-col-2"></th>
|
<th class="action-col-2"></th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -137,17 +136,6 @@
|
|||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td>
|
|
||||||
{% for channel in cl.auto_checkin_sales_channels.all %}
|
|
||||||
{% if "." in channel.icon %}
|
|
||||||
<img src="{% static channel.icon %}" class="fa-like-image"
|
|
||||||
data-toggle="tooltip" title="{{ channel.label }}">
|
|
||||||
{% else %}
|
|
||||||
<span class="fa fa-{{ channel.icon }} text-muted"
|
|
||||||
data-toggle="tooltip" title="{{ channel.label }}"></span>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
{% if cl.all_products %}
|
{% if cl.all_products %}
|
||||||
<em>{% trans "All" %}</em>
|
<em>{% trans "All" %}</em>
|
||||||
|
|||||||
@@ -12,10 +12,22 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if object.id and not object.quotas.exists %}
|
{% if object.id and not object.quotas.exists %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
{% blocktrans trimmed %}
|
<div class="row">
|
||||||
Please note that your product will <strong>not</strong> be available for sale until you have added your
|
<div class="col-lg-8">
|
||||||
item to an existing or newly created quota.
|
{% blocktrans trimmed %}
|
||||||
{% endblocktrans %}
|
Please note that your product will <strong>not</strong> be available for sale until you have added your
|
||||||
|
item to an existing or newly created quota.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 text-right">
|
||||||
|
<a class="btn btn-default btn-sm" href="{% url "control:event.items.quotas" organizer=request.event.organizer.slug event=request.event.slug %}">
|
||||||
|
<i class="fa fa-wrench"></i> {% trans "Manage quotas" %}
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-default btn-sm" href="{% url "control:event.items.quotas.add" organizer=request.event.organizer.slug event=request.event.slug %}?{% if object.has_variations %}{% for var in object.variations.all %}product={{ object.pk }}-{{ var.pk }}&{% endfor %}{% else %}product={{ object.pk }}{% endif %}">
|
||||||
|
<i class="fa fa-plus"></i> {% trans "Create a new quota" %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% elif object.pk and not object.is_available_by_time %}
|
{% elif object.pk and not object.is_available_by_time %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
|
|||||||
@@ -67,10 +67,22 @@
|
|||||||
<div class="panel-body form-horizontal">
|
<div class="panel-body form-horizontal">
|
||||||
{% if form.instance.pk and not form.instance.quotas.exists %}
|
{% if form.instance.pk and not form.instance.quotas.exists %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
{% blocktrans trimmed %}
|
<div class="row">
|
||||||
Please note that your variation will <strong>not</strong> be available for sale
|
<div class="col-lg-8">
|
||||||
until you have added it to an existing or newly created quota.
|
{% blocktrans trimmed %}
|
||||||
{% endblocktrans %}
|
Please note that your variation will <strong>not</strong> be available for sale
|
||||||
|
until you have added it to an existing or newly created quota.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 text-right">
|
||||||
|
<a class="btn btn-default btn-xs" href="{% url "control:event.items.quotas" organizer=request.event.organizer.slug event=request.event.slug %}">
|
||||||
|
<i class="fa fa-wrench"></i> {% trans "Manage quotas" %}
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-default btn-xs" href="{% url "control:event.items.quotas.add" organizer=request.event.organizer.slug event=request.event.slug %}?product={{ form.instance.item.pk }}-{{ form.instance.pk }}">
|
||||||
|
<i class="fa fa-plus"></i> {% trans "Create a new quota" %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% bootstrap_form_errors form %}
|
{% bootstrap_form_errors form %}
|
||||||
|
|||||||
@@ -16,8 +16,18 @@
|
|||||||
{% bootstrap_field form.internal_name layout="control" %}
|
{% bootstrap_field form.internal_name layout="control" %}
|
||||||
</div>
|
</div>
|
||||||
{% bootstrap_field form.description layout="control" %}
|
{% bootstrap_field form.description layout="control" %}
|
||||||
{% bootstrap_field form.category_type layout="control" horizontal_field_class="big-radio-wrapper col-lg-9" %}
|
{% bootstrap_field form.category_type layout="control" horizontal_field_class="big-radio-wrapper col-md-9" %}
|
||||||
{% bootstrap_field form.cross_selling_condition layout="control" horizontal_field_class="col-lg-9" %}
|
<div class="row" data-display-dependency="#id_category_type_2">
|
||||||
|
<div class="col-md-offset-3 col-md-9">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
Please note that cross-selling categories are intended as a marketing feature and are not
|
||||||
|
suitable for strictly ensuring that products are only available in certain combinations.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% bootstrap_field form.cross_selling_condition layout="control" horizontal_field_class="col-md-9" %}
|
||||||
{% bootstrap_field form.cross_selling_match_products layout="control" %}
|
{% bootstrap_field form.cross_selling_match_products layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -296,11 +296,11 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
<div class="formset" data-formset data-formset-prefix="{{ add_formset.prefix }}">
|
<div class="formset" data-formset data-formset-prefix="{{ add_position_formset.prefix }}">
|
||||||
{{ add_formset.management_form }}
|
{{ add_position_formset.management_form }}
|
||||||
{% bootstrap_formset_errors add_formset %}
|
{% bootstrap_formset_errors add_position_formset %}
|
||||||
<div data-formset-body>
|
<div data-formset-body>
|
||||||
{% for add_form in add_formset %}
|
{% for add_form in add_position_formset %}
|
||||||
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
@@ -351,25 +351,25 @@
|
|||||||
</button>
|
</button>
|
||||||
{% trans "Add product" %}
|
{% trans "Add product" %}
|
||||||
<div class="sr-only">
|
<div class="sr-only">
|
||||||
{{ add_formset.empty_form.id }}
|
{{ add_position_formset.empty_form.id }}
|
||||||
{% bootstrap_field add_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
{% bootstrap_field add_position_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
||||||
</div>
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
{% bootstrap_field add_formset.empty_form.itemvar layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.itemvar layout="control" %}
|
||||||
{% bootstrap_field add_formset.empty_form.price addon_after=request.event.currency layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.price addon_after=request.event.currency layout="control" %}
|
||||||
{% if add_formset.empty_form.addon_to %}
|
{% if add_position_formset.empty_form.addon_to %}
|
||||||
{% bootstrap_field add_formset.empty_form.addon_to layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.addon_to layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if add_formset.empty_form.subevent %}
|
{% if add_position_formset.empty_form.subevent %}
|
||||||
{% bootstrap_field add_formset.empty_form.subevent layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.subevent layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if add_formset.empty_form.used_membership %}
|
{% if add_position_formset.empty_form.used_membership %}
|
||||||
{% bootstrap_field add_formset.empty_form.used_membership layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.used_membership layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% bootstrap_field add_formset.empty_form.seat layout="control" %}
|
{% bootstrap_field add_position_formset.empty_form.seat layout="control" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -431,13 +431,77 @@
|
|||||||
{% bootstrap_field fee.form.operation_cancel layout='inline' %}
|
{% bootstrap_field fee.form.operation_cancel layout='inline' %}
|
||||||
{% if fee.fee_type == "payment" %}
|
{% if fee.fee_type == "payment" %}
|
||||||
<em class="text-danger">
|
<em class="text-danger">
|
||||||
{% trans "Manually modifying payment fees is discouraged since they might automatically be on subsequent order changes or when choosing a different payment method." %}
|
{% trans "Manually modifying payment fees is discouraged since they might automatically be updated on subsequent order changes or when choosing a different payment method." %}
|
||||||
</em>
|
</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
<div class="formset" data-formset data-formset-prefix="{{ add_fee_formset.prefix }}">
|
||||||
|
{{ add_fee_formset.management_form }}
|
||||||
|
{% bootstrap_formset_errors add_fee_formset %}
|
||||||
|
<div data-formset-body>
|
||||||
|
{% for add_form in add_fee_formset %}
|
||||||
|
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<button type="button" class="btn btn-danger btn-xs pull-right flip"
|
||||||
|
data-formset-delete-button>
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
{% trans "Add fee" %}
|
||||||
|
<div class="sr-only">
|
||||||
|
{{ add_form.id }}
|
||||||
|
{% bootstrap_field add_form.DELETE form_group_class="" layout="inline" %}
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
{% bootstrap_field add_form.fee_type layout='control' %}
|
||||||
|
{% bootstrap_field add_form.value addon_after=request.event.currency layout='control' %}
|
||||||
|
{% bootstrap_field add_form.tax_rule layout='control' %}
|
||||||
|
{% bootstrap_field add_form.description layout='control' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<script type="form-template" data-formset-empty-form>
|
||||||
|
{% escapescript %}
|
||||||
|
<div class="panel panel-default items" data-formset-form data-subevent="0">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<button type="button" class="btn btn-danger btn-xs pull-right flip"
|
||||||
|
data-formset-delete-button>
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
{% trans "Add fee" %}
|
||||||
|
<div class="sr-only">
|
||||||
|
{{ add_fee_formset.empty_form.id }}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.fee_type layout='control' %}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.value addon_after=request.event.currency layout='control' %}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.tax_rule layout='control' %}
|
||||||
|
{% bootstrap_field add_fee_formset.empty_form.description layout='control' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endescapescript %}
|
||||||
|
</script>
|
||||||
|
<p>
|
||||||
|
<button type="button" class="btn btn-primary" data-formset-add>
|
||||||
|
<i class="fa fa-plus"></i> {% trans "Add fee" %}</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default items">
|
<div class="panel panel-default items">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
|
|||||||
@@ -198,7 +198,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
{% if order.status == "n" %}
|
{% if order.status == "n" and not order.require_approval %}
|
||||||
<dt>{% trans "Expiry date" %}</dt>
|
<dt>{% trans "Expiry date" %}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{{ order.expires|date:"SHORT_DATETIME_FORMAT" }}
|
{{ order.expires|date:"SHORT_DATETIME_FORMAT" }}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ class CheckinListList(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = self.request.event.checkin_lists.select_related('subevent').prefetch_related(
|
qs = self.request.event.checkin_lists.select_related('subevent').prefetch_related(
|
||||||
"limit_products", "auto_checkin_sales_channels"
|
"limit_products",
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.filter_form.is_valid():
|
if self.filter_form.is_valid():
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ class CategoryUpdate(EventPermissionRequiredMixin, UpdateView):
|
|||||||
messages.success(self.request, _('Your changes have been saved.'))
|
messages.success(self.request, _('Your changes have been saved.'))
|
||||||
if form.has_changed():
|
if form.has_changed():
|
||||||
self.object.log_action(
|
self.object.log_action(
|
||||||
'pretix.event.category.reordered', user=self.request.user, data={
|
'pretix.event.category.changed', user=self.request.user, data={
|
||||||
k: form.cleaned_data.get(k) for k in form.changed_data
|
k: form.cleaned_data.get(k) for k in form.changed_data
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -920,16 +920,19 @@ class QuotaCreate(EventPermissionRequiredMixin, CreateView):
|
|||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
kwargs = super().get_form_kwargs()
|
kwargs = super().get_form_kwargs()
|
||||||
|
|
||||||
|
kwargs.setdefault('initial', {})
|
||||||
if self.copy_from:
|
if self.copy_from:
|
||||||
i = modelcopy(self.copy_from)
|
i = modelcopy(self.copy_from)
|
||||||
i.pk = None
|
i.pk = None
|
||||||
kwargs['instance'] = i
|
kwargs['instance'] = i
|
||||||
kwargs.setdefault('initial', {})
|
|
||||||
kwargs['initial']['itemvars'] = [str(i.pk) for i in self.copy_from.items.all()] + [
|
kwargs['initial']['itemvars'] = [str(i.pk) for i in self.copy_from.items.all()] + [
|
||||||
'{}-{}'.format(v.item_id, v.pk) for v in self.copy_from.variations.all()
|
'{}-{}'.format(v.item_id, v.pk) for v in self.copy_from.variations.all()
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
kwargs['instance'] = Quota(event=self.request.event)
|
kwargs['instance'] = Quota(event=self.request.event)
|
||||||
|
if 'product' in self.request.GET:
|
||||||
|
kwargs['initial']['itemvars'] = self.request.GET.getlist('product')
|
||||||
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def form_invalid(self, form):
|
def form_invalid(self, form):
|
||||||
|
|||||||
@@ -122,10 +122,11 @@ from pretix.control.forms.filter import (
|
|||||||
)
|
)
|
||||||
from pretix.control.forms.orders import (
|
from pretix.control.forms.orders import (
|
||||||
CancelForm, CommentForm, DenyForm, EventCancelForm, ExporterForm,
|
CancelForm, CommentForm, DenyForm, EventCancelForm, ExporterForm,
|
||||||
ExtendForm, MarkPaidForm, OrderContactForm, OrderFeeChangeForm,
|
ExtendForm, MarkPaidForm, OrderContactForm, OrderFeeAddForm,
|
||||||
OrderLocaleForm, OrderMailForm, OrderPositionAddForm,
|
OrderFeeAddFormset, OrderFeeChangeForm, OrderLocaleForm, OrderMailForm,
|
||||||
OrderPositionAddFormset, OrderPositionChangeForm, OrderPositionMailForm,
|
OrderPositionAddForm, OrderPositionAddFormset, OrderPositionChangeForm,
|
||||||
OrderRefundForm, OtherOperationsForm, ReactivateOrderForm,
|
OrderPositionMailForm, OrderRefundForm, OtherOperationsForm,
|
||||||
|
ReactivateOrderForm,
|
||||||
)
|
)
|
||||||
from pretix.control.forms.rrule import RRuleForm
|
from pretix.control.forms.rrule import RRuleForm
|
||||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||||
@@ -1874,18 +1875,30 @@ class OrderChange(OrderView):
|
|||||||
data=self.request.POST if self.request.method == "POST" else None)
|
data=self.request.POST if self.request.method == "POST" else None)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def add_formset(self):
|
def add_position_formset(self):
|
||||||
ff = formset_factory(
|
ff = formset_factory(
|
||||||
OrderPositionAddForm, formset=OrderPositionAddFormset,
|
OrderPositionAddForm, formset=OrderPositionAddFormset,
|
||||||
can_order=False, can_delete=True, extra=0
|
can_order=False, can_delete=True, extra=0
|
||||||
)
|
)
|
||||||
return ff(
|
return ff(
|
||||||
prefix='add',
|
prefix='add_position',
|
||||||
order=self.order,
|
order=self.order,
|
||||||
items=self.items,
|
items=self.items,
|
||||||
data=self.request.POST if self.request.method == "POST" else None
|
data=self.request.POST if self.request.method == "POST" else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def add_fee_formset(self):
|
||||||
|
ff = formset_factory(
|
||||||
|
OrderFeeAddForm, formset=OrderFeeAddFormset,
|
||||||
|
can_order=False, can_delete=True, extra=0
|
||||||
|
)
|
||||||
|
return ff(
|
||||||
|
prefix='add_fee',
|
||||||
|
order=self.order,
|
||||||
|
data=self.request.POST if self.request.method == "POST" else None
|
||||||
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def items(self):
|
def items(self):
|
||||||
return self.request.event.items.prefetch_related('variations', 'tax_rule').all()
|
return self.request.event.items.prefetch_related('variations', 'tax_rule').all()
|
||||||
@@ -1914,7 +1927,8 @@ class OrderChange(OrderView):
|
|||||||
ctx = super().get_context_data(**kwargs)
|
ctx = super().get_context_data(**kwargs)
|
||||||
ctx['positions'] = self.positions
|
ctx['positions'] = self.positions
|
||||||
ctx['fees'] = self.fees
|
ctx['fees'] = self.fees
|
||||||
ctx['add_formset'] = self.add_formset
|
ctx['add_position_formset'] = self.add_position_formset
|
||||||
|
ctx['add_fee_formset'] = self.add_fee_formset
|
||||||
ctx['other_form'] = self.other_form
|
ctx['other_form'] = self.other_form
|
||||||
ctx['use_revocation_list'] = self.request.event.ticket_secret_generator.use_revocation_list
|
ctx['use_revocation_list'] = self.request.event.ticket_secret_generator.use_revocation_list
|
||||||
return ctx
|
return ctx
|
||||||
@@ -1929,12 +1943,35 @@ class OrderChange(OrderView):
|
|||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _process_add(self, ocm):
|
def _process_add_fees(self, ocm):
|
||||||
if not self.add_formset.is_valid():
|
if not self.add_fee_formset.is_valid():
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
for f in self.add_formset.forms:
|
for f in self.add_fee_formset.forms:
|
||||||
if f in self.add_formset.deleted_forms or not f.has_changed():
|
if f in self.add_fee_formset.deleted_forms or not f.has_changed():
|
||||||
|
continue
|
||||||
|
|
||||||
|
f = OrderFee(
|
||||||
|
fee_type=f.cleaned_data['fee_type'],
|
||||||
|
value=f.cleaned_data['value'],
|
||||||
|
order=ocm.order,
|
||||||
|
tax_rule=f.cleaned_data['tax_rule'],
|
||||||
|
description=f.cleaned_data['description'],
|
||||||
|
)
|
||||||
|
f._calculate_tax()
|
||||||
|
try:
|
||||||
|
ocm.add_fee(f)
|
||||||
|
except OrderError as e:
|
||||||
|
f.custom_error = str(e)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _process_add_positions(self, ocm):
|
||||||
|
if not self.add_position_formset.is_valid():
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
for f in self.add_position_formset.forms:
|
||||||
|
if f in self.add_position_formset.deleted_forms or not f.has_changed():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if '-' in f.cleaned_data['itemvar']:
|
if '-' in f.cleaned_data['itemvar']:
|
||||||
@@ -1959,7 +1996,7 @@ class OrderChange(OrderView):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _process_fees(self, ocm):
|
def _process_change_fees(self, ocm):
|
||||||
for f in self.fees:
|
for f in self.fees:
|
||||||
if not f.form.is_valid():
|
if not f.form.is_valid():
|
||||||
return False
|
return False
|
||||||
@@ -1980,7 +2017,7 @@ class OrderChange(OrderView):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _process_change(self, ocm):
|
def _process_change_positions(self, ocm):
|
||||||
for p in self.positions:
|
for p in self.positions:
|
||||||
if not p.form.is_valid():
|
if not p.form.is_valid():
|
||||||
return False
|
return False
|
||||||
@@ -2061,7 +2098,11 @@ class OrderChange(OrderView):
|
|||||||
notify=notify,
|
notify=notify,
|
||||||
reissue_invoice=self.other_form.cleaned_data['reissue_invoice'] if self.other_form.is_valid() else True
|
reissue_invoice=self.other_form.cleaned_data['reissue_invoice'] if self.other_form.is_valid() else True
|
||||||
)
|
)
|
||||||
form_valid = self._process_add(ocm) and self._process_fees(ocm) and self._process_change(ocm) and self._process_other(ocm)
|
form_valid = (self._process_add_fees(ocm) and
|
||||||
|
self._process_add_positions(ocm) and
|
||||||
|
self._process_change_fees(ocm) and
|
||||||
|
self._process_change_positions(ocm) and
|
||||||
|
self._process_other(ocm))
|
||||||
|
|
||||||
if not form_valid:
|
if not form_valid:
|
||||||
messages.error(self.request, _('An error occurred. Please see the details below.'))
|
messages.error(self.request, _('An error occurred. Please see the details below.'))
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ def event_list(request):
|
|||||||
max_fromto=Greatest(Max('subevents__date_to'), Max('subevents__date_from'))
|
max_fromto=Greatest(Max('subevents__date_to'), Max('subevents__date_from'))
|
||||||
).annotate(
|
).annotate(
|
||||||
order_from=Coalesce('min_from', 'date_from'),
|
order_from=Coalesce('min_from', 'date_from'),
|
||||||
).order_by('-order_from')
|
).order_by('-order_from', 'slug')
|
||||||
|
|
||||||
total = qs.count()
|
total = qs.count()
|
||||||
pagesize = 20
|
pagesize = 20
|
||||||
@@ -318,7 +318,7 @@ def nav_context_list(request):
|
|||||||
max_fromto=Greatest(Max('subevents__date_to'), Max('subevents__date_from'))
|
max_fromto=Greatest(Max('subevents__date_to'), Max('subevents__date_from'))
|
||||||
).annotate(
|
).annotate(
|
||||||
order_from=Coalesce('min_from', 'date_from'),
|
order_from=Coalesce('min_from', 'date_from'),
|
||||||
).order_by('-order_from')
|
).order_by('-order_from', 'slug')
|
||||||
|
|
||||||
if request.user.has_active_staff_session(request.session.session_key):
|
if request.user.has_active_staff_session(request.session.session_key):
|
||||||
qs_orga = Organizer.objects.all()
|
qs_orga = Organizer.objects.all()
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
|
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
|
||||||
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
|
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
|
||||||
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -656,40 +656,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr "تباين اللون سيئ للخلفية البيضاء، الرجاء اختيار لون غامق."
|
msgstr "تباين اللون سيئ للخلفية البيضاء، الرجاء اختيار لون غامق."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "البحث في الاستفسارات"
|
msgstr "البحث في الاستفسارات"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "الكل"
|
msgstr "الكل"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "لا شيء"
|
msgstr "لا شيء"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "المختارة فقط"
|
msgstr "المختارة فقط"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "قم باستخدم اسم مختلف داخليا"
|
msgstr "قم باستخدم اسم مختلف داخليا"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "اضغط لاغلاق الصفحة"
|
msgstr "اضغط لاغلاق الصفحة"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "لم تقم بحفظ التعديلات!"
|
msgstr "لم تقم بحفظ التعديلات!"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
||||||
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
||||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
@@ -623,40 +623,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
|
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
|
||||||
"Last-Translator: Michael <michael.happl@gmx.at>\n"
|
"Last-Translator: Michael <michael.happl@gmx.at>\n"
|
||||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -650,40 +650,40 @@ msgstr ""
|
|||||||
"Tato barva je pro text na bílém pozadí špatně kontrastní, zvolte prosím "
|
"Tato barva je pro text na bílém pozadí špatně kontrastní, zvolte prosím "
|
||||||
"tmavší odstín."
|
"tmavší odstín."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Hledaný výraz"
|
msgstr "Hledaný výraz"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Všechny"
|
msgstr "Všechny"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Žádný"
|
msgstr "Žádný"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Pouze vybrané"
|
msgstr "Pouze vybrané"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Interně používat jiný název"
|
msgstr "Interně používat jiný název"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Kliknutím zavřete"
|
msgstr "Kliknutím zavřete"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Máte neuložené změny!"
|
msgstr "Máte neuložené změny!"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -623,40 +623,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-07-10 15:00+0000\n"
|
"PO-Revision-Date: 2024-07-10 15:00+0000\n"
|
||||||
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
|
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
|
||||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -670,40 +670,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Ingen"
|
msgstr "Ingen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klik for at lukke"
|
msgstr "Klik for at lukke"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Du har ændringer, der ikke er gemt!"
|
msgstr "Du har ændringer, der ikke er gemt!"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
||||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -644,40 +644,40 @@ msgstr ""
|
|||||||
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
||||||
"Hintergrund. Bitte wählen Sie eine dunklere Farbe."
|
"Hintergrund. Bitte wählen Sie eine dunklere Farbe."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Suchbegriff"
|
msgstr "Suchbegriff"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Keine"
|
msgstr "Keine"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Nur ausgewählte"
|
msgstr "Nur ausgewählte"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
|
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Ungültige Seitenzahl."
|
msgstr "Ungültige Seitenzahl."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Intern einen anderen Namen verwenden"
|
msgstr "Intern einen anderen Namen verwenden"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klicken zum Schließen"
|
msgstr "Klicken zum Schließen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Sie haben ungespeicherte Änderungen!"
|
msgstr "Sie haben ungespeicherte Änderungen!"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
||||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||||
@@ -643,40 +643,40 @@ msgstr ""
|
|||||||
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
||||||
"Hintergrund. Bitte wähle eine dunklere Farbe."
|
"Hintergrund. Bitte wähle eine dunklere Farbe."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Suchbegriff"
|
msgstr "Suchbegriff"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Keine"
|
msgstr "Keine"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Nur ausgewählte"
|
msgstr "Nur ausgewählte"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
|
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Ungültige Seitenzahl."
|
msgstr "Ungültige Seitenzahl."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Intern einen anderen Namen verwenden"
|
msgstr "Intern einen anderen Namen verwenden"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klicken zum Schließen"
|
msgstr "Klicken zum Schließen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Du hast ungespeicherte Änderungen!"
|
msgstr "Du hast ungespeicherte Änderungen!"
|
||||||
|
|
||||||
|
|||||||
+930
-834
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:14+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
||||||
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
||||||
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -686,40 +686,40 @@ msgstr ""
|
|||||||
"Το χρώμα σας έχει κακή αντίθεση για κείμενο σε λευκό φόντο, επιλέξτε μια πιο "
|
"Το χρώμα σας έχει κακή αντίθεση για κείμενο σε λευκό φόντο, επιλέξτε μια πιο "
|
||||||
"σκούρα σκιά."
|
"σκούρα σκιά."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Όλα"
|
msgstr "Όλα"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Κανένας"
|
msgstr "Κανένας"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
|
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Κάντε κλικ για να κλείσετε"
|
msgstr "Κάντε κλικ για να κλείσετε"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+2350
-2283
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-10-22 17:00+0000\n"
|
"PO-Revision-Date: 2024-11-15 20:00+0000\n"
|
||||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
|
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
|
||||||
"pretix-js/es/>\n"
|
"pretix-js/es/>\n"
|
||||||
@@ -17,7 +17,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.7.2\n"
|
"X-Generator: Weblate 5.8.3\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||||
@@ -326,13 +326,13 @@ msgstr "Tickets válidos"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
||||||
msgid "Currently inside"
|
msgid "Currently inside"
|
||||||
msgstr "Actualmente adentro"
|
msgstr "Actualmente en el interior"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
||||||
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
||||||
#: pretix/static/pretixpresale/js/ui/questions.js:270
|
#: pretix/static/pretixpresale/js/ui/questions.js:270
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr "Sí"
|
msgstr "Si"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:72
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:72
|
||||||
#: pretix/static/pretixcontrol/js/ui/question.js:138
|
#: pretix/static/pretixcontrol/js/ui/question.js:138
|
||||||
@@ -570,10 +570,8 @@ msgid "Group of objects"
|
|||||||
msgstr "Grupo de objetos"
|
msgstr "Grupo de objetos"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Text object"
|
|
||||||
msgid "Text object (deprecated)"
|
msgid "Text object (deprecated)"
|
||||||
msgstr "Objeto de texto"
|
msgstr "Objeto texto (obsoleto)"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||||
msgid "Text box"
|
msgid "Text box"
|
||||||
@@ -644,40 +642,40 @@ msgstr ""
|
|||||||
"Tu color tiene mal contraste para un texto con fondo blanco, por favor, "
|
"Tu color tiene mal contraste para un texto con fondo blanco, por favor, "
|
||||||
"escoge un tono más oscuro."
|
"escoge un tono más oscuro."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Consultar búsqueda"
|
msgstr "Consultar búsqueda"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Ninguno"
|
msgstr "Ninguno"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Solamente seleccionados"
|
msgstr "Solamente seleccionados"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Introduce un número de página entre 1 y %(max)s."
|
msgstr "Introduce un número de página entre 1 y %(max)s."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Número de página inválido."
|
msgstr "Número de página inválido."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Usar un nombre diferente internamente"
|
msgstr "Usar un nombre diferente internamente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Click para cerrar"
|
msgstr "Click para cerrar"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "¡Tienes cambios sin guardar!"
|
msgstr "¡Tienes cambios sin guardar!"
|
||||||
|
|
||||||
@@ -704,12 +702,12 @@ msgid ""
|
|||||||
"The items in your cart are no longer reserved for you. You can still "
|
"The items in your cart are no longer reserved for you. You can still "
|
||||||
"complete your order as long as they’re available."
|
"complete your order as long as they’re available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Los elementos en su carrito de compras ya no se encuentran reservados. "
|
"Los elementos en su cesta de compras ya no se encuentran reservados. Puedes "
|
||||||
"Puedes seguir añadiendo más productos mientras estén disponibles."
|
"seguir añadiendo más productos mientras estén disponibles."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
||||||
msgid "Cart expired"
|
msgid "Cart expired"
|
||||||
msgstr "El carrito de compras ha expirado"
|
msgstr "La cesta de compra ha expirado"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:50
|
#: pretix/static/pretixpresale/js/ui/cart.js:50
|
||||||
msgid "The items in your cart are reserved for you for one minute."
|
msgid "The items in your cart are reserved for you for one minute."
|
||||||
@@ -730,7 +728,7 @@ msgstr "Obtienes %(currency)s %(price)s de vuelta"
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:227
|
#: pretix/static/pretixpresale/js/ui/main.js:227
|
||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Por favor, ingrese el monto que el organizador puede quedarse."
|
msgstr "Por favor, ingrese el importe que el organizador puede quedarse."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:449
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
@@ -1060,7 +1058,7 @@ msgstr "febrero"
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:80
|
#: pretix/static/pretixpresale/js/widget/widget.js:80
|
||||||
msgid "March"
|
msgid "March"
|
||||||
msgstr "marzo"
|
msgstr "Marzo"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:81
|
#: pretix/static/pretixpresale/js/widget/widget.js:81
|
||||||
msgid "April"
|
msgid "April"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
|
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
|
||||||
"Last-Translator: Albizuri <oier@puntu.eus>\n"
|
"Last-Translator: Albizuri <oier@puntu.eus>\n"
|
||||||
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -635,40 +635,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Guztiak"
|
msgstr "Guztiak"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
|
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
|
||||||
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
||||||
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
@@ -651,40 +651,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Kaikki"
|
msgstr "Kaikki"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Käytä toista nimeä sisäisesti"
|
msgstr "Käytä toista nimeä sisäisesti"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Sulje klikkaamalla"
|
msgstr "Sulje klikkaamalla"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Sinulla on tallentamattomia muutoksia!"
|
msgstr "Sinulla on tallentamattomia muutoksia!"
|
||||||
|
|
||||||
|
|||||||
+1607
-1760
File diff suppressed because it is too large
Load Diff
@@ -6,9 +6,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: French\n"
|
"Project-Id-Version: French\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-06-12 03:00+0000\n"
|
"PO-Revision-Date: 2024-11-16 05:00+0000\n"
|
||||||
"Last-Translator: simonD <simon.dalvy@gmail.com>\n"
|
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
"fr/>\n"
|
"fr/>\n"
|
||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
@@ -16,7 +16,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 5.5.5\n"
|
"X-Generator: Weblate 5.8.3\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||||
@@ -175,7 +175,7 @@ msgstr "Communication avec votre banque …"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
|
||||||
msgid "Select a check-in list"
|
msgid "Select a check-in list"
|
||||||
msgstr "Sélectionner une liste d'enregistrement"
|
msgstr "Choisis une liste d'enregistrement"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
|
||||||
msgid "No active check-in lists found."
|
msgid "No active check-in lists found."
|
||||||
@@ -191,7 +191,7 @@ msgstr "Résultats de recherche"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:34
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:34
|
||||||
msgid "No tickets found"
|
msgid "No tickets found"
|
||||||
msgstr "Aucun billet trouvé"
|
msgstr "Pas de billets trouvés"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:35
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:35
|
||||||
msgid "Result"
|
msgid "Result"
|
||||||
@@ -236,11 +236,11 @@ msgstr "Annulé"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
|
||||||
msgid "Confirmed"
|
msgid "Confirmed"
|
||||||
msgstr ""
|
msgstr "Confirmé"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
|
||||||
msgid "Approval pending"
|
msgid "Approval pending"
|
||||||
msgstr ""
|
msgstr "En attente d'approbation"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
|
||||||
msgid "Redeemed"
|
msgid "Redeemed"
|
||||||
@@ -293,7 +293,7 @@ msgstr "Entrée non autorisée"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:62
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:62
|
||||||
msgid "Ticket code revoked/changed"
|
msgid "Ticket code revoked/changed"
|
||||||
msgstr "Code du billet révoqué/modifié"
|
msgstr "Code de billet bloqué/modifié"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
|
||||||
msgid "Ticket blocked"
|
msgid "Ticket blocked"
|
||||||
@@ -325,7 +325,7 @@ msgstr "Billets valides"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
||||||
msgid "Currently inside"
|
msgid "Currently inside"
|
||||||
msgstr "Présent actuellement"
|
msgstr "Actuellement à l'intérieur"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
||||||
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
||||||
@@ -452,13 +452,12 @@ msgid "Product variation"
|
|||||||
msgstr "Variation du produit"
|
msgstr "Variation du produit"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
||||||
#, fuzzy
|
|
||||||
msgid "Gate"
|
msgid "Gate"
|
||||||
msgstr "Pont"
|
msgstr "Pont"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
||||||
msgid "Current date and time"
|
msgid "Current date and time"
|
||||||
msgstr "Date et heure courante"
|
msgstr "Date et heure actuelle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
||||||
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
||||||
@@ -466,7 +465,7 @@ msgstr "Jour courant de la semaine (1 = Lundi, 7 = Dimanche)"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
||||||
msgid "Current entry status"
|
msgid "Current entry status"
|
||||||
msgstr ""
|
msgstr "Statut actuel de l'entrée"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
||||||
msgid "Number of previous entries"
|
msgid "Number of previous entries"
|
||||||
@@ -477,14 +476,10 @@ msgid "Number of previous entries since midnight"
|
|||||||
msgstr "Nombre d'entrées depuis minuit"
|
msgstr "Nombre d'entrées depuis minuit"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of previous entries"
|
|
||||||
msgid "Number of previous entries since"
|
msgid "Number of previous entries since"
|
||||||
msgstr "Nombre d'entrées précédentes depuis"
|
msgstr "Nombre d'entrées précédentes depuis"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of previous entries"
|
|
||||||
msgid "Number of previous entries before"
|
msgid "Number of previous entries before"
|
||||||
msgstr "Nombre d'entrées précédentes avant"
|
msgstr "Nombre d'entrées précédentes avant"
|
||||||
|
|
||||||
@@ -493,16 +488,12 @@ msgid "Number of days with a previous entry"
|
|||||||
msgstr "Nombre de jours avec entrée préalable"
|
msgstr "Nombre de jours avec entrée préalable"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of days with a previous entry"
|
|
||||||
msgid "Number of days with a previous entry since"
|
msgid "Number of days with a previous entry since"
|
||||||
msgstr "Nombre de jours avec entrée préalable"
|
msgstr "Nombre de jours avec entrée préalable depuis"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of days with a previous entry"
|
|
||||||
msgid "Number of days with a previous entry before"
|
msgid "Number of days with a previous entry before"
|
||||||
msgstr "Nombre de jours avec entrée préalable"
|
msgstr "Nombre de jours avec entrée préalable avant"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
|
||||||
msgid "Minutes since last entry (-1 on first entry)"
|
msgid "Minutes since last entry (-1 on first entry)"
|
||||||
@@ -559,12 +550,12 @@ msgstr "Doublon"
|
|||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
|
||||||
msgctxt "entry_status"
|
msgctxt "entry_status"
|
||||||
msgid "present"
|
msgid "present"
|
||||||
msgstr ""
|
msgstr "présent"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
|
||||||
msgctxt "entry_status"
|
msgctxt "entry_status"
|
||||||
msgid "absent"
|
msgid "absent"
|
||||||
msgstr ""
|
msgstr "absent"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||||
msgid "Check-in QR"
|
msgid "Check-in QR"
|
||||||
@@ -581,16 +572,12 @@ msgid "Group of objects"
|
|||||||
msgstr "Groupe d'objets"
|
msgstr "Groupe d'objets"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Text object"
|
|
||||||
msgid "Text object (deprecated)"
|
msgid "Text object (deprecated)"
|
||||||
msgstr "Objet texte"
|
msgstr "Objet textuel (obsolète)"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Text object"
|
|
||||||
msgid "Text box"
|
msgid "Text box"
|
||||||
msgstr "Objet texte"
|
msgstr "Zone de texte"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||||
msgid "Barcode area"
|
msgid "Barcode area"
|
||||||
@@ -656,41 +643,40 @@ msgstr ""
|
|||||||
"Votre choix de couleur n'a pas un bon contraste avec du texte sur un fond "
|
"Votre choix de couleur n'a pas un bon contraste avec du texte sur un fond "
|
||||||
"blanc, SVP choisissez un ton plus sombre."
|
"blanc, SVP choisissez un ton plus sombre."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Recherche"
|
msgstr "Requête de recherche"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tous"
|
msgstr "Tous"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Aucun"
|
msgstr "Aucun"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Seuls les sélectionnés"
|
msgstr "Seuls les sélectionnés"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr "Saisir le numéro de page entre 1 et %(max)s."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
#, fuzzy
|
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Numéro de page invalide."
|
msgstr "Numéro de page invalide."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Utiliser un nom différent en interne"
|
msgstr "Utiliser un nom différent en interne"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Cliquez pour fermer"
|
msgstr "Cliquez pour fermer"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Vous avez des modifications non sauvegardées !"
|
msgstr "Vous avez des modifications non sauvegardées !"
|
||||||
|
|
||||||
@@ -718,7 +704,7 @@ msgid ""
|
|||||||
"complete your order as long as they’re available."
|
"complete your order as long as they’re available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les articles de votre panier ne vous sont plus réservés. Vous pouvez "
|
"Les articles de votre panier ne vous sont plus réservés. Vous pouvez "
|
||||||
"toujours terminer votre commande tant qu’ils sont disponibles."
|
"toujours compléter votre commande tant qu'ils sont disponibles."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
||||||
msgid "Cart expired"
|
msgid "Cart expired"
|
||||||
@@ -785,12 +771,9 @@ msgid "Price"
|
|||||||
msgstr "Prix"
|
msgstr "Prix"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:20
|
#: pretix/static/pretixpresale/js/widget/widget.js:20
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "Select %s"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Sélectionné %s"
|
msgstr "Sélectionner"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:21
|
#: pretix/static/pretixpresale/js/widget/widget.js:21
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
@@ -866,22 +849,16 @@ msgid "Only available with a voucher"
|
|||||||
msgstr "Disponible avec un bon de réduction"
|
msgstr "Disponible avec un bon de réduction"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:35
|
#: pretix/static/pretixpresale/js/widget/widget.js:35
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Payment method unavailable"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Not yet available"
|
msgid "Not yet available"
|
||||||
msgstr "Méthode de paiement non disponible"
|
msgstr "Pas encore disponible"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:36
|
#: pretix/static/pretixpresale/js/widget/widget.js:36
|
||||||
#, fuzzy
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Not available anymore"
|
msgid "Not available anymore"
|
||||||
msgstr "Méthode de paiement plus disponible"
|
msgstr "Plus disponible"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:37
|
#: pretix/static/pretixpresale/js/widget/widget.js:37
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "currently available: %s"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Currently not available"
|
msgid "Currently not available"
|
||||||
msgstr "Actuellement non disponible"
|
msgstr "Actuellement non disponible"
|
||||||
@@ -977,20 +954,14 @@ msgid "Continue"
|
|||||||
msgstr "Continuer"
|
msgstr "Continuer"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:56
|
#: pretix/static/pretixpresale/js/widget/widget.js:56
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "Select variant %s"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Show variants"
|
msgid "Show variants"
|
||||||
msgstr "Voir les variations"
|
msgstr "Afficher les variantes"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:57
|
#: pretix/static/pretixpresale/js/widget/widget.js:57
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "Select variant %s"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Hide variants"
|
msgid "Hide variants"
|
||||||
msgstr "Masquer les variations"
|
msgstr "Masquer les variantes"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:58
|
#: pretix/static/pretixpresale/js/widget/widget.js:58
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
||||||
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
||||||
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
@@ -658,40 +658,40 @@ msgstr ""
|
|||||||
"A túa cor ten mal contraste para un texto con fondo branco. Por favor, "
|
"A túa cor ten mal contraste para un texto con fondo branco. Por favor, "
|
||||||
"escolle un ton máis escuro."
|
"escolle un ton máis escuro."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Consultar unha procura"
|
msgstr "Consultar unha procura"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Ningún"
|
msgstr "Ningún"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Soamente seleccionados"
|
msgstr "Soamente seleccionados"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Usar un nome diferente internamente"
|
msgstr "Usar un nome diferente internamente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Click para cerrar"
|
msgstr "Click para cerrar"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Tes cambios sen gardar!"
|
msgstr "Tes cambios sen gardar!"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
|
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
|
||||||
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
|
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
|
||||||
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -630,40 +630,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user