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. 3
      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. 1109
      project_dashboard_odoo/static/src/js/dashboard.js
  31. 541
      project_dashboard_odoo/static/src/xml/dashboard.xml

3
project_dashboard_odoo/README.rst

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

3
project_dashboard_odoo/__init__.py

@ -20,4 +20,5 @@
# #
############################################################################# #############################################################################
from .import models from .import models
from . import controllers

4
project_dashboard_odoo/__manifest__.py

@ -3,7 +3,7 @@
# #
# Cybrosys Technologies Pvt. Ltd. # 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>) # Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
# #
# You can modify it under the terms of the GNU LESSER # You can modify it under the terms of the GNU LESSER
@ -25,7 +25,7 @@
'category': 'Productivity', 'category': 'Productivity',
'summary': 'Detailed Dashboard View for Project', 'summary': 'Detailed Dashboard View for Project',
'description': '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', 'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions', 'company': 'Cybrosys Techno Solutions',
'maintainer': '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 #### 26.05.2022
#### Version 15.0.1.0.0 #### Version 15.0.1.0.0
## Module <project_dashboard_odoo> ## Module <project_dashboard_odoo>
##### Initial Commit for 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 datetime import datetime
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
import pandas as pd
import calendar from odoo import models, api
class PosDashboard(models.Model): 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' _inherit = 'project.project'
@api.model @api.model
def get_tiles_data(self): 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_project = self.env['project.project'].search([])
all_task = self.env['project.task'].search([]) all_task = self.env['project.task'].search([])
analytic_project = self.env['account.analytic.line'].search([]) analytic_project = self.env['account.analytic.line'].search([])
@ -48,18 +86,39 @@ class PosDashboard(models.Model):
('sale_order_id', '!=', False) ('sale_order_id', '!=', False)
], ['sale_order_id']) ], ['sale_order_id'])
task_so_ids = [o['sale_order_id'][0] for o in task] 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 { return {
'total_projects': len(all_project), 'total_projects': len(all_project),
'total_tasks': len(all_task), 'total_tasks': len(all_task),
'total_hours': total_time, 'total_hours': total_time,
'total_profitability': profitability, 'total_profitability': profitability,
'total_employees': len(employees), '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 @api.model
def get_top_timesheet_employees(self): 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 query = '''select hr_employee.name as employee,sum(unit_amount) as unit
from account_analytic_line from account_analytic_line
@ -80,80 +139,19 @@ class PosDashboard(models.Model):
return final return final
@api.model @api.model
def get_project_task(self): def get_details(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'))
return { Summery:
'payment_details': payment_details, 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, 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(expense_cost) as expen_cost,
sum(margin) as payment_details from project_profitability_report''' sum(margin) as payment_details from project_profitability_report'''
self._cr.execute(query) self._cr.execute(query)
@ -165,7 +163,7 @@ class PosDashboard(models.Model):
to_invoice = [] to_invoice = []
for record in data: for record in data:
to_invoice.append(record.get('to_invoice')) to_invoice.append(record.get('to_invoice'))
record.get('to_invoice')
time_cost = [] time_cost = []
for record in data: for record in data:
time_cost.append(record.get('time_cost')) time_cost.append(record.get('time_cost'))
@ -177,7 +175,6 @@ class PosDashboard(models.Model):
payment_details = [] payment_details = []
for record in data: for record in data:
payment_details.append(record.get('payment_details')) payment_details.append(record.get('payment_details'))
return { return {
'invoiced': invoiced, 'invoiced': invoiced,
'to_invoice': to_invoice, 'to_invoice': to_invoice,
@ -188,6 +185,14 @@ class PosDashboard(models.Model):
@api.model @api.model
def get_hours_data(self): 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 query = '''SELECT sum(unit_amount) as hour_recorded FROM account_analytic_line
WHERE timesheet_invoice_type='non_billable_project' ''' WHERE timesheet_invoice_type='non_billable_project' '''
self._cr.execute(query) self._cr.execute(query)
@ -239,6 +244,14 @@ class PosDashboard(models.Model):
@api.model @api.model
def get_income_this_year(self): 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 = [] month_list = []
for i in range(11, -1, -1): for i in range(11, -1, -1):
@ -256,7 +269,8 @@ class PosDashboard(models.Model):
records = [] records = []
for month in month_list: 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: if not last_month_inc:
records.append({ records.append({
@ -283,6 +297,14 @@ class PosDashboard(models.Model):
@api.model @api.model
def get_income_last_year(self): 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 = [] month_list = []
for i in range(11, -1, -1): for i in range(11, -1, -1):
l_month = datetime.now() - relativedelta(months=i) l_month = datetime.now() - relativedelta(months=i)
@ -290,7 +312,6 @@ class PosDashboard(models.Model):
month_list.append(text) month_list.append(text)
states_arg = "" states_arg = ""
self._cr.execute(('''select sum(margin) as income ,to_char(project_profitability_report.line_date, 'Month') self._cr.execute(('''select sum(margin) as income ,to_char(project_profitability_report.line_date, 'Month')
as month from project_profitability_report where as month from project_profitability_report where
Extract(year FROM project_profitability_report.line_date) = Extract(year FROM DATE(NOW())) -1 Extract(year FROM project_profitability_report.line_date) = Extract(year FROM DATE(NOW())) -1
@ -299,7 +320,8 @@ class PosDashboard(models.Model):
records = [] records = []
for month in month_list: 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: if not last_month_inc:
records.append({ records.append({
'month': month, 'month': month,
@ -327,6 +349,14 @@ class PosDashboard(models.Model):
@api.model @api.model
def get_income_this_month(self): 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 = "" states_arg = ""
day_list = [] day_list = []
now = datetime.now() now = datetime.now()
@ -370,6 +400,15 @@ class PosDashboard(models.Model):
@api.model @api.model
def get_task_data(self): 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 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''') Inner join project_project as pro on project_task.project_id = pro.id ORDER BY project_name ASC''')
data = self._cr.fetchall() data = self._cr.fetchall()
@ -380,3 +419,43 @@ class PosDashboard(models.Model):
return { return {
'project': project_name '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"> <div class="col-lg-12 my-2">
<h4 class="mt-2" <h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> 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 <p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> 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, User can click the Tiles and States in tile,That shows the detailed view of corresponding tiles.</p>
Hours Recorded, Total Profitability, Total Sale Orders.</p> <img src="assets/screenshots/Screenshot1.png" class="img-responsive img-thumbnail border" width="100%"
<img src="assets/screenshots/pd1.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/> height="auto"/>
</div> </div>
<div class="col-lg-12 my-3"> <div class="col-lg-12 my-3">
<h4 class="mt-3" <h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> 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 <p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Task analysis from various projects. </p> Project dashboard have different types of graphs that will give you complete analyse of the project module. </p>
<img src="assets/screenshots/pd2.png" class="img-responsive img-thumbnail border" width="100%" <img src="assets/screenshots/Screenshot2.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/> height="auto"/>
</div> </div>
<div class="col-lg-12 my-3"> <div class="col-lg-12 my-3">
<h4 class="mt-3" <h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Employees Timesheet</h4> Employees Timesheet Graphh</h4>
<img src="assets/screenshots/pd3.png" class="img-responsive img-thumbnail border" width="100%" <img src="assets/screenshots/Screenshot3.png" class="img-responsive img-thumbnail border" width="100%"
height="auto"/> height="auto"/>
</div> </div>
@ -218,11 +226,24 @@
<div class="col-lg-12 my-3"> <div class="col-lg-12 my-3">
<h4 class="mt-3" <h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Project Profitability</h4> Project Profitability Graph</h4>
<img src="assets/screenshots/pd4.png" class="img-responsive img-thumbnail border" width="100%" <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"/> height="auto"/>
</div> </div>
</div> </div>
<!-- SUGGESTED PRODUCTS --> <!-- SUGGESTED PRODUCTS -->

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

@ -13,28 +13,6 @@ overflow: auto !important;
.breadcrumbs { .breadcrumbs {
margin-top: 0; 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{ .stat-icon{
display: inline-block; display: inline-block;
} }
@ -67,120 +45,6 @@ overflow: auto !important;
.stat_count { .stat_count {
font-size: 28px !important; 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 { .oh_dashboards {
background-color: #f8faff !important; background-color: #f8faff !important;
@ -190,25 +54,6 @@ rect:hover { fill:#934da5; }
.container-fluid.o_hr_dashboard { .container-fluid.o_hr_dashboard {
padding: 0px !important; 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 { .oh-card {
padding-top: 0px; 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; 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 { .oh-payslip {
margin-top: 1.5%; margin-top: 1.5%;
@ -348,7 +83,6 @@ rect:hover { fill:#934da5; }
height: 85px; height: 85px;
text-align: center; text-align: center;
padding-top: 2%; padding-top: 2%;
background: #ff8762;
color: #fff; color: #fff;
} }
@ -362,7 +96,6 @@ rect:hover { fill:#934da5; }
.stat-widget-one .stat-text { .stat-widget-one .stat-text {
font-size: 14px; font-size: 14px;
color: #ff8762;
margin-top: 2.3rem; margin-top: 2.3rem;
margin-left: 1rem; margin-left: 1rem;
@ -380,7 +113,7 @@ rect:hover { fill:#934da5; }
font-size: 42px; font-size: 42px;
font-weight: 900; font-weight: 900;
display: inline-block; display: inline-block;
color: #fff; color: #000;
top: 16px; top: 16px;
position: relative; position: relative;
} }
@ -401,147 +134,7 @@ rect:hover { fill:#934da5; }
padding-top: 2%; 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{ .hr-chart-1{
margin: 15px 0px; margin: 15px 0px;
background: #fff; background: #fff;
@ -568,223 +161,12 @@ h4 .stat-count {
padding-bottom: 65px; padding-bottom: 65px;
text-align: center !important; 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 { .hr_notification {
background: #fff; background: #fff;
transition: transform 0.2s ease, box-shadow 0.2s ease; transition: transform 0.2s ease, box-shadow 0.2s ease;
will-change: transform, box-shadow; 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); box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62,57,107,0.06);
height: 316px; height: 757pxpx;
overflow-y: auto;
margin-bottom: 15px; margin-bottom: 15px;
} }
.hr_notification .media { .hr_notification .media {
@ -810,32 +192,6 @@ h4 .stat-count {
background: #5ebade; background: #5ebade;
margin-bottom: 9px; 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 { .hr-chart-1 {
margin: 15px 0px; margin: 15px 0px;
background: #fff; 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); 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; padding-top: 3px !important;
} }
.monthly_leave_trend { .row.main-section {
background: #fff; margin-right: 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);
}
.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;
} }
.monthly_attrition_rate .oh-card:hover{ .text-align {
transform: translateY(-2px) translateZ(0) !important; margin-left: 17px;
box-shadow: 0 10px 10px 0 rgba(62, 57, 107, 0.12), 0 0 0 transparent !important;
} }
.chart {
.row.main-section { width: 100% !important;
margin-right: 0px; !important; height: 400px !important;
} }
/* width */ .inner_select {
.hr_notification::-webkit-scrollbar { min-width: 150px
width: 4px;
} }
/* Track */ #table_status {
.hr_notification::-webkit-scrollbar-track { width: 90%;
background: #f1f1f1; margin-left: 5%;
font-family: Arial, Helvetica, sans-serif;
} }
/* Handle */ #table_status tr:nth-child(even) {
.hr_notification::-webkit-scrollbar-thumb { background-color: #f2f2f2;
background: #495057;;
} }
/* Handle on hover */ #table_status tr:hover {
.hr_notification::-webkit-scrollbar-thumb:hover { background-color: #ddd;
background: #598da1;
} }
.oh-card-body { .project-pill {
display: flex;
justify-content: space-between;
align-items: center; align-items: center;
} font-family: "Open Sans", Arial, Verdana, sans-serif;
.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-weight: bold; font-weight: bold;
color: #FFF; font-size: 11px;
text-transform: uppercase; display: inline-block;
text-align: center; height: 100%;
line-height: 20px; white-space: nowrap;
transform: rotate(-45deg); width: auto;
-webkit-transform: rotate(-45deg); position: relative;
width: 200px; border-radius: 100px;
display: block; line-height: 1;
background: #79A70A; overflow: hidden;
background: linear-gradient(#2989d8 0%, #1e5799 100%); padding: 0px 8px 0px 7px;
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1); text-overflow: ellipsis;
position: absolute; line-height: 1.25rem;
top: 56px; color: #fff;
left: -35px; word-break: break-word;
} background: #0253e8;
.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;
} }
.chart { .inner_select p {
width: 100% !important; margin-left: 20px
height: 400px !important;
} }

1109
project_dashboard_odoo/static/src/js/dashboard.js

File diff suppressed because it is too large

541
project_dashboard_odoo/static/src/xml/dashboard.xml

@ -9,81 +9,105 @@
<t t-name="DashboardProject"> <t t-name="DashboardProject">
<div class="row main-section" style="margin-left: 170px;"> <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" style="width: 410px;">
<div class="oh-card-body"> <div class="oh-card-body tot_projects" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one"> <div class="stat-widget-one" style="display:flex;">
<div class="stat-icon" style="background:#e08048;"><i class="fa fa-puzzle-piece"/></div> <div class="stat-icon"><i class="fa fa-puzzle-piece" /></div>
<div class="stat-content"> <div class="stat-head" style="padding: 5%;width: 60%;">Total Project</div>
<div class="stat-head">Total Project</div> <div class="stat_count" style="padding: 4%;width: 30%;" id="tot_project">
<div class="stat_count"><t t-esc="widget.total_projects"/></div> <t t-esc="widget.total_projects" />
</div> </div>
</div> </div>
</div> </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" style="width: 410px;">
<div class="oh-card-body"> <div class="oh-card-body tot_emp" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one"> <div class="stat-widget-one" style="display:flex;">
<div class="stat-icon" style="background:#645bd0"><i class="fa fa-user"/></div> <div class="stat-icon"><i class="fa fa-user" /></div>
<div class="stat-content"> <div class="stat-head" style="padding: 5%;width: 60%;">Total Employees</div>
<div class="stat-head">Total Employees</div> <div class="stat_count" style="padding: 4%;width: 30%;" id="tot_employee">
<div class="stat_count"><t t-esc="widget.total_employees"/></div> <t t-esc="widget.total_employees" />
</div> </div>
</div> </div>
</div> </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" style="width: 410px;">
<div class="oh-card-body"> <div class="oh-card-body tot_tasks" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one"> <div class="stat-widget-one" style="display:flex;">
<div class="stat-icon" style="background:#85d05b"><i class="fa fa-tasks"/></div> <div class="stat-icon"><i class="fa fa-tasks" /></div>
<div class="stat-content"> <div class="stat-head" style="padding: 5%;width: 60%;">Total tasks</div>
<div class="stat-head">Total tasks</div> <div class="stat_count" style="padding: 4%;width: 30%;" id="tot_task">
<div class="stat_count"><t t-esc="widget.total_tasks"/></div> <t t-esc="widget.total_tasks" />
</div> </div>
</div> </div>
</div> </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" style="width: 410px;">
<div class="oh-card-body"> <div class="oh-card-body hr_recorded" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one"> <div class="stat-widget-one" style="display:flex;">
<div class="stat-icon" style="background:#d05bb8"><i class="fa fa-clock-o"/></div> <div class="stat-icon"><i class="fa fa-clock-o" /></div>
<div class="stat-content"> <div class="stat-head" style="padding: 5%;width: 60%;">Hours Recorded</div>
<div class="stat-head">Hours Recorded</div> <div class="stat_count" style="padding: 4%;width: 30%;" id="tot_hrs">
<div class="stat_count"><t t-esc="widget.total_hours"/></div> <t t-esc="widget.total_hours" />
</div> </div>
</div> </div>
</div> </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" style="width: 410px;">
<div class="oh-card-body"> <div class="oh-card-body tot_profitability" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one"> <div class="stat-widget-one" style="display:flex;">
<div class="stat-icon" style="background:#d0c35b"><i class="fa fa-dollar"/></div> <div class="stat-icon"><i class="fa fa-dollar" /></div>
<div class="stat-content"> <div class="stat-head" style="padding: 5%;width: 60%;">Total Profitability</div>
<div class="stat-head">Total Profitability</div> <div class="stat_count" style="padding: 4%;width: 30%;" id="tot_margin">
<div class="stat_count"><t t-esc="widget.total_profitability"/></div> <t t-esc="widget.total_profitability" />
</div> </div>
</div> </div>
</div> </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" style="width: 410px;">
<div class="oh-card-body"> <div class="oh-card-body tot_sale" style="box-shadow:5px 11px 30px;">
<div class="stat-widget-one"> <div class="stat-widget-one" style="display:flex;">
<div class="stat-icon" style="background:#5b8ed0"><i class="fa fa-ticket"/></div> <div class="stat-icon"><i class="fa fa-ticket" /></div>
<div class="stat-content"> <div class="stat-head" style="padding: 5%;width: 60%;">Total Sale Orders</div>
<div class="stat-head">Total Sale Orders</div> <div class="stat_count" style="padding: 4%;width: 30%;" id="tot_so">
<div class="stat_count"><t t-esc="widget.total_sale_orders"/></div> <t t-esc="widget.total_sale_orders" />
</div> </div>
</div> </div>
</div> </div>
@ -95,79 +119,87 @@
<t t-name="DashboardChart"> <t t-name="DashboardChart">
<div class="col-xs-12 col-sm-12 col-lg-12 col-md-12"> <div class="col-xs-12 col-sm-12 col-lg-12 col-md-12">
<div class="row main-section"> <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="graph_view" style="padding:0">
<div class="text-color hr-chart-1"> <div class="text-color hr-chart-1">
<div class="oh-card-body pb-0"> <canvas id="project_doughnut" style="background:#fff;" width="200" height="120" />
<h4 class="mb-0"/> </div>
<p class="stat-head" style="padding : 0px;">ProjectTask Analysis</p> </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>
<div class="emp_graph"/>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4 col-lg-4" style="top: 82px;right: -100px;"> <div class="col-md-4 col-lg-4" style="top: 20px;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); <div class="hr_notification" style="background: #fff;
height: 316px;overflow-y: auto;margin-bottom: 15px;"> height: 763px;margin-bottom: 15px;margin-top: 15px;box-shadow:5px 11px 30px;">
<div class="hr_notification_head" <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;">
style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #218a45a3;margin-bottom: 9px;"> Project Task Details
ProjectTask Details
</div> </div>
<div class="col-sm-12 col-lg-12" style="padding:0;"> <div class="col-sm-12 col-lg-12" style="padding:0;">
<div class="text-color"> <div class="text-color">
<div class="media"> <div class="media" style="overflow-y: auto;height: 704px;">
<div class="media-body"> <div class="media-body">
<table class="table table-sm"> <table class="table table-sm">
<thead> <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> <tr>
<th rowspan="14">Project Name</th> <td>
<th rowspan="14">Task Name</th> <t t-esc="proj[1]" />
</td>
<td>
<t t-esc="proj[0]" />
</td>
</tr> </tr>
</thead> </t>
<tbody> </tbody>
<t t-foreach="widget.task_data" t-as="proj"> </table>
<tr>
<td>
<t t-esc="proj[1]"/>
</td>
<td>
<t t-esc="proj[0]"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</div> </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> </div>
<canvas class="top_selling_employees" width="200" height="120"/>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4 col-lg-4" style="top: 149px;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); <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;"> height: 284px;margin-bottom: 15px;">
<div class="hr_notification_head" <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;">
style="font-size: 17px;text-align: center;padding: 12px 0;color: #fff;font-weight: 300;background: #218a45a3;margin-bottom: 9px;"> Hours Recorded
Hours Recorded
</div> </div>
<div class="col-sm-12 col-lg-12" style="padding:0;"> <div class="col-sm-12 col-lg-12" style="padding:0;">
<div class="text-color"> <div class="text-color">
@ -186,7 +218,7 @@
<tr> <tr>
<td> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <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> </h2>
</td> </td>
</tr> </tr>
@ -200,15 +232,15 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<t t-foreach="widget.billable_fix" t-as="billable_fix"> <t t-foreach="widget.billable_fix" t-as="billable_fix">
<tr> <tr>
<td> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <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> </h2>
</td> </td>
</tr> </tr>
</t> </t>
</tbody> </tbody>
</table> </table>
<table class="table table-sm"> <table class="table table-sm">
@ -219,13 +251,13 @@
</thead> </thead>
<tbody> <tbody>
<t t-foreach="widget.hour_recorded" t-as="hour_recorded"> <t t-foreach="widget.hour_recorded" t-as="hour_recorded">
<tr> <tr>
<td> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <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> </h2>
</td> </td>
</tr> </tr>
@ -240,207 +272,184 @@
</thead> </thead>
<tbody> <tbody>
<t t-foreach="widget.non_billable" t-as="non_billable"> <t t-foreach="widget.non_billable" t-as="non_billable">
<tr> <tr>
<td> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <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> </h2>
</td> </td>
</tr> </tr>
</t> </t>
</tbody> </tbody>
</table> </table>
<table class="table table-sm"> <table class="table table-sm">
<thead> <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> <tr>
<th rowspan="14" style="padding-left: 24.3rem;">Total:</th>
</tr>
<td> </thead>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <tbody>
<t t-foreach="widget.total_hr" t-as="total_hr">
<tr>
<t t-esc="total_hr"/> <td>
</h2> <h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
</td>
</tr>
</t>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-lg-12 col-md-12"> <t t-esc="total_hr" />
<div class="row main-section"> </h2>
<div class="col-sm-7 col-lg-7"> </td>
<div class="row" style="margin:0px"> </tr>
<div class="col-md-12" id="col-graph"> </t>
<div class="card"> </tbody>
<div class="card-header"> </table>
<div class="card-title"> </div>
<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>-->
</div> </div>
</div> </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>
<div class="col-sm-12 col-lg-12" style="padding:0;"> <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);
<div class="text-color"> height: 284px;margin-bottom: 15px;">
<div class=""> <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;">
<div class="media"> Profitability
<div class="media-body"> </div>
<table class="table table-sm"> <div class="col-sm-12 col-lg-12" style="padding:0;">
<thead> <div class="text-color">
<tr> <div class="">
<th rowspan="14">Invoiced</th> <div class="media">
</tr> <div class="media-body">
</thead> <table class="table table-sm">
<tbody> <thead>
<t t-foreach="widget.invoiced" t-as="invoiced">
<tr> <tr>
<td> <th rowspan="14">Invoiced</th>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="invoiced"/>
</h2>
</td>
</tr> </tr>
</t> </thead>
</tbody> <tbody>
</table> <t t-foreach="widget.invoiced" t-as="invoiced">
<table class="table table-sm"> <tr>
<thead> <td>
<tr> <h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<th rowspan="14">To Invoice</th> <t t-esc="invoiced" />
</tr> </h2>
</thead> </td>
<tbody> </tr>
<t t-foreach="widget.to_invoice" t-as="to_invoice"> </t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr> <tr>
<td> <th rowspan="14">To Invoice</th>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="to_invoice"/>
</h2>
</td>
</tr> </tr>
</t> </thead>
</tbody> <tbody>
</table> <t t-foreach="widget.to_invoice" t-as="to_invoice">
<table class="table table-sm"> <tr>
<thead> <td>
<tr> <h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<th rowspan="14">Timesheet costs</th>
</tr> <t t-esc="to_invoice" />
</thead> </h2>
<tbody> </td>
<t t-foreach="widget.time_cost" t-as="time_cost"> </tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr> <tr>
<th rowspan="14">Timesheet costs</th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.time_cost" t-as="time_cost">
<tr>
<td> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="time_cost"/> <t t-esc="time_cost" />
</h2> </h2>
</td> </td>
</tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Other costs</th>
</tr> </tr>
</t>
</tbody>
</table>
<table class="table table-sm">
<thead>
<tr>
<th rowspan="14">Other costs</th>
</tr>
</thead> </thead>
<tbody> <tbody>
<t t-foreach="widget.expen_cost" t-as="expen_cost"> <t t-foreach="widget.expen_cost" t-as="expen_cost">
<tr> <tr>
<td> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="expen_cost"/> <t t-esc="expen_cost" />
</h2> </h2>
</td> </td>
</tr> </tr>
</t> </t>
</tbody> </tbody>
</table> </table>
<table class="table table-sm"> <table class="table table-sm">
<thead> <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> <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> <td>
<h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;"> <h2 class="text-color display-6" style="font-size: 15px;margin-left: 400px;margin-top: -30px;">
<t t-esc="payment_method"/> <t t-esc="payment_method" />
</h2> </h2>
</td> </td>
</tr> </tr>
</t> </t>
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
</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> </div>
</div>
</div>
</t> </t>
</templates> </templates>
Loading…
Cancel
Save