diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index a5d5b5b3be1..d9ddf9290c5 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -605,7 +605,10 @@ def calculate_exchange_rate_using_last_gle(company, account, party_type, party): last_exchange_rate = ( qb.from_(gl) - .select((gl.debit - gl.credit) / (gl.debit_in_account_currency - gl.credit_in_account_currency)) + .select( + (gl.debit - gl.credit) + / NullIf(gl.debit_in_account_currency - gl.credit_in_account_currency, 0) + ) .where( (gl.voucher_type == voucher_type) & (gl.voucher_no == voucher_no) & (gl.account == account) ) 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") diff --git a/erpnext/selling/report/lost_quotations/lost_quotations.py b/erpnext/selling/report/lost_quotations/lost_quotations.py index c3bcd54cfd3..799dbec5878 100644 --- a/erpnext/selling/report/lost_quotations/lost_quotations.py +++ b/erpnext/selling/report/lost_quotations/lost_quotations.py @@ -6,7 +6,7 @@ from typing import Literal import frappe from frappe import _ from frappe.model.docstatus import DocStatus -from frappe.query_builder.functions import Coalesce, Count, Round, Sum +from frappe.query_builder.functions import Coalesce, Count, NullIf, Round, Sum from frappe.utils.data import get_timespan_date_range @@ -86,7 +86,7 @@ def get_data(company: str, from_date: str, to_date: str, group_by: Literal["Lost # `* 100.0` before dividing: count/count is integer division on Postgres (truncates to 0) Round((Count(q.name).distinct() * 100.0 / total_quotations), 2), Sum(q.base_net_total), - Round((Sum(q.base_net_total) / total_value * 100), 2), + Round((Sum(q.base_net_total) / NullIf(total_value, 0) * 100), 2), ) .left_join(dimension) .on(dimension.parent == q.name) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index a99c536dd5b..fbb9a38150c 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -383,7 +383,7 @@ class PurchaseReceipt(BuyingController): self.update_received_qty_if_from_pp() def update_received_qty_if_from_pp(self): - from frappe.query_builder.functions import Coalesce, Sum + from frappe.query_builder.functions import Coalesce, NullIf, Sum items_from_po = [item.purchase_order_item for item in self.items if item.purchase_order_item] if items_from_po: @@ -404,7 +404,9 @@ class PurchaseReceipt(BuyingController): frappe.qb.from_(table) .select( table.production_plan_sub_assembly_item, - Sum(table.received_qty / (table.qty / table.fg_item_qty)).as_("received_qty"), + Sum(table.received_qty / NullIf(table.qty / NullIf(table.fg_item_qty, 0), 0)).as_( + "received_qty" + ), ) .where(table.production_plan_sub_assembly_item.isin(result)) .groupby(table.production_plan_sub_assembly_item) diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 1025bbf5355..b11868347ea 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -11,7 +11,7 @@ from frappe.model import child_table_fields, default_fields from frappe.model.document import Document from frappe.model.meta import get_field_precision from frappe.model.utils import get_fetch_values -from frappe.query_builder.functions import IfNull, Sum +from frappe.query_builder.functions import IfNull, NullIf, Sum from frappe.utils import add_days, add_months, cint, cstr, flt, get_link_to_form, getdate, parse_json import erpnext @@ -1734,7 +1734,7 @@ def get_valuation_rate(item_code: str, company: str, warehouse: str | None = Non pi_item = frappe.qb.DocType("Purchase Invoice Item") valuation_rate = ( frappe.qb.from_(pi_item) - .select(Sum(pi_item.base_net_amount) / Sum(pi_item.qty * pi_item.conversion_factor)) + .select(Sum(pi_item.base_net_amount) / NullIf(Sum(pi_item.qty * pi_item.conversion_factor), 0)) .where((pi_item.docstatus == 1) & (pi_item.item_code == item_code)) ).run() diff --git a/erpnext/stock/report/incorrect_serial_no_valuation/incorrect_serial_no_valuation.py b/erpnext/stock/report/incorrect_serial_no_valuation/incorrect_serial_no_valuation.py index 101b6a21461..c7a256c7c57 100644 --- a/erpnext/stock/report/incorrect_serial_no_valuation/incorrect_serial_no_valuation.py +++ b/erpnext/stock/report/incorrect_serial_no_valuation/incorrect_serial_no_valuation.py @@ -115,7 +115,7 @@ def get_stock_ledger_entries(report_filters): "posting_time", "company", "warehouse", - {"DIV": ["stock_value_difference", "actual_qty"], "as": "valuation_rate"}, + {"DIV": ["stock_value_difference", {"NULLIF": ["actual_qty", 0]}], "as": "valuation_rate"}, ] filters = {"is_cancelled": 0}