Browse Source

Jun 20 : [ADD] Initial Commit 'project_dashboard_odoo'

pull/257/head
AjmalCybro 2 years ago
parent
commit
6eccebf0f8
  1. 45
      project_dashboard_odoo/README.rst
  2. 22
      project_dashboard_odoo/__init__.py
  3. 57
      project_dashboard_odoo/__manifest__.py
  4. 21
      project_dashboard_odoo/controllers/__init__.py
  5. 150
      project_dashboard_odoo/controllers/project_dashboard_odoo.py
  6. 6
      project_dashboard_odoo/doc/RELEASE_NOTES.md
  7. 21
      project_dashboard_odoo/models/__init__.py
  8. 339
      project_dashboard_odoo/models/project.py
  9. BIN
      project_dashboard_odoo/static/description/assets/icons/check.png
  10. BIN
      project_dashboard_odoo/static/description/assets/icons/chevron.png
  11. BIN
      project_dashboard_odoo/static/description/assets/icons/cogs.png
  12. BIN
      project_dashboard_odoo/static/description/assets/icons/consultation.png
  13. BIN
      project_dashboard_odoo/static/description/assets/icons/ecom-black.png
  14. BIN
      project_dashboard_odoo/static/description/assets/icons/education-black.png
  15. BIN
      project_dashboard_odoo/static/description/assets/icons/hotel-black.png
  16. BIN
      project_dashboard_odoo/static/description/assets/icons/license.png
  17. BIN
      project_dashboard_odoo/static/description/assets/icons/lifebuoy.png
  18. BIN
      project_dashboard_odoo/static/description/assets/icons/manufacturing-black.png
  19. BIN
      project_dashboard_odoo/static/description/assets/icons/pos-black.png
  20. BIN
      project_dashboard_odoo/static/description/assets/icons/puzzle.png
  21. BIN
      project_dashboard_odoo/static/description/assets/icons/restaurant-black.png
  22. BIN
      project_dashboard_odoo/static/description/assets/icons/service-black.png
  23. BIN
      project_dashboard_odoo/static/description/assets/icons/trading-black.png
  24. BIN
      project_dashboard_odoo/static/description/assets/icons/training.png
  25. BIN
      project_dashboard_odoo/static/description/assets/icons/update.png
  26. BIN
      project_dashboard_odoo/static/description/assets/icons/user.png
  27. BIN
      project_dashboard_odoo/static/description/assets/icons/wrench.png
  28. BIN
      project_dashboard_odoo/static/description/assets/misc/categories.png
  29. BIN
      project_dashboard_odoo/static/description/assets/misc/check-box.png
  30. BIN
      project_dashboard_odoo/static/description/assets/misc/compass.png
  31. BIN
      project_dashboard_odoo/static/description/assets/misc/corporate.png
  32. BIN
      project_dashboard_odoo/static/description/assets/misc/customer-support.png
  33. BIN
      project_dashboard_odoo/static/description/assets/misc/cybrosys-logo.png
  34. BIN
      project_dashboard_odoo/static/description/assets/misc/features.png
  35. BIN
      project_dashboard_odoo/static/description/assets/misc/logo.png
  36. BIN
      project_dashboard_odoo/static/description/assets/misc/pictures.png
  37. BIN
      project_dashboard_odoo/static/description/assets/misc/pie-chart.png
  38. BIN
      project_dashboard_odoo/static/description/assets/misc/right-arrow.png
  39. BIN
      project_dashboard_odoo/static/description/assets/misc/star.png
  40. BIN
      project_dashboard_odoo/static/description/assets/misc/support.png
  41. BIN
      project_dashboard_odoo/static/description/assets/misc/whatsapp.png
  42. BIN
      project_dashboard_odoo/static/description/assets/modules/l1.png
  43. BIN
      project_dashboard_odoo/static/description/assets/modules/l2.png
  44. BIN
      project_dashboard_odoo/static/description/assets/modules/l3.png
  45. BIN
      project_dashboard_odoo/static/description/assets/modules/l4.png
  46. BIN
      project_dashboard_odoo/static/description/assets/modules/l5.png
  47. BIN
      project_dashboard_odoo/static/description/assets/modules/l6.png
  48. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot.png
  49. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot2.png
  50. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot3.png
  51. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot4.png
  52. BIN
      project_dashboard_odoo/static/description/assets/screenshots/hero.gif
  53. BIN
      project_dashboard_odoo/static/description/banner.png
  54. BIN
      project_dashboard_odoo/static/description/icon.png
  55. 520
      project_dashboard_odoo/static/description/index.html
  56. 426
      project_dashboard_odoo/static/src/css/dashboard.css
  57. 483
      project_dashboard_odoo/static/src/js/dashboard.js
  58. 322
      project_dashboard_odoo/static/src/xml/dashboard.xml
  59. 16
      project_dashboard_odoo/views/dashboard_views.xml

