diff --git a/content/developer/misc/i18n/images/tax-report.png b/content/developer/misc/i18n/images/tax-report.png new file mode 100644 index 000000000..cf31e49fb Binary files /dev/null and b/content/developer/misc/i18n/images/tax-report.png differ diff --git a/content/developer/misc/i18n/localization.rst b/content/developer/misc/i18n/localization.rst index 3aa6a336f..703e04d5f 100644 --- a/content/developer/misc/i18n/localization.rst +++ b/content/developer/misc/i18n/localization.rst @@ -8,136 +8,234 @@ Accounting Localization This tutorial requires knowledges about how to build a module in Odoo (see :doc:`/developer/howtos/backend`). + +How localization works +====================== + +On installing the `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 `__ (US) localization module is installed by default. +Check `post init hook `__ for details. + +For example, `l10n_ch `__ will be installed if the company has ``Switzerland`` as country. + 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. +Structure of a basic ``l10n_XX`` module may be described as following ``__manifest__.py`` file: -For example, ``l10n_be`` will be installed if the company has ``Belgium`` as country. +.. code-block:: py -This behavior is allowed by the presence of a *.xml* file containing the following code: + { + "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_data.xml", + "data/account.group.template.csv", + "data/l10n_XX_chart_post_data.xml", + "data/account_chart_template_configure_data.xml", + + # 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", + ], + "demo": [ + "demo/demo_company.xml", + ] + } + + +In the first file `data/account_chart_template_data.xml` we give name for the Chart of Accounts and set some basic fields. For example, for Swiss localization the file looks as following .. code-block:: xml - - + + + + Plan comptable 2015 (Suisse) + 4 + 102 + 100 + 1090 + + + + + + + + +.. note:: + + Recommended **xmlid** for the record is `l10n_XX_chart_template`. + It will be used for field `chart_template_id`, for example. + If you need many chart of accounts, you can add some suffixes, i.e. `l10n_XX_chart_template_XXX`. + + **Number of digits** to use for account codes is specified in `code_digits` parameter. + + **Bank/cash code** prefixes are used to create *Suspense Account*, *Outstanding Payments*, *Outstanding Receipts* accounts, if those are not set implicitly in the chart template (see note below about `account_journal_suspense_account_id` field). It may be also used to create `default_account_id` in a new `account.journal` record. + + **Transfer code** is used to create a transfer account that is an intermediary + account used when moving money from a liquidity account to another, + e.g. internal transfer from one bank account to another bank account. + + **Spoken languages** instructs to load translations for Chart of Accounts on module installations. It's useful for countries with several official languages. To use this option you must add `l10n_multilang` to the module dependencies. List of supported lang codes can be found in `base/data/res.lang.csv `__. + + To check the **currency** codes open `base/data/res_currency_data.xml `__. And the **country** codes are listed in `base/data/res_country_data.xml `__. + +Next settings for the chart of accounts are set in a separate file, because we need to provide `list of accounts <#accounts>`__ first. In `data/l10n_XX_chart_post_data.xml` we set some default accounts: + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +For example, the Swiss file `data/l10n_ch_chart_post_data.xml` looks as following: + +.. code-block:: xml + + + + + + + + + + + +The last step on installing Chart of Accounts is applying it on current company. File `data/account_chart_template_configure_data.xml` is responsible for that: + +.. code-block:: xml + + + -Where ``module.template_xmlid`` is the **fully-qualified** xmlid of the corresponding template. +Finally, you may add a demo company, so the localization can be easily tested in demo mode. Check `l10n_ch/demo/demo_company.xml `__ for example. -Usually located in the ``data`` folder, it must be loaded at the very last in the ``__manifest__.py`` file. +Chart of Accounts +================= -.. danger:: +Accounts +-------- - 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. +Obviously, *Chart of Accounts* cannot exist without *Accounts*. You need to specify them in `data/account_account_template_data.xml`. .. code-block:: xml - - ... + + XXX + XXX + + - - ... - - - ... - - - + + This account is used for ... - + - + - - - - - + + -Some of the described fields above deserve a bit more explanation. +.. note:: + + You may use csv format instead. Check `l10n_ch/data/account.account.template.csv `__ for example. 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. +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:: @@ -149,94 +247,145 @@ The usage of these generic types ensures the generic reports working correctly i 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 -######################################## +Account tags +------------ -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. +Tags is 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 their ``code`` or ``name``. +The solution is the usage of tags, one for each report line, to filter accounts like you want. + +Put the tags in `data/account_account_tag_data.xml` file: .. code-block:: xml - - + ... + + accounts + + + + + + +Then apply tags on some accounts (field `tag_ids`). Examples: + +* csv: `l10n_lt/data/account.account.template.csv `__ +* xml: `l10n_at/data/account_account_template.xml `__ + +Account groups +-------------- + +Account groups allows to describe structure of chart of accounts. Just check example from `l10n_il/data/account.group.template.csv `__: + + ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| id | code_prefix_start | code_prefix_end | name | chart_template_id/id | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_100100 | 100100 | 100499 | Fixed Assets | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_101110 | 101110 | 101400 | Current Assets | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_101401 | 101401 | 101799 | Bank And Cash | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_111000 | 111000 | 111999 | Current Liabilities | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_112000 | 112000 | 112210 | Non-current Liabilities | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_200000 | 200000 | 200199 | Sales Income | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_200200 | 200200 | 200300 | Other Income | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_201000 | 201000 | 201299 | Cost of Goods | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_202000 | 202000 | 220900 | Expenses | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ +| il_group_300000 | 300000 | 399999 | Capital And Shares | l10n_il.il_chart_template | ++-----------------+-------------------+-----------------+-------------------------+---------------------------+ + + +Taxes +----- + +To add taxes you first need to specify tax groups. It has just two fields: name and country. Create file `data/account_tax_group_data.xml` and list the groups: + +.. code-block:: xml + + + + + + TVA 0% + + + + ... + + + + +Examples: + +* xml: `l10n_ch/data/account_tax_group_data.xml `__ +* csv: `l10n_uk/data/account.tax.group.csv `__ + + +Now you can add the taxes via `data/account_tax_template_data.xml` file: + +.. code-block:: xml + + + + XXX + + + + + + + - - - - - - - - - - - - - ... + - + percent - + + + + sale - + - ... + VAT 20% - + If price_include = False, the computed tax amount will be 132 * 0.2 = 26.4. + If price_include = True, the computed tax amount will be 132 - (132 / 1.2) = 132 - 110 = 22. --> + - + - + - - + + on_invoice - - + + - - ... - - - + + + -An example found in the ``l10n_pl`` module: +Check `l10n_ae/data/account_tax_template_data.xml `__ for example. + +Tax Report +---------- + +In previous section you noticed fields `invoice_repartition_line_ids` / `refund_repartition_line_ids` and probably understand nothing about it. Good news: you are not alone on this incomprehension. Bad news: you have to figure it out a bit. The topic is complicated indeed: + +.. image:: images/tax-report.png + +But lucky we have a presentation explaining the tax reports in details: + +.. youtube:: PuXE_NyFRTM + :align: right + :width: 700 + :height: 394 + +So, once you have properly configured taxes, you just need to add `data/account_tax_report_data.xml` file with a single record for `account.tax.report` in beginning: .. code-block:: xml - - - VAT - leasing pojazdu(sale) - VLP - 1.00 - - group - sale - - - - + + + + Tax Report + + + + ... + + +... following by a list of records for `account.tax.report.line`. Check for example `l10n_au/data/account_tax_report_data.xml `__. Meaning of the fields can be found directly in the `code `__: + +.. code-block:: py + + class AccountTaxReportLine(models.Model): + _name = "account.tax.report.line" + _description = "Account Tax Report Line" + _order = "sequence" + _parent_store = True + + name = fields.Char( + string="Name", + required=True, + help="Complete name for this report line, to be used in report.", + ) + tag_ids = fields.Many2many( + string="Tags", + comodel_name="account.account.tag", + relation="account_tax_report_line_tags_rel", + help="Tax tags populating this line", + ) + report_action_id = fields.Many2one( + string="Report Action", + comodel_name="ir.actions.act_window", + help="The optional action to call when clicking on this line in accounting reports.", + ) + children_line_ids = fields.One2many( + string="Children Lines", + comodel_name="account.tax.report.line", + inverse_name="parent_id", + help="Lines that should be rendered as children of this one", + ) + parent_id = fields.Many2one( + string="Parent Line", comodel_name="account.tax.report.line" + ) + sequence = fields.Integer( + string="Sequence", + required=True, + help="Sequence determining the order of the lines in the report (smaller ones come first). " + "This order is applied locally per section " + "(so, children of the same line are always rendered one after the other).", + ) + parent_path = fields.Char(index=True) + report_id = fields.Many2one( + string="Tax Report", + required=True, + comodel_name="account.tax.report", + ondelete="cascade", + help="The parent tax report of this line", + ) + + # helper to create tags (positive and negative) on report line creation + tag_name = fields.Char( + string="Tag Name", + help="Short name for the tax grid corresponding to this report line. " + "Leave empty if this report line should not correspond to any such grid.", + ) + + # fields used in specific localization reports, + # where a report line isn't simply the given by the sum of account.move.line with selected tags + code = fields.Char( + string="Code", + help="Optional unique code to refer to this line in total formulas", + ) + formula = fields.Char( + string="Formula", + help="Python expression used to compute the value of a total line. " + "This field is mutually exclusive with tag_name, setting it turns the line to a total line. " + "Tax report line codes can be used as variables in this expression to refer to the balance " + "of the corresponding lines in the report. A formula cannot refer to another line using a formula.", + ) + + # fields used to carry over amounts between periods + + # The selection should be filled in localizations using the system + carry_over_condition_method = fields.Selection( + selection=[ + ("no_negative_amount_carry_over_condition", "No negative amount"), + ("always_carry_over_and_set_to_0", "Always carry over and set to 0"), + ], + string="Method", + help="The method used to determine if this line should be carried over.", + ) + carry_over_destination_line_id = fields.Many2one( + string="Destination", + comodel_name="account.tax.report.line", + domain="[('report_id', '=', report_id)]", + help="The line to which the value of this line will be carried over to if needed." + " If left empty the line will carry over to itself.", + ) + carryover_line_ids = fields.One2many( + string="Carryover lines", + comodel_name="account.tax.carryover.line", + inverse_name="tax_report_line_id", + ) + is_carryover_persistent = fields.Boolean( + string="Persistent", + help="Defines how this report line creates carry over lines when performing tax closing." + "If true, the amounts carried over will always be added on top of each other: " + "for example, a report line with a balance of 10 with an existing carryover of 50 " + "will add an additional 10 to it when doing the closing, making a total carryover of 60. " + "If false, the total carried over amount will be forced to the total of this report line: " + "a report line with a balance of 10 with an existing carryover of 50 will create a new " + "carryover line of -40, so that the total carryover becomes 10.", + default=True, + ) + is_carryover_used_in_balance = fields.Boolean( + string="Used in line balance", + help="If set, the carryover amount for this line will be used when calculating its balance in the report." + "This means that the carryover could affect other lines if they are using this one in their computation.", + ) -Adding a new fiscal position to my Chart of Accounts -#################################################### + +Fiscal positions +---------------- .. 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: +Specify fiscal positions in `data/account_fiscal_position_template_data.xml` file as following: .. code-block:: xml @@ -303,123 +591,74 @@ To create a new fiscal position, simply use the ``account.fiscal.position.templa ... - + + + + 10 ... + + + + + + + + + + ... + ... + -Adding the properties to my Chart of Accounts -############################################# +You may have as many fiscal position as you need. Check `l10n_es/data/account_fiscal_position_template_data.xml `__ for example. -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. +Accounting reports +================== -.. code-block:: xml +Accounting reports should be added via a separate module **l10n_XX_reports** that should go to the `enterprise repository `__. - - - +Basic `__manifest__.py` file for such a module looks as following: - - - - - - - - - - - - - - - - - - - - - - - - -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'], + { + "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, + } -Once it's done, you can start the creation of your report statements. The documentation is available in the following `slides `_. + +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 `__ +* `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) `__ + +Menu for the new report is created automatically. By default it's located under *Accounting >> Reporting* menu. +To create a dedicated section in Reporting menu, you need to create new `ir.ui.menu` record (usually in the main `l10n_XX` module) and set it as `parent_id` field in `account.financial.html.report` model. Example for Belgium localization: + +* `ir.ui.menu record in l10n_be `__ +* `parent_id field in l10n_be_reports (v15) `__