|
@ -0,0 +1,187 @@
|
|||
===============
|
||||
Module Analysis
|
||||
===============
|
||||
|
||||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |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/licence-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%2Fserver--tools-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/server-tools/tree/15.0/module_analysis
|
||||
:alt: OCA/server-tools
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-module_analysis
|
||||
:alt: Translate me on Weblate
|
||||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
|
||||
:target: https://runbot.odoo-community.org/runbot/149/15.0
|
||||
:alt: Try me on Runbot
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
|
||||
This module allows you to know 'how much code' is running on your Odoo
|
||||
instance, group by 'Type' (Odoo Core, OCA, other...)
|
||||
|
||||
This module can be usefull in the following cases :
|
||||
|
||||
* To analyse the size of your technical debt, regarding your Custom modules
|
||||
* To know the ratio between Odoo / OCA and Custom modules
|
||||
* To evaluate the amount to pay to odoo to upgrade your custom code, or the
|
||||
induced workload
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/installed_modules_by_types.png
|
||||
|
||||
For that purpose, it adds new concepts
|
||||
|
||||
* ``ir.module.author``, based on the value ``author`` present in the manifest
|
||||
file.
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_authors.png
|
||||
|
||||
* ``ir.module.type``, populated by default with Odoo and OCA values.
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_types.png
|
||||
|
||||
Each installed modules have extra data in the 'Technical Data' tab :
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_form.png
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To use this module, you have to install the ``pygount`` python librairy.
|
||||
|
||||
``pip install pygount``
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
* Go to Apps / Module Analysis / Modules Types Rules
|
||||
|
||||
The Module types Rules are usefull to get the Type of a module, based on
|
||||
it information.
|
||||
|
||||
This module comes with default rules.
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/default_module_type_rules.png
|
||||
|
||||
|
||||
You can add your custom rules to identify the modules your team have
|
||||
developped for exemple,
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/add_module_type_rules.png
|
||||
|
||||
|
||||
to update the data manually, you have to :
|
||||
|
||||
* Go to 'Apps' / 'Update Apps List'
|
||||
|
||||
* Check the box 'Analyse Installed modules'
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/base_module_update.png
|
||||
|
||||
This will update analysis of your installed modules.
|
||||
|
||||
to update the data automatically, you have to :
|
||||
|
||||
* Go to 'Settings' / 'Technical' / 'Scheduled Actions'
|
||||
|
||||
* Configure the action 'Update Module Analysis'. (By default, the analysis will be done nightly)
|
||||
|
||||
|
||||
Adding Extra data
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to analyse other data, (for exemple, having the number of HTML
|
||||
files), create a custom modules and overload the module model :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
class IrModuleModule(models.Model):
|
||||
_inherit = 'ir.module.module'
|
||||
|
||||
xml_documentation_qty = fields.Integer(
|
||||
string='Quantity of Comments in XML Files')
|
||||
|
||||
@api.model
|
||||
def _get_analyse_settings(self):
|
||||
res = super()._get_analyse_settings()
|
||||
if not '.html' in res:
|
||||
res['.html'] = {}
|
||||
res['.html']['documentation'] 'xml_documentation_qty'
|
||||
return res
|
||||
|
||||
Exclude files and directories
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Two parameters are availaible in 'Settings' / 'Technical' / 'Parameters'
|
||||
'System Parameters' :
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/config_parameters.png
|
||||
|
||||
The list of folders and filename will be exclude from the analysis.
|
||||
You can change the default settings.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
* Go to 'Apps' / 'Module Analysis' / 'Installed module by Types'
|
||||
|
||||
Open the stats to analyse the detail of the code installed
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/analysis_pivot.png
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/analysis_pie.png
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us smashing it by providing a detailed and welcomed
|
||||
`feedback <https://github.com/OCA/server-tools/issues/new?body=module:%20module_analysis%0Aversion:%2015.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
|
||||
~~~~~~~
|
||||
|
||||
* GRAP
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
|
||||
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.
|
||||
|
||||
This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/15.0/module_analysis>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
|
@ -0,0 +1 @@
|
|||
from . import models
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
{
|
||||
"name": "Module Analysis",
|
||||
"summary": "Add analysis tools regarding installed modules"
|
||||
" to know which installed modules comes from Odoo Core, OCA, or are"
|
||||
" custom modules",
|
||||
"author": "GRAP, Odoo Community Association (OCA)",
|
||||
"maintainers": ["legalsylvain"],
|
||||
"website": "https://github.com/OCA/server-tools",
|
||||
"version": "16.0.1.0.0",
|
||||
"license": "AGPL-3",
|
||||
"depends": ["base"],
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"views/menu.xml",
|
||||
"views/view_ir_module_author.xml",
|
||||
"views/view_ir_module_type.xml",
|
||||
"views/view_ir_module_type_rule.xml",
|
||||
"views/view_ir_module_module.xml",
|
||||
"data/ir_cron.xml",
|
||||
"data/ir_config_parameter.xml",
|
||||
"data/ir_module_type.xml",
|
||||
"data/ir_module_type_rule.xml",
|
||||
"data/ir_cron.xml",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": ["pygount"],
|
||||
},
|
||||
"installable": True,
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="parameter_exclude_directories" model="ir.config_parameter">
|
||||
<field name="key">module_analysis.exclude_directories</field>
|
||||
<field name="value">lib,demo,test,tests,doc,description</field>
|
||||
</record>
|
||||
<record id="parameter_exclude_files" model="ir.config_parameter">
|
||||
<field name="key">module_analysis.exclude_files</field>
|
||||
<field name="value">__openerp__.py,__manifest__.py</field>
|
||||
</record>
|
||||
</odoo>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2021-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="cron_module_analysis" model="ir.cron">
|
||||
<field name="name">Update Module Analysis</field>
|
||||
<field name="active" eval="False" />
|
||||
<field name="model_id" ref="base.model_ir_module_module" />
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.cron_analyse_code()</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="nextcall" eval="(DateTime.today()).strftime('%Y-%m-%d')" />
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
</record>
|
||||
</odoo>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<record id="module_type_odoo" model="ir.module.type">
|
||||
<field name="name">Odoo Core</field>
|
||||
</record>
|
||||
<record id="module_type_oca" model="ir.module.type">
|
||||
<field name="name">OCA</field>
|
||||
</record>
|
||||
</odoo>
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<!-- Odoo Rules -->
|
||||
<record id="module_type_rule_odoo_a" model="ir.module.type.rule">
|
||||
<field name="sequence">1</field>
|
||||
<field name="module_domain">[('author_ids', 'ilike', 'Odoo S.A')]</field>
|
||||
<field name="module_type_id" ref="module_type_odoo" />
|
||||
</record>
|
||||
<record id="module_type_rule_odoo_b" model="ir.module.type.rule">
|
||||
<field name="sequence">2</field>
|
||||
<field name="module_domain">[('author_ids', 'ilike', 'OpenERP SA')]</field>
|
||||
<field name="module_type_id" ref="module_type_odoo" />
|
||||
</record>
|
||||
<record id="module_type_rule_odoo_c" model="ir.module.type.rule">
|
||||
<field name="sequence">3</field>
|
||||
<field name="module_domain">[('author_ids', '=', 'Odoo SA')]</field>
|
||||
<field name="module_type_id" ref="module_type_odoo" />
|
||||
</record>
|
||||
<record id="module_type_rule_odoo_d" model="ir.module.type.rule">
|
||||
<field name="sequence">4</field>
|
||||
<field name="module_domain">[('author_ids', '=', 'Odoo')]</field>
|
||||
<field name="module_type_id" ref="module_type_odoo" />
|
||||
</record>
|
||||
<!-- OCA Rules -->
|
||||
<record id="module_type_rule_oca_a" model="ir.module.type.rule">
|
||||
<field name="sequence">100</field>
|
||||
<field
|
||||
name="module_domain"
|
||||
>[('author_ids', '=', 'Odoo Community Association (OCA)')]</field>
|
||||
<field name="module_type_id" ref="module_type_oca" />
|
||||
</record>
|
||||
</odoo>
|
|
@ -0,0 +1,222 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * module_analysis
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 13.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2023-03-07 19:33+0000\n"
|
||||
"Last-Translator: Francesco Foresti <francesco.foresti@ooops404.com>\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 4.14.1\n"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_base_module_update__analyse_installed_modules
|
||||
msgid "Analyse Installed Modules"
|
||||
msgstr "Analizza Moduli Installati"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis
|
||||
msgid "Analysis"
|
||||
msgstr "Analisi"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids
|
||||
msgid "Authors"
|
||||
msgstr "Autori"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty
|
||||
msgid "CSS Code Quantity"
|
||||
msgstr "Quantità Codice CSS"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Code Size"
|
||||
msgstr "Dimensione Codice"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creato da"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creato il"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nome Visualizzato"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids
|
||||
msgid "Installed Modules"
|
||||
msgstr "Moduli Installati"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty
|
||||
msgid "Installed Modules Quantity"
|
||||
msgstr "Quantità Moduli Installati"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_by_type
|
||||
msgid "Installed Modules by Types"
|
||||
msgstr "Moduli Installati per Tipo"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty
|
||||
msgid "JS Code Quantity"
|
||||
msgstr "Quantità Codice JS"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author____last_update
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type____last_update
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Ultima Modifica il"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Ultimo aggiornamento di"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Ultimo aggiornamento il"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_module
|
||||
msgid "Module"
|
||||
msgstr "Modulo"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain
|
||||
msgid "Module Domain"
|
||||
msgstr "Dominio Modulo"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id
|
||||
msgid "Module Type"
|
||||
msgstr "Tipo Modulo"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id
|
||||
msgid "Module type"
|
||||
msgstr "Tipo Modulo"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids
|
||||
msgid "Modules"
|
||||
msgstr "Moduli"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_author
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_authors
|
||||
msgid "Modules Authors"
|
||||
msgstr "Autori Moduli"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty
|
||||
msgid "Modules Quantity"
|
||||
msgstr "Quantità Moduli"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_type
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_types
|
||||
msgid "Modules Types"
|
||||
msgstr "Tipologia Moduli"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_type_rule
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules
|
||||
msgid "Modules Types Rules"
|
||||
msgstr "Regole Tipologie Moduli"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty
|
||||
msgid "Python Code Quantity"
|
||||
msgstr "Quantità Codice Python"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Refresh Code Analysis"
|
||||
msgstr "Aggiorna Analisi Codice"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting
|
||||
msgid "Reporting"
|
||||
msgstr "Resoconti"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence
|
||||
msgid "Sequence"
|
||||
msgstr "Sequenza"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings
|
||||
msgid "Settings"
|
||||
msgstr "Impostazioni"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__smart_search
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__smart_search
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__smart_search
|
||||
msgid "Smart Search"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq
|
||||
msgid "The name of the modules author should be unique per database!"
|
||||
msgstr "Il nome dell'autore del modulo deve essere unico nel database!"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Type and Authors"
|
||||
msgstr "Tipologia e Autori"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model,name:module_analysis.model_base_module_update
|
||||
msgid "Update Module"
|
||||
msgstr "Aggiorna Modulo"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty
|
||||
msgid "XML Code Quantity"
|
||||
msgstr "Quantità Codice XML"
|
|
@ -0,0 +1,219 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * module_analysis
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 15.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: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_base_module_update__analyse_installed_modules
|
||||
msgid "Analyse Installed Modules"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis
|
||||
msgid "Analysis"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids
|
||||
msgid "Authors"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty
|
||||
msgid "CSS Code Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Code Size"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids
|
||||
msgid "Installed Modules"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty
|
||||
msgid "Installed Modules Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_by_type
|
||||
msgid "Installed Modules by Types"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty
|
||||
msgid "JS Code Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author____last_update
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type____last_update
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_module
|
||||
msgid "Module"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain
|
||||
msgid "Module Domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id
|
||||
msgid "Module Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id
|
||||
msgid "Module type"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids
|
||||
msgid "Modules"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_author
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_authors
|
||||
msgid "Modules Authors"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty
|
||||
msgid "Modules Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_type
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_types
|
||||
msgid "Modules Types"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_type_rule
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules
|
||||
msgid "Modules Types Rules"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty
|
||||
msgid "Python Code Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Refresh Code Analysis"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting
|
||||
msgid "Reporting"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq
|
||||
msgid "The name of the modules author should be unique per database!"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Type and Authors"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model,name:module_analysis.model_base_module_update
|
||||
msgid "Update Module"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.server,name:module_analysis.cron_module_analysis_ir_actions_server
|
||||
#: model:ir.cron,cron_name:module_analysis.cron_module_analysis
|
||||
#: model:ir.cron,name:module_analysis.cron_module_analysis
|
||||
msgid "Update Module Analysis"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty
|
||||
msgid "XML Code Quantity"
|
||||
msgstr ""
|
|
@ -0,0 +1,222 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * module_analysis
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 13.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2019-08-31 06:51+0000\n"
|
||||
"Last-Translator: 黎伟杰 <674416404@qq.com>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh_CN\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 3.8\n"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_base_module_update__analyse_installed_modules
|
||||
msgid "Analyse Installed Modules"
|
||||
msgstr "分析已安装的模块"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis
|
||||
msgid "Analysis"
|
||||
msgstr "分析"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__author_ids
|
||||
msgid "Authors"
|
||||
msgstr "作者"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__css_code_qty
|
||||
msgid "CSS Code Quantity"
|
||||
msgstr "CSS代码数量"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Code Size"
|
||||
msgstr "代码大小"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "创建者"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__create_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__create_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__create_date
|
||||
msgid "Created on"
|
||||
msgstr "创建时间"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__display_name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__display_name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "显示名称"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__id
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__id
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_ids
|
||||
msgid "Installed Modules"
|
||||
msgstr "已安装的模块"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_qty
|
||||
msgid "Installed Modules Quantity"
|
||||
msgstr "已安装的模块数量"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_module_by_type
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_by_type
|
||||
msgid "Installed Modules by Types"
|
||||
msgstr "按类型安装的模块"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__js_code_qty
|
||||
msgid "JS Code Quantity"
|
||||
msgstr "JS代码数量"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author____last_update
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type____last_update
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "最后修改时间"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_uid
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "最后更新者"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__write_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__write_date
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "最后更新时间"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_module
|
||||
msgid "Module"
|
||||
msgstr "模块"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_domain
|
||||
msgid "Module Domain"
|
||||
msgstr "模块域"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__module_type_id
|
||||
msgid "Module Type"
|
||||
msgstr "模块类型"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__module_type_id
|
||||
msgid "Module type"
|
||||
msgstr "模块类型"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__installed_module_ids
|
||||
msgid "Modules"
|
||||
msgstr "模块"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_author
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_author
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_authors
|
||||
msgid "Modules Authors"
|
||||
msgstr "模块作者"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__installed_module_qty
|
||||
msgid "Modules Quantity"
|
||||
msgstr "模块数量"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_type
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_types
|
||||
msgid "Modules Types"
|
||||
msgstr "模块类型"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.actions.act_window,name:module_analysis.action_ir_module_type_rule
|
||||
#: model:ir.model,name:module_analysis.model_ir_module_type_rule
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_type_rules
|
||||
msgid "Modules Types Rules"
|
||||
msgstr "模块类型规则"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__name
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__name
|
||||
msgid "Name"
|
||||
msgstr "名称"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__python_code_qty
|
||||
msgid "Python Code Quantity"
|
||||
msgstr "Python代码数量"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Refresh Code Analysis"
|
||||
msgstr "刷新代码分析"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_reporting
|
||||
msgid "Reporting"
|
||||
msgstr "报告"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__sequence
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__sequence
|
||||
msgid "Sequence"
|
||||
msgstr "序列"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.ui.menu,name:module_analysis.menu_module_analysis_settings
|
||||
msgid "Settings"
|
||||
msgstr "设置"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_author__smart_search
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type__smart_search
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_type_rule__smart_search
|
||||
msgid "Smart Search"
|
||||
msgstr ""
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.constraint,message:module_analysis.constraint_ir_module_author_name_uniq
|
||||
msgid "The name of the modules author should be unique per database!"
|
||||
msgstr "模块作者的名称应该是每个数据库唯一的!"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model_terms:ir.ui.view,arch_db:module_analysis.view_ir_module_module_form
|
||||
msgid "Type and Authors"
|
||||
msgstr "类型和作者"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model,name:module_analysis.model_base_module_update
|
||||
msgid "Update Module"
|
||||
msgstr "更新模块"
|
||||
|
||||
#. module: module_analysis
|
||||
#: model:ir.model.fields,field_description:module_analysis.field_ir_module_module__xml_code_qty
|
||||
msgid "XML Code Quantity"
|
||||
msgstr "XML代码数量"
|
|
@ -0,0 +1,4 @@
|
|||
from . import ir_module_author
|
||||
from . import ir_module_module
|
||||
from . import ir_module_type
|
||||
from . import ir_module_type_rule
|
|
@ -0,0 +1,45 @@
|
|||
# Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class IrModuleAuthor(models.Model):
|
||||
_name = "ir.module.author"
|
||||
_description = "Modules Authors"
|
||||
|
||||
name = fields.Char(required=True)
|
||||
|
||||
installed_module_ids = fields.Many2many(
|
||||
string="Modules",
|
||||
comodel_name="ir.module.module",
|
||||
relation="ir_module_module_author_rel",
|
||||
)
|
||||
|
||||
installed_module_qty = fields.Integer(
|
||||
string="Installed Modules Quantity",
|
||||
compute="_compute_installed_module_qty",
|
||||
store=True,
|
||||
)
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
"name_uniq",
|
||||
"unique(name)",
|
||||
"The name of the modules author should be unique per database!",
|
||||
),
|
||||
]
|
||||
|
||||
@api.depends("installed_module_ids")
|
||||
def _compute_installed_module_qty(self):
|
||||
for author in self:
|
||||
author.installed_module_qty = len(author.installed_module_ids)
|
||||
|
||||
@api.model
|
||||
def _get_or_create(self, name):
|
||||
authors = self.search([("name", "=", name)])
|
||||
if authors:
|
||||
return authors[0]
|
||||
else:
|
||||
return self.create({"name": name})
|
|
@ -0,0 +1,180 @@
|
|||
# Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from pygount import SourceAnalysis
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.modules.module import get_module_path
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IrModuleModule(models.Model):
|
||||
_inherit = "ir.module.module"
|
||||
|
||||
author_ids = fields.Many2many(
|
||||
string="Authors",
|
||||
comodel_name="ir.module.author",
|
||||
readonly=True,
|
||||
relation="ir_module_module_author_rel",
|
||||
)
|
||||
|
||||
module_type_id = fields.Many2one(
|
||||
string="Module Type", comodel_name="ir.module.type", readonly=True
|
||||
)
|
||||
|
||||
python_code_qty = fields.Integer(string="Python Code Quantity", readonly=True)
|
||||
|
||||
xml_code_qty = fields.Integer(string="XML Code Quantity", readonly=True)
|
||||
|
||||
js_code_qty = fields.Integer(string="JS Code Quantity", readonly=True)
|
||||
|
||||
css_code_qty = fields.Integer(string="CSS Code Quantity", readonly=True)
|
||||
scss_code_qty = fields.Integer(string="SCSS Code Quantity", readonly=True)
|
||||
|
||||
# Overloadable Section
|
||||
@api.model
|
||||
def _get_analyse_settings(self):
|
||||
"""Return a dictionnary of data analysed
|
||||
Overload this function if you want to analyse other data
|
||||
{
|
||||
'extension': {
|
||||
'data_to_analyse': 'field_name',
|
||||
},
|
||||
}, [...]
|
||||
extension: extension of the file, with the '.'
|
||||
data_to_analyse : possible value : code, documentation, empty, string
|
||||
field_name: Odoo field name to store the analysis
|
||||
"""
|
||||
return {
|
||||
".py": {"code": "python_code_qty"},
|
||||
".xml": {"code": "xml_code_qty"},
|
||||
".js": {"code": "js_code_qty"},
|
||||
".css": {"code": "css_code_qty"},
|
||||
".scss": {"code": "scss_code_qty"},
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _get_clean_analyse_values(self):
|
||||
"""List of fields to unset when a module is uninstalled"""
|
||||
return {
|
||||
"author_ids": [(6, 0, [])],
|
||||
"module_type_id": False,
|
||||
"python_code_qty": False,
|
||||
"xml_code_qty": 0,
|
||||
"js_code_qty": 0,
|
||||
"css_code_qty": 0,
|
||||
"scss_code_qty": 0,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _get_module_encoding(self, file_ext):
|
||||
return "utf-8"
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if vals.get("state", False) == "uninstalled" and "module_analysis" not in [
|
||||
x.name for x in self
|
||||
]:
|
||||
self.write(self._get_clean_analyse_values())
|
||||
return res
|
||||
|
||||
# Public Section
|
||||
def button_analyse_code(self):
|
||||
self._analyse_code()
|
||||
|
||||
@api.model
|
||||
def cron_analyse_code(self, domain=None):
|
||||
if domain is None:
|
||||
domain = [("state", "=", "installed")]
|
||||
self.search(domain)._analyse_code()
|
||||
|
||||
# Custom Section
|
||||
def _analyse_code(self):
|
||||
IrModuleAuthor = self.env["ir.module.author"]
|
||||
IrModuleTypeRule = self.env["ir.module.type.rule"]
|
||||
rules = IrModuleTypeRule.search([])
|
||||
|
||||
cfg = self.env["ir.config_parameter"]
|
||||
val = cfg.get_param("module_analysis.exclude_directories", "")
|
||||
exclude_directories = [x.strip() for x in val.split(",") if x.strip()]
|
||||
val = cfg.get_param("module_analysis.exclude_files", "")
|
||||
exclude_files = [x.strip() for x in val.split(",") if x.strip()]
|
||||
|
||||
for module in self:
|
||||
_logger.info("Analysing Code for module %s ..." % (module.name))
|
||||
|
||||
# Update Authors, based on manifest key
|
||||
authors = []
|
||||
if module.author and module.author[0] == "[":
|
||||
author_txt_list = safe_eval(module.author)
|
||||
else:
|
||||
author_txt_list = (module.author and module.author.split(",")) or []
|
||||
|
||||
author_txt_list = [x.strip() for x in author_txt_list]
|
||||
author_txt_list = [x for x in author_txt_list if x]
|
||||
for author_txt in author_txt_list:
|
||||
authors.append(IrModuleAuthor._get_or_create(author_txt))
|
||||
|
||||
author_ids = [x.id for x in authors]
|
||||
module.author_ids = author_ids
|
||||
|
||||
# Update Module Type, based on rules
|
||||
module_type_id = rules._get_module_type_id_from_module(module)
|
||||
module.module_type_id = module_type_id
|
||||
|
||||
# Get Path of module folder and parse the code
|
||||
module_path = get_module_path(module.name)
|
||||
|
||||
# Get Files
|
||||
analysed_datas = self._get_analyse_data_dict()
|
||||
file_extensions = analysed_datas.keys()
|
||||
file_list = self._get_files_to_analyse(
|
||||
module_path, file_extensions, exclude_directories, exclude_files
|
||||
)
|
||||
|
||||
for file_path, file_ext in file_list:
|
||||
file_res = SourceAnalysis.from_file(
|
||||
file_path, "", encoding=self._get_module_encoding(file_ext)
|
||||
)
|
||||
for k, v in analysed_datas.get(file_ext).items():
|
||||
v["value"] += getattr(file_res, k)
|
||||
|
||||
# Update the module with the datas
|
||||
values = {}
|
||||
for analyses in analysed_datas.values():
|
||||
for v in analyses.values():
|
||||
values[v["field"]] = v["value"]
|
||||
module.write(values)
|
||||
|
||||
@api.model
|
||||
def _get_files_to_analyse(
|
||||
self, path, file_extensions, exclude_directories, exclude_files
|
||||
):
|
||||
res = []
|
||||
if not path:
|
||||
return res
|
||||
for root, _, files in os.walk(path, followlinks=True):
|
||||
if set(Path(root).parts) & set(exclude_directories):
|
||||
continue
|
||||
for name in files:
|
||||
if name in exclude_files:
|
||||
continue
|
||||
filename, file_extension = os.path.splitext(name)
|
||||
if file_extension in file_extensions:
|
||||
res.append((os.path.join(root, name), file_extension))
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_analyse_data_dict(self):
|
||||
res_dict = self._get_analyse_settings().copy()
|
||||
for analyse_dict in res_dict.values():
|
||||
for analyse_type, v in analyse_dict.items():
|
||||
analyse_dict[analyse_type] = {"field": v, "value": 0}
|
||||
return res_dict
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class IrModuleType(models.Model):
|
||||
_name = "ir.module.type"
|
||||
_description = "Modules Types"
|
||||
_order = "sequence"
|
||||
|
||||
name = fields.Char(required=True)
|
||||
|
||||
sequence = fields.Integer()
|
||||
|
||||
installed_module_ids = fields.One2many(
|
||||
string="Installed Modules",
|
||||
comodel_name="ir.module.module",
|
||||
inverse_name="module_type_id",
|
||||
)
|
||||
|
||||
installed_module_qty = fields.Integer(
|
||||
string="Modules Quantity", compute="_compute_installed_module_qty", store=True
|
||||
)
|
||||
|
||||
@api.depends("installed_module_ids.module_type_id")
|
||||
def _compute_installed_module_qty(self):
|
||||
for module_type in self:
|
||||
module_type.installed_module_qty = len(module_type.installed_module_ids)
|
|
@ -0,0 +1,29 @@
|
|||
# Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
class IrModuleType(models.Model):
|
||||
_name = "ir.module.type.rule"
|
||||
_description = "Modules Types Rules"
|
||||
_order = "sequence"
|
||||
|
||||
sequence = fields.Integer()
|
||||
|
||||
module_domain = fields.Char(required=True, default="[]")
|
||||
|
||||
module_type_id = fields.Many2one(
|
||||
string="Module type", comodel_name="ir.module.type", required=True
|
||||
)
|
||||
|
||||
def _get_module_type_id_from_module(self, module):
|
||||
IrModuleModule = self.env["ir.module.module"]
|
||||
for rule in self:
|
||||
domain = safe_eval(rule.module_domain)
|
||||
domain.append(("id", "=", module.id))
|
||||
if IrModuleModule.search(domain):
|
||||
return rule.module_type_id.id
|
||||
return False
|
|
@ -0,0 +1,65 @@
|
|||
* Go to Apps / Module Analysis / Modules Types Rules
|
||||
|
||||
The Module types Rules are usefull to get the Type of a module, based on
|
||||
it information.
|
||||
|
||||
This module comes with default rules.
|
||||
|
||||
.. image:: ../static/description/default_module_type_rules.png
|
||||
|
||||
|
||||
You can add your custom rules to identify the modules your team have
|
||||
developped for exemple,
|
||||
|
||||
.. image:: ../static/description/add_module_type_rules.png
|
||||
|
||||
|
||||
to update the data manually, you have to :
|
||||
|
||||
* Go to 'Settings' / 'Technical' / 'Scheduled Actions'
|
||||
|
||||
* Run manually the action : 'Update Module Analysis'
|
||||
|
||||
This will update analysis of your installed modules.
|
||||
|
||||
to update the data automatically, you have to :
|
||||
|
||||
* Go to 'Settings' / 'Technical' / 'Scheduled Actions'
|
||||
|
||||
* Configure the action 'Update Module Analysis' and activate it. (By default, the cron is unactive and no analysis is done)
|
||||
|
||||
|
||||
Adding Extra data
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to analyse other data, (for exemple, having the number of HTML
|
||||
files), create a custom modules and overload the module model :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
class IrModuleModule(models.Model):
|
||||
_inherit = 'ir.module.module'
|
||||
|
||||
xml_documentation_qty = fields.Integer(
|
||||
string='Quantity of Comments in XML Files')
|
||||
|
||||
@api.model
|
||||
def _get_analyse_settings(self):
|
||||
res = super()._get_analyse_settings()
|
||||
if not '.html' in res:
|
||||
res['.html'] = {}
|
||||
res['.html']['documentation'] 'xml_documentation_qty'
|
||||
return res
|
||||
|
||||
Exclude files and directories
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Two parameters are availaible in 'Settings' / 'Technical' / 'Parameters'
|
||||
'System Parameters' :
|
||||
|
||||
.. image:: ../static/description/config_parameters.png
|
||||
|
||||
The list of folders and filename will be exclude from the analysis.
|
||||
You can change the default settings.
|
|
@ -0,0 +1 @@
|
|||
* Sylvain LE GAL (https://twitter.com/legalsylvain)
|
|
@ -0,0 +1,26 @@
|
|||
This module allows you to know 'how much code' is running on your Odoo
|
||||
instance, group by 'Type' (Odoo Core, OCA, other...)
|
||||
|
||||
This module can be usefull in the following cases :
|
||||
|
||||
* To analyse the size of your technical debt, regarding your Custom modules
|
||||
* To know the ratio between Odoo / OCA and Custom modules
|
||||
* To evaluate the amount to pay to odoo to upgrade your custom code, or the
|
||||
induced workload
|
||||
|
||||
.. image:: ../static/description/installed_modules_by_types.png
|
||||
|
||||
For that purpose, it adds new concepts
|
||||
|
||||
* ``ir.module.author``, based on the value ``author`` present in the manifest
|
||||
file.
|
||||
|
||||
.. image:: ../static/description/module_authors.png
|
||||
|
||||
* ``ir.module.type``, populated by default with Odoo and OCA values.
|
||||
|
||||
.. image:: ../static/description/module_types.png
|
||||
|
||||
Each installed modules have extra data in the 'Technical Data' tab :
|
||||
|
||||
.. image:: ../static/description/module_form.png
|
|
@ -0,0 +1,3 @@
|
|||
To use this module, you have to install the ``pygount`` python librairy.
|
||||
|
||||
``pip install pygount``
|
|
@ -0,0 +1,7 @@
|
|||
* Go to 'Apps' / 'Module Analysis' / 'Installed module by Types'
|
||||
|
||||
Open the stats to analyse the detail of the code installed
|
||||
|
||||
.. image:: ../static/description/analysis_pivot.png
|
||||
|
||||
.. image:: ../static/description/analysis_pie.png
|
|
@ -0,0 +1,4 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_ir_module_author_manager,ir_module_author_manager,model_ir_module_author,base.group_system,1,1,1,1
|
||||
access_ir_module_type_manager,ir_module_type_manager,model_ir_module_type,base.group_system,1,1,1,1
|
||||
access_ir_module_type_rule_manager,ir_module_type_rule_manager,model_ir_module_type_rule,base.group_system,1,1,1,1
|
|
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 9.2 KiB |
|
@ -0,0 +1,528 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!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 0.15.1: http://docutils.sourceforge.net/" />
|
||||
<title>Module Analysis</title>
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
:Author: David Goodger (goodger@python.org)
|
||||
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
|
||||
See http://docutils.sf.net/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: grey; } /* 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 {
|
||||
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" id="module-analysis">
|
||||
<h1 class="title">Module Analysis</h1>
|
||||
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<p><a class="reference external" 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" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/server-tools/tree/15.0/module_analysis"><img alt="OCA/server-tools" src="https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-module_analysis"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/149/15.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
|
||||
<p>This module allows you to know ‘how much code’ is running on your Odoo
|
||||
instance, group by ‘Type’ (Odoo Core, OCA, other…)</p>
|
||||
<p>This module can be usefull in the following cases :</p>
|
||||
<ul class="simple">
|
||||
<li>To analyse the size of your technical debt, regarding your Custom modules</li>
|
||||
<li>To know the ratio between Odoo / OCA and Custom modules</li>
|
||||
<li>To evaluate the amount to pay to odoo to upgrade your custom code, or the
|
||||
induced workload</li>
|
||||
</ul>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/installed_modules_by_types.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/installed_modules_by_types.png" />
|
||||
<p>For that purpose, it adds new concepts</p>
|
||||
<ul class="simple">
|
||||
<li><tt class="docutils literal">ir.module.author</tt>, based on the value <tt class="docutils literal">author</tt> present in the manifest
|
||||
file.</li>
|
||||
</ul>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_authors.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_authors.png" />
|
||||
<ul class="simple">
|
||||
<li><tt class="docutils literal">ir.module.type</tt>, populated by default with Odoo and OCA values.</li>
|
||||
</ul>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_types.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_types.png" />
|
||||
<p>Each installed modules have extra data in the ‘Technical Data’ tab :</p>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_form.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/module_form.png" />
|
||||
<p><strong>Table of contents</strong></p>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#installation" id="id1">Installation</a></li>
|
||||
<li><a class="reference internal" href="#configuration" id="id2">Configuration</a><ul>
|
||||
<li><a class="reference internal" href="#adding-extra-data" id="id3">Adding Extra data</a></li>
|
||||
<li><a class="reference internal" href="#exclude-files-and-directories" id="id4">Exclude files and directories</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#usage" id="id5">Usage</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="id6">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="id7">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="id8">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="id9">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="id10">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="installation">
|
||||
<h1><a class="toc-backref" href="#id1">Installation</a></h1>
|
||||
<p>To use this module, you have to install the <tt class="docutils literal">pygount</tt> python librairy.</p>
|
||||
<p><tt class="docutils literal">pip install pygount</tt></p>
|
||||
</div>
|
||||
<div class="section" id="configuration">
|
||||
<h1><a class="toc-backref" href="#id2">Configuration</a></h1>
|
||||
<ul class="simple">
|
||||
<li>Go to Apps / Module Analysis / Modules Types Rules</li>
|
||||
</ul>
|
||||
<p>The Module types Rules are usefull to get the Type of a module, based on
|
||||
it information.</p>
|
||||
<p>This module comes with default rules.</p>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/default_module_type_rules.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/default_module_type_rules.png" />
|
||||
</blockquote>
|
||||
<p>You can add your custom rules to identify the modules your team have
|
||||
developped for exemple,</p>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/add_module_type_rules.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/add_module_type_rules.png" />
|
||||
</blockquote>
|
||||
<p>to update the data manually, you have to :</p>
|
||||
<ul>
|
||||
<li><p class="first">Go to ‘Apps’ / ‘Update Apps List’</p>
|
||||
</li>
|
||||
<li><p class="first">Check the box ‘Analyse Installed modules’</p>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/base_module_update.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/base_module_update.png" />
|
||||
</blockquote>
|
||||
</li>
|
||||
</ul>
|
||||
<p>This will update analysis of your installed modules.</p>
|
||||
<p>to update the data automatically, you have to :</p>
|
||||
<ul class="simple">
|
||||
<li>Go to ‘Settings’ / ‘Technical’ / ‘Scheduled Actions’</li>
|
||||
<li>Configure the action ‘Update Module Analysis’. (By default, the analysis will be done nightly)</li>
|
||||
</ul>
|
||||
<div class="section" id="adding-extra-data">
|
||||
<h2><a class="toc-backref" href="#id3">Adding Extra data</a></h2>
|
||||
<p>If you want to analyse other data, (for exemple, having the number of HTML
|
||||
files), create a custom modules and overload the module model :</p>
|
||||
<pre class="code python literal-block">
|
||||
<span class="kn">from</span> <span class="nn">odoo</span> <span class="kn">import</span> <span class="n">api</span><span class="p">,</span> <span class="n">fields</span><span class="p">,</span> <span class="n">models</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">IrModuleModule</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
|
||||
<span class="n">_inherit</span> <span class="o">=</span> <span class="s1">'ir.module.module'</span>
|
||||
|
||||
<span class="n">xml_documentation_qty</span> <span class="o">=</span> <span class="n">fields</span><span class="o">.</span><span class="n">Integer</span><span class="p">(</span>
|
||||
<span class="n">string</span><span class="o">=</span><span class="s1">'Quantity of Comments in XML Files'</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@api</span><span class="o">.</span><span class="n">model</span>
|
||||
<span class="k">def</span> <span class="nf">_get_analyse_settings</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">res</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_get_analyse_settings</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="s1">'.html'</span> <span class="ow">in</span> <span class="n">res</span><span class="p">:</span>
|
||||
<span class="n">res</span><span class="p">[</span><span class="s1">'.html'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="n">res</span><span class="p">[</span><span class="s1">'.html'</span><span class="p">][</span><span class="s1">'documentation'</span><span class="p">]</span> <span class="s1">'xml_documentation_qty'</span>
|
||||
<span class="k">return</span> <span class="n">res</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="exclude-files-and-directories">
|
||||
<h2><a class="toc-backref" href="#id4">Exclude files and directories</a></h2>
|
||||
<p>Two parameters are availaible in ‘Settings’ / ‘Technical’ / ‘Parameters’
|
||||
‘System Parameters’ :</p>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/config_parameters.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/config_parameters.png" />
|
||||
</blockquote>
|
||||
<p>The list of folders and filename will be exclude from the analysis.
|
||||
You can change the default settings.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h1><a class="toc-backref" href="#id5">Usage</a></h1>
|
||||
<ul class="simple">
|
||||
<li>Go to ‘Apps’ / ‘Module Analysis’ / ‘Installed module by Types’</li>
|
||||
</ul>
|
||||
<p>Open the stats to analyse the detail of the code installed</p>
|
||||
<blockquote>
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/analysis_pivot.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/analysis_pivot.png" />
|
||||
<img alt="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/analysis_pie.png" src="https://raw.githubusercontent.com/OCA/server-tools/15.0/module_analysis/static/description/analysis_pie.png" />
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h1><a class="toc-backref" href="#id6">Bug Tracker</a></h1>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-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 smashing it by providing a detailed and welcomed
|
||||
<a class="reference external" href="https://github.com/OCA/server-tools/issues/new?body=module:%20module_analysis%0Aversion:%2015.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">
|
||||
<h1><a class="toc-backref" href="#id7">Credits</a></h1>
|
||||
<div class="section" id="authors">
|
||||
<h2><a class="toc-backref" href="#id8">Authors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>GRAP</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h2><a class="toc-backref" href="#id9">Contributors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>Sylvain LE GAL (<a class="reference external" href="https://twitter.com/legalsylvain">https://twitter.com/legalsylvain</a>)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h2><a class="toc-backref" href="#id10">Maintainers</a></h2>
|
||||
<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>This module is part of the <a class="reference external" href="https://github.com/OCA/server-tools/tree/15.0/module_analysis">OCA/server-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>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1 @@
|
|||
from . import test_module
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestModule(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.IrModuleModule = self.env["ir.module.module"]
|
||||
|
||||
def test_installed_modules(self):
|
||||
self.IrModuleModule.cron_analyse_code()
|
||||
installed_modules = self.IrModuleModule.search(
|
||||
[("state", "=", "installed"), ("name", "not like", "_test")]
|
||||
)
|
||||
for module in installed_modules:
|
||||
self.assertTrue(
|
||||
module.python_code_qty > 0
|
||||
or module.xml_code_qty > 0
|
||||
or module.js_code_qty > 0,
|
||||
"module '%s' doesn't have code analysed defined, whereas it is"
|
||||
" installed." % (module.name),
|
||||
)
|
||||
|
||||
def test_uninstalled_modules(self):
|
||||
uninstalled_modules = self.IrModuleModule.search([("state", "!=", "installed")])
|
||||
for module in uninstalled_modules:
|
||||
self.assertTrue(
|
||||
module.python_code_qty == 0,
|
||||
"module '%s' has python lines defined, whereas it is"
|
||||
" not installed." % (module.name),
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<menuitem
|
||||
id="menu_module_analysis"
|
||||
name="Analysis"
|
||||
parent="base.menu_management"
|
||||
sequence="100"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
<menuitem
|
||||
id="menu_module_analysis_settings"
|
||||
name="Settings"
|
||||
parent="menu_module_analysis"
|
||||
sequence="10"
|
||||
/>
|
||||
<menuitem
|
||||
id="menu_module_analysis_reporting"
|
||||
name="Reporting"
|
||||
parent="menu_module_analysis"
|
||||
sequence="20"
|
||||
/>
|
||||
</odoo>
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<record id="view_ir_module_author_form" model="ir.ui.view">
|
||||
<field name="model">ir.module.author</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<div class="oe_edit_only">
|
||||
<label for="name" />
|
||||
</div>
|
||||
<h1>
|
||||
<field name="name" />
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="installed_module_qty" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_ir_module_author_tree" model="ir.ui.view">
|
||||
<field name="model">ir.module.author</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
<field name="installed_module_qty" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_ir_module_author" model="ir.actions.act_window">
|
||||
<field name="name">Modules Authors</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.module.author</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_module_authors"
|
||||
parent="menu_module_analysis_settings"
|
||||
sequence="1"
|
||||
action="action_ir_module_author"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
</odoo>
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<record id="view_ir_module_module_form" model="ir.ui.view">
|
||||
<field name="model">ir.module.module</field>
|
||||
<field name="inherit_id" ref="base.module_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='state']/.." position="after">
|
||||
<button
|
||||
name="button_analyse_code"
|
||||
states="installed"
|
||||
string="Refresh Code Analysis"
|
||||
type="object"
|
||||
class="btn btn-primary"
|
||||
/>
|
||||
<group string="Code Size" col="4">
|
||||
<field name="python_code_qty" />
|
||||
<field name="xml_code_qty" />
|
||||
<field name="js_code_qty" />
|
||||
<field name="css_code_qty" />
|
||||
<field name="scss_code_qty" />
|
||||
</group>
|
||||
<group string="Type and Authors">
|
||||
<field name="author_ids" widget="many2many_tags" />
|
||||
<field name="module_type_id" />
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_ir_module_module_pivot" model="ir.ui.view">
|
||||
<field name="model">ir.module.module</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot>
|
||||
<field name="module_type_id" type="row" />
|
||||
<field name="python_code_qty" type="measure" />
|
||||
<field name="xml_code_qty" type="measure" />
|
||||
<field name="js_code_qty" type="measure" />
|
||||
<field name="css_code_qty" type="measure" />
|
||||
<field name="scss_code_qty" type="measure" />
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_ir_module_module_graph" model="ir.ui.view">
|
||||
<field name="model">ir.module.module</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph type="pie">
|
||||
<field name="module_type_id" type="row" />
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_ir_module_module_by_type" model="ir.actions.act_window">
|
||||
<field name="name">Installed Modules by Types</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.module.module</field>
|
||||
<field name="domain">[('state', '=', 'installed')]</field>
|
||||
<field name="view_mode">pivot,graph</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_module_by_type"
|
||||
parent="menu_module_analysis_reporting"
|
||||
sequence="5"
|
||||
action="action_ir_module_module_by_type"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
</odoo>
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<record id="view_ir_module_type_form" model="ir.ui.view">
|
||||
<field name="model">ir.module.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<div class="oe_edit_only">
|
||||
<label for="name" />
|
||||
</div>
|
||||
<h1>
|
||||
<field name="name" />
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_ir_module_type_tree" model="ir.ui.view">
|
||||
<field name="model">ir.module.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
<field name="installed_module_qty" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_ir_module_type" model="ir.actions.act_window">
|
||||
<field name="name">Modules Types</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.module.type</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_module_types"
|
||||
parent="menu_module_analysis_settings"
|
||||
sequence="2"
|
||||
action="action_ir_module_type"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
</odoo>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2019-Today: GRAP (<http://www.grap.coop/>)
|
||||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
-->
|
||||
<odoo>
|
||||
<record id="view_ir_module_type_rule_tree" model="ir.ui.view">
|
||||
<field name="model">ir.module.type.rule</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="module_type_id" />
|
||||
<field name="module_domain" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_ir_module_type_rule" model="ir.actions.act_window">
|
||||
<field name="name">Modules Types Rules</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.module.type.rule</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_module_type_rules"
|
||||
parent="menu_module_analysis_settings"
|
||||
sequence="3"
|
||||
action="action_ir_module_type_rule"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
</odoo>
|
|
@ -5,4 +5,5 @@ mako
|
|||
odoorpc
|
||||
openpyxl
|
||||
openupgradelib
|
||||
pygount
|
||||
sentry_sdk>=1.17.0
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../../../module_analysis
|
|
@ -0,0 +1,6 @@
|
|||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|