45
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 <https://cybrosys.com/>`__
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 <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

22
project_dashboard_odoo/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# 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 <http://www.gnu.org/licenses/>.
################################################################################
from . import controllers
from . import models

57
project_dashboard_odoo/__manifest__.py

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# 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 <http://www.gnu.org/licenses/>.
################################################################################
{
'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,
}

21
project_dashboard_odoo/controllers/__init__.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# 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 <http://www.gnu.org/licenses/>.
################################################################################
from . import project_dashboard_odoo

150
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(<https://www.cybrosys.com>).
# 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 <http://www.gnu.org/licenses/>.
################################################################################
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
}

6
project_dashboard_odoo/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <project_dashboard_odoo>
#### 29.03.2023
#### Version 16.0.1.0.0
##### ADD
##### Initial Commit for Project Dashboard

21
project_dashboard_odoo/models/__init__.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# 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 <http://www.gnu.org/licenses/>.
################################################################################
from . import project

339
project_dashboard_odoo/models/project.py

@ -0,0 +1,339 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# 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 <http://www.gnu.org/licenses/>.
################################################################################
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

BIN
project_dashboard_odoo/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
project_dashboard_odoo/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
project_dashboard_odoo/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
project_dashboard_odoo/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
project_dashboard_odoo/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
project_dashboard_odoo/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
project_dashboard_odoo/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
project_dashboard_odoo/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
project_dashboard_odoo/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
project_dashboard_odoo/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
project_dashboard_odoo/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
project_dashboard_odoo/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
project_dashboard_odoo/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
project_dashboard_odoo/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
project_dashboard_odoo/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
project_dashboard_odoo/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
project_dashboard_odoo/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
project_dashboard_odoo/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
project_dashboard_odoo/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
project_dashboard_odoo/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
project_dashboard_odoo/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
project_dashboard_odoo/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
project_dashboard_odoo/static/description/assets/modules/l1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
project_dashboard_odoo/static/description/assets/modules/l2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
project_dashboard_odoo/static/description/assets/modules/l3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
project_dashboard_odoo/static/description/assets/modules/l4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
project_dashboard_odoo/static/description/assets/modules/l5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
project_dashboard_odoo/static/description/assets/modules/l6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
project_dashboard_odoo/static/description/assets/screenshots/Screenshot.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

BIN
project_dashboard_odoo/static/description/assets/screenshots/Screenshot2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

BIN
project_dashboard_odoo/static/description/assets/screenshots/Screenshot3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

BIN
project_dashboard_odoo/static/description/assets/screenshots/Screenshot4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
project_dashboard_odoo/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
project_dashboard_odoo/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
project_dashboard_odoo/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

520
project_dashboard_odoo/static/description/index.html

