diff --git a/conf.py b/conf.py index 7f348b985f..e21c236414 100644 --- a/conf.py +++ b/conf.py @@ -1,9 +1,12 @@ import re import os +import shutil import sys from pathlib import Path +import docutils from pygments.lexers import JsonLexer, XmlLexer +from sphinx.ext import graphviz from sphinx.util import logging import sphinx @@ -53,6 +56,11 @@ #=== Extensions configuration ===# +source_read_replace_vals = { + 'GITHUB_PATH': f'https://github.com/odoo/odoo/blob/{version}', + 'GITHUB_ENT_PATH': f'https://github.com/odoo/enterprise/blob/{version}', +} + # Add extensions directory to PYTHONPATH extension_dir = Path('extensions') sys.path.insert(0, str(extension_dir.absolute())) @@ -75,7 +83,11 @@ ) else: odoo_dir = odoo_sources_dirs[0].resolve() + source_read_replace_vals['ODOO_RELPATH'] = '/../' + str(odoo_sources_dirs[0]) + source_read_replace_vals['ODOO_ABSPATH'] = str(odoo_dir) sys.path.insert(0, str(odoo_dir)) + import odoo.addons + odoo.addons.__path__.append(str(odoo_dir) + '/addons') if (3, 6) < sys.version_info < (3, 7): # Running odoo needs python 3.7 min but monkey patch version_info to be compatible with 3.6 sys.version_info = (3, 7, 0) @@ -98,12 +110,18 @@ ) odoo_dir_in_path = True +# Mapping between odoo models related to master data and the declaration of the +# data. This is used to point users to available xml_ids when giving values for +# a field with the autodoc_field extension. +model_references = { + 'account.account.type': 'addons/account/data/data_account_type.xml', + 'res.country': 'odoo/addons/base/data/res_country_data.xml', + 'res.currency': 'odoo/addons/base/data/res_currency_data.xml', +} + # The Sphinx extensions to use, as module names. # They can be extensions coming with Sphinx (named 'sphinx.ext.*') or custom ones. extensions = [ - # Parse Python docstrings (autodoc, automodule, autoattribute directives) - 'sphinx.ext.autodoc' if odoo_dir_in_path else 'autodoc_placeholder', - # Link sources in other projects (used to build the reference doc) 'sphinx.ext.intersphinx', @@ -133,7 +151,15 @@ extensions += [ 'sphinx.ext.linkcode', 'github_link', + # Parse Python docstrings (autodoc, automodule, autoattribute directives) + 'sphinx.ext.autodoc', + 'autodoc_field', ] +else: + extensions += [ + 'autodoc_placeholder', + ] +extensions.append('sphinx.ext.graphviz' if shutil.which('dot') else 'graphviz_placeholder') todo_include_todos = False @@ -265,6 +291,22 @@ # If true, show URL addresses after external links. latex_show_urls = 'True' +# https://github.com/sphinx-doc/sphinx/issues/4054#issuecomment-329097229 +def source_read_replace(app, docname, source): + """Substitute parts of strings with computed values. + + Since the RST substitution is not working everywhere, i.e. in directives' + options, we need to be able to input those values when reading the sources. + This is using the config `source_read_replace_vals`, mapping a name to its + replacement. This will look for the name surrounded by curly braces in the source. + + Meant to be connected to the `source-read` event. + """ + result = source[0] + for key in app.config.source_read_replace_vals: + result = result.replace(f"{{{key}}}", app.config.source_read_replace_vals[key]) + source[0] = result + def setup(app): # Generate all alternate URLs for each document @@ -273,12 +315,34 @@ def setup(app): app.add_config_value('versions', None, 'env') app.add_config_value('languages', None, 'env') app.add_config_value('is_remote_build', None, 'env') # Whether the build is remotely deployed + app.add_config_value('source_read_replace_vals', {}, 'env') + app.connect('source-read', source_read_replace) app.add_lexer('json', JsonLexer) app.add_lexer('xml', XmlLexer) app.connect('html-page-context', _generate_alternate_urls) + # Add a `condition` option on directives to ignore them based on config values + app.add_config_value('odoo_dir_in_path', None, 'env') + def context_eval(expr): + return eval(expr, {confval.name: confval.value for confval in app.config}) + + def patch(to_patch): + to_patch.option_spec['condition'] = context_eval + original_run = to_patch.run + def new_run(self): + if not self.options.get('condition', True): + return [] + return original_run(self) + to_patch.run = new_run + + for to_patch in ( + sphinx.directives.code.LiteralInclude, + docutils.parsers.rst.directives.tables.CSVTable, + ): + patch(to_patch) + def _generate_alternate_urls(app, pagename, templatename, context, doctree): """ Add keys of required alternate URLs for the current document in the rendering context. diff --git a/content/developer/howtos.rst b/content/developer/howtos.rst index 1b5972acfb..bea4d90796 100644 --- a/content/developer/howtos.rst +++ b/content/developer/howtos.rst @@ -13,3 +13,5 @@ Tutorials howtos/backend howtos/profilecode howtos/company + howtos/accounting_localization + howtos/translations diff --git a/content/developer/howtos/accounting_localization.rst b/content/developer/howtos/accounting_localization.rst new file mode 100644 index 0000000000..4740fbdbd5 --- /dev/null +++ b/content/developer/howtos/accounting_localization.rst @@ -0,0 +1,386 @@ + +======================= +Accounting localization +======================= + +.. warning:: + + This tutorial requires knowledge about how to build a module in Odoo (see + :doc:`/developer/howtos/backend`). + + +Installation procedure +====================== + +On installing the `account <{GITHUB_PATH}/addons/account>`_ module, the localization module corresponding to the country code of the company is installed automatically. +In case of no country code set or no localization module found, the `l10n_generic_coa <{GITHUB_PATH}/addons/l10n_generic_coa>`_ (US) localization module is installed by default. +Check `post init hook <{GITHUB_PATH}/addons/account/__init__.py>`_ for details. + +For example, `l10n_ch <{GITHUB_PATH}/addons/l10n_ch>`_ will be installed if the company has ``Switzerland`` as country. + +Building a localization module +============================== + +The structure of a basic ``l10n_XX`` module may be described with the following :file:`__manifest__.py` file: + +.. code-block:: py + + { + "name": "COUNTRY - Accounting", + "version": "1.0.0", + "category": "Accounting/Localizations/Account Charts", + "license": "LGPL-3", + "depends": [ + "account", + # "l10n_multilang", + ], + "data": [ + # Chart of Accounts + "data/account_chart_template_data.xml", + "data/account_account_tag_data.xml", + "data/account.account.template.csv", + "data/account.group.template.csv", + + # Taxes + "data/account_tax_group_data.xml", + "data/account_tax_report_data.xml", + "data/account_tax_template_data.xml", + "data/account_fiscal_position_template_data.xml", + "data/account_account_template_post_data.xml", + + "data/account_chart_post_data.xml", + "data/account_chart_template_try_loading.xml", + + # Views and others + "views/xxxmodel_views.xml" + ], + "demo": [ + "demo/demo_company.xml", + ] + } + + +In the first file :file:`data/account_chart_template_data.xml`, we set the name for the chart of accounts along with some basic fields. + +.. seealso:: + :ref:`Chart Template References ` + +.. example:: + `addons/l10n_ch/data/l10n_ch_chart_data.xml <{GITHUB_PATH}/addons/l10n_ch/data/l10n_ch_chart_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ch/data/l10n_ch_chart_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: l10nch_chart_template + :end-at: + + +.. note:: + + Recommended **xmlid** for the record is `chart_template`. + If you need many chart of accounts, you can add some suffixes, i.e. `chart_template_XXX`. + + +Chart of Accounts +================= + +Account tags +------------ + +.. seealso:: + :ref:`Account Tag References ` + +Tags are a way to sort accounts. +For example, imagine you want to create a financial report having multiple lines but you have no way to find a rule to dispatch the accounts according to their ``code``. +The solution is the usage of tags, one for each report line, to filter accounts like you want. + +Put the tags in the :file:`data/account_account_tag_data.xml` file. + +.. example:: + `addons/l10n_lt/data/account.account.template.csv <{GITHUB_PATH}/addons/l10n_lt/data/account.account.template.csv>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_lt/data/account.account.template.csv + :condition: odoo_dir_in_path + :language: csv + :end-at: account_account_template_1201 + +.. example:: + `addons/l10n_at/data/account_account_template.xml <{GITHUB_PATH}/addons/l10n_at/data/account_account_template.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_at/data/account_account_template.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: chart_at_template_0010 + :end-at: + +.. _howtos/account_localization/accounts: + +Accounts +-------- + +.. seealso:: + - :ref:`Account References ` + - :doc:`/applications/finance/accounting/getting_started/initial_configuration/chart_of_accounts` + +Obviously, :guilabel:`Chart of Accounts` cannot exist without :guilabel:`Accounts`. You need to specify them in :file:`data/account.account.template.csv`. + +.. example:: + `addons/l10n_ch/data/account.account.template.csv <{GITHUB_PATH}/addons/l10n_ch/data/account.account.template.csv>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ch/data/account.account.template.csv + :condition: odoo_dir_in_path + :language: csv + :end-at: ch_coa_1171 + +CSV is prefered but you may use XML format instead. + +.. example:: + `addons/l10n_at/data/account_account_template.xml <{GITHUB_PATH}/addons/l10n_at/data/account_account_template.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_at/data/account_account_template.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: chart_at_template_0010 + :end-at: + +.. warning:: + + - Avoid the usage of liquidity ``account.account.type``! + Indeed, the bank & cash accounts are created directly at the installation of the localization module and then, are linked to an ``account.journal``. + - Only one account of type payable/receivable is enough for the generic case. We need to define a PoS receivable account as well however. (linked in the CoA) + - Don't create too many accounts: 200-300 is enough. But mostly, we try to find a good balance where the CoA needs minimal adapting for most companies afterwards. + +Next settings for the chart of accounts are set in a separate file, because we need to provide a :ref:`list of accounts ` first. In :file:`data/account_chart_post_data.xml`, we set some default accounts: + +.. todo add reference to account_id in CoA + +.. example:: + `addons/l10n_ch/data/l10n_ch_chart_post_data.xml <{GITHUB_PATH}/addons/l10n_ch/data/l10n_ch_chart_post_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ch/data/l10n_ch_chart_post_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: l10nch_chart_template + :end-at: + + +Account groups +-------------- + +.. seealso:: + :ref:`Account Group References ` + +Account groups allow describing the hierarchical structure of the chart of accounts. The filter needs to be activated in the report and then when you decollapse into journal entries it will show the parents of the account. + +It works with the prefix *start*/*end*, so every account where the code starts with something between *start* and *end* will have this account.group as the parent group. Furthermore, the account groups can have a parent account group as well to form the hierarchy. + + +.. example:: + `addons/l10n_il/data/account.group.template.csv <{GITHUB_PATH}/addons/l10n_il/data/account.group.template.csv>`_ + + .. csv-table:: + :condition: odoo_dir_in_path + :file: {ODOO_ABSPATH}/addons/l10n_il/data/account.group.template.csv + :widths: 20,20,20,20,20 + :header-rows: 1 + +Taxes +----- + +.. seealso:: + - :ref:`Tax References ` + - :doc:`/applications/finance/accounting/taxation/taxes/taxes` + +To add taxes you first need to specify tax groups. You normally need just one tax group for every tax rate, except for the 0% as you need to often distinguish between exempt, 0%, not subject, ... taxes. +This model only has two required fields: *name* and *country*. Create the file :file:`data/account_tax_group_data.xml` and list the groups: + +.. code-block:: xml + + + + + TVA 0% + + + + ... + + + +.. example:: + `addons/l10n_ch/data/account_tax_group_data.xml <{GITHUB_PATH}/addons/l10n_ch/data/account_tax_group_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ch/data/account_tax_group_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-after: + +.. example:: + `addons/l10n_uk/data/account.tax.group.csv <{GITHUB_PATH}/addons/l10n_uk/data/account.tax.group.csv>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_uk/data/account.tax.group.csv + :condition: odoo_dir_in_path + :language: csv + + +Now you can add the taxes via :file:`data/account_tax_template_data.xml` file. The first tax you define that is purchase/sale also becomes the default purchase/sale tax for your products. + + +.. example:: + `addons/l10n_ae/data/account_tax_template_data.xml <{GITHUB_PATH}/addons/l10n_ae/data/account_tax_template_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ae/data/account_tax_template_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: uae_sale_tax_5_dubai + :end-at: + +If some accounts should use default taxes, you can set them up in :file:`data/account_account_template_post_data.xml` + +Tax Report +---------- + +.. raw:: html + +
Enterprise feature
+ +The tax report is declared in the :guilabel:`Invoicing` (`account`) app, but the report is only accessible when :guilabel:`Accounting` (`account_accountant`) is installed. + +.. seealso:: + - :ref:`Tax Report Line References ` + - :doc:`/applications/finance/accounting/reporting/declarations/tax_returns` + +In the previous section, you noticed the fields `invoice_repartition_line_ids` or `refund_repartition_line_ids` and probably understood nothing about them. Good news: you are not alone on this incomprehension. Bad news: you have to figure it out a bit. The topic is complicated. Indeed: + +.. graphviz:: accounting_localization/tax_report.dot + :class: overflow-auto + +The simple version is that, in the tax template, you indicate in the invoice/refund repartition lines whether the base or a percentage of the tax needs to be reported in which report line (through the *minus/plus_report_line_ids* fields). +It becomes clear also when you check the tax configuration in the Odoo interface (or check the docs :ref:`Tax References `, :ref:`Tax Repartition References `). +And fortunately we have a presentation explaining the tax reports (as in version 13.0) in details: + +.. youtube:: PuXE_NyFRTM + :align: right + :width: 700 + :height: 394 + +So, once you have properly configured taxes, you just need to add the :file:`data/account_tax_report_data.xml` file with a record for your `account.tax.report` at the beginning: + +.. code-block:: xml + + + + Tax Report + + + + ... + + +... followed by the declaration of its lines, as `account.tax.report.line` records. + +.. example:: + `addons/l10n_au/data/account_tax_report_data.xml <{GITHUB_PATH}/addons/l10n_au/data/account_tax_report_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_au/data/account_tax_report_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: tax_report + :end-before: account_tax_report_gstrpt_g3 + + + +Fiscal positions +---------------- + +.. seealso:: + - :ref:`Fiscal Position References ` + - :doc:`/applications/finance/accounting/taxation/taxes/fiscal_positions` + +Specify fiscal positions in the :file:`data/account_fiscal_position_template_data.xml` file. + +.. example:: + `addons/l10n_es/data/account_fiscal_position_template_data.xml <{GITHUB_PATH}/addons/l10n_es/data/account_fiscal_position_template_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_es/data/account_fiscal_position_template_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: fp_nacional + :end-before: fp_intra + +Final steps +=========== + +The last step when installing a localization module is to try to apply its chart of accounts to the current company (if it does not already have one). +The file :file:`data/account_chart_template_try_loading.xml` is responsible for that. + +.. example:: + `addons/l10n_ch/data/account_chart_template_data.xml <{GITHUB_PATH}/addons/l10n_ch/data/account_chart_template_data.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ch/data/account_chart_template_data.xml + :condition: odoo_dir_in_path + :language: xml + :start-at: + +Finally, you may add a demo company, so the localization can easily be tested in demo mode. + +.. example:: + `addons/l10n_ch/demo/demo_company.xml <{GITHUB_PATH}/addons/l10n_ch/demo/demo_company.xml>`_ + + .. literalinclude:: {ODOO_RELPATH}/addons/l10n_ch/demo/demo_company.xml + :condition: odoo_dir_in_path + :language: xml + :start-after: + :end-before: + +Accounting reports +================== + +.. raw:: html + +
Enterprise feature
+ +.. seealso:: + :doc:`/applications/finance/accounting/reporting/overview` + +Accounting reports should be added via a separate module `l10n_XX_reports` that should go to the `enterprise repository <{GITHUB_ENT_PATH}>`_. + +Basic :file:`__manifest__.py` file for such a module looks as following: + + +.. code-block:: py + + { + "name": "COUNTRY - Accounting Reports", + "category": "Accounting/Localizations/Reporting", + "version": "1.0.0", + "license": "OEEL-1", + "depends": [ + "l10n_XX", "account_reports" + ], + "data": [ + "data/account_financial_html_report_data.xml", + ], + "auto_install": True, + } + + +Functional overview of financial reports is here: :doc:`/applications/finance/accounting/reporting/overview/main_reports`. + +Some good examples: + +* `l10n_ch_reports/data/account_financial_html_report_data.xml <{GITHUB_ENT_PATH}/l10n_ch_reports/data/account_financial_html_report_data.xml>`_ +* `l10n_be_reports/data/account_financial_html_report_data.xml <{GITHUB_ENT_PATH}/l10n_be_reports/data/account_financial_html_report_data.xml>`_ + +For the fields' meaning, dive directly to the source: + +* `account.financial.html.report (v15) `_ +* `account.financial.html.report.line (v15) `_ + +The menu for the new report is created automatically. By default, it is located under :menuselection:`Accounting -> Reporting`. +To create a dedicated section in the :guilabel:`Reporting` menu, you need to create a new `ir.ui.menu` record (usually in the main `l10n_XX` module) and set it as `parent_id` field in the `account.financial.html.report` model. Example for the Belgian localization: + +* `ir.ui.menu record in l10n_be <{GITHUB_PATH}/addons/l10n_be/data/menuitem_data.xml>`_ +* `parent_id field in l10n_be_reports (v15) `_ diff --git a/content/developer/howtos/accounting_localization/tax_report.dot b/content/developer/howtos/accounting_localization/tax_report.dot new file mode 100644 index 0000000000..1617088b04 --- /dev/null +++ b/content/developer/howtos/accounting_localization/tax_report.dot @@ -0,0 +1,73 @@ +digraph foo { + graph [ + newrank=true, + overlap=false, + ]; + node [ + fontname="Ubuntu" + fontsize=10, + style="filled,setlinewidth(6)", + shape=box, + height=0.1, + width=0.1, + ]; + edge [ + fontsize=8, + ]; + res_country[label="res.country", fillcolor=white, penwidth=1]; + subgraph cluster_invoice { + style = filled; + label = "Invoices"; + color = lightyellow; + node [style=filled, color=white]; + account_move_line[label="account.move.line"] + account_tax[label="account.tax"] + account_tax_repartition_line[label="account.tax.repartition.line"]; + account_account_tag[label="account.account.tag"]; + account_move_line -> account_tax [label="tax_ids | tax_line_ids"]; + account_move_line -> account_tax_repartition_line [label="tax_repartition_line_id"]; + account_move_line -> account_account_tag [label="tag_ids"]; + account_tax_repartition_line -> account_account_tag [label="tag_ids"]; + account_tax -> account_tax_repartition_line [label="1 for base, 1..* for tax amount"]; + } + subgraph cluster_reporting { + style = filled; + label = "Reporting"; + color = mistyrose; + node [style=filled, color=white]; + account_tax_report_line[label="account.tax.report.line"]; + account_generic_tax_report[label="account.generic.tax.report"]; + account_tax_report[label="account.tax.report"]; + account_tax_report -> account_generic_tax_report [label="Calls and displays", dir=back]; + account_tax_report -> account_tax_report_line [label="0..*"] + } + subgraph cluster_templates { + style = filled; + label = "Templates"; + color = lightblue; + node [style=filled, color=white]; + account_tax_template[label="account.tax.template"]; + account_tax_repartition_line_template[label="account.tax.repartition.line.template"]; + account_tax_template -> account_tax_repartition_line_template [label="1 for base, 1..* for tax amount"]; + } + { + rank=same; + account_tax; + account_tax_repartition_line; + account_account_tag; + res_country; + } + { + rank=same; + account_tax_report; + account_tax_report_line; + account_tax_template; + account_tax_repartition_line_template; + } + account_tax -> account_tax_template [label="Creates when installing CoA", dir=back]; + account_tax_repartition_line -> account_tax_repartition_line_template [label="Creates when installing CoA", dir=back]; + account_tax_repartition_line_template -> account_account_tag [label="tag_ids"]; + account_tax_report_line -> account_account_tag [label="Creates (+ and -)"]; + account_tax_report -> res_country [label="0..1"]; + account_account_tag -> res_country [label="0..1"]; +} \ No newline at end of file diff --git a/content/developer/misc/i18n/translations.rst b/content/developer/howtos/translations.rst similarity index 100% rename from content/developer/misc/i18n/translations.rst rename to content/developer/howtos/translations.rst diff --git a/content/developer/misc/i18n/translations/po-export.png b/content/developer/howtos/translations/po-export.png similarity index 100% rename from content/developer/misc/i18n/translations/po-export.png rename to content/developer/howtos/translations/po-export.png diff --git a/content/developer/misc.rst b/content/developer/misc.rst index 0b30597af4..57294d4597 100644 --- a/content/developer/misc.rst +++ b/content/developer/misc.rst @@ -8,5 +8,4 @@ Misc :titlesonly: misc/api - misc/i18n misc/other diff --git a/content/developer/misc/i18n.rst b/content/developer/misc/i18n.rst deleted file mode 100644 index 3069e91ad3..0000000000 --- a/content/developer/misc/i18n.rst +++ /dev/null @@ -1,11 +0,0 @@ -:nosearch: - -==================== -Internationalization -==================== - -.. toctree:: - :titlesonly: - - i18n/localization - i18n/translations diff --git a/content/developer/misc/i18n/localization.rst b/content/developer/misc/i18n/localization.rst deleted file mode 100644 index 3aa6a336f6..0000000000 --- a/content/developer/misc/i18n/localization.rst +++ /dev/null @@ -1,425 +0,0 @@ - -======================= -Accounting Localization -======================= - -.. warning:: - - This tutorial requires knowledges about how to build a module in Odoo (see - :doc:`/developer/howtos/backend`). - -Building a localization module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When installing the ``accounting`` module, the localization module corresponding to the country code of the company is installed automatically. -In case of no country code set or no localization module found, the ``l10n_generic_coa`` (US) localization module is installed by default. - -For example, ``l10n_be`` will be installed if the company has ``Belgium`` as country. - -This behavior is allowed by the presence of a *.xml* file containing the following code: - -.. code-block:: xml - - - - - -Where ``module.template_xmlid`` is the **fully-qualified** xmlid of the corresponding template. - -Usually located in the ``data`` folder, it must be loaded at the very last in the ``__manifest__.py`` file. - -.. danger:: - - If the *.xml* file is missing, the right chart of accounts won't be loaded on time! - - -Configuring my own Chart of Accounts? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -First of all, before I proceed, we need to talk about the templates. A template is a record that allows replica of itself. -This mechanism is needed when working in multi-companies. For example, the creation of a new account is done using the ``account.account.template`` model. -However, each company using this chart of accounts will be linked to a replica having ``account.account`` as model. -So, the templates are never used directly by the company. - -Then, when a chart of accounts needs to be installed, all templates dependent of this one will create a replica and link this newly generated record to the company's user. -It means all such templates must be linked to the chart of accounts in some way. To do so, each one must reference the desired chart of accounts using the ``chart_template_id`` field. -For this reason, we need to define an instance of the ``account.chart.template`` model before creating its templates. - -.. code-block:: xml - - - - ... - - - - - - ... - - - ... - - - - - - ... - - - - - - - - - - - - - - -For example, let's take a look to the Belgium chart of accounts. - -.. code-block:: xml - - - Belgian PCMN - - 550 - 570 - - - -Now that the chart of accounts is created, we can focus on the creation of the templates. -As said previously, each record must reference this record through the ``chart_template_id`` field. -If not, the template will be ignored. The following sections show in details how to create these templates. - -Adding a new account to my Chart of Accounts -############################################ - -It's time to create our accounts. It consists to creating records of ``account.account.template`` type. -Each ``account.account.template`` is able to create an ``account.account`` for each company. - -.. code-block:: xml - - - - ... - - - ... - - - ... - - - - - - - - - - - - - - - - - -Some of the described fields above deserve a bit more explanation. - -The ``user_type_id`` field requires a value of type ``account.account.type``. -Although some additional types could be created in a localization module, we encourage the usage of the existing types in the `account/data/data_account_type.xml `_ file. -The usage of these generic types ensures the generic reports working correctly in addition to those that you could create in your localization module. - -.. warning:: - - Avoid the usage of liquidity ``account.account.type``! - Indeed, the bank & cash accounts are created directly at the installation of the localization module and then, are linked to an ``account.journal``. - -.. warning:: - - Only one account of type payable/receivable is enough. - -Although the ``tag_ids`` field is optional, this one remains a very powerful feature. -Indeed, this one allows you to define some tags for your accounts to spread them correctly on your reports. -For example, suppose you want to create a financial report having multiple lines but you have no way to find a rule to dispatch the accounts according their ``code`` or ``name``. -The solution is the usage of tags, one for each report line, to spread and aggregate your accounts like you want. - -Like any other record, a tag can be created with the following xml structure: - -.. code-block:: xml - - - - ... - - - ... - - -As you can well imagine with the usage of tags, this feature can also be used with taxes. - -An examples coming from the ``l10n_be`` module: - -.. code-block:: xml - - - Clients - 4000 - - - - -.. warning:: - - Don't create too much accounts: 200-300 is enough. - -Adding a new tax to my Chart of Accounts -######################################## - -To create a new tax record, you just need to follow the same process as the creation of accounts. -The only difference being that you must use the ``account.tax.template`` model. - -.. code-block:: xml - - - - ... - - - - - - - - - - - - - - - ... - - - - - - - - - - - - ... - - - - - - - - - - - - - - - - - - ... - - - - - -An example found in the ``l10n_pl`` module: - -.. code-block:: xml - - - - VAT - leasing pojazdu(sale) - VLP - 1.00 - - group - sale - - - - - - -Adding a new fiscal position to my Chart of Accounts -#################################################### - -.. note:: - - If you need more information about what is a fiscal position and how it works in Odoo, - please refer to :doc:`/applications/finance/accounting/taxation/taxes/fiscal_positions`. - -To create a new fiscal position, simply use the ``account.fiscal.position.template`` model: - -.. code-block:: xml - - - - ... - - - - - - ... - - -Adding the properties to my Chart of Accounts -############################################# - -When the whole accounts are generated, you have the possibility to override the newly generated chart of accounts by adding some properties that correspond to default accounts used in certain situations. -This must be done after the creation of accounts before each one must be linked to the chart of accounts. - -.. code-block:: xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -For example, let's come back to the Belgium PCMN. This chart of accounts is override in this way to add some properties. - -.. code-block:: xml - - - - - - - - - - - -How to create a new bank operation model? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. note:: - - How a bank operation model works exactly in Odoo? See :doc:`/applications/finance/accounting/bank/reconciliation/reconciliation_models`. - -Since ``V10``, a new feature is available in the bank statement reconciliation widget: the bank operation model. -This allows the user to pre-fill some accounting entries with a single click. -The creation of an ``account.reconcile.model.template`` record is quite easy: - -.. code-block:: xml - - - - ... - - - - - - - - - - - - ... - - - ... - - - ... - - - - - - - - ... - ... - ... - - - -How to create a new dynamic report? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you need to add some reports on your localization, you need to create a new module named **l10n_xx_reports**. -Furthermore, this additional module must be present in the ``enterprise`` repository and must have at least two dependencies, -one to bring all the stuff for your localization module and one more, ``account_reports``, to design dynamic reports. - -.. code-block:: py - - 'depends': ['l10n_xx', 'account_reports'], - -Once it's done, you can start the creation of your report statements. The documentation is available in the following `slides `_. diff --git a/content/developer/reference/backend.rst b/content/developer/reference/backend.rst index ae698ce64c..c6971134b2 100644 --- a/content/developer/reference/backend.rst +++ b/content/developer/reference/backend.rst @@ -17,3 +17,4 @@ Backend backend/testing backend/http backend/mixins + backend/standard_modules diff --git a/content/developer/reference/backend/standard_modules.rst b/content/developer/reference/backend/standard_modules.rst new file mode 100644 index 0000000000..7eeb3a1135 --- /dev/null +++ b/content/developer/reference/backend/standard_modules.rst @@ -0,0 +1,10 @@ +:nosearch: + +================ +Standard modules +================ + +.. toctree:: + :titlesonly: + + standard_modules/account diff --git a/content/developer/reference/backend/standard_modules/account.rst b/content/developer/reference/backend/standard_modules/account.rst new file mode 100644 index 0000000000..ed1e6d6f14 --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account.rst @@ -0,0 +1,17 @@ +:nosearch: + +========== +Accounting +========== + +.. toctree:: + :titlesonly: + + account/account_account_tag + account/account_account + account/account_chart_template + account/account_fiscal_position + account/account_group + account/account_tax_report_line + account/account_tax + account/account_tax_repartition diff --git a/content/developer/reference/backend/standard_modules/account/account_account.rst b/content/developer/reference/backend/standard_modules/account/account_account.rst new file mode 100644 index 0000000000..7399a9cfb7 --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_account.rst @@ -0,0 +1,19 @@ +.. _reference/account_account: + +======= +Account +======= + +.. automodel:: odoo.addons.account.models.chart_template.AccountAccountTemplate + :main: + + .. autofield:: name + .. autofield:: currency_id + .. autofield:: code + .. autofield:: user_type_id + .. autofield:: reconcile + .. autofield:: note + .. autofield:: tax_ids + .. autofield:: nocreate + .. autofield:: chart_template_id + .. autofield:: tag_ids diff --git a/content/developer/reference/backend/standard_modules/account/account_account_tag.rst b/content/developer/reference/backend/standard_modules/account/account_account_tag.rst new file mode 100644 index 0000000000..bd13aea945 --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_account_tag.rst @@ -0,0 +1,16 @@ +.. _reference/account_account_tag: + +=========== +Account Tag +=========== + +.. automodel:: odoo.addons.account.models.account_account_tag.AccountAccountTag + :main: + + .. autofield:: name + .. autofield:: applicability + .. autofield:: color + .. autofield:: active + .. autofield:: tax_report_line_ids + .. autofield:: tax_negate + .. autofield:: country_id diff --git a/content/developer/reference/backend/standard_modules/account/account_chart_template.rst b/content/developer/reference/backend/standard_modules/account/account_chart_template.rst new file mode 100644 index 0000000000..70d3bfe83f --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_chart_template.rst @@ -0,0 +1,50 @@ +.. _reference/account_chart_template: + +============== +Chart Template +============== + +.. automodel:: odoo.addons.account.models.chart_template.AccountChartTemplate + :main: + + .. autofield:: name + .. autofield:: parent_id + .. autofield:: code_digits + .. autofield:: visible + .. autofield:: currency_id + .. autofield:: country_id + .. autofield:: use_anglo_saxon + .. autofield:: bank_account_code_prefix + .. autofield:: cash_account_code_prefix + .. autofield:: transfer_account_code_prefix + .. autofield:: account_ids + .. autofield:: income_currency_exchange_account_id + .. autofield:: expense_currency_exchange_account_id + .. autofield:: account_journal_suspense_account_id + .. autofield:: account_journal_payment_debit_account_id + .. autofield:: account_journal_payment_credit_account_id + .. autofield:: default_cash_difference_income_account_id + .. autofield:: default_cash_difference_expense_account_id + .. autofield:: default_pos_receivable_account_id + .. autofield:: property_account_receivable_id + .. autofield:: property_account_payable_id + .. autofield:: property_account_expense_categ_id + .. autofield:: property_account_income_categ_id + .. autofield:: property_account_expense_id + .. autofield:: property_account_income_id + .. autofield:: property_stock_account_input_categ_id + .. autofield:: property_stock_account_output_categ_id + .. autofield:: property_stock_valuation_account_id + .. autofield:: property_tax_payable_account_id + .. autofield:: property_tax_receivable_account_id + .. autofield:: property_advance_tax_payment_account_id + .. autofield:: property_cash_basis_base_account_id + + + +.. automodel:: odoo.addons.l10n_multilang.models.account.AccountChartTemplate + + Multi language support for Chart of Accounts, Taxes, Tax Codes, Journals, + Accounting Templates, Analytic Chart of Accounts and Analytic Journals. + + .. autofield:: spoken_languages diff --git a/content/developer/reference/backend/standard_modules/account/account_fiscal_position.rst b/content/developer/reference/backend/standard_modules/account/account_fiscal_position.rst new file mode 100644 index 0000000000..cd2ffa6bff --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_fiscal_position.rst @@ -0,0 +1,22 @@ +.. _reference/account_fiscal_position: + +=============== +Fiscal Position +=============== + +.. automodel:: odoo.addons.account.models.chart_template.AccountFiscalPositionTemplate + :main: + + .. autofield:: sequence + .. autofield:: name + .. autofield:: chart_template_id + .. autofield:: account_ids + .. autofield:: tax_ids + .. autofield:: note + .. autofield:: auto_apply + .. autofield:: vat_required + .. autofield:: country_id + .. autofield:: country_group_id + .. autofield:: state_ids + .. autofield:: zip_from + .. autofield:: zip_to diff --git a/content/developer/reference/backend/standard_modules/account/account_group.rst b/content/developer/reference/backend/standard_modules/account/account_group.rst new file mode 100644 index 0000000000..7d1ba8384f --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_group.rst @@ -0,0 +1,14 @@ +.. _reference/account_group: + +============= +Account Group +============= + +.. automodel:: odoo.addons.account.models.chart_template.AccountGroupTemplate + :main: + + .. autofield:: parent_id + .. autofield:: name + .. autofield:: code_prefix_start + .. autofield:: code_prefix_end + .. autofield:: chart_template_id diff --git a/content/developer/reference/backend/standard_modules/account/account_tax.rst b/content/developer/reference/backend/standard_modules/account/account_tax.rst new file mode 100644 index 0000000000..48a92317f5 --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_tax.rst @@ -0,0 +1,28 @@ +.. _reference/account_tax: + +===== +Taxes +===== + +.. automodel:: odoo.addons.account.models.chart_template.AccountTaxTemplate + :main: + + .. autofield:: chart_template_id + .. autofield:: name + .. autofield:: type_tax_use + .. autofield:: tax_scope + .. autofield:: amount_type + .. autofield:: active + .. autofield:: children_tax_ids + .. autofield:: sequence + .. autofield:: amount + .. autofield:: description + .. autofield:: price_include + .. autofield:: include_base_amount + .. autofield:: is_base_affected + .. autofield:: analytic + .. autofield:: invoice_repartition_line_ids + .. autofield:: refund_repartition_line_ids + .. autofield:: tax_group_id + .. autofield:: tax_exigibility + .. autofield:: cash_basis_transition_account_id diff --git a/content/developer/reference/backend/standard_modules/account/account_tax_repartition.rst b/content/developer/reference/backend/standard_modules/account/account_tax_repartition.rst new file mode 100644 index 0000000000..8573adf38a --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_tax_repartition.rst @@ -0,0 +1,16 @@ +.. _reference/account_tax_repartition: + +================ +Tax Repartitions +================ + +.. automodel:: odoo.addons.account.models.chart_template.AccountTaxRepartitionLineTemplate + :main: + + .. autofield:: factor_percent + .. autofield:: repartition_type + .. autofield:: account_id + .. autofield:: invoice_tax_id + .. autofield:: refund_tax_id + .. autofield:: tag_ids + .. autofield:: use_in_tax_closing diff --git a/content/developer/reference/backend/standard_modules/account/account_tax_report_line.rst b/content/developer/reference/backend/standard_modules/account/account_tax_report_line.rst new file mode 100644 index 0000000000..fa9df6e21a --- /dev/null +++ b/content/developer/reference/backend/standard_modules/account/account_tax_report_line.rst @@ -0,0 +1,24 @@ +.. _reference/account_tax_report_line: + +=============== +Tax Report Line +=============== + +.. automodel:: odoo.addons.account.models.account_tax_report.AccountTaxReportLine + :main: + + .. autofield:: name + .. autofield:: tag_ids + .. autofield:: report_action_id + .. autofield:: children_line_ids + .. autofield:: parent_id + .. autofield:: sequence + .. autofield:: report_id + .. autofield:: tag_name + .. autofield:: code + .. autofield:: formula + .. autofield:: carry_over_condition_method + .. autofield:: carry_over_destination_line_id + .. autofield:: carryover_line_ids + .. autofield:: is_carryover_persistent + .. autofield:: is_carryover_used_in_balance diff --git a/content/developer/reference/frontend/javascript_reference.rst b/content/developer/reference/frontend/javascript_reference.rst index d0676261c4..5b25aad625 100644 --- a/content/developer/reference/frontend/javascript_reference.rst +++ b/content/developer/reference/frontend/javascript_reference.rst @@ -1134,7 +1134,7 @@ to be translated. The way it currently works is the following: is found. Note that translations are explained in more details, from the server point of -view, in the document :doc:`/developer/misc/i18n/translations`. +view, in the document :doc:`/developer/howtos/translations`. There are two important functions for the translations in javascript: *_t* and *_lt*. The difference is that *_lt* is lazily evaluated. @@ -2245,5 +2245,3 @@ For more information, look into the `control_panel_renderer.js None: + """Add the directive header and options to the generated content.""" + sourcename = self.get_sourcename() + module = self.modname.split('addons.')[1].split('.')[0] + if 'main' in self.options: + title = f"Original definition from `{module}`" + else: + title = f"Additional fields with `{module}`" + + self.add_line(title, sourcename) + self.add_line('=' * len(title), sourcename) + self.add_line('', sourcename) + return super().add_directive_header(sig) + + +class FieldDocumenter(AttributeDocumenter): + objtype = 'field' + priority = 10 + AttributeDocumenter.priority + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + return isinstance(member, odoo.fields.Field) + + def update_annotations(self, parent): + super().update_annotations(parent) + annotation = parent.__annotations__ + attrname = self.object.name + annotation[attrname] = dict + field = self.object + if field.type == 'many2one': + annotation[attrname] = int + elif field.type in ('one2many', 'many2many'): + annotation[attrname] = Sequence[odoo.fields.Command] + elif field.type in ('selection', 'reference', 'char', 'text', 'html'): + annotation[attrname] = str + elif field.type == 'boolean': + annotation[attrname] = bool + elif field.type in ('float', 'monetary'): + annotation[attrname] = float + elif field.type == 'integer': + annotation[attrname] = int + elif field.type == 'date': + annotation[attrname] = datetime.date + elif field.type == 'datetime': + annotation[attrname] = datetime.datetime + + def add_content(self, more_content): + source_name = self.get_sourcename() + field = self.object + if field.required: + self.add_line(f":required:", source_name) + self.add_line(f":name: {field.string}", source_name) + if field.readonly: + self.add_line(f":readonly: this field is not supposed to/cannot be set manually", source_name) + if not field.store: + self.add_line(f":store: this field is there only for technical reasons", source_name) + if field.type == 'selection': + if isinstance(field.selection, (list, tuple)): + self.add_line(f":selection:", source_name) + for tech, nice in field.selection: + self.add_line(f" ``{tech}``: {nice}", source_name) + if field.type in ('many2one', 'one2many', 'many2many'): + comodel_name = field.comodel_name + string = f":comodel: :ref:`{comodel_name} `" + self.add_line(string, source_name) + reference = self.config.model_references.get(comodel_name) + if reference: + self.add_line(f":possible_values: `{reference} <{self.config.source_read_replace_vals['GITHUB_PATH']}/{reference}>`__", source_name) + if field.default: + self.add_line(f":default: {field.default(odoo.models.Model)}", source_name) + + super().add_content(more_content) + if field.help: + self.add_line('', source_name) + for line in field.help.strip().split('\n'): + self.add_line(line, source_name) + self.add_line('', source_name) + + def get_doc(self, encoding=None, ignore=None): + # only read docstring of field instance, do not fallback on field class + field = self.object + field.__doc__ = field.__dict__.get('__doc__', "") + res = super().get_doc(encoding, ignore) + return res + + +def disable_warn_missing_reference(app, domain, node): + if not ((domain and domain.name != 'std') or node['reftype'] != 'ref'): + target = node['reftarget'] + if target.startswith('model-'): + node['reftype'] = 'odoo_missing_ref' + return True + + +def setup(app): + app.add_config_value('model_references', {}, 'env') + directives.register_directive('py:model', PyClasslike) + directives.register_directive('py:field', PyAttribute) + app.add_autodocumenter(FieldDocumenter) + app.add_autodocumenter(OdooClassDocumenter) + app.connect('warn-missing-reference', disable_warn_missing_reference, priority=400) + + return { + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/extensions/autodoc_placeholder/__init__.py b/extensions/autodoc_placeholder/__init__.py index 470f53830d..b6eb4f2906 100644 --- a/extensions/autodoc_placeholder/__init__.py +++ b/extensions/autodoc_placeholder/__init__.py @@ -19,6 +19,8 @@ def setup(app): directives.register_directive('autodata', PlaceHolder) directives.register_directive('automethod', PlaceHolder) directives.register_directive('autoattribute', PlaceHolder) + directives.register_directive('autofield', PlaceHolder) + directives.register_directive('automodel', PlaceHolder) return { 'parallel_read_safe': True, diff --git a/extensions/graphviz_placeholder/__init__.py b/extensions/graphviz_placeholder/__init__.py new file mode 100644 index 0000000000..130fb1269f --- /dev/null +++ b/extensions/graphviz_placeholder/__init__.py @@ -0,0 +1,25 @@ +from docutils.parsers.rst import Directive, directives +from docutils import nodes + + +class PlaceHolder(Directive): + """ Placeholder class for directives that must be skipped. """ + + has_content = True + + def run(self): + node = nodes.literal_block('graphviz', '') + node += nodes.Text( + f'{self.content[0]}\n' + '> Graph not rendered because `dot` is not installed' + ) + return [node] + + +def setup(app): + directives.register_directive('graphviz', PlaceHolder) + + return { + 'parallel_read_safe': True, + 'parallel_write_safe': True + } diff --git a/extensions/odoo_theme/static/style.scss b/extensions/odoo_theme/static/style.scss index fcef11a86d..bb3294483d 100644 --- a/extensions/odoo_theme/static/style.scss +++ b/extensions/odoo_theme/static/style.scss @@ -971,6 +971,13 @@ header.o_main_header { } } } + .graphviz { + overflow-x: auto; + white-space: nowrap; + img { + max-width: unset; + } + } } } //------------------------------------------------------------------------------ diff --git a/redirects.txt b/redirects.txt index 9d9f7e105e..76bec65c09 100644 --- a/redirects.txt +++ b/redirects.txt @@ -338,4 +338,7 @@ developer/reference/backend/assets.rst developer/refer developer/reference/frontend/owl_component_system.rst developer/reference/frontend/owl_components.rst developer/reference/frontend/generic_components.rst developer/reference/frontend/owl_components.rst +developer/misc/i18n/localization.rst developer/howtos/accounting_localization.rst +developer/misc/i18n/translations.rst developer/howtos/translations.rst + # Redirections introduced in saas-15.1 : diff --git a/requirements.txt b/requirements.txt index edc26a2260..38d53a2709 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +docutils>=0.14,<0.19 libsass==0.18.0 pygments~=2.6.1 pygments-csv-lexer~=0.1