Browse Source

Jul 25 : [UPDT] Updated 'inventory_stock_dashboard_odoo'

pull/267/head
AjmalCybro 2 years ago
parent
commit
6de4ffad6f
  1. 25
      inventory_stock_dashboard_odoo/README.rst
  2. 1
      inventory_stock_dashboard_odoo/__init__.py
  3. 12
      inventory_stock_dashboard_odoo/__manifest__.py
  4. 7
      inventory_stock_dashboard_odoo/doc/RELEASE_NOTES.md
  5. 11
      inventory_stock_dashboard_odoo/models/__init__.py
  6. 52
      inventory_stock_dashboard_odoo/models/res_config_settings.py
  7. 37
      inventory_stock_dashboard_odoo/models/res_config_settings_inherit.py
  8. 2
      inventory_stock_dashboard_odoo/models/stock_move.py
  9. 2
      inventory_stock_dashboard_odoo/models/stock_move_line.py
  10. 2
      inventory_stock_dashboard_odoo/models/stock_picking.py
  11. 2
      inventory_stock_dashboard_odoo/models/stock_quant.py
  12. 187
      inventory_stock_dashboard_odoo/static/src/css/dashboard.css
  13. 62
      inventory_stock_dashboard_odoo/static/src/js/dashboard.js
  14. 356
      inventory_stock_dashboard_odoo/static/src/xml/dashboard.xml
  15. 9
      inventory_stock_dashboard_odoo/views/dashboard_menus.xml
  16. 54
      inventory_stock_dashboard_odoo/views/res_config_settings_inherit.xml
  17. 53
      inventory_stock_dashboard_odoo/views/res_config_settings_views.xml

25
inventory_stock_dashboard_odoo/README.rst

@ -1,28 +1,33 @@
.. image:: https://img.shields.io/badge/licence-LGPL--3-green.svg
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
Inventory Dashboard Inventory Dashboard
=================== ===================
* Inventory Dashboard module for Odoo 16. * Inventory Dashboard module for Odoo 16.
Installation Installation
============ ============
- www.odoo.com/documentation/16.0/setup/install.html - www.odoo.com/documentation/16.0/setup/install.html
- Install our custom addon - Install our custom addon
License Company
------- -------
General Public License, Version 3 (LGPL v3). * `Cybrosys Techno Solutions <https://cybrosys.com/>`__
(https://www.odoo.com/documentation/user/15.0/legal/licenses/licenses.html)
Company License
------- -------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>'__ General Public License, Version 3 (LGPL v3).
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html)
Credits Credits
------- -------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>'__ * `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Contacts Contacts
-------- --------
* Mail Contact : odoo@cybrosys.com * Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Bug Tracker Bug Tracker
----------- -----------
@ -30,6 +35,9 @@ Bugs are tracked on GitHub Issues. In case of trouble, please check there if you
Maintainer Maintainer
========== ==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies. This module is maintained by Cybrosys Technologies.
For support and more information, please visit https://www.cybrosys.com For support and more information, please visit https://www.cybrosys.com
@ -37,4 +45,3 @@ For support and more information, please visit https://www.cybrosys.com
Further information Further information
=================== ===================
HTML Description: `<static/description/index.html>`__ HTML Description: `<static/description/index.html>`__

1
inventory_stock_dashboard_odoo/__init__.py

@ -19,5 +19,4 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from . import models from . import models

12
inventory_stock_dashboard_odoo/__manifest__.py