@ -0,0 +1,520 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between" style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42" style="width: 42px; height: 42px;" />
<div>
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;" class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;" class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
<div style="color: #017E84; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;" class="mr-2">
<i class="fa fa-check mr-1"></i>Odoo.sh
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<!-- APP HERO -->
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
Project Dashboard
</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">In This Dashboard You Can Get Detailed View for Project.</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/hero.gif" class="img-responsive" style="width: 100%; margin-left: auto; margin-right: auto;" />
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center" style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36" />
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center" style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36" />
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center" style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36" />
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Overview
</h2>
</div>
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
In this dashboard you can get all the details about project module.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Features
</h2>
</div>
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2" />
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">User can see all details about project and task through graphs.</span>
</div>
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2" />
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">User can see all details about timesheet through graphs.</span>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center" style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2" />
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">User can see all projects with stages.</span>
</div>
<img src="assets/misc/check-box.png" class="mr-2" />
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">User can use filter based on the employee, project and dates.</span>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Dynamic And Clickable Dashboard Tiles
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
User can click the Tiles and States in tile,That shows the detailed view of corresponding tiles.
</p>
<img src="assets/screenshots/Screenshot.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Different Types of Graphs
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Project dashboard have different types of graphs that will give you complete analyse of the project module.
</p>
<img src="assets/screenshots/Screenshot2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<img src="assets/screenshots/Screenshot3.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Project Table
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">User can see all Project ad its current status.
</p>
<img src="assets/screenshots/Screenshot4.png" class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED PRODUCTS -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/website_repeat_sale/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/l1.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/woo_commerce/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/l2.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/shopify_odoo_connector/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/l3.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/odoo_dynamic_dashboard/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/l4.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/custom_gantt_view/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/l5.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/pos_credit_limit/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/l6.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev" style="width:35px; color:#000"> <span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo1" data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3" style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/education-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/service-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center" style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</div>
<!-- END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2" style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4" style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48" style="width: 42px; height: 42px;" />
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help?
Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4" style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52" style="width: 52px; height: 52px;" />
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31" style="width:144px; height: 31px; margin-top: 40px;" />
</div>
</div>
</div>
<!-- END OF SUPPORT -->

426
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
}

