Stable repeat Ticketing flow
This commit is contained in:
parent
1f4b37dbe9
commit
9ca0809ceb
5 changed files with 110 additions and 202 deletions
|
|
@ -149,7 +149,7 @@ def resolve_prescription(result: Result, ENUM_MAP: dict, *args, **kwargs):
|
||||||
# Priority 2: Look up the Enum map
|
# Priority 2: Look up the Enum map
|
||||||
logger.info("checking enum map")
|
logger.info("checking enum map")
|
||||||
if result.error_type not in ENUM_MAP:
|
if result.error_type not in ENUM_MAP:
|
||||||
logger.info(f"No solution in the ENUM_MAP of {ENUM_MAP}")
|
# logger.info(f"No solution in the ENUM_MAP of {ENUM_MAP}")
|
||||||
return None # No solution
|
return None # No solution
|
||||||
|
|
||||||
enum_value = ENUM_MAP[result.error_type]
|
enum_value = ENUM_MAP[result.error_type]
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class ServerReply():
|
||||||
message: Optional[str] = None
|
message: Optional[str] = None
|
||||||
model_version: int = 1
|
model_version: int = 1
|
||||||
data: Optional[dict] = None
|
data: Optional[dict] = None
|
||||||
conf: str = None
|
conf: Optional[str] = None
|
||||||
payment_status: Optional[bool] = None
|
payment_status: Optional[bool] = None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,23 +112,11 @@ class CheckPaidTimer:
|
||||||
print("PAID! Stopping timer")
|
print("PAID! Stopping timer")
|
||||||
self.stop_polling()
|
self.stop_polling()
|
||||||
|
|
||||||
# Reset instance:
|
# Since paid, reset the instance (wipe it):
|
||||||
CheckPaidTimer._instance = None
|
CheckPaidTimer._instance = None
|
||||||
|
|
||||||
marked = mark_as_paid(profile_id=self.profile_id)
|
marked = mark_as_paid(profile_id=self.profile_id)
|
||||||
|
|
||||||
# # SAVE INDIVIDUAL:
|
|
||||||
# if self.payment_type == PaymentType.CRYPTO:
|
|
||||||
# marked = mark_as_paid(profile_id=self.profile_id)
|
|
||||||
|
|
||||||
# # SAVE TICKETS PAID:
|
|
||||||
# elif self.payment_type == PaymentType.TICKET:
|
|
||||||
# marked = mark_global_tickets_paid()
|
|
||||||
|
|
||||||
# else:
|
|
||||||
# logger.error("Invalid payment type picked.")
|
|
||||||
# marked = Result(valid=False, error_type=ResultError.INVALID_INPUT, message="Unsupported protocol.", billing_code=self.billing_code)
|
|
||||||
|
|
||||||
# Either way evaluate:
|
# Either way evaluate:
|
||||||
if not marked.valid:
|
if not marked.valid:
|
||||||
message = marked.message
|
message = marked.message
|
||||||
|
|
@ -173,3 +161,17 @@ class CheckPaidTimer:
|
||||||
CheckPaidTimer._instance = None
|
CheckPaidTimer._instance = None
|
||||||
self.view_callback(paid=False, stopped=True, message=result.message, billing_code=self.billing_code)
|
self.view_callback(paid=False, stopped=True, message=result.message, billing_code=self.billing_code)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# # SAVE INDIVIDUAL:
|
||||||
|
# if self.payment_type == PaymentType.CRYPTO:
|
||||||
|
# marked = mark_as_paid(profile_id=self.profile_id)
|
||||||
|
|
||||||
|
# # SAVE TICKETS PAID:
|
||||||
|
# elif self.payment_type == PaymentType.TICKET:
|
||||||
|
# marked = mark_global_tickets_paid()
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# logger.error("Invalid payment type picked.")
|
||||||
|
# marked = Result(valid=False, error_type=ResultError.INVALID_INPUT, message="Unsupported protocol.", billing_code=self.billing_code)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
from core.models.pydantic_models.type_checker import validate_model
|
from core.models.pydantic_models.type_checker import validate_model
|
||||||
from core.models.pydantic_models.ServerReply import SubscriptionInvoice
|
from core.models.pydantic_models.ServerReply import SubscriptionInvoice
|
||||||
from core.models.Subscription import Subscription
|
from core.models.Subscription import Subscription
|
||||||
|
from core.utils.type_checker import type_checker
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
from core.models.Result import Result, ResultError
|
from core.models.Result import Result, ResultError
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
|
@ -100,8 +101,8 @@ def error_about_mismatch(category: PaymentCategory) -> Result:
|
||||||
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
||||||
|
|
||||||
|
|
||||||
|
@type_checker
|
||||||
def evaluate_cycle(payment_cycle: OverallPaymentCycle, profile_id: int) -> Result:
|
def evaluate_repeat_cycle(payment_cycle: OverallPaymentCycle, profile_id: int) -> Result:
|
||||||
if the_same_payment_cycle(payment_cycle=payment_cycle, profile_id=profile_id):
|
if the_same_payment_cycle(payment_cycle=payment_cycle, profile_id=profile_id):
|
||||||
logger.info("It's the same as before, returning the data")
|
logger.info("It's the same as before, returning the data")
|
||||||
return Result(valid=True, data=payment_cycle.billing_data)
|
return Result(valid=True, data=payment_cycle.billing_data)
|
||||||
|
|
@ -111,104 +112,80 @@ def evaluate_cycle(payment_cycle: OverallPaymentCycle, profile_id: int) -> Resul
|
||||||
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
||||||
|
|
||||||
|
|
||||||
|
@type_checker
|
||||||
def start_new_payment_cycle(category: PaymentCategory, profile_id: Optional[int] = None) -> Result:
|
def start_new_payment_cycle(category: PaymentCategory, profile_id: Optional[int] = None) -> Result:
|
||||||
"""
|
# 1. Pre-requisites
|
||||||
Purpose:
|
if category == PaymentCategory.INDIVIDUAL and not profile_id:
|
||||||
Starts the overall payment cycle, and the individual category's billing data.
|
|
||||||
|
|
||||||
On Conflict:
|
|
||||||
If there's already a cycle running, this function addresses that,
|
|
||||||
by returning the cycle if it's the same, or offering to end it if different.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# PRE-REQS:
|
|
||||||
if not profile_id and category == PaymentCategory.INDIVIDUAL:
|
|
||||||
error_msg = "Need a profile id for an individual profile."
|
error_msg = "Need a profile id for an individual profile."
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
logger.info("Got pre-reqs for individual.")
|
|
||||||
|
|
||||||
# This is the singleton:
|
|
||||||
payment_cycle = OverallPaymentCycle()
|
payment_cycle = OverallPaymentCycle()
|
||||||
logger.info(f"payment_cycle is {payment_cycle}")
|
|
||||||
|
|
||||||
# ----------------------------
|
# 2. Exact Match Check
|
||||||
# MISMATCH IN CATEGORY FROM WHAT EXISTS:
|
# If a cycle is active, we first check if it is EXACTLY what the user is requesting.
|
||||||
# ----------------------------
|
if payment_cycle.active and payment_cycle.billing_data:
|
||||||
if category != payment_cycle.category:
|
is_same_category = (payment_cycle.category == category)
|
||||||
return error_about_mismatch(category)
|
|
||||||
logger.info("Made it past the mismatch check.")
|
if is_same_category:
|
||||||
|
if category == PaymentCategory.TICKET:
|
||||||
|
# Return active ticket cycle even if billing_code is blank
|
||||||
|
logger.info("Existing active ticket cycle found. Returning it.")
|
||||||
|
return Result(valid=True, data=payment_cycle)
|
||||||
|
|
||||||
|
if category == PaymentCategory.INDIVIDUAL:
|
||||||
|
# Let evaluate_repeat_cycle handle the profile_id comparison
|
||||||
|
# and the specific "same user" vs "different user" Result errors.
|
||||||
|
return evaluate_repeat_cycle(payment_cycle=payment_cycle, profile_id=profile_id)
|
||||||
|
|
||||||
# ----------------------------
|
# 3. Collision Check (The "Prompt" Logic)
|
||||||
# ALREADY ACTIVE INDIVIDUAL CYCLE:
|
# If we reached here, the active cycle (if any) is NOT a match.
|
||||||
# ----------------------------
|
if payment_cycle.active:
|
||||||
if all([ # all are true:
|
# We return ACTIVE_BILLING so the UI can prompt the user to call wipe_billing_cycle()
|
||||||
payment_cycle.billing_data,
|
error_msg = f"An active {payment_cycle.category} cycle is already running. Stop it first?"
|
||||||
payment_cycle.active,
|
logger.info(error_msg)
|
||||||
payment_cycle.category == PaymentCategory.INDIVIDUAL,
|
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
||||||
category == PaymentCategory.INDIVIDUAL
|
|
||||||
]):
|
|
||||||
profile_id_already_running = payment_cycle.billing_data.instance_id
|
|
||||||
if profile_id_already_running:
|
|
||||||
logger.info(f"Triggering the evaluate_cycle reply because of {profile_id_already_running} running already")
|
|
||||||
return evaluate_cycle(payment_cycle=payment_cycle, profile_id=profile_id)
|
|
||||||
|
|
||||||
# ----------------------------
|
# 4. Stale Timer Check
|
||||||
# ALREADY POLLING TIMER:
|
# This handles cases where the cycle state is gone but the background thread is still humming.
|
||||||
# ----------------------------
|
|
||||||
try:
|
try:
|
||||||
timer_loop = CheckPaidTimer.get_instance()
|
timer_loop = CheckPaidTimer.get_instance()
|
||||||
if timer_loop.is_running:
|
if timer_loop.is_running:
|
||||||
error_msg = "There's already a billing cycle that's actively checking if paid. Do you want to stop that?"
|
error_msg = "A billing timer is still running in the background. Do you want to stop it?"
|
||||||
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
return Result(valid=False, error_type=ResultError.ACTIVE_BILLING, message=error_msg)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info("All good, the timer isn't running, and we were afraid it was.")
|
logger.debug(f"Timer check skipped: {e}")
|
||||||
|
|
||||||
|
# 5. Initialization
|
||||||
logger.info("Process is NOT yet active, starting..")
|
|
||||||
payment_cycle.begin()
|
|
||||||
payment_cycle.category = category
|
payment_cycle.category = category
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# START INDIVIDUAL:
|
|
||||||
# ----------------------------
|
|
||||||
if category == PaymentCategory.INDIVIDUAL:
|
if category == PaymentCategory.INDIVIDUAL:
|
||||||
payment_cycle.profile_id = profile_id
|
payment_cycle.profile_id = profile_id
|
||||||
payment_cycle.billing_data = PaymentData(instance_id=profile_id)
|
payment_cycle.billing_data = PaymentData(instance_id=profile_id)
|
||||||
subscription = get_profile_subscription(profile_id=profile_id, save_pending=True) # save to disk that it's pending
|
subscription = get_profile_subscription(profile_id=profile_id, save_pending=True)
|
||||||
if subscription:
|
billing_code = subscription.billing_code if subscription else None
|
||||||
billing_code = subscription.billing_code
|
logger.info("Individual setup complete.")
|
||||||
else:
|
|
||||||
billing_code = None
|
|
||||||
logger.info("Individual profile initial setup complete.")
|
|
||||||
|
|
||||||
# ----------------------------
|
|
||||||
# START TICKETS:
|
|
||||||
# ----------------------------
|
|
||||||
elif category == PaymentCategory.TICKET:
|
elif category == PaymentCategory.TICKET:
|
||||||
billing_data = TicketPaymentData()
|
billing_data = TicketPaymentData()
|
||||||
payment_cycle.billing_data = billing_data # saves
|
payment_cycle.billing_data = billing_data
|
||||||
billing_code = billing_data.billing_code # might be empty if new
|
billing_code = billing_data.billing_code
|
||||||
logger.info("Ticketing initial setup complete.")
|
logger.info("Ticket setup complete.")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
error_msg = f"Invalid PaymentCategory selected of {str(category)}"
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message="Invalid Category")
|
||||||
logger.error(error_msg)
|
|
||||||
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
|
||||||
|
|
||||||
# ----------------------------
|
# 6. Activation
|
||||||
# COMMON FOR BOTH CATEGORIES:
|
|
||||||
# ----------------------------
|
|
||||||
payment_cycle.billing_code = billing_code
|
payment_cycle.billing_code = billing_code
|
||||||
payment_cycle.active = True
|
payment_cycle.begin()
|
||||||
|
|
||||||
logger.info(f"Returning the entire payment_cycle")
|
if payment_cycle.billing_data:
|
||||||
return Result(valid=True, data=payment_cycle)
|
return Result(valid=True, data=payment_cycle)
|
||||||
|
|
||||||
# else:
|
return Result(valid=False, error_type=ResultError.UNKNOWN, message="Failed to create billing data.")
|
||||||
# return Result(valid=False, error_type=ResultError.UNKNOWN, message="We failed to create new billing cycle data.")
|
|
||||||
|
|
||||||
|
|
||||||
|
@type_checker
|
||||||
def create_new_invoice(connection_observer: ConnectionObserver) -> Result:
|
def create_new_invoice(connection_observer: ConnectionObserver) -> Result:
|
||||||
"""Requires an active OverallPaymentCycle, that does NOT have an invoice already."""
|
"""Requires an active OverallPaymentCycle, that does NOT have an invoice already."""
|
||||||
|
|
||||||
|
|
@ -230,19 +207,28 @@ def create_new_invoice(connection_observer: ConnectionObserver) -> Result:
|
||||||
return create_individual_invoice(payment_cycle=payment_cycle, connection_observer=connection_observer)
|
return create_individual_invoice(payment_cycle=payment_cycle, connection_observer=connection_observer)
|
||||||
|
|
||||||
if category == PaymentCategory.TICKET:
|
if category == PaymentCategory.TICKET:
|
||||||
return create_ticket_invoice(payment_cycle=payment_cycle, connection_observer=connection_observer)
|
return get_ticket_invoice(connection_observer=connection_observer)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return not_supported()
|
return not_supported()
|
||||||
|
|
||||||
|
|
||||||
def return_pre_existing_invoice(billing_code: str, connection_observer: ConnectionObserver) -> Result:
|
@type_checker
|
||||||
|
def return_pre_existing_invoice(billing_code: str, connection_observer: ConnectionObserver, category: PaymentCategory = PaymentCategory.INDIVIDUAL) -> Result:
|
||||||
"""This billing_code already got an invoice, but needs to fetch that data from the server again."""
|
"""This billing_code already got an invoice, but needs to fetch that data from the server again."""
|
||||||
|
|
||||||
logger.info("Fetching a pre-existing invoice..")
|
logger.info("Fetching a pre-existing invoice..")
|
||||||
payload = {
|
|
||||||
"billing_code": billing_code
|
if category == PaymentCategory.TICKET:
|
||||||
}
|
payload = {
|
||||||
|
"billing_code": billing_code,
|
||||||
|
"category": "tickets"
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
payload = {
|
||||||
|
"billing_code": billing_code,
|
||||||
|
"category": "individual"
|
||||||
|
}
|
||||||
|
|
||||||
#-----------------------------
|
#-----------------------------
|
||||||
# SEND TO API
|
# SEND TO API
|
||||||
|
|
@ -253,9 +239,17 @@ def return_pre_existing_invoice(billing_code: str, connection_observer: Connecti
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def create_ticket_invoice(payment_cycle: OverallPaymentCycle, connection_observer: ConnectionObserver) -> Result:
|
|
||||||
|
|
||||||
logger.info("Creating a new TICKET invoice..")
|
def get_ticket_invoice(connection_observer: ConnectionObserver) -> Result:
|
||||||
|
"""Evaluates if it needs a new ticket invoice, and then returns pre-existing"""
|
||||||
|
|
||||||
|
payment_cycle = OverallPaymentCycle()
|
||||||
|
|
||||||
|
logger.info(f"Creating a TICKET invoice for the payment_cycle: {payment_cycle}")
|
||||||
|
|
||||||
|
logger.info(f"payment_cycle is type {type(payment_cycle)}")
|
||||||
|
logger.info(f"connection_observer is type {type(connection_observer)}")
|
||||||
|
|
||||||
billing_data = payment_cycle.billing_data
|
billing_data = payment_cycle.billing_data
|
||||||
|
|
||||||
if not billing_data:
|
if not billing_data:
|
||||||
|
|
@ -266,7 +260,7 @@ def create_ticket_invoice(payment_cycle: OverallPaymentCycle, connection_observe
|
||||||
billing_code = billing_data.billing_code
|
billing_code = billing_data.billing_code
|
||||||
if billing_code:
|
if billing_code:
|
||||||
logger.info("We already have a billing_code id for this ticket prep.")
|
logger.info("We already have a billing_code id for this ticket prep.")
|
||||||
return return_pre_existing_invoice(billing_code=billing_code, connection_observer=connection_observer)
|
return return_pre_existing_invoice(billing_code=billing_code, connection_observer=connection_observer, category=PaymentCategory.TICKET)
|
||||||
|
|
||||||
#-----------------------------
|
#-----------------------------
|
||||||
# MAKE PAYLOAD.
|
# MAKE PAYLOAD.
|
||||||
|
|
@ -275,6 +269,7 @@ def create_ticket_invoice(payment_cycle: OverallPaymentCycle, connection_observe
|
||||||
# which_key = billing_data.which_key
|
# which_key = billing_data.which_key
|
||||||
# currency = billing_data.currency
|
# currency = billing_data.currency
|
||||||
|
|
||||||
|
logger.info(f"Evaluating if billing_data is ready to prep a payload: {billing_data}")
|
||||||
payload = billing_data.prep_payload()
|
payload = billing_data.prep_payload()
|
||||||
|
|
||||||
if not payload:
|
if not payload:
|
||||||
|
|
@ -305,6 +300,7 @@ def create_ticket_invoice(payment_cycle: OverallPaymentCycle, connection_observe
|
||||||
return Result(valid=True, data=final_invoice)
|
return Result(valid=True, data=final_invoice)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_individual_invoice(payment_cycle: OverallPaymentCycle, connection_observer: ConnectionObserver) -> Result:
|
def create_individual_invoice(payment_cycle: OverallPaymentCycle, connection_observer: ConnectionObserver) -> Result:
|
||||||
"""Prepare the payment data payload and send it to the API. Returns an invoice nested inside Result's data"""
|
"""Prepare the payment data payload and send it to the API. Returns an invoice nested inside Result's data"""
|
||||||
|
|
||||||
|
|
@ -390,54 +386,6 @@ def create_individual_invoice(payment_cycle: OverallPaymentCycle, connection_obs
|
||||||
return Result(valid=True, data=final_invoice)
|
return Result(valid=True, data=final_invoice)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# def check_paid(billing_code: str, connection_observer: ConnectionObserver) -> Result:
|
|
||||||
# """
|
|
||||||
# Purpose:
|
|
||||||
# Evaluates Payment Status for EITHER payment category
|
|
||||||
|
|
||||||
# Requires:
|
|
||||||
# Valid OverallPaymentCycle
|
|
||||||
# billing_code is provided by the timer for BOTH types.
|
|
||||||
# """
|
|
||||||
|
|
||||||
# payment_cycle = OverallPaymentCycle()
|
|
||||||
# category = payment_cycle.category
|
|
||||||
|
|
||||||
# logger.info(f"Checking paid with category of {category}")
|
|
||||||
|
|
||||||
# # Get endpoint:
|
|
||||||
# if category == PaymentCategory.INDIVIDUAL:
|
|
||||||
# url = f'{Constants.SP_BASE_URL}/v2/check_paid'
|
|
||||||
# elif category == PaymentCategory.TICKET:
|
|
||||||
# url = f'{Constants.TICKET_API_BASE_URL}/check_ticket_paid'
|
|
||||||
# else:
|
|
||||||
# return Result(valid=False, error_type=ResultError.INVALID_INPUT, message="This is not a supported payment category to check")
|
|
||||||
|
|
||||||
# submit_data = {
|
|
||||||
# "billing_code": billing_code
|
|
||||||
# }
|
|
||||||
|
|
||||||
# result = api_call_and_extraction(
|
|
||||||
# desired_type="payment_status",
|
|
||||||
# method=ApiCall.POST,
|
|
||||||
# url=url,
|
|
||||||
# connection_observer=connection_observer,
|
|
||||||
# payload=submit_data
|
|
||||||
# )
|
|
||||||
|
|
||||||
# if not result.valid:
|
|
||||||
# return result
|
|
||||||
|
|
||||||
# payment_status = result.data
|
|
||||||
|
|
||||||
# # paid
|
|
||||||
# if payment_status:
|
|
||||||
# return Result(valid=True, message="paid")
|
|
||||||
# else:
|
|
||||||
# return Result(valid=False, error_type=ResultError.UNPAID, message="The API call went through, but this subscription is not yet paid.")
|
|
||||||
|
|
||||||
|
|
||||||
def paying_for_tickets() -> bool:
|
def paying_for_tickets() -> bool:
|
||||||
"""Returns boolean for if the current billing is tickets"""
|
"""Returns boolean for if the current billing is tickets"""
|
||||||
|
|
||||||
|
|
@ -491,8 +439,11 @@ def wipe_billing_cycle() -> Result:
|
||||||
timer_loop = CheckPaidTimer.get_instance()
|
timer_loop = CheckPaidTimer.get_instance()
|
||||||
if timer_loop.is_running:
|
if timer_loop.is_running:
|
||||||
timer_loop.stop_polling()
|
timer_loop.stop_polling()
|
||||||
|
logger.info("Wiped the CheckPaidTimer")
|
||||||
|
else:
|
||||||
|
logger.error("Timer wasn't running to begin with.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info("Skipping Timer since it's not yet created.")
|
logger.info(f"Skipping Timer since it's not yet created. BTW error was: {str(e)}")
|
||||||
|
|
||||||
# Overall State:
|
# Overall State:
|
||||||
payment_cycle = OverallPaymentCycle()
|
payment_cycle = OverallPaymentCycle()
|
||||||
|
|
@ -503,6 +454,7 @@ def wipe_billing_cycle() -> Result:
|
||||||
return Result(valid=True)
|
return Result(valid=True)
|
||||||
|
|
||||||
|
|
||||||
|
@type_checker
|
||||||
def get_profile_subscription(profile_id: int, save_pending: Optional[bool] = False) -> Subscription:
|
def get_profile_subscription(profile_id: int, save_pending: Optional[bool] = False) -> Subscription:
|
||||||
"""
|
"""
|
||||||
Main Purpose:
|
Main Purpose:
|
||||||
|
|
@ -543,61 +495,7 @@ def wipe_subscription(profile_id: int) -> Result:
|
||||||
return Result(valid=True)
|
return Result(valid=True)
|
||||||
|
|
||||||
|
|
||||||
# def mark_as_paid() -> Result:
|
@type_checker
|
||||||
# """Conclude the payment phase"""
|
|
||||||
|
|
||||||
# logger.info("Marking as paid..")
|
|
||||||
|
|
||||||
# payment_cycle = OverallPaymentCycle()
|
|
||||||
|
|
||||||
# if not payment_cycle:
|
|
||||||
# error_msg = "There is no current billing cycle."
|
|
||||||
# return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
|
||||||
|
|
||||||
# billing_data = payment_cycle.instance
|
|
||||||
|
|
||||||
# if not billing_data:
|
|
||||||
# error_msg = "There is no current billing data."
|
|
||||||
# return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
|
||||||
|
|
||||||
# category = payment_cycle.category
|
|
||||||
|
|
||||||
# if category == PaymentCategory.INDIVIDUAL:
|
|
||||||
# profile_id = billing_data.instance_id
|
|
||||||
# result = mark_profile_as_paid(profile_id)
|
|
||||||
# if not result.valid:
|
|
||||||
# return result
|
|
||||||
|
|
||||||
# elif category == PaymentCategory.TICKET:
|
|
||||||
# # saving global ticket data:
|
|
||||||
# billing_data.billing_pending = False
|
|
||||||
# billing_data.paid = True
|
|
||||||
# billing_data.save()
|
|
||||||
|
|
||||||
# else:
|
|
||||||
# return not_supported()
|
|
||||||
|
|
||||||
# # finally:
|
|
||||||
# payment_cycle.wipe()
|
|
||||||
# return Result(valid=True)
|
|
||||||
|
|
||||||
|
|
||||||
# def mark_profile_as_paid(profile_id: int):
|
|
||||||
|
|
||||||
# logger.info(f"Marking profile_id {str(profile_id)} as paid..")
|
|
||||||
|
|
||||||
# # Get real profile object:
|
|
||||||
# profile = ProfileController.get(profile_id)
|
|
||||||
# if not profile:
|
|
||||||
# error_msg = f"Invalid profile id of {profile_id}"
|
|
||||||
# logger.error(error_msg)
|
|
||||||
# return Result(valid=False, message=error_msg, error_type=ResultError.INVALID_INPUT)
|
|
||||||
|
|
||||||
# profile.subscription.billing_pending = False
|
|
||||||
# ProfileController.update(profile)
|
|
||||||
# return Result(valid=True)
|
|
||||||
|
|
||||||
|
|
||||||
def save_billing_code(profile_id: int, billing_code: str, expires_at: datetime) -> Result:
|
def save_billing_code(profile_id: int, billing_code: str, expires_at: datetime) -> Result:
|
||||||
"""Checks if the billing code is already saved, and if not, saves it."""
|
"""Checks if the billing code is already saved, and if not, saves it."""
|
||||||
|
|
||||||
|
|
@ -631,6 +529,7 @@ def save_billing_code(profile_id: int, billing_code: str, expires_at: datetime)
|
||||||
|
|
||||||
|
|
||||||
# this can be modified to accept an id, once the UI has a cache layer:
|
# this can be modified to accept an id, once the UI has a cache layer:
|
||||||
|
@type_checker
|
||||||
def save_subscription(profile: Profile, subscription: Subscription) -> bool:
|
def save_subscription(profile: Profile, subscription: Subscription) -> bool:
|
||||||
"""Saves subscription with the code and date."""
|
"""Saves subscription with the code and date."""
|
||||||
|
|
||||||
|
|
@ -643,8 +542,9 @@ def save_subscription(profile: Profile, subscription: Subscription) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@type_checker
|
||||||
def return_pre_existing_payment_data(profile_id: int, subscription: SubscriptionInvoice) -> Result:
|
def return_pre_existing_payment_data(profile_id: int, subscription: SubscriptionInvoice) -> Result:
|
||||||
"""Return the pre-existing payment details (or lack of) for a profile"""
|
"""Return the pre-existing payment details (or lack of) for an individual profile"""
|
||||||
|
|
||||||
logger.info("Starting a fetch of pre-existing payment data")
|
logger.info("Starting a fetch of pre-existing payment data")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
from core.models.Result import Result
|
from core.models.Result import Result
|
||||||
|
from core.errors.logger import logger
|
||||||
|
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
@ -20,7 +22,9 @@ def type_checker(func):
|
||||||
bound_args.apply_defaults()
|
bound_args.apply_defaults()
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
# This handles cases where the wrong number of arguments are passed
|
# This handles cases where the wrong number of arguments are passed
|
||||||
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=str(e))
|
error_msg = f"For {func}, {str(e)}"
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
# 2. Perform type validation
|
# 2. Perform type validation
|
||||||
for name, value in bound_args.arguments.items():
|
for name, value in bound_args.arguments.items():
|
||||||
|
|
@ -31,10 +35,12 @@ def type_checker(func):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not isinstance(value, expected_type):
|
if not isinstance(value, expected_type):
|
||||||
|
error_msg = f"For function {func}, Argument '{name}' must be {expected_type.__name__}, got type {type(value).__name__}"
|
||||||
|
logger.error(error_msg)
|
||||||
return Result(
|
return Result(
|
||||||
valid=False,
|
valid=False,
|
||||||
error_type=ResultError.INVALID_INPUT,
|
error_type=ResultError.INVALID_INPUT,
|
||||||
message=f"Argument '{name}' must be {expected_type.__name__}, got type {type(value).__name__}"
|
message=error_msg
|
||||||
)
|
)
|
||||||
|
|
||||||
# 3. If all checks pass, call the original function
|
# 3. If all checks pass, call the original function
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue