mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-01 03:09:09 +00:00
fix: time out error while submitting the purchase receipt which has more than 100 serial nos
This commit is contained in:
@@ -262,6 +262,30 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
self.assertEqual(pr2.per_billed, 80)
|
self.assertEqual(pr2.per_billed, 80)
|
||||||
self.assertEqual(pr2.status, "To Bill")
|
self.assertEqual(pr2.status, "To Bill")
|
||||||
|
|
||||||
|
def test_serial_no_against_purchase_receipt(self):
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
|
||||||
|
item_code = "Test Manual Created Serial No"
|
||||||
|
if not frappe.db.exists("Item", item_code):
|
||||||
|
item = make_item(item_code, dict(has_serial_no=1))
|
||||||
|
|
||||||
|
serial_no = random_string(5)
|
||||||
|
pr_doc = make_purchase_receipt(item_code=item_code,
|
||||||
|
qty=1, serial_no = serial_no)
|
||||||
|
|
||||||
|
self.assertEqual(serial_no, frappe.db.get_value("Serial No",
|
||||||
|
{"purchase_document_type": "Purchase Receipt", "purchase_document_no": pr_doc.name}, "name"))
|
||||||
|
|
||||||
|
item_code = "Test Auto Created Serial No"
|
||||||
|
if not frappe.db.exists("Item", item_code):
|
||||||
|
item = make_item(item_code, dict(has_serial_no=1, serial_no_series="KLJL.###"))
|
||||||
|
|
||||||
|
new_pr_doc = make_purchase_receipt(item_code=item_code, qty=1)
|
||||||
|
|
||||||
|
serial_no = get_serial_nos(new_pr_doc[0].serial_no)[0]
|
||||||
|
self.assertEqual(serial_no, frappe.db.get_value("Serial No",
|
||||||
|
{"purchase_document_type": "Purchase Receipt", "purchase_document_no": new_pr_doc.name}, "name"))
|
||||||
|
|
||||||
def test_not_accept_duplicate_serial_no(self):
|
def test_not_accept_duplicate_serial_no(self):
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||||
|
|||||||
@@ -29,13 +29,12 @@ class SerialNo(StockController):
|
|||||||
self.via_stock_ledger = False
|
self.via_stock_ledger = False
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.get("__islocal") and self.warehouse:
|
if self.get("__islocal") and self.warehouse and not self.via_stock_ledger:
|
||||||
frappe.throw(_("New Serial No cannot have Warehouse. Warehouse must be set by Stock Entry or Purchase Receipt"), SerialNoCannotCreateDirectError)
|
frappe.throw(_("New Serial No cannot have Warehouse. Warehouse must be set by Stock Entry or Purchase Receipt"), SerialNoCannotCreateDirectError)
|
||||||
|
|
||||||
self.set_maintenance_status()
|
self.set_maintenance_status()
|
||||||
self.validate_warehouse()
|
self.validate_warehouse()
|
||||||
self.validate_item()
|
self.validate_item()
|
||||||
self.on_stock_ledger_entry()
|
|
||||||
|
|
||||||
def set_maintenance_status(self):
|
def set_maintenance_status(self):
|
||||||
if not self.warranty_expiry_date and not self.amc_expiry_date:
|
if not self.warranty_expiry_date and not self.amc_expiry_date:
|
||||||
@@ -68,7 +67,7 @@ class SerialNo(StockController):
|
|||||||
"""
|
"""
|
||||||
Validate whether serial no is required for this item
|
Validate whether serial no is required for this item
|
||||||
"""
|
"""
|
||||||
item = frappe.get_doc("Item", self.item_code)
|
item = frappe.get_cached_doc("Item", self.item_code)
|
||||||
if item.has_serial_no!=1:
|
if item.has_serial_no!=1:
|
||||||
frappe.throw(_("Item {0} is not setup for Serial Nos. Check Item master").format(self.item_code))
|
frappe.throw(_("Item {0} is not setup for Serial Nos. Check Item master").format(self.item_code))
|
||||||
|
|
||||||
@@ -117,9 +116,9 @@ class SerialNo(StockController):
|
|||||||
"warranty_expiry_date"):
|
"warranty_expiry_date"):
|
||||||
self.set(fieldname, None)
|
self.set(fieldname, None)
|
||||||
|
|
||||||
def get_last_sle(self):
|
def get_last_sle(self, serial_no=None):
|
||||||
entries = {}
|
entries = {}
|
||||||
sle_dict = self.get_stock_ledger_entries()
|
sle_dict = self.get_stock_ledger_entries(serial_no)
|
||||||
if sle_dict:
|
if sle_dict:
|
||||||
if sle_dict.get("incoming", []):
|
if sle_dict.get("incoming", []):
|
||||||
entries["purchase_sle"] = sle_dict["incoming"][0]
|
entries["purchase_sle"] = sle_dict["incoming"][0]
|
||||||
@@ -132,13 +131,28 @@ class SerialNo(StockController):
|
|||||||
|
|
||||||
return entries
|
return entries
|
||||||
|
|
||||||
def get_stock_ledger_entries(self):
|
def get_stock_ledger_entries(self, serial_no=None):
|
||||||
sle_dict = {}
|
sle_dict = {}
|
||||||
for sle in frappe.db.sql("""select * from `tabStock Ledger Entry`
|
if not serial_no:
|
||||||
where serial_no like %s and item_code=%s and ifnull(is_cancelled, 'No')='No'
|
serial_no = self.name
|
||||||
order by posting_date desc, posting_time desc, creation desc""",
|
|
||||||
("%%%s%%" % self.name, self.item_code), as_dict=1):
|
for sle in frappe.db.sql("""
|
||||||
if self.name.upper() in get_serial_nos(sle.serial_no):
|
SELECT voucher_type, voucher_no,
|
||||||
|
posting_date, posting_time, incoming_rate, actual_qty, serial_no
|
||||||
|
FROM
|
||||||
|
`tabStock Ledger Entry`
|
||||||
|
WHERE
|
||||||
|
item_code=%s AND company = %s AND ifnull(is_cancelled, 'No')='No'
|
||||||
|
AND (serial_no = %s
|
||||||
|
OR serial_no like %s
|
||||||
|
OR serial_no like %s
|
||||||
|
OR serial_no like %s
|
||||||
|
)
|
||||||
|
ORDER BY
|
||||||
|
posting_date desc, posting_time desc, creation desc""",
|
||||||
|
(self.item_code, self.company,
|
||||||
|
serial_no, serial_no+'\n%', '%\n'+serial_no, '%\n'+serial_no+'\n%'), as_dict=1):
|
||||||
|
if serial_no.upper() in get_serial_nos(sle.serial_no):
|
||||||
if cint(sle.actual_qty) > 0:
|
if cint(sle.actual_qty) > 0:
|
||||||
sle_dict.setdefault("incoming", []).append(sle)
|
sle_dict.setdefault("incoming", []).append(sle)
|
||||||
else:
|
else:
|
||||||
@@ -178,12 +192,11 @@ class SerialNo(StockController):
|
|||||||
where name=%s""" % (dt[0], '%s', '%s'),
|
where name=%s""" % (dt[0], '%s', '%s'),
|
||||||
('\n'.join(list(serial_nos)), item[0]))
|
('\n'.join(list(serial_nos)), item[0]))
|
||||||
|
|
||||||
def on_stock_ledger_entry(self):
|
def update_serial_no_reference(self, serial_no=None):
|
||||||
if self.via_stock_ledger and not self.get("__islocal"):
|
last_sle = self.get_last_sle(serial_no)
|
||||||
last_sle = self.get_last_sle()
|
self.set_purchase_details(last_sle.get("purchase_sle"))
|
||||||
self.set_purchase_details(last_sle.get("purchase_sle"))
|
self.set_sales_details(last_sle.get("delivery_sle"))
|
||||||
self.set_sales_details(last_sle.get("delivery_sle"))
|
self.set_maintenance_status()
|
||||||
self.set_maintenance_status()
|
|
||||||
|
|
||||||
def process_serial_no(sle):
|
def process_serial_no(sle):
|
||||||
item_det = get_item_details(sle.item_code)
|
item_det = get_item_details(sle.item_code)
|
||||||
@@ -407,27 +420,16 @@ def get_serial_nos(serial_no):
|
|||||||
|
|
||||||
def make_serial_no(serial_no, args):
|
def make_serial_no(serial_no, args):
|
||||||
sr = frappe.new_doc("Serial No")
|
sr = frappe.new_doc("Serial No")
|
||||||
sr.warehouse = None
|
|
||||||
sr.dont_update_if_missing.append("warehouse")
|
|
||||||
sr.flags.ignore_permissions = True
|
|
||||||
sr.serial_no = serial_no
|
sr.serial_no = serial_no
|
||||||
sr.item_code = args.get('item_code')
|
sr.item_code = args.get('item_code')
|
||||||
sr.company = args.get('company')
|
sr.company = args.get('company')
|
||||||
sr.batch_no = args.get('batch_no')
|
sr.batch_no = args.get('batch_no')
|
||||||
sr.via_stock_ledger = args.get('via_stock_ledger') or True
|
sr.via_stock_ledger = args.get('via_stock_ledger') or True
|
||||||
sr.asset = args.get('asset')
|
sr.warehouse = args.get('warehouse')
|
||||||
sr.location = args.get('location')
|
|
||||||
|
|
||||||
|
sr.validate_item()
|
||||||
if args.get('purchase_document_type'):
|
sr.update_serial_no_reference(serial_no)
|
||||||
sr.purchase_document_type = args.get('purchase_document_type')
|
sr.db_insert()
|
||||||
sr.purchase_document_no = args.get('purchase_document_no')
|
|
||||||
sr.supplier = args.get('supplier')
|
|
||||||
|
|
||||||
sr.insert()
|
|
||||||
if args.get('warehouse'):
|
|
||||||
sr.warehouse = args.get('warehouse')
|
|
||||||
sr.save()
|
|
||||||
|
|
||||||
return sr.name
|
return sr.name
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user