# -*- coding: utf-8 -*-
from odoo.addons.l10n_ar.tests.common import TestArCommon
from odoo.tests import tagged, Form
from odoo import Command
from datetime import datetime


@tagged('post_install_l10n', 'post_install', '-at_install')
class TestArWithholdingArRi(TestArCommon):

    @classmethod
    def setUpClass(cls):

        super().setUpClass()

        cls.tax_wth_seq = cls.env['ir.sequence'].create({
            'implementation': 'standard',
            'name': 'tax wth test',
            'padding': 8,
            'number_increment': 1,
        })
        # Withholding 1: 1% untaxed_amount
        cls.tax_wth_test_1 = cls.env.ref('account.%i_ex_tax_withholding_iibb_caba_applied' % cls.env.company.id)
        cls.tax_wth_test_1.write({
            'amount': 10,
            'amount_type': 'percent',
            'l10n_ar_withholding_sequence_id': cls.tax_wth_seq.id,
        })

        # Withholding 2: 1% total_amount
        cls.tax_wth_test_2 = cls.env.ref('account.%i_ex_tax_withholding_iibb_ba_applied' % cls.env.company.id)
        cls.tax_wth_test_2.write({
            'amount': 10,
            'amount_type': 'percent',
            'l10n_ar_withholding_sequence_id': cls.tax_wth_seq.id,
        })

        cls.tax_21 = cls.env.ref('account.%s_ri_tax_vat_21_ventas' % cls.env.company.id)

        cls.other_currency = cls.setup_other_currency('USD', rounding=0.001, rates=[('2022-12-31', 0.01), ('2023-04-30', 0.005)])
        cls.tax_wth_earnings_incurred_scale_test_5 = cls.env.ref('account.%i_ex_tax_withholding_profits_regimen_110_insc' % cls.env.company.id)
        cls.tax_wth_earnings_incurred_test_6 = cls.env.ref('account.%i_ex_tax_withholding_profits_regimen_35_insc' % cls.env.company.id)
        cls.earnings_withholding_sequence = cls.env['ir.sequence'].create({
            'implementation': 'standard',
            'name': 'tax wth test',
            'padding': 1,
            'number_increment': 1,
        })

    def in_invoice_wht(self, l10n_latam_document_number):
        in_invoice_wht = self.env['account.move'].create({
            'move_type': 'in_invoice',
            'date': '2023-01-01',
            'invoice_date': '2023-01-01',
            'partner_id': self.res_partner_adhoc.id,
            'invoice_line_ids': [Command.create({'product_id': self.product_a.id, 'price_unit': 1000.0, 'tax_ids': [Command.set(self.tax_21.ids)]})],
            'l10n_latam_document_number': l10n_latam_document_number,

        })
        in_invoice_wht.action_post()
        return in_invoice_wht

    def in_invoice_2_wht(self, l10n_latam_document_number):
        in_invoice_wht = self.env['account.move'].create({
            'move_type': 'in_invoice',
            'date': '2023-01-01',
            'invoice_date': '2023-01-01',
            'partner_id': self.res_partner_adhoc.id,
            'invoice_line_ids': [
                (0, 0, {'product_id': self.product_b.id, 'price_unit': 1000.0, 'tax_ids': [Command.set(self.tax_21.ids)]})
            ],
            'l10n_latam_document_number': l10n_latam_document_number,

        })
        in_invoice_wht.action_post()
        return in_invoice_wht

    def in_invoice_3_wht(self):
        invoice = self.env['account.move'].create({
            "ref": "Invoice from partner Adhoc service",
            "partner_id": self.res_partner_adhoc.id,
            "move_type": "in_invoice",
            "invoice_line_ids": [(0, 0, {
                'product_id': self.service_iva_21.id,
                'price_unit': 30000.0,
                'quantity': 1
            })],
            "invoice_date": datetime.today(),
            "l10n_latam_document_number": '1-1',
        })
        invoice.action_post()
        return invoice

    def in_invoice_4_wht(self):
        invoice = self.env['account.move'].create({
            "ref": "Invoice from partner Adhoc service",
            "partner_id": self.res_partner_adhoc.id,
            "move_type": "in_invoice",
            "invoice_line_ids": [(0, 0, {
                'product_id': self.service_iva_21.id,
                'price_unit': 40000.0,
                'quantity': 1
            })],
            "invoice_date": datetime.today(),
            "l10n_latam_document_number": '1-2',
        })
        invoice.action_post()
        return invoice

    def third_party_check_journal(self):
        journal_vals = {
                'name': ('Third Party Checks'),
                'type': 'cash',
                'outbound_payment_method_line_ids': [
                    Command.create({'payment_method_id': self.env.ref('l10n_latam_check.account_payment_method_out_third_party_checks').id}),
                ],
                'inbound_payment_method_line_ids': [
                    Command.create({'payment_method_id': self.env.ref('l10n_latam_check.account_payment_method_new_third_party_checks').id}),
                    Command.create({'payment_method_id': self.env.ref('l10n_latam_check.account_payment_method_in_third_party_checks').id}),
                ],
            }
        third_party_check_journal = self.env['account.journal'].create(journal_vals)
        return third_party_check_journal

    def in_third_party_check(self, journal):
        in_third_party_check = self.env['account.payment'].create({
            'date': datetime.today(),
            'amount': 30762.71,
            'payment_type': 'inbound',
            'partner_id': self.res_partner_adhoc.id,
            'journal_id': journal.id,
            'payment_method_line_id': journal.inbound_payment_method_line_ids[0].id,
            'l10n_latam_new_check_ids': [Command.clear()] + [Command.create({'name': 1, 'amount': 30762.71, 'payment_date': datetime.today()})]
        })
        in_third_party_check.action_post()
        return in_third_party_check

    def in_invoice_wht_5(self, l10n_latam_document_number):
        in_invoice_wht = self.env['account.move'].create({
            'move_type': 'in_invoice',
            'date': '2023-01-01',
            'invoice_date': '2023-01-01',
            'partner_id': self.res_partner_adhoc.id,
            'invoice_line_ids': [Command.create({'product_id': self.product_a.id, 'price_unit': 156087.00, 'tax_ids': [Command.set(self.tax_21.ids)]})],
            'l10n_latam_document_number': l10n_latam_document_number,

        })
        in_invoice_wht.action_post()
        return in_invoice_wht

    def new_payment_register(self, move_ids, taxes):
        wizard = self.env['account.payment.register'].with_context(active_model='account.move', active_ids=move_ids.ids).create({'payment_date': '2023-01-01'})
        wizard.l10n_ar_withholding_ids = [Command.clear()] + [Command.create({'tax_id': x['id'], 'base_amount': x['base_amount'], 'amount': 0}) for x in taxes]
        wizard.l10n_ar_withholding_ids._compute_amount()
        return wizard

    def test_01_simple_full_payment(self):
        """Simple full payment in Company currency"""
        moves = self.in_invoice_wht('2-1')
        taxes = [{'id': self.tax_wth_test_1.id, 'base_amount': sum(moves.mapped('amount_untaxed'))}]
        wizard = self.new_payment_register(moves, taxes)
        self.assertEqual(wizard.currency_id.round(sum(wizard.l10n_ar_withholding_ids.mapped('amount'))) + wizard.l10n_ar_net_amount, wizard.amount)
        action = wizard.action_create_payments()
        payment = self.env['account.payment'].browse(action['res_id'])
        self.assertRecordValues(payment.move_id.line_ids.sorted('balance'), [
            # Liquidity line:
            {'debit': 0.0, 'credit': 1110.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -1110.0, 'reconciled': False},
            # base line:
            {'debit': 0.0, 'credit': 1000.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -1000.0, 'reconciled': False},
            # withholding line:
            {'debit': 0.0, 'credit': 100.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -100.0, 'reconciled': False},
            # base line:
            {'debit': 1000.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 1000.0, 'reconciled': False},
            # Receivable line:
            {'debit': 1210.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 1210.0, 'reconciled': True}
        ])
        self.assertEqual(1210, payment.currency_id.round(sum(payment.l10n_ar_withholding_ids.mapped('amount_currency')) * -1  + payment.amount))

    def test_02_two_payments_same_invoice(self):
        """Test two payments to same invoice"""
        moves = self.in_invoice_wht('2-2')
        taxes = [{'id': self.tax_wth_test_1.id, 'base_amount': sum(moves.mapped('amount_untaxed')) * 0.5}]

        wizard_1 = self.new_payment_register(moves, taxes)
        wizard_1.amount = 605.00
        self.assertEqual(wizard_1.currency_id.round(sum(wizard_1.l10n_ar_withholding_ids.mapped('amount'))) + wizard_1.l10n_ar_net_amount, wizard_1.amount)
        action = wizard_1.action_create_payments()
        payment_1 = self.env['account.payment'].browse(action['res_id'])

        # Alf payments in Company currency
        wizard_2 = self.new_payment_register(moves, taxes)
        self.assertEqual(605, wizard_2.source_amount)
        self.assertEqual(wizard_2.currency_id.round(sum(wizard_2.l10n_ar_withholding_ids.mapped('amount'))) + wizard_2.l10n_ar_net_amount, wizard_2.amount)
        action = wizard_2.action_create_payments()
        payment_2 = self.env['account.payment'].browse(action['res_id'])
        self.assertRecordValues(payment_1.move_id.line_ids.sorted('balance'), [
            # Liquidity line:
            {'debit': 0.0, 'credit': 555.0, 'currency_id': wizard_1.currency_id.id, 'amount_currency': -555.0, 'reconciled': False},
            # base line:
            {'debit': 0.0, 'credit': 500.0, 'currency_id': wizard_1.currency_id.id, 'amount_currency': -500.0, 'reconciled': False},
            # withholding line:
            {'debit': 0.0, 'credit': 50.0, 'currency_id': wizard_1.currency_id.id, 'amount_currency': -50.0, 'reconciled': False},
            # base line:
            {'debit': 500, 'credit': 0.0, 'currency_id': wizard_1.currency_id.id, 'amount_currency': 500, 'reconciled': False},
            # Receivable line:
            {'debit': 605.0, 'credit': 0.0, 'currency_id': wizard_1.currency_id.id, 'amount_currency': 605.0, 'reconciled': True}
        ])
        self.assertEqual(605, payment_1.currency_id.round(sum(payment_1.l10n_ar_withholding_ids.mapped('amount_currency')) * -1  + payment_1.amount))

        self.assertRecordValues(payment_2.move_id.line_ids.sorted('balance'), [
            # Liquidity line:
            {'debit': 0.0, 'credit': 555.0, 'currency_id': wizard_2.currency_id.id, 'amount_currency': -555.0, 'reconciled': False},
            # base line:
            {'debit': 0.0, 'credit': 500.0, 'currency_id': wizard_2.currency_id.id, 'amount_currency': -500.0, 'reconciled': False},
            # withholding line:
            {'debit': 0.0, 'credit': 50.0, 'currency_id': wizard_2.currency_id.id, 'amount_currency': -50.0, 'reconciled': False},
            # base line:
            {'debit': 500, 'credit': 0.0, 'currency_id': wizard_2.currency_id.id, 'amount_currency': 500, 'reconciled': False},
            # Receivable line:
            {'debit': 605.0, 'credit': 0.0, 'currency_id': wizard_2.currency_id.id, 'amount_currency': 605.0, 'reconciled': True}
        ])
        self.assertEqual(605, payment_2.currency_id.round(sum(payment_2.l10n_ar_withholding_ids.mapped('amount_currency')) * -1  + payment_2.amount))

    def test_03_two_withholdings_one_payment(self):
        """Simple full payment in Company currency and two wht"""
        moves = self.in_invoice_2_wht('2-3')
        taxes = [{'id': self.tax_wth_test_1.id, 'base_amount': sum(moves.mapped('amount_untaxed'))}, {'id': self.tax_wth_test_2.id, 'base_amount': sum(moves.mapped('amount_total'))}]

        wizard = self.new_payment_register(moves, taxes)
        self.assertEqual(wizard.currency_id.round(sum(wizard.l10n_ar_withholding_ids.mapped('amount'))) + wizard.l10n_ar_net_amount, wizard.amount)
        action = wizard.action_create_payments()
        payment = self.env['account.payment'].browse(action['res_id'])
        line_1 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == self.tax_wth_test_1.id)
        line_2 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == self.tax_wth_test_2.id)
        self.assertEqual(-100, line_1.amount_currency)
        self.assertEqual(-121, line_2.amount_currency)
        self.assertEqual(1210, payment.currency_id.round(sum(payment.l10n_ar_withholding_ids.mapped('amount_currency')) * -1  + payment.amount))

    def test_04_two_withholdings_different_currency(self):
        """Payment in other currency and two withholdings"""
        moves = self.in_invoice_2_wht('2-4')
        taxes = [{'id': self.tax_wth_test_1.id, 'base_amount': 5}, {'id': self.tax_wth_test_2.id, 'base_amount': 6.05}]
        wizard = self.new_payment_register(moves, [])
        wizard.currency_id = self.other_currency.id
        wizard.amount = 6.05
        wizard.l10n_ar_withholding_ids = [Command.clear()] + [Command.create({'tax_id': x['id'], 'base_amount': x['base_amount'], 'amount': 0}) for x in taxes]
        wizard.l10n_ar_withholding_ids._compute_amount()
        self.assertEqual(wizard.currency_id.round(sum(wizard.l10n_ar_withholding_ids.mapped('amount')) + wizard.l10n_ar_net_amount), wizard.currency_id.round(wizard.amount))
        action = wizard.action_create_payments()

        payment = self.env['account.payment'].browse(action['res_id'])
        line_1 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == self.tax_wth_test_1.id)
        line_2 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == self.tax_wth_test_2.id)
        self.assertEqual(-0.50, line_1.amount_currency)
        self.assertEqual(-50, line_1.balance)
        self.assertEqual(-0.605, line_2.amount_currency)
        self.assertEqual(-60.5, line_2.balance)
        self.assertEqual(6.05, payment.currency_id.round(sum(payment.l10n_ar_withholding_ids.mapped('amount_currency')) * -1  + payment.amount))

    def test_05_earnings_withholding_applied_with_scale(self):
        """Two payments with same withholding tax (with tax type 'Earnings Scale'). Verify withholding amount."""
        invoice = self.in_invoice_3_wht()
        self.tax_wth_earnings_incurred_scale_test_5.l10n_ar_withholding_sequence_id = self.earnings_withholding_sequence
        self.env['l10n_ar.partner.tax'].create({
            'partner_id': self.res_partner_adhoc.id,
            'company_id': invoice.company_id.id,
            'tax_id': self.tax_wth_earnings_incurred_scale_test_5.id
        })
        taxes = [{'id': invoice.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice.amount_untaxed}]
        wizard = self.new_payment_register(invoice, taxes)
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 1600)
        wizard.action_create_payments()
        invoice2 = self.in_invoice_4_wht()
        taxes = [{'id': invoice2.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice2.amount_untaxed}]
        wizard = self.new_payment_register(invoice2, taxes)
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 7480)
        wizard.action_create_payments()

    def test_06_earnings_withholding_applied(self):
        """Two payments with same withholding tax (with tax type 'Earnings'). Verify withholding amount."""
        invoice = self.in_invoice_3_wht()
        self.tax_wth_earnings_incurred_test_6.l10n_ar_withholding_sequence_id = self.earnings_withholding_sequence
        self.env['l10n_ar.partner.tax'].create({
            'partner_id': self.res_partner_adhoc.id,
            'company_id': invoice.company_id.id,
            'tax_id': self.tax_wth_earnings_incurred_test_6.id
        })
        taxes = [{'id': invoice.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice.amount_untaxed}]
        wizard = self.new_payment_register(invoice, taxes)
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 1327.8)
        wizard.action_create_payments()
        invoice2 = self.in_invoice_4_wht()
        taxes = [{'id': invoice2.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice2.amount_untaxed}]
        wizard = self.new_payment_register(invoice2, taxes)
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 2400)
        wizard.action_create_payments()

    def test_07_earnings_partial_payment_withholding_applied_with_scale(self):
        """Partial payment with withholding tax (with tax type 'Earnings Scale'). Verify withholding amount."""
        invoice = self.in_invoice_3_wht()
        self.tax_wth_earnings_incurred_scale_test_5.l10n_ar_withholding_sequence_id = self.earnings_withholding_sequence
        self.env['l10n_ar.partner.tax'].create({
            'partner_id': self.res_partner_adhoc.id,
            'company_id': invoice.company_id.id,
            'tax_id': self.tax_wth_earnings_incurred_scale_test_5.id
        })
        taxes = [{'id': invoice.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice.amount_untaxed}]
        wizard = self.new_payment_register(invoice, taxes)
        wizard.amount -= 2420
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 1360)

    def test_08_earnings_withholding_applied_with_scale_and_minimun_withholdable_amount_set(self):
        """Payment with withholding tax type 'Earnings Scale' and minimun withholdable amount set. Verify withholding amount."""
        invoice = self.in_invoice_3_wht()
        self.tax_wth_earnings_incurred_scale_test_5.l10n_ar_withholding_sequence_id = self.earnings_withholding_sequence
        self.tax_wth_earnings_incurred_scale_test_5.l10n_ar_minimum_threshold = 2000
        self.env['l10n_ar.partner.tax'].create({
            'partner_id': self.res_partner_adhoc.id,
            'company_id': invoice.company_id.id,
            'tax_id': self.tax_wth_earnings_incurred_scale_test_5.id
        })
        taxes = [{'id': invoice.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice.amount_untaxed}]
        wizard = self.new_payment_register(invoice, taxes)
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 0.0)

    def test_09_foreign_invoice(self):
        """ Ensure a correct behavior when the invoice has a foreign currency and the payment not. """
        in_invoice_wht = self.env['account.move'].create({
            'move_type': 'in_invoice',
            'date': '2023-01-01',
            'invoice_date': '2023-01-01',
            'currency_id': self.other_currency.id,
            'partner_id': self.res_partner_adhoc.id,
            'invoice_line_ids': [Command.create(
                {'product_id': self.product_a.id, 'price_unit': 1000.0, 'tax_ids': [Command.set(self.tax_21.ids)]}
            )],
            'l10n_latam_document_number': '2-1',
        })
        in_invoice_wht.action_post()
        wizard = self.env['account.payment.register'].with_context(active_model='account.move', active_ids=in_invoice_wht.ids).create({
            'payment_date': '2023-01-01',
            'currency_id': self.company_data['currency'].id,
            'l10n_ar_withholding_ids': [Command.create({'tax_id': self.tax_wth_test_1.id, 'base_amount': sum(in_invoice_wht.mapped('amount_untaxed')), 'amount': 0})],
        })
        wizard.l10n_ar_withholding_ids._compute_amount()
        action = wizard.action_create_payments()
        payment = self.env['account.payment'].browse(action['res_id'])
        self.assertRecordValues(payment.move_id.line_ids.sorted('balance'), [
            # Liquidity line:
            {'debit': 0.0, 'credit': 120900.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -120900.0, 'reconciled': False},
            # base line:
            {'debit': 0.0, 'credit': 1000.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -1000.0, 'reconciled': False},
            # withholding line:
            {'debit': 0.0, 'credit': 100.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -100.0, 'reconciled': False},
            # base line:
            {'debit': 1000.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 1000.0, 'reconciled': False},
            # Receivable line:
            {'debit': 121000.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 121000.0, 'reconciled': True}
        ])

    def test_10_foreign_invoice_and_payment(self):
        """ Ensure a correct behavior when the invoice and the payment have a foreign currency. """
        in_invoice_wht = self.env['account.move'].create({
            'move_type': 'in_invoice',
            'date': '2023-01-01',
            'invoice_date': '2023-01-01',
            'currency_id': self.other_currency.id,
            'partner_id': self.res_partner_adhoc.id,
            'invoice_line_ids': [Command.create(
                {'product_id': self.product_a.id, 'price_unit': 1000.0, 'tax_ids': [Command.set(self.tax_21.ids)]}
            )],
            'l10n_latam_document_number': '2-1',
        })
        in_invoice_wht.action_post()
        wizard = self.env['account.payment.register'].with_context(active_model='account.move', active_ids=in_invoice_wht.ids).create({
            'payment_date': '2023-01-01',
            'currency_id': self.other_currency.id,
            'l10n_ar_withholding_ids': [Command.create({'tax_id': self.tax_wth_test_1.id, 'base_amount': sum(in_invoice_wht.mapped('amount_untaxed')), 'amount': 0})],
        })
        wizard.l10n_ar_withholding_ids._compute_amount()
        action = wizard.action_create_payments()
        payment = self.env['account.payment'].browse(action['res_id'])
        self.assertRecordValues(payment.move_id.line_ids.sorted('balance'), [
            # Liquidity line:
            {'debit': 0.0, 'credit': 111000.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -1110.0, 'reconciled': False},
            # base line:
            {'debit': 0.0, 'credit': 100000.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -1000.0, 'reconciled': False},
            # withholding line:
            {'debit': 0.0, 'credit': 10000.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -100.0, 'reconciled': False},
            # base line:
            {'debit': 100000.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 1000.0, 'reconciled': False},
            # Receivable line:
            {'debit': 121000.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 1210.0, 'reconciled': True}
        ])

    def test_11_earnings_withholding_applied_with_scale(self):
        """Payment with third party check with withholding tax type 'Earnings Scale'. Verify withholding amount."""
        third_party_check_journal = self.third_party_check_journal()
        in_third_party_check = self.in_third_party_check(third_party_check_journal)
        invoice = self.in_invoice_4_wht()
        self.tax_wth_earnings_incurred_scale_test_5.l10n_ar_withholding_sequence_id = self.earnings_withholding_sequence
        self.env['l10n_ar.partner.tax'].create({
            'partner_id': self.res_partner_adhoc.id,
            'company_id': invoice.company_id.id,
            'tax_id': self.tax_wth_earnings_incurred_scale_test_5.id
        })
        taxes = [{'id': invoice.partner_id.l10n_ar_partner_tax_ids.tax_id.id, 'base_amount': invoice.amount_untaxed}]
        wizard = self.new_payment_register(invoice, taxes)
        wizard.journal_id = third_party_check_journal.id
        wizard.payment_method_line_id = wizard.journal_id.inbound_payment_method_line_ids[1].id
        wizard.l10n_latam_move_check_ids = in_third_party_check.l10n_latam_new_check_ids
        wizard._compute_amount()
        self.assertEqual(wizard.amount, 31929.25)
        self.assertEqual(wizard.l10n_ar_withholding_ids.base_amount, 26387.81)
        self.assertEqual(wizard.l10n_ar_withholding_ids.amount, 1166.54)
        self.assertEqual(wizard.l10n_ar_net_amount, 30762.71)

    def test_11_withholding_amounts_1(self):
        """Check computation of withholding tax amount."""
        self.tax_wth_test_1.write({'amount': 4.5})
        moves = self.in_invoice_wht_5('2-1')
        taxes = [{'id': self.tax_wth_test_1.id, 'base_amount': sum(moves.mapped('amount_untaxed'))}]
        wizard = self.new_payment_register(moves, taxes)
        action = wizard.action_create_payments()
        payment = self.env['account.payment'].browse(action['res_id'])
        self.assertRecordValues(payment.move_id.line_ids.sorted('balance'), [
            # Liquidity line:
            {'debit': 0.0, 'credit': 181841.35, 'currency_id': wizard.currency_id.id, 'amount_currency': -181841.35, 'reconciled': False},
            # base line:
            {'debit': 0.0, 'credit': 156087.0, 'currency_id': wizard.currency_id.id, 'amount_currency': -156087.0, 'reconciled': False},
            # withholding line:
            {'debit': 0.0, 'credit': 7023.92, 'currency_id': wizard.currency_id.id, 'amount_currency': -7023.92, 'reconciled': False},
            # base line:
            {'debit': 156087.0, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 156087.0, 'reconciled': False},
            # Receivable line:
            {'debit': 188865.27, 'credit': 0.0, 'currency_id': wizard.currency_id.id, 'amount_currency': 188865.27, 'reconciled': True}
        ])

    def test_12_withholding_check_payment_iterative_flush(self):
        """Test the iterative solver cache flush bug.
        A 30,250 ARS vendor bill with 1% withholding tax (250 ARS retention) paid with an
        own check of 30,000 ARS must iteratively converge to 30,250 gross.
        """
        self.tax_wth_test_1.amount = 1.0

        # Setup Journal with Own Checks Outbound Payment Method
        third_party_check_journal = self.third_party_check_journal()
        own_check_method = self.env.ref('l10n_latam_check.account_payment_method_own_checks')
        third_party_check_journal.outbound_payment_method_line_ids = [Command.create({'payment_method_id': own_check_method.id})]
        own_check_line = third_party_check_journal.outbound_payment_method_line_ids.filtered(lambda l: l.payment_method_id == own_check_method)[:1]

        # Create a Vendor Bill of exactly 30,250 (25000 untaxed + 21% VAT = 30250)
        invoice = self._create_invoice_one_line(
            move_type='in_invoice',
            partner_id=self.res_partner_adhoc,
            product_id=self.product_a,
            price_unit=25000.0,
            tax_ids=self.tax_21,
            l10n_latam_document_number='1-99',
            post=True,
        )

        # Add partner tax configuration to guarantee withholdings automatically apply on the wizard
        self.env['l10n_ar.partner.tax'].create({
            'partner_id': self.res_partner_adhoc.id,
            'company_id': invoice.company_id.id,
            'tax_id': self.tax_wth_test_1.id
        })

        with Form(self.env['account.payment.register'].with_context(active_model='account.move', active_ids=invoice.ids)) as pay_form:
            pay_form.journal_id = third_party_check_journal
            pay_form.payment_method_line_id = own_check_line

            # Add check details triggering onchange combinations
            with pay_form.l10n_latam_new_check_ids.new() as check_line:
                check_line.name = 'CHK-999'
                check_line.payment_date = datetime.today()
                check_line.amount = 30000.0

        wizard = pay_form.save()

        # Validate perfectly converged mathematical values
        self.assertRecordValues(wizard, [{
            'l10n_ar_net_amount': 30000.0,
            'amount': 30250.0,
        }])
        self.assertRecordValues(wizard.l10n_ar_withholding_ids, [{
            'amount': 250.0,
            'base_amount': 25000.0,
        }])

    def test_payment_register_without_currency(self):
        "check computation of amount and adjustment warning without currency"
        moves = self.in_invoice_wht_5('2-1')
        taxes = [{'id': self.tax_wth_test_1.id, 'base_amount': sum(moves.mapped('amount_untaxed'))}]
        wizard = Form(self.new_payment_register(moves, taxes))
        wizard.currency_id = self.env['res.currency']
        self.assertEqual(wizard.amount, 188865.27)
        self.assertFalse(wizard.l10n_ar_adjustment_warning)

    def test_payment_withholding_kept(self):
        """ Check that resetting a payment doesn't remove any payment withholding line. """
        # Vendor Payment Withholding Tax: 0%
        tax_wth_0 = self.tax_wth_test_2.copy({
            'amount': 0.0,
            'l10n_ar_withholding_sequence_id': self.tax_wth_seq.id,
        })
        moves = self.in_invoice_2_wht('2-5')
        taxes = [{'id': self.tax_wth_test_2.id, 'base_amount': 1000.0}, {'id': tax_wth_0.id, 'base_amount': 1000.0}]
        wizard = self.new_payment_register(moves, [])
        wizard.l10n_ar_withholding_ids = [Command.clear()] + [Command.create({'tax_id': x['id'], 'base_amount': x['base_amount'], 'amount': 0}) for x in taxes]
        wizard.l10n_ar_withholding_ids._compute_amount()
        action = wizard.action_create_payments()

        payment = self.env['account.payment'].browse(action['res_id'])
        # There should be 2 payment withholding lines
        self.assertEqual(len(payment.l10n_ar_withholding_ids), 2)
        line_1 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == self.tax_wth_test_2.id)
        line_2 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == tax_wth_0.id)
        self.assertEqual(-100.0, line_1.balance)
        self.assertEqual(0.0, line_2.balance)
        # Reset the payment to draft
        payment.action_draft()
        # Payment withholding lines should be the same
        self.assertEqual(len(payment.l10n_ar_withholding_ids), 2)
        line_1 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == self.tax_wth_test_2.id)
        line_2 = payment.l10n_ar_withholding_ids.filtered(lambda x: x.tax_line_id.id == tax_wth_0.id)
        self.assertEqual(-100.0, line_1.balance)
        self.assertEqual(0.0, line_2.balance)
