blob: 860506b96159f3e2a6d664885a662c9456b25f30 [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"];
vishdha09acb772018-02-20 12:44:11 +053022 this.desc_fields = ["total_sales_amount", "total_request","total_purchase_amount","commission_rate"];
Ayush Shuklaa111f782017-06-20 13:04:45 +053023 this.filters = {
vishdha09acb772018-02-20 12:44:11 +053024 "Customer": ["total_item_purchased_qty", "total_sales_amount","receivable_amount_outstanding_amount"],
25 "Item": ["total_purchase_amount", "total_purchased_qty", "total_sales_amount", "total_sold_qty","available_stock_qty"],
26 "Supplier": ["total_item_sold_qty", "total_purchase_amount","payable_amount_outstanding_amount"],
27 "Sales Partner": ["commission_rate", "target_qty", "target_amount", "total_sales_amount"],
28 "Sales Person": ["target_qty", "target_amount", "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'),
vishdha9a64d432018-02-21 11:26:58 +053068 change: function() {
vishdhad4491d32018-02-21 09:33:35 +053069 me.options.selected_company = this.value;
70 me.make_request($container);
71 }
72
73 });
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
vishdhad4491d32018-02-21 09:33:35 +053080
81
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053082 // this.timespan_select.val(this.timespans[1]);
83
84 this.type_select = this.page.add_select(__("Type"),
85 me.options.selected_filter.map(d => {
86 return {"label": __(frappe.model.unscrub(d)), value: d }
87 })
88 );
89
90 this.$sidebar_list.on('click', 'li', function(e) {
91 let $li = $(this);
92 let doctype = $li.find('span').html();
93
vishdha9a64d432018-02-21 11:26:58 +053094 me.options.selected_company = frappe.defaults.get_default('company');
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053095 me.options.selected_doctype = doctype;
96 me.options.selected_filter = me.filters[doctype];
97 me.options.selected_filter_item = me.filters[doctype][0];
98
99 me.type_select.empty().add_options(
100 me.options.selected_filter.map(d => {
101 return {"label": __(frappe.model.unscrub(d)), value: d }
102 })
103 );
104
105 me.$sidebar_list.find('li').removeClass('active');
106 $li.addClass('active');
107
108 me.make_request($container);
109 });
110
111 this.timespan_select.on("change", function() {
112 me.options.selected_timespan = this.value;
113 me.make_request($container);
114 });
115
116 this.type_select.on("change", function() {
117 me.options.selected_filter_item = this.value
118 me.make_request($container);
119 });
Ayush Shuklaa111f782017-06-20 13:04:45 +0530120
121 // now get leaderboard
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530122 this.$sidebar_list.find('li:first').trigger('click');
Ayush Shuklaa111f782017-06-20 13:04:45 +0530123 },
124
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530125 make_request: function ($container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530126 var me = this;
127
128 frappe.model.with_doctype(me.options.selected_doctype, function () {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530129 me.get_leaderboard(me.get_leaderboard_data, $container);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530130 });
131 },
132
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530133 get_leaderboard: function (notify, $container, start=0) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530134 var me = this;
135
136 frappe.call({
137 method: "erpnext.utilities.page.leaderboard.leaderboard.get_leaderboard",
138 args: {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530139 doctype: me.options.selected_doctype,
140 timespan: me.options.selected_timespan,
vishdhad4491d32018-02-21 09:33:35 +0530141 company: me.options.selected_company,
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530142 field: me.options.selected_filter_item,
143 start: start
Ayush Shuklaa111f782017-06-20 13:04:45 +0530144 },
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530145 callback: function (r) {
146 let results = r.message || [];
147
148 let graph_items = results.slice(0, 10);
149
150 me.$graph_area.show().empty();
151 let args = {
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530152 parent: '.leaderboard-graph',
153 data: {
154 datasets: [
155 {
156 values: graph_items.map(d=>d.value)
157 }
158 ],
159 labels: graph_items.map(d=>d.name)
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530160 },
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530161 colors: ['light-green'],
162 format_tooltip_x: d=>d[me.options.selected_filter_item],
163 type: 'bar',
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530164 height: 140
165 };
Prateeksha Singh04c4ce32017-12-20 10:51:25 +0530166 new Chart(args);
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530167
168 notify(me, r, $container);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530169 }
170 });
171 },
172
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530173 get_leaderboard_data: function (me, res, $container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530174 if (res && res.message) {
175 me.message = null;
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530176 $container.find(".leaderboard-list").html(me.render_list_view(res.message));
Ayush Shuklaa111f782017-06-20 13:04:45 +0530177 } else {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530178 me.$graph_area.hide();
Ayush Shuklaa111f782017-06-20 13:04:45 +0530179 me.message = "No items found.";
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530180 $container.find(".leaderboard-list").html(me.render_list_view());
Ayush Shuklaa111f782017-06-20 13:04:45 +0530181 }
182 },
183
184 render_list_view: function (items = []) {
185 var me = this;
186
187 var html =
188 `${me.render_message()}
189 <div class="result" style="${me.message ? "display:none;" : ""}">
190 ${me.render_result(items)}
191 </div>`;
192
193 return $(html);
194 },
195
196 render_result: function (items) {
197 var me = this;
198
199 var html =
200 `${me.render_list_header()}
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530201 ${me.render_list_result(items)}`;
Ayush Shuklaa111f782017-06-20 13:04:45 +0530202
203 return html;
204 },
205
206 render_list_header: function () {
207 var me = this;
208 const _selected_filter = me.options.selected_filter
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530209 .map(i => frappe.model.unscrub(i));
210 const fields = ['name', me.options.selected_filter_item];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530211
212 const html =
213 `<div class="list-headers">
214 <div class="list-item list-item--head" data-list-renderer="${"List"}">
215 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530216 fields.map(filter => {
217 const col = frappe.model.unscrub(filter);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530218 return (
219 `<div class="leaderboard-item list-item_content ellipsis text-muted list-item__content--flex-2
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530220 header-btn-base
Ayush Shuklaa111f782017-06-20 13:04:45 +0530221 ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}">
222 <span class="list-col-title ellipsis">
223 ${col}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530224 </span>
225 </div>`);
226 }).join("")
227 }
228 </div>
229 </div>`;
230 return html;
231 },
232
233 render_list_result: function (items) {
234 var me = this;
235
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530236 let _html = items.map((item, index) => {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530237 const $value = $(me.get_item_html(item));
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530238
239 let item_class = "";
240 if(index == 0) {
241 item_class = "first";
242 } else if (index == 1) {
243 item_class = "second";
244 } else if(index == 2) {
245 item_class = "third";
246 }
247 const $item_container = $(`<div class="list-item-container ${item_class}">`).append($value);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530248 return $item_container[0].outerHTML;
249 }).join("");
250
251 let html =
252 `<div class="result-list">
253 <div class="list-items">
254 ${_html}
255 </div>
256 </div>`;
257
258 return html;
259 },
260
261 render_message: function () {
262 var me = this;
263
264 let html =
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530265 `<div class="no-result text-center" style="${me.message ? "" : "display:none;"}">
Ayush Shuklaa111f782017-06-20 13:04:45 +0530266 <div class="msg-box no-border">
267 <p>No Item found</p>
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530268 </div>
Ayush Shuklaa111f782017-06-20 13:04:45 +0530269 </div>`;
270
271 return html;
272 },
273
274 get_item_html: function (item) {
275 var me = this;
vishdha9a64d432018-02-21 11:26:58 +0530276 const company = frappe.defaults.get_default('Company');
277 const currency = frappe.get_doc(":Company", company).default_currency;
Ayush Shuklaa111f782017-06-20 13:04:45 +0530278 const _selected_filter = me.options.selected_filter
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530279 .map(i => frappe.model.unscrub(i));
vishdhad4491d32018-02-21 09:33:35 +0530280 const fields = ['name','value'];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530281
282 const html =
283 `<div class="list-item">
284 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530285 fields.map(filter => {
286 const col = frappe.model.unscrub(filter);
287 let val = item[filter];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530288 if (col === "Modified") {
289 val = comment_when(val);
290 }
291 return (
292 `<div class="list-item_content ellipsis list-item__content--flex-2
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530293 ${(col !== "Name" && col !== "Modified") ? "hidden-xs" : ""}
vishdha09acb772018-02-20 12:44:11 +0530294 ${(filter == "value") ? "text-right" : ""}">
vishdhad4491d32018-02-21 09:33:35 +0530295 ${ col === "Name" ? `<a class="grey list-id ellipsis" href="#Form/${me.options.selected_doctype}/${item["name"]}"> ${val} </a>` : `<span class="text-muted ellipsis"> ${format_currency(val, currency)}</span>`
Ayush Shuklaa111f782017-06-20 13:04:45 +0530296 }
297 </div>`);
298 }).join("")
299 }
300 </div>`;
301
302 return html;
303 },
304
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530305 get_sidebar_item: function(item) {
306 return $(`<li class="strong module-sidebar-item">
307 <a class="module-link">
308 <span>${ item }</span></a>
309 </li>`);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530310 }
311});