Skip to content

Commit

Permalink
Merge f24a731 into 571966d
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenzoterzulli committed Dec 2, 2019
2 parents 571966d + f24a731 commit 62e1b87
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 91 deletions.
1 change: 1 addition & 0 deletions l10n_it_account/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from . import models

import logging
import tools
from openerp import SUPERUSER_ID


Expand Down
1 change: 1 addition & 0 deletions l10n_it_account/tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import account_tools
9 changes: 9 additions & 0 deletions l10n_it_account/tools/account_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import re

# compiled reg expression for whitespace characters substitution
reg_whitespace = re.compile(r'\s+')


def encode_for_export(string_to_encode, max_chars, encoding='latin'):
return reg_whitespace.sub(' ', string_to_encode).encode(
encoding, errors='replace').decode(encoding)[:max_chars]
1 change: 1 addition & 0 deletions l10n_it_fatturapa_out/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
'l10n_it_fatturapa_out',
'license': 'LGPL-3',
"depends": [
'l10n_it_account',
'l10n_it_fatturapa',
'l10n_it_split_payment',
],
Expand Down
112 changes: 112 additions & 0 deletions l10n_it_fatturapa_out/tests/data/IT06363391001_00011.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<ns1:FatturaElettronica xmlns:ns1="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" versione="FPR12">
<FatturaElettronicaHeader>
<DatiTrasmissione>
<IdTrasmittente>
<IdPaese>IT</IdPaese>
<IdCodice>06363391001</IdCodice>
</IdTrasmittente>
<ProgressivoInvio>00011</ProgressivoInvio>
<FormatoTrasmissione>FPR12</FormatoTrasmissione>
<CodiceDestinatario>XXXXXXX</CodiceDestinatario>
<ContattiTrasmittente>
<Telefono>06543534343</Telefono>
<Email>info@yourcompany.example.com</Email>
</ContattiTrasmittente>
</DatiTrasmissione>
<CedentePrestatore>
<DatiAnagrafici>
<IdFiscaleIVA>
<IdPaese>IT</IdPaese>
<IdCodice>06363391001</IdCodice>
</IdFiscaleIVA>
<Anagrafica>
<Denominazione>YourCompany</Denominazione>
</Anagrafica>
<RegimeFiscale>RF01</RegimeFiscale>
</DatiAnagrafici>
<Sede>
<Indirizzo>Via Milano, 1</Indirizzo>
<CAP>00100</CAP>
<Comune>Roma</Comune>
<Provincia>AK</Provincia>
<Nazione>IT</Nazione>
</Sede>
<Contatti>
<Telefono>06543534343</Telefono>
<Email>info@yourcompany.example.com</Email>
</Contatti>
</CedentePrestatore>
<CessionarioCommittente>
<DatiAnagrafici>
<IdFiscaleIVA>
<IdPaese>SI</IdPaese>
<IdCodice>12345679</IdCodice>
</IdFiscaleIVA>
<Anagrafica>
<Denominazione>REMODELA&#199;&#195;O DECORA&#199;&#195;O ?ALEC LDA?</Denominazione>
</Anagrafica>
</DatiAnagrafici>
<Sede>
<Indirizzo>M?aja ?tra&#199;&#195; 14</Indirizzo>
<CAP>00000</CAP>
<Comune>?of?a</Comune>
<Provincia>EE</Provincia>
<Nazione>SI</Nazione>
</Sede>
</CessionarioCommittente>
</FatturaElettronicaHeader>
<FatturaElettronicaBody>
<DatiGenerali>
<DatiGeneraliDocumento>
<TipoDocumento>TD01</TipoDocumento>
<Divisa>EUR</Divisa>
<Data>2018-01-07</Data>
<Numero>INV/2018/0021</Numero>
<ImportoTotaleDocumento>17.08</ImportoTotaleDocumento>
<Art73>SI</Art73>
</DatiGeneraliDocumento>
</DatiGenerali>
<DatiBeniServizi>
<DettaglioLinee>
<NumeroLinea>1</NumeroLinea>
<CodiceArticolo>
<CodiceTipo>ODOO</CodiceTipo>
<CodiceValore>GH82?23??D11</CodiceValore>
</CodiceArticolo>
<Descrizione>Mouse Optical &#216;23 &#223;11</Descrizione>
<Quantita>1.000</Quantita>
<UnitaMisura>Unit(s)</UnitaMisura>
<PrezzoUnitario>10.00000</PrezzoUnitario>
<PrezzoTotale>10.00</PrezzoTotale>
<AliquotaIVA>22.00</AliquotaIVA>
</DettaglioLinee>
<DettaglioLinee>
<NumeroLinea>2</NumeroLinea>
<CodiceArticolo>
<CodiceTipo>ODOO</CodiceTipo>
<CodiceValore>GZD11</CodiceValore>
</CodiceArticolo>
<Descrizione>Zed+^ Antiv&#176; (&#163;)</Descrizione>
<Quantita>1.000</Quantita>
<UnitaMisura>Unit(s)</UnitaMisura>
<PrezzoUnitario>4.00000</PrezzoUnitario>
<PrezzoTotale>4.00</PrezzoTotale>
<AliquotaIVA>22.00</AliquotaIVA>
</DettaglioLinee>
<DatiRiepilogo>
<AliquotaIVA>22.00</AliquotaIVA>
<ImponibileImporto>14.00</ImponibileImporto>
<Imposta>3.08</Imposta>
</DatiRiepilogo>
</DatiBeniServizi>
<DatiPagamento>
<CondizioniPagamento>TP02</CondizioniPagamento>
<DettaglioPagamento>
<ModalitaPagamento>MP05</ModalitaPagamento>
<DataScadenzaPagamento>2018-02-28</DataScadenzaPagamento>
<ImportoPagamento>17.08</ImportoPagamento>
</DettaglioPagamento>
</DatiPagamento>
</FatturaElettronicaBody>
</ns1:FatturaElettronica>
54 changes: 54 additions & 0 deletions l10n_it_fatturapa_out/tests/test_fatturapa_xml_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,57 @@ def test_9_xml_export(self):

