@ -0,0 +1,45 @@ |
|||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
|||
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
Odoo Dynamic Dashboard |
|||
========================== |
|||
* Dynamically Arrange the dashboard to get the information that are relevant to your business, department, or a specific process or need. |
|||
|
|||
Configuration |
|||
============= |
|||
- No configuration needed |
|||
|
|||
License |
|||
======= |
|||
Affero General Public License v3.0 (AGPL v3) |
|||
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
Credits |
|||
------- |
|||
* Developers: (V18) Bhagyadev KP, |
|||
* Contact: odoo@cybrosys.com |
|||
|
|||
Contacts |
|||
-------- |
|||
* Mail Contact : odoo@cybrosys.com |
|||
* Website : http://www.cybrosys.com |
|||
|
|||
Bug Tracker |
|||
----------- |
|||
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
|||
|
|||
Maintainer |
|||
========== |
|||
.. image:: https://cybrosys.com/images/logo.png |
|||
:target: https://cybrosys.com |
|||
This module is maintained by Cybrosys Technologies. |
|||
For support and more information, please visit https://www.cybrosys.com |
|||
|
|||
Further information |
|||
=================== |
|||
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,24 @@ |
|||
# -*- 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 . import controllers |
|||
from . import models |
|||
from . import wizard |
@ -0,0 +1,63 @@ |
|||
# -*- 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/>. |
|||
# |
|||
################################################################################ |
|||
{ |
|||
'name': "Odoo Dynamic Dashboard", |
|||
'version': '18.0.1.0.0', |
|||
'category': 'Productivity', |
|||
'summary': """Create Configurable Dashboards Easily""", |
|||
'description': """Create Configurable Odoo Dynamic Dashboard to get the |
|||
information that are relevant to your business, department, or a specific |
|||
process or need""", |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'company': 'Cybrosys Techno Solutions', |
|||
'maintainer': 'Cybrosys Techno Solutions', |
|||
'website': "https://www.cybrosys.com", |
|||
'depends': ['web'], |
|||
'data': [ |
|||
'security/ir.model.access.csv', |
|||
'data/dashboard_theme_data.xml', |
|||
'views/dashboard_views.xml', |
|||
'views/dynamic_block_views.xml', |
|||
'views/dashboard_menu_views.xml', |
|||
'views/dashboard_theme_views.xml', |
|||
'wizard/dashboard_mail_views.xml', |
|||
], |
|||
'assets': { |
|||
'web.assets_backend': [ |
|||
'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js', |
|||
'odoo_dynamic_dashboard/static/src/css/**/*.css', |
|||
'odoo_dynamic_dashboard/static/src/scss/**/*.scss', |
|||
'odoo_dynamic_dashboard/static/src/js/**/*.js', |
|||
'odoo_dynamic_dashboard/static/src/xml/**/*.xml', |
|||
'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css', |
|||
'odoo_dynamic_dashboard/static/lib/js/interactjs.js', |
|||
], |
|||
}, |
|||
'images': ['static/description/banner.gif'], |
|||
'license': "AGPL-3", |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': True, |
|||
} |
|||
|
|||
|
|||
|
@ -0,0 +1,22 @@ |
|||
# -*- 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 . import odoo_dynamic_dashboard |
@ -0,0 +1,34 @@ |
|||
# -*- 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 odoo import http |
|||
from odoo.http import request |
|||
|
|||
|
|||
class DynamicDashboard(http.Controller): |
|||
"""Class to search and filter values in dashboard""" |
|||
|
|||
@http.route('/custom_dashboard/search_input_chart', type='json', |
|||
auth="public", website=True) |
|||
def dashboard_search_input_chart(self, search_input): |
|||
"""Function to filter search input in dashboard""" |
|||
return request.env['dashboard.block'].search([ |
|||
('name', 'ilike', search_input)]).ids |
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<data> |
|||
<!-- Demo Dashboard Theme --> |
|||
<record id="demo_theme" model="dashboard.theme"> |
|||
<field name="name">Demo</field> |
|||
<field name="color_x">#4158D0</field> |
|||
<field name="color_y">#C850C0</field> |
|||
<field name="color_z">#FFCC70</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,6 @@ |
|||
## Module <odoo_dynamic_dashboard> |
|||
|
|||
#### 15.10.2024 |
|||
#### Version 18.0.1.0.0 |
|||
##### ADD |
|||
- Initial commit for Odoo Dynamic Dashboard |
@ -0,0 +1,25 @@ |
|||
# -*- 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 . import dashboard_block |
|||
from . import dashboard_menu |
|||
from . import dashboard_theme |
|||
from . import domain_to_sql |
@ -0,0 +1,181 @@ |
|||
# -*- 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 |
@ -0,0 +1,80 @@ |
|||
# -*- 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 odoo import api, fields, models |
|||
|
|||
|
|||
class DashboardMenu(models.Model): |
|||
"""Class to create new dashboard menu""" |
|||
_name = "dashboard.menu" |
|||
_description = "Dashboard Menu" |
|||
|
|||
name = fields.Char(string="Name", ondelete='cascade', |
|||
help="Enter a name for the dashboard menu") |
|||
menu_id = fields.Many2one('ir.ui.menu', string="Parent Menu", |
|||
help="Parent Menu Location of New Dashboard", |
|||
ondelete='cascade') |
|||
group_ids = fields.Many2many('res.groups', string='Groups', |
|||
related='menu_id.groups_id', |
|||
help="User need to be at least in one of " |
|||
"these groups to see the menu") |
|||
client_action_id = fields.Many2one('ir.actions.client', |
|||
string="Client Action", |
|||
help="Client action of the " |
|||
"corresponding dashboard menu") |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
"""Function to create new dashboard menu""" |
|||
action_id = self.env['ir.actions.client'].create([{ |
|||
'name': vals['name'], |
|||
'tag': 'OdooDynamicDashboard', |
|||
}]) |
|||
vals['client_action_id'] = action_id.id |
|||
self.env['ir.ui.menu'].create([{ |
|||
'name': vals['name'], |
|||
'parent_id': vals['menu_id'], |
|||
'action': 'ir.actions.client,%d' % (action_id.id,) |
|||
}]) |
|||
return super(DashboardMenu, self).create(vals) |
|||
|
|||
def write(self, vals): |
|||
"""Function to save edited data in dashboard menu""" |
|||
for rec in self: |
|||
client_act_id = rec['client_action_id'].id |
|||
self.env['ir.ui.menu'].search( |
|||
[('parent_id', '=', rec['menu_id'].id), |
|||
('action', '=', f'ir.actions.client,{client_act_id}')]).write({ |
|||
'name': vals['name'] if 'name' in vals.keys() else rec['name'], |
|||
'parent_id': vals['menu_id'] if 'menu_id' in vals.keys() else |
|||
rec['menu_id'], |
|||
'action': f'ir.actions.client,{client_act_id}' |
|||
}) |
|||
return super(DashboardMenu, self).write(vals) |
|||
|
|||
def unlink(self): |
|||
"""Delete dashboard along with menu item""" |
|||
for rec in self: |
|||
self.env['ir.ui.menu'].search( |
|||
[('parent_id', '=', rec['menu_id'].id), |
|||
('action', '=', |
|||
f'ir.actions.client,{rec["client_action_id"].id}')]).unlink() |
|||
return super(DashboardMenu, self).unlink() |
@ -0,0 +1,53 @@ |
|||
# -*- 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 odoo import api, fields, models |
|||
|
|||
|
|||
class DashboardTheme(models.Model): |
|||
_name = 'dashboard.theme' |
|||
_description = 'Dashboard Theme' |
|||
|
|||
name = fields.Char(string='Theme Name', help='Name of the theme') |
|||
color_x = fields.Char(string='Color X', help='Select the color_x for theme', |
|||
default='#4158D0') |
|||
color_y = fields.Char(string='Color Y', help='Select the color_y for theme', |
|||
default='#C850C0') |
|||
color_z = fields.Char(string='Color Z', help='Select the color_z for theme', |
|||
default='#FFCC70') |
|||
body = fields.Html(string='Body', help='Preview of the theme will be shown') |
|||
style = fields.Char(string='Style', |
|||
help='It store the style of the gradient') |
|||
|
|||
@api.constrains('name', 'color_x', 'color_y', 'color_z') |
|||
def save_record(self): |
|||
""" |
|||
Function for saving the datas including body and style |
|||
""" |
|||
self.body = f"<div style='width:300px; height:300px;background-image: linear-gradient(50deg, {self.color_x} 0%, {self.color_y} 46%, {self.color_z} 100%);'/>" |
|||
self.style = f"background-image: linear-gradient(50deg, {self.color_x} 0%, {self.color_y} 46%, {self.color_z} 100%);" |
|||
|
|||
def get_records(self): |
|||
""" |
|||
Function for returning all records with fields name and style |
|||
""" |
|||
records = self.search_read([], ['name', 'style']) |
|||
return records |
@ -0,0 +1,72 @@ |
|||
# -*- 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 odoo import models |
|||
|
|||
|
|||
def get_query(self, args, operation, field, start_date=None, end_date=None, |
|||
group_by=False, apply_ir_rules=False): |
|||
""" Dashboard block Query Creation """ |
|||
query = self._where_calc(args) |
|||
if apply_ir_rules: |
|||
self._apply_ir_rules(query, 'read') |
|||
if operation and field: |
|||
data = 'COALESCE(%s("%s".%s),0) AS value' % ( |
|||
operation.upper(), self._table, field.name) |
|||
join = '' |
|||
group_by_str = '' |
|||
if group_by: |
|||
if group_by.ttype == 'many2one': |
|||
relation_model = group_by.relation.replace('.', '_') |
|||
join = ' INNER JOIN %s on "%s".id = "%s".%s' % ( |
|||
relation_model, relation_model, self._table, group_by.name) |
|||
rec_name = self.env[group_by.relation]._rec_name_fallback() |
|||
data = data + ',"%s".%s AS %s' % ( |
|||
relation_model, rec_name, group_by.name) |
|||
group_by_str = ' Group by "%s".%s' % (relation_model, rec_name) |
|||
else: |
|||
data = data + ',"%s".%s' % (self._table, group_by.name) |
|||
group_by_str = ' Group by "%s".%s' % ( |
|||
self._table, str(group_by.name)) |
|||
else: |
|||
data = '"%s".id' % (self._table) |
|||
from_clause, from_params = query.from_clause |
|||
where_clause, where_clause_params = query.where_clause |
|||
where_str = where_clause and (" WHERE %s" % where_clause) or '' |
|||
if start_date and start_date != 'null': |
|||
start_date_query = f' AND ({from_clause}."create_date" >= \'{start_date}\')' |
|||
else: |
|||
start_date_query = '' |
|||
if end_date and end_date != 'null': |
|||
end_date_query = f' AND ({from_clause}."create_date" <= \'{end_date}\')' |
|||
else: |
|||
end_date_query = '' |
|||
query_str = 'SELECT %s FROM ' % data + from_clause + join + where_str + start_date_query + end_date_query + group_by_str |
|||
def format_param(x): |
|||
if not isinstance(x, tuple): |
|||
return "'" + str(x) + "'" |
|||
elif isinstance(x, tuple) and len(x) == 1: |
|||
return "(" + str(x[0]) + ")" |
|||
else: |
|||
return str(x) |
|||
exact_query = query_str % tuple(map(format_param, where_clause_params)) |
|||
return exact_query |
|||
models.BaseModel.get_query = get_query |
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 172 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 171 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 581 KiB |
After Width: | Height: | Size: 188 KiB |
After Width: | Height: | Size: 43 KiB |