Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association
========================
Account Dashboard Banner
========================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:fa75cd0388f3a14931f7963eec0bec827c2ed902c0c6e7dc1a295695f0a2c1f5
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/18.0/account_dashboard_banner
:alt: OCA/account-financial-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-financial-tools-18-0/account-financial-tools-18-0-account_dashboard_banner
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
The development of this module started with a simple analysis:
accountants tend to forget to update the lock dates. Part of the problem
lies in the fact that the lock dates can be seen in the wizard to update
the lock dates, but accountants have no incentive to start this wizard
regularly to check the lock dates. The idea was to display the lock
dates in a banner at the top of the accounting dashboard, so that
accountants have the value of the lock dates in front of their eyes.
With such a banner in the accounting dashboard to display the lock
dates, there was a great temptation to display other interesting
information in that banner, such as some key figures of the accounting:
liquidity, turnover, customer overdue, etc. It gave birth to the idea to
have a configurable banner in the accounting dashboard!
**Table of contents**
.. contents::
:local:
Configuration
=============
Go to the menu **Invoicing > Configuration > Dashboard > Dashboard
Banner Cells**: in this menu, you can add or remove cells from the
banner, change the cell type, modify the order via drag-and-drop,
customize the labels if necessary.
|Cell configuration menu|
Many cell types are available:
- **Income** with 4 options: *Fiscal Year-to-date Income*, *Year-to-date
Income*, *Quarter-to-date Income* and *Month-to-date Income*. It
displays the period balance of the accounts with type *Income* and
*Other Income*.
- **Liquidity**: it display the ending balance of the accounts linked to
a bank or cash or credit journal.
- **Customer Debt**: it displays the ending balance of the default
*Account Receivable* and, if the point of sale is installed, the
intermediary account used for unidentified customers.
- **Customer Overdue**: same as the *Customer Debt*, but limited to
journal items with a due date in the past.
- **Supplier Debt**: it displays the ending balance of the default
*Account Payable*.
- **Lock dates**: all the lock dates are available: *Tax Return Lock
Date*, *Sales Lock Date*, *Purchase Lock Date*, *Global Lock Date* and
*Hard Lock Date*.
The module is designed to allow the modification of the computation of
the different cell types by inheriting the method
*\_prepare_cell_data\_<cell_type>()* or *\_prepare_cell_data()*. It is
also easy for a developper to add more cell types.
It is possible to display a cell as a warning cell (yellow background
color instead of light grey): click on the *Warning* option and
customize the conditions to trigger the warning.
|Cell form with warning|
.. |Cell configuration menu| image:: https://raw.githubusercontent.com/OCA/account-financial-tools/18.0/account_dashboard_banner/static/description/banner_cell_config.png
.. |Cell form with warning| image:: https://raw.githubusercontent.com/OCA/account-financial-tools/18.0/account_dashboard_banner/static/description/cell_form_with_warning.png
Usage
=====
Enjoy the accounting dashboard with the banner at the top:
|Accounting dashboard with banner|
.. |Accounting dashboard with banner| image:: https://raw.githubusercontent.com/OCA/account-financial-tools/18.0/account_dashboard_banner/static/description/account_dashboard_banner.png
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_dashboard_banner%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Akretion
Contributors
------------
- Alexis de Lattre <alexis.delattre@akretion.com>
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-alexis-via| image:: https://github.com/alexis-via.png?size=40px
:target: https://github.com/alexis-via
:alt: alexis-via
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-alexis-via|
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/18.0/account_dashboard_banner>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,2 @@
from . import models
from .post_install import create_default_account_dashboard_cells

View File

@@ -0,0 +1,29 @@
# Copyright 2025 Akretion France (https://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Account Dashboard Banner",
"version": "18.0.1.1.0",
"category": "Accounting",
"license": "AGPL-3",
"summary": "Add a configurable banner on the accounting dashboard",
"author": "Akretion,Odoo Community Association (OCA)",
"maintainers": ["alexis-via"],
"development_status": "Beta",
"website": "https://github.com/OCA/account-financial-tools",
"depends": ["account"],
"data": [
"security/ir.model.access.csv",
"views/account_journal_dashboard.xml",
"views/account_dashboard_banner_cell.xml",
],
"assets": {
"web.assets_backend": [
"account_dashboard_banner/static/src/views/account_dashboard_kanban_banner.esm.js",
"account_dashboard_banner/static/src/views/account_dashboard_kanban_banner.xml",
],
},
"post_init_hook": "create_default_account_dashboard_cells",
"installable": True,
}

View File

