From 9c3dca63fa252278eb9032bcb7f822cb3234e6d9 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Tue, 21 Jul 2015 13:27:18 +0530 Subject: [PATCH 1/4] Disallowed End of Life Items from getting selected in Production Orders and Stock Reconciliation --- .../doctype/production_order/production_order.js | 3 ++- .../doctype/production_order/production_order.py | 3 +++ .../doctype/production_order/test_production_order.py | 6 ++++++ .../doctype/stock_reconciliation/stock_reconciliation.js | 8 ++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index 17fa202a4d..50f46ca401 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -262,7 +262,8 @@ cur_frm.fields_dict['production_item'].get_query = function(doc) { return { filters:[ ['Item', 'is_pro_applicable', '=', 'Yes'], - ['Item', 'has_variants', '=', 'No'] + ['Item', 'has_variants', '=', 'No'], + ['Item', 'end_of_life', '>', frappe.datetime.now_datetime()] ] } } diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 93ce5e16f6..7a0921d513 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -9,6 +9,7 @@ from frappe import _ 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 @@ -329,6 +330,8 @@ class ProductionOrder(Document): if frappe.db.get_value("Item", self.production_item, "has_variants"): frappe.throw(_("Production Order cannot be raised against a Item Template")) + + 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 34d584a94a..f9aa03194a 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -135,6 +135,12 @@ class TestProductionOrder(unittest.TestCase): prod_order.set_production_order_operations() self.assertEqual(prod_order.planned_operating_cost, cost*2) + def test_production_item(self): + item = frappe.get_doc("Item", "_Test FG Item") + item.end_of_life = + + prod_order = make_prod_order_test_record(item="_Test FG Item", qty=1, do_not_save=True) + 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 c0ae213b87..b394b71a22 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.company = function(doc, cdt, cdn) { 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.now_datetime()] + ] + } +} \ No newline at end of file From 21647974c499c995d59593efaff70eccb2551ffd Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Tue, 21 Jul 2015 15:30:31 +0530 Subject: [PATCH 2/4] Test Cases Added to Production Order --- .../production_order/production_order.py | 6 ++++-- .../production_order/test_production_order.py | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 7a0921d513..c2cbbfd9d6 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -14,6 +14,8 @@ 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 @@ -326,10 +328,10 @@ class ProductionOrder(Document): 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) diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index f9aa03194a..c62be8260a 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 unittest 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 @@ -137,10 +138,24 @@ class TestProductionOrder(unittest.TestCase): def test_production_item(self): item = frappe.get_doc("Item", "_Test FG Item") - item.end_of_life = + item.is_pro_applicable= "No" + item.save() prod_order = make_prod_order_test_record(item="_Test FG Item", qty=1, do_not_save=True) + self.assertRaises(ProductionNotApplicableError, prod_order.save) + item.is_pro_applicable= "Yes" + item.end_of_life = "2000-1-1" + item.save() + + self.assertRaises(frappe.ValidationError, prod_order.save) + + item.end_of_life=None + item.save() + + 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) From f965c5d20327e0e580a9deb248bb681702734ff3 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Thu, 23 Jul 2015 16:56:27 +0530 Subject: [PATCH 3/4] now_datetime changed to nowdate --- .../manufacturing/doctype/production_order/production_order.js | 2 +- .../stock/doctype/stock_reconciliation/stock_reconciliation.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index 50f46ca401..151854c30a 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -263,7 +263,7 @@ cur_frm.fields_dict['production_item'].get_query = function(doc) { filters:[ ['Item', 'is_pro_applicable', '=', 'Yes'], ['Item', 'has_variants', '=', 'No'], - ['Item', 'end_of_life', '>', frappe.datetime.now_datetime()] + ['Item', 'end_of_life', '>=', frappe.datetime.nowdate()] ] } } diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index b394b71a22..f833a251be 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -102,7 +102,7 @@ cur_frm.cscript.posting_date = function(doc, cdt, cdn){ cur_frm.fields_dict.items.grid.get_field('item_code').get_query = function(doc, cdt, cdn) { return { filters:[ - ['Item', 'end_of_life', '>', frappe.datetime.now_datetime()] + ['Item', 'end_of_life', '>=', frappe.datetime.nowdate()] ] } } \ No newline at end of file From 8a9d41a92edae41aacc959a4799f4dd8d74ff5a1 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Fri, 24 Jul 2015 13:18:45 +0530 Subject: [PATCH 4/4] Modified Test Cases for Production Order --- .../production_order/test_production_order.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index c62be8260a..b91b2e12c8 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -137,21 +137,17 @@ class TestProductionOrder(unittest.TestCase): self.assertEqual(prod_order.planned_operating_cost, cost*2) def test_production_item(self): - item = frappe.get_doc("Item", "_Test FG Item") - item.is_pro_applicable= "No" - item.save() - + 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) - item.is_pro_applicable= "Yes" - item.end_of_life = "2000-1-1" - item.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) - item.end_of_life=None - item.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)