diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index af26d7b6689..e0fcf47365f 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -396,38 +396,54 @@ class StockController(AccountsController): def validate_putaway_capacity(self): # if over receipt is attempted while 'apply putaway rule' is disabled # and if rule was applied on the transaction, validate it. - from erpnext.stock.doctype.putaway_rule.putaway_rule import get_putaway_capacity - valid_doctype = self.doctype in ("Purchase Receipt", "Stock Entry") - rule_applied = any(item.get("putaway_rule") for item in self.get("items")) + from erpnext.stock.doctype.putaway_rule.putaway_rule import get_available_putaway_capacity + valid_doctype = self.doctype in ("Purchase Receipt", "Stock Entry", "Purchase Invoice", + "Stock Reconciliation") - if valid_doctype and rule_applied and not self.apply_putaway_rule: + if self.doctype == "Purchase Invoice" and self.get("update_stock") == 0: + valid_doctype = False + + if valid_doctype: rule_map = defaultdict(dict) for item in self.get("items"): - if item.get("putaway_rule"): - rule = item.get("putaway_rule") - disabled = frappe.db.get_value("Putaway Rule", rule, "disable") - if disabled: return # dont validate for disabled rule - stock_qty = flt(item.transfer_qty) if self.doctype == "Stock Entry" else flt(item.stock_qty) - warehouse_field = "t_warehouse" if self.doctype == "Stock Entry" else "warehouse" - if not rule_map[rule]: - rule_map[rule]["warehouse"] = item.get(warehouse_field) - rule_map[rule]["item"] = item.get("item_code") - rule_map[rule]["qty_put"] = 0 - rule_map[rule]["capacity"] = get_putaway_capacity(rule) - rule_map[rule]["qty_put"] += flt(stock_qty) + warehouse_field = "t_warehouse" if self.doctype == "Stock Entry" else "warehouse" + rule = frappe.db.get_value("Putaway Rule", + { + "item_code": item.get("item_code"), + "warehouse": item.get(warehouse_field) + }, + ["name", "disable"], as_dict=True) + if rule: + if rule.get("disabled"): continue # dont validate for disabled rule + + if self.doctype == "Stock Reconciliation": + stock_qty = flt(item.qty) + else: + stock_qty = flt(item.transfer_qty) if self.doctype == "Stock Entry" else flt(item.stock_qty) + + rule_name = rule.get("name") + if not rule_map[rule_name]: + rule_map[rule_name]["warehouse"] = item.get(warehouse_field) + rule_map[rule_name]["item"] = item.get("item_code") + rule_map[rule_name]["qty_put"] = 0 + rule_map[rule_name]["capacity"] = get_available_putaway_capacity(rule_name) + rule_map[rule_name]["qty_put"] += flt(stock_qty) for rule, values in rule_map.items(): if flt(values["qty_put"]) > flt(values["capacity"]): - message = _("{0} qty of Item {1} is being received into Warehouse {2} with capacity {3}.") \ - .format( - frappe.bold(values["qty_put"]), frappe.bold(values["item"]), - frappe.bold(values["warehouse"]), frappe.bold(values["capacity"]) - ) - message += "

" - rule_link = frappe.utils.get_link_to_form("Putaway Rule", rule) - message += _(" Please adjust the qty or edit {0} to proceed.").format(rule_link) + message = self.prepare_over_receipt_message(rule, values) frappe.throw(msg=message, title=_("Over Receipt")) - return rule_map + + def prepare_over_receipt_message(self, rule, values): + message = _("{0} qty of Item {1} is being received into Warehouse {2} with capacity {3}.") \ + .format( + frappe.bold(values["qty_put"]), frappe.bold(values["item"]), + frappe.bold(values["warehouse"]), frappe.bold(values["capacity"]) + ) + message += "

" + rule_link = frappe.utils.get_link_to_form("Putaway Rule", rule) + message += _(" Please adjust the qty or edit {0} to proceed.").format(rule_link) + return message def repost_future_sle_and_gle(self): args = frappe._dict({ diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 5e6a3f22b5e..61c531067ca 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -86,7 +86,7 @@ class PurchaseReceipt(BuyingController): def before_validate(self): from erpnext.stock.doctype.putaway_rule.putaway_rule import apply_putaway_rule - if self.get("items") and self.apply_putaway_rule: + if self.get("items") and self.apply_putaway_rule and not self.get("is_return"): apply_putaway_rule(self.doctype, self.get("items"), self.company) def validate(self): @@ -415,7 +415,7 @@ class PurchaseReceipt(BuyingController): if warehouse_with_no_account: frappe.msgprint(_("No accounting entries for the following warehouses") + ": \n" + "\n".join(warehouse_with_no_account)) - + return process_gl_map(gl_entries) def get_asset_gl_entry(self, gl_entries): diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.py b/erpnext/stock/doctype/putaway_rule/putaway_rule.py index 56752583fa7..ea26caced04 100644 --- a/erpnext/stock/doctype/putaway_rule/putaway_rule.py +++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.py @@ -44,7 +44,7 @@ class PutawayRule(Document): stock_uom = frappe.db.get_value("Item", self.item_code, "stock_uom") balance_qty = get_stock_balance(self.item_code, self.warehouse, nowdate()) - if flt(self.stock_capacity) < flt(balance_qty) and self.get('__islocal'): + if flt(self.stock_capacity) < flt(balance_qty): frappe.throw(_("Warehouse Capacity for Item '{0}' must be greater than the existing stock level of {1} {2}.") .format(self.item_code, frappe.bold(balance_qty), stock_uom), title=_("Insufficient Capacity")) @@ -56,7 +56,7 @@ class PutawayRule(Document): self.stock_capacity = (flt(self.conversion_factor) or 1) * flt(self.capacity) @frappe.whitelist() -def get_putaway_capacity(rule): +def get_available_putaway_capacity(rule): stock_capacity, item_code, warehouse = frappe.db.get_value("Putaway Rule", rule, ["stock_capacity", "item_code", "warehouse"]) balance_qty = get_stock_balance(item_code, warehouse, nowdate()) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 5b40292ea8f..f0a90f9754b 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -30,6 +30,7 @@ class StockReconciliation(StockController): self.validate_data() self.validate_expense_account() self.set_total_qty_and_amount() + self.validate_putaway_capacity() if self._action=="submit": self.make_batches('warehouse')