diff --git a/stock_account_operating_unit/README.rst b/stock_account_operating_unit/README.rst new file mode 100644 index 0000000000..57235d076f --- /dev/null +++ b/stock_account_operating_unit/README.rst @@ -0,0 +1,89 @@ +======================================= +Stock account moves with Operating Unit +======================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:4c1b8e31f015492e7d5387ff3f79eeb230a94add7a9e551203bc5cac586b2dfd + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/18.0/stock_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-18-0/operating-unit-18-0-stock_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=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module introduces the following features: + +- Creates account move lines when stock moves are posted between + internal locations within the same company, but different OU’s. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Create stock moves between internal locations within the same company, +but different OU’s. The journal entries are created and they are +self-balanced within the OU when the journal entries are posted + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Eficent Business and IT Consulting Services S.L. +* Serpent Consulting Services Pvt. Ltd. + +Contributors +------------ + +- Eficent Business and IT Consulting Services S.L. +- Serpent Consulting Services Pvt. Ltd. +- Jarsa Sistemas + +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 `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_account_operating_unit/__init__.py b/stock_account_operating_unit/__init__.py new file mode 100644 index 0000000000..50170638d0 --- /dev/null +++ b/stock_account_operating_unit/__init__.py @@ -0,0 +1,2 @@ +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +from . import model diff --git a/stock_account_operating_unit/__manifest__.py b/stock_account_operating_unit/__manifest__.py new file mode 100644 index 0000000000..39727d5e45 --- /dev/null +++ b/stock_account_operating_unit/__manifest__.py @@ -0,0 +1,23 @@ +# © 2019 Eficent Business and IT Consulting Services S.L. +# - Jordi Ballester Alomar +# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +{ + "name": "Stock account moves with Operating Unit", + "summary": "Create journal entries in moves between internal locations " + "with different operating units.", + "version": "18.0.1.0.0", + "category": "Generic Modules/Sales & Purchases", + "author": "Eficent Business and IT Consulting Services S.L., " + "Serpent Consulting Services Pvt. Ltd.," + "Odoo Community Association (OCA)", + "license": "LGPL-3", + "website": "https://github.com/OCA/operating-unit", + "depends": [ + "stock_operating_unit", + "account_operating_unit", + "stock_account", + ], + "installable": True, +} diff --git a/stock_account_operating_unit/i18n/es.po b/stock_account_operating_unit/i18n/es.po new file mode 100644 index 0000000000..19e497b745 --- /dev/null +++ b/stock_account_operating_unit/i18n/es.po @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_account_operating_unit +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-03-14 11:17+0000\n" +"Last-Translator: Javier Colmenero \n" +"Language-Team: none\n" +"Language: es\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.3.2\n" + +#. module: stock_account_operating_unit +#: code:addons/stock_account_operating_unit/model/stock_move.py:0 +#, python-format +msgid "%s - OU Move" +msgstr "%s - movimiento unidad operacional" + +#. module: stock_account_operating_unit +#: model:ir.model,name:stock_account_operating_unit.model_stock_move +msgid "Stock Move" +msgstr "Movimiento de stock" + +#. module: stock_account_operating_unit +#: code:addons/stock_account_operating_unit/model/stock_move.py:0 +#, python-format +msgid "" +"You cannot create stock moves involving separate source and destination " +"accounts related to different operating units." +msgstr "" +"No puedes crear movimientos de stock, involucrando distintos orígines y " +"destinos asociados a unidades operacionales diferentes." diff --git a/stock_account_operating_unit/i18n/stock_account_operating_unit.pot b/stock_account_operating_unit/i18n/stock_account_operating_unit.pot new file mode 100644 index 0000000000..ed4538c694 --- /dev/null +++ b/stock_account_operating_unit/i18n/stock_account_operating_unit.pot @@ -0,0 +1,33 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_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: stock_account_operating_unit +#: code:addons/stock_account_operating_unit/model/stock_move.py:0 +#, python-format +msgid "%s - OU Move" +msgstr "" + +#. module: stock_account_operating_unit +#: model:ir.model,name:stock_account_operating_unit.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: stock_account_operating_unit +#: code:addons/stock_account_operating_unit/model/stock_move.py:0 +#, python-format +msgid "" +"You cannot create stock moves involving separate source and destination " +"accounts related to different operating units." +msgstr "" diff --git a/stock_account_operating_unit/model/__init__.py b/stock_account_operating_unit/model/__init__.py new file mode 100644 index 0000000000..6ac287cbfc --- /dev/null +++ b/stock_account_operating_unit/model/__init__.py @@ -0,0 +1,2 @@ +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +from . import stock_move diff --git a/stock_account_operating_unit/model/stock_move.py b/stock_account_operating_unit/model/stock_move.py new file mode 100644 index 0000000000..6181cca3fe --- /dev/null +++ b/stock_account_operating_unit/model/stock_move.py @@ -0,0 +1,124 @@ +# © 2019 Eficent Business and IT Consulting Services S.L. +# - Jordi Ballester Alomar +# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +from odoo import exceptions, models + + +class StockMove(models.Model): + _inherit = "stock.move" + + def _generate_valuation_lines_data( + self, + partner_id, + qty, + debit_value, + credit_value, + debit_account_id, + credit_account_id, + svl_id, + description, + ): + res = super()._generate_valuation_lines_data( + partner_id, + qty, + debit_value, + credit_value, + debit_account_id, + credit_account_id, + svl_id, + description, + ) + if res: + debit_line_vals = res.get("debit_line_vals") + credit_line_vals = res.get("credit_line_vals") + price_diff_line_vals = res.get("price_diff_line_vals", {}) + + if ( + self.operating_unit_id + and self.operating_unit_dest_id + and self.operating_unit_id != self.operating_unit_dest_id + and debit_line_vals["account_id"] != credit_line_vals["account_id"] + ): + raise exceptions.UserError( + self.env._( + "You cannot create stock moves involving separate source" + " and destination accounts related to different " + "operating units." + ) + ) + + if not self.operating_unit_dest_id and not self.operating_unit_id: + ou_id = ( + self.picking_id.picking_type_id.warehouse_id.operating_unit_id.id + ) + else: + ou_id = False + + debit_line_vals["operating_unit_id"] = ( + ou_id or self.operating_unit_dest_id.id or self.operating_unit_id.id + ) + credit_line_vals["operating_unit_id"] = ( + ou_id or self.operating_unit_id.id or self.operating_unit_dest_id.id + ) + rslt = { + "credit_line_vals": credit_line_vals, + "debit_line_vals": debit_line_vals, + } + if price_diff_line_vals: + price_diff_line_vals["operating_unit_id"] = ( + ou_id or self.operating_unit_id.id or self.operating_unit_dest_id.id + ) + rslt["price_diff_line_vals"] = price_diff_line_vals + return rslt + return res + + def _action_done(self, cancel_backorder=False): + """ + Generate accounting moves if the product being moved is subject + to real_time valuation tracking, + and the source or destination location are + a transit location or is outside of the company or the source or + destination locations belong to different operating units. + """ + res = super()._action_done(cancel_backorder) + for move in self: + if move.product_id.valuation == "real_time": + # Inter-operating unit moves do not accept to + # from/to non-internal location + if move.location_id.company_id and ( + move.location_id.company_id == move.location_dest_id.company_id + and move.operating_unit_id != move.operating_unit_dest_id + ): + ( + journal_id, + acc_src, + acc_dest, + acc_valuation, + ) = move._get_accounting_data_for_valuation() + + move_lines = move._prepare_account_move_line( + move.product_qty, + move.product_id.standard_price, + acc_valuation, + acc_valuation, + self.env._("%s - OU Move") % move.product_id.display_name, + ) + am = ( + self.env["account.move"] + .with_context( + company_id=move.company_id.id, + ) + .create( + { + "journal_id": journal_id, + "line_ids": move_lines, + "company_id": move.company_id.id, + "ref": move.picking_id and move.picking_id.name, + "stock_move_id": move.id, + } + ) + .with_company(move.location_id.company_id.id) + ) + am.action_post() + return res diff --git a/stock_account_operating_unit/pyproject.toml b/stock_account_operating_unit/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/stock_account_operating_unit/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/stock_account_operating_unit/readme/CONFIGURATION.rst b/stock_account_operating_unit/readme/CONFIGURATION.rst new file mode 100644 index 0000000000..a4a154d498 --- /dev/null +++ b/stock_account_operating_unit/readme/CONFIGURATION.rst @@ -0,0 +1,11 @@ +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. + +#. Create an account for "Inter-OU Clearing" of type Regular. +#. Go to *Settings / Companies / Configuration* and: + + * Set the "Operating Units are self-balanced" checkbox. + * Set the "Inter-OU Clearing" account in "Inter-operating unit clearing + account" field. +#. Assign Operating Unit in Accounts. diff --git a/stock_account_operating_unit/readme/CONTRIBUTORS.md b/stock_account_operating_unit/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..bc29752309 --- /dev/null +++ b/stock_account_operating_unit/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Eficent Business and IT Consulting Services S.L. + \ +- Serpent Consulting Services Pvt. Ltd. \ +- Jarsa Sistemas \ diff --git a/stock_account_operating_unit/readme/DESCRIPTION.md b/stock_account_operating_unit/readme/DESCRIPTION.md new file mode 100644 index 0000000000..f6ae3b2eb1 --- /dev/null +++ b/stock_account_operating_unit/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +This module introduces the following features: + +- Creates account move lines when stock moves are posted between + internal locations within the same company, but different OU’s. diff --git a/stock_account_operating_unit/readme/USAGE.md b/stock_account_operating_unit/readme/USAGE.md new file mode 100644 index 0000000000..32fec63b86 --- /dev/null +++ b/stock_account_operating_unit/readme/USAGE.md @@ -0,0 +1,3 @@ +Create stock moves between internal locations within the same company, +but different OU’s. The journal entries are created and they are +self-balanced within the OU when the journal entries are posted diff --git a/stock_account_operating_unit/static/description/icon.png b/stock_account_operating_unit/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/stock_account_operating_unit/static/description/icon.png differ diff --git a/stock_account_operating_unit/static/description/index.html b/stock_account_operating_unit/static/description/index.html new file mode 100644 index 0000000000..9dd70ddcd6 --- /dev/null +++ b/stock_account_operating_unit/static/description/index.html @@ -0,0 +1,437 @@ + + + + + +Stock account moves with Operating Unit + + + +
+

Stock account moves with Operating Unit

+ + +

Beta License: LGPL-3 OCA/operating-unit Translate me on Weblate Try me on Runboat

+

This module introduces the following features:

+
    +
  • Creates account move lines when stock moves are posted between +internal locations within the same company, but different OU’s.
  • +
+

Table of contents

+ +
+

Usage

+

Create stock moves between internal locations within the same company, +but different OU’s. The journal entries are created and they are +self-balanced within the OU when the journal entries are posted

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Eficent Business and IT Consulting Services S.L.
  • +
  • Serpent Consulting Services Pvt. Ltd.
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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 project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/stock_account_operating_unit/tests/__init__.py b/stock_account_operating_unit/tests/__init__.py new file mode 100644 index 0000000000..604c5f9c2e --- /dev/null +++ b/stock_account_operating_unit/tests/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import test_stock_account_operating_unit diff --git a/stock_account_operating_unit/tests/test_stock_account_operating_unit.py b/stock_account_operating_unit/tests/test_stock_account_operating_unit.py new file mode 100644 index 0000000000..fcafc7a2c9 --- /dev/null +++ b/stock_account_operating_unit/tests/test_stock_account_operating_unit.py @@ -0,0 +1,376 @@ +# © 2019 Eficent Business and IT Consulting Services S.L. +# - Jordi Ballester Alomar +# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +from odoo.tests import Form + +from odoo.addons.stock.tests.common import TestStockCommon + + +class TestStockAccountOperatingUnit(TestStockCommon): + @classmethod + def setUpClass(self): + super().setUpClass() + self.res_groups = self.env["res.groups"] + self.res_users_model = self.env["res.users"] + self.aml_model = self.env["account.move.line"] + self.account_model = self.env["account.account"] + self.product_model = self.env["product.product"] + self.product_cteg_model = self.env["product.category"] + self.acc_type_model = self.env["account.account.type"] + self.operating_unit_model = self.env["operating.unit"] + self.company_model = self.env["res.company"] + self.move_model = self.env["stock.move"] + self.picking_model = self.env["stock.picking"] + + # Company + self.company = self.env.ref("base.main_company") + self.group_stock_manager = self.env.ref("stock.group_stock_manager") + self.grp_acc_user = self.env.ref("account.group_account_invoice") + self.grp_stock_user = self.env.ref("stock.group_stock_user") + # Main Operating Unit + self.ou1 = self.env.ref("operating_unit.main_operating_unit") + # B2B Operating Unit + self.b2b = self.env.ref("operating_unit.b2b_operating_unit") + # B2C Operating Unit + self.b2c = self.env.ref("operating_unit.b2c_operating_unit") + # Partner + self.partner1 = self.env.ref("base.res_partner_1") + self.stock_location_stock = self.env.ref("stock.stock_location_stock") + self.supplier_location = self.env.ref("stock.stock_location_suppliers") + + # Create user1 + self.user1 = self._create_user( + "stock_account_user_1", + [self.grp_stock_user, self.grp_acc_user, self.group_stock_manager], + self.company, + [self.ou1, self.b2c], + ) + # Create user2 + self.user2 = self._create_user( + "stock_account_user_2", + [self.grp_stock_user, self.grp_acc_user, self.group_stock_manager], + self.company, + [self.b2c], + ) + # Create account for Goods Received Not Invoiced + name = "Goods Received Not Invoiced" + code = "grni" + acc_type = self.env.ref("account.data_account_type_equity") + self.account_grni = self._create_account(acc_type, name, code, self.company) + # Create account for Cost of Goods Sold + name = "Cost of Goods Sold" + code = "cogs" + acc_type = self.env.ref("account.data_account_type_expenses") + self.account_cogs_id = self._create_account(acc_type, name, code, self.company) + # Create account for Inventory + name = "Inventory" + code = "inventory" + acc_type = self.env.ref("account.data_account_type_fixed_assets") + self.account_inventory = self._create_account( + acc_type, name, code, self.company + ) + # Create account for Inter-OU Clearing + name = "Inter-OU Clearing" + code = "inter_ou" + acc_type = self.env.ref("account.data_account_type_equity") + self.account_inter_ou_clearing = self._create_account( + acc_type, name, code, self.company + ) + # Update company data + self.company.write( + { + "inter_ou_clearing_account_id": self.account_inter_ou_clearing.id, + "ou_is_self_balanced": True, + } + ) + + # Create Product + self.product = self._create_product() + # Create incoming stock picking type + self.incoming_id = self.env.ref("stock.warehouse0").in_type_id + # Create incoming and internal stock picking types + b2c_wh = self.env.ref("stock_operating_unit.stock_warehouse_b2c") + b2c_wh.lot_stock_id.write({"operating_unit_id": self.b2c.id}) + self.location_b2c_id = b2c_wh.lot_stock_id + self.b2c_type_in_id = b2c_wh.in_type_id + self.b2c_type_int_id = b2c_wh.int_type_id + + def _create_user(self, login, groups, company, operating_units): + """Create a user.""" + group_ids = [group.id for group in groups] + user = self.res_users_model.create( + { + "name": "Test Stock Account User", + "login": login, + "password": "demo", + "email": "example@yourcompany.com", + "company_id": company.id, + "company_ids": [(4, company.id)], + "operating_unit_ids": [(4, ou.id) for ou in operating_units], + "groups_id": [(6, 0, group_ids)], + } + ) + return user + + def _create_account(self, acc_type, name, code, company): + """Create an account.""" + account = self.account_model.create( + { + "name": name, + "code": code, + "user_type_id": acc_type.id, + "company_id": company.id, + } + ) + return account + + def _create_product(self): + """Create a Product with inventory valuation set to auto.""" + product_cteg = self.product_cteg_model.create( + { + "name": "test_product_ctg", + "property_valuation": "real_time", + "property_stock_valuation_account_id": self.account_inventory.id, + "property_stock_account_input_categ_id": self.account_grni.id, + "property_stock_account_output_categ_id": self.account_cogs_id, + } + ) + product = self.product_model.create( + { + "name": "test_product", + "categ_id": product_cteg.id, + "type": "product", + "list_price": 1.0, + "standard_price": 1.0, + } + ) + return product + + def _create_picking(self, user, ou_id, picking_type, src_loc_id, dest_loc_id): + """Create a Picking.""" + picking = self.picking_model.with_user(user.id).create( + { + "picking_type_id": picking_type.id, + "location_id": src_loc_id.id, + "location_dest_id": dest_loc_id.id, + "operating_unit_id": ou_id.id, + } + ) + self.move_model.with_user(user.id).create( + { + "name": "a move", + "product_id": self.product.id, + "product_uom_qty": 1.0, + "product_uom": 1, + "picking_id": picking.id, + "location_id": src_loc_id.id, + "location_dest_id": dest_loc_id.id, + } + ) + return picking + + def _confirm_receive(self, user_id, picking): + """ + Checks the stock availability, validates and process the stock picking. + """ + picking.action_confirm() + picking.action_assign() + res = picking.with_user(user_id).button_validate() + wiz = Form( + self.env[res["res_model"]].with_context(**res["context"]), + view=self.env.ref("stock.view_immediate_transfer"), + ).save() + wiz.process() + + def _check_account_balance( + self, account_id, operating_unit=None, expected_balance=0.0 + ): + """ + Check the balance of the account based on different operating units. + """ + domain = [("account_id", "=", account_id)] + if operating_unit: + domain.extend([("operating_unit_id", "=", operating_unit.id)]) + + balance = self._get_balance(domain) + if operating_unit: + self.assertEqual( + balance, + expected_balance, + ( + f"Balance is not {expected_balance} for " + f"Operating Unit {operating_unit.name}." + ), + ) + else: + self.assertEqual( + balance, + expected_balance, + f"Balance is not {str(expected_balance)} for all Operating Units.", + ) + + def _get_balance(self, domain): + """ + Call read_group method and return the balance of particular account. + """ + aml_rec = self.aml_model.read_group( + domain, ["debit", "credit", "account_id"], ["account_id"] + ) + if aml_rec: + return aml_rec[0].get("debit", 0.0) - aml_rec[0].get("credit", 0.0) + else: + return 0.0 + + def test_pickings(self): + """Test account balances during receiving stock into the main + operating unit, then into b2c operating unit, and then transfer stock + from main ou to b2c.""" + # Create Incoming Shipment 1 + self.picking = self._create_picking( + self.user1, + self.ou1, + self.incoming_id, + self.supplier_location, + self.stock_location_stock, + ) + # Receive it + self._confirm_receive(self.user1.id, self.picking) + # GL account ‘Inventory’ has balance 1 irrespective of the OU + expected_balance = 1.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=None, + expected_balance=expected_balance, + ) + # GL account ‘Inventory’ has balance 1 on OU main_operating_unit + expected_balance = 1.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=self.ou1, + expected_balance=expected_balance, + ) + # GL account ‘Inventory’ has balance 0 on OU B2C + expected_balance = 0.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=self.b2c, + expected_balance=expected_balance, + ) + # GL account ‘Goods Received Not Invoiced’ has balance - 1 + # irrespective of the OU + expected_balance = -1.0 + self._check_account_balance( + self.account_grni.id, + operating_unit=None, + expected_balance=expected_balance, + ) + # GL account ‘Goods Received Not Invoiced’ has balance -1 on Main OU + expected_balance = -1.0 + self._check_account_balance( + self.account_grni.id, + operating_unit=self.ou1, + expected_balance=expected_balance, + ) + # GL account ‘Goods Received Not Invoiced’ has balance 0 on OU b2c + expected_balance = 0.0 + self._check_account_balance( + self.account_grni.id, + operating_unit=self.b2c, + expected_balance=expected_balance, + ) + + # Create Incoming Shipment 2 + self.picking = self._create_picking( + self.user2, + self.b2c, + self.b2c_type_in_id, + self.supplier_location, + self.location_b2c_id, + ) + + # Receive it + self._confirm_receive(self.user2.id, self.picking) + + # GL account ‘Inventory’ has balance 2 irrespective of the OU + expected_balance = 2.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=None, + expected_balance=expected_balance, + ) + # GL account ‘Inventory’ has balance 1 on OU main_operating_unit + expected_balance = 1.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=self.ou1, + expected_balance=expected_balance, + ) + # GL account ‘Inventory’ has balance 1 on OU b2c + expected_balance = 1.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=self.b2c, + expected_balance=expected_balance, + ) + # GL account ‘Goods Received Not Invoiced’ has balance - 2 + # irrespective of the OU + expected_balance = -2.0 + self._check_account_balance( + self.account_grni.id, + operating_unit=None, + expected_balance=expected_balance, + ) + # GL account ‘Goods Received Not Invoiced’ has balance -1 on Main OU + expected_balance = -1.0 + self._check_account_balance( + self.account_grni.id, + operating_unit=self.ou1, + expected_balance=expected_balance, + ) + # GL account ‘Goods Received Not Invoiced’ has balance 0 on OU b2c + expected_balance = -1.0 + self._check_account_balance( + self.account_grni.id, + operating_unit=self.b2c, + expected_balance=expected_balance, + ) + + # Create Internal Transfer + self.picking = self._create_picking( + self.user1, + self.b2c, + self.b2c_type_int_id, + self.stock_location_stock, + self.location_b2c_id, + ) + # Receive it + self._confirm_receive(self.user1.id, self.picking) + # GL account ‘Inventory’ has balance 2 irrespective of the OU + expected_balance = 2.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=None, + expected_balance=expected_balance, + ) + # GL account ‘Inventory’ has balance 0 on OU main_operating_unit + expected_balance = 0.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=self.ou1, + expected_balance=expected_balance, + ) + # GL account ‘Inventory’ has balance 2 on OU b2c + expected_balance = 2.0 + self._check_account_balance( + self.account_inventory.id, + operating_unit=self.b2c, + expected_balance=expected_balance, + ) + # GL account ‘Inter-OU clearing’ has balance 0 irrespective of the OU + expected_balance = 0.0 + self._check_account_balance( + self.account_inter_ou_clearing.id, + operating_unit=None, + expected_balance=expected_balance, + )