483
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("<option value=" + projects[project].id + ">" + projects[project].name + "</option>");
});
$(employees).each(function(employee) {
$('#employee_selection').append("<option value=" + employees[employee].id + ">" + employees[employee].name + "</option>");
});
})
},
/**
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;
});

322
project_dashboard_odoo/static/src/xml/dashboard.xml

@ -0,0 +1,322 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Template for the project dashboard -->
<templates id="template" xml:space="preserve">
<t t-name="ProjectDashboard">
<div class="oh_dashboards" style="margin-top: 20px; overflow-y: scroll;vertical-align: middle;overflow-x: clip;max-height: -webkit-fill-available;">
<div class="container-fluid o_pj_dashboard" style="margin-left:4%;">
</div>
</div>
</t>
<t t-name="DashboardProject">
<div class="row main-section">
<t t-if="widget.flag_user == 1">
<div class="inner_select" style="display: flex;">
<p style="margin-left: 20px;">Start Date :</p>
<p>
<input type="date" class="inner_select" id="start_date" name="start_date" />
</p>
<p>End Date :</p>
<p>
<input type="date" class="inner_select" id="end_date" name="end_date" />
</p>
<p>Project :</p>
<p>
<select class="inner_select" id="project_selection">
<option value="null">All Projects</option>
</select>
</p>
<p>Employees :</p>
<p>
<select class="inner_select" id="employee_selection">
<option value="null">All Employees</option>
</select>
</p>
</div>
</t>
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body tot_projects" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one" style="display:flex;">
<div class="stat-icon"><i class="fa fa-puzzle-piece" /></div>
<div class="stat-head" style="padding: 5%;width: 60%;">Total Project</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_project">
<t t-esc="widget.total_projects" />
</div>
</div>
</div>
</div>
</div>
<t t-if="widget.flag_user == 1">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body tot_emp" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one" style="display:flex;">
<div class="stat-icon"><i class="fa fa-user" /></div>
<div class="stat-head" style="padding: 5%;width: 60%;">Total Employees</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_employee">
<t t-esc="widget.total_employees" />
</div>
</div>
</div>
</div>
</div>
</t>
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body tot_tasks" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one" style="display:flex;">
<div class="stat-icon"><i class="fa fa-tasks" /></div>
<div class="stat-head" style="padding: 5%;width: 60%;">Total tasks</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_task">
<t t-esc="widget.total_tasks" />
</div>
</div>
</div>
</div>
</div>
<t t-if="widget.flag_user == 1">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body hr_recorded" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one" style="display:flex;">
<div class="stat-icon"><i class="fa fa-clock-o" /></div>
<div class="stat-head" style="padding: 5%;width: 60%;">Hours Recorded</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_hrs">
<t t-esc="widget.total_hours" />
</div>
</div>
</div>
</div>
</div>
</t>
<t t-if="widget.flag_user == 1">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body tot_profitability" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one" style="display:flex;">
<div class="stat-icon"><i class="fa fa-dollar" /></div>
<div class="stat-head" style="padding: 5%;width: 60%;">Total Margin</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_margin">
<t t-esc="widget.total_profitability" />
</div>
</div>
</div>
</div>
</div>
</t>
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body tot_sale" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one" style="display:flex;">
<div class="stat-icon"><i class="fa fa-ticket" /></div>
<div class="stat-head" style="padding: 5%;width: 60%;">Total Sale Orders</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_so">
<t t-esc="widget.total_sale_orders" />
</div>
</div>
</div>
</div>
</div>
</div>
</t>
<t t-name="DashboardChart">
<div class="col-xs-12 col-sm-12 col-lg-12 col-md-12">
<div class="row main-section">
<div class="col-sm-7 col-lg-7">
<div class="graph_view" style="box-shadow:5px 11px 30px;">
<div class="text-color hr-chart-1">
<div class="oh-card-body pb-0" style="text-align:center;">
<h2 style="margin-left:45%;padding-top:2%;">Project Task Analysis</h2>
</div>
<canvas id="project_doughnut" style="background:#fff;" width="200" height="120" />
</div>
</div>
<div class="selling_product_graph_view" style="box-shadow:5px 11px 30px;">
<div class="oh-card text-color">
<canvas class="top_selling_employees" style="background:#fff;" width="200" height="120" />
</div>
</div>
</div>
<div class="col-md-4 col-lg-4" style="top: 82px;right: -100px;">
<div class="hr_notification" style="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: 763px;margin-bottom: 15px;margin-top: 15px;box-shadow:5px 11px 30px;">
<div class="hr_notification_head" style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #000080;margin-bottom: 9px;">
Project Task Details
</div>
<div class="col-sm-12 col-lg-12" style="padding:0;">
<div class="text-color">
<div class="media" style="overflow-y: auto;height: 704px;">
<div class="media-body">
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Project Name</th>
<th rowspan="14">Task Name</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.task_data" t-as="proj">
<tr>
<td>
<t t-if="widget.flag_user == 1">
<t t-esc="proj[1]['en_US']" />
</t>
<t t-els="">
<t t-esc="proj[1]" />
</t>
</td>
<td>
<t t-esc="proj[0]" />
</td>
</tr>
</t>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="hr_notification" style="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: 356px;margin-bottom: 15px;box-shadow:5px 11px 30px;">
<div class="hr_notification_head" style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #000080;margin-bottom: 9px;">
Hours Recorded
</div>
<div class="col-sm-12 col-lg-12" style="padding:0;">
<div class="text-color">
<div class="">
<div class="media">
<div class="media-body">
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Billed on Timesheet</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.hour_recorde" t-as="hour_recorde">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="hour_recorde" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Billed at a Fixed price</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.billable_fix" t-as="billable_fix">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="billable_fix" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">No task found</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.hour_recorded" t-as="hour_recorded">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="hour_recorded" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Non Billable Tasks</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.non_billable" t-as="non_billable">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="non_billable" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14" style="padding-left: 24.3rem;">Total:</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.total_hr" t-as="total_hr">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="total_hr" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="hr_notification" style="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: auto;padding-bottom: 15px;box-shadow:5px 11px 30px;">
<div class="hr_notification_head" style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #000080;margin-bottom: 9px;">
Stage Wise Total Projects
</div>
<table id="table_status" style="width">
<tr>
<th />
<th />
</tr>
<t t-foreach="widget.project_stage_list" t-as="data">
<tr>
<td style="text-align:center;">
<h4 t-esc="data['name']" />
</td>
<td style="text-align:center;">
<h4 class="fleet-pill" t-esc="data['projects']" />
</td>
</tr>
</t>
</table>
</div>
</div>
</div>
</div>
</div>
</t>
</templates>

16
project_dashboard_odoo/views/dashboard_views.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- action for project dashboard-->
<record id="project_action_dashboard" model="ir.actions.client">
<field name="name">Dashboard</field>
<field name="tag">project_dashboard</field>
</record>
<!-- Dashboard menu item -->
<menuitem id="menu_project_dashboard"
name="Dashboard"
action="project_action_dashboard"
parent="project.menu_main_pm"
sequence="1"/>
</data>
</odoo>
Loading…
Cancel
Save