diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 29e126351a3bccf172b502b3f9a7b5baa9d3a03c..862e1bd3076e847b755ba58722ef358abd717bd5 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -889,7 +889,8 @@ class AccountMove(models.Model):
                         ARRAY_AGG(counterpart_move.move_type) AS counterpart_move_types,
                         COALESCE(BOOL_AND(COALESCE(pay.is_matched, FALSE))
                             FILTER (WHERE counterpart_move.payment_id IS NOT NULL), TRUE) AS all_payments_matched,
-                        BOOL_OR(COALESCE(BOOL(pay.id), FALSE)) as has_payment
+                        BOOL_OR(COALESCE(BOOL(pay.id), FALSE)) as has_payment,
+                        BOOL_OR(COALESCE(BOOL(counterpart_move.statement_line_id), FALSE)) as has_st_line
                     FROM account_partial_reconcile part
                     JOIN account_move_line source_line ON source_line.id = part.{source_field}_move_id
                     JOIN account_account account ON account.id = source_line.account_id
@@ -932,7 +933,7 @@ class AccountMove(models.Model):
                 if payment_state_matters:
 
                     if currency.is_zero(invoice.amount_residual):
-                        if any(x['has_payment'] for x in reconciliation_vals):
+                        if any(x['has_payment'] or x['has_st_line'] for x in reconciliation_vals):
 
                             # Check if the invoice/expense entry is fully paid or 'in_payment'.
                             if all(x['all_payments_matched'] for x in reconciliation_vals):
diff --git a/addons/account/tests/test_account_move_in_invoice.py b/addons/account/tests/test_account_move_in_invoice.py
index d4106dde3f3964a684193cd7d4f4469e09beeb8c..8693ea6bcefb37d44738cec48336f5738a1d5dfd 100644
--- a/addons/account/tests/test_account_move_in_invoice.py
+++ b/addons/account/tests/test_account_move_in_invoice.py
@@ -5,6 +5,7 @@ from odoo.addons.account.tests.common import AccountTestInvoicingCommon
 from odoo.tests.common import Form
 from odoo.tests import tagged
 from odoo import fields, Command
+from odoo.osv import expression
 from odoo.exceptions import ValidationError, RedirectWarning
 from datetime import date
 
@@ -2059,6 +2060,13 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon):
         self.assertEqual(move.invoice_date.strftime('%Y-%m-%d'), '2022-05-06')
 
     def _assert_payment_move_state(self, move_type, amount, counterpart_values_list, payment_state):
+        def assert_partial(line1, line2):
+            partial = self.env['account.partial.reconcile'].search(expression.OR([
+                [('debit_move_id', '=', line1.id), ('credit_move_id', '=', line2.id)],
+                [('debit_move_id', '=', line2.id), ('credit_move_id', '=', line1.id)],
+            ]), limit=1)
+            self.assertTrue(partial)
+
         def create_move(move_type, amount, account=None):
             move_vals = {
                 'move_type': move_type,
@@ -2132,6 +2140,22 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon):
                 .filtered(lambda line: line.account_type in ('asset_receivable', 'liability_payable'))\
                 .reconcile()
 
+        def create_statement_line(move, amount):
+            statement_line = self.env['account.bank.statement.line'].create({
+                'payment_ref': 'ref',
+                'journal_id': self.company_data['default_journal_bank'].id,
+                'amount': amount,
+                'date': '2020-01-10',
+            })
+            _st_liquidity_lines, st_suspense_lines, _st_other_lines = statement_line\
+                .with_context(skip_account_move_synchronization=True)\
+                ._seek_for_lines()
+            line = move.line_ids.filtered(lambda line: line.account_type in ('asset_receivable', 'liability_payable'))
+
+            st_suspense_lines.account_id = line.account_id
+            (st_suspense_lines + line).reconcile()
+            assert_partial(st_suspense_lines, line)
+
         move = create_move(move_type, amount)
         line = move.line_ids.filtered(lambda line: line.account_type in ('asset_receivable', 'liability_payable'))
         for counterpart_move_type, counterpart_amount in counterpart_values_list:
@@ -2139,10 +2163,13 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon):
                 create_payment(move, counterpart_amount)
             elif counterpart_move_type == 'reverse':
                 create_reverse(move, counterpart_amount)
