Merge pull request #56247 from nabinhait/commission-rate-data-to-percent

fix(selling): make commission_rate a Percent field on Sales Person and Sales Team
This commit is contained in:
Nabin Hait
2026-06-22 15:56:30 +05:30
committed by GitHub
4 changed files with 54 additions and 6 deletions

View File

@@ -261,6 +261,7 @@ erpnext.patches.v14_0.update_proprietorship_to_individual
erpnext.patches.v15_0.rename_subcontracting_fields
erpnext.patches.v15_0.unset_incorrect_additional_discount_percentage
erpnext.patches.v16_0.create_company_custom_fields
erpnext.patches.v16_0.convert_commission_rate_to_percent
[post_model_sync]
erpnext.patches.v15_0.rename_gross_purchase_amount_to_net_purchase_amount

View File

@@ -0,0 +1,47 @@
import frappe
from frappe.utils import flt
def execute():
"""Sanitize the free-text commission_rate values before the Data -> Percent column change.
Sales Person and Sales Team stored ``commission_rate`` as Data (varchar). This runs in
pre_model_sync so the values are clean numbers by the time the schema sync alters the column
to Percent: a trailing percent sign (e.g. "20%" / "20 %") is stripped, and empty / NULL /
non-numeric values become 0.
"""
for doctype in ("Sales Person", "Sales Team"):
if not frappe.db.has_column(doctype, "commission_rate"):
continue
# 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))
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):
"""Drop a trailing percent sign so "20%" / "20 %" parse as 20 instead of 0."""
if isinstance(value, str):
return value.replace("%", "").strip()
return value

View File

@@ -68,7 +68,7 @@
"fetch_from": "sales_person.commission_rate",
"fetch_if_empty": 1,
"fieldname": "commission_rate",
"fieldtype": "Data",
"fieldtype": "Percent",
"in_list_view": 1,
"label": "Commission Rate",
"read_only": 1
@@ -87,7 +87,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:38.504580",
"modified": "2026-06-21 12:52:33.742603",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Team",
@@ -98,4 +98,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -54,7 +54,7 @@
},
{
"fieldname": "commission_rate",
"fieldtype": "Data",
"fieldtype": "Percent",
"label": "Commission Rate",
"print_hide": 1
},
@@ -145,7 +145,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2024-03-27 13:10:37.891377",
"modified": "2026-06-21 12:52:33.742603",
"modified_by": "Administrator",
"module": "Setup",
"name": "Sales Person",
@@ -184,4 +184,4 @@
"sort_field": "creation",
"sort_order": "ASC",
"states": []
}
}