Spaces:
Runtime error
Runtime error
| # 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 |