Use of a pre-existing billing code, to then connect
This commit is contained in:
parent
b68d1ea6bd
commit
f54ed5686a
5 changed files with 117 additions and 18 deletions
|
|
@ -7,6 +7,7 @@ from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
|
||||||
class ServerError(str, Enum):
|
class ServerError(str, Enum):
|
||||||
"""Why the Server's Operation was False."""
|
"""Why the Server's Operation was False."""
|
||||||
NONE = "none"
|
NONE = "none"
|
||||||
|
|
@ -24,8 +25,9 @@ class ServerError(str, Enum):
|
||||||
SERVER_SIDE = "server_side"
|
SERVER_SIDE = "server_side"
|
||||||
|
|
||||||
|
|
||||||
|
# @validate_types
|
||||||
|
|
||||||
@dataclass_json
|
@dataclass_json
|
||||||
@validate_types
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ServerReply():
|
class ServerReply():
|
||||||
"""Server-Client Communication Format."""
|
"""Server-Client Communication Format."""
|
||||||
|
|
@ -38,7 +40,12 @@ class ServerReply():
|
||||||
boolean_result: Optional[bool] = None
|
boolean_result: Optional[bool] = None
|
||||||
conf: Optional[str] = None
|
conf: Optional[str] = None
|
||||||
payment_status: Optional[bool] = None
|
payment_status: Optional[bool] = None
|
||||||
expires_at: Optional[datetime] = None
|
expires_at: Optional[datetime] = field(
|
||||||
|
default=None,
|
||||||
|
metadata=config(
|
||||||
|
decoder=lambda x: datetime.fromisoformat(x.replace('Z', '+00:00')) if x else None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from core.errors.logger import logger
|
||||||
from core.errors.error_shortcuts import not_supported
|
from core.errors.error_shortcuts import not_supported
|
||||||
from core.observers.Notifications import Notifications, EventType
|
from core.observers.Notifications import Notifications, EventType
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
def _mark_profile_as_paid(profile_id: int):
|
def _mark_profile_as_paid(profile_id: int):
|
||||||
"""Save to disk that an individual profile is paid."""
|
"""Save to disk that an individual profile is paid."""
|
||||||
|
|
@ -68,7 +69,7 @@ def mark_as_paid() -> Result:
|
||||||
return Result(valid=True)
|
return Result(valid=True)
|
||||||
|
|
||||||
|
|
||||||
def check_paid(billing_code: str, connection_observer: ConnectionObserver) -> Result:
|
def check_paid(billing_code: str, connection_observer: ConnectionObserver, get_expired_date: Optional[bool] = False) -> Result:
|
||||||
"""
|
"""
|
||||||
Purpose:
|
Purpose:
|
||||||
Evaluates Payment Status for EITHER payment category
|
Evaluates Payment Status for EITHER payment category
|
||||||
|
|
@ -95,22 +96,51 @@ def check_paid(billing_code: str, connection_observer: ConnectionObserver) -> Re
|
||||||
"billing_code": billing_code
|
"billing_code": billing_code
|
||||||
}
|
}
|
||||||
|
|
||||||
result = api_call_and_extraction(
|
#-----------------
|
||||||
desired_type="payment_status",
|
# Just get paid or not
|
||||||
|
#-----------------
|
||||||
|
if not get_expired_date:
|
||||||
|
|
||||||
|
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.")
|
||||||
|
|
||||||
|
|
||||||
|
#-----------------
|
||||||
|
# Find out if Paid & Get expiration:
|
||||||
|
#-----------------
|
||||||
|
# Get entire ServerReply
|
||||||
|
server_reply = api_call_and_extraction(
|
||||||
|
desired_type=None,
|
||||||
method=ApiCall.POST,
|
method=ApiCall.POST,
|
||||||
url=url,
|
url=url,
|
||||||
connection_observer=connection_observer,
|
connection_observer=connection_observer,
|
||||||
payload=submit_data
|
payload=submit_data,
|
||||||
|
return_server_reply=True # get server reply
|
||||||
)
|
)
|
||||||
|
|
||||||
if not result.valid:
|
if not server_reply.valid:
|
||||||
return result
|
return server_reply
|
||||||
|
|
||||||
payment_status = result.data
|
payment_status = server_reply.payment_status
|
||||||
|
expires_at = server_reply.expires_at
|
||||||
# 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.")
|
|
||||||
|
|
||||||
|
if payment_status and expires_at:
|
||||||
|
return Result(valid=True, data=expires_at, message="Paid with an expiration")
|
||||||
|
|
||||||
|
return Result(valid=False, error_type=ResultError.UNPAID, message="The API call went through, but this subscription is not yet paid.")
|
||||||
38
core/services/payment_phase/pre_existing.py
Normal file
38
core/services/payment_phase/pre_existing.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
from core.services.payment_phase.payment_update_tools import check_paid
|
||||||
|
from core.services.subscriptions.subscriptions_by_protocol import save_billing_code, wipe_billing_cycle_IF_its_this_profile
|
||||||
|
from core.services.payment_phase.payment_state import OverallPaymentCycle
|
||||||
|
from core.models.Result import Result
|
||||||
|
from core.errors.logger import logger
|
||||||
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
|
|
||||||
|
|
||||||
|
def check_then_save_billing_code(profile_id: int, billing_code: str, connection_observer: ConnectionObserver) -> Result:
|
||||||
|
"""Check if a billing code is paid for, and if it is, then save it and wipe the profile's billing cycle"""
|
||||||
|
|
||||||
|
logger.info(f"Checking payment status of a pre-existing billing code for profile {str(profile_id)}")
|
||||||
|
|
||||||
|
payment_result = check_paid(billing_code=billing_code, connection_observer=connection_observer, get_expired_date=True)
|
||||||
|
|
||||||
|
if not payment_result.valid:
|
||||||
|
logger.error(f"Check of paid came back that it's NOT paid, despite the user using a pre-existing billing code. {payment_result.message}")
|
||||||
|
return payment_result
|
||||||
|
|
||||||
|
expires_at = payment_result.data
|
||||||
|
|
||||||
|
saved = save_billing_code(
|
||||||
|
profile_id=profile_id,
|
||||||
|
billing_code=billing_code,
|
||||||
|
expires_at=expires_at,
|
||||||
|
which_ticket=None,
|
||||||
|
billing_pending=False
|
||||||
|
)
|
||||||
|
|
||||||
|
if saved.valid:
|
||||||
|
print("save worked, we are clearing the billing cycle")
|
||||||
|
wiped = wipe_billing_cycle_IF_its_this_profile(profile_id)
|
||||||
|
if not wiped.valid:
|
||||||
|
logger.error(f"Unable to wipe the current billing cycle: {wiped.message}")
|
||||||
|
return wiped
|
||||||
|
else:
|
||||||
|
logger.error(f"failed to save the new billing code, returning the saved result {saved}")
|
||||||
|
return saved
|
||||||
|
|
@ -14,6 +14,8 @@ from core.observers.TicketObserver import TicketObserver
|
||||||
from core.services.assassin.ticket_respawn import respawn_profile
|
from core.services.assassin.ticket_respawn import respawn_profile
|
||||||
from core.services.assassin import assassin_tools
|
from core.services.assassin import assassin_tools
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
from core.services.payment_phase.payment_state import OverallPaymentCycle
|
||||||
|
from core.services.subscriptions.subscriptions_by_protocol import wipe_billing_cycle_IF_its_this_profile
|
||||||
|
|
||||||
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError, ConnectionTerminationError, ProfileActivationError, ProfileDeactivationError, MissingLocationError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
|
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError, ConnectionTerminationError, ProfileActivationError, ProfileDeactivationError, MissingLocationError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
|
||||||
from core.controllers.ApplicationController import ApplicationController
|
from core.controllers.ApplicationController import ApplicationController
|
||||||
|
|
@ -310,6 +312,14 @@ def destroy_profile(
|
||||||
2) Disabling it,
|
2) Disabling it,
|
||||||
3) Destroying it on disk & cache
|
3) Destroying it on disk & cache
|
||||||
"""
|
"""
|
||||||
|
####################################
|
||||||
|
# ACTIVE BILLING STATE:
|
||||||
|
####################################
|
||||||
|
wiped = wipe_billing_cycle_IF_its_this_profile(profile.id)
|
||||||
|
if not wiped.valid:
|
||||||
|
logger.error(f"Unable to wipe the current billing cycle: {wiped.message}")
|
||||||
|
return wiped
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# RESPAWN TICKET
|
# RESPAWN TICKET
|
||||||
####################################
|
####################################
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,20 @@ def get_current_billing_data(category: Optional[PaymentCategory] = None, profile
|
||||||
return Result(valid=True, data=billing_data)
|
return Result(valid=True, data=billing_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def wipe_billing_cycle_IF_its_this_profile(profile_id) -> Result:
|
||||||
|
# Overall State:
|
||||||
|
payment_cycle = OverallPaymentCycle()
|
||||||
|
if not payment_cycle:
|
||||||
|
return Result(valid=True)
|
||||||
|
|
||||||
|
if payment_cycle.billing_code != profile_id:
|
||||||
|
return Result(valid=True)
|
||||||
|
|
||||||
|
return wipe_billing_cycle(inserted_profile_id=profile.id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def wipe_billing_cycle(inserted_profile_id: Optional[int] = None) -> Result:
|
def wipe_billing_cycle(inserted_profile_id: Optional[int] = None) -> Result:
|
||||||
"""Wipes the entire overall cycle"""
|
"""Wipes the entire overall cycle"""
|
||||||
logger.info("Wiping the overall cycle, so this cycle no longer blocks other new ones")
|
logger.info("Wiping the overall cycle, so this cycle no longer blocks other new ones")
|
||||||
|
|
@ -573,10 +587,10 @@ def wipe_subscription(profile_id: int) -> Result:
|
||||||
|
|
||||||
|
|
||||||
@type_checker
|
@type_checker
|
||||||
def save_billing_code(profile_id: int, billing_code: str, expires_at: datetime, which_ticket: Optional[int] = None) -> Result:
|
def save_billing_code(profile_id: int, billing_code: str, expires_at: datetime, which_ticket: Optional[int] = None, billing_pending: bool = True) -> 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."""
|
||||||
|
|
||||||
logger.info("Saving billing code..")
|
logger.info(f"Saving billing code with the billing_pending as {billing_pending}")
|
||||||
|
|
||||||
PRE_REQS = [profile_id, billing_code, expires_at]
|
PRE_REQS = [profile_id, billing_code, expires_at]
|
||||||
if None in PRE_REQS:
|
if None in PRE_REQS:
|
||||||
|
|
@ -595,7 +609,7 @@ def save_billing_code(profile_id: int, billing_code: str, expires_at: datetime,
|
||||||
profile.subscription = Subscription(
|
profile.subscription = Subscription(
|
||||||
billing_code=billing_code,
|
billing_code=billing_code,
|
||||||
expires_at=expires_at,
|
expires_at=expires_at,
|
||||||
billing_pending=True
|
billing_pending=billing_pending
|
||||||
)
|
)
|
||||||
if which_ticket:
|
if which_ticket:
|
||||||
profile.ticket = which_ticket
|
profile.ticket = which_ticket
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue