mirror of
https://github.com/pretix/pretix.git
synced 2026-05-14 16:44:06 +00:00
Store event_id in OrderSyncQueue, always fill not_before, log unhandled exceptions
This commit is contained in:
@@ -148,9 +148,10 @@ class OutboundSyncProvider:
|
||||
raise TypeError('Call this method on a derived class that defines an "identifier" attribute.')
|
||||
OrderSyncQueue.objects.create(
|
||||
order=order,
|
||||
event=order.event,
|
||||
sync_provider=cls.identifier,
|
||||
triggered_by=triggered_by,
|
||||
not_before=not_before,
|
||||
not_before=not_before or now(),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -235,6 +236,11 @@ class OutboundSyncProvider:
|
||||
f"Could not sync order {sq.order.code} to {type(self).__name__} (unhandled exception)"
|
||||
)
|
||||
sentry_sdk.capture_exception(e)
|
||||
sq.order.log_action("pretix.event.order.data_sync.failed.internal", {
|
||||
"provider": self.identifier,
|
||||
"error": [],
|
||||
"full_message": str(e),
|
||||
})
|
||||
sq.delete()
|
||||
else:
|
||||
sq.order.log_action("pretix.event.order.data_sync.success", {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 4.2.16 on 2025-04-01 14:52
|
||||
# Generated by Django 4.2.16 on 2025-05-07 13:01
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
@@ -11,33 +11,6 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="OrderSyncQueue",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True, primary_key=True, serialize=False
|
||||
),
|
||||
),
|
||||
("sync_provider", models.CharField(max_length=128)),
|
||||
("triggered_by", models.CharField(max_length=128)),
|
||||
("triggered", models.DateTimeField(auto_now_add=True)),
|
||||
("failed_attempts", models.PositiveIntegerField(default=0)),
|
||||
("not_before", models.DateTimeField(blank=True, null=True)),
|
||||
(
|
||||
"order",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="queued_sync_jobs",
|
||||
to="pretixbase.order",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"unique_together": {("order", "sync_provider")},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="OrderSyncResult",
|
||||
fields=[
|
||||
@@ -79,9 +52,45 @@ class Migration(migrations.Migration):
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["order", "sync_provider"],
|
||||
name="pretixbase__order_i_23d278_idx",
|
||||
name="pretixbase__order_i_3e3c84_idx",
|
||||
)
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="OrderSyncQueue",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True, primary_key=True, serialize=False
|
||||
),
|
||||
),
|
||||
("sync_provider", models.CharField(max_length=128)),
|
||||
("triggered_by", models.CharField(max_length=128)),
|
||||
("triggered", models.DateTimeField(auto_now_add=True)),
|
||||
("failed_attempts", models.PositiveIntegerField(default=0)),
|
||||
("not_before", models.DateTimeField(db_index=True)),
|
||||
(
|
||||
"event",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="queued_sync_jobs",
|
||||
to="pretixbase.event",
|
||||
),
|
||||
),
|
||||
(
|
||||
"order",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="queued_sync_jobs",
|
||||
to="pretixbase.order",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"ordering": ("triggered",),
|
||||
"unique_together": {("order", "sync_provider")},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -25,7 +25,7 @@ from functools import cached_property
|
||||
|
||||
from django.db import models
|
||||
|
||||
from pretix.base.models import Order, OrderPosition
|
||||
from pretix.base.models import Event, Order, OrderPosition
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,11 +40,14 @@ class OrderSyncQueue(models.Model):
|
||||
order = models.ForeignKey(
|
||||
Order, on_delete=models.CASCADE, related_name="queued_sync_jobs"
|
||||
)
|
||||
event = models.ForeignKey(
|
||||
Event, on_delete=models.CASCADE, related_name="queued_sync_jobs"
|
||||
)
|
||||
sync_provider = models.CharField(blank=False, null=False, max_length=128)
|
||||
triggered_by = models.CharField(blank=False, null=False, max_length=128)
|
||||
triggered = models.DateTimeField(blank=False, null=False, auto_now_add=True)
|
||||
failed_attempts = models.PositiveIntegerField(default=0)
|
||||
not_before = models.DateTimeField(blank=True, null=True)
|
||||
not_before = models.DateTimeField(blank=False, null=False, db_index=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (("order", "sync_provider"),)
|
||||
|
||||
@@ -446,6 +446,7 @@ class OrderDataSyncLogEntryType(OrderLogEntryType):
|
||||
"pretix.event.order.data_sync.failed.config": _("Transferring data to {provider} failed due to invalid configuration:"),
|
||||
"pretix.event.order.data_sync.failed.exceeded": _("Maximum number of retries exceeded while transferring data to {provider}:"),
|
||||
"pretix.event.order.data_sync.failed.permanent": _("Error while transferring data to {provider}:"),
|
||||
"pretix.event.order.data_sync.failed.internal": _("Internal error while transferring data to {provider}."),
|
||||
})
|
||||
class OrderDataSyncErrorLogEntryType(OrderLogEntryType):
|
||||
def display(self, logentry, data):
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<form action="{% url "control:event.order.sync_job" organizer=event.organizer.slug event=event.slug code=order.code provider=identifier %}" method="post" class="form-inline pull-right">
|
||||
{% csrf_token %}
|
||||
{% if pending %}
|
||||
{% if pending.not_before %}
|
||||
{% if pending.not_before > now %}
|
||||
<button type="submit" name="run_job_now" value="{{ pending.pk }}" class="btn btn-default"><i class="fa fa-refresh"></i> {% trans "Retry now" %}</button>
|
||||
{% endif %}
|
||||
<button type="submit" name="cancel_job" value="{{ pending.pk }}" class="btn btn-danger"><i class="fa fa-times"></i> {% trans "Cancel" %}</button>
|
||||
@@ -35,7 +35,7 @@
|
||||
Waiting until {{ datetime }}
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% elif pending.not_before %}
|
||||
{% elif pending.not_before > now %}
|
||||
{% blocktrans trimmed with datetime=pending.not_before|date:"SHORT_DATETIME_FORMAT" %}
|
||||
Waiting until {{ datetime }}
|
||||
{% endblocktrans %}
|
||||
|
||||
@@ -27,6 +27,7 @@ from django.dispatch import receiver
|
||||
from django.http import HttpResponseNotAllowed
|
||||
from django.shortcuts import redirect
|
||||
from django.template.loader import get_template
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from pretix.base.datasync.datasync import sync_targets
|
||||
@@ -55,6 +56,7 @@ def on_control_order_info(sender: Event, request, order: Order, **kwargs):
|
||||
"request": request,
|
||||
"event": sender,
|
||||
"providers": providers,
|
||||
"now": now(),
|
||||
}
|
||||
return template.render(ctx, request=request)
|
||||
|
||||
@@ -74,7 +76,7 @@ class ControlSyncJob(OrderView):
|
||||
messages.success(self.request, _('The sync job has been canceled.'))
|
||||
elif self.request.POST.get("run_job_now"):
|
||||
job = self.order.queued_sync_jobs.get(pk=self.request.POST.get("run_job_now"))
|
||||
job.not_before = None
|
||||
job.not_before = now()
|
||||
job.save()
|
||||
messages.success(self.request, _('The sync job has been set to run as soon as possible.'))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user