From e222922a6a016aa660457d64fe9b4d1d28c457db Mon Sep 17 00:00:00 2001 From: padreug Date: Sat, 5 Jul 2025 14:58:38 +0200 Subject: [PATCH] Update fiat amount handling in models and transaction processor: Modified models to store fiat amounts in centavos for precision. Adjusted transaction processing logic to calculate and display fiat values in centavos, ensuring consistency across the application. Enhanced comments for clarity on the new storage format. --- models.py | 8 ++++---- transaction_processor.py | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/models.py b/models.py index ff8a5b2..9d0e8e7 100644 --- a/models.py +++ b/models.py @@ -62,7 +62,7 @@ class UpdateDepositStatusData(BaseModel): class CreateDcaPaymentData(BaseModel): client_id: str amount_sats: int - amount_fiat: int + amount_fiat: int # Stored in centavos (GTQ * 100) for precision exchange_rate: float transaction_type: str # 'flow', 'fixed', 'manual', 'commission' lamassu_transaction_id: Optional[str] = None @@ -74,7 +74,7 @@ class DcaPayment(BaseModel): id: str client_id: str amount_sats: int - amount_fiat: int + amount_fiat: int # Stored in centavos (GTQ * 100) for precision exchange_rate: float transaction_type: str lamassu_transaction_id: Optional[str] @@ -96,7 +96,7 @@ class ClientBalanceSummary(BaseModel): # Transaction Processing Models class LamassuTransaction(BaseModel): transaction_id: str - amount_fiat: int + amount_fiat: int # Stored in centavos (GTQ * 100) for precision amount_crypto: int exchange_rate: float transaction_type: str # 'cash_in' or 'cash_out' @@ -107,7 +107,7 @@ class LamassuTransaction(BaseModel): # Lamassu Transaction Storage Models class CreateLamassuTransactionData(BaseModel): lamassu_transaction_id: str - fiat_amount: int + fiat_amount: int # Stored in centavos (GTQ * 100) for precision crypto_amount: int commission_percentage: float discount: float = 0.0 diff --git a/transaction_processor.py b/transaction_processor.py index ceaedd4..6fc5647 100644 --- a/transaction_processor.py +++ b/transaction_processor.py @@ -714,9 +714,9 @@ class LamassuTransactionProcessor: # Calculate client's share of the base crypto (after commission) client_sats_amount = int(base_crypto_atoms * proportion) - # Calculate equivalent fiat value for tracking purposes - # TODO: make client_fiat_amount float with 2 decimal presicion - client_fiat_amount = int(client_sats_amount / exchange_rate) if exchange_rate > 0 else 0 + # Calculate equivalent fiat value in centavos for tracking purposes (industry standard) + # Store as centavos to maintain precision and avoid floating-point errors + client_fiat_amount = round(client_sats_amount * 100 / exchange_rate) if exchange_rate > 0 else 0 distributions[client_id] = { "fiat_amount": client_fiat_amount, @@ -724,7 +724,7 @@ class LamassuTransactionProcessor: "exchange_rate": exchange_rate } - logger.info(f"Client {client_id[:8]}... gets {client_sats_amount} sats (≈{client_fiat_amount} fiat units, {proportion:.2%} share)") + logger.info(f"Client {client_id[:8]}... gets {client_sats_amount} sats (≈{client_fiat_amount/100:.2f} GTQ, {proportion:.2%} share)") return distributions @@ -759,7 +759,7 @@ class LamassuTransactionProcessor: payment_data = CreateDcaPaymentData( client_id=client_id, amount_sats=distribution["sats_amount"], - amount_fiat=distribution["fiat_amount"], + amount_fiat=distribution["fiat_amount"], # Still store centavos in DB exchange_rate=distribution["exchange_rate"], transaction_type="flow", lamassu_transaction_id=transaction_id, @@ -802,16 +802,19 @@ class LamassuTransactionProcessor: return False # Create descriptive memo with DCA metrics - fiat_amount = distribution.get("fiat_amount", 0) + fiat_amount_centavos = distribution.get("fiat_amount", 0) exchange_rate = distribution.get("exchange_rate", 0) + # Convert centavos to GTQ for display + fiat_amount_gtq = fiat_amount_centavos / 100 + # Calculate cost basis (fiat per BTC) if exchange_rate > 0: # exchange_rate is sats per fiat unit, so convert to fiat per BTC cost_basis_per_btc = 100_000_000 / exchange_rate # 100M sats = 1 BTC - memo = f"DCA: {amount_sats:,} sats • {fiat_amount:,} GTQ • Cost basis: {cost_basis_per_btc:,.2f} GTQ/BTC" + memo = f"DCA: {amount_sats:,} sats • {fiat_amount_gtq:.2f} GTQ • Cost basis: {cost_basis_per_btc:,.2f} GTQ/BTC" else: - memo = f"DCA: {amount_sats:,} sats • {fiat_amount:,} GTQ" + memo = f"DCA: {amount_sats:,} sats • {fiat_amount_gtq:.2f} GTQ" # Create invoice in target wallet extra={ @@ -932,10 +935,10 @@ class LamassuTransactionProcessor: # Calculate exchange rate exchange_rate = base_crypto_atoms / fiat_amount if fiat_amount > 0 else 0 - # Create transaction data + # Create transaction data (store fiat_amount in centavos for consistency) transaction_data = CreateLamassuTransactionData( lamassu_transaction_id=transaction["transaction_id"], - fiat_amount=fiat_amount, + fiat_amount=int(fiat_amount * 100), # Convert GTQ to centavos crypto_amount=crypto_atoms, commission_percentage=commission_percentage, discount=discount,