git-svn-id: svn://10.65.10.50/branches/R_10_00@22717 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1626 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1626 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <applicat.h>
 | ||
| #include <defmask.h>
 | ||
| #include <filetext.h>
 | ||
| #include <progind.h>
 | ||
| #include <recarray.h>
 | ||
| #include <recset.h>
 | ||
| 
 | ||
| #include "tc9.h"
 | ||
| #include "tc9100a.h"
 | ||
| 
 | ||
| #include <pagsca.h>
 | ||
| #include <partite.h>
 | ||
| 
 | ||
| #include "../cg/cg2101.h"
 | ||
| #include "../cg/cg2103.h"
 | ||
| #include "../cg/cgsaldac.h"
 | ||
| 
 | ||
| #include "../ca/calib01.h"
 | ||
| #include "../ca/movana.h"
 | ||
| #include "../ca/rmovana.h"
 | ||
| #include "../ve/velib.h"
 | ||
| 
 | ||
| #include <doc.h>
 | ||
| #include <rdoc.h>
 | ||
| 
 | ||
| 
 | ||
| class TInvioP_file: public TFile_text
 | ||
| {
 | ||
| protected:
 | ||
|   virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str);
 | ||
| 
 | ||
| public:
 | ||
|   TInvioP_file(const TString& file_name);
 | ||
| };
 | ||
| 
 | ||
| TInvioP_file::TInvioP_file(const TString& file_name)
 | ||
|           : TFile_text(file_name, "tc9100a.ini")
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| //////////////////////////////////////////////////////
 | ||
| //	MASCHERA
 | ||
| //////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TInvioP_mask : public TAutomask
 | ||
| {
 | ||
| protected:
 | ||
|   bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
| 	void config_loader(TSheet_field& sf, const char* paragrafo);
 | ||
|   void config_setter(TSheet_field& sf, const char* paragrafo);
 | ||
| 
 | ||
| public:
 | ||
|   TInvioP_mask(); 
 | ||
|   virtual ~TInvioP_mask(){};
 | ||
| };
 | ||
|   
 | ||
| TInvioP_mask::TInvioP_mask() :TAutomask ("tc9100a")
 | ||
| {
 | ||
| 	config_loader(sfield(F_PDCC), "Pdcc");
 | ||
| }  
 | ||
|   
 | ||
