mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-19 06:45:11 +00:00
fix: auto batch not set for raw materials in subcontracting receipt
(cherry picked from commit 23f9d4c600)
# Conflicts:
# erpnext/controllers/subcontracting_controller.py
This commit is contained in:
committed by
Mergify
parent
b18afa8bdd
commit
6c8e8384d5
@@ -12,6 +12,12 @@ from frappe.utils import cint, flt, get_link_to_form
|
||||
|
||||
from erpnext.controllers.stock_controller import StockController
|
||||
from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import (
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
combine_datetime,
|
||||
get_auto_batch_nos,
|
||||
get_available_serial_nos,
|
||||
>>>>>>> 23f9d4c600 (fix: auto batch not set for raw materials in subcontracting receipt)
|
||||
get_voucher_wise_serial_batch_from_bundle,
|
||||
)
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
@@ -52,9 +58,42 @@ class SubcontractingController(StockController):
|
||||
if self.doctype in ["Subcontracting Order", "Subcontracting Receipt"]:
|
||||
self.validate_items()
|
||||
self.create_raw_materials_supplied()
|
||||
self.set_valuation_rate_for_rm()
|
||||
else:
|
||||
super().validate()
|
||||
|
||||
def set_valuation_rate_for_rm(self):
|
||||
rate_changed = False
|
||||
if self.doctype == "Subcontracting Receipt":
|
||||
for row in self.supplied_items:
|
||||
kwargs = frappe._dict(
|
||||
{
|
||||
"item_code": row.rm_item_code,
|
||||
"warehouse": self.supplier_warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time,
|
||||
"qty": flt(row.consumed_qty) * (-1 if not self.is_return else 1),
|
||||
"voucher_type": self.doctype,
|
||||
"voucher_no": self.name,
|
||||
"company": self.company,
|
||||
"serial_and_batch_bundle": row.serial_and_batch_bundle,
|
||||
"voucher_detail_no": row.name,
|
||||
"batch_no": row.batch_no,
|
||||
"serial_no": row.serial_no,
|
||||
"use_serial_batch_fields": row.use_serial_batch_fields,
|
||||
}
|
||||
)
|
||||
|
||||
rate = get_incoming_rate(kwargs)
|
||||
precision = frappe.get_precision("Subcontracting Receipt Supplied Item", "rate")
|
||||
if flt(rate, precision) != flt(row.rate, precision):
|
||||
row.rate = rate
|
||||
row.amount = flt(row.consumed_qty) * flt(rate)
|
||||
rate_changed = True
|
||||
|
||||
if rate_changed:
|
||||
self.calculate_items_qty_and_amount()
|
||||
|
||||
def validate_rejected_warehouse(self):
|
||||
for item in self.get("items"):
|
||||
if flt(item.rejected_qty) and not item.rejected_warehouse:
|
||||
@@ -610,6 +649,64 @@ class SubcontractingController(StockController):
|
||||
self.set_rate_for_supplied_items(rm_obj, item_row)
|
||||
elif self.backflush_based_on == "BOM":
|
||||
self.update_rate_for_supplied_items()
|
||||
self.set_batch_for_supplied_items()
|
||||
|
||||
def set_batch_for_supplied_items(self):
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos_for_outward
|
||||
from erpnext.stock.get_item_details import get_filtered_serial_nos
|
||||
|
||||
for row in self.supplied_items:
|
||||
item_details = frappe.get_cached_value(
|
||||
"Item", row.rm_item_code, ["has_batch_no", "has_serial_no"], as_dict=1
|
||||
)
|
||||
|
||||
if not item_details.has_batch_no and not item_details.has_serial_no:
|
||||
continue
|
||||
|
||||
if not row.use_serial_batch_fields:
|
||||
continue
|
||||
|
||||
kwargs = frappe._dict(
|
||||
{
|
||||
"item_code": row.rm_item_code,
|
||||
"warehouse": self.supplier_warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time,
|
||||
"qty": flt(row.consumed_qty),
|
||||
}
|
||||
)
|
||||
|
||||
if item_details.has_serial_no and not row.serial_and_batch_bundle and not row.serial_no:
|
||||
serial_nos = get_available_serial_nos(kwargs)
|
||||
if serial_nos:
|
||||
serial_nos = [sn.get("serial_no") for sn in serial_nos]
|
||||
serial_nos = get_filtered_serial_nos(serial_nos, self, "supplied_items")
|
||||
row.serial_no = "\n".join(serial_nos)
|
||||
|
||||
elif item_details.has_batch_no and not row.serial_and_batch_bundle and not row.batch_no:
|
||||
batches = get_auto_batch_nos(kwargs)
|
||||
if batches:
|
||||
consumed_qty = row.consumed_qty
|
||||
for index, d in enumerate(batches):
|
||||
if consumed_qty <= 0:
|
||||
break
|
||||
|
||||
if index == 0:
|
||||
row.batch_no = d.get("batch_no")
|
||||
row.consumed_qty = d.get("qty")
|
||||
consumed_qty -= d.get("qty")
|
||||
else:
|
||||
new_row = self.append("supplied_items", {})
|
||||
new_row.update(frappe.copy_doc(row).as_dict())
|
||||
new_row.update(
|
||||
{
|
||||
"consumed_qty": d.get("qty"),
|
||||
"batch_no": d.get("batch_no"),
|
||||
"rate": row.rate,
|
||||
"amount": flt(d.get("qty")) * flt(row.rate),
|
||||
}
|
||||
)
|
||||
consumed_qty -= d.get("qty")
|
||||
|
||||
def update_rate_for_supplied_items(self):
|
||||
if self.doctype != "Subcontracting Receipt":
|
||||
|
||||
@@ -260,10 +260,13 @@ def filter_batches(batches, doc):
|
||||
del batches[row.get("batch_no")]
|
||||
|
||||
|
||||
def get_filtered_serial_nos(serial_nos, doc):
|
||||
def get_filtered_serial_nos(serial_nos, doc, table=None):
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
for row in doc.get("items"):
|
||||
if not table:
|
||||
table = "items"
|
||||
|
||||
for row in doc.get(table):
|
||||
if row.get("serial_no"):
|
||||
for serial_no in get_serial_nos(row.get("serial_no")):
|
||||
if serial_no in serial_nos:
|
||||
|
||||
@@ -740,13 +740,13 @@ class TestSubcontractingReceipt(FrappeTestCase):
|
||||
for row in scr.supplied_items:
|
||||
self.assertEqual(row.rate, 300.00)
|
||||
self.assertTrue(row.serial_and_batch_bundle)
|
||||
auto_created_serial_batch = frappe.db.get_value(
|
||||
serial_and_batch_bundle = frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{"voucher_no": scr.name, "voucher_detail_no": row.name},
|
||||
"auto_created_serial_and_batch_bundle",
|
||||
"serial_and_batch_bundle",
|
||||
)
|
||||
|
||||
self.assertTrue(auto_created_serial_batch)
|
||||
self.assertTrue(serial_and_batch_bundle)
|
||||
|
||||
self.assertEqual(scr.items[0].rm_cost_per_qty, 900)
|
||||
self.assertEqual(scr.items[0].service_cost_per_qty, 100)
|
||||
|
||||
Reference in New Issue
Block a user