@@ -0,0 +1,246 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_dashboard_banner
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__above
msgid "Above Maximum"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model,name:account_dashboard_banner.model_account_dashboard_banner_cell
msgid "Accounting Dashboard Banner Cell"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__inside
msgid "Between Minimum and Maximum"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__cell_type
msgid "Cell Type"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__create_uid
msgid "Created by"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__create_date
msgid "Created on"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__custom_label
msgid "Custom Label"
msgstr ""
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_list
msgid "Custom Label (optional)"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__custom_tooltip
msgid "Custom Tooltip"
msgstr ""
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Custom Tooltip (optional)"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__customer_debt
msgid "Customer Debt"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__customer_overdue
msgid "Customer Overdue"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.ui.menu,name:account_dashboard_banner.account_dashboard_config
msgid "Dashboard"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.actions.act_window,name:account_dashboard_banner.account_dashboard_banner_cell_action
#: model:ir.ui.menu,name:account_dashboard_banner.account_dashboard_banner_cell_menu
msgid "Dashboard Banner Cells"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__display_name
msgid "Display Name"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_fiscalyear
msgid "Fiscal Year-to-date Income"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__fiscalyear_lock_date
msgid "Global Lock Date"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__hard_lock_date
msgid "Hard Lock Date"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__id
msgid "ID"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__liquidity
msgid "Liquidity"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_max
msgid "Maximum"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_min
msgid "Minimum"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_month
msgid "Month-to-date Income"
msgstr ""
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid ""
"On cell '%(cell_type)s' with warning enabled, the minimum (%(warn_min)s) "
"must be under the maximum (%(warn_max)s)."
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__purchase_lock_date
msgid "Purchase Lock Date"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_quarter
msgid "Quarter-to-date Income"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__sale_lock_date
msgid "Sales Lock Date"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__sequence
msgid "Sequence"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__supplier_debt
msgid "Supplier Debt"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__tax_lock_date
msgid "Tax Return Lock Date"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__under
msgid "Under Minimum"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__outside
msgid "Under Minimum or Above Maximum"
msgstr ""
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Warn If"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_lock_date_days
msgid "Warn Lock Date Days"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_type
msgid "Warn Type"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_type_show
msgid "Warn Type Show"
msgstr ""
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Warn if lock date is older than"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.constraint,message:account_dashboard_banner.constraint_account_dashboard_banner_cell_warn_lock_date_days_positive
msgid "Warn if lock date is older than N days must be positive or null."
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn
msgid "Warning"
msgstr ""
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_year
msgid "Year-to-date Income"
msgstr ""
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "days"
msgstr ""
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid "from %s"
msgstr ""
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid "with due date before %s"
msgstr ""

View File

@@ -0,0 +1,263 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_dashboard_banner
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-06 14:17+0000\n"
"PO-Revision-Date: 2025-09-05 00:42+0000\n"
"Last-Translator: Alexis de Lattre <alexis@via.ecp.fr>\n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.10.4\n"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__above
msgid "Above Maximum"
msgstr "supérieur au maximum"
#. module: account_dashboard_banner
#: model:ir.model,name:account_dashboard_banner.model_account_dashboard_banner_cell
msgid "Accounting Dashboard Banner Cell"
msgstr "Cellule du bandeau du tableau de bord de la comptabilité"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__inside
msgid "Between Minimum and Maximum"
msgstr "entre le minimum et le maximum"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__cell_type
msgid "Cell Type"
msgstr "Type de cellule"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__create_date
msgid "Created on"
msgstr "Créé le"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__custom_label
msgid "Custom Label"
msgstr "Libellé personnalisé"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_list
msgid "Custom Label (optional)"
msgstr "Libellé personnalisé (facultatif)"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__custom_tooltip
msgid "Custom Tooltip"
msgstr "Info-bulle personnalisée"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Custom Tooltip (optional)"
msgstr "Info-bulle personnalisée (facultatif)"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__customer_debt
msgid "Customer Debt"
msgstr "Dette client"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__customer_overdue
msgid "Customer Overdue"
msgstr "Impayés client"
#. module: account_dashboard_banner
#: model:ir.ui.menu,name:account_dashboard_banner.account_dashboard_config
msgid "Dashboard"
msgstr "Tableau de bord"
#. module: account_dashboard_banner
#: model:ir.actions.act_window,name:account_dashboard_banner.account_dashboard_banner_cell_action
#: model:ir.ui.menu,name:account_dashboard_banner.account_dashboard_banner_cell_menu
msgid "Dashboard Banner Cells"
msgstr "Cellules du bandeau du tableau de bord"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__display_name
msgid "Display Name"
msgstr "Nom affiché"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_fiscalyear
msgid "Fiscal Year-to-date Income"
msgstr "Revenus depuis le début de l'exercice comptable"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__fiscalyear_lock_date
msgid "Global Lock Date"
msgstr "Date de verrouillage globale"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__hard_lock_date
msgid "Hard Lock Date"
msgstr "Date de verrouillage ferme"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__id
msgid "ID"
msgstr "ID"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__liquidity
msgid "Liquidity"
msgstr "Liquidités"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_max
msgid "Maximum"
msgstr "Maximum"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_min
msgid "Minimum"
msgstr "Minimum"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_month
msgid "Month-to-date Income"
msgstr "Revenus depuis le début du mois"
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid ""
"On cell '%(cell_type)s' with warning enabled, the minimum (%(warn_min)s) "
"must be under the maximum (%(warn_max)s)."
msgstr ""
"Pour la cellule '%(cell_type)s' dont l'avertissement est activé, le minimum "
"(%(warn_min)s) doit être inférieur au maximum (%(warn_max)s)."
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__purchase_lock_date
msgid "Purchase Lock Date"
msgstr "Date de verrouillage des achats"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_quarter
msgid "Quarter-to-date Income"
msgstr "Revenus depuis le début du trimestre"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__sale_lock_date
msgid "Sales Lock Date"
msgstr "Date de verrouillage des ventes"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__sequence
msgid "Sequence"
msgstr "Séquence"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__supplier_debt
msgid "Supplier Debt"
msgstr "Dette fournisseur"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__tax_lock_date
msgid "Tax Return Lock Date"
msgstr "Date de verrouillage de la déclaration de TVA"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__under
msgid "Under Minimum"
msgstr "inférieur au minimum"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__outside
msgid "Under Minimum or Above Maximum"
msgstr "inférieur au minimum ou supérieur au maximum"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Warn If"
msgstr "Avertissement si"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_lock_date_days
msgid "Warn Lock Date Days"
msgstr "Nb jours avertissement verrouillage"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_type
msgid "Warn Type"
msgstr "Type d'avertissement"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_type_show
msgid "Warn Type Show"
msgstr "Afficher le type d'avertissement"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Warn if lock date is older than"
msgstr "Avertissement si la date de verrouillage est antérieure à"
#. module: account_dashboard_banner
#: model:ir.model.constraint,message:account_dashboard_banner.constraint_account_dashboard_banner_cell_warn_lock_date_days_positive
msgid "Warn if lock date is older than N days must be positive or null."
msgstr ""
"Avertissement si la date de verrouillage est supérieure à N jours. Doit être "
"positif ou nul."
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn
msgid "Warning"
msgstr "Avertissement"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_year
msgid "Year-to-date Income"
msgstr "Revenus depuis le début de l'année"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "days"
msgstr "jours"
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid "from %s"
msgstr "depuis le %s"
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid "with due date before %s"
msgstr "avec date d'échéance antérieure au %s"
#~ msgid "Balance of account(s) %(account_codes)s%(specific)s."
#~ msgstr "Solde du/des compte(s) %(account_codes)s%(specific)s."
#~ msgid "None"
#~ msgstr "Aucun"
#~ msgid "_compute_warn_fields"
#~ msgstr "calculer les champs d'avertissement"

