fix: serial and batch for internal transfer (backport #40467) (#40477)

fix: serial and batch for internal transfer (#40467)

* fix: serial and batch for internal transfer

* chore: fix test cases

(cherry picked from commit 59222813af)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
This commit is contained in:
mergify[bot]
2024-03-15 18:19:56 +05:30
committed by GitHub
parent 3397b80ddf
commit 61d59b392a
13 changed files with 374 additions and 19 deletions

View File

@@ -3932,7 +3932,6 @@ def create_internal_supplier(supplier_name, represents_company, allowed_to_inter
) )
supplier.append("companies", {"company": allowed_to_interact_with}) supplier.append("companies", {"company": allowed_to_interact_with})
supplier.insert() supplier.insert()
supplier_name = supplier.name supplier_name = supplier.name
else: else:

View File

@@ -513,6 +513,14 @@ class BuyingController(SubcontractingController):
(not cint(self.is_return) and self.docstatus == 1) (not cint(self.is_return) and self.docstatus == 1)
or (cint(self.is_return) and self.docstatus == 2) or (cint(self.is_return) and self.docstatus == 2)
): ):
serial_and_batch_bundle = d.get("serial_and_batch_bundle")
if self.is_internal_transfer() and self.is_return and self.docstatus == 2:
serial_and_batch_bundle = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_detail_no": d.name, "warehouse": d.from_warehouse},
"serial_and_batch_bundle",
)
from_warehouse_sle = self.get_sl_entries( from_warehouse_sle = self.get_sl_entries(
d, d,
{ {
@@ -521,19 +529,24 @@ class BuyingController(SubcontractingController):
"outgoing_rate": d.rate, "outgoing_rate": d.rate,
"recalculate_rate": 1, "recalculate_rate": 1,
"dependant_sle_voucher_detail_no": d.name, "dependant_sle_voucher_detail_no": d.name,
"serial_and_batch_bundle": serial_and_batch_bundle,
}, },
) )
sl_entries.append(from_warehouse_sle) sl_entries.append(from_warehouse_sle)
type_of_transaction = "Inward"
if self.docstatus == 2:
type_of_transaction = "Outward"
sle = self.get_sl_entries( sle = self.get_sl_entries(
d, d,
{ {
"actual_qty": flt(pr_qty), "actual_qty": flt(pr_qty),
"serial_and_batch_bundle": ( "serial_and_batch_bundle": (
d.serial_and_batch_bundle d.serial_and_batch_bundle
if not self.is_internal_transfer() if not self.is_internal_transfer() or self.is_return
else self.get_package_for_target_warehouse(d) else self.get_package_for_target_warehouse(d, type_of_transaction=type_of_transaction)
), ),
}, },
) )
@@ -570,7 +583,17 @@ class BuyingController(SubcontractingController):
or (cint(self.is_return) and self.docstatus == 1) or (cint(self.is_return) and self.docstatus == 1)
): ):
from_warehouse_sle = self.get_sl_entries( from_warehouse_sle = self.get_sl_entries(
d, {"actual_qty": -1 * pr_qty, "warehouse": d.from_warehouse, "recalculate_rate": 1} d,
{
"actual_qty": -1 * pr_qty,
"warehouse": d.from_warehouse,
"recalculate_rate": 1,
"serial_and_batch_bundle": (
self.get_package_for_target_warehouse(d, d.from_warehouse, "Inward")
if self.is_internal_transfer() and self.is_return
else None
),
},
) )
sl_entries.append(from_warehouse_sle) sl_entries.append(from_warehouse_sle)
@@ -597,13 +620,15 @@ class BuyingController(SubcontractingController):
via_landed_cost_voucher=via_landed_cost_voucher, via_landed_cost_voucher=via_landed_cost_voucher,
) )
def get_package_for_target_warehouse(self, item) -> str: def get_package_for_target_warehouse(self, item, warehouse=None, type_of_transaction=None) -> str:
if not item.serial_and_batch_bundle: if not item.serial_and_batch_bundle:
return "" return ""
if not warehouse:
warehouse = item.warehouse
return self.make_package_for_transfer( return self.make_package_for_transfer(
item.serial_and_batch_bundle, item.serial_and_batch_bundle, warehouse, type_of_transaction=type_of_transaction
item.warehouse,
) )
def update_ordered_and_reserved_qty(self): def update_ordered_and_reserved_qty(self):

