summaryrefslogtreecommitdiff
path: root/addons/l10n_it_edi/tests/test_ir_mail_server.py
blob: 734c7246f3ba566ab3ec39eb7220b128e219234a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

import datetime
import logging
from collections import namedtuple
from unittest.mock import patch
import freezegun

from odoo import tools
from odoo.addons.account_edi.tests.common import AccountEdiTestCommon
from odoo.addons.l10n_it_edi.tools.remove_signature import remove_signature

_logger = logging.getLogger(__name__)


class PecMailServerTests(AccountEdiTestCommon):
    """ Main test class for the l10n_it_edi vendor bills XML import from a PEC mail account"""

    fake_test_content = """<?xml version="1.0" encoding="UTF-8"?>
        <p:FatturaElettronica versione="FPR12" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
        xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd">
          <FatturaElettronicaHeader>
            <CessionarioCommittente>
              <DatiAnagrafici>
                <CodiceFiscale>01234560157</CodiceFiscale>
              </DatiAnagrafici>
            </CessionarioCommittente>
          </FatturaElettronicaHeader>
          <FatturaElettronicaBody>
            <DatiGenerali>
              <DatiGeneraliDocumento>
                <TipoDocumento>TD02</TipoDocumento>
              </DatiGeneraliDocumento>
            </DatiGenerali>
          </FatturaElettronicaBody>
        </p:FatturaElettronica>"""

    @classmethod
    def setUpClass(cls):
        """ Setup the test class with a PEC mail server and a fake fatturaPA content """

        super().setUpClass(chart_template_ref='l10n_it.l10n_it_chart_template_generic',
                           edi_format_ref='l10n_it_edi.edi_fatturaPA')

        # Use the company_data_2 to test that the e-invoice is imported for the right company
        cls.company = cls.company_data_2['company']

        # Initialize the company's codice fiscale
        cls.company.l10n_it_codice_fiscale = 'IT01234560157'

        # Build test data.
        # invoice_filename1 is used for vendor bill receipts tests
        # invoice_filename2 is used for vendor bill tests
        cls.invoice_filename1 = 'IT01234567890_FPR01.xml'
        cls.invoice_filename2 = 'IT01234567890_FPR02.xml'
        cls.signed_invoice_filename = 'IT01234567890_FPR01.xml.p7m'
        cls.invoice_content = cls._get_test_file_content(cls.invoice_filename1)
        cls.signed_invoice_content = cls._get_test_file_content(cls.signed_invoice_filename)
        cls.invoice = cls.env['account.move'].create({
            'move_type': 'in_invoice',
            'ref': '01234567890'
        })
        cls.attachment = cls.env['ir.attachment'].create({
            'name': cls.invoice_filename1,
            'raw': cls.invoice_content,
            'res_id': cls.invoice.id,
            'res_model': 'account.move',
        })
        cls.edi_document = cls.env['account.edi.document'].create({
            'edi_format_id': cls.edi_format.id,
            'move_id': cls.invoice.id,
            'attachment_id': cls.attachment.id,
            'state': 'sent'
        })

        # Initialize the fetchmail server that has to be tested
        cls.server = cls.env['fetchmail.server'].sudo().create({
            'name': 'test_server',
            'server_type': 'imap',
            'l10n_it_is_pec': True})

    @classmethod
    def _get_test_file_content(cls, filename):
        """ Get the content of a test file inside this module """
        path = 'l10n_it_edi/tests/expected_xmls/' + filename
        with tools.file_open(path, mode='rb') as test_file:
            return test_file.read()

    def _create_invoice(self, content, filename):
        """ Create an invoice from given attachment content """
        with patch.object(self.server._cr, 'commit', return_value=None):
            if filename.endswith(".p7m"):
                content = remove_signature(content)
            return self.server._create_invoice_from_mail(content, filename, 'fake@address.be')

    # -----------------------------
    #
    # Vendor bills
    #
    # -----------------------------

    def test_receive_vendor_bill(self):
        """ Test a sample e-invoice file from https://www.fatturapa.gov.it/export/documenti/fatturapa/v1.2/IT01234567890_FPR01.xml """
        invoices = self._create_invoice(self.invoice_content, self.invoice_filename2)
        self.assertTrue(bool(invoices))

    def test_receive_signed_vendor_bill(self):
        """ Test a signed (P7M) sample e-invoice file from https://www.fatturapa.gov.it/export/documenti/fatturapa/v1.2/IT01234567890_FPR01.xml """
        with freezegun.freeze_time('2020-04-06'):
            invoices = self._create_invoice(self.signed_invoice_content, self.signed_invoice_filename)
            self.assertRecordValues(invoices, [{
                'company_id': self.company.id,
                'name': 'BILL/2014/12/0001',
                'invoice_date': datetime.date(2014, 12, 18),
                'ref': '01234567890',
            }])

    def test_receive_same_vendor_bill_twice(self):
        """ Test that the second time we are receiving a PEC mail with the same attachment, the second is discarded """
        content = self.fake_test_content.encode()
        for result in [True, False]:
            invoice = self._create_invoice(content, self.invoice_filename2)
            self.assertEqual(result, bool(invoice))

    # -----------------------------
    #
    # Receipts
    #
    # -----------------------------

    def _test_receipt(self, receipt_type, source_state, destination_state):
        """ Test a receipt from the ones in the module's test files """

        # Simulate the 'sent' state of the move, even if we didn't actually send an email in this test
        self.invoice.l10n_it_send_state = source_state

        # Create a fake receipt from the test file
        receipt_filename = 'IT01234567890_FPR01_%s_001.xml' % receipt_type
        receipt_content = self._get_test_file_content(receipt_filename).decode()

        create_mail_attachment = namedtuple('Attachment', ('fname', 'content', 'info'))
        receipt_mail_attachment = create_mail_attachment(receipt_filename, receipt_content, {})

        # Simulate the arrival of the receipt
        with patch.object(self.server._cr, 'commit', return_value=None):
            self.server._message_receipt_invoice(receipt_type, receipt_mail_attachment)

        # Check the Destination state of the edi_document
        self.assertTrue(destination_state, self.edi_document.state)

    def test_ricevuta_consegna(self):
        """ Test a receipt adapted from https://www.fatturapa.gov.it/export/documenti/messaggi/v1.0/IT01234567890_11111_RC_001.xml """
        self._test_receipt('RC', 'sent', 'delivered')

    def test_decorrenza_termini(self):
        """ Test a receipt adapted from https://www.fatturapa.gov.it/export/documenti/messaggi/v1.0/IT01234567890_11111_DT_001.xml """
        self._test_receipt('DT', 'delivered', 'delivered_expired')