+            elif counterpart_move_type == 'statement_line':
+                create_statement_line(move, counterpart_amount)
             else:
                 counterpart_move = create_move(counterpart_move_type, counterpart_amount, account=line.account_id)
                 counterpart_line = counterpart_move.line_ids.filtered(lambda x: x.account_id == line.account_id)
                 (line + counterpart_line).reconcile()
+                assert_partial(line, counterpart_line)
 
         if payment_state == 'in_payment' and move._get_invoice_in_payment_state() == 'paid':
             payment_state = 'paid'
@@ -2170,24 +2197,42 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon):
 
             ('out_invoice', 1000.0, [('payment', 500.0)], 'partial'),
             ('out_invoice', 1000.0, [('payment', 1000.0)], 'in_payment'),
+            ('out_invoice', 1000.0, [('statement_line', 500.0)], 'partial'),
+            ('out_invoice', 1000.0, [('statement_line', 1000.0)], 'paid'),
             ('out_receipt', 1000.0, [('payment', 500.0)], 'partial'),
             ('out_receipt', 1000.0, [('payment', 1000.0)], 'in_payment'),
+            ('out_receipt', 1000.0, [('statement_line', 500.0)], 'partial'),
+            ('out_receipt', 1000.0, [('statement_line', 1000.0)], 'paid'),
             ('out_refund', 1000.0, [('payment', 500.0)], 'partial'),
             ('out_refund', 1000.0, [('payment', 1000.0)], 'in_payment'),
+            ('out_refund', 1000.0, [('statement_line', -500.0)], 'partial'),
+            ('out_refund', 1000.0, [('statement_line', -1000.0)], 'paid'),
             ('in_invoice', 1000.0, [('payment', 500.0)], 'partial'),
             ('in_invoice', 1000.0, [('payment', 1000.0)], 'in_payment'),
+            ('in_invoice', 1000.0, [('statement_line', -500.0)], 'partial'),
+            ('in_invoice', 1000.0, [('statement_line', -1000.0)], 'paid'),
             ('in_receipt', 1000.0, [('payment', 500.0)], 'partial'),
             ('in_receipt', 1000.0, [('payment', 1000.0)], 'in_payment'),
+            ('in_receipt', 1000.0, [('statement_line', -500.0)], 'partial'),
+            ('in_receipt', 1000.0, [('statement_line', -1000.0)], 'paid'),
             ('in_refund', 1000.0, [('payment', 500.0)], 'partial'),
             ('in_refund', 1000.0, [('payment', 1000.0)], 'in_payment'),
+            ('in_refund', 1000.0, [('statement_line', 500.0)], 'partial'),
+            ('in_refund', 1000.0, [('statement_line', 1000.0)], 'paid'),
             ('entry', 1000.0, [('payment', 500.0)], 'not_paid'),
             ('entry', 1000.0, [('payment', 1000.0)], 'not_paid'),
+            ('entry', 1000.0, [('statement_line', 500.0)], 'not_paid'),
+            ('entry', 1000.0, [('statement_line', 1000.0)], 'not_paid'),
 
             ('out_invoice', 1000.0, [('out_refund', 500.0), ('payment', 500.0)], 'in_payment'),
             ('out_invoice', 1000.0, [('out_refund', 500.0), ('payment', 400.0)], 'partial'),
+            ('out_invoice', 1000.0, [('out_refund', 500.0), ('statement_line', 500.0)], 'paid'),
+            ('out_invoice', 1000.0, [('out_refund', 500.0), ('statement_line', 400.0)], 'partial'),
             ('out_invoice', 1000.0, [('entry', -1000.0)], 'paid'),
             ('in_invoice', 1000.0, [('in_refund', 500.0), ('payment', 500.0)], 'in_payment'),
             ('in_invoice', 1000.0, [('in_refund', 500.0), ('payment', 400.0)], 'partial'),
+            ('in_invoice', 1000.0, [('in_refund', 500.0), ('statement_line', -500.0)], 'paid'),
+            ('in_invoice', 1000.0, [('in_refund', 500.0), ('statement_line', -400.0)], 'partial'),
             ('in_invoice', 1000.0, [('entry', 1000.0)], 'paid'),
         ):
             with self.subTest(