From 943c6d210a3afc82004213a0129180d6949244dc Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 22 Jun 2026 13:14:57 +0530 Subject: [PATCH] fix: only rewrite commission_rate rows the column change can't cast The previous string comparison (str(raw) != str(cleaned)) rewrote every whole-number row ('20' vs '20.0'), turning a targeted cleanup into a full-table rewrite on Sales Team. Skip rows already holding a plain numeric string and only fix NULL / empty / non-numeric / percent-sign values. --- .../convert_commission_rate_to_percent.py | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/erpnext/patches/v16_0/convert_commission_rate_to_percent.py b/erpnext/patches/v16_0/convert_commission_rate_to_percent.py index e9d49d9e8bc..39609c3f8ec 100644 --- a/erpnext/patches/v16_0/convert_commission_rate_to_percent.py +++ b/erpnext/patches/v16_0/convert_commission_rate_to_percent.py @@ -14,13 +14,30 @@ def execute(): if not frappe.db.has_column(doctype, "commission_rate"): continue - # Percent maps to a NOT NULL decimal column, so empty/NULL/non-numeric text must become 0 - # as well, otherwise the column type change fails under strict SQL mode. + # Only rewrite the rows the column change can't cast as-is. Plain numeric strings (the vast + # majority, e.g. "20") are left untouched so this stays a targeted cleanup instead of a + # full-table rewrite; NULL / empty / non-numeric / percent-sign values become a clean number, + # otherwise the Data -> Percent change fails under strict SQL mode (Percent is NOT NULL decimal). rows = frappe.db.get_all(doctype, fields=["name", "commission_rate"]) for row in rows: + if _is_plain_number(row.commission_rate): + continue cleaned = flt(_strip_percent_sign(row.commission_rate)) - if str(row.commission_rate) != str(cleaned): - frappe.db.set_value(doctype, row.name, "commission_rate", cleaned, update_modified=False) + frappe.db.set_value(doctype, row.name, "commission_rate", cleaned, update_modified=False) + + +def _is_plain_number(value) -> bool: + """True if the stored value is already a clean numeric string the column change can cast.""" + if value is None: + return False + text = str(value) + if text != text.strip() or "%" in text: + return False + try: + float(text) + except ValueError: + return False + return True def _strip_percent_sign(value):