moved directory structure

This commit is contained in:
Rushabh Mehta
2012-09-24 19:13:42 +05:30
parent e47a6779e9
commit 2fa2f7178d
1637 changed files with 47 additions and 11450 deletions

1
selling/page/__init__.py Normal file
View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

View File

@@ -0,0 +1,264 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
wn.pages['sales-analytics'].onload = function(wrapper) {
wn.ui.make_app_page({
parent: wrapper,
title: 'Sales Analytics',
single_column: true
});
new erpnext.SalesAnalytics(wrapper);
}
erpnext.SalesAnalytics = wn.views.TreeGridReport.extend({
init: function(wrapper) {
this._super({
title: "Sales Analytics",
page: wrapper,
parent: $(wrapper).find('.layout-main'),
appframe: wrapper.appframe,
doctypes: ["Item", "Item Group", "Customer", "Customer Group", "Company",
"Sales Invoice", "Sales Invoice Item", "Territory"],
tree_grid: { show: true }
});
this.tree_grids = {
"Customer Group": {
label: "Customer Group / Customer",
show: true,
item_key: "customer",
parent_field: "parent_customer_group",
formatter: function(item) {
// return repl('<a href="#Report2/stock-invoices/customer=%(enc_value)s">%(value)s</a>', {
// value: item.name,
// enc_value: encodeURIComponent(item.name)
// });
return item.name;
}
},
"Customer": {
label: "Customer",
show: false,
item_key: "customer",
formatter: function(item) {
return item.name;
}
},
"Item Group": {
label: "Item",
show: true,
parent_field: "parent_item_group",
item_key: "item_code",
formatter: function(item) {
return item.name;
}
},
"Item": {
label: "Item",
show: false,
item_key: "item_code",
formatter: function(item) {
return item.name;
}
},
"Territory": {
label: "Territory / Customer",
show: true,
item_key: "customer",
parent_field: "parent_territory",
formatter: function(item) {
return item.name;
}
}
}
},
setup_columns: function() {
this.tree_grid = this.tree_grids[this.tree_type];
var std_columns = [
{id: "check", name: "Plot", field: "check", width: 30,
formatter: this.check_formatter},
{id: "name", name: this.tree_grid.label, field: "name", width: 300,
formatter: this.tree_formatter},
{id: "total", name: "Total", field: "total", plot: false,
formatter: this.currency_formatter}
];
this.make_date_range_columns();
this.columns = std_columns.concat(this.columns);
},
filters: [
{fieldtype:"Select", label: "Tree Type", options:["Customer Group", "Customer",
"Item Group", "Item", "Territory"],
filter: function(val, item, opts, me) {
return me.apply_zero_filter(val, item, opts, me);
}},
{fieldtype:"Select", label: "Value or Qty", options:["Value", "Quantity"]},
{fieldtype:"Select", label: "Company", link:"Company",
default_value: "Select Company..."},
{fieldtype:"Date", label: "From Date"},
{fieldtype:"Label", label: "To"},
{fieldtype:"Date", label: "To Date"},
{fieldtype:"Select", label: "Range",
options:["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]},
{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
{fieldtype:"Button", label: "Reset Filters"}
],
setup_filters: function() {
var me = this;
this._super();
this.filter_inputs.value_or_qty.change(function() {
me.filter_inputs.refresh.click();
});
this.filter_inputs.tree_type.change(function() {
me.filter_inputs.refresh.click();
});
this.show_zero_check()
this.setup_plot_check();
},
init_filter_values: function() {
this._super();
this.filter_inputs.range.val('Weekly');
},
prepare_data: function() {
var me = this;
if (!this.tl) {
this.make_transaction_list("Sales Invoice", "Sales Invoice Item");
// add 'Not Set' Customer & Item
// (Customer / Item are not mandatory!!)
wn.report_dump.data["Customer"].push({
name: "Not Set",
parent_customer_group: "All Customer Groups",
parent_territory: "All Territories",
id: "Not Set",
});
wn.report_dump.data["Item"].push({
name: "Not Set",
parent_item_group: "All Item Groups",
id: "Not Set",
});
}
if(!this.data || me.item_type != me.tree_type) {
if(me.tree_type=='Customer') {
var items = wn.report_dump.data["Customer"];
} if(me.tree_type=='Customer Group') {
var items = this.prepare_tree("Customer", "Customer Group");
} else if(me.tree_type=="Item Group") {
var items = this.prepare_tree("Item", "Item Group");
} else if(me.tree_type=="Item") {
var items = wn.report_dump.data["Item"];
} else if(me.tree_type=="Territory") {
var items = this.prepare_tree("Customer", "Territory");
}
me.item_type = me.tree_type
me.parent_map = {};
me.item_by_name = {};
me.data = [];
$.each(items, function(i, v) {
var d = copy_dict(v);
me.data.push(d);
me.item_by_name[d.name] = d;
if(d[me.tree_grid.parent_field]) {
me.parent_map[d.name] = d[me.tree_grid.parent_field];
}
me.reset_item_values(d);
});
this.set_indent();
} else {
// otherwise, only reset values
$.each(this.data, function(i, d) {
me.reset_item_values(d);
});
}
this.prepare_balances();
if(me.tree_grid.show) {
this.set_totals(false);
this.update_groups();
} else {
this.set_totals(true);
}
},
prepare_balances: function() {
var me = this;
var from_date = dateutil.str_to_obj(this.from_date);
var to_date = dateutil.str_to_obj(this.to_date);
var is_val = this.value_or_qty == 'Value';
$.each(this.tl, function(i, tl) {
if (me.is_default('company') ? true : me.apply_filter(tl, "company")) {
var posting_date = dateutil.str_to_obj(tl.posting_date);
if (posting_date >= from_date && posting_date <= to_date) {
var item = me.item_by_name[tl[me.tree_grid.item_key]] || me.item_by_name['Not Set'];
item[me.column_map[tl.posting_date].field] += (is_val ? tl.amount : tl.qty);
}
}
});
},
update_groups: function() {
var me = this;
$.each(this.data, function(i, item) {
var parent = me.parent_map[item.name];
while(parent) {
parent_group = me.item_by_name[parent];
$.each(me.columns, function(c, col) {
if (col.formatter == me.currency_formatter) {
parent_group[col.field] =
flt(parent_group[col.field])
+ flt(item[col.field]);
}
});
parent = me.parent_map[parent];
}
});
},
set_totals: function(sort) {
var me = this;
var checked = false;
$.each(this.data, function(i, d) {
d.total = 0.0;
$.each(me.columns, function(i, col) {
if(col.formatter==me.currency_formatter && !col.hidden && col.field!="total")
d.total += d[col.field];
if(d.checked) checked = true;
})
});
if(sort)this.data = this.data.sort(function(a, b) { return a.total < b.total; });
if(!this.checked) {
this.data[0].checked = true;
}
},
get_plot_points: function(item, col, idx) {
return [[dateutil.str_to_obj(col.id).getTime(), item[col.field]],
[dateutil.user_to_obj(col.name).getTime(), item[col.field]]];
}
});

View File

@@ -0,0 +1,28 @@
# Page, sales-analytics
[
# These values are common in all dictionaries
{
u'creation': '2012-09-21 12:06:14',
u'docstatus': 0,
u'modified': '2012-09-21 12:06:14',
u'modified_by': u'Administrator',
u'owner': u'Administrator'
},
# These values are common for all Page
{
u'doctype': u'Page',
'module': u'Selling',
u'name': u'__common__',
'page_name': u'sales-analytics',
'standard': u'Yes',
'title': u'Sales Analytics'
},
# Page, sales-analytics
{
u'doctype': u'Page',
u'name': u'sales-analytics'
}
]

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1,14 @@
span.tree-node-toolbar {
padding: 2px;
margin-left: 15px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
background-color: #ddd;
}
.tree-area a.selected {
font-weight: bold;
text-decoration: underline;
}

View File

@@ -0,0 +1,11 @@
<div class="layout-wrapper layout-wrapper-background">
<div class="appframe-area"></div>
<div class="layout-main-section">
<div class="tree-area"></div>
</div>
<div class="layout-side-section">
<div class="help">To add child nodes, explore tree and click on the node under which you want to add more nodes.
</div>
</div>
<div class="clear"></div>
</div>

View File

@@ -0,0 +1,144 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pscript['onload_Sales Browser'] = function(wrapper){
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'));
wrapper.appframe.add_button('Refresh', function() {
wrapper.make_tree();
}, 'icon-refresh');
wrapper.make_tree = function() {
var ctype = wn.get_route()[1] || 'Territory';
erpnext.sales_chart = new erpnext.SalesChart(ctype, wrapper);
}
wrapper.make_tree();
}
pscript['onshow_Sales Browser'] = function(wrapper){
// set route
var ctype = wn.get_route()[1] || 'Territory';
wrapper.appframe.clear_breadcrumbs();
wrapper.appframe.add_breadcrumb(ctype+' Tree')
document.title = ctype+' Tree';
wrapper.appframe.add_breadcrumb(' in <a href="#!selling-home">Selling</a>');
if(erpnext.sales_chart && erpnext.sales_chart.ctype != ctype) {
wrapper.make_tree();
}
};
erpnext.SalesChart = Class.extend({
init: function(ctype, wrapper) {
var root_nodes = {
'Territory': 'All Territories',
'Item Group': 'All Item Groups',
'Customer Group': 'All Customer Groups',
'Sales Person': 'All Sales Persons'
}
$(wrapper).find('.tree-area').empty();
var me = this;
me.ctype = ctype;
this.tree = new wn.ui.Tree({
parent: $(wrapper).find('.tree-area'),
label: root_nodes[ctype],
args: {ctype: ctype},
method: 'selling.page.sales_browser.sales_browser.get_children',
click: function(link) {
if(me.cur_toolbar)
$(me.cur_toolbar).toggle(false);
if(!link.toolbar)
me.make_link_toolbar(link);
if(link.toolbar) {
me.cur_toolbar = link.toolbar;
$(me.cur_toolbar).toggle(true);
}
}
});
this.tree.rootnode.$a
.data('node-data', {value: root_nodes[ctype], expandable:1})
.click();
},
make_link_toolbar: function(link) {
var data = $(link).data('node-data');
if(!data) return;
link.toolbar = $('<span class="tree-node-toolbar"></span>').insertAfter(link);
// edit
var node_links = [];
if (wn.boot.profile.can_read.indexOf(this.ctype) !== -1) {
node_links.push('<a href="#!Form/'+encodeURIComponent(this.ctype)+'/'
+encodeURIComponent(data.value)+'">Edit</a>');
}
if(data.expandable) {
if (wn.boot.profile.can_create.indexOf(this.ctype) !== -1 ||
wn.boot.profile.in_create.indexOf(this.ctype) !== -1) {
node_links.push('<a onclick="erpnext.sales_chart.new_node();">Add Child</a>');
}
}
link.toolbar.append(node_links.join(" | "));
},
new_node: function() {
var me = this;
// the dialog
var d = new wn.ui.Dialog({
title:'New ' + me.ctype,
fields: [
{fieldtype:'Data', fieldname: 'name_field', label:'New ' + me.ctype + ' Name', reqd:true},
{fieldtype:'Select', fieldname:'is_group', label:'Group Node',
options:'No\nYes', description:'Entries can made only against non-group (leaf) nodes'},
{fieldtype:'Button', fieldname:'create_new', label:'Create New' }
]
})
// create
$(d.fields_dict.create_new.input).click(function() {
var btn = this;
$(btn).set_working();
var v = d.get_values();
if(!v) return;
var node = me.selected_node();
v.parent = node.data('label');
v.ctype = me.ctype;
wn.call({
method: 'selling.page.sales_browser.sales_browser.add_node',
args: v,
callback: function() {
$(btn).done_working();
d.hide();
node.trigger('reload');
}
})
});
d.show();
},
selected_node: function() {
return this.tree.$w.find('.tree-link.selected');
}
});

View File

@@ -0,0 +1,26 @@
from __future__ import unicode_literals
import webnotes
@webnotes.whitelist()
def get_children():
ctype = webnotes.form_dict.get('ctype')
webnotes.form_dict['parent_field'] = 'parent_' + ctype.lower().replace(' ', '_')
return webnotes.conn.sql("""select name as value,
if(is_group='Yes', 1, 0) as expandable
from `tab%(ctype)s`
where docstatus < 2
and %(parent_field)s = "%(parent)s"
order by name""" % webnotes.form_dict, as_dict=1)
@webnotes.whitelist()
def add_node():
from webnotes.model.doc import Document
ctype = webnotes.form_dict.get('ctype')
parent_field = 'parent_' + ctype.lower().replace(' ', '_')
d = Document(ctype)
d.fields[ctype.lower().replace(' ', '_') + '_name'] = webnotes.form_dict['name_field']
d.fields[parent_field] = webnotes.form_dict['parent']
d.is_group = webnotes.form_dict['is_group']
d.save()

View File

@@ -0,0 +1,51 @@
# Page, Sales Browser
[
# These values are common in all dictionaries
{
'creation': '2010-12-14 10:23:21',
'docstatus': 0,
'modified': '2010-12-24 11:56:34',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': 'Selling',
'name': '__common__',
'page_name': 'Sales Browser',
'show_in_menu': 0,
'standard': 'Yes'
},
# These values are common for all Page Role
{
'doctype': 'Page Role',
'name': '__common__',
'parent': 'Sales Browser',
'parentfield': 'roles',
'parenttype': 'Page'
},
# Page, Sales Browser
{
'doctype': 'Page',
'name': 'Sales Browser'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 1,
'role': 'Sales Master Manager'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 2,
'role': 'Material Master Manager'
}
]

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@@ -0,0 +1,125 @@
<div class="layout-wrapper layout-wrapper-background">
<div class="appframe-area"></div>
<div class="layout-main-section">
<div style="width: 48%; float: left;">
<h4><a href="#!List/Lead">Lead</a></h4>
<p class="help">Prospective customers</p>
<br>
<h4><a href="#!List/Opportunity">Opportunity</a></h4>
<p class="help">Business opportunities</p>
<br>
<h4><a href="#!List/Quotation">Quotation</a></h4>
<p class="help">Quotes sent to Leads / Customers</p>
<br>
<h4><a href="#!List/Sales Order">Sales Order</a></h4>
<p class="help">Confirmed orders from Customers</p>
</div>
<div style="width: 48%; float: right;">
<h4><a href="#!List/Customer">Customer</a></h4>
<p class="help">Customer Master</p>
<br>
<h4><a href="#!List/Item">Item</a></h4>
<p class="help">Item Master</p>
<br>
<h4><a href="#!List/Contact">Contact</a></h4>
<p class="help">Contact Master</p>
<br>
<h4><a href="#!List/Address">Address</a></h4>
<p class="help">Address Master</p>
<br>
<h4><a href="#sales-analytics" data-role="Analytics">Sales Analytics</a>
<span style="background-color: #fed; font-weight: normal; font-size: 80%">beta</span>
</h4>
<p class="help">Sales trends based on Sales Invoice</p>
</div>
<div style="clear: both"></div>
<hr>
<h3>Reports</h3>
<div class="reports-list"></div>
</div>
<div class="layout-side-section">
<div class="psidebar">
<div class="section">
<div class="section-head">Setup</div>
<div class="section-body">
<div class="section-item">
<a class="section-link"
title = "Tax and charges structure master"
href="#!List/Sales Taxes and Charges Master">Sales Taxes and Charges Master</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Multiple prices lists for items"
href="#!List/Price List">Price List</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Group items and accessories in one item code"
href="#!List/Sales BOM">Sales BOM</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Terms of contract template"
href="#!List/Terms and Conditions">Terms and Conditions Template</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Tree of customer groups"
href="#!Sales Browser/Customer Group">Customer Group</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Tree of sales territories"
href="#!Sales Browser/Territory">Territory</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Sales persons and targets"
href="#!Sales Browser/Sales Person">Sales Person</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Commission partners and targets"
href="#!List/Sales Partner">Sales Partner</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Tree of item classification"
href="#!Sales Browser/Item Group">Item Group</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Sales campaigns"
href="#!List/Campaign">Campaign</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Send mass SMS to your contacts, leads and employees"
href="#!Form/SMS Center/SMS Center">SMS Center</a>
</div>
</div>
</div>
<div class="section">
<div class="section-head">Tools</div>
<div class="section-body">
<div class="section-item">
<a class="section-link"
title = "Helper for managing return of goods (sales or purchase)"
href="#!Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool">Sales Returns</a>
</div>
<div class="section-item">
<a class="section-link"
title = "Analyze Sales and Purchase trends and slice them based on item, customer, groups etc"
href="#!Report/Profile/Trend Analyzer">Trend Analyzer</a>
</div>
<!--<div class="section-item">
<a class="section-link"
title = "sales trends"
href="#!Sales Dashboard">Sales Dashboard</a>
</div>-->
</div>
</div>
</div>
</div>
<div style="clear: both;"></div>
</div>

View File

@@ -0,0 +1,20 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pscript['onload_selling-home'] = function(wrapper) {
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'), 'Selling');
erpnext.module_page.setup_page('Selling', wrapper);
}

View File

@@ -0,0 +1,43 @@
# Page, selling-home
[
# These values are common in all dictionaries
{
'creation': '2012-02-20 15:46:39',
'docstatus': 0,
'modified': '2012-02-20 15:46:57',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': u'Selling',
'name': '__common__',
'page_name': u'selling-home',
'standard': u'Yes',
'title': u'Selling Home'
},
# These values are common for all Page Role
{
'doctype': u'Page Role',
'name': '__common__',
'parent': u'selling-home',
'parentfield': u'roles',
'parenttype': u'Page',
'role': u'All'
},
# Page, selling-home
{
'doctype': 'Page',
'name': u'selling-home'
},
# Page Role
{
'doctype': u'Page Role'
}
]