planify / app /CurrencyMapping /currency_mapping.py
devZenaight's picture
Test Planify V1
8126b08
Raw
History Blame Contribute Delete
21.3 kB
# Currency Mapping Module
# Contains canonical_currency_map dictionary and convert_currency_symbols_to_iso() function
# Canonical currency map for symbol resolution (matches TypeScript version)
canonical_currency_map = {
# Standard currency symbols
"$": "USD",
"£": "GBP",
"€": "EUR",
"¥": "JPY",
"₹": "INR",
"₽": "RUB",
"₩": "KRW",
"₪": "ILS",
"₺": "TRY",
"₴": "UAH",
"₼": "AZN",
"₸": "KZT",
"₾": "GEL",
"֏": "AMD",
"₲": "PYG",
"₡": "CRC",
"₣": "XPF",
"₦": "NGN",
"₵": "GHS",
"₨": "PKR",
"₱": "PHP",
"₫": "VND",
"₭": "LAK",
"៛": "KHR",
"৳": "BDT",
"؋": "AFN",
"﷼": "IRR",
# Custom symbols
"‡": "CUSTOM_DAGGER",
"†": "CUSTOM_DAGGER_SINGLE",
# Letter-based currencies
"R": "ZAR", # South African Rand
"C$": "CAD", # Canadian Dollar
"A$": "AUD", # Australian Dollar
"R$": "BRL", # Brazilian Real
"S/": "PEN", # Peruvian Sol
"Bs": "BOB", # Bolivian Boliviano
"Q": "GTQ", # Guatemalan Quetzal
"L": "HNL", # Honduran Lempira
"ƒ": "AWG", # Aruban Florin
"Vt": "VUV", # Vanuatu Vatu
"T$": "TOP", # Tongan Pa'anga
"T": "WST", # Samoan Tala
"лв": "BGN", # Bulgarian Lev
"Kč": "CZK", # Czech Koruna
"kr": "DKK", # Danish Krone
"Ft": "HUF", # Hungarian Forint
"zł": "PLN", # Polish Zloty
"lei": "RON", # Romanian Leu
"CHF": "CHF", # Swiss Franc
"KM": "BAM", # Bosnian Marka
"ден": "MKD", # North Macedonian Denar
"дин": "RSD", # Serbian Dinar
"so'm": "UZS", # Uzbekistani Som
"NT$": "TWD", # Taiwan Dollar
"HK$": "HKD", # Hong Kong Dollar
"S$": "SGD", # Singapore Dollar
"RM": "MYR", # Malaysian Ringgit
"฿": "THB", # Thai Baht
"Rp": "IDR", # Indonesian Rupiah
"K": "MMK", # Myanmar Kyat
"Rs": "LKR", # Sri Lankan Rupee
"Nu": "BTN", # Bhutanese Ngultrum
"MVR": "MVR", # Maldivian Rufiyaa
# Middle Eastern currencies
"ع.د": "IQD", # Iraqi Dinar
"ل.ل": "LBP", # Lebanese Pound
"د.ا": "JOD", # Jordanian Dinar
"ر.س": "SAR", # Saudi Riyal
"د.إ": "AED", # UAE Dirham
"ر.ق": "QAR", # Qatari Riyal
"د.ك": "KWD", # Kuwaiti Dinar
"د.ب": "BHD", # Bahraini Dinar
"ر.ع.": "OMR", # Omani Rial
"ر.ي": "YER", # Yemeni Rial
"ج.م": "EGP", # Egyptian Pound
"ل.د": "LYD", # Libyan Dinar
"د.ت": "TND", # Tunisian Dinar
"د.ج": "DZD", # Algerian Dinar
"د.م.": "MAD", # Moroccan Dirham
"ج.س.": "SDG", # Sudanese Pound
"SSP": "SSP", # South Sudanese Pound
# African currencies
"KSh": "KES", # Kenyan Shilling
"USh": "UGX", # Ugandan Shilling
"TSh": "TZS", # Tanzanian Shilling
"FRw": "RWF", # Rwandan Franc
"FBu": "BIF", # Burundian Franc
"MT": "MZN", # Mozambican Metical
"P": "BWP", # Botswanan Pula
"N$": "NAD", # Namibian Dollar
"Ar": "MGA", # Malagasy Ariary
"CF": "KMF", # Comorian Franc
"MK": "MWK", # Malawian Kwacha
"ZK": "ZMW", # Zambian Kwacha
"Kz": "AOA", # Angolan Kwanza
"FC": "CDF", # Congolese Franc
"FCFA": "XAF", # Central African Franc
"Db": "STD", # Sao Tomean Dobra
"D": "GMD", # Gambian Dalasi
"FG": "GNF", # Guinean Franc
"CFA": "XOF", # West African Franc
"Le": "SLL", # Sierra Leonean Leone
"L$": "LRD", # Liberian Dollar
"Br": "ETB", # Ethiopian Birr
"Nfk": "ERN", # Eritrean Nakfa
"Fdj": "DJF", # Djiboutian Franc
"S": "SOS", # Somali Shilling
# Caribbean & Central American currencies
"J$": "JMD", # Jamaican Dollar
"BZ$": "BZD", # Belize Dollar
"TT$": "TTD", # Trinidad and Tobago Dollar
"Bds$": "BBD", # Barbadian Dollar
"EC$": "XCD", # East Caribbean Dollar
"GY$": "GYD", # Guyanese Dollar
"SRD": "SRD", # Surinamese Dollar
"RD$": "DOP", # Dominican Peso
# Pacific Island currencies
"FJ$": "FJD", # Fijian Dollar
"PGK": "PGK", # Papua New Guinean Kina
"SI$": "SBD", # Solomon Islands Dollar
"WS$": "WST", # Samoan Tala
"VT": "VUV", # Vanuatu Vatu
# European currencies
"ISK": "ISK", # Icelandic Krona
"Lt": "LTL", # Lithuanian Litas
"Ls": "LVL", # Latvian Lats
"EEK": "EEK", # Estonian Kroon
"NOK": "NOK", # Norwegian Krone
"SEK": "SEK", # Swedish Krona
"ALL": "ALL", # Albanian Lek
# South American currencies
"Gs": "PYG", # Paraguayan Guarani
"Bs.S": "VES", # Venezuelan Bolívar Soberano
"Bs": "VEF", # Venezuelan Bolívar
"$U": "UYU", # Uruguayan Peso
"$a": "ARS", # Argentine Peso
"$b": "BOB", # Bolivian Boliviano
"CLP": "CLP", # Chilean Peso
"COP": "COP", # Colombian Peso
"MXN": "MXN", # Mexican Peso
# Small Island Nations
"BMD": "BMD", # Bermudian Dollar
"BSD": "BSD", # Bahamian Dollar
"KYD": "KYD", # Cayman Islands Dollar
"TVD": "TVD", # Tuvaluan Dollar
"ZWL": "ZWL", # Zimbabwean Dollar
# Additional African currencies
"LSL": "LSL", # Lesotho Loti
"SZL": "SZL", # Swazi Lilangeni
"CVE": "CVE", # Cape Verdean Escudo
"MRO": "MRO", # Mauritanian Ouguiya
"MRU": "MRU", # Mauritanian Ouguiya
"SCR": "SCR", # Seychellois Rupee
"SHP": "SHP", # Saint Helena Pound
# Additional Asian currencies
"BND": "BND", # Brunei Dollar
"MOP": "MOP", # Macanese Pataca
"NPR": "NPR", # Nepalese Rupee
# Additional Pacific currencies
"NZD": "NZD", # New Zealand Dollar
# Alternative $ symbols for countries (context-dependent)
"$BMD": "BMD", # Bermudian Dollar
"$BSD": "BSD", # Bahamian Dollar
"$BZD": "BZD", # Belize Dollar
"$KYD": "KYD", # Cayman Islands Dollar
"$FJD": "FJD", # Fijian Dollar
"$GYD": "GYD", # Guyanese Dollar
"$JMD": "JMD", # Jamaican Dollar
"$LRD": "LRD", # Liberian Dollar
"$NAD": "NAD", # Namibian Dollar
"$SBD": "SBD", # Solomon Islands Dollar
"$SRD": "SRD", # Surinamese Dollar
"$TTD": "TTD", # Trinidad and Tobago Dollar
"$TVD": "TVD", # Tuvaluan Dollar
"$VUV": "VUV", # Vanuatu Vatu
"$WST": "WST", # Samoan Tala
"$XCD": "XCD", # East Caribbean Dollar
"$ZWL": "ZWL", # Zimbabwean Dollar
"$BWP": "BWP", # Botswanan Pula
"$LSL": "LSL", # Lesotho Loti
"$SZL": "SZL", # Swazi Lilangeni
"$ZAR": "ZAR", # South African Rand
"$HKD": "HKD", # Hong Kong Dollar
"$SGD": "SGD", # Singapore Dollar
"$TWD": "TWD", # Taiwan Dollar
"$CHF": "CHF", # Swiss Franc
"$DKK": "DKK", # Danish Krone
"$NOK": "NOK", # Norwegian Krone
"$SEK": "SEK", # Swedish Krona
"$ARS": "ARS", # Argentine Peso
"$BOB": "BOB", # Bolivian Boliviano
"$CLP": "CLP", # Chilean Peso
"$COP": "COP", # Colombian Peso
"$MXN": "MXN", # Mexican Peso
"$PEN": "PEN", # Peruvian Sol
"$UYU": "UYU", # Uruguayan Peso
"$VES": "VES", # Venezuelan Bolívar Soberano
# Cryptocurrencies (for modern business plans)
"₿": "BTC", # Bitcoin
"Ξ": "ETH", # Ethereum
"Ł": "LTC", # Litecoin
# Special Drawing Rights
"XDR": "XDR", # Special Drawing Rights
# Precious Metals
"XAU": "XAU", # Gold (troy ounce)
"XAG": "XAG", # Silver (troy ounce)
"XPT": "XPT", # Platinum (troy ounce)
"XPD": "XPD", # Palladium (troy ounce)
# Other
"XTS": "XTS", # Testing Currency Code
"XXX": "XXX", # No Currency
# Missing currencies from canonical_currency_map.py
"ADP": "ADP", # Andorran Peseta
"AFA": "AFA", # Afghan Afghani (1927–2002)
"ALK": "ALK", # Albanian Lek (1946–1965)
"ANG": "ANG", # Netherlands Antillean Guilder
"AOK": "AOK", # Angolan Kwanza (1977–1991)
"AON": "AON", # Angolan New Kwanza (1990–2000)
"AOR": "AOR", # Angolan Readjusted Kwanza (1995–1999)
"ARA": "ARA", # Argentine Austral
"ARL": "ARL", # Argentine Peso Ley (1970–1983)
"ARM": "ARM", # Argentine Peso (1881–1970)
"ARP": "ARP", # Argentine Peso (1983–1985)
"ATS": "ATS", # Austrian Schilling
"AZM": "AZM", # Azerbaijani Manat (1993–2006)
"BAD": "BAD", # Bosnia-Herzegovina Dinar (1992–1994)
"BAN": "BAN", # Bosnia-Herzegovina New Dinar (1994–1997)
"BEC": "BEC", # Belgian Franc (convertible)
"BEF": "BEF", # Belgian Franc
"BEL": "BEL", # Belgian Franc (financial)
"BGL": "BGL", # Bulgarian Hard Lev
"BGM": "BGM", # Bulgarian Socialist Lev
"BGO": "BGO", # Bulgarian Lev (1879–1952)
"BOL": "BOL", # Bolivian Boliviano (1863–1963)
"BOP": "BOP", # Bolivian Peso
"BOV": "BOV", # Bolivian Mvdol
"BRB": "BRB", # Brazilian New Cruzeiro (1967–1986)
"BRC": "BRC", # Brazilian Cruzado (1986–1989)
"BRE": "BRE", # Brazilian Cruzeiro (1990–1993)
"BRN": "BRN", # Brazilian New Cruzado (1989–1990)
"BRR": "BRR", # Brazilian Cruzeiro (1993–1994)
"BRZ": "BRZ", # Brazilian Cruzeiro (1942–1967)
"BUK": "BUK", # Burmese Kyat
"BYB": "BYB", # Belarusian Ruble (1994–1999)
"BYN": "BYN", # Belarusian Ruble
"BYR": "BYR", # Belarusian Ruble (2000–2016)
"CA$": "CAD", # Canadian Dollar
"CHE": "CHE", # WIR Euro
"CHW": "CHW", # WIR Franc
"CLE": "CLE", # Chilean Escudo
"CLF": "CLF", # Chilean Unit of Account (UF)
"CNH": "CNH", # Chinese Yuan (offshore)
"CNX": "CNX", # Chinese People's Bank Dollar
"CN¥": "CNY", # Chinese Yuan
"COU": "COU", # Colombian Real Value Unit
"CSD": "CSD", # Serbian Dinar (2002–2006)
"CSK": "CSK", # Czechoslovak Hard Koruna
"CUC": "CUC", # Cuban Convertible Peso
"CUP": "CUP", # Cuban Peso
"CYP": "CYP", # Cypriot Pound
"DDM": "DDM", # East German Mark
"DEM": "DEM", # German Mark
"ECS": "ECS", # Ecuadorian Sucre
"ECV": "ECV", # Ecuadorian Unit of Constant Value
"ESA": "ESA", # Spanish Peseta (A account)
"ESB": "ESB", # Spanish Peseta (convertible account)
"ESP": "ESP", # Spanish Peseta
"FIM": "FIM", # Finnish Markka
"FKP": "FKP", # Falkland Islands Pound
"FRF": "FRF", # French Franc
"GEK": "GEK", # Georgian Kupon Larit
"GHC": "GHC", # Ghanaian Cedi (1979–2007)
"GIP": "GIP", # Gibraltar Pound
"GNS": "GNS", # Guinean Syli
"GQE": "GQE", # Equatorial Guinean Ekwele
"GRD": "GRD", # Greek Drachma
"GWE": "GWE", # Portuguese Guinea Escudo
"GWP": "GWP", # Guinea-Bissau Peso
"HRD": "HRD", # Croatian Dinar
"HRK": "HRK", # Croatian Kuna
"HTG": "HTG", # Haitian Gourde
"IEP": "IEP", # Irish Pound
"ILP": "ILP", # Israeli Pound
"ILR": "ILR", # Israeli Shekel (1980–1985)
"ISJ": "ISJ", # Icelandic Króna (1918–1981)
"ITL": "ITL", # Italian Lira
"KGS": "KGS", # Kyrgystani Som
"KPW": "KPW", # North Korean Won
"KRH": "KRH", # South Korean Hwan (1953–1962)
"KRO": "KRO", # South Korean Won (1945–1953)
"LTT": "LTT", # Lithuanian Talonas
"LUC": "LUC", # Luxembourgian Convertible Franc
"LUF": "LUF", # Luxembourgian Franc
"LUL": "LUL", # Luxembourg Financial Franc
"LVR": "LVR", # Latvian Ruble
"MAF": "MAF", # Moroccan Franc
"MCF": "MCF", # Monegasque Franc
"MDC": "MDC", # Moldovan Cupon
"MDL": "MDL", # Moldovan Leu
"MGF": "MGF", # Malagasy Franc
"MKN": "MKN", # Macedonian Denar (1992–1993)
"MLF": "MLF", # Malian Franc
"MNT": "MNT", # Mongolian Tugrik
"MTL": "MTL", # Maltese Lira
"MTP": "MTP", # Maltese Pound
"MUR": "MUR", # Mauritian Rupee
"MVP": "MVP", # Maldivian Rupee (1947–1981)
"MX$": "MXN", # Mexican Peso
"MXP": "MXP", # Mexican Silver Peso (1861–1992)
"MXV": "MXV", # Mexican Investment Unit
"MZE": "MZE", # Mozambican Escudo
"MZM": "MZM", # Mozambican Metical (1980–2006)
"NIC": "NIC", # Nicaraguan Córdoba (1988–1991)
"NIO": "NIO", # Nicaraguan Córdoba
"NLG": "NLG", # Dutch Guilder
"NZ$": "NZD", # New Zealand Dollar
"PAB": "PAB", # Panamanian Balboa
"PEI": "PEI", # Peruvian Inti
"PES": "PES", # Peruvian Sol (1863–1965)
"PLZ": "PLZ", # Polish Zloty (1950–1995)
"PTE": "PTE", # Portuguese Escudo
"RHD": "RHD", # Rhodesian Dollar
"ROL": "ROL", # Romanian Leu (1952–2006)
"RUR": "RUR", # Russian Ruble (1991–1998)
"SDD": "SDD", # Sudanese Dinar (1992–2007)
"SDP": "SDP", # Sudanese Pound (1957–1998)
"SIT": "SIT", # Slovenian Tolar
"SKK": "SKK", # Slovak Koruna
"SLE": "SLE", # Sierra Leonean Leone
"SRG": "SRG", # Surinamese Guilder
"STN": "STN", # São Tomé & Príncipe Dobra
"SUR": "SUR", # Soviet Rouble
"SVC": "SVC", # Salvadoran Colón
"SYP": "SYP", # Syrian Pound
"TJR": "TJR", # Tajikistani Ruble
"TJS": "TJS", # Tajikistani Somoni
"TMM": "TMM", # Turkmenistani Manat (1993–2009)
"TMT": "TMT", # Turkmenistani Manat
"TPE": "TPE", # Timorese Escudo
"TRL": "TRL", # Turkish Lira (1922–2005)
"UAK": "UAK", # Ukrainian Karbovanets
"UGS": "UGS", # Ugandan Shilling (1966–1987)
"USN": "USN", # US Dollar (Next day)
"USS": "USS", # US Dollar (Same day)
"UYI": "UYI", # Uruguayan Peso (Indexed Units)
"UYP": "UYP", # Uruguayan Peso (1975–1993)
"UYW": "UYW", # Uruguayan Nominal Wage Index Unit
"VEB": "VEB", # Venezuelan Bolívar (1871–2008)
"VED": "VED", # Bolívar Soberano
"VNN": "VNN", # Vietnamese Dong (1978–1985)
"XBA": "XBA", # European Composite Unit
"XBB": "XBB", # European Monetary Unit
"XBC": "XBC", # European Unit of Account (XBC)
"XBD": "XBD", # European Unit of Account (XBD)
"Cg.": "XCG", # Caribbean guilder
"XEU": "XEU", # European Currency Unit
"XFO": "XFO", # French Gold Franc
"XFU": "XFU", # French UIC-Franc
"F CFA": "XOF", # West African CFA Franc
"XRE": "XRE", # RINET Funds
"XSU": "XSU", # Sucre
"XUA": "XUA", # ADB Unit of Account
"¤": "XXX", # Unknown Currency
"YDD": "YDD", # Yemeni Dinar
"YUD": "YUD", # Yugoslavian Hard Dinar (1966–1990)
"YUM": "YUM", # Yugoslavian New Dinar (1994–2002)
"YUN": "YUN", # Yugoslavian Convertible Dinar (1990–1992)
"YUR": "YUR", # Yugoslavian Reformed Dinar (1992–1993)
"ZAL": "ZAL", # South African Rand (financial)
"ZMK": "ZMK", # Zambian Kwacha (1968–2012)
"ZRN": "ZRN", # Zairean New Zaire (1993–1998)
"ZRZ": "ZRZ", # Zairean Zaire (1971–1993)
"ZWD": "ZWD", # Zimbabwean Dollar (1980–2008)
"ZWG": "ZWG", # Zimbabwean Gold
"ZWR": "ZWR", # Zimbabwean Dollar (2008)
"US$": "USD", # US Dollar
"C$": "NIO", # Nicaraguan Córdoba
"TT$": "TTD", # Trinidad & Tobago Dollar
"BD$": "BBD", # Barbadian Dollar
"B$": "BND", # Brunei Dollar
"SI$": "SBD", # Solomon Islands Dollar
"G$": "GYD", # Guyanaese Dollar
"SR$": "SRD", # Surinamese Dollar
"CLP$": "CLP", # Chilean Peso
"Bs.": "VES", # Venezuelan Bolívar
"Rf": "MVR", # Maldivian Rufiyaa
"SSh": "SOS", # Somali Shilling
"GH₵": "GHS", # Ghanaian Cedi
"Br": "BYN", # Belarusian Ruble
"CFA F": "XOF", # West African CFA Franc
"CFAF": "XAF", # Central African CFA Franc
"JP¥": "JPY", # Japanese Yen
"元": "TWD", # New Taiwan Dollar
"TL": "TRY", # Turkish Lira
"лв.": "BGN", # Bulgarian Lev
"₮": "MNT", # Mongolian Tugrik
"﷼": "SAR", # Saudi Riyal
".د.ب": "BHD", # Bahraini Dinar
"ل.س": "SYP", # Syrian Pound
"﷼‎": "IRR", # Iranian Rial
"ש״ח": "ILS", # Israeli New Shekel
"Fr": "CHF", # Swiss Franc
"CFP": "XPF", # CFP Franc
"E": "SZL", # Swazi Lilangeni
"Rf.": "MVR", # Maldivian Rufiyaa
"QR": "QAR", # Qatari Riyal
"SR": "SAR", # Saudi Riyal
"BD": "BHD", # Bahraini Dinar
"KD": "KWD", # Kuwaiti Dinar
"₯": "GRD", # Greek Drachma
"ЅМ": "TJS", # Tajikistani Somoni
"Br (BYN)": "BYN", # Belarusian Ruble
"B/.": "PAB", # Panamanian Balboa
"Gs.": "PYG", # Paraguayan Guarani
"Afl.": "AWG", # Aruban Florin
"NAƒ": "ANG", # Netherlands Antillean Guilder
"lei (MDL)": "MDL", # Moldovan Leu
"KM (BAM)": "BAM", # Bosnia-Herzegovina Convertible Mark
"ден (MKD)": "MKD", # Macedonian Denar
"kn": "HRK", # Croatian Kuna
"Z$": "ZWL", # Zimbabwean Dollar (2009–2024)
"RTGS$": "ZWL", # Zimbabwean Dollar (2009–2024)
"Skr": "SEK", # Swedish Krona
"Nkr": "NOK", # Norwegian Krone
"Dkr": "DKK", # Danish Krone
"Íkr": "ISK", # Icelandic Króna
"AU$": "AUD", # Australian Dollar
"SG$": "SGD", # Singapore Dollar
"BB$": "BBD", # Barbadian Dollar
"BS$": "BSD", # Bahamian Dollar
"KY$": "KYD", # Cayman Islands Dollar
"BM$": "BMD", # Bermudan Dollar
"JM$": "JMD", # Jamaican Dollar
}
def convert_currency_symbols_to_iso(text: str) -> str:
"""
Convert currency symbols to ISO codes for PDF compatibility
Matches the TypeScript canonicalCurrencyMap logic
"""
import re # Import at function level to avoid scope issues
processed_text = text
# Track all conversions for detailed logging
conversions_made = []
total_conversions = 0
# Process each currency symbol in the canonical map
for symbol, iso_code in canonical_currency_map.items():
if symbol in processed_text:
# Check if it's a single character
is_single_character = len(symbol) == 1
is_unicode_currency = is_single_character and ord(symbol) > 127 # Non-ASCII
is_latin_single_letter = is_single_character and symbol.isalpha() and ord(symbol) < 128
# Handle multi-character symbols (like "Le", "KSh", etc.)
is_multi_char_symbol = len(symbol) > 1
# Skip plain Latin single letters (to avoid converting words like "A", "R", etc.)
# but DO convert single-character Unicode currency symbols like €, £, ¥, ؋, etc.
if not is_unicode_currency and is_latin_single_letter:
# Only convert if it's followed by a number (currency context)
# Pattern: R500, R 500, R500,000 etc.
pattern = rf'\b{re.escape(symbol)}\s*(\d{{1,3}}(?:,?\d{{3}})*(?:\.\d{{2}})?)\b'
matches = re.findall(pattern, processed_text)
if matches:
old_text = processed_text
processed_text = re.sub(pattern, rf'{iso_code} \1', processed_text)
if old_text != processed_text:
conversions_made.append(f"{symbol}{iso_code} (context: {matches})")
total_conversions += len(matches)
continue
# For multi-character symbols like "Ar", "Le", etc., be very careful
# Only convert if they appear as standalone words or in currency contexts
if is_multi_char_symbol and len(symbol) == 2 and symbol.isalpha():
# Only convert if it's a standalone word or followed by a number
# Pattern: \bAr\b or \bAr\s*\d or \bLe\b or \bLe\s*\d
standalone_pattern = rf'\b{re.escape(symbol)}\b'
currency_pattern = rf'\b{re.escape(symbol)}\s*(\d{{1,3}}(?:,?\d{{3}})*(?:\.\d{{2}})?)'
# Check for standalone occurrences first
standalone_matches = re.findall(standalone_pattern, processed_text)
currency_matches = re.findall(currency_pattern, processed_text)
if standalone_matches or currency_matches:
old_text = processed_text
# Replace standalone occurrences
processed_text = re.sub(standalone_pattern, iso_code, processed_text)
# Replace currency context occurrences
processed_text = re.sub(currency_pattern, rf'{iso_code} \1', processed_text)
if old_text != processed_text:
conversions_made.append(f"{symbol}{iso_code} (standalone/currency context)")
total_conversions += len(standalone_matches) + len(currency_matches)
continue
# For all other symbols (Unicode currency symbols, multi-character symbols)
# Count occurrences before replacement
old_count = processed_text.count(symbol)
# Replace all occurrences
old_text = processed_text
processed_text = processed_text.replace(symbol, iso_code)
# Check if replacement actually happened
if old_text != processed_text:
conversions_made.append(f"{symbol}{iso_code} ({old_count} instances)")
total_conversions += old_count
return processed_text