View File

@@ -423,6 +423,15 @@ def make_return_doc(
]: ]:
type_of_transaction = "Outward" type_of_transaction = "Outward"
warehouse = source_doc.warehouse if qty_field == "stock_qty" else source_doc.rejected_warehouse
if source_parent.doctype in [
"Sales Invoice",
"POS Invoice",
"Delivery Note",
] and source_parent.get("is_internal_customer"):
type_of_transaction = "Outward"
warehouse = source_doc.target_warehouse
cls_obj = SerialBatchCreation( cls_obj = SerialBatchCreation(
{ {
"type_of_transaction": type_of_transaction, "type_of_transaction": type_of_transaction,
@@ -432,7 +441,7 @@ def make_return_doc(
"returned_serial_nos": returned_serial_nos, "returned_serial_nos": returned_serial_nos,
"voucher_type": source_parent.doctype, "voucher_type": source_parent.doctype,
"do_not_submit": True, "do_not_submit": True,
"warehouse": source_doc.warehouse, "warehouse": warehouse,
"has_serial_no": item_details.has_serial_no, "has_serial_no": item_details.has_serial_no,
"has_batch_no": item_details.has_batch_no, "has_batch_no": item_details.has_batch_no,
} }
@@ -575,11 +584,14 @@ def make_return_doc(
if not item_details.has_batch_no and not item_details.has_serial_no: if not item_details.has_batch_no and not item_details.has_serial_no:
return return
for qty_field in ["stock_qty", "rejected_qty"]: if not target_doc.get("use_serial_batch_fields"):
if target_doc.get(qty_field) and not target_doc.get("use_serial_batch_fields"): for qty_field in ["stock_qty", "rejected_qty"]:
if not target_doc.get(qty_field):
continue
update_serial_batch_no(source_doc, target_doc, source_parent, item_details, qty_field) update_serial_batch_no(source_doc, target_doc, source_parent, item_details, qty_field)
elif target_doc.get(qty_field) and target_doc.get("use_serial_batch_fields"): elif target_doc.get("use_serial_batch_fields"):
update_non_bundled_serial_nos(source_doc, target_doc, source_parent) update_non_bundled_serial_nos(source_doc, target_doc, source_parent)
def update_non_bundled_serial_nos(source_doc, target_doc, source_parent): def update_non_bundled_serial_nos(source_doc, target_doc, source_parent):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos

View File

@@ -442,8 +442,10 @@ class SellingController(StockController):
# Get incoming rate based on original item cost based on valuation method # Get incoming rate based on original item cost based on valuation method
qty = flt(d.get("stock_qty") or d.get("actual_qty")) qty = flt(d.get("stock_qty") or d.get("actual_qty"))
if not d.incoming_rate or ( if (
get_valuation_method(d.item_code) == "Moving Average" and self.get("is_return") not d.incoming_rate
or self.is_internal_transfer()
or (get_valuation_method(d.item_code) == "Moving Average" and self.get("is_return"))
): ):
d.incoming_rate = get_incoming_rate( d.incoming_rate = get_incoming_rate(
{ {
@@ -458,6 +460,8 @@ class SellingController(StockController):
"voucher_no": self.name, "voucher_no": self.name,
"voucher_detail_no": d.name, "voucher_detail_no": d.name,
"allow_zero_valuation": d.get("allow_zero_valuation"), "allow_zero_valuation": d.get("allow_zero_valuation"),
"batch_no": d.batch_no,
"serial_no": d.serial_no,
}, },
raise_error_if_no_rate=False, raise_error_if_no_rate=False,
) )
@@ -530,13 +534,26 @@ class SellingController(StockController):
self.make_sl_entries(sl_entries) self.make_sl_entries(sl_entries)
def get_sle_for_source_warehouse(self, item_row): def get_sle_for_source_warehouse(self, item_row):
serial_and_batch_bundle = item_row.serial_and_batch_bundle
if serial_and_batch_bundle and self.is_internal_transfer() and self.is_return:
if self.docstatus == 1:
serial_and_batch_bundle = self.make_package_for_transfer(
serial_and_batch_bundle, item_row.warehouse, type_of_transaction="Inward"
)
else:
serial_and_batch_bundle = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_detail_no": item_row.name, "warehouse": item_row.warehouse},
"serial_and_batch_bundle",
)
sle = self.get_sl_entries( sle = self.get_sl_entries(
item_row, item_row,
{ {
"actual_qty": -1 * flt(item_row.qty), "actual_qty": -1 * flt(item_row.qty),
"incoming_rate": item_row.incoming_rate, "incoming_rate": item_row.incoming_rate,
"recalculate_rate": cint(self.is_return), "recalculate_rate": cint(self.is_return),
"serial_and_batch_bundle": item_row.serial_and_batch_bundle, "serial_and_batch_bundle": serial_and_batch_bundle,
}, },
) )
if item_row.target_warehouse and not cint(self.is_return): if item_row.target_warehouse and not cint(self.is_return):
@@ -557,9 +574,15 @@ class SellingController(StockController):
if item_row.warehouse: if item_row.warehouse:
sle.dependant_sle_voucher_detail_no = item_row.name sle.dependant_sle_voucher_detail_no = item_row.name
if item_row.serial_and_batch_bundle: if item_row.serial_and_batch_bundle and not cint(self.is_return):
type_of_transaction = "Inward"
if cint(self.is_return):
type_of_transaction = "Outward"
sle["serial_and_batch_bundle"] = self.make_package_for_transfer( sle["serial_and_batch_bundle"] = self.make_package_for_transfer(
item_row.serial_and_batch_bundle, item_row.target_warehouse item_row.serial_and_batch_bundle,
item_row.target_warehouse,
type_of_transaction=type_of_transaction,
) )
return sle return sle

View File

@@ -236,6 +236,14 @@ class StockController(AccountsController):
qty = row.get("rejected_qty") qty = row.get("rejected_qty")
warehouse = row.get("rejected_warehouse") warehouse = row.get("rejected_warehouse")
if (
self.is_internal_transfer()
and self.doctype in ["Sales Invoice", "Delivery Note"]
and self.is_return
):
warehouse = row.get("target_warehouse") or row.get("warehouse")
type_of_transaction = "Outward"
bundle_details.update( bundle_details.update(
{ {
"qty": qty, "qty": qty,
@@ -579,7 +587,7 @@ class StockController(AccountsController):
bundle_doc.warehouse = warehouse bundle_doc.warehouse = warehouse
bundle_doc.type_of_transaction = type_of_transaction bundle_doc.type_of_transaction = type_of_transaction
bundle_doc.voucher_type = self.doctype bundle_doc.voucher_type = self.doctype
bundle_doc.voucher_no = self.name bundle_doc.voucher_no = "" if self.is_new() or self.docstatus == 2 else self.name
bundle_doc.is_cancelled = 0 bundle_doc.is_cancelled = 0
for row in bundle_doc.entries: for row in bundle_doc.entries:
@@ -595,6 +603,7 @@ class StockController(AccountsController):
bundle_doc.calculate_qty_and_amount() bundle_doc.calculate_qty_and_amount()
bundle_doc.flags.ignore_permissions = True bundle_doc.flags.ignore_permissions = True
bundle_doc.flags.ignore_validate = True
bundle_doc.save(ignore_permissions=True) bundle_doc.save(ignore_permissions=True)
return bundle_doc.name return bundle_doc.name

View File

@@ -542,6 +542,10 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
frappe.throw(__("Please add atleast one Serial No / Batch No")); frappe.throw(__("Please add atleast one Serial No / Batch No"));
} }
if (!warehouse) {
frappe.throw(__("Please select a Warehouse"));
}
frappe frappe
.call({ .call({
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.add_serial_batch_ledgers", method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.add_serial_batch_ledgers",

View File

@@ -333,6 +333,7 @@ class DeliveryNote(SellingController):
"type_of_transaction": "Outward", "type_of_transaction": "Outward",
"serial_and_batch_bundle": bundle_id, "serial_and_batch_bundle": bundle_id,
"item_code": item.get("item_code"), "item_code": item.get("item_code"),
"warehouse": item.get("warehouse"),
} }
) )

View File

@@ -2522,6 +2522,280 @@ class TestPurchaseReceipt(FrappeTestCase):
self.assertEqual(row.serial_no, "\n".join(serial_nos[:2])) self.assertEqual(row.serial_no, "\n".join(serial_nos[:2]))
self.assertEqual(row.rejected_serial_no, serial_nos[2]) self.assertEqual(row.rejected_serial_no, serial_nos[2])
def test_internal_transfer_with_serial_batch_items_and_their_valuation(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
prepare_data_for_internal_transfer()
customer = "_Test Internal Customer 2"
company = "_Test Company with perpetual inventory"
batch_item_doc = make_item(
"_Test Batch Item For Stock Transfer",
{"has_batch_no": 1, "create_new_batch": 1, "batch_number_series": "BT-BIFST-.####"},
)
serial_item_doc = make_item(
"_Test Serial No Item For Stock Transfer",
{"has_serial_no": 1, "serial_no_series": "BT-BIFST-.####"},
)
inward_entry = make_purchase_receipt(
item_code=batch_item_doc.name,
qty=10,
rate=150,
warehouse="Stores - TCP1",
company="_Test Company with perpetual inventory",
use_serial_batch_fields=1,
do_not_submit=1,
)
inward_entry.append(
"items",
{
"item_code": serial_item_doc.name,
"qty": 15,
"rate": 250,
"item_name": serial_item_doc.item_name,
"conversion_factor": 1.0,
"uom": serial_item_doc.stock_uom,
"stock_uom": serial_item_doc.stock_uom,
"warehouse": "Stores - TCP1",
"use_serial_batch_fields": 1,
},
)
inward_entry.submit()
inward_entry.reload()
for row in inward_entry.items:
self.assertTrue(row.serial_and_batch_bundle)
inter_transfer_dn = create_delivery_note(
item_code=inward_entry.items[0].item_code,
company=company,
customer=customer,
cost_center="Main - TCP1",
expense_account="Cost of Goods Sold - TCP1",
qty=10,
rate=500,
warehouse="Stores - TCP1",
target_warehouse="Work In Progress - TCP1",
batch_no=get_batch_from_bundle(inward_entry.items[0].serial_and_batch_bundle),
use_serial_batch_fields=1,
do_not_submit=1,
)
inter_transfer_dn.append(
"items",
{
"item_code": serial_item_doc.name,
"qty": 15,
"rate": 350,
"item_name": serial_item_doc.item_name,
"conversion_factor": 1.0,
"uom": serial_item_doc.stock_uom,
"stock_uom": serial_item_doc.stock_uom,
"warehouse": "Stores - TCP1",
"target_warehouse": "Work In Progress - TCP1",
"serial_no": "\n".join(
get_serial_nos_from_bundle(inward_entry.items[1].serial_and_batch_bundle)
),
"use_serial_batch_fields": 1,
},
)
inter_transfer_dn.submit()
inter_transfer_dn.reload()
for row in inter_transfer_dn.items:
if row.item_code == batch_item_doc.name:
self.assertEqual(row.rate, 150.0)
else:
self.assertEqual(row.rate, 250.0)
self.assertTrue(row.serial_and_batch_bundle)
inter_transfer_pr = make_inter_company_purchase_receipt(inter_transfer_dn.name)
for row in inter_transfer_pr.items:
row.from_warehouse = "Work In Progress - TCP1"
row.warehouse = "Stores - TCP1"
inter_transfer_pr.submit()
for row in inter_transfer_pr.items:
if row.item_code == batch_item_doc.name:
self.assertEqual(row.rate, 150.0)
else:
self.assertEqual(row.rate, 250.0)
self.assertTrue(row.serial_and_batch_bundle)
inter_transfer_pr_return = make_return_doc("Purchase Receipt", inter_transfer_pr.name)
inter_transfer_pr_return.submit()
inter_transfer_pr_return.reload()
for row in inter_transfer_pr_return.items:
self.assertTrue(row.serial_and_batch_bundle)
if row.item_code == serial_item_doc.name:
self.assertEqual(row.rate, 250.0)
serial_nos = get_serial_nos_from_bundle(row.serial_and_batch_bundle)
for sn in serial_nos:
serial_no_details = frappe.db.get_value("Serial No", sn, ["status", "warehouse"], as_dict=1)
self.assertTrue(serial_no_details.status == "Active")
self.assertEqual(serial_no_details.warehouse, "Work In Progress - TCP1")
inter_transfer_dn_return = make_return_doc("Delivery Note", inter_transfer_dn.name)
inter_transfer_dn_return.posting_date = today()
inter_transfer_dn_return.posting_time = nowtime()
for row in inter_transfer_dn_return.items:
row.target_warehouse = "Work In Progress - TCP1"
inter_transfer_dn_return.submit()
inter_transfer_dn_return.reload()
for row in inter_transfer_dn_return.items:
self.assertTrue(row.serial_and_batch_bundle)
def test_internal_transfer_with_serial_batch_items_without_user_serial_batch_fields(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 0)
prepare_data_for_internal_transfer()
customer = "_Test Internal Customer 2"
company = "_Test Company with perpetual inventory"
batch_item_doc = make_item(
"_Test Batch Item For Stock Transfer USE SERIAL BATCH FIELDS",
{"has_batch_no": 1, "create_new_batch": 1, "batch_number_series": "USBF-BT-BIFST-.####"},
)
serial_item_doc = make_item(
"_Test Serial No Item For Stock Transfer USE SERIAL BATCH FIELDS",
{"has_serial_no": 1, "serial_no_series": "USBF-BT-BIFST-.####"},
)
inward_entry = make_purchase_receipt(
item_code=batch_item_doc.name,
qty=10,
rate=150,
warehouse="Stores - TCP1",
company="_Test Company with perpetual inventory",
use_serial_batch_fields=0,
do_not_submit=1,
)
inward_entry.append(
"items",
{
"item_code": serial_item_doc.name,
"qty": 15,
"rate": 250,
"item_name": serial_item_doc.item_name,
"conversion_factor": 1.0,
"uom": serial_item_doc.stock_uom,
"stock_uom": serial_item_doc.stock_uom,
"warehouse": "Stores - TCP1",
"use_serial_batch_fields": 0,
},
)
inward_entry.submit()
inward_entry.reload()
for row in inward_entry.items:
self.assertTrue(row.serial_and_batch_bundle)
inter_transfer_dn = create_delivery_note(
item_code=inward_entry.items[0].item_code,
company=company,
customer=customer,
cost_center="Main - TCP1",
expense_account="Cost of Goods Sold - TCP1",
qty=10,
rate=500,
warehouse="Stores - TCP1",
target_warehouse="Work In Progress - TCP1",
batch_no=get_batch_from_bundle(inward_entry.items[0].serial_and_batch_bundle),
use_serial_batch_fields=0,
do_not_submit=1,
)
inter_transfer_dn.append(
"items",
{
"item_code": serial_item_doc.name,
"qty": 15,
"rate": 350,
"item_name": serial_item_doc.item_name,
"conversion_factor": 1.0,
"uom": serial_item_doc.stock_uom,
"stock_uom": serial_item_doc.stock_uom,
"warehouse": "Stores - TCP1",
"target_warehouse": "Work In Progress - TCP1",
"serial_no": "\n".join(
get_serial_nos_from_bundle(inward_entry.items[1].serial_and_batch_bundle)
),
"use_serial_batch_fields": 0,
},
)
inter_transfer_dn.submit()
inter_transfer_dn.reload()
for row in inter_transfer_dn.items:
if row.item_code == batch_item_doc.name:
self.assertEqual(row.rate, 150.0)
else:
self.assertEqual(row.rate, 250.0)
self.assertTrue(row.serial_and_batch_bundle)
inter_transfer_pr = make_inter_company_purchase_receipt(inter_transfer_dn.name)
for row in inter_transfer_pr.items:
row.from_warehouse = "Work In Progress - TCP1"
row.warehouse = "Stores - TCP1"
inter_transfer_pr.submit()
for row in inter_transfer_pr.items:
if row.item_code == batch_item_doc.name:
self.assertEqual(row.rate, 150.0)
else:
self.assertEqual(row.rate, 250.0)
self.assertTrue(row.serial_and_batch_bundle)
inter_transfer_pr_return = make_return_doc("Purchase Receipt", inter_transfer_pr.name)
inter_transfer_pr_return.submit()
inter_transfer_pr_return.reload()
for row in inter_transfer_pr_return.items:
self.assertTrue(row.serial_and_batch_bundle)
if row.item_code == serial_item_doc.name:
self.assertEqual(row.rate, 250.0)
serial_nos = get_serial_nos_from_bundle(row.serial_and_batch_bundle)
for sn in serial_nos:
serial_no_details = frappe.db.get_value("Serial No", sn, ["status", "warehouse"], as_dict=1)
self.assertTrue(serial_no_details.status == "Active")
self.assertEqual(serial_no_details.warehouse, "Work In Progress - TCP1")
inter_transfer_dn_return = make_return_doc("Delivery Note", inter_transfer_dn.name)
inter_transfer_dn_return.posting_date = today()
inter_transfer_dn_return.posting_time = nowtime()
for row in inter_transfer_dn_return.items:
row.target_warehouse = "Work In Progress - TCP1"
inter_transfer_dn_return.submit()
inter_transfer_dn_return.reload()
for row in inter_transfer_dn_return.items:
self.assertTrue(row.serial_and_batch_bundle)
frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1)
def prepare_data_for_internal_transfer(): def prepare_data_for_internal_transfer():
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier

View File

@@ -113,6 +113,7 @@
{ {
"fieldname": "voucher_no", "fieldname": "voucher_no",
"fieldtype": "Dynamic Link", "fieldtype": "Dynamic Link",
"in_standard_filter": 1,
"label": "Voucher No", "label": "Voucher No",
"no_copy": 1, "no_copy": 1,
"options": "voucher_type", "options": "voucher_type",
@@ -250,7 +251,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2023-12-07 17:56:55.528563", "modified": "2024-03-15 15:22:24.003486",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Serial and Batch Bundle", "name": "Serial and Batch Bundle",

View File

@@ -801,6 +801,7 @@ class SerialandBatchBundle(Document):
self.set_purchase_document_no() self.set_purchase_document_no()
def on_submit(self): def on_submit(self):
self.validate_batch_inventory()
self.validate_serial_nos_inventory() self.validate_serial_nos_inventory()
def set_purchase_document_no(self): def set_purchase_document_no(self):

View File

@@ -2606,6 +2606,7 @@ def move_sample_to_retention_warehouse(company, items):
"type_of_transaction": "Outward", "type_of_transaction": "Outward",
"serial_and_batch_bundle": item.get("serial_and_batch_bundle"), "serial_and_batch_bundle": item.get("serial_and_batch_bundle"),
"item_code": item.get("item_code"), "item_code": item.get("item_code"),
"warehouse": item.get("t_warehouse"),
} }
) )

View File

@@ -999,6 +999,7 @@ class TestStockEntry(FrappeTestCase):
"type_of_transaction": "Inward", "type_of_transaction": "Inward",
"serial_and_batch_bundle": s2.items[0].serial_and_batch_bundle, "serial_and_batch_bundle": s2.items[0].serial_and_batch_bundle,
"item_code": "_Test Serialized Item", "item_code": "_Test Serialized Item",
"warehouse": "_Test Warehouse - _TC",
} }
) )

View File

@@ -820,6 +820,10 @@ class SerialBatchCreation:
self.remove_returned_serial_nos(new_package) self.remove_returned_serial_nos(new_package)
new_package.docstatus = 0 new_package.docstatus = 0
new_package.warehouse = self.warehouse
new_package.voucher_no = ""
new_package.posting_date = today()
new_package.posting_time = nowtime()
new_package.type_of_transaction = self.type_of_transaction new_package.type_of_transaction = self.type_of_transaction
new_package.returned_against = self.get("returned_against") new_package.returned_against = self.get("returned_against")
new_package.save() new_package.save()