diff --git a/src/pretix/base/datasync/datasync.py b/src/pretix/base/datasync/datasync.py index 4bb1285520..dd951e0a39 100644 --- a/src/pretix/base/datasync/datasync.py +++ b/src/pretix/base/datasync/datasync.py @@ -28,7 +28,6 @@ from functools import cached_property from itertools import groupby import sentry_sdk -from django.db import models from django.db.models import Q from django.dispatch import receiver from django.utils.timezone import now @@ -39,76 +38,12 @@ from pretix.base.datasync.sourcefields import ( EVENT, EVENT_OR_SUBEVENT, ORDER, ORDER_POSITION, get_data_fields, ) from pretix.base.logentrytype_registry import make_link -from pretix.base.models import Order, OrderPosition +from pretix.base.models.datasync import OrderSyncLink, OrderSyncQueue from pretix.base.signals import EventPluginRegistry, periodic_task from pretix.celery_app import app logger = logging.getLogger(__name__) -MODE_OVERWRITE = "overwrite" -MODE_SET_IF_NEW = "if_new" -MODE_SET_IF_EMPTY = "if_empty" -MODE_APPEND_LIST = "append" - - -class OrderSyncQueue(models.Model): - class Meta: - unique_together = (("order", "sync_provider"),) - ordering = ("triggered",) - - order = models.ForeignKey( - Order, 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) - - @cached_property - def _provider_class_info(self): - return sync_targets.get(identifier=self.sync_provider) - - @property - def provider_class(self): - return self._provider_class_info[0] - - @property - def is_provider_active(self): - return self._provider_class_info[1] - - @property - def max_retry_attempts(self): - return self.provider_class.max_attempts - - -class OrderSyncLink(models.Model): - class Meta: - indexes = [ - models.Index(fields=("order", "sync_provider")), - ] - order = models.ForeignKey( - Order, on_delete=models.CASCADE, related_name="synced_objects" - ) - sync_provider = models.CharField(blank=False, null=False, max_length=128) - order_position = models.ForeignKey( - OrderPosition, on_delete=models.CASCADE, related_name="synced_objects", blank=True, null=True, - ) - external_object_type = models.CharField(blank=False, null=False, max_length=128) - external_id_field = models.CharField(blank=False, null=False, max_length=128) - id_value = models.CharField(blank=False, null=False, max_length=128) - external_link_href = models.CharField(blank=True, null=True, max_length=255) - external_link_display_name = models.CharField(blank=True, null=True, max_length=255) - timestamp = models.DateTimeField(blank=False, null=False, auto_now_add=True) - - def external_link_html(self): - if not self.external_link_display_name: - return None - - prov, meta = sync_targets.get(identifier=self.sync_provider) - if prov: - return prov.get_external_link_html(self.order.event, self.external_link_href, self.external_link_display_name) - @receiver(periodic_task, dispatch_uid="data_sync_periodic") def on_periodic_task(sender, **kwargs): diff --git a/src/pretix/base/datasync/utils.py b/src/pretix/base/datasync/utils.py index 1e84f7e3c7..647881e1da 100644 --- a/src/pretix/base/datasync/utils.py +++ b/src/pretix/base/datasync/utils.py @@ -22,9 +22,9 @@ from typing import List, Tuple -from pretix.base.datasync.datasync import ( +from pretix.base.datasync.datasync import SyncConfigError +from pretix.base.models.datasync import ( MODE_APPEND_LIST, MODE_OVERWRITE, MODE_SET_IF_EMPTY, MODE_SET_IF_NEW, - SyncConfigError, ) diff --git a/src/pretix/base/models/datasync.py b/src/pretix/base/models/datasync.py new file mode 100644 index 0000000000..620f2ad926 --- /dev/null +++ b/src/pretix/base/models/datasync.py @@ -0,0 +1,98 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +import logging +from functools import cached_property + +from django.db import models + +from pretix.base.models import Order, OrderPosition + +logger = logging.getLogger(__name__) + + +MODE_OVERWRITE = "overwrite" +MODE_SET_IF_NEW = "if_new" +MODE_SET_IF_EMPTY = "if_empty" +MODE_APPEND_LIST = "append" + + +class OrderSyncQueue(models.Model): + order = models.ForeignKey( + Order, 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) + + class Meta: + unique_together = (("order", "sync_provider"),) + ordering = ("triggered",) + + @cached_property + def _provider_class_info(self): + from pretix.base.datasync.datasync import sync_targets + return sync_targets.get(identifier=self.sync_provider) + + @property + def provider_class(self): + return self._provider_class_info[0] + + @property + def is_provider_active(self): + return self._provider_class_info[1] + + @property + def max_retry_attempts(self): + return self.provider_class.max_attempts + + +class OrderSyncLink(models.Model): + order = models.ForeignKey( + Order, on_delete=models.CASCADE, related_name="synced_objects" + ) + sync_provider = models.CharField(blank=False, null=False, max_length=128) + order_position = models.ForeignKey( + OrderPosition, on_delete=models.CASCADE, related_name="synced_objects", blank=True, null=True, + ) + external_object_type = models.CharField(blank=False, null=False, max_length=128) + external_id_field = models.CharField(blank=False, null=False, max_length=128) + id_value = models.CharField(blank=False, null=False, max_length=128) + external_link_href = models.CharField(blank=True, null=True, max_length=255) + external_link_display_name = models.CharField(blank=True, null=True, max_length=255) + timestamp = models.DateTimeField(blank=False, null=False, auto_now_add=True) + + class Meta: + indexes = [ + models.Index(fields=("order", "sync_provider")), + ] + + def external_link_html(self): + if not self.external_link_display_name: + return None + + from pretix.base.datasync.datasync import sync_targets + prov, meta = sync_targets.get(identifier=self.sync_provider) + if prov: + return prov.get_external_link_html(self.order.event, self.external_link_href, self.external_link_display_name) diff --git a/src/pretix/control/forms/mapping.py b/src/pretix/control/forms/mapping.py index 382d221bb9..09c49f13bc 100644 --- a/src/pretix/control/forms/mapping.py +++ b/src/pretix/control/forms/mapping.py @@ -25,10 +25,10 @@ from django import forms from django.forms import formset_factory from django.utils.translation import gettext_lazy as _ -from pretix.base.datasync.datasync import ( +from pretix.base.datasync.sourcefields import QUESTION_TYPE_IDENTIFIERS +from pretix.base.models.datasync import ( MODE_APPEND_LIST, MODE_OVERWRITE, MODE_SET_IF_EMPTY, MODE_SET_IF_NEW, ) -from pretix.base.datasync.sourcefields import QUESTION_TYPE_IDENTIFIERS class PropertyMappingForm(forms.Form):