# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.account_reports.tests.common import TestAccountReportsCommon from odoo.tests.common import test_xsd from odoo.tests import tagged from odoo import Command, fields from freezegun import freeze_time class TestNoSaftReportCommon(TestAccountReportsCommon): @classmethod @TestAccountReportsCommon.setup_country('no') def setUpClass(cls): super().setUpClass() (cls.partner_a + cls.partner_b).write({ 'city': 'Garnich', 'zip': 'L-8353', 'country_id': cls.env.ref('base.lu').id, 'phone': '+352 24 11 11 11', }) cls.company_data['company'].write({ 'city': 'OSLO', 'zip': 'N-0104', 'company_registry': '123456', 'phone': '+47 11 11 11 11', 'l10n_no_bronnoysund_number': '987654325', }) cls.env['res.partner'].create({ 'name': 'Mr Big CEO', 'is_company': False, 'phone': '+47 11 11 12 34', 'parent_id': cls.company_data['company'].partner_id.id, }) cls.product_a.default_code = 'PA' cls.product_b.default_code = 'PB' ChartTemplate = cls.env['account.chart.template'] provision_acc = ChartTemplate.ref("chart2045") allocation_acc = ChartTemplate.ref("chart8900") # Create invoices cls.invoices = cls.env['account.move'].create([ { 'move_type': 'out_invoice', 'invoice_date': '2019-01-01', 'date': '2019-01-01', 'partner_id': cls.partner_a.id, 'invoice_line_ids': [(0, 0, { 'product_id': cls.product_a.id, 'quantity': 5.0, 'price_unit': 1000.0, 'tax_ids': [(6, 0, cls.company_data['default_tax_sale'].ids)], })], }, { 'move_type': 'out_refund', 'invoice_date': '2019-03-01', 'date': '2019-03-01', 'partner_id': cls.partner_a.id, 'invoice_line_ids': [(0, 0, { 'product_id': cls.product_a.id, 'quantity': 3.0, 'price_unit': 1000.0, 'tax_ids': [(6, 0, cls.company_data['default_tax_sale'].ids)], })], }, { 'move_type': 'in_invoice', 'invoice_date': '2018-12-31', 'date': '2018-12-31', 'partner_id': cls.partner_b.id, 'invoice_line_ids': [(0, 0, { 'product_id': cls.product_b.id, 'quantity': 10.0, 'price_unit': 800.0, 'tax_ids': [(6, 0, cls.company_data['default_tax_purchase'].ids)], })], }, { # allocation of undistributed profits/losses 'move_type': 'entry', 'date': '2018-12-31', 'line_ids': [ Command.create({ 'debit': 8000.0, 'credit': 0.0, 'account_id': provision_acc.id, }), Command.create({ 'debit': 0.0, 'credit': 8000.0, 'account_id': allocation_acc.id, }), ], }, { # this entry is added to ensure that the XML will have CreditAmount tag # CreditAmount (or DebitAmount) is necessary for the SAF-T XML validator (even if the entry is empty) 'move_type': 'entry', 'date': '2019-11-30', 'partner_id': cls.partner_a.id, 'line_ids': [Command.create({ 'debit': 0.0, 'credit': 0.0, 'account_id': cls.company_data['default_account_revenue'].id, })], }, ]) cls.invoices.action_post() @tagged('post_install_l10n', 'post_install', '-at_install') class TestNoSaftReport(TestNoSaftReportCommon): @freeze_time('2019-12-31') def test_saft_report_values(self): report = self.env.ref('account_reports.general_ledger_report') options = self._generate_options(report, fields.Date.from_string('2019-01-01'), fields.Date.from_string('2019-12-31')) self.assertXmlTreeEqual( self.get_xml_tree_from_string(self.env[report.custom_handler_model_name].l10n_no_export_saft_to_xml(options)['file_content']), self.get_xml_tree_from_string(f'''
1.30 NO 2019-12-31 Odoo SA Odoo ___ignore___ 123456 company_1_data
OSLO N-0104 NO
NotUsed Mr Big CEO +47 11 11 12 34
NOK 2019-01-01 2019-12-31 A
___ignore___ Accounts receivable RF-1167 1500 GL 0.00 2500.00 ___ignore___ Reserve for non-realised gains RF-1167 2045 GL 8000.00 8000.00 ___ignore___ Trade creditors (copy) RF-1167 2401 GL 10000.00 10000.00 ___ignore___ Output VAT, high rate RF-1167 2700 GL 0.00 500.00 ___ignore___ Input VAT, high rate RF-1167 2710 GL 2000.00 2000.00 ___ignore___ Sales revenue, merchandise, subject to VAT, high rate RF-1167 3000 GL 0.00 2000.00 partner_a
Garnich L-8353 LU
NotUsed partner_a +352 24 11 11 11 ___ignore___ ___ignore___ 0.00 2500.00
MVA Merverdiavgift ___ignore___ 25% 25.0 NO 3 100 123456 company_1_data
OSLO N-0104 NO
NotUsed Mr Big CEO +47 11 11 12 34 ___ignore___
3 10000.00 10000.00 ___ignore___ Sales sale ___ignore___ 01 2019 2019-01-01 out_invoi INV/2019/00001 ___ignore___ 2019-01-01 ___ignore___ ___ignore___ ___ignore___ 2019-01-01 ___ignore___ ___ignore___ [PA] product_a 5000.00 MVA ___ignore___ 25.0 25% 1250.00 ___ignore___ ___ignore___ 2019-01-01 ___ignore___ ___ignore___ 25% 1250.00 ___ignore___ ___ignore___ 2019-01-01 ___ignore___ ___ignore___ {self.invoices[0]._get_kid_number()} 6250.00 ___ignore___ 03 2019 2019-03-01 out_refun RINV/2019/00001 ___ignore___ 2019-03-01 ___ignore___ ___ignore___ ___ignore___ 2019-03-01 ___ignore___ ___ignore___ [PA] product_a 3000.00 MVA ___ignore___ 25.0 25% 750.00 ___ignore___ ___ignore___ 2019-03-01 ___ignore___ ___ignore___ 25% 750.00 ___ignore___ ___ignore___ 2019-03-01 ___ignore___ ___ignore___ RINV/2019/00001 3750.00 ___ignore___ Miscellaneous Operations general ___ignore___ 11 2019 2019-11-30 entry MISC/2019/11/0001 ___ignore___ 2019-11-30 ___ignore___ ___ignore___ ___ignore___ 2019-11-30 ___ignore___ ___ignore___ MISC/2019/11/0001 0.00
'''), ) @tagged('external_l10n', 'post_install', '-at_install', '-standard', 'external') class TestNoSaftReportXmlValidity(TestNoSaftReportCommon): @test_xsd(url='https://raw.githubusercontent.com/Skatteetaten/saf-t/master/SAF-T_Financial_1.3/Norwegian_SAF-T_Financial_Schema_v_1.30.xsd') def test_xml_validity(self): report = self.env.ref('account_reports.general_ledger_report') options = self._generate_options(report, fields.Date.from_string('2019-01-01'), fields.Date.from_string('2019-12-31')) return self.get_xml_tree_from_string(self.env[report.custom_handler_model_name].l10n_no_export_saft_to_xml(options)['file_content'])