From 6162d000c6b8b3bdec93928c55f6b7c22167f1a6 Mon Sep 17 00:00:00 2001 From: SimplifiedPrivacy Date: Tue, 20 Oct 2026 15:42:13 -0400 Subject: [PATCH] Improved error handling for billing conflicts of individual profiles at the same time --- core/models/Result.py | 1 + .../subscriptions_by_protocol.py | 41 +++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/core/models/Result.py b/core/models/Result.py index 73d1aa3..1c0f9c7 100644 --- a/core/models/Result.py +++ b/core/models/Result.py @@ -23,6 +23,7 @@ class ResultError(Enum): UNPAID = "unpaid" EXPIRED_SUB = "expired_sub" ACTIVE_BILLING = "active_billing" + BILLING_CONFLICT = "billing_conflict" STATE_CONFLICT = "state_conflict" ZOMBIE_CONNECTION = "zombie_connection" TICKET = "ticket" diff --git a/core/services/subscriptions/subscriptions_by_protocol.py b/core/services/subscriptions/subscriptions_by_protocol.py index fc8546f..ef2c57a 100644 --- a/core/services/subscriptions/subscriptions_by_protocol.py +++ b/core/services/subscriptions/subscriptions_by_protocol.py @@ -18,6 +18,7 @@ from core.errors.error_shortcuts import not_supported # generic from datetime import datetime from typing import Optional +from functools import partial def invalid_server_format() -> Result: @@ -110,7 +111,8 @@ def evaluate_repeat_cycle(payment_cycle: OverallPaymentCycle, profile_id: int) - else: error_msg = f"You activated profile {profile_id}, but profile {payment_cycle.billing_data.instance_id} has active billing, stop that?" logger.error(error_msg) - return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg) + func_choice = partial(wipe_billing_cycle) + return Result(valid=False, function_choice=func_choice, error_type=ResultError.BILLING_CONFLICT, message=error_msg) @type_checker @@ -218,6 +220,8 @@ def return_pre_existing_invoice(billing_code: str, connection_observer: Connecti """This billing_code already got an invoice, but needs to fetch that data from the server again.""" logger.info("Fetching a pre-existing invoice..") + payment_cycle = OverallPaymentCycle() + payment_cycle.active = True if category == PaymentCategory.TICKET: payload = { @@ -422,7 +426,21 @@ def paying_for_tickets() -> bool: return False -def get_current_billing_data(category: Optional[PaymentCategory] = None) -> Result: +# def start_new_process_if_already(profile_id: int) +# # Is there currently a process? +# payment_cycle = OverallPaymentCycle() + +# if not payment_cycle and not category: +# error_msg = "There is no current billing cycle AND no category provided." +# return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg) + +# billing_data = payment_cycle.billing_data + +# if not billing_data: + + + +def get_current_billing_data(category: Optional[PaymentCategory] = None, profile_id: Optional[int] = None) -> Result: """ Goal: Get whatever current billing data is relevant by the overall cycle, for either billing category @@ -438,14 +456,21 @@ def get_current_billing_data(category: Optional[PaymentCategory] = None) -> Resu error_msg = "There is no current billing cycle AND no category provided." return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg) - # if not payment_cycle and category: - - billing_data = payment_cycle.billing_data if not billing_data: - error_msg = "There is no current billing data." - return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg) + if profile_id and category: + logger.info("starting a new cycle..") + return start_new_payment_cycle(category=category, profile_id=profile_id) + # else: + # error_msg = "Do you want to start a new billing cycle?" + # if not category: + # category = PaymentCategory.INDIVIDUAL + # new_choice = partial(start_new_payment_cycle, category=category, profile_id=profile_id) + # return Result(valid=False, function_choice=new_choice, error_type=ResultError.INVALID_INPUT, message=error_msg) + else: + error_msg = "Please restart the billing for this profile." + return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="menu", message=error_msg) return Result(valid=True, data=billing_data) @@ -623,4 +648,4 @@ def return_pre_existing_payment_data(profile_id: int, subscription: Subscription def evaluate_ticketing() -> bool: setup = ConfigurationController.are_tickets_setup() - return setup \ No newline at end of file + return setup \ No newline at end of file