Merge pull request #40967 from rohitwaghchaure/fixed-13250
fix: zero division error
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 5916f2e..4df3726 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -166,7 +166,7 @@
# remove extra whitespace and store one serial no on each line
row.serial_no = clean_serial_no_string(row.serial_no)
- def make_bundle_using_old_serial_batch_fields(self, table_name=None):
+ def make_bundle_using_old_serial_batch_fields(self, table_name=None, via_landed_cost_voucher=False):
if self.get("_action") == "update_after_submit":
return
@@ -205,7 +205,7 @@
"company": self.company,
"is_rejected": 1 if row.get("rejected_warehouse") else 0,
"use_serial_batch_fields": row.use_serial_batch_fields,
- "do_not_submit": True,
+ "do_not_submit": True if not via_landed_cost_voucher else False,
}
if row.get("qty") or row.get("consumed_qty"):
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index 5e5efb5..222ffb4 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -250,6 +250,7 @@
# update stock & gl entries for submit state of PR
doc.docstatus = 1
+ doc.make_bundle_using_old_serial_batch_fields(via_landed_cost_voucher=True)
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
doc.make_gl_entries()
doc.repost_future_sle_and_gle()
diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
index 9ec2d69..32b384d 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
@@ -596,6 +596,155 @@
lcv.cancel()
pr.cancel()
+ def test_landed_cost_voucher_with_serial_batch_for_legacy_pr(self):
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ frappe.flags.ignore_serial_batch_bundle_validation = True
+ frappe.flags.use_serial_and_batch_fields = True
+ sn_item = "Test Landed Cost Voucher Serial NO for Legacy PR"
+ batch_item = "Test Landed Cost Voucher Batch NO for Legacy PR"
+ sn_item_doc = make_item(
+ sn_item,
+ {
+ "has_serial_no": 1,
+ "serial_no_series": "SN-TLCVSNO-.####",
+ "is_stock_item": 1,
+ },
+ )
+
+ batch_item_doc = make_item(
+ batch_item,
+ {
+ "has_batch_no": 1,
+ "batch_number_series": "BATCH-TLCVSNO-.####",
+ "create_new_batch": 1,
+ "is_stock_item": 1,
+ },
+ )
+
+ serial_nos = [
+ "SN-TLCVSNO-0001",
+ "SN-TLCVSNO-0002",
+ "SN-TLCVSNO-0003",
+ "SN-TLCVSNO-0004",
+ "SN-TLCVSNO-0005",
+ ]
+
+ for sn in serial_nos:
+ if not frappe.db.exists("Serial No", sn):
+ sn_doc = frappe.get_doc(
+ {
+ "doctype": "Serial No",
+ "item_code": sn_item,
+ "serial_no": sn,
+ }
+ )
+ sn_doc.insert()
+
+ if not frappe.db.exists("Batch", "BATCH-TLCVSNO-0001"):
+ batch_doc = frappe.get_doc(
+ {
+ "doctype": "Batch",
+ "item": batch_item,
+ "batch_id": "BATCH-TLCVSNO-0001",
+ }
+ )
+ batch_doc.insert()
+
+ warehouse = "_Test Warehouse - _TC"
+ company = frappe.db.get_value("Warehouse", warehouse, "company")
+
+ pr = make_purchase_receipt(
+ company=company,
+ warehouse=warehouse,
+ item_code=sn_item,
+ qty=5,
+ rate=100,
+ uom=sn_item_doc.stock_uom,
+ stock_uom=sn_item_doc.stock_uom,
+ do_not_submit=True,
+ )
+
+ pr.append(
+ "items",
+ {
+ "item_code": batch_item,
+ "item_name": batch_item,
+ "description": "Test Batch Item",
+ "uom": batch_item_doc.stock_uom,
+ "stock_uom": batch_item_doc.stock_uom,
+ "qty": 5,
+ "rate": 100,
+ "warehouse": warehouse,
+ },
+ )
+
+ pr.submit()
+ pr.reload()
+
+ for row in pr.items:
+ self.assertEqual(row.valuation_rate, 100)
+ self.assertFalse(row.serial_no)
+ self.assertFalse(row.batch_no)
+ self.assertFalse(row.serial_and_batch_bundle)
+
+ if row.item_code == sn_item:
+ row.db_set("serial_no", ", ".join(serial_nos))
+ else:
+ row.db_set("batch_no", "BATCH-TLCVSNO-0001")
+
+ for sn in serial_nos:
+ sn_doc = frappe.get_doc("Serial No", sn)
+ sn_doc.db_set(
+ {
+ "warehouse": warehouse,
+ "status": "Active",
+ }
+ )
+
+ batch_doc.db_set(
+ {
+ "batch_qty": 5,
+ }
+ )
+
+ frappe.flags.ignore_serial_batch_bundle_validation = False
+ frappe.flags.use_serial_and_batch_fields = False
+
+ lcv = make_landed_cost_voucher(
+ company=pr.company,
+ receipt_document_type="Purchase Receipt",
+ receipt_document=pr.name,
+ charges=20,
+ distribute_charges_based_on="Qty",
+ do_not_save=True,
+ )
+
+ lcv.get_items_from_purchase_receipts()
+ lcv.save()
+ lcv.submit()
+
+ pr.reload()
+
+ for row in pr.items:
+ self.assertEqual(row.valuation_rate, 102)
+ self.assertTrue(row.serial_and_batch_bundle)
+ self.assertEqual(
+ row.valuation_rate,
+ frappe.db.get_value("Serial and Batch Bundle", row.serial_and_batch_bundle, "avg_rate"),
+ )
+
+ lcv.cancel()
+ pr.reload()
+
+ for row in pr.items:
+ self.assertEqual(row.valuation_rate, 100)
+ self.assertTrue(row.serial_and_batch_bundle)
+ self.assertEqual(
+ row.valuation_rate,
+ frappe.db.get_value("Serial and Batch Bundle", row.serial_and_batch_bundle, "avg_rate"),
+ )
+
def make_landed_cost_voucher(**args):
args = frappe._dict(args)