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

178 lines
6.6 KiB
Python

# core
from core.services.using_tickets.use_ticket_orchestrator import use_ticket_orchestrator
from core.controllers.tickets.TicketPrepController import prepare_tickets
from core.controllers.ConfigurationController import ConfigurationController
from core.services.prepare_tickets.ticket_tracker import get_a_random_ticket
from core.services.subscriptions.subscriptions_by_protocol import start_new_payment_cycle, get_ticket_invoice
from core.services.payment_phase.ticket_cycle import wipe_ticket_cycle
from core.services.payment_phase.payment_state import TicketPaymentData
from core.models.enum_models import PaymentCategory
from core.services.prepare_tickets.ticket_tracker import get_all_unused_tickets
from core.utils.type_checker import type_checker
from core.models.Result import Result, ResultError
from core.errors.logger import logger
from core.observers.Notifications import Notifications, EventType
# 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
from gui.v2.actions.error_handlers import navigate_to_new_sub_page
# generic:
from typing import Callable
# 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
@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")
@register_action(ResultError.NO_TICKET)
def start_and_navigate_to_ticketing() -> Result:
"""Starts a new ticketing cycle. (assumes the user opted in)."""
start_result = start_new_payment_cycle(category=PaymentCategory.TICKET)
if start_result.valid:
logger.info("creating a new payment cycle was valid, it worked.")
return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="plan_picker")
else:
logger.info(f"Returning the error of start_result {start_result}")
return start_result
@type_checker
def random_ticket_dispatch(profile_id: int, passed_ui_caller: Callable) -> Result:
"""
User explicitly wants a random ticket.
The reason this is in GUI repo, is because use_a_ticket is.
"""
random_ticket_result = get_a_random_ticket()
if not random_ticket_result.valid:
return random_ticket_result
which_ticket = random_ticket_result.data
# this is a redundant sanity check:
if not which_ticket:
Result(valid=False, error_type=ResultError.NO_TICKET, message="No tickets left. Would you like to get some?")
# thread work that calls the caller, not return:
take_action(
action=use_ticket_orchestrator,
ui_caller=passed_ui_caller,
profile_id=profile_id,
which_ticket=which_ticket,
connection_observer=connection_observer,
ticket_observer=ticket_observer
)
return Result(valid=True)
@type_checker
def dispatch_ticketing(profile_id: int, passed_ui_caller: Callable) -> Result:
"""Evaluate if a random ticket will be used."""
use_random_setting = ConfigurationController.use_random()
if use_random_setting:
return random_ticket_dispatch(profile_id=profile_id, passed_ui_caller=passed_ui_caller)
# User does NOT want an automated selection, so they can pick from their tickets:
do_they_have_tickets = get_ticket_data()
if do_they_have_tickets.valid:
return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="ticket_or_billing_choice")
else:
# user can decide if they want to setup tickets or do an individual profile:
return navigate_to_new_sub_page()
def start_ticket(ui_caller: Callable):
"""Start the entire billing cycle for tickets"""
logger.info("started ticketing billing state")
notification = "Started Ticket Billing"
Notifications.emit(EventType.STATUS_UPDATE, notification)
take_action(
action=start_new_payment_cycle,
category=PaymentCategory.TICKET,
ui_caller=ui_caller
)
def fetch_ticket_invoice(ui_caller: Callable):
"""Fetch the invoice for tickets"""
take_action(
action=get_ticket_invoice,
ui_caller=ui_caller,
connection_observer=connection_observer
)
def start_bulk_ticket_prep(ui_caller: Callable) -> Result:
"""After paid for, start the actual math"""
logger.info("Starting a bulk ticket prep")
ticket_cycle = TicketPaymentData()
how_many_profiles = ticket_cycle.how_many_profiles
if not ticket_cycle.paid:
logger.error("Not yet paid")
return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="id", message="Tickets are not yet paid for, yet the prep started.")
logger.info("Threading to prepare_tickets")
take_action(
action=prepare_tickets,
ui_caller=ui_caller,
how_many_profiles=how_many_profiles,
connection_observer=connection_observer,
ticket_observer=ticket_observer,
which_ticket=None,
billing_code=None
)
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):
"""Use of a given ticket."""
take_action(
action=use_ticket_orchestrator,
ui_caller=ui_caller,
profile_id=profile_id,
which_ticket=which_ticket,
ticket_observer=ticket_observer,
connection_observer=connection_observer
)