2026-07-22 22:29:04 -04:00
|
|
|
import datetime
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
from types import SimpleNamespace
|
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
|
|
from trytond.modules.account.tests.test_module import (
|
|
|
|
|
create_chart, get_fiscalyear)
|
|
|
|
|
from trytond.modules.account_invoice_do.invoice import InvoiceLine
|
|
|
|
|
from trytond.modules.company.tests import create_company, set_company
|
|
|
|
|
from trytond.pool import Pool
|
|
|
|
|
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AccountInvoiceDoTestCase(ModuleTestCase):
|
|
|
|
|
"Test Account Invoice Do module"
|
|
|
|
|
module = 'account_invoice_do'
|
|
|
|
|
|
|
|
|
|
@with_transaction()
|
|
|
|
|
def test_customer_invoice_without_product_posts_and_computes_do_fields(self):
|
|
|
|
|
'Post customer invoice and compute Dominican invoice helper fields'
|
|
|
|
|
pool = Pool()
|
|
|
|
|
Account = pool.get('account.account')
|
|
|
|
|
FiscalYear = pool.get('account.fiscalyear')
|
|
|
|
|
InvoiceSequence = pool.get('account.fiscalyear.invoice_sequence')
|
|
|
|
|
Invoice = pool.get('account.invoice')
|
|
|
|
|
Journal = pool.get('account.journal')
|
|
|
|
|
Party = pool.get('party.party')
|
|
|
|
|
PaymentTerm = pool.get('account.invoice.payment_term')
|
|
|
|
|
Sequence = pool.get('ir.sequence.strict')
|
|
|
|
|
SequenceType = pool.get('ir.sequence.type')
|
|
|
|
|
|
|
|
|
|
today = datetime.date.today()
|
|
|
|
|
company = create_company()
|
|
|
|
|
create_chart(company)
|
|
|
|
|
fiscalyear = get_fiscalyear(company, today=today)
|
|
|
|
|
sequence_type, = SequenceType.search([
|
|
|
|
|
('name', '=', 'Invoice'),
|
|
|
|
|
], limit=1)
|
|
|
|
|
invoice_sequence, = Sequence.create([{
|
|
|
|
|
'name': fiscalyear.name,
|
|
|
|
|
'sequence_type': sequence_type.id,
|
|
|
|
|
'company': company.id,
|
|
|
|
|
}])
|
|
|
|
|
fiscalyear.invoice_sequences = [InvoiceSequence(
|
|
|
|
|
company=company,
|
|
|
|
|
in_invoice_sequence=invoice_sequence,
|
|
|
|
|
in_credit_note_sequence=invoice_sequence,
|
|
|
|
|
out_invoice_sequence=invoice_sequence,
|
|
|
|
|
out_credit_note_sequence=invoice_sequence)]
|
|
|
|
|
fiscalyear.save()
|
|
|
|
|
FiscalYear.create_period([fiscalyear])
|
|
|
|
|
|
|
|
|
|
receivable, = Account.search([
|
|
|
|
|
('company', '=', company.id),
|
|
|
|
|
('type.receivable', '=', True),
|
|
|
|
|
('party_required', '=', True),
|
|
|
|
|
], limit=1)
|
|
|
|
|
revenue, = Account.search([
|
|
|
|
|
('company', '=', company.id),
|
|
|
|
|
('type.revenue', '=', True),
|
|
|
|
|
('closed', '!=', True),
|
|
|
|
|
], limit=1)
|
|
|
|
|
journal, = Journal.search([('type', '=', 'revenue')], limit=1)
|
|
|
|
|
party, = Party.create([{
|
|
|
|
|
'name': 'Cliente local',
|
|
|
|
|
'addresses': [('create', [{}])],
|
|
|
|
|
}])
|
|
|
|
|
term, = PaymentTerm.create([{
|
|
|
|
|
'name': 'Contado',
|
|
|
|
|
'lines': [('create', [{'type': 'remainder'}])],
|
|
|
|
|
}])
|
|
|
|
|
|
|
|
|
|
with set_company(company):
|
|
|
|
|
invoice, = Invoice.create([{
|
|
|
|
|
'type': 'out',
|
|
|
|
|
'company': company.id,
|
|
|
|
|
'party': party.id,
|
|
|
|
|
'invoice_address': party.addresses[0].id,
|
|
|
|
|
'account': receivable.id,
|
|
|
|
|
'currency': company.currency.id,
|
|
|
|
|
'invoice_date': today,
|
|
|
|
|
'accounting_date': today,
|
|
|
|
|
'journal': journal.id,
|
|
|
|
|
'payment_term': term.id,
|
|
|
|
|
'lines': [('create', [{
|
|
|
|
|
'type': 'line',
|
|
|
|
|
'description': 'Servicio local',
|
|
|
|
|
'quantity': 2,
|
|
|
|
|
'unit_price': Decimal('150.00'),
|
|
|
|
|
'account': revenue.id,
|
|
|
|
|
}])],
|
|
|
|
|
}])
|
|
|
|
|
Invoice.post([invoice])
|
|
|
|
|
invoice = Invoice(invoice.id)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(invoice.state, 'posted')
|
|
|
|
|
self.assertEqual(invoice.untaxed_amount, Decimal('300.00'))
|
|
|
|
|
self.assertEqual(invoice.total_amount, Decimal('300.00'))
|
|
|
|
|
line, = invoice.lines
|
|
|
|
|
self.assertEqual(line.product_type, '')
|
2026-07-22 22:40:12 -04:00
|
|
|
self.assertEqual(line.itbis_invoiced_line, Decimal('0.00'))
|
2026-07-22 22:29:04 -04:00
|
|
|
self.assertEqual(line.line_total, Decimal('300.00'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
del ModuleTestCase
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AccountInvoiceDoUnitTestCase(unittest.TestCase):
|
|
|
|
|
|
|
|
|
|
def _currency(self):
|
|
|
|
|
return SimpleNamespace(round=lambda amount: amount.quantize(
|
|
|
|
|
Decimal('0.01')))
|
|
|
|
|
|
|
|
|
|
def _tax(self, kind, rate):
|
|
|
|
|
return SimpleNamespace(tax_kind=kind, rate=Decimal(rate))
|
|
|
|
|
|
|
|
|
|
def _line(self, **values):
|
|
|
|
|
defaults = {
|
|
|
|
|
'id': 1,
|
|
|
|
|
'type': 'line',
|
|
|
|
|
'product': None,
|
|
|
|
|
'taxes': [],
|
|
|
|
|
'currency': self._currency(),
|
|
|
|
|
'amount': Decimal('100.00'),
|
|
|
|
|
}
|
|
|
|
|
defaults.update(values)
|
|
|
|
|
return SimpleNamespace(**defaults)
|
|
|
|
|
|
|
|
|
|
def test_product_type_is_empty_without_product(self):
|
|
|
|
|
line = self._line()
|
|
|
|
|
self.assertEqual(InvoiceLine.on_change_with_product_type(line), '')
|
|
|
|
|
|
|
|
|
|
def test_tax_kind_amounts_are_computed_from_line_base(self):
|
|
|
|
|
line = self._line(taxes=[
|
|
|
|
|
self._tax('itbis', '0.18'),
|
|
|
|
|
self._tax('isc', '0.10'),
|
|
|
|
|
])
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
InvoiceLine._compute_tax_kind_amount(line, 'itbis'),
|
|
|
|
|
Decimal('18.00'))
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
InvoiceLine._compute_tax_kind_amount(line, 'isc'),
|
|
|
|
|
Decimal('10.00'))
|
|
|
|
|
|
|
|
|
|
def test_line_total_includes_all_line_taxes(self):
|
|
|
|
|
line = self._line(taxes=[
|
|
|
|
|
self._tax('itbis', '0.18'),
|
|
|
|
|
self._tax('cdt', '0.02'),
|
|
|
|
|
])
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
InvoiceLine._compute_line_total_amount(line),
|
|
|
|
|
Decimal('120.00'))
|