Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 1 | frappe.pages["leaderboard"].on_page_load = function (wrapper) { |
| 2 | frappe.leaderboard = new frappe.Leaderboard(wrapper); |
| 3 | } |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 4 | |
| 5 | frappe.Leaderboard = Class.extend({ |
| 6 | |
| 7 | init: function (parent) { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 8 | frappe.ui.make_app_page({ |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 9 | parent: parent, |
| 10 | title: "Leaderboard", |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 11 | single_column: false |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 12 | }); |
| 13 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 14 | 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 19 | // const list of doctypes |
vishdha | 09acb77 | 2018-02-20 12:44:11 +0530 | [diff] [blame] | 20 | this.doctypes = ["Customer", "Item", "Supplier", "Sales Partner","Sales Person"]; |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 21 | this.timespans = ["Week", "Month", "Quarter", "Year"]; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 22 | this.filters = { |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 23 | "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"], |
Zlash65 | fa5ecb0 | 2018-04-22 12:11:01 +0530 | [diff] [blame] | 27 | "Sales Partner": ["total_sales_amount", "total_commission"], |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 28 | "Sales Person": ["total_sales_amount"], |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 29 | }; |
| 30 | |
| 31 | // for saving current selected filters |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 32 | // 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 37 | this.options = { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 38 | selected_doctype: _initial_doctype, |
| 39 | selected_filter: _initial_filter, |
| 40 | selected_filter_item: _initial_filter[0], |
| 41 | selected_timespan: _initial_timespan, |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 42 | }; |
| 43 | |
| 44 | this.message = null; |
| 45 | this.make(); |
| 46 | }, |
| 47 | |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 48 | make: function () { |
| 49 | var me = this; |
| 50 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 51 | 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 55 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 56 | this.$graph_area = $container.find('.leaderboard-graph'); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 57 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 58 | this.doctypes.map(doctype => { |
| 59 | this.get_sidebar_item(doctype).appendTo(this.$sidebar_list); |
| 60 | }); |
| 61 | |
vishdha | d4491d3 | 2018-02-21 09:33:35 +0530 | [diff] [blame] | 62 | 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 Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 68 | reqd: 1, |
vishdha | 9a64d43 | 2018-02-21 11:26:58 +0530 | [diff] [blame] | 69 | change: function() { |
vishdha | d4491d3 | 2018-02-21 09:33:35 +0530 | [diff] [blame] | 70 | me.options.selected_company = this.value; |
| 71 | me.make_request($container); |
| 72 | } |
vishdha | d4491d3 | 2018-02-21 09:33:35 +0530 | [diff] [blame] | 73 | }); |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 74 | this.timespan_select = this.page.add_select(__("Timespan"), |
| 75 | this.timespans.map(d => { |
| 76 | return {"label": __(d), value: d } |
| 77 | }) |
| 78 | ); |
| 79 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 80 | 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 | |
vishdha | 9a64d43 | 2018-02-21 11:26:58 +0530 | [diff] [blame] | 90 | me.options.selected_company = frappe.defaults.get_default('company'); |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 91 | 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 116 | |
| 117 | // now get leaderboard |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 118 | this.$sidebar_list.find('li:first').trigger('click'); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 119 | }, |
| 120 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 121 | make_request: function ($container) { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 122 | var me = this; |
| 123 | |
| 124 | frappe.model.with_doctype(me.options.selected_doctype, function () { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 125 | me.get_leaderboard(me.get_leaderboard_data, $container); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 126 | }); |
| 127 | }, |
| 128 | |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 129 | get_leaderboard: function (notify, $container) { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 130 | var me = this; |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 131 | if(!me.options.selected_company) { |
| 132 | frappe.throw(__("Please select Company")); |
| 133 | } |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 134 | frappe.call({ |
| 135 | method: "erpnext.utilities.page.leaderboard.leaderboard.get_leaderboard", |
| 136 | args: { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 137 | doctype: me.options.selected_doctype, |
| 138 | timespan: me.options.selected_timespan, |
vishdha | d4491d3 | 2018-02-21 09:33:35 +0530 | [diff] [blame] | 139 | company: me.options.selected_company, |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 140 | field: me.options.selected_filter_item, |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 141 | }, |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 142 | 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 Singh | 04c4ce3 | 2017-12-20 10:51:25 +0530 | [diff] [blame] | 149 | 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 Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 157 | }, |
Prateeksha Singh | 04c4ce3 | 2017-12-20 10:51:25 +0530 | [diff] [blame] | 158 | colors: ['light-green'], |
| 159 | format_tooltip_x: d=>d[me.options.selected_filter_item], |
| 160 | type: 'bar', |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 161 | height: 140 |
| 162 | }; |
Prateeksha Singh | 04c4ce3 | 2017-12-20 10:51:25 +0530 | [diff] [blame] | 163 | new Chart(args); |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 164 | |
| 165 | notify(me, r, $container); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 166 | } |
| 167 | }); |
| 168 | }, |
| 169 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 170 | get_leaderboard_data: function (me, res, $container) { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 171 | if (res && res.message) { |
| 172 | me.message = null; |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 173 | $container.find(".leaderboard-list").html(me.render_list_view(res.message)); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 174 | } else { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 175 | me.$graph_area.hide(); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 176 | me.message = "No items found."; |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 177 | $container.find(".leaderboard-list").html(me.render_list_view()); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 178 | } |
| 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 Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 198 | ${me.render_list_result(items)}`; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 199 | |
| 200 | return html; |
| 201 | }, |
| 202 | |
| 203 | render_list_header: function () { |
| 204 | var me = this; |
| 205 | const _selected_filter = me.options.selected_filter |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 206 | .map(i => frappe.model.unscrub(i)); |
| 207 | const fields = ['name', me.options.selected_filter_item]; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 208 | |
| 209 | const html = |
| 210 | `<div class="list-headers"> |
| 211 | <div class="list-item list-item--head" data-list-renderer="${"List"}"> |
| 212 | ${ |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 213 | fields.map(filter => { |
| 214 | const col = frappe.model.unscrub(filter); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 215 | return ( |
| 216 | `<div class="leaderboard-item list-item_content ellipsis text-muted list-item__content--flex-2 |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 217 | header-btn-base |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 218 | ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}"> |
| 219 | <span class="list-col-title ellipsis"> |
| 220 | ${col} |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 221 | </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 Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 233 | let _html = items.map((item, index) => { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 234 | const $value = $(me.get_item_html(item)); |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 235 | |
| 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 245 | 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 Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 262 | `<div class="no-result text-center" style="${me.message ? "" : "display:none;"}"> |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 263 | <div class="msg-box no-border"> |
| 264 | <p>No Item found</p> |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 265 | </div> |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 266 | </div>`; |
| 267 | |
| 268 | return html; |
| 269 | }, |
| 270 | |
| 271 | get_item_html: function (item) { |
| 272 | var me = this; |
vishdha | 09d5675 | 2018-02-21 16:10:09 +0530 | [diff] [blame] | 273 | const company = me.options.selected_company; |
vishdha | 9a64d43 | 2018-02-21 11:26:58 +0530 | [diff] [blame] | 274 | const currency = frappe.get_doc(":Company", company).default_currency; |
vishdha | d4491d3 | 2018-02-21 09:33:35 +0530 | [diff] [blame] | 275 | const fields = ['name','value']; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 276 | |
| 277 | const html = |
| 278 | `<div class="list-item"> |
| 279 | ${ |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 280 | 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 288 | } |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 289 | |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 290 | return ( |
| 291 | `<div class="list-item_content ellipsis list-item__content--flex-2 |
Nabin Hait | 7d86227 | 2018-02-22 13:59:41 +0530 | [diff] [blame] | 292 | ${(col == "value") ? "text-right" : ""}"> |
| 293 | ${formatted_value} |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 294 | </div>`); |
| 295 | }).join("") |
| 296 | } |
| 297 | </div>`; |
| 298 | |
| 299 | return html; |
| 300 | }, |
| 301 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 302 | 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 Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 307 | } |
| 308 | }); |