diff --git a/tests/test_invoice.py b/tests/test_invoice.py index a30b98f..9ecaf34 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -3,18 +3,146 @@ # from m-ds for Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +from decimal import Decimal +from datetime import date from trytond.tests.test_tryton import ModuleTestCase, with_transaction +from trytond.pool import Pool +from trytond.transaction import Transaction +from trytond.modules.company.tests import create_company, set_company +from trytond.modules.account.tests import create_chart, get_fiscalyear + + +def set_invoice_sequences(fiscalyear): + pool = Pool() + Sequence = pool.get('ir.sequence.strict') + SequenceType = pool.get('ir.sequence.type') + InvoiceSequence = pool.get('account.fiscalyear.invoice_sequence') + ModelData = pool.get('ir.model.data') + + sequence = Sequence( + name=fiscalyear.name, + sequence_type=SequenceType(ModelData.get_id( + 'account_invoice', 'sequence_type_account_invoice')), + company=fiscalyear.company, + ) + sequence.save() + fiscalyear.invoice_sequences = [] + invoice_sequence = InvoiceSequence() + invoice_sequence.fiscalyear = fiscalyear + invoice_sequence.in_invoice_sequence = sequence + invoice_sequence.in_credit_note_sequence = sequence + invoice_sequence.out_invoice_sequence = sequence + invoice_sequence.out_credit_note_sequence = sequence + invoice_sequence.save() + return fiscalyear class InvoiceTestCase(ModuleTestCase): 'Test invoice module' module = 'account_invoice_xrechnung' - @with_transaction() - def test_xrechnung(self): - """ run default tests + def prep_fiscalyear(self, company1): + """ prepare fiscal year, sequences... """ - pass + pool = Pool() + FiscalYear = pool.get('account.fiscalyear') + + fisc_year = get_fiscalyear(company1, today=date(2024, 1, 15)) + set_invoice_sequences(fisc_year) + self.assertEqual(len(fisc_year.invoice_sequences), 1) + FiscalYear.create_period([fisc_year]) + + def prep_invoice(self, party_customer): + """ add invoice + """ + pool = Pool() + Invoice = pool.get('account.invoice') + Taxes = pool.get('account.tax') + Account = pool.get('account.account') + Journal = pool.get('account.journal') + Currency = pool.get('currency.currency') + Uom = pool.get('product.uom') + + currency1, = Currency.search([('code', '=', 'usd')]) + + tax_lst = Taxes.search([('name', '=', '20% VAT')]) + self.assertEqual(len(tax_lst), 1) + + account_lst = Account.search([ + ('name', 'in', ['Main Revenue', 'Main Receivable']) + ], order=[('name', 'ASC')]) + self.assertEqual(len(account_lst), 2) + self.assertEqual(account_lst[0].name, 'Main Receivable') + + journ_lst = Journal.search([('name', '=', 'Revenue')]) + self.assertEqual(len(journ_lst), 1) + + to_create_invoice = [{ + 'type': 'out', + 'description': 'Parts', + 'invoice_date': date(2024, 7, 1), + 'party': party_customer.id, + 'invoice_address': party_customer.addresses[0].id, + 'account': account_lst[0].id, + 'journal': journ_lst[0].id, + 'currency': currency1.id, + 'lines': [('create', [{ + 'type': 'line', + 'quantity': 2.0, + 'unit': Uom.search([('symbol', '=', 'u')])[0].id, + 'unit_price': Decimal('50.0'), + 'taxes': [('add', [tax_lst[0].id])], + 'account': account_lst[1].id, + 'currency': currency1.id, + }])], + }] + inv_lst, = Invoice.create(to_create_invoice) + inv_lst.on_change_lines() + inv_lst.save() + Invoice.validate_invoice([inv_lst]) + Invoice.post([inv_lst]) + self.assertEqual(inv_lst.currency.code, 'usd') + self.assertEqual(len(inv_lst.move.lines), 3) + return inv_lst + + @with_transaction() + def test_xrechnung_configuration(self): + """ test configuration + """ + pool = Pool() + Configuration = pool.get('account.configuration') + Party = pool.get('party.party') + ActionReport = pool.get('ir.action.report') + + pty1, = Party.create([{ + 'name': 'Payee', + 'addresses': [('create', [{ + 'invoice': True, + 'street': 'Applicant Street 1', + 'postal_code': '12345', + 'city': 'Usertown', + }])], + }]) + + company1 = create_company('m-ds') + with set_company(company1): + with Transaction().set_context({'company': company1.id}): + + # update report to 'pdf' + inv_report, = ActionReport.search([ + ('model', '=', 'account.invoice'), + ('report_name', '=', 'account.invoice')]) + self.assertEqual(inv_report.extension, '') + ActionReport.write(*[ + [inv_report], {'extension': 'pdf'}]) + + cfg1 = Configuration(xrechn_zugferd_report=inv_report) + cfg1.save() + self.assertEqual(cfg1.xrechn_zugferd_report.name, 'Invoice') + create_chart(company=company1, tax=True) + self.prep_fiscalyear(company1) + invoice = self.prep_invoice(pty1) + # end InvoiceTestCase diff --git a/xreport.py b/xreport.py index 4d68e82..77715ad 100644 --- a/xreport.py +++ b/xreport.py @@ -4,6 +4,7 @@ # this repository contains the full copyright notices and license terms. import zipfile +from facturx import generate_from_binary from io import BytesIO from trytond.report import Report from trytond.pool import Pool @@ -31,27 +32,45 @@ class XReport(Report): pool = Pool() IrDate = pool.get('ir.date') Invoice = pool.get('account.invoice') - EDocument = pool.get(data['edocument'].split('-')[0]) + document_para = pool.get(data['edocument'].split('-')[0]) + + EDocument = document_para[0] + document_var = document_para[1] if len(document_para) > 1 else None invoice, = Invoice.browse([data['invoice']]) template = EDocument(invoice) - invoice_string = template.render(edoc_versions[data['edocument']]) + invoice_xml = template.render(edoc_versions[data['edocument']]) file_name = slugify('%(date)s-%(descr)s' % { 'date': IrDate.today().isoformat().replace('-', ''), 'descr': invoice.rec_name}, max_length=100, word_boundary=True, save_order=True) + # if document_var and ( + # document_var == 'ferd') and ( + # EDocument.__name__ == 'edocument.facturxext.invoice'): + # # convert to zugferd + # pdf_data = generate_from_binary( + # pdf_file='pdf_content', + # xml=invoice_xml, + # check_xsd=True, + # pdf_metadata={ + # 'author': invoice.company.rec_name, + # 'keywords': 'Factur-X, Invoice', + # 'title': invoice.number, + # 'subject': invoice.description}, + # lang='de-DE') + if data['as_zip'] is True: return ( 'zip', cls.compress_as_zip('%(fname)s.%(ext)s' % { 'fname': file_name, 'ext': 'xml', - }, invoice_string), + }, invoice_xml), False, file_name) else: - return ('xml', invoice_string, False, file_name) + return ('xml', invoice_xml, False, file_name) # end XReport