Changeset View
Changeset View
Standalone View
Standalone View
looper/clock.py
| Show All 37 Lines | class AbstractClock(metaclass=abc.ABCMeta): | ||||
| def now(self) -> datetime.datetime: | def now(self) -> datetime.datetime: | ||||
| """Return what is considered to be 'now'. | """Return what is considered to be 'now'. | ||||
| This can be any timestamp. Subclasses can override this method for | This can be any timestamp. Subclasses can override this method for | ||||
| simulating events rather than executing them. | simulating events rather than executing them. | ||||
| """ | """ | ||||
| return django.utils.timezone.now() | return django.utils.timezone.now() | ||||
| def queryset_renewal(self) -> django.db.models.QuerySet: | def queryset_renewal(self) -> 'django.db.models.QuerySet[models.Subscription]': | ||||
| """Return a QuerySet of all subscriptions that need renewal.""" | """Return a QuerySet of all subscriptions that need renewal.""" | ||||
| my_log = self.log.getChild('queryset_renewal') | my_log = self.log.getChild('queryset_renewal') | ||||
| now = self.now() | now = self.now() | ||||
| from django.db.models import F | from django.db.models import F | ||||
| qs = ( | qs = ( | ||||
| models.Subscription.objects.filter( | models.Subscription.objects.filter( | ||||
| status__in=RENEWABLE_SUBSCRIPTION_STATUSES, next_payment__lt=now | status__in=RENEWABLE_SUBSCRIPTION_STATUSES, next_payment__lt=now | ||||
| ) | ) | ||||
| .exclude(order__retry_after__gt=now) | .exclude(order__retry_after__gt=now) | ||||
| .exclude(collection_method='managed', next_payment__gt=now) | .exclude(collection_method='managed', next_payment__gt=now) | ||||
| .exclude(collection_method='managed', last_notification__gt=F('next_payment')) | .exclude(collection_method='managed', last_notification__gt=F('next_payment')) | ||||
| ) | ) | ||||
| my_log.info( | my_log.info( | ||||
| 'Found %d subscriptions with status in %s and next_payment < %s', | 'Found %d subscriptions with status in %s and next_payment < %s', | ||||
| len(qs), | len(qs), | ||||
| RENEWABLE_SUBSCRIPTION_STATUSES, | RENEWABLE_SUBSCRIPTION_STATUSES, | ||||
| now, | now, | ||||
| ) | ) | ||||
| return qs | return qs | ||||
| def queryset_cancel(self) -> django.db.models.QuerySet: | def queryset_cancel(self) -> 'django.db.models.QuerySet[models.Subscription]': | ||||
| """Return a QuerySet of all subscriptions that need cancellation.""" | """Return a QuerySet of all subscriptions that need cancellation.""" | ||||
| my_log = self.log.getChild('queryset_cancel') | my_log = self.log.getChild('queryset_cancel') | ||||
| now = self.now() | now = self.now() | ||||
| qs = models.Subscription.objects.filter( | qs = models.Subscription.objects.filter( | ||||
| status__in=CANCELLABLE_SUBSCRIPTION_STATUSES, next_payment__lt=now | status__in=CANCELLABLE_SUBSCRIPTION_STATUSES, next_payment__lt=now | ||||
| ) | ) | ||||
| my_log.info( | my_log.info( | ||||
| Show All 40 Lines | def renew_subscription(self, subscription: models.Subscription) -> None: | ||||
| if not collection_ok: | if not collection_ok: | ||||
| return | return | ||||
| subscription.bump_next_payment() | subscription.bump_next_payment() | ||||
| my_log.info('Renewal of subscription %d successful', subscription.pk) | my_log.info('Renewal of subscription %d successful', subscription.pk) | ||||
| self.on_subscription_renewal_ok(subscription) | self.on_subscription_renewal_ok(subscription) | ||||
| def order_to_renew(self, subscription) -> Optional[models.Order]: | def order_to_renew(self, subscription: models.Subscription) -> Optional[models.Order]: | ||||
| """Determine which order to use for renewals. | """Determine which order to use for renewals. | ||||
| This can be an existing order (when retrying), a new one (when not | This can be an existing order (when retrying), a new one (when not | ||||
| retrying), or None (for managed subscriptions). | retrying), or None (for managed subscriptions). | ||||
| """ | """ | ||||
| my_log = self.log.getChild('order_to_renew') | my_log = self.log.getChild('order_to_renew') | ||||
| # Figure out whether this is a fresh renewal or the re-try of a previously failed one. | # Figure out whether this is a fresh renewal or the re-try of a previously failed one. | ||||
| ▲ Show 20 Lines • Show All 372 Lines • Show Last 20 Lines | |||||