Merge pull request #3701 from neilLasrado/po
Disallowed End of Life Items from getting selected in Production Orders and Stock Reconciliation
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 17fa202..151854c 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -262,7 +262,8 @@
return {
filters:[
['Item', 'is_pro_applicable', '=', 'Yes'],
- ['Item', 'has_variants', '=', 'No']
+ ['Item', 'has_variants', '=', 'No'],
+ ['Item', 'end_of_life', '>=', frappe.datetime.nowdate()]
]
}
}
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 93ce5e1..c2cbbfd 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -9,10 +9,13 @@
from frappe.model.document import Document
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
from dateutil.relativedelta import relativedelta
+from erpnext.stock.doctype.item.item import validate_end_of_life
class OverProductionError(frappe.ValidationError): pass
class StockOverProductionError(frappe.ValidationError): pass
class OperationTooLongError(frappe.ValidationError): pass
+class ProductionNotApplicableError(frappe.ValidationError): pass
+class ItemHasVariantError(frappe.ValidationError): pass
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
from erpnext.projects.doctype.time_log.time_log import OverlapError
@@ -325,10 +328,12 @@
def validate_production_item(self):
if frappe.db.get_value("Item", self.production_item, "is_pro_applicable")=='No':
- frappe.throw(_("Item is not allowed to have Production Order."))
+ frappe.throw(_("Item is not allowed to have Production Order."), ProductionNotApplicableError)
if frappe.db.get_value("Item", self.production_item, "has_variants"):
- frappe.throw(_("Production Order cannot be raised against a Item Template"))
+ frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError)
+
+ validate_end_of_life(self.production_item)
@frappe.whitelist()
def get_item_details(item):
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py
index 34d584a..b91b2e1 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py
@@ -7,7 +7,8 @@
import frappe
from frappe.utils import flt, get_datetime, time_diff_in_hours
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
-from erpnext.manufacturing.doctype.production_order.production_order import make_stock_entry, make_time_log
+from erpnext.manufacturing.doctype.production_order.production_order \
+ import make_stock_entry, make_time_log, ProductionNotApplicableError,ItemHasVariantError
from erpnext.stock.doctype.stock_entry import test_stock_entry
from erpnext.projects.doctype.time_log.time_log import OverProductionLoggedError
@@ -135,6 +136,22 @@
prod_order.set_production_order_operations()
self.assertEqual(prod_order.planned_operating_cost, cost*2)
+ def test_production_item(self):
+ frappe.db.set_value("Item", "_Test FG Item", "is_pro_applicable", "No")
+
+ prod_order = make_prod_order_test_record(item="_Test FG Item", qty=1, do_not_save=True)
+ self.assertRaises(ProductionNotApplicableError, prod_order.save)
+
+ frappe.db.set_value("Item", "_Test FG Item", "is_pro_applicable", "Yes")
+ frappe.db.set_value("Item", "_Test FG Item", "end_of_life", "2000-1-1")
+
+ self.assertRaises(frappe.ValidationError, prod_order.save)
+
+ frappe.db.set_value("Item", "_Test FG Item", "end_of_life", None)
+
+ prod_order = make_prod_order_test_record(item="_Test Variant Item", qty=1, do_not_save=True)
+ self.assertRaises(ItemHasVariantError, prod_order.save)
+
def make_prod_order_test_record(**args):
args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index c0ae213..f833a25 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -98,3 +98,11 @@
cur_frm.cscript.posting_date = function(doc, cdt, cdn){
erpnext.get_fiscal_year(doc.company, doc.posting_date);
}
+
+cur_frm.fields_dict.items.grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
+ return {
+ filters:[
+ ['Item', 'end_of_life', '>=', frappe.datetime.nowdate()]
+ ]
+ }
+}
\ No newline at end of file