Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use package information on new services when available #2367

Merged
merged 1 commit into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions weblate_web/invoices/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

from django_stubs_ext import StrOrPromise

from weblate_web.models import Package

Check warning on line 52 in weblate_web/invoices/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/invoices/models.py#L52

Added line #L52 was not covered by tests
from weblate_web.payments.models import Payment

INVOICES_URL = "invoices:"
Expand Down Expand Up @@ -355,6 +356,11 @@
def is_draft(self):
return self.kind in {InvoiceKind.DRAFT, InvoiceKind.QUOTE}

def get_package(self) -> Package | None:
if not self.all_items:
return None

Check warning on line 361 in weblate_web/invoices/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/invoices/models.py#L361

Added line #L361 was not covered by tests
return self.all_items[0].package

def render_amount(self, amount: int | Decimal) -> str:
if self.currency == Currency.EUR:
return f"€{amount}"
Expand Down
146 changes: 86 additions & 60 deletions weblate_web/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,72 +300,94 @@
return service


def process_subscription(payment):
if payment.state != Payment.ACCEPTED:
raise ValueError("Can not process not accepted payment")
if payment.repeat:
# Update existing
subscription = Subscription.objects.get(payment=payment.repeat.pk)
payment.start = subscription.expires
subscription.expires += get_period_delta(payment.repeat.recurring)
payment.end = subscription.expires
subscription.save()
elif isinstance(payment.extra["subscription"], int):
# Payment for current subscription
subscription = Subscription.objects.get(pk=payment.extra["subscription"])
def process_repeated_payment(payment: Payment, repeated: Payment) -> Subscription:
subscription = Subscription.objects.get(payment=repeated.pk)
payment.start = subscription.expires
subscription.expires += get_period_delta(repeated.recurring)
payment.end = subscription.expires
subscription.save()
return subscription


def process_renewal_payment(payment: Payment) -> Subscription:
subscription = Subscription.objects.get(pk=payment.extra["subscription"])
if subscription.payment:
subscription.pastpayments_set.create(payment=subscription.payment)
payment.start = subscription.expires
subscription.expires += get_period_delta(subscription.package.get_repeat())
payment.end = subscription.expires
subscription.payment = payment.pk
subscription.save()
return subscription


def process_new_payment(payment: Payment) -> Subscription:
user = User.objects.get(pk=payment.customer.user_id)
service = get_service(payment, user)
if payment.paid_invoice and (paid_package := payment.paid_invoice.get_package()):
package = paid_package
elif payment.draft_invoice and (
draft_package := payment.draft_invoice.get_package()
):
package = draft_package

Check warning on line 332 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L332

Added line #L332 was not covered by tests
else:
package = Package.objects.get(name=payment.extra["subscription"])

Check warning on line 334 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L334

Added line #L334 was not covered by tests
repeat = package.get_repeat()
if package.name.startswith("hosted:") and service.hosted_subscriptions:
# Package upgrade / downgrade
subscription = service.hosted_subscriptions[0]
if subscription.payment:
subscription.pastpayments_set.create(payment=subscription.payment)
payment.start = subscription.expires
subscription.expires += get_period_delta(subscription.package.get_repeat())
payment.end = subscription.expires
subscription.package = package
subscription.expires += get_period_delta(repeat)
subscription.payment = payment.pk
subscription.save()
else:
user = User.objects.get(pk=payment.customer.user_id)
service = get_service(payment, user)
package = Package.objects.get(name=payment.extra["subscription"])
repeat = package.get_repeat()
if package.name.startswith("hosted:") and service.hosted_subscriptions:
# Package upgrade / downgrade
subscription = service.hosted_subscriptions[0]
if subscription.payment:
subscription.pastpayments_set.create(payment=subscription.payment)
subscription.package = package
subscription.expires += get_period_delta(repeat)
subscription.payment = payment.pk
subscription.save()
if start_date := payment.extra.get("start_date"):
expires = datetime.fromisoformat(start_date)
else:
if start_date := payment.extra.get("start_date"):
expires = datetime.fromisoformat(start_date)
else:
expires = timezone.now()
# Calculate expiry
if repeat:
payment.start = expires
expires += get_period_delta(repeat)
payment.end = expires
# Create new
subscription = Subscription.objects.create(
service=service,
payment=payment.pk,
package=package,
expires=expires,
)
with override("en"):
send_notification(
"new_subscription",
settings.NOTIFY_SUBSCRIPTION,
subscription=subscription,
service=subscription.service,
)
if service.was_created and service.needs_token:
subscription.send_notification("subscription_intro")
expires = timezone.now()

Check warning on line 349 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L349

Added line #L349 was not covered by tests
# Calculate expiry
if repeat:
payment.start = expires
expires += get_period_delta(repeat)
payment.end = expires
# Create new
subscription = Subscription.objects.create(
service=service,
payment=payment.pk,
package=package,
expires=expires,
)
with override("en"):
send_notification(
"new_subscription",
settings.NOTIFY_SUBSCRIPTION,
subscription=subscription,
service=subscription.service,
)
if service.was_created and service.needs_token:
subscription.send_notification("subscription_intro")

if (
service.was_created
and subscription.package.category == PackageCategory.PACKAGE_DEDICATED
):
create_dedicated_hosting_ticket(subscription)
return subscription

if (
service.was_created
and subscription.package.category == PackageCategory.PACKAGE_DEDICATED
):
create_dedicated_hosting_ticket(subscription)

def process_subscription(payment: Payment) -> Subscription:
if payment.state != Payment.ACCEPTED:
raise ValueError("Can not process not accepted payment")

Check warning on line 382 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L382

Added line #L382 was not covered by tests
if payment.repeat:
# Update existing
subscription = process_repeated_payment(payment, payment.repeat)
elif isinstance(payment.extra["subscription"], int):
# Payment for current subscription
subscription = process_renewal_payment(payment)
else:
subscription = process_new_payment(payment)

# Flag payment as processed
payment.state = Payment.PROCESSED
Expand All @@ -374,7 +396,11 @@


def process_payment(payment: Payment):
if "subscription" in payment.extra:
if (
"subscription" in payment.extra
or (payment.paid_invoice and payment.paid_invoice.get_package())
or (payment.draft_invoice and payment.draft_invoice.get_package())
):
process_subscription(payment)
else:
process_donation(payment)
Expand Down
Loading