summaryrefslogtreecommitdiff
path: root/addons/account_edi_extended/tests/test_edi.py
blob: 164a6c88b5d0aa19e7a01ea052e41d889f09bbb2 (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

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo.addons.account_edi_extended.tests.common import AccountEdiExtendedTestCommon, _mocked_post, _mocked_post_two_steps, _generate_mocked_needs_web_services, _mocked_cancel_failed, _generate_mocked_support_batching


class TestAccountEdi(AccountEdiExtendedTestCommon):

    @classmethod
    def setUpClass(cls, chart_template_ref=None, edi_format_ref=None):
        super().setUpClass(chart_template_ref=chart_template_ref, edi_format_ref=edi_format_ref)

        cls.invoice = cls.init_invoice('out_invoice', products=cls.product_a + cls.product_b)

    def test_edi_flow(self):
        with self.mock_edi():
            doc = self.invoice._get_edi_document(self.edi_format)
            self.assertFalse(doc)
            self.invoice.action_post()
            doc = self.invoice._get_edi_document(self.edi_format)
            self.assertEqual(len(doc), 1)
            self.assertEqual(doc.state, 'sent')
            self.invoice.button_draft()
            self.invoice.button_cancel()
            self.assertEqual(doc.state, 'cancelled')

    def test_edi_flow_two_steps(self):
        with self.mock_edi(_post_invoice_edi_method=_mocked_post_two_steps,
                           _needs_web_services_method=_generate_mocked_needs_web_services(True)):
            doc = self.invoice._get_edi_document(self.edi_format)
            self.assertFalse(doc)
            self.invoice.action_post()
            doc = self.invoice._get_edi_document(self.edi_format)
            self.assertEqual(len(doc), 1)
            self.assertEqual(doc.state, 'to_send')
            doc._process_documents_web_services(with_commit=False)
            self.assertEqual(doc.state, 'to_send')
            doc._process_documents_web_services(with_commit=False)
            self.assertEqual(doc.state, 'sent')

    def test_edi_flow_request_cancel_success(self):
        with self.mock_edi(_needs_web_services_method=_generate_mocked_needs_web_services(True)):
            self.assertEqual(self.invoice.state, 'draft')
            self.invoice.action_post()
            doc = self.invoice._get_edi_document(self.edi_format)
            self.assertEqual(doc.state, 'to_send')
            self.assertEqual(self.invoice.state, 'posted')
            doc._process_documents_web_services(with_commit=False)
            self.assertEqual(doc.state, 'sent')
            self.assertEqual(self.invoice.state, 'posted')
            self.invoice.button_cancel_posted_moves()
            self.assertEqual(doc.state, 'to_cancel')
            self.assertEqual(self.invoice.state, 'posted')
            doc._process_documents_web_services()
            self.assertEqual(doc.state, 'cancelled')
            self.assertEqual(self.invoice.state, 'cancel')

    def test_edi_flow_request_cancel_failed(self):
        with self.mock_edi(_needs_web_services_method=_generate_mocked_needs_web_services(True),
                           _cancel_invoice_edi_method=_mocked_cancel_failed):
            self.assertEqual(self.invoice.state, 'draft')
            self.invoice.action_post()
            doc = self.invoice._get_edi_document(self.edi_format)
            self.assertEqual(doc.state, 'to_send')
            self.assertEqual(self.invoice.state, 'posted')
            doc._process_documents_web_services(with_commit=False)
            self.assertEqual(doc.state, 'sent')
            self.assertEqual(self.invoice.state, 'posted')
            self.invoice.button_cancel_posted_moves()
            self.assertEqual(doc.state, 'to_cancel')
            self.assertEqual(self.invoice.state, 'posted')
            # Call off edi Cancellation
            self.invoice.button_abandon_cancel_posted_posted_moves()
            self.assertEqual(doc.state, 'sent')
            self.assertFalse(doc.error)

            # Failed cancel
            self.invoice.button_cancel_posted_moves()
            self.assertEqual(doc.state, 'to_cancel')
            self.assertEqual(self.invoice.state, 'posted')
            doc._process_documents_web_services()
            self.assertEqual(doc.state, 'to_cancel')
            self.assertEqual(self.invoice.state, 'posted')

            # Call off edi Cancellation
            self.invoice.button_abandon_cancel_posted_posted_moves()
            self.assertEqual(doc.state, 'sent')
            self.assertIsNotNone(doc.error)

    def test_edi_flow_two_step_cancel_with_call_off_request(self):
        def _mock_cancel(edi_format, invoices, test_mode):
            invoices_no_ref = invoices.filtered(lambda i: not i.ref)
            if len(invoices_no_ref) == len(invoices):  # first step
                invoices_no_ref.ref = 'test_ref_cancel'
                return {invoice: {} for invoice in invoices}
            elif len(invoices_no_ref) == 0:  # second step
                for invoice in invoices:
                    invoice.ref = None
                return {invoice: {'success': True} for invoice in invoices}
            else:
                raise ValueError('wrong use of "_mocked_post_two_steps"')

        def _is_needed_for_invoice(edi_format, invoice):
            return not bool(invoice.ref)

        with self.mock_edi(_needs_web_services_method=_generate_mocked_needs_web_services(True),
                           _is_required_for_invoice_method=_is_needed_for_invoice,
                           _cancel_invoice_edi_method=_mock_cancel):
            self.invoice.action_post()
            doc = self.invoice._get_edi_document(self.edi_format)
            doc._process_documents_web_services(with_commit=False)
            self.assertEqual(doc.state, 'sent')

            # Request Cancellation
            self.invoice.button_cancel_posted_moves()
            doc._process_documents_web_services(with_commit=False)  # first step of cancel
            self.assertEqual(doc.state, 'to_cancel')

            # Call off edi Cancellation
            self.invoice.button_abandon_cancel_posted_posted_moves()
            self.assertEqual(doc.state, 'to_cancel')

            # If we cannot call off edi cancellation, only solution is to post again
            doc._process_documents_web_services(with_commit=False)  # second step of cancel
            self.assertEqual(doc.state, 'cancelled')
            self.invoice.action_post()
            doc._process_documents_web_services(with_commit=False)
            self.assertEqual(doc.state, 'sent')

    def test_batches(self):
        def _get_batch_key_method(edi_format, move, state):
            return (move.ref)

        with self.mock_edi(_get_batch_key_method=_get_batch_key_method,
                           _support_batching_method=_generate_mocked_support_batching(True)):
            edi_docs = self.env['account.edi.document']
            doc1 = self.create_edi_document(self.edi_format, 'to_send')
            edi_docs |= doc1
            doc2 = self.create_edi_document(self.edi_format, 'to_send')
            edi_docs |= doc2
            doc3 = self.create_edi_document(self.edi_format, 'to_send')
            edi_docs |= doc3

            to_process = edi_docs._prepare_jobs()
            self.assertEqual(len(to_process), 1)

            doc1.move_id.ref = 'batch1'
            doc2.move_id.ref = 'batch2'
            doc3.move_id.ref = 'batch3'

            to_process = edi_docs._prepare_jobs()
            self.assertEqual(len(to_process), 3)

            doc2.move_id.ref = 'batch1'
            to_process = edi_docs._prepare_jobs()
            self.assertEqual(len(to_process), 2)