Fix amount parsing to handle both @ and @@ SATS notation
Pending expense entries use per-unit price notation (@ SATS) while migrated entries use total price notation (@@ SATS). Formats handled: - "50.00 EUR @@ 50000 SATS" - total price (multiply = amount) - "50.00 EUR @ 1000.5 SATS" - per-unit price (multiply for total) - "50.00 EUR" with metadata - legacy format - "50000 SATS" - old SATS-first format 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
7173e051fe
commit
913e4705b1
2 changed files with 144 additions and 51 deletions
77
views_api.py
77
views_api.py
|
|
@ -508,21 +508,38 @@ async def api_get_user_entries(
|
|||
if isinstance(first_posting, dict):
|
||||
amount_str = first_posting.get("amount", "")
|
||||
|
||||
# Parse amount string: can be EUR/USD directly (new format) or "SATS {EUR}" (old format)
|
||||
# Parse amount string: price notation, simple fiat, or legacy SATS format
|
||||
if isinstance(amount_str, str) and amount_str:
|
||||
import re
|
||||
# Try EUR/USD format first (new format: "37.22 EUR")
|
||||
fiat_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})$', amount_str)
|
||||
if fiat_match and fiat_match.group(2) in ('EUR', 'USD', 'GBP'):
|
||||
# Direct fiat amount (new approach)
|
||||
fiat_amount = abs(float(fiat_match.group(1)))
|
||||
fiat_currency = fiat_match.group(2)
|
||||
|
||||
# Get SATS from metadata
|
||||
posting_meta = first_posting.get("meta", {})
|
||||
sats_equiv = posting_meta.get("sats-equivalent")
|
||||
if sats_equiv:
|
||||
amount_sats = abs(int(sats_equiv))
|
||||
# Try total price notation: "50.00 EUR @@ 50000 SATS"
|
||||
total_price_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})\s+@@\s+(\d+)\s+SATS$', amount_str)
|
||||
# Try per-unit price notation: "50.00 EUR @ 1000.5 SATS"
|
||||
unit_price_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})\s+@\s+([\d.]+)\s+SATS$', amount_str)
|
||||
|
||||
if total_price_match:
|
||||
fiat_amount = abs(float(total_price_match.group(1)))
|
||||
fiat_currency = total_price_match.group(2)
|
||||
amount_sats = abs(int(total_price_match.group(3)))
|
||||
elif unit_price_match:
|
||||
fiat_amount = abs(float(unit_price_match.group(1)))
|
||||
fiat_currency = unit_price_match.group(2)
|
||||
sats_per_unit = float(unit_price_match.group(3))
|
||||
amount_sats = abs(int(fiat_amount * sats_per_unit))
|
||||
|
||||
# Try simple fiat format: "50.00 EUR" (check metadata for sats)
|
||||
elif re.match(r'^(-?[\d.]+)\s+([A-Z]{3})$', amount_str):
|
||||
fiat_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})$', amount_str)
|
||||
if fiat_match and fiat_match.group(2) in ('EUR', 'USD', 'GBP'):
|
||||
fiat_amount = abs(float(fiat_match.group(1)))
|
||||
fiat_currency = fiat_match.group(2)
|
||||
|
||||
# Get SATS from metadata (legacy)
|
||||
posting_meta = first_posting.get("meta", {})
|
||||
sats_equiv = posting_meta.get("sats-equivalent")
|
||||
if sats_equiv:
|
||||
amount_sats = abs(int(sats_equiv))
|
||||
|
||||
else:
|
||||
# Old format: "36791 SATS {33.33 EUR, 2025-11-09}" or "36791 SATS"
|
||||
sats_match = re.match(r'^(-?\d+)\s+SATS', amount_str)
|
||||
|
|
@ -781,17 +798,33 @@ async def api_get_pending_entries(
|
|||
if isinstance(amount_str, str) and amount_str:
|
||||
import re
|
||||
|
||||
# Try EUR/USD format first (new architecture): "50.00 EUR"
|
||||
fiat_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})$', amount_str)
|
||||
if fiat_match and fiat_match.group(2) in ('EUR', 'USD', 'GBP'):
|
||||
fiat_amount = abs(float(fiat_match.group(1)))
|
||||
fiat_currency = fiat_match.group(2)
|
||||
# Try total price notation: "50.00 EUR @@ 50000 SATS"
|
||||
total_price_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})\s+@@\s+(\d+)\s+SATS$', amount_str)
|
||||
# Try per-unit price notation: "50.00 EUR @ 1000.5 SATS"
|
||||
unit_price_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})\s+@\s+([\d.]+)\s+SATS$', amount_str)
|
||||
|
||||
# Extract sats equivalent from metadata
|
||||
posting_meta = first_posting.get("meta", {})
|
||||
sats_equiv = posting_meta.get("sats-equivalent")
|
||||
if sats_equiv:
|
||||
amount_sats = abs(int(sats_equiv))
|
||||
if total_price_match:
|
||||
fiat_amount = abs(float(total_price_match.group(1)))
|
||||
fiat_currency = total_price_match.group(2)
|
||||
amount_sats = abs(int(total_price_match.group(3)))
|
||||
elif unit_price_match:
|
||||
fiat_amount = abs(float(unit_price_match.group(1)))
|
||||
fiat_currency = unit_price_match.group(2)
|
||||
sats_per_unit = float(unit_price_match.group(3))
|
||||
amount_sats = abs(int(fiat_amount * sats_per_unit))
|
||||
|
||||
# Try simple fiat format: "50.00 EUR" (check metadata for sats)
|
||||
elif re.match(r'^(-?[\d.]+)\s+([A-Z]{3})$', amount_str):
|
||||
fiat_match = re.match(r'^(-?[\d.]+)\s+([A-Z]{3})$', amount_str)
|
||||
if fiat_match and fiat_match.group(2) in ('EUR', 'USD', 'GBP'):
|
||||
fiat_amount = abs(float(fiat_match.group(1)))
|
||||
fiat_currency = fiat_match.group(2)
|
||||
|
||||
# Extract sats equivalent from metadata (legacy)
|
||||
posting_meta = first_posting.get("meta", {})
|
||||
sats_equiv = posting_meta.get("sats-equivalent")
|
||||
if sats_equiv:
|
||||
amount_sats = abs(int(sats_equiv))
|
||||
|
||||
else:
|
||||
# Legacy SATS format: "36791 SATS {33.33 EUR, 2025-11-09}" or "36791 SATS"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue