Merge lp:~a-camilli/openobject-italia/6.1-spesometro into lp:~openobject-italia-core-devs/openobject-italia/italian-addons-6.1

Proposed by Alessandro Camilli
Status: Work in progress
Proposed branch: lp:~a-camilli/openobject-italia/6.1-spesometro
Merge into: lp:~openobject-italia-core-devs/openobject-italia/italian-addons-6.1
Diff against target: 3158 lines (+3092/-0)
12 files modified
l10n_it_spesometro/__init__.py (+23/-0)
l10n_it_spesometro/__openerp__.py (+49/-0)
l10n_it_spesometro/security/ir.model.access.csv (+11/-0)
l10n_it_spesometro/spesometro.py (+1280/-0)
l10n_it_spesometro/spesometro_view.xml (+650/-0)
l10n_it_spesometro/wizard/__init__.py (+25/-0)
l10n_it_spesometro/wizard/wizard_crea_comunicazione.py (+128/-0)
l10n_it_spesometro/wizard/wizard_crea_comunicazione_view.xml (+67/-0)
l10n_it_spesometro/wizard/wizard_default.py (+65/-0)
l10n_it_spesometro/wizard/wizard_default_view.xml (+39/-0)
l10n_it_spesometro/wizard/wizard_export.py (+710/-0)
l10n_it_spesometro/wizard/wizard_export_view.xml (+45/-0)
To merge this branch: bzr merge lp:~a-camilli/openobject-italia/6.1-spesometro
Reviewer Review Type Date Requested Status
Lorenzo Battistini Needs Fixing
Review via email: mp+210439@code.launchpad.net
To post a comment you must log in.
245. By Alessandro Camilli

Spesometro - Tolta la sequenza

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Ciao Alessandro, grazie ancora per il modulo :-)

Negli header potresti aggiungere il copyright dell'associazione?

# Copyright (C) 2014
# Associazione OpenERP Italia (<http://www.openerp-italia.org>)

Ovviamente se vuoi puoi anche aggiungere il tuo

riga 64: come website, piuttosto che niente, potresti mettere http://www.openerp-italia.org ?

righe 163, 168 e forse altre: vedo un carattere probabilmente non unicode

Campi che usano il metodo _tot_operation_number: hai usato store=True. Visto che il ricalcolo dipende anche dal campo 'line_BL_ids', è sufficiente mettere store=True, o è necessario specificare il dizionario con almeno le due chiavi 'spesometro.comunicazione' e 'spesometro.comunicazione.line.bl'?
In altre parole, modificando campi di 'spesometro.comunicazione.line.bl', i campi 'totale_FA' etc vengono ricalcolati?

riga 320 e siccessive: il parse a int è necessario?

riga 1375: _default è necessario?

riga 1508: pdb (a cosa serve wizard.spesometro.default ? )

riga 1604 : serve?

review: Needs Fixing
Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Nel file l10n_it_spesometro/spesometro.py a riga 28 è stato definito il
campo

codice_stato_agenzia_entrate

che è un duplicato del campo ufficioiva della tabella res.country nel nuovo modulo l10n_it_base in fase di approvazione
Inoltre nel modulo l10n_it_base in fase di approvazione sono inseriti i seguenti campi necessari allo spesometro:

  * blacklist: indica se un paese è in black (la tabella in oggetto è
    già correttamente compilata)
  * blacklist_dat: data di ingresso (se blacklist = True) o di uscita
    (se blacklist = false) nella blacklist; serve nei casi in cui un
    paese entra o esce dalla black list durante l'esercizio che da
    origine alla comunicazione
  * inue: indica se un paese è nella UE (True): sever per identificare i
    movimenti Intracee sia ai fini della Comunicazione Polivalente che
    il futuro Intrasta integrato in questa comunicazione
  * inue_date: indica la data di ingresso nella UE

Il campo inue indica anche indirettamente i paesi Extra-UE che sono
quelli non in UE e non l'Italia

Il 12/03/2014 21:45, Lorenzo Battistini - Agile BG ha scritto:
> Review: Needs Fixing
>
> Ciao Alessandro, grazie ancora per il modulo :-)
>
>
> Negli header potresti aggiungere il copyright dell'associazione?
>
> # Copyright (C) 2014
> # Associazione OpenERP Italia (<http://www.openerp-italia.org>)
>
> Ovviamente se vuoi puoi anche aggiungere il tuo
>
>
> riga 64: come website, piuttosto che niente, potresti mettere http://www.openerp-italia.org ?
>
>
> righe 163, 168 e forse altre: vedo un carattere probabilmente non unicode
>
>
> Campi che usano il metodo _tot_operation_number: hai usato store=True. Visto che il ricalcolo dipende anche dal campo 'line_BL_ids', è sufficiente mettere store=True, o è necessario specificare il dizionario con almeno le due chiavi 'spesometro.comunicazione' e 'spesometro.comunicazione.line.bl'?
> In altre parole, modificando campi di 'spesometro.comunicazione.line.bl', i campi 'totale_FA' etc vengono ricalcolati?
>
>
> riga 320 e siccessive: il parse a int è necessario?
>
>
> riga 1375: _default è necessario?
>
>
> riga 1508: pdb (a cosa serve wizard.spesometro.default ? )
>
>
> riga 1604 : serve?

--

Antonio M. Vigliotti
(Presidente & Chief Technical Officer)

*SHS-AV s.r.l. (impresa innovativa)
zeroincombenze®
*

Via Domodossola, 64 - 10145 TORINO - ITALY

Tel. (+39) 011.0566929(2)

www.shs-av.com

PEC <email address hidden>

Revision history for this message
Lorenzo Battistini (elbati) wrote :

On 03/13/2014 07:57 AM, Antonio M. - Zeroincombenze wrote:
> Nel file l10n_it_spesometro/spesometro.py a riga 28 è stato definito il
> campo
>
> codice_stato_agenzia_entrate
>
> che è un duplicato del campo ufficioiva della tabella res.country nel nuovo modulo l10n_it_base in fase di approvazione
> Inoltre nel modulo l10n_it_base in fase di approvazione sono inseriti i seguenti campi necessari allo spesometro:
>
> * blacklist: indica se un paese è in black (la tabella in oggetto è
> già correttamente compilata)
> * blacklist_dat: data di ingresso (se blacklist = True) o di uscita
> (se blacklist = false) nella blacklist; serve nei casi in cui un
> paese entra o esce dalla black list durante l'esercizio che da
> origine alla comunicazione
> * inue: indica se un paese è nella UE (True): sever per identificare i
> movimenti Intracee sia ai fini della Comunicazione Polivalente che
> il futuro Intrasta integrato in questa comunicazione
> * inue_date: indica la data di ingresso nella UE
>
> Il campo inue indica anche indirettamente i paesi Extra-UE che sono
> quelli non in UE e non l'Italia

Non ho ancora visto la merge proposal quindi non mi posso esprimere
sulla bontà del nuovo modulo.

Da quello che capisco, sono stati aggiunti a l10n_it_base dei campi che
non sono legati a funzionalità "base", che quindi probabilmente
andrebbero messi in uno o più moduli dedicati, se non servono solo allo
spesometro.
Se invece questi campi servono solo allo spesometro, allo è corretto che
vengano aggiunti al modulo dello spesometro.

Considera inoltre che questa MP è relativa alla versione 6.1

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

L'appartenza o meno alla UE è un dato universale che serve ovunque.
Il campo nazione invece serve alle dichiarazioni verso l'ufficio IVA. Se
questo modulo sarà usato per tutte le comunicazioni polivalenti, allora
il campo dovrebbe stare in questo modulo. Allo stato attuale, però il
codice sembra più adatto alla sola comunicazione specifica dello Spesometro.
Stesso discorso per i campi relativi alla blacklist

Antonio M. Vigliotti

Il 13/03/2014 08:18, Lorenzo Battistini - Agile BG ha scritto:
> On 03/13/2014 07:57 AM, Antonio M. - Zeroincombenze wrote:
>> Nel file l10n_it_spesometro/spesometro.py a riga 28 è stato definito il
>> campo
>>
>> codice_stato_agenzia_entrate
>>
>> che è un duplicato del campo ufficioiva della tabella res.country nel nuovo modulo l10n_it_base in fase di approvazione
>> Inoltre nel modulo l10n_it_base in fase di approvazione sono inseriti i seguenti campi necessari allo spesometro:
>>
>> * blacklist: indica se un paese è in black (la tabella in oggetto è
>> già correttamente compilata)
>> * blacklist_dat: data di ingresso (se blacklist = True) o di uscita
>> (se blacklist = false) nella blacklist; serve nei casi in cui un
>> paese entra o esce dalla black list durante l'esercizio che da
>> origine alla comunicazione
>> * inue: indica se un paese è nella UE (True): sever per identificare i
>> movimenti Intracee sia ai fini della Comunicazione Polivalente che
>> il futuro Intrasta integrato in questa comunicazione
>> * inue_date: indica la data di ingresso nella UE
>>
>> Il campo inue indica anche indirettamente i paesi Extra-UE che sono
>> quelli non in UE e non l'Italia
> Non ho ancora visto la merge proposal quindi non mi posso esprimere
> sulla bontà del nuovo modulo.
>
> Da quello che capisco, sono stati aggiunti a l10n_it_base dei campi che
> non sono legati a funzionalità "base", che quindi probabilmente
> andrebbero messi in uno o più moduli dedicati, se non servono solo allo
> spesometro.
> Se invece questi campi servono solo allo spesometro, allo è corretto che
> vengano aggiunti al modulo dello spesometro.
>
> Considera inoltre che questa MP è relativa alla versione 6.1
>
>

Revision history for this message
Davide Corio (enlightx-deactivatedaccount) wrote :

Esiste il modulo l10n_it_account, nel quale dovrebbero stare tutte le configurazioni e la logica relativa ai dati contabili.
Se parliamo di IVA, forse quello è il posto giusto (anche se il modulo, come tutti gli altri, avrebbe bisogno di refactoring estremo).

Appartenenza a EU o meno, sono d'accordo ad averlo in l10n_it_base, anche se non ho ancora visto come è stata implementata.

Penso però che se andiamo a cambiare molto questi moduli, ha senso farlo per la 8.0 e non per 6.1 e 7.0.

Se fossero necessari aggiustamenti dei moduli, chi già li usa si vedrebbe cambiamenti drastici.
In questo caso, avere cambiamenti in un modulo separato risolverebbe molti problemi.

Oltretutto mantenere ogni singolo modulo contenuto e snello consente una manutenzione più facile.

Revision history for this message
Alessandro Camilli (a-camilli) wrote :

Per l'appartenenza a EU -> l10n_it_base ok
I campi IVA -> l10n_it_account ok

Per i dati come Cognome, Nome, Data nascita ecc legati alla persona fisica?
Per me sono da mettere su l10n_it_account.
Anzi farei anche un <page> specifico nella scheda cliente tipo "Dati fiscali".

Non penso che farli sulla 7.0 porti tanto scompiglio, alla fine sono solo dati in più che non modificano la logica di procedure esistenti.

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Per me, che non ho esperienze precedenti con OpenERP, ogni soluzione è buona
Sulla base di quanto dice Davide proporrei quanto segue:
  - I campi blacklist e blacklist_date inserirli in l10n_it_account (non
dovrebbero dare problemi alle versioni precedenti)
- Il campo con nome da conccordare "ufficioiva" nello stesso modulo
- Il campo inue e inue_date nel modulo l10n_base_it in quanto più universali

Colgo l'occasione per segnalare che nella tabella abbiamo aggiunto anche
2 campi per il SEPA (paese aderente a SEPA e data di accesso),
riservandoci di integrarli nel moduli RIBA e assimilabili. Tutti i campi
di cui sopara sono già compilati e utilizzabili, aggiornati a febbraio
2014, quindi ritengo utili a tutti

Il 13/03/2014 09:07, Davide Corio @ LS ha scritto:
> Esiste il modulo l10n_it_account, nel quale dovrebbero stare tutte le configurazioni e la logica relativa ai dati contabili.
> Se parliamo di IVA, forse quello è il posto giusto (anche se il modulo, come tutti gli altri, avrebbe bisogno di refactoring estremo).
>
> Appartenenza a EU o meno, sono d'accordo ad averlo in l10n_it_base, anche se non ho ancora visto come è stata implementata.
>
> Penso però che se andiamo a cambiare molto questi moduli, ha senso farlo per la 8.0 e non per 6.1 e 7.0.
>
> Se fossero necessari aggiustamenti dei moduli, chi già li usa si vedrebbe cambiamenti drastici.
> In questo caso, avere cambiamenti in un modulo separato risolverebbe molti problemi.
>
> Oltretutto mantenere ogni singolo modulo contenuto e snello consente una manutenzione più facile.

Revision history for this message
Lorenzo Battistini (elbati) wrote :

"Per i dati come Cognome, Nome, Data nascita ecc legati alla persona fisica?"

In 6.1 questi campi erano aggiunti da l10n_it_account
Per la 7 però probabilmente andrebbero aggiunti al modulo l10n_it_fiscalcode. Questo comporterebbe però dei fastidi nelle migrazioni alla 7: gli stessi campi sono aggiunti in 6.1 da un modulo e in 7.0 da un altro. Si potrebbe gestire con degli script di migrazione.

Revision history for this message
Lorenzo Battistini (elbati) wrote :

On 03/13/2014 09:24 AM, Antonio M. - Zeroincombenze wrote:
> Colgo l'occasione per segnalare che nella tabella abbiamo aggiunto anche
> 2 campi per il SEPA (paese aderente a SEPA e data di accesso),

I moduli SEPA e bancari in generale sono qua
https://launchpad.net/banking-addons

246. By Alessandro Camilli
Revision history for this message
Alessandro Camilli (a-camilli) wrote :

> Ciao Alessandro, grazie ancora per il modulo :-)
>
>
> Negli header potresti aggiungere il copyright dell'associazione?
>
> # Copyright (C) 2014
> # Associazione OpenERP Italia (<http://www.openerp-italia.org>)
>
> Ovviamente se vuoi puoi anche aggiungere il tuo
>
>
> riga 64: come website, piuttosto che niente, potresti mettere http://www
> .openerp-italia.org ?
ok
>
>
> righe 163, 168 e forse altre: vedo un carattere probabilmente non unicode
>
ok
>
> Campi che usano il metodo _tot_operation_number: hai usato store=True. Visto
> che il ricalcolo dipende anche dal campo 'line_BL_ids', è sufficiente mettere
> store=True, o è necessario specificare il dizionario con almeno le due chiavi
> 'spesometro.comunicazione' e 'spesometro.comunicazione.line.bl'?
> In altre parole, modificando campi di 'spesometro.comunicazione.line.bl', i
> campi 'totale_FA' etc vengono ricalcolati?
>
Sinceramente non ho capito. Vorrei che ogni volta che viene salvata la comunicazione vengano ricalcolati i totali di tutti i quadri
>
> riga 320 e siccessive: il parse a int è necessario?
Prima occorre sommare i valori considerando i decimali
>
>
> riga 1375: _default è necessario?
>
ok
>
> riga 1508: pdb (a cosa serve wizard.spesometro.default ? )
>
ok.. residui di debug ;-)
>
> riga 1604 : serve?
ok

Revision history for this message
Alessandro Camilli (a-camilli) wrote :

Nell'ultimo push oltre ai suggerimenti di Lorenzo, ho aggiunto la gestione del "Documento riepilogativo" usato principalmente per la scheda carburante.

Revision history for this message
Lorenzo Battistini (elbati) wrote :

> Sinceramente non ho capito. Vorrei che ogni volta che viene salvata la comunicazione vengano ricalcolati i totali di tutti i quadri

Se le righe della comunicazione vengono modificate sempre e solo tramite
il form della comunicazione, allora dovrebbe funzionare anche solo con
store=True (invece di store = dizionario
<https://doc.openerp.com/6.1/developer/03_modules_2/#store-parameter>)

>> riga 320 e siccessive: il parse a int è necessario?
> Prima occorre sommare i valori considerando i decimali

Voglio dire: perchè invece di

'attive_imponibile_non_esente': int(line.attive_imponibile_non_esente),

non usare

'attive_imponibile_non_esente': line.attive_imponibile_non_esente,

?

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Sto esaminando il codice
Ho alcune domanda da fare ad Alessandro

    1) Anagrafica partner. Il significato del campo campo spesometro_escludi è chiaro ma gli altri? Mi pare di capire che spesometro_operazione serva a stabilire se il soggetto è italiano (quadro FA), se il soggetto è straniero (vari quadri BL). In questo caso mancherebbe la dichirazione per la Repubblica di San Marino e sarebbe opportuno inserire un indicazione di soggetto riepilogativo di spese (Scheda Carburanti).
    2) Anagrafica partner. Il limite importo non è un attributo del partner ma della singola operazione. Ad esempio, un soggetto italiano potrebbe effettuare 3 acquisti con fattura da corrispettivi, ciascun da 2.000 euro. Nessuna delle 3 operazioni è soggetta a spesometro ma se totalizziamo l'importo diventa 6.000 euro ed entrebebe in elenco?

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Alessando,
in crezione di una nuova comunicazione sarebbe opportuno effettuare il controllo della partita IVA e del codice fiscale, altrimenti c'è il serio rischio del rifiuto della comunicazione.

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Altra segnalazione:
L'anno della dichiarazione non è l'anno fiscale ma l'anno solare. Io ho aziende che hanno l'esercizio contabile dal 1-luglio al 30-giugno ma la dichiarazione dello spesometro è comunque relativa all'anno 2013.
Idem quando di parlerà di black-list e altro.

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Creazione comunicazione -> Soggetto tenuto alla comunicazione
La dicitura "Tipo fornitore" è errata. La dicitura esatta è "Tipo fornitura"

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Creazione conunicazione -> Incaricato alla trasmissione
Quando si seleziona in "Impegno alla trasmissione" appare la partita IVA della contribuente o del del soggeto obbligato.
Errore: le istruioni ministriale dicono
"Dato obbligatorio se presente un altro dato nella sezione.
Dato obbligatorio se il campo 4 del record A è uguale a 10."
ovvero obbligatorio se l'invio è a cario di un intermediario e qui va dichiarato il codice fiscale o la partita IVA dell'intermediario.
La copia invece sarebbe utilissima per copiare i dati da "Soggetto obbligato" a "Soggetto tenuto alla comunicazione" che solitamente coincidono.

Grazie

PS scusa per le tante segnalazioni

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Abbiamo scaricato la versione modificata per la V7.0
https://code.launchpad.net/~zeroincombenze/openobject-italia/7.0-base-spesometro
Non ci sono altre modifiche, in modo da mantenere la sincornia con il lavoro di Alessando, che ringrazio per i consigli su l'uso di Launchpad e altro.

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Problemone o problemino!

Il programma va in errore sulla funzione .format con errore
zero length field name in format

Cercando nella documentazione abbiamo scoperto che la forma usata nel software richiede python 2.7 mentre noi stiamo utilizzando la V2.6.9

Domanda:
OpenERP richiede la V2.7 di python, oppure esistono installazioni con la V2.6.x ?
Nel primo caso ci aggiorneremo noi ma se esistono versioni con python più vecchio andiamo incontro a tanti problemi.

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Mi sono informato
Qui ha risposto Davide
http://help.openerp.com/question/3466/which-python-version-is-recommended/
Qui c'è la risposta ufficiale di OpenERP
https://doc.openerp.com/v6.0/install/linux/server/
La minima versione di python richiesta è la 2.5 (secondo OpenERP) e la 2.6 (secondo Davide)

Abbaimo risocntrato anche un'altra anomalia: i campi non valorizzati hanno il valore False in 7.0 mentre probabilmente in V6.1 era vuoto. Tutte le funzioni che operano su questi campi, ad esempio len(), vanno in errore.

Revision history for this message
Davide Corio (enlightx-deactivatedaccount) wrote :

On 14 Mar 2014, at 17:39, Antonio M. - Zeroincombenze <email address hidden> wrote:

> Problemone o problemino!
>
> Il programma va in errore sulla funzione .format con errore
> zero length field name in format
>
> Cercando nella documentazione abbiamo scoperto che la forma usata nel software richiede python 2.7 mentre noi stiamo utilizzando la V2.6.9
>
> Domanda:
> OpenERP richiede la V2.7 di python, oppure esistono installazioni con la V2.6.x ?
> Nel primo caso ci aggiorneremo noi ma se esistono versioni con python più vecchio andiamo incontro a tanti problemi.

Il supporto a Python 2.6 sarebbe opportuno, anche se pochi sistemi lo usano, penso solo più Centos/RedHat.

Anche le linee guida OCA lo prevedono.

--
Davide Corio
<email address hidden>

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Per oggi smettimao qui.
Innanzitutto un grande ringrazimanro ad Alessandro; mi rendo conot che le tante segnalazioi potrebbero apparire come una critica. Il modulo è molto bello anche se c'è ancora molto da fare per migliorarlo.

Bravo Alessandro!

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Dovresti inserire la tua risposta qui
https://code.launchpad.net/~a-camilli/openobject-italia/6.1-spesometro/+merge/210439

Il 14/03/2014 17:51, Davide Corio @ LS ha scritto:
> On 14 Mar 2014, at 17:39, Antonio M. - Zeroincombenze <email address hidden> wrote:
>
>> Problemone o problemino!
>>
>> Il programma va in errore sulla funzione .format con errore
>> zero length field name in format
>>
>> Cercando nella documentazione abbiamo scoperto che la forma usata nel software richiede python 2.7 mentre noi stiamo utilizzando la V2.6.9
>>
>> Domanda:
>> OpenERP richiede la V2.7 di python, oppure esistono installazioni con la V2.6.x ?
>> Nel primo caso ci aggiorneremo noi ma se esistono versioni con python più vecchio andiamo incontro a tanti problemi.
> Il supporto a Python 2.6 sarebbe opportuno, anche se pochi sistemi lo usano, penso solo più Centos/RedHat.
>
> Anche le linee guida OCA lo prevedono.
>
> --
> Davide Corio
> <email address hidden>
>
>

--

Antonio M. Vigliotti
(Presidente & Chief Technical Officer)

*SHS-AV s.r.l. (impresa innovativa)
zeroincombenze®
*

Via Domodossola, 64 - 10145 TORINO - ITALY

Tel. (+39) 011.0566929(2)

www.shs-av.com

PEC <email address hidden>

247. By Alessandro Camilli

Gestione Anno solare - Limite su operazioni - Correzioni varie

Revision history for this message
Alessandro Camilli (a-camilli) wrote :

Ciao Antonio e grazie delle segnalazioni!
In questo aggiornamento ho modificato la logica dei periodi ( ora totalmente staccata dall'anno fiscale).
> Creazione conunicazione -> Incaricato alla trasmissione
> Quando si seleziona in "Impegno alla trasmissione" appare la partita IVA della
> contribuente o del del soggeto obbligato.
> Errore: le istruioni ministriale dicono
> "Dato obbligatorio se presente un altro dato nella sezione.
> Dato obbligatorio se il campo 4 del record A è uguale a 10."
> ovvero obbligatorio se l'invio è a cario di un intermediario e qui va
> dichiarato il codice fiscale o la partita IVA dell'intermediario.
> La copia invece sarebbe utilissima per copiare i dati da "Soggetto obbligato"
> a "Soggetto tenuto alla comunicazione" che solitamente coincidono.
--> Fatto

>Creazione comunicazione -> Soggetto tenuto alla comunicazione
>La dicitura "Tipo fornitore" è errata. La dicitura esatta è "Tipo fornitura"
Sicuro? Io nella documentazione che ho sul tracciato ho proprio "tipo fornitore"

>1) Anagrafica partner. Il significato del campo campo spesometro_escludi è chiaro ma gli altri? Mi >pare di capire che spesometro_operazione serva a stabilire se il soggetto è italiano (quadro FA), se >il soggetto è straniero (vari quadri BL). In questo caso mancherebbe la dichirazione per la >Repubblica di San Marino e sarebbe opportuno inserire un indicazione di soggetto riepilogativo di >spese (Scheda Carburanti).
Per la scheda carburante ho aggiunto il campo "documento riepilogativo".
Per San Marino dici di gestire i record SE? Posso metterli insieme a quelli della comunicazione aggregata?

>2) Anagrafica partner. Il limite importo non è un attributo del partner ma della singola operazione. >Ad esempio, un soggetto italiano potrebbe effettuare 3 acquisti con fattura da corrispettivi, ciascun >da 2.000 euro. Nessuna delle 3 operazioni è soggetta a spesometro ma se totalizziamo l'importo diventa >6.000 euro ed entrebebe in elenco?
Fatto. Ho aggiunto 2 tipi di limiti per ogni quadro, quello totale e quello x singola operazione

Quindi resta da fare:
- Il quadro x San Marino
- Eventuale controllo della PIVA e codice fiscale.

Poi se trovi altre cose fammi sapere ;-)

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :
Download full text (3.5 KiB)

Bravo Alessandro,
ottimo lavoro veramente straordinario.

Per l'incompatibilità con python 2.6, se posso permettermi, coglierei l'occasione per rivedere il codice anche in funzione degli sviluppi futuri, visto che vuoi introdurre anche la dichiarazione analitica.
Soltanto a titolo di esempio, ovviamente puoi operare come meglio credi, ti propongo, un pezzo di codice del software estratto dal mio precedente gestionale.
Questa parte di codice inserisce un valore del campi formattando secondo le specifiche ministeriali e può essere usato in qualsiasi quadro; in questo modo non è necessario ripetere le stesse istruzioni in ogni quadro e si può utilizzare nei record C, D e anche E; inoltre si avrebbe un punto di scrittura comune per tutti (anche per debug).
Ho fatto una rapida simil-traduzione in python, come ho detto è soltanto un codice di esempio

