feat: add validation for on hold purchase order
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 5c0e8fa..857842d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -96,7 +96,7 @@
},
get_query_filters: {
docstatus: 1,
- status: ["!=", "Closed"],
+ status: ["not in", ["Closed", "On Hold"]],
per_billed: ["<", 99.99],
company: me.frm.doc.company
}
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index c0d0d83..5080ccf 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -15,7 +15,7 @@
from erpnext.stock import get_warehouse_account_map
from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entries, delete_gl_entries
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
-from erpnext.buying.utils import check_for_closed_status
+from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
from erpnext.assets.doctype.asset.asset import get_asset_account
from frappe.model.mapper import get_mapped_doc
@@ -93,7 +93,7 @@
self.check_conversion_rate()
self.validate_credit_to_acc()
self.clear_unallocated_advances("Purchase Invoice Advance", "advances")
- self.check_for_closed_status()
+ self.check_on_hold_or_closed_status()
self.validate_with_previous_doc()
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", "stock_qty")
@@ -156,13 +156,13 @@
self.party_account_currency = account.account_currency
- def check_for_closed_status(self):
+ def check_on_hold_or_closed_status(self):
check_list = []
for d in self.get('items'):
if d.purchase_order and not d.purchase_order in check_list and not d.purchase_receipt:
check_list.append(d.purchase_order)
- check_for_closed_status('Purchase Order', d.purchase_order)
+ check_on_hold_or_closed_status('Purchase Order', d.purchase_order)
def validate_with_previous_doc(self):
super(PurchaseInvoice, self).validate_with_previous_doc({
@@ -754,7 +754,7 @@
def on_cancel(self):
super(PurchaseInvoice, self).on_cancel()
- self.check_for_closed_status()
+ self.check_on_hold_or_closed_status()
self.update_status_updater_args()
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 93805fb..f294ee4 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -11,7 +11,7 @@
from erpnext.stock.doctype.item.item import get_last_purchase_details
from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
from frappe.desk.notifications import clear_doctype_notifications
-from erpnext.buying.utils import validate_for_items, check_for_closed_status
+from erpnext.buying.utils import validate_for_items, check_on_hold_or_closed_status
from erpnext.stock.utils import get_bin
from erpnext.accounts.party import get_party_account_currency
from six import string_types
@@ -45,7 +45,7 @@
self.validate_supplier()
self.validate_schedule_date()
validate_for_items(self)
- self.check_for_closed_status()
+ self.check_on_hold_or_closed_status()
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", "stock_qty")
@@ -144,12 +144,12 @@
= d.rate = d.last_purchase_rate = item_last_purchase_rate
# Check for Closed status
- def check_for_closed_status(self):
+ def check_on_hold_or_closed_status(self):
check_list =[]
for d in self.get('items'):
if d.meta.get_field('material_request') and d.material_request and d.material_request not in check_list:
check_list.append(d.material_request)
- check_for_closed_status('Material Request', d.material_request)
+ check_on_hold_or_closed_status('Material Request', d.material_request)
def update_requested_qty(self):
material_request_map = {}
diff --git a/erpnext/buying/utils.py b/erpnext/buying/utils.py
index 9ad1c5c..981ee5d 100644
--- a/erpnext/buying/utils.py
+++ b/erpnext/buying/utils.py
@@ -73,10 +73,10 @@
not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items") or 0):
frappe.throw(_("Same item cannot be entered multiple times."))
-def check_for_closed_status(doctype, docname):
+def check_on_hold_or_closed_status(doctype, docname):
status = frappe.db.get_value(doctype, docname, "status")
- if status == "Closed":
+ if status in ("Closed", "On Hold"):
frappe.throw(_("{0} {1} status is {2}").format(doctype, docname, status), frappe.InvalidStatusError)
@frappe.whitelist()
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index a7fc845..0123101 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -88,7 +88,7 @@
},
get_query_filters: {
docstatus: 1,
- status: ["!=", "Closed"],
+ status: ["not in", ["Closed", "On Hold"]],
per_received: ["<", 99.99],
company: me.frm.doc.company
}
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index a3c1e27..1350e0c 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -12,7 +12,7 @@
from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.utils import get_account_currency
from frappe.desk.notifications import clear_doctype_notifications
-from erpnext.buying.utils import check_for_closed_status
+from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.assets.doctype.asset.asset import get_asset_account
from six import iteritems
@@ -62,7 +62,7 @@
self.validate_uom_is_integer("uom", ["qty", "received_qty"])
self.validate_uom_is_integer("stock_uom", "stock_qty")
- self.check_for_closed_status()
+ self.check_on_hold_or_closed_status()
if getdate(self.posting_date) > getdate(nowdate()):
throw(_("Posting Date cannot be future date"))
@@ -103,13 +103,13 @@
return po_qty, po_warehouse
# Check for Closed status
- def check_for_closed_status(self):
+ def check_on_hold_or_closed_status(self):
check_list =[]
for d in self.get('items'):
if (d.meta.get_field('purchase_order') and d.purchase_order
and d.purchase_order not in check_list):
check_list.append(d.purchase_order)
- check_for_closed_status('Purchase Order', d.purchase_order)
+ check_on_hold_or_closed_status('Purchase Order', d.purchase_order)
# on submit
def on_submit(self):
@@ -147,7 +147,7 @@
def on_cancel(self):
super(PurchaseReceipt, self).on_cancel()
- self.check_for_closed_status()
+ self.check_on_hold_or_closed_status()
# Check if Purchase Invoice has been submitted against current Purchase Order
submitted = frappe.db.sql("""select t1.name
from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2