[enhance] warehouse browser page for warehouse tree
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 7da7c25..0ed7a82 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -87,15 +87,22 @@
.format(self.country.lower()))(self)
def create_default_warehouses(self):
- for whname in (_("Stores"), _("Work In Progress"), _("Finished Goods")):
- if not frappe.db.exists("Warehouse", whname + " - " + self.abbr):
+ for wh_detail in [{"warehouse_name": _("All Warehouses"), "is_group": "Yes"},
+ {"warehouse_name": _("Stores"), "is_group": "No"},
+ {"warehouse_name": _("Work In Progress"), "is_group": "No"},
+ {"warehouse_name": _("Finished Goods"), "is_group": "No"}]:
+
+ if not frappe.db.exists("Warehouse", "{0} - {1}".format(wh_detail["warehouse_name"], self.abbr)):
stock_group = frappe.db.get_value("Account", {"account_type": "Stock",
"is_group": 1, "company": self.name})
if stock_group:
warehouse = frappe.get_doc({
"doctype":"Warehouse",
- "warehouse_name": whname,
+ "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(_("All Warehouses"), self.abbr),
"create_account_under": stock_group
})
warehouse.flags.ignore_permissions = True
diff --git a/erpnext/stock/page/warehouse_browser/__init__.py b/erpnext/stock/page/warehouse_browser/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/page/warehouse_browser/__init__.py
diff --git a/erpnext/stock/page/warehouse_browser/warehouse_browser.js b/erpnext/stock/page/warehouse_browser/warehouse_browser.js
new file mode 100644
index 0000000..d123ff4
--- /dev/null
+++ b/erpnext/stock/page/warehouse_browser/warehouse_browser.js
@@ -0,0 +1,158 @@
+frappe.pages['warehouse-browser'].on_page_load = function(wrapper) {
+ var page = frappe.ui.make_app_page({
+ parent: wrapper,
+ single_column: true
+ });
+
+ wrapper.page.add_menu_item(__('Refresh'), function() {
+ wrapper.make_tree();
+ });
+
+ wrapper.make_tree = function() {
+ var ctype = frappe.get_route()[1] || 'Warehouse';
+ return frappe.call({
+ method: 'erpnext.stock.page.warehouse_browser.warehouse_browser.get_children',
+ args: {ctype: ctype},
+ callback: function(r) {
+ var root = r.message[0]["value"];
+ erpnext.warehouse_chart = new erpnext.WarehouseChart(ctype, root, page,
+ page.main.css({
+ "min-height": "300px",
+ "padding-bottom": "25px"
+ }));
+ }
+ });
+ }
+
+ wrapper.make_tree();
+}
+
+frappe.pages['warehouse-browser'].on_page_show = function(wrapper){
+ // set route
+ var ctype = frappe.get_route()[1] || 'Warehouse';
+
+ wrapper.page.set_title(__('{0} Tree',[__(ctype)]));
+
+ if(erpnext.warehouse_chart && erpnext.warehouse_chart.ctype != ctype) {
+ wrapper.make_tree();
+ }
+
+ frappe.breadcrumbs.add(frappe.breadcrumbs.last_module || "Stock");
+};
+
+erpnext.WarehouseChart = Class.extend({
+ init: function(ctype, root, page, parent){
+ $(parent).empty();
+ var me = this;
+ me.ctype = ctype;
+ me.page = page;
+ me.can_read = frappe.model.can_read(this.ctype);
+ me.can_create = frappe.boot.user.can_create.indexOf(this.ctype) !== -1 ||
+ frappe.boot.user.in_create.indexOf(this.ctype) !== -1;
+ me.can_write = frappe.model.can_write(this.ctype);
+ me.can_delete = frappe.model.can_delete(this.ctype);
+
+ me.page.set_primary_action(__("New"), function() {
+ me.new_node();
+ }, "octicon octicon-plus");
+
+ this.tree = new frappe.ui.Tree({
+ parent: $(parent),
+ label: __(root),
+ args: {ctype: ctype},
+ method: 'erpnext.stock.page.warehouse_browser.warehouse_browser.get_children',
+ toolbar: [
+ {toggle_btn: true},
+ {
+ label:__("Edit"),
+ condition: function(node) {
+ return !node.root && me.can_read;
+ },
+ click: function(node) {
+ frappe.set_route("Form", me.ctype, node.label);
+ }
+ },
+ {
+ label:__("Add Child"),
+ condition: function(node) { return me.can_create && node.expandable; },
+ click: function(node) {
+ me.new_node();
+ },
+ btnClass: "hidden-xs"
+ },
+ {
+ label:__("Rename"),
+ condition: function(node) { return !node.root && me.can_write; },
+ click: function(node) {
+ frappe.model.rename_doc(me.ctype, node.label, function(new_name) {
+ node.$a.html(new_name);
+ });
+ },
+ btnClass: "hidden-xs"
+ },
+ {
+ label:__("Delete"),
+ condition: function(node) { return !node.root && me.can_delete; },
+ click: function(node) {
+ frappe.model.delete_doc(me.ctype, node.label, function() {
+ node.parent.remove();
+ });
+ },
+ btnClass: "hidden-xs"
+ }
+
+ ]
+ });
+ },
+ new_node: function() {
+ var me = this;
+ var node = me.tree.get_selected_node();
+
+ if(!(node && node.expandable)) {
+ frappe.msgprint(__("Select a group node first."));
+ return;
+ }
+
+ var fields = [
+ {fieldtype:'Data', fieldname: 'name_field',
+ label:__('New {0} Name',[__(me.ctype)]), reqd:true},
+ {fieldtype:'Select', fieldname:'is_group', label:__('Group Node'), options:'No\nYes',
+ description: __("Further nodes can be only created under 'Group' type nodes")}
+ ]
+
+ // the dialog
+ var d = new frappe.ui.Dialog({
+ title: __('New {0}',[__(me.ctype)]),
+ fields: fields
+ })
+
+ d.set_value("is_group", "No");
+ // create
+ d.set_primary_action(__("Create New"), function() {
+ var btn = this;
+ var v = d.get_values();
+ if(!v) return;
+
+ var node = me.tree.get_selected_node();
+
+ v.parent = node.label;
+ v.ctype = me.ctype;
+
+ return frappe.call({
+ method: 'erpnext.stock.page.warehouse_browser.warehouse_browser.add_node',
+ args: v,
+ callback: function(r) {
+ if(!r.exc) {
+ d.hide();
+ if(node.expanded) {
+ node.toggle_node();
+ }
+ node.reload();
+ }
+ }
+ });
+ });
+
+ d.show();
+ },
+})
\ No newline at end of file
diff --git a/erpnext/stock/page/warehouse_browser/warehouse_browser.json b/erpnext/stock/page/warehouse_browser/warehouse_browser.json
new file mode 100644
index 0000000..3d0dcbc
--- /dev/null
+++ b/erpnext/stock/page/warehouse_browser/warehouse_browser.json
@@ -0,0 +1,27 @@
+{
+ "content": null,
+ "creation": "2016-05-24 11:01:06.887660",
+ "docstatus": 0,
+ "doctype": "Page",
+ "idx": 0,
+ "modified": "2016-05-24 11:11:32.317342",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "warehouse-browser",
+ "owner": "Administrator",
+ "page_name": "Warehouse Browser",
+ "roles": [
+ {
+ "role": "Stock Manager"
+ },
+ {
+ "role": "Stock User"
+ },
+ {
+ "role": "System Manager"
+ }
+ ],
+ "script": null,
+ "standard": "Yes",
+ "style": null
+}
\ No newline at end of file
diff --git a/erpnext/stock/page/warehouse_browser/warehouse_browser.py b/erpnext/stock/page/warehouse_browser/warehouse_browser.py
new file mode 100644
index 0000000..48bb8a3
--- /dev/null
+++ b/erpnext/stock/page/warehouse_browser/warehouse_browser.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+@frappe.whitelist()
+def get_children():
+ ctype = frappe.local.form_dict.get('ctype')
+ parent_field = 'parent_' + ctype.lower().replace(' ', '_')
+ parent = frappe.form_dict.get("parent") or ""
+
+ return 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
+ order by name""".format(ctype=frappe.db.escape(ctype), parent_field=frappe.db.escape(parent_field)),
+ parent, as_dict=1)
+
+@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()
\ No newline at end of file