#
# Extract from Italian Agenzia delle Entrate (Revenue Agency), here AdE standard
# format_id: means how field if formatted
# pic: public section; may be “FA”, “BL”, “SE”, etc
# prog_sezione: section index
# val_id: index to value from Ade standard
# val: value to insert in file
# parter_id: in order to extrat partner info from record
#
# AdE standard is: pic (2 chars), prog_sezione (3 digit, zero left filled),
# val_id (3 digit, zero left filled, val (16 chars)
# val may be one of
# string text: left align, space filled -> i.e. 'FOO '
# combobox: value '1' right align, space filled -> i.e. ' 1'
# numeric: right align, space filled -> i.e. ' 123'
# date: day (2 digit), month (2 digit), year (4 digit) -> i.e. '26061959'
#
add_1_field (format_id, pic, prog_sezione, val_id, val, partner_id)

    rcd += '{0:2s}'.format(pic)
    rcd += '{0:3d}'.format(prog_sezione)
    rcd += '{0:3d}'.format(val_id)
    if format_id == 'AN':
    # Text -> if is longer than 16 chars, will be splitted in 2 o more fields
 if val.len > 16:
     _split_string_positional_field(self, val)
 else:
     rcd += '{0:16s}'.format(val)
    elif format_id == 'CB':
    # Combobox -> if false do nothing, if true set value ' 1 '
      if val_id:
     rcd += '{0:16d}'.format(val)
    elif format_id == 'NP':
    # Positive number -> right align, space filled
 rcd += '{0:16d}' ….
    elif format_id == 'CF':
    # Fiscal code -> May of vatnumber too, left align
 rcd += '{0:16s}'.format(val)
    elif format_id == 'DT':
    # Birthday, extracted by parter_id -> day, month, year, left align
 rcd += '{0:16s}' ….
    elif format_id == 'PN':
    # Born district, extracted by parter_id -> 2 chars, left align
 rcd += '{0:16s}' ….
    elif format_id == 'r1':
    # Name, extracted by parter_id -> 2 chars, left align
 rcd += '{0:16s}' ….
    elif format_id == 'r3':
    # Born in city, extracted by parter_id -> 2 chars, left align
 rcd += '{0:16s}' ….
    elif format_id == 'r4':
    # Live in city, extracted by parter_id -> 2 chars, left align
 rcd += '{0:16s}' ….
    elif format_id == 'r5':
    # Live in country, extracted by parter_id -> 2 chars, left align
    # Warning: code extracted by res.country of l10n_it_base v7.0.02 (2014)
    # Warning: it is a numeric code, right align space filled but …
    # must be...

Read more...

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :
Download full text (3.2 KiB)

> Ciao Antonio e grazie delle segnalazioni!
> In questo aggiornamento ho modificato la logica dei periodi ( ora totalmente
> staccata dall'anno fiscale).
> > Creazione conunicazione -> Incaricato alla trasmissione
> > Quando si seleziona in "Impegno alla trasmissione" appare la partita IVA
> della
> > contribuente o del del soggeto obbligato.
> > Errore: le istruioni ministriale dicono
> > "Dato obbligatorio se presente un altro dato nella sezione.
> > Dato obbligatorio se il campo 4 del record A è uguale a 10."
> > ovvero obbligatorio se l'invio è a cario di un intermediario e qui va
> > dichiarato il codice fiscale o la partita IVA dell'intermediario.
> > La copia invece sarebbe utilissima per copiare i dati da "Soggetto
> obbligato"
> > a "Soggetto tenuto alla comunicazione" che solitamente coincidono.
> --> Fatto
>
> >Creazione comunicazione -> Soggetto tenuto alla comunicazione
> >La dicitura "Tipo fornitore" è errata. La dicitura esatta è "Tipo fornitura"
> Sicuro? Io nella documentazione che ho sul tracciato ho proprio "tipo
> fornitore"
Hai ragione è la dicitura utilizzata dalla AdE però induce all'errore. Infatti, dal punto di vista della AdE che presenta la dichiarazione è il fornitore; dal punto di vista dell'utente che usa il software, il fornitore è uno dei tanti soggetti da cui ha ricevuto fattura.
Io userei "Tipo fornitura"

>
> >1) Anagrafica partner. Il significato del campo campo spesometro_escludi è
> chiaro ma gli altri? Mi >pare di capire che spesometro_operazione serva a
> stabilire se il soggetto è italiano (quadro FA), se >il soggetto è straniero
> (vari quadri BL). In questo caso mancherebbe la dichirazione per la
> >Repubblica di San Marino e sarebbe opportuno inserire un indicazione di
> soggetto riepilogativo di >spese (Scheda Carburanti).
> Per la scheda carburante ho aggiunto il campo "documento riepilogativo".
> Per San Marino dici di gestire i record SE? Posso metterli insieme a quelli
> della comunicazione aggregata?
Se te la devo tutta non mi piace la classificazione che hai adottato in quanto presenta problemi di varia natura.
Dal punto di vista della comunicazione un soggetto (cliente o fornitore) va evidenziato se appartiene a particolari classificazioni Gerico
Nella documentazione collegata al BP ho inserito un capitolo sulla classificazione Gerico
http://www.zeroincombenze.org/wiki/Analisi_Spesometro
Inoltre l'esclusione per intrastat e RSM dovrebbe derivare direttamente dall'anagrafica partner
Per quanto riguarda i soggetti BL la tabella re.country è stata da noi modificata ad hoc ma andrebbe bene anche come hai fatto ora con la classificazione "BL"
>
> >2) Anagrafica partner. Il limite importo non è un attributo del partner ma
> della singola operazione. >Ad esempio, un soggetto italiano potrebbe
> effettuare 3 acquisti con fattura da corrispettivi, ciascun >da 2.000 euro.
> Nessuna delle 3 operazioni è soggetta a spesometro ma se totalizziamo
> l'importo diventa >6.000 euro ed entrebebe in elenco?
> Fatto. Ho aggiunto 2 tipi di limiti per ogni quadro, quello totale e quello x
> singola operazione
>
> Quindi resta da fare:
> - Il quadro x San Marino
> - Eventuale controllo della PIVA e codice fisca...

Read more...

Revision history for this message
Alessandro Camilli (a-camilli) wrote :

Ciao Antonio,
gli acquisti da San Marino vanno solo su comunicazioni mensili analitiche?

Vuol dire che posso fare la comunicazione aggregata senza le comunicazioni di San Marino e poi queste mandarle un una comunicazione a parte?

Grazie

248. By Alessandro Camilli

Aggiunto documento riepilogativo e corretto export su periodo

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

> Ciao Antonio,
> gli acquisti da San Marino vanno solo su comunicazioni mensili analitiche?
>
> Vuol dire che posso fare la comunicazione aggregata senza le comunicazioni di
> San Marino e poi queste mandarle un una comunicazione a parte?
>
> Grazie
Confermo. Gli acquisti da RSM devono essere scartati per lo spesomentro vero e proprio ma inseriti nella comunicazione relativa ad acquisti da RSM

Revision history for this message
Antonio M. - Zeroincombenze (zeroincombenze) wrote :

Oggi è emerso un altro problema, importante dal punto di fiscale:
la fattura non va trattata per interno ma per ciascuna norma fiscale.

Esempio:
Fattura da fornitore xyz, per 125 euro
Parte imponibile 100 euro, con 22% IVA pari a 22 euro
Escluso art. 15 per 3 euro

Totale fattura: 100 (imponibile) + 22 (IVA) + 3 (escluso) = 125 Euro
Somme da riportare in elenco:
Imponibile 100 euro con relativa IVA da 22 Euro.
L'importo da 3 euro NON VA in elenco.

Ci sono casi con importi esclusi, fuori campo IVA o non soggeti di valore molto importante

249. By Alessandro Camilli

Gestione San Marino e quadro analitico SE - Corretto calcolo imponibili e imposta

Revision history for this message
Alessandro Camilli (a-camilli) wrote :