xml_content = attachment.datas.decode('base64')
self.check_content(xml_content, 'IT06363391001_00009.xml')

def test_11_xml_export(self):
self.set_sequences(11, 21, '2018')
self.product_product_10.default_code = 'GH82Ø23€ŦD11'
self.product_order_01.default_code = 'GZD11'
partner = self.res_partner_fatturapa_2
partner.name = 'REMODELAÇÃO DECORAÇÃO ŽALEC LDAŠ'
partner.street = 'Mžaja ŠtraÇÃ 14'
partner.zip = 'ES-49714'
partner.city = 'Šofıa'
partner.country_id = self.env.ref('base.si').id
partner.vat = 'SI12345679'
partner.fiscalcode = False
partner.onchange_country_id_e_inv()
partner.write(partner._convert_to_write(partner._cache))
self.assertEqual(partner.codice_destinatario, 'XXXXXXX')
invoice = self.invoice_model.create({
'date_invoice': '2018-01-07',
'partner_id': self.res_partner_fatturapa_2.id,
'journal_id': self.sales_journal.id,
'account_id': self.a_recv.id,
'payment_term': self.account_payment_term.id,
'user_id': self.user_demo.id,
'type': 'out_invoice',
'currency_id': self.EUR.id,
'invoice_line': [
(0, 0, {
'account_id': self.a_sale.id,
'product_id': self.product_product_10.id,
'name': 'Mouse Optical Ø23 ß11',
'quantity': 1,
'uos_id': self.product_uom_unit.id,
'price_unit': 10,
'invoice_line_tax_id': [(6, 0, {
self.tax_22.id})]
}),
(0, 0, {
'account_id': self.a_sale.id,
'product_id': self.product_order_01.id,
'name': 'Zed+^ Antiv° (£)',
'quantity': 1,
'uos_id': self.product_uom_unit.id,
'price_unit': 4,
'invoice_line_tax_id': [(6, 0, {
self.tax_22.id})]
})],
})
invoice.signal_workflow('invoice_open')
res = self.run_wizard(invoice.id)
attachment = self.attach_model.browse(res['res_id'])
self.assertEqual(attachment.datas_fname, 'IT06363391001_00011.xml')

xml_content = attachment.datas.decode('base64')
self.check_content(xml_content, 'IT06363391001_00011.xml')
56 changes: 29 additions & 27 deletions l10n_it_fatturapa_out/wizard/wizard_export_fatturapa.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import logging
import os


