from datetime import date from decimal import Decimal from types import SimpleNamespace import unittest from dateutil.relativedelta import relativedelta from trytond.modules.account_invoice_do.cron import _build_error_message from trytond.modules.account_invoice_do.invoice import Invoice, InvoiceLine class AccountInvoiceDoUnitTestCase(unittest.TestCase): class Currency: def round(self, amount): return amount.quantize(Decimal('0.01')) def test_due_date_from_payment_term(self): invoice = SimpleNamespace() invoice.payment_term = SimpleNamespace(lines=[ SimpleNamespace(relativedeltas=[ relativedelta(months=1, days=5), ]), ]) invoice.invoice_date = date(2026, 1, 10) self.assertEqual( Invoice.get_remainder_time(invoice, 'due_date'), date(2026, 2, 15)) def test_amount_paid_only_for_posted_or_paid_invoices(self): posted = SimpleNamespace( id=1, state='posted', total_amount=Decimal('118.00'), amount_to_pay=Decimal('18.00'), currency=self.Currency()) draft = SimpleNamespace( id=2, state='draft', total_amount=Decimal('118.00'), amount_to_pay=Decimal('0.00'), currency=self.Currency()) self.assertEqual(Invoice.get_amount_paid([posted, draft], 'amount_paid'), { 1: Decimal('100.00'), 2: Decimal('0.00'), }) def test_tax_kind_amount_and_line_total(self): line = SimpleNamespace( id=1, type='line', amount=Decimal('100.00'), taxes=[ SimpleNamespace(tax_kind='itbis', rate=Decimal('0.18')), SimpleNamespace(tax_kind='tip', rate=Decimal('0.10')), ], currency=self.Currency()) self.assertEqual( InvoiceLine._compute_tax_kind_amount(line, 'itbis'), Decimal('18.00')) self.assertEqual( InvoiceLine.on_change_with_itbis_invoiced_line(line), Decimal('18.00')) self.assertEqual( InvoiceLine._compute_line_total_amount(line), Decimal('128.00')) def test_subtotal_resets_after_previous_subtotal(self): invoice = SimpleNamespace() line1 = SimpleNamespace( type='line', amount=Decimal('100.00'), taxes=[], currency=None) subtotal1 = SimpleNamespace( id=1, type='subtotal', invoice=invoice, currency=None) line2 = SimpleNamespace( type='line', amount=Decimal('50.00'), taxes=[], currency=None) subtotal2 = SimpleNamespace( id=2, type='subtotal', invoice=invoice, currency=None) invoice.lines = [line1, subtotal1, line2, subtotal2] self.assertEqual( InvoiceLine._compute_line_total_amount(subtotal2), Decimal('50.00')) def test_cron_error_message_uses_fallbacks(self): inv = SimpleNamespace(id=10) message = _build_error_message(inv, ValueError('boom')) self.assertIn('ID: 10', message) self.assertIn('Numero: N/D', message) self.assertIn('Error: boom', message)