Skip to content

Commit

Permalink
perf: don't query unless required, and use cache
Browse files Browse the repository at this point in the history
- added cache for querying values which are rarely changed.
- Reordering conditionals so queries are not performed unless absolutely
required.

Essentially, both option below are semantically correct but one will
always hit the DB before before evaulating to `False`.

- `False and frappe.db.sql("select * from tabItem")`

- `frappe.db.sql("select * from tabItem") and False`
  • Loading branch information
ankush committed Jun 23, 2021
1 parent da66cef commit 7d4139e
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 15 deletions.
9 changes: 5 additions & 4 deletions erpnext/controllers/sales_and_purchase_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ def validate_returned_items(doc):
frappe.throw(_("Row # {0}: Serial No {1} does not match with {2} {3}")
.format(d.idx, s, doc.doctype, doc.return_against))

if warehouse_mandatory and frappe.db.get_value("Item", d.item_code, "is_stock_item") \
and not d.get("warehouse"):
frappe.throw(_("Warehouse is mandatory"))
if (warehouse_mandatory and not d.get("warehouse") and
frappe.db.get_value("Item", d.item_code, "is_stock_item", cache=True)
):
frappe.throw(_("Warehouse is mandatory"))

items_returned = True

Expand Down Expand Up @@ -462,4 +463,4 @@ def get_returned_serial_nos(child_doc, parent_doc):
for row in frappe.get_all(parent_doc.doctype, fields = fields, filters=filters):
serial_nos.extend(get_serial_nos(row.serial_no))

return serial_nos
return serial_nos
2 changes: 1 addition & 1 deletion erpnext/controllers/selling_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ def validate_for_duplicate_items(self):
stock_items = [d.item_code, d.description, d.warehouse, '']
non_stock_items = [d.item_code, d.description]

if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
if frappe.db.get_value("Item", d.item_code, "is_stock_item", cache=True) == 1:
duplicate_items_msg = _("Item {0} entered multiple times.").format(frappe.bold(d.item_code))
duplicate_items_msg += "<br><br>"
duplicate_items_msg += _("Please enable {} in {} to allow same item in multiple rows").format(
Expand Down
7 changes: 3 additions & 4 deletions erpnext/stock/doctype/batch/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def validate(self):
self.item_has_batch_enabled()

def item_has_batch_enabled(self):
if frappe.db.get_value("Item", self.item, "has_batch_no") == 0:
if frappe.db.get_value("Item", self.item, "has_batch_no", cache=True) == 0:
frappe.throw(_("The selected item cannot have Batch"))

def before_save(self):
Expand Down Expand Up @@ -230,9 +230,8 @@ def set_batch_nos(doc, warehouse_field, throw=False):
"""Automatically select `batch_no` for outgoing items in item table"""
for d in doc.items:
qty = d.get('stock_qty') or d.get('transfer_qty') or d.get('qty') or 0
has_batch_no = frappe.db.get_value('Item', d.item_code, 'has_batch_no')
warehouse = d.get(warehouse_field, None)
if has_batch_no and warehouse and qty > 0:
if warehouse and qty > 0 and frappe.db.get_value('Item', d.item_code, 'has_batch_no'):
if not d.batch_no:
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw, d.serial_no)
else:
Expand Down Expand Up @@ -308,4 +307,4 @@ def validate_serial_no_with_batch(serial_nos, item_code):

message = "Serial Nos" if len(serial_nos) > 1 else "Serial No"
frappe.throw(_("There is no batch found against the {0}: {1}")
.format(message, serial_no_link))
.format(message, serial_no_link))
5 changes: 2 additions & 3 deletions erpnext/stock/doctype/delivery_note/delivery_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,8 @@ def validate_warehouse(self):
super(DeliveryNote, self).validate_warehouse()

for d in self.get_item_list():
if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == 1:
if not d['warehouse']:
frappe.throw(_("Warehouse required for stock Item {0}").format(d["item_code"]))
if not d['warehouse'] and frappe.db.get_value("Item", d['item_code'], "is_stock_item", cache=True) == 1:
frappe.throw(_("Warehouse required for stock Item {0}").format(d["item_code"]))


def update_current_stock(self):
Expand Down
2 changes: 1 addition & 1 deletion erpnext/stock/doctype/material_request/material_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def update_requested_qty(self, mr_item_rows=None):
item_wh_list = []
for d in self.get("items"):
if (not mr_item_rows or d.name in mr_item_rows) and [d.item_code, d.warehouse] not in item_wh_list \
and frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and d.warehouse:
and d.warehouse and frappe.db.get_value("Item", d.item_code, "is_stock_item", cache=True) == 1 :
item_wh_list.append([d.item_code, d.warehouse])

for item_code, warehouse in item_wh_list:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@
"fieldname": "is_cancelled",
"fieldtype": "Check",
"label": "Is Cancelled",
"report_hide": 1
"report_hide": 1,
"search_index": 1
},
{
"default": "1",
Expand Down Expand Up @@ -316,7 +317,7 @@
"in_create": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2020-09-07 11:10:35.318872",
"modified": "2021-06-23 20:45:54.140217",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Ledger Entry",
Expand Down

0 comments on commit 7d4139e

Please sign in to comment.