From 07ca1cd9e1aa3b72b84cd5894cd8969ce9ca20be Mon Sep 17 00:00:00 2001 From: Jan Novak Date: Thu, 7 May 2026 23:59:35 +0200 Subject: [PATCH 1/3] fix(py): coerce VS column to string in payments tx projection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Sheets API returns VS (variabilní symbol) cells as float64 when the column is number-formatted, so Python was emitting vs: 0 (a JSON number) while Go's getVal uses fmt.Sprint and always emits vs: "0" (a string). Add get_str helper that converts whole-number floats via int() first (matching Go's %g formatting), applied to the vs field. Co-Authored-By: Claude Sonnet 4.6 --- scripts/match_payments.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/match_payments.py b/scripts/match_payments.py index 76beace..b82e28e 100644 --- a/scripts/match_payments.py +++ b/scripts/match_payments.py @@ -249,6 +249,12 @@ def fetch_sheet_data(spreadsheet_id: str, credentials_path: str) -> list[dict]: def get_val(idx): return row[idx] if idx != -1 and idx < len(row) else "" + def get_str(idx): + v = get_val(idx) + if isinstance(v, float) and v.is_integer(): + return str(int(v)) + return str(v) + tx = { "date": format_date(get_val(idx_date)), "amount": get_val(idx_amount), @@ -257,7 +263,7 @@ def fetch_sheet_data(spreadsheet_id: str, credentials_path: str) -> list[dict]: "purpose": get_val(idx_purpose), "inferred_amount": get_val(idx_inferred_amount), "sender": get_val(idx_sender), - "vs": get_val(idx_vs), + "vs": get_str(idx_vs), "message": get_val(idx_message), "bank_id": get_val(idx_bank_id), "sync_id": get_val(idx_sync_id), -- 2.49.1 From b68d95d217186018e32aaa798c59233cd05df320 Mon Sep 17 00:00:00 2001 From: Jan Novak Date: Fri, 8 May 2026 00:26:04 +0200 Subject: [PATCH 2/3] fix(py): coerce amount to float and message to string in tx projection Two remaining make parity diffs vs Go: - amount: non-numeric sheet values like "---" passed through as strings; Go's parseFloat silently returns 0.0 for unparseable values. Add get_float helper that matches that behaviour. - message: numeric cell values (e.g. a bank reference in the message column) passed through as float64; Go's getVal uses fmt.Sprint and always emits a string. Apply get_str to the message field. Co-Authored-By: Claude Sonnet 4.6 --- scripts/match_payments.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/match_payments.py b/scripts/match_payments.py index b82e28e..96f9f63 100644 --- a/scripts/match_payments.py +++ b/scripts/match_payments.py @@ -255,16 +255,25 @@ def fetch_sheet_data(spreadsheet_id: str, credentials_path: str) -> list[dict]: return str(int(v)) return str(v) + def get_float(idx): + v = get_val(idx) + if isinstance(v, (int, float)): + return float(v) + try: + return float(str(v).strip()) + except (ValueError, TypeError): + return 0.0 + tx = { "date": format_date(get_val(idx_date)), - "amount": get_val(idx_amount), + "amount": get_float(idx_amount), "manual_fix": get_val(idx_manual), "person": get_val(idx_person), "purpose": get_val(idx_purpose), "inferred_amount": get_val(idx_inferred_amount), "sender": get_val(idx_sender), "vs": get_str(idx_vs), - "message": get_val(idx_message), + "message": get_str(idx_message), "bank_id": get_val(idx_bank_id), "sync_id": get_val(idx_sync_id), } -- 2.49.1 From 58973473c9b02611ee7bb4e0c6d7a8018909dd0a Mon Sep 17 00:00:00 2001 From: Jan Novak Date: Fri, 8 May 2026 00:26:04 +0200 Subject: [PATCH 3/3] fix(py): make junior '?' cell text sticky across exception overrides Go's build_juniors sets cellText = "?" + countStr whenever md.IsUnknown is true, regardless of whether an exception overrides the expected amount. Python was checking expected == "?" for this branch, but reconcile replaces expected with the exception amount (e.g. 0) before the view builder runs, so the "?" was silently dropped to "-". Fix: derive is_unknown from original_expected == "?" (set before exception substitution) instead of expected == "?". Also align the tooltip guard: Go only shows Received/Expected tooltip for non-unknown months (or when paid > 0), matching the same is_unknown flag. Co-Authored-By: Claude Sonnet 4.6 --- scripts/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/views.py b/scripts/views.py index 05e5055..c63f67e 100644 --- a/scripts/views.py +++ b/scripts/views.py @@ -310,8 +310,9 @@ def build_juniors_view_model( cell_text = "-" amount_to_pay = 0 - if expected == "?" or (isinstance(expected, int) and expected > 0): - if expected == "?": + is_unknown = original_expected == "?" + if is_unknown or (isinstance(expected, int) and expected > 0): + if is_unknown: status = "empty" cell_text = f"?{count_str}" elif paid >= expected: @@ -339,7 +340,7 @@ def build_juniors_view_model( status = "surplus" cell_text = f"PAID {paid}" - if (isinstance(expected, int) and expected > 0) or paid > 0: + if (not is_unknown and isinstance(expected, int) and expected > 0) or paid > 0: tooltip = f"Received: {paid}, Expected: {expected}" else: tooltip = "" -- 2.49.1