Files correlati : pe0.exe Ricompilazione Demo : [ ] Commento : Preventivi/incarichi (Dinamica) git-svn-id: svn://10.65.10.50/trunk@18734 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			727 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			727 lines
		
	
	
		
			26 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;
 | ||
| }
 | ||
| 
 | ||
| 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;
 | ||
| }
 | ||
| 
 | ||
| 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()
 | ||
| {
 | ||
|   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);
 | ||
| 			const real impmin(cache().get(LF_CFVEN, key, CFV_IMPMINEFF));
 | ||
| 
 | ||
|       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)
 | ||
| {
 | ||
|   // 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 = "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();
 | ||
|     
 | ||
|     int last_rata = 0;
 | ||
|     
 | ||
|     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 = "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);
 | ||
|         return 0L;
 | ||
|       }    
 | ||
|       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)
 | ||
|         {
 | ||
|           _error = scadenze_error;
 | ||
|           display_error(doc);
 | ||
|           return 0L;
 | ||
|         }
 | ||
|         
 | ||
|         if (numrate > last_rata)
 | ||
|         {
 | ||
|           if (valid_type(pag.tipo_rata(numrate-1)))
 | ||
|             last_rata = numrate;
 | ||
|           else  
 | ||
|             last_rata = 0;
 | ||
|         } 
 | ||
|         
 | ||
|         // 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 index = n+offset-1;
 | ||
|             // Nuovo effetto: crea effetto con i dati di questo documento (e' il primo che incontro nella scansione)
 | ||
|             if (index >= _effetti_array.items()) 
 | ||
|             {
 | ||
|               TEffetto* effetto = new TEffetto;
 | ||
|               // Setta i dati della testata;
 | ||
|               effetto->put(EFF_DATASCAD, pag.data_rata(n-1));
 | ||
|               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_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);
 | ||
|             }
 | ||
|           }
 | ||
|         } // Ciclo sulle scadenze
 | ||
|       }
 | ||
|     } // Ciclo sui documenti di questo gruppo
 | ||
|     offset=_effetti_array.items();           
 | ||
|     
 | ||
|     if (last_rata > 0)
 | ||
|     {
 | ||
|       TEffetto& last_effetto = (TEffetto&)_effetti_array[offset-1];
 | ||
|       last_effetto.put(EFF_ULTRATA, "X");
 | ||
|     }
 | ||
|   }   // 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() == 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) // 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 TString16 codpag(doc.get(DOC_CODPAG));
 | ||
|     const TRectype& cpg = cache().get("%CPG", codpag);
 | ||
|     if (cpg.empty())
 | ||
|     {
 | ||
|       _error = codpag_error;
 | ||
|       return;
 | ||
|     }
 | ||
|     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)
 | ||
|       {
 | ||
|         _error = scadenze_error;
 | ||
|         return;
 | ||
|       }
 | ||
|       
 | ||
|       _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 TString16 provv(doc.get(DOC_PROVV));
 | ||
|       const int anno = doc.get_int(DOC_ANNO);
 | ||
|       const TString16 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_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);
 | ||
| 					
 | ||
| 					TString key;
 | ||
| 
 | ||
| 					key.format("%c|%ld", tipocf, codcf);
 | ||
| 					const real impmin(cache().get(LF_CFVEN, key, CFV_IMPMINEFF));
 | ||
| 
 | ||
|           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("Generazione effetti documento %s/%ld.", (const char*) doc.numerazione(), doc.numero());
 | ||
|     xvtil_statbar_set(msg);
 | ||
|     do_events();
 | ||
| 
 | ||
|     generate_bill(doc);       // Genera gli effetti corrispondenti
 | ||
|     if (!good()) 
 | ||
|       display_error(doc);
 | ||
|   }
 | ||
| 	post_process_input(doc_in);
 | ||
|   post_process_output(doc_out);
 | ||
| 
 | ||
|   return _can_write;
 | ||
| } 
 | ||
| 
 |