Spreadsheet import: \"45,000 - 55k\" becomes 55,000 to 45 million, and \"R$\" is read as US dollars #471
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#471
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, reading the salary parsing in the CSV importer and running its functions.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atcore/csv_import.py:749-750(parse_salary_range),:622-638(CURRENCY_SYMBOLS, with"$"on line 624 and"R$"on line 633) and:715-717(parse_currency).The salary parsing that #224 repaired still gets two common forms wrong. When the low figure is written in full and the high figure has a
k, the low one is multiplied by a thousand anyway, so the range is stored a thousandfold wrong. And a Brazilian real amount written with its symbol is stored as US dollars, although the symbol table mapsR$to BRL on purpose. Related to #224 (closed), whose fix is incomplete here.core/csv_import.py:754-755inparse_salary_range;core/csv_import.py:618-634(CURRENCY_SYMBOLS) and:720-722inparse_currency.parse_salary_rangescales the low figure whenever the high side carries ak, the low side does not, andlow < high. That test is true for"45,000 - 55k"(45,000 is less than 55,000), so the low figure becomes 45,000,000 and the swap stores(55000, 45000000). The same happens to"50000-60k"→(60000, 50000000),"€40,000 to 50k"→(50000, 40000000)and"900 - 1.2k"→(1200, 900000).parse_currencywalksCURRENCY_SYMBOLSin insertion order and testssymbol in raw."$"(line 620) comes before"R$"(line 629), so"R$ 5000"and"R$8.000"both returnUSD.plugins/builtin/patterns.py:103-115, which reads salaries from captured pages, already listsR$and leaves out the bare$; the importer's table has drifted from it.kacross only when the scaled low figure stays at or below the high one (low * 1000 <= high), so a low figure already written in full is left alone. Inparse_currency, try symbols longest first (sorted(CURRENCY_SYMBOLS.items(), key=lambda item: -len(item[0]))), soR$is matched before$.Done when
tests/test_counting.pyassertsparse_salary_range("45,000 - 55k") == (45000, 55000),parse_salary_range("900 - 1.2k") == (900, 1200)and, as today,parse_salary_range("50-60k") == (50000, 60000).tests/test_counting.py::test_the_currency_is_read_from_the_cellgains("R$ 8.000", "BRL").