Merge pull request #48734 from frappe/mergify/bp/version-15-hotfix/pr-48720

fix: valuation for rejected materials (backport #48720)
This commit is contained in:
rohitwaghchaure
2025-07-23 08:45:35 +05:30
committed by GitHub
3 changed files with 82 additions and 11 deletions

View File

@@ -310,9 +310,12 @@ class BuyingController(SubcontractingController):
stock_and_asset_items_qty, stock_and_asset_items_amount = 0, 0
last_item_idx = 1
total_rejected_qty = 0
for d in self.get("items"):
if d.item_code and d.item_code in stock_and_asset_items:
stock_and_asset_items_qty += flt(d.qty)
total_rejected_qty += flt(d.get("rejected_qty", 0))
stock_and_asset_items_amount += flt(d.base_net_amount)
last_item_idx = d.idx
@@ -324,12 +327,19 @@ class BuyingController(SubcontractingController):
valuation_amount_adjustment = total_valuation_amount
for i, item in enumerate(self.get("items")):
if item.item_code and item.qty and item.item_code in stock_and_asset_items:
item_proportion = (
flt(item.base_net_amount) / stock_and_asset_items_amount
if stock_and_asset_items_amount
else flt(item.qty) / stock_and_asset_items_qty
)
if (
item.item_code
and (item.qty or item.get("rejected_qty"))
and item.item_code in stock_and_asset_items
):
if stock_and_asset_items_qty:
item_proportion = (
flt(item.base_net_amount) / stock_and_asset_items_amount
if stock_and_asset_items_amount
else flt(item.qty) / stock_and_asset_items_qty
)
elif total_rejected_qty:
item_proportion = flt(item.get("rejected_qty")) / flt(total_rejected_qty)
if i == (last_item_idx - 1):
item.item_tax_amount = flt(
@@ -351,7 +361,19 @@ class BuyingController(SubcontractingController):
if item.sales_incoming_rate: # for internal transfer
net_rate = item.qty * item.sales_incoming_rate
if (
not net_rate
and item.get("rejected_qty")
and frappe.get_single_value(
"Buying Settings", "set_valuation_rate_for_rejected_materials"
)
):
net_rate = item.rejected_qty * item.net_rate
qty_in_stock_uom = flt(item.qty * item.conversion_factor)
if not qty_in_stock_uom and item.get("rejected_qty"):
qty_in_stock_uom = flt(item.rejected_qty * item.conversion_factor)
if self.get("is_old_subcontracting_flow"):
item.rm_supp_cost = self.get_supplied_items_cost(item.name, reset_outgoing_rate)
item.valuation_rate = (

View File

@@ -668,6 +668,10 @@ class PurchaseReceipt(BuyingController):
warehouse_with_no_account = []
for d in self.get("items"):
remarks = self.get("remarks") or _("Accounting Entry for {0}").format(
"Asset" if d.is_fixed_asset else "Stock"
)
if (
provisional_accounting_for_non_stock_items
and d.item_code not in stock_items
@@ -679,10 +683,6 @@ class PurchaseReceipt(BuyingController):
d, gl_entries, self.posting_date, d.get("provisional_expense_account")
)
elif flt(d.qty) and (flt(d.valuation_rate) or self.is_return):
remarks = self.get("remarks") or _("Accounting Entry for {0}").format(
"Asset" if d.is_fixed_asset else "Stock"
)
if not (
(erpnext.is_perpetual_inventory_enabled(self.company) and d.item_code in stock_items)
or (d.is_fixed_asset and not d.purchase_invoice)
@@ -737,7 +737,7 @@ class PurchaseReceipt(BuyingController):
make_amount_difference_entry(d)
make_sub_contracting_gl_entries(d)
make_divisional_loss_gl_entry(d, outgoing_amount)
elif (d.warehouse and d.warehouse not in warehouse_with_no_account) or (
elif (d.warehouse and d.qty and d.warehouse not in warehouse_with_no_account) or (
not frappe.db.get_single_value("Buying Settings", "set_valuation_rate_for_rejected_materials")
and d.rejected_warehouse
and d.rejected_warehouse not in warehouse_with_no_account
@@ -750,10 +750,18 @@ class PurchaseReceipt(BuyingController):
if d.rejected_qty and frappe.db.get_single_value(
"Buying Settings", "set_valuation_rate_for_rejected_materials"
):
stock_asset_rbnb = (
self.get_company_default("asset_received_but_not_billed")
if d.is_fixed_asset
else self.get_company_default("stock_received_but_not_billed")
)
stock_value_diff = get_stock_value_difference(self.name, d.name, d.rejected_warehouse)
stock_asset_account_name = warehouse_account[d.rejected_warehouse]["account"]
make_item_asset_inward_gl_entry(d, stock_value_diff, stock_asset_account_name)
if not d.qty:
make_stock_received_but_not_billed_entry(d)
if warehouse_with_no_account:
frappe.msgprint(

View File

@@ -4261,6 +4261,47 @@ class TestPurchaseReceipt(FrappeTestCase):
frappe.db.set_single_value("Buying Settings", "set_valuation_rate_for_rejected_materials", 0)
def test_valuation_rate_for_rejected_materials_withoout_accepted_materials(self):
item = make_item("Test Item with Rej Material Valuation WO Accepted", {"is_stock_item": 1})
company = "_Test Company with perpetual inventory"
warehouse = create_warehouse(
"_Test In-ward Warehouse",
company="_Test Company with perpetual inventory",
)
rej_warehouse = create_warehouse(
"_Test Warehouse - Rejected Material",
company="_Test Company with perpetual inventory",
)
frappe.db.set_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice", 1)
frappe.db.set_single_value("Buying Settings", "set_valuation_rate_for_rejected_materials", 1)
pr = make_purchase_receipt(
item_code=item.name,
qty=0,
rate=100,
company=company,
warehouse=warehouse,
rejected_qty=5,
rejected_warehouse=rej_warehouse,
)
gl_entry = frappe.get_all(
"GL Entry", filters={"debit": (">", 0), "voucher_no": pr.name}, pluck="name"
)
stock_value_diff = frappe.db.get_value(
"Stock Ledger Entry",
{"warehouse": rej_warehouse, "voucher_no": pr.name},
"stock_value_difference",
)
self.assertTrue(gl_entry)
self.assertEqual(stock_value_diff, 500.00)
def test_no_valuation_rate_for_rejected_materials(self):
item = make_item("Test Item with Rej Material No Valuation", {"is_stock_item": 1})
company = "_Test Company with perpetual inventory"