diff --git a/project_dashboard_odoo/README.rst b/project_dashboard_odoo/README.rst new file mode 100644 index 000000000..fefbf581f --- /dev/null +++ b/project_dashboard_odoo/README.rst @@ -0,0 +1,45 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +=========================== +Project Dashboard +=========================== +In this dashboard you can get Detailed Dashboard View for Project + + +Configuration +============= +* No additional configurations needed + +Company +------- +* `Cybrosys Techno Solutions `__ + +Credits +------- +* Developers: yadhukrishnan @ cybrosys, odoo@cybrosys.com + + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit `Our Website `__ + +Further information +=================== +HTML Description: ``__ + + diff --git a/project_dashboard_odoo/__init__.py b/project_dashboard_odoo/__init__.py new file mode 100644 index 000000000..1e015eaa4 --- /dev/null +++ b/project_dashboard_odoo/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Yadhukrishnan K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +################################################################################ +from . import controllers +from . import models diff --git a/project_dashboard_odoo/__manifest__.py b/project_dashboard_odoo/__manifest__.py new file mode 100644 index 000000000..d6010becc --- /dev/null +++ b/project_dashboard_odoo/__manifest__.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Yadhukrishnan K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +################################################################################ +{ + 'name': 'Project Dashboard', + 'category': 'Productivity, Project', + 'summary': """Project Dashboard For Odoo16 Community And Enterprise Edition""", + 'description': """In this dashboard user the Detailed information about + project, task, employee, hours recorded, total margin and total + sale orders.""", + 'version': '16.0.1.0.0', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'license': 'AGPL-3', + 'depends': [ + 'base', + 'sale_management', + 'project', + 'sale_timesheet', + ], + 'data': [ + 'views/dashboard_views.xml', + ], + 'images': [ + 'static/description/banner.png', + ], + 'assets': { + 'web.assets_backend': [ + 'project_dashboard_odoo/static/src/css/dashboard.css', + "project_dashboard_odoo/static/src/js/dashboard.js", + 'project_dashboard_odoo/static/src/xml/dashboard.xml', + 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js' + ], + }, + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/project_dashboard_odoo/controllers/__init__.py b/project_dashboard_odoo/controllers/__init__.py new file mode 100644 index 000000000..3478f4f60 --- /dev/null +++ b/project_dashboard_odoo/controllers/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Yadhukrishnan K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +################################################################################ +from . import project_dashboard_odoo diff --git a/project_dashboard_odoo/controllers/project_dashboard_odoo.py b/project_dashboard_odoo/controllers/project_dashboard_odoo.py new file mode 100644 index 000000000..e77160a06 --- /dev/null +++ b/project_dashboard_odoo/controllers/project_dashboard_odoo.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Yadhukrishnan K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +################################################################################ +import datetime + +from odoo import http +from odoo.http import request + + +class ProjectFilter(http.Controller): + """ + The ProjectFilter class provides the filter option to the js. + When applying the filter return the corresponding data. + Methods: + project_filter(self): + when the page is loaded adding filter options to the selection + field. + return a list variable. + project_filter_apply(self,**kw): + after applying the filter receiving the values and return the + filtered data. + + """ + + @http.route('/project/filter', auth='public', type='json') + def project_filter(self): + """ + + Summery: + transferring data to the selection field that works as a filter + Returns: + type:list of lists , it contains the data for the corresponding + filter. + + + """ + project_list = [] + employee_list = [] + project_ids = request.env['project.project'].search([]) + employee_ids = request.env['hr.employee'].search([]) + # getting partner data + for employee_id in employee_ids: + dic = {'name': employee_id.name, + 'id': employee_id.id} + employee_list.append(dic) + for project_id in project_ids: + dic = {'name': project_id.name, + 'id': project_id.id} + project_list.append(dic) + return [project_list, employee_list] + + @http.route('/project/filter-apply', auth='public', type='json') + def project_filter_apply(self, **kw): + """ + Summery: + transferring data after filter 9is applied + Args: + kw(dict):This parameter contain value of selection field + Returns: + type:dict, it contains the data for the corresponding + filter. + + and transferring data to ui after filtration. + + + """ + data = kw['data'] + # checking the employee selected or not + if data['employee'] == 'null': + emp_selected = [employee.id for employee in + request.env['hr.employee'].search([])] + else: + emp_selected = [int(data['employee'])] + start_date = data['start_date'] + end_date = data['end_date'] + # checking the dates are selected or not + if start_date != 'null' and end_date != 'null': + start_date = datetime.datetime.strptime(start_date, + "%Y-%m-%d").date() + end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d").date() + if data['project'] == 'null': + pro_selected = [project.id for project in + request.env['project.project'].search( + [('date_start', '>', start_date), + ('date_start', '<', end_date)])] + else: + pro_selected = [int(data['project'])] + elif start_date == 'null' and end_date != 'null': + end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d").date() + if data['project'] == 'null': + pro_selected = [project.id for project in + request.env['project.project'].search( + [('date_start', '<', end_date)])] + else: + pro_selected = [int(data['project'])] + + elif start_date != 'null' and end_date == 'null': + start_date = datetime.datetime.strptime(start_date, + "%Y-%m-%d").date() + if data['project'] == 'null': + pro_selected = [project.id for project in + request.env['project.project'].search( + [('date_start', '>', start_date)])] + else: + pro_selected = [int(data['project'])] + else: + if data['project'] == 'null': + pro_selected = [project.id for project in + request.env['project.project'].search([])] + else: + pro_selected = [int(data['project'])] + report_project = request.env['timesheets.analysis.report'].search( + [('project_id', 'in', pro_selected), + ('employee_id', 'in', emp_selected)]) + analytic_project = request.env['account.analytic.line'].search( + [('project_id', 'in', pro_selected), + ('employee_id', 'in', emp_selected)]) + margin = sum(report_project.mapped('margin')) + sale_orders = [] + for rec in analytic_project: + if rec.order_id.id and rec.order_id.id not in sale_orders: + sale_orders.append(rec.order_id.id) + total_time = sum(analytic_project.mapped('unit_amount')) + return { + 'total_project': pro_selected, + 'total_emp': emp_selected, + 'total_task': [rec.id for rec in request.env['project.task'].search( + [('project_id', 'in', pro_selected)])], + 'hours_recorded': total_time, + 'list_hours_recorded': [rec.id for rec in analytic_project], + 'total_margin': margin, + 'total_so': sale_orders + } diff --git a/project_dashboard_odoo/doc/RELEASE_NOTES.md b/project_dashboard_odoo/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..31d9ff2ae --- /dev/null +++ b/project_dashboard_odoo/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 29.03.2023 +#### Version 16.0.1.0.0 +##### ADD +##### Initial Commit for Project Dashboard diff --git a/project_dashboard_odoo/models/__init__.py b/project_dashboard_odoo/models/__init__.py new file mode 100644 index 000000000..229b85462 --- /dev/null +++ b/project_dashboard_odoo/models/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Yadhukrishnan K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +################################################################################ +from . import project diff --git a/project_dashboard_odoo/models/project.py b/project_dashboard_odoo/models/project.py new file mode 100644 index 000000000..c6165037a --- /dev/null +++ b/project_dashboard_odoo/models/project.py @@ -0,0 +1,339 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Yadhukrishnan K (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +################################################################################ +import random +from odoo import api, models + + +class Project(models.Model): + """ + + The ProjectDashboard class provides the data to the js when the dashboard is + loaded. + Methods: + get_tiles_data(self): + when the page is loaded get the data from different models and + transfer to the js file. + return a dictionary variable. + get_top_timesheet_employees(model_ids): + getting data for the timesheet graph. + get_hours_data(self): + getting data for the hours table. + get_task_data(self): + getting data to project task table + get_project_task_count(self): + getting data to project task table + get_color_code(self): + getting dynamic color code for the graph + + """ + _inherit = 'project.project' + + @api.model + def get_tiles_data(self): + """ + + Summery: + when the page is loaded get the data from different models and + transfer to the js file. + return a dictionary variable. + return: + type:It is a dictionary variable. This dictionary contain data that + affecting the dashboard view. + + """ + user_employee = self.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + all_project = self.env['project.project'].search([]) + all_task = self.env['project.task'].search([]) + analytic_project = self.env['account.analytic.line'].search([]) + report_project = self.env['timesheets.analysis.report'].search([]) + margin = sum(report_project.mapped('margin')) + total_time = sum(analytic_project.mapped('unit_amount')) + employees = self.env['hr.employee'].search([]) + + task = self.env['project.task'].search_read([ + ('sale_order_id', '!=', False) + ], ['sale_order_id']) + task_so_ids = [o['sale_order_id'][0] for o in task] + sale_orders = self.mapped('sale_line_id.order_id') | self.env[ + 'sale.order'].browse(task_so_ids) + project_stage_ids = self.env['project.project.stage'].search([]) + project_stage_list = [] + for project_stage_id in project_stage_ids: + total_projects = self.env['project.project'].search_count( + [('stage_id', '=', project_stage_id.id)]) + project_stage_list.append({ + 'name': project_stage_id.name, + 'projects': total_projects + }) + return { + 'total_projects': len(all_project), + 'total_projects_ids': all_project.ids, + 'total_tasks': len(all_task), + 'total_tasks_ids': all_task.ids, + 'total_hours': total_time, + 'total_profitability': margin, + 'total_employees': len(employees), + 'total_sale_orders': len(sale_orders), + 'sale_orders_ids': sale_orders.mapped('id'), + 'project_stage_list': project_stage_list, + 'flag': 1 + } + else: + all_project = self.env['project.project'].search( + [('user_id', '=', self.env.uid)]) + all_task = [] + for task in self.env['project.task'].search([]): + for assignee in task.user_ids: + if assignee.id == self.env.uid: + all_task.append(task.id) + analytic_project = self.env['account.analytic.line'].search( + [('project_id', 'in', all_project.ids)]) + total_time = sum(analytic_project.mapped('unit_amount')) + task = self.env['project.task'].search_read([ + ('sale_order_id', '!=', False), + ('project_id', 'in', all_project.ids) + ], ['sale_order_id']) + task_so_ids = [o['sale_order_id'][0] for o in task] + sale_orders = self.mapped('sale_line_id.order_id') | self.env[ + 'sale.order'].browse(task_so_ids) + project_stage_ids = self.env['project.project.stage'].search([]) + project_stage_list = [] + for project_stage_id in project_stage_ids: + total_projects = self.env['project.project'].search_count( + [('stage_id', '=', project_stage_id.id), + ('id', 'in', all_project.ids)]) + project_stage_list.append({ + 'name': project_stage_id.name, + 'projects': total_projects + }) + return { + 'total_projects': len(all_project), + 'total_projects_ids': all_project.ids, + 'total_tasks': len(all_task), + 'total_tasks_ids': all_task, + 'total_hours': total_time, + 'total_sale_orders': len(sale_orders), + 'sale_orders_ids': sale_orders.mapped('id'), + 'project_stage_list': project_stage_list, + 'flag': 2 + } + + @api.model + def get_top_timesheet_employees(self): + """ + + Summery: + when the page is loaded get the data for the timesheet graph. + return: + type:It is a list. This list contain data that affecting the graph + of employees. + + """ + query = '''select hr_employee.name as employee,sum(unit_amount) as unit + from account_analytic_line + inner join hr_employee on hr_employee.id = + account_analytic_line.employee_id + group by hr_employee.id ORDER + BY unit DESC Limit 10 ''' + self._cr.execute(query) + top_product = self._cr.dictfetchall() + + unit = [] + for record in top_product: + unit.append(record.get('unit')) + employee = [] + for record in top_product: + employee.append(record.get('employee')) + final = [unit, employee] + + return final + + @api.model + def get_hours_data(self): + """ + + Summery: + when the page is loaded get the data for the hours table. + return: + type:It is a dictionary variable. This dictionary contain data that + hours table. + + """ + user_employee = self.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + query = '''SELECT sum(unit_amount) as hour_recorded FROM account_analytic_line + WHERE timesheet_invoice_type='non_billable_project' ''' + self._cr.execute(query) + data = self._cr.dictfetchall() + hour_recorded = [] + for record in data: + hour_recorded.append(record.get('hour_recorded')) + + query = '''SELECT sum(unit_amount) as hour_recorde FROM account_analytic_line + WHERE timesheet_invoice_type='billable_time' ''' + self._cr.execute(query) + data = self._cr.dictfetchall() + hour_recorde = [] + for record in data: + hour_recorde.append(record.get('hour_recorde')) + + query = '''SELECT sum(unit_amount) as billable_fix FROM account_analytic_line + WHERE timesheet_invoice_type='billable_fixed' ''' + self._cr.execute(query) + data = self._cr.dictfetchall() + billable_fix = [] + for record in data: + billable_fix.append(record.get('billable_fix')) + + query = '''SELECT sum(unit_amount) as non_billable FROM account_analytic_line + WHERE timesheet_invoice_type='non_billable' ''' + self._cr.execute(query) + data = self._cr.dictfetchall() + non_billable = [] + for record in data: + non_billable.append(record.get('non_billable')) + + query = '''SELECT sum(unit_amount) as total_hr FROM account_analytic_line + WHERE timesheet_invoice_type='non_billable_project' or + timesheet_invoice_type='billable_time' + or timesheet_invoice_type='billable_fixed' or + timesheet_invoice_type='non_billable' ''' + self._cr.execute(query) + data = self._cr.dictfetchall() + total_hr = [] + for record in data: + total_hr.append(record.get('total_hr')) + return { + 'hour_recorded': hour_recorded, + 'hour_recorde': hour_recorde, + 'billable_fix': billable_fix, + 'non_billable': non_billable, + 'total_hr': total_hr, + } + else: + all_project = self.env['project.project'].search( + [('user_id', '=', self.env.uid)]).ids + analytic_project = self.env['account.analytic.line'].search( + [('project_id', 'in', all_project)]) + all_hour_recorded = analytic_project.filtered( + lambda x: x.timesheet_invoice_type == 'non_billable_project') + all_hour_recorde = analytic_project.filtered( + lambda x: x.timesheet_invoice_type == 'billable_time') + all_billable_fix = analytic_project.filtered( + lambda x: x.timesheet_invoice_type == 'billable_fixed') + all_non_billable = analytic_project.filtered( + lambda x: x.timesheet_invoice_type == 'non_billable') + + hour_recorded = [sum(all_hour_recorded.mapped('unit_amount'))] + hour_recorde = [sum(all_hour_recorde.mapped('unit_amount'))] + billable_fix = [sum(all_billable_fix.mapped('unit_amount'))] + non_billable = [sum(all_non_billable.mapped('unit_amount'))] + total_hr = [sum(hour_recorded + hour_recorde + billable_fix + non_billable)] + + return { + 'hour_recorded': hour_recorded, + 'hour_recorde': hour_recorde, + 'billable_fix': billable_fix, + 'non_billable': non_billable, + 'total_hr': total_hr, + } + + @api.model + def get_task_data(self): + """ + + Summery: + when the page is loaded get the data from different models and + transfer to the js file. + return a dictionary variable. + return: + type:It is a dictionary variable. This dictionary contain data that + affecting project task table. + + """ + user_employee = self.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + self._cr.execute('''select project_task.name as task_name, + pro.name as project_name from project_task + Inner join project_project as pro on project_task.project_id = pro.id + ORDER BY project_name ASC''') + data = self._cr.fetchall() + project_name = [] + for rec in data: + project_name.append(list(rec)) + return { + 'project': project_name + } + else: + all_project = self.env['project.project'].search( + [('user_id', '=', self.env.uid)]).ids + all_tasks = self.env['project.task'].search( + [('project_id', 'in', all_project)]) + + task_project = [[task.name, task.project_id.name] for task in + all_tasks] + return { + 'project': task_project + } + + @api.model + def get_project_task_count(self): + """ + Summery: + when the page is loaded get the data from different models and + transfer to the js file. + return a dictionary variable. + return: + type:It is a dictionary variable. This dictionary contain data for + the project task graph. + """ + project_name = [] + total_task = [] + colors = [] + user_employee = self.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + project_ids = self.env['project.project'].search([]) + else: + project_ids = self.env['project.project'].search( + [('user_id', '=', self.env.uid)]) + for project_id in project_ids: + project_name.append(project_id.name) + task = self.env['project.task'].search_count( + [('project_id', '=', project_id.id)]) + total_task.append(task) + color_code = self.get_color_code() + colors.append(color_code) + return { + 'project': project_name, + 'task': total_task, + 'color': colors + } + + def get_color_code(self): + """ + Summery: + the function is for creating the dynamic color code. + return: + type:variable containing color code. + """ + color = "#{:06x}".format(random.randint(0, 0xFFFFFF)) + return color diff --git a/project_dashboard_odoo/static/description/assets/icons/check.png b/project_dashboard_odoo/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/check.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/chevron.png b/project_dashboard_odoo/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/chevron.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/cogs.png b/project_dashboard_odoo/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/cogs.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/consultation.png b/project_dashboard_odoo/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/consultation.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/ecom-black.png b/project_dashboard_odoo/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/ecom-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/education-black.png b/project_dashboard_odoo/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/education-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/hotel-black.png b/project_dashboard_odoo/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/hotel-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/license.png b/project_dashboard_odoo/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/license.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/lifebuoy.png b/project_dashboard_odoo/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/lifebuoy.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/manufacturing-black.png b/project_dashboard_odoo/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/manufacturing-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/pos-black.png b/project_dashboard_odoo/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/pos-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/puzzle.png b/project_dashboard_odoo/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/puzzle.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/restaurant-black.png b/project_dashboard_odoo/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/restaurant-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/service-black.png b/project_dashboard_odoo/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/service-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/trading-black.png b/project_dashboard_odoo/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/trading-black.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/training.png b/project_dashboard_odoo/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/training.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/update.png b/project_dashboard_odoo/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/update.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/user.png b/project_dashboard_odoo/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/user.png differ diff --git a/project_dashboard_odoo/static/description/assets/icons/wrench.png b/project_dashboard_odoo/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/wrench.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/categories.png b/project_dashboard_odoo/static/description/assets/misc/categories.png new file mode 100644 index 000000000..bedf1e0b1 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/categories.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/check-box.png b/project_dashboard_odoo/static/description/assets/misc/check-box.png new file mode 100644 index 000000000..42caf24b9 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/check-box.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/compass.png b/project_dashboard_odoo/static/description/assets/misc/compass.png new file mode 100644 index 000000000..d5fed8faa Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/compass.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/corporate.png b/project_dashboard_odoo/static/description/assets/misc/corporate.png new file mode 100644 index 000000000..2eb13edbf Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/corporate.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/customer-support.png b/project_dashboard_odoo/static/description/assets/misc/customer-support.png new file mode 100644 index 000000000..79efc72ed Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/customer-support.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/cybrosys-logo.png b/project_dashboard_odoo/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 000000000..cc3cc0ccf Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/cybrosys-logo.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/features.png b/project_dashboard_odoo/static/description/assets/misc/features.png new file mode 100644 index 000000000..b41769f77 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/features.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/logo.png b/project_dashboard_odoo/static/description/assets/misc/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/logo.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/pictures.png b/project_dashboard_odoo/static/description/assets/misc/pictures.png new file mode 100644 index 000000000..56d255fe9 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/pictures.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/pie-chart.png b/project_dashboard_odoo/static/description/assets/misc/pie-chart.png new file mode 100644 index 000000000..426e05244 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/pie-chart.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/right-arrow.png b/project_dashboard_odoo/static/description/assets/misc/right-arrow.png new file mode 100644 index 000000000..730984a06 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/right-arrow.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/star.png b/project_dashboard_odoo/static/description/assets/misc/star.png new file mode 100644 index 000000000..2eb9ab29f Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/star.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/support.png b/project_dashboard_odoo/static/description/assets/misc/support.png new file mode 100644 index 000000000..4f18b8b82 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/support.png differ diff --git a/project_dashboard_odoo/static/description/assets/misc/whatsapp.png b/project_dashboard_odoo/static/description/assets/misc/whatsapp.png new file mode 100644 index 000000000..d513a5356 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/whatsapp.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/l1.png b/project_dashboard_odoo/static/description/assets/modules/l1.png new file mode 100644 index 000000000..ed175b076 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/l1.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/l2.png b/project_dashboard_odoo/static/description/assets/modules/l2.png new file mode 100644 index 000000000..a3194264c Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/l2.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/l3.png b/project_dashboard_odoo/static/description/assets/modules/l3.png new file mode 100644 index 000000000..e894393ef Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/l3.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/l4.png b/project_dashboard_odoo/static/description/assets/modules/l4.png new file mode 100644 index 000000000..f3c986fc1 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/l4.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/l5.png b/project_dashboard_odoo/static/description/assets/modules/l5.png new file mode 100644 index 000000000..b21837312 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/l5.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/l6.png b/project_dashboard_odoo/static/description/assets/modules/l6.png new file mode 100644 index 000000000..e64a5b55c Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/l6.png differ diff --git a/project_dashboard_odoo/static/description/assets/screenshots/Screenshot.png b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot.png new file mode 100644 index 000000000..c1fea9f67 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot.png differ diff --git a/project_dashboard_odoo/static/description/assets/screenshots/Screenshot2.png b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot2.png new file mode 100644 index 000000000..4604b198f Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot2.png differ diff --git a/project_dashboard_odoo/static/description/assets/screenshots/Screenshot3.png b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot3.png new file mode 100644 index 000000000..b4923f837 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot3.png differ diff --git a/project_dashboard_odoo/static/description/assets/screenshots/Screenshot4.png b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot4.png new file mode 100644 index 000000000..3880a808f Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/screenshots/Screenshot4.png differ diff --git a/project_dashboard_odoo/static/description/assets/screenshots/hero.gif b/project_dashboard_odoo/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..38201a40e Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/screenshots/hero.gif differ diff --git a/project_dashboard_odoo/static/description/banner.png b/project_dashboard_odoo/static/description/banner.png new file mode 100644 index 000000000..6c8c8adc3 Binary files /dev/null and b/project_dashboard_odoo/static/description/banner.png differ diff --git a/project_dashboard_odoo/static/description/icon.png b/project_dashboard_odoo/static/description/icon.png new file mode 100644 index 000000000..9730d8059 Binary files /dev/null and b/project_dashboard_odoo/static/description/icon.png differ diff --git a/project_dashboard_odoo/static/description/index.html b/project_dashboard_odoo/static/description/index.html new file mode 100644 index 000000000..4e7c34412 --- /dev/null +++ b/project_dashboard_odoo/static/description/index.html @@ -0,0 +1,520 @@ +
+ +
+ +
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+ +
+
+
+ +

