From 7f98f1f6624250258682431e8cac75ecfe4ffd87 Mon Sep 17 00:00:00 2001 From: khushal Date: Thu, 2 Jan 2025 10:12:05 +0000 Subject: [PATCH] (20250102) Print statement removed. --- .../finstitutions/trading/oauth/request.py | 4 -- controllers_v2/finstitutions/payments/base.py | 46 +++++++++++++++++++ .../payments/safaricom_mpesa_express.py | 34 ++++++-------- models/api/finstitutions/payments/request.py | 28 +---------- models/core/payment.py | 45 ++++++++++++++++++ 5 files changed, 108 insertions(+), 49 deletions(-) diff --git a/api/blueprints/finstitutions/trading/oauth/request.py b/api/blueprints/finstitutions/trading/oauth/request.py index 4fab058..d079f9d 100644 --- a/api/blueprints/finstitutions/trading/oauth/request.py +++ b/api/blueprints/finstitutions/trading/oauth/request.py @@ -213,8 +213,6 @@ async def request_oauth_authorization_url( if inbound_data.client == "zerodhaKite": - print("Zerodha") - # Prepare the inputs: auth_url = await current_app.zerodha_kite_controller.get_authorization_url(api_key = inbound_data.auth.apiKey) @@ -252,8 +250,6 @@ async def request_oauth_authorization_url( if inbound_data.client == "iciciBreeze": - print("ICICI") - # Prepare the inputs: auth_url = await current_app.icici_breeze_controller.get_authorization_url(api_key = inbound_data.auth.apiKey) diff --git a/controllers_v2/finstitutions/payments/base.py b/controllers_v2/finstitutions/payments/base.py index e8f16ad..c94d8a3 100644 --- a/controllers_v2/finstitutions/payments/base.py +++ b/controllers_v2/finstitutions/payments/base.py @@ -36,6 +36,7 @@ sys.path.append(".") sys.path.append("..") # My async utils: +from utils_v2.string import json from utils_v2.database.async_mysql_v2 import AsyncMySQL from utils_v2.database.async_mongo_v2 import AsyncMongo from utils_v2.cache.async_redis_cache_v2 import AsyncRedisCache @@ -310,6 +311,51 @@ class PaymentsController(CoreAuthTokenController, ABC): # We don't support updating payments themselves, # but we will allow updating fields like tags, adding events, etc. + async def add_receipt( + self, + sql_conn: AsyncMySQL, + mongo_data_conn: AsyncMongo, + payment: CorePaymentModel, + session_token: str = None + ) -> bool: + + """ + The API endpoint that initiates the payment request will send details for calling this procedure in the + 'metadata' field. We take those values and invoke the procedure to add a receipt in the database's records. + :param sql_conn: The database connection to use to perform this activity. + :param mongo_data_conn: The database connection to use to perform this activity. + :param payment: The record of the payment whose details need to be added as a receipt. + :param session_token: The session token of the user to identify whose request caused this receipt update. + :return: True is the receipt was added, else False. + """ + + # Call the database's procedure: + sql_json = await self.call_procedure( + sql_conn = sql_conn, + proc_name = "accounting_receipt_add", + proc_args = ( + payment.metadata["idClient"], + payment.metadata["date"], + payment.metadata["source"], + payment.metadata["amount"], + payment.metadata["reference"], + payment.metadata["inAccount"], + payment.metadata["idUser"], + payment.metadata["documentUrl"], + payment.metadata["notes"] + ), + retry_count = 1, + backoff_seconds = 0.5, + backoff_multiplier = 1.1, + session_token = session_token + ) + + print("RECEIPT ADD SQL JSON:", json.to_string(sql_json, default=str)) + + # Return the response: + if sql_json["status"] == 1: return True + else: return False + async def add_event_by_payment_id( self, mongo_data_conn: AsyncMongo, diff --git a/controllers_v2/finstitutions/payments/safaricom_mpesa_express.py b/controllers_v2/finstitutions/payments/safaricom_mpesa_express.py index 5678acf..c3f88ac 100644 --- a/controllers_v2/finstitutions/payments/safaricom_mpesa_express.py +++ b/controllers_v2/finstitutions/payments/safaricom_mpesa_express.py @@ -238,7 +238,6 @@ class SafaricomMPesaExpressPaymentsController(PaymentsController): ) if isinstance(payment_request.payerNo, str) else payment_request.payerNo, party_b = auth_token.auth["businessShortCode"] ) - print(client_response.to_markdown()) # Add this event to the payment's document: event_note_success = await self.add_event_by_payment_id( @@ -345,7 +344,7 @@ class SafaricomMPesaExpressPaymentsController(PaymentsController): } ) - # For now, we just insert the event into the record: + # We just insert the event into the record: event_note_success = await self.add_event_by_client_reference_id( mongo_data_conn = mongo_data_conn, event = PaymentEvent( @@ -360,23 +359,20 @@ class SafaricomMPesaExpressPaymentsController(PaymentsController): client_reference_id = pg_reference_id ) - # In case the payment collector's credentials have changed, - # we mark his account as disabled: - # if pg_result_code in [2001]: - # payment = await self.get_payment_by_client_reference_id( - # mongo_data_conn = mongo_data_conn, - # client_reference_id = pg_reference_id - # ) - # auth_token = await self.get_token_from_id( - # mongo_data_conn = mongo_data_conn, - # token_id = payment.tokenId - # ) - # auth_token.status = "disabled" - # await self.set_token( - # sql_conn = sql_conn, - # mongo_data_conn = mongo_data_conn, - # auth_token = auth_token - # ) + # We now fetch the payment record and use that for cases like adding the receipt or disabling an account whose + # credentials are invalid: + payment = await self.get_payment_by_client_reference_id( + mongo_data_conn = mongo_data_conn, + client_reference_id = pg_reference_id + ) + + # For when the payment is successful: + if pg_result_code in []: + await self.add_receipt( + sql_conn = sql_conn, + mongo_data_conn = mongo_data_conn, + payment = payment + ) # Done here: if event_note_success: diff --git a/models/api/finstitutions/payments/request.py b/models/api/finstitutions/payments/request.py index 7db3496..6286b9d 100644 --- a/models/api/finstitutions/payments/request.py +++ b/models/api/finstitutions/payments/request.py @@ -44,7 +44,7 @@ from utils_v2.string import regex from utils_v2.date_time import date_time # Models: -from models.core.payment import CorePaymentModel +from models.core.payment import CorePaymentModel, PaymentMetadata # To work with date and time: import datetime @@ -108,30 +108,6 @@ class PGPaymentRequestHeaders(BaseModel): # --------------------------------------------------------------------------------------------------------------------- -class PaymentRequestMetadata(BaseModel): - - idClient: str | int = Field( - description = "account master id for the user's customer", - frozen = True - ) - - inAccount: str | int = Field( - description = "account master id for the user's bank account", - frozen = True - ) - - # ┏┓ ┏• - # ┃ ┏┓┏┓╋┓┏┓ - # ┗┛┗┛┛┗┛┗┗┫ - # ┛ - - class Config: - extra = "allow" - - -# --------------------------------------------------------------------------------------------------------------------- - - class PGPaymentRequestData(BaseModel): tokenKey: ObjectId = Field( @@ -183,7 +159,7 @@ class PGPaymentRequestData(BaseModel): frozen = True ) - metadata: PaymentRequestMetadata = Field( + metadata: PaymentMetadata = Field( description = "any extra information about this payment", frozen = True ) diff --git a/models/core/payment.py b/models/core/payment.py index 8197e12..3366409 100644 --- a/models/core/payment.py +++ b/models/core/payment.py @@ -134,6 +134,51 @@ class CustomerDetails(BaseModel): # --------------------------------------------------------------------------------------------------------------------- +class PaymentMetadata(BaseModel): + + """ + These are things that the UI will send you, and you must use them as-is for adding receipts. Their internal workings + and use-cases are not known and are not of this code's direct concern except that you must ensure that these details + get delivered through the mechanism of adding receipts. + """ + + idClient: int = Field(frozen = True) + inAccount: int = Field(frozen = True) + reference: str | None = Field(frozen = True, default = None, validate_default = True) + againstReference: str | None = Field(frozen = True, default = None, validate_default = True) + documentUrl: str | None = Field(frozen = False, default = None, validate_default = True) + + # ┏┓ ┏• + # ┃ ┏┓┏┓╋┓┏┓ + # ┗┛┗┛┛┗┛┗┗┫ + # ┛ + + class Config: + extra = "allow" + + # ┓┏ ┓• ┓ • + # ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓ + # ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗ + + @field_validator("reference") + def validate_reference(cls, value): + if not value: value = "On Account" + return value + + @field_validator("againstReference") + def validate_against_reference(cls, value): + if not value: value = None + return value + + @field_validator("documentUrl") + def validate_document_url(cls, value): + if not value: value = None + return value + + +# --------------------------------------------------------------------------------------------------------------------- + + class PaymentEvent(BaseModel): eventTs: AwareDatetime = Field(