import openerp
from openerp import fields, models, api, _
from openerp.exceptions import Warning as UserError
from openerp.addons.l10n_it_account.tools.account_tools import encode_for_export
from openerp.tools.safe_eval import safe_eval
import time

Expand Down Expand Up @@ -247,9 +249,9 @@ def _setSedeCedente(self, CedentePrestatore, company):
# TODO: manage address number in <NumeroCivico>
# see https://github.com/OCA/partner-contact/pull/96
CedentePrestatore.Sede = IndirizzoType(
Indirizzo=company.street,
Indirizzo=encode_for_export(company.street, 60),
CAP=company.zip,
Comune=company.city,
Comune=encode_for_export(company.city, 60),
Nazione=company.country_id.code)
if company.partner_id.state_id:
CedentePrestatore.Sede.Provincia = company.partner_id.state_id.code
Expand Down Expand Up @@ -364,15 +366,15 @@ def _setDatiAnagraficiCessionario(self, partner, fatturapa):
if partner.is_company:
fatturapa.FatturaElettronicaHeader.CessionarioCommittente. \
DatiAnagrafici.Anagrafica = AnagraficaType(
Denominazione=partner.name)
Denominazione=encode_for_export(partner.name, 80))
else:
if not partner.lastname or not partner.firstname:
raise UserError(
_("Partner %s deve avere nome e cognome") % partner.name)
fatturapa.FatturaElettronicaHeader.CessionarioCommittente. \
DatiAnagrafici.Anagrafica = AnagraficaType(
Cognome=partner.lastname,
Nome=partner.firstname)
Cognome=encode_for_export(partner.lastname, 60),
Nome=encode_for_export(partner.firstname, 60))

if partner.eori_code:
fatturapa.FatturaElettronicaHeader.CessionarioCommittente. \
Expand All @@ -397,7 +399,7 @@ def _setDatiAnagraficiRappresentanteFiscale(self, partner, fatturapa):
IdPaese=partner.vat[0:2], IdCodice=partner.vat[2:])
fatturapa.FatturaElettronicaHeader.RappresentanteFiscale. \
DatiAnagrafici.Anagrafica = AnagraficaType(
Denominazione=partner.name)
Denominazione=encode_for_export(partner.name, 80))
if partner.eori_code:
fatturapa.FatturaElettronicaHeader.RappresentanteFiscale. \
DatiAnagrafici.Anagrafica.CodEORI = partner.eori_code
Expand All @@ -413,7 +415,7 @@ def _setTerzoIntermediarioOSoggettoEmittente(self, partner, fatturapa):
DatiAnagrafici = DatiAnagraficiTerzoIntermediarioType()
if not partner.vat and not partner.fiscalcode:
raise UserError(
_('Partner VAT and Fiscalcode not set.'))
_('Partner VAT and Fiscalcode not set for %s.' % partner.name))
if partner.fiscalcode:
fatturapa.FatturaElettronicaHeader. \
TerzoIntermediarioOSoggettoEmittente. \
Expand All @@ -439,32 +441,32 @@ def _setSedeCessionario(self, partner, fatturapa):

if not partner.street:
raise UserError(
_('Customer street not set.'))
_('Customer street not set for %s.' % partner.name))
if not partner.city:
raise UserError(
_('Customer city not set.'))
_('Customer city not set for %s.' % partner.name))
if not partner.country_id:
raise UserError(
_('Customer country not set.'))
_('Customer country not set for %s.' % partner.name))

# TODO: manage address number in <NumeroCivico>
if partner.codice_destinatario == 'XXXXXXX':
fatturapa.FatturaElettronicaHeader.CessionarioCommittente.Sede = (
IndirizzoType(
Indirizzo=partner.street,
Indirizzo=encode_for_export(partner.street, 60),
CAP='00000',
Comune=partner.city,
Comune=encode_for_export(partner.city, 60),
Provincia='EE',
Nazione=partner.country_id.code))
else:
if not partner.zip:
raise UserError(
_('Customer ZIP not set.'))
_('Customer ZIP not set for %s.' % partner.name))
fatturapa.FatturaElettronicaHeader.CessionarioCommittente.Sede = (
IndirizzoType(
Indirizzo=partner.street,
Indirizzo=encode_for_export(partner.street, 60),
CAP=partner.zip,
Comune=partner.city,
Comune=encode_for_export(partner.city, 60),
Nazione=partner.country_id.code))
if partner.state_id:
fatturapa.FatturaElettronicaHeader.CessionarioCommittente.\
Expand Down Expand Up @@ -498,7 +500,7 @@ def setDatiGeneraliDocumento(self, invoice, body):
body.DatiGenerali = DatiGeneraliType()
if not invoice.number:
raise UserError(
_('Invoice does not have a number.'))
_('Invoice %s does not have a number.' % invoice.display_name))

