fix: check if Moving average item can use batchwise valuation
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 96751d6..b5e56ad 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -6,6 +6,7 @@
from frappe import _
from frappe.model.document import Document
from frappe.model.naming import make_autoname, revert_series_if_last
+from frappe.query_builder.functions import Sum
from frappe.utils import cint, flt, get_link_to_form
from frappe.utils.data import add_days
from frappe.utils.jinja import render_template
@@ -110,11 +111,15 @@
def validate(self):
self.item_has_batch_enabled()
+ self.set_batchwise_valuation()
def item_has_batch_enabled(self):
if frappe.db.get_value("Item", self.item, "has_batch_no") == 0:
frappe.throw(_("The selected item cannot have Batch"))
+ def set_batchwise_valuation(self):
+ self.use_batchwise_valuation = int(can_use_batchwise_valuation(self.item))
+
def before_save(self):
has_expiry_date, shelf_life_in_days = frappe.db.get_value('Item', self.item, ['has_expiry_date', 'shelf_life_in_days'])
if not self.expiry_date and has_expiry_date and shelf_life_in_days:
@@ -338,3 +343,30 @@
flt_reserved_batch_qty = flt(reserved_batch_qty[0][0])
return flt_reserved_batch_qty
+
+def can_use_batchwise_valuation(item_code: str) -> bool:
+ """ Check if item can use batchwise valuation.
+
+ Note: Item with existing moving average batches can't use batchwise valuation
+ until they are exhausted.
+ """
+ from erpnext.stock.stock_ledger import get_valuation_method
+ batch = frappe.qb.DocType("Batch")
+
+ if get_valuation_method(item_code) != "Moving Average":
+ return True
+
+ batch_qty = (
+ frappe.qb
+ .from_(batch)
+ .select(Sum(batch.batch_qty))
+ .where(
+ (batch.use_batchwise_valuation == 0)
+ & (batch.item == item_code)
+ )
+ ).run()
+
+ if batch_qty and batch_qty[0][0]:
+ return False
+
+ return True
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index e2bd2f1..f85a04f 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -261,7 +261,7 @@
"""get valuation method from item or default"""
val_method = frappe.db.get_value('Item', item_code, 'valuation_method', cache=True)
if not val_method:
- val_method = frappe.db.get_value("Stock Settings", None, "valuation_method") or "FIFO"
+ val_method = frappe.db.get_value("Stock Settings", None, "valuation_method", cache=True) or "FIFO"
return val_method
def get_fifo_rate(previous_stock_queue, qty):