Merge pull request #57820 from aerele/fix-asset-capitalization-grouped-row-valuation

fix(assets): split fifo/lifo rate across grouped stock item rows
This commit is contained in:
Khushi Rawat
2026-08-12 14:34:12 +05:30
committed by GitHub
2 changed files with 55 additions and 0 deletions

View File

@@ -152,6 +152,8 @@ class AssetCapitalization(StockController):
if d.meta.has_field(k) and (not d.get(k) or k in force_fields):
d.set(k, v)
self.split_valuation_rate_for_grouped_stock_items()
for d in self.asset_items:
args = self.as_dict()
args.update(d.as_dict())
@@ -173,6 +175,30 @@ class AssetCapitalization(StockController):
if d.meta.has_field(k) and (not d.get(k) or k in force_fields):
d.set(k, v)
def split_valuation_rate_for_grouped_stock_items(self):
groups = {}
for d in self.stock_items:
if d.item_code and d.warehouse and not (d.serial_no or d.batch_no or d.serial_and_batch_bundle):
groups.setdefault((d.item_code, d.warehouse), []).append(d)
for rows in groups.values():
if len(rows) < 2:
continue
cumulative_qty = 0.0
prev_cumulative_value = 0.0
for d in rows:
cumulative_qty += flt(d.stock_qty)
args = self.get_args_for_incoming_rate(d)
args["qty"] = -1 * cumulative_qty
cumulative_rate = flt(get_incoming_rate(args, raise_error_if_no_rate=False))
cumulative_value = cumulative_rate * cumulative_qty
row_value = cumulative_value - prev_cumulative_value
d.valuation_rate = flt(row_value / d.stock_qty) if flt(d.stock_qty) else 0.0
d.amount = flt(flt(d.stock_qty) * d.valuation_rate, d.precision("amount"))
prev_cumulative_value = cumulative_value
def validate_target_item(self):
target_item = frappe.get_cached_doc("Item", self.target_item_code)
@@ -306,6 +332,8 @@ class AssetCapitalization(StockController):
warehouse_details = get_warehouse_details(args)
d.update(warehouse_details)
self.split_valuation_rate_for_grouped_stock_items()
@frappe.whitelist()
def set_asset_values(self):
for d in self.get("asset_items"):

View File

@@ -397,6 +397,33 @@ class TestAssetCapitalization(ERPNextTestSuite):
actual_gle = get_actual_gle_dict(asset_capitalization.name)
self.assertEqual(actual_gle, {})
def test_grouped_stock_item_rows_split_fifo_rate(self):
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
company = "_Test Company"
warehouse = create_warehouse("_Test Warehouse for Grouped FIFO Rows", company=company)
item = create_item(
"_Test Grouped FIFO Rows Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=1
)
target_item = create_fixed_asset_item("_Test Grouped FIFO Rows Target Item")
make_purchase_receipt(item_code=item.item_code, qty=1, rate=100, company=company, warehouse=warehouse)
make_purchase_receipt(item_code=item.item_code, qty=1, rate=200, company=company, warehouse=warehouse)
asset_capitalization = frappe.new_doc("Asset Capitalization")
asset_capitalization.company = company
asset_capitalization.target_item_code = target_item.name
asset_capitalization.append(
"stock_items", {"item_code": item.item_code, "warehouse": warehouse, "stock_qty": 1}
)
asset_capitalization.append(
"stock_items", {"item_code": item.item_code, "warehouse": warehouse, "stock_qty": 1}
)
asset_capitalization.insert()
rates = [d.valuation_rate for d in asset_capitalization.stock_items]
self.assertEqual(rates, [100, 200])
def create_asset_capitalization_data():
create_item("Capitalization Target Stock Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=0)