From 332042eb2e0b1fc91bd3c266890130ec0ee8a28c Mon Sep 17 00:00:00 2001 From: eLBati Date: Wed, 5 Sep 2018 12:32:59 +0200 Subject: [PATCH 001/236] copying l10n_it_fatturapa_in from 7.0 as is --- l10n_it_fatturapa_in/__init__.py | 24 + l10n_it_fatturapa_in/__openerp__.py | 94 ++ l10n_it_fatturapa_in/i18n/it.po | 570 +++++++ l10n_it_fatturapa_in/models/__init__.py | 24 + l10n_it_fatturapa_in/models/account.py | 75 + l10n_it_fatturapa_in/models/attachment.py | 40 + .../security/ir.model.access.csv | 3 + l10n_it_fatturapa_in/static/src/img/icon.png | Bin 0 -> 4829 bytes l10n_it_fatturapa_in/tests/__init__.py | 23 + .../tests/data/IT01234567890_11002.xml | 134 ++ .../tests/data/IT02780790107_11003.xml | 172 +++ .../tests/data/IT02780790107_11004.xml | 211 +++ .../tests/data/IT02780790107_11005.xml | 214 +++ .../tests/data/IT02780790107_11006.xml | 94 ++ .../tests/data/IT02780790107_11007.xml | 96 ++ .../tests/data/IT03638121008_X11111.xml | 155 ++ .../tests/data/IT05979361218_001.xml | 107 ++ .../tests/data/IT05979361218_002.xml | 103 ++ .../tests/data/IT05979361218_002.xml.p7m | Bin 0 -> 6367 bytes .../tests/data/IT05979361218_003.xml | 95 ++ .../tests/data/IT05979361218_004.xml | 118 ++ .../tests/data/IT05979361218_005.xml | 109 ++ .../tests/data/IT05979361218_006.XML | 108 ++ .../tests/data/IT05979361218_007.xml | 94 ++ .../tests/data/IT05979361218_008.xml | 90 ++ .../tests/data/IT05979361218_fake.xml.p7m | 1 + .../tests/test_import_fatturapa_xml.py | 329 ++++ l10n_it_fatturapa_in/views/account_view.xml | 290 ++++ l10n_it_fatturapa_in/views/partner_view.xml | 24 + l10n_it_fatturapa_in/wizard/__init__.py | 22 + .../wizard/wizard_import_fatturapa.py | 1373 +++++++++++++++++ .../wizard/wizard_import_fatturapa_view.xml | 34 + 32 files changed, 4826 insertions(+) create mode 100644 l10n_it_fatturapa_in/__init__.py create mode 100644 l10n_it_fatturapa_in/__openerp__.py create mode 100644 l10n_it_fatturapa_in/i18n/it.po create mode 100644 l10n_it_fatturapa_in/models/__init__.py create mode 100644 l10n_it_fatturapa_in/models/account.py create mode 100644 l10n_it_fatturapa_in/models/attachment.py create mode 100644 l10n_it_fatturapa_in/security/ir.model.access.csv create mode 100644 l10n_it_fatturapa_in/static/src/img/icon.png create mode 100644 l10n_it_fatturapa_in/tests/__init__.py create mode 100644 l10n_it_fatturapa_in/tests/data/IT01234567890_11002.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT02780790107_11003.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT02780790107_11004.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT02780790107_11005.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT02780790107_11006.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT02780790107_11007.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT03638121008_X11111.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_001.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml.p7m create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_003.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_004.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_005.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_006.XML create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_007.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_008.xml create mode 100644 l10n_it_fatturapa_in/tests/data/IT05979361218_fake.xml.p7m create mode 100644 l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py create mode 100644 l10n_it_fatturapa_in/views/account_view.xml create mode 100644 l10n_it_fatturapa_in/views/partner_view.xml create mode 100644 l10n_it_fatturapa_in/wizard/__init__.py create mode 100644 l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py create mode 100644 l10n_it_fatturapa_in/wizard/wizard_import_fatturapa_view.xml diff --git a/l10n_it_fatturapa_in/__init__.py b/l10n_it_fatturapa_in/__init__.py new file mode 100644 index 000000000000..823e6fcb9a56 --- /dev/null +++ b/l10n_it_fatturapa_in/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015 AgileBG SAGL +# Copyright (C) 2015 innoviu Srl +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import models +from . import tests +from . import wizard diff --git a/l10n_it_fatturapa_in/__openerp__.py b/l10n_it_fatturapa_in/__openerp__.py new file mode 100644 index 000000000000..8a8013b893fc --- /dev/null +++ b/l10n_it_fatturapa_in/__openerp__.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015 AgileBG SAGL +# Copyright (C) 2015 innoviu Srl +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + 'name': 'Italian Localization - FatturaPA reception', + 'version': '0.1', + 'category': 'Localization/Italy', + 'summary': 'Electronic invoices reception', + 'author': 'Agile Business Group, Innoviu, ' + 'Odoo Community Association (OCA)', + 'description': """ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License + + +Italian Localization - FatturaPA - Reception +============================================ + +This module allows you to receive and parse the fatturaPA XML file version 1.1 +http://www.fatturapa.gov.it/export/fatturazione/en/normativa/f-2.htm +received from the Exchange System +http://www.fatturapa.gov.it/export/fatturazione/en/sdi.htm + + +Configuration +============= + +See l10n_it_fatturapa + +Usage +===== + + * Go to knowledge -> Documents + * Create a Incoming fatturaPA file + * Run Import FatturaPA wizard + +Credits +======= + +Contributors +------------ + +* Lorenzo Battistini +* Roberto Onnis +* Alessio Gerace + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. +""", + 'website': 'http://www.agilebg.com', + 'license': 'AGPL-3', + "depends": [ + 'l10n_it_fatturapa', + 'partner_firstname', + 'stock_invoice_picking_incoterm', + 'l10n_it_withholding_tax', + ], + "data": [ + 'views/account_view.xml', + 'views/partner_view.xml', + 'wizard/wizard_import_fatturapa_view.xml', + 'security/ir.model.access.csv', + ], + "installable": True +} diff --git a/l10n_it_fatturapa_in/i18n/it.po b/l10n_it_fatturapa_in/i18n/it.po new file mode 100644 index 000000000000..8ccb9628d9b1 --- /dev/null +++ b/l10n_it_fatturapa_in/i18n/it.po @@ -0,0 +1,570 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * l10n_it_fatturapa_in +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: l10n-italy (7.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-25 16:46+0000\n" +"PO-Revision-Date: 2015-11-18 17:08+0000\n" +"Last-Translator: <>\n" +"Language-Team: Italian (http://www.transifex.com/oca/OCA-l10n-italy-7-0/language/it/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice,fatturapa_attachment_in_id:0 +msgid "FatturaPA Import File" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1229 +#, python-format +msgid "Parsing PEM to DER file %s" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice.line,cod_article_ids:0 +msgid "Cod. Articles" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:97 +#, python-format +msgid "DatiAnagrafici.Anagrafica.Cognome contains \"%s\". Your System contains \"%s\"" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1208 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1228 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1235 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1256 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1263 +#, python-format +msgid "Errore" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.article.code,code_val:0 +msgid "Code Value" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:res.partner:0 +msgid "FatturaPA Registration" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Inconsistencies" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: selection:account.invoice.line,service_type:0 +msgid "sconto" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1257 +#, python-format +msgid "Signed Xml file %s" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:771 +#, python-format +msgid "tipoDocumento %s not handled" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Related Documents " +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:311 +#, python-format +msgid "Too many taxes with percentage %s and nature %s found" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1061 +#, python-format +msgid "Payment method Code %s is incorrect" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:fatturapa.attachment.in:0 +msgid "History" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:453 +#, python-format +msgid "TipoCassa is not defined " +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:248 +#, python-format +msgid "REA Office Code ( %s ) not present in system" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1284 +#, python-format +msgid "File is linked to invoices yet" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:232 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:304 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:310 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:452 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:561 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:697 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:743 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1052 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1060 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1084 +#, python-format +msgid "Error!" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:533 +#, python-format +msgid "Global invoice discount from DatiGeneraliDocumento" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: help:fatturapa.attachment.in,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice.line,service_type:0 +msgid "Service Type" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:fatturapa.attachment.in:0 +#: model:ir.actions.act_window,name:l10n_it_fatturapa_in.action_wizard_import_fatturapa +#: model:ir.model,name:l10n_it_fatturapa_in.model_wizard_import_fatturapa +#: view:wizard.import.fatturapa:0 +msgid "Import FatturaPA" +msgstr "Importa FatturaPA" + +#. module: l10n_it_fatturapa_in +#: help:fatturapa.attachment.in,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Related Documents" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Welfare Fund Details" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:698 +#, python-format +msgid "Define a purchase journal for this company: \"%s\" (id:%d)." +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:562 +#, python-format +msgid "ModalitaPagamento %s not defined in your system" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Rise Price Discount" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice.line:0 +msgid "Articles Code" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:132 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:171 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:212 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:247 +#, python-format +msgid "Error !" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "FatturaPA Payment" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice.line,service_start:0 +msgid "Service start at" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:623 +#, python-format +msgid "Name of Bank with BIC \"%s\" is not set. Can't create bank" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Payments Details" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,in_invoice_ids:0 +msgid "In Invoices" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "FatturaPA" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:135 +#, python-format +msgid "" +"Two distinct partners with Vat %s and Fiscalcode %s already present in db" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice.line,ftpa_uom:0 +msgid "Fattura Pa Unit of Measure" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:328 +#, python-format +msgid "" +"XML contains tax with percentage \"%s\" but it does not exist in your system" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:fatturapa.attachment.in:0 +msgid "on" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:fatturapa.attachment.in:0 +msgid "Invoices" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:fatturapa.attachment.in:0 +msgid "Xml Attachment" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: model:ir.model,name:l10n_it_fatturapa_in.model_account_invoice_line +msgid "Invoice Line" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.article.code,invoice_line_id:0 +msgid "Related Invoice line" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:84 +#, python-format +msgid "DatiAnagrafici.Anagrafica.Nome contains \"%s\". Your System contains \"%s\"" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: selection:account.invoice.line,service_type:0 +msgid "abbuono" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,ir_attachment_id:0 +msgid "Attachment" +msgstr "Allegato" + +#. module: l10n_it_fatturapa_in +#: view:wizard.import.fatturapa:0 +msgid "Import" +msgstr "Importa" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1120 +#, python-format +msgid "XML IPA code (%s) different from company IPA code (%s)" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice.line:0 +msgid "Discount Rise Price" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: selection:account.invoice.line,service_type:0 +msgid "premio" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:744 +#, python-format +msgid "No currency found with code %s" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:213 +#, python-format +msgid "ProvinciaAlbo ( %s ) not present in system" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1053 +#, python-format +msgid "Payment method Code not found in document" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice,inconsistencies:0 +msgid "Import Inconsistencies" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:172 +#, python-format +msgid "Country Code %s not found in system" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: model:ir.model,name:l10n_it_fatturapa_in.model_fatturapa_article_code +msgid "FatturaPA Article Code" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1085 +#, python-format +msgid "Attachment Name is Required" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.attachment.in,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:473 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:770 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1119 +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1284 +#, python-format +msgid "Error" +msgstr "Errore" + +#. module: l10n_it_fatturapa_in +#: field:fatturapa.article.code,name:0 +msgid "Cod Type" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:305 +#, python-format +msgid "No tax with percentage %s and nature %s found" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Fattura PA V1.1 Schema" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Attachments" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: model:ir.model,name:l10n_it_fatturapa_in.model_account_invoice +msgid "Invoice" +msgstr "Fattura" + +#. module: l10n_it_fatturapa_in +#: selection:account.invoice.line,service_type:0 +msgid "spesa accessoria" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:wizard.import.fatturapa:0 +msgid "Cancel" +msgstr "Annulla" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Summary Data" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice.line,discount_rise_price_ids:0 +msgid "Discount and Rise Price Details" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:337 +#, python-format +msgid "" +"Line '%s': Too many taxes with percentage equals to \"%s\"\n" +"fix it if required" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:fatturapa.attachment.in:0 +msgid "Creation" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Welfare Fund" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1175 +#, python-format +msgid "Computed amount untaxed %s is different from DatiRiepilogo %s" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1264 +#, python-format +msgid "Signed Xml file not decryptable" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1209 +#, python-format +msgid "Check PEM file %s" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1158 +#, python-format +msgid "Invoice total %s is different from ImportoTotaleDocumento %s" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: model:ir.model,name:l10n_it_fatturapa_in.model_fatturapa_attachment_in +msgid "FatturaPA import File" +msgstr "Fattura PA Importazione File" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Delivery" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Progress Work" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:474 +#, python-format +msgid "TipoCassa %s is not present in your system" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:wizard.import.fatturapa:0 +msgid "Confirm?" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "FatturaPA attachments" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:653 +#, python-format +msgid "" +"BIC is required and not exist in Xml\n" +"Curr bank data is: \n" +"IBAN: %s\n" +"Bank Name: %s\n" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Payments" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: field:account.invoice.line,service_end:0 +msgid "Service end at" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: help:fatturapa.attachment.in,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:1236 +#, python-format +msgid "ASN.1 structure is not parsable in DER" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: model:ir.actions.act_window,name:l10n_it_fatturapa_in.action_fattura_pa_in +#: model:ir.ui.menu,name:l10n_it_fatturapa_in.menu_fattura_pa_in_tree +msgid "Incoming fatturaPA files" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: view:account.invoice:0 +msgid "Results" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:71 +#, python-format +msgid "" +"DatiAnagrafici.Anagrafica.Denominazione contains \"%s\". Your System " +"contains \"%s\"" +msgstr "" + +#. module: l10n_it_fatturapa_in +#: code:addons/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py:233 +#, python-format +msgid "RegimeFiscale %s is not present in your system" +msgstr "" diff --git a/l10n_it_fatturapa_in/models/__init__.py b/l10n_it_fatturapa_in/models/__init__.py new file mode 100644 index 000000000000..98b75af48313 --- /dev/null +++ b/l10n_it_fatturapa_in/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015 AgileBG SAGL +# Copyright (C) 2015 innoviu Srl +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +from . import attachment +from . import account diff --git a/l10n_it_fatturapa_in/models/account.py b/l10n_it_fatturapa_in/models/account.py new file mode 100644 index 000000000000..91a13940e8de --- /dev/null +++ b/l10n_it_fatturapa_in/models/account.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2014 Davide Corio +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import fields, orm + + +class account_invoice(orm.Model): + _inherit = "account.invoice" + + _columns = { + 'fatturapa_attachment_in_id': fields.many2one( + 'fatturapa.attachment.in', 'FatturaPA Import File', + ondelete='restrict'), + 'inconsistencies': fields.text('Import Inconsistencies'), + } + + +class fatturapa_article_code(orm.Model): + # _position = ['2.2.1.3'] + _name = "fatturapa.article.code" + _description = 'FatturaPA Article Code' + + _columns = { + 'name': fields.char('Cod Type', size=35), + 'code_val': fields.char('Code Value', size=35), + 'invoice_line_id': fields.many2one( + 'account.invoice.line', 'Related Invoice line', + ondelete='cascade', select=True + ) + } + + +class account_invoice_line(orm.Model): + # _position = [ + # '2.2.1.3', '2.2.1.6', '2.2.1.7', + # '2.2.1.8', '2.1.1.10' + # ] + _inherit = "account.invoice.line" + + _columns = { + 'cod_article_ids': fields.one2many( + 'fatturapa.article.code', 'invoice_line_id', + 'Cod. Articles' + ), + 'service_type': fields.selection([ + ('SC', 'sconto'), + ('PR', 'premio'), + ('AB', 'abbuono'), + ('AC', 'spesa accessoria'), + ], string="Service Type"), + 'ftpa_uom': fields.char('Fattura Pa Unit of Measure', size=10), + 'service_start': fields.date('Service start at'), + 'service_end': fields.date('Service end at'), + 'discount_rise_price_ids': fields.one2many( + 'discount.rise.price', 'invoice_line_id', + 'Discount and Rise Price Details' + ), + } diff --git a/l10n_it_fatturapa_in/models/attachment.py b/l10n_it_fatturapa_in/models/attachment.py new file mode 100644 index 000000000000..83d8767d2d67 --- /dev/null +++ b/l10n_it_fatturapa_in/models/attachment.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015 AgileBG SAGL +# Copyright (C) 2015 innoviu Srl +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import fields, orm + + +class FatturaPAAttachmentIn(orm.Model): + _name = "fatturapa.attachment.in" + _description = "FatturaPA import File" + _inherits = {'ir.attachment': 'ir_attachment_id'} + _inherit = ['mail.thread'] + + _columns = { + 'ir_attachment_id': fields.many2one( + 'ir.attachment', 'Attachment', required=True, ondelete="cascade"), + 'in_invoice_ids': fields.one2many( + 'account.invoice', 'fatturapa_attachment_in_id', + string="In Invoices", readonly=True), + } + + def set_name(self, cr, uid, ids, datas_fname, context=None): + return {'value': {'name': datas_fname}} diff --git a/l10n_it_fatturapa_in/security/ir.model.access.csv b/l10n_it_fatturapa_in/security/ir.model.access.csv new file mode 100644 index 000000000000..93910a1eca6c --- /dev/null +++ b/l10n_it_fatturapa_in/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_fatturapa_attachment_in,access_fatturapa_attachment_in,model_fatturapa_attachment_in,account.group_account_invoice,1,1,1,1 +access_fatturapa_article_code,access_fatturapa_article_code,model_fatturapa_article_code,account.group_account_invoice,1,1,1,1 diff --git a/l10n_it_fatturapa_in/static/src/img/icon.png b/l10n_it_fatturapa_in/static/src/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1f07394c3b7990a313c758a4aaf6eab53e23e072 GIT binary patch literal 4829 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 r8aiT|hVCWM^FKV(3jG&l)t9W+$TKay +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import test_import_fatturapa_xml + +checks = [test_import_fatturapa_xml] diff --git a/l10n_it_fatturapa_in/tests/data/IT01234567890_11002.xml b/l10n_it_fatturapa_in/tests/data/IT01234567890_11002.xml new file mode 100644 index 000000000000..a5e9e02cc1b9 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT01234567890_11002.xml @@ -0,0 +1,134 @@ + + + + + + IT + 01234567890 + + 00001 + SDI11 + AAAAAA + + + + + + IT + 02537410900 + + + SOCIETA' ALPHA SRL + + RF01 + + + VIALE ROMA 543 + 07100 + SASSARI + SS + IT + + + + + 02537410900 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2014-12-18 + 123 + LA FATTURA FA RIFERIMENTO AD UNA OPERAZIONE AAAA BBBBBBBBBBBBBBBBBB CCC DDDDDDDDDDDDDDD E FFFFFFFFFFFFFFFFFFFF GGGGGGGGGG HHHHHHH II LLLLLLLLLLLLLLLLL MMM NNNNN OO PPPPPPPPPPP QQQQ RRRR SSSSSSSSSSSSSS + SEGUE DESCRIZIONE CAUSALE NEL CASO IN CUI NON SIANO STATI SUFFICIENTI 200 CARATTERI AAAAAAAAAAA BBBBBBBBBBBBBBBBB + + + 1 + 66685 + 1 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + + + IT + 24681012141 + + + Trasporto spa + + + 2012-10-22T16:46:12.000+02:00 + + + + + 1 + LA DESCRIZIONE DELLA FORNITURA PUO' SUPERARE I CENTO CARATTERI CHE RAPPRESENTAVANO IL PRECEDENTE LIMITE DIMENSIONALE. TALE LIMITE NELLA NUOVA VERSIONE E' STATO PORTATO A MILLE CARATTERI + 5.00 + 1.00 + 5.00 + 22.00 + + + 2 + FORNITURE VARIE PER UFFICIO + 10.00 + 2.00 + 20.00 + 22.00 + + + 22.00 + 27.00 + 5.95 + D + + + + TP01 + + MP01 + 2015-01-30 + 32.95 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT02780790107_11003.xml b/l10n_it_fatturapa_in/tests/data/IT02780790107_11003.xml new file mode 100644 index 000000000000..c4b664bd73d4 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT02780790107_11003.xml @@ -0,0 +1,172 @@ + + + + + + IT + 02780790107 + + 00001 + SDI11 + AAAAAA + + + + + + IT + 02780790107 + + + SOCIETA' ALPHA SRL + + RF01 + + + VIALE ROMA 543 + 07100 + SASSARI + SS + IT + + + + + 09876543210 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2014-12-23 + 125 + LA FATTURA FA RIFERIMENTO AD UNA OPERAZIONE AAAA BBBBBBBBBBBBBBBBBB CCC DDDDDDDDDDDDDDD E FFFFFFFFFFFFFFFFFFFF GGGGGGGGGG HHHHHHH II LLLLLLLLLLLLLLLLL + SEGUE DESCRIZIONE CAUSALE NEL CASO IN CUI NON SIANO STATI SUFFICIENTI 200 CARATTERI AAAAAAAAAAA BBBBBBBBBBBBBBBBB + + + 1 + 1 + 66685 + 1 + 123abc + 456def + + + 2 + 666852 + 2012-10-01 + 4 + 123cba2 + 456fed2 + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + 2 + 1232 + 2012-08-01 + 4 + 123abc2 + 456def2 + + + 1 + 2 + 123 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 1 + 123abc + 456def + + + + + IT + 05714511002 + + + Trasporto spa + + + 2012-10-22T16:46:12.000+02:00 + + + + + 1 + LA DESCRIZIONE DELLA FORNITURA PUO' SUPERARE I CENTO CARATTERI CHE RAPPRESENTAVANO IL PRECEDENTE LIMITE DIMENSIONALE. TALE LIMITE NELLA NUOVA VERSIONE E' STATO PORTATO A MILLE CARATTERI + 5.00 + 1.00 + 5.00 + 22.00 + + + 2 + FORNITURE VARIE PER UFFICIO + 10.00 + 2.00 + 20.00 + 22.00 + + + 22.00 + 27.00 + 5.95 + D + + + + TP01 + + MP01 + 2015-01-30 + 32.95 + + + + test.png + png + descrizione test + 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ly1bJ//xna6PPesN3lx+rf7qsla6+DefwLNTH7xakvz5u6mDELyHHBpgWkgEEAnp8wAge0e2bVESi8UcIsLMSZPeCgYCb8e6YQbAUz0cx1HZbBaM8/cfeeSRkvPPP9999dVX+bZt246LIaq3bNGvueYaedmIEbjv3nufNAOBB5UXkAs/Y1E4GPyaoeupO9ev95maA8Dll1/u0UR0ddDTo7sdmEIINDU1YeCgQdNWr127ctiwYZBSyoMHDx5XH+3evVt77bXXaMmSJVizfv0KJsR17777bo+JIo8XR8XQbLnnovhs04FaYirlSeni7qFtL4wLvJt6HwEhbqkZd9/G3++ZgdN/MtD923easfeHyaNa5e794RT9b985xD5+x31OPnUVqq+4525G5gPvp5tAIOoufa9Syi0NxqBp5v/865opf9iMaoSWHxkals16DK6Fw1ODgYAfm9glbZxznsvlKONlWGp56KGHvvi5z31ONTQ0yA0bNuhHuVhkO3bsMDOZDCZPmeI8VF2Nl3772zc1wxizd+9eWJblKqVIKUX5fF4dOnTINkOhyKm6/hQAVFZWEgCEQiGHiDB9+vSXhRB/725gtmfqAwcOIGia19y/cuUzQ4YMwZAhQ9zm5mYkk0fZR3v36rt378Y555zj7t27F7+85541hqb98NChQ/3OzMAx5LazbiI9dBtz6sevuYgZ9NsDyQ8guGeB7i4hOYFQHohBKpU1BT9n1LYl//C98zB9o/EkBkC/HtL6goXxGE+P4lEWejkE5y6Iy4PvAqsX2F6DGZ4cty6eg/U3g2untOZb/LMBWLE2tOWfALHSQAlKA+FBwzde1VD3uzox5qLOuR785OGVGze+aFnW8EQi4TAvPWy3abRM02TxeBxpy1oXC4fnzCocZVZTU8MCgYA+evRo2rZtm5o4cSIBwOOPP85efPFFPmLECDZixAjFOW9juocfeWSMct0niQiJZLJTtqH2WZtisRgGlJcfkb/i2muv1e+77z5n49atH80lk283NjX1ipn88gCAdP38xXPn/tW/vn79euOUU04BAGlZFsaPH0+PPvooM00To0eP5g888ABfvHhx3m/f6tWrB+UcZ7ehafHW1tZj9tdgAE7/6EfNKePG2fX19T0ebXds2Ud3rgX79znYMXXdk2knN6Yh1ywFetaLXKUoaoZZVAuiCdhpB+1p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 + + + test2.png + png + descrizione test 2 + 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ly1bJ//xna6PPesN3lx+rf7qsla6+DefwLNTH7xakvz5u6mDELyHHBpgWkgEEAnp8wAge0e2bVESi8UcIsLMSZPeCgYCb8e6YQbAUz0cx1HZbBaM8/cfeeSRkvPPP9999dVX+bZt246LIaq3bNGvueYaedmIEbjv3nufNAOBB5UXkAs/Y1E4GPyaoeupO9ev95maA8Dll1/u0UR0ddDTo7sdmEIINDU1YeCgQdNWr127ctiwYZBSyoMHDx5XH+3evVt77bXXaMmSJVizfv0KJsR17777bo+JIo8XR8XQbLnnovhs04FaYirlSeni7qFtL4wLvJt6HwEhbqkZd9/G3++ZgdN/MtD923easfeHyaNa5e794RT9b985xD5+x31OPnUVqq+4525G5gPvp5tAIOoufa9Syi0NxqBp5v/865opf9iMaoSWHxkals16DK6Fw1ODgYAfm9glbZxznsvlKONlWGp56KGHvvi5z31ONTQ0yA0bNuhHuVhkO3bsMDOZDCZPmeI8VF2Nl3772zc1wxizd+9eWJblKqVIKUX5fF4dOnTINkOhyKm6/hQAVFZWEgCEQiGHiDB9+vSXhRB/725gtmfqAwcOIGia19y/cuUzQ4YMwZAhQ9zm5mYkk0fZR3v36rt378Y555zj7t27F7+85541hqb98NChQ/3OzMAx5LazbiI9dBtz6sevuYgZ9NsDyQ8guGeB7i4hOYFQHohBKpU1BT9n1LYl//C98zB9o/EkBkC/HtL6goXxGE+P4lEWejkE5y6Iy4PvAqsX2F6DGZ4cty6eg/U3g2untOZb/LMBWLE2tOWfALHSQAlKA+FBwzde1VD3uzox5qLOuR785OGVGze+aFnW8EQi4TAvPWy3abRM02TxeBxpy1oXC4fnzCocZVZTU8MCgYA+evRo2rZtm5o4cSIBwOOPP85efPFFPmLECDZixAjFOW9juocfeWSMct0niQiJZLJTtqH2WZtisRgGlJcfkb/i2muv1e+77z5n49atH80lk283NjX1ipn88gCAdP38xXPn/tW/vn79euOUU04BAGlZFsaPH0+PPvooM00To0eP5g888ABfvHhx3m/f6tWrB+UcZ7ehafHW1tZj9tdgAE7/6EfNKePG2fX19T0ebXds2Ud3rgX79znYMXXdk2knN6Yh1ywFetaLXKUoaoZZVAuiCdhpB+1pv53WfOiBcTf1XCcID85ZURbKxDeUUulox3XQkk9B6yaRvp/kUSpJgyMDWIDrP/nKlrk3yu8REz8uvvDxmWLz5s1IWxYlE4lus3a2Z2rGGCstLYXrujACgRWxcPi2iRMn9kgbUDjjUNeHJxKJat0wTmlubkYulyPeRXozwAt2DYVC/NQhQz4/fvz4/26ffbS5uRllZWWo2rRpVSafX9Dc0KC4ED1m61dKUSgYZJFoFFDqjxnLmjJs2LC/f/7zn++RBiLCTd/73sCygQMry8vKRuRyOT+Laq/eQTGcGIYuZBvaPvEeCBiUsS1Ybk4JLrrMCN/W8QTFGPFSIwY7b4OBpyNG8IFYKLLVYexVEzKXFwKmlLBJBAj2sBaWGp92Uotd5cZLqRyJXAqSZCFHdA8pbkFuiRnTdMYOvJXB6dfVXwP0cJpsIpHg8XhcrV69enogGNzYU15lX/oUGFsZhuEdZea6MEzzD7FweBUZRj3l8393HAcFdQY5YKBJdGEik5mZSaWm+wdwFsxa3TJzoT4ViUT4aaeeeuGVV175cnuGpkKOu40bN8LK5Ww7n9czmUy31oV2dSki4rFYDHnHAUkpI+Hwyng8vsW27Vd0TctIKeGGwzDzeZMx9tnGxsaKdCazRCkVLy0tRTKZhJSyN1lHu8XRMvQxKf4MTH1wa6MYdOsA+eTk1edEjPDuPDlcSkmikMG/U0R4YfEoGDgRQ4udshVTRkwPR1yhln6Qa1qaymcL2f09+x7jDFE9CI3pCMgQ0k4OLUjYDMzgnGtd6cxe/gyCIqWCWkAzmEDWyp5+Xf03UbezToz59+7TSsXjcXXo0CEMHjx40y/vuefK8gEDrmr44APyEnh2rrO9KsA5567rqpaWFimE0Bljw1qlHJbL5ZDP5QDPEw4AYBgGgsEgUIjOSCQSCoAqHOLTZQb8dm3ghciO/waAZ555RrV7RlVWVvIZM2aoVatWDQkEAo22bYtCDF+X2ZQK4IwxJBIJlzGmBYNBQcDXmpqbv5bNZuG4LjgRFLxFajgchqbrCAaDSKfTaG1ttRljxvEy87HgmOeCQbcOkJVTqvnl1fPfYtCmnBoaBMEYkyRBrPguG7WLiOJghgBHKm+pD3ItdnM26SooCM6gCQHGvY5vzibdD3ItdjJvKealx/Uc06mHmUApZQiDR40whMLHJj79TaSXZ3hPzOxj8ODBnIhw6L33Zrmu++cBgwYxKaXqagfRo+8IhtCVUtTa2uq2tLTY2WxWEdB2FLIQAo7jIJFI2ImWFtvO5xXnnAsh2madHuhzSkpKEI/FXhs3bpyqqalhHfO/zZw5U9XW1oqFCxc2aUJcXFJS4nu3Kb+srlBYLGqMMWSzWdXS0mK3tra6rutCcA6h6xCFGcWn0bIsVfD0awseOJHMDBznoUEzt0xWNK0Go7fNq87CXnxqZAh06G0ZJrvTZzx7NSAE4xrjhia83FWOUuQoh/ydOk1omne/K9+5w2jX2TKgGTxuxsHBvjDy0av/vnlqNY/ccVQHVSoA7Me33Qb97bc/7TrOWwMGDOBth+P0Aowxpmmaxjk3mJf0hRzHIcc5TB9jzGCMGSgkhekmBOwI+sxAQOdCIJvNfhkAwuFw0b6sqKiQNTU1mD179k7O2MTS0lJomsbb+qibwdlu5uGcc6PgHwKlFDm2TargtdeBxm7b7xePfspnctwOKaxqAmhaLa7YsujBtMpNLw3GEdACXIHcgumhS03dl9j+y2MAOBjj4Izh8JTrfTrHu7a1oe1oF4JUSkXNsIgbYRDkBaO2Lfw/26bVsqmbJx+1RxljjCo3bhRzf/xjBIPBc3K2/fLQoUP9xWGPUu5w29sYg3HOWUE3Pur1CxF5x1BEIiISDoNc95y5c+cmtm7diu50ywkTJqDA1DUucFk0GkUwGORKKdnbwdmJDk/9Yh3vdYl2g1FwzgKBQE8mTer0Ry/QJx5WrKoCNK0W47ZeXcUYOz+sBVEeiGsSBCVJFVw8elyCElA45oe6NQEertiXWoCUUATCoFApF4wj52jhK7Zd/ZctU6rZxKqKY573Zs6YIR966CHx/sGDuHbx4guT6fSvhwwe7Es592im1PYMfhRS3v+xIiIMGDCAgzE3x7m5YOHCt5LJJCZNmtRjOT5TL5g9+1ldiNN0XUdZWZkotKXHwdkVHUfVfilRWlYmNE1D2rLeKMRkdlsIAQgchfGiz1wGWVUFKqdsZ6O3LvirXqpYK2v981mx02HoJpcgqeRhidYXPrCs4BWipFKukhQ2TX5q5BQ053K1Gg1hFdsXWK3fzbEpWyYftxK3aNEiuXTpUrZv3z4smj//GzmlhgeDQZSVlfn6bp+FMfnvp81yopQrpaRgKMQHDR6MXDb76CkDB+rXzpljJxMJ7tuNe4MJEybgscce47Nmz34vEg4zO5fbeeqppyIQCPiqVJ/1UTvLj1JKkRkI8Gg8jrxt77XzeRaNxaZFolGQlzq3y3IIgK7rDgCE+iaNQe8xc8tY2vuf08XI1ddg1rbvfNp2rHEGZxgULBWGrnEppXKldH0llLF2HdjFIGRgnToZAClStlSSAnqADwiXMwWGvHKHzar75oTLr9mPP98wWSu5PdBnKxLGGA0dOpRVVVVhwaxZL5XEYiyXy62PxWIoKSnxN16cjtKuSNuLlX2EWVBKSUopW0qJQCCglZaXMyIiuO6wa6+9tuLve/Zg5cqVPBaPH7UaNW7cOLVgwQKRyWSw5NprL85ls5dwxlBWVsYMw+BSSpJH9FHR998tDYC3MyulVJqm8bKyMsYAxYi+kM9kzr5+6VIENS3rOg6UUkZ7Xb7deyBN01AajyOdTisAGD685yxc/eID+wgqxfBbLpQf+8HZ+M30TUg4TTeQLX9q6CZcRUg7aSilHO84czDGSXBwdOLqwlaiggIpJsGhoJTQNU1E9AgAwCUJLY85nzTK1330sen48w17cMHPzmLHc7Z3T/jggw/E5s2b5de//nVs2bIlmLWs7TnbvlTTNORyOf+sQT9ZokZErLDbV8wURwCoYLNVAHRd11koFIJSClJKlXPdafFgsHrBwoXYs2cPzjrrrKM+HaojamtrxYUXXigHDx6MLZs348B7711rBoP36p5jFtLptO8V5x9p4Z8GXYxnOtJghEIhBAIB5LxMU4tLo9EHp8+YgZUrV8I0TWzZsgVXzZyZzWSzgUQikRPCTyjh5eNQRM6QwYN1TYg7Z8yYsYwK59/0RFe/OnW/fcvftW0/qHWXYxlevKIeLSXNFUbWuiPrZv9FEzoYCLZ04JILx5WFcwxJwcsFQwyMc3AmNAGDaTCECSIJR0mE9eD/uIZ9vZtsen78Ezfhobo1mPhchVb2s/gJiTTfvHmzGDFihCorKyPA2+lzstnbU5nMja7rIhiJQCkF27bhui5c1/V3ExW8dRUBEJxzaJoG0zQhPMd3EBEi0ejTdi73nYMHD/7PihUrQEQ4dOiQNmTIkD6l7+DBg9rgwYNdxhhWrlyJQQMHjkpb1s+sbPaTonCQpuM4sG0bUkoo7/RY2ZEGXddhGAaEEMik09AMIxMLh69TSq2aPWcOHl61ClOnTdMikYi7efNmMXXqVLlx48azrGx2T8Hm7asnvKDfI2tZ75qp1Blzly0DetgM89Hv4UMEYr+YX6lft/oq26/s91dthFK8gojNyLjpESnbKss6FjjXYQqtzS8kL1040kVECyGmhxpCwfAz5NCGSB5PfuaxaX752DB9ozFr00wHfetr3St861vf0v/rv/5LBgIBBQDX7dyJkc3NA3NSzkllMhOtTOaL6XQaXAgEDQNcLzjDKYW8bQNECAaDCEUibwcCgccEsE667p+mTivQR4SHH37YWLhwYX/Sx2pra/WKioq2FLzbtm2DUupyxdhVuWx2hJXJDEqn0zB0HbqugxU2g2zbBkmJcCiEUCj051A4vKm5pWXloUOHWlasWAEAaGho0AYOHCjbt78Q7YMtmzeHs/n8K+lM5uMggiIC5xwa5w8rpRYuWbIEnt9Z72bcExkPx2pn7TLU7EZ74qgjrQ51Sx5BrDUEcFWuMxFziQwtz2zHlElTqCY26AMM+/m3jihs3a5KFl0ZMirWV9j4JzByR9TV1QmdMTFi9Ogj8jLv3r0bb775JnK5nG4YxkAQhVwpGec8S0StgUAg/e6776LjSbNLly7Vbr/9dmaa5onMm8F27dpl7Nu3z77qqquOeKe1tbUgpSB1vVS5bgkRGQaQA2MJSNn6SjCI2664ou35wkA0FyxYYLMumNFnagB47NFHoYjO4Zw72Wx277Rp0/CjH/0IN910E+vq9x8aPPF8vaDp9QbNrzV7G0BLIEbza80t3m8+LBmLioERkb59+3bDdd1eu17W19eLuro6k7zA0X86fUTEa2trzdraWpN6mQzmmaefFvX19WZtbe+DOOrr60VNTU2n8t944w1BJy5fSN+CQLxyV62g5+pE8ruunr85r+dvJt394TJ9K7aLDzkD9wRORHz71q1imevqlM/r+Xxed11Xr6ur6zLo9cOGAoOLuro64bquns/ndSLSly1bpv/ud787bhr8cpPJpP6/lpFP4iRO4iRO4iRO4iRO4iT+F+L/AviS5OZi+9hAAAAAAElFTkSuQmCC + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT02780790107_11004.xml b/l10n_it_fatturapa_in/tests/data/IT02780790107_11004.xml new file mode 100644 index 000000000000..1bb43017a3b2 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT02780790107_11004.xml @@ -0,0 +1,211 @@ + + + + + + IT + 02780790107 + + 00001 + SDI11 + 79SRAK + + + + + + IT + 02780790107 + + + SOCIETA' ALPHA SRL + + RF01 + + + VIALE ROMA 543 + 07100 + SASSARI + SS + IT + + + + + + IT + 03339130126 + + 03339130126 + + Rappresentante fiscale + 1234567890123 + + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + IT + 03339130126 + + 03339130126 + + Rappresentante fiscale + 1234567890123 + + + + + + + + TD01 + EUR + 2014-12-18 + 123 + + TC01 + 4.00 + 9.00 + 22.00 + rif. amm + + LA FATTURA FA RIFERIMENTO AD UNA OPERAZIONE AAAA BBBBBBBBBBBBBBBBBB CCC DDDDDDDDDDDDDDD E FFFFFFFFFFFFFFFFFFFF GGGGGGGGGG HHHHHHH II LLLLLLLLLLLLLLLLL MMM NNNNN OO PPPPPPPPPPP QQQQ + SEGUE DESCRIZIONE CAUSALE NEL CASO IN CUI NON SIANO STATI SUFFICIENTI 200 CARATTERI AAAAAAAAAAA BBBBBBBBBBBBBBBBB + + + 1 + 66685 + 1 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + + + IT + 05714511002 + + + Trasporto spa + + + KGM + DAP + + strada dei test + 150/B + 12042 + Bra + CN + IT + + 2012-10-22T16:46:12.000+02:00 + + + + + 1 + LA DESCRIZIONE DELLA FORNITURA PUO' SUPERARE I CENTO CARATTERI CHE RAPPRESENTAVANO IL PRECEDENTE LIMITE DIMENSIONALE. TALE LIMITE NELLA NUOVA VERSIONE E' STATO PORTATO A MILLE CARATTERI + 5.00 + 1.00 + 5.00 + 22.00 + + + 2 + FORNITURE VARIE PER UFFICIO + 10.00 + 2.00 + 20.00 + 22.00 + + + 22.00 + 25.00 + 5.50 + D + + + + TP01 + + MP05 + 2015-04-30 + 20.00 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 2.00 + 2015-05-01 + + + MP05 + 2015-05-30 + 9.00 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 1.00 + 2015-05-31 + + + + TP02 + + MP05 + 2015-06-30 + 1.50 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 0.15 + 2015-07-01 + + + + test.png + png + descrizione test + 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ly1bJ//xna6PPesN3lx+rf7qsla6+DefwLNTH7xakvz5u6mDELyHHBpgWkgEEAnp8wAge0e2bVESi8UcIsLMSZPeCgYCb8e6YQbAUz0cx1HZbBaM8/cfeeSRkvPPP9999dVX+bZt246LIaq3bNGvueYaedmIEbjv3nufNAOBB5UXkAs/Y1E4GPyaoeupO9ev95maA8Dll1/u0UR0ddDTo7sdmEIINDU1YeCgQdNWr127ctiwYZBSyoMHDx5XH+3evVt77bXXaMmSJVizfv0KJsR17777bo+JIo8XR8XQbLnnovhs04FaYirlSeni7qFtL4wLvJt6HwEhbqkZd9/G3++ZgdN/MtD923easfeHyaNa5e794RT9b985xD5+x31OPnUVqq+4525G5gPvp5tAIOoufa9Syi0NxqBp5v/865opf9iMaoSWHxkals16DK6Fw1ODgYAfm9glbZxznsvlKONlWGp56KGHvvi5z31ONTQ0yA0bNuhHuVhkO3bsMDOZDCZPmeI8VF2Nl3772zc1wxizd+9eWJblKqVIKUX5fF4dOnTINkOhyKm6/hQAVFZWEgCEQiGHiDB9+vSXhRB/725gtmfqAwcOIGia19y/cuUzQ4YMwZAhQ9zm5mYkk0fZR3v36rt378Y555zj7t27F7+85541hqb98NChQ/3OzMAx5LazbiI9dBtz6sevuYgZ9NsDyQ8guGeB7i4hOYFQHohBKpU1BT9n1LYl//C98zB9o/EkBkC/HtL6goXxGE+P4lEWejkE5y6Iy4PvAqsX2F6DGZ4cty6eg/U3g2untOZb/LMBWLE2tOWfALHSQAlKA+FBwzde1VD3uzox5qLOuR785OGVGze+aFnW8EQi4TAvPWy3abRM02TxeBxpy1oXC4fnzCocZVZTU8MCgYA+evRo2rZtm5o4cSIBwOOPP85efPFFPmLECDZixAjFOW9juocfeWSMct0niQiJZLJTtqH2WZtisRgGlJcfkb/i2muv1e+77z5n49atH80lk283NjX1ipn88gCAdP38xXPn/tW/vn79euOUU04BAGlZFsaPH0+PPvooM00To0eP5g888ABfvHhx3m/f6tWrB+UcZ7ehafHW1tZj9tdgAE7/6EfNKePG2fX19T0ebXds2Ud3rgX79znYMXXdk2knN6Yh1ywFetaLXKUoaoZZVAuiCdhpB+1p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 + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT02780790107_11005.xml b/l10n_it_fatturapa_in/tests/data/IT02780790107_11005.xml new file mode 100644 index 000000000000..d14bfb7c3095 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT02780790107_11005.xml @@ -0,0 +1,214 @@ + + + + + + IT + 02780790107 + + 11005 + SDI11 + 79SRAK + + + + + + IT + 02780790107 + + + Societa' Alpha SRL + + RF01 + + + VIALE ROMA 543 + 07100 + SASSARI + SS + IT + + + + + + IT + 03339130126 + + 03339130126 + + Rappresentante fiscale + 1234567890123 + + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + IT + 03339130126 + + 03339130126 + + Rappresentante fiscale + 1234567890123 + + + + + + + + TD01 + EUR + 2014-12-18 + 124 + + TC01 + 4.00 + 9.00 + 225.00 + 22.00 + rif. amm + + LA FATTURA FA RIFERIMENTO AD UNA OPERAZIONE AAAA BBBBBBBBBBBBBBBBBB CCC DDDDDDDDDDDDDDD E FFFFFFFFFFFFFFFFFFFF GGGGGGGGGG HHHHHHH II LLLLLLLLLLLLLLLLL MMM NNNNN OO PPPPPPPPPPP QQQQ + SEGUE DESCRIZIONE CAUSALE NEL CASO IN CUI NON SIANO STATI SUFFICIENTI 200 CARATTERI AAAAAAAAAAA BBBBBBBBBBBBBBBBB + + + 1 + 66685 + 1 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + 1 + 123 + 5 + 123abc + 456def + + + + + IT + 05714511002 + + + Trasporto spa + + + + strada dei test + 150/B + 12042 + Bra + CN + IT + + 2012-10-22T16:46:12.000+02:00 + + + + + 1 + + EAN + 12345 + + LA DESCRIZIONE DELLA FORNITURA PUO' SUPERARE I CENTO CARATTERI CHE RAPPRESENTAVANO IL PRECEDENTE LIMITE DIMENSIONALE. TALE LIMITE NELLA NUOVA VERSIONE E' STATO PORTATO A MILLE CARATTERI + 5.00 + 1.00 + 5.00 + 22.00 + + + 2 + FORNITURE VARIE PER UFFICIO + 10.00 + 2.00 + 20.00 + 22.00 + + + 22.00 + 25.00 + 5.50 + D + + + + TP01 + + MP05 + 2015-04-30 + 20.00 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 2.00 + 2015-05-01 + + + MP05 + 2015-05-30 + 9.00 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 1.00 + 2015-05-31 + + + + TP02 + + MP05 + 2015-06-30 + 1.50 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 0.15 + 2015-07-01 + + + + test.png + png + descrizione test + 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ly1bJ//xna6PPesN3lx+rf7qsla6+DefwLNTH7xakvz5u6mDELyHHBpgWkgEEAnp8wAge0e2bVESi8UcIsLMSZPeCgYCb8e6YQbAUz0cx1HZbBaM8/cfeeSRkvPPP9999dVX+bZt246LIaq3bNGvueYaedmIEbjv3nufNAOBB5UXkAs/Y1E4GPyaoeupO9ev95maA8Dll1/u0UR0ddDTo7sdmEIINDU1YeCgQdNWr127ctiwYZBSyoMHDx5XH+3evVt77bXXaMmSJVizfv0KJsR17777bo+JIo8XR8XQbLnnovhs04FaYirlSeni7qFtL4wLvJt6HwEhbqkZd9/G3++ZgdN/MtD923easfeHyaNa5e794RT9b985xD5+x31OPnUVqq+4525G5gPvp5tAIOoufa9Syi0NxqBp5v/865opf9iMaoSWHxkals16DK6Fw1ODgYAfm9glbZxznsvlKONlWGp56KGHvvi5z31ONTQ0yA0bNuhHuVhkO3bsMDOZDCZPmeI8VF2Nl3772zc1wxizd+9eWJblKqVIKUX5fF4dOnTINkOhyKm6/hQAVFZWEgCEQiGHiDB9+vSXhRB/725gtmfqAwcOIGia19y/cuUzQ4YMwZAhQ9zm5mYkk0fZR3v36rt378Y555zj7t27F7+85541hqb98NChQ/3OzMAx5LazbiI9dBtz6sevuYgZ9NsDyQ8guGeB7i4hOYFQHohBKpU1BT9n1LYl//C98zB9o/EkBkC/HtL6goXxGE+P4lEWejkE5y6Iy4PvAqsX2F6DGZ4cty6eg/U3g2untOZb/LMBWLE2tOWfALHSQAlKA+FBwzde1VD3uzox5qLOuR785OGVGze+aFnW8EQi4TAvPWy3abRM02TxeBxpy1oXC4fnzCocZVZTU8MCgYA+evRo2rZtm5o4cSIBwOOPP85efPFFPmLECDZixAjFOW9juocfeWSMct0niQiJZLJTtqH2WZtisRgGlJcfkb/i2muv1e+77z5n49atH80lk283NjX1ipn88gCAdP38xXPn/tW/vn79euOUU04BAGlZFsaPH0+PPvooM00To0eP5g888ABfvHhx3m/f6tWrB+UcZ7ehafHW1tZj9tdgAE7/6EfNKePG2fX19T0ebXds2Ud3rgX79znYMXXdk2knN6Yh1ywFetaLXKUoaoZZVAuiCdhpB+1pv53WfOiBcTf1XCcID85ZURbKxDeUUulox3XQkk9B6yaRvp/kUSpJgyMDWIDrP/nKlrk3yu8REz8uvvDxmWLz5s1IWxYlE4lus3a2Z2rGGCstLYXrujACgRWxcPi2iRMn9kgbUDjjUNeHJxKJat0wTmlubkYulyPeRXozwAt2DYVC/NQhQz4/fvz4/26ffbS5uRllZWWo2rRpVSafX9Dc0KC4ED1m61dKUSgYZJFoFFDqjxnLmjJs2LC/f/7zn++RBiLCTd/73sCygQMry8vKRuRyOT+Laq/eQTGcGIYuZBvaPvEeCBiUsS1Ybk4JLrrMCN/W8QTFGPFSIwY7b4OBpyNG8IFYKLLVYexVEzKXFwKmlLBJBAj2sBaWGp92Uotd5cZLqRyJXAqSZCFHdA8pbkFuiRnTdMYOvJXB6dfVXwP0cJpsIpHg8XhcrV69enogGNzYU15lX/oUGFsZhuEdZea6MEzzD7FweBUZRj3l8393HAcFdQY5YKBJdGEik5mZSaWm+wdwFsxa3TJzoT4ViUT4aaeeeuGVV175cnuGpkKOu40bN8LK5Ww7n9czmUy31oV2dSki4rFYDHnHAUkpI+Hwyng8vsW27Vd0TctIKeGGwzDzeZMx9tnGxsaKdCazRCkVLy0tRTKZhJSyN1lHu8XRMvQxKf4MTH1wa6MYdOsA+eTk1edEjPDuPDlcSkmikMG/U0R4YfEoGDgRQ4udshVTRkwPR1yhln6Qa1qaymcL2f09+x7jDFE9CI3pCMgQ0k4OLUjYDMzgnGtd6cxe/gyCIqWCWkAzmEDWyp5+Xf03UbezToz59+7TSsXjcXXo0CEMHjx40y/vuefK8gEDrmr44APyEnh2rrO9KsA5567rqpaWFimE0Bljw1qlHJbL5ZDP5QDPEw4AYBgGgsEgUIjOSCQSCoAqHOLTZQb8dm3ghciO/waAZ555RrV7RlVWVvIZM2aoVatWDQkEAo22bYtCDF+X2ZQK4IwxJBIJlzGmBYNBQcDXmpqbv5bNZuG4LjgRFLxFajgchqbrCAaDSKfTaG1ttRljxvEy87HgmOeCQbcOkJVTqvnl1fPfYtCmnBoaBMEYkyRBrPguG7WLiOJghgBHKm+pD3ItdnM26SooCM6gCQHGvY5vzibdD3ItdjJvKealx/Uc06mHmUApZQiDR40whMLHJj79TaSXZ3hPzOxj8ODBnIhw6L33Zrmu++cBgwYxKaXqagfRo+8IhtCVUtTa2uq2tLTY2WxWEdB2FLIQAo7jIJFI2ImWFtvO5xXnnAsh2madHuhzSkpKEI/FXhs3bpyqqalhHfO/zZw5U9XW1oqFCxc2aUJcXFJS4nu3Kb+srlBYLGqMMWSzWdXS0mK3tra6rutCcA6h6xCFGcWn0bIsVfD0awseOJHMDBznoUEzt0xWNK0Go7fNq87CXnxqZAh06G0ZJrvTZzx7NSAE4xrjhia83FWOUuQoh/ydOk1omne/K9+5w2jX2TKgGTxuxsHBvjDy0av/vnlqNY/ccVQHVSoA7Me33Qb97bc/7TrOWwMGDOBth+P0Aowxpmmaxjk3mJf0hRzHIcc5TB9jzGCMGSgkhekmBOwI+sxAQOdCIJvNfhkAwuFw0b6sqKiQNTU1mD179k7O2MTS0lJomsbb+qibwdlu5uGcc6PgHwKlFDm2TargtdeBxm7b7xePfspnctwOKaxqAmhaLa7YsujBtMpNLw3GEdACXIHcgumhS03dl9j+y2MAOBjj4Izh8JTrfTrHu7a1oe1oF4JUSkXNsIgbYRDkBaO2Lfw/26bVsqmbJx+1RxljjCo3bhRzf/xjBIPBc3K2/fLQoUP9xWGPUu5w29sYg3HOWUE3Pur1CxF5x1BEIiISDoNc95y5c+cmtm7diu50ywkTJqDA1DUucFk0GkUwGORKKdnbwdmJDk/9Yh3vdYl2g1FwzgKBQE8mTer0Ry/QJx5WrKoCNK0W47ZeXcUYOz+sBVEeiGsSBCVJFVw8elyCElA45oe6NQEertiXWoCUUATCoFApF4wj52jhK7Zd/ZctU6rZxKqKY573Zs6YIR966CHx/sGDuHbx4guT6fSvhwwe7Es592im1PYMfhRS3v+xIiIMGDCAgzE3x7m5YOHCt5LJJCZNmtRjOT5TL5g9+1ldiNN0XUdZWZkotKXHwdkVHUfVfilRWlYmNE1D2rLeKMRkdlsIAQgchfGiz1wGWVUFKqdsZ6O3LvirXqpYK2v981mx02HoJpcgqeRhidYXPrCs4BWipFKukhQ2TX5q5BQ053K1Gg1hFdsXWK3fzbEpWyYftxK3aNEiuXTpUrZv3z4smj//GzmlhgeDQZSVlfn6bp+FMfnvp81yopQrpaRgKMQHDR6MXDb76CkDB+rXzpljJxMJ7tuNe4MJEybgscce47Nmz34vEg4zO5fbeeqppyIQCPiqVJ/1UTvLj1JKkRkI8Gg8jrxt77XzeRaNxaZFolGQlzq3y3IIgK7rDgCE+iaNQe8xc8tY2vuf08XI1ddg1rbvfNp2rHEGZxgULBWGrnEppXKldH0llLF2HdjFIGRgnToZAClStlSSAnqADwiXMwWGvHKHzar75oTLr9mPP98wWSu5PdBnKxLGGA0dOpRVVVVhwaxZL5XEYiyXy62PxWIoKSnxN16cjtKuSNuLlX2EWVBKSUopW0qJQCCglZaXMyIiuO6wa6+9tuLve/Zg5cqVPBaPH7UaNW7cOLVgwQKRyWSw5NprL85ls5dwxlBWVsYMw+BSSpJH9FHR998tDYC3MyulVJqm8bKyMsYAxYi+kM9kzr5+6VIENS3rOg6UUkZ7Xb7deyBN01AajyOdTisAGD685yxc/eID+wgqxfBbLpQf+8HZ+M30TUg4TTeQLX9q6CZcRUg7aSilHO84czDGSXBwdOLqwlaiggIpJsGhoJTQNU1E9AgAwCUJLY85nzTK1330sen48w17cMHPzmLHc7Z3T/jggw/E5s2b5de//nVs2bIlmLWs7TnbvlTTNORyOf+sQT9ZokZErLDbV8wURwCoYLNVAHRd11koFIJSClJKlXPdafFgsHrBwoXYs2cPzjrrrKM+HaojamtrxYUXXigHDx6MLZs348B7711rBoP36p5jFtLptO8V5x9p4Z8GXYxnOtJghEIhBAIB5LxMU4tLo9EHp8+YgZUrV8I0TWzZsgVXzZyZzWSzgUQikRPCTyjh5eNQRM6QwYN1TYg7Z8yYsYwK59/0RFe/OnW/fcvftW0/qHWXYxlevKIeLSXNFUbWuiPrZv9FEzoYCLZ04JILx5WFcwxJwcsFQwyMc3AmNAGDaTCECSIJR0mE9eD/uIZ9vZtsen78Ezfhobo1mPhchVb2s/gJiTTfvHmzGDFihCorKyPA2+lzstnbU5nMja7rIhiJQCkF27bhui5c1/V3ExW8dRUBEJxzaJoG0zQhPMd3EBEi0ejTdi73nYMHD/7PihUrQEQ4dOiQNmTIkD6l7+DBg9rgwYNdxhhWrlyJQQMHjkpb1s+sbPaTonCQpuM4sG0bUkoo7/RY2ZEGXddhGAaEEMik09AMIxMLh69TSq2aPWcOHl61ClOnTdMikYi7efNmMXXqVLlx48azrGx2T8Hm7asnvKDfI2tZ75qp1Blzly0DetgM89Hv4UMEYr+YX6lft/oq26/s91dthFK8gojNyLjpESnbKss6FjjXYQqtzS8kL1040kVECyGmhxpCwfAz5NCGSB5PfuaxaX752DB9ozFr00wHfetr3St861vf0v/rv/5LBgIBBQDX7dyJkc3NA3NSzkllMhOtTOaL6XQaXAgEDQNcLzjDKYW8bQNECAaDCEUibwcCgccEsE667p+mTivQR4SHH37YWLhwYX/Sx2pra/WKioq2FLzbtm2DUupyxdhVuWx2hJXJDEqn0zB0HbqugxU2g2zbBkmJcCiEUCj051A4vKm5pWXloUOHWlasWAEAaGho0AYOHCjbt78Q7YMtmzeHs/n8K+lM5uMggiIC5xwa5w8rpRYuWbIEnt9Z72bcExkPx2pn7TLU7EZ74qgjrQ51Sx5BrDUEcFWuMxFziQwtz2zHlElTqCY26AMM+/m3jihs3a5KFl0ZMirWV9j4JzByR9TV1QmdMTFi9Ogj8jLv3r0bb775JnK5nG4YxkAQhVwpGec8S0StgUAg/e6776LjSbNLly7Vbr/9dmaa5onMm8F27dpl7Nu3z77qqquOeKe1tbUgpSB1vVS5bgkRGQaQA2MJSNn6SjCI2664ou35wkA0FyxYYLMumNFnagB47NFHoYjO4Zw72Wx277Rp0/CjH/0IN910E+vq9x8aPPF8vaDp9QbNrzV7G0BLIEbza80t3m8+LBmLioERkb59+3bDdd1eu17W19eLuro6k7zA0X86fUTEa2trzdraWpN6mQzmmaefFvX19WZtbe+DOOrr60VNTU2n8t944w1BJy5fSN+CQLxyV62g5+pE8ruunr85r+dvJt394TJ9K7aLDzkD9wRORHz71q1imevqlM/r+Xxed11Xr6ur6zLo9cOGAoOLuro64bquns/ndSLSly1bpv/ud787bhr8cpPJpP6/lpFP4iRO4iRO4iRO4iRO4iT+F+L/AviS5OZi+9hAAAAAAElFTkSuQmCC + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT02780790107_11006.xml b/l10n_it_fatturapa_in/tests/data/IT02780790107_11006.xml new file mode 100644 index 000000000000..969383576ed9 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT02780790107_11006.xml @@ -0,0 +1,94 @@ + + + + + + IT + 02780790107 + + 11005 + SDI11 + 79SRAK + + + + + + IT + 02780790107 + + + Societa' Alpha SRL + + RF01 + + + VIALE ROMA 543 + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2014-12-18 + 125 + + + 60 + 66685 + 1 + 123abc + 456def + + + + + 1 + + EAN + 12345 + + + 5.00 + 1.00 + 5.00 + 22.00 + + + 2 + FORNITURE VARIE PER UFFICIO + 10.00 + 2.00 + 20.00 + 22.00 + + + 22.00 + 25.00 + 5.50 + D + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT02780790107_11007.xml b/l10n_it_fatturapa_in/tests/data/IT02780790107_11007.xml new file mode 100644 index 000000000000..52f3df99f6c6 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT02780790107_11007.xml @@ -0,0 +1,96 @@ + + + + + + IT + 02780790107 + + 11007 + SDI11 + 79SRAK + + + + + + IT + 02780790107 + + + Societa' Alpha SRL + + RF01 + + + VIALE ROMA 543 + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2015-06-18 + 136 + 56.50 + + + 60 + 66685 + 1 + 123abc + 456def + + + + + 1 + + EAN + 12345 + + ABC + 5.00 + 1.00 + 5.00 + 15.55 + + + 2 + FORNITURE VARIE PER UFFICIO + 10.00 + 2.00 + 20.00 + 15.55 + + + 15.55 + 26.00 + 25.00 + 5.50 + D + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT03638121008_X11111.xml b/l10n_it_fatturapa_in/tests/data/IT03638121008_X11111.xml new file mode 100644 index 000000000000..50eb005f9678 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT03638121008_X11111.xml @@ -0,0 +1,155 @@ + + + + + IT + 03638121008 + + 00001 + SDI11 + 79SRAK + + 060601 + prova@mail.it + + + + + + IT + 03638121008 + + + Societa' alpha S.r.l. + + RF01 + + + Via Roma + 00166 + Roma + RM + IT + + + Piazza Garibaldi + 00100 + Roma + RM + IT + + + + + 09876543210 + + Societa beta' S.r.l. + + + + Via Milano + 00100 + Roma + RM + IT + + + CC + + + + + TD01 + EUR + 2012-11-27 + 00001 + SI + + + 1 + 123 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + 1 + 123 + 2012-09-01 + 5 + 123abc + 456def + + + + + IT + 09399880153 + + + Trasporto spa + + + 2012-10-22T16:46:12.000+02:00 + + + + + 1 + BADGES MAGNETICI - PVC laminato bianco + 3.00000000 + 3.00 + 22.00 + + + 22.00 + 3.00 + 0.66 + + + + TP01 + + MP01 + 2012-12-31 + 3.66 + + + +/descendant::ds:SignaturedXKU0DEkuP9UUU+vhmUkS43CFwrQNcB370Om70mNRBM=wVXlY0vXFkhGtIf2w4o8RUkSO+8g2F2gnIBW4Y3NlMY=NoitlOJ+CRggD+X9ohF6Pw1gEHPXOu7ra1/by4BO0/U=lkOsFVW6pP/h/iMlQqKQLOqQX0I4ur/2xqoYNdjAkpNX36iSPispzDX+NMw56mkdmex0vaKZEdZU +5zjKMnXM5QGJMP85osa/ju57G2sneF66N6J0vfEttEhCeC6fV/k7fxa0OCSp7jy37ozvKE3+wZ6y +UfjuD+r/TfgLwKp1kiE=MIIEYDCCA0igAwIBAgIDEIgbMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNVBAYTAklUMR4wHAYDVQQK +ExVBZ2VuemlhIGRlbGxlIEVudHJhdGUxGzAZBgNVBAsTElNlcnZpemkgVGVsZW1hdGljaTEhMB8G +A1UEAxMYQ0EgQWdlbnppYSBkZWxsZSBFbnRyYXRlMB4XDTExMDcwNDEzMTkyNFoXDTE0MDcwNDEz +MTkyM1owdDELMAkGA1UEBhMCSVQxHjAcBgNVBAoTFUFnZW56aWEgZGVsbGUgRW50cmF0ZTEbMBkG +A1UECxMSU2Vydml6aSBUZWxlbWF0aWNpMSgwJgYDVQQDEx9TaXN0ZW1hIEludGVyc2NhbWJpbyBG +YXR0dXJhIFBBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMxOQj1dj6xgQBwB/S5naHvVqP +FL25Y3GnAulrcaeO8ZFFK5fWKPgiBwfyJ7qdlzn/RF7y+w92XLgh9zROmNlIjsJcp3rRwsAiKjuW +CkqwVXE0/Qtvxpo2Eovk1SV4+rf+7WKSHtabjmWXbM2FVccyN2AOvfR4WAdpr4hHkoEIiwIDAQAB +o4IBhDCCAYAwDgYDVR0PAQH/BAQDAgZAMIGZBgNVHSMEgZEwgY6AFOpEPx8Z4zc+q6qUgqWf6/wW +un+1oXGkbzBtMQswCQYDVQQGEwJJVDEeMBwGA1UEChMVQWdlbnppYSBkZWxsZSBFbnRyYXRlMRsw +GQYDVQQLExJTZXJ2aXppIFRlbGVtYXRpY2kxITAfBgNVBAMTGENBIEFnZW56aWEgZGVsbGUgRW50 +cmF0ZYIDEGJwMIGyBgNVHR8EgaowgacwgaSggaGggZ6GgZtsZGFwOi8vY2Fkcy5lbnRyYXRlLmZp +bmFuemUuaXQvY24lM2RDQSUyMEFnZW56aWElMjBkZWxsZSUyMEVudHJhdGUsb3UlM2RTZXJ2aXpp +JTIwVGVsZW1hdGljaSxvJTNkQWdlbnppYSUyMGRlbGxlJTIwRW50cmF0ZSxjJTNkaXQ/Y2VydGlm +aWNhdGVSZXZvY2F0aW9uTGlzdDAdBgNVHQ4EFgQUn+JY07NI6xlrCUXERiHoFFN66dkwDQYJKoZI +hvcNAQEFBQADggEBALZ0po2uLhLyZ8uiVfQUCAQd8s5o8ZJw2mcgZc/iaoNmDfcslZnTLWeuT6Gr +UFgG0uc1rY0UwWx/R1UOyc0ZesRo7Z6+kFmVubT1tbjLMuLjjUIyt4zWeNjf4PwNS0+s6Y6eC8tx +fOJmQNGQIbujWhAejoIteG01ciGeeII6AMnGK8KvbCA0UZmWl3Bou49zWajiEjtHFGkq/WNfDwRa +Fd4UWjR+UWS3rLahV7iOfh/+Yy7h1F0RzQuPJk7TCm7iHyc9QtgwxHHCmknRyNXMv6DeTOfK8ciq +uFWd6DasmblXLUm+uqhsWVRIkj2Bz63bpjuJU+8ptRfxHrVnzyCr9M4=2014-06-05T14:21:40Z diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_001.xml b/l10n_it_fatturapa_in/tests/data/IT05979361218_001.xml new file mode 100644 index 000000000000..07076657a068 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_001.xml @@ -0,0 +1,107 @@ + + + + + + IT + 05979361218 + + 001 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + Albo di test + TO + TO1258B + 2010-01-16 + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2015-02-16 + FT/2015/0006 + + TC22 + 0.00 + 3.00 + 3.00 + 0.00 + N4 + + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + 0.00 + 0.00 + + + + + 1 + Prodotto di test al giorno + 15.00 + Giorno(i) + 3.60 + 54.00 + 0.00 + N4 + + + 0.00 + N4 + 54.00 + 0.00 + Operazioni senza addebito imposta regime contribuenti minimi art.27 c.1-2 DL.98/11 + + + + TP01 + + MP05 + 2015-03-18 + 27.00 + + + MP05 + 2015-04-17 + 27.00 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml b/l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml new file mode 100644 index 000000000000..e264753a1e0a --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml @@ -0,0 +1,103 @@ + + + + + + IT + 05979361218 + + 002 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + Albo di test + TO + TO1258B + 2010-01-16 + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2015-02-16 + FT/2015/0007 + + TC22 + 0.00 + 3.00 + 3.00 + 0.00 + N4 + + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + Prodotto di test al giorno + 15.00 + Giorno(i) + 3.60 + 54.00 + 0.00 + N4 + + + 0.00 + N4 + 54.00 + 0.00 + Operazioni senza addebito imposta regime contribuenti minimi art.27 c.1-2 DL.98/11 + + + + TP01 + + MP05 + 2015-03-18 + 27.00 + + + MP05 + 2015-04-17 + 27.00 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml.p7m b/l10n_it_fatturapa_in/tests/data/IT05979361218_002.xml.p7m new file mode 100644 index 0000000000000000000000000000000000000000..59f6c323f0b57ad5b21ff5966e7f3ed2981b8255 GIT binary patch literal 6367 zcmd5=dvp}l8PDu)7V;uQAVh1z7z8wQckb+F^Kw|&Y&OYCvWdG3;wsuK$xhujUvY(TpyeQ16rj4kYJTgQ0$n}VTF3}d zx~Y|wY&WbFJ^^N8_+C(>C{={sC0G=OvQKnlGgAxbE_KQxT zpBJqNnHVZ-HdAG*D1}*B%-E=>#Yxi)m5Y=qtQy(EMIn5w%u29keWS;1o6k@=NGVx{ z8r!#woeN-xcEe6&FiaZdS_X^S1U4wKJ-naK3<~xtc(j#|`q>cYTxiQCCs@uRGzreL z504@MA^NuE8C6|^#ky$GBA?IKh#V$MGfmTgluUZcWmq@_}YqR$N*2u5H^O& zrf07J^8LKv=UL2b^>!&x9Wj$F;pz)>lIV>3C0^NGLXb9D8k!j@CpB9M;D;Th!h~pK zK(v9bQ;<2DoUOyn1^Fmhk}MvxCVvg#Zs5T_sue z(%sc*BQ3RN*lL=Tv5o=|yRF-b>S=@kOYob6K@9gnHS^d!9-G^V5vPo^8B+nWdORb7 zlS8E|fi_&~lK&a{7%FpxzD zot;jX)8lp9e9kVHL&>uLAj7@`xRBm1x6{={ni~vf0~bWsTFw9$jJ~tNio5f_fR(ZF z0BtJkv@o)j=jim!Vqj$�rqwIDwPc(CEy>y(UR&5&ckp1X)arDis+QWiKBQ({yhO zg6^3)myr!hp0@D)e3Z317Puka>VFOL_js?`O> zB=MWYr>3!D&Kdm7*x9})j)0r*Aw>z!#2nda>$WwK27`fgNk-C%&qO>Ncp!59BH5+# z&?a-Or4AyUl+Un1UH@C)o5_$4zmgHnoWOfHsUJFRnxX<1PUUPc#ETtZXAaabDi|@9 zwL&6{9A+4p(3WcFR%kc@QI=EZ2$BtvL0*&u5lrRMeA!wq>tn$`kSnxB!A@$N&ALDU zzD_=h!`G%Lzlgt>p+-(;3qb&(5i30SkZU&90k%g?jwR&an5(XR$JQtT$7!wRWFo?ykDP~-8zktd^2^H`D%1h^$U;Eh++l9F<+BmIebgmaFBvos&(Nmi1L zrh3wEqzxvrrNh|RK;b)5&V@4UQL`+EmsLW}JW~SG%?8;V4F_%za4=N1k>>DrqBVgOp9%%*udyAhlZvgfm9@#)&*hnqC`H!ZJrFtY()ZF6&EYr?^W z-Y`N*{m8bEp3e{+0r;^vzE>aA8fd83-=_~$*o|^du2YnHOk$|qFEZA`p|~!H;yOQy zYv&JXHH1bpvF_>{j(+&-lG~d7wWXIx8~31+)Kd^ql%Iz}bP+1hYZvJBlQd2*U4hE+ zps={qCiN|0yB&7YV~iMWM*0FY4O5DWE9{(PQR3y5cA7+0m_=JWb(Apa zY9sA7(u}I6me93u5i-GX2tFSS@x2JTrlrx+=tHreXPPqwO;XJ%7GS9eJU~DJ;OMDn zin`E*Hiz40cfeKJ;qf@T==0Hen2&EIA>T{U-T`HdU( z#ih@ip82e4Qn&lZ!$*jDzi4`*`Gxl`eD<0LOWs_+yy}UQ`yab=e$RnVZ*abR-CsX{ z?4-D8Lta_s&Iiw1U%X-az2hhP4$jtSi9BL!oLG$F#1+c!DoY9C8=X$8(a%Gbu$9UQ zx^ms**JfG{S2fM6`26u*&%JT@b;qd!;cnE1$)s)`vLZ%bG+R&Th}a1OK@f2Bo~<7b z6Z!e$G(`C{{GJzu2R%P)WHBltoF6~s`6E$duN)4cMOe`^-DRi?bq>uRat^d5UI6`4 zC_^F%3s1zB0ira9s16oCSJ>ShMi53+(hNeYn~p9(|ty3^s zIb8=ZUOoBL6OO$PTORu8nu|~0sJ-+!^~L_{P9SqiBcYpxW}xZGF(L-0Cd?N7(a1=< zN5&s=MjI!HJnEL8ift2o2U*uw26pMA(+|#K-Wv@0K5~8aJLhLd-#L64+CsgxGq0uh zflbB7s@zoz^WI;3to%@Z$&K29j`jO$KfYq`3oF=J+hRYvZ=wJ1&n%sG(W8&K-aR=u zesyU0t>8)MPd;s(QTS%}RrAdM+$&u2n&nToZ(02Cr8+vU0nll#fahiuTm8Q+Be|b*NZ zZzxU}QAMiI6=-RA4^O_76X^WZpdgL*o0t8M^<0o|(gUqS#aVqJ;8-i5iNI?L)CWD7Fj5cIe2i z#XhF<@UFhWKW=r1uZFjNcKtOQ-|`&~H=erOr`bwRL$Ng|vQ7AZaA0B&1e7>kY;}F- zs?A54DODdt=1(-Z4#0`; n>{H5*#+y(7 + + + + + IT + 05979361218 + + 003 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + IT + 05979361228 + + MRORSS90E25B111T + + MARIO + ROSSI + + + + TZ + + + + + TD01 + EUR + 2015-02-16 + FT/2015/0008 + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + Prodotto di test al giorno + 1.00 + 10.00 + + SC + 10.00 + + 9.00 + 0.00 + N4 + + + 0.00 + N4 + 9.00 + 0.00 + Operazioni senza addebito imposta regime contribuenti minimi art.27 c.1-2 DL.98/11 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_004.xml b/l10n_it_fatturapa_in/tests/data/IT05979361218_004.xml new file mode 100644 index 000000000000..1c2e8121e678 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_004.xml @@ -0,0 +1,118 @@ + + + + + + IT + 05979361218 + + 004 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + IT + 05979361228 + + MRORSS90E25B111T + + MARIO + ROSSI + + + + TZ + + + + + TD01 + EUR + 2015-02-16 + FT/2015/0009 + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + + SA + 123456-01 + + USB + 4.00 + PZ + 177.00 + + SC + 10.00 + + 637.20 + 22.00 + D122353 + + + 2 + + SA + 123456-04 + + USB + 1.00 + PZ + 596.00 + + SC + 10.00 + + 536.40 + 22.00 + D122354 + + + 22.00 + 1173.60 + 258.19 + S + SCISSIONE PAGAMENTI Split Payment art.17-ter del DPR 633/1972 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_005.xml b/l10n_it_fatturapa_in/tests/data/IT05979361218_005.xml new file mode 100644 index 000000000000..dc9f4267c8d8 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_005.xml @@ -0,0 +1,109 @@ + + + + + + IT + 05979361218 + + 005 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2015-02-16 + FT/2015/0010 + + SC + 10.00 + + 1288.61 + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + + SA + 123456-01 + + USB + 4.00 + PZ + 177.00 + + SC + 10.00 + + 637.20 + 22.00 + + + + 2 + + SA + 123456-04 + + USB + 1.00 + PZ + 596.00 + + SC + 10.00 + + 536.40 + 22.00 + + + + 22.00 + 1173.60 + 258.19 + S + SCISSIONE PAGAMENTI Split Payment art.17-ter del DPR 633/1972 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_006.XML b/l10n_it_fatturapa_in/tests/data/IT05979361218_006.XML new file mode 100644 index 000000000000..e86b6765c2e6 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_006.XML @@ -0,0 +1,108 @@ + + + + + + IT + 05979361218 + + 006 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2015-02-17 + FT/2015/0011 + + SC + 10.00 + + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + + SA + 123456-01 + + USB + 4.00 + PZ + 177.00 + + SC + 10.00 + + 637.20 + 22.00 + + + + 2 + + SA + 123456-04 + + USB + 1.00 + PZ + 596.00 + + SC + 10.00 + + 536.40 + 22.00 + + + + 22.00 + 1173.60 + 258.19 + S + SCISSIONE PAGAMENTI Split Payment art.17-ter del DPR 633/1972 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_007.xml b/l10n_it_fatturapa_in/tests/data/IT05979361218_007.xml new file mode 100644 index 000000000000..f6385a9f6685 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_007.xml @@ -0,0 +1,94 @@ + + + + + + IT + 05979361218 + + 007 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + + TD01 + EUR + 2015-03-16+02:00 + FT/2015/0009 + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + Prodotto di test al giorno + 1.00 + 10.00 + + SC + 10.00 + + 9.00 + 0.00 + N4 + + + 0.00 + N4 + 9.00 + 0.00 + Operazioni senza addebito imposta regime contribuenti minimi art.27 c.1-2 DL.98/11 + + + + TP02 + + MP18 + 2015-06-03+02:00 + 9.00 + Bank Test + IT28V0100003245232200001200 + GEBABEBB + 2.00 + 2015-06-04+02:00 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_008.xml b/l10n_it_fatturapa_in/tests/data/IT05979361218_008.xml new file mode 100644 index 000000000000..a054f728f770 --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_008.xml @@ -0,0 +1,90 @@ + + + + + + IT + 05979361218 + + 008 + SDI11 + 79SRAK + + + + + IT + 05979361218 + + + SOCIETA' ALPHA BETA SRL + + RF02 + + + VIALE ROMA 543B + 07100 + SASSARI + SS + IT + + + + + 80213330584 + + AMMINISTRAZIONE BETA + + + + VIA TORINO 38-B + 00145 + ROMA + RM + IT + + + + + + MARIO + ROSSI + + + + TZ + + + + + TD01 + EUR + 2015-06-22 + FT/2015/0012 + Rif ordine MAPA: --- Nr. Identificativo Ordine 1234567 + + + + + 1 + Prodotto di test al giorno + 1.00 + 10.00 + + SC + 10.00 + + 9.00 + 0.00 + N4 + + + 0.00 + N4 + 9.00 + 0.00 + Operazioni senza addebito imposta regime contribuenti minimi art.27 c.1-2 DL.98/11 + + + + diff --git a/l10n_it_fatturapa_in/tests/data/IT05979361218_fake.xml.p7m b/l10n_it_fatturapa_in/tests/data/IT05979361218_fake.xml.p7m new file mode 100644 index 000000000000..8d1c8b69c3fc --- /dev/null +++ b/l10n_it_fatturapa_in/tests/data/IT05979361218_fake.xml.p7m @@ -0,0 +1 @@ + diff --git a/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py b/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py new file mode 100644 index 000000000000..e613cc138dfe --- /dev/null +++ b/l10n_it_fatturapa_in/tests/test_import_fatturapa_xml.py @@ -0,0 +1,329 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2014 Davide Corio +# Copyright (C) 2015 Lorenzo Battistini +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import base64 +import tempfile +import openerp.tests.common as test_common +from openerp import addons +from openerp.osv.orm import except_orm + + +class TestFatturaPAXMLValidation(test_common.SingleTransactionCase): + + def getFile(self, filename): + path = addons.get_module_resource('l10n_it_fatturapa_in', + 'tests', 'data', filename) + with open(path) as test_data: + with tempfile.TemporaryFile() as out: + base64.encode(test_data, out) + out.seek(0) + return path, out.read() + + def setUp(self): + super(TestFatturaPAXMLValidation, self).setUp() + self.wizard_model = self.registry('wizard.import.fatturapa') + self.data_model = self.registry('ir.model.data') + self.attach_model = self.registry('fatturapa.attachment.in') + self.invoice_model = self.registry('account.invoice') + + def run_wizard(self, name, file_name): + cr, uid = self.cr, self.uid + attach_id = self.attach_model .create( + cr, uid, + { + 'name': name, + 'datas': self.getFile(file_name)[1], + 'datas_fname': file_name + }) + wizard_id = self.wizard_model.create(cr, uid, {}) + + return self.wizard_model.importFatturaPA( + cr, uid, wizard_id, context={'active_ids': [attach_id]}) + + def run_wizard_multi(self, file_name_list): + cr, uid = self.cr, self.uid + active_ids = [] + for file_name in file_name_list: + active_ids.append(self.attach_model .create( + cr, uid, + { + 'name': file_name, + 'datas': self.getFile(file_name)[1], + 'datas_fname': file_name + })) + wizard_id = self.wizard_model.create(cr, uid, {}) + + return self.wizard_model.importFatturaPA( + cr, uid, wizard_id, context={'active_ids': active_ids}) + + def test_00_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test0', 'IT05979361218_001.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.partner_id.register_code, 'TO1258B') + self.assertEqual( + invoice.partner_id.register_fiscalpos.code, 'RF02') + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0006') + self.assertEqual(invoice.amount_total, 54.00) + self.assertEqual(invoice.gross_weight, 0.00) + self.assertEqual(invoice.net_weight, 0.00) + + def test_01_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test1', 'IT02780790107_11004.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, '123') + self.assertEqual(invoice.amount_untaxed, 25.00) + self.assertEqual(invoice.amount_tax, 5.50) + self.assertEqual( + len(invoice.invoice_line[0].invoice_line_tax_id), 1) + self.assertEqual( + invoice.invoice_line[0].invoice_line_tax_id[0].name, '22% ftPA') + self.assertEqual( + invoice.fatturapa_summary_ids[0].amount_untaxed, 25.00) + self.assertEqual( + invoice.fatturapa_summary_ids[0].amount_tax, 5.50) + self.assertEqual( + invoice.fatturapa_summary_ids[0].payability, 'D') + self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") + self.assertEqual(invoice.partner_id.street, "VIALE ROMA 543") + self.assertEqual(invoice.partner_id.province.code, "SS") + self.assertEqual( + invoice.tax_representative_id.name, "Rappresentante fiscale") + self.assertEqual(invoice.welfare_fund_ids[0].welfare_rate_tax, 0.04) + self.assertEqual( + invoice.related_documents[0].type, "order") + self.assertEqual( + invoice.related_documents[0].cig, '456def') + self.assertEqual( + invoice.related_documents[0].cup, '123abc') + self.assertEqual( + invoice.welfare_fund_ids[0].welfare_amount_tax, 9) + self.assertFalse(invoice.welfare_fund_ids[0].welfare_taxable) + self.assertEqual(invoice.unit_weight, 'KGM') + self.assertEqual(invoice.incoterm.code, 'DAP') + + def test_02_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test2', 'IT03638121008_X11111.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, '00001') + self.assertEqual(invoice.amount_untaxed, 3) + self.assertEqual(invoice.amount_tax, 0.66) + self.assertEqual( + invoice.fatturapa_summary_ids[0].amount_untaxed, 3) + self.assertEqual( + invoice.fatturapa_summary_ids[0].amount_tax, 0.66) + self.assertEqual(invoice.partner_id.name, "Societa' alpha S.r.l.") + + def test_03_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test3', 'IT05979361218_002.xml.p7m') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.partner_id.register_code, 'TO1258B') + self.assertEqual( + invoice.partner_id.register_fiscalpos.code, 'RF02') + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0007') + self.assertEqual(invoice.amount_total, 54.00) + + def test_04_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test4', 'IT02780790107_11005.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, '124') + self.assertEqual(invoice.partner_id.name, "SOCIETA' ALPHA SRL") + self.assertEqual( + invoice.invoice_line[0].invoice_line_tax_id[0].name, '22% ftPA') + self.assertEqual( + invoice.invoice_line[1].invoice_line_tax_id[0].name, '22% ftPA') + self.assertEqual( + invoice.invoice_line[0].invoice_line_tax_id[0].amount, 0.22) + self.assertEqual( + invoice.invoice_line[1].invoice_line_tax_id[0].amount, 0.22) + self.assertEqual( + invoice.invoice_line[1].price_unit, 2) + self.assertEqual( + invoice.invoice_line[0].cod_article_ids[0].name, 'EAN') + self.assertEqual( + invoice.invoice_line[0].cod_article_ids[0].code_val, '12345') + self.assertEqual( + invoice.inconsistencies, + u'DatiAnagrafici.Anagrafica.Denominazione contains "Societa\' ' + 'Alpha SRL". Your System contains "SOCIETA\' ALPHA SRL"') + + def test_05_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test5', 'IT05979361218_003.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0008') + self.assertEqual(invoice.sender, 'TZ') + self.assertEqual(invoice.intermediary.name, 'ROSSI MARIO') + self.assertEqual(invoice.intermediary.firstname, 'MARIO') + self.assertEqual(invoice.intermediary.lastname, 'ROSSI') + self.assertEqual( + invoice.invoice_line[0].discount_rise_price_ids[0].name, 'SC') + self.assertEqual( + invoice.invoice_line[0].discount_rise_price_ids[0].percentage, 10) + self.assertEqual(invoice.amount_untaxed, 9) + self.assertEqual(invoice.amount_tax, 0) + self.assertEqual(invoice.amount_total, 9) + + def test_06_import_except(self): + # File not exist Exception + self.assertRaises( + Exception, self.run_wizard, 'test6_Exception', '') + # fake Signed file is passed , generate orm_exception + self.assertRaises( + except_orm, self.run_wizard, 'test6_orm_exception', + 'IT05979361218_fake.xml.p7m' + ) + + def test_07_xml_import(self): + cr, uid = self.cr, self.uid + # 2 lines with quantity != 1 and discounts + res = self.run_wizard('test7', 'IT05979361218_004.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0009') + self.assertEqual(invoice.amount_untaxed, 1173.60) + self.assertEqual(invoice.amount_tax, 258.19) + self.assertEqual(invoice.amount_total, 1431.79) + self.assertEqual(invoice.invoice_line[0].admin_ref, 'D122353') + + def test_08_xml_import(self): + cr, uid = self.cr, self.uid + # using ImportoTotaleDocumento + res = self.run_wizard('test8', 'IT05979361218_005.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0010') + self.assertEqual(invoice.amount_total, 1288.61) + self.assertFalse(invoice.inconsistencies) + + def test_09_xml_import(self): + cr, uid = self.cr, self.uid + # using DatiGeneraliDocumento.ScontoMaggiorazione without + # ImportoTotaleDocumento + # add test file name case sensitive + res = self.run_wizard('test9', 'IT05979361218_006.XML') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0011') + self.assertEqual(invoice.amount_total, 1288.61) + self.assertEqual( + invoice.inconsistencies, + 'Computed amount untaxed 1030.42 is different from' + ' DatiRiepilogo 1173.6') + + def test_10_xml_import(self): + # Fix Date format + cr, uid = self.cr, self.uid + res = self.run_wizard('test6', 'IT05979361218_007.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0009') + self.assertEqual( + invoice.date_invoice, '2015-03-16') + self.assertEqual( + invoice.fatturapa_payments[0].payment_methods[0].payment_due_date, + '2015-06-03' + ) + self.assertEqual( + invoice.fatturapa_payments[0].payment_methods[0]. + fatturapa_pm_id.code, + 'MP18' + ) + + def test_11_xml_import(self): + # DatiOrdineAcquisto with RiferimentoNumeroLinea referring to + # not existing invoice line + cr, uid = self.cr, self.uid + res = self.run_wizard('test11', 'IT02780790107_11006.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual( + len(invoice.invoice_line[0].related_documents), 0) + self.assertEqual( + invoice.invoice_line[0].sequence, 1) + self.assertEqual( + invoice.related_documents[0].type, "order") + self.assertEqual( + invoice.related_documents[0].lineRef, 60) + + def test_12_xml_import(self): + cr, uid = self.cr, self.uid + res = self.run_wizard('test12', 'IT05979361218_008.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, 'FT/2015/0012') + self.assertEqual(invoice.sender, 'TZ') + self.assertEqual(invoice.intermediary.name, 'ROSSI MARIO') + self.assertEqual(invoice.intermediary.firstname, 'MARIO') + self.assertEqual(invoice.intermediary.lastname, 'ROSSI') + + def test_13_xml_import(self): + # inconsistencies must not be duplicated + cr, uid = self.cr, self.uid + res = self.run_wizard_multi([ + 'IT02780790107_11005.xml', + 'IT02780790107_11005.xml', + ]) + invoice1_id = res.get('domain')[0][2][0] + invoice2_id = res.get('domain')[0][2][1] + invoice1 = self.invoice_model.browse(cr, uid, invoice1_id) + invoice2 = self.invoice_model.browse(cr, uid, invoice2_id) + self.assertEqual( + invoice1.inconsistencies, + u'DatiAnagrafici.Anagrafica.Denominazione contains "Societa\' ' + 'Alpha SRL". Your System contains "SOCIETA\' ALPHA SRL"') + self.assertEqual( + invoice2.inconsistencies, + u'DatiAnagrafici.Anagrafica.Denominazione contains "Societa\' ' + 'Alpha SRL". Your System contains "SOCIETA\' ALPHA SRL"') + + def test_14_xml_import(self): + # check: no tax code found , write inconsisteance and anyway + # create draft + cr, uid = self.cr, self.uid + res = self.run_wizard('test14', 'IT02780790107_11007.xml') + invoice_id = res.get('domain')[0][2][0] + invoice = self.invoice_model.browse(cr, uid, invoice_id) + self.assertEqual(invoice.supplier_invoice_number, '136') + self.assertEqual(invoice.partner_id.name, 'SOCIETA\' ALPHA SRL') + self.assertEqual(invoice.amount_untaxed, 25.00) + self.assertEqual(invoice.amount_tax, 0.0) + # check: filling check_total invoice field with summary data take from + # ''DatitRiepilogo' + self.assertEqual(invoice.check_total, 56.50) + self.assertEqual( + invoice.inconsistencies, + u'DatiAnagrafici.Anagrafica.Denominazione contains "Societa\' ' + 'Alpha SRL". Your System contains "SOCIETA\' ALPHA SRL"\n' + u'XML contains tax with percentage "15.55"' + ' but it does not exist in your system\n' + 'XML contains tax with percentage "15.55"' + ' but it does not exist in your system') diff --git a/l10n_it_fatturapa_in/views/account_view.xml b/l10n_it_fatturapa_in/views/account_view.xml new file mode 100644 index 000000000000..5074a2a50ac5 --- /dev/null +++ b/l10n_it_fatturapa_in/views/account_view.xml @@ -0,0 +1,290 @@ + + + + + + fatturapa.attachment.in.form + fatturapa.attachment.in + +
+
+ + + + + + + + + +
+ on + +
+
+
+
+ + +
+
+
+
+ + fatturapa.attachment.in.tree + fatturapa.attachment.in + + + + + + + + + Incoming fatturaPA files + fatturapa.attachment.in + form + tree,form + + + + + + account.invoice.line.fatturapa.in + account.invoice.line + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + account.invoice.fatturapa_in + account.invoice + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+
+
+
+
diff --git a/l10n_it_fatturapa_in/views/partner_view.xml b/l10n_it_fatturapa_in/views/partner_view.xml new file mode 100644 index 000000000000..171671e26fb4 --- /dev/null +++ b/l10n_it_fatturapa_in/views/partner_view.xml @@ -0,0 +1,24 @@ + + + + + partner.form.fatturapa.in + res.partner + + + + + + + + + + + + + + + + + + diff --git a/l10n_it_fatturapa_in/wizard/__init__.py b/l10n_it_fatturapa_in/wizard/__init__.py new file mode 100644 index 000000000000..a45fc832329f --- /dev/null +++ b/l10n_it_fatturapa_in/wizard/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015 AgileBG SAGL +# Copyright (C) 2015 innoviu Srl +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import wizard_import_fatturapa diff --git a/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py b/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py new file mode 100644 index 000000000000..c252b594faf9 --- /dev/null +++ b/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa.py @@ -0,0 +1,1373 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015 AgileBG SAGL +# Copyright (C) 2015 innoviu Srl +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import base64 +import os +import shlex +import subprocess +from openerp.osv import orm +from openerp.tools.translate import _ +import logging + + +from openerp.addons.l10n_it_fatturapa.bindings import fatturapa_v_1_1 +from openerp.addons.base_iban import base_iban +from lxml import etree + +_logger = logging.getLogger(__name__) + + +class WizardImportFatturapa(orm.TransientModel): + _name = "wizard.import.fatturapa" + _description = "Import FatturaPA" + + def saveAttachment(self, cr, uid, context=None): + if not context: + context = {} + + return False + + def CountryByCode(self, cr, uid, CountryCode, context=None): + country_model = self.pool['res.country'] + return country_model.search( + cr, uid, [('code', '=', CountryCode)], context=context) + + def ProvinceByCode(self, cr, uid, provinceCode, context=None): + province_model = self.pool['res.province'] + return province_model.search( + cr, uid, [('code', '=', provinceCode)], context=context) + + def check_partner_base_data( + self, cr, uid, partner_id, DatiAnagrafici, context=None + ): + if context is None: + context = {} + partner = self.pool['res.partner'].browse( + cr, uid, partner_id, context=context) + if ( + DatiAnagrafici.Anagrafica.Denominazione and + partner.name != DatiAnagrafici.Anagrafica.Denominazione + ): + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _( + "DatiAnagrafici.Anagrafica.Denominazione contains \"%s\"." + " Your System contains \"%s\"" + ) + % (DatiAnagrafici.Anagrafica.Denominazione, partner.name) + ) + if ( + DatiAnagrafici.Anagrafica.Nome and + partner.firstname != DatiAnagrafici.Anagrafica.Nome + ): + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _( + "DatiAnagrafici.Anagrafica.Nome contains \"%s\"." + " Your System contains \"%s\"" + ) + % (DatiAnagrafici.Anagrafica.Nome, partner.firstname) + ) + if ( + DatiAnagrafici.Anagrafica.Cognome and + partner.lastname != DatiAnagrafici.Anagrafica.Cognome + ): + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _( + "DatiAnagrafici.Anagrafica.Cognome contains \"%s\"." + " Your System contains \"%s\"" + ) + % (DatiAnagrafici.Anagrafica.Cognome, partner.lastname) + ) + + def getPartnerBase(self, cr, uid, DatiAnagrafici, context=None): + if not DatiAnagrafici: + return False + partner_model = self.pool['res.partner'] + cf = DatiAnagrafici.CodiceFiscale or False + vat = False + if DatiAnagrafici.IdFiscaleIVA: + vat = "%s%s" % ( + DatiAnagrafici.IdFiscaleIVA.IdPaese, + DatiAnagrafici.IdFiscaleIVA.IdCodice + ) + partner_ids = partner_model.search( + cr, uid, + ['|', + ('vat', '=', vat or 0), + ('fiscalcode', '=', cf or 0), + ], + context=context) + commercial_partner = False + if len(partner_ids) > 1: + for partner in partner_model.browse( + cr, uid, partner_ids, context=context + ): + if ( + commercial_partner and + partner.commercial_partner_id.id != commercial_partner + ): + raise orm.except_orm( + _('Error !'), + _("Two distinct partners with " + "Vat %s and Fiscalcode %s already present in db" % + (vat, cf)) + ) + commercial_partner = partner.commercial_partner_id.id + if not partner_ids: + if DatiAnagrafici.Anagrafica.Denominazione: + partner_ids = partner_model.search( + cr, uid, + [('name', '=', DatiAnagrafici.Anagrafica.Denominazione)], + context=context) + elif ( + DatiAnagrafici.Anagrafica.Nome and + DatiAnagrafici.Anagrafica.Cognome + ): + partner_ids = partner_model.search( + cr, uid, + [ + ('firstname', '=', DatiAnagrafici.Anagrafica.Nome), + ('lastname', '=', DatiAnagrafici.Anagrafica.Cognome), + ], + context=context) + if partner_ids: + commercial_partner = partner_ids[0] + self.check_partner_base_data( + cr, uid, commercial_partner, DatiAnagrafici, context=context) + return commercial_partner + else: + # partner to be created + country_id = False + if DatiAnagrafici.IdFiscaleIVA: + CountryCode = DatiAnagrafici.IdFiscaleIVA.IdPaese + country_ids = self.CountryByCode( + cr, uid, CountryCode, context=context) + if country_ids: + country_id = country_ids[0] + else: + raise orm.except_orm( + _('Error !'), + _("Country Code %s not found in system") % CountryCode + ) + vals = { + 'vat': vat, + 'fiscalcode': cf, + 'customer': False, + 'supplier': True, + 'is_company': ( + DatiAnagrafici.Anagrafica.Denominazione and True or False), + 'eori_code': DatiAnagrafici.Anagrafica.CodEORI or '', + 'country_id': country_id, + } + if DatiAnagrafici.Anagrafica.Nome: + vals['firstname'] = DatiAnagrafici.Anagrafica.Nome + if DatiAnagrafici.Anagrafica.Cognome: + vals['lastname'] = DatiAnagrafici.Anagrafica.Cognome + if DatiAnagrafici.Anagrafica.Denominazione: + vals['name'] = DatiAnagrafici.Anagrafica.Denominazione + + return partner_model.create(cr, uid, vals, context=context) + + def getCedPrest(self, cr, uid, cedPrest, context=None): + partner_model = self.pool['res.partner'] + partner_id = self.getPartnerBase( + cr, uid, cedPrest.DatiAnagrafici, context=context) + fiscalPosModel = self.pool['fatturapa.fiscal_position'] + vals = {} + if partner_id: + vals = { + 'street': cedPrest.Sede.Indirizzo, + 'zip': cedPrest.Sede.CAP, + 'city': cedPrest.Sede.Comune, + 'register': cedPrest.DatiAnagrafici.AlboProfessionale or '' + } + if cedPrest.DatiAnagrafici.ProvinciaAlbo: + ProvinciaAlbo = cedPrest.DatiAnagrafici.ProvinciaAlbo + prov_ids = self.ProvinceByCode( + cr, uid, ProvinciaAlbo, context=context) + if not prov_ids: + raise orm.except_orm( + _('Error !'), + _('ProvinciaAlbo ( %s ) not present in system') % + ProvinciaAlbo + ) + vals['register_province'] = prov_ids[0] + + vals['register_code'] = ( + cedPrest.DatiAnagrafici.NumeroIscrizioneAlbo) + vals['register_regdate'] = ( + cedPrest.DatiAnagrafici.DataIscrizioneAlbo) + + if cedPrest.DatiAnagrafici.RegimeFiscale: + rfPos = cedPrest.DatiAnagrafici.RegimeFiscale + FiscalPosIds = fiscalPosModel.search( + cr, uid, + [('code', '=', rfPos)], + context=context + ) + if not FiscalPosIds: + raise orm.except_orm( + _('Error!'), + _('RegimeFiscale %s is not present in your system') + % rfPos + ) + else: + vals['register_fiscalpos'] = FiscalPosIds[0] + + if cedPrest.IscrizioneREA: + REA = cedPrest.IscrizioneREA + vals['rea_code'] = REA.NumeroREA + office_id = False + office_ids = self.ProvinceByCode( + cr, uid, REA.Ufficio, context=context) + if not office_ids: + raise orm.except_orm( + _('Error !'), + _('REA Office Code ( %s ) not present in system') % + REA.Ufficio + ) + office_id = office_ids[0] + vals['rea_office'] = office_id + vals['rea_capital'] = REA.CapitaleSociale or 0.0 + vals['rea_member_type'] = REA.SocioUnico or False + vals['rea_liquidation_state'] = REA.StatoLiquidazione or False + + if cedPrest.Contatti: + vals['phone'] = cedPrest.Contatti.Telefono + vals['email'] = cedPrest.Contatti.Email + vals['fax'] = cedPrest.Contatti.Fax + partner_model.write(cr, uid, partner_id, vals, context=context) + return partner_id + + def getCarrirerPartner(self, cr, uid, Carrier, context=None): + partner_model = self.pool['res.partner'] + partner_id = self.getPartnerBase( + cr, uid, Carrier.DatiAnagraficiVettore, context=context) + vals = {} + if partner_id: + vals = { + 'license_number': + Carrier.DatiAnagraficiVettore.NumeroLicenzaGuida or '', + } + partner_model.write(cr, uid, partner_id, vals, context=context) + return partner_id + + def _prepareInvoiceLine( + self, cr, uid, credit_account_id, line, context=None + ): + account_tax_model = self.pool['account.tax'] + # check if a default tax exists and generate def_purchase_tax object + ir_values = self.pool.get('ir.values') + company_id = self.pool.get('res.company')._company_default_get( + cr, uid, 'account.invoice.line', context=context + ) + supplier_taxes_ids = ir_values.get_default( + cr, uid, 'product.product', 'supplier_taxes_id', + company_id=company_id + ) + def_purchase_tax = False + if supplier_taxes_ids: + def_purchase_tax = account_tax_model.browse( + cr, uid, supplier_taxes_ids, context=context)[0] + if float(line.AliquotaIVA) == 0.0 and line.Natura: + account_tax_ids = account_tax_model.search( + cr, uid, + [ + ('type_tax_use', 'in', ('purchase', 'all')), + ('non_taxable_nature', '=', line.Natura), + ('amount', '=', 0.0), + ], context=context) + if not account_tax_ids: + raise orm.except_orm( + _('Error!'), + _('No tax with percentage ' + '%s and nature %s found') + % (line.AliquotaIVA, line.Natura)) + if len(account_tax_ids) > 1: + raise orm.except_orm( + _('Error!'), + _('Too many taxes with percentage ' + '%s and nature %s found') + % (line.AliquotaIVA, line.Natura)) + else: + account_tax_ids = account_tax_model.search( + cr, uid, + [ + ('type_tax_use', 'in', ('purchase', 'all')), + ('amount', '=', float(line.AliquotaIVA) / 100), + ('price_include', '=', False), + # partially deductible VAT must be set by user + ('child_ids', '=', False), + ], context=context) + if not account_tax_ids: + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _( + 'XML contains tax with percentage "%s" ' + 'but it does not exist in your system' + ) % line.AliquotaIVA + ) + # check if there are multiple taxes with + # same percentage + if len(account_tax_ids) > 1: + # just logging because this is an usual case: see split payment + _logger.warning(_( + "Line '%s': Too many taxes with percentage equals " + "to \"%s\"\nfix it if required" + ) % (line.Descrizione, line.AliquotaIVA)) + # if there are multiple taxes with same percentage + # and there is a default tax with this percentage, + # set taxes list equal to supplier_taxes_id, loaded before + if ( + def_purchase_tax and + def_purchase_tax.amount == (float(line.AliquotaIVA) / 100) + ): + account_tax_ids = supplier_taxes_ids + retLine = { + 'name': line.Descrizione, + 'sequence': int(line.NumeroLinea), + 'account_id': credit_account_id, + } + if account_tax_ids: + retLine['invoice_line_tax_id'] = [(6, 0, [account_tax_ids[0]])] + if line.PrezzoUnitario: + retLine['price_unit'] = float(line.PrezzoUnitario) + if line.Quantita: + retLine['quantity'] = float(line.Quantita) + if line.TipoCessionePrestazione: + retLine['service_type'] = line.TipoCessionePrestazione + if line.TipoCessionePrestazione: + retLine['service_type'] = line.TipoCessionePrestazione + if line.UnitaMisura: + retLine['ftpa_uom'] = line.UnitaMisura + if line.DataInizioPeriodo: + retLine['service_start'] = line.DataInizioPeriodo + if line.DataFinePeriodo: + retLine['service_end'] = line.DataFinePeriodo + if ( + line.PrezzoTotale and line.PrezzoUnitario and line.Quantita and + line.ScontoMaggiorazione + ): + retLine['discount'] = self._computeDiscount( + cr, uid, line, context=context) + if line.RiferimentoAmministrazione: + retLine['admin_ref'] = line.RiferimentoAmministrazione + + return retLine + + def _prepareRelDocsLine( + self, cr, uid, invoice_id, line, type, context=None + ): + res = [] + lineref = line.RiferimentoNumeroLinea or False + IdDoc = line.IdDocumento or 'Error' + Data = line.Data or False + NumItem = line.NumItem or '' + Code = line.CodiceCommessaConvenzione or '' + Cig = line.CodiceCIG or '' + Cup = line.CodiceCUP or '' + invoice_lineid = False + if lineref: + for numline in lineref: + invoice_lineid = False + invoice_line_model = self.pool['account.invoice.line'] + invoice_line_ids = invoice_line_model.search( + cr, uid, + [ + ('invoice_id', '=', invoice_id), + ('sequence', '=', int(numline)), + ], context=context) + if invoice_line_ids: + invoice_lineid = invoice_line_ids[0] + val = { + 'type': type, + 'name': IdDoc, + 'lineRef': numline, + 'invoice_line_id': invoice_lineid, + 'invoice_id': invoice_id, + 'date': Data, + 'numitem': NumItem, + 'code': Code, + 'cig': Cig, + 'cup': Cup, + } + res.append(val) + else: + val = { + 'type': type, + 'name': IdDoc, + 'invoice_line_id': invoice_lineid, + 'invoice_id': invoice_id, + 'date': Data, + 'numitem': NumItem, + 'code': Code, + 'cig': Cig, + 'cup': Cup + } + res.append(val) + return res + + def _prepareWelfareLine( + self, cr, uid, invoice_id, line, context=None + ): + res = [] + TipoCassa = line.TipoCassa or False + AlCassa = line.AlCassa and (float(line.AlCassa)/100) or None + ImportoContributoCassa = ( + line.ImportoContributoCassa and + float(line.ImportoContributoCassa) or None) + ImponibileCassa = ( + line.ImponibileCassa and float(line.ImponibileCassa) or None) + AliquotaIVA = ( + line.AliquotaIVA and (float(line.AliquotaIVA)/100) or None) + Ritenuta = line.Ritenuta or '' + Natura = line.Natura or False + RiferimentoAmministrazione = line.RiferimentoAmministrazione or '' + WelfareTypeModel = self.pool['welfare.fund.type'] + if not TipoCassa: + raise orm.except_orm( + _('Error!'), + _('TipoCassa is not defined ') + ) + WelfareTypeId = WelfareTypeModel.search( + cr, uid, + [('name', '=', TipoCassa)], + context=context + ) + + res = { + 'welfare_rate_tax': AlCassa, + 'welfare_amount_tax': ImportoContributoCassa, + 'welfare_taxable': ImponibileCassa, + 'welfare_Iva_tax': AliquotaIVA, + 'subjected_withholding': Ritenuta, + 'fund_nature': Natura or False, + 'pa_line_code': RiferimentoAmministrazione, + 'invoice_id': invoice_id, + } + if not WelfareTypeId: + raise orm.except_orm( + _('Error'), + _('TipoCassa %s is not present in your system') % TipoCassa) + else: + res['name'] = WelfareTypeId[0] + + return res + + def _prepareDiscRisePriceLine( + self, cr, uid, id, line, context=None + ): + res = [] + Tipo = line.Tipo or False + Percentuale = line.Percentuale and float(line.Percentuale) or 0.0 + Importo = line.Importo and float(line.Importo) or 0.0 + res = { + 'percentage': Percentuale, + 'amount': Importo, + context.get('drtype'): id, + } + res['name'] = Tipo + + return res + + def _computeDiscount( + self, cr, uid, DettaglioLinea, context=None + ): + line_total = float(DettaglioLinea.PrezzoTotale) + line_unit = line_total / float(DettaglioLinea.Quantita) + discount = ( + 1 - (line_unit / float(DettaglioLinea.PrezzoUnitario)) + ) * 100.0 + return discount + + def _addGlobalDiscount( + self, cr, uid, invoice_id, DatiGeneraliDocumento, context=None + ): + discount = 0.0 + if DatiGeneraliDocumento.ScontoMaggiorazione: + invoice = self.pool['account.invoice'].browse( + cr, uid, invoice_id, context=context) + invoice.button_compute(context=context, set_total=True) + for DiscRise in DatiGeneraliDocumento.ScontoMaggiorazione: + if DiscRise.Percentuale: + amount = ( + invoice.amount_total * ( + float(DiscRise.Percentuale) / 100)) + if DiscRise.Tipo == 'SC': + discount -= amount + elif DiscRise.Tipo == 'MG': + discount += amount + elif DiscRise.Importo: + if DiscRise.Tipo == 'SC': + discount -= float(DiscRise.Importo) + elif DiscRise.Tipo == 'MG': + discount += float(DiscRise.Importo) + journal = self.get_purchase_journal( + cr, uid, invoice.company_id, context=context) + credit_account_id = journal.default_credit_account_id.id + line_vals = { + 'invoice_id': invoice_id, + 'name': _( + "Global invoice discount from DatiGeneraliDocumento"), + 'account_id': credit_account_id, + 'price_unit': discount, + 'quantity': 1, + } + self.pool['account.invoice.line'].create( + cr, uid, line_vals, context=context) + return True + + def _createPayamentsLine( + self, cr, uid, payment_id, line, partner_id, + context=None + ): + PaymentModel = self.pool['fatturapa.payment.detail'] + PaymentMethodModel = self.pool['fatturapa.payment_method'] + details = line.DettaglioPagamento or False + if details: + for dline in details: + BankModel = self.pool['res.bank'] + PartnerBankModel = self.pool['res.partner.bank'] + method_id = PaymentMethodModel.search( + cr, uid, + [('code', '=', dline.ModalitaPagamento)], + context=context + ) + if not method_id: + raise orm.except_orm( + _('Error!'), + _( + 'ModalitaPagamento %s not defined in your system' + % dline.ModalitaPagamento + ) + ) + val = { + 'recipient': dline.Beneficiario, + 'fatturapa_pm_id': method_id[0], + 'payment_term_start': + dline.DataRiferimentoTerminiPagamento or False, + 'payment_days': + dline.GiorniTerminiPagamento or 0, + 'payment_due_date': + dline.DataScadenzaPagamento or False, + 'payment_amount': + dline.ImportoPagamento or 0.0, + 'post_office_code': + dline.CodUfficioPostale or '', + 'recepit_surname': + dline.CognomeQuietanzante or '', + 'recepit_name': + dline.NomeQuietanzante or '', + 'recepit_cf': + dline.CFQuietanzante or '', + 'recepit_title': + dline.TitoloQuietanzante or '1', + 'payment_bank_name': + dline.IstitutoFinanziario or '', + 'payment_bank_iban': + dline.IBAN or '', + 'payment_bank_abi': + dline.ABI or '', + 'payment_bank_cab': + dline.CAB or '', + 'payment_bank_bic': + dline.BIC or '', + 'payment_bank': False, + 'prepayment_discount': + dline.ScontoPagamentoAnticipato or 0.0, + 'max_payment_date': + dline.DataLimitePagamentoAnticipato or False, + 'penalty_amount': + dline.PenalitaPagamentiRitardati or 0.0, + 'penalty_date': + dline.DataDecorrenzaPenale or False, + 'payment_code': + dline.CodicePagamento or '', + 'payment_data_id': payment_id + } + bankid = False + payment_bank_id = False + if dline.BIC: + bankids = BankModel.search( + cr, uid, + [('bic', '=', dline.BIC.strip())], context=context + ) + if not bankids: + if not dline.IstitutoFinanziario: + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _("Name of Bank with BIC \"%s\" is not set." + " Can't create bank") % dline.BIC + ) + else: + bankid = BankModel.create( + cr, uid, + { + 'name': dline.IstitutoFinanziario, + 'bic': dline.BIC, + }, + context=context + ) + else: + bankid = bankids[0] + if dline.IBAN: + SearchDom = [ + ('state', '=', 'iban'), + ( + 'acc_number', '=', + base_iban._pretty_iban(dline.IBAN.strip()) + ), + ('partner_id', '=', partner_id), + ] + payment_bank_id = False + payment_bank_ids = PartnerBankModel.search( + cr, uid, SearchDom, context=context) + if not payment_bank_ids and not bankid: + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _( + 'BIC is required and not exist in Xml\n' + 'Curr bank data is: \n' + 'IBAN: %s\n' + 'Bank Name: %s\n' + ) + % ( + dline.IBAN.strip() or '', + dline.IstitutoFinanziario or '' + ) + ) + + elif not payment_bank_ids and bankid: + payment_bank_id = PartnerBankModel.create( + cr, uid, + { + 'state': 'iban', + 'acc_number': dline.IBAN.strip(), + 'partner_id': partner_id, + 'bank': bankid, + 'bank_name': dline.IstitutoFinanziario, + 'bank_bic': dline.BIC + }, + context=context + ) + if payment_bank_ids: + payment_bank_id = payment_bank_ids[0] + + if payment_bank_id: + val['payment_bank'] = payment_bank_id + PaymentModel.create(cr, uid, val, context=context) + return True + + def get_purchase_journal(self, cr, uid, company, context=None): + journal_model = self.pool['account.journal'] + journal_ids = journal_model.search( + cr, uid, + [ + ('type', '=', 'purchase'), + ('company_id', '=', company.id) + ], + limit=1, context=context) + if not journal_ids: + raise orm.except_orm( + _('Error!'), + _( + 'Define a purchase journal ' + 'for this company: "%s" (id:%d).' + ) % (company.name, company.id) + ) + purchase_journal = journal_model.browse( + cr, uid, journal_ids[0], context=context) + return purchase_journal + + def invoiceCreate( + self, cr, uid, fatt, fatturapa_attachment, FatturaBody, + partner_id, context=None + ): + if context is None: + context = {} + partner_model = self.pool['res.partner'] + invoice_model = self.pool['account.invoice'] + currency_model = self.pool['res.currency'] + invoice_line_model = self.pool['account.invoice.line'] + ftpa_doctype_poll = self.pool['fatturapa.document_type'] + rel_docs_model = self.pool['fatturapa.related_document_type'] + WelfareFundLineModel = self.pool['welfare.fund.data.line'] + DiscRisePriceModel = self.pool['discount.rise.price'] + SalModel = self.pool['faturapa.activity.progress'] + DdTModel = self.pool['fatturapa.related_ddt'] + PaymentDataModel = self.pool['fatturapa.payment.data'] + PaymentTermsModel = self.pool['fatturapa.payment_term'] + SummaryDatasModel = self.pool['faturapa.summary.data'] + + company = self.pool['res.users'].browse( + cr, uid, uid, context=context).company_id + partner = partner_model.browse(cr, uid, partner_id, context=context) + pay_acc_id = partner.property_account_payable.id + # currency 2.1.1.2 + currency_id = currency_model.search( + cr, uid, + [ + ( + 'name', '=', + FatturaBody.DatiGenerali.DatiGeneraliDocumento.Divisa + ) + ], + context=context) + if not currency_id: + raise orm.except_orm( + _('Error!'), + _( + 'No currency found with code %s' + % FatturaBody.DatiGenerali.DatiGeneraliDocumento.Divisa + ) + ) + purchase_journal = self.get_purchase_journal( + cr, uid, company, context=context) + credit_account_id = purchase_journal.default_credit_account_id.id + invoice_lines = [] + comment = '' + # 2.1.1 + docType_id = False + invtype = 'in_invoice' + docType = FatturaBody.DatiGenerali.DatiGeneraliDocumento.TipoDocumento + if docType: + docType_ids = ftpa_doctype_poll.search( + cr, uid, + [ + ('code', '=', docType) + ], + context=context + ) + if docType_ids: + docType_id = docType_ids[0] + else: + raise orm.except_orm( + _("Error"), + _("tipoDocumento %s not handled") + % docType) + if docType == 'TD04' or docType == 'TD05': + invtype = 'in_refund' + # 2.1.1.11 + causLst = FatturaBody.DatiGenerali.DatiGeneraliDocumento.Causale + if causLst: + for item in causLst: + comment += item + '\n' + # 2.2.1 + CodeArts = self.pool['fatturapa.article.code'] + for line in FatturaBody.DatiBeniServizi.DettaglioLinee: + invoice_line_data = self._prepareInvoiceLine( + cr, uid, credit_account_id, line, context=context) + invoice_line_id = invoice_line_model.create( + cr, uid, invoice_line_data, context=context) + + if line.CodiceArticolo: + for caline in line.CodiceArticolo: + CodeArts.create( + cr, uid, + { + 'name': caline.CodiceTipo or '', + 'code_val': caline.CodiceValore or '', + 'invoice_line_id': invoice_line_id + }, + context=context + ) + if line.ScontoMaggiorazione: + context['drtype'] = 'invoice_line_id' + for DiscRisePriceLine in line.ScontoMaggiorazione: + DiscRisePriceVals = self._prepareDiscRisePriceLine( + cr, uid, invoice_line_id, DiscRisePriceLine, + context=context + ) + DiscRisePriceModel.create( + cr, uid, DiscRisePriceVals, context=context) + invoice_lines.append(invoice_line_id) + + invoice_data = { + 'doc_type': docType_id, + 'date_invoice': + FatturaBody.DatiGenerali.DatiGeneraliDocumento.Data, + 'supplier_invoice_number': + FatturaBody.DatiGenerali.DatiGeneraliDocumento.Numero, + 'sender': fatt.FatturaElettronicaHeader.SoggettoEmittente or False, + 'account_id': pay_acc_id, + 'type': invtype, + 'partner_id': partner_id, + 'currency_id': currency_id[0], + 'journal_id': purchase_journal.id, + 'invoice_line': [(6, 0, invoice_lines)], + # 'origin': xmlData.datiOrdineAcquisto, + 'fiscal_position': False, + 'payment_term': False, + 'company_id': company.id, + 'fatturapa_attachment_in_id': fatturapa_attachment.id, + 'comment': comment + } + # 2.1.1.5 + Withholding = FatturaBody.DatiGenerali.\ + DatiGeneraliDocumento.DatiRitenuta + if Withholding: + invoice_data['withholding_amount'] = Withholding.ImportoRitenuta + invoice_data['ftpa_withholding_type'] = Withholding.TipoRitenuta + invoice_data['ftpa_withholding_rate'] = float( + Withholding.AliquotaRitenuta)/100 + invoice_data['ftpa_withholding_payment_reason'] = Withholding.\ + CausalePagamento + # 2.1.1.6 + Stamps = FatturaBody.DatiGenerali.\ + DatiGeneraliDocumento.DatiBollo + if Stamps: + invoice_data['virtual_stamp'] = Stamps.BolloVirtuale + invoice_data['stamp_amount'] = float(Stamps.ImportoBollo) + invoice_id = invoice_model.create( + cr, uid, invoice_data, context=context) + + invoice = invoice_model.browse(cr, uid, invoice_id, context=context) + # 2.1.1.7 + Walfares = FatturaBody.DatiGenerali.\ + DatiGeneraliDocumento.DatiCassaPrevidenziale + if Walfares: + for walfareLine in Walfares: + WalferLineVals = self._prepareWelfareLine( + cr, uid, invoice_id, walfareLine, context=context) + WelfareFundLineModel.create( + cr, uid, WalferLineVals, context=context) + # 2.1.1.8 + DiscountRises = FatturaBody.DatiGenerali.\ + DatiGeneraliDocumento.ScontoMaggiorazione + if DiscountRises: + context['drtype'] = 'invoice_id' + for DiscRisePriceLine in DiscountRises: + DiscRisePriceVals = self._prepareDiscRisePriceLine( + cr, uid, invoice_id, DiscRisePriceLine, context=context) + DiscRisePriceModel.create( + cr, uid, DiscRisePriceVals, context=context) + # 2.1.2 + relOrders = FatturaBody.DatiGenerali.DatiOrdineAcquisto + if relOrders: + for order in relOrders: + doc_datas = self._prepareRelDocsLine( + cr, uid, invoice_id, order, 'order', context=context) + if doc_datas: + for doc_data in doc_datas: + rel_docs_model.create( + cr, uid, doc_data, context=context) + # 2.1.3 + relContracts = FatturaBody.DatiGenerali.DatiContratto + if relContracts: + for contract in relContracts: + doc_datas = self._prepareRelDocsLine( + cr, uid, invoice_id, contract, 'contract', context=context) + if doc_datas: + for doc_data in doc_datas: + rel_docs_model.create( + cr, uid, doc_data, context=context) + # 2.1.4 + relAgreements = FatturaBody.DatiGenerali.DatiConvenzione + if relAgreements: + for agreement in relAgreements: + doc_datas = self._prepareRelDocsLine( + cr, uid, invoice_id, agreement, + 'agreement', context=context) + if doc_datas: + for doc_data in doc_datas: + rel_docs_model.create( + cr, uid, doc_data, context=context) + # 2.1.5 + relReceptions = FatturaBody.DatiGenerali.DatiRicezione + if relReceptions: + for reception in relReceptions: + doc_datas = self._prepareRelDocsLine( + cr, uid, invoice_id, reception, + 'reception', context=context) + if doc_datas: + for doc_data in doc_datas: + rel_docs_model.create( + cr, uid, doc_data, context=context) + # 2.1.6 + RelInvoices = FatturaBody.DatiGenerali.DatiFattureCollegate + if RelInvoices: + for invoice in RelInvoices: + doc_datas = self._prepareRelDocsLine( + cr, uid, invoice_id, invoice, 'invoice', context=context) + if doc_datas: + for doc_data in doc_datas: + rel_docs_model.create( + cr, uid, doc_data, context=context) + # 2.1.7 + SalDatas = FatturaBody.DatiGenerali.DatiSAL + if SalDatas: + for SalDataLine in SalDatas: + SalModel.create( + cr, uid, + { + 'fatturapa_activity_progress': ( + SalDataLine.RiferimentoFase or 0), + 'invoice_id': invoice_id + }, context=context + ) + # 2.1.8 + DdtDatas = FatturaBody.DatiGenerali.DatiDDT + if DdtDatas: + for DdtDataLine in DdtDatas: + if not DdtDataLine.RiferimentoNumeroLinea: + DdTModel.create( + cr, uid, + { + 'name': DdtDataLine.NumeroDDT or '', + 'date': DdtDataLine.DataDDT or False, + 'invoice_id': invoice_id + }, context=context + ) + else: + for numline in DdtDataLine.RiferimentoNumeroLinea: + invoice_line_ids = invoice_line_model.search( + cr, uid, + [ + ('invoice_id', '=', invoice_id), + ('sequence', '=', int(numline)), + ], context=context) + invoice_lineid = False + if invoice_line_ids: + invoice_lineid = invoice_line_ids[0] + DdTModel.create( + cr, uid, + { + 'name': DdtDataLine.NumeroDDT or '', + 'date': DdtDataLine.DataDDT or False, + 'invoice_id': invoice_id, + 'invoice_line_id': invoice_lineid + }, context=context + ) + # 2.1.9 + Delivery = FatturaBody.DatiGenerali.DatiTrasporto + if Delivery: + delivery_id = self.getCarrirerPartner( + cr, uid, Delivery, context=context) + delivery_dict = { + 'carrier_id': delivery_id, + 'transport_vehicle': Delivery.MezzoTrasporto or '', + 'transport_reason': Delivery.CausaleTrasporto or '', + 'number_items': Delivery.NumeroColli or 0, + 'description': Delivery.Descrizione or '', + 'unit_weight': Delivery.UnitaMisuraPeso or 0.0, + 'gross_weight': Delivery.PesoLordo or 0.0, + 'net_weight': Delivery.PesoNetto or 0.0, + 'pickup_datetime': Delivery.DataOraRitiro or False, + 'transport_date': Delivery.DataInizioTrasporto or False, + 'delivery_datetime': Delivery.DataOraConsegna or False, + 'delivery_address': '', + } + + if Delivery.IndirizzoResa: + delivery_dict['delivery_address'] = ( + '{0}, {1}\n{2} - {3}\n{4} {5}'.format( + Delivery.IndirizzoResa.Indirizzo or '', + Delivery.IndirizzoResa.NumeroCivico or '', + Delivery.IndirizzoResa.CAP or '', + Delivery.IndirizzoResa.Comune or '', + Delivery.IndirizzoResa.Provincia or '', + Delivery.IndirizzoResa.Nazione or '' + ) + ) + if Delivery.TipoResa: + StockModel = self.pool['stock.incoterms'] + stock_incoterm_id = StockModel.search( + cr, uid, [('code', '=', Delivery.TipoResa)], + context=context + ) + if stock_incoterm_id: + delivery_dict['incoterm'] = stock_incoterm_id[0] + invoice_model.write( + cr, uid, invoice_id, delivery_dict, context=context) + # 2.2.2 + Summary_datas = FatturaBody.DatiBeniServizi.DatiRiepilogo + if Summary_datas: + for summary in Summary_datas: + summary_line = { + 'tax_rate': summary.AliquotaIVA or 0.0, + 'non_taxable_nature': summary.Natura or False, + 'incidental charges': summary.SpeseAccessorie or 0.0, + 'rounding': summary.Arrotondamento or 0.0, + 'amount_untaxed': summary.ImponibileImporto or 0.0, + 'amount_tax': summary.Imposta or 0.0, + 'payability': summary.EsigibilitaIVA or False, + 'law_reference': summary.RiferimentoNormativo or '', + 'invoice_id': invoice_id, + } + SummaryDatasModel.create( + cr, uid, summary_line, context=context) + + # 2.1.10 + ParentInvoice = FatturaBody.DatiGenerali.FatturaPrincipale + if ParentInvoice: + parentinv_vals = { + 'related_invoice_code': + ParentInvoice.NumeroFatturaPrincipale or '', + 'related_invoice_date': + ParentInvoice.DataFatturaPrincipale or False + } + invoice_model.write( + cr, uid, invoice_id, parentinv_vals, context=context) + # 2.3 + Vehicle = FatturaBody.DatiVeicoli + if Vehicle: + veicle_vals = { + 'vehicle_registration': Vehicle.Data or False, + 'total_travel': Vehicle.TotalePercorso or '', + } + invoice_model.write( + cr, uid, invoice_id, veicle_vals, context=context) + # 2.4 + PaymentsData = FatturaBody.DatiPagamento + if PaymentsData: + for PaymentLine in PaymentsData: + cond = PaymentLine.CondizioniPagamento or False + if not cond: + raise orm.except_orm( + _('Error!'), + _('Payment method Code not found in document') + ) + term_id = False + term_ids = PaymentTermsModel.search( + cr, uid, [('code', '=', cond)], context=context) + if not term_ids: + raise orm.except_orm( + _('Error!'), + _('Payment method Code %s is incorrect') % cond + ) + else: + term_id = term_ids[0] + PayDataId = PaymentDataModel.create( + cr, uid, + { + 'payment_terms': term_id, + 'invoice_id': invoice_id + }, + context=context + ) + self._createPayamentsLine( + cr, uid, PayDataId, PaymentLine, partner_id, + context=context + ) + # 2.5 + AttachmentsData = FatturaBody.Allegati + if AttachmentsData: + AttachModel = self.pool['fatturapa.attachments'] + for attach in AttachmentsData: + if not attach.NomeAttachment: + raise orm.except_orm( + _('Error!'), + _('Attachment Name is Required') + ) + content = attach.Attachment + name = attach.NomeAttachment + _attach_dict = { + 'name': name, + 'datas': base64.b64encode(str(content)), + 'datas_fname': name, + 'description': attach.DescrizioneAttachment or '', + 'compression': attach.AlgoritmoCompressione or '', + 'format': attach.FormatoAttachment or '', + 'invoice_id': invoice_id, + } + AttachModel.create( + cr, uid, _attach_dict, context=context) + + self._addGlobalDiscount( + cr, uid, invoice_id, + FatturaBody.DatiGenerali.DatiGeneraliDocumento, context=context) + + # compute the invoice + invoice_model.button_compute( + cr, uid, [invoice_id], context=context, + set_total=True) + return invoice_id + + def check_CessionarioCommittente( + self, cr, uid, company, FatturaElettronicaHeader, context=None + ): + if ( + company.partner_id.ipa_code != + FatturaElettronicaHeader.DatiTrasmissione.CodiceDestinatario + ): + raise orm.except_orm( + _('Error'), + _('XML IPA code (%s) different from company IPA code (%s)') + % ( + FatturaElettronicaHeader.DatiTrasmissione. + CodiceDestinatario, company.partner_id.ipa_code)) + + def compute_xml_amount_untaxed(self, cr, uid, DatiRiepilogo, context=None): + amount_untaxed = 0.0 + for Riepilogo in DatiRiepilogo: + amount_untaxed += float(Riepilogo.ImponibileImporto) + return amount_untaxed + + def check_invoice_amount( + self, cr, uid, invoice, FatturaElettronicaBody, context=None + ): + if context is None: + context = {} + + invoice.write( + { + 'check_total': FatturaElettronicaBody.DatiGenerali. + DatiGeneraliDocumento.ImportoTotaleDocumento + }, context=context) + if ( + FatturaElettronicaBody.DatiGenerali.DatiGeneraliDocumento. + ScontoMaggiorazione and + FatturaElettronicaBody.DatiGenerali.DatiGeneraliDocumento. + ImportoTotaleDocumento + ): + # assuming that, if someone uses + # DatiGeneraliDocumento.ScontoMaggiorazione, also fills + # DatiGeneraliDocumento.ImportoTotaleDocumento + ImportoTotaleDocumento = float( + FatturaElettronicaBody.DatiGenerali.DatiGeneraliDocumento. + ImportoTotaleDocumento) + if invoice.amount_total != ImportoTotaleDocumento: + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _('Invoice total %s is different from ' + 'ImportoTotaleDocumento %s') + % (invoice.amount_total, ImportoTotaleDocumento) + ) + else: + # else, we can only check DatiRiepilogo if + # DatiGeneraliDocumento.ScontoMaggiorazione is not present, + # because otherwise DatiRiepilogo and openerp invoice total would + # differ + amount_untaxed = self.compute_xml_amount_untaxed( + cr, uid, + FatturaElettronicaBody.DatiBeniServizi.DatiRiepilogo, + context=context) + if invoice.amount_untaxed != amount_untaxed: + if context.get('inconsistencies'): + context['inconsistencies'] += '\n' + context['inconsistencies'] += ( + _('Computed amount untaxed %s is different from' + ' DatiRiepilogo %s') + % (invoice.amount_untaxed, amount_untaxed) + ) + + def strip_xml_content(self, xml): + root = etree.XML(xml) + for elem in root.iter('*'): + if elem.text is not None: + elem.text = elem.text.strip() + return etree.tostring(root) + + def remove_xades_sign(self, xml): + root = etree.XML(xml) + for elem in root.iter('*'): + if elem.tag.find('Signature') > -1: + elem.getparent().remove(elem) + break + return etree.tostring(root) + + def check_file_is_pem(self, p7m_file): + file_is_pem = True + strcmd = ( + 'openssl asn1parse -inform PEM -in %s' + ) % (p7m_file) + cmd = shlex.split(strcmd) + try: + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + stdoutdata, stderrdata = proc.communicate() + if proc.wait() != 0: + file_is_pem = False + except Exception as e: + raise orm.except_orm( + _('Errore'), + _( + 'Check PEM file %s' + ) % e.args + ) + return file_is_pem + + def parse_pem_2_der(self, pem_file, tmp_der_file): + strcmd = ( + 'openssl asn1parse -in %s -out %s' + ) % (pem_file, tmp_der_file) + cmd = shlex.split(strcmd) + try: + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + stdoutdata, stderrdata = proc.communicate() + if proc.wait() != 0: + _logger.warning(stdoutdata) + raise Exception(stderrdata) + except Exception as e: + raise orm.except_orm( + _('Errore'), + _( + 'Parsing PEM to DER file %s' + ) % e.args + ) + if not os.path.isfile(tmp_der_file): + raise orm.except_orm( + _('Errore'), + _( + 'ASN.1 structure is not parsable in DER' + ) + ) + return tmp_der_file + + def decrypt_to_xml(self, signed_file, xml_file): + strcmd = ( + 'openssl smime -decrypt -verify -inform' + ' DER -in %s -noverify -out %s' + ) % (signed_file, xml_file) + cmd = shlex.split(strcmd) + try: + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + stdoutdata, stderrdata = proc.communicate() + if proc.wait() != 0: + _logger.warning(stdoutdata) + raise Exception(stderrdata) + except Exception as e: + raise orm.except_orm( + _('Errore'), + _( + 'Signed Xml file %s' + ) % e.args + ) + if not os.path.isfile(xml_file): + raise orm.except_orm( + _('Errore'), + _( + 'Signed Xml file not decryptable' + ) + ) + return xml_file + + def importFatturaPA(self, cr, uid, ids, context=None): + if not context: + context = {} + context['inconsistencies'] = '' + fatturapa_attachment_obj = self.pool['fatturapa.attachment.in'] + fatturapa_attachment_ids = context.get('active_ids', False) + invoice_model = self.pool['account.invoice'] + new_invoices = [] + for fatturapa_attachment_id in fatturapa_attachment_ids: + ctx = context.copy() + fatturapa_attachment = fatturapa_attachment_obj.browse( + cr, uid, fatturapa_attachment_id, context=ctx) + if fatturapa_attachment.in_invoice_ids: + raise orm.except_orm( + _("Error"), _("File is linked to invoices yet")) + # decrypt p7m file + if fatturapa_attachment.datas_fname.lower().endswith('.p7m'): + temp_file_name = ( + '/tmp/%s' % fatturapa_attachment.datas_fname.lower()) + temp_der_file_name = ( + '/tmp/%s_tmp' % fatturapa_attachment.datas_fname.lower()) + with open(temp_file_name, 'w') as p7m_file: + p7m_file.write(fatturapa_attachment.datas.decode('base64')) + xml_file_name = os.path.splitext(temp_file_name)[0] + + # check if temp_file_name is a PEM file + file_is_pem = self.check_file_is_pem(temp_file_name) + + # if temp_file_name is a PEM file + # parse it in a DER file + if file_is_pem: + temp_file_name = self.parse_pem_2_der( + temp_file_name, temp_der_file_name) + + # decrypt signed DER file in XML readable + xml_file_name = self.decrypt_to_xml( + temp_file_name, xml_file_name) + + with open(xml_file_name, 'r') as fatt_file: + file_content = fatt_file.read() + xml_string = file_content + elif fatturapa_attachment.datas_fname.lower().endswith('.xml'): + xml_string = fatturapa_attachment.datas.decode('base64') + xml_string = self.remove_xades_sign(xml_string) + xml_string = self.strip_xml_content(xml_string) + fatt = fatturapa_v_1_1.CreateFromDocument(xml_string) + cedentePrestatore = fatt.FatturaElettronicaHeader.CedentePrestatore + # 1.2 + partner_id = self.getCedPrest( + cr, uid, cedentePrestatore, context=ctx) + # 1.3 + TaxRappresentative = fatt.FatturaElettronicaHeader.\ + RappresentanteFiscale + # 1.5 + Intermediary = fatt.FatturaElettronicaHeader.\ + TerzoIntermediarioOSoggettoEmittente + # 2 + for fattura in fatt.FatturaElettronicaBody: + invoice_id = self.invoiceCreate( + cr, uid, fatt, fatturapa_attachment, fattura, + partner_id, context=ctx) + if TaxRappresentative: + tax_partner_id = self.getPartnerBase( + cr, uid, TaxRappresentative.DatiAnagrafici, + context=ctx) + invoice_model.write( + cr, uid, invoice_id, + { + 'tax_representative_id': tax_partner_id + }, context=ctx + ) + if Intermediary: + Intermediary_id = self.getPartnerBase( + cr, uid, Intermediary.DatiAnagrafici, context=ctx) + invoice_model.write( + cr, uid, invoice_id, + { + 'intermediary': Intermediary_id + }, context=ctx + ) + new_invoices.append(invoice_id) + invoice = invoice_model.browse(cr, uid, invoice_id, ctx) + self.check_CessionarioCommittente( + cr, uid, invoice.company_id, fatt.FatturaElettronicaHeader, + context=ctx) + self.check_invoice_amount( + cr, uid, invoice, + fattura, + context=ctx) + + if ctx.get('inconsistencies'): + invoice.write( + {'inconsistencies': ctx['inconsistencies']}, + context=ctx) + + return { + 'view_type': 'form', + 'name': "PA Supplier Invoices", + 'view_mode': 'tree,form', + 'res_model': 'account.invoice', + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', new_invoices)], + 'context': context + } diff --git a/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa_view.xml b/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa_view.xml new file mode 100644 index 000000000000..ad207b533b44 --- /dev/null +++ b/l10n_it_fatturapa_in/wizard/wizard_import_fatturapa_view.xml @@ -0,0 +1,34 @@ + + + + + + Import FatturaPA + wizard.import.fatturapa + +
+ + + + + +