sp-hydra-veil-core/core/controllers/tickets/TicketPayController.py

180 lines
7 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from core.essentials.observers.ConnectionObserver import ConnectionObserver
from core.observers.TicketObserver import TicketObserver
#
from core.models.invoice.TicketInvoice import TicketInvoice
from core.services.prepare_tickets.get_pub_key import get_pub_key
from core.observers.BaseObserver import BaseObserver
from core.services.payment_phase.save_and_send_intitial_billing import save_and_send_intitial_billing
from core.services.payment_phase.check_if_paid import _check_if_paid
from core.services.prepare_tickets.ticket_tracker import does_ticket_tracker_exist
from core.services.networking.send_data_to_server import send_data_to_server
from core.services.networking.make_url import make_url
# from core.utils.confirm_its_a_valid_key_choice import confirm_its_a_valid_key_choice
from core.services.helpers.valid_profile_quantity import valid_profile_quantity
from core.errors.exceptions import *
from core.errors.logger import logger
from core.controllers.tickets.TicketSyncController import sync_ticket_prices
"""
Inputs: Which plan (key), which crypto, and how many profiles
Outputs: a temp billing code & crypto address. (or "error")
"""
def initiate_payment(
how_many_profiles: int,
which_key: str,
which_cryptocurrency: str,
ticket_observer: TicketObserver,
connection_observer: ConnectionObserver,
bypass_existing: bool,
) -> TicketInvoice:
###############
invoice_data_object = TicketInvoice()
try:
if bypass_existing == False:
tickets_exist_already, path = does_ticket_tracker_exist()
logger.debug(f"tickets_exist_already is {tickets_exist_already}")
if tickets_exist_already:
invoice_data_object.add_error_code("already_exists")
return invoice_data_object
rejected_choices = [None, "", False]
if how_many_profiles in rejected_choices:
notification = "Missing profile quantity, to initiate payment"
ticket_observer.notify("failed_input", subject=notification)
invoice_data_object.add_error_code("invalid_quantity")
return invoice_data_object
if not valid_profile_quantity(how_many_profiles):
notification = "Invalid profile quantity"
ticket_observer.notify("failed_input", subject=notification)
invoice_data_object.add_error_code("invalid_quantity")
return invoice_data_object
if which_key in rejected_choices:
notification = "Missing key plan, to initiate payment"
ticket_observer.notify("failed_input", subject=notification)
invoice_data_object.add_error_code("no_keyplan")
return invoice_data_object
# confirm the key choice is among the choices from their sync file,
# and if not, then sync again, and try the results from that new file,
# is_valid_key = confirm_its_a_valid_key_choice(which_key, ticket_observer)
# if not is_valid_key:
# sync_results = sync_ticket_prices(ticket_observer, connection_observer)
# second_try_to_match = confirm_its_a_valid_key_choice(
# which_key, ticket_observer
# )
# if not second_try_to_match:
# invoice_data_object.add_error_code("invalid_key")
# return invoice_data_object
# get & save the public key:
public_key_results = get_pub_key(which_key, connection_observer, "local")
if isinstance(public_key_results, dict):
status = public_key_results.get("valid", False)
if status == False:
message = public_key_results.get(
"message", "Please fix before you continue"
)
error_code = public_key_results.get("error_code", "No error_code")
logger.debug(f"error_code: {error_code}")
invoice_data_object.add_error_code(error_code)
notification = f"Connection Issues or Invalid Key chosen. {message}"
ticket_observer.notify("failed_input", subject=notification)
return invoice_data_object
else:
notification = f"Invalid Key chosen or the server is down for that key."
ticket_observer.notify("failed_input", subject=notification)
invoice_data_object.add_error_code("no_pub_key")
return invoice_data_object
# In this case, the controller is going to send the whole JSON payload to the service,
# instead of passing 4 values seperately.
payload = {
"which_key": which_key,
"payment_type": "crypto",
"which_cryptocurrency": which_cryptocurrency,
"how_many_profiles": how_many_profiles,
}
# controller sends to the service:
result = save_and_send_intitial_billing(
payload, connection_observer, invoice_data_object
)
if result == False or result == None:
invoice_data_object.add_error_code("failed_save")
return invoice_data_object
except InvalidData as e:
error_msg = "Invalid Data."
ticket_observer.notify("failed_input", subject=error_msg)
invoice_data_object.add_error_code("invalid_data")
return invoice_data_object
except NetworkingError as e:
error_msg = f"NetworkingError: {e}"
logger.error(error_msg, exc_info=True)
ticket_observer.notify("connection_error", subject=error_msg)
invoice_data_object.add_error_code("connection_error")
return invoice_data_object
except ServerSideError as e:
error_msg = f"ServerSideError: {e}"
logger.error(error_msg, exc_info=True)
ticket_observer.notify("failed_output", subject=error_msg)
invoice_data_object.add_error_code("server_error")
return invoice_data_object
except Exception as e:
error_msg = f"Error: {e}"
logger.error(error_msg, exc_info=True)
ticket_observer.notify("unknown_error", subject=error_msg)
invoice_data_object.add_error_code("unknown_error")
return invoice_data_object
###############
def check_if_paid(
temp_billing_code: str,
ticket_observer: TicketObserver,
connection_observer: ConnectionObserver,
) -> dict:
rejected_reasons = [None, "", False]
if temp_billing_code in rejected_reasons:
error_msg = "Invalid Temp Billing Code"
logger.error(f"{error_msg} inside the check_if_paid function", exc_info=True)
ticket_observer.notify("failed_input", subject=error_msg)
return {"valid": False, "error_code": "rejected"}
else:
# prep the JSON payload:
payload = {"temp_billing_code": temp_billing_code}
# prep endpoint:
which_endpoint = "check_paid"
url = make_url(which_endpoint)
# literally send:
reply = send_data_to_server(payload, url, connection_observer)
logger.debug(f"inside ticketpay controller the reply is {reply}")
return reply