Ciao Lorenze
> > Sinceramente non ho capito. Vorrei che ogni volta che viene salvata la
> comunicazione vengano ricalcolati i totali di tutti i quadri
>
> Se le righe della comunicazione vengono modificate sempre e solo tramite
> il form della comunicazione, allora dovrebbe funzionare anche solo con
> store=True (invece di store = dizionario
> <https://doc.openerp.com/6.1/developer/03_modules_2/#store-parameter>)
>
posso averlo fatto senza volerlo ma a me non sembra di usare il dizionario. Oppure mi sa che mi sono perso qualcosa nell'uso di queste funzioni...
>
> >> riga 320 e siccessive: il parse a int è necessario?
> > Prima occorre sommare i valori considerando i decimali
>
> Voglio dire: perchè invece di
>
> 'attive_imponibile_non_esente': int(line.attive_imponibile_non_esente),
>
> non usare
>
> 'attive_imponibile_non_esente': line.attive_imponibile_non_esente,
>
> ?
per ovviare a questo errore
"rcd += '{:8s}'.format("SE" + prog_sezione + "015" ) + '{:16d}'.format(line.importo)
ValueError: Unknown format code 'd' for object of type 'float'
Ora ho tolto int() e cambiato la formattazione usando {:16.0f} anzichè {:16d}.
Spero in giornata di pubblicare le modifiche

250. By Alessandro Camilli

export quadro SE -Aggiunte labels e help sui quadri- opzioni x selezione quadri in fase di creazione nuova comunicazione (in futuro quando si richiede al forma anlitica lo si può fare solo x i movimenti che riguardano San Marino) - Aggiunti su db anche gli altri quadri analitici(per ora viene gestito solo quello SE x San Marino)

251. By Alessandro Camilli

Esclusione da dichiarazione su conto imposte

252. By Alessandro Camilli

fix e aggiunto controllo su codice fiscale soggetto tenuto se presente, deve essere diverso da quello del soggetto obbligato

Revision history for this message
Lorenzo Battistini (elbati) wrote :

This project is now hosted on https://github.com/OCA/l10n-italy. Please move your proposal there. This guide may help you https://github.com/OCA/maintainers-tools/wiki/How-to-move-a-Merge-Proposal-to-GitHub

Unmerged revisions

252. By Alessandro Camilli

fix e aggiunto controllo su codice fiscale soggetto tenuto se presente, deve essere diverso da quello del soggetto obbligato

251. By Alessandro Camilli

Esclusione da dichiarazione su conto imposte

250. By Alessandro Camilli

export quadro SE -Aggiunte labels e help sui quadri- opzioni x selezione quadri in fase di creazione nuova comunicazione (in futuro quando si richiede al forma anlitica lo si può fare solo x i movimenti che riguardano San Marino) - Aggiunti su db anche gli altri quadri analitici(per ora viene gestito solo quello SE x San Marino)

249. By Alessandro Camilli

Gestione San Marino e quadro analitico SE - Corretto calcolo imponibili e imposta

248. By Alessandro Camilli

Aggiunto documento riepilogativo e corretto export su periodo

247. By Alessandro Camilli

Gestione Anno solare - Limite su operazioni - Correzioni varie

246. By Alessandro Camilli
245. By Alessandro Camilli

Spesometro - Tolta la sequenza

244. By Alessandro Camilli

Spesometro - Dati aggregati

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'l10n_it_spesometro'
2=== added file 'l10n_it_spesometro/__init__.py'
3--- l10n_it_spesometro/__init__.py 1970-01-01 00:00:00 +0000
4+++ l10n_it_spesometro/__init__.py 2014-04-03 06:37:29 +0000
5@@ -0,0 +1,23 @@
6+# -*- coding: utf-8 -*-
7+##############################################################################
8+#
9+# Author: Alessandro Camilli (a.camilli@yahoo.it)
10+# Copyright (C) 2014
11+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
12+#
13+# This program is free software: you can redistribute it and/or modify
14+# it under the terms of the GNU Affero General Public License as published
15+# by the Free Software Foundation, either version 3 of the License, or
16+# (at your option) any later version.
17+#
18+# This program is distributed in the hope that it will be useful,
19+# but WITHOUT ANY WARRANTY; without even the implied warranty of
20+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+# GNU General Public License for more details.
22+#
23+# You should have received a copy of the GNU Affero General Public License
24+# along with this program. If not, see <http://www.gnu.org/licenses/>.
25+#
26+##############################################################################
27+import spesometro
28+import wizard
29\ No newline at end of file
30
31=== added file 'l10n_it_spesometro/__openerp__.py'
32--- l10n_it_spesometro/__openerp__.py 1970-01-01 00:00:00 +0000
33+++ l10n_it_spesometro/__openerp__.py 2014-04-03 06:37:29 +0000
34@@ -0,0 +1,49 @@
35+# -*- coding: utf-8 -*-
36+##############################################################################
37+#
38+# Author: Alessandro Camilli (a.camilli@yahoo.it)
39+# Copyright (C) 2014
40+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
41+#
42+# This program is free software: you can redistribute it and/or modify
43+# it under the terms of the GNU Affero General Public License as published
44+# by the Free Software Foundation, either version 3 of the License, or
45+# (at your option) any later version.
46+#
47+# This program is distributed in the hope that it will be useful,
48+# but WITHOUT ANY WARRANTY; without even the implied warranty of
49+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+# GNU General Public License for more details.
51+#
52+# You should have received a copy of the GNU Affero General Public License
53+# along with this program. If not, see <http://www.gnu.org/licenses/>.
54+#
55+##############################################################################
56+{
57+ 'name': 'Spesometro - Comunicazione art.21',
58+ 'version': '0.2',
59+ 'category': 'Localisation/Italy',
60+ 'description': """Spesometro - Comunicazione art.21
61+
62+Functionalities:
63+- Creazione comunicazione art.21 in forma Aggregata
64+- Export file per agenzia delle entrate
65+
66+""",
67+ 'author': 'Alessandro Camilli',
68+ 'website': 'http://www.openerp-italia.org',
69+ 'license': 'AGPL-3',
70+ "depends" : ['account', 'l10n_it_base', 'l10n_it_account'],
71+ "data" : [
72+ 'security/ir.model.access.csv',
73+ 'spesometro_view.xml',
74+ 'wizard/wizard_crea_comunicazione_view.xml',
75+ 'wizard/wizard_default_view.xml',
76+ 'wizard/wizard_export_view.xml',
77+ ],
78+ "demo" : [],
79+ "active": False,
80+ "installable": True
81+}
82+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
83+
84
85=== added directory 'l10n_it_spesometro/security'
86=== added file 'l10n_it_spesometro/security/ir.model.access.csv'
87--- l10n_it_spesometro/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
88+++ l10n_it_spesometro/security/ir.model.access.csv 2014-04-03 06:37:29 +0000
89@@ -0,0 +1,11 @@
90+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
91+spesometro_comunicazione_user,spesometro_comunicazione user,model_spesometro_comunicazione,base.group_user,1,0,0,0
92+spesometro_comunicazione_manager,spesometro_comunicazione manager,model_spesometro_comunicazione,account.group_account_manager,1,1,1,1
93+spesometro_comunicazione_line_fa_user,spesometro_comunicazione_line_fa user,model_spesometro_comunicazione_line_fa,base.group_user,1,0,0,0
94+spesometro_comunicazione_line_fa_manager,spesometro_comunicazione_line_fa manager,model_spesometro_comunicazione_line_fa,account.group_account_manager,1,1,1,1
95+spesometro_comunicazione_line_bl_user,spesometro_comunicazione_line_bl user,model_spesometro_comunicazione_line_bl,base.group_user,1,0,0,0
96+spesometro_comunicazione_line_bl_manager,spesometro_comunicazione_line_bl manager,model_spesometro_comunicazione_line_bl,account.group_account_manager,1,1,1,1
97+spesometro_comunicazione_line_sa_user,spesometro_comunicazione_line_sa user,model_spesometro_comunicazione_line_sa,base.group_user,1,0,0,0
98+spesometro_comunicazione_line_sa_manager,spesometro_comunicazione_line_sa manager,model_spesometro_comunicazione_line_sa,account.group_account_manager,1,1,1,1
99+spesometro_configurazione_user,spesometro_configurazione user,model_spesometro_configurazione,base.group_user,1,0,0,0
100+spesometro_configurazione_manager,spesometro_configurazione manager,model_spesometro_configurazione,account.group_account_manager,1,1,1,1
101\ No newline at end of file
102
103=== added file 'l10n_it_spesometro/spesometro.py'
104--- l10n_it_spesometro/spesometro.py 1970-01-01 00:00:00 +0000
105+++ l10n_it_spesometro/spesometro.py 2014-04-03 06:37:29 +0000
106@@ -0,0 +1,1280 @@
107+# -*- coding: utf-8 -*-
108+##############################################################################
109+#
110+# Author: Alessandro Camilli (a.camilli@yahoo.it)
111+# Copyright (C) 2014
112+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
113+#
114+# This program is free software: you can redistribute it and/or modify
115+# it under the terms of the GNU Affero General Public License as published
116+# by the Free Software Foundation, either version 3 of the License, or
117+# (at your option) any later version.
118+#
119+# This program is distributed in the hope that it will be useful,
120+# but WITHOUT ANY WARRANTY; without even the implied warranty of
121+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
122+# GNU General Public License for more details.
123+#
124+# You should have received a copy of the GNU Affero General Public License
125+# along with this program. If not, see <http://www.gnu.org/licenses/>.
126+#
127+##############################################################################
128+
129+from osv import fields, orm
130+from openerp.tools.translate import _
131+import decimal_precision as dp
132+import datetime, time
133+
134+class res_country(orm.Model):
135+ _inherit = "res.country"
136+ _columns = {
137+ 'codice_stato_agenzia_entrate': fields.char('Codice stato Agenzia Entrate', size=3)
138+ }
139+
140+class account_tax_code(orm.Model):
141+ _inherit = "account.tax.code"
142+ _columns = {
143+ 'spesometro_escludi': fields.boolean('Escludi dalla dichiarazione'),
144+ }
145+
146+ _defaults = {
147+ 'spesometro_escludi' : False,
148+ }
149+
150+class account_journal(orm.Model):
151+ _inherit = "account.journal"
152+ _columns = {
153+ 'spesometro': fields.boolean('Da includere'),
154+ 'spesometro_operazione': fields.selection((('FA','Operazioni documentate da fattura'),
155+ ('SA','Operazioni senza fattura'),
156+ ('BL1','Operazioni con paesi con fiscalità privilegiata'),
157+ ('BL2','Operazioni con soggetti non residenti'),
158+ ('BL3','Acquisti di servizi da soggetti non residenti'),
159+ ('DR','Documento Riepilogativo')),
160+ 'Operazione' ),
161+ 'spesometro_segno': fields.selection((('attiva','Attiva'),
162+ ('passiva','Passiva')),
163+ 'Segno operaz.' ),
164+ 'spesometro_IVA_non_esposta': fields.boolean('IVA non esposta')
165+ }
166+
167+class res_partner(orm.Model):
168+ _inherit = "res.partner"
169+ _columns = {
170+ 'spesometro_escludi': fields.boolean('Escludi'),
171+ 'spesometro_operazione': fields.selection((('FA','Operazioni documentate da fattura'),
172+ ('SA','Operazioni senza fattura'),
173+ ('BL1','Operazioni con paesi con fiscalità privilegiata'),
174+ ('BL2','Operazioni con soggetti non residenti'),
175+ ('BL3','Acquisti di servizi da soggetti non residenti'),
176+ ('DR','Documento Riepilogativo')),
177+ 'Operazione' ),
178+ 'spesometro_IVA_non_esposta': fields.boolean('IVA non esposta'),
179+ 'spesometro_leasing': fields.selection((('A','Autovettura'),
180+ ('B','Caravan'),
181+ ('C','Altri veicoli'),
182+ ('D','Unità da diporto'),
183+ ('E','Aeromobili')),
184+ 'Tipo Leasing' ),
185+ 'spesometro_tipo_servizio': fields.selection((('cessione','Cessione Beni'),
186+ ('servizi','Prestazione di servizi')),
187+ 'Tipo servizio', help="Specificare per 'Operazioni con paesi con fiscalità privilegiata' "),
188+ 'spesometro_indirizzo_estero': fields.many2one('res.partner.address', 'Indirizzo non residente'),
189+ }
190+
191+ _defaults = {
192+ 'spesometro_escludi' : False,
193+ }
194+
195+class spesometro_configurazione(orm.Model):
196+
197+ def _check_one_year(self, cr, uid, ids, context=None):
198+ for element in self.browse(cr, uid, ids, context=context):
199+ element_ids = self.search(cr, uid, [('anno','=', element.anno)], context=context)
200+ if len(element_ids) > 1:
201+ return False
202+ return True
203+
204+ _name = "spesometro.configurazione"
205+ _description = "Spesometro - Configurazione"
206+ _columns = {
207+ 'anno': fields.integer('Anno', size=4, required=True ),
208+ 'stato_san_marino': fields.many2one('res.country', 'Stato San Marino', required=True),
209+ 'quadro_fa_limite_importo': fields.float('Quadro FA - Limite importo'),
210+ 'quadro_fa_limite_importo_line': fields.float('Quadro FA - Limite importo singola operaz.'),
211+ 'quadro_sa_limite_importo': fields.float('Quadro SA - Limite importo'),
212+ 'quadro_sa_limite_importo_line': fields.float('Quadro SA - Limite importo singola operaz.'),
213+ 'quadro_bl_limite_importo': fields.float('Quadro BL - Limite importo'),
214+ 'quadro_bl_limite_importo_line': fields.float('Quadro BL - Limite importo singola operaz.'),
215+ 'quadro_se_limite_importo_line': fields.float('Quadro SE - Limite importo singola operaz.'),
216+ }
217+ _constraints = [
218+ (_check_one_year, 'Error! Config for this year already exists.', ['anno']),
219+ ]
220+
221+class spesometro_comunicazione(orm.Model):
222+
223+ _name = "spesometro.comunicazione"
224+ _description = "Spesometro - Comunicazione "
225+
226+ def _tot_operation_number(self, cr, uid, ids, field_names, args, context=None):
227+ res = {}
228+ for com in self.browse(cr, uid, ids):
229+ # Aggregate
230+ tot_FA = len(com.line_FA_ids)
231+ tot_SA = len(com.line_SA_ids)
232+ tot_BL1 = 0
233+ tot_BL2 = 0
234+ tot_BL3 = 0
235+ for line in com.line_BL_ids:
236+ if line.operazione_fiscalita_privilegiata:
237+ tot_BL1 += 1
238+ elif line.operazione_con_soggetti_non_residenti:
239+ tot_BL2 += 1
240+ elif line.Acquisto_servizi_da_soggetti_non_residenti:
241+ tot_BL3 += 1
242+ #Analitiche
243+ tot_FE = 0 # Fatture emesse
244+ tot_FE_R = 0 # Doc riepilogativi
245+ for line in com.line_FE_ids:
246+ if line.documento_riepilogativo:
247+ tot_FE_R += 1
248+ else:
249+ tot_FE += 1
250+ tot_FR = 0 # Fatture ricevute
251+ tot_FR_R = 0 # Doc riepilogativi ricevuti
252+ for line in com.line_FR_ids:
253+ if line.documento_riepilogativo:
254+ tot_FR_R += 1
255+ else:
256+ tot_FR += 1
257+ tot_NE = len(com.line_NE_ids)
258+ tot_NR = len(com.line_NR_ids)
259+ tot_DF = len(com.line_DF_ids)
260+ tot_FN = len(com.line_FN_ids)
261+ tot_SE = len(com.line_SE_ids)
262+ tot_TU = len(com.line_TU_ids)
263+
264+ res[com.id] = {
265+ 'totale_FA' : tot_FA,
266+ 'totale_SA' : tot_SA,
267+ 'totale_BL1' : tot_BL1,
268+ 'totale_BL2' : tot_BL2,
269+ 'totale_BL3' : tot_BL3,
270+ 'totale_FE' : tot_FE,
271+ 'totale_FE_R' : tot_FE_R,
272+ 'totale_FR' : tot_FR,
273+ 'totale_FR_r' : tot_FR_R,
274+ 'totale_NE' : tot_NE,
275+ 'totale_NR' : tot_NR,
276+ 'totale_DF' : tot_DF,
277+ 'totale_FN' : tot_FN,
278+ 'totale_SE' : tot_SE,
279+ 'totale_TU' : tot_TU,
280+ }
281+ return res
282+
283+ _columns = {
284+ 'company_id': fields.many2one('res.company', 'Azienda', required=True ),
285+ 'periodo': fields.selection((('anno','Annuale'), ('trimestre','Trimestrale'), ('mese','Mensile')),
286+ 'Periodo', required=True),
287+ 'anno' : fields.integer('Anno', size=4, required=True),
288+ 'trimestre' : fields.integer('Trimestre', size=1 ),
289+ 'mese' : fields.selection((('1','Gennaio'), ('2','Febbraio'), ('3','Marzo'), ('4','Aprile'),
290+ ('5','Maggio'), ('6','Giugno'), ('7','Luglio'), ('8','Agosto'),
291+ ('9','Settembre'), ('10','Ottobre'), ('11','Novembre'), ('12','Dicembre'),
292+ ),'Mese'),
293+ 'tipo': fields.selection((('ordinaria','Ordinaria'), ('sostitutiva','Sostitutiva'), ('annullamento','Annullamento')),
294+ 'Tipo comunicazione', required=True),
295+ 'comunicazione_da_sostituire_annullare': fields.integer('Protocollo comunicaz. da sostituire/annullare'),
296+ 'documento_da_sostituire_annullare': fields.integer('Protocollo documento da sostituire/annullare'),
297+
298+ 'formato_dati': fields.selection((('aggregati','Dati Aggregati'), ('analitici','Dati Analitici')),
299+ 'Formato dati', readonly=True ),
300+
301+ 'codice_fornitura': fields.char('Codice fornitura', readonly=True, size=5, help='Impostare a "NSP00" '),
302+ 'tipo_fornitore': fields.selection((('01','Invio propria comunicazione'), ('10','Intermediario')),
303+ 'Tipo fornitore' ),
304+ 'codice_fiscale_fornitore': fields.char('Codice fiscale Fornitore', size=16,
305+ help="Deve essere uguale al Codice fiscale dell'intermediario (campo 52 del record B) se presente, altrimenti al Codice fiscale del soggetto tenuto alla comunicazione (campo 41 del record B) se presente, altrimenti al Codice fiscale del soggetto obbligato (campo 2 del record B)"),
306+ #
307+ # Valori per comunicazione su più invii (non gestito)
308+ 'progressivo_telematico': fields.integer('Progressivo telematico', readonly=True),
309+ 'numero_totale_invii': fields.integer('Numero totale invii telematici', readonly=True),
310+ #
311+ # Soggetto a cui si riferisce la comunicazione
312+ #
313+ 'soggetto_codice_fiscale': fields.char('Codice fiscale soggetto obbligato', size=16,
314+ help="Soggetto cui si riferisce la comunicazione"),
315+ 'soggetto_partitaIVA': fields.char('Partita IVA', size=11),
316+ 'soggetto_codice_attivita': fields.char('Codice attività', size=6, help="Codice ATECO 2007"),
317+ 'soggetto_telefono': fields.char('Telefono', size=12),
318+ 'soggetto_fax': fields.char('Fax', size=12),
319+ 'soggetto_email': fields.char('E-mail', size=50),
320+ 'soggetto_forma_giuridica': fields.selection((('persona_giuridica','Persona Giuridica'), ('persona_fisica','Persona Fisica')),
321+ 'Forma Giuridica'),
322+
323+ 'soggetto_pf_cognome': fields.char('Cognome', size=24, help=""),
324+ 'soggetto_pf_nome': fields.char('Nome', size=20, help=""),
325+ 'soggetto_pf_sesso': fields.selection((('M','M'), ('F','F')),'Sesso'),
326+ 'soggetto_pf_data_nascita': fields.date('Data di nascita'),
327+ 'soggetto_pf_comune_nascita': fields.char('Comune o stato estero di nascita', size=40),
328+ 'soggetto_pf_provincia_nascita': fields.char('Provincia', size=2),
329+ 'soggetto_pg_denominazione': fields.char('Denominazione', size=60),
330+
331+ # Soggetto tenuto alla comunicazione
332+ 'soggetto_cm_forma_giuridica': fields.selection((('persona_giuridica','Persona Giuridica'), ('persona_fisica','Persona Fisica')),
333+ 'Forma Giuridica'),
334+ 'soggetto_cm_codice_fiscale': fields.char('Codice Fiscale', size=16, help="Soggetto che effettua la comunicazione se diverso dal soggetto tenuto alla comunicazione"),
335+ 'soggetto_cm_pf_cognome': fields.char('Cognome', size=24, help=""),
336+ 'soggetto_cm_pf_nome': fields.char('Nome', size=20, help=""),
337+ 'soggetto_cm_pf_sesso': fields.selection((('M','M'), ('F','F')),'Sesso'),
338+ 'soggetto_cm_pf_data_nascita': fields.date('Data di nascita'),
339+ 'soggetto_cm_pf_comune_nascita': fields.char('Comune o stato estero di nascita', size=40),
340+ 'soggetto_cm_pf_provincia_nascita': fields.char('Provincia', size=2),
341+ 'soggetto_cm_pf_codice_carica': fields.integer('Codice Fiscale', size=2, help=""),
342+ 'soggetto_cm_pf_data_inizio_procedura': fields.date('Data inizio procedura'),
343+ 'soggetto_cm_pf_data_fine_procedura': fields.date('Data fine procedura'),
344+ 'soggetto_cm_pg_denominazione': fields.char('Denominazione', size=60),
345+
346+ # Soggetto incaricato alla trasmissione
347+ 'soggetto_trasmissione_codice_fiscale': fields.char('Codice Fiscale', size=16, help="Intermediario che effettua la trasmissione telematica"),
348+ 'soggetto_trasmissione_numero_CAF': fields.integer('Nr iscrizione albo del C.A.F.', size=5, help="Intermediario che effettua la trasmissione telematica"),
349+ 'soggetto_trasmissione_impegno': fields.selection((('1','Soggetto obbligato'), ('2','Intermediario')),'Impegno trasmissione'),
350+ 'soggetto_trasmissione_data_impegno': fields.date('Data data impegno'),
351+
352+ 'line_FA_ids': fields.one2many('spesometro.comunicazione.line.fa', 'comunicazione_id', 'Quadri FA' ),
353+ 'line_SA_ids': fields.one2many('spesometro.comunicazione.line.sa', 'comunicazione_id', 'Quadri SA' ),
354+ 'line_BL_ids': fields.one2many('spesometro.comunicazione.line.bl', 'comunicazione_id', 'Quadri BL' ),
355+
356+ 'line_FE_ids': fields.one2many('spesometro.comunicazione.line.fe', 'comunicazione_id', 'Quadri FE' ),
357+ 'line_FR_ids': fields.one2many('spesometro.comunicazione.line.fr', 'comunicazione_id', 'Quadri FR' ),
358+ 'line_NE_ids': fields.one2many('spesometro.comunicazione.line.ne', 'comunicazione_id', 'Quadri NE' ),
359+ 'line_NR_ids': fields.one2many('spesometro.comunicazione.line.nr', 'comunicazione_id', 'Quadri NR' ),
360+ 'line_DF_ids': fields.one2many('spesometro.comunicazione.line.df', 'comunicazione_id', 'Quadri DF' ),
361+ 'line_FN_ids': fields.one2many('spesometro.comunicazione.line.fn', 'comunicazione_id', 'Quadri FN' ),
362+ 'line_SE_ids': fields.one2many('spesometro.comunicazione.line.se', 'comunicazione_id', 'Quadri SE' ),
363+ 'line_TU_ids': fields.one2many('spesometro.comunicazione.line.tu', 'comunicazione_id', 'Quadri TU' ),
364+
365+ 'totale_FA': fields.function(_tot_operation_number, string='Tot operazioni FA', type='integer', multi='operation_number'),
366+ 'totale_SA': fields.function(_tot_operation_number, string='Tot operazioni SA', type='integer', multi='operation_number'),
367+ 'totale_BL1': fields.function(_tot_operation_number, string='Tot operazioni BL - Paesi con fiscalita privilegiata', type='integer', multi='operation_number'),
368+ 'totale_BL2': fields.function(_tot_operation_number, string='Tot operazioni BL - Soggetti non residenti', type='integer', multi='operation_number'),
369+ 'totale_BL3': fields.function(_tot_operation_number, string='Tot operazioni BL - Acquisti servizi non soggetti non residenti', type='integer', multi='operation_number'),
370+
371+ 'totale_FE': fields.function(_tot_operation_number, string='Tot operazioni FE', type='integer', multi='operation_number'),
372+ 'totale_FE_R': fields.function(_tot_operation_number, string='Tot operazioni FE doc riepil.', type='integer', multi='operation_number'),
373+ 'totale_FR': fields.function(_tot_operation_number, string='Tot operazioni FR', type='integer', multi='operation_number'),
374+ 'totale_FR_R': fields.function(_tot_operation_number, string='Tot operazioni FR doc riepil.', type='integer', multi='operation_number'),
375+ 'totale_NE': fields.function(_tot_operation_number, string='Tot operazioni NE', type='integer', multi='operation_number'),
376+ 'totale_NR': fields.function(_tot_operation_number, string='Tot operazioni NR', type='integer', multi='operation_number'),
377+ 'totale_DF': fields.function(_tot_operation_number, string='Tot operazioni DF', type='integer', multi='operation_number'),
378+ 'totale_FN': fields.function(_tot_operation_number, string='Tot operazioni FN', type='integer', multi='operation_number'),
379+ 'totale_SE': fields.function(_tot_operation_number, string='Tot operazioni SE', type='integer', multi='operation_number'),
380+ 'totale_TU': fields.function(_tot_operation_number, string='Tot operazioni TU', type='integer', multi='operation_number'),
381+ }
382+
383+ _default ={
384+ 'codice_fornitura': 'NSP00',
385+ 'tipo_fornitore': '01',
386+ 'formato_dati': 'aggregati',
387+ }
388+
389+ def onchange_trasmissione_impegno(self, cr, uid, ids, type, context=None):
390+ res = {}
391+ fiscalcode = False
392+ if type == '1': # soggetto obbligato
393+ fiscalcode = context.get('soggetto_codice_fiscale', False)
394+ res = {
395+ 'value' : {'soggetto_trasmissione_codice_fiscale' : fiscalcode}
396+ }
397+ return res
398+
399+ def partner_is_from_san_marino(self, cr, uid, move, invoice, arg):
400+ # configurazione
401+ anno_competenza = datetime.datetime.strptime(move.period_id.date_start, "%Y-%m-%d").year
402+ configurazione_ids = self.pool.get('spesometro.configurazione').search(cr, uid, \
403+ [('anno', '=', anno_competenza)])
404+ if not configurazione_ids:
405+ raise orm.except_orm(_('Configurazione mancante!'),_("Configurare l'anno relativo alla comunicazione") )
406+ configurazione = self.pool.get('spesometro.configurazione').browse(cr, uid, configurazione_ids[0])
407+ stato_estero = False
408+ address = self._get_partner_address_obj(cr, uid, move, invoice, arg)
409+ if address and address.country_id and configurazione.stato_san_marino.id == address.country_id.id:
410+ return True
411+ else:
412+ return False
413+
414+ def _get_partner_address_obj(self, cr, uid, move, invoice, arg):
415+ address = False
416+ if move.partner_id.spesometro_indirizzo_estero:
417+ address = move.partner_id.spesometro_indirizzo_estero
418+ elif move.partner_id.address[0]:
419+ address = move.partner_id.address[0]
420+ return address
421+
422+ def compute_invoice_amounts(self, cr, uid, move, invoice, arg):
423+ '''
424+ Calcolo totali documento. Dall'imponibile vanno esclusi gli importi assoggettati ad un'imposta che ha l'esclusione sulla "Comunicazione art.21"
425+ '''
426+ res ={
427+ 'amount_untaxed' : 0,
428+ 'amount_tax' : 0,
429+ 'amount_total' : 0,
430+ }
431+ for line in invoice.tax_line:
432+ if not line.tax_code_id.spesometro_escludi:
433+ res['amount_untaxed'] += line.base
434+ res['amount_tax'] += line.amount
435+ res['amount_total'] += round(line.base + line.amount, 2)
436+ return res
437+
438+ def truncate_values(self, cr, uid, ids, context=None):
439+ for com in self.browse(cr, uid, ids):
440+ for line in com.line_FA_ids:
441+ vals = {
442+ 'attive_imponibile_non_esente': int(line.attive_imponibile_non_esente),
443+ 'attive_imposta': int(line.attive_imposta),
444+ 'attive_operazioni_iva_non_esposta': int(line.attive_operazioni_iva_non_esposta),
445+ 'attive_note_variazione': int(line.attive_note_variazione),
446+ 'attive_note_variazione_imposta': int(line.attive_note_variazione_imposta),
447+
448+ 'passive_imponibile_non_esente': int(line.passive_imponibile_non_esente),
449+ 'passive_imposta': int(line.passive_imposta),
450+ 'passive_operazioni_iva_non_esposta': int(line.passive_operazioni_iva_non_esposta),
451+ 'passive_note_variazione': int(line.passive_note_variazione),
452+ 'passive_note_variazione_imposta': int(line.passive_note_variazione_imposta),
453+ }
454+ self.pool.get('spesometro.comunicazione.line.fa').write(cr, uid, [line.id], vals)
455+
456+ for line in com.line_SA_ids:
457+ vals = {
458+ 'importo_complessivo': int(line.importo_complessivo),
459+ }
460+ self.pool.get('spesometro.comunicazione.line.sa').write(cr, uid, [line.id], vals)
461+
462+ for line in com.line_BL_ids:
463+ vals = {
464+ 'attive_importo_complessivo': int(line.attive_importo_complessivo),
465+ 'attive_imposta': int(line.attive_imposta),
466+ 'attive_non_sogg_cessione_beni': int(line.attive_non_sogg_cessione_beni),
467+ 'attive_non_sogg_servizi': int(line.attive_non_sogg_servizi),
468+ 'attive_note_variazione': int(line.attive_note_variazione),
469+ 'attive_note_variazione_imposta': int(line.attive_note_variazione_imposta),
470+
471+ 'passive_importo_complessivo': int(line.passive_importo_complessivo),
472+ 'passive_imposta': int(line.passive_imposta),
473+ 'passive_non_sogg_importo_complessivo': int(line.passive_non_sogg_importo_complessivo),
474+ 'passive_note_variazione': int(line.passive_note_variazione),
475+ 'passive_note_variazione_imposta': int(line.passive_note_variazione_imposta),
476+ }
477+ self.pool.get('spesometro.comunicazione.line.bl').write(cr, uid, [line.id], vals)
478+
479+ return True
480+
481+ def validate_lines(self, cr, uid, ids, context=None):
482+ for com in self.browse(cr, uid, ids):
483+
484+ # configurazione
485+ configurazione_ids = self.pool.get('spesometro.configurazione').search(cr, uid, \
486+ [('anno', '=', com.anno)])
487+ if not configurazione_ids:
488+ raise orm.except_orm(_('Configurazione mancante!'),_("Configurare l'anno relativo alla comunicazione") )
489+ configurazione = self.pool.get('spesometro.configurazione').browse(cr, uid, configurazione_ids[0])
490+
491+ for line in com.line_FA_ids:
492+ if configurazione.quadro_fa_limite_importo :
493+ if line.attive_imponibile_non_esente and \
494+ line.attive_imponibile_non_esente < configurazione.quadro_fa_limite_importo:
495+ self.pool.get('spesometro.comunicazione.line.fa').unlink(cr, uid, [line.id])
496+
497+ for line in com.line_SA_ids:
498+ if configurazione.quadro_sa_limite_importo :
499+ if line.importo_complessivo and \
500+ line.importo_complessivo < configurazione.quadro_sa_limite_importo:
501+ self.pool.get('spesometro.comunicazione.line.sa').unlink(cr, uid, [line.id])
502+
503+ for line in com.line_BL_ids:
504+ if configurazione.quadro_bl_limite_importo :
505+ importo_test = 0
506+ if line.attive_importo_complessivo :
507+ importo_test = line.attive_importo_complessivo
508+ elif line.attive_non_sogg_cessione_beni :
509+ importo_test = line.attive_non_sogg_cessione_beni
510+ elif line.attive_non_sogg_servizi :
511+ importo_test = line.attive_non_sogg_servizi
512+
513+ if importo_test and \
514+ importo_test < configurazione.quadro_bl_limite_importo:
515+ self.pool.get('spesometro.comunicazione.line.bl').unlink(cr, uid, [line.id])
516+
517+ # Controllo formale comunicazione
518+ # ... periodo in presenza di linee nel quadro SE
519+ if com.line_SE_ids and not com.trimestre and not com.mese:
520+ raise orm.except_orm(_('Perido Errato!'),_("In presenza di operazione nel qudro SE (Acquisti da San Marino) \
521+ sono ammessi solo periodi mensili/trimestrali") )
522+
523+ return True
524+
525+ def validate_operation(self, cr, uid, move, invoice, arg):
526+ # configurazione
527+ anno_competenza = datetime.datetime.strptime(move.period_id.date_start, "%Y-%m-%d").year
528+ configurazione_ids = self.pool.get('spesometro.configurazione').search(cr, uid, \
529+ [('anno', '=', anno_competenza)])
530+ if not configurazione_ids:
531+ raise orm.except_orm(_('Configurazione mancante!'),_("Configurare l'anno relativo alla comunicazione") )
532+ configurazione = self.pool.get('spesometro.configurazione').browse(cr, uid, configurazione_ids[0])
533+
534+ doc_vals = self.pool.get('spesometro.comunicazione').compute_invoice_amounts(cr, uid, move, invoice, arg)
535+ # Nessu quadro definito
536+ if not arg['quadro']:
537+ return False
538+ # Quadro richiesto
539+ if arg['quadro'] not in arg['quadri_richiesti']:
540+ return False
541+ # Valori minimi
542+ if arg['quadro'] == 'FA':
543+ if configurazione.quadro_fa_limite_importo_line :
544+ if not doc_vals.get('amount_untaxed', 0) or doc_vals.get('amount_untaxed', 0) < configurazione.quadro_fa_limite_importo_line:
545+ return False
546+ if arg['quadro'] == 'SA':
547+ if configurazione.quadro_sa_limite_importo_line :
548+ if not doc_vals.get('amount_total', 0) or doc_vals.get('amount_total', 0) < configurazione.quadro_sa_limite_importo_line:
549+ return False
550+ if arg['quadro'] == 'BL':
551+ if configurazione.quadro_bl_limite_importo_line :
552+ if not doc_vals.get('amount_total', 0) or doc_vals.get('amount_total', 0) < configurazione.quadro_bl_limite_importo_line:
553+ return False
554+
555+ if arg['quadro'] == 'SE':
556+ if configurazione.quadro_se_limite_importo_line :
557+ if not doc_vals.get('amount_untaxed', 0) or doc_vals.get('amount_untaxed', 0) < configurazione.quadro_se_limite_importo_line:
558+ return False
559+
560+ # Operazioni con San Marino Escluse se richiesta forma aggregata
561+ if arg['formato_dati'] == 'aggregati' and self.partner_is_from_san_marino(cr, uid, move, invoice, arg):
562+ return False
563+
564+ return True
565+
566+ def get_define_quadro(self, cr, uid, move, invoice, arg):
567+
568+ quadro = False
569+ operazione = arg.get('operazione')
570+ # Forma aggregata
571+ if arg['formato_dati'] == 'aggregati':
572+ if operazione == 'FA' or operazione == 'DR':
573+ quadro = 'FA'
574+ elif operazione == 'SA': # Operazioni senza fattura
575+ quadro = 'SA'
576+ elif (operazione == 'BL1') or (operazione == 'BL2') or (operazione == 'BL2'):
577+ quadro = 'BL'
578+
579+ # Forma analitica
580+ if arg['formato_dati'] == 'analitici':
581+
582+ # Priorità x San Marino -> quadro SE
583+ if self.partner_is_from_san_marino(cr, uid, move, invoice, arg):
584+ operazione = 'BL3'
585+
586+ # Impostazioni anagrafiche partner
587+ if operazione == 'FA' or operazione == 'DR':
588+ if arg.get('segno') == 'attiva':
589+ quadro = 'FE'
590+ elif arg.get('segno') == 'passiva':
591+ quadro = 'FR'
592+ elif operazione == 'SA': # Operazioni senza fattura
593+ quadro = 'DF'
594+ elif operazione == 'BL2': #Operazioni con soggetti non residenti
595+ quadro = 'FN'
596+ elif operazione == 'BL1' or operazione == 'BL3': #Operazioni con paesi con fiscalità privilegiata - Acquisti di servizi da soggetti non residenti
597+ quadro = 'SE'
598+ # Note di variazione
599+ if operazione == 'FE' and 'refund' in move.journal_id.type:
600+ operazione = 'NE'
601+ elif operazione == 'FR' and 'refund' in move.journal_id.type:
602+ operazione = 'NR'
603+
604+ return quadro
605+
606+
607+ def genera_comunicazione(self, cr, uid, params, context=None):
608+
609+ def _get_periods(cr, uid, params, context=None):
610+ '''
611+ Definizione periodi di competenza
612+ '''
613+ sql_select = "SELECT p.id FROM account_period p "
614+ sql_where = " WHERE p.special = False "
615+ search_params = {}
616+ # Periodo annuale
617+ if params.get('periodo') == 'anno':
618+ period_date_start = datetime.date(params.get('anno') , 1, 1)
619+ period_date_stop = datetime.date(params.get('anno') , 12, 31)
620+ sql_where += " AND p.date_start >= date(%(period_date_start)s) AND p.date_stop <=date(%(period_date_stop)s) "
621+ search_params.update({
622+ 'period_date_start' : period_date_start,
623+ 'period_date_stop' : period_date_stop
624+ })
625+ # Periodo mensile
626+ if params.get('periodo') == 'mese':
627+ period_date_start = datetime.date(params.get('anno') , int(params.get('mese')), 1)
628+ sql_where += " AND p.date_start = date(%(period_date_start)s) "
629+ search_params.update({
630+ 'period_date_start' : period_date_start,
631+ })
632+ # Periodo trimestrale
633+ if params.get('periodo') == 'trimestre':
634+ if params.get('trimestre') == 1:
635+ period_date_start = datetime.date(params.get('anno') , 1, 1)
636+ period_date_start = datetime.date(params.get('anno') , 3, 31)
637+ elif params.get('trimestre') == 2:
638+ period_date_start = datetime.date(params.get('anno') , 3, 1)
639+ period_date_start = datetime.date(params.get('anno') , 6, 30)
640+ elif params.get('trimestre') == 2:
641+ period_date_start = datetime.date(params.get('anno') , 7, 1)
642+ period_date_start = datetime.date(params.get('anno') , 9, 30)
643+ elif params.get('trimestre') == 2:
644+ period_date_start = datetime.date(params.get('anno') , 10, 1)
645+ period_date_start = datetime.date(params.get('anno') , 12, 31)
646+ else:
647+ raise orm.except_orm(_('Dato errato!'),_("Errore nel valore del trimestre") )
648+ sql_where += " AND p.date_start >= date(%(period_date_start)s) AND p.date_stop <=date(%(period_date_stop)s) "
649+ search_params.update({
650+ 'period_date_start' : period_date_start,
651+ 'period_date_stop' : period_date_stop
652+ })
653+
654+ sql = sql_select + sql_where
655+ cr.execute(sql, search_params)
656+ periods = [i[0] for i in cr.fetchall()]
657+ return periods
658+
659+ def _genera_testata(cr, uid, params, context=None):
660+ '''
661+ Generazione testata dichiarazione
662+ '''
663+ company = self.pool.get('res.company').browse(cr, uid, params['company_id'])
664+ # progressivo telematico :" il progressivo deve essere univoco e crescente (con incrementi di una unità per ogni file prodotto)"
665+ if params['tipo'] == 'ordinaria':
666+ com_search = [('tipo', '=', 'ordinaria')]
667+ com_last_ids = self.search(cr, uid, com_search, order='progressivo_telematico desc', limit=1)
668+ com_next_prg = 1
669+ if com_last_ids:
670+ com_next_prg = self.browse(cr, uid, com_last_ids[0]).progressivo_telematico + 1
671+ progressivo_telematico = com_next_prg
672+ # vat
673+ if company.partner_id.vat:
674+ partita_iva = company.partner_id.vat[2:]
675+ else:
676+ partita_iva = '{:11s}'.format("".zfill(11))
677+ # codice fiscale soggetto incaricato alla trasmissione
678+ codice_fiscale_incaricato_trasmissione=''
679+ if params.get('tipo_fornitore') == '10' and params.get('partner_intermediario', False):
680+ partner_intermediario = self.pool.get('res.partner').browse(cr, uid, params.get('partner_intermediario'))
681+ codice_fiscale_incaricato_trasmissione = partner_intermediario.fiscalcode or False
682+ # Soggetto con impegno alla trasmissione
683+ if params.get('tipo_fornitore') == '10':
684+ soggetto_trasmissione_impegno = '2'
685+ else:
686+ soggetto_trasmissione_impegno = '1'
687+ # Persona fisica o giuridica
688+ # Considerazione: se se lunghezza codice fiscale < 16 allora c'è la P.Iva e quindi trattasi di soggetto giuridico
689+ tipo_persona = 'persona_fisica'
690+ if len(company.partner_id.fiscalcode) < 16:
691+ tipo_persona = 'persona_giuridica'
692+
693+ values = {
694+ 'company_id' : company.id,
695+ 'codice_fiscale_fornitore' : company.partner_id.fiscalcode,
696+ 'tipo' : params.get('tipo', False),
697+ 'periodo' : params.get('periodo', False),
698+ 'anno' : params.get('anno', False),
699+ 'mese' : params.get('mese', False),
700+ 'trimestre' : params.get('trimestre', False),
701+ 'progressivo_telematico' : progressivo_telematico or False,
702+ 'tipo_fornitore' : params.get('tipo_fornitore', False),
703+ 'formato_dati' : params.get('formato_dati', False),
704+ 'soggetto_codice_fiscale' : company.partner_id and company.partner_id.fiscalcode or '',
705+ 'soggetto_partitaIVA' : partita_iva,
706+ 'soggetto_telefono' : company.partner_id and company.partner_id.address[0].phone or '',
707+ 'soggetto_fax' : company.partner_id and company.partner_id.address[0].fax or '',
708+ 'soggetto_email' : company.partner_id and company.partner_id.address[0].email or '',
709+ 'soggetto_forma_giuridica' : tipo_persona,
710+ 'soggetto_pg_denominazione' : company.partner_id and company.partner_id.name or company.name or '',
711+ 'soggetto_cm_forma_giuridica' : tipo_persona,
712+ 'soggetto_cm_pg_denominazione' : company.partner_id and company.partner_id.name or company.name or '',
713+ 'soggetto_trasmissione_codice_fiscale' : codice_fiscale_incaricato_trasmissione,
714+ 'soggetto_trasmissione_impegno' : soggetto_trasmissione_impegno,
715+ }
716+ comunicazione_id = self.create(cr, uid, values)
717+
718+ return comunicazione_id
719+
720+
721+ # Esistenza record di configurazione per l'anno della comunicazione
722+ configurazione_ids = self.pool.get('spesometro.configurazione').search(cr, uid, [('anno', '=', params.get('anno'))])
723+ if not configurazione_ids:
724+ raise orm.except_orm(_('Configurazione mancante!'),_("Configurare l'anno relativo alla comunicazione") )
725+ configurazione = self.pool.get('spesometro.configurazione').browse(cr, uid, configurazione_ids[0])
726+
727+ # Testata comunicazione
728+ comunicazione_id = _genera_testata(cr, uid, params, context=None)
729+
730+ period_obj = self.pool.get('account.period')
731+ journal_obj = self.pool.get('account.journal')
732+ partner_obj = self.pool.get('res.partner')
733+ account_move_obj = self.pool.get('account.move')
734+ invoice_obj = self.pool.get('account.invoice')
735+ # periods
736+ period_ids = _get_periods(cr, uid, params, context=None)
737+ # journal
738+ journal_search = [('spesometro','=', True)]
739+ journal_ids = journal_obj.search(cr, uid, journal_search, context=context)
740+ # Partners to exclude
741+ partner_search = [('spesometro_escludi','=', True)]
742+ partner_to_exclude_ids = partner_obj.search(cr, uid, partner_search, context=context)
743+
744+ move_search = [('company_id', '=', params['company_id']),('period_id','in', period_ids), ('journal_id','in', journal_ids), ('partner_id','not in', partner_to_exclude_ids)]
745+ move_ids = account_move_obj.search(cr, uid, move_search, context=context)
746+
747+ for move in self.pool.get('account.move').browse(cr, uid, move_ids):
748+ # Test move validate
749+ if not move.partner_id:
750+ continue
751+
752+ # Invoice
753+ invoice_search = [('move_id','=', move.id)]
754+ invoice_ids = invoice_obj.search(cr, uid, invoice_search, context=context)
755+ if not invoice_ids:
756+ continue
757+ invoice = invoice_obj.browse(cr,uid, invoice_ids[0])
758+
759+ # Config spesometro
760+ operazione = False
761+ operazione_iva_non_esposta = False
762+ operazione = move.journal_id.spesometro_operazione
763+ operazione_iva_non_esposta = move.journal_id.spesometro_IVA_non_esposta
764+ segno = move.journal_id.spesometro_segno
765+ if move.partner_id.spesometro_operazione:
766+ operazione = move.partner_id.spesometro_operazione
767+ operazione_iva_non_esposta = move.partner_id.spesometro_IVA_non_esposta
768+
769+ arg = {
770+ 'comunicazione_id' : comunicazione_id,
771+ 'segno' : segno,
772+ 'operazione_iva_non_esposta' : operazione_iva_non_esposta,
773+ 'operazione' : operazione,
774+ 'formato_dati' : params['formato_dati'],
775+ 'quadri_richiesti' : params['quadri_richiesti'],
776+ }
777+
778+ # Quadro di competenza
779+ quadro = self.get_define_quadro(cr, uid, move, invoice, arg)
780+
781+ arg.update({'quadro': quadro})
782+
783+ # Test operazione da includere nella comunicazione
784+ if not self.validate_operation(cr, uid, move, invoice, arg):
785+ continue
786+
787+ if quadro == 'FA':
788+ line_id = self.pool.get('spesometro.comunicazione.line.fa').add_line(cr, uid, move, invoice, arg)
789+ if quadro == 'SA':
790+ line_id = self.pool.get('spesometro.comunicazione.line.sa').add_line(cr, uid, move, invoice, arg)
791+ if quadro == 'BL':
792+ line_id = self.pool.get('spesometro.comunicazione.line.bl').add_line(cr, uid, move, invoice, arg)
793+ if quadro == 'SE':
794+ line_id = self.pool.get('spesometro.comunicazione.line.se').add_line(cr, uid, move, invoice, arg)
795+
796+ # Arrotonda importi su valori raggruppati -> troncare i decimali
797+ if params['formato_dati'] == 'aggregati':
798+ self.truncate_values(cr, uid, [comunicazione_id])
799+
800+ # Rimuove le linee che non rientrano nei limiti ed effettua un controllo formale sull'intera comunicazione
801+ self.validate_lines(cr, uid, [comunicazione_id])
802+
803+ # Update for compute totals
804+ self.write(cr, uid, [comunicazione_id],{})
805+
806+ return True
807+
808+
809+class spesometro_comunicazione_line_FA(orm.Model):
810+ '''
811+ QUADRO FA - Operazioni documentate da fattura esposte in forma aggregata
812+ '''
813+
814+ _name = "spesometro.comunicazione.line.fa"
815+ _description = "Spesometro - Comunicazione linee quadro FA"
816+ _columns = {
817+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
818+
819+ 'partner_id': fields.many2one('res.partner', 'Partner'),
820+ 'partita_iva': fields.char('Partita IVA', size=11),
821+ 'codice_fiscale': fields.char('Codice Fiscale', size=16),
822+ 'documento_riepilogativo': fields.boolean('Documento Riepilogativo'),
823+ 'noleggio': fields.selection((('A','Autovettura'), ('B','Caravan'), ('C','Altri Veicoli'), ('D','Unità da diporto'), ('E','Aeromobii')),'Leasing'),
824+
825+ 'numero_operazioni_attive_aggregate': fields.integer('Nr op. attive', size=16),
826+ 'numero_operazioni_passive_aggregate': fields.integer('Nr op. passive', size=16),
827+
828+ 'attive_imponibile_non_esente': fields.float('Tot impon., non impon ed esenti', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
829+ 'attive_imposta': fields.float(' Tot imposta', digits_compute=dp.get_precision('Account'), help="Totale imposta"),
830+ 'attive_operazioni_iva_non_esposta': fields.float('Totale operaz. IVA non esposta', digits_compute=dp.get_precision('Account'), help="Totale operazioni con IVA non esposta"),
831+ 'attive_note_variazione': fields.float('Totale note variazione', digits_compute=dp.get_precision('Account'), help="Totale note di variazione a debito per la controparte"),
832+ 'attive_note_variazione_imposta': fields.float('Totale imposta note variazione', digits_compute=dp.get_precision('Account'), help="Totale imposta sulle note di variazione a debito"),
833+
834+ 'passive_imponibile_non_esente': fields.float('Tot impon., non impon ed esenti', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
835+ 'passive_imposta': fields.float('Totale imposta', digits_compute=dp.get_precision('Account'), help="Totale imposta"),
836+ 'passive_operazioni_iva_non_esposta': fields.float('Totale operaz. IVA non esposta', digits_compute=dp.get_precision('Account'), help="Totale operazioni con IVA non esposta"),
837+ 'passive_note_variazione': fields.float('Totale note variazione', digits_compute=dp.get_precision('Account'), help="Totale note di variazione a credito per la controparte"),
838+ 'passive_note_variazione_imposta': fields.float('Totale imposta note variazione', digits_compute=dp.get_precision('Account'), help="Totale imposta sulle note di variazione a credito"),
839+ }
840+
841+
842+ def add_line(self, cr, uid, move, invoice, arg):
843+ comunicazione_lines_obj = self.pool.get('spesometro.comunicazione.line.fa')
844+ comunicazione_id = arg.get('comunicazione_id', False)
845+ com_line_search = [('comunicazione_id','=',comunicazione_id), ('partner_id', '=', move.partner_id.id)]
846+ com_line_ids = self.search(cr, uid, com_line_search)
847+ val = {}
848+ # Valori documento
849+ doc_vals = self.pool.get('spesometro.comunicazione').compute_invoice_amounts(cr, uid, move, invoice, arg)
850+ # New partner
851+ if not com_line_ids:
852+ partita_iva =''
853+ if move.partner_id.vat:
854+ partita_iva = move.partner_id.vat[2:]
855+ documento_riepilogativo = False
856+ if arg['operazione'] == 'DR':
857+ documento_riepilogativo = True
858+ val = {
859+ 'comunicazione_id' : comunicazione_id,
860+ 'partner_id' : move.partner_id.id,
861+ 'partita_iva' : partita_iva,
862+ 'codice_fiscale' : move.partner_id.fiscalcode or '',
863+ 'noleggio' : move.partner_id.spesometro_leasing or '',
864+ 'documento_riepilogativo' : documento_riepilogativo,
865+ }
866+ # attive
867+ if arg.get('segno', False) == 'attiva':
868+ val['numero_operazioni_attive_aggregate'] = 1
869+ if 'refund' in move.journal_id.type:
870+ val['attive_note_variazione'] = doc_vals.get('amount_untaxed', 0)
871+ val['attive_note_variazione_imposta'] = doc_vals.get('amount_tax', 0)
872+ else:
873+ if arg.get('operazione_iva_non_esposta', False):
874+ val['attive_operazioni_iva_non_esposta' ] = doc_vals.get('amount_total', 0)
875+ else:
876+ val['attive_imponibile_non_esente' ] = doc_vals.get('amount_untaxed', 0)
877+ val['attive_imposta'] =doc_vals.get('amount_tax', 0)
878+ # passive
879+ else:
880+ val['numero_operazioni_passive_aggregate'] = 1
881+ if 'refund' in move.journal_id.type:
882+ val['passive_note_variazione'] = doc_vals.get('amount_untaxed', 0)
883+ val['passive_note_variazione_imposta'] = doc_vals.get('amount_tax', 0)
884+ else:
885+ if arg.get('operazione_iva_non_esposta', False):
886+ val['passive_operazioni_iva_non_esposta' ] = doc_vals.get('amount_total', 0)
887+ else:
888+ val['passive_imponibile_non_esente' ] = doc_vals.get('amount_untaxed', 0)
889+ val['passive_imposta' ] = doc_vals.get('amount_tax', 0)
890+
891+ # Partner already exists
892+ if com_line_ids:
893+ for com_line in self.browse(cr, uid, com_line_ids):
894+ # attive
895+ if arg.get('segno', False) == 'attiva':
896+ val['numero_operazioni_attive_aggregate'] = com_line.numero_operazioni_attive_aggregate + 1
897+ if 'refund' in move.journal_id.type:
898+ val['attive_note_variazione'] = com_line.attive_note_variazione + doc_vals.get('amount_untaxed', 0)
899+ val['attive_note_variazione_imposta'] = com_line.attive_note_variazione_imposta + doc_vals.get('amount_tax', 0)
900+ else:
901+ if arg.get('operazione_iva_non_esposta', False):
902+ val['attive_operazioni_iva_non_esposta' ] = com_line.attive_operazioni_iva_non_esposta + doc_vals.get('amount_total', 0)
903+ else:
904+ val['attive_imponibile_non_esente' ] = com_line.attive_imponibile_non_esente + doc_vals.get('amount_untaxed', 0)
905+ val['attive_imposta' ] = com_line.attive_imposta + doc_vals.get('amount_tax', 0)
906+ # passive
907+ else:
908+ val['numero_operazioni_passive_aggregate'] = com_line.numero_operazioni_passive_aggregate + 1
909+ if 'refund' in move.journal_id.type:
910+ val['passive_note_variazione'] = com_line.passive_note_variazione + doc_vals.get('amount_untaxed', 0)
911+ val['passive_note_variazione_imposta'] = com_line.passive_note_variazione_imposta + doc_vals.get('amount_tax', 0)
912+ else:
913+ if arg.get('operazione_iva_non_esposta', False):
914+ val['passive_operazioni_iva_non_esposta' ] = com_line.passive_operazioni_iva_non_esposta + doc_vals.get('amount_total', 0)
915+ else:
916+ val['passive_imponibile_non_esente' ] = com_line.passive_imponibile_non_esente + doc_vals.get('amount_untaxed', 0)
917+ val['passive_imposta' ] = com_line.passive_imposta + doc_vals.get('amount_tax', 0)
918+
919+ if com_line_ids:
920+ line_id = com_line.id
921+ self.write(cr, uid, [com_line.id], val)
922+ else:
923+ line_id = self.create(cr, uid, val)
924+
925+ return line_id
926+
927+class spesometro_comunicazione_line_SA(orm.Model):
928+ '''
929+ QUADRO SA - Operazioni senza fattura esposte in forma aggregata
930+ '''
931+ _name = "spesometro.comunicazione.line.sa"
932+ _description = "Spesometro - Comunicazione linee quadro SA"
933+ _columns = {
934+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione' , ondelete='cascade'),
935+ 'partner_id': fields.many2one('res.partner', 'Partner'),
936+ 'codice_fiscale': fields.char('Codice Fiscale', size=16),
937+
938+ 'numero_operazioni': fields.integer('Numero operazioni'),
939+ 'importo_complessivo': fields.float('Importo complessivo', digits_compute=dp.get_precision('Account')),
940+ 'noleggio': fields.selection((('A','Autovettura'), ('B','Caravan'), ('C','Altri Veicoli'), ('D','Unità da diporto'), ('E','Aeromobii')),'Leasing'),
941+ }
942+
943+ def add_line(self, cr, uid, move, invoice, arg):
944+ comunicazione_lines_obj = self.pool.get('spesometro.comunicazione.line.fa')
945+ comunicazione_id = arg.get('comunicazione_id', False)
946+ com_line_search = [('comunicazione_id','=',comunicazione_id), ('partner_id', '=', move.partner_id.id)]
947+ com_line_ids = self.search(cr, uid, com_line_search)
948+ val = {}
949+ # Valori documento
950+ doc_vals = self.pool.get('spesometro.comunicazione').compute_invoice_amounts(cr, uid, move, invoice, arg)
951+ # New partner
952+ if not com_line_ids:
953+ val = {
954+ 'comunicazione_id' : comunicazione_id,
955+ 'partner_id' : move.partner_id.id,
956+ 'codice_fiscale' : move.partner_id.fiscalcode or False,
957+ 'noleggio' : move.partner_id.spesometro_leasing or False,
958+ 'numero_operazioni' : 1,
959+ 'importo_complessivo' : doc_vals.get('amount_total', 0),
960+ }
961+ # Partner already exists
962+ if com_line_ids:
963+ for com_line in self.browse(cr, uid, com_line_ids):
964+ val['numero_operazioni'] = com_line.numero_operazioni + 1
965+ val['importo_complessivo'] = com_line.importo_complessivo + doc_vals.get('amount_total', 0)
966+
967+ if com_line_ids:
968+ line_id = com_line.id
969+ self.write(cr, uid, [com_line.id], val)
970+ else:
971+ line_id = self.create(cr, uid, val)
972+
973+ return line_id
974+
975+class spesometro_comunicazione_line_BL(orm.Model):
976+ '''
977+ QUADRO BL
978+ - Operazioni con paesi con fiscalità privilegiata (è obbligatorio compilare le sezioni BL001, BL002
979+ e almeno un campo delle sezioni BL003, BL004, BL005, BL006, BL007, BL008)
980+ - Operazioni con soggetti non residenti (è obbligatorio compilare le sezioni BL001, BL002 e almeno
981+ un campo delle sezioni BL003 e BL006)
982+ - Acquisti di servizi da soggetti non residenti (è obbligatorio compilare le sezioni BL001, BL002 e
983+ almeno un campo della sezione BL006)
984+ '''
985+ _name = "spesometro.comunicazione.line.bl"
986+ _description = "Spesometro - Comunicazione linee quadro BL"
987+ _columns = {
988+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
989+ 'partner_id': fields.many2one('res.partner', 'Partner'),
990+ 'codice_fiscale': fields.char('Codice Fiscale', size=16),
991+
992+ 'numero_operazioni': fields.integer('Numero operazioni'),
993+ 'importo_complessivo': fields.integer('Importo complessivo', digits_compute=dp.get_precision('Account')),
994+ 'noleggio': fields.selection((('A','Autovettura'), ('B','Caravan'), ('C','Altri Veicoli'), ('D','Unità da diporto'), ('E','Aeromobii')),'Leasing'),
995+
996+ 'pf_cognome': fields.char('Cognome', size=24, help=""),
997+ 'pf_nome': fields.char('Nome', size=20, help=""),
998+ 'pf_data_nascita': fields.date('Data di nascita'),
999+ 'pf_comune_stato_nascita': fields.char('Comune o stato estero di nascita', size=40),
1000+ 'pf_provincia_nascita': fields.char('Provincia', size=2),
1001+ 'pf_codice_stato_estero': fields.char('Codice Stato Estero', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1002+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1003+ 'pg_denominazione': fields.char('Denominazione/Ragione sociale', size=60),
1004+ 'pg_citta_estera_sede_legale': fields.char('Città estera delle Sede legale', size=40),
1005+ 'pg_codice_stato_estero': fields.char('Codice Stato Estero', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1006+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1007+ 'pg_indirizzo_sede_legale': fields.char('Indirizzo sede legale', size=60),
1008+
1009+ 'codice_identificativo_IVA': fields.char('Codice identificativo IVA', size=16),
1010+ 'operazione_fiscalita_privilegiata': fields.boolean('Operazione con pesei con fiscalità privilegiata'),
1011+ 'operazione_con_soggetti_non_residenti': fields.boolean('Operazione con soggetto non residente'),
1012+ 'Acquisto_servizi_da_soggetti_non_residenti': fields.boolean('Acquisto di servizi da soggetti non residenti'),
1013+
1014+ 'attive_importo_complessivo': fields.float('Tot operaz. attive impon., non impon ed esenti', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
1015+ 'attive_imposta': fields.float('Tot operaz. attive imposta', digits_compute=dp.get_precision('Account'), help="Totale imposta"),
1016+ 'attive_non_sogg_cessione_beni': fields.float('Operaz.attive non soggette ad IVA - Cessione beni', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
1017+ 'attive_non_sogg_servizi': fields.float('Operaz.attive non soggette ad IVA - Servizi', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
1018+ 'attive_note_variazione': fields.float('Totale note variazione', digits_compute=dp.get_precision('Account'), help="Totale note di variazione a debito per la controparte"),
1019+ 'attive_note_variazione_imposta': fields.float('Totale imposta note variazione', digits_compute=dp.get_precision('Account'), help="Totale imposta sulle note di variazione a debito"),
1020+
1021+ 'passive_importo_complessivo': fields.float('Tot operaz. passive impon., non impon ed esenti', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
1022+ 'passive_imposta': fields.float('Tot operaz. passive imposta', digits_compute=dp.get_precision('Account'), help="Totale imposta"),
1023+ 'passive_non_sogg_importo_complessivo': fields.float('Operaz.passive non soggette ad IVA', digits_compute=dp.get_precision('Account'), help="Totale operazioni imponibili, non imponibili ed esenti"),
1024+ 'passive_note_variazione': fields.float('Totale note variazione', digits_compute=dp.get_precision('Account'), help="Totale note di variazione a debito per la controparte"),
1025+ 'passive_note_variazione_imposta': fields.float('Totale imposta note variazione', digits_compute=dp.get_precision('Account'), help="Totale imposta sulle note di variazione a debito"),
1026+
1027+ }
1028+
1029+ def add_line(self, cr, uid, move, invoice, arg):
1030+ comunicazione_lines_obj = self.pool.get('spesometro.comunicazione.line.bl')
1031+ comunicazione_id = arg.get('comunicazione_id', False)
1032+ com_line_search = [('comunicazione_id','=',comunicazione_id), ('partner_id', '=', move.partner_id.id)]
1033+ com_line_ids = self.search(cr, uid, com_line_search)
1034+ val = {}
1035+ # Valori documento
1036+ doc_vals = self.pool.get('spesometro.comunicazione').compute_invoice_amounts(cr, uid, move, invoice, arg)
1037+ # New partner
1038+ if not com_line_ids:
1039+ # p.iva
1040+ if move.partner_id.vat:
1041+ partita_iva = move.partner_id.vat[2:]
1042+ else:
1043+ partita_iva = '{:11s}'.format("".zfill(11))
1044+ # prov. nascita
1045+ prov_code = False
1046+ if move.partner_id.birth_city.name:
1047+ city_data = move.partner_id.address[0]._set_vals_city_data(cr, uid, {'city' : move.partner_id.birth_city.name})
1048+ prov_id = city_data.get('province_id', False)
1049+ if prov_id:
1050+ prov = self.pool.get('res.province').borwse(cr, uid, prov_id)
1051+ prov_nascita_code = prov.code
1052+
1053+ val = {
1054+ 'comunicazione_id' : comunicazione_id,
1055+ 'partner_id' : move.partner_id.id,
1056+ 'codice_fiscale' : move.partner_id.fiscalcode or False,
1057+ 'noleggio' : move.partner_id.spesometro_leasing or False,
1058+
1059+ 'pf_cognome' : move.partner_id.fiscalcode_surname or False,
1060+ 'pf_nome' : move.partner_id.fiscalcode_firstname or False,
1061+ 'pf_data_nascita' : move.partner_id.birth_date or False,
1062+ 'pf_comune_stato_nascita' : move.partner_id.birth_city.name or False,
1063+ 'pf_provincia_nascita' : prov_code or False,
1064+ 'pf_codice_stato_estero' : move.partner_id.address[0].country_id.codice_stato_agenzia_entrate or '',
1065+
1066+ 'pg_denominazione' : move.partner_id.name or False,
1067+ 'pg_citta_estera_sede_legale' : move.partner_id.address[0].city or False,
1068+ 'pg_codice_stato_estero' : move.partner_id.address[0].country_id.codice_stato_agenzia_entrate or '',
1069+ 'pg_indirizzo_sede_legale' : move.partner_id.address[0].street or False,
1070+
1071+ 'operazione_fiscalita_privilegiata' : False,
1072+ 'operazione_con_soggetti_non_residenti' : False,
1073+ 'Acquisto_servizi_da_soggetti_non_residenti' : False,
1074+ }
1075+
1076+ if move.partner_id.spesometro_operazione == 'BL1':
1077+ val['operazione_fiscalita_privilegiata'] = True
1078+ elif move.partner_id.spesometro_operazione == 'BL2':
1079+ val['operazione_con_soggetti_non_residenti'] = True
1080+ elif move.partner_id.spesometro_operazione == 'BL3':
1081+ val['Acquisto_servizi_da_soggetti_non_residenti'] = True
1082+
1083+ # attive
1084+ if arg.get('segno', False) == 'attiva':
1085+
1086+ if val['operazione_fiscalita_privilegiata'] or val['operazione_con_soggetti_non_residenti']:
1087+ val['attive_importo_complessivo'] = doc_vals.get('amount_total', 0)
1088+ val['attive_imposta'] = doc_vals.get('amount_tax', 0)
1089+ if val['operazione_fiscalita_privilegiata'] == True:
1090+ if move.partner_id.spesometro_operazione == 'cessioni':
1091+ val['attive_non_sogg_cessione_beni'] = doc_vals.get('amount_total', 0)
1092+ else:
1093+ val['attive_non_sogg_servizi'] = doc_vals.get('amount_total', 0)
1094+ if 'refund' in move.journal_id.type:
1095+ val['attive_note_variazione'] = doc_vals.get('amount_untaxed', 0)
1096+ val['attive_note_variazione_imposta'] = doc_vals.get('amount_tax', 0)
1097+ # passive
1098+ else:
1099+
1100+ if val['operazione_fiscalita_privilegiata'] or val['operazione_con_soggetti_non_residenti'] or val['Acquisto_servizi_da_soggetti_non_residenti']:
1101+ val['passive_importo_complessivo'] = doc_vals.get('amount_total', 0)
1102+ val['passive_imposta'] = doc_vals.get('amount_tax', 0)
1103+ if val['operazione_fiscalita_privilegiata'] == True:
1104+ val['passive_non_sogg_importo_complessivo'] = doc_vals.get('amount_total', 0)
1105+ if 'refund' in move.journal_id.type:
1106+ val['passive_note_variazione'] = doc_vals.get('amount_untaxed', 0)
1107+ val['passive_note_variazione_imposta'] = doc_vals.get('amount_tax', 0)
1108+
1109+ # Partner already exists
1110+ if com_line_ids:
1111+ for com_line in self.browse(cr, uid, com_line_ids):
1112+ # attive
1113+ if arg.get('segno', False) == 'attiva':
1114+
1115+ if val['operazione_fiscalita_privilegiata'] or val['operazione_con_soggetti_non_residenti']:
1116+ val['attive_importo_complessivo'] = com_line.attive_importo_complessivo + doc_vals.get('amount_total', 0)
1117+ val['attive_imposta'] = com_line.attive_imposta + doc_vals.get('amount_tax', 0)
1118+ if val['operazione_fiscalita_privilegiata'] == True:
1119+ if move.partner_id.spesometro_operazione == 'cessioni':
1120+ val['attive_non_sogg_cessione_beni'] = com_line.attive_non_sogg_cessione_beni + doc_vals.get('amount_total', 0)
1121+ else:
1122+ val['attive_non_sogg_servizi'] = com_line.attive_non_sogg_servizi + doc_vals.get('amount_total', 0)
1123+ if 'refund' in move.journal_id.type:
1124+ val['attive_note_variazione'] = com_line.attive_note_variazione + doc_vals.get('amount_untaxed', 0)
1125+ val['attive_note_variazione_imposta'] = com_line.attive_note_variazione_imposta + doc_vals.get('amount_tax', 0)
1126+
1127+ # passive
1128+ else:
1129+
1130+ if val['operazione_fiscalita_privilegiata'] or val['operazione_con_soggetti_non_residenti'] or val['Acquisto_servizi_da_soggetti_non_residenti']:
1131+ val['passive_importo_complessivo'] = com_line.passive_importo_complessivo + doc_vals.get('amount_total', 0)
1132+ val['passive_imposta'] = com_line.passive_imposta + doc_vals.get('amount_tax', 0)
1133+ if val['operazione_fiscalita_privilegiata'] == True:
1134+ val['passive_non_sogg_importo_complessivo'] = com_line.passive_non_sogg_importo_complessivo + doc_vals.get('amount_total', 0)
1135+ if 'refund' in move.journal_id.type:
1136+ val['passive_note_variazione'] = com_line.passive_note_variazione + doc_vals.get('amount_untaxed', 0)
1137+ val['passive_note_variazione_imposta'] = com_line.passive_note_variazione_imposta + doc_vals.get('amount_tax', 0)
1138+
1139+ if com_line_ids:
1140+ line_id = com_line.id
1141+ self.write(cr, uid, [com_line.id], val)
1142+ else:
1143+ line_id = self.create(cr, uid, val)
1144+
1145+ return line_id
1146+
1147+class spesometro_comunicazione_line_FE(orm.Model):
1148+
1149+ _name = "spesometro.comunicazione.line.fe"
1150+ _description = "Spesometro - Comunicazione linee quadro FE"
1151+ _columns = {
1152+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1153+
1154+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1155+ 'partita_iva': fields.char('Partita IVA', size=11),
1156+ 'codice_fiscale': fields.char('Codice Fiscale', size=16),
1157+ 'documento_riepilogativo': fields.boolean('Documento Riepilogativo'),
1158+ 'noleggio': fields.selection((('A','Autovettura'), ('B','Caravan'), ('C','Altri Veicoli'), ('D','Unità da diporto'), ('E','Aeromobii')),'Leasing'),
1159+
1160+ 'autofattura': fields.boolean('Autofattura'),
1161+ 'data_documento': fields.date('Data documento'),
1162+ 'data_registrazione': fields.date('Data registrazione'),
1163+ 'numero_fattura': fields.char('Numero Fattura - Doc riepilog.', size=16),
1164+
1165+ 'importo': fields.float('Importo', digits_compute=dp.get_precision('Account')),
1166+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1167+ }
1168+
1169+class spesometro_comunicazione_line_FR(orm.Model):
1170+
1171+ _name = "spesometro.comunicazione.line.fr"
1172+ _description = "Spesometro - Comunicazione linee quadro FR"
1173+ _columns = {
1174+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1175+
1176+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1177+ 'partita_iva': fields.char('Partita IVA', size=11),
1178+ 'documento_riepilogativo': fields.boolean('Documento Riepilogativo'),
1179+ 'data_documento': fields.date('Data documento'),
1180+ 'data_registrazione': fields.date('Data registrazione'),
1181+ 'iva_non_esposta': fields.boolean('IVA non esposta'),
1182+ 'reverse_charge': fields.boolean('Reverse charge'),
1183+ 'autofattura': fields.boolean('Autofattura'),
1184+
1185+ 'importo': fields.float('Importo', digits_compute=dp.get_precision('Account')),
1186+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1187+ }
1188+
1189+class spesometro_comunicazione_line_NE(orm.Model):
1190+
1191+ _name = "spesometro.comunicazione.line.ne"
1192+ _description = "Spesometro - Comunicazione linee quadro NE"
1193+ _columns = {
1194+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1195+
1196+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1197+ 'partita_iva': fields.char('Partita IVA', size=11),
1198+ 'codice_fiscale': fields.char('Codice Fiscale', size=16),
1199+ 'data_emissione': fields.date('Data emissione'),
1200+ 'data_registrazione': fields.date('Data registrazione'),
1201+ 'numero_nota': fields.char('Numero Nota', size=16),
1202+
1203+ 'importo': fields.float('Importo', digits_compute=dp.get_precision('Account')),
1204+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1205+ }
1206+
1207+class spesometro_comunicazione_line_NR(orm.Model):
1208+
1209+ _name = "spesometro.comunicazione.line.nr"
1210+ _description = "Spesometro - Comunicazione linee quadro NR"
1211+ _columns = {
1212+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1213+
1214+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1215+ 'partita_iva': fields.char('Partita IVA', size=11),
1216+ 'data_documento': fields.date('Data documento'),
1217+ 'data_registrazione': fields.date('Data registrazione'),
1218+
1219+ 'importo': fields.float('Importo', digits_compute=dp.get_precision('Account')),
1220+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1221+ }
1222+
1223+class spesometro_comunicazione_line_DF(orm.Model):
1224+
1225+ _name = "spesometro.comunicazione.line.df"
1226+ _description = "Spesometro - Comunicazione linee quadro DF"
1227+ _columns = {
1228+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1229+
1230+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1231+ 'codice_fiscale': fields.char('Codice Fiscale', size=16),
1232+ 'data_operazione': fields.date('Data operazione'),
1233+
1234+ 'importo': fields.float('Importo', digits_compute=dp.get_precision('Account')),
1235+ 'noleggio': fields.selection((('A','Autovettura'), ('B','Caravan'), ('C','Altri Veicoli'), ('D','Unità da diporto'), ('E','Aeromobii')),'Leasing'),
1236+ }
1237+
1238+class spesometro_comunicazione_line_FN(orm.Model):
1239+
1240+ _name = "spesometro.comunicazione.line.fn"
1241+ _description = "Spesometro - Comunicazione linee quadro FN"
1242+ _columns = {
1243+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1244+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1245+
1246+ 'pf_cognome': fields.char('Cognome', size=24, help=""),
1247+ 'pf_nome': fields.char('Nome', size=20, help=""),
1248+ 'pf_data_nascita': fields.date('Data di nascita'),
1249+ 'pf_comune_stato_nascita': fields.char('Comune o stato estero di nascita', size=40),
1250+ 'pf_provincia_nascita': fields.char('Provincia', size=2),
1251+ 'pf_codice_stato_estero_domicilio': fields.char('Codice Stato Estero del Domicilio', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1252+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1253+
1254+ 'pg_denominazione': fields.char('Denominazione/Ragione sociale', size=60),
1255+ 'pg_citta_estera_sede_legale': fields.char('Città estera delle Sede legale', size=40),
1256+ 'pg_codice_stato_estero_domicilio': fields.char('Codice Stato Estero del Domicilio', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1257+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1258+ 'pg_indirizzo_sede_legale': fields.char('Indirizzo legale', size=40),
1259+
1260+ 'data_emissione': fields.date('Data emissione'),
1261+ 'data_registrazione': fields.date('Data registrazione'),
1262+ 'numero_fattura': fields.char('Numero Fattura/Doc riepilog.', size=16),
1263+ 'noleggio': fields.selection((('A','Autovettura'), ('B','Caravan'), ('C','Altri Veicoli'), ('D','Unità da diporto'), ('E','Aeromobii')),'Leasing'),
1264+
1265+ 'importo': fields.float('Importo', digits_compute=dp.get_precision('Account')),
1266+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1267+ }
1268+
1269+
1270+class spesometro_comunicazione_line_SE(orm.Model):
1271+ '''
1272+ QUADRO SE - Acquisti di servizi da non residenti e Acquisti da operatori di San Marino
1273+ '''
1274+ _name = "spesometro.comunicazione.line.se"
1275+ _description = "Spesometro - Comunicazione linee quadro SE"
1276+ _columns = {
1277+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1278+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1279+
1280+ 'pf_cognome': fields.char('Cognome', size=24, help=""),
1281+ 'pf_nome': fields.char('Nome', size=20, help=""),
1282+ 'pf_data_nascita': fields.date('Data di nascita'),
1283+ 'pf_comune_stato_nascita': fields.char('Comune o stato estero di nascita', size=40),
1284+ 'pf_provincia_nascita': fields.char('Provincia', size=2),
1285+ 'pf_codice_stato_estero_domicilio': fields.char('Codice Stato Estero del Domicilio', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1286+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1287+
1288+ 'pg_denominazione': fields.char('Denominazione/Ragione sociale', size=60),
1289+ 'pg_citta_estera_sede_legale': fields.char('Città estera delle Sede legale', size=40),
1290+ 'pg_codice_stato_estero_domicilio': fields.char('Codice Stato Estero del Domicilio', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1291+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1292+ 'pg_indirizzo_sede_legale': fields.char('Indirizzo legale', size=40),
1293+
1294+ 'codice_identificativo_IVA': fields.char('Codice Identificativo IVA (037=San Marino)', size=3),
1295+ 'data_emissione': fields.date('Data emissione'),
1296+ 'data_registrazione': fields.date('Data registrazione'),
1297+ 'numero_fattura': fields.char('Numero Fattura/Doc riepilog.', size=16),
1298+
1299+ 'importo': fields.float('Importo/imponibile', digits_compute=dp.get_precision('Account')),
1300+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1301+ }
1302+
1303+ def add_line(self, cr, uid, move, invoice, arg):
1304+ comunicazione_lines_obj = self.pool.get('spesometro.comunicazione.line.se')
1305+ comunicazione_id = arg.get('comunicazione_id', False)
1306+ com_line_search = [('comunicazione_id','=',comunicazione_id), ('partner_id', '=', move.partner_id.id)]
1307+ com_line_ids = self.search(cr, uid, com_line_search)
1308+ val = {}
1309+ # Valori documento
1310+ doc_vals = self.pool.get('spesometro.comunicazione').compute_invoice_amounts(cr, uid, move, invoice, arg)
1311+ # p.iva
1312+ if move.partner_id.vat:
1313+ partita_iva = move.partner_id.vat[2:]
1314+ else:
1315+ partita_iva = '{:11s}'.format("".zfill(11))
1316+ # prov. nascita
1317+ prov_code = False
1318+ if move.partner_id.birth_city.name:
1319+ city_data = move.partner_id.address[0]._set_vals_city_data(cr, uid, {'city' : move.partner_id.birth_city.name})
1320+ prov_id = city_data.get('province_id', False)
1321+ if prov_id:
1322+ prov = self.pool.get('res.province').borwse(cr, uid, prov_id)
1323+ prov_nascita_code = prov.code
1324+ # Indirizzo
1325+ address = self.pool.get('spesometro.comunicazione')._get_partner_address_obj(cr, uid, move, invoice, arg)
1326+ # Codice identificativo IVA -Da indicare esclusivamente per operazioni con San Marino (Codice Stato = 037)
1327+ codice_identificativo_iva=''
1328+ if self.pool.get('spesometro.comunicazione').partner_is_from_san_marino(cr, uid, move, invoice, arg):
1329+ codice_identificativo_iva = '037'
1330+ val = {
1331+ 'comunicazione_id' : comunicazione_id,
1332+ 'partner_id' : move.partner_id.id,
1333+ 'codice_fiscale' : move.partner_id.fiscalcode or False,
1334+ 'noleggio' : move.partner_id.spesometro_leasing or False,
1335+
1336+ 'pf_cognome' : move.partner_id.fiscalcode_surname or False,
1337+ 'pf_nome' : move.partner_id.fiscalcode_firstname or False,
1338+ 'pf_data_nascita' : move.partner_id.birth_date or False,
1339+ 'pf_comune_stato_nascita' : move.partner_id.birth_city.name or False,
1340+ 'pf_provincia_nascita' : prov_code or False,
1341+ 'pf_codice_stato_estero_domicilio' : address.country_id.codice_stato_agenzia_entrate or codice_identificativo_iva or '',
1342+
1343+ 'pg_denominazione' : move.partner_id.name or False,
1344+ 'pg_citta_estera_sede_legale' : address.city or False,
1345+ 'pg_codice_stato_estero_domicilio' : address.country_id.codice_stato_agenzia_entrate or codice_identificativo_iva or '',
1346+ 'pg_indirizzo_sede_legale' : address.street or False,
1347+
1348+ 'codice_identificativo_IVA' : codice_identificativo_iva,
1349+
1350+ 'data_emissione': move.date,
1351+ 'data_registrazione': invoice.date_invoice or move.date,
1352+ 'numero_fattura': move.name,
1353+
1354+ 'importo': doc_vals.get('amount_untaxed', 0),
1355+ 'imposta': doc_vals.get('amount_tax', 0)
1356+ }
1357+
1358+ line_id = self.create(cr, uid, val)
1359+
1360+ return line_id
1361+
1362+class spesometro_comunicazione_line_TU(orm.Model):
1363+
1364+ _name = "spesometro.comunicazione.line.tu"
1365+ _description = "Spesometro - Comunicazione linee quadro TU"
1366+ _columns = {
1367+ 'comunicazione_id': fields.many2one('spesometro.comunicazione', 'Comunicazione', ondelete='cascade'),
1368+ 'partner_id': fields.many2one('res.partner', 'Partner'),
1369+
1370+ 'cognome': fields.char('Cognome', size=24, help=""),
1371+ 'nome': fields.char('Nome', size=20, help=""),
1372+ 'data_nascita': fields.date('Data di nascita'),
1373+ 'comune_stato_nascita': fields.char('Comune o stato estero di nascita', size=40),
1374+ 'provincia_nascita': fields.char('Provincia', size=2),
1375+ 'citta_estera_residenza': fields.char('Città Estera di residenza', size=40),
1376+ 'codice_stato_estero': fields.char('Codice Stato Estero', size=3, help="Deve essere uno di quelli presenti nella tabella 'elenco dei paesi e\
1377+ territori esteri' pubblicata nelle istruzioni del modello Unico"),
1378+ 'indirizzo_estero_residenza': fields.char('Indirizzo Estero di residenza', size=40),
1379+
1380+ 'data_emissione': fields.date('Data emissione'),
1381+ 'data_registrazione': fields.date('Data registrazione'),
1382+ 'numero_fattura': fields.char('Numero Fattura/Doc riepilog.', size=16),
1383+
1384+ 'importo': fields.float('Importo/imponibile', digits_compute=dp.get_precision('Account')),
1385+ 'imposta': fields.float('Imposta', digits_compute=dp.get_precision('Account')),
1386+ }
1387
1388=== added file 'l10n_it_spesometro/spesometro_view.xml'
1389--- l10n_it_spesometro/spesometro_view.xml 1970-01-01 00:00:00 +0000
1390+++ l10n_it_spesometro/spesometro_view.xml 2014-04-03 06:37:29 +0000
1391@@ -0,0 +1,650 @@
1392+<?xml version="1.0" encoding="utf-8"?>
1393+<openerp>
1394+ <data>
1395+
1396+ <!--
1397+ PARTNER
1398+ -->
1399+ <record id="spesometro_account_partner_view_form" model="ir.ui.view">
1400+ <field name="name">spesometro.account.partner.view.form</field>
1401+ <field name="model">res.partner</field>
1402+ <field name="inherit_id" ref="base.view_partner_form"/>
1403+ <field name="arch" type="xml">
1404+ <xpath expr="//field[@name='bank_ids']" position="before">
1405+ <separator string="Comunicazione art.21" colspan="4" />
1406+ <group colspan="2">
1407+ <field name="spesometro_escludi"/>
1408+ <field name="spesometro_operazione" attrs="{'invisible': [('spesometro_escludi', '=', True)]}"/>
1409+ <field name="spesometro_tipo_servizio" attrs="{'invisible': [('spesometro_operazione', '!=', 'BL1')], 'required': [('spesometro_operazione', '=', 'BL1')]}"/>
1410+ </group>
1411+ <group>
1412+ <field name="spesometro_IVA_non_esposta" attrs="{'invisible': ['|', ('spesometro_escludi', '=', True), ('spesometro_operazione', '!=', 'FA')]}" />
1413+ <field name="spesometro_indirizzo_estero" attrs="{'invisible': ['|','|',('spesometro_operazione', '=', 'FA'), ('spesometro_operazione', '=', 'SA'), ('spesometro_operazione', '=', 'DR')]}"
1414+ domain="[('partner_id','=', id)]" />
1415+ </group>
1416+ <group>
1417+ <field name="spesometro_leasing" attrs="{'invisible': [('spesometro_escludi', '=', True)]}" />
1418+ </group>
1419+ </xpath>
1420+ </field>
1421+ </record>
1422+
1423+ <!--
1424+ TAX CODE
1425+ -->
1426+ <record id="spesometro_account_tax_code_view_form" model="ir.ui.view">
1427+ <field name="name">spesometro.account.tax.code.view.form</field>
1428+ <field name="model">account.tax.code</field>
1429+ <field name="inherit_id" ref="account.view_tax_code_form"/>
1430+ <field name="arch" type="xml">
1431+ <xpath expr="//field[@name='sum']" position="after">
1432+ <group colspan="2" col="2">
1433+ <separator string="Comunicazione art.21" colspan="2" />
1434+ <field name="spesometro_escludi"/>
1435+ </group>
1436+ </xpath>
1437+ </field>
1438+ </record>
1439+
1440+ <!--
1441+ JOURNAL
1442+ -->
1443+ <record id="spesometro_account_journal_view_form" model="ir.ui.view">
1444+ <field name="name">spesometro.account.journal.view.form</field>
1445+ <field name="model">account.journal</field>
1446+ <field name="inherit_id" ref="account.view_account_journal_form"/>
1447+ <field name="arch" type="xml">
1448+ <xpath expr="//field[@name='sequence_id']" position="after">
1449+ <separator string="Comunicazione art.21" colspan="4" />
1450+ <field name="spesometro"/>
1451+ <field name="spesometro_operazione" attrs="{'invisible': [('spesometro', '=', False)], 'required': [('spesometro', '=', True)]}"/>
1452+ <field name="spesometro_segno" attrs="{'invisible': ['|', ('spesometro', '=', False), ('spesometro_operazione', '=', 'SA')], 'required': [('spesometro_operazione', 'IN', ('FA','BL1','BL2','BL3') )]}" />
1453+ <field name="spesometro_IVA_non_esposta" attrs="{'invisible': ['|', ('spesometro', '=', False), ('spesometro_operazione', '=', 'SA')]}" />
1454+ </xpath>
1455+ </field>
1456+ </record>
1457+
1458+
1459+ <!--
1460+ COUNTRY
1461+ -->
1462+ <record id="spesometro_res_country_view_form" model="ir.ui.view">
1463+ <field name="name">spesometro.res.country.view.form</field>
1464+ <field name="model">res.country</field>
1465+ <field name="inherit_id" ref="base.view_country_form"/>
1466+ <field name="arch" type="xml">
1467+ <xpath expr="//field[@name='address_format']" position="after">
1468+ <field name="codice_stato_agenzia_entrate"/>
1469+ </xpath>
1470+ </field>
1471+ </record>
1472+ <record id="spesometro_res_country_view_tree" model="ir.ui.view">
1473+ <field name="name">spesometro.res.country.view.tree</field>
1474+ <field name="model">res.country</field>
1475+ <field name="inherit_id" ref="base.view_country_tree"/>
1476+ <field name="arch" type="xml">
1477+ <xpath expr="//field[@name='code']" position="after">
1478+ <field name="codice_stato_agenzia_entrate"/>
1479+ </xpath>
1480+ </field>
1481+ </record>
1482+
1483+ <!--
1484+ SPESOMETRO
1485+ -->
1486+ <menuitem id="menu_spesometro_main"
1487+ name="Spesometro" parent="account.menu_account_end_year_treatments"/>
1488+
1489+ <!--
1490+ Configurazione
1491+ -->
1492+
1493+ <record id="spesometro_configurazione_view_tree" model="ir.ui.view">
1494+ <field name="name">spesometro.configurazione.view.tree</field>
1495+ <field name="model">spesometro.configurazione</field>
1496+ <field name="type">tree</field>
1497+ <field name="arch" type="xml">
1498+ <tree string="Configurazione Spesometro">
1499+ <field name="anno"/>
1500+ </tree>
1501+ </field>
1502+ </record>
1503+ <record id="spesometro_configurazione_view_form" model="ir.ui.view">
1504+ <field name="name">spesometro.configurazione.view.form</field>
1505+ <field name="model">spesometro.configurazione</field>
1506+ <field name="type">form</field>
1507+ <field name="arch" type="xml">
1508+ <form>
1509+ <group>
1510+ <field name="anno"/>
1511+ <newline/>
1512+ <field name="stato_san_marino"/>
1513+ </group>
1514+ <newline/>
1515+ <separator string="Quadri per dati in forma aggregata" colspan="6"></separator>
1516+ <group string="Quadro FA" col="2">
1517+ <label colspan="2">Operazioni documentate da fattura esposte in forma aggregata</label>
1518+ <field name="quadro_fa_limite_importo" />
1519+ <field name="quadro_fa_limite_importo_line" />
1520+ </group>
1521+ <group string="Quadro SA" col="2">
1522+ <label colspan="2">Operazioni senza fattura esposte in forma aggregata</label>
1523+ <field name="quadro_sa_limite_importo" />
1524+ <field name="quadro_sa_limite_importo_line" />
1525+ </group>
1526+ <group string="Quadro BL" col="2">
1527+ <label colspan="2">Operazioni con paesi con fiscalità privilegiata - Operazioni con soggetti non residenti - Acquisti di servizi da soggetti non residenti </label>
1528+ <field name="quadro_bl_limite_importo" />
1529+ <field name="quadro_bl_limite_importo_line" />
1530+ </group>
1531+ <newline/>
1532+ <separator string="Quadri per dati in forma analitica" colspan="6"></separator>
1533+ <group string="Quadro SE" col="2">
1534+ <label colspan="2">Acquisti di servizi da non residenti e Acquisti da operatori di San Marino</label>
1535+ <field name="quadro_se_limite_importo_line" />
1536+ </group>
1537+ </form>
1538+ </field>
1539+ </record>
1540+
1541+ <record id="spesometro_configurazione_action" model="ir.actions.act_window">
1542+ <field name="name">Configurazione Spesometro</field>
1543+ <field name="type">ir.actions.act_window</field>
1544+ <field name="res_model">spesometro.configurazione</field>
1545+ <field name="view_type">form</field>
1546+ <field name="view_mode">tree,form</field>
1547+ </record>
1548+
1549+ <menuitem id="menu_spesometro_configurazione" action="spesometro_configurazione_action"
1550+ name="Configurazione Spesometro" parent="menu_spesometro_main" sequence="100"/>
1551+
1552+
1553+ <!--
1554+ Comunicazioni
1555+ -->
1556+ <record id="spesometro_comunicazione_view_form" model="ir.ui.view">
1557+ <field name="name">spesometro.comunicazione.view.form</field>
1558+ <field name="model">spesometro.comunicazione</field>
1559+ <field name="type">form</field>
1560+ <field name="arch" type="xml">
1561+ <form>
1562+ <group colspan="4">
1563+ <field name="tipo"/>
1564+ <field name="progressivo_telematico"/>
1565+ <field name="periodo"/>
1566+ <field name="anno"/>
1567+ <field name="mese" attrs="{'invisible':[('periodo','!=','mese')], 'required':[('periodo','=','mese')]}"/>
1568+ <field name="trimestre" attrs="{'invisible':[('periodo','!=','trimestre')], 'required':[('periodo','=','trimestre')]}"/>
1569+ <field name="tipo_fornitore" invisible="1"/>
1570+ <field name="comunicazione_da_sostituire_annullare" attrs="{'invisible':[('tipo','=','ordinaria')], 'required':[('tipo','!=','ordinaria')]}"/>
1571+ <field name="documento_da_sostituire_annullare" attrs="{'invisible':[('tipo','=','ordinaria')], 'required':[('comunicazione_da_sostituire_annullare','!=',0)]}"/>
1572+ <newline/>
1573+ <field name="formato_dati"/>
1574+ </group>
1575+
1576+ <newline/>
1577+ <!--
1578+ Soggetto comunicazione
1579+ -->
1580+ <notebook>
1581+ <page string="Soggetto Obbligato">
1582+ <group colspan="4">
1583+ <field name="soggetto_codice_fiscale"/>
1584+ <field name="soggetto_partitaIVA"/>
1585+ <field name="soggetto_codice_attivita" required="1"/>
1586+ <field name="soggetto_telefono"/>
1587+ <field name="soggetto_fax"/>
1588+ <field name="soggetto_email"/>
1589+ <field name="soggetto_forma_giuridica"/>
1590+ </group>
1591+ <group attrs="{'invisible':[('soggetto_forma_giuridica','!=','persona_giuridica')]}">
1592+ <separator string="Dati persona giuridica" colspan="4"/>
1593+ <field name="soggetto_pg_denominazione" attrs="{'required':[('soggetto_forma_giuridica','==','persona_giuridica')]}" />
1594+ </group>
1595+ <group attrs="{'invisible':[('soggetto_forma_giuridica','==','persona_giuridica')]}">
1596+ <separator string="Dati persona fisica" colspan="4"/>
1597+ <field name="soggetto_pf_cognome" attrs="{'required':[('soggetto_forma_giuridica','!=','persona_giuridica')]}"/>
1598+ <field name="soggetto_pf_nome" attrs="{'required':[('soggetto_forma_giuridica','!=','persona_giuridica')]}"/>
1599+ <field name="soggetto_pf_sesso" attrs="{'required':[('soggetto_forma_giuridica','!=','persona_giuridica')]}"/>
1600+ <field name="soggetto_pf_data_nascita" attrs="{'required':[('soggetto_forma_giuridica','!=','persona_giuridica')]}"/>
1601+ <field name="soggetto_pf_comune_nascita" attrs="{'required':[('soggetto_forma_giuridica','!=','persona_giuridica')]}"/>
1602+ <field name="soggetto_pf_provincia_nascita" attrs="{'required':[('soggetto_forma_giuridica','!=','persona_giuridica')]}"/>
1603+ </group>
1604+ </page>
1605+
1606+ <page string="Soggetto Tenuto alla comunicazione">
1607+ <group colspan="4">
1608+ <field name="tipo_fornitore"/>
1609+ <field name="soggetto_cm_forma_giuridica"/>
1610+ <field name="soggetto_cm_codice_fiscale"/>
1611+ </group>
1612+ <group attrs="{'invisible':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}">
1613+ <separator string="Dati persona giuridica" colspan="4"/>
1614+ <field name="soggetto_cm_pg_denominazione" attrs="{'required':[('soggetto_cm_forma_giuridica','==','persona_giuridica')]}" />
1615+ </group>
1616+ <group attrs="{'invisible':[('soggetto_cm_forma_giuridica','==','persona_giuridica')]}">
1617+ <separator string="Dati persona fisica" colspan="4"/>
1618+ <field name="soggetto_cm_pf_cognome" attrs="{'required':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}"/>
1619+ <field name="soggetto_cm_pf_nome" attrs="{'required':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}"/>
1620+ <field name="soggetto_cm_pf_sesso" attrs="{'required':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}"/>
1621+ <field name="soggetto_cm_pf_data_nascita" attrs="{'required':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}"/>
1622+ <field name="soggetto_cm_pf_comune_nascita" attrs="{'required':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}"/>
1623+ <field name="soggetto_cm_pf_provincia_nascita" attrs="{'required':[('soggetto_cm_forma_giuridica','!=','persona_giuridica')]}"/>
1624+ </group>
1625+ </page>
1626+
1627+ <page string="Incaricato alla trasmissione">
1628+ <group colspan="4">
1629+ <field name="soggetto_trasmissione_codice_fiscale" attrs="{'required':[('tipo_fornitore','==','10')]}" />
1630+ <field name="soggetto_trasmissione_numero_CAF" />
1631+ <field name="soggetto_trasmissione_impegno" required="1" on_change="onchange_trasmissione_impegno(soggetto_trasmissione_impegno, context)" context="{'soggetto_codice_fiscale': soggetto_codice_fiscale}"/>
1632+ <field name="soggetto_trasmissione_data_impegno" attrs="{'required':[('soggetto_trasmissione_codice_fiscale','!=',False)]}"/>
1633+ </group>
1634+ </page>
1635+
1636+ </notebook>
1637+ <newline/>
1638+ <!--
1639+ Quadri
1640+ -->
1641+ <notebook>
1642+ <page string="Quadri FA">
1643+ <label colspan="4">FORMA AGGREGATA : Operazioni documentate da fattura esposte in forma aggregata</label>
1644+ <newline/>
1645+ <field name="line_FA_ids" nolabel="1">
1646+ <tree>
1647+ <field name="partner_id"/>
1648+ <field name="numero_operazioni_attive_aggregate" string="Nr op. attive"/>
1649+ <field name="numero_operazioni_passive_aggregate" string="Nr op. passive"/>
1650+ <field name="noleggio"/>
1651+ <field name="attive_imponibile_non_esente" string="Attive : Impon., non impon, esente"/>
1652+ <field name="attive_imposta" string="Attive : imposta"/>
1653+ <field name="passive_imponibile_non_esente" string="Passive : Impon., non impon, esente"/>
1654+ <field name="passive_imposta" string="Passive : imposta"/>
1655+ </tree>
1656+ </field>
1657+ </page>
1658+ <page string="Quadri SA">
1659+ <label colspan="4">FORMA AGGREGATA : Operazioni senza fattura esposte in forma aggregata</label>
1660+ <newline/>
1661+ <field name="line_SA_ids" nolabel="1">
1662+ <tree>
1663+ <field name="partner_id"/>
1664+ <field name="codice_fiscale"/>
1665+ <field name="numero_operazioni"/>
1666+ <field name="noleggio"/>
1667+ <field name="importo_complessivo"/>
1668+ </tree>
1669+ </field>
1670+ </page>
1671+ <page string="Quadri BL">
1672+ <label colspan="4">FORMA AGGREGATA : Operazioni con paesi con fiscalità privilegiata - Operazioni con soggetti non residenti
1673+ - Acquisti di servizi da soggetti non residenti</label>
1674+ <newline/>
1675+ <field name="line_BL_ids" nolabel="1">
1676+ <tree>
1677+ <field name="partner_id"/>
1678+ <field name="codice_fiscale"/>
1679+ <field name="noleggio"/>
1680+ <field name="pf_cognome"/>
1681+ <field name="pg_denominazione"/>
1682+ <field name="operazione_fiscalita_privilegiata"/>
1683+ <field name="operazione_con_soggetti_non_residenti"/>
1684+ <field name="Acquisto_servizi_da_soggetti_non_residenti"/>
1685+ <field name="attive_importo_complessivo"/>
1686+ <field name="passive_importo_complessivo"/>
1687+ </tree>
1688+ </field>
1689+ </page>
1690+ <page string="Quadri SE">
1691+ <label colspan="4">FORMA ANALITICA : Acquisti di servizi da non residenti e Acquisti da operatori di San Marino</label>
1692+ <newline/>
1693+ <field name="line_SE_ids" nolabel="1">
1694+ <tree>
1695+ <field name="partner_id"/>
1696+ <field name="pf_cognome"/>
1697+ <field name="pg_denominazione"/>
1698+ <field name="numero_fattura"/>
1699+ <field name="data_emissione"/>
1700+ <field name="data_registrazione"/>
1701+ <field name="importo"/>
1702+ <field name="imposta"/>
1703+ </tree>
1704+ </field>
1705+ </page>
1706+
1707+ <page string="Quadri FE">
1708+ <label colspan="4">FORMA ANALITICA : Fatture emesse e Documenti riepilogativi(Operazioni Attive)</label>
1709+ <newline/>
1710+ <field name="line_FE_ids" nolabel="1">
1711+ <tree>
1712+ <field name="partner_id"/>
1713+ <field name="partita_iva"/>
1714+ <field name="codice_fiscale"/>
1715+ <field name="numero_fattura"/>
1716+ <field name="data_documento"/>
1717+ <field name="data_registrazione"/>
1718+ <field name="importo"/>
1719+ <field name="imposta"/>
1720+ </tree>
1721+ </field>
1722+ </page>
1723+ <page string="Quadri FR">
1724+ <label colspan="4">FORMA ANALITICA : Fatture ricevute e Documenti riepilogativi (Operazioni passive)</label>
1725+ <newline/>
1726+ <field name="line_FR_ids" nolabel="1">
1727+ <tree>
1728+ <field name="partner_id"/>
1729+ <field name="partita_iva"/>
1730+ <field name="documento_riepilogativo"/>
1731+ <field name="data_documento"/>
1732+ <field name="data_registrazione"/>
1733+ <field name="importo"/>
1734+ <field name="imposta"/>
1735+ </tree>
1736+ </field>
1737+ </page>
1738+ <page string="Quadri NE">
1739+ <label colspan="4">FORMA ANALITICA : Note di variazione emesse</label>
1740+ <newline/>
1741+ <field name="line_NE_ids" nolabel="1">
1742+ <tree>
1743+ <field name="partner_id"/>
1744+ <field name="partita_iva"/>
1745+ <field name="codice_fiscale"/>
1746+ <field name="numero_nota"/>
1747+ <field name="data_emissione"/>
1748+ <field name="data_registrazione"/>
1749+ <field name="importo"/>
1750+ <field name="imposta"/>
1751+ </tree>
1752+ </field>
1753+ </page>
1754+ <page string="Quadri NR">
1755+ <label colspan="4">FORMA ANALITICA : Note di variazione ricevute</label>
1756+ <newline/>
1757+ <field name="line_NR_ids" nolabel="1">
1758+ <tree>
1759+ <field name="partner_id"/>
1760+ <field name="partita_iva"/>
1761+ <field name="data_documento"/>
1762+ <field name="data_registrazione"/>
1763+ <field name="importo"/>
1764+ <field name="imposta"/>
1765+ </tree>
1766+ </field>
1767+ </page>
1768+ <page string="Quadri DF">
1769+ <label colspan="4">FORMA ANALITICA : Operazioni senza fattura</label>
1770+ <newline/>
1771+ <field name="line_DF_ids" nolabel="1">
1772+ <tree>
1773+ <field name="partner_id"/>
1774+ <field name="codice_fiscale"/>
1775+ <field name="data_operazione"/>
1776+ <field name="importo"/>
1777+ </tree>
1778+ </field>
1779+ </page>
1780+ <page string="Quadri FN">
1781+ <label colspan="4">FORMA ANALITICA : Operazioni con soggetti non residenti (Operazioni attive)</label>
1782+ <newline/>
1783+ <field name="line_FN_ids" nolabel="1">
1784+ <tree>
1785+ <field name="partner_id"/>
1786+ <field name="pf_cognome"/>
1787+ <field name="pf_nome"/>
1788+ <field name="pg_denominazione"/>
1789+
1790+ <field name="numero_fattura"/>
1791+ <field name="data_emissione"/>
1792+ <field name="data_registrazione"/>
1793+ <field name="importo"/>
1794+ <field name="imposta"/>
1795+ </tree>
1796+ </field>
1797+ </page>
1798+ <page string="Quadri TU">
1799+ <label colspan="4">FORMA ANALITICA : Operazioni legate al turismo - Art. 3 comma 1 D.L. 16/2012</label>
1800+ <newline/>
1801+ <field name="line_TU_ids" nolabel="1">
1802+ <tree>
1803+ <field name="partner_id"/>
1804+ <field name="cognome"/>
1805+ <field name="nome"/>
1806+
1807+ <field name="numero_fattura"/>
1808+ <field name="data_emissione"/>
1809+ <field name="data_registrazione"/>
1810+ <field name="importo"/>
1811+ <field name="imposta"/>
1812+ </tree>
1813+ </field>
1814+ </page>
1815+ </notebook>
1816+ </form>
1817+ </field>
1818+ </record>
1819+
1820+ <record id="spesometro_comunicazione_view_tree" model="ir.ui.view">
1821+ <field name="name">spesometro.comunicazione.view.tree</field>
1822+ <field name="model">spesometro.comunicazione</field>
1823+ <field name="type">tree</field>
1824+ <field name="arch" type="xml">
1825+ <tree string="Comunicazioni">
1826+ <field name="progressivo_telematico"/>
1827+ <field name="tipo"/>
1828+ <field name="formato_dati"/>
1829+ <field name="periodo"/>
1830+ <field name="anno"/>
1831+ <field name="mese"/>
1832+ <field name="trimestre"/>
1833+ <field name="soggetto_codice_fiscale"/>
1834+ </tree>
1835+ </field>
1836+ </record>
1837+
1838+ <record model="ir.ui.view" id="spesometro_comunicazione_search">
1839+ <field name="name">salesman.commission.search</field>
1840+ <field name="model">spesometro.comunicazione</field>
1841+ <field name="type">search</field>
1842+ <field name="arch" type="xml">
1843+ <search string="Ricerca comunicazioni">
1844+ <field name="anno"/>
1845+ <newline/>
1846+ <group expand="0" string="Group By...">
1847+ <filter string="tipo" icon="terp-personal" domain="[]" context="{'group_by':'tipo'}"/>
1848+ <filter string="Periodo" icon="terp-go-month" domain="[]" context="{'group_by':'anno'}"/>
1849+ </group>
1850+ </search>
1851+ </field>
1852+ </record>
1853+
1854+ <record id="spesometro_comunicazione_action" model="ir.actions.act_window">
1855+ <field name="name">Comunicazioni</field>
1856+ <field name="type">ir.actions.act_window</field>
1857+ <field name="res_model">spesometro.comunicazione</field>
1858+ <field name="view_type">form</field>
1859+ <field name="view_mode">tree,form</field>
1860+ <field name="view_id" ref="spesometro_comunicazione_view_tree"/>
1861+ <!-- <field name="search_view_id" ref="spesometro_comunicazione_search" /> -->
1862+ </record>
1863+
1864+ <menuitem id="menu_spesometro_comunicazione" action="spesometro_comunicazione_action"
1865+ name="Comunicazioni" parent="menu_spesometro_main"/>
1866+
1867+ <!--
1868+ Quadro FA
1869+ -->
1870+ <record id="spesometro_comunicazione_fa_view_form" model="ir.ui.view">
1871+ <field name="name">spesometro.comunicazione.fa.view.form</field>
1872+ <field name="model">spesometro.comunicazione.line.fa</field>
1873+ <field name="type">form</field>
1874+ <field name="arch" type="xml">
1875+ <form string="Quado FA - Linea">
1876+ <group>
1877+ <field name="partner_id"/>
1878+ <newline/>
1879+ <field name="partita_iva"/>
1880+ <field name="codice_fiscale"/>
1881+ <field name="documento_riepilogativo"/>
1882+ <field name="noleggio"/>
1883+ </group>
1884+ <newline/>
1885+ <group string="Operazioni Attive">
1886+ <field name="numero_operazioni_attive_aggregate"/>
1887+ <field name="attive_imponibile_non_esente"/>
1888+ <field name="attive_imposta"/>
1889+ <field name="attive_operazioni_iva_non_esposta"/>
1890+ <field name="attive_note_variazione"/>
1891+ <field name="attive_note_variazione_imposta"/>
1892+ </group>
1893+ <newline/>
1894+ <group string="Operazioni Passive">
1895+ <field name="numero_operazioni_passive_aggregate"/>
1896+ <field name="passive_imponibile_non_esente"/>
1897+ <field name="passive_imposta"/>
1898+ <field name="passive_operazioni_iva_non_esposta"/>
1899+ <field name="passive_note_variazione"/>
1900+ <field name="passive_note_variazione_imposta"/>
1901+ </group>
1902+
1903+ </form>
1904+ </field>
1905+ </record>
1906+
1907+ <!--
1908+ Quadro SA
1909+ -->
1910+ <record id="spesometro_comunicazione_sa_view_form" model="ir.ui.view">
1911+ <field name="name">spesometro.comunicazione.sa.view.form</field>
1912+ <field name="model">spesometro.comunicazione.line.sa</field>
1913+ <field name="type">form</field>
1914+ <field name="arch" type="xml">
1915+ <form string="Quado SA - Linea">
1916+ <group>
1917+ <field name="partner_id"/>
1918+ <newline/>
1919+ <field name="codice_fiscale"/>
1920+ <field name="noleggio"/>
1921+ </group>
1922+ <newline/>
1923+ <group>
1924+ <field name="numero_operazioni"/>
1925+ <field name="importo_complessivo"/>
1926+ </group>
1927+ </form>
1928+ </field>
1929+ </record>
1930+
1931+
1932+ <!--
1933+ Quadro BL
1934+ -->
1935+ <record id="spesometro_comunicazione_bl_view_form" model="ir.ui.view">
1936+ <field name="name">spesometro.comunicazione.bl.view.form</field>
1937+ <field name="model">spesometro.comunicazione.line.bl</field>
1938+ <field name="type">form</field>
1939+ <field name="arch" type="xml">
1940+ <form string="Quado BL - Linea">
1941+ <group>
1942+ <field name="partner_id"/>
1943+ <newline/>
1944+ <field name="codice_fiscale"/>
1945+ <field name="noleggio"/>
1946+ <field name="codice_identificativo_IVA"/>
1947+ </group>
1948+ <newline/>
1949+ <group>
1950+ <field name="operazione_fiscalita_privilegiata"/>
1951+ <field name="operazione_con_soggetti_non_residenti"/>
1952+ <field name="Acquisto_servizi_da_soggetti_non_residenti"/>
1953+ </group>
1954+ <newline/>
1955+ <notebook>
1956+ <page string="Persona Giuridica">
1957+ <field name="pg_denominazione"/>
1958+ <field name="pg_citta_estera_sede_legale"/>
1959+ <field name="pg_codice_stato_estero"/>
1960+ <field name="pg_indirizzo_sede_legale"/>
1961+ </page>
1962+ <page string="Persona Fisica">
1963+ <field name="pf_cognome"/>
1964+ <field name="pf_nome"/>
1965+ <field name="pf_data_nascita"/>
1966+ <field name="pf_comune_stato_nascita"/>
1967+ <field name="pf_provincia_nascita"/>
1968+ <field name="pf_codice_stato_estero"/>
1969+ </page>
1970+ </notebook>
1971+ <newline/>
1972+ <group string="Operazioni Attive">
1973+ <field name="attive_importo_complessivo"/>
1974+ <field name="attive_imposta"/>
1975+ <field name="attive_non_sogg_cessione_beni"/>
1976+ <field name="attive_non_sogg_servizi"/>
1977+ <field name="attive_note_variazione"/>
1978+ <field name="attive_note_variazione_imposta"/>
1979+ </group>
1980+ <newline/>
1981+ <group string="Operazioni Passive">
1982+ <field name="passive_importo_complessivo"/>
1983+ <field name="passive_imposta"/>
1984+ <field name="passive_non_sogg_importo_complessivo"/>
1985+ <field name="passive_note_variazione"/>
1986+ <field name="passive_note_variazione_imposta"/>
1987+ </group>
1988+ </form>
1989+ </field>
1990+ </record>
1991+
1992+ <!--
1993+ Quadro SE
1994+ -->
1995+ <record id="spesometro_comunicazione_se_view_form" model="ir.ui.view">
1996+ <field name="name">spesometro.comunicazione.se.view.form</field>
1997+ <field name="model">spesometro.comunicazione.line.se</field>
1998+ <field name="type">form</field>
1999+ <field name="arch" type="xml">
2000+ <form string="Quado SE - Linea">
2001+ <group>
2002+ <group colspan="4">
2003+ <field name="partner_id"/>
2004+ <newline/>
2005+ <field name="codice_identificativo_IVA"/>
2006+ </group>
2007+ <newline/>
2008+ <separator string="Persona Giuridica" colspan="4"></separator>
2009+ <group>
2010+ <field name="pg_denominazione"/>
2011+ <field name="pg_citta_estera_sede_legale"/>
2012+ <field name="pg_codice_stato_estero_domicilio"/>
2013+ <field name="pg_indirizzo_sede_legale"/>
2014+ </group>
2015+ <newline/>
2016+ <separator string="Persona Fisica" colspan="4"></separator>
2017+ <group>
2018+ <field name="pf_cognome"/>
2019+ <field name="pf_nome"/>
2020+ <field name="pf_data_nascita"/>
2021+ <field name="pf_comune_stato_nascita"/>
2022+ <field name="pf_provincia_nascita"/>
2023+ <field name="pf_codice_stato_estero_domicilio"/>
2024+ </group>
2025+ <newline/>
2026+ <separator string="Documento" colspan="4"></separator>
2027+ <group>
2028+ <field name="data_emissione"/>
2029+ <field name="data_registrazione"/>
2030+ <field name="numero_fattura"/>
2031+ <newline/>
2032+ <field name="importo"/>
2033+ <field name="imposta"/>
2034+ </group>
2035+ </group>
2036+ </form>
2037+ </field>
2038+ </record>
2039+
2040+ </data>
2041+</openerp>
2042
2043=== added directory 'l10n_it_spesometro/wizard'
2044=== added file 'l10n_it_spesometro/wizard/__init__.py'
2045--- l10n_it_spesometro/wizard/__init__.py 1970-01-01 00:00:00 +0000
2046+++ l10n_it_spesometro/wizard/__init__.py 2014-04-03 06:37:29 +0000
2047@@ -0,0 +1,25 @@
2048+# -*- coding: utf-8 -*-
2049+##############################################################################
2050+#
2051+# Author: Alessandro Camilli (a.camilli@yahoo.it)
2052+# Copyright (C) 2014
2053+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
2054+#
2055+# This program is free software: you can redistribute it and/or modify
2056+# it under the terms of the GNU Affero General Public License as published
2057+# by the Free Software Foundation, either version 3 of the License, or
2058+# (at your option) any later version.
2059+#
2060+# This program is distributed in the hope that it will be useful,
2061+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2062+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2063+# GNU General Public License for more details.
2064+#
2065+# You should have received a copy of the GNU Affero General Public License
2066+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2067+#
2068+##############################################################################
2069+
2070+import wizard_crea_comunicazione
2071+import wizard_default
2072+import wizard_export
2073\ No newline at end of file
2074
2075=== added file 'l10n_it_spesometro/wizard/wizard_crea_comunicazione.py'
2076--- l10n_it_spesometro/wizard/wizard_crea_comunicazione.py 1970-01-01 00:00:00 +0000
2077+++ l10n_it_spesometro/wizard/wizard_crea_comunicazione.py 2014-04-03 06:37:29 +0000
2078@@ -0,0 +1,128 @@
2079+# -*- coding: utf-8 -*-
2080+##############################################################################
2081+#
2082+# Author: Alessandro Camilli (a.camilli@yahoo.it)
2083+# Copyright (C) 2014
2084+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
2085+#
2086+# This program is free software: you can redistribute it and/or modify
2087+# it under the terms of the GNU Affero General Public License as published
2088+# by the Free Software Foundation, either version 3 of the License, or
2089+# (at your option) any later version.
2090+#
2091+# This program is distributed in the hope that it will be useful,
2092+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2093+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2094+# GNU General Public License for more details.
2095+#
2096+# You should have received a copy of the GNU Affero General Public License
2097+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2098+#
2099+##############################################################################
2100+
2101+from osv import fields,osv
2102+from tools.translate import _
2103+import time
2104+
2105+class wizard_crea_comunicazione(osv.osv_memory):
2106+
2107+ def default_get(self, cr, uid, fields, context=None):
2108+
2109+ res = super(wizard_crea_comunicazione, self).default_get(cr, uid, fields, context=context)
2110+
2111+ res['periodo'] = 'anno'
2112+ res['anno'] = int(time.strftime('%Y')) -1
2113+ res['tipo'] = 'ordinaria'
2114+ res['formato_dati'] = 'aggregati'
2115+ res['quadro_FA'] = True
2116+ res['quadro_SA'] = True
2117+ res['quadro_BL'] = True
2118+ res['quadro_SE'] = True
2119+ res['tipo_fornitore'] = '01'
2120+
2121+ return res
2122+
2123+ _name = "wizard.spesometro.crea.comunicazione"
2124+
2125+ _columns = {
2126+ 'company_id': fields.many2one('res.company', 'Azienda', required=True ),
2127+ 'periodo': fields.selection((('anno','Annuale'), ('trimestre','Trimestrale'), ('mese','Mensile')),
2128+ 'Periodo', required=True),
2129+ 'anno' : fields.integer('Anno', size=4, required=True),
2130+ 'trimestre' : fields.integer('Trimestre', size=1 ),
2131+ 'mese' : fields.selection(((1,'Gennaio'), (2,'Febbraio'), (3,'Marzo'), (4,'Aprile'),
2132+ (5,'Maggio'), (6,'Giugno'), (7,'Luglio'), (8,'Agosto'),
2133+ (9,'Settembre'), (10,'Ottobre'), (11,'Novembre'), (12,'Dicembre'),
2134+ ),'Mese'),
2135+
2136+ 'tipo': fields.selection((('ordinaria','Ordinaria'), ('sostitutiva','Sostitutiva'), ('annullamento','Annullamento')),
2137+ 'Tipo comunicazione', required=True),
2138+ 'comunicazione_da_sostituire_annullare': fields.integer('Protocollo comunicaz. da sostituire/annullare'),
2139+ 'documento_da_sostituire_annullare': fields.integer('Protocollo documento da sostituire/annullare'),
2140+ 'formato_dati': fields.selection((('aggregati','Aggregati'),('analitici','Analitici')),'Formato comunicazione', required=True),
2141+ 'tipo_fornitore': fields.selection((('01','Soggetti che inviano la propria comunicazione'), ('10','Intermediari')),
2142+ 'Tipo fornitore', required=True),
2143+ 'partner_intermediario': fields.many2one('res.partner', 'Intermediario'),
2144+ 'quadro_FA': fields.boolean('Quadro FA', help="Operazioni documentate da fattura esposte in forma aggregata"),
2145+ 'quadro_SA': fields.boolean('Quadro SA', help="Operazioni senza fattura esposte in forma aggregata"),
2146+ 'quadro_BL': fields.boolean('Quadro BL', help="- Operazioni con paesi con fiscalità privilegiata - Operazioni con soggetti non residenti - Acquisti di servizi da soggetti non residenti "),
2147+
2148+ 'quadro_FE': fields.boolean('Quadro FE', help="Fatture emesse e Documenti riepilogativi (Operazioni attive)"),
2149+ 'quadro_FR': fields.boolean('Quadro FR', help="Fatture ricevute e Documenti riepilogativi (Operazioni passive)"),
2150+ 'quadro_NE': fields.boolean('Quadro NE', help="Note di variazione emesse"),
2151+ 'quadro_NR': fields.boolean('Quadro NR', help="Note di variazioni ricevute"),
2152+ 'quadro_DF': fields.boolean('Quadro DF', help="Operazioni senza fattura"),
2153+ 'quadro_FN': fields.boolean('Quadro FN', help="Operazioni con soggetti non residenti (Operazioni attive)"),
2154+ 'quadro_SE': fields.boolean('Quadro SE', help="Acquisti di servizi da non residenti e Acquisti da operatori di San Marino"),
2155+ 'quadro_TU': fields.boolean('Quadro TU', help="Operazioni legate al turismo - Art. 3 comma 1 D.L. 16/2012"),
2156+ }
2157+
2158+ def genera_comunicazione(self, cr, uid, ids, context=None):
2159+
2160+ comunicazione_obj = self.pool.get('spesometro.comunicazione')
2161+ wizard = self.read(cr, uid, ids)[0]
2162+
2163+ # Quadri richiesti:
2164+ quadri_richiesti = []
2165+ if wizard['quadro_FA']:
2166+ quadri_richiesti.append('FA')
2167+ if wizard['quadro_SA']:
2168+ quadri_richiesti.append('SA')
2169+ if wizard['quadro_BL']:
2170+ quadri_richiesti.append('BL')
2171+ if wizard['quadro_FE']:
2172+ quadri_richiesti.append('FE')
2173+ if wizard['quadro_FR']:
2174+ quadri_richiesti.append('FR')
2175+ if wizard['quadro_NE']:
2176+ quadri_richiesti.append('NE')
2177+ if wizard['quadro_NR']:
2178+ quadri_richiesti.append('NR')
2179+ if wizard['quadro_DF']:
2180+ quadri_richiesti.append('DF')
2181+ if wizard['quadro_FN']:
2182+ quadri_richiesti.append('FN')
2183+ if wizard['quadro_SE']:
2184+ quadri_richiesti.append('SE')
2185+ if wizard['quadro_TU']:
2186+ quadri_richiesti.append('TU')
2187+
2188+ params ={
2189+ 'company_id': wizard['company_id'][0],
2190+ 'periodo': wizard['periodo'],
2191+ 'anno': wizard['anno'],
2192+ 'trimestre': wizard['trimestre'],
2193+ 'mese': wizard['mese'],
2194+ 'tipo': wizard['tipo'],
2195+ 'comunicazione_da_sostituire_annullare': wizard['comunicazione_da_sostituire_annullare'],
2196+ 'documento_da_sostituire_annullare': wizard['documento_da_sostituire_annullare'],
2197+ 'formato_dati': wizard['formato_dati'],
2198+ 'tipo_fornitore': wizard['tipo_fornitore'],
2199+ 'partner_intermediario': wizard['partner_intermediario'],
2200+ 'quadri_richiesti': quadri_richiesti,
2201+ }
2202+ comunicazione_obj.genera_comunicazione(cr, uid, params, context=None)
2203+
2204+ return {
2205+ 'type': 'ir.actions.act_window_close',
2206+ }
2207
2208=== added file 'l10n_it_spesometro/wizard/wizard_crea_comunicazione_view.xml'
2209--- l10n_it_spesometro/wizard/wizard_crea_comunicazione_view.xml 1970-01-01 00:00:00 +0000
2210+++ l10n_it_spesometro/wizard/wizard_crea_comunicazione_view.xml 2014-04-03 06:37:29 +0000
2211@@ -0,0 +1,67 @@
2212+<?xml version="1.0" encoding="utf-8"?>
2213+<openerp>
2214+ <data>
2215+
2216+ <record id="wizard_spesometro_crea_comunicazione" model="ir.ui.view">
2217+ <field name="name">Crea comunicazione</field>
2218+ <field name="model">wizard.spesometro.crea.comunicazione</field>
2219+ <field name="type">form</field>
2220+ <field name="arch" type="xml">
2221+ <form string="Dati comunicazione">
2222+ <field name="company_id"/>
2223+ <newline/>
2224+ <field name="tipo_fornitore"/>
2225+ <field name="partner_intermediario" attrs="{'invisible': [('tipo_fornitore', '=', '01')], 'required': [('tipo_fornitore', '=', '10')]}"/>
2226+ <newline/>
2227+ <separator colspan="4"/>
2228+ <field name="periodo"/>
2229+ <field name="anno"/>
2230+ <field name="trimestre" attrs="{'invisible': [('periodo', '!=', 'trimestre')], 'required': [('periodo', '=', 'trimestre')]}"/>
2231+ <field name="mese" attrs="{'invisible': [('periodo', '!=', 'mese')], 'required': [('periodo', '=', 'mese')]}"/>
2232+ <separator colspan="4"/>
2233+ <field name="tipo"/>
2234+ <field name="comunicazione_da_sostituire_annullare" attrs="{'invisible': [('tipo', '=', 'ordinaria')]}" />
2235+ <field name="documento_da_sostituire_annullare" attrs="{'invisible': [('tipo', '=', 'ordinaria')]}"/>
2236+ <field name="formato_dati"/>
2237+ <newline/>
2238+ <group colspan="2">
2239+ <field name="quadro_FA" attrs="{'invisible': [('formato_dati', '!=', 'aggregati')]}" />
2240+ <field name="quadro_SA" attrs="{'invisible': [('formato_dati', '!=', 'aggregati')]}" />
2241+
2242+ <field name="quadro_SE" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}"/>
2243+ <field name="quadro_FE" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2244+ <field name="quadro_FR" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2245+ <field name="quadro_NE" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2246+ </group>
2247+ <group colspan="2">
2248+ <field name="quadro_BL" attrs="{'invisible': [('formato_dati', '!=', 'aggregati')]}" />
2249+
2250+ <field name="quadro_NR" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2251+ <field name="quadro_DF" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2252+ <field name="quadro_FN" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2253+ <field name="quadro_TU" attrs="{'invisible': [('formato_dati', '!=', 'analitici')]}" readonly="1"/>
2254+ </group>
2255+ <group colspan="4">
2256+ <separator colspan="4"/>
2257+ <button icon="gtk-cancel" special="cancel" string="Cancel"/>
2258+ <button icon="gtk-ok" name="genera_comunicazione" string="Crea" type="object"/>
2259+ </group>
2260+ </form>
2261+ </field>
2262+ </record>
2263+
2264+ <record id="wizard_spesometro_crea_comunicazione_action" model="ir.actions.act_window">
2265+ <field name="name">Nuova comunicazione</field>
2266+ <field name="type">ir.actions.act_window</field>
2267+ <field name="res_model">wizard.spesometro.crea.comunicazione</field>
2268+ <field name="view_type">form</field>
2269+ <field name="view_mode">form</field>
2270+ <field name="target">new</field>
2271+ <field name="view_id" ref="wizard_spesometro_crea_comunicazione"/>
2272+ <!-- <field name="search_view_id" ref="spesometro_comunicazione_search" /> -->
2273+ </record>
2274+
2275+ <menuitem id="menu_spesometro_crea_comunicazione" action="wizard_spesometro_crea_comunicazione_action"
2276+ name="Nuova comunicazione" parent="menu_spesometro_main"/>
2277+ </data>
2278+</openerp>
2279
2280=== added file 'l10n_it_spesometro/wizard/wizard_default.py'
2281--- l10n_it_spesometro/wizard/wizard_default.py 1970-01-01 00:00:00 +0000
2282+++ l10n_it_spesometro/wizard/wizard_default.py 2014-04-03 06:37:29 +0000
2283@@ -0,0 +1,65 @@
2284+# -*- coding: utf-8 -*-
2285+##############################################################################
2286+#
2287+# Author: Alessandro Camilli (a.camilli@yahoo.it)
2288+# Copyright (C) 2014
2289+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
2290+#
2291+# This program is free software: you can redistribute it and/or modify
2292+# it under the terms of the GNU Affero General Public License as published
2293+# by the Free Software Foundation, either version 3 of the License, or
2294+# (at your option) any later version.
2295+#
2296+# This program is distributed in the hope that it will be useful,
2297+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2298+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2299+# GNU General Public License for more details.
2300+#
2301+# You should have received a copy of the GNU Affero General Public License
2302+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2303+#
2304+##############################################################################
2305+
2306+from osv import fields,osv
2307+from tools.translate import _
2308+import time
2309+
2310+class wizard_spesometro_default(osv.osv_memory):
2311+
2312+ def default_get(self, cr, uid, fields, context=None):
2313+
2314+ res = super(wizard_spesometro_default, self).default_get(cr, uid, fields, context=context)
2315+ res = {
2316+ 'partner_spesometro_escludi' : False,
2317+ 'partner_spesometro_operazione' : 'FA'
2318+ }
2319+ return res
2320+
2321+ _name = "wizard.spesometro.default"
2322+
2323+ _columns = {
2324+ 'partner_spesometro_escludi': fields.boolean('Da Escludere'),
2325+ 'partner_spesometro_operazione': fields.selection((('FA','Operazioni documentate da fattura'),
2326+ ('SA','Operazioni senza fattura'),
2327+ ('BL1','Operazioni con paesi con fiscalit� privilegiata'),
2328+ ('BL2','Operazioni con soggetti non residenti'),
2329+ ('BL3','Acquisti di servizi da soggetti non residenti')),
2330+ 'Operazione' ),
2331+ }
2332+
2333+
2334+ def setting_default(self, cr, uid, ids, context=None):
2335+
2336+ partners_obj = self.pool.get('res.partner')
2337+ wizard = self.read(cr, uid, ids)[0]
2338+ vals = {
2339+ 'spesometro_escludi': wizard.get('partner_spesometro_escludi'),
2340+ 'spesometro_operazione': wizard.get('partner_spesometro_operazione'),
2341+ }
2342+
2343+ partners_ids = partners_obj.search(cr, uid, [('id','!=', 0)], context=context)
2344+ partners_obj.write(cr, uid, partners_ids, vals)
2345+
2346+ return {
2347+ 'type': 'ir.actions.act_window_close',
2348+ }
2349
2350=== added file 'l10n_it_spesometro/wizard/wizard_default_view.xml'
2351--- l10n_it_spesometro/wizard/wizard_default_view.xml 1970-01-01 00:00:00 +0000
2352+++ l10n_it_spesometro/wizard/wizard_default_view.xml 2014-04-03 06:37:29 +0000
2353@@ -0,0 +1,39 @@
2354+<?xml version="1.0" encoding="utf-8"?>
2355+<openerp>
2356+ <data>
2357+
2358+ <record id="wizard_spesometro_default_view" model="ir.ui.view">
2359+ <field name="name">Spesometro default</field>
2360+ <field name="model">wizard.spesometro.default</field>
2361+ <field name="type">form</field>
2362+ <field name="arch" type="xml">
2363+ <form string="Dati comunicazione">
2364+ <group string="Partner">
2365+ <field name="partner_spesometro_escludi"/>
2366+ <field name="partner_spesometro_operazione"/>
2367+ </group>
2368+
2369+ <newline/>
2370+ <group colspan="4">
2371+ <separator colspan="4"/>
2372+ <button icon="gtk-cancel" special="cancel" string="Cancel"/>
2373+ <button icon="gtk-ok" name="setting_default" string="Imposta default" type="object"/>
2374+ </group>
2375+ </form>
2376+ </field>
2377+ </record>
2378+
2379+ <record id="wizard_spesometro_default_action" model="ir.actions.act_window">
2380+ <field name="name">Spesometro default</field>
2381+ <field name="type">ir.actions.act_window</field>
2382+ <field name="res_model">wizard.spesometro.default</field>
2383+ <field name="view_type">form</field>
2384+ <field name="view_mode">form</field>
2385+ <field name="target">new</field>
2386+ <field name="view_id" ref="wizard_spesometro_default_view"/>
2387+ </record>
2388+
2389+ <menuitem id="menu_spesometro_default" action="wizard_spesometro_default_action"
2390+ name="Impostazione Default" parent="menu_spesometro_main"/>
2391+ </data>
2392+</openerp>
2393
2394=== added file 'l10n_it_spesometro/wizard/wizard_export.py'
2395--- l10n_it_spesometro/wizard/wizard_export.py 1970-01-01 00:00:00 +0000
2396+++ l10n_it_spesometro/wizard/wizard_export.py 2014-04-03 06:37:29 +0000
2397@@ -0,0 +1,710 @@
2398+# -*- coding: utf-8 -*-
2399+#################################################################################
2400+# Author: Alessandro Camilli (a.camilli@yahoo.it)
2401+# Copyright (C) 2014
2402+# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
2403+#
2404+# This program is free software: you can redistribute it and/or modify
2405+# it under the terms of the GNU General Public License as published by
2406+# the Free Software Foundation, either version 3 of the License, or
2407+# (at your option) any later version.
2408+#
2409+# This program is distributed in the hope that it will be useful,
2410+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2411+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2412+# GNU General Public License for more details.
2413+#
2414+# You should have received a copy of the GNU General Public License
2415+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2416+#
2417+##############################################################################
2418+
2419+from osv import fields,osv
2420+from tools.translate import _
2421+from datetime import datetime
2422+from StringIO import StringIO
2423+import base64
2424+from decimal import *
2425+
2426+class wizard_spesometro_export(osv.osv_memory):
2427+
2428+ _name = "wizard.spesometro.export"
2429+ _description = 'Use this wizard to export fiscal file'
2430+ _columns={
2431+ 'file_spesometro': fields.binary('File spesometro', readonly=True),
2432+ }
2433+
2434+ def _split_string_positional_field(self, string):
2435+ '''
2436+ Da manuale:
2437+ Con riferimento ai campi non posizionali, nel caso in cui la lunghezza del dato da inserire
2438+ ecceda i 16 caratteri disponibili, dovrà essere inserito un ulteriore elemento con un identico
2439+ campo-codice e con un campo-valore il cui primo carattere dovrà essere impostato con il simbolo “+”,
2440+ mentre i successivi quindici potranno essere utilizzati per la continuazione del dato da inserire.
2441+ Tale situazione può verificarsi solo per alcuni campi con formato AN.
2442+ '''
2443+ # Prima parte:
2444+ res = []
2445+ res.append(string[:16])
2446+ length = 15
2447+ # Parte in eccesso:
2448+ str_eccesso = string[16:]
2449+ str_split = [str_eccesso[i:i+length] for i in range(0, len(str_eccesso), length)]
2450+ for s in str_split:
2451+ new_string = '+' + s
2452+ res.append(new_string)
2453+ return res
2454+
2455+ def _record_A(self, cr, uid, comunicazione, context=None):
2456+
2457+ if not comunicazione.soggetto_trasmissione_codice_fiscale:
2458+ raise osv.except_osv(_('Errore comunicazione!'),_("Manca il codice fiscale dell'incaricato alla trasmissione"))
2459+
2460+ rcd = "A"
2461+ rcd += '{:14s}'.format("") # Filler
2462+ rcd += "NSP00" # codice fornitura
2463+ rcd += comunicazione.tipo_fornitore # 01 - Soggetti che inviano la propria comunicazione 10 -Intermediari
2464+ rcd += '{:16s}'.format(comunicazione.soggetto_trasmissione_codice_fiscale) # cd fiscale (se intermediaro va messo quello dell'intermediario)
2465+ rcd += '{:483s}'.format("")# Filler
2466+ #rcd += '{:4s}'.format(str(comunicazione.progressivo_telematico).zfill(4)) # dich.su più invii: Progressivo dell'invio telematico
2467+ rcd += '{:4s}'.format("0".zfill(4)) # dich.su più invii: Progressivo dell'invio telematico
2468+ rcd += '{:4s}'.format("0".zfill(4)) # dich.su più invii: Numero totale degli invii telematici
2469+ rcd += '{:100s}'.format("") # Filler
2470+ rcd += '{:1068s}'.format("") # Filler
2471+ rcd += '{:200s}'.format("") # Filler
2472+ rcd += "A" # Impostare al valore "A"
2473+ rcd += "\r" #
2474+ rcd += "\n" #
2475+
2476+ return rcd
2477+
2478+ def _record_B(self, cr, uid, comunicazione, context=None):
2479+ rcd = "B"
2480+ rcd += '{:16s}'.format(comunicazione.soggetto_codice_fiscale)
2481+ rcd += '{:8s}'.format("1".zfill(8)) # Progressivo modulo - vale 1
2482+ rcd += '{:3s}'.format("") # Spazio a disposizione dell'utente
2483+ rcd += '{:25s}'.format("") # Filler
2484+ rcd += '{:20s}'.format("") # Spazio a disposizione dell'utente
2485+ rcd += '{:16s}'.format("") # Identificativo del produttore del software (codice fiscale)
2486+ # tipo comunicazione ( alterntative: ordinaria,sostitutiva o di annullamento )
2487+ if comunicazione.tipo == 'ordinaria':
2488+ rcd += "1"
2489+ else:
2490+ rcd += "0"
2491+ if comunicazione.tipo == 'sostitutiva':
2492+ rcd += "1"
2493+ else:
2494+ rcd += "0"
2495+ if comunicazione.tipo == 'annullamento':
2496+ rcd += "1"
2497+ else:
2498+ rcd += "0"
2499+ # campi x annullamento e sostituzione
2500+ if comunicazione.comunicazione_da_sostituire_annullare == 0:
2501+ rcd += '{:17s}'.format("".zfill(17))
2502+ else:
2503+ rcd += '{:17s}'.format(str(comunicazione_da_sostituire_annullare).zfill(17))
2504+ if comunicazione.documento_da_sostituire_annullare == 0:
2505+ rcd += '{:6s}'.format("".zfill(6))
2506+ else:
2507+ rcd += '{:6s}'.format(str(comunicazione.documento_da_sostituire_annullare).zfill(6))
2508+ # formato dati: aggregata o analitica (caselle alternative)
2509+ if comunicazione.formato_dati == 'aggregati':
2510+ rcd += "10"
2511+ else:
2512+ rcd += "01"
2513+ # Quadri compilati
2514+ if comunicazione.line_FA_ids :
2515+ rcd += "1"
2516+ else:
2517+ rcd += "0"
2518+ if comunicazione.line_SA_ids :
2519+ rcd += "1"
2520+ else:
2521+ rcd += "0"
2522+ if comunicazione.line_BL_ids :
2523+ rcd += "1"
2524+ else:
2525+ rcd += "0"
2526+ #if comunicazione.quadro_FE :
2527+ # rcd += "1"
2528+ #else:
2529+ rcd += "0"
2530+ #if comunicazione.quadro_FR :
2531+ # rcd += "1"
2532+ #else:
2533+ rcd += "0"
2534+ #if comunicazione.quadro_NE :
2535+ # rcd += "1"
2536+ #else:
2537+ rcd += "0"
2538+ #if comunicazione.quadro_NR :
2539+ # rcd += "1"
2540+ #else:
2541+ rcd += "0"
2542+ #if comunicazione.quadro_DF :
2543+ # rcd += "1"
2544+ #else:
2545+ rcd += "0"
2546+ #if comunicazione.quadro_FN :
2547+ # rcd += "1"
2548+ #else:
2549+ rcd += "0"
2550+ if comunicazione.line_SE_ids :
2551+ rcd += "1"
2552+ else:
2553+ rcd += "0"
2554+ #if comunicazione.quadro_TU :
2555+ # rcd += "1"
2556+ #else:
2557+ rcd += "0"
2558+
2559+ rcd += "1" # Quadro TA - RIEPILOGO
2560+ #Partita IVA , Codice Attività e riferimenti del Soggetto cui si riferisce la comunicazione
2561+ rcd += '{:11s}'.format(comunicazione.soggetto_partitaIVA) # PARTITA IVA
2562+ if not comunicazione.soggetto_codice_attivita:
2563+ raise osv.except_osv(_('Errore comunicazione!'),_("Manca il codice attività"))
2564+ rcd += '{:6s}'.format(comunicazione.soggetto_codice_attivita) # CODICE attività (6 caratteri) --> obbligatorio
2565+ tel = comunicazione.soggetto_telefono
2566+ rcd += '{:12s}'.format(tel.replace(' ','') or '') # telefono
2567+ fax = comunicazione.soggetto_fax
2568+ rcd += '{:12s}'.format(fax.replace(' ','') or '') # fax
2569+ rcd += '{:50s}'.format(comunicazione.soggetto_email or '') # ind posta elettronica
2570+ # Dati Anagrafici del Soggetto cui si riferisce la comunicazione - Persona Fisica
2571+ if comunicazione.soggetto_cm_codice_fiscale and \
2572+ comunicazione.soggetto_cm_codice_fiscale == comunicazione.soggetto_codice_fiscale:
2573+ raise osv.except_osv(_('Errore comunicazione!'),_("Codice fiscale del soggetto tenuto \
2574+ Deve essere diverso da quello del soggetto obbligato a cui si riferisce la comunicazione"))
2575+ if comunicazione.soggetto_forma_giuridica == 'persona_fisica':
2576+ if not comunicazione.soggetto_pf_cognome or not comunicazione.soggetto_pf_nome or not comunicazione.soggetto_pf_sesso \
2577+ or not comunicazione.soggetto_pf_data_nascita or not comunicazione.soggetto_pf_comune_nascita or not comunicazione.soggetto_pf_provincia_nascita:
2578+ raise osv.except_osv(_('Errore comunicazione!'),_("Soggetto obbligato: Inserire tutti i dati della persona fisica"))
2579+ rcd += '{:24s}'.format(comunicazione.soggetto_pf_cognome) # cognome
2580+ rcd += '{:20s}'.format(comunicazione.soggetto_pf_nome) # nome
2581+ rcd += '{:1s}'.format(comunicazione.soggetto_pf_sesso) # sesso
2582+ rcd += '{:8s}'.format(datetime.strptime(comunicazione.soggetto_pf_data_nascita, "%Y-%m-%d").strftime("%d%m%Y")) # data nascita
2583+ rcd += '{:40s}'.format(comunicazione.soggetto_pf_comune_nascita) # comune di nascita
2584+ rcd += '{:2s}'.format(comunicazione.soggetto_pf_provincia_nascita) # provincia comune di nascita
2585+ rcd += '{:60s}'.format("") # persona giuridica
2586+ else:
2587+ if not comunicazione.soggetto_pg_denominazione:
2588+ raise osv.except_osv(_('Errore comunicazione!'),_("Soggetto obbligato: Inserire tutti i dati della persona giuridica"))
2589+ rcd += '{:24s}'.format("") # cognome
2590+ rcd += '{:20s}'.format("") # nome
2591+ rcd += '{:1s}'.format("") # sesso
2592+ rcd += '{:8s}'.format("".zfill(8)) # data nascita
2593+ rcd += '{:40s}'.format("") # comune di nascita
2594+ rcd += '{:2s}'.format("") # provincia comune di nascita
2595+ rcd += '{:60s}'.format(comunicazione.soggetto_pg_denominazione) # persona giuridica
2596+
2597+ rcd += '{:4d}'.format(comunicazione.anno) # anno riferimento
2598+ # Mese di riferimento : Da valorizzare obbligatoriamente solo se presenti Acquisti da Operatori di San Marino. In tutti gli altri casi non deve essere compilato
2599+ if comunicazione.periodo == 'trimestre' and comunicazione.trimestre:
2600+ rcd += '{:2s}'.format( str(comunicazione.trimestre) + "T")
2601+ elif comunicazione.periodo == 'mese' and comunicazione.mese:
2602+ rcd += '{:2s}'.format( str(comunicazione.mese).zfill(2))
2603+ else:
2604+ rcd += '{:2s}'.format("")
2605+ # Dati del Soggetto tenuto alla comunicazione (soggetto che effettua la comunicazione, se diverso dal soggetto cui si riferisce la comunicazione)
2606+ rcd += '{:16s}'.format(comunicazione.soggetto_cm_codice_fiscale or "")
2607+ rcd += '{:2s}'.format(comunicazione.tipo_fornitore or "01") # codice carica
2608+ rcd += '{:8s}'.format("".zfill(8)) # data inizio procedura
2609+ rcd += '{:8s}'.format("".zfill(8)) # data fine procedura
2610+ # Dati anagrafici del soggetto tenuto alla comunicazione - Persona fisica
2611+ # (Obbligatorio e da compilare solo se si tratta di Persona Fisica. )
2612+ if comunicazione.soggetto_cm_forma_giuridica == 'persona_fisica':
2613+ if not comunicazione.soggetto_cm_pf_cognome or not comunicazione.soggetto_cm_pf_nome or not comunicazione.soggetto_cm_pf_sesso \
2614+ or not comunicazione.soggetto_cm_pf_data_nascita or not comunicazione.soggetto_cm_pf_comune_nascita or not comunicazione.soggetto_cm_pf_provincia_nascita:
2615+ raise osv.except_osv(_('Errore comunicazione!'),_("Soggetto tenuto alla comunicazione: Inserire tutti i dati della persona fisica"))
2616+ rcd += '{:24s}'.format(comunicazione.soggetto_cm_pf_cognome) # cognome
2617+ rcd += '{:20s}'.format(comunicazione.soggetto_cm_pf_nome) # nome
2618+ rcd += '{:1s}'.format(comunicazione.soggetto_cm_pf_sesso) # sesso
2619+ rcd += '{:8s}'.format(datetime.strptime(comunicazione.soggetto_cm_pf_data_nascita, "%Y-%m-%d").strftime("%d%m%Y")) # data nascita
2620+ rcd += '{:40s}'.format(comunicazione.soggetto_cm_pf_comune_nascita) # comune di nascita
2621+ rcd += '{:2s}'.format(comunicazione.soggetto_cm_pf_provincia_nascita) # provincia comune di nascita
2622+ rcd += '{:60s}'.format("") # persona giuridica
2623+ else:
2624+ if not comunicazione.soggetto_cm_pg_denominazione:
2625+ raise osv.except_osv(_('Errore comunicazione!'),_("Soggetto tenuto alla comunicazione: Inserire tutti i dati della persona giuridica"))
2626+ rcd += '{:24s}'.format("") # cognome
2627+ rcd += '{:20s}'.format("") # nome
2628+ rcd += '{:1s}'.format("") # sesso
2629+ rcd += '{:8s}'.format("".zfill(8)) # data nascita
2630+ rcd += '{:40s}'.format("") # comune di nascita
2631+ rcd += '{:2s}'.format("") # provincia comune di nascita
2632+ rcd += '{:60s}'.format(comunicazione.soggetto_cm_pg_denominazione) # persona giuridica
2633+
2634+ # Impegno alla trasmissione telematica
2635+ if comunicazione.tipo_fornitore == '10' and not comunicazione.soggetto_trasmissione_codice_fiscale:
2636+ raise osv.except_osv(_('Errore comunicazione!'),_("Manca il codice fiscale dell'intermediario incaricato alla trasmissione telematica"))
2637+ rcd += '{:16s}'.format(comunicazione.soggetto_trasmissione_codice_fiscale or '') # Codice fiscale dell'intermediario
2638+ rcd += '{:5s}'.format(str(comunicazione.soggetto_trasmissione_numero_CAF).zfill(5)) # Numero di iscrizione all'albo del C.A.F.
2639+ rcd += '{:1s}'.format(comunicazione.soggetto_trasmissione_impegno)# Impegno a trasmettere in via telematica la comunicazione
2640+ # Dato obbligatorio Vale 1 se la comunicazione è stata predisposta dal soggetto obbligato
2641+ # Vale 2 se è stata predisposta dall'intermediario.
2642+ rcd += '{:1s}'.format("") # Filler
2643+ if not comunicazione.soggetto_trasmissione_data_impegno:
2644+ raise osv.except_osv(_('Errore comunicazione!'),_("Manca la data dell'impegno alla trasmissione"))
2645+ rcd += '{:8s}'.format(datetime.strptime(comunicazione.soggetto_trasmissione_data_impegno, "%Y-%m-%d").strftime("%d%m%Y")) # Data dell'impegno
2646+ # Spazio riservato al Servizio telematico
2647+ rcd += '{:1258s}'.format("") # Filler
2648+ rcd += '{:20s}'.format("") # Spazio riservato al Servizio Telematico
2649+ rcd += '{:18s}'.format("") # Filler
2650+ # Ultimi caratteri di controllo
2651+ rcd += "A" # Impostare al valore "A"
2652+ rcd += "\r" #
2653+ rcd += "\n" #
2654+
2655+ return rcd
2656+
2657+ def _record_C_FA(self, cr, uid, line, prog_modulo, prog_sezione, context=None):
2658+ prog_sezione = str(prog_sezione).zfill(3)
2659+
2660+ rcd = "C"
2661+ rcd += '{:16s}'.format(line.comunicazione_id.soggetto_codice_fiscale) # codice fiscale soggetto obbligato
2662+ rcd += '{:8s}'.format(str(prog_modulo).zfill(8)) # Progressivo modulo
2663+ rcd += '{:3s}'.format("") # Filler
2664+ rcd += '{:25s}'.format("") # Filler
2665+ rcd += '{:20s}'.format("") # Spazio utente
2666+ rcd += '{:16s}'.format("") # Filler
2667+
2668+ # QUADRO FA
2669+ # Partita iva o codice fiscale presenti se non si tratta di documento riepilogativo(ES: scheda carburante)
2670+ if not line.partita_iva and not line.codice_fiscale and not line.documento_riepilogativo:
2671+ raise osv.except_osv(_('Errore comunicazione!'),_("Inserire Codice Fiscale o partita IVA su partner %s") % (line.partner_id.name,))
2672+ # Doc. riepilogativo : non ammessi codice fiscale o partita iva
2673+ if line.documento_riepilogativo and (line.partita_iva or line.codice_fiscale) :
2674+ raise osv.except_osv(_('Errore comunicazione!'),_("Documento riepilogativo per partner %s, togliere Codice Fiscale E partita IVA") % (line.partner_id.name,))
2675+
2676+ if line.partita_iva:
2677+ rcd += '{:8s}'.format("FA" + prog_sezione + "001" )
2678+ rcd += '{:16s}'.format(line.partita_iva)
2679+ elif line.codice_fiscale:
2680+ rcd += '{:8s}'.format("FA" + prog_sezione + "002" )
2681+ rcd += '{:16s}'.format(line.codice_fiscale)
2682+ if line.documento_riepilogativo:
2683+ rcd += '{:8s}'.format("FA" + prog_sezione + "003" ) + '{:>16s}'.format('1')
2684+ # Numero operazioni attive aggregate
2685+ if line.numero_operazioni_attive_aggregate > 0:
2686+ rcd += '{:8s}'.format("FA" + prog_sezione + "004" ) + '{:16d}'.format(line.numero_operazioni_attive_aggregate)
2687+ # Numero operazioni passive aggregate
2688+ if line.numero_operazioni_passive_aggregate > 0:
2689+ rcd += '{:8s}'.format("FA" + prog_sezione + "005" ) + '{:16d}'.format(line.numero_operazioni_passive_aggregate)
2690+ # Noleggio / Leasing
2691+ if line.noleggio:
2692+ rcd += '{:8s}'.format("FA" + prog_sezione + "006" ) + '{:16s}'.format(line.noleggio)
2693+
2694+ # OPERAZIONI ATTIVE
2695+ if line.attive_imponibile_non_esente > 0:
2696+ rcd += '{:8s}'.format("FA" + prog_sezione + "007" ) + '{:16.0f}'.format(line.attive_imponibile_non_esente)
2697+ # Totale imposta
2698+ if line.attive_imposta > 0:
2699+ rcd += '{:8s}'.format("FA" + prog_sezione + "008" ) + '{:16.0f}'.format(line.attive_imposta)
2700+ # Totale operazioni con IVA non esposta
2701+ if line.attive_operazioni_iva_non_esposta > 0:
2702+ rcd += '{:8s}'.format("FA" + prog_sezione + "009" ) + '{:16.0f}'.format(line.attive_operazioni_iva_non_esposta)
2703+ # Totale note di variazione a debito per la controparte
2704+ if line.attive_note_variazione > 0:
2705+ rcd += '{:8s}'.format("FA" + prog_sezione + "010" ) + '{:16.0f}'.format(line.attive_note_variazione)
2706+ if line.attive_note_variazione_imposta > 0:
2707+ rcd += '{:8s}'.format("FA" + prog_sezione + "011" ) + '{:16.0f}'.format(line.attive_note_variazione_imposta)
2708+
2709+ # OPERAZIONI PASSIVE
2710+ # Totale operazioni imponibili, non imponibili ed esenti
2711+ if line.passive_imponibile_non_esente > 0:
2712+ rcd += '{:8s}'.format("FA" + prog_sezione + "012" ) + '{:16.0f}'.format(line.passive_imponibile_non_esente)
2713+ if line.passive_imposta > 0:
2714+ rcd += '{:8s}'.format("FA" + prog_sezione + "013" ) + '{:16.0f}'.format(line.passive_imposta)
2715+ if line.passive_operazioni_iva_non_esposta > 0:
2716+ rcd += '{:8s}'.format("FA" + prog_sezione + "014" ) + '{:16.0f}'.format(line.passive_operazioni_iva_non_esposta)
2717+ if line.passive_note_variazione > 0:
2718+ rcd += '{:8s}'.format("FA" + prog_sezione + "015" ) + '{:16.0f}'.format(line.passive_note_variazione)
2719+ if line.passive_note_variazione_imposta > 0:
2720+ rcd += '{:8s}'.format("FA" + prog_sezione + "016" ) + '{:16.0f}'.format(line.passive_note_variazione_imposta)
2721+
2722+ # riempio fino a 1900 caratteri
2723+ rcd += " " * (1897 -len(rcd))
2724+ # Ultimi caratteri di controllo
2725+ rcd += "A" # Impostare al valore "A"
2726+ rcd += "\r" #
2727+ rcd += "\n" #
2728+
2729+ return rcd
2730+
2731+ def _record_C_SA(self, cr, uid, line, prog_modulo, prog_sezione, context=None):
2732+ prog_sezione = str(prog_sezione).zfill(3)
2733+
2734+ if not line.codice_fiscale:
2735+ raise osv.except_osv(_('Errore comunicazione!'),_("Manca codice fiscale su partner %s") % (line.partner_id.name,))
2736+ rcd = "C"
2737+ rcd += '{:16s}'.format(line.comunicazione_id.soggetto_codice_fiscale) # codice fiscale soggetto obbligato
2738+ rcd += '{:8s}'.format(str(prog_modulo).zfill(8)) # Progressivo modulo
2739+ rcd += '{:3s}'.format("") # Filler
2740+ rcd += '{:25s}'.format("") # Filler
2741+ rcd += '{:20s}'.format("") # Spazio utente
2742+ rcd += '{:16s}'.format("") # Filler
2743+
2744+ rcd += '{:8s}'.format("SA" + prog_sezione + "001" ) + '{:16s}'.format(line.codice_fiscale)
2745+ if line.numero_operazioni:
2746+ rcd += '{:8s}'.format("SA" + prog_sezione + "002" ) + '{:16d}'.format(line.numero_operazioni)
2747+ if line.importo_complessivo:
2748+ rcd += '{:8s}'.format("SA" + prog_sezione + "003" ) + '{:16.0f}'.format(line.importo_complessivo)
2749+ if line.noleggio:
2750+ rcd += '{:8s}'.format("SA" + prog_sezione + "004" ) + '{:16s}'.format(line.noleggio)
2751+
2752+ # riempio fino a 1900 caratteri
2753+ rcd += " " * (1897 -len(rcd))
2754+ # Ultimi caratteri di controllo
2755+ rcd += "A" # Impostare al valore "A"
2756+ rcd += "\r" #
2757+ rcd += "\n" #
2758+
2759+ return rcd
2760+
2761+ def _record_C_BL(self, cr, uid, line, prog_modulo, prog_sezione, context=None):
2762+
2763+ prog_sezione = str(prog_sezione).zfill(3)
2764+
2765+ # Controlli
2766+ # ...Operazioni con paesi con fiscalità privilegiata (è obbligatorio compilare le sezioni BL001, BL002 e almeno un campo delle sezioni BL003, BL004, BL005, BL006, BL007, BL008)
2767+ if line.operazione_fiscalita_privilegiata:
2768+ if (not line.pf_cognome or not line.pf_nome) and not line.pg_denominazione:
2769+ raise osv.except_osv(_("Errore quadro BL"), _(" - Partner %s! Cognome e nome obbligatori oppure ragione sociale per soggetto giuridico") % (line.partner_id.name ,) )
2770+ # ...Operazioni con soggetti non residenti (è obbligatorio compilare le sezioni BL001, BL002 e almeno un campo delle sezioni BL003 e BL006)
2771+ if line.operazione_con_soggetti_non_residenti:
2772+ if (not line.pf_cognome or not line.pf_nome) and not line.pg_denominazione:
2773+ raise osv.except_osv(_("Errore quadro BL"), _(" - Partner %s! Cognome e nome obbligatori oppure ragione sociale per soggetto giuridico") % (line.partner_id.name ,) )
2774+ if line.pf_cognome and not line.pf_data_nascita and not line.pf_codice_stato_estero:
2775+ raise osv.except_osv(_("Errore quadro BL - Partner %s! Inserire alemno uno dei seguenti valori: \
2776+ Pers.Fisica-Data di nascita, Pers.Fisica-Codice Stato") % (line.partner_id.name ,) )
2777+ # ...Acquisti di servizi da soggetti non residenti (è obbligatorio compilare le sezioni BL001, BL002 e almeno un campo della sezione BL006)
2778+ if line.Acquisto_servizi_da_soggetti_non_residenti:
2779+ if (not line.pf_cognome or not line.pf_nome) and not line.pg_denominazione:
2780+ raise osv.except_osv(_("Errore quadro BL"), _(" - Partner %s! Cognome e nome obbligatori oppure ragione sociale per soggetto giuridico") % (line.partner_id.name ,) )
2781+ if line.pf_cognome and not line.pf_data_nascita and not line.pf_codice_stato_estero:
2782+ raise osv.except_osv(_("Errore quadro BL"), _(" - Partner %s! Inserire alemno uno dei seguenti valori: \
2783+ Pers.Fisica-Data di nascita, Pers.Fisica-Codice Stato") % (line.partner_id.name ,) )
2784+
2785+ rcd = "C"
2786+ rcd += '{:16s}'.format(line.comunicazione_id.soggetto_codice_fiscale) # codice fiscale soggetto obbligato
2787+ rcd += '{:8s}'.format(str(prog_modulo).zfill(8)) # Progressivo modulo
2788+ rcd += '{:3s}'.format("") # Filler
2789+ rcd += '{:25s}'.format("") # Filler
2790+ rcd += '{:20s}'.format("") # Spazio utente
2791+ rcd += '{:16s}'.format("") # Filler
2792+
2793+ # Dati anagrafici
2794+ # .. persona fisica
2795+ if line.pf_cognome:
2796+ if not line.pf_nome or not line.pf_data_nascita or not line.pf_comune_stato_nascita or not line.pf_provincia_nascita \
2797+ or not line.pf_codice_stato_estero:
2798+ raise osv.except_osv('Error', _('Completare dati persona fisica nel quadro BL del partner: %s') %(line.partner_id.name,))
2799+ str_split = self._split_string_positional_field(line.pf_cognome)
2800+ for s in str_split:
2801+ rcd += '{:8s}'.format("BL" + "001" + "001" ) + '{:16s}'.format(s)
2802+ str_split = self._split_string_positional_field(line.pf_nome)
2803+ for s in str_split:
2804+ rcd += '{:8s}'.format("BL" + "001" + "002" ) + '{:16s}'.format(s)
2805+ rcd += '{:8s}'.format("BL" + "001" + "003" ) + '{:16s}'.format(datetime.strptime(line.pf_data_nascita, "%Y-%m-%d").strftime("%d%m%Y")) # Data di nascita
2806+ str_split = self._split_string_positional_field(line.pf_comune_stato_nascita)
2807+ for s in str_split:
2808+ rcd += '{:8s}'.format("BL" + "001" + "004" ) + '{:16s}'.format(s)
2809+ rcd += '{:8s}'.format("BL" + "001" + "005" ) + '{:16s}'.format(line.pf_provincia_nascita)
2810+ rcd += '{:8s}'.format("BL" + "001" + "006" ) + '{:>16s}'.format(line.pf_codice_stato_estero)
2811+ # .. persona giuridica
2812+ if line.pg_denominazione:
2813+ if not line.pg_citta_estera_sede_legale or not line.pg_codice_stato_estero or not line.pg_indirizzo_sede_legale:
2814+ raise osv.except_osv('Error', _('Completare dati persona giuridica nel quadro BL del partner: %s : Citta estera - Codice Stato estero - Indirizzo') %(line.partner_id.name,))
2815+ str_split = self._split_string_positional_field(line.pg_denominazione)
2816+ for s in str_split:
2817+ rcd += '{:8s}'.format("BL" + "001" + "007" ) + '{:16s}'.format(s)
2818+ str_split = self._split_string_positional_field(line.pg_citta_estera_sede_legale)
2819+ for s in str_split:
2820+ rcd += '{:8s}'.format("BL" + "001" + "008" ) + '{:16s}'.format(s)
2821+ rcd += '{:8s}'.format("BL" + "001" + "009" ) + '{:>16s}'.format(line.pg_codice_stato_estero)
2822+ str_split = self._split_string_positional_field(line.pg_indirizzo_sede_legale)
2823+ for s in str_split:
2824+ rcd += '{:8s}'.format("BL" + "001" + "010" ) + '{:16s}'.format(s)
2825+ # Codice identificativo IVA
2826+ if line.codice_identificativo_IVA:
2827+ rcd += '{:8s}'.format("BL" + "002" + "001" ) + '{:16s}'.format(line.codice_identificativo_IVA or '')
2828+ # Operazioni con paesi con fiscalità privilegiata
2829+ rcd += '{:8s}'.format("BL" + "002" + "002" )
2830+ if line.operazione_fiscalita_privilegiata:
2831+ rcd += '{:>16s}'.format("1")
2832+ else:
2833+ rcd += '{:>16s}'.format("0")
2834+
2835+ # Operazioni con soggetti non residenti
2836+ rcd += '{:8s}'.format("BL" + "002" + "003" )
2837+ if line.operazione_con_soggetti_non_residenti:
2838+ rcd += '{:>16s}'.format("1")
2839+ else:
2840+ rcd += '{:>16s}'.format("0")
2841+ # Acquisti di servizi da soggetti non residenti
2842+ rcd += '{:8s}'.format("BL" + "002" + "004" )
2843+ if line.Acquisto_servizi_da_soggetti_non_residenti:
2844+ rcd += '{:>16s}'.format("1")
2845+ else:
2846+ rcd += '{:>16s}'.format("0")
2847+
2848+
2849+ # OPERAZIONI ATTIVE
2850+ if line.attive_importo_complessivo > 0:
2851+ rcd += '{:8s}'.format("BL" + "003" + "001" ) + '{:16.0f}'.format(line.attive_importo_complessivo)
2852+ if line.attive_imposta > 0:
2853+ rcd += '{:8s}'.format("BL" + "003" + "002" ) + '{:16.0f}'.format(line.attive_imposta)
2854+
2855+ if line.operazione_fiscalita_privilegiata:
2856+ if line.attive_non_sogg_cessione_beni > 0:
2857+ rcd += '{:8s}'.format("BL" + "004" + "001" ) + '{:16.0f}'.format(line.attive_non_sogg_cessione_beni)
2858+ if line.attive_non_sogg_servizi > 0:
2859+ rcd += '{:8s}'.format("BL" + "004" + "002" ) + '{:16.0f}'.format(line.attive_non_sogg_servizi)
2860+ if line.attive_note_variazione > 0:
2861+ rcd += '{:8s}'.format("BL" + "005" + "001" ) + '{:16.0f}'.format(line.attive_note_variazione)
2862+ if line.attive_note_variazione_imposta > 0:
2863+ rcd += '{:8s}'.format("BL" + "005" + "002" ) + '{:16.0f}'.format(line.attive_note_variazione_imposta)
2864+
2865+ # OPERAZIONI PASSIVE
2866+ if line.passive_importo_complessivo > 0:
2867+ rcd += '{:8s}'.format("BL" + "006" + "001" ) + '{:16.0f}'.format(line.passive_importo_complessivo)
2868+ if line.passive_imposta > 0:
2869+ rcd += '{:8s}'.format("BL" + "006" + "002" ) + '{:16.0f}'.format(line.passive_imposta)
2870+
2871+ if line.operazione_fiscalita_privilegiata:
2872+ if line.passive_non_sogg_importo_complessivo > 0:
2873+ rcd += '{:8s}'.format("BL" + "007" + "001" ) + '{:16.0f}'.format(line.passive_non_sogg_importo_complessivo)
2874+ if line.passive_note_variazione > 0:
2875+ rcd += '{:8s}'.format("BL" + "008" + "001" ) + '{:16.0f}'.format(line.passive_note_variazione)
2876+ if line.passive_note_variazione_imposta > 0:
2877+ rcd += '{:8s}'.format("BL" + "008" + "002" ) + '{:16.0f}'.format(line.passive_note_variazione_imposta)
2878+
2879+ # riempio fino a 1900 caratteri
2880+ rcd += " " * (1897 -len(rcd))
2881+ # Ultimi caratteri di controllo
2882+ rcd += "A" # Impostare al valore "A"
2883+ rcd += "\r" #
2884+ rcd += "\n" #
2885+
2886+ return rcd
2887+
2888+ def _record_D_SE(self, cr, uid, line, prog_modulo, prog_sezione, context=None):
2889+
2890+ prog_sezione = str(prog_sezione).zfill(3)
2891+
2892+ # Controlli
2893+ # ...Cognome o Ragione sociale
2894+ if (not line.pf_cognome or not line.pf_nome) and not line.pg_denominazione:
2895+ raise osv.except_osv(_("Errore quadro SE"), _(" - Partner %s! Cognome e nome obbligatori oppure ragione sociale per soggetto giuridico") % (line.partner_id.name ,) )
2896+ # ...
2897+ if line.pf_cognome and not line.pf_data_nascita and not line.pf_codice_stato_estero:
2898+ raise osv.except_osv(_("Errore quadro SE - Partner %s! Inserire alemno uno dei seguenti valori: \
2899+ Pers.Fisica-Data di nascita, Pers.Fisica-Codice Stato") % (line.partner_id.name ,) )
2900+
2901+ rcd = "D"
2902+ rcd += '{:16s}'.format(line.comunicazione_id.soggetto_codice_fiscale) # codice fiscale soggetto obbligato
2903+ rcd += '{:8s}'.format(str(prog_modulo).zfill(8)) # Progressivo modulo
2904+ rcd += '{:3s}'.format("") # Filler
2905+ rcd += '{:25s}'.format("") # Filler
2906+ rcd += '{:20s}'.format("") # Spazio utente
2907+ rcd += '{:16s}'.format("") # Filler
2908+
2909+ # Dati anagrafici
2910+ # .. persona fisica
2911+ if line.pf_cognome:
2912+ if not line.pf_nome or not line.pf_data_nascita or not line.pf_comune_stato_nascita or not line.pf_provincia_nascita \
2913+ or not line.pf_codice_stato_estero:
2914+ raise osv.except_osv('Error', _('Completare dati persona fisica nel quadro SE del partner: %s') %(line.partner_id.name,))
2915+ str_split = self._split_string_positional_field(line.pf_cognome)
2916+ for s in str_split:
2917+ rcd += '{:8s}'.format("SE" + prog_sezione + "001" ) + '{:16s}'.format(s)
2918+ str_split = self._split_string_positional_field(line.pf_nome)
2919+ for s in str_split:
2920+ rcd += '{:8s}'.format("SE" + prog_sezione + "002" ) + '{:16s}'.format(s)
2921+ rcd += '{:8s}'.format("SE" + prog_sezione + "003" ) + '{:16s}'.format(datetime.strptime(line.pf_data_nascita, "%Y-%m-%d").strftime("%d%m%Y")) # Data di nascita
2922+ str_split = self._split_string_positional_field(line.pf_comune_stato_nascita)
2923+ for s in str_split:
2924+ rcd += '{:8s}'.format("SE" + prog_sezione + "004" ) + '{:16s}'.format(s)
2925+ rcd += '{:8s}'.format("SE" + prog_sezione + "005" ) + '{:16s}'.format(line.pf_provincia_nascita)
2926+ rcd += '{:8s}'.format("SE" + prog_sezione + "006" ) + '{:>16s}'.format(line.pf_codice_stato_estero_domicilio)
2927+ # .. persona giuridica
2928+ if line.pg_denominazione:
2929+ if not line.pg_citta_estera_sede_legale or not line.pg_codice_stato_estero_domicilio or not line.pg_indirizzo_sede_legale:
2930+ raise osv.except_osv('Error', _('Completare dati persona giuridica nel quadro SE del partner: %s : Citta estera - Codice Stato estero - Indirizzo') %(line.partner_id.name,))
2931+ str_split = self._split_string_positional_field(line.pg_denominazione)
2932+ for s in str_split:
2933+ rcd += '{:8s}'.format("SE" + prog_sezione + "007" ) + '{:16s}'.format(s)
2934+ str_split = self._split_string_positional_field(line.pg_citta_estera_sede_legale)
2935+ for s in str_split:
2936+ rcd += '{:8s}'.format("SE" + prog_sezione + "008" ) + '{:16s}'.format(s)
2937+ rcd += '{:8s}'.format("SE" + prog_sezione + "009" ) + '{:>16s}'.format(line.pg_codice_stato_estero_domicilio)
2938+ str_split = self._split_string_positional_field(line.pg_indirizzo_sede_legale)
2939+ for s in str_split:
2940+ rcd += '{:8s}'.format("SE" + prog_sezione + "010" ) + '{:16s}'.format(s)
2941+ # Codice identificativo IVA
2942+ if line.codice_identificativo_IVA:
2943+ rcd += '{:8s}'.format("SE" + prog_sezione + "011" ) + '{:16s}'.format(line.codice_identificativo_IVA)
2944+ # Dati documento
2945+ rcd += '{:8s}'.format("SE" + prog_sezione + "012" ) + '{:>16s}'.format(datetime.strptime(line.data_emissione, "%Y-%m-%d").strftime("%d%m%Y"))
2946+ rcd += '{:8s}'.format("SE" + prog_sezione + "013" ) + '{:>16s}'.format(datetime.strptime(line.data_registrazione, "%Y-%m-%d").strftime("%d%m%Y"))
2947+ rcd += '{:8s}'.format("SE" + prog_sezione + "014" ) + '{:16s}'.format(line.numero_fattura)
2948+
2949+ if line.importo > 0:
2950+ rcd += '{:8s}'.format("SE" + prog_sezione + "015" ) + '{:16.0f}'.format(line.importo)
2951+ if line.imposta > 0:
2952+ rcd += '{:8s}'.format("SE" + prog_sezione + "016" ) + '{:16.0f}'.format(line.imposta)
2953+
2954+ # riempio fino a 1900 caratteri
2955+ rcd += " " * (1897 -len(rcd))
2956+ # Ultimi caratteri di controllo
2957+ rcd += "A" # Impostare al valore "A"
2958+ rcd += "\r" #
2959+ rcd += "\n" #
2960+
2961+ return rcd
2962+
2963+
2964+ def _record_E(self, cr, uid, comunicazione, prog_modulo, context=None):
2965+ rcd = "E"
2966+ rcd += '{:16s}'.format(comunicazione.soggetto_codice_fiscale)
2967+ #rcd += '{:8d}'.format(prog_modulo) # Progressivo modulo
2968+ rcd += '{:8s}'.format(str(prog_modulo).zfill(8)) # Progressivo modulo
2969+ rcd += '{:3s}'.format("") # Filler
2970+ rcd += '{:25s}'.format("") # Filler
2971+ rcd += '{:20s}'.format("") # Filler
2972+ rcd += '{:16s}'.format("") # Filler
2973+ # Aggregate
2974+ if comunicazione.totale_FA:
2975+ rcd += '{:8s}'.format("TA001001") + '{:16d}'.format(comunicazione.totale_FA)
2976+ if comunicazione.totale_SA:
2977+ rcd += '{:8s}'.format("TA002001") + '{:16d}'.format(comunicazione.totale_SA)
2978+ if comunicazione.totale_BL1:
2979+ rcd += '{:8s}'.format("TA003001") + '{:16d}'.format(comunicazione.totale_BL1)
2980+ if comunicazione.totale_BL2:
2981+ rcd += '{:8s}'.format("TA003002") + '{:16d}'.format(comunicazione.totale_BL2)
2982+ if comunicazione.totale_BL3:
2983+ rcd += '{:8s}'.format("TA003003") + '{:16d}'.format(comunicazione.totale_BL3)
2984+ # Analitiche
2985+ if comunicazione.totale_FE:
2986+ rcd += '{:8s}'.format("TA004001") + '{:16d}'.format(comunicazione.totale_FE)
2987+ if comunicazione.totale_FE_R:
2988+ rcd += '{:8s}'.format("TA004002") + '{:16d}'.format(comunicazione.totale_FE_R)
2989+ if comunicazione.totale_FR:
2990+ rcd += '{:8s}'.format("TA005001") + '{:16d}'.format(comunicazione.totale_FR)
2991+ if comunicazione.totale_FR_R:
2992+ rcd += '{:8s}'.format("TA005002") + '{:16d}'.format(comunicazione.totale_FR_R)
2993+ if comunicazione.totale_NE:
2994+ rcd += '{:8s}'.format("TA006001") + '{:16d}'.format(comunicazione.totale_NE)
2995+ if comunicazione.totale_NR:
2996+ rcd += '{:8s}'.format("TA007001") + '{:16d}'.format(comunicazione.totale_NR)
2997+ if comunicazione.totale_DF:
2998+ rcd += '{:8s}'.format("TA008001") + '{:16d}'.format(comunicazione.totale_DF)
2999+ if comunicazione.totale_FN:
3000+ rcd += '{:8s}'.format("TA009001") + '{:16d}'.format(comunicazione.totale_FN)
3001+ if comunicazione.totale_SE:
3002+ rcd += '{:8s}'.format("TA010001") + '{:16d}'.format(comunicazione.totale_SE)
3003+ if comunicazione.totale_TU:
3004+ rcd += '{:8s}'.format("TA011001") + '{:16d}'.format(comunicazione.totale_TU)
3005+
3006+ rcd += " " * (1897 -len(rcd))
3007+
3008+ # Ultimi caratteri di controllo
3009+ rcd += "A" # Impostare al valore "A"
3010+ rcd += "\r" #
3011+ rcd += "\n" #
3012+ return rcd
3013+
3014+ def _record_Z(self, cr, uid, args, context=None):
3015+ rcd = "Z"
3016+ rcd += '{:14s}'.format("") # filler
3017+ rcd += '{:9s}'.format(str(args.get('numero_record_B')).zfill(9))
3018+ rcd += '{:9s}'.format(str(args.get('numero_record_C')).zfill(9))
3019+ rcd += '{:9s}'.format(str(args.get('numero_record_D')).zfill(9))
3020+ rcd += '{:9s}'.format(str(args.get('numero_record_E')).zfill(9))
3021+ rcd += " " * 1846
3022+ # Ultimi caratteri di controllo
3023+ rcd += "A" # Impostare al valore "A"
3024+ rcd += "\r" #
3025+ rcd += "\n" #
3026+ return rcd
3027+
3028+ def execute_export(self, cr, uid, ids, context=None):
3029+ if len(ids) > 1:
3030+ raise osv.except_osv('Error', _('Only one comunication'))
3031+
3032+ numero_record_B = 0
3033+ numero_record_C = 0
3034+ numero_record_D = 0
3035+ numero_record_E = 0
3036+
3037+ comunicazione_id = context.get('active_id', False)
3038+ comunicazione = self.pool.get('spesometro.comunicazione').browse(cr, uid, comunicazione_id)
3039+
3040+ # Testata
3041+ content = self._record_A(cr, uid, comunicazione, context=context)
3042+ numero_record_B += 1
3043+ content += self._record_B(cr, uid, comunicazione, context=context)
3044+
3045+ # Dettaglio
3046+ progressivo_modulo = 0
3047+ progressivo_sezione = 0
3048+ sezione_max = 3
3049+ # .. quadro FA
3050+ for line in comunicazione.line_FA_ids:
3051+ progressivo_modulo +=1
3052+ progressivo_sezione +=1
3053+ if progressivo_sezione > sezione_max :
3054+ progressivo_sezione = 1
3055+ content += self._record_C_FA(cr, uid, line, progressivo_modulo, progressivo_sezione, context=context)
3056+ numero_record_C += 1
3057+ # .. quadro SA
3058+ progressivo_sezione = 0
3059+ sezione_max = 10
3060+ for line in comunicazione.line_SA_ids:
3061+ progressivo_modulo +=1
3062+ progressivo_sezione +=1
3063+ if progressivo_sezione > sezione_max :
3064+ progressivo_sezione = 1
3065+ content += self._record_C_SA(cr, uid, line, progressivo_modulo, progressivo_sezione, context=context)
3066+ numero_record_C += 1
3067+
3068+ # .. quadro BL
3069+ progressivo_sezione = 0
3070+ sezione_max = 1
3071+ for line in comunicazione.line_BL_ids:
3072+ progressivo_modulo +=1
3073+ progressivo_sezione +=1
3074+ if progressivo_sezione > sezione_max :
3075+ progressivo_sezione = 1
3076+ content += self._record_C_BL(cr, uid, line, progressivo_modulo, progressivo_sezione, context=context)
3077+ numero_record_C += 1
3078+
3079+ # .. quadro SE
3080+ progressivo_sezione = 0
3081+ sezione_max = 3
3082+ for line in comunicazione.line_SE_ids:
3083+ progressivo_modulo +=1
3084+ progressivo_sezione +=1
3085+ if progressivo_sezione > sezione_max :
3086+ progressivo_sezione = 1
3087+ content += self._record_D_SE(cr, uid, line, progressivo_modulo, progressivo_sezione, context=context)
3088+ numero_record_D += 1
3089+
3090+ # Riepilogo
3091+ progressivo_modulo = 1
3092+ content += self._record_E(cr, uid, comunicazione, progressivo_modulo, context=context)
3093+ numero_record_E += 1
3094+
3095+ # Coda
3096+ args = {
3097+ 'numero_record_B' : numero_record_B,
3098+ 'numero_record_C' : numero_record_C,
3099+ 'numero_record_D' : numero_record_D,
3100+ 'numero_record_E' : numero_record_E,
3101+ }
3102+ content += self._record_Z(cr, uid, args, context=None)
3103+
3104+ out=base64.encodestring(content.encode("utf8"))
3105+ return self.write(cr, uid, ids, {'file_spesometro':out}, context=context)
3106+
3107+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3108\ No newline at end of file
3109
3110=== added file 'l10n_it_spesometro/wizard/wizard_export_view.xml'
3111--- l10n_it_spesometro/wizard/wizard_export_view.xml 1970-01-01 00:00:00 +0000
3112+++ l10n_it_spesometro/wizard/wizard_export_view.xml 2014-04-03 06:37:29 +0000
3113@@ -0,0 +1,45 @@
3114+<?xml version="1.0" encoding="utf-8"?>
3115+<openerp>
3116+ <data>
3117+ <!--
3118+ Form
3119+ -->
3120+ <record id="wizard_spesometro_export_view" model="ir.ui.view">
3121+ <field name="name">wizard.spesometro.export.view</field>
3122+ <field name="model">wizard.spesometro.export</field>
3123+ <field name="type">form</field>
3124+ <field name="arch" type="xml">
3125+ <form string="Params">
3126+ <!--<field name="file_to_import" />
3127+ <separator colspan="4" />-->
3128+ <field name="file_spesometro" readonly="1"/>
3129+ <separator colspan="4" />
3130+ <button name="execute_export" string="Export" type="object" icon="gtk-execute" />
3131+ </form>
3132+ </field>
3133+ </record>
3134+
3135+ <!-- ACTION -->
3136+ <record id="wizard_spesometro_export_action" model="ir.actions.act_window">
3137+ <field name="name">Export spesometro</field>
3138+ <field name="res_model">wizard.spesometro.export</field>
3139+ <field name="src_model">spesometro.comunicazione</field>
3140+ <field name="view_type">form</field>
3141+ <field name="view_mode">form</field>
3142+ <field name="view_id" ref="wizard_spesometro_export_view"/>
3143+ <field name="help">Crea file spesometro - Comunicazione art.21 </field>
3144+ <field name="target">new</field>
3145+ </record>
3146+
3147+ <act_window name="Export spesometro"
3148+ res_model="wizard.spesometro.export"
3149+ src_model="spesometro.comunicazione"
3150+ view_mode="form"
3151+ target="new"
3152+ context="{'search_default_in_location':1}"
3153+ key2="client_action_multi"
3154+ view_id="wizard_spesometro_export_view"
3155+ id="wizard_spesometro_export_action2"/>
3156+
3157+ </data>
3158+</openerp>

Subscribers

People subscribed via source and target branches