l10n_it_invoices_data_communication/models/communication.py
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
from openerp.exceptions import ValidationError
from openerp.osv import expression
from openerp.addons.l10n_it_account.tools.account_tools import encode_for_export
from lxml import etree
import re
NS_2 = 'http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v2.0'
VERSION = 'DAT20'
NS_MAP = {
'ns2': NS_2,
}
etree.register_namespace("vi", NS_2)
def format_decimal(value=0.0):
return "{:.2f}".format(value)
def clear_xml_element(element):
if element.text:
return False
return all((clear_xml_element(e) for e in element.iterchildren()))
def clear_xml(xml_root):
xml_root = etree.iterwalk(xml_root)
for dummy, xml_element in xml_root:
parent = xml_element.getparent()
if clear_xml_element(xml_element):
parent.remove(xml_element)
def check_normalized_string(value):
normalized = True
if not value:
return normalized
if value != value.strip():
normalized = False
return normalized
def _get_invoice_date_domain(date_start, date_end):
reg_date_domain = [
'&',
('registration_date', '>=', date_start),
('registration_date', '<=', date_end),
]
date_inv_domain = [
'&',
('move_id.date', '>=', date_start),
('move_id.date', '<=', date_end),
]
return expression.OR([reg_date_domain, date_inv_domain])
class ComunicazioneDatiIva(models.Model):
_name = 'comunicazione.dati.iva'
_description = 'Invoices data communication'
_rec_name = 'identificativo'
@api.model
def _default_company(self):
company_id = self._context.get(
'company_id', self.env.user.company_id.id)
return company_id
@api.constrains('identificativo')
def _check_identificativo(self):
domain = [('identificativo', '=', self.identificativo)]
dichiarazioni = self.search(domain)
if len(dichiarazioni) > 1:
raise ValidationError(
_("Statement already exists with ID {}"
).format(self.identificativo))
def _get_identificativo(self):
dichiarazioni = self.search([])
if dichiarazioni:
return len(dichiarazioni) + 1
else:
return 1
company_id = fields.Many2one(
'res.company', string='Company', required=True,
default=_default_company)
identificativo = fields.Integer(string='Identifier', copy=False,
default=_get_identificativo)
id_comunicazione = fields.Char(
string='Communication ID',
help='Identifier provided by the Revenue Agency after performing the '
'communication by XML file')
splitting_note = fields.Text("Splitting note", readonly=True, copy=False)
declarant_fiscalcode = fields.Char(
string='Declarant fiscal code',
help="Fiscal code of the person communicating the invoices data")
codice_carica_id = fields.Many2one(
'codice.carica', string='Role code')
date_start = fields.Date(string='Date start', required=True)
date_end = fields.Date(string='Date end', required=True)
fatture_emesse_ids = fields.One2many(
'comunicazione.dati.iva.fatture.emesse', 'comunicazione_id',
string='Customer invoices')
fatture_ricevute_ids = fields.One2many(
'comunicazione.dati.iva.fatture.ricevute', 'comunicazione_id',
string='Supplier bills')
fatture_emesse = fields.Boolean(string="Customer invoices")
fatture_ricevute = fields.Boolean(string="Supplier bills")
dati_trasmissione = fields.Selection(
[('DTE', 'Customer invoices'),
('DTR', 'Supplier bills'),
('ANN', 'Cancellation previously sent data')],
string='Data transmission', required=True)
# Cedente
partner_cedente_id = fields.Many2one('res.partner', string='Partner')
cedente_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cedente_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=28)
cedente_CodiceFiscale = fields.Char(string='Fiscal code', size=16)
cedente_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cedente_Nome = fields.Char(
string='Natural person name', size=60,
help="To fill along with 2.1.2.3 <Cognome> and alternatively to "
"2.1.2.1 <Denominazione>")
cedente_Cognome = fields.Char(
string='Natural person surname', size=60,
help="To fill along with 2.1.2.2 <Nome> and alternatively to "
"2.1.2.1 <Denominazione>")
cedente_sede_Indirizzo = fields.Char(
string='Headquarters address', size=60)
cedente_sede_NumeroCivico = fields.Char(
string='Street number', size=8)
cedente_sede_Cap = fields.Char(
string='ZIP', size=5)
cedente_sede_Comune = fields.Char(
string='City', size=60)
cedente_sede_Provincia = fields.Char(
string='State', size=2)
cedente_sede_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cedente_so_Indirizzo = fields.Char(
string='Permanent establishment address', size=60)
cedente_so_NumeroCivico = fields.Char(
string='Street number', size=8)
cedente_so_Cap = fields.Char(
string='ZIP', size=5)
cedente_so_Comune = fields.Char(
string='City', size=60)
cedente_so_Provincia = fields.Char(
string='State', size=2)
cedente_so_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cedente_rf_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2, help="Only IT is accepted")
cedente_rf_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=11)
cedente_rf_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cedente_rf_Nome = fields.Char(
string='Natural person name', size=60,
help="To fill along with 2.1.2.3 <Cognome> and alternatively to "
"2.1.2.1 <Denominazione>")
cedente_rf_Cognome = fields.Char(
string='Natural person surname', size=60,
help="To fill along with 2.1.2.2 <Nome> and alternatively to "
"2.1.2.1 <Denominazione>")
# Cessionario
partner_cessionario_id = fields.Many2one('res.partner', string='Partner')
cessionario_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cessionario_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=28)
cessionario_CodiceFiscale = fields.Char(
string='Fiscal code', size=16)
cessionario_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cessionario_Nome = fields.Char(
string='Natural person name', size=60,
help="To fill along with 3.1.2.3 <Cognome> and alternatively to "
"3.1.2.1 <Denominazione>")
cessionario_Cognome = fields.Char(
string='Natural person surname', size=60,
help="To fill along with 3.1.2.3 <Nome> and alternatively to "
"3.1.2.1 <Denominazione>")
cessionario_sede_Indirizzo = fields.Char(
string='Headquarters address', size=60)
cessionario_sede_NumeroCivico = fields.Char(
string='Street number', size=8)
cessionario_sede_Cap = fields.Char(
string='ZIP', size=5)
cessionario_sede_Comune = fields.Char(
string='City', size=60)
cessionario_sede_Provincia = fields.Char(
string='State', size=2)
cessionario_sede_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cessionario_so_Indirizzo = fields.Char(
string='Permanent establishment address', size=60)
cessionario_so_NumeroCivico = fields.Char(
string='Street number', size=8)
cessionario_so_Cap = fields.Char(
string='ZIP', size=5)
cessionario_so_Comune = fields.Char(
string='City', size=60)
cessionario_so_Provincia = fields.Char(
string='State', size=2)
cessionario_so_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cessionario_rf_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2, help="Only IT is accepted")
cessionario_rf_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=11)
cessionario_rf_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cessionario_rf_Nome = fields.Char(
string='Natural person name', size=60,
help="To fill along with 2.1.2.3 <Cognome> and alternatively to "
"2.1.2.1 <Denominazione>")
cessionario_rf_Cognome = fields.Char(
string='Natural person surname', size=60,
help="To fill along with 2.1.2.2 <Nome> and alternatively to "
"2.1.2.1 <Denominazione>")
errors = fields.Text(copy=False)
@api.onchange('company_id')
def onchange_company_id(self):
if self.company_id:
if self.company_id.partner_id.vat:
self.taxpayer_vat = self.company_id.partner_id.vat[2:]
else:
self.taxpayer_vat = ''
self.taxpayer_fiscalcode = \
self.company_id.partner_id.fiscalcode
@api.onchange('partner_cedente_id')
def onchange_partner_cedente_id(self):
for comunicazione in self:
if comunicazione.partner_cedente_id:
vals = self._prepare_cedente_partner_id(
comunicazione.partner_cedente_id)
comunicazione.cedente_IdFiscaleIVA_IdPaese = \
vals['cedente_IdFiscaleIVA_IdPaese']
comunicazione.cedente_IdFiscaleIVA_IdCodice = \
vals['cedente_IdFiscaleIVA_IdCodice']
comunicazione.cedente_CodiceFiscale = \
vals['cedente_CodiceFiscale']
comunicazione.cedente_Denominazione = \
vals['cedente_Denominazione']
# Sede
comunicazione.cedente_sede_Indirizzo =\
vals['cedente_sede_Indirizzo']
comunicazione.cedente_sede_Cap = \
vals['cedente_sede_Cap']
comunicazione.cedente_sede_Comune = \
vals['cedente_sede_Comune']
comunicazione.cedente_sede_Provincia = \
vals['cedente_sede_Provincia']
comunicazione.cedente_sede_Nazione = \
vals['cedente_sede_Nazione']
def _prepare_cedente_partner_id(self, partner, vals=None):
vals = {}
# ----- Get vat
partner_vat = partner.commercial_partner_id.vat or ''
if partner.country_id:
vals['cedente_IdFiscaleIVA_IdPaese'] = partner.country_id.code
elif partner_vat:
vals['cedente_IdFiscaleIVA_IdPaese'] = partner_vat[:2]
else:
vals['cedente_IdFiscaleIVA_IdPaese'] = ''
vals['cedente_IdFiscaleIVA_IdCodice'] = \
partner_vat[2:] if partner_vat else ''
# ----- Get fiscalcode
vals['cedente_CodiceFiscale'] = \
partner.commercial_partner_id.fiscalcode or ''
vals['cedente_Denominazione'] = encode_for_export(partner.name, 80)
# Sede
vals['cedente_sede_Indirizzo'] = '{} {}'.format(
encode_for_export(partner.street or '', 60),
encode_for_export(partner.street2 or '', 60)).strip()
vals['cedente_sede_Cap'] = encode_for_export(
partner.zip or '', 5, encoding='ascii')
vals['cedente_sede_Comune'] = encode_for_export(partner.city or '', 60)
vals['cedente_sede_Provincia'] = partner.state_id and \
partner.state_id.code or ''
if partner.country_id:
vals['cedente_sede_Nazione'] = partner.country_id.code
elif partner_vat:
vals['cedente_sede_Nazione'] = partner_vat[:2]
else:
vals['cedente_sede_Nazione'] = ''
# Normalizzazione dati in base alla nazione UE o EXTRA UE:
vals_norm = {
'sede_Nazione': vals['cedente_sede_Nazione'],
'IdFiscaleIVA_IdCodice': vals['cedente_IdFiscaleIVA_IdCodice']
}
vals_norm = self._normalizza_dati_partner(partner, vals_norm)
if 'sede_Cap' in vals_norm:
vals['cedente_sede_Cap'] = vals_norm['sede_Cap']
if 'sede_Provincia' in vals_norm:
vals['cedente_sede_Provincia'] = vals_norm['sede_Provincia']
if 'CodiceFiscale' in vals_norm:
vals['cedente_CodiceFiscale'] = vals_norm['CodiceFiscale']
if 'IdFiscaleIVA_IdCodice' in vals_norm:
vals['cedente_IdFiscaleIVA_IdCodice'] = \
vals_norm['IdFiscaleIVA_IdCodice']
return vals
@api.multi
@api.onchange('partner_cessionario_id')
def onchange_partner_cessionario_id(self):
for comunicazione in self:
if comunicazione.partner_cessionario_id:
vals = self._prepare_cessionario_partner_id(
comunicazione.partner_cessionario_id)
comunicazione.cessionario_IdFiscaleIVA_IdPaese = \
vals['cessionario_IdFiscaleIVA_IdPaese']
comunicazione.cessionario_IdFiscaleIVA_IdCodice = \
vals['cessionario_IdFiscaleIVA_IdCodice']
comunicazione.cessionario_CodiceFiscale = \
vals['cessionario_CodiceFiscale']
comunicazione.cessionario_Denominazione = \
vals['cessionario_Denominazione']
# Sede
comunicazione.cessionario_sede_Indirizzo =\
vals['cessionario_sede_Indirizzo']
comunicazione.cessionario_sede_Cap = \
vals['cessionario_sede_Cap']
comunicazione.cessionario_sede_Comune = \
vals['cessionario_sede_Comune']
comunicazione.cessionario_sede_Provincia = \
vals['cessionario_sede_Provincia']
comunicazione.cessionario_sede_Nazione = \
vals['cessionario_sede_Nazione']
def _prepare_cessionario_partner_id(self, partner, vals=None):
vals = {}
# ----- Get vat
partner_vat = partner.commercial_partner_id.vat or ''
if partner.country_id:
vals['cessionario_IdFiscaleIVA_IdPaese'] = partner.country_id.code
elif partner_vat:
vals['cessionario_IdFiscaleIVA_IdPaese'] = partner_vat[:2]
else:
vals['cessionario_IdFiscaleIVA_IdPaese'] = ''
vals['cessionario_IdFiscaleIVA_IdCodice'] = \
partner_vat[2:] if partner_vat else ''
# ----- Get fiscalcode
vals['cessionario_CodiceFiscale'] = \
partner.commercial_partner_id.fiscalcode or ''
vals['cessionario_Denominazione'] = encode_for_export(partner.name or '', 80)
# Sede
vals['cessionario_sede_Indirizzo'] = '{} {}'.format(
encode_for_export(partner.street or '', 60),
encode_for_export(partner.street2 or '', 60)).strip()
vals['cessionario_sede_Cap'] = encode_for_export(
partner.zip or '', 5, encoding='ascii')
vals['cessionario_sede_Comune'] = encode_for_export(partner.city or '', 60)
vals['cessionario_sede_Provincia'] = partner.state_id and \
partner.state_id.code or ''
if partner.country_id:
vals['cessionario_sede_Nazione'] = partner.country_id.code
elif partner_vat:
vals['cessionario_sede_Nazione'] = partner_vat[:2]
else:
vals['cessionario_sede_Nazione'] = ''
# Normalizzazione dati in base alla nazione UE o EXTRA UE:
vals_norm = {
'sede_Nazione': vals['cessionario_sede_Nazione'],
'IdFiscaleIVA_IdCodice': vals['cessionario_IdFiscaleIVA_IdCodice']
}
vals_norm = self._normalizza_dati_partner(partner, vals_norm)
if 'sede_Cap' in vals_norm:
vals['cessionario_sede_Cap'] = vals_norm['sede_Cap']
if 'sede_Provincia' in vals_norm:
vals['cessionario_sede_Provincia'] = vals_norm['sede_Provincia']
if 'CodiceFiscale' in vals_norm:
vals['cessionario_CodiceFiscale'] = vals_norm['CodiceFiscale']
if 'IdFiscaleIVA_IdCodice' in vals_norm:
vals['cessionario_IdFiscaleIVA_IdCodice'] = \
vals_norm['IdFiscaleIVA_IdCodice']
return vals
def _normalizza_dati_partner(self, partner, vals):
# Paesi Esteri :
# - Rimuovo CAP/provincia che potrebbero dare problemi nella
# validazione
# Paesi UE :
# - No codice fiscale se presente partita iva
# Paesi EXTRA-UE :
# - Non ci sono controlli su id fiscale, ma dato che va messo e può
# non esistere, viene messa la ragione sociale(troncata a 28)
if vals['sede_Nazione'] not in ['', 'IT']:
vals['sede_Cap'] = ''
vals['sede_Provincia'] = ''
country = self.env['res.country'].search(
[('code', '=', vals['sede_Nazione'])])
if country.intrastat:
if vals['IdFiscaleIVA_IdCodice']:
vals['CodiceFiscale'] = ''
if not country.intrastat:
if not vals['IdFiscaleIVA_IdCodice']:
vals['IdFiscaleIVA_IdCodice'] = partner.name[:28]
return vals
def _prepare_fattura_emessa(self, vals, fattura):
return vals
def _prepare_fattura_ricevuta(self, vals, fattura):
return vals
def _parse_fattura_numero(self, fattura_numero):
try:
fattura_numero = fattura_numero[-20:]
except:
pass
return fattura_numero
@api.multi
def compute_values(self):
# Unlink existing lines
self._unlink_sections()
for comunicazione in self:
comunicazione.splitting_note = ''
# Fatture Emesse
if comunicazione.dati_trasmissione == 'DTE':
comunicazione.compute_fatture_emesse()
# Fatture Ricevute
if comunicazione.dati_trasmissione == 'DTR':
comunicazione.compute_fatture_ricevute()
def _prepare_cessionari_dati_fatture(self, fatture_emesse, cessionari):
dati_fatture = []
posizione = 0
for cessionario in cessionari:
fatture = fatture_emesse.filtered(
lambda fe: fe.partner_id.id == cessionario.id)
vals_fatture = []
for fattura in fatture:
posizione += 1
val = {
'posizione': posizione,
'invoice_id': fattura.id,
'dati_fattura_TipoDocumento':
fattura.fiscal_document_type_id.id,
'dati_fattura_Data': fattura.date_invoice,
'dati_fattura_Numero': self._parse_fattura_numero(
fattura.number),
'dati_fattura_iva_ids':
fattura._get_tax_comunicazione_dati_iva()
}
val = self._prepare_fattura_emessa(val, fattura)
vals_fatture.append((0, 0, val))
val_cessionario = {
'partner_id': cessionario.id,
'fatture_emesse_body_ids': vals_fatture
}
vals = self._prepare_cessionario_partner_id(
cessionario)
val_cessionario.update(vals)
dati_fatture.append((0, 0, val_cessionario))
return dati_fatture
def compute_fatture_emesse(self):
self.ensure_one()
fatture_emesse = self._get_fatture_emesse()
if fatture_emesse:
# Cedente
self.partner_cedente_id = \
fatture_emesse[0].company_id.partner_id.id
self.onchange_partner_cedente_id()
# Cessionari
cessionari = fatture_emesse.mapped('partner_id')
dati_fatture = self._prepare_cessionari_dati_fatture(
fatture_emesse, cessionari)
self.fatture_emesse_ids = dati_fatture
def _get_fatture_emesse_domain(self):
self.ensure_one()
domain = [('comunicazione_dati_iva_escludi', '=', True)]
no_journal_ids = self.env['account.journal'].search(domain).ids
domain = [('type', 'in', ['out_invoice', 'out_refund']),
('comunicazione_dati_iva_escludi', '=', False),
('move_id', '!=', False),
('move_id.journal_id', 'not in', no_journal_ids),
('company_id', '=', self.company_id.id),
'|',
('fiscal_document_type_id.out_invoice', '=', True),
('fiscal_document_type_id.out_refund', '=', True),
]
date_domain = _get_invoice_date_domain(self.date_start, self.date_end)
domain = expression.AND([domain, date_domain])
return domain
def _get_fatture_emesse(self):
self.ensure_one()
domain = self._get_fatture_emesse_domain()
return self.env['account.invoice'].search(domain)
def _prepare_cedenti_dati_fatture(self, fatture_ricevute, cedenti):
dati_fatture = []
posizione = 0
for cedente in cedenti:
# Fatture
fatture = fatture_ricevute.filtered(
lambda fr: fr.partner_id.id == cedente.id)
vals_fatture = []
for fattura in fatture:
posizione += 1
val = {
'posizione': posizione,
'invoice_id': fattura.id,
'dati_fattura_TipoDocumento':
fattura.fiscal_document_type_id.id,
'dati_fattura_Data': fattura.date_invoice,
'dati_fattura_DataRegistrazione':
fattura.registration_date or fattura.move_id.date,
'dati_fattura_Numero': self._parse_fattura_numero(
fattura.supplier_invoice_number) or '',
'dati_fattura_iva_ids':
fattura._get_tax_comunicazione_dati_iva()
}
val = self._prepare_fattura_ricevuta(val, fattura)
vals_fatture.append((0, 0, val))
val_cedente = {
'partner_id': cedente.id,
'fatture_ricevute_body_ids': vals_fatture
}
vals = self._prepare_cedente_partner_id(
cedente)
val_cedente.update(vals)
dati_fatture.append((0, 0, val_cedente))
return dati_fatture
def compute_fatture_ricevute(self):
self.ensure_one()
fatture_ricevute = self._get_fatture_ricevute()
if fatture_ricevute:
self.partner_cessionario_id = \
fatture_ricevute[0].company_id.partner_id.id
self.onchange_partner_cessionario_id()
cedenti = fatture_ricevute.mapped('partner_id')
dati_fatture = self._prepare_cedenti_dati_fatture(
fatture_ricevute, cedenti)
self.fatture_ricevute_ids = dati_fatture
def _get_fatture_ricevute_domain(self):
self.ensure_one()
domain = [('comunicazione_dati_iva_escludi', '=', True)]
no_journal_ids = self.env['account.journal'].search(domain).ids
domain = [('type', 'in', ['in_invoice', 'in_refund']),
('comunicazione_dati_iva_escludi', '=', False),
('move_id', '!=', False),
('move_id.journal_id', 'not in', no_journal_ids),
('company_id', '=', self.company_id.id),
'|',
('fiscal_document_type_id.in_invoice', '=', True),
('fiscal_document_type_id.in_refund', '=', True), ]
date_domain = _get_invoice_date_domain(self.date_start, self.date_end)
domain = expression.AND([domain, date_domain])
return domain
def _get_fatture_ricevute(self):
self.ensure_one()
domain = self._get_fatture_ricevute_domain()
return self.env['account.invoice'].search(domain)
def _unlink_sections(self):
for comunicazione in self:
comunicazione.fatture_emesse_ids.unlink()
comunicazione.fatture_ricevute_ids.unlink()
return True
def split_communication(self):
self.ensure_one()
if self.dati_trasmissione == 'DTE':
if not self.check_fatture_emesse_partners():
fatture_emesse = self.mapped(
'fatture_emesse_ids.fatture_emesse_body_ids.invoice_id')
cessionari = fatture_emesse.mapped('partner_id')
first_set_ids = cessionari.ids[:len(cessionari)/2]
second_set_ids = cessionari.ids[len(cessionari)/2:]
first_set_cessionari = self.env['res.partner'].browse(
first_set_ids)
second_set_cessionari = self.env['res.partner'].browse(
second_set_ids)
self._unlink_sections()
dati_fatture_1 = self._prepare_cessionari_dati_fatture(
fatture_emesse, first_set_cessionari)
self.fatture_emesse_ids = dati_fatture_1
self.splitting_note = _(
"Splitted considering partners\n%s"
% '\n'.join(first_set_cessionari.mapped('name')))
comm_2 = self.copy()
comm_2._unlink_sections()
dati_fatture_2 = self._prepare_cessionari_dati_fatture(
fatture_emesse, second_set_cessionari)
comm_2.fatture_emesse_ids = dati_fatture_2
comm_2.splitting_note = _(
"Splitted considering partners\n%s"
% '\n'.join(second_set_cessionari.mapped('name')))
return self | comm_2
elif not self.check_fatture_emesse_body():
fatture_emesse = self.mapped(
'fatture_emesse_ids.fatture_emesse_body_ids.invoice_id')
cessionari = fatture_emesse.mapped('partner_id')
new_set = self.env['account.invoice']
old_set = fatture_emesse
for cessionario in cessionari:
fatture = fatture_emesse.filtered(
lambda fe: fe.partner_id.id == cessionario.id)
if len(fatture) > 1000:
new_set_ids = fatture.ids[:len(fatture)/2]
new_partial_set = self.env['account.invoice'].browse(
new_set_ids)
new_set |= new_partial_set
old_set -= new_partial_set
self._unlink_sections()
cessionari_1 = old_set.mapped('partner_id')
dati_fatture_1 = self._prepare_cessionari_dati_fatture(
old_set, cessionari_1)
self.fatture_emesse_ids = dati_fatture_1
self.splitting_note = _(
"Splitted considering invoices\n%s"
% '\n'.join(old_set.mapped('number')))
comm_2 = self.copy()
comm_2._unlink_sections()
cessionari_2 = new_set.mapped('partner_id')
dati_fatture_2 = self._prepare_cessionari_dati_fatture(
new_set, cessionari_2)
comm_2.fatture_emesse_ids = dati_fatture_2
comm_2.splitting_note = _(
"Splitted considering invoices\n%s"
% '\n'.join(new_set.mapped('number')))
return self | comm_2
elif self.dati_trasmissione == 'DTR':
if not self.check_fatture_ricevute_partners():
fatture_ricevute = self.mapped(
'fatture_ricevute_ids.fatture_ricevute_body_ids.'
'invoice_id')
cedenti = fatture_ricevute.mapped('partner_id')
first_set_ids = cedenti.ids[:len(cedenti)/2]
second_set_ids = cedenti.ids[len(cedenti)/2:]
first_set_cedenti = self.env['res.partner'].browse(
first_set_ids)
second_set_cedenti = self.env['res.partner'].browse(
second_set_ids)
self._unlink_sections()
dati_fatture_1 = self._prepare_cedenti_dati_fatture(
fatture_ricevute, first_set_cedenti)
self.fatture_ricevute_ids = dati_fatture_1
self.splitting_note = _(
"Splitted considering partners\n%s"
% '\n'.join(first_set_cedenti.mapped('name')))
comm_2 = self.copy()
comm_2._unlink_sections()
dati_fatture_2 = self._prepare_cedenti_dati_fatture(
fatture_ricevute, second_set_cedenti)
comm_2.fatture_ricevute_ids = dati_fatture_2
comm_2.splitting_note = _(
"Splitted considering partners\n%s"
% '\n'.join(second_set_cedenti.mapped('name')))
return self | comm_2
elif not self.check_fatture_ricevute_body():
fatture_ricevute = self.mapped(
'fatture_ricevute_ids.fatture_ricevute_body_ids.'
'invoice_id')
cedenti = fatture_ricevute.mapped('partner_id')
new_set = self.env['account.invoice']
old_set = fatture_ricevute
for cedente in cedenti:
fatture = fatture_ricevute.filtered(
lambda fr: fr.partner_id.id == cedente.id)
if len(fatture) > 1000:
new_set_ids = fatture.ids[:len(fatture)/2]
new_partial_set = self.env['account.invoice'].browse(
new_set_ids)
new_set |= new_partial_set
old_set -= new_partial_set
self._unlink_sections()
cedenti_1 = old_set.mapped('partner_id')
dati_fatture_1 = self._prepare_cedenti_dati_fatture(
old_set, cedenti_1)
self.fatture_ricevute_ids = dati_fatture_1
self.splitting_note = _(
"Splitted considering invoices\n%s"
% '\n'.join(old_set.mapped('number')))
comm_2 = self.copy()
comm_2._unlink_sections()
cedenti_2 = new_set.mapped('partner_id')
dati_fatture_2 = self._prepare_cedenti_dati_fatture(
new_set, cedenti_2)
comm_2.fatture_ricevute_ids = dati_fatture_2
comm_2.splitting_note = _(
"Splitted considering invoices\n%s"
% '\n'.join(new_set.mapped('number')))
return self | comm_2
def split_communications(self):
res = self.env['comunicazione.dati.iva']
for com in self:
if com.check_1k_limit():
res |= com
else:
new_communications = com.split_communication()
res |= new_communications.split_communications()
return res
def check_1k_limit(self):
self.ensure_one()
if (
self.check_fatture_emesse_body() and
self.check_fatture_emesse_partners() and
self.check_fatture_ricevute_body() and
self.check_fatture_ricevute_partners()
):
return True
return False
def check_fatture_emesse_body(self):
for line in self.fatture_emesse_ids:
invoices_limit = len(line.fatture_emesse_body_ids)
if invoices_limit > 1000:
return False
return True
def check_fatture_emesse_partners(self):
if len(self.fatture_emesse_ids) > 1000:
return False
return True
def check_fatture_ricevute_body(self):
for line in self.fatture_ricevute_ids:
invoices_limit = len(line.fatture_ricevute_body_ids)
if invoices_limit > 1000:
return False
return True
def check_fatture_ricevute_partners(self):
if len(self.fatture_ricevute_ids) > 1000:
return False
return True
@api.multi
def _check_errors_dte(self):
self.ensure_one()
comunicazione = self
errors = []
# ----- Conta il limite di partner e fatture
partner_limit = 0
for line in comunicazione.fatture_emesse_ids:
partner_limit += 1
invoices_limit = len(line.fatture_emesse_body_ids)
if invoices_limit > 1000:
errors += [
_('Limit of 1000 invoices per assignee (%s) exceeded')
% line.partner_id.display_name]
if partner_limit > 1000:
errors += [
_('Limit of 1000 assignees per communication exceeded')]
# ----- Cedente
# ----- Normalizzazione delle stringhe
if not check_normalized_string(comunicazione.cedente_Denominazione):
errors.append(
_('Remove empty characters around seller\'s denomination'))
if not check_normalized_string(comunicazione.cedente_Nome):
errors.append(
_('Remove empty characters around seller\'s name'))
if not check_normalized_string(comunicazione.cedente_Cognome):
errors.append(
_('Remove empty characters around seller\'s surname'))
if not check_normalized_string(comunicazione.cedente_sede_Indirizzo):
errors.append(
_('Remove empty characters around seller\'s headquarters '
'address'))
if not check_normalized_string(
comunicazione.cedente_sede_NumeroCivico):
errors.append(
_('Remove empty characters around seller\'s street number'))
if not check_normalized_string(comunicazione.cedente_sede_Comune):
errors.append(
_('Remove empty characters around seller\'s city'))
if not check_normalized_string(comunicazione.cedente_so_Indirizzo):
errors.append(
_('Remove empty characters around address of permanent '
'establishment'))
if not check_normalized_string(comunicazione.cedente_so_NumeroCivico):
errors.append(
_('Remove empty characters around street number of permanent '
'establishment'))
if not check_normalized_string(comunicazione.cedente_so_Comune):
errors.append(
_('Remove empty characters around city of permanent '
'establishment'))
if not check_normalized_string(comunicazione.cedente_rf_Denominazione):
errors.append(
_('Remove empty characters around denomination of fiscal '
'representative'))
if not check_normalized_string(comunicazione.cedente_rf_Nome):
errors.append(
_('Remove empty characters around name of fiscal '
'representative'))
if not check_normalized_string(comunicazione.cedente_rf_Cognome):
errors.append(
_('Remove empty characters around surname of fiscal '
'representative'))
# ----- Cessionario
for invoices_partner in comunicazione.fatture_emesse_ids:
# ----- Normalizzazione delle stringhe
if not check_normalized_string(
invoices_partner.cessionario_Denominazione
):
errors.append(_(
u'Remove empty characters around denomination of assignee '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(invoices_partner.cessionario_Nome):
errors.append(_(
u'Remove empty characters around name of assignee '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_Cognome
):
errors.append(_(
u'Remove empty characters around surname of assignee '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_sede_Indirizzo
):
errors.append(_(
u'Remove empty characters around headquarters address of '
u'assignee %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_sede_NumeroCivico
):
errors.append(_(
u'Remove empty characters around street number of assignee'
u' %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_sede_Comune
):
errors.append(_(
u'Remove empty characters around city of assignee '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_so_Indirizzo
):
errors.append(_(
u'Remove empty characters around address of permanent '
u'establishment %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_so_NumeroCivico
):
errors.append(_(
u'Remove empty characters around street number of '
u'permanent establishment %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_so_Comune
):
errors.append(_(
u'Remove empty characters around city of permanent '
u'establishment %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_rf_Denominazione):
errors.append(_(
u'Remove empty characters around denomination of fiscal '
u'representative %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_rf_Nome
):
errors.append(_(
u'Remove empty characters around name of fiscal '
u'representative %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cessionario_rf_Cognome
):
errors.append(_(
u'Remove empty characters around surname of fiscal '
u'representative %s'
) % invoices_partner.partner_id.display_name)
# ----- Dati fiscali
if not invoices_partner.cessionario_IdFiscaleIVA_IdPaese and \
invoices_partner.cessionario_IdFiscaleIVA_IdCodice:
errors.append(_(
u'Define a country ID for assignee %s'
) % invoices_partner.partner_id.display_name)
# ----- Dati Sede
if not all([invoices_partner.cessionario_sede_Indirizzo,
invoices_partner.cessionario_sede_Comune,
invoices_partner.cessionario_sede_Nazione, ]):
errors.append(_(
u'Address, city, country of %s are mandatory'
) % invoices_partner.partner_id.display_name)
# ----- Dati Stabile Organizzazione
if any([invoices_partner.cessionario_so_Indirizzo,
invoices_partner.cessionario_so_NumeroCivico,
invoices_partner.cessionario_so_Cap,
invoices_partner.cessionario_so_Comune,
invoices_partner.cessionario_so_Provincia,
invoices_partner.cessionario_so_Nazione,
]) and not all([invoices_partner.cessionario_so_Indirizzo,
invoices_partner.cessionario_so_Comune,
invoices_partner.cessionario_so_Cap,
invoices_partner.cessionario_so_Nazione,
]):
errors.append(_(
u'Address, city, ZIP and country of permanent '
u'establishment %s are mandatory, when at least one value '
u'is defined'
) % invoices_partner.partner_id.display_name)
# ----- Rappresentante Fiscale
if any([invoices_partner.cessionario_rf_IdFiscaleIVA_IdPaese,
invoices_partner.cessionario_rf_IdFiscaleIVA_IdCodice,
invoices_partner.cessionario_rf_Denominazione,
invoices_partner.cessionario_rf_Nome,
invoices_partner.cessionario_rf_Cognome,
]) and not all([
invoices_partner.cessionario_rf_IdFiscaleIVA_IdPaese,
invoices_partner.cessionario_rf_IdFiscaleIVA_IdCodice,
]):
errors.append(_(
u'Country ID and fiscal identifier of fiscal '
u'representative %s are mandatory, when at least one '
u'value is defined'
) % invoices_partner.partner_id.display_name)
# ----- CAP
if invoices_partner.cessionario_sede_Cap and \
not re.match(
'[0-9]{5}', invoices_partner.cessionario_sede_Cap):
errors.append(_(
u'ZIP %s of assignee %s is not 5 numeric characters'
) % (
invoices_partner.cessionario_sede_Cap,
invoices_partner.partner_id.display_name
))
# ----- Dettagli IVA
for invoice in invoices_partner.fatture_emesse_body_ids:
if not invoice.dati_fattura_iva_ids:
errors.append(_(
u'No VAT data defined for invoice %s of partner %s'
) % (
invoice.invoice_id.number,
invoices_partner.partner_id.display_name))
return errors
@api.multi
def _check_errors_dtr(self):
self.ensure_one()
comunicazione = self
errors = []
# ----- Conta il limite di partner e fatture
partner_limit = 0
for line in comunicazione.fatture_ricevute_ids:
partner_limit += 1
invoices_limit = len(line.fatture_ricevute_body_ids)
if invoices_limit > 1000:
errors += [
_('Limit of 1000 invoices per assignee (%s) exceeded')
% line.partner_id.display_name]
if partner_limit > 1000:
errors += [
_('Limit of 1000 assignees per communication exceeded')]
# ----- Cessionario
# ----- Normalizzazione delle stringhe
if not check_normalized_string(
comunicazione.cessionario_Denominazione):
errors.append(
_('Remove empty characters around assignee\'s denomination'))
if not check_normalized_string(comunicazione.cessionario_Nome):
errors.append(
_('Remove empty characters around assignee\'s name'))
if not check_normalized_string(comunicazione.cessionario_Cognome):
errors.append(
_('Remove empty characters around assignee\'s surname'))
if not check_normalized_string(
comunicazione.cessionario_sede_Indirizzo):
errors.append(
_('Remove empty characters around assignee\'s headquarters '
'address'))
if not check_normalized_string(
comunicazione.cessionario_sede_NumeroCivico):
errors.append(
_('Remove empty characters around assignee\'s street number'))
if not check_normalized_string(comunicazione.cessionario_sede_Comune):
errors.append(
_('Remove empty characters around assignee\'s city'))
if not check_normalized_string(comunicazione.cessionario_so_Indirizzo):
errors.append(
_('Remove empty characters around address of permanent '
'establishment'))
if not check_normalized_string(
comunicazione.cessionario_so_NumeroCivico):
errors.append(
_('Remove empty characters around street number of permanent '
'establishment'))
if not check_normalized_string(comunicazione.cessionario_so_Comune):
errors.append(
_('Remove empty characters around city of permanent '
'establishment'))
if not check_normalized_string(
comunicazione.cessionario_rf_Denominazione):
errors.append(
_('Remove empty characters around denomination of fiscal '
'representative'))
if not check_normalized_string(comunicazione.cessionario_rf_Nome):
errors.append(
_('Remove empty characters around name of fiscal '
'representative'))
if not check_normalized_string(comunicazione.cessionario_rf_Cognome):
errors.append(
_('Remove empty characters around surname of fiscal '
'representative'))
# ----- Cedente
for invoices_partner in comunicazione.fatture_ricevute_ids:
# ----- Normalizzazione delle stringhe
if not check_normalized_string(
invoices_partner.cedente_Denominazione
):
errors.append(_(
u'Remove empty characters around denomination of seller '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(invoices_partner.cedente_Nome):
errors.append(_(
u'Remove empty characters around name of seller '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(invoices_partner.cedente_Cognome):
errors.append(_(
u'Remove empty characters around surname of seller '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_sede_Indirizzo
):
errors.append(_(
u'Remove empty characters around headquarters address of '
u'seller %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_sede_NumeroCivico
):
errors.append(_(
u'Remove empty characters around street number of seller '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_sede_Comune
):
errors.append(_(
u'Remove empty characters around city of seller '
u'%s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_so_Indirizzo
):
errors.append(_(
u'Remove empty characters around address of permanent '
u'establishment %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_so_NumeroCivico
):
errors.append(_(
u'Remove empty characters around street number of '
u'permanent establishment %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(invoices_partner.cedente_so_Comune):
errors.append(_(
u'Remove empty characters around city of permanent '
u'establishment %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_rf_Denominazione):
errors.append(_(
u'Remove empty characters around denomination of fiscal '
u'representative %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(invoices_partner.cedente_rf_Nome):
errors.append(_(
u'Remove empty characters around name of fiscal '
u'representative %s'
) % invoices_partner.partner_id.display_name)
if not check_normalized_string(
invoices_partner.cedente_rf_Cognome
):
errors.append(_(
u'Remove empty characters around surname of fiscal '
u'representative %s'
) % invoices_partner.partner_id.display_name)
# ----- Dati fiscali
if not invoices_partner.cedente_IdFiscaleIVA_IdPaese and \
invoices_partner.cedente_IdFiscaleIVA_IdCodice:
errors.append(_(
u'Define a country ID for seller %s'
) % invoices_partner.partner_id.display_name)
# ----- Dati Sede
if not all([invoices_partner.cedente_sede_Indirizzo,
invoices_partner.cedente_sede_Comune,
invoices_partner.cedente_sede_Nazione, ]):
errors.append(_(
u'Address, city, country of %s are mandatory'
) % invoices_partner.partner_id.display_name)
# ----- Dati Stabile Organizzazione
if any([invoices_partner.cedente_so_Indirizzo,
invoices_partner.cedente_so_NumeroCivico,
invoices_partner.cedente_so_Cap,
invoices_partner.cedente_so_Comune,
invoices_partner.cedente_so_Provincia,
invoices_partner.cedente_so_Nazione,
]) and not all([invoices_partner.cedente_so_Indirizzo,
invoices_partner.cedente_so_Comune,
invoices_partner.cedente_so_Cap,
invoices_partner.cedente_so_Nazione, ]):
errors.append(_(
u'Address, city, ZIP and country of permanent '
u'establishment %s are mandatory, when at least one value '
u'is defined'
) % invoices_partner.partner_id.display_name)
# ----- Rappresentante Fiscale
if any([invoices_partner.cedente_rf_IdFiscaleIVA_IdPaese,
invoices_partner.cedente_rf_IdFiscaleIVA_IdCodice,
invoices_partner.cedente_rf_Denominazione,
invoices_partner.cedente_rf_Nome,
invoices_partner.cedente_rf_Cognome,
]) and not all([
invoices_partner.cedente_rf_IdFiscaleIVA_IdPaese,
invoices_partner.cedente_rf_IdFiscaleIVA_IdCodice, ]):
errors.append(_(
u'Country ID and fiscal identifier of fiscal '
u'representative %s are mandatory, when at least one '
u'value is defined'
) % invoices_partner.partner_id.display_name)
# ----- CAP
if invoices_partner.cedente_sede_Cap and \
not re.match(
'[0-9]{5}', invoices_partner.cedente_sede_Cap):
errors.append(_(
u'ZIP %s of seller %s is not 5 characters'
) % (
invoices_partner.cedente_sede_Cap,
invoices_partner.partner_id.display_name
))
# ----- Dettagli IVA
for invoice in invoices_partner.fatture_ricevute_body_ids:
if not invoice.dati_fattura_iva_ids:
errors.append(_(
u'No VAT data defined for invoice %s of partner %s'
) % (
invoice.invoice_id.number,
invoices_partner.partner_id.display_name))
if not invoice.dati_fattura_Numero:
errors.append(
_(u'No invoice number for supplier bill %s') % (
invoice.invoice_id.number))
if not invoice.dati_fattura_DataRegistrazione:
errors.append(
_(u'No registration date for supplier bill %s') % (
invoice.invoice_id.number))
return errors
@api.multi
def check_errors(self):
for comunicazione in self:
errors = []
if comunicazione.dati_trasmissione == 'DTE':
errors += comunicazione._check_errors_dte()
elif comunicazione.dati_trasmissione == 'DTR':
errors += comunicazione._check_errors_dtr()
if not errors:
errors = [_(u'All data are correct.\nIt possible to export '
u'XML file')]
else:
errors = [_('Errors:')] + errors
comunicazione.errors = u'\n - '.join(errors)
def _validate(self):
"""
Controllo congruitĂ dati della comunicazione
"""
return True
def _export_xml_get_dati_fattura(self):
# ----- 0 - Dati Fattura
attrs = {
'versione': VERSION
}
x_0_dati_fattura = etree.Element(
etree.QName(NS_2, "DatiFattura"), attrib=attrs, nsmap=NS_MAP)
return x_0_dati_fattura
def _export_xml_get_dati_fattura_header(self):
# ----- 1 - Dati Fattura
x_1_dati_fattura_header = etree.Element(
etree.QName("DatiFatturaHeader"))
# ----- 1.1 - Progressivo Invio
x_1_1_progressivo_invio = etree.SubElement(
x_1_dati_fattura_header,
etree.QName("ProgressivoInvio"))
x_1_1_progressivo_invio.text = str(self.identificativo)
# Nota del file excel:
# Questo blocco va valorizzato solo se il soggetto obbligato
# alla comunicazione dei dati fattura non coincide con
# il soggetto passivo IVA al quale i dati si riferiscono.
# NON deve essere valorizzato se per il soggetto trasmittente
# è vera una delle seguenti affermazioni:
# - coincide con il soggetto IVA al quale i dati si riferiscono;
# - è legato da vincolo di incarico con il soggetto IVA al quale i dati
# si riferiscono;
# - è un intermediario.
# In tutti gli altri casi questo blocco DEVE essere valorizzato.
# ----- 1.2 - Dichiarante
x_1_2_dichiarante = etree.SubElement(
x_1_dati_fattura_header,
etree.QName("Dichiarante"))
# ----- 1.2.1 - Codice Fiscale
x_1_2_1_codice_fiscale = etree.SubElement(
x_1_2_dichiarante,
etree.QName("CodiceFiscale"))
x_1_2_1_codice_fiscale.text = self.declarant_fiscalcode or ''
# ----- 1.2.2 - Carica
x_1_2_2_carica = etree.SubElement(
x_1_2_dichiarante,
etree.QName("Carica"))
x_1_2_2_carica.text = self.codice_carica_id.code if \
self.codice_carica_id else ''
return x_1_dati_fattura_header
def _export_xml_get_dte(self):
# ----- 2 - DTE
x_2_dte = etree.Element(
etree.QName("DTE"))
# ----- 2.1 - Cedente Prestatore DTE
x_2_1_cedente_prestatore = etree.SubElement(
x_2_dte,
etree.QName("CedentePrestatoreDTE"))
# ----- 2.1.1 - IdentificativiFiscali
x_2_1_1_identificativi_fiscali = etree.SubElement(
x_2_1_cedente_prestatore,
etree.QName("IdentificativiFiscali"))
# ----- 2.1.1.1 - Id Fiscale IVA
x_2_1_1_1_id_fiscale_iva = etree.SubElement(
x_2_1_1_identificativi_fiscali,
etree.QName("IdFiscaleIVA"))
# ----- 2.1.1.1.1 - Id Paese
x_2_1_1_1_1_id_paese = etree.SubElement(
x_2_1_1_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_2_1_1_1_1_id_paese.text = self.cedente_IdFiscaleIVA_IdPaese or ''
# ----- 2.1.1.1.2 - Id Codice
x_2_1_1_1_2_id_codice = etree.SubElement(
x_2_1_1_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_2_1_1_1_2_id_codice.text = self.cedente_IdFiscaleIVA_IdCodice or ''
# ----- 2.1.1.2 - Codice Fiscale
x_2_1_1_2_codice_fiscale = etree.SubElement(
x_2_1_1_identificativi_fiscali,
etree.QName("CodiceFiscale"))
x_2_1_1_2_codice_fiscale.text = self.cedente_CodiceFiscale or ''
# ----- 2.1.2 - AltriDatiIdentificativi
x_2_1_2_altri_identificativi = etree.SubElement(
x_2_1_cedente_prestatore,
etree.QName("AltriDatiIdentificativi"))
# ----- 2.1.2.1 - Denominazione
x_2_1_2_1_denominazione = etree.SubElement(
x_2_1_2_altri_identificativi,
etree.QName("Denominazione"))
x_2_1_2_1_denominazione.text = self.cedente_Denominazione or ''
# ----- 2.1.2.2 - Nome
x_2_1_2_2_nome = etree.SubElement(
x_2_1_2_altri_identificativi,
etree.QName("Nome"))
x_2_1_2_2_nome.text = self.cedente_Nome or ''
# ----- 2.1.2.3 - Cognome
x_2_1_2_3_cognome = etree.SubElement(
x_2_1_2_altri_identificativi,
etree.QName("Cognome"))
x_2_1_2_3_cognome.text = self.cedente_Cognome or ''
# ----- 2.1.2.4 - Sede
x_2_1_2_4_sede = etree.SubElement(
x_2_1_2_altri_identificativi,
etree.QName("Sede"))
# ----- 2.1.2.4.1 - Indirizzo
x_2_1_2_4_1_indirizzo = etree.SubElement(
x_2_1_2_4_sede,
etree.QName("Indirizzo"))
x_2_1_2_4_1_indirizzo.text = self.cedente_sede_Indirizzo or ''
# ----- 2.1.2.4.2 - Numero Civico
x_2_1_2_4_2_numero_civico = etree.SubElement(
x_2_1_2_4_sede,
etree.QName("NumeroCivico"))
x_2_1_2_4_2_numero_civico.text = self.cedente_sede_NumeroCivico or ''
# ----- 2.1.2.4.3 - CAP
x_2_1_2_4_3_cap = etree.SubElement(
x_2_1_2_4_sede,
etree.QName("CAP"))
x_2_1_2_4_3_cap.text = self.cedente_sede_Cap or ''
# ----- 2.1.2.4.4 - Comune
x_2_1_2_4_4_comune = etree.SubElement(
x_2_1_2_4_sede,
etree.QName("Comune"))
x_2_1_2_4_4_comune.text = self.cedente_sede_Comune or ''
# ----- 2.1.2.4.5 - Provincia
x_2_1_2_4_5_provincia = etree.SubElement(
x_2_1_2_4_sede,
etree.QName("Provincia"))
x_2_1_2_4_5_provincia.text = self.cedente_sede_Provincia or ''
# ----- 2.1.2.4.6 - Nazione
x_2_1_2_4_6_nazione = etree.SubElement(
x_2_1_2_4_sede,
etree.QName("Nazione"))
x_2_1_2_4_6_nazione.text = self.cedente_sede_Nazione or ''
# ----- 2.1.2.5 - Stabile Organizzazione
x_2_1_2_5_stabile_organizzazione = etree.SubElement(
x_2_1_2_altri_identificativi,
etree.QName("StabileOrganizzazione"))
# ----- 2.1.2.5.1 - Indirizzo
x_2_1_2_5_1_indirizzo = etree.SubElement(
x_2_1_2_5_stabile_organizzazione,
etree.QName("Indirizzo"))
x_2_1_2_5_1_indirizzo.text = self.cedente_so_Indirizzo or ''
# ----- 2.1.2.5.2 - Numero Civico
x_2_1_2_5_2_numero_civico = etree.SubElement(
x_2_1_2_5_stabile_organizzazione,
etree.QName("Numerocivico"))
x_2_1_2_5_2_numero_civico.text = self.cedente_so_NumeroCivico or ''
# ----- 2.1.2.5.3 - CAP
x_2_1_2_5_3_cap = etree.SubElement(
x_2_1_2_5_stabile_organizzazione,
etree.QName("CAP"))
x_2_1_2_5_3_cap.text = self.cedente_so_Cap or ''
# ----- 2.1.2.5.4 - Comune
x_2_1_2_5_4_comune = etree.SubElement(
x_2_1_2_5_stabile_organizzazione,
etree.QName("Comune"))
x_2_1_2_5_4_comune.text = self.cedente_so_Comune or ''
# ----- 2.1.2.5.5 - Provincia
x_2_1_2_5_5_provincia = etree.SubElement(
x_2_1_2_5_stabile_organizzazione,
etree.QName("Provincia"))
x_2_1_2_5_5_provincia.text = self.cedente_so_Provincia or ''
# ----- 2.1.2.5.6 - Nazione
x_2_1_2_5_6_nazione = etree.SubElement(
x_2_1_2_5_stabile_organizzazione,
etree.QName("Nazione"))
x_2_1_2_5_6_nazione.text = self.cedente_so_Nazione or ''
# ----- 2.1.2.6 - Rappresentante Fiscale
x_2_1_2_6_rappresentante_fiscale = etree.SubElement(
x_2_1_2_altri_identificativi,
etree.QName("RappresentanteFiscale"))
# ----- 2.1.2.6.1 - Id Fiscale IVA
x_2_1_2_6_1_id_fiscale_iva = etree.SubElement(
x_2_1_2_6_rappresentante_fiscale,
etree.QName("IdFiscaleIVA"))
# ----- 2.1.2.6.1.1 - Id Paese
x_2_1_2_6_1_1_id_paese = etree.SubElement(
x_2_1_2_6_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_2_1_2_6_1_1_id_paese.text = (
self.cedente_rf_IdFiscaleIVA_IdPaese or '')
# ----- 2.1.2.6.1.2 - Id Codice
x_2_1_2_6_1_2_id_codice = etree.SubElement(
x_2_1_2_6_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_2_1_2_6_1_2_id_codice.text = \
self.cedente_rf_IdFiscaleIVA_IdCodice or ''
# ----- 2.1.2.6.2 - Denominazione
x_2_1_2_6_2_denominazione = etree.SubElement(
x_2_1_2_6_rappresentante_fiscale,
etree.QName("Denominazione"))
x_2_1_2_6_2_denominazione.text = \
self.cedente_rf_Denominazione or ''
# ----- 2.1.2.6.3 - Nome
x_2_1_2_6_3_nome = etree.SubElement(
x_2_1_2_6_rappresentante_fiscale,
etree.QName("Nome"))
x_2_1_2_6_3_nome.text = self.cedente_rf_Nome or ''
# ----- 2.1.2.6.4 - Cognome
x_2_1_2_6_4_cognome = etree.SubElement(
x_2_1_2_6_rappresentante_fiscale,
etree.QName("Cognome"))
x_2_1_2_6_4_cognome.text = self.cedente_rf_Cognome or ''
for partner_invoice in self.fatture_emesse_ids:
# ----- 2.2 - Cessionario Committente DTE
x_2_2_cessionario_committente = etree.SubElement(
x_2_dte,
etree.QName("CessionarioCommittenteDTE"))
# ----- 2.2.1 - IdentificativiFiscali
x_2_2_1_identificativi_fiscali = etree.SubElement(
x_2_2_cessionario_committente,
etree.QName("IdentificativiFiscali"))
if partner_invoice.cessionario_IdFiscaleIVA_IdPaese and \
partner_invoice.cessionario_IdFiscaleIVA_IdCodice:
# ----- 2.2.1.1 - Id Fiscale IVA
x_2_2_1_1_id_fiscale_iva = etree.SubElement(
x_2_2_1_identificativi_fiscali,
etree.QName("IdFiscaleIVA"))
# ----- 2.2.1.1.1 - Id Paese
x_2_2_1_1_1_id_paese = etree.SubElement(
x_2_2_1_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_2_2_1_1_1_id_paese.text = \
partner_invoice.cessionario_IdFiscaleIVA_IdPaese or ''
# ----- 2.2.1.1.2 - Id Codice
x_2_2_1_1_2_id_codice = etree.SubElement(
x_2_2_1_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_2_2_1_1_2_id_codice.text = \
partner_invoice.cessionario_IdFiscaleIVA_IdCodice or ''
# ----- 2.2.1.2 - Codice Fiscale
x_2_2_1_2_codice_fiscale = etree.SubElement(
x_2_2_1_identificativi_fiscali,
etree.QName("CodiceFiscale"))
x_2_2_1_2_codice_fiscale.text = \
partner_invoice.cessionario_CodiceFiscale or ''
# ----- 2.2.2 - AltriDatiIdentificativi
x_2_2_2_altri_identificativi = etree.SubElement(
x_2_2_cessionario_committente,
etree.QName("AltriDatiIdentificativi"))
# ----- 2.2.2.1 - Denominazione
x_2_2_2_1_altri_identificativi_denominazione = etree.SubElement(
x_2_2_2_altri_identificativi,
etree.QName("Denominazione"))
x_2_2_2_1_altri_identificativi_denominazione.text = \
encode_for_export(partner_invoice.cessionario_Denominazione or '', 80)
# ----- 2.2.2.2 - Nome
x_2_2_2_2_nome = etree.SubElement(
x_2_2_2_altri_identificativi,
etree.QName("Nome"))
x_2_2_2_2_nome.text = \
encode_for_export(partner_invoice.cessionario_Nome or '', 60)
# ----- 2.2.2.3 - Cognome
x_2_2_2_3_cognome = etree.SubElement(
x_2_2_2_altri_identificativi,
etree.QName("Cognome"))
x_2_2_2_3_cognome.text = \
encode_for_export(partner_invoice.cessionario_Cognome or '', 60)
# ----- 2.2.2.4 - Sede
x_2_2_2_4_sede = etree.SubElement(
x_2_2_2_altri_identificativi,
etree.QName("Sede"))
# ----- 2.2.2.4.1 - Indirizzo
x_2_2_2_4_1_indirizzo = etree.SubElement(
x_2_2_2_4_sede,
etree.QName("Indirizzo"))
x_2_2_2_4_1_indirizzo.text = \
encode_for_export(partner_invoice.cessionario_sede_Indirizzo or '', 60)
# ----- 2.2.2.4.2 - Numero Civico
x_2_2_2_4_2_numero_civico = etree.SubElement(
x_2_2_2_4_sede,
etree.QName("NumeroCivico"))
x_2_2_2_4_2_numero_civico.text = encode_for_export(
partner_invoice.cessionario_sede_NumeroCivico or '', 8,
encoding='ascii')
# ----- 2.2.2.4.3 - CAP
x_2_2_2_4_3_cap = etree.SubElement(
x_2_2_2_4_sede,
etree.QName("CAP"))
x_2_2_2_4_3_cap.text = encode_for_export(
partner_invoice.cessionario_sede_Cap or '', 5, encoding='ascii')
# ----- 2.2.2.4.4 - Comune
x_2_2_2_4_4_comune = etree.SubElement(
x_2_2_2_4_sede,
etree.QName("Comune"))
x_2_2_2_4_4_comune.text = encode_for_export(
partner_invoice.cessionario_sede_Comune or '', 60)
# ----- 2.2.2.4.5 - Provincia
x_2_2_2_4_5_provincia = etree.SubElement(
x_2_2_2_4_sede,
etree.QName("Provincia"))
x_2_2_2_4_5_provincia.text = \
partner_invoice.cessionario_sede_Provincia or ''
# ----- 2.2.2.4.6 - Nazione
x_2_2_2_4_6_nazione = etree.SubElement(
x_2_2_2_4_sede,
etree.QName("Nazione"))
x_2_2_2_4_6_nazione.text = \
partner_invoice.cessionario_sede_Nazione or ''
# ----- 2.2.2.5 - Stabile Organizzazione
x_2_2_2_5_stabile_organizzazione = etree.SubElement(
x_2_2_2_altri_identificativi,
etree.QName("StabileOrganizzazione"))
# ----- 2.2.2.5.1 - Indirizzo
x_2_2_2_5_1_indirizzo = etree.SubElement(
x_2_2_2_5_stabile_organizzazione,
etree.QName("Indirizzo"))
x_2_2_2_5_1_indirizzo.text = encode_for_export(
partner_invoice.cessionario_so_Indirizzo or '', 60)
# ----- 2.2.2.5.2 - Numero Civico
x_2_2_2_5_2_numero_civico = etree.SubElement(
x_2_2_2_5_stabile_organizzazione,
etree.QName("NumeroCivico"))
x_2_2_2_5_2_numero_civico.text = encode_for_export(
partner_invoice.cessionario_so_NumeroCivico or '', 8, encoding='ascii')
# ----- 2.2.2.5.3 - CAP
x_2_2_2_5_3_cap = etree.SubElement(
x_2_2_2_5_stabile_organizzazione,
etree.QName("CAP"))
x_2_2_2_5_3_cap.text = \
encode_for_export(
partner_invoice.cessionario_so_Cap or '', 5, encoding='ascii')
# ----- 2.2.2.5.4 - Comune
x_2_2_2_5_4_comune = etree.SubElement(
x_2_2_2_5_stabile_organizzazione,
etree.QName("Comune"))
x_2_2_2_5_4_comune.text = encode_for_export(
partner_invoice.cessionario_so_Comune or '', 60)
# ----- 2.2.2.5.5 - Provincia
x_2_2_2_5_5_provincia = etree.SubElement(
x_2_2_2_5_stabile_organizzazione,
etree.QName("Provincia"))
x_2_2_2_5_5_provincia.text = \
partner_invoice.cessionario_so_Provincia or ''
# ----- 2.2.2.5.6 - Nazione
x_2_2_2_5_6_nazione = etree.SubElement(
x_2_2_2_5_stabile_organizzazione,
etree.QName("Nazione"))
x_2_2_2_5_6_nazione.text = \
partner_invoice.cessionario_so_Nazione or ''
# ----- 2.2.2.6 - Rappresentante Fiscale
x_2_2_2_6_rappresentante_fiscale = etree.SubElement(
x_2_2_2_altri_identificativi,
etree.QName("RappresentanteFiscale"))
# ----- 2.2.2.6.1 - Id Fiscale IVA
x_2_2_2_6_1_id_fiscale_iva = etree.SubElement(
x_2_2_2_6_rappresentante_fiscale,
etree.QName("IdFiscaleIVA"))
x_2_2_2_6_rappresentante_fiscale.text = \
partner_invoice.cessionario_rf_IdFiscaleIVA_IdPaese or ''
# ----- 2.2.2.6.1.1 - Id Paese
x_2_2_2_6_1_1_id_paese = etree.SubElement(
x_2_2_2_6_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_2_2_2_6_1_1_id_paese.text = \
partner_invoice.cessionario_rf_IdFiscaleIVA_IdPaese or ''
# ----- 2.2.2.6.1.2 - Id Codice
x_2_2_2_6_1_2_id_codice = etree.SubElement(
x_2_2_2_6_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_2_2_2_6_1_2_id_codice.text = \
partner_invoice.cessionario_rf_IdFiscaleIVA_IdCodice or ''
# ----- 2.2.2.6.2 - Denominazione
x_2_2_2_6_2_denominazione = etree.SubElement(
x_2_2_2_6_rappresentante_fiscale,
etree.QName("Denominazione"))
x_2_2_2_6_2_denominazione.text = encode_for_export(
partner_invoice.cessionario_rf_Denominazione or '', 80)
# ----- 2.2.2.6.3 - Nome
x_2_2_2_6_3_nome = etree.SubElement(
x_2_2_2_6_rappresentante_fiscale,
etree.QName("Nome"))
x_2_2_2_6_3_nome.text = encode_for_export(
partner_invoice.cessionario_rf_Nome or '', 60)
# ----- 2.2.2.6.4 - Cognome
x_2_2_2_6_4_cognome = etree.SubElement(
x_2_2_2_6_rappresentante_fiscale,
etree.QName("Cognome"))
x_2_2_2_6_4_cognome.text = encode_for_export(
partner_invoice.cessionario_rf_Cognome or '', 60)
for invoice in partner_invoice.fatture_emesse_body_ids:
# ----- 2.2.3 - Dati Fattura Body DTE
x_2_2_3_dati_fattura_body_dte = etree.SubElement(
x_2_2_cessionario_committente,
etree.QName("DatiFatturaBodyDTE"))
# ----- 2.2.3.1 - Dati Generali
x_2_2_3_1_dati_generali = etree.SubElement(
x_2_2_3_dati_fattura_body_dte,
etree.QName("DatiGenerali"))
# ----- 2.2.3.1.1 - Tipo Documento
x_2_2_3_1_1_tipo_documento = etree.SubElement(
x_2_2_3_1_dati_generali,
etree.QName("TipoDocumento"))
x_2_2_3_1_1_tipo_documento.text = \
invoice.dati_fattura_TipoDocumento.code or ''
# ----- 2.2.3.1.2 - Data
x_2_2_3_1_2_data = etree.SubElement(
x_2_2_3_1_dati_generali,
etree.QName("Data"))
x_2_2_3_1_2_data.text = invoice.dati_fattura_Data or ''
# ----- 2.2.3.1.3 - Numero
x_2_2_3_1_2_numero = etree.SubElement(
x_2_2_3_1_dati_generali,
etree.QName("Numero"))
x_2_2_3_1_2_numero.text = invoice.dati_fattura_Numero or ''
for tax in invoice.dati_fattura_iva_ids:
# ----- 2.2.3.2 - Dati Riepilogo
x_2_2_3_2_riepilogo = etree.SubElement(
x_2_2_3_dati_fattura_body_dte,
etree.QName("DatiRiepilogo"))
# ----- 2.2.3.2.1 - Imponibile Importo
x_2_2_3_2_1_imponibile_importo = etree.SubElement(
x_2_2_3_2_riepilogo,
etree.QName("ImponibileImporto"))
x_2_2_3_2_1_imponibile_importo.text = \
format_decimal(tax.ImponibileImporto)
# ----- 2.2.3.2.2 - Dati IVA
x_2_2_3_2_2_dati_iva = etree.SubElement(
x_2_2_3_2_riepilogo,
etree.QName("DatiIVA"))
# ----- 2.2.3.2.2.1 - Imposta
x_2_2_3_2_2_1_imposta = etree.SubElement(
x_2_2_3_2_2_dati_iva,
etree.QName("Imposta"))
x_2_2_3_2_2_1_imposta.text = format_decimal(tax.Imposta)
# ----- 2.2.3.2.2.2 - Aliquota
x_2_2_3_2_2_2_aliquota = etree.SubElement(
x_2_2_3_2_2_dati_iva,
etree.QName("Aliquota"))
x_2_2_3_2_2_2_aliquota.text = format_decimal(tax.Aliquota)
# ----- 2.2.3.2.3 - Natura
x_2_2_3_2_3_natura = etree.SubElement(
x_2_2_3_2_riepilogo,
etree.QName("Natura"))
x_2_2_3_2_3_natura.text = \
tax.Natura_id.code if tax.Natura_id else ''
# ----- 2.2.3.2.4 - Detraibile
x_2_2_3_2_4_detraibile = etree.SubElement(
x_2_2_3_2_riepilogo,
etree.QName("Detraibile"))
x_2_2_3_2_4_detraibile.text = format_decimal(
tax.Detraibile)
# ----- 2.2.3.2.5 - Deducibile
x_2_2_3_2_5_deducibile = etree.SubElement(
x_2_2_3_2_riepilogo,
etree.QName("Deducibile"))
x_2_2_3_2_5_deducibile.text = tax.Deducibile or ''
# ----- 2.2.3.2.6 - Esigibilita IVA
x_2_2_3_2_6_esagibilita_iva = etree.SubElement(
x_2_2_3_2_riepilogo,
etree.QName("EsigibilitaIVA"))
x_2_2_3_2_6_esagibilita_iva.text = tax.EsigibilitaIVA or ''
return x_2_dte
def _export_xml_get_dtr(self):
# ----- 3 - DTR
x_3_dtr = etree.Element(
etree.QName("DTR"))
# ----- 2.1 - Cessionario Committente DTR
x_3_1_cessionario_committente = etree.SubElement(
x_3_dtr,
etree.QName("CessionarioCommittenteDTR"))
# ----- 2.1.1 - IdentificativiFiscali
x_3_1_1_identificativi_fiscali = etree.SubElement(
x_3_1_cessionario_committente,
etree.QName("IdentificativiFiscali"))
# ----- 2.1.1.1 - Id Fiscale IVA
x_3_1_1_1_id_fiscale_iva = etree.SubElement(
x_3_1_1_identificativi_fiscali,
etree.QName("IdFiscaleIVA"))
# ----- 2.1.1.1.1 - Id Paese
x_3_1_1_1_1_id_paese = etree.SubElement(
x_3_1_1_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_3_1_1_1_1_id_paese.text = self.cessionario_IdFiscaleIVA_IdPaese or ''
# ----- 2.1.1.1.2 - Id Codice
x_3_1_1_1_2_id_codice = etree.SubElement(
x_3_1_1_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_3_1_1_1_2_id_codice.text = (
self.cessionario_IdFiscaleIVA_IdCodice or '')
# ----- 2.1.1.2 - Codice Fiscale
x_3_1_1_2_codice_fiscale = etree.SubElement(
x_3_1_1_identificativi_fiscali,
etree.QName("CodiceFiscale"))
x_3_1_1_2_codice_fiscale.text = self.cessionario_CodiceFiscale or ''
# ----- 2.1.2 - AltriDatiIdentificativi
x_3_1_2_altri_identificativi = etree.SubElement(
x_3_1_cessionario_committente,
etree.QName("AltriDatiIdentificativi"))
# ----- 2.1.2.1 - Denominazione
x_3_1_2_1_denominazione = etree.SubElement(
x_3_1_2_altri_identificativi,
etree.QName("Denominazione"))
x_3_1_2_1_denominazione.text = self.cessionario_Denominazione or ''
# ----- 2.1.2.2 - Nome
x_3_1_2_2_nome = etree.SubElement(
x_3_1_2_altri_identificativi,
etree.QName("Nome"))
x_3_1_2_2_nome.text = self.cessionario_Nome or ''
# ----- 2.1.2.3 - Cognome
x_3_1_2_3_cognome = etree.SubElement(
x_3_1_2_altri_identificativi,
etree.QName("Cognome"))
x_3_1_2_3_cognome.text = self.cessionario_Cognome or ''
# ----- 2.1.2.4 - Sede
x_3_1_2_4_sede = etree.SubElement(
x_3_1_2_altri_identificativi,
etree.QName("Sede"))
# ----- 2.1.2.4.1 - Indirizzo
x_3_1_2_4_1_indirizzo = etree.SubElement(
x_3_1_2_4_sede,
etree.QName("Indirizzo"))
x_3_1_2_4_1_indirizzo.text = self.cessionario_sede_Indirizzo or ''
# ----- 2.1.2.4.2 - Numero Civico
x_3_1_2_4_2_numero_civico = etree.SubElement(
x_3_1_2_4_sede,
etree.QName("NumeroCivico"))
x_3_1_2_4_2_numero_civico.text = (
self.cessionario_sede_NumeroCivico or '')
# ----- 2.1.2.4.3 - CAP
x_3_1_2_4_3_cap = etree.SubElement(
x_3_1_2_4_sede,
etree.QName("CAP"))
x_3_1_2_4_3_cap.text = self.cessionario_sede_Cap or ''
# ----- 2.1.2.4.4 - Comune
x_3_1_2_4_4_comune = etree.SubElement(
x_3_1_2_4_sede,
etree.QName("Comune"))
x_3_1_2_4_4_comune.text = self.cessionario_sede_Comune or ''
# ----- 2.1.2.4.5 - Provincia
x_3_1_2_4_5_provincia = etree.SubElement(
x_3_1_2_4_sede,
etree.QName("Provincia"))
x_3_1_2_4_5_provincia.text = self.cessionario_sede_Provincia or ''
# ----- 2.1.2.4.6 - Nazione
x_3_1_2_4_6_nazione = etree.SubElement(
x_3_1_2_4_sede,
etree.QName("Nazione"))
x_3_1_2_4_6_nazione.text = self.cessionario_sede_Nazione or ''
# ----- 2.1.2.5 - Stabile Organizzazione
x_3_1_2_5_stabile_organizzazione = etree.SubElement(
x_3_1_2_altri_identificativi,
etree.QName("StabileOrganizzazione"))
# ----- 2.1.2.5.1 - Indirizzo
x_3_1_2_5_1_indirizzo = etree.SubElement(
x_3_1_2_5_stabile_organizzazione,
etree.QName("Indirizzo"))
x_3_1_2_5_1_indirizzo.text = self.cessionario_so_Indirizzo or ''
# ----- 2.1.2.5.2 - Numero Civico
x_3_1_2_5_2_numero_civico = etree.SubElement(
x_3_1_2_5_stabile_organizzazione,
etree.QName("Numerocivico"))
x_3_1_2_5_2_numero_civico.text = self.cessionario_so_NumeroCivico or ''
# ----- 2.1.2.5.3 - CAP
x_3_1_2_5_3_cap = etree.SubElement(
x_3_1_2_5_stabile_organizzazione,
etree.QName("CAP"))
x_3_1_2_5_3_cap.text = self.cessionario_so_Cap or ''
# ----- 2.1.2.5.4 - Comune
x_3_1_2_5_4_comune = etree.SubElement(
x_3_1_2_5_stabile_organizzazione,
etree.QName("Comune"))
x_3_1_2_5_4_comune.text = self.cessionario_so_Comune or ''
# ----- 2.1.2.5.5 - Provincia
x_3_1_2_5_5_provincia = etree.SubElement(
x_3_1_2_5_stabile_organizzazione,
etree.QName("Provincia"))
x_3_1_2_5_5_provincia.text = self.cessionario_so_Provincia or ''
# ----- 2.1.2.5.6 - Nazione
x_3_1_2_5_6_nazione = etree.SubElement(
x_3_1_2_5_stabile_organizzazione,
etree.QName("Nazione"))
x_3_1_2_5_6_nazione.text = self.cessionario_so_Nazione or ''
# ----- 2.1.2.6 - Rappresentante Fiscale
x_3_1_2_6_rappresentante_fiscale = etree.SubElement(
x_3_1_2_altri_identificativi,
etree.QName("RappresentanteFiscale"))
# ----- 2.1.2.6.1 - Id Fiscale IVA
x_3_1_2_6_1_id_fiscale_iva = etree.SubElement(
x_3_1_2_6_rappresentante_fiscale,
etree.QName("IdFiscaleIVA"))
# ----- 2.1.2.6.1.1 - Id Paese
x_3_1_2_6_1_1_id_paese = etree.SubElement(
x_3_1_2_6_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_3_1_2_6_1_1_id_paese.text = (
self.cessionario_rf_IdFiscaleIVA_IdPaese or '')
# ----- 2.1.2.6.1.2 - Id Codice
x_3_1_2_6_1_2_id_codice = etree.SubElement(
x_3_1_2_6_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_3_1_2_6_1_2_id_codice.text = \
self.cessionario_rf_IdFiscaleIVA_IdCodice or ''
# ----- 2.1.2.6.2 - Denominazione
x_3_1_2_6_2_denominazione = etree.SubElement(
x_3_1_2_6_rappresentante_fiscale,
etree.QName("Denominazione"))
x_3_1_2_6_2_denominazione.text = \
self.cessionario_rf_Denominazione or ''
# ----- 2.1.2.6.3 - Nome
x_3_1_2_6_3_nome = etree.SubElement(
x_3_1_2_6_rappresentante_fiscale,
etree.QName("Nome"))
x_3_1_2_6_3_nome.text = self.cessionario_rf_Nome or ''
# ----- 2.1.2.6.4 - Cognome
x_3_1_2_6_4_cognome = etree.SubElement(
x_3_1_2_6_rappresentante_fiscale,
etree.QName("Cognome"))
x_3_1_2_6_4_cognome.text = self.cessionario_rf_Cognome or ''
for partner_invoice in self.fatture_ricevute_ids:
# ----- 2.2 - Cessionario Committente DTE
x_3_2_cedente_prestatore = etree.SubElement(
x_3_dtr,
etree.QName("CedentePrestatoreDTR"))
# ----- 2.2.1 - IdentificativiFiscali
x_3_2_1_identificativi_fiscali = etree.SubElement(
x_3_2_cedente_prestatore,
etree.QName("IdentificativiFiscali"))
if partner_invoice.cedente_IdFiscaleIVA_IdPaese and \
partner_invoice.cedente_IdFiscaleIVA_IdCodice:
# ----- 2.2.1.1 - Id Fiscale IVA
x_3_2_1_1_id_fiscale_iva = etree.SubElement(
x_3_2_1_identificativi_fiscali,
etree.QName("IdFiscaleIVA"))
# ----- 2.2.1.1.1 - Id Paese
x_3_2_1_1_1_id_paese = etree.SubElement(
x_3_2_1_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_3_2_1_1_1_id_paese.text = \
partner_invoice.cedente_IdFiscaleIVA_IdPaese or ''
# ----- 2.2.1.1.2 - Id Codice
x_3_2_1_1_2_id_codice = etree.SubElement(
x_3_2_1_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_3_2_1_1_2_id_codice.text = \
partner_invoice.cedente_IdFiscaleIVA_IdCodice or ''
# ----- 2.2.1.2 - Codice Fiscale
x_3_2_1_2_codice_fiscale = etree.SubElement(
x_3_2_1_identificativi_fiscali,
etree.QName("CodiceFiscale"))
x_3_2_1_2_codice_fiscale.text = \
partner_invoice.cedente_CodiceFiscale or ''
# ----- 2.2.2 - AltriDatiIdentificativi
x_3_2_2_altri_identificativi = etree.SubElement(
x_3_2_cedente_prestatore,
etree.QName("AltriDatiIdentificativi"))
# ----- 2.2.2.1 - Denominazione
x_3_2_2_1_altri_identificativi_denominazione = etree.SubElement(
x_3_2_2_altri_identificativi,
etree.QName("Denominazione"))
x_3_2_2_1_altri_identificativi_denominazione.text = encode_for_export(
partner_invoice.cedente_Denominazione or '', 80)
# ----- 2.2.2.2 - Nome
x_3_2_2_2_nome = etree.SubElement(
x_3_2_2_altri_identificativi,
etree.QName("Nome"))
x_3_2_2_2_nome.text = encode_for_export(
partner_invoice.cedente_Nome or '', 60)
# ----- 2.2.2.3 - Cognome
x_3_2_2_3_cognome = etree.SubElement(
x_3_2_2_altri_identificativi,
etree.QName("Cognome"))
x_3_2_2_3_cognome.text = encode_for_export(
partner_invoice.cedente_Cognome or '', 60)
# ----- 2.2.2.4 - Sede
x_3_2_2_4_sede = etree.SubElement(
x_3_2_2_altri_identificativi,
etree.QName("Sede"))
# ----- 2.2.2.4.1 - Indirizzo
x_3_2_2_4_1_indirizzo = etree.SubElement(
x_3_2_2_4_sede,
etree.QName("Indirizzo"))
x_3_2_2_4_1_indirizzo.text = encode_for_export(
partner_invoice.cedente_sede_Indirizzo or '', 60)
# ----- 2.2.2.4.2 - Numero Civico
x_3_2_2_4_2_numero_civico = etree.SubElement(
x_3_2_2_4_sede,
etree.QName("NumeroCivico"))
x_3_2_2_4_2_numero_civico.text = encode_for_export(
partner_invoice.cedente_sede_NumeroCivico or '', 8, encoding='ascii')
# ----- 2.2.2.4.3 - CAP
x_3_2_2_4_3_cap = etree.SubElement(
x_3_2_2_4_sede,
etree.QName("CAP"))
x_3_2_2_4_3_cap.text = encode_for_export(
partner_invoice.cedente_sede_Cap or '', 5, encoding='ascii')
# ----- 2.2.2.4.4 - Comune
x_3_2_2_4_4_comune = etree.SubElement(
x_3_2_2_4_sede,
etree.QName("Comune"))
x_3_2_2_4_4_comune.text = encode_for_export(
partner_invoice.cedente_sede_Comune or '', 60)
# ----- 2.2.2.4.5 - Provincia
x_3_2_2_4_5_provincia = etree.SubElement(
x_3_2_2_4_sede,
etree.QName("Provincia"))
x_3_2_2_4_5_provincia.text = \
partner_invoice.cedente_sede_Provincia or ''
# ----- 2.2.2.4.6 - Nazione
x_3_2_2_4_6_nazione = etree.SubElement(
x_3_2_2_4_sede,
etree.QName("Nazione"))
x_3_2_2_4_6_nazione.text = \
partner_invoice.cedente_sede_Nazione or ''
# ----- 2.2.2.5 - Stabile Organizzazione
x_3_2_2_5_stabile_organizzazione = etree.SubElement(
x_3_2_2_altri_identificativi,
etree.QName("StabileOrganizzazione"))
# ----- 2.2.2.5.1 - Indirizzo
x_3_2_2_5_1_indirizzo = etree.SubElement(
x_3_2_2_5_stabile_organizzazione,
etree.QName("Indirizzo"))
x_3_2_2_5_1_indirizzo.text = encode_for_export(
partner_invoice.cedente_so_Indirizzo or '', 60)
# ----- 2.2.2.5.2 - Numero Civico
x_3_2_2_5_2_numero_civico = etree.SubElement(
x_3_2_2_5_stabile_organizzazione,
etree.QName("NumeroCivico"))
x_3_2_2_5_2_numero_civico.text = encode_for_export(
partner_invoice.cedente_so_NumeroCivico or '', 8, encoding='ascii')
# ----- 2.2.2.5.3 - CAP
x_3_2_2_5_3_cap = etree.SubElement(
x_3_2_2_5_stabile_organizzazione,
etree.QName("CAP"))
x_3_2_2_5_3_cap.text = encode_for_export(
partner_invoice.cedente_so_Cap or '', 5, encoding='ascii')
# ----- 2.2.2.5.4 - Comune
x_3_2_2_5_4_comune = etree.SubElement(
x_3_2_2_5_stabile_organizzazione,
etree.QName("Comune"))
x_3_2_2_5_4_comune.text = encode_for_export(
partner_invoice.cedente_so_Comune or '', 60)
# ----- 2.2.2.5.5 - Provincia
x_3_2_2_5_5_provincia = etree.SubElement(
x_3_2_2_5_stabile_organizzazione,
etree.QName("Provincia"))
x_3_2_2_5_5_provincia.text = \
partner_invoice.cedente_so_Provincia or ''
# ----- 2.2.2.5.6 - Nazione
x_3_2_2_5_6_nazione = etree.SubElement(
x_3_2_2_5_stabile_organizzazione,
etree.QName("Nazione"))
x_3_2_2_5_6_nazione.text = \
partner_invoice.cedente_so_Nazione or ''
# ----- 2.2.2.6 - Rappresentante Fiscale
x_3_2_2_6_rappresentante_fiscale = etree.SubElement(
x_3_2_2_altri_identificativi,
etree.QName("RappresentanteFiscale"))
# ----- 2.2.2.6.1 - Id Fiscale IVA
x_3_2_2_6_1_id_fiscale_iva = etree.SubElement(
x_3_2_2_6_rappresentante_fiscale,
etree.QName("IdFiscaleIVA"))
x_3_2_2_6_rappresentante_fiscale.text = \
partner_invoice.cedente_rf_IdFiscaleIVA_IdPaese or ''
# ----- 2.2.2.6.1.1 - Id Paese
x_3_2_2_6_1_1_id_paese = etree.SubElement(
x_3_2_2_6_1_id_fiscale_iva,
etree.QName("IdPaese"))
x_3_2_2_6_1_1_id_paese.text = \
partner_invoice.cedente_rf_IdFiscaleIVA_IdPaese or ''
# ----- 2.2.2.6.1.2 - Id Codice
x_3_2_2_6_1_2_id_codice = etree.SubElement(
x_3_2_2_6_1_id_fiscale_iva,
etree.QName("IdCodice"))
x_3_2_2_6_1_2_id_codice.text = \
partner_invoice.cedente_rf_IdFiscaleIVA_IdCodice or ''
# ----- 2.2.2.6.2 - Denominazione
x_3_2_2_6_2_denominazione = etree.SubElement(
x_3_2_2_6_rappresentante_fiscale,
etree.QName("Denominazione"))
x_3_2_2_6_2_denominazione.text = encode_for_export(
partner_invoice.cedente_rf_Denominazione or '', 80)
# ----- 2.2.2.6.3 - Nome
x_3_2_2_6_3_nome = etree.SubElement(
x_3_2_2_6_rappresentante_fiscale,
etree.QName("Nome"))
x_3_2_2_6_3_nome.text = encode_for_export(
partner_invoice.cedente_rf_Nome or '', 60)
# ----- 2.2.2.6.4 - Cognome
x_3_2_2_6_4_cognome = etree.SubElement(
x_3_2_2_6_rappresentante_fiscale,
etree.QName("Cognome"))
x_3_2_2_6_4_cognome.text = encode_for_export(
partner_invoice.cedente_rf_Cognome or '', 60)
for invoice in partner_invoice.fatture_ricevute_body_ids:
# ----- 2.2.3 - Dati Fattura Body DTE
x_3_2_3_dati_fattura_body_dte = etree.SubElement(
x_3_2_cedente_prestatore,
etree.QName("DatiFatturaBodyDTR"))
# ----- 2.2.3.1 - Dati Generali
x_3_2_3_1_dati_generali = etree.SubElement(
x_3_2_3_dati_fattura_body_dte,
etree.QName("DatiGenerali"))
# ----- 2.2.3.1.1 - Tipo Documento
x_3_2_3_1_1_tipo_documento = etree.SubElement(
x_3_2_3_1_dati_generali,
etree.QName("TipoDocumento"))
x_3_2_3_1_1_tipo_documento.text = \
invoice.dati_fattura_TipoDocumento.code or ''
# ----- 2.2.3.1.2 - Data
x_3_2_3_1_2_data = etree.SubElement(
x_3_2_3_1_dati_generali,
etree.QName("Data"))
x_3_2_3_1_2_data.text = invoice.dati_fattura_Data or ''
# ----- 2.2.3.1.3 - Numero
x_3_2_3_1_3_numero = etree.SubElement(
x_3_2_3_1_dati_generali,
etree.QName("Numero"))
x_3_2_3_1_3_numero.text = invoice.dati_fattura_Numero or ''
# ----- 2.2.3.1.4 - Data Registrazione
x_3_2_3_1_4_data_registrazione = etree.SubElement(
x_3_2_3_1_dati_generali,
etree.QName("DataRegistrazione"))
x_3_2_3_1_4_data_registrazione.text = \
invoice.dati_fattura_DataRegistrazione or ''
for tax in invoice.dati_fattura_iva_ids:
# ----- 2.2.3.2 - Dati Riepilogo
x_3_2_3_2_riepilogo = etree.SubElement(
x_3_2_3_dati_fattura_body_dte,
etree.QName("DatiRiepilogo"))
# ----- 2.2.3.2.1 - Imponibile Importo
x_3_2_3_2_1_imponibile_importo = etree.SubElement(
x_3_2_3_2_riepilogo,
etree.QName("ImponibileImporto"))
x_3_2_3_2_1_imponibile_importo.text = \
format_decimal(tax.ImponibileImporto)
# ----- 2.2.3.2.2 - Dati IVA
x_3_2_3_2_2_dati_iva = etree.SubElement(
x_3_2_3_2_riepilogo,
etree.QName("DatiIVA"))
# ----- 2.2.3.2.2.1 - Imposta
x_3_2_3_2_2_1_imposta = etree.SubElement(
x_3_2_3_2_2_dati_iva,
etree.QName("Imposta"))
x_3_2_3_2_2_1_imposta.text = format_decimal(tax.Imposta)
# ----- 2.2.3.2.2.2 - Aliquota
x_3_2_3_2_2_2_aliquota = etree.SubElement(
x_3_2_3_2_2_dati_iva,
etree.QName("Aliquota"))
x_3_2_3_2_2_2_aliquota.text = format_decimal(tax.Aliquota)
# ----- 2.2.3.2.3 - Natura
x_3_2_3_2_3_natura = etree.SubElement(
x_3_2_3_2_riepilogo,
etree.QName("Natura"))
x_3_2_3_2_3_natura.text = \
tax.Natura_id.code if tax.Natura_id else ''
# ----- 2.2.3.2.4 - Detraibile
x_3_2_3_2_4_detraibile = etree.SubElement(
x_3_2_3_2_riepilogo,
etree.QName("Detraibile"))
x_3_2_3_2_4_detraibile.text = format_decimal(
tax.Detraibile)
# ----- 2.2.3.2.5 - Deducibile
x_3_2_3_2_5_deducibile = etree.SubElement(
x_3_2_3_2_riepilogo,
etree.QName("Deducibile"))
x_3_2_3_2_5_deducibile.text = tax.Deducibile or ''
# ----- 2.2.3.2.6 - Esigibilita IVA
x_3_2_3_2_6_esagibilita_iva = etree.SubElement(
x_3_2_3_2_riepilogo,
etree.QName("EsigibilitaIVA"))
x_3_2_3_2_6_esagibilita_iva.text = tax.EsigibilitaIVA or ''
return x_3_dtr
def _export_xml_get_ann(self):
# ----- 4 - ANN
x_4_ann = etree.Element(
etree.QName("ANN"))
# ----- 4.1 - Id File
x_4_1_id_file = etree.SubElement(
x_4_ann,
etree.QName("IdFile"))
x_4_1_id_file.text = self.id_comunicazione
# ----- 4.2 - Posizione
# If this node is empty, cancel all invoices of previous comunication
# x_4_2_posizione = etree.SubElement(
# x_4_ann,
# etree.QName("Posizione"))
return x_4_ann
@api.multi
def get_export_xml_filename(self):
self.ensure_one()
filename = '{id}_{type}_{ann}{number}.{ext}'.format(
id=self.company_id.vat or '',
type='DF',
ann='A' if self.dati_trasmissione == 'ANN' else '0',
number=str(self.identificativo or 0).rjust(4, '0'),
ext='xml',
)
return filename
@api.multi
def get_export_xml(self):
self.ensure_one()
self._validate()
# ----- 0 - Dati Fattura
x_0_dati_fattura = self._export_xml_get_dati_fattura()
# ----- 1 - Dati Fattura header
if self.dati_trasmissione in ('DTE', 'DTR'):
x_1_dati_fattura_header = (
self._export_xml_get_dati_fattura_header())
x_0_dati_fattura.append(x_1_dati_fattura_header)
# ----- 2 - DTE
if self.dati_trasmissione == 'DTE':
x_2_dte = self._export_xml_get_dte()
x_0_dati_fattura.append(x_2_dte)
# ----- 3 - DTR
elif self.dati_trasmissione == 'DTR':
x_3_dtr = self._export_xml_get_dtr()
x_0_dati_fattura.append(x_3_dtr)
# ----- 4 - ANN
elif self.dati_trasmissione == 'ANN':
x_4_ann = self._export_xml_get_ann()
x_0_dati_fattura.append(x_4_ann)
# ----- Remove empty nodes
clear_xml(x_0_dati_fattura)
# ----- Create XML
xml_string = etree.tostring(
x_0_dati_fattura, encoding='latin1', method='xml', pretty_print=True)
return xml_string
class ComunicazioneDatiIvaFattureEmesse(models.Model):
_name = 'comunicazione.dati.iva.fatture.emesse'
_description = 'Invoices data communication - Customer invoices'
comunicazione_id = fields.Many2one(
'comunicazione.dati.iva', string='Communication', readonly=True,
ondelete="cascade")
# Cedente
partner_id = fields.Many2one('res.partner', string='Partner')
cessionario_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cessionario_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=28)
cessionario_CodiceFiscale = fields.Char(
string='Fiscal code', size=16)
cessionario_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cessionario_Nome = fields.Char(
string='Natural person name', size=60,
help="To fill along with 2.1.2.3 <Cognome> and alternatively to "
"2.1.2.1 <Denominazione>")
cessionario_Cognome = fields.Char(
string='Natural person surname', size=60,
help="To fill along with 2.1.2.2 <Nome> and alternatively to "
"2.1.2.1 <Denominazione>")
cessionario_sede_Indirizzo = fields.Char(
string='Headquarters address', size=60)
cessionario_sede_NumeroCivico = fields.Char(
string='Street number', size=8)
cessionario_sede_Cap = fields.Char(
string='ZIP', size=5)
cessionario_sede_Comune = fields.Char(
string='City', size=60)
cessionario_sede_Provincia = fields.Char(
string='State', size=2)
cessionario_sede_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cessionario_so_Indirizzo = fields.Char(
string='Permanent establishment address', size=60)
cessionario_so_NumeroCivico = fields.Char(
string='Street number', size=8)
cessionario_so_Cap = fields.Char(
string='ZIP', size=5)
cessionario_so_Comune = fields.Char(
string='City', size=60)
cessionario_so_Provincia = fields.Char(
string='State', size=2)
cessionario_so_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cessionario_rf_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2, help="Only IT is accepted")
cessionario_rf_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=11)
cessionario_rf_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cessionario_rf_Nome = fields.Char(
string='Natural person name', size=60)
cessionario_rf_Cognome = fields.Char(
string='Natural person surname', size=60)
# Dati Cessionario e Fattura
fatture_emesse_body_ids = fields.One2many(
'comunicazione.dati.iva.fatture.emesse.body', 'fattura_emessa_id',
string='Customer invoices body')
# Rettifica
rettifica_IdFile = fields.Char(
string='File identifier',
help="Identifier of file to be amended. This identifer is "
"communicated by the system after transmission")
rettifica_Posizione = fields.Integer(
string='Position', help="Invoice position within transmitted file")
# totali
totale_imponibile = fields.Float('Total untaxed amount',
compute="_compute_total", store=True)
totale_iva = fields.Float('Total VAT',
compute="_compute_total", store=True)
@api.depends('fatture_emesse_body_ids.totale_imponibile',
'fatture_emesse_body_ids.totale_iva')
def _compute_total(self):
for line in self:
totale_imponibile = 0
totale_iva = 0
for fattura in line.fatture_emesse_body_ids:
totale_imponibile += fattura.totale_imponibile
totale_iva += fattura.totale_iva
line.totale_imponibile = totale_imponibile
line.totale_iva = totale_iva
@api.multi
@api.onchange('partner_id')
def onchange_partner_id(self):
for fattura in self:
if fattura.partner_id:
vals = fattura.comunicazione_id.\
_prepare_cessionario_partner_id(fattura.partner_id)
fattura.cessionario_IdFiscaleIVA_IdPaese = \
vals['cessionario_IdFiscaleIVA_IdPaese']
fattura.cessionario_IdFiscaleIVA_IdCodice = \
vals['cessionario_IdFiscaleIVA_IdCodice']
fattura.cessionario_CodiceFiscale = \
vals['cessionario_CodiceFiscale']
fattura.cessionario_Denominazione = \
vals['cessionario_Denominazione']
# Sede
fattura.cessionario_sede_Indirizzo =\
vals['cessionario_sede_Indirizzo']
fattura.cessionario_sede_Cap = \
vals['cessionario_sede_Cap']
fattura.cessionario_sede_Comune = \
vals['cessionario_sede_Comune']
fattura.cessionario_sede_Provincia = \
vals['cessionario_sede_Provincia']
fattura.cessionario_sede_Nazione = \
vals['cessionario_sede_Nazione']
class ComunicazioneDatiIvaFattureEmesseBody(models.Model):
_name = 'comunicazione.dati.iva.fatture.emesse.body'
_description = 'Invoices data communication - Customer invoices body'
@api.depends('dati_fattura_iva_ids.ImponibileImporto',
'dati_fattura_iva_ids.Imposta')
def _compute_total(self):
for ft in self:
totale_imponibile = 0
totale_iva = 0
for tax_line in ft.dati_fattura_iva_ids:
totale_imponibile += tax_line.ImponibileImporto
totale_iva += tax_line.Imposta
ft.totale_imponibile = totale_imponibile
ft.totale_iva = totale_iva
fattura_emessa_id = fields.Many2one(
'comunicazione.dati.iva.fatture.emesse', string="Customer invoice",
ondelete="cascade")
posizione = fields.Integer(
"Position", help="Invoice position within transmitted file",
required=True)
invoice_id = fields.Many2one('account.invoice', string='Invoice')
dati_fattura_TipoDocumento = fields.Many2one(
'fiscal.document.type', string='Document type', required=True)
dati_fattura_Data = fields.Date(string='Document date', required=True)
dati_fattura_Numero = fields.Char(string='Document number', required=True)
dati_fattura_iva_ids = fields.One2many(
'comunicazione.dati.iva.fatture.emesse.iva', 'fattura_emessa_body_id',
string='VAT summary')
totale_imponibile = fields.Float('Total untaxed amount',
compute="_compute_total", store=True)
totale_iva = fields.Float('Total VAT',
compute="_compute_total", store=True)
@api.onchange('invoice_id')
def onchange_invoice_id(self):
for fattura in self:
if fattura.invoice_id:
fattura.dati_fattura_TipoDocumento = \
fattura.invoice_id.fiscal_document_type_id and \
fattura.invoice_id.fiscal_document_type_id.id or False
fattura.dati_fattura_Numero = fattura.invoice_id.number
fattura.dati_fattura_Data = fattura.invoice_id.date_invoice
fattura.dati_fattura_iva_ids = \
fattura.invoice_id._get_tax_comunicazione_dati_iva()
class ComunicazioneDatiIvaFattureEmesseIva(models.Model):
_name = 'comunicazione.dati.iva.fatture.emesse.iva'
_description = 'Invoices data communication - Customer invoices VAT'
fattura_emessa_body_id = fields.Many2one(
'comunicazione.dati.iva.fatture.emesse.body',
string='Customer invoice body', readonly=True, ondelete="cascade")
ImponibileImporto = fields.Float(
string='Base amount',
help="Base amount (for operations VAT subjected) or not taxable amount"
" (for operations where seller does not indicate VAT) or sum of "
"taxable and tax amounts, when expected, like for simplified "
"invoices (TD07 or TD08)")
Imposta = fields.Float(
string='VAT',
help="If element 2.2.3.1.1 is TD07 or TD08, this can be used instead "
"of 2.2.3.2.2.2 <Aliquota>")
Aliquota = fields.Float(
string='Tax rate',
help="VAT rate, in percentage")
Natura_id = fields.Many2one('account.tax.kind', string='Exemption kind')
Detraibile = fields.Float(string='Deductible %')
Deducibile = fields.Char(string='Deductible', size=2,
help="Possible value: [SI] = deductible expense")
EsigibilitaIVA = fields.Selection(
[('I', 'Immediate'), ('D', 'Deferred'),
('S', 'Split payment')], string='VAT payability')
class ComunicazioneDatiIvaFattureRicevute(models.Model):
_name = 'comunicazione.dati.iva.fatture.ricevute'
_description = 'Invoices data communication - Supplier bills'
comunicazione_id = fields.Many2one(
'comunicazione.dati.iva', string='Communication', readonly=True,
ondelete="cascade")
# Cessionario
partner_id = fields.Many2one('res.partner', string='Partner')
cedente_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cedente_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=28)
cedente_CodiceFiscale = fields.Char(
string='Fiscal code', size=16)
cedente_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cedente_Nome = fields.Char(
string='Natural person name', size=60,
help="To fill along with 3.2.2.3 <Cognome> and alternatively to "
"3.2.2.1 <Denominazione>")
cedente_Cognome = fields.Char(
string='Natural person surname', size=60,
help="To fill along with 3.2.2.2 <Nome> and alternatively to "
"3.2.2.1 <Denominazione>")
cedente_sede_Indirizzo = fields.Char(
string='Headquarters address', size=60)
cedente_sede_NumeroCivico = fields.Char(
string='Street number', size=8)
cedente_sede_Cap = fields.Char(
string='ZIP', size=5)
cedente_sede_Comune = fields.Char(
string='City', size=60)
cedente_sede_Provincia = fields.Char(
string='State', size=2)
cedente_sede_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cedente_so_Indirizzo = fields.Char(
string='Permanent establishment address', size=60)
cedente_so_NumeroCivico = fields.Char(
string='Street number', size=8)
cedente_so_Cap = fields.Char(
string='ZIP', size=5)
cedente_so_Comune = fields.Char(
string='City', size=60)
cedente_so_Provincia = fields.Char(
string='State', size=2)
cedente_so_Nazione = fields.Char(
string='Country', size=2,
help="Country code, expressed using the 3166-1 alpha-2 standard")
cedente_rf_IdFiscaleIVA_IdPaese = fields.Char(
string='Country ID', size=2, help="Only IT is accepted")
cedente_rf_IdFiscaleIVA_IdCodice = fields.Char(
string='Fiscal identifier', size=11)
cedente_rf_Denominazione = fields.Char(
string='Company, denomination or business name', size=80)
cedente_rf_Nome = fields.Char(
string='Natural person name', size=60)
cedente_rf_Cognome = fields.Char(
string='Natural person surname', size=60)
# Dati Cedente e Fattura
fatture_ricevute_body_ids = fields.One2many(
'comunicazione.dati.iva.fatture.ricevute.body', 'fattura_ricevuta_id',
string='Supplier bills body')
# Rettifica
rettifica_IdFile = fields.Char(
string='File identifier',
help="Identifier of file to be amended. This identifer is "
"communicated by the system after transmission")
rettifica_Posizione = fields.Integer(
string='Position', help="Invoice position within transmitted file")
# totali
totale_imponibile = fields.Float('Total untaxed amount',
compute="_compute_total", store=True)
totale_iva = fields.Float('Total VAT',
compute="_compute_total", store=True)
@api.depends('fatture_ricevute_body_ids.totale_imponibile',
'fatture_ricevute_body_ids.totale_iva')
def _compute_total(self):
for line in self:
totale_imponibile = 0
totale_iva = 0
for fattura in line.fatture_ricevute_body_ids:
totale_imponibile += fattura.totale_imponibile
totale_iva += fattura.totale_iva
line.totale_imponibile = totale_imponibile
line.totale_iva = totale_iva
@api.onchange('partner_id')
def onchange_partner_id(self):
for fattura in self:
if fattura.partner_id:
fattura.cedente_IdFiscaleIVA_IdPaese = \
fattura.partner_id.country_id.code or ''
fattura.cedente_IdFiscaleIVA_IdCodice = \
fattura.partner_id.vat[2:] if fattura.partner_id.vat \
else ''
fattura.cedente_CodiceFiscale = \
fattura.partner_id.fiscalcode or ''
fattura.cedente_Denominazione = \
fattura.partner_id.name or ''
# Sede
fattura.cedente_sede_Indirizzo = '{} {}'.format(
fattura.partner_id.street, fattura.partner_id.street2
).strip()
fattura.cedente_sede_Cap = \
fattura.partner_id.zip or ''
fattura.cedente_sede_Comune = \
fattura.partner_id.city or ''
fattura.cedente_sede_Provincia = \
fattura.partner_id.state_id and \
fattura.partner_id.state_id.code or ''
fattura.cedente_sede_Nazione = \
fattura.partner_id.country_id and \
fattura.partner_id.country_id.code or ''
class ComunicazioneDatiIvaFattureRicevuteBody(models.Model):
_name = 'comunicazione.dati.iva.fatture.ricevute.body'
_description = 'Invoices data communication - Supplier bills body'
@api.depends('dati_fattura_iva_ids.ImponibileImporto',
'dati_fattura_iva_ids.Imposta')
def _compute_total(self):
for ft in self:
totale_imponibile = 0
totale_iva = 0
for tax_line in ft.dati_fattura_iva_ids:
totale_imponibile += tax_line.ImponibileImporto
totale_iva += tax_line.Imposta
ft.totale_imponibile = totale_imponibile
ft.totale_iva = totale_iva
fattura_ricevuta_id = fields.Many2one(
'comunicazione.dati.iva.fatture.ricevute', string="Supplier bill",
ondelete="cascade")
posizione = fields.Integer(
"Position", help="Invoice position within transmitted file",
required=True)
invoice_id = fields.Many2one('account.invoice', string='Invoice')
dati_fattura_TipoDocumento = fields.Many2one(
'fiscal.document.type', string='Document type', required=True)
dati_fattura_Data = fields.Date(string='Document date', required=True)
dati_fattura_Numero = fields.Char(string='Document number', required=True)
dati_fattura_DataRegistrazione = fields.Date(string='Registration date',
required=True)
dati_fattura_iva_ids = fields.One2many(
'comunicazione.dati.iva.fatture.ricevute.iva',
'fattura_ricevuta_body_id',
string='VAT summary')
totale_imponibile = fields.Float('Total untaxed amount',
compute="_compute_total", store=True)
totale_iva = fields.Float('Total VAT',
compute="_compute_total", store=True)
@api.onchange('invoice_id')
def onchange_invoice_id(self):
for fattura in self:
if fattura.invoice_id:
fattura.dati_fattura_TipoDocumento = \
fattura.invoice_id.fiscal_document_type_id and \
fattura.invoice_id.fiscal_document_type_id.id or False
fattura.dati_fattura_Numero = \
fattura.invoice_id.supplier_invoice_number
fattura.dati_fattura_Data = fattura.invoice_id.date_invoice
fattura.dati_fattura_DataRegistrazione = \
fattura.invoice_id.registration_date \
or fattura.invoice_id.move_id.date
# tax
tax_lines = []
for tax_line in fattura.invoice_id.tax_line:
# aliquota
aliquota = 0
domain = [('tax_code_id', '=', tax_line.tax_code_id.id)]
tax = self.env['account.tax'].search(
domain, order='id', limit=1)
if tax:
aliquota = tax.amount * 100
val = {
'ImponibileImporto': tax_line.base_amount,
'Imposta': tax_line.amount,
'Aliquota': aliquota,
}
tax_lines.append((0, 0, val))
fattura.dati_fattura_iva_ids = tax_lines
class ComunicazioneDatiIvaFattureRicevuteIva(models.Model):
_name = 'comunicazione.dati.iva.fatture.ricevute.iva'
_description = 'Invoices data communication - Supplier bills VAT'
fattura_ricevuta_body_id = fields.Many2one(
'comunicazione.dati.iva.fatture.ricevute.body',
string='Supplier bill body', readonly=True, ondelete="cascade")
ImponibileImporto = fields.Float(
string='Base amount',
help="Base amount (for operations VAT subjected) or not taxable amount"
" (for operations where seller does not indicate VAT) or sum of "
"taxable and tax amounts, when expected, like for simplified "
"invoices (TD07 or TD08)")
Imposta = fields.Float(
string='VAT',
help="If element 2.2.3.1.1 is TD07 or TD08, this can be used instead "
"of 2.2.3.2.2.2 <Aliquota>")
Aliquota = fields.Float(
string='Tax rate',
help="VAT rate, in percentage")
Natura_id = fields.Many2one('account.tax.kind', string='Exemption kind')
Detraibile = fields.Float(string='Deductible %')
Deducibile = fields.Char(string='Deductible', size=2,
help="Possible value: [SI] = deductible expense")
EsigibilitaIVA = fields.Selection([('I', 'Immediate'),
('D', 'Deferred'),
('S', 'Split payment')],
string='VAT payability')