blob: 746ac794884c7bc3553ed5eba1fc2033e2253803 [file] [log] [blame]
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +05301frappe.pages["leaderboard"].on_page_load = function (wrapper) {
2 frappe.leaderboard = new frappe.Leaderboard(wrapper);
3}
Ayush Shuklaa111f782017-06-20 13:04:45 +05304
5frappe.Leaderboard = Class.extend({
6
7 init: function (parent) {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +05308 frappe.ui.make_app_page({
Ayush Shuklaa111f782017-06-20 13:04:45 +05309 parent: parent,
10 title: "Leaderboard",
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053011 single_column: false
Ayush Shuklaa111f782017-06-20 13:04:45 +053012 });
13
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053014 this.parent = parent;
15 this.page = this.parent.page;
16 this.page.sidebar.html(`<ul class="module-sidebar-nav overlay-sidebar nav nav-pills nav-stacked"></ul>`);
17 this.$sidebar_list = this.page.sidebar.find('ul');
18
Ayush Shuklaa111f782017-06-20 13:04:45 +053019 // const list of doctypes
vishdha09acb772018-02-20 12:44:11 +053020 this.doctypes = ["Customer", "Item", "Supplier", "Sales Partner","Sales Person"];
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053021 this.timespans = ["Week", "Month", "Quarter", "Year"];
Ayush Shuklaa111f782017-06-20 13:04:45 +053022 this.filters = {
Nabin Hait7d862272018-02-22 13:59:41 +053023 "Customer": ["total_sales_amount", "total_qty_sold", "outstanding_amount", ],
24 "Item": ["total_sales_amount", "total_qty_sold", "total_purchase_amount",
25 "total_qty_purchased", "available_stock_qty", "available_stock_value"],
26 "Supplier": ["total_purchase_amount", "total_qty_purchased", "outstanding_amount"],
27 "Sales Partner": ["total_sales_amount", "total_commision"],
28 "Sales Person": ["total_sales_amount"],
Ayush Shuklaa111f782017-06-20 13:04:45 +053029 };
30
31 // for saving current selected filters
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053032 // TODO: revert to 0 index for doctype and timespan, and remove preset down
33 const _initial_doctype = this.doctypes[0];
34 const _initial_timespan = this.timespans[0];
35 const _initial_filter = this.filters[_initial_doctype];
36
Ayush Shuklaa111f782017-06-20 13:04:45 +053037 this.options = {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053038 selected_doctype: _initial_doctype,
39 selected_filter: _initial_filter,
40 selected_filter_item: _initial_filter[0],
41 selected_timespan: _initial_timespan,
Ayush Shuklaa111f782017-06-20 13:04:45 +053042 };
43
44 this.message = null;
45 this.make();
46 },
47
Ayush Shuklaa111f782017-06-20 13:04:45 +053048 make: function () {
49 var me = this;
50
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053051 var $container = $(`<div class="leaderboard page-main-content">
52 <div class="leaderboard-graph"></div>
53 <div class="leaderboard-list"></div>
54 </div>`).appendTo(this.page.main);
Ayush Shuklaa111f782017-06-20 13:04:45 +053055
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053056 this.$graph_area = $container.find('.leaderboard-graph');
Ayush Shuklaa111f782017-06-20 13:04:45 +053057
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053058 this.doctypes.map(doctype => {
59 this.get_sidebar_item(doctype).appendTo(this.$sidebar_list);
60 });
61
vishdhad4491d32018-02-21 09:33:35 +053062 this.company_select = this.page.add_field({
63 fieldname: 'company',
64 label: __('Company'),
65 fieldtype:'Link',
66 options:'Company',
67 default:frappe.defaults.get_default('company'),
Nabin Hait7d862272018-02-22 13:59:41 +053068 reqd: 1,
vishdha9a64d432018-02-21 11:26:58 +053069 change: function() {
vishdhad4491d32018-02-21 09:33:35 +053070 me.options.selected_company = this.value;
71 me.make_request($container);
72 }
vishdhad4491d32018-02-21 09:33:35 +053073 });
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053074 this.timespan_select = this.page.add_select(__("Timespan"),
75 this.timespans.map(d => {
76 return {"label": __(d), value: d }
77 })
78 );
79
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053080 this.type_select = this.page.add_select(__("Type"),
81 me.options.selected_filter.map(d => {
82 return {"label": __(frappe.model.unscrub(d)), value: d }
83 })
84 );
85
86 this.$sidebar_list.on('click', 'li', function(e) {
87 let $li = $(this);
88 let doctype = $li.find('span').html();
89
vishdha9a64d432018-02-21 11:26:58 +053090 me.options.selected_company = frappe.defaults.get_default('company');
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053091 me.options.selected_doctype = doctype;
92 me.options.selected_filter = me.filters[doctype];
93 me.options.selected_filter_item = me.filters[doctype][0];
94
95 me.type_select.empty().add_options(
96 me.options.selected_filter.map(d => {
97 return {"label": __(frappe.model.unscrub(d)), value: d }
98 })
99 );
100
101 me.$sidebar_list.find('li').removeClass('active');
102 $li.addClass('active');
103
104 me.make_request($container);
105 });
106
107 this.timespan_select.on("change", function() {
108 me.options.selected_timespan = this.value;
109 me.make_request($container);
110 });
111
112 this.type_select.on("change", function() {
113 me.options.selected_filter_item = this.value
114 me.make_request($container);
115 });
Ayush Shuklaa111f782017-06-20 13:04:45 +0530116
117 // now get leaderboard
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530118 this.$sidebar_list.find('li:first').trigger('click');
Ayush Shuklaa111f782017-06-20 13:04:45 +0530119 },
120
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530121 make_request: function ($container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530122 var me = this;
123
124 frappe.model.with_doctype(me.options.selected_doctype, function () {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530125 me.get_leaderboard(me.get_leaderboard_data, $container);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530126 });
127 },
128
Nabin Hait7d862272018-02-22 13:59:41 +0530129 get_leaderboard: function (notify, $container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530130 var me = this;
Nabin Hait7d862272018-02-22 13:59:41 +0530131 if(!me.options.selected_company) {
132 frappe.throw(__("Please select Company"));
133 }
Ayush Shuklaa111f782017-06-20 13:04:45 +0530134 frappe.call({
135 method: "erpnext.utilities.page.leaderboard.leaderboard.get_leaderboard",
136 args: {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530137 doctype: me.options.selected_doctype,
138 timespan: me.options.selected_timespan,
vishdhad4491d32018-02-21 09:33:35 +0530139 company: me.options.selected_company,
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530140 field: me.options.selected_filter_item,
Ayush Shuklaa111f782017-06-20 13:04:45 +0530141 },
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530142 callback: function (r) {
143 let results = r.message || [];
144
145 let graph_items = results.slice(0, 10);
146
147 me.$graph_area.show().empty();
148 let args = {
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530149 parent: '.leaderboard-graph',
150 data: {
151 datasets: [
152 {
153 values: graph_items.map(d=>d.value)
154 }
155 ],
156 labels: graph_items.map(d=>d.name)
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530157 },
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530158 colors: ['light-green'],
159 format_tooltip_x: d=>d[me.options.selected_filter_item],
160 type: 'bar',
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530161 height: 140
162 };
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530163 new Chart(args);
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530164
165 notify(me, r, $container);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530166 }
167 });
168 },
169
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530170 get_leaderboard_data: function (me, res, $container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530171 if (res && res.message) {
172 me.message = null;
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530173 $container.find(".leaderboard-list").html(me.render_list_view(res.message));
Ayush Shuklaa111f782017-06-20 13:04:45 +0530174 } else {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530175 me.$graph_area.hide();
Ayush Shuklaa111f782017-06-20 13:04:45 +0530176 me.message = "No items found.";
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530177 $container.find(".leaderboard-list").html(me.render_list_view());
Ayush Shuklaa111f782017-06-20 13:04:45 +0530178 }
179 },
180
181 render_list_view: function (items = []) {
182 var me = this;
183
184 var html =
185 `${me.render_message()}
186 <div class="result" style="${me.message ? "display:none;" : ""}">
187 ${me.render_result(items)}
188 </div>`;
189
190 return $(html);
191 },
192
193 render_result: function (items) {
194 var me = this;
195
196 var html =
197 `${me.render_list_header()}
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530198 ${me.render_list_result(items)}`;
Ayush Shuklaa111f782017-06-20 13:04:45 +0530199
200 return html;
201 },
202
203 render_list_header: function () {
204 var me = this;
205 const _selected_filter = me.options.selected_filter
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530206 .map(i => frappe.model.unscrub(i));
207 const fields = ['name', me.options.selected_filter_item];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530208
209 const html =
210 `<div class="list-headers">
211 <div class="list-item list-item--head" data-list-renderer="${"List"}">
212 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530213 fields.map(filter => {
214 const col = frappe.model.unscrub(filter);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530215 return (
216 `<div class="leaderboard-item list-item_content ellipsis text-muted list-item__content--flex-2
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530217 header-btn-base
Ayush Shuklaa111f782017-06-20 13:04:45 +0530218 ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}">
219 <span class="list-col-title ellipsis">
220 ${col}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530221 </span>
222 </div>`);
223 }).join("")
224 }
225 </div>
226 </div>`;
227 return html;
228 },
229
230 render_list_result: function (items) {
231 var me = this;
232
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530233 let _html = items.map((item, index) => {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530234 const $value = $(me.get_item_html(item));
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530235
236 let item_class = "";
237 if(index == 0) {
238 item_class = "first";
239 } else if (index == 1) {
240 item_class = "second";
241 } else if(index == 2) {
242 item_class = "third";
243 }
244 const $item_container = $(`<div class="list-item-container ${item_class}">`).append($value);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530245 return $item_container[0].outerHTML;
246 }).join("");
247
248 let html =
249 `<div class="result-list">
250 <div class="list-items">
251 ${_html}
252 </div>
253 </div>`;
254
255 return html;
256 },
257
258 render_message: function () {
259 var me = this;
260
261 let html =
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530262 `<div class="no-result text-center" style="${me.message ? "" : "display:none;"}">
Ayush Shuklaa111f782017-06-20 13:04:45 +0530263 <div class="msg-box no-border">
264 <p>No Item found</p>
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530265 </div>
Ayush Shuklaa111f782017-06-20 13:04:45 +0530266 </div>`;
267
268 return html;
269 },
270
271 get_item_html: function (item) {
272 var me = this;
vishdha09d56752018-02-21 16:10:09 +0530273 const company = me.options.selected_company;
vishdha9a64d432018-02-21 11:26:58 +0530274 const currency = frappe.get_doc(":Company", company).default_currency;
vishdhad4491d32018-02-21 09:33:35 +0530275 const fields = ['name','value'];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530276
277 const html =
278 `<div class="list-item">
279 ${
Nabin Hait7d862272018-02-22 13:59:41 +0530280 fields.map(col => {
281 let val = item[col];
282 if(col=="name") {
283 var formatted_value = `<a class="grey list-id ellipsis"
284 href="#Form/${me.options.selected_doctype}/${item["name"]}"> ${val} </a>`
285 } else {
286 var formatted_value = `<span class="text-muted ellipsis">
287 ${(me.options.selected_filter_item.indexOf('qty') == -1) ? format_currency(val, currency) : val}</span>`
Ayush Shuklaa111f782017-06-20 13:04:45 +0530288 }
Nabin Hait7d862272018-02-22 13:59:41 +0530289
Ayush Shuklaa111f782017-06-20 13:04:45 +0530290 return (
291 `<div class="list-item_content ellipsis list-item__content--flex-2
Nabin Hait7d862272018-02-22 13:59:41 +0530292 ${(col == "value") ? "text-right" : ""}">
293 ${formatted_value}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530294 </div>`);
295 }).join("")
296 }
297 </div>`;
298
299 return html;
300 },
301
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530302 get_sidebar_item: function(item) {
303 return $(`<li class="strong module-sidebar-item">
304 <a class="module-link">
305 <span>${ item }</span></a>
306 </li>`);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530307 }
308});