From 34da20972e912b0a4b5c668ea090cc4319b0dfdd Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 31 Jan 2025 16:21:06 +0100 Subject: [PATCH 1/6] Bump version to 2025.2.0.dev0 --- src/pretix/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pretix/__init__.py b/src/pretix/__init__.py index 3f06d7852..7504f262f 100644 --- a/src/pretix/__init__.py +++ b/src/pretix/__init__.py @@ -19,4 +19,4 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -__version__ = "2025.1.0" +__version__ = "2025.2.0.dev0" From 58db550e239f4c9c9d492186198551c269b7c303 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 3 Feb 2025 17:07:19 +0100 Subject: [PATCH 2/6] Do not allow to cancel pending payments by default (Z#23179178) --- src/pretix/base/payment.py | 11 +++++++++-- src/tests/plugins/banktransfer/test_import.py | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index 81fa9b9e7..69bea1359 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -957,12 +957,19 @@ class BasePaymentProvider: def cancel_payment(self, payment: OrderPayment): """ - Will be called to cancel a payment. The default implementation just sets the payment state to canceled, - but in some cases you might want to notify an external provider. + Will be called to cancel a payment. The default implementation fails if the payment is + ``OrderPayment.PAYMENT_STATE_PENDING`` and ``abort_pending_allowed`` is false. Otherwise, it just sets the + payment state to canceled. In some cases you might want to modify this behaviour to notify the external provider + of the cancellation. On success, you should set ``payment.state = OrderPayment.PAYMENT_STATE_CANCELED`` (or call the super method). On failure, you should raise a PaymentException. """ + if payment.state == OrderPayment.PAYMENT_STATE_PENDING and not self.abort_pending_allowed: + raise PaymentException(_( + "This payment is already being processed and can not be canceled any more." + )) + payment.state = OrderPayment.PAYMENT_STATE_CANCELED payment.save(update_fields=['state']) diff --git a/src/tests/plugins/banktransfer/test_import.py b/src/tests/plugins/banktransfer/test_import.py index 05e2a76b8..49a7f8db3 100644 --- a/src/tests/plugins/banktransfer/test_import.py +++ b/src/tests/plugins/banktransfer/test_import.py @@ -574,7 +574,7 @@ def test_pending_paypal_drop_fee(env, job): env[2].save() p = env[2].payments.create( provider='paypal', - state=OrderPayment.PAYMENT_STATE_PENDING, + state=OrderPayment.PAYMENT_STATE_CREATED, fee=fee, amount=env[2].total ) From 0b840f8133cc29891cf8aa96ed79bba455de2320 Mon Sep 17 00:00:00 2001 From: pretix translation bot Date: Mon, 3 Feb 2025 17:08:21 +0100 Subject: [PATCH 3/6] Update translations (#4799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translations: Update Portuguese (Portugal) Currently translated at 85.2% (4986 of 5846 strings) Translation: pretix/pretix Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_PT/ powered by weblate * Translations: Update Portuguese Currently translated at 3.0% (178 of 5846 strings) Translation: pretix/pretix Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt/ powered by weblate * Translations: Update Korean Currently translated at 1.3% (76 of 5846 strings) Translation: pretix/pretix Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/ powered by weblate --------- Co-authored-by: Vasco Baleia Co-authored-by: Cornelius Kibelka Co-authored-by: 조정화 --- src/pretix/locale/ko/LC_MESSAGES/django.po | 4 ++-- src/pretix/locale/pt/LC_MESSAGES/django.po | 10 ++++------ src/pretix/locale/pt_PT/LC_MESSAGES/django.po | 10 ++++------ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/pretix/locale/ko/LC_MESSAGES/django.po b/src/pretix/locale/ko/LC_MESSAGES/django.po index 7970cf7fc..0c7c1c107 100644 --- a/src/pretix/locale/ko/LC_MESSAGES/django.po +++ b/src/pretix/locale/ko/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-01-29 13:18+0000\n" -"PO-Revision-Date: 2025-01-31 05:00+0000\n" +"PO-Revision-Date: 2025-02-03 16:07+0000\n" "Last-Translator: 조정화 \n" "Language-Team: Korean \n" @@ -319,7 +319,7 @@ msgstr "질문 간의 순환 의존성이 감지되었습니다." #: pretix/api/serializers/item.py:543 pretix/control/forms/item.py:191 msgid "This type of question cannot be asked during check-in." -msgstr "" +msgstr "체크인 하는 동안에는 그러한 질문을 할 수 없습니다." #: pretix/api/serializers/item.py:546 pretix/control/forms/item.py:199 msgid "This type of question cannot be shown during check-in." diff --git a/src/pretix/locale/pt/LC_MESSAGES/django.po b/src/pretix/locale/pt/LC_MESSAGES/django.po index c97f38ccf..f4fefb399 100644 --- a/src/pretix/locale/pt/LC_MESSAGES/django.po +++ b/src/pretix/locale/pt/LC_MESSAGES/django.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-01-29 13:18+0000\n" -"PO-Revision-Date: 2021-08-12 21:00+0000\n" -"Last-Translator: amandajurno \n" +"PO-Revision-Date: 2025-02-03 16:07+0000\n" +"Last-Translator: Cornelius Kibelka \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Weblate 4.6\n" +"X-Generator: Weblate 5.9.2\n" #: pretix/_base_settings.py:87 msgid "English" @@ -3399,10 +3399,8 @@ msgid "The relevant plugin is currently not active." msgstr "" #: pretix/base/logentrytypes.py:49 -#, fuzzy -#| msgid "Delete" msgid "(deleted)" -msgstr "Deletar" +msgstr "(deletado)" #: pretix/base/logentrytypes.py:78 #, python-brace-format diff --git a/src/pretix/locale/pt_PT/LC_MESSAGES/django.po b/src/pretix/locale/pt_PT/LC_MESSAGES/django.po index 476494cc2..6303157da 100644 --- a/src/pretix/locale/pt_PT/LC_MESSAGES/django.po +++ b/src/pretix/locale/pt_PT/LC_MESSAGES/django.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-01-29 13:18+0000\n" -"PO-Revision-Date: 2025-01-10 20:00+0000\n" -"Last-Translator: David Vaz \n" +"PO-Revision-Date: 2025-02-01 17:45+0000\n" +"Last-Translator: Vasco Baleia \n" "Language-Team: Portuguese (Portugal) \n" "Language: pt_PT\n" @@ -33831,7 +33831,7 @@ msgstr "Ver outra data" #: pretix/presale/templates/pretixpresale/event/index.html:89 msgid "Choose date to book a ticket" -msgstr "Escolha uma data para comprar um bilhete" +msgstr "Escolha um evento" #: pretix/presale/templates/pretixpresale/event/index.html:152 #: pretix/presale/views/waiting.py:141 pretix/presale/views/widget.py:756 @@ -34625,11 +34625,9 @@ msgstr "Layout de bilhete PDF" #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:18 #: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:60 #: pretix/presale/views/widget.py:416 -#, fuzzy -#| msgid "Pay now" msgctxt "available_event_in_list" msgid "Buy now" -msgstr "Pagar agora" +msgstr "Disponível" #: pretix/presale/templates/pretixpresale/fragment_calendar.html:93 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:108 From 2a3cdd85e81e557b1f73af038c0b5fa19e789a08 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 3 Feb 2025 17:09:17 +0100 Subject: [PATCH 4/6] Prevent order changes that interfer with a pending payment that can't be aborted (Z#23179178) (#4765) --- src/pretix/presale/views/order.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index 1843ec398..68396c0e2 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -1650,6 +1650,13 @@ class OrderChangeMixin: raise OrderError(_('You may not change your order in a way that increases the total price since ' 'payments are no longer being accepted for this event.')) + if ocm._totaldiff > Decimal('0.00') and self.order.status == Order.STATUS_PENDING: + for p in self.order.payments.filter(state=OrderPayment.PAYMENT_STATE_PENDING): + if not p.payment_provider.abort_pending_allowed: + raise OrderError(_('You may not change your order in a way that requires additional payment while ' + 'we are processing your current payment. Please check back after your current ' + 'payment has been accepted.')) + @method_decorator(xframe_options_exempt, 'dispatch') class OrderChange(OrderChangeMixin, EventViewMixin, OrderDetailMixin, TemplateView): From c820d742d414b970c4c928e7f1a9727ddc8366cf Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 3 Feb 2025 17:39:46 +0100 Subject: [PATCH 5/6] Generate invoice earlier in payment method change process (Z#23179304) (#4763) * Generate invoice earlier in payment method change process (Z##23179304) * Resolve review note --- src/pretix/base/services/orders.py | 24 ++++++++++++++++++++-- src/pretix/plugins/banktransfer/tasks.py | 5 +++-- src/pretix/presale/views/order.py | 26 ++++++++---------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index 9e12e9e30..456318398 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -3114,14 +3114,34 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay } ) + new_invoice_created = False if recreate_invoices: + # Lock to prevent duplicate invoice creation + order = Order.objects.select_for_update(of=OF_SELF).get(pk=order.pk) + i = order.invoices.filter(is_cancellation=False).last() - if i and order.total != oldtotal and not i.canceled: + has_active_invoice = i and not i.canceled + + if has_active_invoice and order.total != oldtotal: generate_cancellation(i) generate_invoice(order) + new_invoice_created = True + + elif (not has_active_invoice or order.invoice_dirty) and invoice_qualified(order): + if order.event.settings.get('invoice_generate') == 'True' or ( + order.event.settings.get('invoice_generate') == 'paid' and + new_payment.payment_provider.requires_invoice_immediately + ): + if has_active_invoice: + generate_cancellation(i) + i = generate_invoice(order) + new_invoice_created = True + order.log_action('pretix.event.order.invoice.generated', data={ + 'invoice': i.pk + }) order.create_transactions() - return old_fee, new_fee, fee, new_payment + return old_fee, new_fee, fee, new_payment, new_invoice_created @receiver(order_paid, dispatch_uid="pretixbase_order_paid_giftcards") diff --git a/src/pretix/plugins/banktransfer/tasks.py b/src/pretix/plugins/banktransfer/tasks.py index 15c084d57..174ff437e 100644 --- a/src/pretix/plugins/banktransfer/tasks.py +++ b/src/pretix/plugins/banktransfer/tasks.py @@ -267,8 +267,9 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = N if created: # We're perform a payment method switching on-demand here - old_fee, new_fee, fee, p = change_payment_provider(order, p.payment_provider, p.amount, - new_payment=p, create_log=False) # noqa + old_fee, new_fee, fee, p, new_invoice_created = change_payment_provider( + order, p.payment_provider, p.amount, new_payment=p, create_log=False + ) # noqa if fee: p.fee = fee p.save(update_fields=['fee']) diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index 68396c0e2..e373e14d9 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -86,7 +86,6 @@ from pretix.base.signals import order_modified, register_ticket_outputs from pretix.base.templatetags.money import money_filter from pretix.base.views.mixins import OrderQuestionsViewMixin from pretix.base.views.tasks import AsyncAction -from pretix.helpers import OF_SELF from pretix.helpers.http import redirect_to_url from pretix.helpers.safedownload import check_token from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse @@ -445,22 +444,8 @@ class OrderPaymentConfirm(EventViewMixin, OrderDetailMixin, TemplateView): def post(self, request, *args, **kwargs): try: - with transaction.atomic(): - order = Order.objects.select_for_update(of=OF_SELF).get(pk=self.order.pk) - i = order.invoices.filter(is_cancellation=False).last() - has_active_invoice = i and not i.canceled - if (not has_active_invoice or order.invoice_dirty) and invoice_qualified(order): - if self.request.event.settings.get('invoice_generate') == 'True' or ( - self.request.event.settings.get('invoice_generate') == 'paid' and self.payment.payment_provider.requires_invoice_immediately): - if has_active_invoice: - generate_cancellation(i) - i = generate_invoice(order) - order.log_action('pretix.event.order.invoice.generated', data={ - 'invoice': i.pk - }) - messages.success(self.request, _('An invoice has been generated.')) - self.payment.process_initiated = True - self.payment.save(update_fields=['process_initiated']) + self.payment.process_initiated = True + self.payment.save(update_fields=['process_initiated']) resp = self.payment.payment_provider.execute_payment(request, self.payment) except PaymentException as e: messages.error(request, str(e)) @@ -674,7 +659,12 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView): request.session['payment_change_{}'.format(self.order.pk)] = '1' with transaction.atomic(): - old_fee, new_fee, fee, newpayment = change_payment_provider(self.order, p['provider'], None) + old_fee, new_fee, fee, newpayment, new_invoice_created = change_payment_provider( + self.order, p['provider'], None + ) + + if new_invoice_created: + messages.success(self.request, _('An invoice has been generated.')) resp = p['provider'].payment_prepare(request, newpayment) if isinstance(resp, str): From 9179621e72bbbc54ce835d9a37a07c4cea98d709 Mon Sep 17 00:00:00 2001 From: UpdateBot Date: Wed, 5 Feb 2025 22:02:20 +0100 Subject: [PATCH 6/6] Use latest tag in master branch --- .gitea/workflows/cicd.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/cicd.yaml b/.gitea/workflows/cicd.yaml index 3ddc71a06..877d6f721 100644 --- a/.gitea/workflows/cicd.yaml +++ b/.gitea/workflows/cicd.yaml @@ -13,6 +13,6 @@ jobs: - name: Login to Docker Registry run: podman login -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_TOKEN }} cr.ortlerstrasse.de - name: Build Docker image - run: podman build -t cr.ortlerstrasse.de/cgo/pretix:2025.1.0 . + run: podman build -t cr.ortlerstrasse.de/cgo/pretix:latest . - name: Push Docker image - run: podman push cr.ortlerstrasse.de/cgo/pretix:2025.1.0 \ No newline at end of file + run: podman push cr.ortlerstrasse.de/cgo/pretix:latest \ No newline at end of file