perf: single update per Sales Order.

For each SO item the sales order picking status was being updated, this
isn't required and wasteful.
This commit is contained in:
Ankush Menat 2022-04-22 15:31:41 +05:30
parent e64cc66df7
commit c3fc0a4f55
2 changed files with 27 additions and 12 deletions

View File

@ -385,6 +385,16 @@ class SalesOrder(SellingController):
if tot_qty != 0: if tot_qty != 0:
self.db_set("per_delivered", flt(delivered_qty / tot_qty) * 100, update_modified=False) self.db_set("per_delivered", flt(delivered_qty / tot_qty) * 100, update_modified=False)
def update_picking_status(self):
total_picked_qty = 0.0
total_qty = 0.0
for so_item in self.items:
total_picked_qty += flt(so_item.picked_qty)
total_qty += flt(so_item.stock_qty)
per_picked = total_picked_qty / total_qty * 100
self.db_set("per_picked", flt(per_picked), update_modified=False)
def set_indicator(self): def set_indicator(self):
"""Set indicator for portal""" """Set indicator for portal"""
if self.per_billed < 100 and self.per_delivered < 100: if self.per_billed < 100 and self.per_delivered < 100:

View File

@ -5,6 +5,7 @@ import json
from collections import OrderedDict, defaultdict from collections import OrderedDict, defaultdict
from itertools import groupby from itertools import groupby
from operator import itemgetter from operator import itemgetter
from typing import Set
import frappe import frappe
from frappe import _ from frappe import _
@ -39,6 +40,8 @@ class PickList(Document):
) )
def before_submit(self): def before_submit(self):
update_sales_orders = set()
for item in self.locations: for item in self.locations:
# if the user has not entered any picked qty, set it to stock_qty, before submit # if the user has not entered any picked qty, set it to stock_qty, before submit
if item.picked_qty == 0: if item.picked_qty == 0:
@ -47,6 +50,7 @@ class PickList(Document):
if item.sales_order_item: if item.sales_order_item:
# update the picked_qty in SO Item # update the picked_qty in SO Item
self.update_sales_order_item(item, item.picked_qty, item.item_code) self.update_sales_order_item(item, item.picked_qty, item.item_code)
update_sales_orders.add(item.sales_order)
if not frappe.get_cached_value("Item", item.item_code, "has_serial_no"): if not frappe.get_cached_value("Item", item.item_code, "has_serial_no"):
continue continue
@ -66,11 +70,18 @@ class PickList(Document):
title=_("Quantity Mismatch"), title=_("Quantity Mismatch"),
) )
self.update_sales_order_picking_status(update_sales_orders)
def before_cancel(self): def before_cancel(self):
# update picked_qty in SO Item on cancel of PL """Deduct picked qty on cancelling pick list"""
updated_sales_orders = set()
for item in self.get("locations"): for item in self.get("locations"):
if item.sales_order_item: if item.sales_order_item:
self.update_sales_order_item(item, -1 * item.picked_qty, item.item_code) self.update_sales_order_item(item, -1 * item.picked_qty, item.item_code)
updated_sales_orders.add(item.sales_order)
self.update_sales_order_picking_status(updated_sales_orders)
def update_sales_order_item(self, item, picked_qty, item_code): def update_sales_order_item(self, item, picked_qty, item_code):
item_table = "Sales Order Item" if not item.product_bundle_item else "Packed Item" item_table = "Sales Order Item" if not item.product_bundle_item else "Packed Item"
@ -91,17 +102,11 @@ class PickList(Document):
frappe.db.set_value(item_table, item.sales_order_item, "picked_qty", already_picked + picked_qty) frappe.db.set_value(item_table, item.sales_order_item, "picked_qty", already_picked + picked_qty)
# TODO: only do this once after all items @staticmethod
sales_order = frappe.get_doc("Sales Order", item.sales_order) def update_sales_order_picking_status(sales_orders: Set[str]) -> None:
total_picked_qty = 0 for sales_order in sales_orders:
total_so_qty = 0 if sales_order:
for so_item in sales_order.get("items"): frappe.get_doc("Sales Order", sales_order).update_picking_status()
total_picked_qty += flt(so_item.picked_qty)
total_so_qty += flt(so_item.stock_qty)
total_picked_qty = total_picked_qty + picked_qty
per_picked = total_picked_qty / total_so_qty * 100
sales_order.db_set("per_picked", flt(per_picked), update_modified=False)
@frappe.whitelist() @frappe.whitelist()
def set_item_locations(self, save=False): def set_item_locations(self, save=False):