From c80059e10e72f849f82acf1c2f95bd5d48e5a1a0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 28 Jul 2015 11:14:01 +0530 Subject: [PATCH 1/2] [fix] Ignore making SLE for opening stock reco with zero qty --- .../doctype/stock_reconciliation/stock_reconciliation.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index efa6a8a25d..bed8dd7e56 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -163,16 +163,17 @@ class StockReconciliation(StockController): }) if previous_sle: if row.qty in ("", None): - row.qty = previous_sle.get("qty_after_transaction") + row.qty = previous_sle.get("qty_after_transaction", 0) if row.valuation_rate in ("", None): - row.valuation_rate = previous_sle.get("valuation_rate") + row.valuation_rate = previous_sle.get("valuation_rate", 0) if row.qty and not row.valuation_rate: frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) - if previous_sle and row.qty == previous_sle.get("qty_after_transaction") \ - and row.valuation_rate == previous_sle.get("valuation_rate"): + if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction") + and row.valuation_rate == previous_sle.get("valuation_rate")) + or (not previous_sle and not row.qty)): continue self.insert_entries(row) From 9088432f1054c1a76be2c3ebf109f0afbc66b367 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 28 Jul 2015 11:16:14 +0530 Subject: [PATCH 2/2] Fetch default expense account and cost center from item if company matches, otherwise fetch from company master --- erpnext/manufacturing/doctype/bom/bom.py | 13 ++++++++++--- erpnext/manufacturing/doctype/bom/test_bom.py | 6 +++--- erpnext/stock/doctype/stock_entry/stock_entry.py | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index fe67ed8057..5a3bbcdaeb 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -364,7 +364,7 @@ class BOM(Document): if self.with_operations and not self.get('operations'): frappe.throw(_("Operations cannot be left blank.")) -def get_bom_items_as_dict(bom, qty=1, fetch_exploded=1): +def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1): item_dict = {} # Did not use qty_consumed_per_unit in the query, as it leads to rounding loss @@ -405,11 +405,18 @@ def get_bom_items_as_dict(bom, qty=1, fetch_exploded=1): else: item_dict[item.item_code] = item + for item, item_details in item_dict.items(): + for d in [["Account", "expense_account", "default_expense_account"], + ["Cost Center", "cost_center", "cost_center"], ["Warehouse", "default_warehouse", ""]]: + company_in_record = frappe.db.get_value(d[0], item_details.get(d[1]), "company") + if not item_details.get(d[1]) or (company_in_record and company != company_in_record): + item_dict[item][d[1]] = frappe.db.get_value("Company", company, d[2]) if d[2] else None + return item_dict @frappe.whitelist() -def get_bom_items(bom, qty=1, fetch_exploded=1): - items = get_bom_items_as_dict(bom, qty, fetch_exploded).values() +def get_bom_items(bom, company, qty=1, fetch_exploded=1): + items = get_bom_items_as_dict(bom, company, qty, fetch_exploded).values() items.sort(lambda a, b: a.item_code > b.item_code and 1 or -1) return items diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py index 528c62663b..4e520ef233 100644 --- a/erpnext/manufacturing/doctype/bom/test_bom.py +++ b/erpnext/manufacturing/doctype/bom/test_bom.py @@ -12,14 +12,14 @@ test_records = frappe.get_test_records('BOM') class TestBOM(unittest.TestCase): def test_get_items(self): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict - items_dict = get_bom_items_as_dict(bom=get_default_bom(), qty=1, fetch_exploded=0) + items_dict = get_bom_items_as_dict(bom=get_default_bom(), company="_Test Company", qty=1, fetch_exploded=0) self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict) self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict) self.assertEquals(len(items_dict.values()), 2) def test_get_items_exploded(self): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict - items_dict = get_bom_items_as_dict(bom=get_default_bom(), qty=1, fetch_exploded=1) + items_dict = get_bom_items_as_dict(bom=get_default_bom(), company="_Test Company", qty=1, fetch_exploded=1) self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict) self.assertFalse(test_records[2]["items"][1]["item_code"] in items_dict) self.assertTrue(test_records[0]["items"][0]["item_code"] in items_dict) @@ -28,7 +28,7 @@ class TestBOM(unittest.TestCase): def test_get_items_list(self): from erpnext.manufacturing.doctype.bom.bom import get_bom_items - self.assertEquals(len(get_bom_items(bom=get_default_bom())), 3) + self.assertEquals(len(get_bom_items(bom=get_default_bom(), company="_Test Company")), 3) def test_default_bom(self): def _get_default_bom_in_item(): diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 1b01f3aa68..31484553ef 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -553,7 +553,7 @@ class StockEntry(StockController): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict # item dict = { item_code: {qty, description, stock_uom} } - item_dict = get_bom_items_as_dict(self.bom_no, qty=qty, fetch_exploded = self.use_multi_level_bom) + item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty, fetch_exploded = self.use_multi_level_bom) for item in item_dict.values(): item.from_warehouse = self.from_warehouse or item.default_warehouse