From 554f6f70aab8fe15f4a055f1b40d055cbbf446aa Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 6 Jun 2016 14:22:37 +0530 Subject: [PATCH] [fixes] nested set fix for warehouse, tree for accounts and cost center --- .../doctype/account/account_treeview.js | 29 ++++++++++---- .../cost_center/cost_center_treeview.js | 1 + .../v7_0/create_warehouse_nestedset.py | 20 +++------- erpnext/setup/doctype/company/company.py | 5 +-- erpnext/stock/doctype/warehouse/warehouse.py | 40 +++++++++++++++++++ .../doctype/warehouse/warehouse_treeview.js | 20 +++++++++- erpnext/stock/utils.py | 22 +++++++--- 7 files changed, 105 insertions(+), 32 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_treeview.js b/erpnext/accounts/doctype/account/account_treeview.js index 673ef9f58fb..ce5eb8fa7c4 100644 --- a/erpnext/accounts/doctype/account/account_treeview.js +++ b/erpnext/accounts/doctype/account/account_treeview.js @@ -6,7 +6,8 @@ frappe.treeview_settings["Account"] = { fieldname: "comp", fieldtype:"Select", options: $.map(locals[':Company'], function(c) { return c.name; }).sort(), - label: __("Company") + label: __("Company"), + default: frappe.defaults.get_default('company') ? frappe.defaults.get_default('company'): "" }], root_label: "Accounts", get_tree_nodes: 'erpnext.accounts.page.accounts_browser.accounts_browser.get_children', @@ -24,14 +25,28 @@ frappe.treeview_settings["Account"] = { {fieldtype:'Check', fieldname:'is_group', label:__('Is Group'), description: __('Further accounts can be made under Groups, but entries can be made against non-Groups')}, {fieldtype:'Select', fieldname:'root_type', label:__('Root Type'), - options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n'), - }, + options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n')}, {fieldtype:'Select', fieldname:'account_type', label:__('Account Type'), options: ['', 'Bank', 'Cash', 'Warehouse', 'Tax', 'Chargeable'].join('\n'), - description: __("Optional. This setting will be used to filter in various transactions.") }, - {fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate')}, - {fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse"}, + description: __("Optional. This setting will be used to filter in various transactions."), + depends_on: 'eval:doc.is_group==1'}, + {fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'), + depends_on: 'eval:doc.is_group==1&&doc.account_type=="Tax"'}, + {fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse", + depends_on: 'eval:(doc.is_group==1&&doc.account_type=="Warehouse")'}, {fieldtype:'Link', fieldname:'account_currency', label:__('Currency'), options:"Currency", description: __("Optional. Sets company's default currency, if not specified.")} - ] + ], + onrender: function(node) { + var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr"; + if (node.data && node.data.balance!==undefined) { + $('' + + (node.data.balance_in_account_currency ? + (format_currency(Math.abs(node.data.balance_in_account_currency), + node.data.account_currency) + " / ") : "") + + format_currency(Math.abs(node.data.balance), node.data.company_currency) + + " " + dr_or_cr + + '').insertBefore(node.$ul); + } + } } \ No newline at end of file diff --git a/erpnext/accounts/doctype/cost_center/cost_center_treeview.js b/erpnext/accounts/doctype/cost_center/cost_center_treeview.js index c3a222d2ca5..eddf048446c 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center_treeview.js +++ b/erpnext/accounts/doctype/cost_center/cost_center_treeview.js @@ -6,6 +6,7 @@ frappe.treeview_settings["Cost Center"] = { fieldtype:"Select", options: $.map(locals[':Company'], function(c) { return c.name; }).sort(), label: __("Company"), + default: frappe.defaults.get_default('company') ? frappe.defaults.get_default('company'): "" }], root_label: "Cost Centers", get_tree_nodes: 'erpnext.accounts.page.accounts_browser.accounts_browser.get_children', diff --git a/erpnext/patches/v7_0/create_warehouse_nestedset.py b/erpnext/patches/v7_0/create_warehouse_nestedset.py index 01ae89165c9..78cc3999a21 100644 --- a/erpnext/patches/v7_0/create_warehouse_nestedset.py +++ b/erpnext/patches/v7_0/create_warehouse_nestedset.py @@ -2,17 +2,9 @@ import frappe from frappe import _ def execute(): - if not frappe.db.exists("Warehouse", {"warehouse_name": _("Warehouses")}): - parent_warehouse = frappe.get_doc({ - "doctype": "Warehouse", - "warehouse_name": _("Warehouses"), - "is_group": "Yes" - }).insert(ignore_permissions=True) - - for warehouse in frappe.db.sql_list("""select name from tabWarehouse - where name != %s order by name asc""", "Warehouses - SI"): - print warehouse - warehouse = frappe.get_doc("Warehouse", warehouse) - warehouse.is_group = "No" - warehouse.parent_warehouse = parent_warehouse.name - warehouse.save(ignore_permissions=True) \ No newline at end of file + for warehouse in frappe.db.sql_list("""select name from tabWarehouse + order by company asc, name asc"""): + warehouse = frappe.get_doc("Warehouse", warehouse) + warehouse.is_group = "No" + warehouse.parent_warehouse = "" + warehouse.save(ignore_permissions=True) \ No newline at end of file diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 7294834790b..c45c2411dfa 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -87,7 +87,7 @@ class Company(Document): .format(self.country.lower()))(self) def create_default_warehouses(self): - for wh_detail in [{"warehouse_name": _("Warehouses"), "is_group": "Yes"}, + for wh_detail in [ {"warehouse_name": _("Stores"), "is_group": "No"}, {"warehouse_name": _("Work In Progress"), "is_group": "No"}, {"warehouse_name": _("Finished Goods"), "is_group": "No"}]: @@ -101,8 +101,7 @@ class Company(Document): "warehouse_name": wh_detail["warehouse_name"], "is_group": wh_detail["is_group"], "company": self.name, - "parent_warehouse": "" if wh_detail["is_group"] == "Yes" \ - else "{0} - {1}".format(_("Warehouses"), self.abbr), + "parent_warehouse": "", "create_account_under": stock_group }) warehouse.flags.ignore_permissions = True diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index d28a3c4a295..1032fb0ed33 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -165,3 +165,43 @@ class Warehouse(NestedSet): frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock) frappe.db.auto_commit_on_many_writes = 0 + +@frappe.whitelist() +def get_children(): + from erpnext.stock.utils import get_stock_value_on + ctype = frappe.local.form_dict.get('ctype') + company = frappe.local.form_dict.get('comp') + + parent_field = 'parent_' + ctype.lower().replace(' ', '_') + parent = frappe.form_dict.get("parent") or "" + + if parent == "Warehouses": + parent = "" + + warehouses = frappe.db.sql("""select name as value, + if(is_group='Yes', 1, 0) as expandable + from `tab{ctype}` + where docstatus < 2 + and ifnull(`{parent_field}`,'') = %s and `company` = %s + order by name""".format(ctype=frappe.db.escape(ctype), parent_field=frappe.db.escape(parent_field)), + (parent, company), as_dict=1) + + # return warehouses + for wh in warehouses: + wh["balance"] = get_stock_value_on(warehouse=wh.value) + return warehouses + +@frappe.whitelist() +def add_node(): + ctype = frappe.form_dict.get('ctype') + parent_field = 'parent_' + ctype.lower().replace(' ', '_') + name_field = ctype.lower().replace(' ', '_') + '_name' + + doc = frappe.new_doc(ctype) + doc.update({ + name_field: frappe.form_dict['name_field'], + parent_field: frappe.form_dict['parent'], + "is_group": frappe.form_dict['is_group'] + }) + + doc.save() diff --git a/erpnext/stock/doctype/warehouse/warehouse_treeview.js b/erpnext/stock/doctype/warehouse/warehouse_treeview.js index b0be3ec72e0..d23a5362db9 100644 --- a/erpnext/stock/doctype/warehouse/warehouse_treeview.js +++ b/erpnext/stock/doctype/warehouse/warehouse_treeview.js @@ -1,4 +1,20 @@ frappe.treeview_settings['Warehouse'] = { - get_tree_nodes: "erpnext.selling.page.sales_browser.sales_browser.get_children", - add_tree_node: "erpnext.selling.page.sales_browser.sales_browser.add_node" + get_tree_nodes: "erpnext.stock.doctype.warehouse.warehouse.get_children", + add_tree_node: "erpnext.stock.doctype.warehouse.warehouse.add_node", + get_tree_root: false, + root_label: "Warehouses", + filters: [{ + fieldname: "comp", + fieldtype:"Select", + options: $.map(locals[':Company'], function(c) { return c.name; }).sort(), + label: __("Company"), + default: frappe.defaults.get_default('company') ? frappe.defaults.get_default('company'): "" + }], + onrender: function(node) { + if (node.data && node.data.balance!==undefined) { + $('' + + format_currency(Math.abs(node.data.balance), node.data.company_currency) + + '').insertBefore(node.$ul); + } + } } \ No newline at end of file diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index 3f9de864931..af7dc588c19 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -15,24 +15,34 @@ def get_stock_value_on(warehouse=None, posting_date=None, item_code=None): values, condition = [posting_date], "" if warehouse: - values.append(warehouse) - condition += " AND warehouse = %s" + + wh = frappe.get_doc("Warehouse", warehouse) + + if wh.is_group == "Yes": + values.extend([wh.lft, wh.rgt]) + condition += "and exists (\ + select name from `tabWarehouse` wh where wh.name = sle.warehouse\ + and wh.lft >= %s and wh.rgt <= %s)" + + else: + values.append(warehouse) + condition += " AND warehouse = %s" if item_code: values.append(item_code) condition.append(" AND item_code = %s") stock_ledger_entries = frappe.db.sql(""" - SELECT item_code, stock_value - FROM `tabStock Ledger Entry` + SELECT item_code, stock_value, name, warehouse + FROM `tabStock Ledger Entry` sle WHERE posting_date <= %s {0} ORDER BY timestamp(posting_date, posting_time) DESC, name DESC """.format(condition), values, as_dict=1) sle_map = {} for sle in stock_ledger_entries: - sle_map.setdefault(sle.item_code, flt(sle.stock_value)) - + sle_map[sle.item_code] = sle_map.get(sle.item_code, 0.0) + flt(sle.stock_value) + return sum(sle_map.values()) def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None, with_valuation_rate=False):