Merge branch 'master' into release/2025.1.0
All checks were successful
Build Deploy email notification tool / Apply-Kubernetes-Resources (push) Successful in 1m42s

This commit is contained in:
2025-02-10 14:48:25 +00:00
10 changed files with 63 additions and 42 deletions

View File

@@ -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
run: podman push cr.ortlerstrasse.de/cgo/pretix:latest

View File

@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
__version__ = "2025.1.0"
__version__ = "2025.2.0.dev0"

View File

@@ -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'])

View File

@@ -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")

View File

@@ -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: 조정화 <junghwa.jo@om.org>\n"
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/ko/"
">\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."

View File

@@ -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 <amandajurno@gmail.com>\n"
"PO-Revision-Date: 2025-02-03 16:07+0000\n"
"Last-Translator: Cornelius Kibelka <ckibelka-ctr@wikimedia.org>\n"
"Language-Team: Portuguese <https://translate.pretix.eu/projects/pretix/"
"pretix/pt/>\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

View File

@@ -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 <davidmgvaz@gmail.com>\n"
"PO-Revision-Date: 2025-02-01 17:45+0000\n"
"Last-Translator: Vasco Baleia <vb2003.12@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_PT/>\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

View File

@@ -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'])

View File

@@ -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):
@@ -1650,6 +1640,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):

View File

@@ -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
)