270 lines
9.8 KiB
Python
270 lines
9.8 KiB
Python
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
|
|
import datetime
|
|
import os
|
|
from decimal import Decimal
|
|
from unittest.mock import MagicMock, Mock, patch
|
|
|
|
from lxml import etree
|
|
|
|
from trytond.pool import Pool
|
|
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
|
|
|
|
|
def get_invoice():
|
|
pool = Pool()
|
|
Address = pool.get('party.address')
|
|
Company = pool.get('company.company')
|
|
Country = pool.get('country.country')
|
|
Currency = pool.get('currency.currency')
|
|
Identifier = pool.get('party.identifier')
|
|
Invoice = pool.get('account.invoice')
|
|
InvoiceLine = pool.get('account.invoice.line')
|
|
InvoiceTax = pool.get('account.invoice.tax')
|
|
MoveLine = pool.get('account.move.line')
|
|
Party = pool.get('party.party')
|
|
PaymentTerm = pool.get('account.invoice.payment_term')
|
|
Product = pool.get('product.product')
|
|
Tax = pool.get('account.tax')
|
|
Uom = pool.get('product.uom')
|
|
|
|
address = Mock(spec=Address,
|
|
street_unstructured="St sample, 15",
|
|
street="St sample, 15\n2nd floor\nBox 1234\n",
|
|
city="Scranton",
|
|
postal_code="1000",
|
|
subdivision=None,
|
|
country=Mock(spec=Country,
|
|
code='US'),
|
|
)
|
|
address.building_name = "Building A"
|
|
address.country.name = "United States"
|
|
identifier = MagicMock(
|
|
spec=Identifier,
|
|
type='be_vat',
|
|
code='BE123456789')
|
|
type(identifier).iso_6523 = Identifier.iso_6523
|
|
type(identifier)._eas_type = Identifier._eas_type
|
|
type(identifier).eas = Identifier.eas
|
|
type(identifier).unece_code = Identifier.unece_code
|
|
party = MagicMock(
|
|
spec=Party,
|
|
addresses=[address],
|
|
identifiers=[identifier],
|
|
)
|
|
type(party).identifier_iso6523 = Party.identifier_iso6523
|
|
type(party).identifier_eas = Party.identifier_eas
|
|
party.name = "Michael Scott"
|
|
company = Mock(spec=Company,
|
|
party=Mock(
|
|
spec=Party,
|
|
addresses=[Mock(spec=Address,
|
|
street_unstructured="Main street, 42",
|
|
street="Main street, 42",
|
|
country=Mock(spec=Country,
|
|
code='US'))],
|
|
identifiers=[Mock(
|
|
spec=Identifier,
|
|
type='us_ein',
|
|
code='911144442')],
|
|
))
|
|
company.party.name = "Dunder Mifflin"
|
|
company.party.address_get = Mock(return_value=company.party.addresses[0])
|
|
taxes = [Mock(spec=InvoiceTax,
|
|
tax=Mock(spec=Tax,
|
|
legal_notice="Legal Notice",
|
|
unece_category_code='S',
|
|
unece_code='VAT',
|
|
type='percentage',
|
|
rate=Decimal('.1'),
|
|
),
|
|
base=Decimal('100.00'),
|
|
amount=Decimal('10.00'),
|
|
legal_notice="Legal Notice",
|
|
)]
|
|
product = Mock(spec=Product,
|
|
code="12345",
|
|
type='service',
|
|
)
|
|
product.name = "Product"
|
|
product.identifier_get.return_value = '98412345678908'
|
|
lines = [Mock(spec=InvoiceLine,
|
|
type='line',
|
|
product=product,
|
|
unit=Mock(spec=Uom,
|
|
),
|
|
quantity=1,
|
|
unit_price=Decimal('100.0000'),
|
|
amount=Decimal('100.00'),
|
|
description="Description",
|
|
invoice_taxes=taxes,
|
|
)]
|
|
invoice = MagicMock(spec=Invoice,
|
|
id=-1,
|
|
__int__=Mock(return_value=-1),
|
|
type='out',
|
|
sequence_type='invoice',
|
|
number="001",
|
|
party=party,
|
|
party_lang='fr',
|
|
party_tax_identifier=identifier,
|
|
invoice_address=party.addresses[0],
|
|
company=company,
|
|
currency=Mock(spec=Currency,
|
|
code='USD',
|
|
round=lambda a: a),
|
|
invoice_date=datetime.date.today(),
|
|
reference="PO1234",
|
|
payment_term=Mock(spec=PaymentTerm, description="Direct"),
|
|
lines=lines,
|
|
line_lines=lines,
|
|
taxes=taxes,
|
|
untaxed_amount=Decimal('100.00'),
|
|
tax_amount=Decimal('10.00'),
|
|
total_amount=Decimal('110.00'),
|
|
amount_to_pay=Decimal('110.00'),
|
|
lines_to_pay=[Mock(spec=MoveLine,
|
|
maturity_date=datetime.date.today(),
|
|
amount=Decimal('110.00'),
|
|
)],
|
|
sales=[],
|
|
state='posted',
|
|
)
|
|
return invoice
|
|
|
|
|
|
class EdocumentUblTestCase(ModuleTestCase):
|
|
"Test Edocument Ubl module"
|
|
module = 'edocument_ubl'
|
|
extras = [
|
|
'account_invoice', 'document_incoming_invoice', 'purchase', 'sale']
|
|
|
|
@with_transaction()
|
|
def test_Invoice_2(self):
|
|
"Test Invoice-2"
|
|
pool = Pool()
|
|
Template = pool.get('edocument.ubl.invoice')
|
|
InvoiceReport = pool.get('account.invoice', type='report')
|
|
with patch.object(InvoiceReport, 'execute') as execute:
|
|
execute.return_value = ['pdf', b'data', False, 'Invoice-1234']
|
|
invoice = get_invoice()
|
|
template = Template(invoice)
|
|
|
|
invoice_string = template.render('2')
|
|
invoice_xml = etree.fromstring(invoice_string)
|
|
schema_file = os.path.join(
|
|
os.path.dirname(__file__),
|
|
'2.4', 'maindoc', 'UBL-Invoice-2.4.xsd')
|
|
schema = etree.XMLSchema(etree.parse(schema_file))
|
|
schema.assertValid(invoice_xml)
|
|
|
|
@with_transaction()
|
|
def test_Invoice_2_Peppol_BIS_3(self):
|
|
"Test Invoice-2"
|
|
pool = Pool()
|
|
Template = pool.get('edocument.ubl.invoice')
|
|
InvoiceReport = pool.get('account.invoice', type='report')
|
|
with patch.object(InvoiceReport, 'execute') as execute:
|
|
execute.return_value = ['pdf', b'data', False, 'Invoice-1234']
|
|
invoice = get_invoice()
|
|
template = Template(invoice)
|
|
|
|
invoice_string = template.render('2', specification='peppol-bis-3')
|
|
invoice_xml = etree.fromstring(invoice_string)
|
|
schema_file = os.path.join(
|
|
os.path.dirname(__file__),
|
|
'2.4', 'maindoc', 'UBL-Invoice-2.4.xsd')
|
|
schema = etree.XMLSchema(etree.parse(schema_file))
|
|
schema.assertValid(invoice_xml)
|
|
|
|
@with_transaction()
|
|
def test_CreditNote_2(self):
|
|
"Test CreditNote-2"
|
|
pool = Pool()
|
|
Template = pool.get('edocument.ubl.invoice')
|
|
InvoiceReport = pool.get('account.invoice', type='report')
|
|
with patch.object(InvoiceReport, 'execute') as execute:
|
|
execute.return_value = ['pdf', b'data', False, 'Invoice-1234']
|
|
invoice = get_invoice()
|
|
invoice.sequence_type = 'credit_note'
|
|
for line in invoice.lines:
|
|
line.quantity *= -1
|
|
invoice.untaxed_amount *= -1
|
|
invoice.tax_amount *= -1
|
|
invoice.total_amount *= -1
|
|
invoice.amount_to_pay *= -1
|
|
for line in invoice.lines_to_pay:
|
|
line.amount *= -1
|
|
template = Template(invoice)
|
|
|
|
invoice_string = template.render('2')
|
|
invoice_xml = etree.fromstring(invoice_string)
|
|
schema_file = os.path.join(
|
|
os.path.dirname(__file__),
|
|
'2.4', 'maindoc', 'UBL-CreditNote-2.4.xsd')
|
|
schema = etree.XMLSchema(etree.parse(schema_file))
|
|
schema.assertValid(invoice_xml)
|
|
|
|
@with_transaction()
|
|
def test_CreditNote_2_Peppol_BIS_3(self):
|
|
"Test CreditNote-2"
|
|
pool = Pool()
|
|
Template = pool.get('edocument.ubl.invoice')
|
|
InvoiceReport = pool.get('account.invoice', type='report')
|
|
with patch.object(InvoiceReport, 'execute') as execute:
|
|
execute.return_value = ['pdf', b'data', False, 'Invoice-1234']
|
|
invoice = get_invoice()
|
|
invoice.sequence_type = 'credit_note'
|
|
for line in invoice.lines:
|
|
line.quantity *= -1
|
|
invoice.untaxed_amount *= -1
|
|
invoice.tax_amount *= -1
|
|
invoice.total_amount *= -1
|
|
invoice.amount_to_pay *= -1
|
|
for line in invoice.lines_to_pay:
|
|
line.amount *= -1
|
|
template = Template(invoice)
|
|
|
|
invoice_string = template.render('2', specification='peppol-bis-3')
|
|
invoice_xml = etree.fromstring(invoice_string)
|
|
schema_file = os.path.join(
|
|
os.path.dirname(__file__),
|
|
'2.4', 'maindoc', 'UBL-CreditNote-2.4.xsd')
|
|
schema = etree.XMLSchema(etree.parse(schema_file))
|
|
schema.assertValid(invoice_xml)
|
|
|
|
@with_transaction()
|
|
def test_identifier_eas(self):
|
|
"Test EAS identifier"
|
|
pool = Pool()
|
|
Identifier = pool.get('party.identifier')
|
|
|
|
for type, code, eas_code, eas, vatin in [
|
|
('gr_vat', '023456783',
|
|
'9933', 'el023456783', 'EL023456783'),
|
|
('eu_vat', 'EL023456783',
|
|
'9933', 'el023456783', 'EL023456783'),
|
|
('eu_vat', 'GR023456783',
|
|
'9933', 'el023456783', 'EL023456783'),
|
|
('be_vat', '0403019261',
|
|
'9925', 'be0403019261', 'BE0403019261'),
|
|
('eu_vat', 'BE0403019261',
|
|
'9925', 'be0403019261', 'BE0403019261'),
|
|
('gb_vat', '980780684',
|
|
'9932', 'gb980780684', 'GB980780684'),
|
|
('eu_vat', 'GB980780684',
|
|
'9932', 'gb980780684', 'GB980780684'),
|
|
('eu_vat', 'XI980780684',
|
|
'9932', 'gb980780684', 'GB980780684'),
|
|
]:
|
|
with self.subTest(type=type, code=code):
|
|
identifier = Identifier(type=type, code=code)
|
|
|
|
self.assertEqual(identifier.eas_code, eas_code)
|
|
self.assertEqual(identifier.eas, eas)
|
|
self.assertEqual(identifier.vatin, vatin)
|
|
|
|
|
|
del ModuleTestCase
|