Repository: OCA/operating-unit (language: python)

Issue:
Operating unit on account journals
Why is the operating unit on account journal visible only on bank and cash journals?

https://github.com/OCA/operating-unit/blob/cbcc0a597c507efe3e94322d9f3016334770a3d7/account_operating_unit/views/account_journal_view.xml#L10-L13

Would there be any drawbacks to show it on all journals?


Discussion / hints:

Fix patch:
diff --git a/account_operating_unit/README.rst b/account_operating_unit/README.rst
new file mode 100644
index 0000000000..aa6a97ed22
--- /dev/null
+++ b/account_operating_unit/README.rst
@@ -0,0 +1,155 @@
+===============================
+Accounting with Operating Units
+===============================
+
+.. 
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !! This file is generated by oca-gen-addon-readme !!
+   !! changes will be overwritten.                   !!
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   !! source digest: sha256:cd9ccaec17b70901a6cf74858edd86c591380ce55de7027c6e0613cfd9d1b83c
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |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-LGPL--3-blue.png
+    :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
+    :alt: License: LGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Foperating--unit-lightgray.png?logo=github
+    :target: https://github.com/OCA/operating-unit/tree/17.0/account_operating_unit
+    :alt: OCA/operating-unit
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+    :target: https://translation.odoo-community.org/projects/operating-unit-17-0/operating-unit-17-0-account_operating_unit
+    :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
+    :target: https://runboat.odoo-community.org/builds?repo=OCA/operating-unit&target_branch=17.0
+    :alt: Try me on Runboat
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+This module allows a company to manage the accounting based on Operating
+Units (OU's).
+
+-  The financial reports (Trial Balance, P&L, Balance Sheet), allow to
+   report the balances of one or more OU's.
+-  If a company wishes to report Balance Sheet and P&L accounts based on
+   OU's, they should indicate at company level that the OU's are
+   self-balanced, and the corresponding Inter-Operating Unit clearing
+   account. The Chart of Accounts will always be balanced, for each
+   Operating Unit.
+-  A company considering Operating Unit as applicable to report only
+   profits and losses will not need to set the OU's as self-balanced.
+-  The self-balancing of Operating Unit is ensured at the time of
+   posting a journal entry. In case that the journal involves posting of
+   items in separate Operating Units, new journal items will be created,
+   using the Inter-Operating Unit clearing account, to ensure that each
+   OU is going to be self-balanced for that journal entry.
+-  Adds the Operating Unit to the invoice. A user can choose what OU to
+   create the invoice for.
+-  Adds the Operating Unit to payments and payment methods. The
+   operating unit of a payment will be that of the payment method
+   chosen.
+-  Implements security rules at OU level to invoices, payments and
+   journal items.
+-  Adds the Operating Unit to the cash basis journal entries.
+
+**Table of contents**
+
+.. contents::
+   :local:
+
+Configuration
+=============
+
+If your company is required to generate a balanced balance sheet by
+Operating Unit you can specify at company level that Operating Units
+should be self-balanced, and then indicate a self-balancing clearing
+account.
+
+1. Create an account "Inter-OU Clearing". It is a balance sheet account.
+2. Go to *Settings / Companies / Configuration* and Set the "Operating
+   Units are self-balanced" checkbox. Then set the "Inter-OU Clearing"
+   account in "Inter-Operating Unit clearing account" field.
+3. Go to *Accounting / Configuration / Accounting / Journals* and
+   define, for each Payment Method, the Operating Unit that will be used
+   in payments.
+
+Usage
+=====
+
+-  Add the Operating Unit to invoices.
+-  Report invoices by Operating Unit in *Accounting / Reporting*
+   *Business Intelligence / Invoices*
+-  Add the Default Operating Unit to account move. Then all move lines
+   will by default adopt this Operating Unit.
+-  Add Operating Units to the move lines. If they differ across lines of
+   the same move, and the OU's are self-balanced, then additional move
+   lines will be created so as to make the move self-balanced from OU
+   perspective.
+-  In the menu *Accounting / Reporting / PDF Reports*, you can indicate
+   the Operating Units to report on, for the *Trial Balance*, *Balance
+   Sheet*, *Profit and Loss*, and *Financial Reports*.
+
+Known issues / Roadmap
+======================
+
+-  The *General Ledger*, *Aged Partner Balance* reports do not support
+   the filter by Operating Unit. Basically due to lack of proper hooks
+   in the standard methods used by these reports, to introduce the
+   ability to filter by Operating Unit.
+-  Trial Balance, P&L and Balance Sheet were removed from Odoo
+   Community. Once OCA Financial Reports are migrated to 13 we can add
+   the Operating Unit to those reports.
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues <https://github.com/OCA/operating-unit/issues>`_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+`feedback <https://github.com/OCA/operating-unit/issues/new?body=module:%20account_operating_unit%0Aversion:%2017.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
+-------
+
+* ForgeFlow
+* Serpent Consulting Services Pvt. Ltd.
+* WilldooIT Pty Ltd
+
+Contributors
+------------
+
+-  ForgeFlow <contact@forgeflow.com>
+-  Jordi Ballester Alomar <jordi.ballester@forgeflow.com>
+-  Aarón Henríquez <ahenriquez@forgeflow.com>
+-  Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com>
+-  WilldooIT Pty Ltd <info@willdooit.com>
+-  Michael Villamar <michael.villamar@willdooit.com>
+-  Jarsa Sistemas <info@jarsa.com.mx>
+-  Alan Ramos <alan.ramos@jarsa.com.mx>
+-  Saran Lim. <saranl@ecosoft.co.th>
+-  Pimolnat Suntian <pimolnats@ecosoft.co.th>
+-  Hieu, Vo Minh Bao <hieu.vmb@komit-consulting.com>
+
+Maintainers
+-----------
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+   :alt: Odoo Community Association
+   :target: https://odoo-community.org
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+This module is part of the `OCA/operating-unit <https://github.com/OCA/operating-unit/tree/17.0/account_operating_unit>`_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/account_operating_unit/__init__.py b/account_operating_unit/__init__.py
new file mode 100644
index 0000000000..1fc45468f5
--- /dev/null
+++ b/account_operating_unit/__init__.py
@@ -0,0 +1,4 @@
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from . import models
+from . import report
diff --git a/account_operating_unit/__manifest__.py b/account_operating_unit/__manifest__.py
new file mode 100644
index 0000000000..9bddc3138d
--- /dev/null
+++ b/account_operating_unit/__manifest__.py
@@ -0,0 +1,29 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+{
+    "name": "Accounting with Operating Units",
+    "summary": "Introduces Operating Unit (OU) in invoices and "
+    "Accounting Entries with clearing account",
+    "version": "17.0.1.0.0",
+    "author": "ForgeFlow, "
+    "Serpent Consulting Services Pvt. Ltd.,"
+    "WilldooIT Pty Ltd,"
+    "Odoo Community Association (OCA)",
+    "website": "https://github.com/OCA/operating-unit",
+    "category": "Accounting & Finance",
+    "depends": [
+        "account",
+        "analytic_operating_unit",
+        "base_view_inheritance_extension",
+    ],
+    "license": "LGPL-3",
+    "data": [
+        "security/account_security.xml",
+        "views/account_move_view.xml",
+        "views/account_journal_view.xml",
+        "views/company_view.xml",
+        "views/account_payment_view.xml",
+        "views/account_invoice_report_view.xml",
+    ],
+}
diff --git a/account_operating_unit/i18n/account_operating_unit.pot b/account_operating_unit/i18n/account_operating_unit.pot
new file mode 100644
index 0000000000..ebce3f4bef
--- /dev/null
+++ b/account_operating_unit/i18n/account_operating_unit.pot
@@ -0,0 +1,168 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* account_operating_unit
+#
+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: account_operating_unit
+#: model:ir.model.fields,help:account_operating_unit.field_res_company__ou_is_self_balanced
+msgid ""
+"Activate if your company is required to generate a balanced balance sheet "
+"for each operating unit."
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_bank_statement_line
+msgid "Bank Statement Line"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_journal.py:0
+#, python-format
+msgid ""
+"Configuration error. If defined as self-balanced at company level, the "
+"operating unit is mandatory in bank journal."
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/res_company.py:0
+#, python-format
+msgid ""
+"Configuration error. Please provide an Inter-operating unit clearing "
+"account."
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. The Company in the Move Line and in the Operating Unit "
+"must be the same."
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. The Operating Unit in the Move Line and in the Move "
+"must be the same."
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. The operating unit is mandatory for each line as the "
+"operating unit has been defined as self-balanced at company level."
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. You need to define aninter-operating unit clearing "
+"account in the company settings"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model.fields,field_description:account_operating_unit.field_res_company__inter_ou_clearing_account_id
+msgid "Inter-operating unit clearing account"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_invoice_report
+msgid "Invoices Statistics"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_journal
+msgid "Journal"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_move
+msgid "Journal Entry"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_move_line
+msgid "Journal Item"
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid "OU-Balancing"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_bank_statement_line__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_invoice_report__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_journal__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_move__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_move_line__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_payment__operating_unit_id
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_invoice_filter
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_invoice_report_search
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_move_line_filter
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_payment_search
+msgid "Operating Unit"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model.fields,help:account_operating_unit.field_account_journal__operating_unit_id
+msgid ""
+"Operating Unit that will be used in payments, when this journal is used."
+msgstr ""
+
+#. module: account_operating_unit
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_company_form
+msgid "Operating Units"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model.fields,field_description:account_operating_unit.field_res_company__ou_is_self_balanced
+msgid "Operating Units are self-balanced"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_partial_reconcile
+msgid "Partial Reconcile"
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_payment
+msgid "Payments"
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid "The Company in the Move and in Operating Unit must be the same."
+msgstr ""
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid "The OU in the Move and in Journal must be the same."
+msgstr ""
+
+#. module: account_operating_unit
+#: model:ir.model.fields,help:account_operating_unit.field_account_bank_statement_line__operating_unit_id
+#: model:ir.model.fields,help:account_operating_unit.field_account_move__operating_unit_id
+msgid "This operating unit will be defaulted in the move lines."
+msgstr ""
diff --git a/account_operating_unit/i18n/es_MX.po b/account_operating_unit/i18n/es_MX.po
new file mode 100644
index 0000000000..4da345b7e9
--- /dev/null
+++ b/account_operating_unit/i18n/es_MX.po
@@ -0,0 +1,195 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* account_operating_unit
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 15.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2023-03-21 13:02+0000\n"
+"Last-Translator: Jesús Alan Ramos Rodríguez <alan.ramos@jarsa.com.mx>\n"
+"Language-Team: none\n"
+"Language: es_MX\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: account_operating_unit
+#: model:ir.model.fields,help:account_operating_unit.field_res_company__ou_is_self_balanced
+msgid ""
+"Activate if your company is required to generate a balanced balance sheet "
+"for each operating unit."
+msgstr ""
+"Actívelo si su empresa está obligada a generar un balance general por cada "
+"unidad operativa."
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_bank_statement_line
+msgid "Bank Statement Line"
+msgstr "Línea extracto bancario"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_res_company
+msgid "Companies"
+msgstr "Empresas"
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_journal.py:0
+#, python-format
+msgid ""
+"Configuration error. If defined as self-balanced at company level, the "
+"operating unit is mandatory in bank journal."
+msgstr ""
+"Error de configuración. Si se define como auto-balanceado a nivel de "
+"empresa, la unidad operativa es obligatoria en el diario bancario."
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/res_company.py:0
+#, python-format
+msgid ""
+"Configuration error. Please provide an Inter-operating unit clearing account."
+msgstr ""
+"Error de configuración. Proporcione una cuenta de compensación de unidades "
+"interoperativas."
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. The Company in the Move Line and in the Operating Unit "
+"must be the same."
+msgstr ""
+"Error de configuración. La Empresa en la Línea de Movimiento y en la Unidad "
+"Operativa debe ser la misma."
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. The Operating Unit in the Move Line and in the Move "
+"must be the same."
+msgstr ""
+"Error de configuración. La Unidad Operativa en la Línea de Movimiento y en "
+"el Movimiento debe ser la misma."
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. The operating unit is mandatory for each line as the "
+"operating unit has been defined as self-balanced at company level."
+msgstr ""
+"Error de configuración. La unidad operativa es obligatoria para cada línea "
+"ya que la unidad operativa se ha definido como autobalanceada a nivel de "
+"empresa."
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid ""
+"Configuration error. You need to define aninter-operating unit clearing "
+"account in the company settings"
+msgstr ""
+"Error de configuración. Debe definir una cuenta de compensación entre "
+"unidades operativas en la configuración de la empresa."
+
+#. module: account_operating_unit
+#: model:ir.model.fields,field_description:account_operating_unit.field_res_company__inter_ou_clearing_account_id
+msgid "Inter-operating unit clearing account"
+msgstr "Cuenta de compensación de unidades interoperativas"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_invoice_report
+msgid "Invoices Statistics"
+msgstr "Estadísticas de facturas"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_journal
+msgid "Journal"
+msgstr "Diario"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_move
+msgid "Journal Entry"
+msgstr "Asiento de diario"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_move_line
+msgid "Journal Item"
+msgstr "Apunte de diario"
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid "OU-Balancing"
+msgstr "Equilibrio de OU"
+
+#. module: account_operating_unit
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_bank_statement_line__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_invoice_report__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_journal__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_move__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_move_line__operating_unit_id
+#: model:ir.model.fields,field_description:account_operating_unit.field_account_payment__operating_unit_id
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_invoice_filter
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_invoice_report_search
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_move_line_filter
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_account_payment_search
+msgid "Operating Unit"
+msgstr "Unidad Operativa"
+
+#. module: account_operating_unit
+#: model:ir.model.fields,help:account_operating_unit.field_account_journal__operating_unit_id
+msgid ""
+"Operating Unit that will be used in payments, when this journal is used."
+msgstr ""
+"Unidad Operativa que se utilizará en los pagos, cuando se utilice este "
+"diario."
+
+#. module: account_operating_unit
+#: model_terms:ir.ui.view,arch_db:account_operating_unit.view_company_form
+msgid "Operating Units"
+msgstr "Unidades operativas"
+
+#. module: account_operating_unit
+#: model:ir.model.fields,field_description:account_operating_unit.field_res_company__ou_is_self_balanced
+msgid "Operating Units are self-balanced"
+msgstr "Las unidades operativas son autobalanceadas"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_partial_reconcile
+msgid "Partial Reconcile"
+msgstr "Reconciliación parcial"
+
+#. module: account_operating_unit
+#: model:ir.model,name:account_operating_unit.model_account_payment
+msgid "Payments"
+msgstr "Pagos"
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid "The Company in the Move and in Operating Unit must be the same."
+msgstr ""
+"La Empresa en el movimiento y en la Unidad Operativa debe ser la misma."
+
+#. module: account_operating_unit
+#: code:addons/account_operating_unit/models/account_move.py:0
+#, python-format
+msgid "The OU in the Move and in Journal must be the same."
+msgstr "La OU en el movimiento y en diario debe ser la misma."
+
+#. module: account_operating_unit
+#: model:ir.model.fields,help:account_operating_unit.field_account_bank_statement_line__operating_unit_id
+#: model:ir.model.fields,help:account_operating_unit.field_account_move__operating_unit_id
+msgid "This operating unit will be defaulted in the move lines."
+msgstr "Esta unidad operativa estará por defecto en las líneas de movimiento."
+
+#~ msgid "Register Payment"
+#~ msgstr "Registrar pago"
+
+#, python-format
+#~ msgid "The OU in the Bills/Invoices to register payment must be the same."
+#~ msgstr "La OU en las Facturas para registrar el pago debe ser la misma."
diff --git a/account_operating_unit/models/__init__.py b/account_operating_unit/models/__init__.py
new file mode 100644
index 0000000000..51a95d2831
--- /dev/null
+++ b/account_operating_unit/models/__init__.py
@@ -0,0 +1,8 @@
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from . import res_company
+from . import account_bank_statement
+from . import account_journal
+from . import account_move
+from . import account_partial_reconcile
+from . import account_payment
diff --git a/account_operating_unit/models/account_bank_statement.py b/account_operating_unit/models/account_bank_statement.py
new file mode 100644
index 0000000000..7f395ae8cf
--- /dev/null
+++ b/account_operating_unit/models/account_bank_statement.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Jarsa
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo import models
+
+
+class AccountBankStatementLine(models.Model):
+    _inherit = "account.bank.statement.line"
+
+    def _prepare_move_line_default_vals(self, counterpart_account_id=None):
+        result = super()._prepare_move_line_default_vals(
+            counterpart_account_id=counterpart_account_id
+        )
+        result[0][
+            "operating_unit_id"
+        ] = self.statement_id.journal_id.operating_unit_id.id
+        result[1][
+            "operating_unit_id"
+        ] = self.statement_id.journal_id.operating_unit_id.id
+        return result
diff --git a/account_operating_unit/models/account_journal.py b/account_operating_unit/models/account_journal.py
new file mode 100644
index 0000000000..b7e6c2bb4d
--- /dev/null
+++ b/account_operating_unit/models/account_journal.py
@@ -0,0 +1,34 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo import _, api, fields, models
+from odoo.exceptions import UserError
+
+
+class AccountJournal(models.Model):
+    _inherit = "account.journal"
+
+    operating_unit_id = fields.Many2one(
+        check_company=True,
+        comodel_name="operating.unit",
+        help="Operating Unit that will be used in payments, "
+        "when this journal is used.",
+    )
+
+    @api.constrains("type")
+    def _check_ou(self):
+        for journal in self:
+            if (
+                journal.type in ("bank", "cash")
+                and journal.company_id.ou_is_self_balanced
+                and not journal.operating_unit_id
+            ):
+                raise UserError(
+                    _(
+                        "Configuration error. If defined as "
+                        "self-balanced at company level, the "
+                        "operating unit is mandatory in bank "
+                        "journal."
+                    )
+                )
diff --git a/account_operating_unit/models/account_move.py b/account_operating_unit/models/account_move.py
new file mode 100644
index 0000000000..076eb30a6e
--- /dev/null
+++ b/account_operating_unit/models/account_move.py
@@ -0,0 +1,251 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo import _, api, fields, models
+from odoo.exceptions import UserError
+
+
+class AccountMoveLine(models.Model):
+    _inherit = "account.move.line"
+
+    operating_unit_id = fields.Many2one(
+        check_company=True,
+        comodel_name="operating.unit",
+    )
+
+    @api.model_create_multi
+    def create(self, vals_list):
+        for vals in vals_list:
+            if vals.get("move_id", False):
+                move = self.env["account.move"].browse(vals["move_id"])
+                if move.operating_unit_id:
+                    vals["operating_unit_id"] = move.operating_unit_id.id
+        return super().create(vals_list)
+
+    @api.constrains("operating_unit_id", "move_id")
+    def _check_move_operating_unit(self):
+        for rec in self:
+            if (
+                rec.move_id
+                and rec.move_id.operating_unit_id
+                and rec.operating_unit_id
+                and rec.move_id.operating_unit_id != rec.operating_unit_id
+            ):
+                raise UserError(
+                    _(
+                        "Configuration error. The Operating Unit in"
+                        " the Move Line and in the Move must be the"
+                        " same."
+                    )
+                )
+
+    def _check_ou_balance(self, lines):
+        # Look for the balance of each OU
+        ou_balance = {}
+        for line in lines:
+            if line.operating_unit_id.id not in ou_balance:
+                ou_balance[line.operating_unit_id.id] = 0.0
+            ou_balance[line.operating_unit_id.id] += line.credit - line.debit
+        return ou_balance
+
+    def reconcile(self):
+        # if one OU pays the invoices of different OU
+        # a regularization entry must be created (this
+        # was a feature in version <= 12)
+        if self and not self[0].company_id.ou_is_self_balanced:
+            return super().reconcile()
+        bank_journal = self.mapped("move_id.journal_id").filtered(
+            lambda jl: jl.type in ("bank", "cash")
+        )
+        if not bank_journal:
+            return super().reconcile()
+        bank_journal = bank_journal[0]
+        # If all move lines point to the same operating unit, there's no
+        # need to create a balancing move line
+        if len(self.mapped("operating_unit_id")) <= 1:
+            return super().reconcile()
+        # Create balancing entries for un-balanced OU's.
+        move_vals = self._prepare_inter_ou_balancing_move(bank_journal)
+        move = self.env["account.move"].create(move_vals)
+        ou_balances = self._check_ou_balance(self)
+        amls = self.env["account.move.line"]
+        line_datas = []
+        for ou_id in list(ou_balances.keys()):
+            # If the OU is already balanced, then do not continue
+            if move.company_id.currency_id.is_zero(ou_balances[ou_id]):
+                continue
+            # Create a balancing move line in the operating unit
+            # clearing account
+            line_data = move._prepare_inter_ou_balancing_move_line(
+                move, ou_id, ou_balances
+            )
+            if line_data:
+                line_datas.append(line_data)
+        if line_datas:
+            amls = self.with_context(check_move_validity=False).create(line_datas)
+        if amls:
+            move.with_context(check_move_validity=True).write(
+                {"line_ids": [(4, aml.id) for aml in amls]}
+            )
+        move.with_context(inter_ou_balance_entry=True).action_post()
+        return super().reconcile()
+
+    def _prepare_inter_ou_balancing_move(self, journal):
+        move_vals = {
+            "journal_id": journal.id,
+            "date": max(self.mapped("date")),
+            "ref": "Inter OU Balancing",
+            "company_id": journal.company_id.id,
+        }
+        return move_vals
+
+
+class AccountMove(models.Model):
+    _inherit = "account.move"
+
+    operating_unit_id = fields.Many2one(
+        comodel_name="operating.unit",
+        default=lambda self: self._default_operating_unit_id(),
+        help="This operating unit will be defaulted in the move lines.",
+        readonly=False,
+        compute="_compute_operating_unit",
+        store=True,
+        check_company=True,
+    )
+
+    @api.model
+    def _default_operating_unit_id(self):
+        if (
+            self._context.get("default_move_type", False)
+            and self._context.get("default_move_type") != "entry"
+        ):
+            return self.env["res.users"]._get_default_operating_unit()
+        return False
+
+    @api.onchange("operating_unit_id")
+    def _onchange_operating_unit(self):
+        if self.operating_unit_id and (
+            not self.journal_id
+            or self.journal_id.operating_unit_id != self.operating_unit_id
+        ):
+            journal = self.env["account.journal"].search(
+                [("type", "=", self.journal_id.type)]
+            )
+            jf = journal.filtered(
+                lambda aj: aj.operating_unit_id == self.operating_unit_id
+            )
+            if not jf:
+                self.journal_id = journal[0]
+            else:
+                self.journal_id = jf[0]
+            for line in self.line_ids:
+                line.operating_unit_id = self.operating_unit_id
+
+    @api.depends("journal_id")
+    def _compute_operating_unit(self):
+        for record in self:
+            if record.journal_id.operating_unit_id:
+                record.operating_unit_id = record.journal_id.operating_unit_id
+                for line in record.line_ids:
+                    line.operating_unit_id = record.journal_id.operating_unit_id
+
+    def _prepare_inter_ou_balancing_move_line(self, move, ou_id, ou_balances):
+        if not move.company_id.inter_ou_clearing_account_id:
+            raise UserError(
+                _(
+                    "Configuration error. You need to define an"
+                    "inter-operating unit clearing account in the "
+                    "company settings"
+                )
+            )
+
+        res = {
+            "name": _("OU-Balancing"),
+            "move_id": move.id,
+            "journal_id": move.journal_id.id,
+            "date": move.date,
+            "operating_unit_id": ou_id,
+            "partner_id": move.partner_id and move.partner_id.id or False,
+            "account_id": move.company_id.inter_ou_clearing_account_id.id,
+        }
+
+        if ou_balances[ou_id] < 0.0:
+            res["debit"] = abs(ou_balances[ou_id])
+        else:
+            res["credit"] = ou_balances[ou_id]
+        return res
+
+    def _check_ou_balance(self, move):
+        # Look for the balance of each OU
+        ou_balance = {}
+        for line in move.line_ids:
+            if line.operating_unit_id.id not in ou_balance:
+                ou_balance[line.operating_unit_id.id] = 0.0
+            ou_balance[line.operating_unit_id.id] += line.debit - line.credit
+        return ou_balance
+
+    def _post(self, soft=True):
+        ml_obj = self.env["account.move.line"]
+        for move in self:
+            if not move.company_id.ou_is_self_balanced or self.env.context.get(
+                "inter_ou_balance_entry", False
+            ):
+                continue
+
+            # If all move lines point to the same operating unit, there's no
+            # need to create a balancing move line
+            if len(move.line_ids.operating_unit_id) <= 1:
+                continue
+            # Create balancing entries for un-balanced OU's.
+            ou_balances = self._check_ou_balance(move)
+            amls = self.env["account.move.line"]
+            line_datas = []
+            for ou_id in list(ou_balances.keys()):
+                # If the OU is already balanced, then do not continue
+                if move.company_id.currency_id.is_zero(ou_balances[ou_id]):
+                    continue
+                # Create a balancing move line in the operating unit
+                # clearing account
+                line_data = self._prepare_inter_ou_balancing_move_line(
+                    move, ou_id, ou_balances
+                )
+                if line_data:
+                    line_datas.append(line_data)
+            if line_datas:
+                amls = ml_obj.with_context(check_move_validity=False).create(line_datas)
+            if amls:
+                move.with_context(check_move_validity=True).write(
+                    {"line_ids": [(4, aml.id) for aml in amls]}
+                )
+
+        return super()._post(soft)
+
+    @api.constrains("line_ids")
+    def _check_ou(self):
+        for move in self:
+            if not move.company_id.ou_is_self_balanced:
+                continue
+            for line in move.line_ids:
+                if not line.operating_unit_id:
+                    raise UserError(
+                        _(
+                            "Configuration error. The operating unit is "
+                            "mandatory for each line as the operating unit "
+                            "has been defined as self-balanced at company "
+                            "level."
+                        )
+                    )
+
+    @api.constrains("operating_unit_id", "journal_id")
+    def _check_journal_operating_unit(self):
+        for move in self:
+            if (
+                move.journal_id.operating_unit_id
+                and move.operating_unit_id
+                and move.operating_unit_id != move.journal_id.operating_unit_id
+            ):
+                raise UserError(
+                    _("The OU in the Move and in Journal must be the same.")
+                )
+        return True
diff --git a/account_operating_unit/models/account_partial_reconcile.py b/account_operating_unit/models/account_partial_reconcile.py
new file mode 100644
index 0000000000..32d5f26572
--- /dev/null
+++ b/account_operating_unit/models/account_partial_reconcile.py
@@ -0,0 +1,38 @@
+# Copyright 2022 Ecosoft Co., Ltd (http://ecosoft.co.th/)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
+
+from odoo import api, models
+
+
+class AccountPartialReconcile(models.Model):
+    _inherit = "account.partial.reconcile"
+
+    @api.model
+    def _prepare_cash_basis_base_line_vals(self, base_line, balance, amount_currency):
+        res = super()._prepare_cash_basis_base_line_vals(
+            base_line, balance, amount_currency
+        )
+        res.update({"operating_unit_id": base_line.operating_unit_id.id})
+        return res
+
+    @api.model
+    def _prepare_cash_basis_counterpart_base_line_vals(self, cb_base_line_vals):
+        res = super()._prepare_cash_basis_counterpart_base_line_vals(cb_base_line_vals)
+        res.update({"operating_unit_id": cb_base_line_vals.get("operating_unit_id")})
+        return res
+
+    @api.model
+    def _prepare_cash_basis_tax_line_vals(self, tax_line, balance, amount_currency):
+        res = super()._prepare_cash_basis_tax_line_vals(
+            tax_line, balance, amount_currency
+        )
+        res.update({"operating_unit_id": tax_line.operating_unit_id.id})
+        return res
+
+    @api.model
+    def _prepare_cash_basis_counterpart_tax_line_vals(self, tax_line, cb_tax_line_vals):
+        res = super()._prepare_cash_basis_counterpart_tax_line_vals(
+            tax_line, cb_tax_line_vals
+        )
+        res.update({"operating_unit_id": tax_line.operating_unit_id.id})
+        return res
diff --git a/account_operating_unit/models/account_payment.py b/account_operating_unit/models/account_payment.py
new file mode 100644
index 0000000000..9dcc06aa44
--- /dev/null
+++ b/account_operating_unit/models/account_payment.py
@@ -0,0 +1,45 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo import api, fields, models
+
+
+class AccountPayment(models.Model):
+    _inherit = "account.payment"
+
+    operating_unit_id = fields.Many2one(
+        check_company=True,
+        comodel_name="operating.unit",
+        compute="_compute_operating_unit_id",
+        store=True,
+    )
+
+    @api.depends("journal_id")
+    def _compute_operating_unit_id(self):
+        for payment in self.filtered("journal_id"):
+            payment.operating_unit_id = payment.journal_id.operating_unit_id
+
+    def _prepare_move_line_default_vals(
+        self, write_off_line_vals=None, force_balance=None
+    ):
+        lines = super()._prepare_move_line_default_vals(
+            write_off_line_vals, force_balance
+        )
+        for line in lines:
+            line["operating_unit_id"] = self.operating_unit_id.id
+        active_model = self._context.get("active_model", False)
+        if not active_model or active_model != "account.move":
+            return lines
+        invoices = self.env[self._context.get("active_model")].browse(
+            self._context.get("active_ids")
+        )
+        invoices_ou = invoices.operating_unit_id
+        if invoices and len(invoices_ou) == 1 and invoices_ou != self.operating_unit_id:
+            destination_account_id = self.destination_account_id.id
+            for line in lines:
+                if not line.get("operating_unit_id", False) or (
+                    line["account_id"] == destination_account_id
+                ):
+                    line["operating_unit_id"] = invoices_ou.id
+        return lines
diff --git a/account_operating_unit/models/res_company.py b/account_operating_unit/models/res_company.py
new file mode 100644
index 0000000000..d2b4cd123f
--- /dev/null
+++ b/account_operating_unit/models/res_company.py
@@ -0,0 +1,34 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo import api, fields, models
+from odoo.exceptions import UserError
+from odoo.tools.translate import _
+
+
+class ResCompany(models.Model):
+    _inherit = "res.company"
+
+    inter_ou_clearing_account_id = fields.Many2one(
+        comodel_name="account.account",
+        string="Inter-operating unit clearing account",
+    )
+    ou_is_self_balanced = fields.Boolean(
+        string="Operating Units are self-balanced",
+        help="Activate if your company is "
+        "required to generate a balanced"
+        " balance sheet for each "
+        "operating unit.",
+    )
+
+    @api.constrains("ou_is_self_balanced", "inter_ou_clearing_account_id")
+    def _inter_ou_clearing_acc_required(self):
+        for rec in self:
+            if rec.ou_is_self_balanced and not rec.inter_ou_clearing_account_id:
+                raise UserError(
+                    _(
+                        "Configuration error. Please provide an "
+                        "Inter-operating unit clearing account."
+                    )
+                )
diff --git a/account_operating_unit/pyproject.toml b/account_operating_unit/pyproject.toml
new file mode 100644
index 0000000000..4231d0cccb
--- /dev/null
+++ b/account_operating_unit/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["whool"]
+build-backend = "whool.buildapi"
diff --git a/account_operating_unit/readme/CONFIGURE.md b/account_operating_unit/readme/CONFIGURE.md
new file mode 100644
index 0000000000..13df13e0ea
--- /dev/null
+++ b/account_operating_unit/readme/CONFIGURE.md
@@ -0,0 +1,13 @@
+If your company is required to generate a balanced balance sheet by
+Operating Unit you can specify at company level that Operating Units
+should be self-balanced, and then indicate a self-balancing clearing
+account.
+
+1.  Create an account "Inter-OU Clearing". It is a balance sheet
+    account.
+2.  Go to *Settings / Companies / Configuration* and Set the "Operating
+    Units are self-balanced" checkbox. Then set the "Inter-OU Clearing"
+    account in "Inter-Operating Unit clearing account" field.
+3.  Go to *Accounting / Configuration / Accounting / Journals* and
+    define, for each Payment Method, the Operating Unit that will be
+    used in payments.
diff --git a/account_operating_unit/readme/CONTRIBUTORS.md b/account_operating_unit/readme/CONTRIBUTORS.md
new file mode 100644
index 0000000000..9510e6c92a
--- /dev/null
+++ b/account_operating_unit/readme/CONTRIBUTORS.md
@@ -0,0 +1,11 @@
+- ForgeFlow \<<contact@forgeflow.com>\>
+- Jordi Ballester Alomar \<<jordi.ballester@forgeflow.com>\>
+- Aarón Henríquez \<<ahenriquez@forgeflow.com>\>
+- Serpent Consulting Services Pvt. Ltd. \<<support@serpentcs.com>\>
+- WilldooIT Pty Ltd \<<info@willdooit.com>\>
+- Michael Villamar \<<michael.villamar@willdooit.com>\>
+- Jarsa Sistemas \<<info@jarsa.com.mx>\>
+- Alan Ramos \<<alan.ramos@jarsa.com.mx>\>
+- Saran Lim. \<<saranl@ecosoft.co.th>\>
+- Pimolnat Suntian \<<pimolnats@ecosoft.co.th>\>
+- Hieu, Vo Minh Bao \<<hieu.vmb@komit-consulting.com>\>
diff --git a/account_operating_unit/readme/DESCRIPTION.md b/account_operating_unit/readme/DESCRIPTION.md
new file mode 100644
index 0000000000..ef85d9a50b
--- /dev/null
+++ b/account_operating_unit/readme/DESCRIPTION.md
@@ -0,0 +1,24 @@
+This module allows a company to manage the accounting based on Operating
+Units (OU's).
+
+- The financial reports (Trial Balance, P&L, Balance Sheet), allow to
+  report the balances of one or more OU's.
+- If a company wishes to report Balance Sheet and P&L accounts based on
+  OU's, they should indicate at company level that the OU's are
+  self-balanced, and the corresponding Inter-Operating Unit clearing
+  account. The Chart of Accounts will always be balanced, for each
+  Operating Unit.
+- A company considering Operating Unit as applicable to report only
+  profits and losses will not need to set the OU's as self-balanced.
+- The self-balancing of Operating Unit is ensured at the time of posting
+  a journal entry. In case that the journal involves posting of items in
+  separate Operating Units, new journal items will be created, using the
+  Inter-Operating Unit clearing account, to ensure that each OU is going
+  to be self-balanced for that journal entry.
+- Adds the Operating Unit to the invoice. A user can choose what OU to
+  create the invoice for.
+- Adds the Operating Unit to payments and payment methods. The operating
+  unit of a payment will be that of the payment method chosen.
+- Implements security rules at OU level to invoices, payments and
+  journal items.
+- Adds the Operating Unit to the cash basis journal entries.
diff --git a/account_operating_unit/readme/ROADMAP.md b/account_operating_unit/readme/ROADMAP.md
new file mode 100644
index 0000000000..e735215e99
--- /dev/null
+++ b/account_operating_unit/readme/ROADMAP.md
@@ -0,0 +1,7 @@
+- The *General Ledger*, *Aged Partner Balance* reports do not support
+  the filter by Operating Unit. Basically due to lack of proper hooks in
+  the standard methods used by these reports, to introduce the ability
+  to filter by Operating Unit.
+- Trial Balance, P&L and Balance Sheet were removed from Odoo Community.
+  Once OCA Financial Reports are migrated to 13 we can add the Operating
+  Unit to those reports.
diff --git a/account_operating_unit/readme/USAGE.md b/account_operating_unit/readme/USAGE.md
new file mode 100644
index 0000000000..20f339da46
--- /dev/null
+++ b/account_operating_unit/readme/USAGE.md
@@ -0,0 +1,12 @@
+- Add the Operating Unit to invoices.
+- Report invoices by Operating Unit in *Accounting / Reporting*
+  *Business Intelligence / Invoices*
+- Add the Default Operating Unit to account move. Then all move lines
+  will by default adopt this Operating Unit.
+- Add Operating Units to the move lines. If they differ across lines of
+  the same move, and the OU's are self-balanced, then additional move
+  lines will be created so as to make the move self-balanced from OU
+  perspective.
+- In the menu *Accounting / Reporting / PDF Reports*, you can indicate
+  the Operating Units to report on, for the *Trial Balance*, *Balance
+  Sheet*, *Profit and Loss*, and *Financial Reports*.
diff --git a/account_operating_unit/report/__init__.py b/account_operating_unit/report/__init__.py
new file mode 100644
index 0000000000..828ca7dd4d
--- /dev/null
+++ b/account_operating_unit/report/__init__.py
@@ -0,0 +1,3 @@
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from . import account_invoice_report
diff --git a/account_operating_unit/report/account_invoice_report.py b/account_operating_unit/report/account_invoice_report.py
new file mode 100644
index 0000000000..64ab23cf97
--- /dev/null
+++ b/account_operating_unit/report/account_invoice_report.py
@@ -0,0 +1,21 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo import fields, models
+
+
+class AccountInvoiceReport(models.Model):
+    _inherit = "account.invoice.report"
+
+    operating_unit_id = fields.Many2one(
+        comodel_name="operating.unit",
+        string="Operating Unit",
+    )
+
+    def _select(self):
+        select_str = super()._select()
+        select_str += """
+            ,line.operating_unit_id
+        """
+        return select_str
diff --git a/account_operating_unit/security/account_security.xml b/account_operating_unit/security/account_security.xml
new file mode 100644
index 0000000000..57576d995b
--- /dev/null
+++ b/account_operating_unit/security/account_security.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--© 2019 ForgeFlow S.L.-->
+<!--© 2019 Serpent Consulting Services Pvt. Ltd.-->
+<!--License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).-->
+<odoo noupdate="0">
+    <record id="ir_rule_account_journal_allowed_operating_units" model="ir.rule">
+        <field name="model_id" ref="account.model_account_journal" />
+        <field name="domain_force">
+            ['|', ('operating_unit_id','=',False),
+            ('operating_unit_id','in',operating_unit_ids)]
+        </field>
+        <field name="name">Journals from allowed operating units</field>
+        <field name="global" eval="True" />
+        <field eval="0" name="perm_unlink" />
+        <field eval="0" name="perm_write" />
+        <field eval="1" name="perm_read" />
+        <field eval="0" name="perm_create" />
+    </record>
+    <record id="ir_rule_move_line_allowed_operating_units" model="ir.rule">
+        <field name="model_id" ref="account.model_account_move_line" />
+        <field name="domain_force">
+            ['|', ('operating_unit_id','=',False), ('operating_unit_id','in',
+            operating_unit_ids)]
+        </field>
+        <field name="name">Move lines from allowed operating units</field>
+        <field name="global" eval="True" />
+        <field eval="0" name="perm_unlink" />
+        <field eval="0" name="perm_write" />
+        <field eval="1" name="perm_read" />
+        <field eval="0" name="perm_create" />
+    </record>
+    <record id="ir_rule_move_allowed_operating_units" model="ir.rule">
+        <field name="model_id" ref="account.model_account_move" />
+        <field name="domain_force">
+            ['|', ('operating_unit_id','=',False), ('operating_unit_id','in',
+            operating_unit_ids)]
+        </field>
+        <field name="name">Moves from allowed operating units</field>
+        <field name="global" eval="True" />
+        <field eval="0" name="perm_unlink" />
+        <field eval="0" name="perm_write" />
+        <field eval="1" name="perm_read" />
+        <field eval="0" name="perm_create" />
+    </record>
+    <record id="ir_rule_account_payment_allowed_operating_units" model="ir.rule">
+        <field name="model_id" ref="account.model_account_payment" />
+        <field name="domain_force">
+            ['|', ('operating_unit_id','=',False), ('operating_unit_id','in',
+            operating_unit_ids)]
+        </field>
+        <field name="name">Payments from allowed operating units</field>
+        <field name="global" eval="True" />
+        <field eval="0" name="perm_unlink" />
+        <field eval="0" name="perm_write" />
+        <field eval="1" name="perm_read" />
+        <field eval="0" name="perm_create" />
+    </record>
+    <record id="ir_rule_invoice_report_allowed_operating_units" model="ir.rule">
+        <field name="model_id" ref="account.model_account_invoice_report" />
+        <field name="domain_force">
+            ['|', ('operating_unit_id','=',False), ('operating_unit_id','in',
+            operating_unit_ids)]
+        </field>
+        <field name="name">Invoice Report from allowed operating units</field>
+        <field name="global" eval="True" />
+        <field eval="0" name="perm_unlink" />
+        <field eval="0" name="perm_write" />
+        <field eval="1" name="perm_read" />
+        <field eval="0" name="perm_create" />
+    </record>
+</odoo>
diff --git a/account_operating_unit/static/description/icon.png b/account_operating_unit/static/description/icon.png
new file mode 100644
index 0000000000..3a0328b516
Binary files /dev/null and b/account_operating_unit/static/description/icon.png differ
diff --git a/account_operating_unit/static/description/index.html b/account_operating_unit/static/description/index.html
new file mode 100644
index 0000000000..3febd267da
--- /dev/null
+++ b/account_operating_unit/static/description/index.html
@@ -0,0 +1,508 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
+<title>Accounting with Operating Units</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger (goodger@python.org)
+:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+Despite the name, some widely supported CSS2 features are used.
+
+See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+  border: 0 }
+
+table.borderless td, table.borderless th {
+  /* Override padding for "table.docutils td" with "! important".
+     The right padding separates the table cells. */
+  padding: 0 0.5em 0 0 ! important }
+
+.first {
+  /* Override more specific margin styles with "! important". */
+  margin-top: 0 ! important }
+
+.last, .with-subtitle {
+  margin-bottom: 0 ! important }
+
+.hidden {
+  display: none }
+
+.subscript {
+  vertical-align: sub;
+  font-size: smaller }
+
+.superscript {
+  vertical-align: super;
+  font-size: smaller }
+
+a.toc-backref {
+  text-decoration: none ;
+  color: black }
+
+blockquote.epigraph {
+  margin: 2em 5em ; }
+
+dl.docutils dd {
+  margin-bottom: 0.5em }
+
+object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
+  overflow: hidden;
+}
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+  font-weight: bold }
+*/
+
+div.abstract {
+  margin: 2em 5em }
+
+div.abstract p.topic-title {
+  font-weight: bold ;
+  text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+  margin: 2em ;
+  border: medium outset ;
+  padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+  font-weight: bold ;
+  font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title, .code .error {
+  color: red ;
+  font-weight: bold ;
+  font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+   compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+  margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+  margin-top: 0.5em }
+*/
+
+div.dedication {
+  margin: 2em 5em ;
+  text-align: center ;
+  font-style: italic }
+
+div.dedication p.topic-title {
+  font-weight: bold ;
+  font-style: normal }
+
+div.figure {
+  margin-left: 2em ;
+  margin-right: 2em }
+
+div.footer, div.header {
+  clear: both;
+  font-size: smaller }
+
+div.line-block {
+  display: block ;
+  margin-top: 1em ;
+  margin-bottom: 1em }
+
+div.line-block div.line-block {
+  margin-top: 0 ;
+  margin-bottom: 0 ;
+  margin-left: 1.5em }
+
+div.sidebar {
+  margin: 0 0 0.5em 1em ;
+  border: medium outset ;
+  padding: 1em ;
+  background-color: #ffffee ;
+  width: 40% ;
+  float: right ;
+  clear: right }
+
+div.sidebar p.rubric {
+  font-family: sans-serif ;
+  font-size: medium }
+
+div.system-messages {
+  margin: 5em }
+
+div.system-messages h1 {
+  color: red }
+
+div.system-message {
+  border: medium outset ;
+  padding: 1em }
+
+div.system-message p.system-message-title {
+  color: red ;
+  font-weight: bold }
+
+div.topic {
+  margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+  margin-top: 0.4em }
+
+h1.title {
+  text-align: center }
+
+h2.subtitle {
+  text-align: center }
+
+hr.docutils {
+  width: 75% }
+
+img.align-left, .figure.align-left, object.align-left, table.align-left {
+  clear: left ;
+  float: left ;
+  margin-right: 1em }
+
+img.align-right, .figure.align-right, object.align-right, table.align-right {
+  clear: right ;
+  float: right ;
+  margin-left: 1em }
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+table.align-center {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+  text-align: left }
+
+.align-center {
+  clear: both ;
+  text-align: center }
+
+.align-right {
+  text-align: right }
+
+/* reset inner alignment in figures */
+div.align-right {
+  text-align: inherit }
+
+/* div.align-center * { */
+/*   text-align: left } */
+
+.align-top    {
+  vertical-align: top }
+
+.align-middle {
+  vertical-align: middle }
+
+.align-bottom {
+  vertical-align: bottom }
+
+ol.simple, ul.simple {
+  margin-bottom: 1em }
+
+ol.arabic {
+  list-style: decimal }
+
+ol.loweralpha {
+  list-style: lower-alpha }
+
+ol.upperalpha {
+  list-style: upper-alpha }
+
+ol.lowerroman {
+  list-style: lower-roman }
+
+ol.upperroman {
+  list-style: upper-roman }
+
+p.attribution {
+  text-align: right ;
+  margin-left: 50% }
+
+p.caption {
+  font-style: italic }
+
+p.credits {
+  font-style: italic ;
+  font-size: smaller }
+
+p.label {
+  white-space: nowrap }
+
+p.rubric {
+  font-weight: bold ;
+  font-size: larger ;
+  color: maroon ;
+  text-align: center }
+
+p.sidebar-title {
+  font-family: sans-serif ;
+  font-weight: bold ;
+  font-size: larger }
+
+p.sidebar-subtitle {
+  font-family: sans-serif ;
+  font-weight: bold }
+
+p.topic-title {
+  font-weight: bold }
+
+pre.address {
+  margin-bottom: 0 ;
+  margin-top: 0 ;
+  font: inherit }
+
+pre.literal-block, pre.doctest-block, pre.math, pre.code {
+  margin-left: 2em ;
+  margin-right: 2em }
+
+pre.code .ln { color: gray; } /* line numbers */
+pre.code, code { background-color: #eeeeee }
+pre.code .comment, code .comment { color: #5C6576 }
+pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
+pre.code .literal.string, code .literal.string { color: #0C5404 }
+pre.code .name.builtin, code .name.builtin { color: #352B84 }
+pre.code .deleted, code .deleted { background-color: #DEB0A1}
+pre.code .inserted, code .inserted { background-color: #A3D289}
+
+span.classifier {
+  font-family: sans-serif ;
+  font-style: oblique }
+
+span.classifier-delimiter {
+  font-family: sans-serif ;
+  font-weight: bold }
+
+span.interpreted {
+  font-family: sans-serif }
+
+span.option {
+  white-space: nowrap }
+
+span.pre {
+  white-space: pre }
+
+span.problematic, pre.problematic {
+  color: red }
+
+span.section-subtitle {
+  /* font-size relative to parent (h1..h6 element) */
+  font-size: 80% }
+
+table.citation {
+  border-left: solid 1px gray;
+  margin-left: 1px }
+
+table.docinfo {
+  margin: 2em 4em }
+
+table.docutils {
+  margin-top: 0.5em ;
+  margin-bottom: 0.5em }
+
+table.footnote {
+  border-left: solid 1px black;
+  margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+  padding-left: 0.5em ;
+  padding-right: 0.5em ;
+  vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+  font-weight: bold ;
+  text-align: left ;
+  white-space: nowrap ;
+  padding-left: 0 }
+
+/* "booktabs" style (no vertical lines) */
+table.docutils.booktabs {
+  border: 0px;
+  border-top: 2px solid;
+  border-bottom: 2px solid;
+  border-collapse: collapse;
+}
+table.docutils.booktabs * {
+  border: 0px;
+}
+table.docutils.booktabs th {
+  border-bottom: thin solid;
+  text-align: left;
+}
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+  font-size: 100% }
+
+ul.auto-toc {
+  list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="accounting-with-operating-units">
+<h1 class="title">Accounting with Operating Units</h1>
+
+<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!! This file is generated by oca-gen-addon-readme !!
+!! changes will be overwritten.                   !!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!! source digest: sha256:cd9ccaec17b70901a6cf74858edd86c591380ce55de7027c6e0613cfd9d1b83c
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
+<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/operating-unit/tree/17.0/account_operating_unit"><img alt="OCA/operating-unit" src="https://img.shields.io/badge/github-OCA%2Foperating--unit-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/operating-unit-17-0/operating-unit-17-0-account_operating_unit"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/operating-unit&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
+<p>This module allows a company to manage the accounting based on Operating
+Units (OU’s).</p>
+<ul class="simple">
+<li>The financial reports (Trial Balance, P&amp;L, Balance Sheet), allow to
+report the balances of one or more OU’s.</li>
+<li>If a company wishes to report Balance Sheet and P&amp;L accounts based on
+OU’s, they should indicate at company level that the OU’s are
+self-balanced, and the corresponding Inter-Operating Unit clearing
+account. The Chart of Accounts will always be balanced, for each
+Operating Unit.</li>
+<li>A company considering Operating Unit as applicable to report only
+profits and losses will not need to set the OU’s as self-balanced.</li>
+<li>The self-balancing of Operating Unit is ensured at the time of
+posting a journal entry. In case that the journal involves posting of
+items in separate Operating Units, new journal items will be created,
+using the Inter-Operating Unit clearing account, to ensure that each
+OU is going to be self-balanced for that journal entry.</li>
+<li>Adds the Operating Unit to the invoice. A user can choose what OU to
+create the invoice for.</li>
+<li>Adds the Operating Unit to payments and payment methods. The
+operating unit of a payment will be that of the payment method
+chosen.</li>
+<li>Implements security rules at OU level to invoices, payments and
+journal items.</li>
+<li>Adds the Operating Unit to the cash basis journal entries.</li>
+</ul>
+<p><strong>Table of contents</strong></p>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
+<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
+<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-3">Known issues / Roadmap</a></li>
+<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
+<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
+<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
+<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
+<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="configuration">
+<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
+<p>If your company is required to generate a balanced balance sheet by
+Operating Unit you can specify at company level that Operating Units
+should be self-balanced, and then indicate a self-balancing clearing
+account.</p>
+<ol class="arabic simple">
+<li>Create an account “Inter-OU Clearing”. It is a balance sheet account.</li>
+<li>Go to <em>Settings / Companies / Configuration</em> and Set the “Operating
+Units are self-balanced” checkbox. Then set the “Inter-OU Clearing”
+account in “Inter-Operating Unit clearing account” field.</li>
+<li>Go to <em>Accounting / Configuration / Accounting / Journals</em> and
+define, for each Payment Method, the Operating Unit that will be used
+in payments.</li>
+</ol>
+</div>
+<div class="section" id="usage">
+<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
+<ul class="simple">
+<li>Add the Operating Unit to invoices.</li>
+<li>Report invoices by Operating Unit in <em>Accounting / Reporting</em>
+<em>Business Intelligence / Invoices</em></li>
+<li>Add the Default Operating Unit to account move. Then all move lines
+will by default adopt this Operating Unit.</li>
+<li>Add Operating Units to the move lines. If they differ across lines of
+the same move, and the OU’s are self-balanced, then additional move
+lines will be created so as to make the move self-balanced from OU
+perspective.</li>
+<li>In the menu <em>Accounting / Reporting / PDF Reports</em>, you can indicate
+the Operating Units to report on, for the <em>Trial Balance</em>, <em>Balance
+Sheet</em>, <em>Profit and Loss</em>, and <em>Financial Reports</em>.</li>
+</ul>
+</div>
+<div class="section" id="known-issues-roadmap">
+<h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
+<ul class="simple">
+<li>The <em>General Ledger</em>, <em>Aged Partner Balance</em> reports do not support
+the filter by Operating Unit. Basically due to lack of proper hooks
+in the standard methods used by these reports, to introduce the
+ability to filter by Operating Unit.</li>
+<li>Trial Balance, P&amp;L and Balance Sheet were removed from Odoo
+Community. Once OCA Financial Reports are migrated to 13 we can add
+the Operating Unit to those reports.</li>
+</ul>
+</div>
+<div class="section" id="bug-tracker">
+<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
+<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/operating-unit/issues">GitHub Issues</a>.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+<a class="reference external" href="https://github.com/OCA/operating-unit/issues/new?body=module:%20account_operating_unit%0Aversion:%2017.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="#toc-entry-5">Credits</a></h1>
+<div class="section" id="authors">
+<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
+<ul class="simple">
+<li>ForgeFlow</li>
+<li>Serpent Consulting Services Pvt. Ltd.</li>
+<li>WilldooIT Pty Ltd</li>
+</ul>
+</div>
+<div class="section" id="contributors">
+<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
+<ul class="simple">
+<li>ForgeFlow &lt;<a class="reference external" href="mailto:contact&#64;forgeflow.com">contact&#64;forgeflow.com</a>&gt;</li>
+<li>Jordi Ballester Alomar &lt;<a class="reference external" href="mailto:jordi.ballester&#64;forgeflow.com">jordi.ballester&#64;forgeflow.com</a>&gt;</li>
+<li>Aarón Henríquez &lt;<a class="reference external" href="mailto:ahenriquez&#64;forgeflow.com">ahenriquez&#64;forgeflow.com</a>&gt;</li>
+<li>Serpent Consulting Services Pvt. Ltd. &lt;<a class="reference external" href="mailto:support&#64;serpentcs.com">support&#64;serpentcs.com</a>&gt;</li>
+<li>WilldooIT Pty Ltd &lt;<a class="reference external" href="mailto:info&#64;willdooit.com">info&#64;willdooit.com</a>&gt;</li>
+<li>Michael Villamar &lt;<a class="reference external" href="mailto:michael.villamar&#64;willdooit.com">michael.villamar&#64;willdooit.com</a>&gt;</li>
+<li>Jarsa Sistemas &lt;<a class="reference external" href="mailto:info&#64;jarsa.com.mx">info&#64;jarsa.com.mx</a>&gt;</li>
+<li>Alan Ramos &lt;<a class="reference external" href="mailto:alan.ramos&#64;jarsa.com.mx">alan.ramos&#64;jarsa.com.mx</a>&gt;</li>
+<li>Saran Lim. &lt;<a class="reference external" href="mailto:saranl&#64;ecosoft.co.th">saranl&#64;ecosoft.co.th</a>&gt;</li>
+<li>Pimolnat Suntian &lt;<a class="reference external" href="mailto:pimolnats&#64;ecosoft.co.th">pimolnats&#64;ecosoft.co.th</a>&gt;</li>
+<li>Hieu, Vo Minh Bao &lt;<a class="reference external" href="mailto:hieu.vmb&#64;komit-consulting.com">hieu.vmb&#64;komit-consulting.com</a>&gt;</li>
+</ul>
+</div>
+<div class="section" id="maintainers">
+<h2><a class="toc-backref" href="#toc-entry-8">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/operating-unit/tree/17.0/account_operating_unit">OCA/operating-unit</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>
diff --git a/account_operating_unit/views/account_invoice_report_view.xml b/account_operating_unit/views/account_invoice_report_view.xml
new file mode 100644
index 0000000000..b60944dfc9
--- /dev/null
+++ b/account_operating_unit/views/account_invoice_report_view.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--© 2016-17 ForgeFlow S.L.-->
+<!--© 2016 Serpent Consulting Services Pvt. Ltd.-->
+<!--License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).-->
+<odoo>
+    <record id="view_account_invoice_report_search" model="ir.ui.view">
+        <field name="name">account.invoice.report.search</field>
+        <field name="model">account.invoice.report</field>
+        <field name="inherit_id" ref="account.view_account_invoice_report_search" />
+        <field name="arch" type="xml">
+            <field name="invoice_date" position="after">
+                <field
+                    name="operating_unit_id"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+            <xpath expr="//filter[1]" position="after">
+                <filter
+                    name='group_by_operating_unit'
+                    string="Operating Unit"
+                    context="{'group_by':'operating_unit_id'}"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </xpath>
+        </field>
+    </record>
+</odoo>
diff --git a/account_operating_unit/views/account_journal_view.xml b/account_operating_unit/views/account_journal_view.xml
new file mode 100644
index 0000000000..e000b2887d
--- /dev/null
+++ b/account_operating_unit/views/account_journal_view.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--© 2016-17 ForgeFlow S.L.-->
+<!--© 2016 Serpent Consulting Services Pvt. Ltd.-->
+<!--License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).-->
+<odoo>
+    <record id="view_account_journal_form" model="ir.ui.view">
+        <field name="name">account.journal.form</field>
+        <field name="model">account.journal</field>
+        <field name="inherit_id" ref="account.view_account_journal_form" />
+        <field name="arch" type="xml">
+            <field name="country_code" position="before">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+        </field>
+    </record>
+</odoo>
diff --git a/account_operating_unit/views/account_move_view.xml b/account_operating_unit/views/account_move_view.xml
new file mode 100644
index 0000000000..261a445fe7
--- /dev/null
+++ b/account_operating_unit/views/account_move_view.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--© 2016-17 ForgeFlow S.L.-->
+<!--© 2016 Serpent Consulting Services Pvt. Ltd.-->
+<!--License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).-->
+<odoo>
+    <record id="view_move_line_form" model="ir.ui.view">
+        <field name="name">account.move.line.form</field>
+        <field name="model">account.move.line</field>
+        <field name="inherit_id" ref="account.view_move_line_form" />
+        <field name="arch" type="xml">
+            <xpath expr="//field[@name='account_id']" position="after">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </xpath>
+        </field>
+    </record>
+    <record id="view_move_line_tree" model="ir.ui.view">
+        <field name="name">account.move.line.tree</field>
+        <field name="model">account.move.line</field>
+        <field name="inherit_id" ref="account.view_move_line_tree" />
+        <field name="arch" type="xml">
+            <xpath expr="//field[@name='account_id']" position="after">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    optional="show"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </xpath>
+        </field>
+    </record>
+    <record id="view_account_move_line_filter" model="ir.ui.view">
+        <field name="name">Journal Items</field>
+        <field name="model">account.move.line</field>
+        <field name="inherit_id" ref="account.view_account_move_line_filter" />
+        <field name="arch" type="xml">
+            <field name="account_id" position="after">
+                <field
+                    name="operating_unit_id"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+            <filter name="group_by_account" position="after">
+                <filter
+                    string="Operating Unit"
+                    name="operating_unit_grouped"
+                    icon="terp-folder-green"
+                    context="{'group_by':'operating_unit_id'}"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </filter>
+        </field>
+    </record>
+    <record id="view_move_form" model="ir.ui.view">
+        <field name="name">account.move.form</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="account.view_move_form" />
+        <field name="arch" type="xml">
+            <xpath expr="//group[@id='header_right_group']" position="inside">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    groups="operating_unit.group_multi_operating_unit"
+                    readonly="state != 'draft'"
+                />
+                <field
+                    name="operating_unit_id"
+                    invisible="1"
+                    groups="!operating_unit.group_multi_operating_unit"
+                    readonly="state != 'draft'"
+                />
+            </xpath>
+            <field name="invoice_line_ids" position="attributes">
+                <attribute name="context" operation="update">
+                    {
+                        'operating_unit_id': operating_unit_id,
+                        'default_operating_unit_id': operating_unit_id
+                    }
+                </attribute>
+            </field>
+            <field name="line_ids" position="attributes">
+                <attribute name="context" operation="update">
+                    {
+                        'default_operating_unit_id': operating_unit_id
+                    }
+                </attribute>
+            </field>
+            <xpath
+                expr="//field[@name='invoice_line_ids']/tree//field[@name='account_id']"
+                position="after"
+            >
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    optional="show"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+                <field
+                    name="operating_unit_id"
+                    column_invisible="True"
+                    groups="!operating_unit.group_multi_operating_unit"
+                />
+            </xpath>
+            <xpath
+                expr="//field[@name='line_ids']/tree//field[@name='account_id']"
+                position="after"
+            >
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    optional="show"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </xpath>
+        </field>
+    </record>
+    <record id="view_invoice_tree" model="ir.ui.view">
+        <field name="name">account.invoice.tree</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="account.view_invoice_tree" />
+        <field name="arch" type="xml">
+            <field name="company_id" position="before">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    optional="show"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+        </field>
+    </record>
+    <record id="view_account_invoice_filter" model="ir.ui.view">
+        <field name="name">account.invoice.select</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="account.view_account_invoice_filter" />
+        <field name="arch" type="xml">
+            <field name="invoice_user_id" position="after">
+                <field
+                    name="operating_unit_id"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+            <filter name="salesperson" position="after">
+                <filter
+                    string="Operating Unit"
+                    name="operating_unit_grouped"
+                    icon="terp-folder-orange"
+                    domain="[]"
+                    groups="operating_unit.group_multi_operating_unit"
+                    context="{'group_by':'operating_unit_id'}"
+                />
+            </filter>
+        </field>
+    </record>
+</odoo>
diff --git a/account_operating_unit/views/account_payment_view.xml b/account_operating_unit/views/account_payment_view.xml
new file mode 100644
index 0000000000..209ec56ec7
--- /dev/null
+++ b/account_operating_unit/views/account_payment_view.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--© 2016-17 ForgeFlow S.L.-->
+<!--© 2016 Serpent Consulting Services Pvt. Ltd.-->
+<!--License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).-->
+<odoo>
+    <record id="view_account_payment_tree" model="ir.ui.view">
+        <field name="name">account.payment.tree</field>
+        <field name="model">account.payment</field>
+        <field name="inherit_id" ref="account.view_account_payment_tree" />
+        <field name="arch" type="xml">
+            <field name="journal_id" position="after">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    optional="show"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+        </field>
+    </record>
+    <record id="view_account_payment_search" model="ir.ui.view">
+        <field name="name">account.payment.search</field>
+        <field name="model">account.payment</field>
+        <field name="inherit_id" ref="account.view_account_payment_search" />
+        <field name="arch" type="xml">
+            <field name="journal_id" position="after">
+                <field
+                    name="operating_unit_id"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+                <filter
+                    string="Operating Unit"
+                    name="operating_unit_grouped"
+                    domain="[]"
+                    context="{'group_by': 'operating_unit_id'}"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+        </field>
+    </record>
+    <record id="view_account_payment_form" model="ir.ui.view">
+        <field name="name">account.payment.form</field>
+        <field name="model">account.payment</field>
+        <field name="inherit_id" ref="account.view_account_payment_form" />
+        <field name="arch" type="xml">
+            <field name="journal_id" position="after">
+                <field
+                    name="operating_unit_id"
+                    options="{'no_create': True}"
+                    groups="operating_unit.group_multi_operating_unit"
+                />
+            </field>
+        </field>
+    </record>
+</odoo>
diff --git a/account_operating_unit/views/company_view.xml b/account_operating_unit/views/company_view.xml
new file mode 100644
index 0000000000..6ea7bc9ee5
--- /dev/null
+++ b/account_operating_unit/views/company_view.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--© 2016-17 ForgeFlow S.L.-->
+<!--© 2016 Serpent Consulting Services Pvt. Ltd.-->
+<!--License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).-->
+<odoo>
+    <record id="view_company_form" model="ir.ui.view">
+        <field name="name">res.company.form</field>
+        <field name="model">res.company</field>
+        <field name="inherit_id" ref="base.view_company_form" />
+        <field name="arch" type="xml">
+            <xpath expr="//notebook/page/group" position="after">
+                <group string="Operating Units">
+                    <field name="ou_is_self_balanced" />
+                    <field name="inter_ou_clearing_account_id" />
+                </group>
+            </xpath>
+        </field>
+    </record>
+</odoo>


Test patch:
diff --git a/account_operating_unit/tests/__init__.py b/account_operating_unit/tests/__init__.py
new file mode 100644
index 0000000000..071cbac008
--- /dev/null
+++ b/account_operating_unit/tests/__init__.py
@@ -0,0 +1,7 @@
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from . import test_account_operating_unit
+from . import test_invoice_operating_unit
+from . import test_cross_ou_journal_entry
+from . import test_operating_unit_security
+from . import test_payment_operating_unit
diff --git a/account_operating_unit/tests/test_account_operating_unit.py b/account_operating_unit/tests/test_account_operating_unit.py
new file mode 100644
index 0000000000..141d1fe5a3
--- /dev/null
+++ b/account_operating_unit/tests/test_account_operating_unit.py
@@ -0,0 +1,180 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo.models import Command
+from odoo.tests import tagged
+
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo.addons.operating_unit.tests.common import OperatingUnitCommon
+
+
+@tagged("post_install", "-at_install")
+class TestAccountOperatingUnit(AccountTestInvoicingCommon, OperatingUnitCommon):
+    @classmethod
+    def setUpClass(cls, chart_template_ref=None):
+        super().setUpClass(chart_template_ref=chart_template_ref)
+        cls.aml_model = cls.env["account.move.line"]
+        cls.move_model = cls.env["account.move"]
+        cls.account_model = cls.env["account.account"]
+        cls.journal_model = cls.env["account.journal"]
+        cls.product_model = cls.env["product.product"]
+        cls.payment_model = cls.env["account.payment"]
+        cls.register_payments_model = cls.env["account.payment.register"]
+
+        # company
+        cls.grp_acc_manager = cls.env.ref("account.group_account_manager")
+        cls.grp_acc_config = cls.env.ref("account.group_account_user")
+        # Main Operating Unit
+        cls.ou1 = cls.env.ref("operating_unit.main_operating_unit")
+        # B2B Operating Unit
+        cls.b2b = cls.env.ref("operating_unit.b2b_operating_unit")
+        # B2C Operating Unit
+        cls.b2c = cls.env.ref("operating_unit.b2c_operating_unit")
+        # Assign user to main company to allow to write OU
+        cls.env.user.write(
+            {
+                "operating_unit_ids": [
+                    Command.link(cls.b2b.id),
+                    Command.link(cls.b2c.id),
+                ],
+                "company_ids": [Command.link(cls.company.id)],
+            }
+        )
+        # Products
+        cls.product1 = cls.env.ref("product.product_product_7")
+        cls.product2 = cls.env.ref("product.product_product_9")
+        cls.product3 = cls.env.ref("product.product_product_11")
+
+        # Payment methods
+        cls.payment_method_manual_in = cls.env.ref(
+            "account.account_payment_method_manual_in"
+        )
+
+        cls.user1.write(
+            {
+                "groups_id": [
+                    Command.link(cls.grp_acc_manager.id),
+                    Command.link(cls.grp_acc_config.id),
+                ],
+                "operating_unit_ids": [
+                    Command.link(cls.b2b.id),
+                    Command.link(cls.b2c.id),
+                ],
+            }
+        )
+        # Create cash - test account
+        cls.current_asset_account_id = cls.account_model.create(
+            {
+                "name": "Current asset - Test",
+                "code": "test.current.asset",
+                "account_type": "asset_current",
+                "company_id": cls.company.id,
+            }
+        )
+        # Create Inter-OU Clearing - test account
+        cls.inter_ou_account_id = cls.account_model.create(
+            {
+                "name": "Inter-OU Clearing",
+                "code": "test.inter.ou",
+                "account_type": "equity",
+                "company_id": cls.company.id,
+            }
+        )
+        # Assign the Inter-OU Clearing account to the company
+        cls.company.inter_ou_clearing_account_id = cls.inter_ou_account_id.id
+        cls.company.ou_is_self_balanced = True
+
+        # Create user2
+        cls.user2.write(
+            {
+                "groups_id": [
+                    Command.link(cls.grp_acc_manager.id),
+                    Command.link(cls.grp_acc_config.id),
+                ],
+                "operating_unit_ids": [
+                    Command.link(cls.b2c.id),
+                ],
+            }
+        )
+
+        # Create a cash account 1
+        cls.cash1_account_id = cls.account_model.create(
+            {
+                "name": "Cash 1 - Test",
+                "code": "test.cash.1",
+                "account_type": "asset_current",
+                "company_id": cls.company.id,
+            }
+        )
+
+        # Create a journal for cash account 1, associated to the main
+        # operating unit
+        cls.cash_journal_ou1 = cls.journal_model.create(
+            {
+                "name": "Cash Journal 1 - Test",
+                "code": "cash1",
+                "type": "cash",
+                "company_id": cls.company.id,
+                "default_account_id": cls.cash1_account_id.id,
+                "operating_unit_id": cls.ou1.id,
+            }
+        )
+        # Create a cash account 2
+        cls.cash2_account_id = cls.account_model.create(
+            {
+                "name": "Cash 2 - Test",
+                "code": "cash2",
+                "account_type": "asset_current",
+                "company_id": cls.company.id,
+            }
+        )
+
+        # Create a journal for cash account 2, associated to the operating
+        # unit B2B
+        cls.cash2_journal_b2b = cls.journal_model.create(
+            {
+                "name": "Cash Journal 2 - Test",
+                "code": "test_cash_2",
+                "type": "cash",
+                "company_id": cls.company.id,
+                "default_account_id": cls.cash2_account_id.id,
+                "operating_unit_id": cls.b2b.id,
+            }
+        )
+
+    def _prepare_invoice(self, operating_unit_id, name="Test Supplier Invoice"):
+        line_products = [
+            (self.product1, 1000),
+            (self.product2, 500),
+            (self.product3, 800),
+        ]
+        # Prepare invoice lines
+        lines = []
+        for product, qty in line_products:
+            line_values = {
+                "name": product.name,
+                "product_id": product.id,
+                "quantity": qty,
+                "price_unit": 50,
+                "account_id": self.env["account.account"]
+                .search(
+                    [
+                        ("account_type", "=", "expense"),
+                        ("company_id", "=", self.company.id),
+                    ],
+                    limit=1,
+                )
+                .id,
+                # Adding this line so the taxes are explicitly excluded from the lines
+                "tax_ids": [],
+            }
+            lines.append((0, 0, line_values))
+        inv_vals = {
+            "partner_id": self.partner1.id,
+            "operating_unit_id": operating_unit_id,
+            "name": name,
+            "move_type": "in_invoice",
+            "invoice_line_ids": lines,
+        }
+        return inv_vals
diff --git a/account_operating_unit/tests/test_cross_ou_journal_entry.py b/account_operating_unit/tests/test_cross_ou_journal_entry.py
new file mode 100644
index 0000000000..c8fbd5d852
--- /dev/null
+++ b/account_operating_unit/tests/test_cross_ou_journal_entry.py
@@ -0,0 +1,112 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo.exceptions import UserError
+from odoo.tests import tagged
+from odoo.tests.common import Form
+
+from . import test_account_operating_unit as test_ou
+
+
+@tagged("post_install", "-at_install")
+class TestCrossOuJournalEntry(test_ou.TestAccountOperatingUnit):
+    def _check_balance(self, account_id, acc_type="clearing"):
+        # Check balance for all operating units
+        domain = [("account_id", "=", account_id)]
+        balance = self._get_balance(domain)
+        self.assertEqual(balance, 0.0, "Balance is 0 for all Operating Units.")
+        # Check balance for operating B2B units
+        domain = [
+            ("account_id", "=", account_id),
+            ("operating_unit_id", "=", self.b2b.id),
+        ]
+        balance = self._get_balance(domain)
+        if acc_type == "other":
+            self.assertEqual(balance, -100, "Balance is -100 for Operating Unit B2B.")
+        else:
+            self.assertEqual(balance, 100, "Balance is 100 for Operating Unit B2B.")
+        # Check balance for operating B2C units
+        domain = [
+            ("account_id", "=", account_id),
+            ("operating_unit_id", "=", self.b2c.id),
+        ]
+        balance = self._get_balance(domain)
+        if acc_type == "other":
+            self.assertEqual(balance, 100.0, "Balance is 100 for Operating Unit B2C.")
+        else:
+            self.assertEqual(balance, -100.0, "Balance is -100 for Operating Unit B2C.")
+
+    def _get_balance(self, domain):
+        """
+        Call read_group method and return the balance of particular account.
+        """
+        aml_rec = self.aml_model.with_user(self.user1.id)._read_group(
+            domain, ["account_id"], ["debit:sum", "credit:sum"]
+        )[0]
+        return aml_rec[1] - aml_rec[2]
+
+    def test_cross_ou_journal_entry(self):
+        """Test balance of cross OU journal entries.
+        Test that when I create a manual journal entry with multiple
+        operating units, new cross-operating unit entries are created
+        automatically whent the journal entry is posted, ensuring that each
+        OU is self-balanced."""
+        # Create Journal Entries and check the balance of the account
+        # based on different operating units.
+        self.company.write(
+            {"inter_ou_clearing_account_id": self.inter_ou_account_id.id}
+        )
+        # Create Journal Entries
+        journal_ids = self.journal_model.search(
+            [("code", "=", "MISC"), ("company_id", "=", self.company.id)], limit=1
+        )
+        # get default values of account move
+        move_vals = self.move_model.default_get([])
+        lines = [
+            (
+                0,
+                0,
+                {
+                    "name": "Test",
+                    "account_id": self.current_asset_account_id.id,
+                    "debit": 0,
+                    "credit": 100,
+                    "operating_unit_id": self.b2b.id,
+                },
+            ),
+            (
+                0,
+                0,
+                {
+                    "name": "Test",
+                    "account_id": self.current_asset_account_id.id,
+                    "debit": 100,
+                    "credit": 0,
+                    "operating_unit_id": self.b2c.id,
+                },
+            ),
+        ]
+        move_vals.update(
+            {"journal_id": journal_ids and journal_ids.id, "line_ids": lines}
+        )
+        move = (
+            self.move_model.with_user(self.user1.id)
+            .with_context(check_move_validity=False)
+            .create(move_vals)
+        )
+        # Post journal entries
+        move.action_post()
+        # Check the balance of the account
+        self._check_balance(self.current_asset_account_id.id, acc_type="other")
+        clearing_account_id = self.company.inter_ou_clearing_account_id.id
+        self._check_balance(clearing_account_id, acc_type="clearing")
+
+    def test_journal_no_ou(self):
+        """Test journal can not create if use self-balance but not ou in journal"""
+        with self.assertRaises(UserError):
+            with Form(self.journal_model.with_company(self.company)) as f:
+                f.type = "bank"
+                f.name = "Test new bank not ou"
+                f.code = "testcode"
+            f.save()
diff --git a/account_operating_unit/tests/test_invoice_operating_unit.py b/account_operating_unit/tests/test_invoice_operating_unit.py
new file mode 100644
index 0000000000..3899722b59
--- /dev/null
+++ b/account_operating_unit/tests/test_invoice_operating_unit.py
@@ -0,0 +1,73 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo.exceptions import UserError
+from odoo.tests import Form, tagged
+
+from . import test_account_operating_unit as test_ou
+
+
+@tagged("post_install", "-at_install")
+class TestInvoiceOperatingUnit(test_ou.TestAccountOperatingUnit):
+    def test_create_invoice_validate(self):
+        """Create & Validate the invoice.
+        Test that when an invoice is created, the operating unit is
+        passed to the accounting journal items.
+        """
+        # Create invoice
+        self.invoice = self.move_model.with_user(self.user1.id).create(
+            self._prepare_invoice(self.b2b.id)
+        )
+        self.invoice.invoice_date = self.invoice.date
+        # Validate the invoice
+        self.invoice.with_user(self.user1.id).action_post()
+        # Check Operating Units in journal entries
+        all_op_units = all(
+            move_line.operating_unit_id.id == self.b2b.id
+            for move_line in self.invoice.line_ids
+        )
+        # Assert if journal entries of the invoice
+        # have different operating units
+        self.assertNotEqual(
+            all_op_units,
+            False,
+            "Journal Entries have different Operating Units.",
+        )
+        # Test change ou in move
+        with self.assertRaises(UserError):
+            self.invoice.line_ids[0].operating_unit_id = self.b2c.id
+        # Test change company in move
+        new_company = self.env["res.company"].create({"name": "New Company"})
+        with self.assertRaises(UserError):
+            self.invoice.line_ids[0].company_id = new_company.id
+        # Check report invoice
+        self.env["account.invoice.report"].sudo().read_group(
+            [], ["operating_unit_id"], ["operating_unit_id"]
+        )
+
+    def test_form(self):
+        """Test that the UI behaves as expected"""
+        journal_b2b = self.env["account.journal"].create(
+            {
+                "name": "B2B journal",
+                "code": "B2B",
+                "type": "sale",
+                "operating_unit_id": self.b2b.id,
+                "company_id": self.company.id,
+            }
+        )
+        with Form(
+            self.env["account.move"].with_context(default_move_type="out_invoice")
+        ) as invoice_form:
+            self.assertEqual(invoice_form.operating_unit_id, self.ou1)
+            ou1_journal = invoice_form.journal_id.copy(
+                dict(
+                    operating_unit_id=self.ou1.id,
+                    company_id=self.company.id,
+                )
+            )
+            invoice_form.operating_unit_id = self.b2b
+            self.assertEqual(invoice_form.journal_id, journal_b2b)
+            invoice_form.journal_id = ou1_journal
+            self.assertEqual(invoice_form.operating_unit_id, self.ou1)
diff --git a/account_operating_unit/tests/test_operating_unit_security.py b/account_operating_unit/tests/test_operating_unit_security.py
new file mode 100644
index 0000000000..1676d8f2c9
--- /dev/null
+++ b/account_operating_unit/tests/test_operating_unit_security.py
@@ -0,0 +1,21 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+from odoo.tests import tagged
+
+from . import test_account_operating_unit as test_ou
+
+
+@tagged("post_install", "-at_install")
+class TestOuSecurity(test_ou.TestAccountOperatingUnit):
+    def test_security(self):
+        """Test Security of Account Operating Unit"""
+        # User 2 is only assigned to Operating Unit B2C, and cannot list
+        # Journal Entries from Operating Unit B2B.
+        move_ids = self.aml_model.with_user(self.user2.id).search(
+            [("operating_unit_id", "=", self.b2b.id)]
+        )
+        self.assertFalse(
+            move_ids, "user_2 should not have access to OU %s" % self.b2b.name
+        )
diff --git a/account_operating_unit/tests/test_payment_operating_unit.py b/account_operating_unit/tests/test_payment_operating_unit.py
new file mode 100644
index 0000000000..b0aebb188b
--- /dev/null
+++ b/account_operating_unit/tests/test_payment_operating_unit.py
@@ -0,0 +1,107 @@
+# © 2019 ForgeFlow S.L.
+# © 2019 Serpent Consulting Services Pvt. Ltd.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+import time
+
+from odoo.tests import tagged
+
+from . import test_account_operating_unit as test_ou
+
+
+@tagged("post_install", "-at_install")
+class TestInvoiceOperatingUnit(test_ou.TestAccountOperatingUnit):
+    def test_payment_from_invoice(self):
+        """Create and invoice and a subsquent payment, in another OU"""
+
+        # Create invoice for B2B operating unit
+        self.invoice = self.move_model.with_user(self.user1.id).create(
+            self._prepare_invoice(self.b2b.id)
+        )
+        self.invoice.invoice_date = self.invoice.date
+        # Validate the invoice
+        self.invoice.with_user(self.user1.id).action_post()
+
+        # Pay the invoice using a cash journal associated to the main company
+        ctx = {"active_model": "account.move", "active_ids": [self.invoice.id]}
+        payment_method_id = self.cash_journal_ou1.outbound_payment_method_line_ids[0]
+        register_payments = self.register_payments_model.with_context(**ctx).create(
+            {
+                "payment_date": time.strftime("%Y") + "-07-15",
+                "journal_id": self.cash_journal_ou1.id,
+                "payment_method_line_id": payment_method_id.id,
+            }
+        )
+
+        register_payments.action_create_payments()
+        payment = self.payment_model.search([], order="id desc", limit=1)
+        # Validate that inter OU balance move lines are created
+        self.assertEqual(len(payment.move_id.line_ids), 4)
+        self.assertAlmostEqual(payment.amount, self.invoice.amount_total)
+        self.assertEqual(payment.state, "posted")
+        self.assertEqual(self.invoice.payment_state, "paid")
+
+    def test_payment_from_two_invoices(self):
+        """Create two invoices of different OU and payment from a third OU"""
+
+        # Create invoices for B2B and B2C operating units
+        to_create = [
+            self._prepare_invoice(self.b2b.id, "SUPP/B2B/01"),
+            self._prepare_invoice(self.b2c.id, "SUPP/B2C/02"),
+        ]
+        invoices = self.move_model.with_user(self.user1.id).create(to_create)
+        for invoice in invoices:
+            invoice.invoice_date = invoice.date
+        # Validate the invoices
+        invoices.with_user(self.user1.id).action_post()
+
+        # Pay the invoices using a cash journal associated to the main company
+        payment_method_id = self.cash_journal_ou1.outbound_payment_method_line_ids[0]
+        self.register_payments_model.with_context(
+            active_model="account.move", active_ids=invoices.ids
+        ).create(
+            {
+                "payment_date": time.strftime("%Y") + "-07-15",
+                "journal_id": self.cash_journal_ou1.id,
+                "payment_method_line_id": payment_method_id.id,
+            }
+        )._create_payments()
+
+        payments = self.payment_model.search([], order="id desc", limit=2)
+        inter_ou_moves = self.move_model.search(
+            [("ref", "=", "Inter OU Balancing")], order="id desc", limit=2
+        )
+        self.assertEqual(sum(inter_ou_moves[0].mapped("line_ids.debit")), 115000)
+        self.assertEqual(sum(inter_ou_moves[1].mapped("line_ids.debit")), 115000)
+        for payment in payments:
+            # Validate that inter OU balance move lines are created
+            self.assertEqual(len(payment.move_id.line_ids), 2)
+            self.assertEqual(payment.amount, invoices[0].amount_total)
+            self.assertEqual(payment.state, "posted")
+        for invoice in invoices:
+            self.assertEqual(invoice.payment_state, "paid")
+
+    def test_payment_transfer(self):
+        """Create a transfer payment with journals in different OU"""
+        payment_method_id = self.cash_journal_ou1.outbound_payment_method_line_ids[0]
+        payment = self.payment_model.create(
+            {
+                "payment_type": "outbound",
+                "amount": 115000,
+                "date": time.strftime("%Y") + "-07-15",
+                "journal_id": self.cash_journal_ou1.id,
+                "destination_journal_id": self.cash2_journal_b2b.id,
+                "destination_account_id": self.company.transfer_account_id.id,
+                "payment_method_line_id": payment_method_id.id,
+                "is_internal_transfer": True,
+            }
+        )
+        payment.action_post()
+        payments = payment + payment.paired_internal_transfer_payment_id
+        self.assertEqual(len(payments.move_id.mapped("line_ids.operating_unit_id")), 2)
+        # Validate that every move has their correct OU
+        for move in payments.move_id:
+            ou_in_lines = move.line_ids.operating_unit_id
+            self.assertEqual(len(ou_in_lines), 1)
+            ou_in_journal = move.journal_id.operating_unit_id
+            self.assertEqual(ou_in_lines, ou_in_journal)