"""Tests for the documents.document <-> account.move bridge.""" import base64 from odoo.exceptions import UserError from odoo.tests import tagged from odoo.tests.common import TransactionCase @tagged('post_install', '-at_install', 'fusion_accounting_documents') class TestDocumentToInvoice(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() cls.vendor = cls.env['res.partner'].create({ 'name': 'Test Doc Vendor', 'supplier_rank': 1, }) cls.purchase_journal = cls.env['account.journal'].search( [('type', '=', 'purchase'), ('company_id', '=', cls.env.company.id)], limit=1, ) def _make_document(self, name='Test Bill PDF', mimetype='application/pdf', payload=b'%PDF-fake-bill-content'): attachment = self.env['ir.attachment'].create({ 'name': name, 'datas': base64.b64encode(payload), 'mimetype': mimetype, }) Document = self.env['documents.document'] doc_vals = { 'name': name, 'attachment_id': attachment.id, 'mimetype': mimetype, 'type': 'binary', } if 'folder_id' in Document._fields: folder = Document.search( [('type', '=', 'folder')], limit=1, ) if folder: doc_vals['folder_id'] = folder.id return Document.create(doc_vals) def test_invoice_candidate_flag_pdf(self): doc = self._make_document() self.assertTrue(doc.is_invoice_candidate) def test_invoice_candidate_flag_image(self): doc = self._make_document( name='scan.png', mimetype='image/png', payload=b'\x89PNG\r\n\x1a\nfake', ) self.assertTrue(doc.is_invoice_candidate) def test_invoice_candidate_flag_text_excluded(self): doc = self._make_document( name='note.txt', mimetype='text/plain', payload=b'just a note', ) self.assertFalse(doc.is_invoice_candidate) def test_action_create_invoice_opens_wizard(self): doc = self._make_document() action = doc.action_create_invoice() self.assertEqual(action['type'], 'ir.actions.act_window') self.assertEqual( action['res_model'], 'fusion.create.invoice.from.document.wizard', ) self.assertEqual(action['target'], 'new') self.assertEqual(action['context']['default_document_id'], doc.id) def test_wizard_creates_invoice_and_links(self): doc = self._make_document() wizard = self.env['fusion.create.invoice.from.document.wizard'].create({ 'document_id': doc.id, 'partner_id': self.vendor.id, 'move_type': 'in_invoice', }) self.assertTrue(wizard.journal_id, "Default journal should resolve") action = wizard.action_create_invoice() self.assertEqual(action['res_model'], 'account.move') move = self.env['account.move'].browse(action['res_id']) self.assertEqual(move.move_type, 'in_invoice') self.assertEqual(move.partner_id, self.vendor) self.assertEqual(doc.move_id, move) self.assertFalse(doc.is_invoice_candidate, "Linked docs should no longer be candidates") self.assertEqual(move.source_document_count, 1) self.assertIn(doc, move.source_document_ids) attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'account.move'), ('res_id', '=', move.id), ]) self.assertTrue( attachments, "An attachment copy should land on the new move", ) def test_action_create_invoice_already_linked_raises(self): doc = self._make_document() existing_move = self.env['account.move'].create({ 'move_type': 'in_invoice', 'partner_id': self.vendor.id, }) doc.move_id = existing_move.id with self.assertRaises(UserError): doc.action_create_invoice() def test_action_create_invoice_non_candidate_raises(self): doc = self._make_document( name='note.txt', mimetype='text/plain', payload=b'hello', ) with self.assertRaises(UserError): doc.action_create_invoice() def test_wizard_creates_credit_note(self): doc = self._make_document(name='credit-note.pdf') wizard = self.env['fusion.create.invoice.from.document.wizard'].create({ 'document_id': doc.id, 'partner_id': self.vendor.id, 'move_type': 'in_refund', }) action = wizard.action_create_invoice() move = self.env['account.move'].browse(action['res_id']) self.assertEqual(move.move_type, 'in_refund') self.assertEqual(doc.move_id, move)