odoo-addon-l10n-it-edi-extension 18.0.1.0.0.30__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. odoo/addons/l10n_it_edi_extension/README.rst +493 -0
  2. odoo/addons/l10n_it_edi_extension/__init__.py +951 -0
  3. odoo/addons/l10n_it_edi_extension/__manifest__.py +37 -0
  4. odoo/addons/l10n_it_edi_extension/controllers/__init__.py +1 -0
  5. odoo/addons/l10n_it_edi_extension/controllers/portal.py +27 -0
  6. odoo/addons/l10n_it_edi_extension/data/FoglioStileAssoSoftware.xsl +3150 -0
  7. odoo/addons/l10n_it_edi_extension/data/invoice_it_template.xml +50 -0
  8. odoo/addons/l10n_it_edi_extension/data/res.city.it.code.csv +13898 -0
  9. odoo/addons/l10n_it_edi_extension/i18n/l10n_it_edi_extension.pot +1167 -0
  10. odoo/addons/l10n_it_edi_extension/i18n/l10n_it_edi_fatturapa.pot +44 -0
  11. odoo/addons/l10n_it_edi_extension/models/__init__.py +15 -0
  12. odoo/addons/l10n_it_edi_extension/models/account_journal.py +152 -0
  13. odoo/addons/l10n_it_edi_extension/models/account_move.py +765 -0
  14. odoo/addons/l10n_it_edi_extension/models/account_move_line.py +10 -0
  15. odoo/addons/l10n_it_edi_extension/models/ir_attachment.py +37 -0
  16. odoo/addons/l10n_it_edi_extension/models/l10n_it_edi_activity_progress.py +14 -0
  17. odoo/addons/l10n_it_edi_extension/models/l10n_it_edi_article_code.py +15 -0
  18. odoo/addons/l10n_it_edi_extension/models/l10n_it_edi_discount_rise_price.py +25 -0
  19. odoo/addons/l10n_it_edi_extension/models/l10n_it_edi_line.py +48 -0
  20. odoo/addons/l10n_it_edi_extension/models/l10n_it_edi_line_other_data.py +17 -0
  21. odoo/addons/l10n_it_edi_extension/models/l10n_it_edi_summary_data.py +77 -0
  22. odoo/addons/l10n_it_edi_extension/models/res_city_it_code.py +83 -0
  23. odoo/addons/l10n_it_edi_extension/models/res_company.py +62 -0
  24. odoo/addons/l10n_it_edi_extension/models/res_partner.py +64 -0
  25. odoo/addons/l10n_it_edi_extension/readme/CONFIGURE.md +45 -0
  26. odoo/addons/l10n_it_edi_extension/readme/CONTRIBUTORS.md +5 -0
  27. odoo/addons/l10n_it_edi_extension/readme/DESCRIPTION.md +160 -0
  28. odoo/addons/l10n_it_edi_extension/security/ir.model.access.csv +14 -0
  29. odoo/addons/l10n_it_edi_extension/static/description/icon.png +0 -0
  30. odoo/addons/l10n_it_edi_extension/static/description/index.html +832 -0
  31. odoo/addons/l10n_it_edi_extension/tests/__init__.py +2 -0
  32. odoo/addons/l10n_it_edi_extension/tests/import_xmls/IT01234567890_FPR03.xml +166 -0
  33. odoo/addons/l10n_it_edi_extension/tests/import_xmls/IT02780790107_11004.xml +216 -0
  34. odoo/addons/l10n_it_edi_extension/tests/import_xmls/IT02780790107_11005.xml +224 -0
  35. odoo/addons/l10n_it_edi_extension/tests/import_xmls/IT05979361218_003.xml +107 -0
  36. odoo/addons/l10n_it_edi_extension/tests/import_xmls/test.png +0 -0
  37. odoo/addons/l10n_it_edi_extension/tests/import_xmls/xml_import.zip +0 -0
  38. odoo/addons/l10n_it_edi_extension/tests/test_fiscalcode.py +126 -0
  39. odoo/addons/l10n_it_edi_extension/tests/test_import_edi_extension_xml.py +350 -0
  40. odoo/addons/l10n_it_edi_extension/views/company_view.xml +41 -0
  41. odoo/addons/l10n_it_edi_extension/views/l10n_it_view.xml +164 -0
  42. odoo/addons/l10n_it_edi_extension/views/res_partner_view.xml +19 -0
  43. odoo/addons/l10n_it_edi_extension/wizards/__init__.py +2 -0
  44. odoo/addons/l10n_it_edi_extension/wizards/compute_fc.py +176 -0
  45. odoo/addons/l10n_it_edi_extension/wizards/compute_fc_view.xml +65 -0
  46. odoo/addons/l10n_it_edi_extension/wizards/l10n_it_edi_import_file_wizard.py +98 -0
  47. odoo/addons/l10n_it_edi_extension/wizards/l10n_it_edi_import_file_wizard.xml +46 -0
  48. odoo_addon_l10n_it_edi_extension-18.0.1.0.0.30.dist-info/METADATA +513 -0
  49. odoo_addon_l10n_it_edi_extension-18.0.1.0.0.30.dist-info/RECORD +51 -0
  50. odoo_addon_l10n_it_edi_extension-18.0.1.0.0.30.dist-info/WHEEL +5 -0
  51. odoo_addon_l10n_it_edi_extension-18.0.1.0.0.30.dist-info/top_level.txt +1 -0
