odoo/packs/odoo.v18/base/odoo_dynamic_dashboard/models/dashboard_block.py

182 lines
9.1 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Bhagyadev KP (odoo@cybrosys.com)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
################################################################################
from ast import literal_eval
from odoo import api, fields, models
from odoo.osv import expression
class DashboardBlock(models.Model):
"""Class is used to create charts and tiles in dashboard"""
_name = "dashboard.block"
_description = "Dashboard Block"
def get_default_action(self):
"""Function to get values from dashboard if action_id is true return
id else return false"""
action_id = self.env.ref(
'odoo_dynamic_dashboard.dashboard_view_action')
if action_id:
return action_id.id
return False
name = fields.Char(string="Name", help='Name of the block')
fa_icon = fields.Char(string="Icon", help="Add icon for tile")
operation = fields.Selection(
selection=[("sum", "Sum"), ("avg", "Average"), ("count", "Count")],
string="Operation",
help='Tile Operation that needs to bring values for tile',
required=True)
graph_type = fields.Selection(
selection=[("bar", "Bar"), ("radar", "Radar"), ("pie", "Pie"),
("polarArea", "polarArea"), ("line", "Line"),
("doughnut", "Doughnut")],
string="Chart Type", help='Type of Chart')
measured_field_id = fields.Many2one("ir.model.fields",
string="Measured Field",
help="Select the Measured")
client_action_id = fields.Many2one('ir.actions.client',
string="Client action",
default=get_default_action,
help="Client action")
type = fields.Selection(
selection=[("graph", "Chart"), ("tile", "Tile")],
string="Type", help='Type of Block ie, Chart or Tile')
x_axis = fields.Char(string="X-Axis", help="Chart X-axis")
y_axis = fields.Char(string="Y-Axis", help="Chart Y-axis")
height = fields.Char(string="Height ", help="Height of the block")
width = fields.Char(string="Width", help="Width of the block")
translate_x = fields.Char(string="Translate_X",
help="x value for the style transform translate")
translate_y = fields.Char(string="Translate_Y",
help="y value for the style transform translate")
data_x = fields.Char(string="Data_X", help="Data x value for resize")
data_y = fields.Char(string="Data_Y", help="Data y value for resize")
group_by_id = fields.Many2one("ir.model.fields",
string="Group by(Y-Axis)",
help='Field value for Y-Axis')
tile_color = fields.Char(string="Tile Color", help='Primary Color of Tile')
text_color = fields.Char(string="Text Color", help='Text Color of Tile')
val_color = fields.Char(string="Value Color", help='Value Color of Tile')
fa_color = fields.Char(string="Icon Color", help='Icon Color of Tile')
filter = fields.Char(string="Filter", help="Add filter")
model_id = fields.Many2one('ir.model', string='Model',
help="Select the module name")
model_name = fields.Char(related='model_id.model', string="Model Name",
help="Added model_id model")
edit_mode = fields.Boolean(string="Edit Mode",
help="Enable to edit chart and tile",)
@api.onchange('model_id')
def _onchange_model_id(self):
if self.operation or self.measured_field_id:
self.operation = False
self.measured_field_id = False
def get_dashboard_vals(self, action_id, start_date=None, end_date=None):
"""Fetch block values from js and create chart"""
block_id = []
for rec in self.env['dashboard.block'].sudo().search(
[('client_action_id', '=', int(action_id))]):
if rec.filter is False:
rec.filter = "[]"
filter_list = literal_eval(rec.filter)
filter_list = [filter_item for filter_item in filter_list if not (
isinstance(filter_item, tuple) and filter_item[
0] == 'create_date')]
rec.filter = repr(filter_list)
vals = {'id': rec.id, 'name': rec.name, 'type': rec.type,
'graph_type': rec.graph_type, 'icon': rec.fa_icon,
'model_name': rec.model_name,
'color': f'background-color: {rec.tile_color};' if rec.tile_color else '#1f6abb;',
'text_color': f'color: {rec.text_color};' if rec.text_color else '#FFFFFF;',
'val_color': f'color: {rec.val_color};' if rec.val_color else '#FFFFFF;',
'icon_color': f'color: {rec.tile_color};' if rec.tile_color else '#1f6abb;',
'height': rec.height,
'width': rec.width,
'translate_x': rec.translate_x,
'translate_y': rec.translate_y,
'data_x': rec.data_x,
'data_y': rec.data_y,
'domain': filter_list,
}
domain = []
if rec.filter:
domain = expression.AND([literal_eval(rec.filter)])
if rec.model_name:
if rec.type == 'graph':
self._cr.execute(self.env[rec.model_name].get_query(domain,
rec.operation,
rec.measured_field_id,
start_date,
end_date,
group_by=rec.group_by_id))
records = self._cr.dictfetchall()
x_axis = []
for record in records:
if record.get('name') and type(
record.get('name')) == dict:
x_axis.append(record.get('name')[self._context.get(
'lang') or 'en_US'])
else:
x_axis.append(record.get(rec.group_by_id.name))
y_axis = []
for record in records:
y_axis.append(record.get('value'))
vals.update({'x_axis': x_axis, 'y_axis': y_axis})
else:
self._cr.execute(self.env[rec.model_name].get_query(domain,
rec.operation,
rec.measured_field_id,
start_date,
end_date))
records = self._cr.dictfetchall()
magnitude = 0
total = records[0].get('value')
while abs(total) >= 1000:
magnitude += 1
total /= 1000.0
val = '%.2f%s' % (
total, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])
records[0]['value'] = val
vals.update(records[0])
block_id.append(vals)
return block_id
def get_save_layout(self, grid_data_list):
"""Function fetch edited values while edit layout of the chart or tile
and save values in a database"""
for data in grid_data_list:
block = self.browse(int(data['id']))
if data.get('data-x'):
block.write({
'translate_x': f"{data['data-x']}px",
'translate_y': f"{data['data-y']}px",
'data_x': data['data-x'],
'data_y': data['data-y'],
})
if data.get('height'):
block.write({
'height': f"{data['height']}px",
'width': f"{data['width']}px",
})
return True