Defaults in Item Group (#14874)
* Add Defaults table in Item Group
* Fetch defaults from Item group if not found in Item
* Add patch
* Remove default fields from Item Group
* Set query for defaults
* Fix Codacy
* Modify test records
* Modify budget.py and sales_order.py
* Remove join from query
* Else condition to avoid error if no defaults found
* refrain from making item test records before item_group
* default cost center fetch correction
* Remove tab item group from query
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 421d756..771ec8d 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -298,8 +298,7 @@
if not (cost_center and expense_account):
for doctype in ['Item Group', 'Company']:
- data = get_expense_cost_center(doctype,
- args.get(frappe.scrub(doctype)))
+ data = get_expense_cost_center(doctype, args)
if not cost_center and data:
cost_center = data[0]
@@ -312,8 +311,11 @@
return cost_center, expense_account
-def get_expense_cost_center(doctype, value):
- fields = (['default_cost_center', 'default_expense_account']
- if doctype == 'Item Group' else ['cost_center', 'default_expense_account'])
-
- return frappe.db.get_value(doctype, value, fields)
+def get_expense_cost_center(doctype, args):
+ if doctype == 'Item Group':
+ return frappe.db.get_value('Item Default',
+ {'parent': args.get(frappe.scrub(doctype)), 'company': args.get('company')},
+ ['buying_cost_center', 'expense_account'])
+ else:
+ return frappe.db.get_value(doctype, args.get(frappe.scrub(doctype)),\
+ ['cost_center', 'default_expense_account'])
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 5af3078..5b8204a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -15,6 +15,7 @@
from erpnext.stock.utils import get_bin
from six import string_types
from erpnext.stock.doctype.item.item import get_item_defaults
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -390,9 +391,10 @@
target.qty = target.amount / flt(obj.rate) if (flt(obj.rate) and flt(obj.billed_amt)) else flt(obj.qty)
item = get_item_defaults(target.item_code, source_parent.company)
+ item_group = get_item_group_defaults(target.item_code, source_parent.company)
target.cost_center = frappe.db.get_value("Project", obj.project, "cost_center") \
or item.get("buying_cost_center") \
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or item_group.get("buying_cost_center")
doc = get_mapped_doc("Purchase Order", source_name, {
"Purchase Order": {
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index a22a9ec..70a0773 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -79,6 +79,12 @@
{"parent": d.item_code, "company": self.company}, "default_supplier")
if supplier:
self.supplier = supplier
+ else:
+ item_group = frappe.db.get_value("Item", d.item_code, "item_group")
+ supplier = frappe.db.get_value("Item Default",
+ {"parent": item_group, "company": self.company}, "default_supplier")
+ if supplier:
+ self.supplier = supplier
break
def validate_stock_or_nonstock_items(self):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 507f9f5..f66f2a2 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -559,3 +559,4 @@
erpnext.patches.v11_0.set_department_for_doctypes
erpnext.patches.v11_0.update_allow_transfer_for_manufacture
erpnext.patches.v11_0.rename_healthcare_doctype_and_fields
+erpnext.patches.v11_0.add_item_group_defaults
diff --git a/erpnext/patches/v11_0/add_item_group_defaults.py b/erpnext/patches/v11_0/add_item_group_defaults.py
new file mode 100644
index 0000000..2a15ad1
--- /dev/null
+++ b/erpnext/patches/v11_0/add_item_group_defaults.py
@@ -0,0 +1,73 @@
+# Copyright (c) 2018, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ '''
+
+ Fields to move from item group to item defaults child table
+ [ default_cost_center, default_expense_account, default_income_account ]
+
+ '''
+
+ frappe.reload_doc('stock', 'doctype', 'item_default')
+ frappe.reload_doc('setup', 'doctype', 'item_group')
+
+ companies = frappe.get_all("Company")
+ item_groups = frappe.db.sql("""select name, default_income_account, default_expense_account,\
+ default_cost_center from `tabItem Group`""", as_dict=True)
+
+ if len(companies) == 1:
+ for item_group in item_groups:
+ doc = frappe.get_doc("Item Group", item_group.get("name"))
+ item_group_defaults = []
+ item_group_defaults.append({
+ "company": companies[0].name,
+ "income_account": item_group.get("default_income_account"),
+ "expense_account": item_group.get("default_expense_account"),
+ "buying_cost_center": item_group.get("default_cost_center"),
+ "selling_cost_center": item_group.get("default_cost_center")
+ })
+ doc.extend("item_group_defaults", item_group_defaults)
+ for child_doc in doc.item_group_defaults:
+ child_doc.db_insert()
+ else:
+ item_group_dict = {
+ "default_expense_account": ["expense_account"],
+ "default_income_account": ["income_account"],
+ "default_cost_center": ["buying_cost_center", "selling_cost_center"]
+ }
+ for item_group in item_groups:
+ item_group_defaults = []
+ def insert_into_item_defaults(doc_field_name, doc_field_value, company):
+ for d in item_group_defaults:
+ if d.get("company") == company:
+ d[doc_field_name[0]] = doc_field_value
+ if len(doc_field_name) > 1:
+ d[doc_field_name[1]] = doc_field_value
+ return
+
+ item_group_defaults.append({
+ "company": company,
+ doc_field_name[0]: doc_field_value
+ })
+
+ if(len(doc_field_name) > 1):
+ item_group_defaults[len(item_group_defaults)-1][doc_field_name[1]] = doc_field_value
+
+ for d in [
+ ["default_expense_account", "Account"], ["default_income_account", "Account"],
+ ["default_cost_center", "Cost Center"]
+ ]:
+ if item_group.get(d[0]):
+ company = frappe.get_value(d[1], item_group.get(d[0]), "company", cache=True)
+ doc_field_name = item_group_dict.get(d[0])
+
+ insert_into_item_defaults(doc_field_name, item_group.get(d[0]), company)
+
+ doc = frappe.get_doc("Item Group", item_group.get("name"))
+ doc.extend("item_group_defaults", item_group_defaults)
+ for child_doc in doc.item_group_defaults:
+ child_doc.db_insert()
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 8d47416..3ec4a23 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -16,7 +16,7 @@
from frappe.desk.doctype.auto_repeat.auto_repeat import get_next_schedule_date
from erpnext.selling.doctype.customer.customer import check_credit_limit
from erpnext.stock.doctype.item.item import get_item_defaults
-
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -513,11 +513,12 @@
target.qty = flt(source.qty) - flt(source.delivered_qty)
item = get_item_defaults(target.item_code, source_parent.company)
+ item_group = get_item_group_defaults(target.item_code, source_parent.company)
if item:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
or item.get("selling_cost_center") \
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or item_group.get("selling_cost_center")
target_doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
@@ -581,8 +582,9 @@
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center")
if not target.cost_center and target.item_code:
item = get_item_defaults(target.item_code, target.company)
+ item_group = get_item_group_defaults(target.item_code, target.company)
target.cost_center = item.get("selling_cost_center") \
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or item_group.get("selling_cost_center")
doclist = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index c55c7cb..df22231 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -14,6 +14,40 @@
]
}
}
+ frm.fields_dict["item_group_defaults"].grid.get_field("expense_account").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ query: "erpnext.controllers.queries.get_expense_account",
+ filters: { company: row.company }
+ }
+ }
+ frm.fields_dict["item_group_defaults"].grid.get_field("income_account").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ query: "erpnext.controllers.queries.get_income_account",
+ filters: { company: row.company }
+ }
+ }
+
+ frm.fields_dict["item_group_defaults"].grid.get_field("buying_cost_center").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ filters: {
+ "is_group": 0,
+ "company": row.company
+ }
+ }
+ }
+
+ frm.fields_dict["item_group_defaults"].grid.get_field("selling_cost_center").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ filters: {
+ "is_group": 0,
+ "company": row.company
+ }
+ }
+ }
},
refresh: function(frm) {
diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json
index 29486b2..0a16a29 100644
--- a/erpnext/setup/doctype/item_group/item_group.json
+++ b/erpnext/setup/doctype/item_group/item_group.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:item_group_name",
@@ -13,6 +14,8 @@
"editable_grid": 0,
"fields": [
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -38,9 +41,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -68,9 +74,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "unique": 0
+ "translatable": 0,
+ "unique": 1
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -100,9 +109,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -132,9 +144,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -159,15 +174,18 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "default_income_account",
- "fieldtype": "Link",
+ "fieldname": "defaults",
+ "fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -175,11 +193,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Default Income Account",
+ "label": "Defaults",
"length": 0,
"no_copy": 0,
- "options": "Account",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -188,15 +206,18 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "default_expense_account",
- "fieldtype": "Link",
+ "fieldname": "item_group_defaults",
+ "fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -204,11 +225,12 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Default Expense Account",
+ "label": "Item Group Defaults",
"length": 0,
"no_copy": 0,
- "options": "Account",
+ "options": "Item Default",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -217,38 +239,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -274,9 +270,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -303,9 +302,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -333,9 +335,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 1
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -364,9 +369,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -394,9 +402,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -424,9 +435,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -454,9 +468,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -484,9 +501,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -516,21 +536,22 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
+ "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-sitemap",
"idx": 1,
"image_view": 0,
"in_create": 0,
-
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 3,
- "modified": "2017-02-20 13:24:59.364873",
+ "modified": "2018-07-11 16:07:56.050363",
"modified_by": "Administrator",
"module": "Setup",
"name": "Item Group",
@@ -539,7 +560,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -559,7 +579,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -579,7 +598,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -599,7 +617,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -619,7 +636,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -639,7 +655,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -665,5 +680,6 @@
"show_name_in_global_search": 1,
"sort_order": "DESC",
"track_changes": 0,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 230b740..d4f16be 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -173,3 +173,19 @@
item_group_name = frappe.db.get_value("Item Group", d.get('name'))
if item_group_name:
clear_cache(frappe.db.get_value('Item Group', item_group_name, 'route'))
+
+def get_item_group_defaults(item, company):
+ item_group = frappe.db.get_value("Item", item, "item_group")
+ item_group_defaults = frappe.db.sql('''
+ select
+ expense_account, income_account, buying_cost_center, default_warehouse,
+ selling_cost_center, default_supplier
+ from
+ `tabItem Default` where company = %s and parent = %s and parenttype = 'Item Group'
+ ''', (company, item_group), as_dict=1)
+
+ if item_group_defaults:
+ return item_group_defaults[0]
+ else:
+ return frappe.db.get_value("Item", item, ["name", "item_name", "description", "stock_uom",
+ "is_stock_item", "item_code", "item_group"], as_dict=1)
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/test_item_group.js b/erpnext/setup/doctype/item_group/test_item_group.js
new file mode 100644
index 0000000..ea322e2
--- /dev/null
+++ b/erpnext/setup/doctype/item_group/test_item_group.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Item Group", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Item Group
+ () => frappe.tests.make('Item Group', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/setup/doctype/item_group/test_records.json b/erpnext/setup/doctype/item_group/test_records.json
index 74f4641..436535e 100644
--- a/erpnext/setup/doctype/item_group/test_records.json
+++ b/erpnext/setup/doctype/item_group/test_records.json
@@ -4,7 +4,11 @@
"is_group": 0,
"item_group_name": "_Test Item Group",
"parent_item_group": "All Item Groups",
- "default_cost_center": "_Test Cost Center 2 - _TC"
+ "item_group_defaults": [{
+ "company": "_Test Company",
+ "buying_cost_center": "_Test Cost Center 2 - _TC",
+ "selling_cost_center": "_Test Cost Center 2 - _TC"
+ }]
},
{
"doctype": "Item Group",
diff --git a/erpnext/setup/doctype/sales_partner/test_sales_partner.py b/erpnext/setup/doctype/sales_partner/test_sales_partner.py
index a4ae807..4548a4e 100644
--- a/erpnext/setup/doctype/sales_partner/test_sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/test_sales_partner.py
@@ -4,4 +4,6 @@
import frappe
-test_records = frappe.get_test_records('Sales Partner')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Partner')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/doctype/sales_person/test_sales_person.py b/erpnext/setup/doctype/sales_person/test_sales_person.py
index 10b5f7c..8313cb4 100644
--- a/erpnext/setup/doctype/sales_person/test_sales_person.py
+++ b/erpnext/setup/doctype/sales_person/test_sales_person.py
@@ -5,4 +5,6 @@
test_dependencies = ["Employee"]
import frappe
-test_records = frappe.get_test_records('Sales Person')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Person')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/doctype/territory/test_territory.py b/erpnext/setup/doctype/territory/test_territory.py
index 5ec8e4a..efe00c5 100644
--- a/erpnext/setup/doctype/territory/test_territory.py
+++ b/erpnext/setup/doctype/territory/test_territory.py
@@ -4,4 +4,6 @@
import frappe
-test_records = frappe.get_test_records('Territory')
\ No newline at end of file
+test_records = frappe.get_test_records('Territory')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 5c35bec..7ef4f8c 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -17,7 +17,7 @@
from six import iteritems
test_ignore = ["BOM"]
-test_dependencies = ["Warehouse"]
+test_dependencies = ["Warehouse", "Item Group"]
def make_item(item_code, properties=None):
if frappe.db.exists("Item", item_code):
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 011df70..89f90bf 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -9,6 +9,7 @@
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError, get_valuation_rate
from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos, get_batch_qty
from erpnext.stock.doctype.item.item import get_item_defaults
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, add_additional_cost
@@ -579,7 +580,7 @@
pro_doc.run_method("update_planned_qty")
def get_item_details(self, args=None, for_update=False):
- item = frappe.db.sql("""select i.stock_uom, i.description, i.image, i.item_name, i.item_group,
+ item = frappe.db.sql("""select i.name, i.stock_uom, i.description, i.image, i.item_name, i.item_group,
i.has_batch_no, i.sample_quantity, i.has_serial_no,
id.expense_account, id.buying_cost_center
from `tabItem` i LEFT JOIN `tabItem Default` id ON i.name=id.parent and id.company=%s
@@ -592,6 +593,7 @@
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get("item_code")))
item = item[0]
+ item_group_defaults = get_item_group_defaults(item.name, self.company)
ret = frappe._dict({
'uom' : item.stock_uom,
@@ -600,7 +602,7 @@
'image' : item.image,
'item_name' : item.item_name,
'expense_account' : args.get("expense_account"),
- 'cost_center' : get_default_cost_center(args, item),
+ 'cost_center' : get_default_cost_center(args, item, item_group_defaults),
'qty' : 0,
'transfer_qty' : 0,
'conversion_factor' : 1,
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 6d89187..f1afd1c 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -12,7 +12,7 @@
from erpnext.stock.doctype.batch.batch import get_batch_no
from erpnext import get_company_currency
from erpnext.stock.doctype.item.item import get_item_defaults
-
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from six import string_types, iteritems
@@ -208,7 +208,10 @@
if len(user_default_warehouse_list) == 1 else ""
item_defaults = get_item_defaults(item.name, args.company)
- warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or args.warehouse
+ item_group_defaults = get_item_group_defaults(item.name, args.company)
+
+ warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or\
+ item_group_defaults.get("default_warehouse") or args.warehouse
material_request_type = ''
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
@@ -231,9 +234,9 @@
"description": cstr(item.description).strip(),
"image": cstr(item.image).strip(),
"warehouse": warehouse,
- "income_account": get_default_income_account(args, item_defaults),
- "expense_account": get_default_expense_account(args, item_defaults),
- "cost_center": get_default_cost_center(args, item_defaults),
+ "income_account": get_default_income_account(args, item_defaults, item_group_defaults),
+ "expense_account": get_default_expense_account(args, item_defaults, item_group_defaults),
+ "cost_center": get_default_cost_center(args, item_defaults, item_group_defaults),
'has_serial_no': item.has_serial_no,
'has_batch_no': item.has_batch_no,
"batch_no": None,
@@ -252,7 +255,7 @@
"net_rate": 0.0,
"net_amount": 0.0,
"discount_percentage": 0.0,
- "supplier": item_defaults.get("default_supplier"),
+ "supplier": get_default_supplier(args, item_defaults, item_group_defaults),
"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
"is_fixed_asset": item.is_fixed_asset,
@@ -299,15 +302,15 @@
return out
-def get_default_income_account(args, item):
+def get_default_income_account(args, item, item_group):
return (item.get("income_account")
- or args.income_account
- or frappe.db.get_value("Item Group", item.item_group, "default_income_account"))
+ or item_group.get("income_account")
+ or args.income_account)
-def get_default_expense_account(args, item):
+def get_default_expense_account(args, item, item_group):
return (item.get("expense_account")
- or args.expense_account
- or frappe.db.get_value("Item Group", item.item_group, "default_expense_account"))
+ or item_group.get("expense_account")
+ or args.expense_account)
def get_default_deferred_revenue_account(args, item):
if item.enable_deferred_revenue:
@@ -317,12 +320,16 @@
else:
return None
-def get_default_cost_center(args, item):
+def get_default_cost_center(args, item, item_group):
return (frappe.db.get_value("Project", args.get("project"), "cost_center")
or (item.get("selling_cost_center") if args.get("customer") else item.get("buying_cost_center"))
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or (item_group.get("selling_cost_center") if args.get("customer") else item_group.get("buying_cost_center"))
or args.get("cost_center"))
+def get_default_supplier(args, item, item_group):
+ return (item.get("default_supplier")
+ or item_group.get("default_supplier"))
+
def get_price_list_rate(args, item_doc, out):
meta = frappe.get_meta(args.parenttype or args.doctype)
@@ -686,10 +693,11 @@
def get_valuation_rate(item_code, company, warehouse=None):
item = get_item_defaults(item_code, company)
+ item_group = get_item_group_defaults(item_code, company)
# item = frappe.get_doc("Item", item_code)
if item.get("is_stock_item"):
if not warehouse:
- warehouse = item.get("default_warehouse")
+ warehouse = item.get("default_warehouse") or item_group.get("default_warehouse")
return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
["valuation_rate"], as_dict=True) or {"valuation_rate": 0}