@ -21,18 +21,18 @@
############################################################################# #############################################################################
{ {
'name': 'Inventory Dashboard Odoo 16', 'name': 'Inventory Dashboard Odoo 16',
'version': '16.0.1.0.0', 'version': '16.0.1.0.1',
'summary': 'Inventory Dashboard',
'description': """ Detailed Dashboard View For Inventory""",
'category': 'Inventory', 'category': 'Inventory',
'summary': 'Inventory Dashboard',
'description': "Detailed Dashboard View For Inventory",
'author': 'Cybrosys Techno Solutions', 'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions', 'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions', 'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com", 'website': "https://www.cybrosys.com",
'depends': ['stock', 'base'], 'depends': ['stock', 'base'],
'data': ['views/style.xml', 'data': ['views/style.xml',
'views/dashboard_menu.xml', 'views/dashboard_menus.xml',
'views/res_config_settings_inherit.xml', 'views/res_config_settings_views.xml',
], ],
'assets': { 'assets': {
'web.assets_backend': [ 'web.assets_backend': [
@ -45,6 +45,6 @@
'license': 'LGPL-3', 'license': 'LGPL-3',
'images': ['static/description/banner.png'], 'images': ['static/description/banner.png'],
'installable': True, 'installable': True,
'application': True,
'auto_install': False, 'auto_install': False,
'application': True,
} }

7
inventory_stock_dashboard_odoo/doc/RELEASE_NOTES.md

@ -2,5 +2,10 @@
#### 24.05.2022 #### 24.05.2022
#### Version 16.0.1.0.0 #### Version 16.0.1.0.0
#### ADD ##### ADD
- Initial commit for Inventory Dashboard Module - Initial commit for Inventory Dashboard Module
#### 24.07.2023
#### Version 16.0.1.0.1
##### FIX
- The font size reduction problem when installing this module has been fixed.

11
inventory_stock_dashboard_odoo/models/__init__.py

@ -20,9 +20,8 @@
# #
############################################################################# #############################################################################
from . import stock_move_inherit from . import res_config_settings
from . import stock_picking_inherit from . import stock_move
from . import res_config_settings_inherit from . import stock_move_line
from . import stock_quant_inherit from . import stock_picking
from . import stock_move_line_inherit from . import stock_quant

52
inventory_stock_dashboard_odoo/models/res_config_settings.py

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-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 odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
out_of_stock = fields.Boolean(string="Out of stock",
config_parameter='inventory_stock_dashboard_odoo.out_of_stock',
help="Enable if out of stock")
out_of_stock_quantity = fields.Integer(string="Quantity",
config_parameter='inventory_stock_dashboard_odoo.out_of_stock_quantity',
required=True,
help="Set the minimum quantity for "
"considering a product as out "
"of stock.")
dead_stock_bol = fields.Boolean(string="Enable dead stock",
config_parameter='inventory_stock_dashboard_odoo.dead_stock_bol',
help="Enable if you want to consider dead "
"stock.")
dead_stock = fields.Integer(string="Dead stock",
config_parameter='inventory_stock_dashboard_odoo.dead_stock',
required=True,
help="Set the threshold quantity for "
"considering a product as dead stock.")
dead_stock_type = fields.Selection(
[('day', 'Day'), ('week', 'Week'), ('month', 'Month')],
string="Type", default='day',
config_parameter='inventory_stock_dashboard_odoo.dead_stock_type',
required=True,
help="Select the time period to determine dead stock based on product "
"sales.")

37
inventory_stock_dashboard_odoo/models/res_config_settings_inherit.py

@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-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 odoo import fields, models
class ResConfiqSettingInherit(models.TransientModel):
_inherit = "res.config.settings"
out_of_stock = fields.Boolean(config_parameter='inventory_stock_dashboard_odoo.out_of_stock')
out_of_stock_quantity = fields.Integer(string="Quantity",
config_parameter='inventory_stock_dashboard_odoo.out_of_stock_quantity',
required=True)
dead_stock_bol = fields.Boolean(string="Dead Stock",
config_parameter='inventory_stock_dashboard_odoo.dead_stock_bol')
dead_stock = fields.Integer(config_parameter='inventory_stock_dashboard_odoo.dead_stock', required=True)
dead_stock_type = fields.Selection([('day', 'Day'), ('week', 'Week'), ('month', 'Month')],
string="Type", default='day',
config_parameter='inventory_stock_dashboard_odoo.dead_stock_type', required=True)

2
inventory_stock_dashboard_odoo/models/stock_move_inherit.py → inventory_stock_dashboard_odoo/models/stock_move.py

@ -23,7 +23,7 @@
from odoo import api, models from odoo import api, models
class StockMoveInherit(models.Model): class StockMove(models.Model):
_inherit = "stock.move" _inherit = "stock.move"
@api.model @api.model

2
inventory_stock_dashboard_odoo/models/stock_move_line_inherit.py → inventory_stock_dashboard_odoo/models/stock_move_line.py

@ -23,7 +23,7 @@
from odoo import api, models from odoo import api, models
class StockMoveLineInherit(models.Model): class StockMoveLine(models.Model):
_inherit = "stock.move.line" _inherit = "stock.move.line"
@api.model @api.model

2
inventory_stock_dashboard_odoo/models/stock_picking_inherit.py → inventory_stock_dashboard_odoo/models/stock_picking.py

@ -23,7 +23,7 @@
from odoo import api, models from odoo import api, models
class StockPickingInherit(models.Model): class StockPicking(models.Model):
_inherit = "stock.picking" _inherit = "stock.picking"
@api.model @api.model

2
inventory_stock_dashboard_odoo/models/stock_quant_inherit.py → inventory_stock_dashboard_odoo/models/stock_quant.py

@ -23,7 +23,7 @@
from odoo import api, models from odoo import api, models
class StockQuantInherit(models.Model): class StockQuant(models.Model):
_inherit = "stock.quant" _inherit = "stock.quant"
@api.model @api.model

187
inventory_stock_dashboard_odoo/static/src/css/dashboard.css

@ -1,14 +1,10 @@
.item-container { .item-container {
background-image: -webkit-linear-gradient(white, white); background-image: -webkit-linear-gradient(white, white);
} }
.item-header { .item-header {
padding-left: 30px; padding-left: 30px;
background-image: -webkit-linear-gradient(white, #c3c9d4); background-image: -webkit-linear-gradient(white, #c3c9d4);
} }
.col-sm, .col-sm,
.col-sm-1, .col-sm-1,
.col-sm-10, .col-sm-10,
@ -19,11 +15,9 @@
.col-sm-4, .col-sm-4,
.col-xl-auto { .col-xl-auto {
position: relative; position: relative;
padding-right: 7.5px; padding-right: 7.5px;
padding-left: 7.5px; padding-left: 7.5px;
} }
#location_table thead th { #location_table thead th {
border-bottom: none; border-bottom: none;
background-color: #67b7dc; background-color: #67b7dc;
@ -31,7 +25,6 @@
width: 250px; width: 250px;
height: 30px; height: 30px;
} }
.accounts-dashboard-wrap .card-header { .accounts-dashboard-wrap .card-header {
background-color: background-color:
transparent; transparent;
@ -41,8 +34,6 @@
border-top-left-radius: .25rem; border-top-left-radius: .25rem;
border-top-right-radius: .25rem; border-top-right-radius: .25rem;
} }
.accounts-dashboard-wrap .fa:hover { .accounts-dashboard-wrap .fa:hover {
-ms-transform: scale(1.5); -ms-transform: scale(1.5);
/* IE 9 */ /* IE 9 */
@ -50,36 +41,28 @@
/* Safari 3-8 */ /* Safari 3-8 */
transform: scale(1.5); transform: scale(1.5);
} }
.accounts-dashboard-wrap .card-header>.card-tools { .accounts-dashboard-wrap .card-header>.card-tools {
float: right; float: right;
margin-right: -.625rem; margin-right: -.625rem;
} }
.right { .right {
float: left; float: left;
} }
.accounts-dashboard-wrap .tooltip:hover .tooltiptext { .accounts-dashboard-wrap .tooltip:hover .tooltiptext {
visibility: visible; visibility: visible;
} }
.accounts-dashboard-wrap .col-6 { .accounts-dashboard-wrap .col-6 {
-ms-flex: 0 0 50%; -ms-flex: 0 0 50%;
flex: 0 0 50%; flex: 0 0 50%;
max-width: 50%; max-width: 50%;
} }
.accounts-dashboard-wrap .fa-cog { .accounts-dashboard-wrap .fa-cog {
content: "\f013" content: "\f013"
} }
.accounts-dashboard-wrap .fa, .accounts-dashboard-wrap .fa,
.fas { .accounts-dashboard-wrap .fas {
font-weight: 900; font-weight: 900;
} }
.accounts-dashboard-wrap .fa, .accounts-dashboard-wrap .fa,
.accounts-dashboard-wrap .fab, .accounts-dashboard-wrap .fab,
.accounts-dashboard-wrap .fad, .accounts-dashboard-wrap .fad,
@ -94,7 +77,6 @@
text-rendering: auto; text-rendering: auto;
line-height: 1; line-height: 1;
} }
.accounts-dashboard-wrap .info-box .info-box-icon { .accounts-dashboard-wrap .info-box .info-box-icon {
border-radius: .25rem; border-radius: .25rem;
@ -108,10 +90,7 @@
text-align: center; text-align: center;
width: 70px; width: 70px;
} }
.accounts-dashboard-wrap .info-box { .accounts-dashboard-wrap .info-box {
box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2); box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);
border-radius: .25rem; border-radius: .25rem;
background: #fff; background: #fff;
@ -122,64 +101,50 @@
padding: .5rem; padding: .5rem;
position: relative; position: relative;
} }
.accounts-dashboard-wrap .o_datepicker .o_datepicker_input { .accounts-dashboard-wrap .o_datepicker .o_datepicker_input {
width: 100%; width: 100%;
cursor: pointer; cursor: pointer;
} }
.accounts-dashboard-wrap #overdue { .accounts-dashboard-wrap #overdue {
width: 100%; width: 100%;
cursor: pointer; cursor: pointer;
} }
.accounts-dashboard-wrap .o_input { .accounts-dashboard-wrap .o_input {
border: 1px solid #cfcfcf; border: 1px solid #cfcfcf;
border-top-style: none; border-top-style: none;
border-right-style: none; border-right-style: none;
border-left-style: none; border-left-style: none;
} }
.accounts-dashboard-wrap .in_graph { .accounts-dashboard-wrap .in_graph {
padding-left: 90px; padding-left: 90px;
height: auto; height: auto;
padding-bottom: 65px; padding-bottom: 65px;
text-align: center !important; text-align: center !important;
} }
.accounts-dashboard-wrap .oh_dashboards { .accounts-dashboard-wrap .oh_dashboards {
padding-top: 15px; padding-top: 15px;
background-color: #f8faff !important; background-color: #f8faff !important;
} }
.accounts-dashboard-wrap .container-fluid.o_in_dashboard { .accounts-dashboard-wrap .container-fluid.o_in_dashboard {
padding: 0px !important; padding: 0px !important;
} }
.accounts-dashboard-wrap .o_action_manager { .accounts-dashboard-wrap .o_action_manager {
overflow-y: scroll !important; overflow-y: scroll !important;
max-width: 100%; max-width: 100%;
} }
// new tile // new tile
body { .oh_dashboards {
background-color: #ececec; background-color: #ececec;
} }
.accounts-dashboard-wrap .container { .accounts-dashboard-wrap .container {
margin: 50px 0 0 100px; margin: 50px 0 0 100px;
} }
.accounts-dashboard-wrap .o_dashboards { .accounts-dashboard-wrap .o_dashboards {
color: #2a2a2a; color: #2a2a2a;
background-color: #f2f2f2 !important; background-color: #f2f2f2 !important;
} }
.accounts-dashboard-wrap .dash-header { .accounts-dashboard-wrap .dash-header {
margin: 15px 0px 12px 0 !important; margin: 15px 0px 12px 0 !important;
display: block; display: block;
padding: 7px 25px 7px 0; padding: 7px 25px 7px 0;
@ -195,24 +160,17 @@ body {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.accounts-dashboard-wrap .dashboard-h1 { .accounts-dashboard-wrap .dashboard-h1 {
display: block; display: block;
padding: 7px 25px 7px 0; padding: 7px 25px 7px 0;
color: #0e1319; color: #0e1319;
font-size: 2rem; font-size: 2rem;
font-weight: 400; font-weight: 400;
color: color: #212529;
#212529;
float: left; float: left;
margin-bottom: 0; margin-bottom: 0;
} }
.accounts-dashboard-wrap .card { .accounts-dashboard-wrap .card {
position: relative !important; position: relative !important;
border-top: 0 !important; border-top: 0 !important;
@ -230,19 +188,16 @@ body {
box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.05) !important; box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.05) !important;
border-radius: 0.25rem; border-radius: 0.25rem;
} }
.accounts-dashboard-wrap .card-header { .accounts-dashboard-wrap .card-header {
border: 0; border: 0;
padding: 0; padding: 0;
} }
.accounts-dashboard-wrap .card-header>.card-tools { .accounts-dashboard-wrap .card-header>.card-tools {
float: right; float: right;
margin-right: 0.375rem; margin-right: 0.375rem;
margin-top: 5px; margin-top: 5px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.accounts-dashboard-wrap .card-header i.fa { .accounts-dashboard-wrap .card-header i.fa {
font-size: 1.3rem; font-size: 1.3rem;
display: inline-block; display: inline-block;
@ -253,7 +208,6 @@ body {
-webkit-transition: 0.3s linear; -webkit-transition: 0.3s linear;
transition: 0.3s linear; transition: 0.3s linear;
} }
.accounts-dashboard-wrap .dropdown-toggle::after { .accounts-dashboard-wrap .dropdown-toggle::after {
display: inline-block; display: inline-block;
margin-left: 0.255em; margin-left: 0.255em;
@ -265,12 +219,9 @@ body {
border-left: 0.3em solid transparent; border-left: 0.3em solid transparent;
color: #7891af; color: #7891af;
} }
.accounts-dashboard-wrap .account-details { .accounts-dashboard-wrap .account-details {
display: flex; display: flex;
} }
.main-title { .main-title {
color: #a3a3a3; color: #a3a3a3;
display: block; display: block;
@ -278,7 +229,6 @@ body {
font-size: 20px; font-size: 20px;
font-weight: 400; font-weight: 400;
} }
.accounts-dashboard-wrap .main-title { .accounts-dashboard-wrap .main-title {
display: block; display: block;
margin-bottom: 5px; margin-bottom: 5px;
@ -291,13 +241,11 @@ body {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
.accounts-dashboard-wrap .card-body { .accounts-dashboard-wrap .card-body {
background-color: rgba(255, 255, 255, 0.9) !important; background-color: rgba(255, 255, 255, 0.9) !important;
color: #212529; color: #212529;
padding-top: 0; padding-top: 0;
} }
.accounts-dashboard-wrap .tile.wide.invoice { .accounts-dashboard-wrap .tile.wide.invoice {
margin-bottom: 27px; margin-bottom: 27px;
-webkit-box-shadow: 1px 5px 24px 0 rgba(68, 102, 242, 0.05); -webkit-box-shadow: 1px 5px 24px 0 rgba(68, 102, 242, 0.05);
@ -310,33 +258,25 @@ body {
border: 1px solid rgba(0, 0, 0, 0.07); border: 1px solid rgba(0, 0, 0, 0.07);
height: 140px; height: 140px;
} }
.accounts-dashboard-wrap .box-1 .main-title { .accounts-dashboard-wrap .box-1 .main-title {
background: #67b7dc; background: #67b7dc;
color: #fff; color: #fff;
} }
.accounts-dashboard-wrap .box-2 .main-title { .accounts-dashboard-wrap .box-2 .main-title {
background: #6794dc !important; background: #6794dc !important;
color: #fff; color: #fff;
} }
.accounts-dashboard-wrap .box-3 .main-title { .accounts-dashboard-wrap .box-3 .main-title {
background: #8067dc; background: #8067dc;
color: #fff; color: #fff;
} }
.accounts-dashboard-wrap .box-4 .main-title { .accounts-dashboard-wrap .box-4 .main-title {
background: #c767dc; background: #c767dc;
color: #fff; color: #fff;
} }
.accounts-dashboard-wrap .count { .accounts-dashboard-wrap .count {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.accounts-dashboard-wrap .main-title~div { .accounts-dashboard-wrap .main-title~div {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -344,14 +284,10 @@ body {
padding: 1rem; padding: 1rem;
background: #fff; background: #fff;
} }
#location_table { #location_table {
background-color: #fff; background-color: #fff;
color: (--mauve); color: (--mauve);
} }
#tile_main_div:hover { #tile_main_div:hover {
border-top-left-radius: 10px; border-top-left-radius: 10px;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
@ -360,7 +296,6 @@ body {
border-left: 8px solid var(--mauve); border-left: 8px solid var(--mauve);
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
} }
#tiles:hover { #tiles:hover {
border-top-left-radius: 10px; border-top-left-radius: 10px;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
@ -368,45 +303,34 @@ body {
animation-duration: 0.25s; animation-duration: 0.25s;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
} }
.details_table{ .details_table{
align-content: left; align-content: left;
} }
.graph_details_table{ .graph_details_table{
position: absolute; position: absolute;
top: 45px; top: 45px;
right: 15px; right: 15px;
background-color: white; background-color: white;
border-collapse: collapse; border-collapse: collapse;
border: 1px solid #ddd; border: 1px solid #ddd;
} }
.graph_details_table th{ .graph_details_table th{
background-color:#67b7dc; background-color:#67b7dc;
color: white; color: white;
width: 250px; width: 250px;
height: 30px; height: 30px;
} }
.graph_details_table td{ .graph_details_table td{
border: 1px solid #ddd; border: 1px solid #ddd;
height: 20px; height: 20px;
} }
.graph_details_table tr:nth-child(even){background-color: #f2f2f2;} .graph_details_table tr:nth-child(even){background-color: #f2f2f2;}
.graph_details_table tr:hover {background-color: #ddd;} .graph_details_table tr:hover {background-color: #ddd;}
#product_moves_selection{ #product_moves_selection{
position: relative; position: relative;
right: 10px; right: 10px;
top: 5px; top: 5px;
} }
:root { :root {
/* Primary */ /* Primary */
--mauve: #7D7EAF; --mauve: #7D7EAF;
@ -431,67 +355,51 @@ height: 20px;
--grey-lighter: #fafafa; --grey-lighter: #fafafa;
--grey-dark-lighter: #f3f3f3; --grey-dark-lighter: #f3f3f3;
} }
/* Background */ /* Background */
.bg-mauve-light { .bg-mauve-light {
background-color: var(--mauve-light); background-color: var(--mauve-light);
} }
.bg-pink-dark-light { .bg-pink-dark-light {
background-color: var(--pink-dark-light); background-color: var(--pink-dark-light);
} }
.bg-pink-light { .bg-pink-light {
background-color: var(--pink-light); background-color: var(--pink-light);
} }
.bg-peach-light { .bg-peach-light {
background-color: var(--peach-light); background-color: var(--peach-light);
} }
.bg-orange-light { .bg-orange-light {
background-color: var(--orange-light); background-color: var(--orange-light);
} }
.bg-gold-light { .bg-gold-light {
background-color: var(--gold-light); background-color: var(--gold-light);
} }
.bg-green-light { .bg-green-light {
background-color: var(--green-light); background-color: var(--green-light);
} }
/* Text */ /* Text */
.text-mauve { .text-mauve {
color: var(--mauve); color: var(--mauve);
} }
.text-pink-dark { .text-pink-dark {
color: var(--pink-dark); color: var(--pink-dark);
} }
.text-pink { .text-pink {
color: var(--pink); color: var(--pink);
} }
.text-peach { .text-peach {
color: var(--peach); color: var(--peach);
} }
.text-orange { .text-orange {
color: var(--orange); color: var(--orange);
} }
.text-gold { .text-gold {
color: var(--gold); color: var(--gold);
} }
.text-green { .text-green {
color: var(--green); color: var(--green);
} }
/* Cards */ /* Cards */
/*.dashboard-card { /*.dashboard-card {
border-radius: 0.3rem; border-radius: 0.3rem;
display: flex; display: flex;
@ -500,71 +408,58 @@ height: 20px;
margin: 1rem auto; margin: 1rem auto;
height: 90px; height: 90px;
}*/ }*/
.dashboard-card__icon-container { .dashboard-card__icon-container {
height: 50px; height: 50px;
width: 50px; width: 50px;
border-radius: 50%; border-radius: 50%;
} }
.dashboard-card__icon-container i { .dashboard-card__icon-container i {
font-size: 20px; font-size: 20px;
} }
.dashboard-card__details { .dashboard-card__details {
margin-left: 0rem !important; margin-left: 0rem !important;
max-width: 120px; max-width: 120px;
} }
.dashboard-card__details h3 { .dashboard-card__details h3 {
font-weight: 700; font-weight: 700;
font-size: 1.5rem; font-size: 1.5rem;
} }
.dashboard-card__details h4 { .dashboard-card__details h4 {
font-weight: 700; font-weight: 700;
font-size: 0.7rem; font-size: 0.7rem;
color: var(--grey); color: var(--grey);
margin-top: -5px; margin-top: -5px;
} }
h2.section-header { h2.section-header {
font-weight: 700; font-weight: 700;
font-size: 1.5rem; font-size: 1.5rem;
} }
.chart-container { .chart-container {
border-radius: 0.3rem; border-radius: 0.3rem;
padding: 1rem; padding: 1rem;
margin: 1rem auto; margin: 1rem auto;
} }
.chart-container.card-shadow { .chart-container.card-shadow {
height: 100%; height: 100%;
} }
.half_chart.chart-container.card-shadow { .half_chart.chart-container.card-shadow {
height: 49%; height: 49%;
} }
.chart-container h2 { .chart-container h2 {
font-weight: 700; font-weight: 700;
font-size: 1.125rem; font-size: 1.125rem;
} }
.item-container { .item-container {
background-color: var(--grey-lighter); background-color: var(--grey-lighter);
border-radius: 0.3rem; border-radius: 0.3rem;
padding: 1.2rem 1rem; padding: 1.2rem 1rem;
margin: 1rem auto; margin: 1rem auto;
} }
.item-container:hover { .item-container:hover {
background-color: var(--grey-dark-lighter); background-color: var(--grey-dark-lighter);
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
cursor: pointer; cursor: pointer;
} }
.count-container { .count-container {
font-weight: 700; font-weight: 700;
font-size: 2rem; font-size: 2rem;
@ -579,40 +474,33 @@ h2.section-header {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.item-header { .item-header {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
} }
.item-title h3 { .item-title h3 {
font-size: 1.3rem; font-size: 1.3rem;
font-weight: 700; font-weight: 700;
} }
.item-content ul { .item-content ul {
list-style: none; list-style: none;
padding-left: 0px; padding-left: 0px;
} }
.item-content ul>li { .item-content ul>li {
font-size: 0.9rem; font-size: 0.9rem;
color: var(--grey); color: var(--grey);
font-weight: 700; font-weight: 700;
} }
/* Misc */ /* Misc */
.card-shadow { .card-shadow {
-webkit-box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1); -webkit-box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1);
-moz-box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1); -moz-box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1);
box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1); box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1);
} }
.table td, .table td,
.table th { .table th {
border-top: 1px solid #eceff2; border-top: 1px solid #eceff2;
} }
.crm_scroll_table { .crm_scroll_table {
max-height: 395px; max-height: 395px;
overflow-y: auto; overflow-y: auto;
@ -620,12 +508,10 @@ h2.section-header {
.recent_activity_div .crm_scroll_table { .recent_activity_div .crm_scroll_table {
max-height: 435px; max-height: 435px;
} }
.crm_scroll_table thead { .crm_scroll_table thead {
position: sticky; position: sticky;
top: 0; top: 0;
} }
.dashboard-card__stat_late:hover { .dashboard-card__stat_late:hover {
border-bottom-color: darkgray; border-bottom-color: darkgray;
} }
@ -656,7 +542,6 @@ h2.section-header {
border: 1px solid #d2d4dd; border: 1px solid #d2d4dd;
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
} }
.btn_info { .btn_info {
position: absolute; position: absolute;
top: 18px; top: 18px;
@ -669,44 +554,33 @@ h2.section-header {
#top_product_selection { #top_product_selection {
position: absolute; position: absolute;
top: 18px; top: 18px;
} }
#top_product_button { #top_product_button {
position: absolute; position: absolute;
top: 1px; top: 1px;
right: 63px; right: 63px;
} }
#product_move_select { #product_move_select {
position: absolute; position: absolute;
top: 1px; top: 1px;
right: 63px; right: 63px;
} }
#product_move_selection { #product_move_selection {
position: absolute; position: absolute;
top: 18px; top: 18px;
} }
#stock_move_select { #stock_move_select {
position: absolute; position: absolute;
top: 1px; top: 1px;
right: 63px; right: 63px;
} }
#stock_moves_selection { #stock_moves_selection {
position: absolute; position: absolute;
top: 18px; top: 18px;
} }
.location_table_value{ .location_table_value{
text-align: center; text-align: center;
} }
/* X-Small devices (portrait phones, less than 576px)*/ /* X-Small devices (portrait phones, less than 576px)*/
@media (max-width: 575.98px) { @media (max-width: 575.98px) {
#top_product_selection{ #top_product_selection{
@ -722,7 +596,6 @@ text-align: center;
margin-left: -100%; margin-left: -100%;
} }
} }
.tile-container { .tile-container {
padding: 1rem; padding: 1rem;
display: flex; display: flex;
@ -735,108 +608,83 @@ text-align: center;
background-size: cover; background-size: cover;
background-position-x: right; background-position-x: right;
} }
.tile-container:hover { .tile-container:hover {
opacity: 0.9; opacity: 0.9;
cursor: pointer; cursor: pointer;
transition: all 0.4s ease-in-out; transition: all 0.4s ease-in-out;
} }
.title-container__icon-container { .title-container__icon-container {
padding: 1.3rem 1rem; padding: 1.3rem 1rem;
border-radius: 0.5rem; border-radius: 0.5rem;
} }
.title-container__icon { .title-container__icon {
font-size: 1.5rem; font-size: 1.5rem;
} }
.title-container__count { .title-container__count {
font-size: 1.6rem; font-size: 1.6rem;
font-weight: 600; font-weight: 600;
} }
.title-container__title { .title-container__title {
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
} }
/* Colors */ /* Colors */
.red-bkg { .red-bkg {
background-color: #FFE1E2; background-color: #FFE1E2;
} }
.red-font { .red-font {
color: #E8565E; color: #E8565E;
} }
.blue-bkg { .blue-bkg {
background-color: #C2D5FF; background-color: #C2D5FF;
} }
.blue-font { .blue-font {
color: #225AE3; color: #225AE3;
} }
.green-bkg { .green-bkg {
background-color: #BDE4E0; background-color: #BDE4E0;
} }
.green-font { .green-font {
color: #2CA79A; color: #2CA79A;
} }
.pink-bkg { .pink-bkg {
background-color: #FFE4EF; background-color: #FFE4EF;
} }
.pink-font { .pink-font {
color: #CE3372; color: #CE3372;
} }
.yellow-bkg { .yellow-bkg {
background-color: #F9ECC6; background-color: #F9ECC6;
} }
.yellow-font { .yellow-font {
color: #CBA846; color: #CBA846;
} }
.white-bkg { .white-bkg {
background-color: #FFFFFF; background-color: #FFFFFF;
} }
.white-font { .white-font {
color: #FFFFFF; color: #FFFFFF;
} }
/*Second Section CSS */ /*Second Section CSS */
.card-contianer__header { .card-contianer__header {
background-color: #37274B; background-color: #37274B;
padding: 0.4rem; padding: 0.4rem;
border-top: 3px solid #D84315; border-top: 3px solid #D84315;
} }
.card-container__content { .card-container__content {
padding: 1rem; padding: 1rem;
} }
.card-container__normal-header { .card-container__normal-header {
font-size: 1.2rem; font-size: 1.2rem;
color: #000000; color: #000000;
font-weight: 600; font-weight: 600;
} }
.card-container__header-text { .card-container__header-text {
font-size: 1.2rem; font-size: 1.2rem;
color: #FFFFFF; color: #FFFFFF;
font-weight: 400; font-weight: 400;
text-align: center; text-align: center;
} }
.dashboard-card { .dashboard-card {
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px; box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
padding: 1.5rem; padding: 1.5rem;
@ -846,19 +694,15 @@ text-align: center;
justify-content: space-between !important; justify-content: space-between !important;
align-items: flex-start !important; align-items: flex-start !important;
} }
.dashboard-card--border-top { .dashboard-card--border-top {
border-top: 5px solid #000; border-top: 5px solid #000;
} }
.dashboard-card--border-top-red { .dashboard-card--border-top-red {
border-color: #D32F2F; border-color: #D32F2F;
} }
.dashboard-card--border-top-blue { .dashboard-card--border-top-blue {
border-color: #2962FF; border-color: #2962FF;
} }
.dashboard-card--border-top-green { .dashboard-card--border-top-green {
border-color: #00FF00; border-color: #00FF00;
} }
@ -877,34 +721,28 @@ text-align: center;
.dashboard-card--border-top-black { .dashboard-card--border-top-black {
border-color: black; border-color: black;
} }
.dashboard-card--border-top-rebecca { .dashboard-card--border-top-rebecca {
border-color: #663399; border-color: #663399;
} }
.dashboard-card--border-top-steel { .dashboard-card--border-top-steel {
border-color: #607D8B; border-color: #607D8B;
} }
.dashboard-card--border-top-orange { .dashboard-card--border-top-orange {
border-color: #FFA500; border-color: #FFA500;
} }
.dashboard-card__title { .dashboard-card__title {
font-weight: bold; font-weight: bold;
display: block; display: block;
margin-top: 0.5rem; margin-top: 0.5rem;
} }
.dashboard-card__count { .dashboard-card__count {
font-size: 3rem; font-size: 3rem;
} }
.dashboard-card__stats { .dashboard-card__stats {
list-style: none; list-style: none;
padding-left: 0; padding-left: 0;
width: 50% width: 50%
} }
.dashboard-card__stat_late { .dashboard-card__stat_late {
padding: 0.5rem 0rem; padding: 0.5rem 0rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1);
@ -917,9 +755,6 @@ text-align: center;
padding: 0.5rem 0rem; padding: 0.5rem 0rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1);
} }
.dashboard-card__stat-count_late { .dashboard-card__stat-count_late {
min-width: 25px; min-width: 25px;
min-height: 20px; min-height: 20px;
@ -956,10 +791,7 @@ text-align: center;
align-items: center; align-items: center;
border-radius: 50%; border-radius: 50%;
} }
.oh_dashboards {
body{
background:#eee;
font-family: 'Raleway', sans-serif; font-family: 'Raleway', sans-serif;
} }
.main-part{ .main-part{
@ -1036,7 +868,6 @@ background-color:#803D9B;
background-color: #16A085; background-color: #16A085;
min-height: 120px; min-height: 120px;
} }
.col-lg-3:hover { .col-lg-3:hover {
-ms-transform: scale(1); -ms-transform: scale(1);
/* IE 9 */ /* IE 9 */

62
inventory_stock_dashboard_odoo/static/src/js/dashboard.js

@ -1,6 +1,5 @@
odoo.define("inventory_dashboard.dashboard", function (require) { odoo.define("inventory_dashboard.dashboard", function (require) {
"use strict"; "use strict";
var AbstractAction = require('web.AbstractAction'); var AbstractAction = require('web.AbstractAction');
var core = require('web.core'); var core = require('web.core');
var rpc = require('web.rpc'); var rpc = require('web.rpc');
@ -32,19 +31,16 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
'click #product_move_info': 'onclick_product_move_info', 'click #product_move_info': 'onclick_product_move_info',
'click #stock_move_info': 'onclick_stock_move_info', 'click #stock_move_info': 'onclick_stock_move_info',
}, },
init: function(parent, context) { init: function(parent, context) {
this._super(parent, context); this._super(parent, context);
this.dashboards_templates = ['InventoryTiles', 'ProductSaleBarGraph']; this.dashboards_templates = ['InventoryTiles', 'ProductSaleBarGraph'];
}, },
willStart: function() { willStart: function() {
var self = this; var self = this;
return $.when(this._super()).then(function() { return $.when(this._super()).then(function() {
return; return;
}); });
}, },
start: function() { start: function() {
var self = this; var self = this;
this.set("title", 'Dashboard'); this.set("title", 'Dashboard');
@ -54,7 +50,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
self.$el.parent().addClass('oe_background_grey'); self.$el.parent().addClass('oe_background_grey');
}); });
}, },
render_dashboards: function() { render_dashboards: function() {
var self = this; var self = this;
_.each(this.dashboards_templates, function(template) { _.each(this.dashboards_templates, function(template) {
@ -72,7 +67,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
self.render_out_of_stock_graph(); self.render_out_of_stock_graph();
self.render_dead_of_stock_graph(); self.render_dead_of_stock_graph();
}, },
// fetch data function-operation type tiles and graph include this function // fetch data function-operation type tiles and graph include this function
render_operation_tile: function() { render_operation_tile: function() {
var self = this; var self = this;
@ -92,13 +86,11 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
var result_1 = key; var result_1 = key;
result_2 = value; result_2 = value;
const colors = ["red", "blue","green","orange","purple","steel","rebecca","brown","pink","grey","black"]; const colors = ["red", "blue","green","orange","purple","steel","rebecca","brown","pink","grey","black"];
$('#set').append('<div class="col-sm-12 col-md-6 col-lg-3" id="' + result_1 + '"> $('#set').append('<div class="col-sm-12 col-md-6 col-lg-3" id="' + result_1 + '">
<div class="dashboard-card dashboard-card--border-top dashboard-card--border-top-' + colors[g] + '"> <div class="dashboard-card dashboard-card--border-top dashboard-card--border-top-' + colors[g] + '">
<div class="dashboard-card__details"><span class="dashboard-card__title">' + result[3][result_1] + '</span> <div class="dashboard-card__details"><span class="dashboard-card__title">' + result[3][result_1] + '</span>
<span class="count-container">' + result_2 + '</span></div> <ul class="dashboard-card__stats"></ul></div></div>'); <span class="count-container">' + result_2 + '</span></div> <ul class="dashboard-card__stats"></ul></div></div>');
g++; g++;
if (key in late) { if (key in late) {
$('#' + key + ' .dashboard-card__stats').append('<li class="dashboard-card__stat_late" id="' + result_1 + '"> $('#' + key + ' .dashboard-card__stats').append('<li class="dashboard-card__stat_late" id="' + result_1 + '">
<div class="d-flex justify-content-between align-items-center text-dark text-decoration-none"> <div class="d-flex justify-content-between align-items-center text-dark text-decoration-none">
@ -120,7 +112,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
var name = Object.values(result[3]) // Add data values to array var name = Object.values(result[3]) // Add data values to array
var count = Object.values(result[0]) var count = Object.values(result[0])
var j = 0; var j = 0;
for (var c in count) { for (var c in count) {
$('#operation_type_table').append('<tr><td>'+name[j]+'</td><td>'+count[c]+'</td></tr>') $('#operation_type_table').append('<tr><td>'+name[j]+'</td><td>'+count[c]+'</td></tr>')
j++; j++;
@ -144,7 +135,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -179,7 +169,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
}); });
}); });
}, },
// top ten bar graph // top ten bar graph
render_top_product_bar_graph:function(){ render_top_product_bar_graph:function(){
var self = this var self = this
@ -214,7 +203,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -228,7 +216,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
barPercentage: 0.5, barPercentage: 0.5,
barThickness: 6, barThickness: 6,
maxBarThickness: 8, maxBarThickness: 8,
@ -250,7 +237,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
}); });
}); });
}, },
// product categories doughnut graph // product categories doughnut graph
render_product_category:function(){ render_product_category:function(){
var self = this var self = this
@ -286,11 +272,9 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
], ],
barPercentage: 0.5, barPercentage: 0.5,
barThickness: 6, barThickness: 6,
@ -313,7 +297,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
}); });
}); });
}, },
// product move line graph // product move line graph
render_product_move_graph_this_month:function(){ render_product_move_graph_this_month:function(){
var self = this var self = this
@ -336,7 +319,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
$('#product_move_selection').append('<option id="'+key+'" value="'+category_id[k]+'">'+value+'</option>') $('#product_move_selection').append('<option id="'+key+'" value="'+category_id[k]+'">'+value+'</option>')
k++; k++;
} }
}); });
var opti = $(self.target).val(); var opti = $(self.target).val();
var option = $( "#product_move_selection" ).val(); var option = $( "#product_move_selection" ).val();
@ -383,12 +365,9 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height
} }
}); });
}); });
}); });
}, },
// stock moves pie graph // stock moves pie graph
render_stock_moves:function(){ render_stock_moves:function(){
rpc.query({ rpc.query({
@ -422,7 +401,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -457,7 +435,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
}); });
}); });
}, },
// location-on hand table // location-on hand table
render_storage_location:function(){ render_storage_location:function(){
var self = this var self = this
@ -471,7 +448,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
}); });
}); });
}, },
//out of stock graph //out of stock graph
render_out_of_stock_graph:function(){ render_out_of_stock_graph:function(){
var self = this var self = this
@ -525,10 +501,8 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
} }
}); });
} }
}); });
}, },
//dead stock graph //dead stock graph
render_dead_of_stock_graph:function(){ render_dead_of_stock_graph:function(){
var self = this var self = this
@ -536,7 +510,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
model: "stock.move", model: "stock.move",
method: "get_dead_of_stock", method: "get_dead_of_stock",
}).then(function (result) { }).then(function (result) {
if (result) { if (result) {
$('#graphs').append('<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> $('#graphs').append('<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
<div class="chart-container card-shadow" id="tiles"><div style="height: 20px; max-height: 20px;"><h2>Dead Stock</h2> <div class="chart-container card-shadow" id="tiles"><div style="height: 20px; max-height: 20px;"><h2>Dead Stock</h2>
@ -583,10 +556,8 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
} }
}); });
} }
}); });
}, },
// event functions // event functions
//top product selection //top product selection
onclick_top_product_selection:function(events){ onclick_top_product_selection:function(events){
@ -626,7 +597,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -640,7 +610,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
barPercentage: 0.5, barPercentage: 0.5,
barThickness: 6, barThickness: 6,
maxBarThickness: 8, maxBarThickness: 8,
@ -661,7 +630,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
} }
}); });
}); });
} }
if (option == 'top_last_30_days'){ if (option == 'top_last_30_days'){
var self = this; var self = this;
@ -698,7 +666,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -712,7 +679,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
barPercentage: 0.5, barPercentage: 0.5,
barThickness: 6, barThickness: 6,
maxBarThickness: 8, maxBarThickness: 8,
@ -768,7 +734,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -838,7 +803,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -852,7 +816,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
barPercentage: 0.5, barPercentage: 0.5,
barThickness: 6, barThickness: 6,
maxBarThickness: 8, maxBarThickness: 8,
@ -875,7 +838,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
}); });
} }
}, },
// stock moves this_mont,last_year change // stock moves this_mont,last_year change
onclick_stock_moves_selection:function(events){ onclick_stock_moves_selection:function(events){
var option = $(events.target).val(); var option = $(events.target).val();
@ -913,7 +875,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -946,9 +907,7 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height
} }
}); });
}); });
} }
if (option == 'this_month'){ if (option == 'this_month'){
rpc.query({ rpc.query({
@ -984,7 +943,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -1017,9 +975,7 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height
} }
}); });
}); });
} }
if (option == 'last_3_month'){ if (option == 'last_3_month'){
rpc.query({ rpc.query({
@ -1055,7 +1011,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -1088,9 +1043,7 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height
} }
}); });
}); });
} }
else if (option == 'last_year'){ else if (option == 'last_year'){
rpc.query({ rpc.query({
@ -1126,7 +1079,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
"#a05195", "#a05195",
"#6d5c16", "#6d5c16",
"#CCCCFF" "#CCCCFF"
], ],
borderColor: [ borderColor: [
"#003f5c", "#003f5c",
@ -1159,11 +1111,9 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height
} }
}); });
}); });
} }
}, },
// product move selection // product move selection
onclick_product_moves_selection:function(events){ onclick_product_moves_selection:function(events){
var option = $(events.target).val(); var option = $(events.target).val();
@ -1211,10 +1161,8 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height
} }
}); });
}); });
}, },
// tile click // tile click
onclick_tiles: function(f) { onclick_tiles: function(f) {
var id = parseInt(this.$(f.currentTarget).attr('id')); var id = parseInt(this.$(f.currentTarget).attr('id'));
@ -1231,8 +1179,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
target: 'current', target: 'current',
}, options); }, options);
}, },
// tile late status onclick // tile late status onclick
onclick_late_status: function(f) { onclick_late_status: function(f) {
f.stopPropagation(); f.stopPropagation();
@ -1251,7 +1197,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
target: 'current', target: 'current',
}, options) }, options)
}, },
// tile waiting status onclick // tile waiting status onclick
onclick_waiting_status: function(f) { onclick_waiting_status: function(f) {
f.stopPropagation(); f.stopPropagation();
@ -1269,7 +1214,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
target: 'current', target: 'current',
}, options) }, options)
}, },
// tile backorder status onclick // tile backorder status onclick
onclick_backorders_status: function(f) { onclick_backorders_status: function(f) {
f.stopPropagation(); f.stopPropagation();
@ -1287,7 +1231,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
target: 'current', target: 'current',
}, options) }, options)
}, },
// top ten product show details button click // top ten product show details button click
onclick_top_product_info: function(f) { onclick_top_product_info: function(f) {
var x = document.getElementById("pro_info"); var x = document.getElementById("pro_info");
@ -1297,7 +1240,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
x.style.display = "none"; x.style.display = "none";
} }
}, },
// product category graph show details button click // product category graph show details button click
onclick_pro_cate_info: function(f) { onclick_pro_cate_info: function(f) {
var x = document.getElementById("category_table"); var x = document.getElementById("category_table");
@ -1307,7 +1249,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
x.style.display = "none"; x.style.display = "none";
} }
}, },
// stock moves show details button click // stock moves show details button click
onclick_location_info: function(f) { onclick_location_info: function(f) {
var x = document.getElementById("location_table"); var x = document.getElementById("location_table");
@ -1317,7 +1258,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
x.style.display = "none"; x.style.display = "none";
} }
}, },
// operation types table show details button click // operation types table show details button click
onclick_operation_type_info: function(f) { onclick_operation_type_info: function(f) {
var x = document.getElementById("operation_type_table"); var x = document.getElementById("operation_type_table");
@ -1327,7 +1267,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
x.style.display = "none"; x.style.display = "none";
} }
}, },
// dead stock table show details button click // dead stock table show details button click
onclick_dead_stock_info: function(f) { onclick_dead_stock_info: function(f) {
var x = document.getElementById("dead_stock_table"); var x = document.getElementById("dead_stock_table");
@ -1337,7 +1276,6 @@ odoo.define("inventory_dashboard.dashboard", function (require) {
x.style.display = "none"; x.style.display = "none";
} }
}, },
// out of stock table show details button click // out of stock table show details button click
onclick_out_of_stock_info: function(f) { onclick_out_of_stock_info: function(f) {
var x = document.getElementById("out_of_stock_table"); var x = document.getElementById("out_of_stock_table");

356
inventory_stock_dashboard_odoo/static/src/xml/dashboard.xml

@ -1,175 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve"> <templates id="template" xml:space="preserve">
<t t-name="Dashboard">
<t t-name="Dashboard"> <div class="oh_dashboards">
<div class="oh_dashboards"> <div class="container-fluid my-5 o_hr_dashboard"/>
<div class="container-fluid my-5 o_hr_dashboard"/> <h1></h1>
<h1> </div>
</h1> </t>
</div> <t t-name="InventoryTiles">
</t> <div class="container-fluid py-5">
<div class="row" id="set"></div>
<t t-name="InventoryTiles"> </div>
<div class="container-fluid py-5"> <div class="accounts-dashboard-wrap">
<div class="row" id="set"> <div class="row main-section" id="new"></div>
</div> </div>
</div> </t>
<div class="accounts-dashboard-wrap"> <t t-name="ProductSaleBarGraph">
<div class="row main-section" id="new"> <div class="row mt-5 px-4" id="graphs">
</div> <div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
</div> <div class="chart-container card-shadow" id="tiles">
</t> <div style="height: 20px; max-height: 20px;">
<h2>Top Moving Products</h2>
<t t-name="ProductSaleBarGraph"> <div class="form-group col-2"
<div class="row mt-5 px-4" id="graphs"> id="top_product_button">
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> <select id="top_product_selection"
<div class="chart-container card-shadow" id="tiles"> class="btn btn-primary">
<div style="height: 20px; max-height: 20px;"> <option id="top_last_10_days"
<h2>Top Moving Products</h2> value="top_last_10_days"
<div class="form-group col-2" id="top_product_button"> selected="selected">Last 10 Days</option>
<select id="top_product_selection" class="btn btn-primary"> <option id="top_last_30_days"
<option id="top_last_10_days" value="top_last_10_days" selected="selected">Last 10 Days</option> value="top_last_30_days">Last 30 Days</option>
<option id="top_last_30_days" value="top_last_30_days">Last 30 Days</option> <option id="top_last_3_month"
<option id="top_last_3_month" value="top_last_3_month">Last 3 Month</option> value="top_last_3_month">Last 3 Month</option>
<option id="top_last_year" value="top_last_year">Last Year</option> <option id="top_last_year"
</select> value="top_last_year">Last Year</option>
</div> </select>
<button class="btn_info" id="top_product_info" title="Show Details"> </div>
<i class="fa fa-ellipsis-v"></i> <button class="btn_info" id="top_product_info"
</button> title="Show Details">
<table class="graph_details_table" id="pro_info"> <i class="fa fa-ellipsis-v"></i>
<tr> </button>
<th>Products</th> <table class="graph_details_table" id="pro_info">
<th>Quantity Transfered</th> <tr>
</tr> <th>Products</th>
</table> <th>Quantity Transfered</th>
</div> </tr>
<hr/> </table>
<div class="graph_canvas" style="margin-top: 30px;"> </div>
<canvas id="canvaspie" height="500px" width="150px"/> <hr/>
</div> <div class="graph_canvas" style="margin-top: 30px;">
</div> <canvas id="canvaspie" height="500px"
</div> width="150px"/>
</div>
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> </div>
<div class="chart-container card-shadow" id="tiles"> </div>
<div style="height: 20px; max-height: 20px;"> <div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
<h2>Product Categories</h2> <div class="chart-container card-shadow" id="tiles">
<button class="btn_info" id="pro_cate_info" title="Show Details"> <div style="height: 20px; max-height: 20px;">
<i class="fa fa-ellipsis-v"></i> <h2>Product Categories</h2>
</button> <button class="btn_info" id="pro_cate_info"
title="Show Details">
<table class="graph_details_table" id="category_table"> <i class="fa fa-ellipsis-v"></i>
<tr> </button>
<th>Categories</th> <table class="graph_details_table" id="category_table">
<th>Onhand Quantity</th> <tr>
</tr> <th>Categories</th>
</table> <th>Onhand Quantity</th>
</div> </tr>
<hr/> </table>
<div class="graph_canvas" style="margin-top: 30px;"> </div>
<canvas id="product_category" height="500px" width="150px"/> <hr/>
</div> <div class="graph_canvas" style="margin-top: 30px;">
</div> <canvas id="product_category" height="500px"
</div> width="150px"/>
</div>
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> </div>
<div class="chart-container card-shadow" id="tiles"> </div>
<div style="height: 20px; max-height: 20px;" <div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
<div class="chart-container card-shadow" id="tiles">
<div style="height: 20px; max-height: 20px;"
class="d-flex justify-content-between align-items-center"> class="d-flex justify-content-between align-items-center">
<h2>Product Moves By Category</h2> <h2>Product Moves By Category</h2>
<div class="form-group col-2" id="product_move_select"> <div class="form-group col-2"
<select id="product_move_selection" class="btn btn-primary"> id="product_move_select">
</select> <select id="product_move_selection"
</div> class="btn btn-primary"></select>
<button class="btn_info" id="product_move_info" title="Show Details"> </div>
<i class="fa fa-ellipsis-v"></i> <button class="btn_info" id="product_move_info"
</button> title="Show Details">
<table class="graph_details_table" id="product_move_table"> <i class="fa fa-ellipsis-v"></i>
<tr> </button>
<th>Products</th> <table class="graph_details_table"
<th>Quantity Done</th> id="product_move_table">
</tr> <tr>
</table> <th>Products</th>
</div> <th>Quantity Done</th>
<hr/> </tr>
<div class="graph_canvas" style="margin-top: 30px;"> </table>
<canvas id="product_move_graph" height="500px" width="150px"/> </div>
</div> <hr/>
</div> <div class="graph_canvas" style="margin-top: 30px;">
</div> <canvas id="product_move_graph" height="500px"
width="150px"/>
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> </div>
<div class="chart-container card-shadow" id="tiles"> </div>
<div style="height: 20px; max-height: 20px;" </div>
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
<div class="chart-container card-shadow" id="tiles">
<div style="height: 20px; max-height: 20px;"
class="d-flex justify-content-between align-items-center"> class="d-flex justify-content-between align-items-center">
<h2>Stock Moves By Location</h2> <h2>Stock Moves By Location</h2>
<div class="form-group col-2"
<div class="form-group col-2" id="stock_move_select"> id="stock_move_select">
<select id="stock_moves_selection" class="btn btn-primary"> <select id="stock_moves_selection"
<option id="last_10_days" value="last_10_days" selected="selected">Last 10 Days</option> class="btn btn-primary">
<option id="this_month" value="this_month">Last months</option> <option id="last_10_days"
<option id="last_3_month" value="last_3_month">Last 3 months</option> value="last_10_days"
<option id="last_year" value="last_year">Last Year</option> selected="selected">Last 10 Days</option>
</select> <option id="this_month" value="this_month">Last months</option>
</div> <option id="last_3_month"
<button class="btn_info" id="stock_move_info" title="Show Details"> value="last_3_month">Last 3 months</option>
<i class="fa fa-ellipsis-v"></i> <option id="last_year" value="last_year">Last Year</option>
</button> </select>
<table class="graph_details_table" id="stock_move_table"> </div>
<tr> <button class="btn_info" id="stock_move_info"
<th>Location</th> title="Show Details">
<th>Stock Moves Count</th> <i class="fa fa-ellipsis-v"></i>
</tr> </button>
</table> <table class="graph_details_table"
</div> id="stock_move_table">
<hr/> <tr>
<div class="graph_canvas" style="margin-top: 30px;"> <th>Location</th>
<canvas id="stock_moves" height="500px" width="150px"/> <th>Stock Moves Count</th>
</div> </tr>
</div> </table>
</div> </div>
<hr/>
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> <div class="graph_canvas" style="margin-top: 30px;">
<div class="chart-container card-shadow" id="tiles"> <canvas id="stock_moves" height="500px"
<div style="height: 20px; max-height: 20px;"> width="150px"/>
<h2>Operation Types</h2> </div>
<button class="btn_info" id="operation_type_info" title="Show Details"> </div>
<i class="fa fa-ellipsis-v"></i> </div>
</button> <div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
<div class="chart-container card-shadow" id="tiles">
<table class="graph_details_table" id="operation_type_table"> <div style="height: 20px; max-height: 20px;">
<tr> <h2>Operation Types</h2>
<th>Operation Types</th> <button class="btn_info" id="operation_type_info"
<th>Transfer Count</th> title="Show Details">
</tr> <i class="fa fa-ellipsis-v"></i>
</table> </button>
</div> <table class="graph_details_table"
<hr/> id="operation_type_table">
<div class="graph_canvas" style="margin-top: 30px;"> <tr>
<canvas id="operation" height="500px" width="150px"/> <th>Operation Types</th>
</div> <th>Transfer Count</th>
</div> </tr>
</div> </table>
</div>
<div class="year_to_date_graph_div col-sm-12 col-md-6 my-4"> <hr/>
<div class="chart-container card-shadow" id="tiles"> <div class="graph_canvas" style="margin-top: 30px;">
<div style="height: 20px; max-height: 20px"> <canvas id="operation" height="500px" width="150px"/>
<h2>Locations</h2> </div>
</div> </div>
<hr/> </div>
<table style="margin-top: 30px;" class="table table-hover" id="location_table"> <div class="year_to_date_graph_div col-sm-12 col-md-6 my-4">
<thead><tr><th> <div class="chart-container card-shadow" id="tiles">
<h2>Location</h2> <div style="height: 20px; max-height: 20px">
</th> <h2>Locations</h2>
<th> </div>
<h2 style="text-align: center;">On Hand Quantity</h2> <hr/>
</th></tr></thead> <table style="margin-top: 30px;" class="table table-hover"
<tbody class="storage"></tbody> id="location_table">
</table> <thead>
</div> <tr>
</div> <th>
</div> <h2>Location</h2>
</t> </th>
<th>
<h2 style="text-align: center;">On Hand Quantity</h2>
</th>
</tr>
</thead>
<tbody class="storage"></tbody>
</table>
</div>
</div>
</div>
</t>
</templates> </templates>

9
inventory_stock_dashboard_odoo/views/dashboard_menu.xml → inventory_stock_dashboard_odoo/views/dashboard_menus.xml

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record id="dashboard_action" model="ir.actions.client"> <record id="dashboard_action" model="ir.actions.client">
<field name="name">Dashboard</field> <field name="name">Dashboard</field>
<field name="tag">inventory_dashboard_tag</field> <field name="tag">inventory_dashboard_tag</field>
</record> </record>
<menuitem id="dashboard" <menuitem id="dashboard_menu_root" name="Dashboard"
name="Dashboard"
parent="stock.menu_stock_root" parent="stock.menu_stock_root"
action="dashboard_action" action="dashboard_action"
groups="stock.group_stock_user" groups="stock.group_stock_user"

54
inventory_stock_dashboard_odoo/views/res_config_settings_inherit.xml

@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="99"/>
<field name="inherit_id" ref="stock.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="production_lot_info" position="after">
<div class="app_settings_block">
<h2>Dashboard</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="out_of_stock"/>
</div>
<div class="o_setting_right_pane">
<label for="out_of_stock"/>
<div class="text-muted">
Set Your Out Of Stock Quantity
</div>
<field name="out_of_stock_quantity"
attrs="{'invisible': [('out_of_stock', '=', False)]}"/>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="dead_stock_bol"/>
</div>
<div class="o_setting_right_pane">
<label for="dead_stock_bol"/>
<div class="text-muted">
Show Dead Stocks In Dashboard
</div>
<div>
<field name="dead_stock"
attrs="{'invisible': [('dead_stock_bol', '=', False)]}"/>
</div>
<div>
<field name="dead_stock_type"
attrs="{'invisible': [('dead_stock_bol', '=', False)]}"/>
<span attrs="{'invisible': [('dead_stock_bol', '=', False)]}">&#160; Duration</span>
</div>
</div>
</div>
</div>
</div>
</div>
</field>
</record>
</data>
</odoo>

53
inventory_stock_dashboard_odoo/views/res_config_settings_views.xml

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.inventory.dashboard</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="99"/>
<field name="inherit_id" ref="stock.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="production_lot_info" position="after">
<div class="app_settings_block">
<h2>Dashboard</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="out_of_stock"/>
</div>
<div class="o_setting_right_pane">
<label for="out_of_stock"/>
<div class="text-muted">
Set Your Out Of Stock Quantity
</div>
<field name="out_of_stock_quantity"
attrs="{'invisible': [('out_of_stock', '=', False)]}"/>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="dead_stock_bol"/>
</div>
<div class="o_setting_right_pane">
<label for="dead_stock_bol"/>
<div class="text-muted">
Show Dead Stocks In Dashboard
</div>
<div>
<field name="dead_stock"
attrs="{'invisible': [('dead_stock_bol', '=', False)]}"/>
</div>
<div>
<field name="dead_stock_type"
attrs="{'invisible': [('dead_stock_bol', '=', False)]}"/>
<span attrs="{'invisible': [('dead_stock_bol', '=', False)]}">
&#160; Duration
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</field>
</record>
</odoo>
Loading…
Cancel
Save