diff --git a/project_dashboard_odoo/README.rst b/project_dashboard_odoo/README.rst new file mode 100644 index 000000000..7adb5a668 --- /dev/null +++ b/project_dashboard_odoo/README.rst @@ -0,0 +1,46 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg + :target: https://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 need of any configuration. + +Company +------- +* `Cybrosys Techno Solutions `__ + +License +------- +General Public License, Version 3 (AGPL v3). +(https://www.gnu.org/licenses/agpl-3.0-standalone.html) + +Credits +------- +* Developer: (V17) Mruthul Raj, Contact: 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..fb46b2eda --- /dev/null +++ b/project_dashboard_odoo/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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..806b36317 --- /dev/null +++ b/project_dashboard_odoo/__manifest__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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', + 'version': '17.0.1.0.0', + 'category': 'Extra Tools', + 'summary': """Get a Detailed View for Project.""", + 'description': """In this dashboard user can get the Detailed Information + about Project, Task, Employee, Hours recorded, Total Margin and Total + Sale Orders.""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'depends': ['sale_management', 'project', 'sale_timesheet'], + 'data': ['views/dashboard_views.xml'], + 'assets': { + 'web.assets_backend': [ + 'project_dashboard_odoo/static/src/js/dashboard.js', + 'project_dashboard_odoo/static/src/css/dashboard.css', + 'project_dashboard_odoo/static/src/xml/dashboard_templates.xml', + 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js' + ]}, + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + '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..f59136d05 --- /dev/null +++ b/project_dashboard_odoo/controllers/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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..9252b3eb3 --- /dev/null +++ b/project_dashboard_odoo/controllers/project_dashboard_odoo.py @@ -0,0 +1,380 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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 returns the corresponding data.""" + + @http.route('/project/task/count', auth='public', type='json') + def get_project_task_count(self): + """Summary: + 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 contains data for + the project task graph.""" + project_name = [] + total_task = [] + colors = [] + user_employee = request.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + project_ids = request.env['project.project'].search([]) + else: + project_ids = request.env['project.project'].search( + [('user_id', '=', request.env.uid)]) + for project_id in project_ids: + project_name.append(project_id.name) + task = request.env['project.task'].search_count( + [('project_id', '=', project_id.id)]) + total_task.append(task) + color_code = request.env['project.project'].get_color_code() + colors.append(color_code) + return { + 'project': project_name, + 'task': total_task, + 'color': colors + } + + @http.route('/employee/timesheet', auth='public', type='json') + def get_top_timesheet_employees(self): + """Summary: + when the page is loaded, get the data for the timesheet graph. + Return: + type:It is a list. This list contains data that affects 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 ''' + request._cr.execute(query) + top_product = request._cr.dictfetchall() + unit = [record.get('unit') for record in top_product] + employee = [record.get('employee') for record in top_product] + return [unit, employee] + + @http.route('/project/filter', auth='public', type='json') + def project_filter(self): + """Summary: + 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): + """Summary: + transferring data after filter 9th applied + Args: + kw(dict):This parameter contains the value of selection field + Returns: + type:dict, it contains the data for the corresponding + filtrated 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 = round(sum(report_project.mapped('margin')), 2) + 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 + } + + @http.route('/get/tiles/data', auth='public', type='json') + def get_tiles_data(self): + """Summary: + 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 contains data that + affects the dashboard view.""" + user_employee = request.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + all_project = request.env['project.project'].search([]) + all_task = request.env['project.task'].search([]) + analytic_project = request.env['account.analytic.line'].search([]) + report_project = request.env['timesheets.analysis.report'].search( + []) + margin = round(sum(report_project.mapped('margin')), 2) + total_time = sum(analytic_project.mapped('unit_amount')) + employees = request.env['hr.employee'].search([]) + task = request.env['project.task'].sudo().search_read([ + ('sale_order_id', '!=', False) + ], ['sale_order_id']) + task_so_ids = [o['sale_order_id'][0] for o in task] + sale_orders = request.env['sale.order'].browse(task_so_ids) + project_stage_ids = request.env['project.project.stage'].search([]) + project_stage_list = [] + for project_stage_id in project_stage_ids: + total_projects = request.env[ + 'project.project'].sudo().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 = request.env['project.project'].search( + [('user_id', '=', request.env.uid)]) + all_task = [] + for task in request.env['project.task'].search([]): + for assignee in task.user_ids: + if assignee.id == request.env.uid: + all_task.append(task.id) + analytic_project = request.env['account.analytic.line'].search( + [('project_id', 'in', all_project.ids)]) + total_time = sum(analytic_project.mapped('unit_amount')) + task = request.env['project.task'].sudo().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 = request.mapped('sale_line_id.order_id') | request.env[ + 'sale.order'].browse(task_so_ids) + project_stage_ids = request.env['project.project.stage'].search([]) + project_stage_list = [] + for project_stage_id in project_stage_ids: + total_projects = request.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} + + @http.route('/get/hours', auth='public', type='json') + def get_hours_data(self): + """Summary: + when the page is loaded get the data for the hour table. + Return: + type:It is a dictionary variable. This dictionary contains data that + hours table.""" + user_employee = request.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' ''' + request._cr.execute(query) + data = request._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' ''' + request._cr.execute(query) + data = request._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' ''' + request._cr.execute(query) + data = request._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' + ''' + request._cr.execute(query) + data = request._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' ''' + request._cr.execute(query) + data = request._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 = request.env['project.project'].search( + [('user_id', '=', request.env.uid)]).ids + analytic_project = request.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, + } + + @http.route('/get/task/data', auth='public', type='json') + def get_task_data(self): + """ + Summary: + 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 contains data that + affecting project task table.""" + user_employee = request.env.user.partner_id + if user_employee.user_has_groups('project.group_project_manager'): + request._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 = request._cr.fetchall() + project_name = [] + for rec in data: + project_name.append(list(rec)) + return { + 'project': project_name + } + else: + all_project = request.env['project.project'].search( + [('user_id', '=', request.env.uid)]).ids + all_tasks = request.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 + } diff --git a/project_dashboard_odoo/doc/RELEASE_NOTES.md b/project_dashboard_odoo/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..66b125a86 --- /dev/null +++ b/project_dashboard_odoo/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 30.11.2023 +#### Version 17.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..a487ad180 --- /dev/null +++ b/project_dashboard_odoo/models/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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_project diff --git a/project_dashboard_odoo/models/project.py b/project_dashboard_odoo/models/project.py new file mode 100644 index 000000000..5e3d13ab2 --- /dev/null +++ b/project_dashboard_odoo/models/project.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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 models + + +class Project(models.Model): + """This class inherits from 'project.project' and adds custom functionality + to it.It provides methods to work with project data.""" + _inherit = 'project.project' + + def get_color_code(self): + """Generate a random color code in hexadecimal format. + :return: A random color code in the format '#RRGGBB.'""" + color = f"#{random.randint(0, 0xFFFFFF):06x}" + return color diff --git a/project_dashboard_odoo/models/project_project.py b/project_dashboard_odoo/models/project_project.py new file mode 100644 index 000000000..e0d28316f --- /dev/null +++ b/project_dashboard_odoo/models/project_project.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies(). +# Author: Mruthul Raj @cybrosys(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 models + + +class ProjectProject(models.Model): + """This class inherits from 'project.project' and adds custom functionality + to it.It provides methods to work with project data.""" + _inherit = 'project.project' + + def get_color_code(self): + """Generate a random color code in hexadecimal format. + :return: A random color code in the format '#RRGGBB.'""" + color = f"#{random.randint(0, 0xFFFFFF):06x}" + return color diff --git a/project_dashboard_odoo/static/description/assets/icons/capture (1).png b/project_dashboard_odoo/static/description/assets/icons/capture (1).png new file mode 100644 index 000000000..8824deafc Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/capture (1).png differ 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/img.png b/project_dashboard_odoo/static/description/assets/icons/img.png new file mode 100644 index 000000000..70197f477 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/img.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/photo-capture.png b/project_dashboard_odoo/static/description/assets/icons/photo-capture.png new file mode 100644 index 000000000..06c111758 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/icons/photo-capture.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/Cybrosys R.png b/project_dashboard_odoo/static/description/assets/misc/Cybrosys R.png new file mode 100644 index 000000000..da4058087 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/misc/Cybrosys R.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/email.svg b/project_dashboard_odoo/static/description/assets/misc/email.svg new file mode 100644 index 000000000..15291cdc3 --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/email.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/phone.svg b/project_dashboard_odoo/static/description/assets/misc/phone.svg new file mode 100644 index 000000000..b7bd7f251 --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/phone.svg @@ -0,0 +1,3 @@ + + + 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 (1) 2.svg b/project_dashboard_odoo/static/description/assets/misc/star (1) 2.svg new file mode 100644 index 000000000..5ae9f507a --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/star (1) 2.svg @@ -0,0 +1,9 @@ + + + + + + + + + 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 (1) 1.svg b/project_dashboard_odoo/static/description/assets/misc/support (1) 1.svg new file mode 100644 index 000000000..7d37a8f30 --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/support (1) 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/project_dashboard_odoo/static/description/assets/misc/support-email.svg b/project_dashboard_odoo/static/description/assets/misc/support-email.svg new file mode 100644 index 000000000..eb70370d6 --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/support-email.svg @@ -0,0 +1,6 @@ + + + + + + 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/tick-mark.svg b/project_dashboard_odoo/static/description/assets/misc/tick-mark.svg new file mode 100644 index 000000000..2dbb40187 --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/tick-mark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/project_dashboard_odoo/static/description/assets/misc/whatsapp 1.svg b/project_dashboard_odoo/static/description/assets/misc/whatsapp 1.svg new file mode 100644 index 000000000..0bfaf8fc6 --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/whatsapp 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + 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/misc/whatsapp.svg b/project_dashboard_odoo/static/description/assets/misc/whatsapp.svg new file mode 100644 index 000000000..b618aea1d --- /dev/null +++ b/project_dashboard_odoo/static/description/assets/misc/whatsapp.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/project_dashboard_odoo/static/description/assets/modules/1.gif b/project_dashboard_odoo/static/description/assets/modules/1.gif new file mode 100644 index 000000000..ae3a880a2 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/1.gif differ diff --git a/project_dashboard_odoo/static/description/assets/modules/1.png b/project_dashboard_odoo/static/description/assets/modules/1.png new file mode 100644 index 000000000..d0f36b007 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/1.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/2.png b/project_dashboard_odoo/static/description/assets/modules/2.png new file mode 100644 index 000000000..8513873ea Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/2.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/3.png b/project_dashboard_odoo/static/description/assets/modules/3.png new file mode 100644 index 000000000..cb17cf612 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/3.png differ diff --git a/project_dashboard_odoo/static/description/assets/modules/4.jpg b/project_dashboard_odoo/static/description/assets/modules/4.jpg new file mode 100644 index 000000000..67c7f7062 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/4.jpg differ diff --git a/project_dashboard_odoo/static/description/assets/modules/5.jpg b/project_dashboard_odoo/static/description/assets/modules/5.jpg new file mode 100644 index 000000000..5141a7802 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/5.jpg differ diff --git a/project_dashboard_odoo/static/description/assets/modules/6.png b/project_dashboard_odoo/static/description/assets/modules/6.png new file mode 100644 index 000000000..0e311ca87 Binary files /dev/null and b/project_dashboard_odoo/static/description/assets/modules/6.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..f40a0756d 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..5738a486e 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..8d99e8c68 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..3415917c2 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..c7ea331ee 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..5990b59f0 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..dab72769c 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..2f39ab05b 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..8697112df 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..7ac8ca0e6 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..164eb62c7 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..aef22d152 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..306febb68 --- /dev/null +++ b/project_dashboard_odoo/static/description/index.html @@ -0,0 +1,654 @@ + + + + + + Odoo App 3 Index + + + + + + + + +
+
+
+
+
+ +
+
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+
+
+
+

