Browse Source

Apr 5 : [UPDT] Updated 'project_dashboard_odoo'

pull/254/head
AjmalCybro 2 years ago
parent
commit
1e4db8dbfb
  1. 3
      project_dashboard_odoo/README.rst
  2. 1
      project_dashboard_odoo/__init__.py
  3. 4
      project_dashboard_odoo/__manifest__.py
  4. 22
      project_dashboard_odoo/controllers/__init__.py
  5. 157
      project_dashboard_odoo/controllers/main.py
  6. 8
      project_dashboard_odoo/doc/RELEASE_NOTES.md
  7. 241
      project_dashboard_odoo/models/pj_dashboard.py
  8. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot1.png
  9. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot2.png
  10. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot3.png
  11. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot4.png
  12. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot5.png
  13. BIN
      project_dashboard_odoo/static/description/assets/screenshots/Screenshot6.png
  14. BIN
      project_dashboard_odoo/static/description/assets/screenshots/checked.png
  15. BIN
      project_dashboard_odoo/static/description/assets/screenshots/hero.gif
  16. BIN
      project_dashboard_odoo/static/description/assets/screenshots/hero.png
  17. BIN
      project_dashboard_odoo/static/description/assets/screenshots/logo.png
  18. BIN
      project_dashboard_odoo/static/description/assets/screenshots/pd1.png
  19. BIN
      project_dashboard_odoo/static/description/assets/screenshots/pd2.png
  20. BIN
      project_dashboard_odoo/static/description/assets/screenshots/pd3.png
  21. BIN
      project_dashboard_odoo/static/description/assets/screenshots/pd4.png
  22. BIN
      project_dashboard_odoo/static/description/assets/screenshots/pd5.png
  23. BIN
      project_dashboard_odoo/static/description/assets/screenshots/prg_db.png
  24. BIN
      project_dashboard_odoo/static/description/assets/screenshots/prg_db2.png
  25. BIN
      project_dashboard_odoo/static/description/assets/screenshots/prg_db3.png
  26. BIN
      project_dashboard_odoo/static/description/assets/screenshots/prg_db4.png
  27. BIN
      project_dashboard_odoo/static/description/assets/screenshots/screenshot.png
  28. 45
      project_dashboard_odoo/static/description/index.html
  29. 831
      project_dashboard_odoo/static/src/css/dashboard.css
  30. 1105
      project_dashboard_odoo/static/src/js/dashboard.js
  31. 539
      project_dashboard_odoo/static/src/xml/dashboard.xml

3
project_dashboard_odoo/README.rst

@ -24,7 +24,8 @@ Company
Credits
-------
* Developers: odoo@cybrosys.com
V15 - Archana V, archana@cybrosys.info
V15 - Archana V, archana @ cybrosys
V16 - YadhuKrishnan K Yadhu @ cybrosys
Contacts
--------

1
project_dashboard_odoo/__init__.py

@ -21,3 +21,4 @@
#############################################################################
from .import models
from . import controllers

4
project_dashboard_odoo/__manifest__.py

@ -3,7 +3,7 @@
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
@ -25,7 +25,7 @@
'category': 'Productivity',
'summary': 'Detailed Dashboard View for Project',
'description': 'Detailed Dashboard View for Project',
'version': '15.0.1.0.0',
'version': '15.0.2.0.1',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',

22
project_dashboard_odoo/controllers/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import main

157
project_dashboard_odoo/controllers/main.py

@ -0,0 +1,157 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL 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']
pro_selected = []
emp_selected = []
# checking tje 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']
pro_selected = False
# 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['project.profitability.report'].search(
[('project_id', 'in', pro_selected)])
to_invoice = sum(report_project.mapped('amount_untaxed_to_invoice'))
invoice = sum(report_project.mapped('amount_untaxed_invoiced'))
timesheet_cost = sum(report_project.mapped('timesheet_cost'))
other_cost = sum(report_project.mapped('expense_cost'))
profitability = to_invoice + invoice + timesheet_cost + other_cost
analytic_project = request.env['account.analytic.line'].search(
[('project_id', 'in', pro_selected),
('employee_id', 'in', emp_selected)])
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': profitability,
'total_so': sale_orders
}

8
project_dashboard_odoo/doc/RELEASE_NOTES.md

@ -4,5 +4,11 @@
#### 26.05.2022
#### Version 15.0.1.0.0
## Module <project_dashboard_odoo>
##### Initial Commit for project_dashboard_odoo
#### 30.03.2023
#### Version 15.0.2.0.1
## Module <project_dashboard_odoo>
#### UPDT
#### Update the module with additional graph and filter, changed the UI.

241
project_dashboard_odoo/models/pj_dashboard.py

