fix: travis for POS merge invoice and putaway rule
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
index db64d06..d8cbcc1 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
@@ -387,7 +387,7 @@
]
for pos_invoice in pos_return_docs:
for item in pos_invoice.items:
- if not item.serial_no:
+ if not item.serial_no and not item.serial_and_batch_bundle:
continue
return_against_is_added = any(
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
index 9e696f1..6af8a00 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
@@ -13,6 +13,9 @@
from erpnext.accounts.doctype.pos_invoice_merge_log.pos_invoice_merge_log import (
consolidate_pos_invoices,
)
+from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
+ get_serial_nos_from_bundle,
+)
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
@@ -410,13 +413,13 @@
try:
se = make_serialized_item()
- serial_no = get_serial_nos(se.get("items")[0].serial_no)[0]
+ serial_no = get_serial_nos_from_bundle(se.get("items")[0].serial_and_batch_bundle)[0]
init_user_and_profile()
pos_inv = create_pos_invoice(
item_code="_Test Serialized Item With Series",
- serial_no=serial_no,
+ serial_no=[serial_no],
qty=1,
rate=100,
do_not_submit=1,
@@ -430,7 +433,7 @@
pos_inv2 = create_pos_invoice(
item_code="_Test Serialized Item With Series",
- serial_no=serial_no,
+ serial_no=[serial_no],
qty=1,
rate=100,
do_not_submit=1,
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 9fa7a86..51e0d91 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -2981,7 +2981,7 @@
# Sales Invoice with Payment Schedule
si_with_payment_schedule = create_sales_invoice(do_not_submit=True)
- si_with_payment_schedule.extend(
+ si_with_payment_schedule.set(
"payment_schedule",
[
{
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 34e3b13..11cee28 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -663,19 +663,31 @@
return filters
-def get_returned_serial_nos(child_doc, parent_doc, serial_no_field=None):
+def get_returned_serial_nos(
+ child_doc, parent_doc, serial_no_field=None, ignore_voucher_detail_no=None
+):
+ from erpnext.stock.doctype.serial_no.serial_no import (
+ get_serial_nos as get_serial_nos_from_serial_no,
+ )
from erpnext.stock.serial_batch_bundle import get_serial_nos
if not serial_no_field:
serial_no_field = "serial_and_batch_bundle"
+ old_field = "serial_no"
+ if serial_no_field == "rejected_serial_and_batch_bundle":
+ old_field = "rejected_serial_no"
+
return_ref_field = frappe.scrub(child_doc.doctype)
if child_doc.doctype == "Delivery Note Item":
return_ref_field = "dn_detail"
serial_nos = []
- fields = [f"`{'tab' + child_doc.doctype}`.`{serial_no_field}`"]
+ fields = [
+ f"`{'tab' + child_doc.doctype}`.`{serial_no_field}`",
+ f"`{'tab' + child_doc.doctype}`.`{old_field}`",
+ ]
filters = [
[parent_doc.doctype, "return_against", "=", parent_doc.name],
@@ -684,9 +696,15 @@
[parent_doc.doctype, "docstatus", "=", 1],
]
+ # Required for POS Invoice
+ if ignore_voucher_detail_no:
+ filters.append([child_doc.doctype, "name", "!=", ignore_voucher_detail_no])
+
ids = []
for row in frappe.get_all(parent_doc.doctype, fields=fields, filters=filters):
ids.append(row.get("serial_and_batch_bundle"))
+ if row.get(old_field):
+ serial_nos.extend(get_serial_nos_from_serial_no(row.get(old_field)))
serial_nos.extend(get_serial_nos(ids))
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index ff2d705..15a72a8 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -931,7 +931,7 @@
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
- "batch_number_series": "TESTBATCH.#####",
+ "batch_number_series": "TESTBATCHIUU.#####",
},
)
make_product_bundle(parent=batched_bundle.name, items=[batched_item.name])
@@ -942,7 +942,7 @@
dn = create_delivery_note(item_code=batched_bundle.name, qty=1)
dn.load_from_db()
- batch_no = get_batch_from_bundle(dn.items[0].serial_and_batch_bundle)
+ batch_no = get_batch_from_bundle(dn.packed_items[0].serial_and_batch_bundle)
self.assertTrue(batch_no)
def test_payment_terms_are_fetched_when_creating_sales_invoice(self):
diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py
index 623fbde..0a04210 100644
--- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py
+++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py
@@ -11,7 +11,6 @@
from frappe.model.document import Document
from frappe.utils import cint, cstr, floor, flt, nowdate
-from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
from erpnext.stock.utils import get_stock_balance
@@ -99,7 +98,6 @@
item = frappe._dict(item)
source_warehouse = item.get("s_warehouse")
- serial_nos = get_serial_nos(item.get("serial_no"))
item.conversion_factor = flt(item.conversion_factor) or 1.0
pending_qty, item_code = flt(item.qty), item.item_code
pending_stock_qty = flt(item.transfer_qty) if doctype == "Stock Entry" else flt(item.stock_qty)
@@ -145,9 +143,7 @@
if not qty_to_allocate:
break
- updated_table = add_row(
- item, qty_to_allocate, rule.warehouse, updated_table, rule.name, serial_nos=serial_nos
- )
+ updated_table = add_row(item, qty_to_allocate, rule.warehouse, updated_table, rule.name)
pending_stock_qty -= stock_qty_to_allocate
pending_qty -= qty_to_allocate
@@ -245,7 +241,7 @@
return False, vacant_rules
-def add_row(item, to_allocate, warehouse, updated_table, rule=None, serial_nos=None):
+def add_row(item, to_allocate, warehouse, updated_table, rule=None):
new_updated_table_row = copy.deepcopy(item)
new_updated_table_row.idx = 1 if not updated_table else cint(updated_table[-1].idx) + 1
new_updated_table_row.name = None
@@ -264,8 +260,8 @@
if rule:
new_updated_table_row.putaway_rule = rule
- if serial_nos:
- new_updated_table_row.serial_no = get_serial_nos_to_allocate(serial_nos, to_allocate)
+
+ new_updated_table_row.serial_and_batch_bundle = ""
updated_table.append(new_updated_table_row)
return updated_table
@@ -297,12 +293,3 @@
)
frappe.msgprint(msg, title=_("Insufficient Capacity"), is_minimizable=True, wide=True)
-
-
-def get_serial_nos_to_allocate(serial_nos, to_allocate):
- if serial_nos:
- allocated_serial_nos = serial_nos[0 : cint(to_allocate)]
- serial_nos[:] = serial_nos[cint(to_allocate) :] # pop out allocated serial nos and modify list
- return "\n".join(allocated_serial_nos) if allocated_serial_nos else ""
- else:
- return ""
diff --git a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py
index ab0ca10..f5bad51 100644
--- a/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py
+++ b/erpnext/stock/doctype/putaway_rule/test_putaway_rule.py
@@ -7,6 +7,11 @@
from erpnext.stock.doctype.batch.test_batch import make_new_batch
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
+from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
+ get_batch_from_bundle,
+ get_serial_nos_from_bundle,
+ make_serial_batch_bundle,
+)
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
from erpnext.stock.get_item_details import get_conversion_factor
@@ -382,42 +387,49 @@
make_new_batch(batch_id="BOTTL-BATCH-1", item_code="Water Bottle")
pr = make_purchase_receipt(item_code="Water Bottle", qty=5, do_not_submit=1)
- pr.items[0].batch_no = "BOTTL-BATCH-1"
pr.save()
pr.submit()
+ pr.load_from_db()
- serial_nos = frappe.get_list(
- "Serial No", filters={"purchase_document_no": pr.name, "status": "Active"}
- )
- serial_nos = [d.name for d in serial_nos]
+ batch_no = get_batch_from_bundle(pr.items[0].serial_and_batch_bundle)
+ serial_nos = get_serial_nos_from_bundle(pr.items[0].serial_and_batch_bundle)
stock_entry = make_stock_entry(
item_code="Water Bottle",
source="_Test Warehouse - _TC",
qty=5,
+ serial_no=serial_nos,
target="Finished Goods - _TC",
purpose="Material Transfer",
apply_putaway_rule=1,
do_not_save=1,
)
- stock_entry.items[0].batch_no = "BOTTL-BATCH-1"
- stock_entry.items[0].serial_no = "\n".join(serial_nos)
stock_entry.save()
+ stock_entry.load_from_db()
self.assertEqual(stock_entry.items[0].t_warehouse, self.warehouse_1)
self.assertEqual(stock_entry.items[0].qty, 3)
self.assertEqual(stock_entry.items[0].putaway_rule, rule_1.name)
- self.assertEqual(stock_entry.items[0].serial_no, "\n".join(serial_nos[:3]))
- self.assertEqual(stock_entry.items[0].batch_no, "BOTTL-BATCH-1")
+ self.assertEqual(
+ get_serial_nos_from_bundle(stock_entry.items[0].serial_and_batch_bundle), serial_nos[0:3]
+ )
+ self.assertEqual(get_batch_from_bundle(stock_entry.items[0].serial_and_batch_bundle), batch_no)
self.assertEqual(stock_entry.items[1].t_warehouse, self.warehouse_2)
self.assertEqual(stock_entry.items[1].qty, 2)
self.assertEqual(stock_entry.items[1].putaway_rule, rule_2.name)
- self.assertEqual(stock_entry.items[1].serial_no, "\n".join(serial_nos[3:]))
- self.assertEqual(stock_entry.items[1].batch_no, "BOTTL-BATCH-1")
+ self.assertEqual(
+ get_serial_nos_from_bundle(stock_entry.items[1].serial_and_batch_bundle), serial_nos[3:5]
+ )
+ self.assertEqual(get_batch_from_bundle(stock_entry.items[1].serial_and_batch_bundle), batch_no)
self.assertUnchangedItemsOnResave(stock_entry)
+ for row in stock_entry.items:
+ if row.serial_and_batch_bundle:
+ frappe.delete_doc("Serial and Batch Bundle", row.serial_and_batch_bundle)
+
+ stock_entry.load_from_db()
stock_entry.delete()
pr.cancel()
rule_1.delete()
diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
index cfb03f0..9f26b40 100644
--- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
+++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
@@ -6,7 +6,7 @@
from typing import Dict, List
import frappe
-from frappe import _, bold
+from frappe import _, _dict, bold
from frappe.model.document import Document
from frappe.query_builder.functions import CombineDatetime, Sum
from frappe.utils import add_days, cint, flt, get_link_to_form, nowtime, today
@@ -82,16 +82,20 @@
return
serial_nos = [d.serial_no for d in self.entries if d.serial_no]
- available_serial_nos = get_available_serial_nos(
- frappe._dict(
- {
- "item_code": self.item_code,
- "posting_date": self.posting_date,
- "posting_time": self.posting_time,
- }
- )
+ kwargs = frappe._dict(
+ {
+ "item_code": self.item_code,
+ "posting_date": self.posting_date,
+ "posting_time": self.posting_time,
+ "serial_nos": serial_nos,
+ }
)
+ if self.returned_against and self.docstatus == 1:
+ kwargs["ignore_voucher_detail_no"] = self.voucher_detail_no
+
+ available_serial_nos = get_available_serial_nos(kwargs)
+
for data in available_serial_nos:
if data.serial_no in serial_nos:
self.throw_error_message(
@@ -776,6 +780,10 @@
ignore_serial_nos = get_reserved_serial_nos_for_pos(kwargs)
+ # To ignore serial nos in the same record for the draft state
+ if kwargs.get("ignore_serial_nos"):
+ ignore_serial_nos.extend(kwargs.get("ignore_serial_nos"))
+
if kwargs.get("posting_date"):
if kwargs.get("posting_time") is None:
kwargs.posting_time = nowtime()
@@ -801,7 +809,7 @@
for d in data:
if d.serial_and_batch_bundle:
- sns = get_serial_nos_from_bundle(d.serial_and_batch_bundle)
+ sns = get_serial_nos_from_bundle(d.serial_and_batch_bundle, kwargs.get("serial_nos", []))
if d.actual_qty > 0:
serial_nos.update(sns)
else:
@@ -823,12 +831,19 @@
def get_reserved_serial_nos_for_pos(kwargs):
+ from erpnext.controllers.sales_and_purchase_return import get_returned_serial_nos
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
ignore_serial_nos = []
pos_invoices = frappe.get_all(
"POS Invoice",
- fields=["`tabPOS Invoice Item`.serial_no", "`tabPOS Invoice Item`.serial_and_batch_bundle"],
+ fields=[
+ "`tabPOS Invoice Item`.serial_no",
+ "`tabPOS Invoice`.is_return",
+ "`tabPOS Invoice Item`.name as child_docname",
+ "`tabPOS Invoice`.name as parent_docname",
+ "`tabPOS Invoice Item`.serial_and_batch_bundle",
+ ],
filters=[
["POS Invoice", "consolidated_invoice", "is", "not set"],
["POS Invoice", "docstatus", "=", 1],
@@ -850,11 +865,35 @@
ignore_serial_nos.append(d.serial_no)
# Will be deprecated in v16
+ returned_serial_nos = []
for pos_invoice in pos_invoices:
if pos_invoice.serial_no:
ignore_serial_nos.extend(get_serial_nos(pos_invoice.serial_no))
- return ignore_serial_nos
+ if pos_invoice.is_return:
+ continue
+
+ child_doc = _dict(
+ {
+ "doctype": "POS Invoice Item",
+ "name": pos_invoice.child_docname,
+ }
+ )
+
+ parent_doc = _dict(
+ {
+ "doctype": "POS Invoice",
+ "name": pos_invoice.parent_docname,
+ }
+ )
+
+ returned_serial_nos.extend(
+ get_returned_serial_nos(
+ child_doc, parent_doc, ignore_voucher_detail_no=kwargs.get("ignore_voucher_detail_no")
+ )
+ )
+
+ return list(set(ignore_serial_nos) - set(returned_serial_nos))
def get_auto_batch_nos(kwargs):
diff --git a/erpnext/stock/doctype/serial_no/test_serial_no.py b/erpnext/stock/doctype/serial_no/test_serial_no.py
index 68623fb..4a0abb6 100644
--- a/erpnext/stock/doctype/serial_no/test_serial_no.py
+++ b/erpnext/stock/doctype/serial_no/test_serial_no.py
@@ -11,6 +11,11 @@
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
+from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
+ get_batch_from_bundle,
+ get_serial_nos_from_bundle,
+ make_serial_batch_bundle,
+)
from erpnext.stock.doctype.serial_no.serial_no import *
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
@@ -209,23 +214,6 @@
self.assertEqual(sn_doc.warehouse, "_Test Warehouse - _TC")
self.assertEqual(sn_doc.purchase_document_no, se.name)
- def test_auto_creation_of_serial_no(self):
- """
- Test if auto created Serial No excludes existing serial numbers
- """
- item_code = make_item(
- "_Test Auto Serial Item ", {"has_serial_no": 1, "serial_no_series": "XYZ.###"}
- ).item_code
-
- # Reserve XYZ005
- pr_1 = make_purchase_receipt(item_code=item_code, qty=1, serial_no="XYZ005")
- # XYZ005 is already used and will throw an error if used again
- pr_2 = make_purchase_receipt(item_code=item_code, qty=10)
-
- self.assertEqual(get_serial_nos(pr_1.get("items")[0].serial_no)[0], "XYZ005")
- for serial_no in get_serial_nos(pr_2.get("items")[0].serial_no):
- self.assertNotEqual(serial_no, "XYZ005")
-
def test_serial_no_sanitation(self):
"Test if Serial No input is sanitised before entering the DB."
item_code = "_Test Serialized Item"
@@ -288,12 +276,12 @@
in1.reload()
in2.reload()
- batch1 = in1.items[0].batch_no
- batch2 = in2.items[0].batch_no
+ batch1 = get_batch_from_bundle(in1.items[0].serial_and_batch_bundle)
+ batch2 = get_batch_from_bundle(in2.items[0].serial_and_batch_bundle)
batch_wise_serials = {
- batch1: get_serial_nos(in1.items[0].serial_no),
- batch2: get_serial_nos(in2.items[0].serial_no),
+ batch1: get_serial_nos_from_bundle(in1.items[0].serial_and_batch_bundle),
+ batch2: get_serial_nos_from_bundle(in2.items[0].serial_and_batch_bundle),
}
# Test FIFO
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index e686e58..2f49822 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -142,7 +142,6 @@
self.validate_job_card_item()
self.set_purpose_for_stock_entry()
self.clean_serial_nos()
- self.validate_duplicate_serial_no()
if not self.from_bom:
self.fg_completed_qty = 0.0
@@ -878,52 +877,63 @@
if self.stock_entry_type and not self.purpose:
self.purpose = frappe.get_cached_value("Stock Entry Type", self.stock_entry_type, "purpose")
- def validate_duplicate_serial_no(self):
- warehouse_wise_serial_nos = {}
-
- # In case of repack the source and target serial nos could be same
- for warehouse in ["s_warehouse", "t_warehouse"]:
- serial_nos = []
- for row in self.items:
- if not (row.serial_no and row.get(warehouse)):
- continue
-
- for sn in get_serial_nos(row.serial_no):
- if sn in serial_nos:
- frappe.throw(
- _("The serial no {0} has added multiple times in the stock entry {1}").format(
- frappe.bold(sn), self.name
- )
- )
-
- serial_nos.append(sn)
-
def make_serial_and_batch_bundle_for_outward(self):
+ if self.docstatus == 1:
+ return
+
serial_or_batch_items = get_serial_or_batch_items(self.items)
if not serial_or_batch_items:
return
+ already_picked_serial_nos = []
+
for row in self.items:
if not row.s_warehouse:
continue
- if row.serial_and_batch_bundle or row.item_code not in serial_or_batch_items:
+ if row.item_code not in serial_or_batch_items:
continue
- bundle_doc = SerialBatchCreation(
- {
- "item_code": row.item_code,
- "warehouse": row.s_warehouse,
- "posting_date": self.posting_date,
- "posting_time": self.posting_time,
- "voucher_type": self.doctype,
- "voucher_detail_no": row.name,
- "qty": row.qty * -1,
- "type_of_transaction": "Outward",
- "company": self.company,
- "do_not_submit": True,
- }
- ).make_serial_and_batch_bundle()
+ bundle_doc = None
+ if row.serial_and_batch_bundle and abs(row.qty) != abs(
+ frappe.get_cached_value("Serial and Batch Bundle", row.serial_and_batch_bundle, "total_qty")
+ ):
+ bundle_doc = SerialBatchCreation(
+ {
+ "item_code": row.item_code,
+ "warehouse": row.s_warehouse,
+ "serial_and_batch_bundle": row.serial_and_batch_bundle,
+ "type_of_transaction": "Outward",
+ "ignore_serial_nos": already_picked_serial_nos,
+ "qty": row.qty * -1,
+ }
+ ).update_serial_and_batch_entries()
+ elif not row.serial_and_batch_bundle:
+ bundle_doc = SerialBatchCreation(
+ {
+ "item_code": row.item_code,
+ "warehouse": row.s_warehouse,
+ "posting_date": self.posting_date,
+ "posting_time": self.posting_time,
+ "voucher_type": self.doctype,
+ "voucher_detail_no": row.name,
+ "qty": row.qty * -1,
+ "ignore_serial_nos": already_picked_serial_nos,
+ "type_of_transaction": "Outward",
+ "company": self.company,
+ "do_not_submit": True,
+ }
+ ).make_serial_and_batch_bundle()
+
+ if not bundle_doc:
+ continue
+
+ if self.docstatus == 0:
+ for entry in bundle_doc.entries:
+ if not entry.serial_no:
+ continue
+
+ already_picked_serial_nos.append(entry.serial_no)
row.serial_and_batch_bundle = bundle_doc.name
diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py
index 06fe0f1..33dd960 100644
--- a/erpnext/stock/serial_batch_bundle.py
+++ b/erpnext/stock/serial_batch_bundle.py
@@ -255,11 +255,14 @@
frappe.db.set_value("Batch", batch_no, "batch_qty", batches_qty.get(batch_no, 0))
-def get_serial_nos(serial_and_batch_bundle):
+def get_serial_nos(serial_and_batch_bundle, serial_nos=None):
filters = {"parent": serial_and_batch_bundle}
if isinstance(serial_and_batch_bundle, list):
filters = {"parent": ("in", serial_and_batch_bundle)}
+ if serial_nos:
+ filters["serial_no"] = ("in", serial_nos)
+
entries = frappe.get_all("Serial and Batch Entry", fields=["serial_no"], filters=filters)
return [d.serial_no for d in entries]
@@ -694,6 +697,18 @@
return doc
+ def update_serial_and_batch_entries(self):
+ doc = frappe.get_doc("Serial and Batch Bundle", self.serial_and_batch_bundle)
+ doc.type_of_transaction = self.type_of_transaction
+ doc.set("entries", [])
+ self.set_auto_serial_batch_entries_for_outward()
+ self.set_serial_batch_entries(doc)
+ if not doc.get("entries"):
+ return frappe._dict({})
+
+ doc.save()
+ return doc
+
def set_auto_serial_batch_entries_for_outward(self):
from erpnext.stock.doctype.batch.batch import get_available_batches
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos_for_outward
@@ -707,6 +722,9 @@
}
)
+ if self.get("ignore_serial_nos"):
+ kwargs["ignore_serial_nos"] = self.ignore_serial_nos
+
if self.has_serial_no and not self.get("serial_nos"):
self.serial_nos = get_serial_nos_for_outward(kwargs)
elif not self.has_serial_no and self.has_batch_no and not self.get("batches"):