+ Project Dashboard

+

+ In This Dashboard, You Can Get a Detailed View for Project. +

+
+ +
+
+
+
+
+

+ Key Highlights +

+
+
+
+
+
+ +
+
+

+ Dashboard view for Project module

+
+
+
+
+
+
+ +
+
+

+ Graphs included

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

+ Different Types of Graphs.

+

Project + Dashboard has different types of Graphs that + will give you a complete analyzing of the Project + module.

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

+ Project Table

+

User can + see all Project ad its current Status.

+
+
+
+
+
+
+
    +
  • + 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. +
  • + +
+
+
+
+
+
+
Version + 17.0.1.0.0|Released on:30th Nov 2023 +
+

+ Initial Commit for Project Dashboard.

+
+
+
+
+
+
+
+

+ Related Products

+
+
+ +
+
+

+ Our Services

+ +
+
+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Customization

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Implementation

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Support

+
+
+
+
+
+
+ service-icon +
+
+

Hire + Odoo Developer

+
+
+
+
+ +
+
+ service-icon +
+
+

Odoo + Integration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Migration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Consultancy

+
+
+
+
+
+
+ service-icon +
+
+

Odoo + Implementation

+
+
+
+
+
+
+ service-icon +
+
+

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 + 99456767686 +
+
+
+
+
+
+
+
+
+ + + + + + 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..7b7d13cc4 --- /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 +} 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..161cddf5b --- /dev/null +++ b/project_dashboard_odoo/static/src/js/dashboard.js @@ -0,0 +1,447 @@ +/** @odoo-module */ +import { registry} from '@web/core/registry'; +import { useService } from "@web/core/utils/hooks"; +const { Component, onWillStart, onMounted} = owl +import { jsonrpc } from "@web/core/network/rpc_service"; +import { _t } from "@web/core/l10n/translation"; + +export class ProjectDashboard extends Component { + /** + * Setup method to initialize required services and register event handlers. + */ + setup() { + this.action = useService("action"); + this.orm = useService("orm"); + this.rpc = this.env.services.rpc + onWillStart(this.onWillStart); + onMounted(this.onMounted); + } + /** + * Event handler for the 'onWillStart' event. + */ + async onWillStart() { + await this.fetch_data(); + } + /** + * Event handler for the 'onMounted' event. + * Renders various components and charts after fetching data. + */ + async onMounted() { + // Render other components after fetching data + this.render_project_task(); + this.render_top_employees_graph(); + this.render_filter(); + } + /** + * Render the project task chart. + */ + async render_project_task() { + await jsonrpc("/project/task/count").then(function(data) { + var ctx = $("#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, + } + }); + }) + } + /** + function for getting values to employee graph + */ + async render_top_employees_graph() { + var ctx = $(".top_selling_employees"); + await jsonrpc('/employee/timesheet').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 employees for filter. + */ + render_filter() { + jsonrpc('/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(""); + }); + }) + } + /** + * Event handler to apply filters based on user selections and update the dashboard data accordingly. + */ + _onchangeFilter(ev) { + this.flag = 1 + var start_date = $('#start_date').val(); + var end_date = $('#end_date').val(); + var employee_selection = $('#employee_selection').val(); + var project_selection = $('#project_selection').val(); + var self = this; + if (!start_date) { + start_date = "null" + } + if (!end_date) { + end_date = "null" + } + if (!employee_selection) { + employee_selection = "null" + } + if (!project_selection) { + project_selection = "null" + } + jsonrpc('/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'] + $('#tot_project')[0].innerHTML = data['total_project'].length + $('#tot_employee')[0].innerHTML = data['total_emp'].length + $("#tot_task")[0].innerHTML = data['total_task'].length + $("#tot_hrs")[0].innerHTML = data['hours_recorded'] + $("#tot_margin")[0].innerHTML = data['total_margin'] + $("#tot_so")[0].innerHTML = data['total_so'].length + }) + } + /** + * Event handler to open a list of employees and display them to the user. + */ + tot_emp(e) { + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + if (this.flag == 0) { + this.action.doAction({ + 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.action.doAction({ + 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 when page is loaded + */ + fetch_data() { + this.flag = 0 + var self = this; + var def1 = jsonrpc('/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 = jsonrpc('/get/hours') + .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 = jsonrpc('/get/task/data') + .then(function(res) { + self.task_data = res['project']; + }); + return $.when(def1, def3, def4); + } + /** + * Event handler to open a list of projects and display them to the user. + */ + tot_projects(e) { + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + if (this.flag == 0) { + this.action.doAction({ + 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.action.doAction({ + 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) + } + } + } + /** + * Event handler to open a list of tasks and display them to the user. + */ + tot_tasks(e) { + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.action.doAction({ + name: _t("Tasks"), + type: 'ir.actions.act_window', + res_model: 'project.task', + domain: [ + ["id", "in", this.tot_task] + ], + view_mode: 'tree,kanban,form', + views: [ + [false, 'list'], + [false, 'form'] + ], + target: 'current' + }, options) + } + /** + for opening account analytic line view + */ + hr_recorded(e) { + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + if (this.flag == 0) { + this.action.doAction({ + 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.action.doAction({ + 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(e) { + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.action.doAction({ + 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) + } + /** + * Event handler to view a list of employees. + * @param {Event} e - The click event. + */ + tot_emp(e) { + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + if (this.flag == 0) { + this.action.doAction({ + 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.action.doAction({ + 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) + + } + } +} +ProjectDashboard.template = "ProjectDashboard" +registry.category("actions").add("project_dashboard", ProjectDashboard) diff --git a/project_dashboard_odoo/static/src/xml/dashboard_templates.xml b/project_dashboard_odoo/static/src/xml/dashboard_templates.xml new file mode 100644 index 000000000..760876422 --- /dev/null +++ b/project_dashboard_odoo/static/src/xml/dashboard_templates.xml @@ -0,0 +1,369 @@ + + + + +
+
+ + +
+
+
+ + +
+ +
+

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 +
+ + + + + + + + + +
+ +
+

+

+

+

+
+
+
+
+
+
+
diff --git a/project_dashboard_odoo/views/dashboard_views.xml b/project_dashboard_odoo/views/dashboard_views.xml new file mode 100644 index 000000000..3084aae3e --- /dev/null +++ b/project_dashboard_odoo/views/dashboard_views.xml @@ -0,0 +1,14 @@ + + + + + Dashboard + project_dashboard + + + +