Files correlati : ef0.exe Ricompilazione Demo : [ ] Commento : Gestione CUP Verificare che i profili persnalizzati continuino a funzionare Nella gestione profili e documenti aggiunti i campi per gestire piu banche di appoggio e presentazione dei clienti/ fornitori La ricerca e sulla tabella se il cliente / fornitore non ha banche altrimenti e sulle banche del cliente/fornitore. Ai profili personalizzati vanno aggiunti-modificati e posizionati i campi : NU 117 5 BE PR 2 11 "Banca appoggio : Cod. ABI " FL "Z" CH NORMAL FI CODABIA US %BAN SE CODTAB?="?????" IN CODTAB[1,5] 117 DI "Cod. Istit." CODTAB[1,5] DI "Cod. Fil." CODTAB[6,10] DI "Denominazione@50" S0 OU 117 CODTAB[1,5] OU 336 S0 OU 197 CODTAB[1,5] ME CO,220 EN NU 118 5 BE PR 42 11 "Cod. CAB " FL "Z" CH NORMAL FI CODCABA US %BAN SE CODTAB?="??????????" IN CODTAB[1,5] 117 IN CODTAB[6,10] 118 CO DI 117 OU 117 CODTAB[1,5] OU 118 CODTAB[6,10] OU 336 S0 OU 198 CODTAB[6,10] ME CO,221 EN NU 220 5 BE PR 2 11 "Banca appoggio : Cod. ABI " FL "ZH" CH NORMAL FI CODABIA US 98 KEY 2 JOIN %BAN INTO CODTAB[1,5]==ABI CODTAB[6,10]==CAB IN TIPOCF 107 SE IN CODCF 108 SE IN TIPOBAN "V" IN ABI 220 IN CAB 221 IN PROGPR "" DI "Cod. Istit." ABI DI "Cod. Fil." CAB DI "IBAN@27" IBAN DI "Denominazione@50" %BAN->S0 OU 220 ABI OU 221 CAB OU 336 %BAN->S0 OU 192 IBAN OU 197 ABI OU 198 CAB EN NU 221 5 BE PR 42 11 "Cod. CAB " FL "ZH" CH NORMAL FI CODCABA CO US 220 CO IN 220 CO DI 220 CO OU 220 EN per la banca di appoggio NU 119 5 BE PR 2 14 "Banca presentazione : Cod. ABI " FL "Z" CH NORMAL FI CODABIP CO US 117 IN CODTAB[1,5] 119 DI "Cod. Istit." CODTAB[1,5] DI "Cod. Fil." CODTAB[6,10] DI "Denominazione@50" S0 OU 119 CODTAB[1,5] OU 338 S0 ME CO,222 EN NU 120 5 BE PR 42 14 "Cod. CAB " FL "Z" CH NORMAL FI CODCABP CO US 118 IN CODTAB[1,5] 119 IN CODTAB[6,10] 120 CO DI 119 OU 119 CODTAB[1,5] OU 120 CODTAB[6,10] OU 338 S0 ME CO,223 EN NU 214 2 BE PR 60 14 "Progressivo " FL "Z" FI PROGBNP US BNP JOIN %BAN ALIAS 100 INTO CODTAB=CODTAB[1,10] IN CODTAB[1,5] 119 IN CODTAB[6,10] 120 IN CODTAB[11,12] 214 DI "Cod. Istit." CODTAB[1,5] DI "Cod. Fil." CODTAB[6,10] DI "Progr." CODTAB[11,12] DI "IBAN@27" S3 DI "Denominazione@50" 100@->S0 OU 119 CODTAB[1,5] OU 120 CODTAB[6,10] OU 214 CODTAB[11,12] OU 338 100@->S0 ME CO,224 EN NU 222 5 BE PR 2 14 "Banca presentazione : Cod. ABI " FL "ZH" CH NORMAL FI CODABIP US 98 KEY 2 JOIN %BAN INTO CODTAB[1,5]==ABI CODTAB[6,10]==CAB IN TIPOCF 107 SE IN CODCF 108 SE IN TIPOBAN "N" IN ABI 222 IN CAB 223 IN PROGPR 224 DI "Cod. Istit." ABI DI "Cod. Fil." CAB DI "Progr." PROGPR DI "IBAN@27" IBAN DI "Denominazione@50" %BAN->S0 OU 222 ABI OU 223 CAB OU 224 PROGPR OU 338 %BAN->S0 OU 192 IBAN EN NU 223 5 BE PR 42 14 "Cod. CAB " FL "ZH" CH NORMAL FI CODCABP CO US 222 CO IN 222 CO DI 222 CO OU 222 EN NU 224 2 BE PR 60 14 "Progressivo " FL "ZH" CH NORMAL FI PROGBNP CO US 222 CO IN 222 CO DI 222 CO OU 222 EN per la banca di presentazione. Sono stati aggiunti campi CUP e CIG che hanno la ricerca sulla tabella ne caso normale e la ricerca sul file commesse clienti nel caso sia presente l'analitica Vanno aggiunti e posizionati ai profili personalizzati nel caso servano: ST 215 15 BE PR 2 11 "Cod.Unico Prog." FL "U" CH NORMAL FI CUP US %CUP IN CODTAB 215 DI "Codice@15" CODTAB DI "Descrizione@50" S0 OU 215 CODTAB OU 216 S0 HE "Inserisci il Codice Unico di Progetto" WA "Codice Unico di Progetto non trovato" CH NORMAL EN ST 216 50 BE PR 35 11 "" FL "" CH NORMAL US %CUP KEY 2 IN S0 216 DI "Descrizione@50" S0 DI "Codice@15" CODTAB CO OU 215 EN ST 217 15 BE PR 2 12 "Cod.Ident.Gara " FL "U" CH NORMAL FI CIG US %CIG IN CODTAB 217 DI "Codice@15" CODTAB DI "Descrizione@50" S0 OU 217 CODTAB OU 218 S0 HE "Inserisci il Codice Identificativo Gara" WA "Codice Identificativo Gara non trovato" CH NORMAL EN ST 218 50 BE PR 35 12 "" FL "" CH NORMAL US %CIG KEY 2 IN S0 218 DI "Descrizione@50" S0 DI "Codice@15" CODTAB CO OU 217 EN ST 219 20 BE PR 2 13 "" FL "H" FI CODCMS EN La generazione effetti scrive il CUP e il CIG sull'effetto. La contabilizzazione scrive il CUP e il CIG sulle righe contabili. git-svn-id: svn://10.65.10.50/branches/R_10_00@21374 c028cbd2-c16b-5b4b-a496-9718f37d4682
741 lines
27 KiB
C++
Executable File
741 lines
27 KiB
C++
Executable File
#include <progind.h>
|
||
|
||
#include "velib04.h"
|
||
#include "../cg/cgsaldac.h"
|
||
#include "../ef/ef0101.h"
|
||
|
||
#include <doc.h>
|
||
#include <rdoc.h>
|
||
#include <effetti.h>
|
||
#include <reffetti.h>
|
||
#include <cfven.h>
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TGenerazione_effetti
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TGenerazione_effetti::TGenerazione_effetti(const char* cod)
|
||
: TElaborazione(cod)
|
||
{
|
||
_valid_array.set(2); // tratta
|
||
_valid_array.set(3); // riba
|
||
_valid_array.set(5); // paghero'
|
||
_valid_array.set(7); // tratta accettata
|
||
_valid_array.set(8); // rapporti interbancari diretti (rid)
|
||
_valid_array.reset(9); // bonifici
|
||
|
||
_docfile = new TLocalisamfile(LF_DOC);
|
||
_rdocfile = new TLocalisamfile(LF_RIGHEDOC);
|
||
_occas = new TLocalisamfile(LF_OCCAS);
|
||
_clifo = new TLocalisamfile(LF_CLIFO);
|
||
_cfven = new TLocalisamfile(LF_CFVEN);
|
||
_tab = new TLocalisamfile(LF_TAB);
|
||
_efffile = new TLocalisamfile(LF_EFFETTI);
|
||
_refffile = new TLocalisamfile(LF_REFFETTI);
|
||
|
||
_can_write = TRUE;
|
||
_error = no_error;
|
||
_total_bills = 0L;
|
||
_impmin = real(ini_get_string(CONFIG_DITTA, "ve", "IMPMINEFF"));
|
||
}
|
||
|
||
TGenerazione_effetti::TGenerazione_effetti(const TRectype& rec)
|
||
: TElaborazione(rec)
|
||
{
|
||
_valid_array.set(2); // tratta
|
||
_valid_array.set(3); // riba
|
||
_valid_array.set(5); // paghero'
|
||
_valid_array.set(7); // tratta accettata
|
||
_valid_array.set(8); // rapporti interbancari diretti (rid)
|
||
_valid_array.reset(9); // bonifici
|
||
_docfile = new TLocalisamfile(LF_DOC);
|
||
_rdocfile = new TLocalisamfile(LF_RIGHEDOC);
|
||
_occas = new TLocalisamfile(LF_OCCAS);
|
||
_clifo = new TLocalisamfile(LF_CLIFO);
|
||
_cfven = new TLocalisamfile(LF_CFVEN);
|
||
_tab = new TLocalisamfile(LF_TAB);
|
||
_efffile = new TLocalisamfile(LF_EFFETTI);
|
||
_refffile = new TLocalisamfile(LF_REFFETTI);
|
||
|
||
_can_write = TRUE;
|
||
_error = no_error;
|
||
_total_bills = 0L;
|
||
_impmin = real(ini_get_string(CONFIG_DITTA, "ve", "IMPMINEFF"));
|
||
}
|
||
|
||
TGenerazione_effetti::~TGenerazione_effetti()
|
||
{
|
||
delete _docfile;
|
||
delete _rdocfile;
|
||
delete _occas;
|
||
delete _clifo;
|
||
delete _cfven;
|
||
delete _efffile;
|
||
delete _refffile;
|
||
delete _tab;
|
||
}
|
||
|
||
void TGenerazione_effetti::display_error(TDocumento& doc)
|
||
{
|
||
TString msg;
|
||
TString numerazione = doc.numerazione();
|
||
const long numero = doc.numero();
|
||
|
||
switch (_error)
|
||
{
|
||
case nr_doc_error:
|
||
msg.format("Rilevato un numero di documento errato contabilizzando il documento %s/%ld."
|
||
"Verificare il numero documento e il codice numerazione inseriti in tabella.",(const char*)numerazione,numero);
|
||
break;
|
||
case chg_stat_error:
|
||
msg.format("Rilevato un errore cambiando lo stato al documento %s/%ld."
|
||
"Verificare l'integrita' del file documenti.",(const char*)numerazione,numero);
|
||
break;
|
||
case datadoc_error:
|
||
msg.format("Rilevato una data documento vuota relativamente al documento %s/%ld."
|
||
"Verificare l'informazione inserita.",(const char*)numerazione,numero);
|
||
break;
|
||
case codpag_error:
|
||
msg.format("Rilevato un codice pagamento non esistente relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del codice pagamento inserito.",(const char*)numerazione,numero);
|
||
break;
|
||
case scadenze_error:
|
||
msg.format("Calcolate 0 scadenze relativamente al documento %s/%ld."
|
||
"Verificare la correttezza del codice pagamento inserito.",(const char*)numerazione,numero);
|
||
break;
|
||
case write_error:
|
||
if (_efffile->status() != NOERR)
|
||
msg.format("Si e' verificato l' errore %d in scrittura sul file effetti relativamente al documento %s/%ld"
|
||
"Verificare la consistenza del file.",_efffile->status(),(const char*)numerazione,numero);
|
||
else
|
||
msg.format("Si e' verificato l' errore %d in scrittura sul file righe effetti relativamente al documento %s/%ld"
|
||
"Verificare la consistenza del file.",_refffile->status(),(const char*)numerazione,numero);
|
||
break;
|
||
default:
|
||
msg.format("E' stato rilevato un errore generico contabilizzando il documento %s/%ld.",
|
||
(const char*)numerazione,numero);
|
||
break;
|
||
}
|
||
warning_box(msg);
|
||
_error = no_error; // reset error, as any other one would do, so you can show me the other ones.
|
||
_can_write = FALSE; // But from now on u cannot write anymore. U must exit this program and repair errors occurred.
|
||
}
|
||
|
||
error_type TGenerazione_effetti::change_doc_status(TDocumento& doc)
|
||
// Cambia lo stato del documento
|
||
{
|
||
doc.stato(get("S4")[0]);
|
||
if (doc.rewrite() != NOERR)
|
||
_error = chg_stat_error;
|
||
return _error;
|
||
}
|
||
|
||
error_type TGenerazione_effetti::change_group_status(TDocumento& doc, TAssoc_array& group_array)
|
||
// Cambia lo stato dei documenti raggruppati
|
||
{
|
||
const int items = group_array.items();
|
||
if (items > 0)
|
||
{
|
||
_error = no_error;
|
||
TToken_string * group_element;
|
||
int i=0;
|
||
// Ciclo sugli elementi dell'assoc_array
|
||
for (group_element = (TToken_string *) group_array.first_item(); group_element != NULL && i < items; i++,group_element = (TToken_string*)group_array.succ_item())
|
||
{
|
||
group_element->restart();
|
||
const int doc_items = group_element->items();
|
||
for (int j=0;j<doc_items;j++)
|
||
{
|
||
TToken_string t(group_element->get(j),'$');
|
||
char provv = t.get_char(0);
|
||
int anno = t.get_int(1);
|
||
TString codnum(t.get(2));
|
||
long numdoc = t.get_long(3);
|
||
if (doc.read(provv,anno,codnum,numdoc) == NOERR) // Legge il documento
|
||
{
|
||
doc.put(DOC_STATO,get("S4")[0]);
|
||
doc.rewrite();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TGenerazione_effetti::write_groups(bool interattivo)
|
||
{
|
||
const int items = _effetti_array.items();
|
||
int err = NOERR;
|
||
int i;
|
||
|
||
_error = no_error;
|
||
for (i = 0; i<items && err == NOERR; i++) // scorre gli effetti generati e li scrive su file
|
||
{
|
||
TEffetto& effetto = (TEffetto&)_effetti_array[i];
|
||
const real importo = effetto.get_real(EFF_IMPORTO);
|
||
|
||
if (importo > ZERO) // Gli effetti negativi non vanno scritti
|
||
{
|
||
const char tipocf = effetto.get_char(EFF_TIPOCF);
|
||
const long codcf = effetto.get_long(EFF_CODCF);
|
||
TString key;
|
||
|
||
key.format("%c|%ld", tipocf, codcf);
|
||
real impmin;
|
||
|
||
if (!interattivo)
|
||
{
|
||
impmin = real(cache().get(LF_CFVEN, key, CFV_IMPMINEFF));
|
||
if (impmin == ZERO)
|
||
impmin = _impmin;
|
||
}
|
||
if (importo >= impmin)
|
||
err = effetto.write(*_efffile); // Pensa a tutto lui per rinumerare...
|
||
else
|
||
_effetti_array.destroy(i);
|
||
}
|
||
}
|
||
_effetti_array.pack();
|
||
if (err != NOERR)
|
||
{
|
||
i--;
|
||
for (int j = 0; j<i; j++) // rimuove gli effetti raggruppati, per non lasciare documenti raggruppati parzialmente
|
||
{
|
||
TEffetto& effetto = (TEffetto&)_effetti_array[j];
|
||
// posso fare tranquillamente la remove, visto che la numerazione dell'effetto e' gia' stata effettuata
|
||
effetto.remove(*_efffile);
|
||
}
|
||
error_box("Errore %d nella scrittura gruppi di effetti. Nessun raggruppamento effettuato.",err);
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
// Criteri di raggruppamento effetti.
|
||
// Un documento puo' essere raggruppato con i seguenti criteri:
|
||
// - flag di raggruppamento effetti a TRUE (obbligatorio)
|
||
// - cliente (obbligatorio)
|
||
// - valuta (obbligatorio)
|
||
// - data scadenza (opzionale)
|
||
// - flag di sosp. d'imposta (opzionale)
|
||
// - cambio valuta (opzionale)
|
||
// - cond di pagamento (opzionale)
|
||
// - banca (opzionale)
|
||
// - tipo doc. (opzionale)
|
||
// - cod. numerazione (opzionale)
|
||
// - agente (opzionale)
|
||
// I parametri opzionali sono decisi nella tabella elaborazioni
|
||
// Spiegazione del raggruppamento:
|
||
// Il raggruppamento di documenti diversi in uno stesso effetto consiste nella creazione
|
||
// di piu' righe dello stesso effetto.
|
||
// Ad esempio supponiamo di avere il cliente 10 con 4 fatture ognuna con condizioni di pagamento diverse
|
||
// la fattura 1 e' suddivisa in 2 rate (10.000 + 30.000)
|
||
// la fattura 2 e' suddivisa in 4 rate (15.000 + 20.000 + 25.000 + 30.000)
|
||
// la fattura 3 e' suddivisa in 5 rate (20.000 + 40.000 + 80.000 + 160.000 + 320.000)
|
||
// la fattura 4 e' suddivisa in 3 rate (50.000 + 100.000 + 150.000)
|
||
// Il numero di effetti generati equivale al massimo numero di rate (5 in questo caso)
|
||
// quindi avremo 5 effetti:
|
||
// il primo avra' 4 righe (prima rata di tutte le fatture)
|
||
// il secondo avra' 4 righe (seconda rata di tutte le fatture)
|
||
// il terzo avra' 3 righe (terza rata delle fatture 2,3,4)
|
||
// il quarto avra' 2 righe (quarta rata delle fatture 2 e 3)
|
||
// il quinto avra' 1 riga (quinta rata della fattura 3)
|
||
// La testata di ogni effetto conterra' il totale (somma) dei singoli importi delle righe
|
||
// ovvero:
|
||
// tot. primo effetto: 95.000
|
||
// tot. secondo effetto: 190.000
|
||
// tot. terzo effetto: 255.000
|
||
// tot. quarto effetto: 190.000
|
||
// tot. quinto effetto: 320.000
|
||
// I dati della testata (soprattutto la data di scadenza) di ogni effetto vengono presi dal
|
||
// primo documento valido per la generazione dell'effetto corrente:
|
||
// per i primi due effetti vale la fattura 1
|
||
// per gli effetti 3 e 4 vale la fattura 2
|
||
// per l'effetto 5 vale la fattura 3.
|
||
// Questo e' quanto ho appreso (Hope I'm right...) ;-)
|
||
|
||
long TGenerazione_effetti::group_bills(TAssoc_array& group_array, bool interattivo)
|
||
{
|
||
// Bail out if there aren't items...
|
||
const int items = group_array.items();
|
||
if (!good() || items == 0)
|
||
return 0L;
|
||
|
||
TDocumento doc;
|
||
_error = no_error;
|
||
|
||
int i=0,j,n,offset=0;
|
||
TString msg1,msg2;
|
||
TString16 codpag;
|
||
real imprata, imprataval, importo, importoval;
|
||
msg1 = TR("Raggruppamento effetti");
|
||
|
||
#ifdef DBG
|
||
TProgind p(items,msg1,TRUE,TRUE,1);
|
||
#else
|
||
TProgind p(items,msg1,FALSE,TRUE,1);
|
||
#endif
|
||
TToken_string * group_element;
|
||
// Ciclo sugli elementi dell'assoc_array
|
||
for (group_element = (TToken_string *) group_array.first_item(); group_element != NULL && i < items; i++,group_element = (TToken_string*)group_array.succ_item())
|
||
{
|
||
#ifdef DBG
|
||
if (p.iscancelled()) break;
|
||
#endif
|
||
p.setstatus(i+1);
|
||
// Ciclo sui documenti da raggruppare
|
||
group_element->restart();
|
||
const int doc_items = group_element->items();
|
||
|
||
for (j=0;j<doc_items;j++)
|
||
{
|
||
#ifdef DBG
|
||
if (p.iscancelled()) break;
|
||
#endif
|
||
TToken_string t(group_element->get(j),'$');
|
||
const char provv = t.get_char(0);
|
||
const int anno = t.get_int(1);
|
||
const TString4 codnum(t.get(2));
|
||
const long numdoc = t.get_long(3);
|
||
if (doc.read(provv,anno,codnum,numdoc) != NOERR)
|
||
continue; // Legge il documento (giusto saltare e proseguire se non lo trova?)
|
||
|
||
msg2 = TR("Documento: ");
|
||
msg2 << codnum << "/" << numdoc;
|
||
xvtil_statbar_set(msg2);
|
||
do_events();
|
||
// Ricalcola le scadenze
|
||
codpag = doc.get(DOC_CODPAG);
|
||
|
||
const TRectype& cpg = cache().get("%CPG", codpag);
|
||
if (cpg.empty())
|
||
{
|
||
_error = codpag_error;
|
||
display_error(doc);
|
||
continue;
|
||
}
|
||
const real tot = doc.totale_doc() - doc.ritenute();
|
||
doc.put(DOC_CODPAG, codpag); //placeholder
|
||
|
||
const TCurrency_documento totale_fatt(tot, doc);
|
||
const bool valuta = doc.in_valuta();
|
||
const real change = doc.cambio();
|
||
const TDate datafatt = doc.get_date(DOC_DATADOC);
|
||
const bool is_nota_credito = doc.is_nota_credito();
|
||
long numdocrif = doc.get_long(DOC_NUMDOCRIF);
|
||
int annodocrif = doc.get_date(DOC_DATADOCRIF).year();
|
||
if (numdocrif > 0L && doc.get_char(DOC_TIPOCF) == 'C' && !doc.tipo().nota_credito())
|
||
{
|
||
annodocrif = 0;
|
||
numdocrif = 0L;
|
||
}
|
||
|
||
// Qui il controllo sul residuo da pagare per il documento corrente non va effettuato,
|
||
// proprio perch<63> si sta effettuando un raggruppamento di effetti; eventuali documenti
|
||
// con importo negativi (assimilati a note di credito) vanno presi in considerazione
|
||
// per la composizione dell'importo finale dell'effetto. Un effetto puo' essere composto
|
||
// anche da righe di valore negativo ma esso non verr<72> scritto solo nel caso in cui l'importo
|
||
// totale (la somma delle singole righe) sia negativo a sua volta
|
||
|
||
{
|
||
calc_pagamento(doc);
|
||
|
||
TPagamento& pag = doc.pagamento();
|
||
int numrate = pag.n_rate( );
|
||
if (numrate <= 0)
|
||
continue;
|
||
|
||
// Scorre le scadenze
|
||
for (n = 1; n <= numrate && good(); n++)
|
||
{
|
||
if (valid_type(pag.tipo_rata(n-1)))
|
||
{
|
||
// Se non esiste effetto n-esimo (corrisponde al numero di rata corrente+offset)
|
||
// lo genera con la relativa riga. Se esiste vi somma gli importi ed accoda la riga
|
||
const int effitems = _effetti_array.items();
|
||
int index = offset;
|
||
const TDate datascad = pag.data_rata(n-1);
|
||
|
||
for (; index < effitems; index++)
|
||
{
|
||
TEffetto& effetto=(TEffetto&)_effetti_array[index];
|
||
|
||
if (datascad == effetto.get_date(EFF_DATASCAD))
|
||
break;
|
||
}
|
||
// const int index = n+j-1;
|
||
// Nuovo effetto: crea effetto con i dati di questo documento (e' il primo che incontro nella scansione)
|
||
if (index >= effitems)
|
||
{
|
||
TEffetto* effetto = new TEffetto;
|
||
// Setta i dati della testata;
|
||
effetto->put(EFF_DATASCAD, datascad);
|
||
effetto->put(EFF_TIPOPAG,pag.tipo_rata(n-1));
|
||
effetto->put(EFF_ULTCLASS,pag.ulc_rata(n-1));
|
||
effetto->put(EFF_TIPOCF, doc.get_char(DOC_TIPOCF));
|
||
effetto->put(EFF_CODCF, doc.get_long(DOC_CODCF));
|
||
effetto->put(EFF_CODVAL, doc.get(DOC_CODVAL));
|
||
effetto->put(EFF_CAMBIO, change);
|
||
effetto->put(EFF_DATACAMBIO,doc.get_date(DOC_DATACAMBIO));
|
||
effetto->put(EFF_CONTROEURO,doc.get_date(DOC_CONTROEURO));
|
||
effetto->put(EFF_CODABI,doc.get(DOC_CODABIA));
|
||
effetto->put(EFF_CODCAB,doc.get(DOC_CODCABA));
|
||
effetto->put(EFF_IBAN,doc.get(DOC_IBAN));
|
||
effetto->put(EFF_CUP,doc.get(DOC_CUP));
|
||
effetto->put(EFF_CIG,doc.get(DOC_CIG));
|
||
effetto->put(EFF_EFFCOMP,TRUE);
|
||
_effetti_array.add(effetto);
|
||
}
|
||
// aggiorna totale effetto (testata)
|
||
TEffetto& effetto=(TEffetto&)_effetti_array[index];
|
||
const int rows = effetto.rows_r();
|
||
|
||
importo = effetto.get_real(EFF_IMPORTO);
|
||
imprata = pag.importo_rata(n-1,FALSE);
|
||
imprataval = valuta ? pag.importo_rata(n-1,TRUE) : ZERO;
|
||
|
||
if (is_nota_credito)
|
||
{
|
||
// Cerca fattura da pagare con la nota di credito
|
||
int r;
|
||
|
||
for (r = 1; r <= rows; r++)
|
||
{
|
||
const int annoeff = effetto.row_r(r).get_int(REFF_ANNODOC);
|
||
const long codeff = effetto.row_r(r).get_long(REFF_NFATT);
|
||
if (annoeff == annodocrif && codeff == numdocrif)
|
||
break;
|
||
}
|
||
if (r <= rows) // Se l'ha trovata ...
|
||
{
|
||
const real importo_rata_lit = effetto.row_r(r).get_real(REFF_IMPORTO);
|
||
const real importo_rata_val = valuta ? effetto.row_r(r).get_real(REFF_IMPORTOVAL) : ZERO;
|
||
real delta_lit = imprata - importo_rata_lit;
|
||
real delta_val = valuta ? imprataval - importo_rata_val : ZERO;
|
||
// Controlla se l'importo della nota di credito supera quello della fattura
|
||
if (delta_lit > ZERO || delta_val > ZERO)
|
||
{
|
||
// Detrae l'eccedenza dalla rata corrente e la sposta nella rata successiva
|
||
imprata -= delta_lit;
|
||
imprataval -= delta_val;
|
||
|
||
if (n == numrate)
|
||
{
|
||
// Crea eventuale ultima rata mancante
|
||
pag.add_rata();
|
||
numrate++;
|
||
}
|
||
else
|
||
{
|
||
// Incrementa importo rata
|
||
delta_lit += pag.importo_rata(n, FALSE);
|
||
delta_val += pag.importo_rata(n, TRUE);
|
||
}
|
||
const TDate oggi(TODAY);
|
||
const int tiporata = pag.tipo_rata(n-1);
|
||
pag.set_rata(n, delta_val, delta_lit, oggi, tiporata, "", FALSE);
|
||
}
|
||
}
|
||
else
|
||
break; // Esce dal ciclo delle rate
|
||
|
||
imprata = -imprata;
|
||
imprataval = -imprataval;
|
||
}
|
||
// Aggiorna importi in lire/valuta dell'effetto
|
||
importo += imprata;
|
||
effetto.put(EFF_IMPORTO,importo);
|
||
if (valuta)
|
||
{
|
||
importoval = effetto.get_real(EFF_IMPORTOVAL);
|
||
importoval += imprataval;
|
||
effetto.put(EFF_IMPORTOVAL,importoval);
|
||
}
|
||
// Crea la nuova riga di questo effetto
|
||
TRectype& riga = effetto.row_r(rows+1,TRUE);
|
||
// reffetto.put(REFF_NPROGTR,nprog);
|
||
riga.put(REFF_NRIGATR,rows+1);
|
||
riga.put(REFF_NRATA,n);
|
||
riga.put(REFF_DATAFATT, datafatt);
|
||
riga.put(REFF_PROVV,provv);
|
||
riga.put(REFF_ANNODOC,anno);
|
||
riga.put(REFF_CODNUM,codnum);
|
||
riga.put(REFF_NFATT,numdoc);
|
||
riga.put(REFF_IMPFATT,totale_fatt.get_num());
|
||
riga.put(REFF_IMPORTO,imprata);
|
||
riga.put(REFF_ANNO, annodocrif);
|
||
riga.put(REFF_NUMPART, numdocrif);
|
||
if (valuta)
|
||
{
|
||
riga.put(REFF_IMPFATTVAL,totale_fatt.get_num());
|
||
TCurrency_documento totfatlit(totale_fatt); totfatlit.change_to_firm_val();
|
||
riga.put(REFF_IMPFATT,totfatlit.get_num());
|
||
riga.put(REFF_IMPORTOVAL,imprataval);
|
||
}
|
||
if (n == numrate)
|
||
effetto.put(EFF_ULTRATA, "X");
|
||
}
|
||
} // Ciclo sulle scadenze
|
||
}
|
||
} // Ciclo sui documenti di questo gruppo
|
||
offset=_effetti_array.items();
|
||
|
||
} // Ciclo sui gruppi
|
||
|
||
// Cambia lo stato a tutti i documenti raggruppati
|
||
long tot = 0L;
|
||
if (_can_write)
|
||
{
|
||
xvtil_statbar_set("Scrittura effetti raggruppati in corso...");
|
||
do_events();
|
||
if (write_groups(interattivo) == no_error)
|
||
{
|
||
tot = _effetti_array.items();
|
||
change_group_status(doc, group_array);
|
||
}
|
||
}
|
||
_effetti_array.destroy();
|
||
group_array.destroy();
|
||
|
||
return tot;
|
||
}
|
||
|
||
bool TGenerazione_effetti::valid_type(int pag) const
|
||
{
|
||
return _valid_array[pag];
|
||
}
|
||
|
||
void TGenerazione_effetti::calc_pagamento(TDocumento& doc)
|
||
{
|
||
TPagamento& pag = doc.pagamento();
|
||
|
||
// const real change = doc.cambio();
|
||
const real tot = doc.totale_doc() - doc.ritenute();
|
||
const TCurrency_documento tot_doc(tot, doc);
|
||
const TCurrency_documento totspese(doc.spese(), doc);
|
||
const TCurrency_documento totimposte(doc.imposta(TRUE), doc);
|
||
const TCurrency_documento totimponibili(tot_doc - totimposte - totspese);
|
||
TCurrency_documento anticipo(doc.get_real(DOC_IMPPAGATO), doc);
|
||
const bool valuta = doc.in_valuta();
|
||
|
||
//Riaggiusta le rate a seconda del valore gia' pagato
|
||
TGeneric_distrib d(anticipo.get_num(), doc.decimals());
|
||
|
||
d.add(totimponibili.get_num());
|
||
d.add(totimposte.get_num());
|
||
d.add(totspese.get_num());
|
||
|
||
const TCurrency_documento pagtotimponibili(totimponibili.get_num() - d.get(), doc);
|
||
const TCurrency_documento pagtotimposte(totimposte.get_num() - d.get(), doc);
|
||
const TCurrency_documento pagtotspese(totspese.get_num() - d.get(), doc);
|
||
|
||
if (valuta)
|
||
{
|
||
TCurrency_documento val2(pagtotimposte); val2.change_to_firm_val();
|
||
TCurrency_documento val3(pagtotspese); val3.change_to_firm_val();
|
||
TCurrency_documento val1(tot_doc); val1.change_to_firm_val(); val1 -= val2 + val3;
|
||
|
||
pag.set_total_valuta(pagtotimponibili, pagtotimposte, pagtotspese, val1, val2, val3);
|
||
}
|
||
else
|
||
pag.set_total(pagtotimponibili, pagtotimposte, pagtotspese);
|
||
pag.set_rate_auto();
|
||
|
||
const int numrate = pag.n_rate();
|
||
|
||
// Scorre all'indietro per rimuovere le rate a 0, evitando fastidiose
|
||
// complicazioni dovute al pack delle rate effettuato dalla remove_rate()
|
||
for (int i=numrate-1; i>=0; i--)
|
||
{
|
||
if (pag.importo_rata(i,valuta) == ZERO)
|
||
pag.remove_rata(i);
|
||
}
|
||
|
||
}
|
||
|
||
void TGenerazione_effetti::generate_bill(TDocumento& doc, bool interattivo) // bill in inglese significa anche effetto eheheh ;-)
|
||
{
|
||
// That's my JOB!
|
||
// Ogni rata della fattura (si parla di effetti attivi per ora) genera 1 effetto.
|
||
// con almeno una riga.
|
||
// Ad es. Se ho una fattura suddivisa in 3 rate essa generera' 3 effetti con una riga.
|
||
// Nel caso si decida di raggruppare gli effetti (vedi criteri di raggruppamento)
|
||
// avro' un effetto con tante righe quante scadenze di fattura sono raggruppabili
|
||
// Le fatture possono generare effetti solo per i seguenti tipi di pagamento:
|
||
// 2 - Tratta
|
||
// 3 - Ri.Ba.
|
||
// 5 - Paghero'
|
||
// 7 - Tratta accettata
|
||
// 8 - Rapporti interbancari diretti
|
||
// Caso mai tale insieme risultasse incompleto od errato basta solo modificare l'enum posto all'inizio del programma
|
||
|
||
if (!doc.is_nota_credito()) // I documenti immessi come note di credito non generano effetti...(che senso hanno gli effetti con importi negativi?)
|
||
{
|
||
const TString4 codpag(doc.get(DOC_CODPAG));
|
||
const TRectype& cpg = cache().get("%CPG", codpag);
|
||
if (cpg.empty())
|
||
{
|
||
_error = codpag_error;
|
||
return;
|
||
}
|
||
|
||
// Totdoc inaffidabile: ne forzo il ricalcolo
|
||
TVariable_field* tot_fld = doc.variable_field(doc.tipo().totale_doc());
|
||
if (tot_fld != NULL)
|
||
tot_fld->set_dirty();
|
||
|
||
TString16 data(doc.get(DOC_DATAINSC));
|
||
if (data.empty())
|
||
data = doc.get(DOC_DATADOC);
|
||
|
||
const real tot = doc.totale_doc() - doc.ritenute();
|
||
const TCurrency_documento totale_fatt(tot, doc); // Importo in valuta
|
||
const TCurrency_documento imppagato(doc.get_real(DOC_IMPPAGATO), doc); // Anticipo pagamento
|
||
if (totale_fatt > imppagato && !doc.get_bool(DOC_ACCSALDO)) // procede se non e' a saldo
|
||
{
|
||
const bool is_anticipo = imppagato.get_num() != ZERO;
|
||
const bool valuta = doc.in_valuta();
|
||
const real change = doc.cambio();
|
||
|
||
// calcolo delle scadenze
|
||
calc_pagamento(doc);
|
||
|
||
TPagamento & pag = doc.pagamento();
|
||
// CHECK(pag,"Failed to create a TPagamento");
|
||
const int numrate = pag.n_rate( );
|
||
if (numrate > 0)
|
||
{
|
||
_efffile->last();
|
||
// Variabili per la scrittura dell'effetto
|
||
long nprog = _efffile->get_long(EFF_NPROGTR)+1;
|
||
const char tipocf = doc.get_char(DOC_TIPOCF);
|
||
const long codcf = doc.get_long(DOC_CODCF);
|
||
const TString4 codval(doc.get(DOC_CODVAL));
|
||
const TDate data_cambio = doc.get_date(DOC_DATACAMBIO);
|
||
const bool contro_euro = doc.get_bool(DOC_CONTROEURO);
|
||
const long codabi = doc.get_long(DOC_CODABIA);
|
||
const long codcab = doc.get_long(DOC_CODCABA);
|
||
const TString80 iban = doc.get(DOC_IBAN);
|
||
const TString4 provv(doc.get(DOC_PROVV));
|
||
const int anno = doc.get_int(DOC_ANNO);
|
||
const TString4 codnum(doc.get(DOC_CODNUM));
|
||
const long nfatt = doc.get_long(DOC_NDOC);
|
||
const TDate datafatt = doc.get_date(DOC_DATADOC);
|
||
TRectype& effetto = _efffile->curr();
|
||
TRectype& reffetto = _refffile->curr();
|
||
real importo;
|
||
for (int i = 0; i < numrate && good(); i++)
|
||
{
|
||
const int nrata = is_anticipo ? i + 2: i + 1;
|
||
|
||
if (valid_type(pag.tipo_rata(i)))
|
||
{
|
||
effetto.zero();
|
||
reffetto.zero();
|
||
effetto.put(EFF_NPROGTR,nprog);
|
||
effetto.put(EFF_DATASCAD, pag.data_rata(i));
|
||
effetto.put(EFF_TIPOPAG,pag.tipo_rata(i));
|
||
effetto.put(EFF_ULTCLASS,pag.ulc_rata(i));
|
||
effetto.put(EFF_TIPOCF, tipocf);
|
||
effetto.put(EFF_CODCF, codcf);
|
||
effetto.put(EFF_CODVAL, codval);
|
||
if (valuta)
|
||
{
|
||
effetto.put(EFF_CAMBIO, change);
|
||
effetto.put(EFF_DATACAMBIO,data_cambio);
|
||
effetto.put(EFF_CONTROEURO, contro_euro);
|
||
}
|
||
effetto.put(EFF_CODABI,codabi);
|
||
effetto.put(EFF_CODCAB,codcab);
|
||
effetto.put(EFF_IBAN,iban);
|
||
effetto.put(EFF_CUP,doc.get(DOC_CUP));
|
||
effetto.put(EFF_CIG,doc.get(DOC_CIG));
|
||
effetto.put(EFF_EFFCOMP,TRUE);
|
||
if (i == numrate - 1) effetto.put(EFF_ULTRATA,TRUE);
|
||
// Put sulla riga dell'effetto
|
||
reffetto.put(REFF_NPROGTR,nprog);
|
||
reffetto.put(REFF_NRIGATR,1);
|
||
reffetto.put(REFF_DATAFATT, datafatt);
|
||
reffetto.put(REFF_NRATA,nrata);
|
||
reffetto.put(REFF_PROVV,provv);
|
||
reffetto.put(REFF_ANNODOC,anno);
|
||
reffetto.put(REFF_CODNUM,codnum);
|
||
reffetto.put(REFF_NFATT,nfatt);
|
||
if (doc.get_char(DOC_TIPOCF) == 'F' || doc.tipo().nota_credito())
|
||
{
|
||
reffetto.put(REFF_ANNO, doc.get_date(DOC_DATADOCRIF).year());
|
||
reffetto.put(REFF_NUMPART, doc.get(DOC_NUMDOCRIF));
|
||
}
|
||
|
||
importo = pag.importo_rata(i,FALSE);
|
||
effetto.put(EFF_IMPORTO,importo);
|
||
reffetto.put(REFF_IMPFATT,totale_fatt.get_num());
|
||
reffetto.put(REFF_IMPORTO,importo);
|
||
|
||
TString8 key;
|
||
key.format("%c|%ld", tipocf, codcf);
|
||
real impmin;
|
||
|
||
if (!interattivo)
|
||
{
|
||
impmin = real(cache().get(LF_CFVEN, key, CFV_IMPMINEFF));
|
||
if (impmin == ZERO)
|
||
impmin = _impmin;
|
||
}
|
||
|
||
if (importo >= impmin)
|
||
{
|
||
if (valuta)
|
||
{
|
||
importo = pag.importo_rata(i, true); // Importo in valuta
|
||
TCurrency_documento totfatlit(totale_fatt); totfatlit.change_to_firm_val();
|
||
effetto.put(EFF_IMPORTOVAL,importo);
|
||
reffetto.put(REFF_IMPFATTVAL,totale_fatt.get_num());
|
||
reffetto.put(REFF_IMPFATT,totfatlit.get_num());
|
||
reffetto.put(REFF_IMPORTOVAL,importo);
|
||
}
|
||
if (_efffile->write() == NOERR && _refffile->write() == NOERR)
|
||
{
|
||
_total_bills++;
|
||
nprog++;
|
||
}
|
||
else
|
||
_error = write_error;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (good() && _can_write)
|
||
change_doc_status(doc);
|
||
}
|
||
|
||
bool TGenerazione_effetti::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
TString msg;
|
||
_error = no_error;
|
||
_total_bills = 0L;
|
||
|
||
pre_process_input(doc_in);
|
||
const int items = doc_in.items(); // Numero dei documenti in questa elaborazione
|
||
for (int i = 0; i < items ; i++) // Scorriamo tutti i documenti nella lista
|
||
{
|
||
TDocumento& doc = doc_in[i];
|
||
msg.format(FR("Generazione effetti documento %s/%ld."), (const char*) doc.numerazione(), doc.numero());
|
||
xvtil_statbar_set(msg);
|
||
do_events();
|
||
|
||
generate_bill(doc, interattivo); // Genera gli effetti corrispondenti
|
||
if (!good())
|
||
display_error(doc);
|
||
}
|
||
post_process_input(doc_in);
|
||
post_process(doc_out, doc_in);
|
||
|
||
return _can_write;
|
||
}
|
||
|