hydraveil-gui/gui/v2/actions/payment_actions.py

107 lines
3.6 KiB
Python

# core
from core.services.subscriptions.check_payment_loop import CheckPaidTimer
from core.services.subscriptions.subscriptions_by_protocol import create_invoice, save_billing_code, get_profile_subscription
from core.models.enum_models import PaymentType
from core.errors.logger import logger
# gui
from gui.v2.infrastructure.ThreadSafetyTool import ThreadSafetyTool
from gui.v2.infrastructure.take_plumbing_action import take_action
from gui.v2.infrastructure.setup_observers import connection_observer
# generic
from typing import Callable, Optional
def gui_starts_invoice(profile_id: int, invoice_ui_caller: Callable, timer_resume_caller: Callable) -> str | None:
"""Create a new invoice if we don't have one yet, or re-use the saved data. Returns any errors as strings for UI to display."""
subscription = get_profile_subscription(profile_id)
#----------------------------
# INVOICE DATA
#----------------------------
take_action(
action=create_invoice,
ui_caller=invoice_ui_caller,
profile_id=profile_id,
connection_observer=connection_observer
)
#----------------------------
# FILTER
#----------------------------
if not subscription:
logger.info(f"Started a New Invoice for Profile {profile_id}..")
return None
if not subscription.billing_pending:
logger.error("This function should not have been called if the invoice is already paid.")
return "Invoice already paid."
if not subscription.billing_code:
return "Previous subscription didn't have a billing code."
#----------------------------
# CHECK PAID ON PRE-EXISTING INVOICE
#----------------------------
logger.info("Resuming a pre-existing payment..")
# Setup PyQt6 GUI as mainthread to bring back to:
pyqt_threader = ThreadSafetyTool()
# setup the timer with the callback:
# it doesn't return result here. It calls the view_callback function.
check_paid_timer = CheckPaidTimer(
view_callback=timer_resume_caller,
billing_code=subscription.billing_code,
ui_dispatcher=pyqt_threader,
payment_type=PaymentType.CRYPTO,
connection_observer=connection_observer,
profile_id=profile_id
)
return None
def save_and_begin_timer(
ticketing: bool,
gui_callback: Callable,
billing_code: str,
profile_id: Optional[int] = None,
expires_at: Optional[str] = None,
) -> bool:
"""
First saves the billing code & profile expiration, if it's an individual (non-ticket) crypto-based one.
Then it Starts a loop of checking if the invoice is paid and saves it.
"""
if ticketing:
payment_type = PaymentType.TICKETS
logger.error("Not yet setup for ticketing")
return False
# NON-ticketing:
elif profile_id and expires_at:
payment_type = PaymentType.CRYPTO
saved = save_billing_code(profile_id=profile_id, billing_code=billing_code, expires_at=expires_at)
if not saved.valid:
return False
else:
logger.error("You need a profile id and expires_at for individual profiles")
return False
# Setup PyQt6 GUI as mainthread to bring back to:
pyqt_threader = ThreadSafetyTool()
# setup the timer with the callback:
# it doesn't return result here. It calls the gui_callback function.
check_paid_timer = CheckPaidTimer(
view_callback=gui_callback,
billing_code=billing_code,
ui_dispatcher=pyqt_threader,
payment_type=payment_type,
connection_observer=connection_observer,
profile_id=profile_id
)
return True # this is just that it started