@@ -0,0 +1,44 @@
1
+ # Translation of Odoo Server.
2
+ # This file contains the translation of the following modules:
3
+ # * l10n_it_edi_fatturapa
4
+ #
5
+ msgid ""
6
+ msgstr ""
7
+ "Project-Id-Version: Odoo Server 18.0\n"
8
+ "Report-Msgid-Bugs-To: \n"
9
+ "POT-Creation-Date: 2024-04-26 09:19+0000\n"
10
+ "PO-Revision-Date: 2024-04-26 09:19+0000\n"
11
+ "Last-Translator: \n"
12
+ "Language-Team: \n"
13
+ "MIME-Version: 1.0\n"
14
+ "Content-Type: text/plain; charset=UTF-8\n"
15
+ "Content-Transfer-Encoding: \n"
16
+ "Plural-Forms: \n"
17
+
18
+ #. module: l10n_it_edi_fatturapa
19
+ #: model:ir.model,name:l10n_it_edi_fatturapa.model_ir_attachment
20
+ msgid "Attachment"
21
+ msgstr ""
22
+
23
+ #. module: l10n_it_edi_fatturapa
24
+ #. odoo-python
25
+ #: code:addons/l10n_it_edi_fatturapa/models/ir_attachment.py:0
26
+ msgid "Invalid xml %s."
27
+ msgstr ""
28
+
29
+ #. module: l10n_it_edi_fatturapa
30
+ #: model:ir.model,name:l10n_it_edi_fatturapa.model_account_move
31
+ msgid "Journal Entry"
32
+ msgstr ""
33
+
34
+ #. module: l10n_it_edi_fatturapa
35
+ #: model_terms:ir.ui.view,arch_db:l10n_it_edi_fatturapa.account_invoice_form_l10n_it_inherit_view
36
+ msgid "Preview FPA"
37
+ msgstr ""
38
+
39
+ #. module: l10n_it_edi_fatturapa
40
+ #: model:ir.model.fields,field_description:l10n_it_edi_fatturapa.field_account_bank_statement_line__l10n_it_edi_attachment_preview_link
41
+ #: model:ir.model.fields,field_description:l10n_it_edi_fatturapa.field_account_move__l10n_it_edi_attachment_preview_link
42
+ #: model:ir.model.fields,field_description:l10n_it_edi_fatturapa.field_account_payment__l10n_it_edi_attachment_preview_link
43
+ msgid "Preview link"
44
+ msgstr ""
@@ -0,0 +1,15 @@
1
+ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
2
+
3
+ from . import res_partner
4
+ from . import res_company
5
+ from . import res_city_it_code
6
+ from . import l10n_it_edi_article_code
7
+ from . import l10n_it_edi_discount_rise_price
8
+ from . import l10n_it_edi_line_other_data
9
+ from . import l10n_it_edi_activity_progress
10
+ from . import l10n_it_edi_summary_data
11
+ from . import l10n_it_edi_line
12
+ from . import account_move_line
13
+ from . import account_move
14
+ from . import ir_attachment
15
+ from . import account_journal
@@ -0,0 +1,152 @@
1
+ # Copyright 2025 Simone Rubino
2
+ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3
+
4
+ import logging
5
+
6
+ from lxml import etree
7
+
8
+ from odoo import api, models
9
+
10
+ from odoo.addons.l10n_it_edi.tools.remove_signature import remove_signature
11
+
12
+ _logger = logging.getLogger(__name__)
13
+
14
+
15
+ class AccountJournal(models.Model):
16
+ _inherit = "account.journal"
17
+
18
+ @api.model
19
+ def _l10n_it_edi_extension_e_invoice_parser(self):
20
+ """Parser used to parse an e-invoice attachment."""
21
+ # Expose the parser used by `l10n_it_edi`.
22
+ return etree.XMLParser(
23
+ recover=True,
24
+ resolve_entities=False,
25
+ )
26
+
27
+ @api.model
28
+ def _l10n_it_edi_extension_parse_e_invoice_content(self, content):
29
+ """Parse the `content` of an e-invoice to a XML tree.
30
+
31
+ Return None if the parsing fails.
32
+ """
33
+ parser = self._l10n_it_edi_extension_e_invoice_parser()
34
+ try:
35
+ parsed_xml = etree.fromstring(content, parser)
36
+ except (etree.ParseError, ValueError):
37
+ parsed_xml = None
38
+ return parsed_xml
39
+
40
+ @api.model
41
+ def _l10n_it_edi_extension_parse_e_invoice(self, attachment):
42
+ """Parse the e-invoice `attachment` to a XML tree, decoding it if needed."""
43
+ parse_content = self._l10n_it_edi_extension_parse_e_invoice_content
44
+ if (xml_tree := parse_content(attachment.raw)) is None:
45
+ xml_tree = parse_content(remove_signature(attachment.raw))
46
+ return xml_tree
47
+
48
+ @api.model
49
+ def _l10n_it_edi_extension_split_content(self, attachment):
50
+ """
51
+ Break down the content of `attachment`
52
+ if contains multiple FatturaElettronicaBody.
53
+
54
+ If `attachment` is an e-invoice that contains N FatturaElettronicaBody:
55
+
56
+ <FatturaElettronica>
57
+ <FatturaElettronicaHeader/>
58
+ <FatturaElettronicaBody>
59
+ // Content of 1st invoice
60
+ </FatturaElettronicaBody>
61
+ // ...
62
+ <FatturaElettronicaBody>
63
+ // Content of N-th invoice
64
+ </FatturaElettronicaBody>
65
+ </FatturaElettronica>
66
+
67
+ return a list of N strings (bytes) with the same FatturaElettronicaHeader:
68
+
69
+ <FatturaElettronica>
70
+ <FatturaElettronicaHeader/>
71
+ <FatturaElettronicaBody>
72
+ // Content of N-th invoice
73
+ </FatturaElettronicaBody>
74
+ </FatturaElettronica>
75
+ """
76
+ attachment.ensure_one()
77
+
78
+ if (
79
+ xml_tree := self._l10n_it_edi_extension_parse_e_invoice(attachment)
80
+ ) is not None:
81
+ header = xml_tree.xpath("//FatturaElettronicaHeader")[0]
82
+ bodies = xml_tree.xpath("//FatturaElettronicaBody")
83
+ result = []
84
+ for body in bodies:
85
+ e_invoice_root = etree.Element("FatturaElettronica")
86
+ e_invoice_root.insert(0, header)
87
+ e_invoice_root.insert(1, body)
88
+ result.append(etree.tostring(e_invoice_root))
89
+ else:
90
+ result = [attachment.raw]
91
+ return result
92
+
93
+ def _l10n_it_edi_extension_split_attachments(self, attachment_ids):
94
+ """
95
+ Split the attachments that contain multiple invoices
96
+ in multiple attachments containing one invoice each.
97
+
98
+ Do not touch the attachments that do not need splitting.
99
+
100
+ Return the IDs of the splitted attachments and of the unaffected ones.
101
+ """
102
+ attachment_model = self.env["ir.attachment"]
103
+ attachments = attachment_model.browse(attachment_ids)
104
+ l10n_it_edi_format = next(
105
+ filter(
106
+ lambda fmt: fmt["format"] == "l10n_it_edi",
107
+ attachment_model._get_edi_supported_formats(),
108
+ )
109
+ )
110
+ l10n_it_edi_check, l10n_it_edi_decoder = (
111
+ l10n_it_edi_format["check"],
112
+ l10n_it_edi_format["decoder"],
113
+ )
114
+
115
+ e_invoice_attachments = attachment_model.browse()
116
+ splitted_attachments_values = dict()
117
+ other_attachments = attachment_model.browse()
118
+ for attachment in attachments:
119
+ if l10n_it_edi_check(attachment):
120
+ parsed_xml_bodies = l10n_it_edi_decoder(attachment.name, attachment.raw)
121
+ if len(parsed_xml_bodies) >= 2:
122
+ # In this e-invoice there are multiple invoices,
123
+ # extract the content of the splitted e-invoice
124
+ # containing only one FatturaElettronicaBody each
125
+ splitted_attachments_values[attachment] = {
126
+ "original_attachment": attachment,
127
+ "contents": self._l10n_it_edi_extension_split_content(
128
+ attachment
129
+ ),
130
+ }
131
+ else:
132
+ e_invoice_attachments |= attachment
133
+ else:
134
+ other_attachments |= attachment
135
+
136
+ if splitted_attachments_values:
137
+ e_invoice_attachments |= attachment_model.create(
138
+ [
139
+ {
140
+ "name": f"Partial {attachment.name}",
141
+ "raw": content,
142
+ }
143
+ for attachment, att_data in splitted_attachments_values.items()
144
+ for content in att_data["contents"]
145
+ ]
146
+ )
147
+
148
+ return (e_invoice_attachments | other_attachments).ids
149
+
150
+ def _create_document_from_attachment(self, attachment_ids):
151
+ attachment_ids = self._l10n_it_edi_extension_split_attachments(attachment_ids)
152
+ return super()._create_document_from_attachment(attachment_ids)