blob: 43d0e6e948cfa2728e0a823f85482271351af501 [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"],
Zlash65fa5ecb02018-04-22 12:11:01 +053027 "Sales Partner": ["total_sales_amount", "total_commission"],
Nabin Hait7d862272018-02-22 13:59:41 +053028 "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);
Rohit Waghchaure06f91e22018-05-28 14:43:17 +053088 let doctype = $li.find('span').attr("doctype-value");
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053089
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 data: {
150 datasets: [
151 {
152 values: graph_items.map(d=>d.value)
153 }
154 ],
155 labels: graph_items.map(d=>d.name)
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530156 },
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530157 colors: ['light-green'],
158 format_tooltip_x: d=>d[me.options.selected_filter_item],
159 type: 'bar',
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530160 height: 140
161 };
Mangesh-Khairnar9955b182019-07-01 12:20:09 +0530162 new frappe.Chart('.leaderboard-graph', args);
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530163
164 notify(me, r, $container);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530165 }
166 });
167 },
168
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530169 get_leaderboard_data: function (me, res, $container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530170 if (res && res.message) {
171 me.message = null;
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530172 $container.find(".leaderboard-list").html(me.render_list_view(res.message));
Ayush Shuklaa111f782017-06-20 13:04:45 +0530173 } else {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530174 me.$graph_area.hide();
Rohit Waghchaure06f91e22018-05-28 14:43:17 +0530175 me.message = __("No items found.");
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530176 $container.find(".leaderboard-list").html(me.render_list_view());
Ayush Shuklaa111f782017-06-20 13:04:45 +0530177 }
178 },
179
180 render_list_view: function (items = []) {
181 var me = this;
182
183 var html =
184 `${me.render_message()}
185 <div class="result" style="${me.message ? "display:none;" : ""}">
186 ${me.render_result(items)}
187 </div>`;
188
189 return $(html);
190 },
191
192 render_result: function (items) {
193 var me = this;
194
195 var html =
196 `${me.render_list_header()}
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530197 ${me.render_list_result(items)}`;
Ayush Shuklaa111f782017-06-20 13:04:45 +0530198
199 return html;
200 },
201
202 render_list_header: function () {
203 var me = this;
204 const _selected_filter = me.options.selected_filter
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530205 .map(i => frappe.model.unscrub(i));
206 const fields = ['name', me.options.selected_filter_item];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530207
208 const html =
209 `<div class="list-headers">
210 <div class="list-item list-item--head" data-list-renderer="${"List"}">
211 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530212 fields.map(filter => {
213 const col = frappe.model.unscrub(filter);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530214 return (
215 `<div class="leaderboard-item list-item_content ellipsis text-muted list-item__content--flex-2
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530216 header-btn-base
Ayush Shuklaa111f782017-06-20 13:04:45 +0530217 ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}">
218 <span class="list-col-title ellipsis">
219 ${col}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530220 </span>
221 </div>`);
222 }).join("")
223 }
224 </div>
225 </div>`;
226 return html;
227 },
228
229 render_list_result: function (items) {
230 var me = this;
231
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530232 let _html = items.map((item, index) => {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530233 const $value = $(me.get_item_html(item));
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530234
235 let item_class = "";
236 if(index == 0) {
237 item_class = "first";
238 } else if (index == 1) {
239 item_class = "second";
240 } else if(index == 2) {
241 item_class = "third";
242 }
243 const $item_container = $(`<div class="list-item-container ${item_class}">`).append($value);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530244 return $item_container[0].outerHTML;
245 }).join("");
246
247 let html =
248 `<div class="result-list">
249 <div class="list-items">
250 ${_html}
251 </div>
252 </div>`;
253
254 return html;
255 },
256
257 render_message: function () {
258 var me = this;
259
260 let html =
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530261 `<div class="no-result text-center" style="${me.message ? "" : "display:none;"}">
Ayush Shuklaa111f782017-06-20 13:04:45 +0530262 <div class="msg-box no-border">
263 <p>No Item found</p>
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530264 </div>
Ayush Shuklaa111f782017-06-20 13:04:45 +0530265 </div>`;
266
267 return html;
268 },
269
270 get_item_html: function (item) {
271 var me = this;
vishdha09d56752018-02-21 16:10:09 +0530272 const company = me.options.selected_company;
vishdha9a64d432018-02-21 11:26:58 +0530273 const currency = frappe.get_doc(":Company", company).default_currency;
vishdhad4491d32018-02-21 09:33:35 +0530274 const fields = ['name','value'];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530275
276 const html =
277 `<div class="list-item">
278 ${
Nabin Hait7d862272018-02-22 13:59:41 +0530279 fields.map(col => {
280 let val = item[col];
281 if(col=="name") {
Prateeksha Singh9362cf32018-03-12 09:54:56 +0530282 var formatted_value = `<a class="grey list-id ellipsis"
Nabin Hait7d862272018-02-22 13:59:41 +0530283 href="#Form/${me.options.selected_doctype}/${item["name"]}"> ${val} </a>`
284 } else {
285 var formatted_value = `<span class="text-muted ellipsis">
286 ${(me.options.selected_filter_item.indexOf('qty') == -1) ? format_currency(val, currency) : val}</span>`
Ayush Shuklaa111f782017-06-20 13:04:45 +0530287 }
Nabin Hait7d862272018-02-22 13:59:41 +0530288
Ayush Shuklaa111f782017-06-20 13:04:45 +0530289 return (
290 `<div class="list-item_content ellipsis list-item__content--flex-2
Nabin Hait7d862272018-02-22 13:59:41 +0530291 ${(col == "value") ? "text-right" : ""}">
292 ${formatted_value}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530293 </div>`);
294 }).join("")
295 }
296 </div>`;
297
298 return html;
299 },
300
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530301 get_sidebar_item: function(item) {
302 return $(`<li class="strong module-sidebar-item">
303 <a class="module-link">
Rohit Waghchaure06f91e22018-05-28 14:43:17 +0530304 <span doctype-value="${item}">${ __(item) }</span></a>
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530305 </li>`);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530306 }
307});