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 from core.services.payment_phase.do_we_have_billing_id import do_we_have_billing_id """ 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 billing_id = do_we_have_billing_id() if billing_id: invoice_data_object.add_error_code("billing_code_exists") invoice_data_object.temp_billing_code = billing_id 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 # 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