forked from Support/sp-hydra-veil-gui
134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
# core
|
|
from core.controllers.tickets.UseTicketController import use_ticket
|
|
from core.models.BaseProfile import BaseProfile as Profile
|
|
from core.controllers.ProfileController import ProfileController
|
|
from core.controllers.tickets.TicketPayController import initiate_payment
|
|
from core.services.subscriptions.subscriptions_by_protocol import start_new_payment_cycle, save_subscription, get_ticket_invoice
|
|
from core.services.payment_phase.ticket_cycle import wipe_ticket_cycle
|
|
from core.services.payment_phase.payment_state import OverallPaymentCycle
|
|
from core.models.enum_models import PaymentCategory
|
|
from core.services.prepare_tickets.ticket_tracker import get_all_unused_tickets
|
|
from core.models.Result import Result, ResultError
|
|
from core.errors.logger import logger
|
|
|
|
# gui
|
|
from gui.v2.infrastructure.action_registry import register_action
|
|
from gui.v2.infrastructure.take_plumbing_action import take_action
|
|
from gui.v2.infrastructure.setup_observers import connection_observer, ticket_observer
|
|
|
|
# generic:
|
|
from typing import Callable
|
|
|
|
|
|
def start_ticket(ui_caller: Callable) -> Result:
|
|
logger.info("started ticketing billing state")
|
|
return take_action(
|
|
action=start_new_payment_cycle,
|
|
category=PaymentCategory.TICKET,
|
|
ui_caller=ui_caller
|
|
)
|
|
|
|
|
|
def fetch_ticket_invoice(ui_caller: Callable) -> str | None:
|
|
return take_action(
|
|
action=get_ticket_invoice,
|
|
ui_caller=ui_caller,
|
|
connection_observer=connection_observer
|
|
)
|
|
|
|
|
|
def get_ticket_data() -> Result:
|
|
"""This is running in the background ALREADY. Get & format a list of unused tickets from core"""
|
|
|
|
ticket_results = get_all_unused_tickets()
|
|
valid = ticket_results.get('valid')
|
|
|
|
if not valid:
|
|
message = ticket_results.get('message')
|
|
if not message:
|
|
message = "Error gathering ticket data"
|
|
Result(valid=False, error_type=ResultError.MISSING_FILE, message=message)
|
|
|
|
raw_tickets = ticket_results.get('data')
|
|
print(f"raw_tickets is {raw_tickets}")
|
|
if not raw_tickets:
|
|
Result(valid=False, error_type=ResultError.NO_TICKET, message="No tickets available. Would you like to get some?")
|
|
|
|
formatted_data = [(f"Ticket #{t}", t) for t in raw_tickets]
|
|
print(f"formatted_data is {formatted_data}")
|
|
return Result(valid=True, data=formatted_data)
|
|
|
|
|
|
def use_a_ticket(profile_id: int, which_ticket: int, ui_caller: Callable) -> str | None:
|
|
"""Coordinate the use of a given ticket. Returns a string on error, or None on success"""
|
|
|
|
try:
|
|
profile = ProfileController.get(int(profile_id))
|
|
except Exception as e:
|
|
return f"The selected profile of {str(profile_id)} is either malformed or missing. {str(e)}"
|
|
|
|
which_location = profile.location.id
|
|
protocol_choice = profile.connection.code
|
|
|
|
PRE_REQS = [profile, which_ticket, which_location, protocol_choice, ui_caller]
|
|
if None in PRE_REQS:
|
|
return "You are missing one of the pre-reqs to use a ticket."
|
|
|
|
ticket_user = TicketUser(
|
|
actual_profile=profile,
|
|
which_ticket=which_ticket,
|
|
ui_caller=ui_caller
|
|
)
|
|
ticket_user.begin_thread()
|
|
return None # no error
|
|
|
|
|
|
class TicketUser():
|
|
actual_profile: Profile
|
|
which_ticket: int
|
|
ui_caller: Callable
|
|
|
|
def begin_thread(self):
|
|
"""Step 1, begin a background thread with use"""
|
|
take_action(
|
|
action=use_ticket,
|
|
ui_caller=self.apply_code,
|
|
which_location=self.which_location,
|
|
protocol_choice=self.protocol_choice,
|
|
ticket_observer=ticket_observer,
|
|
connection_observer=connection_observer,
|
|
)
|
|
|
|
def apply_code(self, result: Result):
|
|
"""Step 2. Check if it worked. If so, apply it"""
|
|
|
|
if not result.valid:
|
|
logger.error("Use failed, returning to UI layer..")
|
|
self.ui_caller(result)
|
|
|
|
subscription = result.data
|
|
if not subscription:
|
|
logger.error("Use of ticket gave a blank subscription, returning to UI layer..")
|
|
self.ui_caller(result)
|
|
|
|
# core saves it:
|
|
logger.info("saving subscription..")
|
|
saved = save_subscription(profile=self.actual_profile, subscription=subscription)
|
|
if not saved:
|
|
error_msg = "Could not save the subscription"
|
|
logger.error(error_msg)
|
|
new_result = Result(valid=False, error_type=ResultError.FILE_SYSTEM, message=error_msg)
|
|
self.ui_caller(new_result)
|
|
|
|
logger.info("Saved sub, returning to UI layer..")
|
|
self.ui_caller(result)
|
|
|
|
|
|
@register_action(ResultError.TICKET_EXPIRED)
|
|
def wipe_ticket_billing() -> Result:
|
|
"""Wipe existing data and start over."""
|
|
wiped = wipe_ticket_cycle()
|
|
if wiped.valid:
|
|
return Result(valid=True, error_type=ResultError.NAVIGATE_TO, navigate_to="plan_picker")
|
|
else:
|
|
return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="plan_picker")
|