+ Project Dashboard +

+

In This Dashboard You Can Get Detailed View for Project.

+ + +
+
+
+
+ + +
+
+ +
+

Explore This + Module

+
+ + + + +
+
+ +
+

Overview +

+
+
+
+ In this dashboard you can get all the details about project module. +
+ +
+ + + +
+
+ +
+

Features +

+
+
+
+
+ + User can see all details about project and task through graphs. +
+
+ + User can see all details about timesheet through graphs. +
+
+
+ +
+ + User can see all projects with stages. +
+ + User can use filter based on the employee, project and dates. +
+
+ + + +
+
+ +
+

Screenshots +

+
+
+
+ +
+

Dynamic And Clickable Dashboard Tiles + +

+

+ User can click the Tiles and States in tile,That shows the detailed view of corresponding tiles. +

+ +
+ +
+

Different Types of Graphs +

+

Project dashboard have different types of graphs that will give you complete analyse of the project module. + +

+ +
+ +
+ +
+ +
+

Project Table + +

+

User can see all Project ad its current status. +

+ +
+ +
+
+ + + +
+
+ +
+

+ Related + Products +

+
+
+
+ +
+
+ + + + +
+
+ +
+

+ Our Services +

+
+ +
+
+
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+ +
+ + + + + +
+
+ +
+

