diff --git a/account_reconcile_payment_order/__manifest__.py b/account_reconcile_payment_order/__manifest__.py index a423b783..b7f539a8 100644 --- a/account_reconcile_payment_order/__manifest__.py +++ b/account_reconcile_payment_order/__manifest__.py @@ -5,16 +5,12 @@ { "name": "Reconcile payment orders", "version": "12.0.1.0.0", - "author": "Therp BV," - "Tecnativa," - "Odoo Community Association (OCA)", + "author": "Therp BV," "Tecnativa," "Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/account-reconcile", "category": "Invoicing Management", "summary": "Automatically propose all lines generated from payment orders", - "depends": [ - 'account_payment_order', - ], + "depends": ["account_payment_order",], "installable": True, - "maintainers": ['pedrobaeza'], + "maintainers": ["pedrobaeza"], } diff --git a/account_reconcile_payment_order/models/account_reconciliation_widget.py b/account_reconcile_payment_order/models/account_reconciliation_widget.py index c3697694..87ffb0cd 100644 --- a/account_reconcile_payment_order/models/account_reconciliation_widget.py +++ b/account_reconcile_payment_order/models/account_reconciliation_widget.py @@ -1,43 +1,45 @@ # Copyright 2019 Tecnativa - Pedro M. Baeza # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo import models, api +from odoo import api, models class AccountReconciliationWidget(models.AbstractModel): - _inherit = 'account.reconciliation.widget' + _inherit = "account.reconciliation.widget" @api.model def _get_possible_payment_orders_for_statement_line(self, st_line): """Find orders that might be candidates for matching a statement line. """ - return self.env['account.payment.order'].search([ - ('total_company_currency', '=', st_line.amount), - ('state', 'in', ['done', 'uploaded']), - ]) + return self.env["account.payment.order"].search( + [ + ("total_company_currency", "=", st_line.amount), + ("state", "in", ["done", "uploaded"]), + ] + ) @api.model - def _get_reconcile_lines_from_order(self, st_line, order, - excluded_ids=None): + def _get_reconcile_lines_from_order(self, st_line, order, excluded_ids=None): """Return lines to reconcile our statement line with.""" - aml_obj = self.env['account.move.line'] - reconciled_lines = aml_obj.search([ - ('bank_payment_line_id', 'in', order.bank_line_ids.ids) - ]) + aml_obj = self.env["account.move.line"] + reconciled_lines = aml_obj.search( + [("bank_payment_line_id", "in", order.bank_line_ids.ids)] + ) return ( - reconciled_lines.mapped('move_id.line_ids') - reconciled_lines - - aml_obj.browse(excluded_ids) + reconciled_lines.mapped("move_id.line_ids") + - reconciled_lines + - aml_obj.browse(excluded_ids) ).filtered(lambda x: not x.reconciled) - def _prepare_proposition_from_orders(self, st_line, orders, - excluded_ids=None): + def _prepare_proposition_from_orders(self, st_line, orders, excluded_ids=None): """Fill with the expected format the reconciliation proposition for the given statement line and possible payment orders. """ target_currency = ( - st_line.currency_id or st_line.journal_id.currency_id or - st_line.journal_id.company_id.currency_id + st_line.currency_id + or st_line.journal_id.currency_id + or st_line.journal_id.company_id.currency_id ) for order in orders: elegible_lines = self._get_reconcile_lines_from_order( @@ -45,7 +47,8 @@ class AccountReconciliationWidget(models.AbstractModel): ) if elegible_lines: return self._prepare_move_lines( - elegible_lines, target_currency=target_currency, + elegible_lines, + target_currency=target_currency, target_date=st_line.date, ) return [] @@ -54,14 +57,13 @@ class AccountReconciliationWidget(models.AbstractModel): res = super().get_bank_statement_line_data( st_line_ids, excluded_ids=excluded_ids, ) - st_line_obj = self.env['account.bank.statement.line'] - for line_vals in res.get('lines', []): - st_line = st_line_obj.browse(line_vals['st_line']['id']) - orders = self._get_possible_payment_orders_for_statement_line( - st_line) + st_line_obj = self.env["account.bank.statement.line"] + for line_vals in res.get("lines", []): + st_line = st_line_obj.browse(line_vals["st_line"]["id"]) + orders = self._get_possible_payment_orders_for_statement_line(st_line) proposition_vals = self._prepare_proposition_from_orders( st_line, orders, excluded_ids=excluded_ids, ) if proposition_vals: - line_vals['reconciliation_proposition'] = proposition_vals + line_vals["reconciliation_proposition"] = proposition_vals return res diff --git a/account_reconcile_payment_order/tests/test_account_reconcile_payment_order.py b/account_reconcile_payment_order/tests/test_account_reconcile_payment_order.py index 220190ff..6bf9a30b 100644 --- a/account_reconcile_payment_order/tests/test_account_reconcile_payment_order.py +++ b/account_reconcile_payment_order/tests/test_account_reconcile_payment_order.py @@ -1,104 +1,106 @@ # Copyright 2019 Tecnativa - Pedro M. Baeza # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo.addons.account_payment_order.tests.test_payment_order_inbound \ - import TestPaymentOrderInboundBase +from odoo.addons.account_payment_order.tests.test_payment_order_inbound import ( + TestPaymentOrderInboundBase, +) class TestAccountReconcilePaymentOrder(TestPaymentOrderInboundBase): @classmethod def setUpClass(cls): super().setUpClass() - cls.widget_obj = cls.env['account.reconciliation.widget'] - cls.bank_journal = cls.env['account.journal'].search( - [('type', '=', 'bank'), - '|', ('company_id', '=', cls.env.user.company_id.id), - ('company_id', '=', False)], limit=1) + cls.widget_obj = cls.env["account.reconciliation.widget"] + cls.bank_journal = cls.env["account.journal"].search( + [ + ("type", "=", "bank"), + "|", + ("company_id", "=", cls.env.user.company_id.id), + ("company_id", "=", False), + ], + limit=1, + ) # Create second invoice for being sure it handles the payment order cls.invoice2 = cls._create_customer_invoice() - cls.partner2 = cls.env['res.partner'].create({ - 'name': 'Test partner 2', - }) + cls.partner2 = cls.env["res.partner"].create({"name": "Test partner 2",}) cls.invoice2.partner_id = cls.partner2.id cls.invoice2.action_invoice_open() # Add to payment order using the wizard - cls.env['account.invoice.payment.line.multi'].with_context( - active_model='account.invoice', - active_ids=cls.invoice2.ids, + cls.env["account.invoice.payment.line.multi"].with_context( + active_model="account.invoice", active_ids=cls.invoice2.ids, ).create({}).run() # Prepare statement - cls.statement = cls.env['account.bank.statement'].create({ - 'name': 'Test statement', - 'date': '2019-01-01', - 'journal_id': cls.bank_journal.id, - 'line_ids': [ - (0, 0, { - 'date': '2019-01-01', - 'name': 'Test line', - 'amount': 200, - }), - ], - }) + cls.statement = cls.env["account.bank.statement"].create( + { + "name": "Test statement", + "date": "2019-01-01", + "journal_id": cls.bank_journal.id, + "line_ids": [ + (0, 0, {"date": "2019-01-01", "name": "Test line", "amount": 200,}), + ], + } + ) def test_reconcile_payment_order_bank(self): self.assertEqual(len(self.inbound_order.payment_line_ids), 2) - self.inbound_mode.write({ - 'offsetting_account': 'bank_account', - 'move_option': 'line', - }) + self.inbound_mode.write( + {"offsetting_account": "bank_account", "move_option": "line",} + ) # Prepare payment order self.inbound_order.draft2open() self.inbound_order.open2generated() self.inbound_order.generated2uploaded() # Check widget result - res = self.widget_obj.get_bank_statement_line_data( - self.statement.line_ids.ids, - ) - self.assertEqual(len(res['lines'][0]['reconciliation_proposition']), 2) + res = self.widget_obj.get_bank_statement_line_data(self.statement.line_ids.ids,) + self.assertEqual(len(res["lines"][0]["reconciliation_proposition"]), 2) def test_reconcile_payment_order_transfer_account(self): self.assertEqual(len(self.inbound_order.payment_line_ids), 2) - receivable_account = self.env['account.account'].create({ - 'name': 'Extra receivable account', - 'code': 'TEST_ERA', - 'reconcile': True, - 'user_type_id': ( - self.env.ref('account.data_account_type_receivable').id), - }) - self.inbound_mode.write({ - 'offsetting_account': 'transfer_account', - 'transfer_account_id': receivable_account.id, - 'transfer_journal_id': self.bank_journal.id, - 'move_option': 'line', - }) + receivable_account = self.env["account.account"].create( + { + "name": "Extra receivable account", + "code": "TEST_ERA", + "reconcile": True, + "user_type_id": ( + self.env.ref("account.data_account_type_receivable").id + ), + } + ) + self.inbound_mode.write( + { + "offsetting_account": "transfer_account", + "transfer_account_id": receivable_account.id, + "transfer_journal_id": self.bank_journal.id, + "move_option": "line", + } + ) self.assertEqual(len(self.inbound_order.payment_line_ids), 2) # Prepare payment order self.inbound_order.draft2open() self.inbound_order.open2generated() self.inbound_order.generated2uploaded() # Check widget result - res = self.widget_obj.get_bank_statement_line_data( - self.statement.line_ids.ids, - ) - proposition = res['lines'][0]['reconciliation_proposition'] + res = self.widget_obj.get_bank_statement_line_data(self.statement.line_ids.ids,) + proposition = res["lines"][0]["reconciliation_proposition"] self.assertEqual(len(proposition), 2) # Reconcile that entries and check again - st_line_vals = res['lines'][0]['st_line'] + st_line_vals = res["lines"][0]["st_line"] self.widget_obj.process_move_lines( - data=[{ - 'type': '', - 'mv_line_ids': [ - proposition[0]['id'], - proposition[1]['id'], - ], - 'new_mv_line_dicts': [{ - 'name': st_line_vals['name'], - 'credit': st_line_vals['amount'], - 'debit': 0, - 'account_id': st_line_vals['account_id'][0], - 'journal_id': st_line_vals['journal_id'], - }], - }], + data=[ + { + "type": "", + "mv_line_ids": [proposition[0]["id"], proposition[1]["id"],], + "new_mv_line_dicts": [ + { + "name": st_line_vals["name"], + "credit": st_line_vals["amount"], + "debit": 0, + "account_id": st_line_vals["account_id"][0], + "journal_id": st_line_vals["journal_id"], + } + ], + } + ], ) res2 = self.widget_obj.get_bank_statement_line_data( self.statement.line_ids.ids,