View File

@@ -0,0 +1,253 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_dashboard_banner
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-07-21 10:25+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__above
msgid "Above Maximum"
msgstr "Oltre il massimo"
#. module: account_dashboard_banner
#: model:ir.model,name:account_dashboard_banner.model_account_dashboard_banner_cell
msgid "Accounting Dashboard Banner Cell"
msgstr "Cella del banner della bacheca di contabilità"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__inside
msgid "Between Minimum and Maximum"
msgstr "Tra minimo e massimo"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__cell_type
msgid "Cell Type"
msgstr "Tipo cella"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__create_date
msgid "Created on"
msgstr "Creato il"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__custom_label
msgid "Custom Label"
msgstr "Etichetta personalizzata"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_list
msgid "Custom Label (optional)"
msgstr "Etichetta personalizzata (opzionale)"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__custom_tooltip
msgid "Custom Tooltip"
msgstr "Descrizione personalizzata"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Custom Tooltip (optional)"
msgstr "Descrizione personalizzata (opzionale)"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__customer_debt
msgid "Customer Debt"
msgstr "Debito cliente"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__customer_overdue
msgid "Customer Overdue"
msgstr "Scaduto cliente"
#. module: account_dashboard_banner
#: model:ir.ui.menu,name:account_dashboard_banner.account_dashboard_config
msgid "Dashboard"
msgstr "Bacheca"
#. module: account_dashboard_banner
#: model:ir.actions.act_window,name:account_dashboard_banner.account_dashboard_banner_cell_action
#: model:ir.ui.menu,name:account_dashboard_banner.account_dashboard_banner_cell_menu
msgid "Dashboard Banner Cells"
msgstr "Celle banner bacheca"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_fiscalyear
msgid "Fiscal Year-to-date Income"
msgstr "Ricavi attuali anno fiscale"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__fiscalyear_lock_date
msgid "Global Lock Date"
msgstr "Data blocco globale"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__hard_lock_date
msgid "Hard Lock Date"
msgstr "Data blocco elevato"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__id
msgid "ID"
msgstr "ID"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__liquidity
msgid "Liquidity"
msgstr "Liquidità"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_max
msgid "Maximum"
msgstr "Massimo"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_min
msgid "Minimum"
msgstr "Minimo"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_month
msgid "Month-to-date Income"
msgstr "Ricavi mensili attuali"
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid ""
"On cell '%(cell_type)s' with warning enabled, the minimum (%(warn_min)s) "
"must be under the maximum (%(warn_max)s)."
msgstr ""
"Nella cella '%(cell_type)s' con avviso abilitato, il minimo (%(warn_min)s) "
"deve essere inferiore al massimo (%(warn_max)s)."
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__purchase_lock_date
msgid "Purchase Lock Date"
msgstr "Data blocco acquisti"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_quarter
msgid "Quarter-to-date Income"
msgstr "Ricavi trimestrali attuali"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__sale_lock_date
msgid "Sales Lock Date"
msgstr "Data blocco vendite"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__sequence
msgid "Sequence"
msgstr "Sequenza"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__supplier_debt
msgid "Supplier Debt"
msgstr "Debito fornitore"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__tax_lock_date
msgid "Tax Return Lock Date"
msgstr "Data blocco rimborso imposta"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__under
msgid "Under Minimum"
msgstr "Inferiore al minimo"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__warn_type__outside
msgid "Under Minimum or Above Maximum"
msgstr "Inferiore al minimo o superiore al massimo"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Warn If"
msgstr "Avvisa se"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_lock_date_days
msgid "Warn Lock Date Days"
msgstr "Giorni avviso data blocco"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_type
msgid "Warn Type"
msgstr "Tipo avviso"
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn_type_show
msgid "Warn Type Show"
msgstr "Visualizza tipo avviso"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "Warn if lock date is older than"
msgstr "Avvisa se la data di blocco è più vecchia di"
#. module: account_dashboard_banner
#: model:ir.model.constraint,message:account_dashboard_banner.constraint_account_dashboard_banner_cell_warn_lock_date_days_positive
msgid "Warn if lock date is older than N days must be positive or null."
msgstr ""
"Avvisa se la data di blocco è più vecchia di N giorni deve essere positivo o "
"nullo."
#. module: account_dashboard_banner
#: model:ir.model.fields,field_description:account_dashboard_banner.field_account_dashboard_banner_cell__warn
msgid "Warning"
msgstr "Attenzione"
#. module: account_dashboard_banner
#: model:ir.model.fields.selection,name:account_dashboard_banner.selection__account_dashboard_banner_cell__cell_type__income_year
msgid "Year-to-date Income"
msgstr "Ricavi annuali attuali"
#. module: account_dashboard_banner
#: model_terms:ir.ui.view,arch_db:account_dashboard_banner.account_dashboard_banner_cell_form
msgid "days"
msgstr "giorni"
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid "from %s"
msgstr "da %s"
#. module: account_dashboard_banner
#. odoo-python
#: code:addons/account_dashboard_banner/models/account_dashboard_banner_cell.py:0
msgid "with due date before %s"
msgstr "con data scadenza anteriore a %s"