+ Our + Industries +

+
+ +
+
+
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+
+
+ + + + +
+
+ +
+

+ Support +

+
+
+
+
+
+
+ +
+
+

Need Help?

+

Got questions or need help? + Get in touch.

+ +

+ odoo@cybrosys.com

+
+
+
+
+
+
+
+ +
+
+

WhatsApp

+

Say hi to us on WhatsApp!

+ +

+ +91 86068 + 27707

+
+
+
+
+
+
+
+ +
+
+
+ \ No newline at end of file diff --git a/project_dashboard_odoo/static/src/css/dashboard.css b/project_dashboard_odoo/static/src/css/dashboard.css new file mode 100644 index 000000000..69822ace7 --- /dev/null +++ b/project_dashboard_odoo/static/src/css/dashboard.css @@ -0,0 +1,426 @@ +.oh-card h4 { + font-size: 1.1rem; +} + +.stat-icon { + display: inline-block; +} + +.stat-widget-one .stat-icon { + vertical-align: top; + margin: auto; + width: 100%; +} + +.stat-widget-one .stat-icon i { + font-size: 30px; + font-weight: 900; + display: inline-block; + color: #01c490; +} + +.stat-widget-one .stat-text { + font-size: 14px; + color: #868e96; + font-weight: bold; + +} + +.stat-widget-one .stat-digit { + font-size: 24px; + color: #02448b; +} + +.stat_count { + font-size: 28px !important; +} + +body .text-color { + color: #00438b; +} +/* Leave graph */ +path { + stroke: #fff; +} + +path:hover { + opacity: 0.9; +} + +rect:hover { + fill: #934da5; +} + +.axis { + font: 10px sans-serif; +} + +.legend tr { + border-bottom: 1px solid grey; +} + +.legend tr:first-child { + border-top: 1px solid grey; +} + +.axis path, +.axis line { + fill: none; + stroke: #000; + shape-rendering: crispEdges; +} + +.x.axis path { + display: none; +} + +.legend { + border-collapse: collapse; + border-spacing: 0px; + display: inline-block; +} + +.legend td, +.legend .legend_col { + padding: 4px 5px; + vertical-align: bottom; +} + +.legendFreq, +.legendPerc { + align: right; + width: 50px; +} + +/* Leave broadfactor graph */ + +.broad_factor_graph .axis path, +.broad_factor_graph .axis line { + fill: none; + stroke: black; + shape-rendering: crispEdges; +} + +.broad_factor_graph .axis text { + font-family: sans-serif; + font-size: 11px; +} + +.broad_factor_graph rect { + -moz-transition: all 0.3s; + -webkit-transition: all 0.3s; + -o-transition: all 0.3s; + transition: all 0.3s; +} + +.broad_factor_graph rect:hover { + fill: #ff618a; +} + +#broad_factor_pdf { + background-color: #ffffff; + border: 0; + color: #000000; + float: right; +} + +#broad_factor_pdf i { + color: red; +} + + +/*=====================New Dashboard===========================*/ + +.oh_dashboards { + background-color: #f8faff !important; + padding: 0px !important; + +} + +.container-fluid.o_hr_dashboard { + padding: 0px !important; +} + +.employee-prof { + + padding: 0px; + height: 100%; + background-color: #3e6282; + /*background-image: linear-gradient(180deg, #3e6282, #41666f);*/ + position: fixed; + /*z-index: 999;*/ +} + +.employee-prof .oh-card:hover { + + transform: none !important; + box-shadow: none !important; + +} + +.oh-card { + + padding-top: 0px; + padding: 0px; + margin-bottom: 1.5rem; + border-radius: 0px; + box-shadow: none; + background: none; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + +} + +.oh-card:hover { + + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; + +} + +.media-body.employee-name { + + background: #466b8d; + float: left; + margin: 0; + width: 100% +} + +.oh-payslip { + + margin-top: 1.5%; + +} + +.oh-payslip .stat-icon { + + width: 30%; + height: 85px; + text-align: center; + padding-top: 2%; + color: #fff; + +} + +.oh-payslip .oh-card { + + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62, 57, 107, 0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.06); + +} + +.stat-widget-one .stat-text { + + font-size: 14px; + color: #ff8762; + margin-top: 2.3rem; + margin-left: 1rem; + +} + +.stat-widget-one .stat-digit { + + font-size: 17px; + color: #000; + margin-left: 1rem; + padding-left: 26px; + +} + +.stat-widget-one .stat-icon i { + font-size: 32px; + display: inline-block; + color: #000; + top: 16px; + position: relative; +} + +.stat-widget-one { + + background-color: white; + text-align: inherit !important; + +} + +.stat-widget-one { + width: 100%; +} + +.oh-payslip .stat-icon { + + width: 30%; + height: 85px; + text-align: center; + padding-top: 2%; + +} + + +h4 .stat-count { + font-size: 17px; + text-align: center; + color: #000 !important; + margin-top: 0px; + width: 100%; + float: left; + margin: 0; +} + +.hr-chart-1 { + margin: 15px 0px; + background: #fff; + padding: 0px !important; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62, 57, 107, 0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.06); +} + +.hr-chart-1:hover { + transform: translateY(-2px) translateZ(0) !important; + box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important; +} + +.stat-head { + text-align: center !important; + font-weight: 300; + font-size: 21px; + margin-bottom: 12px; + margin-left: 2px; +} + + +.hr_birthday { + font-size: 17px; + text-align: center; + padding: 20px 0; + color: #00438b; + font-weight: 300; +} + +.hr_notification img { + width: 40px; + height: 40px; + border-radius: 100%; +} + +.hr_notification { + background: #fff; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62, 57, 107, 0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.06); + height: 757px; + margin-bottom: 15px; +} + +.hr_notification .media { + border-bottom: 1px solid #e6e6e6; + padding-bottom: 6px; + margin-bottom: 10px; +} + +.hr_notification .text-color.display-6 { + margin: 0px 0 3px; + color: #2d2d2d; +} + +.hr_notification p { + margin: 0 0 1px; + color: #666; + font-size: 10px; +} + +.hr_notification_head { + font-size: 17px; + text-align: center; + padding: 12px 0; + color: #fff; + font-weight: 300; + background: #5ebade; + margin-bottom: 9px; +} + +.hr-chart-1 { + margin: 15px 0px; + background: #fff; + padding: 0px !important; + padding-top: 0px; + transition: transform 0.2s ease, box-shadow 0.2s ease; + will-change: transform, box-shadow; + box-shadow: 0 10px 40px 0 rgba(62, 57, 107, 0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.06); + padding-top: 3px !important; +} + +/* width */ +.hr_notification::-webkit-scrollbar { + width: 4px; +} + +/* Track */ +.hr_notification::-webkit-scrollbar-track { + background: #f1f1f1; +} + +/* Handle */ +.hr_notification::-webkit-scrollbar-thumb { + background: #495057; + ; +} + +/* Handle on hover */ +.hr_notification::-webkit-scrollbar-thumb:hover { + background: #598da1; +} + +.oh-card-body { + display: flex; + justify-content: space-between; + align-items: center; +} + +.text-align { + margin-left: 17px; +} + +.inner_select { + min-width: 150px +} + +#table_status { + width: 90%; + margin-left: 5%; + font-family: Arial, Helvetica, sans-serif; +} + +#table_status tr:nth-child(even) { + background-color: #f2f2f2; +} + +#table_status tr:hover { + background-color: #ddd; +} + +.fleet-pill { + align-items: center; + font-family: "Open Sans", Arial, Verdana, sans-serif; + font-weight: bold; + font-size: 11px; + display: inline-block; + height: 100%; + white-space: nowrap; + width: auto; + position: relative; + border-radius: 100px; + line-height: 1; + overflow: hidden; + padding: 0px 8px 0px 7px; + text-overflow: ellipsis; + line-height: 1.25rem; + color: #fff; + word-break: break-word; + background: #0253e8; +} + +.inner_select p { + margin-left: 20px +} \ No newline at end of file diff --git a/project_dashboard_odoo/static/src/js/dashboard.js b/project_dashboard_odoo/static/src/js/dashboard.js new file mode 100644 index 000000000..5d9638caf --- /dev/null +++ b/project_dashboard_odoo/static/src/js/dashboard.js @@ -0,0 +1,483 @@ +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 web_client = require('web.web_client'); + var ProjectDashboard = AbstractAction.extend({ + template: 'ProjectDashboard', + 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 #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(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(); + }); + }, + /** + rendering the dashboard + */ + render_dashboards: function() { + var self = this; + _.each(this.dashboards_templates, function(template) { + self.$('.o_pj_dashboard').append(QWeb.render(template, { + widget: self + })); + }); + }, + /** + function for getting values to the filters + */ + 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(""); + }); + }) + }, + /** + function for getting values to the filters + */ + _onchangeFilter: function() { + this.flag = 1 + var start_date = $('#start_date').val(); + var end_date = $('#end_date').val(); + var self = this; + 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) { + self.tot_hrs = data['list_hours_recorded'] + self.tot_employee = data['total_emp'] + self.tot_project = data['total_project'] + self.tot_task = data['total_task'] + self.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 + }) + }, + /** + rendering the graph + */ + render_graphs: function() { + var self = this; + self.render_project_task(); + self.render_top_employees_graph(); + }, + 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(); + }); + }, + /** + function for getting values to project graph + */ + 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' + }, + cutoutPercentage: 40, + responsive: true, + } + }); + }) + }, + /** + 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 (this.flag == 0) { + this.do_action({ + name: _t("Projects"), + type: 'ir.actions.act_window', + res_model: 'project.project', + domain: [ + ["id", "in", this.total_projects_ids] + ], + view_mode: 'kanban,form', + views: [ + [false, 'kanban'], + [false, 'form'] + ], + target: 'current' + }, options) + } else { + if (this.tot_project) { + this.do_action({ + name: _t("Projects"), + type: 'ir.actions.act_window', + res_model: 'project.project', + domain: [ + ["id", "in", this.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, + }; + this.do_action({ + name: _t("Tasks"), + type: 'ir.actions.act_window', + res_model: 'project.task', + domain: [ + ["id", "in", self.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 (this.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 (this.tot_hrs) { + this.do_action({ + name: _t("Timesheets"), + type: 'ir.actions.act_window', + res_model: 'account.analytic.line', + domain: [ + ["id", "in", this.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, + }; + this.do_action({ + name: _t("Sale Order"), + type: 'ir.actions.act_window', + res_model: 'sale.order', + domain: [ + ["id", "in", this.tot_so] + ], + view_mode: 'tree,form', + views: [ + [false, 'list'], + [false, 'form'] + ], + target: 'current' + }, options) + }, + /** + for opening total hr employee view + */ + tot_emp: function(e) { + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + if (this.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", this.tot_employee] + ], + view_mode: 'tree,form', + views: [ + [false, 'list'], + [false, 'form'] + ], + target: 'current' + }, options) + + } + }, + /** + function for getting values to employee graph + */ + 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" + }, + legend: { + display: false, + }, + scales: { + yAxes: [{ + ticks: { + min: 0 + } + }] + } + }; + //create Chart class object + var chart = new Chart(ctx, { + type: 'bar', + data: data, + options: options + }); + + }); + }, + /** + function for getting values when page is loaded + */ + fetch_data: function() { + this.flag = 0 + var self = this; + var def1 = this._rpc({ + model: 'project.project', + method: 'get_tiles_data' + }).then(function(result) { + if (result['flag'] == 1) { + self.total_projects = result['total_projects'] + self.total_tasks = result['total_tasks'] + self.tot_task = result['total_tasks_ids'] + 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'] + self.tot_so = result['sale_orders_ids'] + self.flag_user = result['flag'] + self.total_projects_ids = result['total_projects_ids'] + } else { + self.tot_task = result['total_tasks_ids'] + self.total_projects = result['total_projects'] + self.total_tasks = result['total_tasks'] + self.total_hours = result['total_hours'] + self.total_sale_orders = result['total_sale_orders'] + self.project_stage_list = result['project_stage_list'] + self.flag_user = result['flag'] + self.tot_so = result['sale_orders_ids'] + self.total_projects_ids = result['total_projects_ids'] + } + }); + /** + function for getting values to hours table + */ + 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, def3, def4); + }, + }); + core.action_registry.add('project_dashboard', ProjectDashboard); + return ProjectDashboard; +}); \ No newline at end of file diff --git a/project_dashboard_odoo/static/src/xml/dashboard.xml b/project_dashboard_odoo/static/src/xml/dashboard.xml new file mode 100644 index 000000000..a6133d019 --- /dev/null +++ b/project_dashboard_odoo/static/src/xml/dashboard.xml @@ -0,0 +1,322 @@ + + + + +
+
+
+
+
+ +
+ +
+

Start Date :

+

+ +

+

End Date :

+

+ +

+

Project :

+

+ +

+

Employees :

+

+ +

+
+
+
+
+
+
+
+
Total Project
+
+ +
+
+
+
+
+ +
+
+
+
+
+
Total Employees
+
+ +
+
+
+
+
+
+
+
+
+
+
+
Total tasks
+
+ +
+
+
+
+
+ +
+
+
+
+
+
Hours Recorded
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
Total Margin
+
+ +
+
+
+
+
+
+
+
+
+
+
+
Total Sale Orders
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+
+

Project Task Analysis

+
+ +
+
+
+
+ +
+
+
+ +
+
+
+ Project Task Details +
+
+
+
+
+ + + + + + + + + + + + + + + +
Project NameTask Name
+ + + + + + + + +
+
+
+
+
+
+
+
+ Hours Recorded +
+
+
+
+
+
+ + + + + + + + + + + + + + +
Billed on Timesheet
+

+ +

+
+ + + + + + + + + + + + + +
Billed at a Fixed price
+

+ +

+
+ + + + + + + + + + + + + + + +
No task found
+

+ + +

+
+ + + + + + + + + + + + + +
Non Billable Tasks
+

+ + +

+
+ + + + + + + + + + + + + + + +
Total:
+

+ + +

+
+
+
+
+
+
+
+
+ Stage Wise Total Projects +
+ + + + + + + + + +
+ +
+

+

+

+

+
+
+
+
+
+
+
\ No newline at end of file diff --git a/project_dashboard_odoo/views/dashboard_views.xml b/project_dashboard_odoo/views/dashboard_views.xml new file mode 100644 index 000000000..59282f381 --- /dev/null +++ b/project_dashboard_odoo/views/dashboard_views.xml @@ -0,0 +1,16 @@ + + + + + + Dashboard + project_dashboard + + + + + \ No newline at end of file