TipoDocumento = invoice.fiscal_document_type_id.code
if not TipoDocumento:
Expand Down Expand Up @@ -529,8 +531,7 @@ def setDatiGeneraliDocumento(self, invoice, body):
for causale200 in causale_list_200:
# Remove non latin chars, but go back to unicode string,
# as expected by String200LatinType
causale = causale200.encode(
'latin', 'ignore').decode('latin')
causale = encode_for_export(causale200, 200)
body.DatiGenerali.DatiGeneraliDocumento.Causale\
.append(causale)

Expand Down Expand Up @@ -632,8 +633,7 @@ def setDettaglioLinea(
# see https://tinyurl.com/ycem923t
# and '&#10;' would not be correctly visualized anyway
# (for example firefox replaces '&#10;' with space
Descrizione=line.name.replace('\n', ' ').encode(
'latin', 'ignore').decode('latin'),
Descrizione=encode_for_export(line.name.replace('\n', ' '), 1000),
PrezzoUnitario=('%.' + str(
price_precision
) + 'f') % prezzo_unitario,
Expand Down Expand Up @@ -665,14 +665,15 @@ def setDettaglioLinea(
CodiceArticolo = CodiceArticoloType(
CodiceTipo=self.env['ir.config_parameter'].sudo(
).get_param('fatturapa.codicetipo.odoo', 'ODOO'),
CodiceValore=line.product_id.default_code.encode(
'latin', 'ignore').decode('latin')
CodiceValore=encode_for_export(
line.product_id.default_code, 35, 'ascii')
)
DettaglioLinea.CodiceArticolo.append(CodiceArticolo)
if line.product_id.ean13:
CodiceArticolo = CodiceArticoloType(
CodiceTipo='EAN',
CodiceValore=line.product_id.ean13
CodiceValore=encode_for_export(
line.product_id.ean13, 35, 'ascii')
)
DettaglioLinea.CodiceArticolo.append(CodiceArticolo)

Expand Down Expand Up @@ -700,8 +701,8 @@ def setDatiRiepilogo(self, invoice, body):
if not tax.law_reference:
raise UserError(
_("No 'law reference' field for tax %s") % tax.name)
riepilogo.RiferimentoNormativo = tax.law_reference.encode(
'latin', 'ignore').decode('latin')
riepilogo.RiferimentoNormativo = encode_for_export(
tax.law_reference, 100)
if tax.payability:
riepilogo.EsigibilitaIVA = tax.payability
# TODO
Expand Down Expand Up @@ -763,7 +764,7 @@ def setAttachments(self, invoice, body):
doc_id.datas_fname) <= 60 else ''.join([
file_name[:(60-len(file_extension))], file_extension])
AttachDoc = AllegatiType(
NomeAttachment=attachment_name,
NomeAttachment=encode_for_export(attachment_name, 60),
Attachment=base64.decodestring(doc_id.datas)
)
body.Allegati.append(AttachDoc)
Expand Down Expand Up @@ -801,7 +802,8 @@ def getPartnerId(self, invoice_ids):
partner = invoice.partner_id
if invoice.partner_id != partner:
raise UserError(
_('Invoices must belong to the same partner'))
_('Invoices %s must belong to the same partner') %
invoices.mapped('number'))

return partner

Expand Down
1 change: 1 addition & 0 deletions l10n_it_invoices_data_communication/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'depends': [
'account',
'account_invoice_entry_date',
'l10n_it_account',
'l10n_it_account_tax_kind',
'l10n_it_codici_carica',
'l10n_it_esigibilita_iva',
Expand Down
Loading

0 comments on commit 62e1b87

Please sign in to comment.