View File

@@ -0,0 +1 @@
from . import account_dashboard_banner_cell

View File

@@ -0,0 +1,328 @@
# Copyright 2025 Akretion France (https://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from dateutil.relativedelta import relativedelta
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.osv import expression
from odoo.tools import date_utils
from odoo.tools.misc import format_amount, format_date
class AccountDashboardBannerCell(models.Model):
_name = "account.dashboard.banner.cell"
_description = "Accounting Dashboard Banner Cell"
_order = "sequence, id"
sequence = fields.Integer()
cell_type = fields.Selection(
[
("income_fiscalyear", "Fiscal Year-to-date Income"),
("income_year", "Year-to-date Income"),
("income_quarter", "Quarter-to-date Income"),
("income_month", "Month-to-date Income"),
("liquidity", "Liquidity"),
("customer_debt", "Customer Debt"),
("customer_overdue", "Customer Overdue"),
("supplier_debt", "Supplier Debt"),
# for lock dates, the key matches exactly the field name on res.company
("tax_lock_date", "Tax Return Lock Date"),
("sale_lock_date", "Sales Lock Date"),
("purchase_lock_date", "Purchase Lock Date"),
("fiscalyear_lock_date", "Global Lock Date"),
("hard_lock_date", "Hard Lock Date"),
],
required=True,
)
custom_label = fields.Char()
custom_tooltip = fields.Char()
warn = fields.Boolean(string="Warning")
warn_lock_date_days = fields.Integer(
compute="_compute_warn_fields", store=True, readonly=False, precompute=True
)
warn_min = fields.Float(string="Minimum")
warn_max = fields.Float(string="Maximum")
warn_type_show = fields.Boolean(
compute="_compute_warn_fields", store=True, precompute=True
)
warn_type = fields.Selection(
[
("under", "Under Minimum"),
("above", "Above Maximum"),
("outside", "Under Minimum or Above Maximum"),
("inside", "Between Minimum and Maximum"),
],
default="under",
)
_sql_constraints = [
(
"warn_lock_date_days_positive",
"CHECK(warn_lock_date_days >= 0)",
"Warn if lock date is older than N days must be positive or null.",
)
]
@api.constrains("warn_min", "warn_max", "warn_type", "warn", "cell_type")
def _check_warn_config(self):
for cell in self:
if (
cell.cell_type
and not cell.cell_type.endswith("_lock_date")
and cell.warn
and cell.warn_type in ("outside", "inside")
and cell.warn_max <= cell.warn_min
):
cell_type2label = dict(
self.fields_get("cell_type", "selection")["cell_type"]["selection"]
)
raise ValidationError(
_(
"On cell '%(cell_type)s' with warning enabled, "
"the minimum (%(warn_min)s) must be under "
"the maximum (%(warn_max)s).",
cell_type=cell_type2label[cell.cell_type],
warn_min=cell.warn_min,
warn_max=cell.warn_max,
)
)
@api.model
def _default_warn_lock_date_days(self, cell_type):
defaultmap = {
"tax_lock_date": 61, # 2 months
"sale_lock_date": 35, # 1 month + a few days
"purchase_lock_date": 61,
"fiscalyear_lock_date": 61, # 2 months
"hard_lock_date": 520, # FY final closing, 1 year + 5 months
}
return defaultmap.get(cell_type)
@api.depends("cell_type", "warn")
def _compute_warn_fields(self):
for cell in self:
warn_type_show = False
warn_lock_date_days = 0
if cell.cell_type and cell.warn:
if cell.cell_type.endswith("_lock_date"):
warn_lock_date_days = self._default_warn_lock_date_days(
cell.cell_type
)
else:
warn_type_show = True
cell.warn_type_show = warn_type_show
cell.warn_lock_date_days = warn_lock_date_days
@api.model
def get_banner_data(self):
"""This is the method called by the JS code that displays the banner"""
company = self.env.company
return self._prepare_banner_data(company)
def _prepare_speedy(self, company):
lock_date_fields = [
"tax_lock_date",
"sale_lock_date",
"purchase_lock_date",
"fiscalyear_lock_date",
"hard_lock_date",
]
speedy = {
"cell_type2label": dict(
self.fields_get("cell_type", "selection")["cell_type"]["selection"]
),
"lock_date2help": dict(
(key, value["help"])
for (key, value) in company.fields_get(lock_date_fields, "help").items()
),
"today": fields.Date.context_today(self),
}
return speedy
@api.model
def _prepare_banner_data(self, company):
# The order in this list will be the display order in the banner
# In fact, it's not a list but a dict. I tried to make it work by returning
# a list but it seems OWL only accepts dicts (I always get errors on lists)
cells = self.search([])
speedy = cells._prepare_speedy(company)
res = {}
seq = 0
for cell in cells:
seq += 1
cell_data = cell._prepare_cell_data(company, speedy)
cell._update_cell_warn(cell_data)
res[seq] = cell_data
# from pprint import pprint
# pprint(res)
return res
def _prepare_cell_data_liquidity(self, company, speedy):
self.ensure_one()
journals = self.env["account.journal"].search(
[
("company_id", "=", company.id),
("type", "in", ("bank", "cash", "credit")),
("default_account_id", "!=", False),
]
)
accounts = journals.default_account_id
return (accounts, 1, False, False)
def _prepare_cell_data_supplier_debt(self, company, speedy):
accounts = (
self.env["res.partner"]
._fields["property_account_payable_id"]
.get_company_dependent_fallback(self.env["res.partner"])
)
return (accounts, -1, False, False)
def _prepare_cell_data_income(self, company, speedy):
cell_type = self.cell_type
accounts = self.env["account.account"].search(
[
("company_ids", "in", [company.id]),
("account_type", "in", ("income", "income_other")),
]
)
if cell_type == "income_fiscalyear":
start_date, end_date = date_utils.get_fiscal_year(
speedy["today"],
day=company.fiscalyear_last_day,
month=int(company.fiscalyear_last_month),
)
elif cell_type == "income_month":
start_date = speedy["today"] + relativedelta(day=1)
elif cell_type == "income_year":
start_date = speedy["today"] + relativedelta(day=1, month=1)
elif cell_type == "income_quarter":
month_start_quarter = 3 * ((speedy["today"].month - 1) // 3) + 1
start_date = speedy["today"] + relativedelta(
day=1, month=month_start_quarter
)
specific_domain = [("date", ">=", start_date)]
specific_tooltip = _("from %s") % format_date(self.env, start_date)
return (accounts, -1, specific_domain, specific_tooltip)
def _prepare_cell_data_customer_debt(self, company, speedy):
accounts = (
self.env["res.partner"]
._fields["property_account_receivable_id"]
.get_company_dependent_fallback(self.env["res.partner"])
)
if hasattr(company, "account_default_pos_receivable_account_id"):
accounts |= company.account_default_pos_receivable_account_id
return (accounts, 1, False, False)
def _prepare_cell_data_customer_overdue(self, company, speedy):
accounts, sign, specific_domain, specific_tooltip = (
self._prepare_cell_data_customer_debt(company, speedy)
)
specific_domain = expression.OR(
[
[("date_maturity", "=", False)],
[("date_maturity", "<", speedy["today"])],
[
("date_maturity", "=", speedy["today"]),
("journal_id.type", "!=", "sale"),
],
]
)
specific_tooltip = _("with due date before %s") % format_date(
self.env, speedy["today"]
)
return (accounts, sign, specific_domain, specific_tooltip)
def _prepare_cell_data(self, company, speedy):
"""Inherit this method to change the computation of a cell type"""
self.ensure_one()
cell_type = self.cell_type
value = raw_value = tooltip = warn = False
if cell_type.endswith("lock_date"):
raw_value = company[cell_type]
value = raw_value and format_date(self.env, raw_value)
tooltip = speedy["lock_date2help"][cell_type]
if self.warn:
if not raw_value:
warn = True
elif raw_value < speedy["today"] - relativedelta(
days=self.warn_lock_date_days
):
warn = True
else:
accounts = False
if hasattr(self, f"_prepare_cell_data_{cell_type}"):
specific_method = getattr(self, f"_prepare_cell_data_{cell_type}")
accounts, sign, specific_domain, specific_tooltip = specific_method(
company, speedy
)
elif cell_type.startswith("income_"):
accounts, sign, specific_domain, specific_tooltip = (
self._prepare_cell_data_income(company, speedy)
)
if accounts:
domain = (specific_domain or []) + [
("company_id", "=", company.id),
("account_id", "in", accounts.ids),
("date", "<=", speedy["today"]),
("parent_state", "=", "posted"),
]
rg_res = self.env["account.move.line"]._read_group(
domain, aggregates=["balance:sum"]
)
assert sign in (1, -1)
raw_value = rg_res and rg_res[0][0] * sign or 0
value = format_amount(self.env, raw_value, company.currency_id)
tooltip = _(
"Balance of account(s) %(account_codes)s%(specific)s.",
account_codes=", ".join(accounts.mapped("code")),
specific=specific_tooltip and f" {specific_tooltip}" or "",
)
res = {
"cell_type": cell_type,
"label": self.custom_label or speedy["cell_type2label"][cell_type],
"raw_value": raw_value,
"value": value or _("None"),
"tooltip": self.custom_tooltip or tooltip,
"warn": warn,
}
return res
def _update_cell_warn(self, cell_data):
self.ensure_one()
if (
not cell_data.get("warn")
and self.warn
and self.warn_type
and isinstance(cell_data["raw_value"], (int | float))
):
raw_value = cell_data["raw_value"]
if (
(self.warn_type == "under" and raw_value < self.warn_min)
or (self.warn_type == "above" and raw_value > self.warn_max)
or (
self.warn_type == "outside"
and (raw_value < self.warn_min or raw_value > self.warn_max)
)
or (
self.warn_type == "inside"
and raw_value > self.warn_min
and raw_value < self.warn_max
)
):
cell_data["warn"] = True
@api.depends("cell_type", "custom_label")
def _compute_display_name(self):
type2name = dict(
self.fields_get("cell_type", "selection")["cell_type"]["selection"]
)
for cell in self:
display_name = "-"
if cell.custom_label:
display_name = cell.custom_label
elif cell.cell_type:
display_name = type2name[cell.cell_type]
cell.display_name = display_name

View File

@@ -0,0 +1,18 @@
# Copyright 2025 Akretion France (https://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# I create default cells via post-install script instead of
# data/account_dashboard_banner_cell.xml
# to avoid the problem when a user deletes a cell that has an XMLID
# and Odoo would re-create the cells when the module is reloaded
def create_default_account_dashboard_cells(env):
vals_list = [
{"cell_type": "hard_lock_date", "sequence": 10, "warn": True},
{"cell_type": "income_fiscalyear", "sequence": 20},
{"cell_type": "customer_overdue", "sequence": 30},
{"cell_type": "customer_debt", "sequence": 40},
{"cell_type": "supplier_debt", "sequence": 50},
{"cell_type": "liquidity", "sequence": 60, "warn": True, "warn_type": "under"},
]
env["account.dashboard.banner.cell"].create(vals_list)

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,34 @@
Go to the menu **Invoicing \> Configuration \> Dashboard \> Dashboard
Banner Cells**: in this menu, you can add or remove cells from the
banner, change the cell type, modify the order via drag-and-drop,
customize the labels if necessary.
![Cell configuration menu](../static/description/banner_cell_config.png)
Many cell types are available:
- **Income** with 4 options: *Fiscal Year-to-date Income*, *Year-to-date
Income*, *Quarter-to-date Income* and *Month-to-date Income*. It
displays the period balance of the accounts with type *Income* and
*Other Income*.
- **Liquidity**: it display the ending balance of the accounts linked to
a bank or cash or credit journal.
- **Customer Debt**: it displays the ending balance of the default
*Account Receivable* and, if the point of sale is installed, the
intermediary account used for unidentified customers.
- **Customer Overdue**: same as the *Customer Debt*, but limited to
journal items with a due date in the past.
- **Supplier Debt**: it displays the ending balance of the default
*Account Payable*.
- **Lock dates**: all the lock dates are available: *Tax Return Lock
Date*, *Sales Lock Date*, *Purchase Lock Date*, *Global Lock Date* and
*Hard Lock Date*.
The module is designed to allow the modification of the computation of
the different cell types by inheriting the method
*\_prepare_cell_data_<cell_type>()* or *\_prepare_cell_data()*.
It is also easy for a developper to add more cell types.
It is possible to display a cell as a warning cell (yellow background color instead of light grey): click on the *Warning* option and customize the conditions to trigger the warning.
![Cell form with warning](../static/description/cell_form_with_warning.png)

View File

@@ -0,0 +1 @@
- Alexis de Lattre \<<alexis.delattre@akretion.com>\>

View File

@@ -0,0 +1,13 @@
The development of this module started with a simple analysis: accountants
tend to forget to update the lock dates. Part of the problem lies in the
fact that the lock dates can be seen in the wizard to update the lock
dates, but accountants have no incentive to start this wizard regularly
to check the lock dates. The idea was to display the lock dates in a
banner at the top of the accounting dashboard, so that accountants
have the value of the lock dates in front of their eyes.
With such a banner in the accounting dashboard to display the lock
dates, there was a great temptation to display other interesting
information in that banner, such as some key figures of the accounting:
liquidity, turnover, customer overdue, etc. It gave birth to the idea to
have a configurable banner in the accounting dashboard!

View File

@@ -0,0 +1,3 @@
Enjoy the accounting dashboard with the banner at the top:
![Accounting dashboard with banner](../static/description/account_dashboard_banner.png)

View File

@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_dashboard_banner_cell_manager,Full access on account.dashboard.banner.cell,model_account_dashboard_banner_cell,account.group_account_manager,1,1,1,1
access_account_dashboard_banner_cell_user,Read access on account.dashboard.banner.cell,model_account_dashboard_banner_cell,account.group_account_user,1,0,0,0
access_account_dashboard_banner_cell_auditor,Read access on account.dashboard.banner.cell,model_account_dashboard_banner_cell,account.group_account_readonly,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_dashboard_banner_cell_manager Full access on account.dashboard.banner.cell model_account_dashboard_banner_cell account.group_account_manager 1 1 1 1
3 access_account_dashboard_banner_cell_user Read access on account.dashboard.banner.cell model_account_dashboard_banner_cell account.group_account_user 1 0 0 0
4 access_account_dashboard_banner_cell_auditor Read access on account.dashboard.banner.cell model_account_dashboard_banner_cell account.group_account_readonly 1 0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,484 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="account-dashboard-banner">
<h1>Account Dashboard Banner</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:fa75cd0388f3a14931f7963eec0bec827c2ed902c0c6e7dc1a295695f0a2c1f5
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-financial-tools/tree/18.0/account_dashboard_banner"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-financial-tools-18-0/account-financial-tools-18-0-account_dashboard_banner"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>The development of this module started with a simple analysis:
accountants tend to forget to update the lock dates. Part of the problem
lies in the fact that the lock dates can be seen in the wizard to update
the lock dates, but accountants have no incentive to start this wizard
regularly to check the lock dates. The idea was to display the lock
dates in a banner at the top of the accounting dashboard, so that
accountants have the value of the lock dates in front of their eyes.</p>
<p>With such a banner in the accounting dashboard to display the lock
dates, there was a great temptation to display other interesting
information in that banner, such as some key figures of the accounting:
liquidity, turnover, customer overdue, etc. It gave birth to the idea to
have a configurable banner in the accounting dashboard!</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h2><a class="toc-backref" href="#toc-entry-1">Configuration</a></h2>
<p>Go to the menu <strong>Invoicing &gt; Configuration &gt; Dashboard &gt; Dashboard
Banner Cells</strong>: in this menu, you can add or remove cells from the
banner, change the cell type, modify the order via drag-and-drop,
customize the labels if necessary.</p>
<p><img alt="Cell configuration menu" src="https://raw.githubusercontent.com/OCA/account-financial-tools/18.0/account_dashboard_banner/static/description/banner_cell_config.png" /></p>
<p>Many cell types are available:</p>
<ul class="simple">
<li><strong>Income</strong> with 4 options: <em>Fiscal Year-to-date Income</em>, <em>Year-to-date
Income</em>, <em>Quarter-to-date Income</em> and <em>Month-to-date Income</em>. It
displays the period balance of the accounts with type <em>Income</em> and
<em>Other Income</em>.</li>
<li><strong>Liquidity</strong>: it display the ending balance of the accounts linked to
a bank or cash or credit journal.</li>
<li><strong>Customer Debt</strong>: it displays the ending balance of the default
<em>Account Receivable</em> and, if the point of sale is installed, the
intermediary account used for unidentified customers.</li>
<li><strong>Customer Overdue</strong>: same as the <em>Customer Debt</em>, but limited to
journal items with a due date in the past.</li>
<li><strong>Supplier Debt</strong>: it displays the ending balance of the default
<em>Account Payable</em>.</li>
<li><strong>Lock dates</strong>: all the lock dates are available: <em>Tax Return Lock
Date</em>, <em>Sales Lock Date</em>, <em>Purchase Lock Date</em>, <em>Global Lock Date</em> and
<em>Hard Lock Date</em>.</li>
</ul>
<p>The module is designed to allow the modification of the computation of
the different cell types by inheriting the method
<em>_prepare_cell_data_&lt;cell_type&gt;()</em> or <em>_prepare_cell_data()</em>. It is
also easy for a developper to add more cell types.</p>
<p>It is possible to display a cell as a warning cell (yellow background
color instead of light grey): click on the <em>Warning</em> option and
customize the conditions to trigger the warning.</p>
<p><img alt="Cell form with warning" src="https://raw.githubusercontent.com/OCA/account-financial-tools/18.0/account_dashboard_banner/static/description/cell_form_with_warning.png" /></p>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
<p>Enjoy the accounting dashboard with the banner at the top:</p>
<p><img alt="Accounting dashboard with banner" src="https://raw.githubusercontent.com/OCA/account-financial-tools/18.0/account_dashboard_banner/static/description/account_dashboard_banner.png" /></p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_dashboard_banner%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-4">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-5">Authors</a></h3>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
<ul class="simple">
<li>Alexis de Lattre &lt;<a class="reference external" href="mailto:alexis.delattre&#64;akretion.com">alexis.delattre&#64;akretion.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/alexis-via"><img alt="alexis-via" src="https://github.com/alexis-via.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/18.0/account_dashboard_banner">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,36 @@
/*
Copyright 2025 Akretion France (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
*/
import {DashboardKanbanRecord} from "@account/views/account_dashboard_kanban/account_dashboard_kanban_record";
import {DashboardKanbanRenderer} from "@account/views/account_dashboard_kanban/account_dashboard_kanban_renderer";
import {kanbanView} from "@web/views/kanban/kanban_view";
import {onWillStart} from "@odoo/owl";
import {registry} from "@web/core/registry";
import {useService} from "@web/core/utils/hooks";
export class DashboardKanbanRendererBanner extends DashboardKanbanRenderer {
static template = "account_dashboard_banner.AccountDashboardBannerRenderer";
static components = {
...DashboardKanbanRenderer.components,
KanbanRecord: DashboardKanbanRecord,
};
setup() {
super.setup();
this.orm = useService("orm");
onWillStart(async () => {
this.state.banner = await this.orm.call("account.dashboard.banner.cell", "get_banner_data");
});
}
}
export const accountDashboardKanbanBanner = {
...kanbanView,
Renderer: DashboardKanbanRendererBanner,
};
registry.category("views").add("account_dashboard_kanban_banner", accountDashboardKanbanBanner);

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2025 Akretion France (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<templates xml:space="preserve">
<t t-name="account_dashboard_banner.AccountDashboardBannerRenderer" t-inherit="account.DashboardKanbanRenderer" t-inherit-mode="primary">
<xpath expr="//div[hasclass('o_kanban_renderer')]" position="before">
<div class="d-none d-md-flex position-sticky start-0 d-flex o_form_statusbar" id="dashboard_banner">
<t t-foreach="Object.entries(state.banner)" t-as="cell_entry" t-key="cell_entry[0]">
<t t-set="cell_data" t-value="cell_entry[1]"/>
<div id="cell_banner_ok" t-if="!cell_data.warn" t-attf-class="o_arrow_button flex-grow-1 d-flex flex-column p-1 text-center" t-att-data-tooltip="cell_data['tooltip']">
<strong class="mx-2" t-out="cell_data['label']"/>
<span t-out="cell_data['value']" class="h2 m-0 text-primary"/>
</div>
<div id="cell_banner_warn" t-if="cell_data.warn" t-attf-class="o_arrow_button flex-grow-1 d-flex flex-column p-1 text-center alert alert-warning" t-att-data-tooltip="cell_data['tooltip']">
<strong class="mx-2" t-out="cell_data['label']"/>
<span t-out="cell_data['value']" class="h2 m-0 text-primary"/>
</div>
</t>
</div>
</xpath>
</t>
</templates>

View File

@@ -0,0 +1 @@
from . import test_banner

View File

@@ -0,0 +1,58 @@
# Copyright 2025 Akretion France (https://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests import tagged
from odoo.tests.common import TransactionCase
@tagged("post_install", "-at_install")
class TestAccountDashboardBanner(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.cell_obj = cls.env["account.dashboard.banner.cell"]
cls.test_custom_label = "TEST Custom Label"
cls.test_custom_tooltip = "TEST customer tooltip"
# add cell_types that don't already exists
existing = cls.cell_obj.search_read([], ["cell_type"])
existing_cell_types = [x["cell_type"] for x in existing]
to_create_vals = []
for cell_type in [
"income_fiscalyear",
"income_year",
"income_quarter",
"income_month",
"liquidity",
"customer_debt",
"customer_overdue",
"supplier_debt",
"tax_lock_date",
"sale_lock_date",
"purchase_lock_date",
"fiscalyear_lock_date",
"hard_lock_date",
]:
if cell_type not in existing_cell_types:
to_create_vals.append({"cell_type": cell_type})
cls.cell_obj.create(to_create_vals)
fy_lock_cell = cls.cell_obj.search([("cell_type", "=", "fiscalyear_lock_date")])
fy_lock_cell.write(
{
"custom_label": cls.test_custom_label,
"custom_tooltip": cls.test_custom_tooltip,
"warn": True,
}
)
def test_banner(self):
res = self.cell_obj.get_banner_data()
self.assertIsInstance(res, dict)
self.assertEqual(len(res), self.cell_obj.search_count([]))
for cell_entry in res.items():
cell_data = cell_entry[1]
if cell_data["cell_type"] == "fiscalyear_lock_date":
self.assertEqual(cell_data["label"], self.test_custom_label)
self.assertEqual(cell_data["tooltip"], self.test_custom_tooltip)
if not self.env.company.fiscalyear_lock_date:
self.assertTrue(cell_data.get("warn"))

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 Akretion France (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="account_dashboard_banner_cell_form" model="ir.ui.view">
<field name="model">account.dashboard.banner.cell</field>
<field name="arch" type="xml">
<form>
<group name="main">
<group name="main-left">
<field name="cell_type"/>
<field name="warn_type_show" invisible="1"/>
<field name="warn"/>
<label for="warn_lock_date_days" string="Warn if lock date is older than" invisible="not warn or cell_type not in ('tax_lock_date', 'sale_lock_date', 'purchase_lock_date', 'fiscalyear_lock_date', 'hard_lock_date')"/>
<div name="warn_lock_date_days" invisible="not warn or cell_type not in ('tax_lock_date', 'sale_lock_date', 'purchase_lock_date', 'fiscalyear_lock_date', 'hard_lock_date')">
<field name="warn_lock_date_days" class="oe_inline"/> days
</div>
<field name="warn_type" invisible="not warn_type_show" required="warn_type_show" string="Warn If"/>
<field name="warn_min" invisible="not warn_type_show or warn_type == 'above'"/>
<field name="warn_max" invisible="not warn_type_show or warn_type == 'under'"/>
</group>
<group name="main-right">
<field name="custom_label" string="Custom Label (optional)" />
<field name="custom_tooltip" string="Custom Tooltip (optional)"/>
</group>
</group>
</form>
</field>
</record>
<record id="account_dashboard_banner_cell_list" model="ir.ui.view">
<field name="model">account.dashboard.banner.cell</field>
<field name="arch" type="xml">
<list>
<field name="sequence" widget="handle"/>
<field name="cell_type"/>
<field name="warn" optional="show"/>
<field name="custom_label" string="Custom Label (optional)" optional="show"/>
<field name="custom_tooltip" optional="hide"/>
</list>
</field>
</record>
<record id="account_dashboard_banner_cell_action" model="ir.actions.act_window">
<field name="name">Dashboard Banner Cells</field>
<field name="res_model">account.dashboard.banner.cell</field>
<field name="view_mode">list,form</field>
</record>
<menuitem id="account_dashboard_config" name="Dashboard" parent="account.menu_finance_configuration" sequence="200"/>
<menuitem id="account_dashboard_banner_cell_menu" action="account_dashboard_banner_cell_action" sequence="10" parent="account_dashboard_config"/>
</odoo>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 Akretion France (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="account_journal_dashboard_kanban_view" model="ir.ui.view">
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view"/>
<field name="arch" type="xml">
<kanban position="attributes">
<attribute name="js_class">account_dashboard_kanban_banner</attribute>
</kanban>
</field>
</record>
</odoo>