@ -20,18 +20,56 @@
#
#############################################################################
from odoo import models, api
import calendar
import random
from datetime import datetime
from dateutil.relativedelta import relativedelta
import pandas as pd
import calendar
from odoo import models, api
class PosDashboard(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
get_income_this_month(self):
getting data to profitable graph after month filter apply
get_income_last_year(self):
getting data to profitable graph after last year filter apply
get_income_this_year(self):
getting data to profitable graph after current year filter apply
get_details(self):
getting data for the profatable table
"""
_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.
"""
all_project = self.env['project.project'].search([])
all_task = self.env['project.task'].search([])
analytic_project = self.env['account.analytic.line'].search([])
@ -48,18 +86,39 @@ class PosDashboard(models.Model):
('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)
sale_orders = self.mapped('sale_line_id.order_id') | self.env[
'sale.order'].browse(task_so_ids)
sale_list = [rec.id for rec in sale_orders]
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_tasks': len(all_task),
'total_hours': total_time,
'total_profitability': profitability,
'total_employees': len(employees),
'total_sale_orders': len(sale_orders)
'total_sale_orders': len(sale_orders),
'project_stage_list': project_stage_list,
'sale_list': sale_list
}
@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
@ -80,80 +139,19 @@ class PosDashboard(models.Model):
return final
@api.model
def get_project_task(self):
cr = self._cr
cr.execute("""select project_id, project_project.name,count(*)
from project_task join project_project on project_project.id=project_task.project_id
group by project_task.project_id,project_project.name""")
dat = cr.fetchall()
data = []
for i in range(0, len(dat)):
data.append({'label': dat[i][1], 'value': dat[i][2]})
return data
@api.model
def project_profitability_trend(self):
leave_lines = []
month_list = []
graph_result = []
for i in range(6, -2, -1):
last_month = datetime.now() - relativedelta(months=i)
text = format(last_month, '%B %Y')
month_list.append(text)
for month in month_list:
vals = {
'l_month': month,
'leave': 0
}
graph_result.append(vals)
sql = """SELECT h.id,h.margin,
to_char(y, 'YYYY') as month_year
FROM (select * from project_profitability_report) h
,date_trunc('year', line_date)y"""
self.env.cr.execute(sql)
results = self.env.cr.dictfetchall()
for line in results:
days = line['margin']
vals = {
'l_month': line['month_year'],
'days': days
}
leave_lines.append(vals)
if leave_lines:
df = pd.DataFrame(leave_lines)
rf = df.groupby(['l_month']).sum()
result_lines = rf.to_dict('index')
for line in result_lines:
match = list(graph_result)
if match:
match[0]['leave'] = result_lines[line]['days']
for result in graph_result:
result['l_month'] = result['l_month'].split(' ')[:1][0].strip()[:3] + " " + \
result['l_month'].split(' ')[1:2][0]
return graph_result
@api.model
def get_profitability_details(self):
query = '''select sum(margin) as payment_details from project_profitability_report'''
self._cr.execute(query)
data = self._cr.dictfetchall()
payment_details = []
for record in data:
payment_details.append(record.get('payment_details'))
def get_details(self):
"""
return {
'payment_details': payment_details,
}
Summery:
when the page is loaded get the data for the profitable table.
return:
type:It is a dictionary variable. This dictionary contain data
that profitable table.
@api.model
def get_details(self):
"""
query = '''select sum(amount_untaxed_invoiced) as invoiced,
sum(amount_untaxed_to_invoice) as to_invoice,sum(timesheet_cost) as time_cost,
sum(amount_untaxed_to_invoice) as to_invoice,sum(timesheet_cost) as
time_cost,
sum(expense_cost) as expen_cost,
sum(margin) as payment_details from project_profitability_report'''
self._cr.execute(query)
@ -165,7 +163,7 @@ class PosDashboard(models.Model):
to_invoice = []
for record in data:
to_invoice.append(record.get('to_invoice'))
record.get('to_invoice')
time_cost = []
for record in data:
time_cost.append(record.get('time_cost'))
@ -177,7 +175,6 @@ class PosDashboard(models.Model):
payment_details = []
for record in data:
payment_details.append(record.get('payment_details'))
return {
'invoiced': invoiced,
'to_invoice': to_invoice,
@ -188,6 +185,14 @@ class PosDashboard(models.Model):
@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.
"""
query = '''SELECT sum(unit_amount) as hour_recorded FROM account_analytic_line
WHERE timesheet_invoice_type='non_billable_project' '''
self._cr.execute(query)
@ -239,6 +244,14 @@ class PosDashboard(models.Model):
@api.model
def get_income_this_year(self):
"""
Summery:
when the filter is applied get the data for the profitable graph.
return:
type:It is a dictionary variable. This dictionary contain data for profitable graph.
"""
month_list = []
for i in range(11, -1, -1):
@ -256,7 +269,8 @@ class PosDashboard(models.Model):
records = []
for month in month_list:
last_month_inc = list(filter(lambda m: m['month'].strip() == month, record))
last_month_inc = list(
filter(lambda m: m['month'].strip() == month, record))
if not last_month_inc:
records.append({
@ -283,6 +297,14 @@ class PosDashboard(models.Model):
@api.model
def get_income_last_year(self):
"""
Summery:
when the filter is applied get the data for the profitable graph.
return:
type:It is a dictionary variable. This dictionary contain data for profitable graph.
"""
month_list = []
for i in range(11, -1, -1):
l_month = datetime.now() - relativedelta(months=i)
@ -290,7 +312,6 @@ class PosDashboard(models.Model):
month_list.append(text)
states_arg = ""
self._cr.execute(('''select sum(margin) as income ,to_char(project_profitability_report.line_date, 'Month')
as month from project_profitability_report where
Extract(year FROM project_profitability_report.line_date) = Extract(year FROM DATE(NOW())) -1
@ -299,7 +320,8 @@ class PosDashboard(models.Model):
records = []
for month in month_list:
last_month_inc = list(filter(lambda m: m['month'].strip() == month, record))
last_month_inc = list(
filter(lambda m: m['month'].strip() == month, record))
if not last_month_inc:
records.append({
'month': month,
@ -327,6 +349,14 @@ class PosDashboard(models.Model):
@api.model
def get_income_this_month(self):
"""
Summery:
when the filter is applied get the data for the profitable graph.
return:
type:It is a dictionary variable. This dictionary contain data for profitable graph.
"""
states_arg = ""
day_list = []
now = datetime.now()
@ -370,6 +400,15 @@ class PosDashboard(models.Model):
@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.
"""
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()
@ -380,3 +419,43 @@ class PosDashboard(models.Model):
return {
'project': project_name
}
@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 = []
project_ids = self.env['project.project'].search([])
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/screenshots/Screenshot1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 5.8 MiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

45
project_dashboard_odoo/static/description/index.html

@ -186,31 +186,39 @@
<div class="col-lg-12 my-2">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Project Details</h4>
Use DIffrent Type of filters<h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"></p>
<img src="assets/screenshots/screenshot.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-2">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Dynamic And Clickable Dashboard Tiles</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Display the Project related information likes Total Project, Total Employees, Total Tasks,
Hours Recorded, Total Profitability, Total Sale Orders.</p>
<img src="assets/screenshots/pd1.png" class="img-responsive img-thumbnail border" width="100%"
User can click the Tiles and States in tile,That shows the detailed view of corresponding tiles.</p>
<img src="assets/screenshots/Screenshot1.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Task Analysis</h4>
Different Types of Graphs</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Task analysis from various projects. </p>
<img src="assets/screenshots/pd2.png" class="img-responsive img-thumbnail border" width="100%"
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-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Employees Timesheet</h4>
<img src="assets/screenshots/pd3.png" class="img-responsive img-thumbnail border" width="100%"
Employees Timesheet Graphh</h4>
<img src="assets/screenshots/Screenshot3.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
@ -218,11 +226,24 @@
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Project Profitability</h4>
<img src="assets/screenshots/pd4.png" class="img-responsive img-thumbnail border" width="100%"
Project Profitability Graph</h4>
<img src="assets/screenshots/Screenshot4.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Diffrent Type Of Tables</h4>
<img src="assets/screenshots/Screenshot5.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
</h4>
<img src="assets/screenshots/Screenshot6.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/>
</div>
</div>
<!-- SUGGESTED PRODUCTS -->

831
project_dashboard_odoo/static/src/css/dashboard.css

@ -13,28 +13,6 @@ overflow: auto !important;
.breadcrumbs {
margin-top: 0;
}
.buttons button {
margin: 2px 0; }
/* Button Reset */
.btn, .button {
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
transition: all .15s ease-in-out;
border-radius: 0;
cursor: pointer; }
/* Widget One
---------------------------*/
.stat-content {
display: inline-block;
width: 66%;
}
.stat-icon{
display: inline-block;
}
@ -67,120 +45,6 @@ overflow: auto !important;
.stat_count {
font-size: 28px !important;
}
.stat-count {
font-size: 28px;
text-align: center;
color: #00438b;}
.stat-title {
font-size: 17px;
text-align: center;
color: #00438b; }
.mb-0{
font-size: 20px;
position: relative;
text-align: center;
}
.mb-0 .dash-title {
font-size: 20px;
text-align: center;
color: rgba(255, 255, 255, 0.81);
}
.hr_birthday {
font-size: 28px;
text-align: center;
padding: 20px 0;
color: #00438b;
font-weight: 600;
}
body .text-color {
color: #00438b;
}
.slice {
stroke: #fff;
stroke-width: 0px;
}
/* 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;
}
.monthly_leave_graph_view .legend{
height: 250px;
overflow: scroll;
margin-left: 112px;
margin-top: 77px;
margin-bottom: -97px
}
.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;
}
.leave_broad_factor{
overflow-x: auto !important;
overflow-y: hidden !important;
height: auto;
}
/*=====================New Dashboard===========================*/
.oh_dashboards {
background-color: #f8faff !important;
@ -190,25 +54,6 @@ rect:hover { fill:#934da5; }
.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;
}
/*.dummy{
height:130vh;
}*/
.oh-card {
padding-top: 0px;
@ -227,116 +72,6 @@ rect:hover { fill:#934da5; }
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
}
.employee-prof .employee-icon {
float: left;
padding-right: 0px;
width: 100%;
height: 185px;
overflow: hidden;
background: #999999;
}
.employee-prof .employee-icon img{
width: 100%;
background: #fff;
}
.employee-prof .employee-name h2 {
text-align: center;
font-weight: 300;
text-transform: uppercase;
font-size: 17px;
margin-top: 12px;
margin-bottom: 2px;
color: #fff;
}
.media-body.employee-name {
background: #466b8d;
float: left;
margin: 0;
width: 100%
}
.employee-prof .employee-name p {
margin: 0 0 9px;
text-align: center;
font-size: 12px;
color: #f3f3f3;
}
.employee-prof p {
margin: 0 0 9px;
color: #fff;
}
.employee-gender {
width: 40%;
margin-left: 10%;
padding: 8% 10% 4%;
text-align: center;
border-right: 1px solid #4d769b;
margin-top: 14%;
float: left;
border-bottom: 1px solid #4d769b;
}
.employee-gender p {
margin: 0px 0 4px !important;
color: #fff;
}
.employee-age {
width: 40%;
margin-right: 10%;
padding: 4% 10% 7%;
text-align: center;
margin-top: 18%;
float: left;
border-bottom: 1px solid #4d769b;
}
.employee-age p {
margin: 0 0 1px;
color: #fff;
}
.employee-experience {
width: 100%;
text-align: center;
padding-top: 8%;
float: left;
padding-bottom: 3%;
}
.employee-country {
width: 40%;
margin-left: 10%;
padding: 9% 0% 4%;
text-align: center;
border-right: 1px solid #4d769b;
margin-top: 2%;
float: left;
border-top: 1px solid #4d769b;
}
.employee-country p {
margin: 0px 0 1px !important;
color: #fff;
}
.employee-mobile {
width: 40%;
margin-right: 10%;
padding: 9% 0% 7%;
text-align: center;
margin-top: 2%;
float: left;
border-top: 1px solid #4d769b;
}
.employee-mobile p {
margin: 0 0 1px;
color: #fff;
}
.oh-payslip {
margin-top: 1.5%;
@ -348,7 +83,6 @@ rect:hover { fill:#934da5; }
height: 85px;
text-align: center;
padding-top: 2%;
background: #ff8762;
color: #fff;
}
@ -362,7 +96,6 @@ rect:hover { fill:#934da5; }
.stat-widget-one .stat-text {
font-size: 14px;
color: #ff8762;
margin-top: 2.3rem;
margin-left: 1rem;
@ -380,7 +113,7 @@ rect:hover { fill:#934da5; }
font-size: 42px;
font-weight: 900;
display: inline-block;
color: #fff;
color: #000;
top: 16px;
position: relative;
}
@ -401,147 +134,7 @@ rect:hover { fill:#934da5; }
padding-top: 2%;
}
.oh-timesheets .stat-icon{
background: #5ebade !important;
}
.oh-contracts .stat-icon{
background: #b298e1 !important;
}
.oh-broad-factor .stat-icon{
background: #70cac1 !important;
}
.oh-timesheets .stat-widget-one .stat-text {
color: #5ebade;
}
.oh-contracts .stat-widget-one .stat-text {
color: #b298e1;
}
.oh-broad-factor .stat-widget-one .stat-text {
color: #70cac1;
}
.leave-manager {
background-color: #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);
padding: 0px;
margin: 15px;
}
.hr_leave_request_approve {
padding: 0;
padding-bottom: 0em;
padding-top: 0em;
transition: transform 0.2s ease, box-shadow 0.2s ease;
will-change: transform, box-shadow;
}
.leaves_request_month {
padding: 0;
padding-top: 0px;
padding-bottom: 0px;
padding-bottom: 0em;
padding-top: 0em;
transition: transform 0.2s ease, box-shadow 0.2s ease;
will-change: transform, box-shadow;
border-bottom: 1px solid #f1f1f133;
}
.leaves_request_today{
padding: 0;
padding-bottom: 0em;
padding-top: 0em;
transition: transform 0.2s ease, box-shadow 0.2s ease;
will-change: transform, box-shadow;
}
.hr_leave_request_approve:hover, .leaves_request_month:hover, .leaves_request_today:hover{
transform: translateY(-2px) translateZ(0) !important;
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
}
.hr_leave_request_approve p {
font-size: 14px;
color: #ff8762;
margin-left: 1rem;
margin-bottom: 0px;
text-align: left;
width: 64%;
font-weight: bold;
float: left;
text-align: center !important;
}
.leaves_request_today p {
font-size: 14px;
color: #5ebade;
margin-left: 1rem;
margin-bottom: 0px;
text-align: left;
width:64%;
float:left;
font-weight: bold;
text-align: center;
text-align: center !important;
}
.leaves_request_month p{
font-size: 14px;
color: #b298e1;
margin-left: 1rem;
margin-bottom:0px;
text-align: left;
width:64%;
float:left;
font-weight: bold;
text-align: center !important;
}
h4 .stat-count {
font-size: 17px;
text-align: center;
color: #000 !important;
margin-top: 0px;
width: 100%;
float: left;
margin: 0;
}
.leave-manager h4 {
float: left;
width: 23%;
}
.hr_leave_request_approve h4 {
padding: 5.2rem 0;
margin: 0;
background: #ff8762;
color: #fff;
}
.leaves_request_today h4 {
padding: 2.2rem 0;
margin: 0 !important;
background: #5ebade;
color: #fff;
}
.leaves_request_month h4 {
padding: 2.1rem 0;
margin: 0 !important;
background: #b298e1;
color: #fff;
}
.leaves_request_today h4 .stat-count ,.leaves_request_month h4 .stat-count , .hr_leave_request_approve h4 .stat-count
{
color:#fff !important;
}
.graph_view .legend {
margin-bottom: -79px !important;
display: inline-block;
border-collapse: collapse;
border-spacing: 0px;
margin-left: 90px !important;
margin-top: 77px !important;
}
.hr-chart-1{
margin: 15px 0px;
background: #fff;
@ -568,223 +161,12 @@ h4 .stat-count {
padding-bottom: 65px;
text-align: center !important;
}
.hr_leave_allocations_approve p {
font-size: 14px;
color: #ff8762;
margin-left: 1rem;
margin-bottom: 0px;
text-align: left;
width: 70%;
float: left;
font-weight: bold;
text-align: center !important;
}
.hr_leave_allocations_approve h4 {
padding: 2.5rem 0;
margin: 0;
background: #ff8762;
color: #fff;
width: 26%;
float: left;
}
.hr_leave_allocations_approve .stat-count {
font-size: 17px;
text-align: center;
color: #fff !important;
margin-top: 0px;
width: 100%;
float: left;
margin: 0;
}
.hr_leave_allocations_approve {
padding: 0;
padding-top: 0px;
padding-bottom: 0px;
padding-bottom: 0em;
padding-top: 0em;
box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06);
transition: transform 0.2s ease, box-shadow 0.2s ease;
will-change: transform, box-shadow;
background: #fff;
height: 80px;
}
.hr_leave_allocations_approve:hover{
transform: translateY(-2px) translateZ(0) !important;
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
}
.leave-manager {
background-color: #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);
padding: 0px;
margin: 15px;
margin-right: 15px;
margin-right: 0px;
width: 95% !important;
padding: 0;
}
.hr_job_application_approve {
padding: 0;
padding-top: 0px;
padding-bottom: 0px;
padding-top: 0px;
padding-bottom: 0px;
padding-top: 0px;
padding-bottom: 0px;
padding-bottom: 0em;
padding-top: 0em;
box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06);
transition: transform 0.2s ease, box-shadow 0.2s ease;
will-change: transform, box-shadow;
background: #fff;
margin-top: 15px;
height: 80px;
}
.hr_job_application_approve p {
font-size: 14px;
color: #70cac1;
margin-left: 1rem;
margin-bottom: 0px;
text-align: left;
width: 70%;
float: left;
font-weight: bold;
text-align: center !important;
}
.hr_job_application_approve h4 {
padding: 2.5rem 0;
margin: 0;
background: #70cac1;
color: #fff;
width: 26%;
float: left;
}
.hr_job_application_approve .stat-count {
font-size: 17px !important;
color: #fff !important;
margin-top: 0px !important;
width: 100%;
float: left;
margin: 0;
margin: 0px !important;
text-align: center !important;
width: 100% !important;
}
.hr_job_application_approve:hover{
transform: translateY(-2px) translateZ(0) !important;
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
}
.hr_attendance_login .oh-card {
margin: 0;
margin-bottom: 0px;
margin-bottom: 0px;
background: #134c8a;
padding-bottom: 7px;
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_attendance_login .stat-widget-one {
background: none;
}
.hr_attendance_login .stat-widget-one .stat-icon {
text-align: center;
padding-top: 9px;
}
.hr_attendance_login .stat-content {
width: 100%;
color: #fff !important;
}
.hr_attendance_login .stat-widget-one .stat-text {
margin: 0;
text-align: center;
width: 100% !important;
padding: 0;
color: #fff;
}
.hr_attendance_login .stat-widget-one .stat-icon .fa {
font-size: 50px;
}
.hr_attendance_login .stat-widget-one .stat-icon .fa {
font-size: 50px;
margin: 0px;
box-shadow: none;
}
.hr_attendance_login {
margin-top: 1.5%;
}
.monthly_leave_graph_view .oh-card {
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);
padding: 15px;
}
.broad_factor_graph .oh-card {
padding: 15px !important;
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);
padding: 15px;
}
.leave_broad_factor {
overflow-x: auto !important;
overflow-y: hidden !important;
height: 336px;
padding: 0px;
padding-left: 0px;
}
#broad_factor_pdf {
background-color: #ffffff;
float: right;
border-radius: 30px;
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);
border: 1px solid #4ec3b7;
color: #757575;
padding-top: 9px;
color: #4ec3b7;
}
#broad_factor_pdf:hover{
transform: translateY(-2px) translateZ(0) !important;
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
}
.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: 316px;
overflow-y: auto;
height: 757pxpx;
margin-bottom: 15px;
}
.hr_notification .media {
@ -810,32 +192,6 @@ h4 .stat-count {
background: #5ebade;
margin-bottom: 9px;
}
.monthly_leave_trend .oh-card{
background: #fff;
transition: none !important;
will-change: none !important;
box-shadow: none !important;
margin-bottom: 5px;
}
.monthly_leave_trend path {
stroke: #70cac1;
stroke-width: 2;
fill: none;
}
.monthly_leave_trend .axis path,
.monthly_leave_trend .axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.monthly_leave_trend circle{
fill: #ffffff;
stroke: #44b7ac;
stroke-width: 1.5;
}
.hr-chart-1 {
margin: 15px 0px;
background: #fff;
@ -846,168 +202,57 @@ h4 .stat-count {
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;
}
.monthly_leave_trend {
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);
}
.monthly_leave_trend:hover{
transform: translateY(-2px) translateZ(0) !important;
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
}
/*----------------------*/
.monthly_join_resign_trend{
padding-right: 0px !important;
}
.monthly_join_resign_trend .oh-card {
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);
padding: 15px;
}
.monthly_join_resign_trend .axis path,
.monthly_join_resign_trend .axis line {
fill: none;
shape-rendering: crispEdges;
}
.monthly_join_resign_trend .line {
fill: none;
stroke-width: 3px;
}
.monthly_join_resign_trend .area {
fill: steelblue;
opacity: 0.5;
}
.monthly_join_resign_trend .dot {
fill: steelblue;
stroke: steelblue;
stroke-width: 1.5px;
}
/*----------------------------------------*/
.monthly_attrition_rate path {
stroke: #70cac1;
stroke-width: 2;
fill: none;
}
.monthly_attrition_rate .axis path,
.monthly_attrition_rate .axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.monthly_attrition_rate circle{
fill: #ffffff;
stroke: #44b7ac;
stroke-width: 1.5;
}
.monthly_attrition_rate .oh-card {
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);
padding: 15px;
.row.main-section {
margin-right: 0px; !important;
}
.monthly_attrition_rate .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;
.text-align {
margin-left: 17px;
}
.row.main-section {
margin-right: 0px; !important;
.chart {
width: 100% !important;
height: 400px !important;
}
/* width */
.hr_notification::-webkit-scrollbar {
width: 4px;
.inner_select {
min-width: 150px
}
/* Track */
.hr_notification::-webkit-scrollbar-track {
background: #f1f1f1;
#table_status {
width: 90%;
margin-left: 5%;
font-family: Arial, Helvetica, sans-serif;
}
/* Handle */
.hr_notification::-webkit-scrollbar-thumb {
background: #495057;;
#table_status tr:nth-child(even) {
background-color: #f2f2f2;
}
/* Handle on hover */
.hr_notification::-webkit-scrollbar-thumb:hover {
background: #598da1;
#table_status tr:hover {
background-color: #ddd;
}
.oh-card-body {
display: flex;
justify-content: space-between;
.project-pill {
align-items: center;
}
.oh-ribbon {
position: absolute;
left: -5px; top: -5px;
z-index: 1;
overflow: hidden;
width: 150px; height: 150px;
text-align: right;
}
.oh-ribbon span {
font-size: 10px;
font-family: "Open Sans", Arial, Verdana, sans-serif;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 20px;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
width: 200px;
display: block;
background: #79A70A;
background: linear-gradient(#2989d8 0%, #1e5799 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 56px;
left: -35px;
}
.oh-ribbon span::before {
content: "";
position: absolute; left: 0px; top: 100%;
z-index: -1;
border-left: 3px solid #1e5799;
border-right: 3px solid transparent;
border-bottom: 3px solid transparent;
border-top: 3px solid #1e5799;
}
.oh-ribbon span::after {
content: "";
position: absolute; right: 0px; top: 100%;
z-index: -1;
border-left: 3px solid transparent;
border-right: 3px solid #1e5799;
border-bottom: 3px solid transparent;
border-top: 3px solid #1e5799;
}
.text-align {
margin-left: 17px;
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;
}
.chart {
width: 100% !important;
height: 400px !important;
.inner_select p {
margin-left: 20px
}

1105
project_dashboard_odoo/static/src/js/dashboard.js

File diff suppressed because it is too large

539
project_dashboard_odoo/static/src/xml/dashboard.xml

@ -9,81 +9,105 @@
<t t-name="DashboardProject">
<div class="row main-section" style="margin-left: 170px;">
<div class="col-md-4 col-sm-6 tot_projects oh-payslip" >
<div class="inner_select" style="display: flex;width:100%;">
<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>
</div>
<div class="row" style="margin-left: 4%;">
<div class="col-md-4 col-sm-6 tot_projects oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body">
<div class="stat-widget-one">
<div class="stat-icon" style="background:#e08048;"><i class="fa fa-puzzle-piece"/></div>
<div class="stat-content">
<div class="stat-head">Total Project</div>
<div class="stat_count"><t t-esc="widget.total_projects"/></div>
<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>
<div class="col-md-4 col-sm-6 tot_emp oh-payslip">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body">
<div class="stat-widget-one">
<div class="stat-icon" style="background:#645bd0"><i class="fa fa-user"/></div>
<div class="stat-content">
<div class="stat-head">Total Employees</div>
<div class="stat_count"><t t-esc="widget.total_employees"/></div>
<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>
<div class="col-md-4 col-sm-6 tot_tasks oh-payslip">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body">
<div class="stat-widget-one">
<div class="stat-icon" style="background:#85d05b"><i class="fa fa-tasks"/></div>
<div class="stat-content">
<div class="stat-head">Total tasks</div>
<div class="stat_count"><t t-esc="widget.total_tasks"/></div>
</div>
<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>
<div class="col-md-4 col-sm-6 hr_recorded oh-payslip">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body">
<div class="stat-widget-one">
<div class="stat-icon" style="background:#d05bb8"><i class="fa fa-clock-o"/></div>
<div class="stat-content">
<div class="stat-head">Hours Recorded</div>
<div class="stat_count"><t t-esc="widget.total_hours"/></div>
<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>
<div class="col-md-4 col-sm-6 tot_profitability oh-payslip">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body">
<div class="stat-widget-one">
<div class="stat-icon" style="background:#d0c35b"><i class="fa fa-dollar"/></div>
<div class="stat-content">
<div class="stat-head">Total Profitability</div>
<div class="stat_count"><t t-esc="widget.total_profitability"/></div>
<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 Profitability</div>
<div class="stat_count" style="padding: 4%;width: 30%;" id="tot_margin">
<t t-esc="widget.total_profitability" />
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 col-sm-6 tot_sale oh-payslip">
<div class="col-md-4 col-sm-6 oh-payslip">
<div class="oh-card" style="width: 410px;">
<div class="oh-card-body">
<div class="stat-widget-one">
<div class="stat-icon" style="background:#5b8ed0"><i class="fa fa-ticket"/></div>
<div class="stat-content">
<div class="stat-head">Total Sale Orders</div>
<div class="stat_count"><t t-esc="widget.total_sale_orders"/></div>
<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>
@ -95,79 +119,87 @@
<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="col-sm-7 col-lg-7" style="margin-left: 2%;">
<div class="graph_view" style="padding:0">
<div class="text-color hr-chart-1">
<div class="oh-card-body pb-0">
<h4 class="mb-0"/>
<p class="stat-head" style="padding : 0px;">ProjectTask Analysis</p>
<canvas id="project_doughnut" style="background:#fff;" width="200" height="120" />
</div>
</div>
<div class="selling_product_graph_view">
<div class="oh-card text-color" style="background-color:#fff;">
<canvas class="top_selling_employees" width="200" height="120" />
</div>
</div>
<div class="row" style="margin:0px">
<div class="col-md-12" id="col-graph">
<div class="card">
<div class="card-header">
<div class="card-title">
<b>
<h3 class="custom-h3">Profitability</h3>
</b>
</div>
<div class="card-tools">
<select id="income_expense_values">
<option id="income_this_year" value="income_this_year">This Year</option>
<option id="income_this_month" value="income_this_month">This Month</option>
<div role="separator" class="dropdown-divider" />
<option id="income_last_year" value="income_last_year">Last Year</option>
</select>
</div>
</div>
<div class="card-body mt-3" id="in_ex_body_hide">
<div class="row">
<p id="myelement1"> </p>
<div class="chart">
<canvas id="canvas" width="100% !important" height="auto !important"> </canvas>
</div>
</div>
</div>
</div>
<div class="emp_graph"/>
</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: 316px;overflow-y: auto;margin-bottom: 15px;">
<div class="hr_notification_head"
style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #218a45a3;margin-bottom: 9px;">
ProjectTask Details
<div class="col-md-4 col-lg-4" style="top: 20px;right: -100px;">
<div class="hr_notification" style="background: #fff;
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">
<div class="media-body">
<table class="table table-sm">
<thead>
<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>
<th rowspan="14">Project Name</th>
<th rowspan="14">Task Name</th>
<td>
<t t-esc="proj[1]" />
</td>
<td>
<t t-esc="proj[0]" />
</td>
</tr>
</thead>
<tbody>
<t t-foreach="widget.task_data" t-as="proj">
<tr>
<td>
<t t-esc="proj[1]"/>
</td>
<td>
<t t-esc="proj[0]"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</t>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<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="selling_product_graph_view">
<div class="oh-card text-color">
<div class="oh-card-body pb-0">
<h4 class="mb-0">
</h4>
<p class="stat-head" style="padding : 0px;">Timesheet Analysis</p>
</div>
<canvas class="top_selling_employees" width="200" height="120"/>
</div>
</div>
</div>
<div class="col-md-4 col-lg-4" style="top: 149px;right: -100px;">
</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: 316px;overflow-y: auto;margin-bottom: 15px;">
<div class="hr_notification_head"
style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #218a45a3;margin-bottom: 9px;">
Hours Recorded
height: 284px;margin-bottom: 15px;">
<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">
@ -186,7 +218,7 @@
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="hour_recorde"/>
<t t-esc="hour_recorde" />
</h2>
</td>
</tr>
@ -200,15 +232,15 @@
</tr>
</thead>
<tbody>
<t t-foreach="widget.billable_fix" t-as="billable_fix">
<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"/>
<t t-esc="billable_fix" />
</h2>
</td>
</tr>
</t>
</t>
</tbody>
</table>
<table class="table table-sm">
@ -219,13 +251,13 @@
</thead>
<tbody>
<t t-foreach="widget.hour_recorded" t-as="hour_recorded">
<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"/>
<t t-esc="hour_recorded" />
</h2>
</td>
</tr>
@ -240,207 +272,184 @@
</thead>
<tbody>
<t t-foreach="widget.non_billable" t-as="non_billable">
<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"/>
<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">
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14" style="padding-left: 24.3rem;">Total:</th>
</tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
</thead>
<tbody>
<t t-foreach="widget.total_hr" t-as="total_hr">
<tr>
<t t-esc="total_hr"/>
</h2>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<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="row" style="margin:0px">
<div class="col-md-12" id="col-graph">
<div class="card">
<div class="card-header">
<div class="card-title">
<b>
<h3 class="custom-h3">Profitability</h3>
</b>
</div>
<div class="card-tools">
<select id="income_expense_values">
<option id="income_this_year" value="income_this_year">This Year</option>
<option id="income_this_month" value="income_this_month">This Month</option>
<div role="separator" class="dropdown-divider" />
<option id="income_last_year" value="income_this_year">Last Year</option>
</select>
</div>
</div>
<div class="card-body mt-3" id="in_ex_body_hide">
<div class="row">
<!-- <div class="col-md-12">-->
<p id="myelement1"> </p>
<div class="chart">
<!-- <canvas id="canvas"> </canvas>-->
<canvas id="canvas" width="100% !important" height="auto !important"> </canvas>
</div>
<!-- </div>-->
<t t-esc="total_hr" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4 col-lg-4" style="top: 155px;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: 316px;overflow-y: auto;margin-bottom: 15px;">
<div class="hr_notification_head"
style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background:#218a45a3;;margin-bottom: 9px;">
Profitability
</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">Invoiced</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.invoiced" t-as="invoiced">
<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: 284px;margin-bottom: 15px;">
<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;">
Profitability
</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>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="invoiced"/>
</h2>
</td>
<th rowspan="14">Invoiced</th>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">To Invoice</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.to_invoice" t-as="to_invoice">
</thead>
<tbody>
<t t-foreach="widget.invoiced" t-as="invoiced">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="invoiced" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="to_invoice"/>
</h2>
</td>
<th rowspan="14">To Invoice</th>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Timesheet costs</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.time_cost" t-as="time_cost">
</thead>
<tbody>
<t t-foreach="widget.to_invoice" t-as="to_invoice">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="to_invoice" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Timesheet costs</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.time_cost" t-as="time_cost">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="time_cost"/>
</h2>
</td>
<t t-esc="time_cost" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Other costs</th>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Other costs</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.expen_cost" t-as="expen_cost">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
</thead>
<tbody>
<t t-foreach="widget.expen_cost" t-as="expen_cost">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="expen_cost"/>
</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.payment_details" t-as="payment_method">
<t t-esc="expen_cost" />
</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.payment_details" t-as="payment_method">
<tr>
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="payment_method"/>
</h2>
</td>
</tr>
</t>
</tbody>
</table>
<t t-esc="payment_method" />
</h2>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</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="project-pill" t-esc="data['projects']" />
</td>
</tr>
</t>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
</templates>

Loading…
Cancel
Save