From affd2fd95d11444042b7a8cb0f1b91ce1e9d13f0 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 23 Jun 2026 17:49:26 +0530 Subject: [PATCH] fix(manufacturing): guard average bin valuation-rate division against a zero divisor (Postgres) _get_avg_valuation_rate_from_bins divides Sum(stock_value) by Sum(actual_qty). The `Count(name) > 0` guard only proves a Bin row exists; Sum(actual_qty) can still be 0 (stock depleted, or per-warehouse quantities cancelling out), and the outer IfNull catches only NULL, not a 0 divisor. MariaDB returns NULL for x/0 (then IfNull -> 0.0); PostgreSQL raises `division by zero` and aborts BOM costing. Wrapping the divisor in NullIf(Sum(actual_qty), 0) keeps the identical 0.0 result on MariaDB and avoids the error on PostgreSQL. --- erpnext/manufacturing/doctype/bom/bom.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 90d898f4751..061fbbf43e7 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -9,7 +9,7 @@ import frappe from frappe import _, bold from frappe.model.document import Document from frappe.query_builder import Field -from frappe.query_builder.functions import Count, IfNull, Max, Min, Sum +from frappe.query_builder.functions import Count, IfNull, Max, Min, NullIf, Sum from frappe.utils import cint, cstr, flt, get_link_to_form, parse_json from frappe.website.website_generator import WebsiteGenerator @@ -1124,7 +1124,8 @@ def _get_avg_valuation_rate_from_bins(item_code, company, data): .select( Case() .when( - Count(bin_table.name) > 0, IfNull(Sum(bin_table.stock_value) / Sum(bin_table.actual_qty), 0.0) + Count(bin_table.name) > 0, + IfNull(Sum(bin_table.stock_value) / NullIf(Sum(bin_table.actual_qty), 0), 0.0), ) .else_(None) .as_("valuation_rate")