diff --git a/account_operating_unit/models/account_invoice.py b/account_operating_unit/models/account_invoice.py index 399b594ec9..7b5bcde49b 100644 --- a/account_operating_unit/models/account_invoice.py +++ b/account_operating_unit/models/account_invoice.py @@ -10,14 +10,14 @@ class AccountInvoice(models.Model): _inherit = "account.invoice" - operating_unit_id = fields.Many2one('operating.unit', 'Operating Unit', - default=lambda self: - self.env['res.users']. - operating_unit_default_get(self._uid), - domain="[('user_ids', '=', uid)]", - readonly=True, - states={'draft': [('readonly', - False)]}) + operating_unit_id = fields.Many2one( + comodel_name='operating.unit', + string='Operating Unit', + default=lambda self: self.env['res.users'].operating_unit_default_get( + self._uid), + domain="[('user_ids', '=', uid)]", + readonly=True, + states={'draft': [('readonly', False)]}) @api.onchange('operating_unit_id') def _onchange_operating_unit(self): diff --git a/account_operating_unit/models/account_journal.py b/account_operating_unit/models/account_journal.py index f8bad2f4bf..cb7fdf738a 100644 --- a/account_operating_unit/models/account_journal.py +++ b/account_operating_unit/models/account_journal.py @@ -9,12 +9,12 @@ class AccountJournal(models.Model): _inherit = "account.journal" - operating_unit_id = fields.Many2one(comodel_name='operating.unit', - string='Operating Unit', - domain="[('user_ids', '=', uid)]", - help="Operating Unit that will be " - "used in payments, when this " - "journal is used.") + operating_unit_id = fields.Many2one( + comodel_name='operating.unit', + string='Operating Unit', + domain="[('user_ids', '=', uid)]", + help="Operating Unit that will be used in payments, " + "when this journal is used.") @api.multi @api.constrains('type') diff --git a/account_operating_unit/models/account_move.py b/account_operating_unit/models/account_move.py index dbe701aa56..d68eab0c7a 100644 --- a/account_operating_unit/models/account_move.py +++ b/account_operating_unit/models/account_move.py @@ -9,8 +9,10 @@ class AccountMoveLine(models.Model): _inherit = "account.move.line" - operating_unit_id = fields.Many2one('operating.unit', 'Operating Unit', - domain="[('user_ids', '=', uid)]",) + operating_unit_id = fields.Many2one( + comodel_name='operating.unit', + string='Operating Unit', + domain="[('user_ids', '=', uid)]",) @api.model def create(self, vals): @@ -54,11 +56,12 @@ def _check_move_operating_unit(self): class AccountMove(models.Model): _inherit = "account.move" - operating_unit_id = fields.Many2one('operating.unit', - 'Default operating unit', - domain="[('user_ids', '=', uid)]", - help="This operating unit will " - "be defaulted in the move lines.") + operating_unit_id = fields.Many2one( + comodel_name='operating.unit', + string='Default operating unit', + domain="[('user_ids', '=', uid)]", + help="This operating unit will be " + "defaulted in the move lines.") @api.multi def _prepare_inter_ou_balancing_move_line(self, move, ou_id, diff --git a/account_operating_unit/models/account_payment.py b/account_operating_unit/models/account_payment.py index b17e9ba693..d19bb7167b 100644 --- a/account_operating_unit/models/account_payment.py +++ b/account_operating_unit/models/account_payment.py @@ -23,7 +23,7 @@ def _compute_operating_unit_id(self): def _get_counterpart_move_line_vals(self, invoice=False): res = super(AccountPayment, self)._get_counterpart_move_line_vals(invoice=invoice) - if len(invoice) == 1: + if invoice and len(invoice) == 1: res['operating_unit_id'] = invoice.operating_unit_id.id or False else: res['operating_unit_id'] = self.operating_unit_id.id or False diff --git a/stock_account_operating_unit/README.rst b/stock_account_operating_unit/README.rst new file mode 100644 index 0000000000..0d3dd6638f --- /dev/null +++ b/stock_account_operating_unit/README.rst @@ -0,0 +1,85 @@ +======================================= +Stock account moves with Operating Unit +======================================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-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/12.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-12-0/operating-unit-12-0-stock_account_operating_unit + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/213/12.0 + :alt: Try me on Runbot + +|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 smashing 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. + +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..82c3cc8b7c --- /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": "12.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/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..d1f14b9618 --- /dev/null +++ b/stock_account_operating_unit/model/stock_move.py @@ -0,0 +1,90 @@ +# © 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 _, api, 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): + res = super(StockMove, self)._generate_valuation_lines_data( + partner_id, qty, debit_value, credit_value, debit_account_id, + credit_account_id) + 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( + _('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 + + @api.multi + def _action_done(self): + """ + 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(StockMove, self)._action_done() + 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) + am = self.env["account.move"].with_context( + force_company=move.location_id.company_id.id, + 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': self.id, + }) + am.post() + return res 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.rst b/stock_account_operating_unit/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..6f26312176 --- /dev/null +++ b/stock_account_operating_unit/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Eficent Business and IT Consulting Services S.L. +* Serpent Consulting Services Pvt. Ltd. diff --git a/stock_account_operating_unit/readme/DESCRIPTION.rst b/stock_account_operating_unit/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..2e9ddaf403 --- /dev/null +++ b/stock_account_operating_unit/readme/DESCRIPTION.rst @@ -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.rst b/stock_account_operating_unit/readme/USAGE.rst new file mode 100644 index 0000000000..419dbd3b53 --- /dev/null +++ b/stock_account_operating_unit/readme/USAGE.rst @@ -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/index.html b/stock_account_operating_unit/static/description/index.html new file mode 100644 index 0000000000..13cd2e6f7f --- /dev/null +++ b/stock_account_operating_unit/static/description/index.html @@ -0,0 +1,432 @@ + + + + + + +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 Runbot

+

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 smashing 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..22fbffe462 --- /dev/null +++ b/stock_account_operating_unit/tests/test_stock_account_operating_unit.py @@ -0,0 +1,311 @@ +# © 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.addons.stock.tests.common import TestStockCommon + + +class TestStockAccountOperatingUnit(TestStockCommon): + + def setUp(self): + super(TestStockAccountOperatingUnit, self).setUp() + 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.inv_line_model = self.env['account.invoice.line'] + 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.sudo(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.sudo(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.sudo(user_id).button_validate() + validate_id = res['res_id'] + validate = self.env['stock.immediate.transfer'].browse(validate_id) + validate.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, + 'Balance is not %s for Operating Unit %s.' + % (str(expected_balance), operating_unit.name)) + else: + self.assertEqual( + balance, expected_balance, + 'Balance is not %s for all Operating Units.' + % str(expected_balance)) \ + + + 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) diff --git a/stock_operating_unit/model/stock_warehouse.py b/stock_operating_unit/model/stock_warehouse.py index f1832f739f..d3daa77f3a 100644 --- a/stock_operating_unit/model/stock_warehouse.py +++ b/stock_operating_unit/model/stock_warehouse.py @@ -46,7 +46,7 @@ def _check_location(self): if (rec.warehouse_id and rec.location_id and rec.warehouse_id.operating_unit_id != rec.location_id.operating_unit_id): - raise UserError( - _('Configuration Error. The Operating Unit of the ' - 'Warehouse and the Location must be the same. ') - ) + raise UserError( + _('Configuration Error. The Operating Unit of the ' + 'Warehouse and the Location must be the same. ') + )