| bool TInvioP_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| { 
 | ||
| 	switch (o.dlg())
 | ||
| 	{
 | ||
| 	case F_CODDITTA:                               
 | ||
| 		if (e==fe_init && o.empty())
 | ||
| 		{
 | ||
| 			set(F_CODDITTA, main_app().get_firm());
 | ||
| 			((TEdit_field&) o).check();
 | ||
| 			disable(F_CODDITTA);
 | ||
| 		}	
 | ||
| 		break;
 | ||
| 	case DLG_SAVEREC:
 | ||
| 		if (e == fe_button)
 | ||
| 		{
 | ||
| 			config_setter(sfield(F_PDCC), "Pdcc");
 | ||
| 		}
 | ||
| 		break;
 | ||
| 	default:
 | ||
| 		break;	
 | ||
| 	}
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| void TInvioP_mask::config_loader(TSheet_field& sf, const char* paragrafo)
 | ||
| {
 | ||
| 	//carica file configurazione conti; attenzione!!!il file di configurazione in questione e' il
 | ||
| 	//medesimo del programma per la stampa del pagato in contabilita' analitica, visto che i due
 | ||
| 	//programmi necessitano degli stessi conti
 | ||
| 	TFilename configname = "ca3600a.ini";
 | ||
| 	configname.custom_path();
 | ||
| 	TConfig configfile(configname, paragrafo);
 | ||
| 
 | ||
|   TString_array conti;
 | ||
| 
 | ||
| 	int first_enabled_row = -1;
 | ||
|   int n = configfile.list_variables(conti, false, paragrafo, true);
 | ||
|   FOR_EACH_ARRAY_ROW(conti, i, row)
 | ||
|   {
 | ||
|     sf.row(-1) = configfile.get(*row);	//carica la riga del .ini senza il contatore
 | ||
| 		sf.check_row(i);
 | ||
| 		TString pippo = sf.row(i);
 | ||
| 		pippo = pippo.left(1);	//disabilita le righe di tipo C e P che riguardano la sola stampa..
 | ||
| /*		if (pippo == "C" || pippo == "P")		//..del pagato
 | ||
| 			sf.disable_row(i);
 | ||
| 		else
 | ||
| 		{
 | ||
| 			if (first_enabled_row < 0)	//se la riga non e' C o P deve incrementare il contatore della..
 | ||
| 				first_enabled_row = i;		//..prima riga disabilitata
 | ||
| 		}*/
 | ||
|   }
 | ||
| 	if (first_enabled_row >= 0)			//se il contatore della prima riga disabilitata e' stato..
 | ||
| 		sf.select(first_enabled_row);	//..incrementato, sposta il focus alla prima riga abile
 | ||
| }
 | ||
| 
 | ||
| void TInvioP_mask::config_setter(TSheet_field& sf, const char* paragrafo)
 | ||
| {
 | ||
| 	TFilename configname = "ca3600a.ini";
 | ||
| 	configname.custom_path();
 | ||
| 	TConfig configfile(configname, paragrafo);
 | ||
|   
 | ||
|   configfile.remove_all();  //svuota il paragrafo sul .ini prima di ricompilarlo (se non si facesse
 | ||
|                         //non si riuscirebbero ad ammazzare le righe sul .ini
 | ||
|   FOR_EACH_SHEET_ROW (sf, i, row)
 | ||
|   {
 | ||
|     TToken_string conto("");
 | ||
|     conto.add(row->get(0));
 | ||
|     conto.add(row->get(1));
 | ||
|     conto.add(row->get(2));
 | ||
| 		conto.add(row->get(3));
 | ||
| 
 | ||
|     configfile.set("conto", conto, NULL, true, i);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| //////////////////////////////////////////////
 | ||
| //	STRUCT (saldo di 1 conto)
 | ||
| //////////////////////////////////////////////
 | ||
| struct TInvioP_saldo : public TObject
 | ||
| {
 | ||
|   TString16 _zio;
 | ||
| 	TImporto _importo;
 | ||
| 
 | ||
| 	TInvioP_saldo(const TRectype& r);
 | ||
| 	TInvioP_saldo(const TString& zio, const TImporto& importo);
 | ||
| };
 | ||
| 
 | ||
| TInvioP_saldo::TInvioP_saldo(const TRectype& r)
 | ||
| {
 | ||
|   const TBill zio(r);
 | ||
|   _zio = zio.string(0x8);
 | ||
| 
 | ||
| 	const char sezione = r.get_char(RMV_SEZIONE);
 | ||
| 	const real imp = r.get_real(RMV_IMPORTO);
 | ||
| 	_importo.set(sezione, imp);
 | ||
| 	_importo.normalize();
 | ||
| }
 | ||
| 
 | ||
| TInvioP_saldo::TInvioP_saldo(const TString& zio, const TImporto& importo)
 | ||
| 						 : _zio(zio), _importo(importo)
 | ||
| {}
 | ||
| 
 | ||
| 
 | ||
| //////////////////////////////////////////////
 | ||
| //	SALDI MOVIMENTO CONTABILE
 | ||
| //////////////////////////////////////////////
 | ||
| class TInvioP_saldi_cg : public TArray
 | ||
| {
 | ||
| public:
 | ||
| 	//prende l'oggetto i-esimo (in questo caso un TInvioP_saldo) e ritorna il conto di tale oggetto
 | ||
| 	const TString& conto(int i) { return ((TInvioP_saldo*)objptr(i))->_zio; }
 | ||
| 	//stessa roba ma per l'importo
 | ||
| 	TImporto& importo(int i) { return ((TInvioP_saldo*)objptr(i))->_importo; }
 | ||
| 	bool sottrai_importo(const TString& conto, const TImporto& importo);
 | ||
| 	void somma(const TRectype& rmov);
 | ||
| 	void sottrai(const TRectype& rmovana);
 | ||
| };
 | ||
| 
 | ||
| void TInvioP_saldi_cg::somma(const TRectype& rmov)
 | ||
| {
 | ||
| 	TInvioP_saldo* s = new TInvioP_saldo(rmov);
 | ||
| 	add(s);
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP_saldi_cg::sottrai_importo(const TString& zio, const TImporto& imp)
 | ||
| {
 | ||
| 	int k;
 | ||
| 	//caso fortunato
 | ||
| 	//scandisce gli elementi dell'array;se ne trova uno (k-esimo) con conto ed importo coincidenti..
 | ||
| 	//..con quelli passati al metodo, azzera l'importo di tale elemento dell'array
 | ||
|   for (k = 0; k < items(); k++)
 | ||
| 	{
 | ||
| 		if (conto(k) == zio && importo(k) == imp)
 | ||
| 		{
 | ||
| 			importo(k).set('D', ZERO);
 | ||
| 			return true;
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	//caso sfortunato
 | ||
| 	//in questo caso gli importi dell'elemento k-esimo dell'array e passato al metodo NON coincidono
 | ||
| 	TImporto residuo = imp;
 | ||
| 	int ultima_riga_buona = -1;
 | ||
| 
 | ||
|   for (k = 0; k < items() && !residuo.is_zero(); k++)
 | ||
| 	{
 | ||
| 		if (conto(k) == zio)
 | ||
| 		{
 | ||
| 			TImporto& val = importo(k);
 | ||
| 			residuo.normalize(val.sezione());
 | ||
| 			if (residuo >= val)
 | ||
| 			{
 | ||
| 				residuo -= val;
 | ||
| 				val.set('D', ZERO);
 | ||
| 			}
 | ||
| 			else
 | ||
| 			{
 | ||
| 				val -= residuo;
 | ||
| 				residuo.set('D', ZERO);
 | ||
| 			}
 | ||
| 			ultima_riga_buona = k;
 | ||
| 		}
 | ||
| 	}
 | ||
| 	//alla fine del ciclo sull'array resta un residuo non nullo..
 | ||
| 	if (!residuo.is_zero())
 | ||
| 	{
 | ||
| 		residuo.normalize();
 | ||
| 		residuo.swap_section();
 | ||
| 		if (ultima_riga_buona >= 0)
 | ||
| 			importo(ultima_riga_buona) += residuo;
 | ||
| 	}
 | ||
| 	return true;
 | ||
| }
 | ||
| 
 | ||
| void TInvioP_saldi_cg::sottrai(const TRectype& rmovana)
 | ||
| {
 | ||
| 	//adesso tocca alle righe contabili senza commessa
 | ||
| 	const int gruppo = atoi(rmovana.get(RMOVANA_CODCONTO).left(3)); 
 | ||
| 	const int conto = atoi(rmovana.get(RMOVANA_CODCONTO).mid(3,3));
 | ||
| 	const long sottoconto = atol(rmovana.get(RMOVANA_CODCONTO).mid(6,6));
 | ||
| 
 | ||
| 	const TBill zio(gruppo, conto, sottoconto);
 | ||
| 
 | ||
| 	const TImporto importo(rmovana.get_char(RMOVANA_SEZIONE), rmovana.get_real(RMOVANA_IMPORTO));
 | ||
| 	sottrai_importo(zio.string(0x8), importo);
 | ||
| }
 | ||
| 
 | ||
| //////////////////////////////////////////////
 | ||
| //	APPLICAZIONE
 | ||
| //////////////////////////////////////////////
 | ||
| 
 | ||
| class TInvioP : public TSkeleton_application
 | ||
| {                     
 | ||
| 	TCursor*				  _cur;
 | ||
|   TInvioP_mask* 		_msk;
 | ||
|   TDate							_dataini, _datafin;
 | ||
| 	long							_nregcosto, _nregpag;
 | ||
| 	real							_importo;
 | ||
|   char              _accsal;
 | ||
|   TConfig*					_configfile;
 | ||
| 	TAssoc_array _fiscali,_sociali, _costi, _pagamenti; //array che contengono i conti
 | ||
| 
 | ||
| protected:
 | ||
|   virtual bool create(void);
 | ||
|   virtual bool destroy(void);
 | ||
|   virtual void main_loop() ;
 | ||
|   void invio_proforma();
 | ||
|   bool i_proforma_movimenti();
 | ||
|   bool i_proforma_righe(TCursor& cur, TInvioP_file* trasfile);
 | ||
|   bool i_proforma_pagamenti();
 | ||
|   bool i_proforma_clifor(char tipocf = 'C');
 | ||
|   bool i_proforma_conti();
 | ||
| 
 | ||
| 	real totale_documento(TMovimentoPN& pn, const bool includi_ritenute = true) const;
 | ||
| 	void lettura_conti(TAssoc_array& assoc, const char tipoconto);
 | ||
| 	bool cerca_conto(const TBill& bill, const TAssoc_array& assoc, const char tipoconto) const;
 | ||
| 	bool cerca_fiscali(const TBill& bill) const;
 | ||
| 	bool cerca_sociali(const TBill& bill) const;
 | ||
| 	int cerca_pagamento(const TBill& bill) const;
 | ||
| 	int cerca_costo(const TBill& bill) const;
 | ||
| 	bool test_swap(TCausale& caus, bool ritsoc) const;
 | ||
| 	real calcola_pagamento(TRectype& curpag_rec, real& iva_indetraibile);
 | ||
| 	bool sottrai_iva(TMovimentoPN& pn, const TRectype& rigaiva);
 | ||
| 	void stringa_grcosot(TRecord_text& recrighe, const TString& zio);
 | ||
| 	long calcola_fattura_originale(long nreg) const;
 | ||
|   bool calcola_imponibile_totdoc(const long nreg, const TRectype& pag_rec, 
 | ||
|                                  real& imponibile, real& totdoc, real& totpagato, real& iva_indetraibile) const;
 | ||
|   void calcola_imposte(const real& importo, const real& imposta, 
 | ||
|                        const TString& codind, real& iva_det, real& iva_ind) const;
 | ||
| 
 | ||
| public:
 | ||
| 	const real get_importo() {return _importo;}
 | ||
| 	const long get_nregcosto() const {return _nregcosto;}
 | ||
| 	const long get_nregpag() const {return _nregpag;}
 | ||
|   const char get_accsal() const {return _accsal;}
 | ||
| 	const TString& get_vocespesa(const TString& zio) const;
 | ||
| 	TInvioP_file* apri_file(const char* nome);
 | ||
| 	void chiudi_file(TInvioP_file* trasfile);
 | ||
| 
 | ||
|   TInvioP() {};
 | ||
|   virtual ~TInvioP() {};
 | ||
| };  
 | ||
| 
 | ||
| // restituisce un riferimento all' applicazione
 | ||
| inline TInvioP& app() { return (TInvioP&) main_app();}
 | ||
| 
 | ||
| // gestione dei messaggi estesi nei campi
 | ||
| void TInvioP_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str)
 | ||
| {
 | ||
|   const TString code(s.get(0));
 | ||
|   TString valore;
 | ||
|   if (code == "_FISSO")
 | ||
|   {
 | ||
|     // gestione dei campi fissi per i record delle riba
 | ||
|     // sintassi: _FISSO,!<valore>
 | ||
|     // dove: <valore> <20> la stringa fissa da emettere
 | ||
|     TString in(s.get());
 | ||
|     CHECK(in[0]=='!',"Macro _FISSO senza carattere '!'");
 | ||
|     in.ltrim(1);
 | ||
|     in.trim();
 | ||
|     valore = in;
 | ||
|   } 
 | ||
| 	else if (code == "_TELEFONO")
 | ||
| 	{
 | ||
| 		valore = str;
 | ||
| 		valore.trim();
 | ||
| 		str = cur.curr().get("PTEL");
 | ||
| 		valore << str;
 | ||
| 		valore.trim();
 | ||
| 	}
 | ||
| 	else if (code == "_RAGSOC")
 | ||
| 	{
 | ||
| 		valore = str;
 | ||
| 		valore = valore.strip_double_spaces();
 | ||
| 	}
 | ||
| 	else if (code == "_FLAG")
 | ||
| 	{
 | ||
| 		if (app().get_accsal() == 'S')
 | ||
| 			valore = "S";
 | ||
| 		else
 | ||
| 			valore = "A";
 | ||
| 
 | ||
| 	}
 | ||
| 	else if (code == "_NREGCOSTO")
 | ||
| 	{
 | ||
| 		valore.format("%ld", app().get_nregcosto());
 | ||
| 	}
 | ||
| 	else if (code == "_NREGPAG")
 | ||
| 	{
 | ||
| 		valore.format("%ld", app().get_nregpag());
 | ||
| 	}
 | ||
| 	else if (code == "_IMPORTO")
 | ||
| 	{
 | ||
| 		valore = app().get_importo().string();
 | ||
| 	}
 | ||
| 
 | ||
|   else NFCHECK("Macro non definita: %s", (const char *)code);
 | ||
|   str = valore;
 | ||
| }
 | ||
| 
 | ||
| TInvioP_file* TInvioP::apri_file(const char* nome)
 | ||
| {
 | ||
| 	TFilename filename = _msk->get(F_DESTINAZIONE);
 | ||
| 	filename.add(nome);
 | ||
| 	filename.ext("txt");
 | ||
| 	if (filename.exist())
 | ||
| 		remove(filename);
 | ||
| 
 | ||
| 	TInvioP_file* trasfile = new TInvioP_file(filename);
 | ||
| 	trasfile->open(filename,'w');
 | ||
| 	trasfile->force_record_separator();
 | ||
| 	return trasfile;
 | ||
| }
 | ||
| 
 | ||
| void TInvioP::chiudi_file(TInvioP_file* trasfile)
 | ||
| {
 | ||
| 	trasfile->close();
 | ||
| 	delete trasfile;
 | ||
| }
 | ||
| 
 | ||
| const TString& TInvioP::get_vocespesa(const TString& zio) const
 | ||
| {
 | ||
| 	TConfig configfile("tc9100conf.ini", "OPZIONI");
 | ||
| 	const TString16 confstringa = configfile.get("CONFSTRINGA");
 | ||
| 	const int len = confstringa.len();
 | ||
| 
 | ||
| 	TLocalisamfile panapdc(LF_PANAPDC);
 | ||
| 	panapdc.zero();
 | ||
| 	panapdc.setkey(2);
 | ||
| 	panapdc.put("GRUPPO", atoi(zio.mid(0,3)));
 | ||
| 	panapdc.put("CONTO", atoi(zio.mid(3,3)));
 | ||
| 	panapdc.put("SOTTOCONTO", atol(zio.mid(6,6)));
 | ||
| 	const TRectype r(panapdc.curr());
 | ||
| 
 | ||
|   for (panapdc.read(); !panapdc.eof(); panapdc.next())
 | ||
| 	{   
 | ||
| 		if (panapdc.curr() != r) 
 | ||
| 			break;
 | ||
| 		const TString& codconto = panapdc.get("CODCONTO");
 | ||
| 		if (codconto.starts_with(confstringa))
 | ||
| 			return codconto.mid(len);
 | ||
| 	}
 | ||
| 	return EMPTY_STRING;
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::i_proforma_conti()
 | ||
| {
 | ||
| 	TInvioP_file* trasfile = apri_file("pianocon");
 | ||
| 
 | ||
|   TRelation rel(LF_PCON);
 | ||
|   TCursor cur(&rel);
 | ||
|   const long cur_items = cur.items();
 | ||
|   if (cur_items != 0) 
 | ||
|   {
 | ||
| 		TProgind pi(cur_items, "Trasferimento conti...", true, true);
 | ||
| 
 | ||
| 	  cur.freeze();
 | ||
|     TRectype& cur_rec = cur.curr();
 | ||
|     for (cur = 0; cur.pos() < cur_items; ++(cur))
 | ||
|     {
 | ||
| 			pi.addstatus(1);
 | ||
|       if (pi.iscancelled())
 | ||
|         break;
 | ||
| 
 | ||
| 			TRecord_text rec;
 | ||
| 			rec.set_type("P");
 | ||
| 			trasfile->autoload(rec, cur); 
 | ||
| 			trasfile->write(rec);
 | ||
|     }	
 | ||
|   }                  
 | ||
| 	chiudi_file(trasfile);
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::i_proforma_movimenti()
 | ||
| {
 | ||
| 	TInvioP_file* trasfile = apri_file("registra");	//file testate 
 | ||
| 	TInvioP_file* trasfilerighe = apri_file("righe");  //file righe movimenti
 | ||
| 
 | ||
| 	//trasferimento testate movimenti (cerca direttamente sui movimenti analitici in chiave 2..
 | ||
| 	//..,cio<69> per DATACOMP e con NUMREGCG!=0
 | ||
| 	TRectype da(LF_MOV);
 | ||
|   TRectype a(LF_MOV);
 | ||
|   da.put(MOV_DATAREG, _dataini);
 | ||
|   a.put(MOV_DATAREG, _datafin);
 | ||
|   TRelation rel(LF_MOV);
 | ||
| 	rel.add(LF_CAUSALI, "CODCAUS==CODCAUS");
 | ||
| 
 | ||
|   TCursor cur(&rel, "", 2, &da, &a);	//chiave per data
 | ||
| 
 | ||
|   const long cur_items = cur.items();
 | ||
|   if (cur_items != 0) 
 | ||
|   { 
 | ||
| 		//prepara i record di tipo testata da scrivere
 | ||
| 		TRecord_text rec;
 | ||
| 		rec.set_type("T");
 | ||
| 
 | ||
| 		TProgind pi(cur_items, "Trasferimento movimenti...", true, true);
 | ||
| 
 | ||
| 	  cur.freeze();
 | ||
|     const TRectype& cur_rec = cur.curr();
 | ||
|     for (cur = 0; cur.pos() < cur_items; ++(cur))
 | ||
| 		{
 | ||
| 			pi.addstatus(1);
 | ||
|       if (pi.iscancelled())
 | ||
|         break;
 | ||
| 
 | ||
| 			//carica e scrive il record di testata in base alle informazioni contenute nel tc9100a.ini
 | ||
| 			trasfile->autoload(rec, cur); 
 | ||
| 			trasfile->write(rec);
 | ||
| 			//trasferisce le righe del movimento analitico corrente solo
 | ||
| 			i_proforma_righe(cur, trasfilerighe);
 | ||
|     }	
 | ||
|   }
 | ||
| 	chiudi_file(trasfilerighe);
 | ||
| 	chiudi_file(trasfile);
 | ||
| 	return true;                 
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::i_proforma_righe(TCursor& cur, TInvioP_file* trasfilerighe)
 | ||
| {
 | ||
| 	//---- righe movimenti ----
 | ||
| 	TInvioP_saldi_cg conti_importi;
 | ||
| 
 | ||
| 	//Creo un movimento PN (con numreg = a quello del mov)che servira' un po' dovunque
 | ||
| 	TMovimentoPN pn;
 | ||
| 	pn.curr() = cur.curr();
 | ||
| 	if (pn.read() == NOERR)
 | ||
| 	{
 | ||
| 		for (int j = 0; j < pn.cg_items(); j++)
 | ||
| 			conti_importi.somma(pn.cg(j));
 | ||
| 	}
 | ||
| 
 | ||
| 	TRecord_text recrighe;	//istanzia il tipo record corretto da scrivere sul trasfilerighe
 | ||
| 	recrighe.set_type("R");
 | ||
| 
 | ||
| 	TAnal_mov analmov(cur.curr());	//..istanzia il movimento analitico con numregcg=numreg del mov
 | ||
| 	const long analrighe_items = analmov.body().rows();
 | ||
| 
 | ||
| 	if (analrighe_items > 0)	//se il movana ha righe..
 | ||
| 	{
 | ||
| 		TRelation rel_rmovana(LF_RMOVANA);	//crea una relazione sulle righe anali cui aggiunge mov e movana
 | ||
| 		rel_rmovana.add(LF_MOVANA, "NUMREG==NUMREG");
 | ||
| 		rel_rmovana.add(LF_MOV, "NUMREG==NUMREGCG", 1, LF_MOVANA);
 | ||
| 		TCursor cur_rmovana(&rel_rmovana);	//crea il cursore sulle righe analitiche che serve per poter usare la autoload
 | ||
| 		cur_rmovana.curr(LF_MOVANA) = analmov;
 | ||
| 		cur_rmovana.curr(LF_MOV) = cur.curr();
 | ||
| 
 | ||
| 		for (int i = 1; i <= analrighe_items; i++)
 | ||
| 		{
 | ||
| 			//..e scandisce le righe
 | ||
| 			const TRectype& riga = analmov.body().row(i);	
 | ||
| 			//inganna il cursore passandogli la riga analitica in esame (bastardo!)
 | ||
| 			cur_rmovana.curr() = riga;
 | ||
| 			//carica le righe analitiche
 | ||
| 			trasfilerighe->autoload(recrighe, cur_rmovana);
 | ||
| 			//toglie le righe contabili corrispondenti che sono appena state aggiunte con la autoload (sarebbero..
 | ||
| 			//..duplicate se non lo facesse!!!)
 | ||
| 			conti_importi.sottrai(riga);
 | ||
| 
 | ||
| 			//procedura orrenda per eliminare gli zeri dai gr/co/sot e passarli come stringhe!
 | ||
| 			const TString16 zio = cur_rmovana.curr().get(RMOVANA_CODCONTO);
 | ||
| 			stringa_grcosot(recrighe, zio);
 | ||
| 
 | ||
| 			//procedura per scrivere la fase che deve essere spezzata in due per sottoprogetto ed edizione
 | ||
| 			const TString& codfase = riga.get(RMOVANA_CODFASE);
 | ||
| 			if (codfase.full())
 | ||
| 			{
 | ||
| 				recrighe.add(codfase.left(4), 14);
 | ||
| 				recrighe.add(codfase.mid(4,4), 15);
 | ||
| 			}
 | ||
| 
 | ||
| 			//procedura per ricavare la voce di spesa
 | ||
| 			const TString& vocespesa = get_vocespesa(zio);
 | ||
| 			recrighe.add(vocespesa, 16);
 | ||
| 
 | ||
| 			//scrive  sul file di trasferimento (alla faccia della semplicita'!)
 | ||
| 			trasfilerighe->write(recrighe);
 | ||
| 		}
 | ||
| 	}
 | ||
| 	//prende le righe contabili che non sono state eliminate dalle analitiche nelle sottrai(riga)..
 | ||
| 	//..in modo da passare anche quelle (in caso contrario sarebbero andati perduti gli importi di..
 | ||
| 	//..tali righe che non avevano commessa!)
 | ||
| 	const long conti_importi_items = conti_importi.items();
 | ||
| 	TString workstring;		//stringa di lavoro che serve nel ciclo sotto
 | ||
| 	for (int k = 0; k < conti_importi_items; k++) 
 | ||
| 	{
 | ||
|     if (!conti_importi.importo(k).is_zero())
 | ||
| 		{
 | ||
| 			//aggiunge i valori ai campi uno ad uno perch<63> non ha un cursore per fare l'autoload
 | ||
| 			recrighe.destroy();
 | ||
| 			recrighe.add(pn.curr().get(MOV_NUMREG), 0);	//numreg
 | ||
| 			workstring = "N";
 | ||
| 			recrighe.add(workstring, 1);	//rigaiva
 | ||
| 			TImporto& imp = conti_importi.importo(k);
 | ||
| 			workstring.cut(0) << imp.sezione();
 | ||
| 			recrighe.add(workstring, 2);	//sezione			
 | ||
| 			//procedura orrenda per eliminare gli zeri dai gr/co/sot e passarli come stringhe!
 | ||
| 			const TString& zio = conti_importi.conto(k);
 | ||
| 			stringa_grcosot(recrighe, zio);
 | ||
| 
 | ||
| 			const TString tipocf = pn.curr().get(MOV_TIPO);
 | ||
| 			recrighe.add(tipocf, 6);	//tipocf
 | ||
| 
 | ||
| 			//procedura per stringare il codice clifo
 | ||
| 			if (tipocf > ' ')
 | ||
| 			{
 | ||
| 				const long codcf = pn.curr().get_long(MOV_CODCF);
 | ||
| 				TString cf;
 | ||
| 				cf.format("%ld", codcf);
 | ||
| 				recrighe.add(cf, 7);	//codcf
 | ||
| 			}
 | ||
| 			else
 | ||
| 			{
 | ||
| 				recrighe.add("", 7);	//codcf
 | ||
| 			}
 | ||
| 
 | ||
| 			recrighe.add(pn.curr().get(RMV_DESCR), 8);	//descrizione
 | ||
| 			recrighe.add(imp.valore().string(), 9);		//importo
 | ||
| 			
 | ||
| 			//procedura per ricavare la voce di spesa
 | ||
| 			const TString& vocespesa = get_vocespesa(zio);
 | ||
| 			recrighe.add(vocespesa, 16);
 | ||
| 
 | ||
| 			//e finalmente scrive le righe avanzate...
 | ||
| 			trasfilerighe->write(recrighe);
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	//---- righe iva ----
 | ||
| 	//adesso tocca alle righe iva...e sara' un casino indicibile!
 | ||
| 
 | ||
| 	//assoc array contenente tutti i diversi conti che incontrera' nello scanning delle righe iva
 | ||
| 	TAssoc_array conti;
 | ||
|   //causale del movimento: serve per conoscere il tipo di detraibilita' dell'iva (piu' sotto)
 | ||
|   const TCausale caus(pn.curr().get(MOV_CODCAUS));
 | ||
|   const int anno = pn.curr().get_date(MOV_DATAREG).year();
 | ||
|   real imp_detr, iva_detr, imp_indetr, iva_indetr;
 | ||
| 
 | ||
| 	//scanning delle righe iva alla ricerca dei conti che compaiono
 | ||
| 	for (int l = 0; l < pn.iva_items(); l++)
 | ||
| 	{
 | ||
| 		//prende il conto e lo mette nell'assoc_array dei conti (notare che, essendo un assoc_array,..
 | ||
| 		//..non vengono inseriti doppioni! mitico!!)
 | ||
| 		TBill conto;
 | ||
| 		conto.get(pn.iva(l));
 | ||
| 		const char* codconto = conto.string(0x8);
 | ||
| 
 | ||
| 		//ad ogni conto lega un assoc_array (codivae) che conterra' tutti i codici iva legati a quel..
 | ||
| 		//..conto nelle righe iva con i relativi importi
 | ||
| 		TAssoc_array* codivae = (TAssoc_array*) conti.objptr(codconto);
 | ||
| 		if (codivae == NULL)	//se non esiste l'assoc_array legato al conto lo crea
 | ||
| 		{
 | ||
| 			codivae = new TAssoc_array;
 | ||
| 			//aggiunge all'assoc_array conti il suo elemento assoc_array codivae..ha un assoc_array..
 | ||
| 			//..di assoc_array!
 | ||
| 			conti.add(codconto, codivae);
 | ||
| 		}
 | ||
| 
 | ||
| 		const TString4 codiva = pn.iva(l).get(RMI_CODIVA);	//prende il codice iva dalla riga iva
 | ||
| 		//aggiungere qui eventuale codice intero di indetraibilita'
 | ||
| 
 | ||
| 		//ad ogni codiva presente in codivae lega un importo che risultera' la somma di tutti gli..
 | ||
| 		//..importi con lo stesso conto e codice iva
 | ||
| 		real* tot_imp = (real*) codivae->objptr(codiva);
 | ||
| 		if (tot_imp == NULL)	//se non esiste l'importo legato al codice iva lo crea
 | ||
| 		{
 | ||
| 			tot_imp = new real;
 | ||
| 			//aggiunge all'assoc_array codivae il suo elemento real tot_imp
 | ||
| 			codivae->add(codiva, tot_imp);
 | ||
| 		}
 | ||
| 		
 | ||
| 		//accresce l'importo tot_imp relativo alla coppia codiva+codconto corrente
 | ||
|     const real imponibile = pn.iva(l).get_real(RMI_IMPONIBILE);
 | ||
|     const real imposta = pn.iva(l).get_real(RMI_IMPOSTA);
 | ||
|     const TString4 codind = pn.iva(l).get(RMI_TIPODET);
 | ||
|     pn.analizza_riga_IVA(imponibile, imposta, caus, anno, codiva, codind, imp_detr, 
 | ||
|                          iva_detr, imp_indetr, iva_indetr);
 | ||
| 		*tot_imp += imp_detr + imp_indetr + iva_indetr;
 | ||
| 		//aggiungere qui eventuale imposta
 | ||
| 	}
 | ||
| 
 | ||
| 	TRecord_text recrigheiva;	//istanzia il tipo record corretto da scrivere sul trasfilerighe
 | ||
| 	recrigheiva.set_type("I");
 | ||
| 	int nrighe = 0;
 | ||
| 
 | ||
| 	TRelation rel_rmoviva(LF_RMOVIVA);
 | ||
| 	rel_rmoviva.add(LF_MOV, "NUMREG==NUMREG");
 | ||
| 	TCursor cur_rmoviva(&rel_rmoviva);
 | ||
| 	cur_rmoviva.curr(LF_MOV) = cur.curr();
 | ||
| 
 | ||
| 	const long analrigheiva_items = analmov.body().rows();
 | ||
| 
 | ||
| 	for (int n = 1; n <= analrigheiva_items; n++)
 | ||
| 	{
 | ||
| 		//scanning delle righe analitiche per estrarne i conti e controllare se compaiono nell'assoc_array..
 | ||
| 		//..dei conti riempito con i conti trovati nelle righe iva
 | ||
| 		const TRectype& riga = analmov.body().row(n);
 | ||
| 		const TString& codconto = riga.get(RMOVANA_CODCONTO);
 | ||
| 		TAssoc_array* codivae = (TAssoc_array*) conti.objptr(codconto);	//assoc_array codivae del codconto
 | ||
| 
 | ||
| 		//se ha almeno un codice iva associato a questo conto nell'assoc_array dei conti..
 | ||
| 		if (codivae != NULL)
 | ||
| 		{
 | ||
| 			//..prende l'importo della riga analitica..
 | ||
| 			real importo_riga = riga.get_real(RMOVANA_IMPORTO);
 | ||
| 			//..lo ridistribuisce secondo le percentuali iva
 | ||
| 			TGeneric_distrib distributore(importo_riga, TCurrency::get_firm_dec());
 | ||
| 
 | ||
| 			FOR_EACH_ASSOC_OBJECT((*codivae), h, k, imp)
 | ||
| 			{
 | ||
| 				const real& imp_iva = *(real*)imp;
 | ||
| 				distributore.add(imp_iva);
 | ||
| 			}
 | ||
| 			
 | ||
| 			//crea una riga iva dal cursore, con numreg = numreg della testata del mov originale
 | ||
| 			TRectype& rigaiva = cur_rmoviva.curr(LF_RMOVIVA);	
 | ||
|       rigaiva.put(RMI_NUMREG, pn.curr().get(MOV_NUMREG));
 | ||
| 			
 | ||
| 			//scan dell'assoc_array ridistribuito e inserimento dei valori nella riga iva appena creata
 | ||
| 			FOR_EACH_ASSOC_OBJECT((*codivae), hi, ki, impi)
 | ||
| 			{
 | ||
| 				rigaiva.put(RMI_NUMRIG, ++nrighe);
 | ||
| 				rigaiva.put(RMI_GRUPPO, codconto.mid(0,3));
 | ||
| 				rigaiva.put(RMI_CONTO, codconto.mid(3,3));
 | ||
| 				rigaiva.put(RMI_SOTTOCONTO, codconto.mid(6,6));
 | ||
|         const TBill zio(rigaiva);
 | ||
| 				rigaiva.put(RMI_TIPOC, zio.tipo());
 | ||
| 				rigaiva.put(RMI_IMPONIBILE, distributore.get());
 | ||
| 				rigaiva.put(RMI_CODIVA, ki);
 | ||
| 
 | ||
| 				//deve sottrarre gli importi trovati dalle righe iva originali
 | ||
| 				sottrai_iva(pn, rigaiva);
 | ||
| 
 | ||
| 				//scrittura delle righe di tipo I; notare che il cur passato alla autoload altri non e'..
 | ||
| 				//..che la rigaiva appena completata
 | ||
| 				trasfilerighe->autoload(recrigheiva, cur_rmoviva);
 | ||
| 
 | ||
| 				//procedura ignorante per stringare il codice clifo
 | ||
| 				if (zio.tipo() > ' ')
 | ||
| 				{
 | ||
| 					const long sottoconto = zio.sottoconto();
 | ||
| 					TString cf;
 | ||
| 					cf.format("%ld", sottoconto);
 | ||
| 					recrigheiva.add(cf, 7);
 | ||
| 				}
 | ||
| 
 | ||
| 				recrigheiva.add(riga.get(RMOVANA_DESCR).left(40), 8);	//descrizione riga iva = riga anale corrente
 | ||
| 				recrigheiva.add(riga.get(RMOVANA_CODCMS), 13);		//commessa presa dalla riga analitica corrente
 | ||
| 
 | ||
| 				//procedura per scrivere la fase che deve essere spezzata in due per sottoprogetto ed edizione
 | ||
| 				const TString& codfase = riga.get(RMOVANA_CODFASE);
 | ||
| 				if (codfase.full())
 | ||
| 				{
 | ||
| 					recrighe.add(codfase.left(4), 14);
 | ||
| 					recrighe.add(codfase.mid(4,4), 15);
 | ||
| 				}
 | ||
| 
 | ||
| 				//procedura per ricavare la voce di spesa
 | ||
| 				TString uncle = zio.string(0x8);
 | ||
| 				const TString& vocespesa = get_vocespesa(uncle);
 | ||
| 				recrighe.add(vocespesa, 16);
 | ||
| 
 | ||
| 				trasfilerighe->write(recrigheiva);
 | ||
| 			}
 | ||
| 		}	//if(codivae!=..
 | ||
| 	}	//for(analmov.rows..
 | ||
| 
 | ||
| 	const long righeiva_items = pn.iva_items();
 | ||
| 	if (righeiva_items > 0)
 | ||
| 	{
 | ||
| 		//deve trasferire le righe iva rimaste dopo la sottrazione degli importi dovuti alle righe analitiche
 | ||
| 		for (int m = 0; m < righeiva_items; m++)
 | ||
| 		{
 | ||
| 			const TRectype& riga = pn.iva(m);
 | ||
| 			if (!riga.get_real(RMI_IMPOSTA).is_zero())
 | ||
| 			{
 | ||
| 				const TBill uncle(riga);
 | ||
| 				cur_rmoviva.curr() = riga;
 | ||
| 				trasfilerighe->autoload(recrigheiva, cur_rmoviva);
 | ||
| 				recrigheiva.add(uncle.tipo(), 6);	//tipocf
 | ||
| 				recrigheiva.add(uncle.descrizione().left(40), 8);	//descrizione della riga iva = descrizione conto
 | ||
| 				//procedura per ricavare la voce di spesa
 | ||
| 				TString zio = uncle.string(0x8);
 | ||
| 				const TString& vocespesa = get_vocespesa(zio);
 | ||
| 				recrighe.add(vocespesa, 14);				
 | ||
| 				trasfilerighe->write(recrigheiva);
 | ||
| 			}
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return true;
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::sottrai_iva(TMovimentoPN& pn, const TRectype& rigaiva)
 | ||
| {
 | ||
| 	const TBill zio(rigaiva);
 | ||
| 	const real imposta = rigaiva.get_real(RMI_IMPOSTA);
 | ||
| 
 | ||
| 	int k;
 | ||
| 	//caso fortunato
 | ||
| 	//scandisce gli elementi dell'array;se ne trova uno (k-esimo) con conto ed importo coincidenti..
 | ||
| 	//..con quelli passati al metodo, azzera l'importo di tale elemento dell'array
 | ||
|   for (k = 0; k < pn.iva_items(); k++)
 | ||
| 	{
 | ||
| 		TRectype& iva_k = pn.iva(k);
 | ||
| 		const TBill conto_k(iva_k);
 | ||
| 		const real imposta_k = iva_k.get_real(RMI_IMPOSTA);
 | ||
| 		if (conto_k == zio && imposta_k == imposta)
 | ||
| 		{
 | ||
| 			iva_k.zero(RMI_IMPOSTA);
 | ||
| 			return true;
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	//caso sfortunato
 | ||
| 	//in questo caso gli importi dell'elemento k-esimo dell'array e passato al metodo NON coincidono
 | ||
| 	real residuo = imposta;
 | ||
| 	int ultima_riga_buona = -1;
 | ||
| 
 | ||
|   for (k = 0; k < pn.iva_items() && !residuo.is_zero(); k++)
 | ||
| 	{
 | ||
| 		TRectype& iva_k = pn.iva(k);
 | ||
| 		const TBill conto_k(iva_k);
 | ||
| 		
 | ||
| 		if (conto_k == zio)
 | ||
| 		{
 | ||
| 			const real imposta_k = iva_k.get_real(RMI_IMPOSTA);
 | ||
| 			if (residuo >= imposta_k)
 | ||
| 			{
 | ||
| 				residuo -= imposta_k;
 | ||
| 				iva_k.zero(RMI_IMPOSTA);
 | ||
| 			}
 | ||
| 			else
 | ||
| 			{
 | ||
| 				iva_k.put(RMI_IMPOSTA, imposta_k - residuo);
 | ||
| 				residuo = ZERO;
 | ||
| 			}
 | ||
| 			ultima_riga_buona = k;
 | ||
| 		}
 | ||
| 	}
 | ||
| 	//alla fine del ciclo sull'array resta un residuo non nullo..
 | ||
| 	if (!residuo.is_zero())
 | ||
| 	{
 | ||
| 		if (ultima_riga_buona >= 0)
 | ||
| 		{
 | ||
| 			TRectype& iva_k = pn.iva(k);
 | ||
|   		iva_k.put(RMI_IMPOSTA, -residuo);
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return true;
 | ||
| }
 | ||
| 
 | ||
| void TInvioP::stringa_grcosot(TRecord_text& recrighe, const TString& zio)
 | ||
| {	
 | ||
| 	TString8 grcosot;
 | ||
| 	long gcs = 0;
 | ||
| 
 | ||
| 	gcs = atoi(zio.left(3));			
 | ||
| 	grcosot.format("%d", gcs);
 | ||
| 	recrighe.add(grcosot, 3);	//gruppo
 | ||
| 
 | ||
| 	gcs = atoi(zio.mid(3,3));
 | ||
| 	grcosot.format("%d", gcs);
 | ||
| 	recrighe.add(grcosot, 4);	//conto
 | ||
| 
 | ||
| 	gcs = atoi(zio.mid(6,6));
 | ||
| 	grcosot.format("%d", gcs);
 | ||
| 	recrighe.add(grcosot, 5);	//sottoconto
 | ||
| }
 | ||
| 
 | ||
| // Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle
 | ||
| // ritenute sociali sulla causale                        
 | ||
| real TInvioP::totale_documento(TMovimentoPN& pn, const bool includi_ritenute) const
 | ||
| {
 | ||
|   //testata del movimento di prima nota
 | ||
|   const TRectype& mov = pn.curr();
 | ||
| 
 | ||
|   real tot = mov.get_real(MOV_TOTDOC);              // Legge totale
 | ||
|   //i conti sulle ritenute li deve fare solo se il movimento e' iva!!
 | ||
|   if (pn.iva_items() > 0)
 | ||
|   {
 | ||
|     if (includi_ritenute)
 | ||
|     {
 | ||
|       const real ritfis = mov.get_real(MOV_RITFIS);
 | ||
|       tot += ritfis;                          // Somma ritenute fiscali
 | ||
|     
 | ||
|       const real ritsoc = mov.get_real(MOV_RITSOC);           
 | ||
| 
 | ||
|       if (!ritsoc.is_zero())
 | ||
|       {
 | ||
|         TCausale caus(mov.get(MOV_CODCAUS));
 | ||
|         const bool swapt = test_swap(caus, false);    // Totale invertito ?
 | ||
|         const bool swaps = test_swap(caus, true);     // Ritenute sociali invertite ?
 | ||
|         if (swapt ^ swaps)                      // Somma ritenute sociali con segno
 | ||
|           tot -= ritsoc;
 | ||
|         else
 | ||
|           tot += ritsoc;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   else  //movimenti non iva; calcolo delle ritenute
 | ||
|   {
 | ||
|     TCausale caus(mov.get(MOV_CODCAUS));
 | ||
|     const char sez = caus.sezione_clifo();
 | ||
|     bool tot_is_zero = tot.is_zero();
 | ||
|     TImporto totdoc(sez, tot);
 | ||
|   	for (int i = 0; i < pn.cg_items(); i++)
 | ||
| 		{
 | ||
| 			const TRectype& rmov = pn.cg(i);
 | ||
| 			const TBill conto(rmov);
 | ||
|       const TImporto importo(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO));
 | ||
| 
 | ||
|       if (tot_is_zero && rmov.get_char(RMV_TIPOC) > ' ')
 | ||
|         totdoc += importo;
 | ||
|       else
 | ||
|       {
 | ||
| 			  if (includi_ritenute && (cerca_fiscali(conto) || cerca_sociali(conto)))
 | ||
| 				  totdoc += importo; //valore da stampare nella colonna Tot.fattura con ritenute
 | ||
|       }
 | ||
|     }
 | ||
|     tot = totdoc.valore();
 | ||
|   }
 | ||
|   return tot;
 | ||
| }
 | ||
| 
 | ||
| // Controlla sulla causale se il segno del totale documento (ritsoc=FALSE) 
 | ||
| // o quello delle ritenute sociali (ritsoc=TRUE) e' invertito rispetto al normale
 | ||
| bool TInvioP::test_swap(TCausale& caus, bool ritsoc) const
 | ||
| {
 | ||
|   const char sez = ritsoc ? caus.sezione_ritsoc() : caus.sezione_clifo();
 | ||
|   const bool s = (caus.iva() == iva_vendite) ^ (sez == 'D');
 | ||
|   return s;
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::cerca_conto(const TBill& bill, const TAssoc_array& assoc, const char tipoconto) const
 | ||
| {
 | ||
|   TToken_string key(15);
 | ||
| 	key.add(tipoconto);		//il primo char della tokenstring e' il tipoconto (Fiscale o Sociale)
 | ||
| 
 | ||
|   key.add(bill.gruppo());
 | ||
|   if (assoc.is_key(key))
 | ||
|     return true;
 | ||
| 
 | ||
|   key.add(bill.conto());
 | ||
|   if (assoc.is_key(key))
 | ||
|     return true;
 | ||
| 
 | ||
|   key.add(bill.sottoconto());
 | ||
|   if (assoc.is_key(key))
 | ||
|     return true;
 | ||
| 
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| int TInvioP::cerca_costo(const TBill& bill) const
 | ||
| {
 | ||
|   if (cerca_conto(bill, _costi, 'C'))
 | ||
| 		return 1;
 | ||
| 	else
 | ||
| 		return 0;
 | ||
| }
 | ||
| 
 | ||
| int TInvioP::cerca_pagamento(const TBill& bill) const
 | ||
| {
 | ||
|   if (cerca_conto(bill, _pagamenti, 'P'))
 | ||
| 		return 2;
 | ||
| 	else
 | ||
| 		return 0;
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::cerca_fiscali(const TBill& bill) const
 | ||
| {
 | ||
|   if (bill.tipo() > ' ')  //non si vogliono i conti tipo Cliente Fornitore
 | ||
|     return false;
 | ||
| 
 | ||
|   return cerca_conto(bill, _fiscali, 'F');
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::cerca_sociali(const TBill& bill) const
 | ||
| {
 | ||
|   if (bill.tipo() > ' ')  //non si vogliono i conti tipo Cliente Fornitore
 | ||
|     return false;
 | ||
| 
 | ||
|   return cerca_conto(bill, _sociali, 'S');
 | ||
| }
 | ||
| 
 | ||
| void TInvioP::lettura_conti(TAssoc_array& assoc, const char tipoconto)
 | ||
| {
 | ||
|   TConfig conti("ca3600a.ini","Pdcc"); //paragrafo da scandire nell'ini
 | ||
|   TAssoc_array& vars = conti.list_variables();
 | ||
| 
 | ||
|   FOR_EACH_ASSOC_STRING(vars, h, k, val)  //riempie l'assoc con i soli valori del paragrafo dell'ini
 | ||
| 	{
 | ||
| 		if (*val == tipoconto)	//mette nell'assocarray solo i conti corrispondenti al tipoconto passato
 | ||
| 			assoc.add(val);
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| void TInvioP::calcola_imposte(const real& importo, const real& imposta, 
 | ||
|                               const TString& codind, real& iva_det, real& iva_ind) const
 | ||
| {
 | ||
|   iva_det = imposta;
 | ||
|   iva_ind = ZERO;
 | ||
| 
 | ||
|   //esiste un codice di indetraibilita'?
 | ||
| 	if (codind.full())
 | ||
| 	{
 | ||
|     real perc = ZERO;
 | ||
| 		const TRectype& rec = cache().get("%DET", codind);
 | ||
|     if (rec.empty())
 | ||
|     {
 | ||
|       if (strchr("139", codind[0]) != NULL) // Clausola di salvaguardia
 | ||
|         perc = CENTO;
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
| 		  if (rec.get_int("I0") > 0)
 | ||
| 			  perc = rec.get_real("R0");
 | ||
|     }
 | ||
|     //valori delle varie ive
 | ||
|     iva_ind = imposta * perc / CENTO;
 | ||
|     iva_ind.round(2);
 | ||
|     iva_det = imposta - iva_ind;
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::calcola_imponibile_totdoc(const long nreg, const TRectype& pag_rec, real& imponibile, real& totdoc, real& totpagato, real& iva_indetraibile) const
 | ||
| {
 | ||
|   totpagato = pag_rec.get_real(PAGSCA_IMPORTO);
 | ||
| 	
 | ||
|   TMovimentoPN pn;
 | ||
| 	pn.curr().put(MOV_NUMREG, nreg);
 | ||
|   bool ok = nreg > 0 && pn.read() == NOERR;
 | ||
| 	if (ok)
 | ||
| 	{
 | ||
|     //percentuale di pagamento sul totale documento senza ritenute
 | ||
|     const real totdoc_no_rit = totale_documento(pn, false);
 | ||
|     const real perc_ritenute = totpagato / totdoc_no_rit;
 | ||
|     //Movimenti CON SALDACONTO
 | ||
|     //se movimento IVA..
 | ||
| 		if (pn.iva_items() > 0)
 | ||
| 		{
 | ||
|       real imposta;
 | ||
|       const TRectype& movfat = pn.curr();
 | ||
| 
 | ||
|       real ritfis = movfat.get_real(MOV_RITFIS);  //ritenute sulla fattura: verranno pagate percentualmente
 | ||
|       if (perc_ritenute < UNO)
 | ||
|       {
 | ||
|         ritfis *= perc_ritenute;
 | ||
|         ritfis.round(2);
 | ||
|       }
 | ||
|       totpagato += pag_rec.get_real(PAGSCA_RITENUTE); //ritenute eventuali sul pagamento
 | ||
| 		  totpagato += ritfis;
 | ||
| 
 | ||
|   	  //Le ritenute sociali invece vanno testate con la test_swap..
 | ||
|       real ritsoc = movfat.get_real(MOV_RITSOC);
 | ||
|       if (perc_ritenute < UNO)
 | ||
|       {
 | ||
|         ritsoc *= perc_ritenute;
 | ||
|         ritsoc.round(2);
 | ||
|       }
 | ||
| 		  ritsoc += pag_rec.get_real(PAGSCA_RITSOC);
 | ||
|       
 | ||
| 		  if (!ritsoc.is_zero())
 | ||
| 		  {
 | ||
| 			  const TRectype& mov = pn.curr();
 | ||
| 			  TCausale caus(mov.get(MOV_CODCAUS));
 | ||
| 			  const bool swapt = test_swap(caus, false);    // Totale invertito ?
 | ||
| 			  const bool swaps = test_swap(caus, true);     // Ritenute sociali invertite ?
 | ||
| 			  if (swapt ^ swaps)                      // Somma ritenute sociali con segno
 | ||
| 				  totpagato -= ritsoc;
 | ||
| 			  else
 | ||
| 				  totpagato += ritsoc;
 | ||
| 		  }
 | ||
| 			for (int i = 0; i < pn.iva_items(); i++)
 | ||
| 			{
 | ||
| 				const TRectype& rmoviva = pn.iva(i);
 | ||
| 				const TBill conto(rmoviva);
 | ||
| 
 | ||
| 				if (conto.indicatore_bilancio() != 5)
 | ||
| 				{
 | ||
| 					const real importo = rmoviva.get_real(RMI_IMPONIBILE);
 | ||
| 					const real iva = rmoviva.get_real(RMI_IMPOSTA);
 | ||
|           //trattamento delle ive indetraibili!
 | ||
| 					const TString& codind = rmoviva.get(RMI_TIPODET);
 | ||
| 
 | ||
| 					imponibile += importo;
 | ||
| 
 | ||
|           real iva_det, iva_ind;
 | ||
|           //calcola i valori dell'iva detraibile e delle ive indetraibili in diverse percentuali
 | ||
|           calcola_imposte(importo, iva, codind, iva_det, iva_ind);
 | ||
|           //se esiste un'iva indetraibile..
 | ||
|           if (iva_ind != ZERO)
 | ||
|           {
 | ||
|             iva_indetraibile += iva_ind;
 | ||
|   				  imponibile += iva_ind;
 | ||
|           }
 | ||
|           //l'iva detraibile va sempre bene sommata alle imposte
 | ||
|           imposta += iva_det;
 | ||
|         }      
 | ||
| 			}
 | ||
|       totdoc = totale_documento(pn); //tot doc con ritenute fiscali + ritenute sociali
 | ||
| 
 | ||
|     }	//if pn.iva_items()..
 | ||
|     else  //NON iva
 | ||
|     {
 | ||
|       totdoc = totale_documento(pn); //tot doc con ritenute fiscali + ritenute sociali
 | ||
|       imponibile = totdoc;  //nel caso di non iva
 | ||
| 
 | ||
|       TCausale caus(pn.curr().get(MOV_CODCAUS));
 | ||
|       TImporto totpag(caus.sezione_clifo(), totpagato);
 | ||
|   	  for (int i = 0; i < pn.cg_items(); i++)
 | ||
| 		  {
 | ||
| 			  const TRectype& rmov = pn.cg(i);
 | ||
| 			  const TBill conto(rmov);
 | ||
| 			  if (cerca_fiscali(conto) || cerca_sociali(conto))
 | ||
|         { 
 | ||
|           real imp = rmov.get_real(RMV_IMPORTO);
 | ||
|           if (perc_ritenute < UNO)
 | ||
|           {
 | ||
|             imp *= perc_ritenute;
 | ||
|             imp.round(2);
 | ||
|           }
 | ||
|           const TImporto importo(rmov.get_char(RMV_SEZIONE), imp);
 | ||
| 				  totpag += importo; //valore da stampare nella colonna Tot.fattura con ritenute
 | ||
|         }
 | ||
|       }
 | ||
|       totpagato = totpag.valore();
 | ||
|     }
 | ||
| 	} //if (pn.read() == NOERR
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| real TInvioP::calcola_pagamento(TRectype& curpag_rec, real& iva_indetraibile)
 | ||
| {
 | ||
| 	//deve costruirsi la riga di partita che riguarda il documento di origine
 | ||
| 	//per prima cosa crea tale riga a partire dal pagamento, che ha una chiave lunghissima...
 | ||
| 	TToken_string key_part;
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_TIPOC));
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_GRUPPO));
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_CONTO));
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_SOTTOCONTO));
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_ANNO));
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_NUMPART));
 | ||
| 	key_part.add(curpag_rec.get(PAGSCA_NRIGA));
 | ||
| 	//..ecco il record delle partite..
 | ||
| 	const TRectype& rec_partite = cache().get(LF_PARTITE, key_part);
 | ||
| 	//..da cui prende nreg
 | ||
| 	const long nreg = rec_partite.get_long(PART_NREG);
 | ||
| 	//se nreg esiste...
 | ||
| 
 | ||
|   //dichiariamo una serie di simpatici real utilizzati in seguito
 | ||
| 	real totdoc,imponibile,totpagato;
 | ||
| 
 | ||
|   if (calcola_imponibile_totdoc(nreg, curpag_rec, imponibile, totdoc, totpagato, iva_indetraibile))
 | ||
|   {
 | ||
| 	  const real percentuale = totpagato /totdoc;
 | ||
|     //cerca se esiste una fattura da ricevere anteriore alla fattura da pagare
 | ||
|     const long fdr = calcola_fattura_originale(nreg);
 | ||
|     //se la trova deve tenerne conto in quanto la presente fattura (nreg) potrebbe pagare solo..
 | ||
|     //..una parte della fdr originale
 | ||
|     if (fdr != nreg)
 | ||
|     {
 | ||
|       real imponibile_fdr, totdoc_fdr, totpagato_fdr, iva_indetraibile_fdr;
 | ||
|       //riutilizza la calcola_imponibile_totdoc per l'fdr;si fa notare che in questo caso gli..
 | ||
|       //..ultimi due parametri del metodo sono del tutto inutili
 | ||
|       if (calcola_imponibile_totdoc(fdr, curpag_rec, imponibile_fdr, totdoc_fdr, totpagato_fdr, iva_indetraibile_fdr))
 | ||
|       {
 | ||
|         const real rapporto_pagati = totdoc / totdoc_fdr;
 | ||
|         const real rapporto_imponibili = imponibile_fdr / imponibile;
 | ||
|         //la fattura con totdoc paga una parte di una precedente fdr con totdoc maggiore!
 | ||
|         //in questo caso totpagato e' quello della fattura e deve uscire senza ricalcolare..
 | ||
|         //..percentuali e cazzi vari (funziona ststisticamente!)
 | ||
|         if (rapporto_pagati >= 0.7)
 | ||
|           imponibile = imponibile_fdr;
 | ||
| 
 | ||
|         if (rapporto_imponibili < 0.7 || rapporto_imponibili > 0.85)
 | ||
|           iva_indetraibile = ZERO;
 | ||
|       }
 | ||
|     } //if(fdr!=nreg..
 | ||
|     else  //se non esiste una fdr eventuali ive indetraibili non sussistono
 | ||
|       iva_indetraibile = ZERO;
 | ||
| 
 | ||
|     //calcolo finale del pagato
 | ||
|     totpagato = imponibile * percentuale;
 | ||
|     totpagato.round(2);
 | ||
| 
 | ||
|   } //if(calcola_imponibile_totdoc(nreg,...
 | ||
| 
 | ||
| 	return totpagato;
 | ||
| }
 | ||
| 
 | ||
| long TInvioP::calcola_fattura_originale(long nreg) const
 | ||
| {
 | ||
| 	//prende il movimento del pagamento
 | ||
| 	const TRectype& mov = cache().get(LF_MOV, nreg);
 | ||
| 
 | ||
| 	TToken_string key;
 | ||
| 	key.add(mov.get(MOV_DCODNUM));
 | ||
| 	key.add(mov.get(MOV_DANNO));
 | ||
| 	key.add(mov.get(MOV_DPROVV));
 | ||
| 	key.add(mov.get(MOV_DNDOC));
 | ||
| 	//crea il documento da cui deriva tale movimento (per il CSA e' in genere una fattura)
 | ||
| 	
 | ||
| 	TRecord_array doc(key, LF_RIGHEDOC);
 | ||
| 	for (int i = 1; i <= doc.rows(); i++)
 | ||
| 	{
 | ||
| 		const TRectype& rdoc = doc.row(i);
 | ||
| 		const TString& dacodnum = rdoc.get(RDOC_DACODNUM);
 | ||
| 		if (dacodnum.full())
 | ||
| 		{
 | ||
| 			const TRectype& num_rec = cache().get("%NUM", dacodnum);
 | ||
| 			if (num_rec.get_bool("B3"))
 | ||
| 			{
 | ||
| 				key = rdoc.get(RDOC_DAPROVV);
 | ||
| 				key.add(rdoc.get(RDOC_DAANNO));
 | ||
| 				key.add(dacodnum);
 | ||
| 				key.add(rdoc.get(RDOC_DANDOC));
 | ||
| 				//cerca da quale documento deriva la fattura (la prima riga che trova e' ok)
 | ||
| 				const TRectype& original_doc = cache().get(LF_DOC, key);
 | ||
| 				//se trova il documento origine (per il CSA e' in genere una FDR) -> prende il suo nreg..
 | ||
| 				//..come nreg da ritornare (attenzione che se il doc originale non e' stato contabilizzato..
 | ||
| 				//..nreg diventa 0!)
 | ||
| 				if (!original_doc.empty())
 | ||
|         {
 | ||
| 					nreg = original_doc.get_long(DOC_NUMREG);
 | ||
|         }
 | ||
| 			}
 | ||
| 			break;
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return nreg;
 | ||
| }
 | ||
| 
 | ||
| // oggetto che serve per memorizzare importo e flag acc/sal dei pagamenti..
 | ||
| //..(usato nel trasferimento pagamenti)
 | ||
| struct TPay_info : public TObject
 | ||
| {
 | ||
|   real _somma;
 | ||
|   char _as;
 | ||
| };
 | ||
| 
 | ||
| bool TInvioP::i_proforma_pagamenti()
 | ||
| {
 | ||
| 	TInvioP_file* trasfilepag = apri_file("pagament");
 | ||
| 	
 | ||
| 	TRectype da(LF_MOV);
 | ||
|   TRectype a(LF_MOV);
 | ||
|   da.put(MOV_DATAREG, _dataini);
 | ||
|   a.put(MOV_DATAREG, _datafin);
 | ||
|   TRelation rel(LF_MOV);
 | ||
| 	rel.add(LF_CAUSALI, "CODCAUS==CODCAUS");
 | ||
|   TCursor cur(&rel, "", 2, &da, &a);
 | ||
|   const long cur_items = cur.items();
 | ||
| 
 | ||
|   if (cur_items != 0) 
 | ||
|   { 
 | ||
| 		//se ha almeno un movimento carica lo sheet dei conti che gli servira' in seguito nel calcolo..
 | ||
| 		//..delle ritenute
 | ||
| 		lettura_conti(_fiscali, 'F');
 | ||
| 		lettura_conti(_sociali, 'S');
 | ||
| 		lettura_conti(_costi, 'C');
 | ||
| 		lettura_conti(_pagamenti, 'P');
 | ||
| 
 | ||
| 		TProgind pi(cur_items, "Trasferimento pagamenti...", true, true);
 | ||
| 
 | ||
| 	  cur.freeze();
 | ||
|     TRectype& cur_rec = cur.curr();
 | ||
|     for (cur = 0; cur.pos() < cur_items; ++(cur))
 | ||
| 		{
 | ||
| 			if (!pi.addstatus(1))
 | ||
|         break;
 | ||
| 
 | ||
| 			//pagamenti saldacontati! vedi l'else per quelli non saldacontati
 | ||
| 			const tipo_movimento tipomov = (tipo_movimento)cur_rec.get_int(MOV_TIPOMOV);
 | ||
| 			if (tipomov == tm_pagamento || tipomov == tm_nota_credito || tipomov == tm_pagamento_insoluto)
 | ||
| 			{
 | ||
|         //attraverso le partite,noto il MOV_NUMREG,riesce a collegarsi al pagamento in LF_PAGSCA
 | ||
| 				TRelation relpart(LF_PARTITE);
 | ||
| 				TRectype da(LF_PARTITE);
 | ||
| 				da.put(PART_NREG, cur_rec.get(MOV_NUMREG));
 | ||
| 				TCursor curpart(&relpart,	"", 2, &da, &da);
 | ||
| 				const long curpart_items = curpart.items();
 | ||
|         //se trova la partita relativa al numreg...
 | ||
| 				if (curpart_items != 0) 
 | ||
| 				{               
 | ||
| 					curpart.freeze();
 | ||
| 					TRectype& curpart_rec = curpart.curr();
 | ||
| 					TRelation relpag(LF_PAGSCA);
 | ||
| 					TRectype da(LF_PAGSCA);
 | ||
|           //..collega i pagamenti filtrando con i parametri estratti dalle partite
 | ||
| 					for (curpart = 0; curpart.pos() < curpart_items; ++(curpart))
 | ||
| 					{
 | ||
| 						da.put(PAGSCA_TIPOC, curpart_rec.get(PART_TIPOCF));
 | ||
| 						da.put(PAGSCA_GRUPPO, curpart_rec.get(PART_GRUPPO));
 | ||
| 						da.put(PAGSCA_CONTO, curpart_rec.get(PART_CONTO));
 | ||
| 						da.put(PAGSCA_SOTTOCONTO, curpart_rec.get(PART_SOTTOCONTO));
 | ||
| 						da.put(PAGSCA_ANNO, curpart_rec.get(PART_ANNO));
 | ||
| 						da.put(PAGSCA_NUMPART, curpart_rec.get(PART_NUMPART));
 | ||
| 						const int nrigapart = curpart_rec.get_int(PART_NRIGA);
 | ||
| 						TString80 filtro;
 | ||
| 						filtro.format("NRIGP == %d", nrigapart);
 | ||
| 						TCursor curpag(&relpag, filtro, 1, &da, &da);
 | ||
| 						const long curpag_items = curpag.items();
 | ||
| 
 | ||
|             real iva_indet = ZERO; //valore dell'eventuale iva indetraibile
 | ||
| 
 | ||
|             //se trova i pagamenti,che sono alla fin fine cio' che cerca...
 | ||
| 						if (curpag_items != 0) 
 | ||
| 						{  
 | ||
| 							TAssoc_array pagame;
 | ||
| 							pagame.destroy();
 | ||
| 							curpag.freeze();
 | ||
| 							TRectype& curpag_rec = curpag.curr();
 | ||
| 							for (curpag = 0; curpag.pos() < curpag_items; ++(curpag))
 | ||
| 							{
 | ||
| 								TString80 indice = curpag_rec.get(PAGSCA_ANNO);
 | ||
| 								indice << '|' << curpag_rec.get(PAGSCA_NUMPART);
 | ||
| 								indice << '|' << curpag_rec.get(PAGSCA_NRIGA);
 | ||
| 
 | ||
|                 TPay_info* pi = (TPay_info*)pagame.objptr(indice);
 | ||
|                 if (pi == NULL)
 | ||
|                 {
 | ||
|                   pi = new TPay_info;
 | ||
|                   pi->_as = 'A';
 | ||
|                   pagame.add(indice, pi);
 | ||
|                 }
 | ||
| 
 | ||
|                 //ricava l'importo del pagamento e lo aggiunge al memorizzatore
 | ||
| 								const real importo_pagato = calcola_pagamento(curpag_rec, iva_indet);
 | ||
| 								pi->_somma += importo_pagato;
 | ||
|                 if (curpag_rec.get_char(PAGSCA_ACCSAL) == 'S')
 | ||
|                   pi->_as = 'S';
 | ||
| 							}
 | ||
| 
 | ||
| 							// scrive i record risultanti
 | ||
| 							for (TPay_info* pi = (TPay_info*)pagame.first_item(); pi != NULL; pi = (TPay_info*)pagame.succ_item())
 | ||
| 							{
 | ||
| 								TToken_string keypart;
 | ||
| 								keypart.add(curpart_rec.get(PART_TIPOCF));
 | ||
| 								keypart.add(curpart_rec.get(PART_GRUPPO));
 | ||
| 								keypart.add(curpart_rec.get(PART_CONTO));
 | ||
| 								keypart.add(curpart_rec.get(PART_SOTTOCONTO));
 | ||
| 								keypart.add(pagame.get_hashobj()->key());
 | ||
| 								const TRectype& fattura = cache().get(LF_PARTITE, keypart);
 | ||
| 								_nregpag = cur_rec.get_long(MOV_NUMREG);  //registrazione del movimento di pagamento
 | ||
| 								//deve cercare la prima registrazione da cui deriva il pagamento..
 | ||
|                 const long nregfatt = fattura.get_long(PART_NREG);
 | ||
| 								_nregcosto = calcola_fattura_originale(nregfatt);
 | ||
|                 _importo = pi->_somma;
 | ||
|                 //acconto/saldo in modo standard
 | ||
|                 _accsal = pi->_as;
 | ||
|                 //Casino plutonico dell'acconto-saldo in ottica CSA
 | ||
|                 //Se il doc in esame discende da una FDR (fattura da ricevere) e' necessario..
 | ||
|                 //..cercare tutte le righe dei documenti che pagano tale FDR e sommare gli importi di tali..
 | ||
|                 //..rdocs con quello corrente; solo se tale somma risulatsse >= del totale delle righe..
 | ||
|                 //..della FDR originale il flag _accsal deve essere messo a saldo 'S'
 | ||
|                 if (_nregcosto != nregfatt)
 | ||
|                 {
 | ||
|                   //deve risalire al documento FDR del movimento _nregcosto
 | ||
| 	                const TRectype& mov_fdr = cache().get(LF_MOV, _nregcosto);
 | ||
| 
 | ||
| 	                const TString8 fdr_codnum = mov_fdr.get(MOV_DCODNUM);
 | ||
| 	                const int fdr_anno = mov_fdr.get_int(MOV_DANNO);
 | ||
| 	                const char fdr_provv = mov_fdr.get_char(MOV_DPROVV);
 | ||
| 	                const long fdr_ndoc = mov_fdr.get_long(MOV_DNDOC);
 | ||
| 
 | ||
|                   //adesso che ha la chiave del documento padre FDR, deve crearsi la query..
 | ||
|                   //..su RDOC alla ricerca di tutte le righe doc che discendono dall'FDR..
 | ||
|                   //..In pratica cerca le "sorelle" dell'attuale fattura nregfatt
 | ||
|                   TString query;
 | ||
|                   query << "USE RDOC KEY 4"; 
 | ||
|                   query << "\nFROM DACODNUM=" << fdr_codnum << " DAANNO=" << fdr_anno << " DAPROVV=" << fdr_provv << " DANDOC=" << fdr_ndoc;
 | ||
|                   query << "\nTO DACODNUM=" << fdr_codnum << " DAANNO=" << fdr_anno << " DAPROVV=" << fdr_provv << " DANDOC=" << fdr_ndoc;
 | ||
| 
 | ||
|                   TISAM_recordset recset(query);
 | ||
|                   const int righe_delle_sorelle = recset.items();
 | ||
|                   TAssoc_array sorelle;
 | ||
|                   TToken_string key;
 | ||
|                   //cerco la mia data di fattura;
 | ||
|                   const TDate datadoc_fattura = cache().get(LF_MOV, nregfatt, MOV_DATAREG);
 | ||
|                   //dalle righe risale ai documenti di tali righe (che posssono essere meno)
 | ||
|                   for (bool ok = recset.move_first(); ok; ok = recset.move_next())
 | ||
|                   {
 | ||
|                     key = recset.get(RDOC_PROVV).as_string();
 | ||
|                     key.add(recset.get(RDOC_ANNO).as_string());
 | ||
|                     key.add(recset.get(RDOC_CODNUM).as_string());
 | ||
|                     key.add(recset.get(RDOC_NDOC).as_string());
 | ||
|                     
 | ||
|                     const TDate datadoc = cache().get(LF_DOC, key, DOC_DATADOC);
 | ||
|                     //se non sono l'ultima fattura (sorella piu' giovane) allora e'..
 | ||
|                     //..sicuramente Acconto! Quindi esce dai cicli for e if
 | ||
|                     if (datadoc > datadoc_fattura)
 | ||
|                     {
 | ||
|                       sorelle.destroy();
 | ||
|                       _accsal = 'A';
 | ||
|                       break;
 | ||
|                     }
 | ||
|                     //accresce l'array delle sorelle
 | ||
|                     sorelle.add(key, key);
 | ||
|                   }
 | ||
|                   //tutto il casino s'ha da fare solo in caso ci sia piu' di una fattura..
 | ||
|                   //.."sorella" di quella in esame
 | ||
|                   if (sorelle.items() > 1)
 | ||
|                   {
 | ||
|                     real importo_totale_sorelle;
 | ||
|                     //giro su tutti i documenti delle sorelle
 | ||
|                     FOR_EACH_ASSOC_OBJECT(sorelle, obj, chiave, itm)
 | ||
|                     {
 | ||
|                       TToken_string& ts = *(TToken_string*)itm;
 | ||
|                       TDocumento sorella(ts.get_char(0), ts.get_int(1), ts.get(2), ts.get_long(3));
 | ||
|                       //per ogni documento deve cercare le righe discendenti dall'FDR
 | ||
|                       for (int r = 1; r <= sorella.rows(); r++)
 | ||
|                       {
 | ||
|                         const TRiga_documento nipotina = sorella[r];
 | ||
|                         //servono solo le righe discendenti dall'FDR madre!
 | ||
|                         if (nipotina.get(RDOC_DACODNUM) == fdr_codnum && nipotina.get_int(RDOC_DAANNO) == fdr_anno && 
 | ||
|                             nipotina.get_char(RDOC_DAPROVV) == fdr_provv && nipotina.get_long(RDOC_DANDOC) == fdr_ndoc)
 | ||
|                         {
 | ||
|                           const real importo_da_aggiungere = nipotina.importo(true, false); //importo scontato netto
 | ||
|                           importo_totale_sorelle += importo_da_aggiungere;
 | ||
|                         }
 | ||
|                       }
 | ||
|                     } //FOR_EACH_ASSOC..
 | ||
| 
 | ||
|                     //Se arriva fin qui la fattura in esame e' la sorella piu' giovane; adesso..
 | ||
|                     //..deve controllare se gli importi di tutte le sorelle sommati saldano..
 | ||
|                     //..o meno l'importo dell'originale mamma FDR...
 | ||
| 
 | ||
|                     //intanto ha bisogno del totale documento FDR originale a partire dal movimento FDR...
 | ||
|                     real totale_fdr = ZERO;
 | ||
|                     TMovimentoPN movimento_fdr;
 | ||
|                     movimento_fdr.curr().put(MOV_NUMREG, _nregcosto);
 | ||
| 	                  if (movimento_fdr.read() == NOERR)
 | ||
|                       totale_fdr = totale_documento(movimento_fdr, false);  //non include ritenute
 | ||
|                     
 | ||
|                     real rimanenza = totale_fdr - importo_totale_sorelle;
 | ||
|                     //arrotonda
 | ||
|                     rimanenza.round();
 | ||
| 
 | ||
|                     //Se l'importo e' inferiore la FDR non e' ancora stata saldata (nasceranno..
 | ||
|                     //..una o piu' sorelle per saldare mamma FDR in futuro)
 | ||
|                     if (rimanenza > ZERO)
 | ||
|                       _accsal = 'A';
 | ||
|                     //Se l'importo e' >= -> la mamma e' saldata e non sono previste ulteriori..
 | ||
|                     //..sorelle (per la felicita' del papa'!)
 | ||
|                     else
 | ||
|                       _accsal = 'S';
 | ||
| 
 | ||
|                   } //if(sorelle.items()>1..
 | ||
|        
 | ||
|                 } //if(_nregcosto!=nregfatt..
 | ||
|                 //..e finalmente scrive 'sta minchia di riga
 | ||
| 								TRecord_text recpag;
 | ||
| 								recpag.set_type("G");
 | ||
| 								trasfilepag->autoload(recpag, curpag); 
 | ||
| 								trasfilepag->write(recpag);
 | ||
| 
 | ||
| 								//se ha una riga di iva indetraibile dovuta al cambio regime fiscale 2005->2006..
 | ||
|                 //..deve aggiungere una ulteriore riga!!
 | ||
|                 if (iva_indet > ZERO)
 | ||
|                 {
 | ||
|                   _nregcosto = nregfatt;
 | ||
|                   _importo = iva_indet;
 | ||
|                   _accsal = 'S';
 | ||
|                   recpag.set_type("G");
 | ||
| 								  trasfilepag->autoload(recpag, curpag); 
 | ||
| 								  trasfilepag->write(recpag);
 | ||
|                 }
 | ||
| 							} //for(
 | ||
| 
 | ||
| 						}//if curpag_items..
 | ||
| 					}//for curpart =..
 | ||
| 				}//if curpart_items..
 | ||
| 
 | ||
| 			}//if tipomov ==..
 | ||
| 			if (tipomov == tm_nessuno)	//tocca ai pagamenti NON saldacontati (procedura analoga a quella della stampa del pagato)
 | ||
| 			{
 | ||
| 				const long numregcg = cur_rec.get_long(MOV_NUMREG);
 | ||
| 
 | ||
| 				//cerca un record di MOVANA che abbia numregcg = nreg;usa il nuovo metodo fighissimo..
 | ||
| 				//..con la isam query
 | ||
| 				TString& query = get_tmp_string();
 | ||
| 				query << "USE MOVANA KEY 3\n";
 | ||
| 				query << "FROM NUMREGCG=" << numregcg << "\n";
 | ||
| 				query << "TO NUMREGCG=" << numregcg;
 | ||
| 
 | ||
| 				TISAM_recordset movana(query);
 | ||
| 				const TRecnotype items = movana.items();
 | ||
| 
 | ||
| 				if (items > 0)
 | ||
| 				{
 | ||
| 					if (items > 1)
 | ||
| 						error_box(TR("Esiste piu' di un movimento analitico collegato al movimento contabile %ld"),numregcg);
 | ||
| 
 | ||
| 					movana.move_last();	//si posiziona sul record corretto
 | ||
| 
 | ||
| 					//crea il movana legato al mov
 | ||
| 					const TAnal_mov anal_mov(cur_rec);
 | ||
| 					const TRecord_array& anal_rows = anal_mov.body();
 | ||
| 
 | ||
| 					for (int j = 1; j <= anal_rows.rows(); j++)	//scansiona righe analitiche..
 | ||
| 					{
 | ||
| 						const TRectype& anal_row = anal_rows[j];
 | ||
| 
 | ||
| 						//prende il conto sulla riga analitica e lo confronta con quelli della configurazione
 | ||
| 						const TString& conto_riga_analitica = anal_row.get(RMOVANA_CODCONTO);
 | ||
| 						const int gruppo_anal = atoi(conto_riga_analitica.left(3)); 
 | ||
| 						const int conto_anal = atoi(conto_riga_analitica.mid(3,3));
 | ||
| 						const long sottoconto_anal = atol(conto_riga_analitica.mid(6,6));
 | ||
| 
 | ||
| 						const TBill conto(gruppo_anal, conto_anal, sottoconto_anal);
 | ||
| 						int tipo = cerca_costo(conto) || cerca_pagamento(conto);
 | ||
| 						if (tipo > 0)
 | ||
| 						{
 | ||
| 							const char sezione = anal_row.get_char(RMOVANA_SEZIONE);
 | ||
| 							const real valore = anal_row.get_real(RMOVANA_IMPORTO);
 | ||
| 							TImporto imp(sezione, valore);
 | ||
| 
 | ||
| 							switch (tipo)
 | ||
| 							{
 | ||
| 							case 1:imp.normalize('D');break;
 | ||
| 							case 2:imp.normalize('A');break;
 | ||
| 							default:break;
 | ||
| 							}
 | ||
| 							_nregpag = numregcg;
 | ||
| 							_nregcosto = numregcg;
 | ||
| 							_importo = imp.valore();
 | ||
|               //deve stabilire adesso se acconto o saldo controllando gli importi
 | ||
|               _accsal = 'S';
 | ||
| 
 | ||
| 							//e finalmente aggiunge il record al file di esportazione
 | ||
| 							TRecord_text recpag;
 | ||
| 							recpag.set_type("G");
 | ||
| 							trasfilepag->autoload(recpag, *movana.cursor()); 
 | ||
| 							trasfilepag->write(recpag);
 | ||
| 						} //if (tipo > 0..
 | ||
| 
 | ||
| 					}	//for(j<anal_rows...
 | ||
| 				}	//if(items>0...
 | ||
| 
 | ||
| 			}	//else if tipomov ==..
 | ||
| 			
 | ||
| 		}//for cur =..
 | ||
| 	}//if cur_items..
 | ||
| 
 | ||
| 	chiudi_file(trasfilepag);
 | ||
| 	return true;
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::i_proforma_clifor(char tipocf)
 | ||
| {
 | ||
| 	TInvioP_file* trasfile = NULL;
 | ||
| 
 | ||
| 	TString progind_string = "Trasferimento ";
 | ||
| 
 | ||
| 	if (tipocf == 'C')
 | ||
| 	{
 | ||
| 		trasfile = apri_file("clienti");
 | ||
| 		progind_string << "clienti";
 | ||
| 	}
 | ||
| 	else
 | ||
| 	{
 | ||
| 		trasfile = apri_file("fornit");
 | ||
| 		progind_string << "fornitori";
 | ||
| 	}
 | ||
| 	
 | ||
|   TString80 filtro = "";
 | ||
| 	filtro.format("TIPOCF == \"%c\"", tipocf);
 | ||
| 	TRelation rel(LF_CLIFO);
 | ||
|   rel.add(LF_COMUNI, "STATO==STATOCF|COM==COMCF", 1);
 | ||
|   TCursor cur(&rel, filtro);
 | ||
|   const long cur_items = cur.items();
 | ||
| 
 | ||
|   if (cur_items != 0) 
 | ||
|   {
 | ||
| 		progind_string << "...";
 | ||
| 		TProgind pi(cur_items, progind_string, true, true);
 | ||
| 
 | ||
| 	  cur.freeze();
 | ||
|     TRectype& cur_rec = cur.curr();
 | ||
|     for (cur = 0; cur.pos() < cur_items; ++(cur))
 | ||
|     {
 | ||
| 			pi.addstatus(1);
 | ||
|       if (pi.iscancelled())
 | ||
|         break;
 | ||
| 
 | ||
| 			TRecord_text rec;
 | ||
| 			rec.set_type("C");
 | ||
| 			trasfile->autoload(rec, cur); 
 | ||
| 			trasfile->write(rec);
 | ||
|     }	
 | ||
|   }                  
 | ||
| 	chiudi_file(trasfile);
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| //"metodo dei metodi":in base ai parametri della maschera esegue la procedura indicata
 | ||
| void TInvioP::invio_proforma()
 | ||
| {
 | ||
| 	if (_msk->get_bool(F_MOVIMENTI))
 | ||
| 		i_proforma_movimenti();
 | ||
| 	if (_msk->get_bool(F_PAGAMENTI))
 | ||
| 		i_proforma_pagamenti();
 | ||
| 	if (_msk->get_bool(F_CLIENTI))
 | ||
| 		i_proforma_clifor();
 | ||
| 	if (_msk->get_bool(F_FORNITORI))
 | ||
| 		i_proforma_clifor('F');
 | ||
| 	if (_msk->get_bool(F_CONTI))
 | ||
| 		i_proforma_conti();
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::create()
 | ||
| {               
 | ||
|   _msk = new TInvioP_mask();
 | ||
| 	_configfile = new TConfig("tc9100a.ini");
 | ||
|   return TSkeleton_application::create();
 | ||
| }
 | ||
| 
 | ||
| bool TInvioP::destroy()
 | ||
| {             
 | ||
| 	if (_configfile != NULL)
 | ||
| 		delete _configfile;
 | ||
|   delete _msk;
 | ||
| 
 | ||
|   return TSkeleton_application::destroy();
 | ||
| }
 | ||
| 
 | ||
| void TInvioP::main_loop()
 | ||
| {
 | ||
| 	//il programma si puo' usare SOLO se in contabilita' analitica si usa il piano dei conti contabile
 | ||
| 	TConfig& cfg = ca_config();
 | ||
| 	const bool use_pdcc = cfg.get_bool("UsePdcc");
 | ||
| 	if (!use_pdcc)
 | ||
| 	{
 | ||
| 		error_box(TR("Programma funzionante SOLO se in contabilita' analitica si usa il piano dei conti contabile"));
 | ||
| 		return;
 | ||
| 	}
 | ||
| 
 | ||
| 	TFilename configname = "tc9100conf.ini";	//file configurazione della maschera
 | ||
| 	configname.custom_path();
 | ||
| 	TConfig configfile(configname);
 | ||
| 	_msk->set(F_DATAINI, configfile.get("DATA","OPZIONI"));
 | ||
| 	_msk->set(F_DESTINAZIONE, configfile.get("PERCORSO","OPZIONI"));
 | ||
| 
 | ||
|   while (_msk->run()!=K_QUIT)
 | ||
|   {                                  
 | ||
|   	configfile.set("DATA", _msk->get_date(F_DATAFIN),"OPZIONI");
 | ||
|   	configfile.set("PERCORSO", _msk->get(F_DESTINAZIONE),"OPZIONI");
 | ||
|   	_dataini = _msk->get_date(F_DATAINI);
 | ||
|   	_datafin = _msk->get_date(F_DATAFIN);
 | ||
| 		const char tipoinvio = _msk->get(F_TIPOINVIO)[0];
 | ||
| 		if (tipoinvio == 'P')
 | ||
| 			invio_proforma();		//dopo aver preso i parametri dalla maschera chiama il "metodo dei metodi"
 | ||
| 	}	
 | ||
| }
 | ||
| 
 | ||
| int tc9100(int argc, char **argv) 
 | ||
| {
 | ||
|   TInvioP a;
 | ||
|   a.run(argc, argv, "Invio dati contabilit<69> a Proforma");
 | ||
| 
 | ||
|   return 0;
 | ||
| }
 |