odoo.define('pj_dashboard.Dashboard', function(require) { "use strict"; var AbstractAction = require('web.AbstractAction'); var core = require('web.core'); var QWeb = core.qweb; var ajax = require('web.ajax'); var rpc = require('web.rpc'); var _t = core._t; var session = require('web.session'); var web_client = require('web.web_client'); var abstractView = require('web.AbstractView'); var flag = 0; var tot_so = [] var tot_project = [] var tot_task = [] var tot_employee = [] var tot_hrs = [] var tot_margin = [] var PjDashboard = AbstractAction.extend({ template: 'PjDashboard', cssLibs: [ '/project_dashboard_odoo/static/src/css/lib/nv.d3.css' ], jsLibs: [ '/project_dashboard_odoo/static/src/js/lib/d3.min.js' ], events: { 'click .tot_projects': 'tot_projects', 'click .tot_tasks': 'tot_tasks', 'click .tot_profitability': 'tot_profitability', 'click .hr_recorded': 'hr_recorded', 'click .tot_sale': 'tot_sale', 'click .tot_emp': 'tot_emp', 'change #income_expense_values': 'onchange_profitability', 'change #start_date': '_onchangeFilter', 'change #end_date': '_onchangeFilter', 'change #employee_selection': '_onchangeFilter', 'change #project_selection': '_onchangeFilter', }, init: function(parent, context) { this._super(parent, context); this.dashboards_templates = ['DashboardProject', 'DashboardChart']; this.today_sale = []; }, willStart: function() { var self = this; return $.when(ajax.loadLibs(this), this._super()).then(function() { return self.fetch_data(); }); }, start: function() { var self = this; this.set("title", 'Dashboard'); return this._super().then(function() { self.render_dashboards(); self.render_graphs(); self.render_filter() }); }, render_dashboards: function() { var self = this; _.each(this.dashboards_templates, function(template) { self.$('.o_pj_dashboard').append(QWeb.render(template, { widget: self })); }); }, render_filter: function() { ajax.rpc('/project/filter').then(function(data) { var projects = data[0] var employees = data[1] $(projects).each(function(project) { $('#project_selection').append(""); }); $(employees).each(function(employee) { $('#employee_selection').append(""); }); }) }, render_graphs: function() { var self = this; self.render_project_task(); self.render_top_employees_graph(); self.income_this_year(); }, render_project_task: function() { var self = this rpc.query({ model: "project.project", method: "get_project_task_count", }).then(function(data) { var ctx = self.$("#project_doughnut"); new Chart(ctx, { type: "doughnut", data: { labels: data.project, datasets: [{ backgroundColor: data.color, data: data.task }] }, options: { legend: { position: 'left' }, title: { display: true, position: "top", text: " ProjectTask Analysis", fontSize: 20, fontColor: "#111" }, cutoutPercentage: 40, responsive: true, } }); }) }, on_reverse_breadcrumb: function() { var self = this; web_client.do_push_state({}); this.fetch_data().then(function() { self.$('.o_pj_dashboard').empty(); self.render_dashboards(); self.render_graphs(); }); }, _onchangeFilter: function() { flag = 1 var start_date = $('#start_date').val(); var end_date = $('#end_date').val(); if (!start_date) { start_date = "null" } if (!end_date) { end_date = "null" } var employee_selection = $('#employee_selection').val(); var project_selection = $('#project_selection').val(); ajax.rpc('/project/filter-apply', { 'data': { 'start_date': start_date, 'end_date': end_date, 'project': project_selection, 'employee': employee_selection } }).then(function(data) { tot_hrs = data['list_hours_recorded'] tot_employee = data['total_emp'] tot_project = data['total_project'] tot_task = data['total_task'] tot_so = data['total_so'] document.getElementById("tot_project").innerHTML = data['total_project'].length document.getElementById("tot_employee").innerHTML = data['total_emp'].length document.getElementById("tot_task").innerHTML = data['total_task'].length document.getElementById("tot_hrs").innerHTML = data['hours_recorded'] document.getElementById("tot_margin").innerHTML = data['total_margin'] document.getElementById("tot_so").innerHTML = data['total_so'].length }) }, onchange_profitability: function(ev) { var selected_filter = $('#income_expense_values').val() var self = this if (selected_filter == 'income_last_year') { self.income_last_year(ev) } else if (selected_filter == 'income_this_year') { self.income_this_year(ev) } else { self.income_this_month(ev) } }, /** for opening project view */ tot_projects: function(e) { var self = this; e.stopPropagation(); e.preventDefault(); var options = { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }; if (flag == 0) { this.do_action({ name: _t("Projects"), type: 'ir.actions.act_window', res_model: 'project.project', view_mode: 'kanban,form', views: [ [false, 'kanban'], [false, 'form'] ], target: 'current' }, options) } else { if (tot_project) { this.do_action({ name: _t("Projects"), type: 'ir.actions.act_window', res_model: 'project.project', domain: [ ["id", "in", tot_project] ], view_mode: 'kanban,form', views: [ [false, 'kanban'], [false, 'form'] ], target: 'current' }, options) } } }, /** for opening project task view */ tot_tasks: function(e) { var self = this; e.stopPropagation(); e.preventDefault(); var options = { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }; if (flag == 0) { this.do_action({ name: _t("Tasks"), type: 'ir.actions.act_window', res_model: 'project.task', view_mode: 'tree,kanban,form', views: [ [false, 'list'], [false, 'form'] ], target: 'current' }, options) } else { if (tot_task) { this.do_action({ name: _t("Tasks"), type: 'ir.actions.act_window', res_model: 'project.task', domain: [ ["id", "in", tot_task] ], view_mode: 'tree,kanban,form', views: [ [false, 'list'], [false, 'form'] ], target: 'current' }, options) } } }, /** for opening margin view */ tot_profitability: function(e) { var self = this; e.stopPropagation(); e.preventDefault(); var options = { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }; this.do_action({ name: _t("Profitability"), type: 'ir.actions.act_window', res_model: 'project.project', view_mode: 'pivot', views: [ [false, 'pivot'], [false, 'graph'] ], target: 'current' }, options) }, /** for opening account analytic line view */ hr_recorded: function(e) { var self = this; e.stopPropagation(); e.preventDefault(); var options = { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }; if (flag == 0) { this.do_action({ name: _t("Timesheets"), type: 'ir.actions.act_window', res_model: 'account.analytic.line', view_mode: 'tree,form', views: [ [false, 'list'] ], target: 'current' }, options) } else { if (tot_hrs) { this.do_action({ name: _t("Timesheets"), type: 'ir.actions.act_window', res_model: 'account.analytic.line', domain: [ ["id", "in", tot_hrs] ], view_mode: 'tree,form', views: [ [false, 'list'] ], target: 'current' }, options) } } }, /** for opening sale order view */ tot_sale: function(e) { var self = this; e.stopPropagation(); e.preventDefault(); var options = { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }; if (flag == 0) { this.do_action({ name: _t("Sale Order"), type: 'ir.actions.act_window', res_model: 'sale.order', view_mode: 'tree', views: [ [false, 'list'] ], domain: [ ["id", "in", tot_so] ], target: 'current' }, options) } else { if (tot_so) { this.do_action({ name: _t("Sale Order"), type: 'ir.actions.act_window', res_model: 'sale.order', domain: [ ["id", "in", tot_so] ], view_mode: 'tree', views: [ [false, 'list'] ], target: 'current' }, options) } } }, /** for opening hr employee view */ tot_emp: function(e) { var self = this; e.stopPropagation(); e.preventDefault(); var options = { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }; if (flag == 0) { this.do_action({ name: _t("Employees"), type: 'ir.actions.act_window', res_model: 'hr.employee', view_mode: 'tree,form', views: [ [false, 'list'], [false, 'form'] ], target: 'current' }, options) } else { this.do_action({ name: _t("Employees"), type: 'ir.actions.act_window', res_model: 'hr.employee', domain: [ ["id", "in", tot_employee] ], view_mode: 'tree,form', views: [ [false, 'list'], [false, 'form'] ], target: 'current' }, options) } }, render_top_employees_graph: function() { var self = this var ctx = self.$(".top_selling_employees"); rpc.query({ model: "project.project", method: 'get_top_timesheet_employees', }).then(function(arrays) { var data = { labels: arrays[1], datasets: [{ label: "Hours Spent", data: arrays[0], backgroundColor: [ "rgba(190, 27, 75,1)", "rgba(31, 241, 91,1)", "rgba(103, 23, 252,1)", "rgba(158, 106, 198,1)", "rgba(250, 217, 105,1)", "rgba(255, 98, 31,1)", "rgba(255, 31, 188,1)", "rgba(75, 192, 192,1)", "rgba(153, 102, 255,1)", "rgba(10,20,30,1)" ], borderColor: [ "rgba(190, 27, 75, 0.2)", "rgba(190, 223, 122, 0.2)", "rgba(103, 23, 252, 0.2)", "rgba(158, 106, 198, 0.2)", "rgba(250, 217, 105, 0.2)", "rgba(255, 98, 31, 0.2)", "rgba(255, 31, 188, 0.2)", "rgba(75, 192, 192, 0.2)", "rgba(153, 102, 255, 0.2)", "rgba(10,20,30,0.3)" ], borderWidth: 1 }, ] }; //options var options = { responsive: true, title: { display: true, position: "top", text: " Time by Employees", fontSize: 18, fontColor: "#111" }, scales: { yAxes: [{ ticks: { min: 0 } }] } }; //create Chart class object var chart = new Chart(ctx, { type: 'bar', data: data, options: options }); }); }, income_last_year: function(ev) { ev.preventDefault(); var selected = $('.btn.btn-tool.income'); var data = $(selected[0]).data(); var posted = 1; rpc.query({ model: 'project.project', method: 'get_income_last_year', args: [], }) .then(function(result) { $('#net_profit_current_months').hide(); $('#net_profit_last_year').show(); $('#net_profit_this_year').hide(); var ctx = document.getElementById("canvas").getContext('2d'); // Define the data var profit = result.profit; var labels = result.month; // Add labels to array // End Defining data // End Defining data if (window.myCharts != undefined) window.myCharts.destroy(); window.myCharts = new Chart(ctx, { //var myChart = new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Profitability', // Name the series data: profit, // Specify the data values array backgroundColor: '#0bd465', borderColor: '#0bd465', borderWidth: 1, // Specify bar border width type: 'line', // Set this data to a line chart fill: false }] }, options: { responsive: true, // Instruct chart js to respond nicely. maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height } }); }) }, income_this_year: function() { var selected = $('.btn.btn-tool.income'); var data = $(selected[0]).data(); var posted = false; rpc.query({ model: 'project.project', method: 'get_income_this_year', args: [], }) .then(function(result) { var ctx = document.getElementById("canvas").getContext('2d'); // Define the data var income = result.income; // Add data values to array // var expense = result.expense; var profit = result.profit; var labels = result.month; // Add labels to array if (window.myCharts != undefined) window.myCharts.destroy(); window.myCharts = new Chart(ctx, { //var myChart = new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Profitability', // Name the series data: profit, // Specify the data values array backgroundColor: '#0bd465', borderColor: '#0bd465', borderWidth: 1, // Specify bar border width type: 'line', // Set this data to a line chart fill: false }] }, options: { responsive: true, // Instruct chart js to respond nicely. maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height } }); }) }, income_this_month: function(ev) { ev.preventDefault(); var selected = $('.btn.btn-tool.income'); var data = $(selected[0]).data(); var posted = 1; rpc.query({ model: 'project.project', method: 'get_income_this_month', args: [], }) .then(function(result) { var ctx = document.getElementById("canvas").getContext('2d'); // Define the data var profit = result.profit; var labels = result.date; // Add labels to array // End Defining data // End Defining data if (window.myCharts != undefined) window.myCharts.destroy(); window.myCharts = new Chart(ctx, { //var myChart = new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [ { label: 'Profitability', // Name the series data: profit, // Specify the data values array backgroundColor: '#0bd465', borderColor: '#0bd465', borderWidth: 1, // Specify bar border width type: 'line', // Set this data to a line chart fill: false } ] }, options: { responsive: true, // Instruct chart js to respond nicely. maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height } }); }) }, fetch_data: function() { var self = this; var def1 = this._rpc({ model: 'project.project', method: 'get_tiles_data' }).then(function(result) { self.total_projects = result['total_projects'], self.total_tasks = result['total_tasks'], self.total_hours = result['total_hours'], self.total_profitability = result['total_profitability'], self.total_employees = result['total_employees'], self.total_sale_orders = result['total_sale_orders'], self.project_stage_list = result['project_stage_list'] tot_so = result['sale_list'] }); var def2 = self._rpc({ model: "project.project", method: "get_details", }) .then(function(res) { self.invoiced = res['invoiced']; self.to_invoice = res['to_invoice']; self.time_cost = res['time_cost']; self.expen_cost = res['expen_cost']; self.payment_details = res['payment_details']; }); var def3 = self._rpc({ model: "project.project", method: "get_hours_data", }) .then(function(res) { self.hour_recorded = res['hour_recorded']; self.hour_recorde = res['hour_recorde']; self.billable_fix = res['billable_fix']; self.non_billable = res['non_billable']; self.total_hr = res['total_hr']; }); var def4 = self._rpc({ model: "project.project", method: "get_task_data", }) .then(function(res) { self.task_data = res['project']; }); return $.when(def1, def2, def3, def4); }, }); core.action_registry.add('project_dashboard', PjDashboard); return PjDashboard; });