Files correlati : Ricompilazione Demo : [ ] Commento :correzioni dovute al passaggio al nuovo compilatore git-svn-id: svn://10.65.10.50/trunk@14698 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1230 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1230 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						||
#include <defmask.h>
 | 
						||
#include <execp.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <reprint.h>
 | 
						||
 | 
						||
#include <clifo.h>
 | 
						||
#include <mov.h>
 | 
						||
#include <partite.h>
 | 
						||
#include <rmov.h>
 | 
						||
#include <rmoviva.h>
 | 
						||
 | 
						||
#include "..\cg\cgsaldac.h"
 | 
						||
#include "..\cg\cg2101.h"
 | 
						||
#include "..\cg\cg2103.h"
 | 
						||
 | 
						||
#include "pconana.h"
 | 
						||
#include "movana.h"
 | 
						||
#include "rmovana.h"
 | 
						||
 | 
						||
#include "ca3.h"
 | 
						||
#include "ca3600.h"
 | 
						||
#include "calib01.h"
 | 
						||
#include "calib02.h"
 | 
						||
#include "camask.h"
 | 
						||
 | 
						||
 | 
						||
//===============================================================================================
 | 
						||
////////////////////////////////////////////////////////
 | 
						||
//	MASCHERA 
 | 
						||
////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TPag_per_cms_mask: public TAnal_report_mask
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						||
	const TString& get_report_class() const; 
 | 
						||
  bool test_compatible_report();
 | 
						||
 | 
						||
	//pagina di configurazione
 | 
						||
	void config_loader(TSheet_field& sf, const char* paragrafo);
 | 
						||
  void config_setter(TSheet_field& sf, const char* paragrafo);
 | 
						||
 | 
						||
public:
 | 
						||
  TPag_per_cms_mask();
 | 
						||
	virtual ~TPag_per_cms_mask() {}
 | 
						||
 | 
						||
};
 | 
						||
 | 
						||
const TString& TPag_per_cms_mask::get_report_class() const
 | 
						||
{
 | 
						||
  TString& classe = get_tmp_string();
 | 
						||
  classe = "ca3600a";
 | 
						||
  return classe;
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_mask::test_compatible_report()
 | 
						||
{
 | 
						||
	const TString& cls = get_report_class();
 | 
						||
  const TString& name = get(F_REPORT);
 | 
						||
  bool ok = name.not_empty();
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    TReport rep; 
 | 
						||
    ok = rep.load(name);
 | 
						||
    if (ok)
 | 
						||
    {
 | 
						||
      const TString& classe = rep.get_class();
 | 
						||
      ok = classe == cls;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  if (!ok)
 | 
						||
  {
 | 
						||
    set(F_REPORT, cls);
 | 
						||
		TFilename path = cls;
 | 
						||
    path.ext("rep");
 | 
						||
    ok = path.custom_path();
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						||
{
 | 
						||
  switch (o.dlg())
 | 
						||
  {
 | 
						||
		case F_REPORT:
 | 
						||
			if (e == fe_button)
 | 
						||
			{
 | 
						||
				const TString8 lib = get_report_class();
 | 
						||
				TFilename path = o.get();
 | 
						||
				if (select_custom_file(path, "rep", lib))
 | 
						||
				{
 | 
						||
					path = path.name();
 | 
						||
					path.ext("");
 | 
						||
					o.set(path);
 | 
						||
				}
 | 
						||
			} else
 | 
						||
			if (e == fe_close)
 | 
						||
			{
 | 
						||
				if (!test_compatible_report())
 | 
						||
					return error_box(TR("Impossibile trovare un report compatibile"));
 | 
						||
			}
 | 
						||
			break;
 | 
						||
		case DLG_SAVEREC:
 | 
						||
			if (e == fe_button)
 | 
						||
			{
 | 
						||
				config_setter(sfield(F_PDCC), "Pdcc");
 | 
						||
//				config_setter(sfield(F_PDCA), "Pdca");	***per ora solo Pdcc***
 | 
						||
			}
 | 
						||
			break;
 | 
						||
    default: 
 | 
						||
      break;
 | 
						||
  }
 | 
						||
  return TAnal_report_mask::on_field_event(o, e, jolly);
 | 
						||
}
 | 
						||
 | 
						||
TPag_per_cms_mask::TPag_per_cms_mask()
 | 
						||
								:TAnal_report_mask("ca3600")
 | 
						||
{
 | 
						||
	//Prima pagina
 | 
						||
	// creazione dei campi della pagina della maschera con lo sheet di cdc/cms/fasi
 | 
						||
	create_sheet(F_RIGHE);
 | 
						||
 | 
						||
	//carica i parametri dei conti per lo sheet dei conti contabili
 | 
						||
	config_loader(sfield(F_PDCC), "Pdcc");
 | 
						||
	// setta gli handlers a tutti i campi generati della maschera;senza questa chiamata la on_field_event
 | 
						||
	// non puo' funzionare sui campi generati!!!
 | 
						||
	set_handlers();
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_mask::config_loader(TSheet_field& sf, const char* paragrafo)
 | 
						||
{
 | 
						||
	TFilename configname = "ca3600a.ini";	//carica file configurazione conti
 | 
						||
	configname.custom_path();
 | 
						||
	TConfig configfile(configname, paragrafo);
 | 
						||
 | 
						||
  TString_array conti;
 | 
						||
 | 
						||
  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);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_mask::config_setter(TSheet_field& sf, const char* paragrafo)
 | 
						||
{
 | 
						||
	TFilename configname = "ca3600a.ini";	//carica file configurazione conti
 | 
						||
	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));		//*****nel caso di pdca deve tener conto dei livelli variabili
 | 
						||
 | 
						||
    configfile.set("conto", conto, NULL, true, i);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////////
 | 
						||
//	RECORDSET 
 | 
						||
///////////////////////////////////////////////////////////////
 | 
						||
class TPag_per_cms_recordset : public TISAM_recordset
 | 
						||
{
 | 
						||
	TExternisamfile* _tmp;
 | 
						||
 | 
						||
protected:
 | 
						||
  TDate _dadata, _adata;
 | 
						||
	long _dacodfor, _acodfor;
 | 
						||
	TString16 _campodata;
 | 
						||
  TString _codcosto, _codcms, _codfas;
 | 
						||
	TAssoc_array _costi,_pagamenti,_fiscali,_sociali; //array che contengono i conti letti dal .ini
 | 
						||
 | 
						||
	
 | 
						||
protected:	//da libreria
 | 
						||
	virtual const TVariant& get(const char* column_name) const;
 | 
						||
 | 
						||
protected:
 | 
						||
	void crea_trr(const TFilename& trr) const;
 | 
						||
	static bool part_callback(const TRelation& rel, void* pJolly);
 | 
						||
  static bool mov_callback(const TRelation& rel, void* pJolly);
 | 
						||
	long find_movimento(const TRectype& riga_pag) const;
 | 
						||
	void find_commesse(const long nreg, const TRectype& riga_pag);
 | 
						||
	void find_commesse_cg(const TRectype& mov);
 | 
						||
	bool check_cms_cdc_fsc(const TRectype& rec_analriga);
 | 
						||
	const TString& query_movama_by_numregcg(const long nreg);
 | 
						||
	void lettura_conti(TAssoc_array& assoc, const char tipoconto);
 | 
						||
	int cerca_riga_fattura_origine(const TPartita& match, const TRectype& riga_pag);
 | 
						||
	real totale_documento(const TRectype& mov) const;
 | 
						||
	real calcola_pagato_prec(const TPartita& match, const int riga_fatt, const TRectype& riga_pag);
 | 
						||
  bool test_swap(TCausale& caus, bool ritsoc) const;
 | 
						||
	bool cerca_conto(const char tipo, const TBill& bill, const TAssoc_array& assoc) const;
 | 
						||
  int cerca_costo(const TBill& bill) const;
 | 
						||
  int cerca_pagamento(const TBill& bill) const;
 | 
						||
  bool cerca_fiscali(const TBill& bill) const;
 | 
						||
  bool cerca_sociali(const TBill& bill) const;
 | 
						||
 | 
						||
public:
 | 
						||
  virtual void set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata);
 | 
						||
	virtual void set_custom_filter(TCursor& cur) const;
 | 
						||
	void scan_pags();
 | 
						||
	void scan_movs();
 | 
						||
 | 
						||
  TPag_per_cms_recordset(const TString& sql) : TISAM_recordset(sql) { _tmp = NULL;}
 | 
						||
	~TPag_per_cms_recordset();
 | 
						||
};
 | 
						||
 | 
						||
//////////////////////////////////
 | 
						||
//	generica
 | 
						||
//////////////////////////////////
 | 
						||
static TPag_per_cms_recordset* myself = NULL;
 | 
						||
 | 
						||
TPag_per_cms_recordset::~TPag_per_cms_recordset() 
 | 
						||
{ }
 | 
						||
 | 
						||
 | 
						||
void TPag_per_cms_recordset::set_custom_filter(TCursor& cur) const
 | 
						||
{
 | 
						||
	relation()->replace(_tmp);	//sostituisce il vero file rmovana con quello temporaneo
 | 
						||
 | 
						||
	//filtro sul file esterno (_tmp, cio<69> 1000) sui conti selezionati sulla maschera
 | 
						||
	TRectype darec(cur.curr()), arec(cur.curr());	//curr perch<63> <20> il file externisamfile
 | 
						||
	darec.zero();
 | 
						||
	arec.zero();
 | 
						||
 | 
						||
	//filtro sulla data(non avendo anche codnum non ho la chiave completa per mettere la data nella setregion)
 | 
						||
	TString filtro;
 | 
						||
	TString80 f;
 | 
						||
	if (_dadata.ok())
 | 
						||
	{
 | 
						||
		f.format("(ANSI(%s)>=\"%s\")", (const char*)_campodata, _dadata.string(ANSI));
 | 
						||
		filtro << f;
 | 
						||
	}
 | 
						||
	if (_adata.ok())
 | 
						||
	{
 | 
						||
		if (filtro.not_empty())
 | 
						||
			filtro << "&&";
 | 
						||
    f.format("(ANSI(%s)<=\"%s\")", (const char*)_campodata, _adata.string(ANSI));
 | 
						||
    filtro << f;
 | 
						||
	}
 | 
						||
 | 
						||
	cur.setregion(darec, arec);
 | 
						||
	cur.setfilter(filtro);
 | 
						||
 | 
						||
  myself = (TPag_per_cms_recordset*)this;
 | 
						||
}
 | 
						||
 | 
						||
//simpatico metodo per riempire in automatico i campi di intestazione speciali
 | 
						||
const TVariant& TPag_per_cms_recordset::get(const char* column_name) const
 | 
						||
{
 | 
						||
 | 
						||
	if (*column_name == '#')
 | 
						||
	{
 | 
						||
		if (strcmp(column_name, "#COSTO") == 0)
 | 
						||
		{
 | 
						||
			TVariant& var = get_tmp_var();
 | 
						||
			var = _codcosto;
 | 
						||
			return var;
 | 
						||
		}
 | 
						||
		if (strcmp(column_name, "#COMMESSA") == 0)
 | 
						||
		{
 | 
						||
			TVariant& var = get_tmp_var();
 | 
						||
			var = _codcms;
 | 
						||
			return var;
 | 
						||
		}
 | 
						||
		if (strcmp(column_name, "#FASE") == 0)
 | 
						||
		{
 | 
						||
			TVariant& var = get_tmp_var();
 | 
						||
			var = _codfas;
 | 
						||
			return var;
 | 
						||
		}
 | 
						||
	}
 | 
						||
  return TISAM_recordset::get(column_name);
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_recordset::crea_trr(const TFilename& trr) const
 | 
						||
{
 | 
						||
	TString chiave;
 | 
						||
	ofstream of(trr);
 | 
						||
	of << 1000 << endl;
 | 
						||
	of << 16 << endl;
 | 
						||
	of << "CODFORN|3|6|0|Codice fornitore" << endl;
 | 
						||
	of << "DESFORN|1|50|0|Descrizione fornitore" << endl;
 | 
						||
	of << "NREG|3|7|0|Numero registrazione" << endl;
 | 
						||
	of << "DATAREG|5|8|0|Data registrazione" << endl;
 | 
						||
	of << "DATAPAG|5|8|0|Data pagamento" << endl;
 | 
						||
	of << "DESCRPAG|1|50|0|Descrizione pagamento" << endl;
 | 
						||
	of << "NDOC|1|6|0|Numero documento" << endl;
 | 
						||
	of << "DATADOC|5|8|0|Data documento" << endl;
 | 
						||
	of << "PROT|2|5|0|Protocollo iva" << endl;
 | 
						||
	of << "TOTDOC|4|18|5|Totale documento" << endl;
 | 
						||
	of << "TOTPAG|4|18|5|Totale pagamento" << endl;
 | 
						||
	of << "TOTRES|4|18|5|Totale residuo" << endl;
 | 
						||
	of << "CDC|1|20|0|Centro di costo" << endl;
 | 
						||
	of << "CMS|1|20|0|Commessa" << endl;
 | 
						||
	of << "FSC|1|10|0|Fase"  << endl;
 | 
						||
	of << "HIDDEN|8|1|0|Record nascosto" << endl;
 | 
						||
	of << 1 << endl;
 | 
						||
	//l'ordinamento dipende dal tipo di data selezionato sulla maschera
 | 
						||
	chiave << "CODFORN+FSC+NREG+";
 | 
						||
	chiave << _campodata;
 | 
						||
	of << chiave << endl;
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_recordset::lettura_conti(TAssoc_array& assoc, const char tipoconto)
 | 
						||
{
 | 
						||
  TConfig conti("ca3600a.ini","Pdcc"); //paragrafo da scandire nell'ini (solo conti contabili!!)
 | 
						||
  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);
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_recordset::cerca_conto(const char tipo, const TBill& bill, const TAssoc_array& assoc) const
 | 
						||
{
 | 
						||
  TToken_string key(15);
 | 
						||
 | 
						||
	key.add(tipo);
 | 
						||
 | 
						||
  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 TPag_per_cms_recordset::cerca_costo(const TBill& bill) const
 | 
						||
{
 | 
						||
  if (cerca_conto('C', bill, _costi))
 | 
						||
		return 1;
 | 
						||
	else
 | 
						||
		return 0;
 | 
						||
}
 | 
						||
 | 
						||
int TPag_per_cms_recordset::cerca_pagamento(const TBill& bill) const
 | 
						||
{
 | 
						||
  if (cerca_conto('P', bill, _pagamenti))
 | 
						||
		return 2;
 | 
						||
	else
 | 
						||
		return 0;
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_recordset::cerca_fiscali(const TBill& bill) const
 | 
						||
{
 | 
						||
  return cerca_conto('F', bill, _fiscali);
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_recordset::cerca_sociali(const TBill& bill) const
 | 
						||
{
 | 
						||
  return cerca_conto('S', bill, _sociali);
 | 
						||
}
 | 
						||
 | 
						||
// Controlla sulla causale se il segno del totale documento (ritsoc=FALSE) 
 | 
						||
// o quello delle ritenute sociali (ritsoc=TRUE) e' invertito rispetto al normale
 | 
						||
bool TPag_per_cms_recordset::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;
 | 
						||
}
 | 
						||
 | 
						||
// Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle
 | 
						||
// ritenute sociali sulla causale                        
 | 
						||
real TPag_per_cms_recordset::totale_documento(const TRectype& mov) const
 | 
						||
{
 | 
						||
  real tot = mov.get_real(MOV_TOTDOC);              // Legge totale
 | 
						||
  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;
 | 
						||
  }
 | 
						||
 | 
						||
  return tot;
 | 
						||
}
 | 
						||
 | 
						||
int TPag_per_cms_recordset::cerca_riga_fattura_origine(const TPartita& match, const TRectype& riga_pag)
 | 
						||
{
 | 
						||
  //scansione delle righe partita passata, precedenti alla riga_pag
 | 
						||
  const int k = riga_pag.get_int(PART_NRIGA);
 | 
						||
  for (int i = match.pred(k); i > 0; i = match.pred(i))
 | 
						||
  {
 | 
						||
    const TRiga_partite& riga_part = match.riga(i);
 | 
						||
    if (riga_part.is_fattura())
 | 
						||
    {
 | 
						||
      for (int j = riga_part.rate(); j > 0; j--)
 | 
						||
      {
 | 
						||
        if (match.esiste(i, j, k)) //se esiste il pagamento k della rata j della riga partita i contenente la fattura
 | 
						||
          return i;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return 0;
 | 
						||
}
 | 
						||
 | 
						||
real TPag_per_cms_recordset::calcola_pagato_prec(const TPartita& match, const int riga_fatt, const TRectype& riga_pag)
 | 
						||
{
 | 
						||
  real pagato = ZERO;
 | 
						||
  if (riga_fatt > 0)
 | 
						||
  {
 | 
						||
    const int k = riga_pag.get_int(PART_NRIGA);
 | 
						||
    const TDate data_rif = riga_pag.get(_campodata);  //data di riferimento selezionata sulla maschera 
 | 
						||
 | 
						||
    const TRiga_partite& riga_part = match.riga(riga_fatt);
 | 
						||
    for (int i = riga_part.rate(); i > 0; i--)
 | 
						||
    {
 | 
						||
      TRiga_scadenze& sc = riga_part.rata(i);
 | 
						||
      for (int j = sc.last(); j > 0; j = sc.pred(j))
 | 
						||
      {
 | 
						||
        const TRiga_partite& pag = match.riga(j);
 | 
						||
        const TDate datapag = pag.get_date(_campodata);
 | 
						||
        const long cmp = datapag - data_rif;
 | 
						||
        //la riga pagamento e' da considerare quando ha data anteriore a quella di riferimento oppur
 | 
						||
        //ha data uguale ma numero di registrazione inferiore (insomma, il pagamento e' precedente
 | 
						||
        //a quello di riga_pag)
 | 
						||
        if (cmp < 0 || (cmp == 0 && j <= k))
 | 
						||
        {
 | 
						||
          pagato += pag.get_real(PAGSCA_IMPORTO);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return pagato;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
/////////////////////////////////////
 | 
						||
//	movimenti senza saldaconto
 | 
						||
/////////////////////////////////////
 | 
						||
long TPag_per_cms_recordset::find_movimento(const TRectype& riga_pag) const
 | 
						||
{
 | 
						||
  int n_fatture = 0;  //numero di fatture trovate
 | 
						||
  int first_fatt = 0; //numero riga della prima fattura
 | 
						||
//scan della partita dall'ultima alla prima riga
 | 
						||
  const TPartita partita(riga_pag);
 | 
						||
  for (int p = partita.last(); p > 0; p = partita.pred(p))
 | 
						||
  {
 | 
						||
    const TRiga_partite& fatt = partita.riga(p);
 | 
						||
    if (fatt.is_fattura())
 | 
						||
    {
 | 
						||
      n_fatture++;
 | 
						||
      first_fatt = p;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (n_fatture > 1)
 | 
						||
  {
 | 
						||
    const int linea_pag = riga_pag.get_int(PART_NRIGA);
 | 
						||
    int linea_fattura = 0;
 | 
						||
    for (int f = first_fatt; (f > 0) && (f <= partita.last()) && (linea_fattura == 0); f = partita.succ(f))
 | 
						||
    {
 | 
						||
      const TRiga_partite& fatt = partita.riga(f);
 | 
						||
      if (fatt.is_fattura())
 | 
						||
      {
 | 
						||
        for (int r = 1; r <= fatt.rate(); r++)
 | 
						||
        {
 | 
						||
          const TRiga_scadenze& rata = fatt.rata(r);
 | 
						||
          if (rata.exist(linea_pag))
 | 
						||
          {
 | 
						||
            linea_fattura = f;
 | 
						||
            break;
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (linea_fattura > 0) // oppure anche (linea_fattura > first_fatt)
 | 
						||
      first_fatt = linea_fattura;
 | 
						||
  }
 | 
						||
 | 
						||
  long nreg = 0;
 | 
						||
  if (first_fatt > 0)
 | 
						||
  {
 | 
						||
    const TRiga_partite& fatt = partita.riga(first_fatt);
 | 
						||
    nreg = fatt.get_long(PART_NREG);
 | 
						||
  }
 | 
						||
 | 
						||
  return nreg;
 | 
						||
}
 | 
						||
 | 
						||
//prepara gli oggetti (_righecosti,_righepagamenti) contenenti le righe dei pagamenti.. 
 | 
						||
//..senza saldaconto
 | 
						||
void TPag_per_cms_recordset::find_commesse_cg(const TRectype& mov)
 | 
						||
{
 | 
						||
	const long numregcg = mov.get_long(MOV_NUMREG);
 | 
						||
 | 
						||
	//cerca un record di MOVANA che abbia numregcg = nreg;usa il nuovo metodo fighissimo..
 | 
						||
	//..con la isam query implementato nella query_movama_by_numregcg()
 | 
						||
	TISAM_recordset movana(query_movama_by_numregcg(numregcg));
 | 
						||
	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
 | 
						||
		//prepara il record tmpcurr sul file temporaneo _tmp su cui registrare i dati da stampare
 | 
						||
		TRectype& tmpcurr = _tmp->curr();
 | 
						||
		tmpcurr.zero();
 | 
						||
 | 
						||
		//crea il movana legato al mov
 | 
						||
		const TAnal_mov anal_mov(mov);
 | 
						||
		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];
 | 
						||
			if (check_cms_cdc_fsc(anal_row))
 | 
						||
			{
 | 
						||
				//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;
 | 
						||
					//case 3:imp.normalize('D');break;
 | 
						||
					//case 4:imp.normalize('A');break;
 | 
						||
					default:break;
 | 
						||
					}
 | 
						||
 | 
						||
					//deve aggiungere ora al file temporaneo il record
 | 
						||
					//codice fornitore e descrizione
 | 
						||
					const long codforn = mov.get_long(MOV_CODCF);
 | 
						||
					if (codforn > 0)
 | 
						||
					{
 | 
						||
						tmpcurr.put("CODFORN", codforn);
 | 
						||
						TString16 keyclifo;
 | 
						||
						keyclifo.format("F|%ld", codforn);
 | 
						||
						const TRectype& rec_clifo = cache().get(LF_CLIFO, keyclifo);
 | 
						||
						tmpcurr.put("DESFORN", rec_clifo.get(CLI_RAGSOC));
 | 
						||
					}
 | 
						||
 | 
						||
					//nreg,data pagamento,descrizione pagamento
 | 
						||
					tmpcurr.put("NREG", numregcg);
 | 
						||
					tmpcurr.put("DATAREG", mov.get_date(MOV_DATAREG));
 | 
						||
					tmpcurr.put("DATAPAG", mov.get_date(MOV_DATACOMP));
 | 
						||
 | 
						||
					//documento origine
 | 
						||
					tmpcurr.put("NDOC", mov.get_long(MOV_NUMDOC));
 | 
						||
					tmpcurr.put("DATADOC", movana.get(MOV_DATADOC).as_date());
 | 
						||
					tmpcurr.put("TOTDOC", movana.get(MOV_TOTDOC).as_real());
 | 
						||
 | 
						||
					//importi
 | 
						||
					tmpcurr.put("TOTPAG", imp.valore());
 | 
						||
					//tmpcurr.put("TOTRES", );	//pagamenti precedenti al
 | 
						||
 | 
						||
					//campi relativi a cdc,commessa,fase
 | 
						||
					tmpcurr.put("CMS",anal_row.get(RMOVANA_CODCMS));
 | 
						||
					tmpcurr.put("CDC",anal_row.get(RMOVANA_CODCCOSTO));
 | 
						||
					tmpcurr.put("FSC",anal_row.get(RMOVANA_CODFASE));
 | 
						||
 | 
						||
					//e finalmente aggiunge il record al file temporaneo
 | 
						||
					_tmp->write();
 | 
						||
				}
 | 
						||
			}
 | 
						||
		}	//for(j<anal_rows...
 | 
						||
	}	//if(items>0...
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_recordset::mov_callback(const TRelation& rel, void* pJolly)
 | 
						||
{
 | 
						||
  TPag_per_cms_recordset* recordset = (TPag_per_cms_recordset*)pJolly;
 | 
						||
  recordset->find_commesse_cg(rel.curr());
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_recordset::scan_movs()
 | 
						||
{
 | 
						||
  if (_campodata == PART_DATAPAG)  // I movimenti non hanno DATAPAG
 | 
						||
    _campodata = MOV_DATAREG;
 | 
						||
 | 
						||
  TString filtro = "(REG==\"\")&&(TIPOMOV==\"\")";
 | 
						||
 | 
						||
  TRectype darec(LF_MOV), arec(LF_MOV);
 | 
						||
  if (_campodata == MOV_DATAREG)
 | 
						||
  {
 | 
						||
    if (_dadata.ok())
 | 
						||
      darec.put(MOV_DATAREG, _dadata);
 | 
						||
    if (_adata.ok())
 | 
						||
      arec.put(MOV_DATAREG, _adata);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    TString80 f;
 | 
						||
    if (_dadata.ok())
 | 
						||
    {
 | 
						||
      f.format("&&(ANSI(%s)>=\"%s\")", (const char*)_campodata, _dadata.string(ANSI));
 | 
						||
      filtro << f;
 | 
						||
    }
 | 
						||
    if (_adata.ok())
 | 
						||
    {
 | 
						||
      f.format("&&(ANSI(%s)<=\"%s\")", (const char*)_campodata, _adata.string(ANSI));
 | 
						||
      filtro << f;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  TRelation rel(LF_MOV);
 | 
						||
  TCursor cur(&rel, filtro, 2, &darec, &arec);
 | 
						||
  cur.scan(mov_callback, this, "Movimenti senza saldaconto...");
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_recordset::check_cms_cdc_fsc(const TRectype& rec_analriga)
 | 
						||
{
 | 
						||
	if (_codcosto.not_empty() && _codcosto != rec_analriga.get(RMOVANA_CODCCOSTO))
 | 
						||
		return false;
 | 
						||
	if (_codcms.not_empty() && _codcms != rec_analriga.get(RMOVANA_CODCMS))
 | 
						||
		return false;
 | 
						||
	if (_codfas.not_empty() && _codfas != rec_analriga.get(RMOVANA_CODFASE))
 | 
						||
		return false;
 | 
						||
 | 
						||
	return true;
 | 
						||
}
 | 
						||
 | 
						||
//////////////////////////////////////
 | 
						||
//	movimenti con saldaconto
 | 
						||
//////////////////////////////////////
 | 
						||
const TString& TPag_per_cms_recordset::query_movama_by_numregcg(const long nreg)
 | 
						||
{
 | 
						||
	TString& query = get_tmp_string();
 | 
						||
	query << "USE MOVANA KEY 3\n";
 | 
						||
	query << "FROM NUMREGCG=" << nreg << "\n";
 | 
						||
	query << "TO NUMREGCG=" << nreg;
 | 
						||
	return query;
 | 
						||
}
 | 
						||
 | 
						||
//prepara l'assoc con tutte le righe da mandare in stampa per quanto riguarda i movimenti con
 | 
						||
//saldaconto (siano essi con o senza iva)
 | 
						||
void TPag_per_cms_recordset::find_commesse(const long nreg, const TRectype& riga_pag)
 | 
						||
{
 | 
						||
	//cerca un record di MOVANA che abbia numregcg = nreg;usa il nuovo metodo fighissimo..
 | 
						||
	//..con la isam query implementato nella query_movama_by_numregcg()
 | 
						||
	TISAM_recordset movana(query_movama_by_numregcg(nreg));
 | 
						||
	const TRecnotype items = movana.items();
 | 
						||
	if (items <= 0)
 | 
						||
		return;
 | 
						||
 | 
						||
	if (items > 1)
 | 
						||
		warning_box(TR("Esiste piu' di un movimento analitico collegato al movimento contabile %ld"),nreg);
 | 
						||
 | 
						||
	movana.move_last();	//si posiziona sul record corretto
 | 
						||
 | 
						||
	//crea il movana e le sue righe
 | 
						||
	const TAnal_mov anal_mov(movana.get(MOVANA_NUMREG).as_int());
 | 
						||
	TRecord_array& anal_rows = anal_mov.body();
 | 
						||
	//scandisce le righe del movana alla ricerca di righe compatibili con le commesse sullo sheet
 | 
						||
	int m;
 | 
						||
  for (m = anal_rows.last_row(); m > 0; m--)
 | 
						||
	{
 | 
						||
		if (check_cms_cdc_fsc(anal_rows[m]))
 | 
						||
			break;
 | 
						||
	}
 | 
						||
	//se non ne ha trovata manco una di righe buone esce!
 | 
						||
  if (m <= 0)
 | 
						||
		return;
 | 
						||
 | 
						||
	//prepara il record tmpcurr sul file temporaneo _tmp su cui registrare i dati da stampare
 | 
						||
	TRectype& tmpcurr = _tmp->curr();
 | 
						||
	tmpcurr.zero();
 | 
						||
 | 
						||
	//crea un movimento p.n. con il numero reg che viene passato al metodo (nreg relativo.. 
 | 
						||
	//..ad un movimento della fattura originaria) 
 | 
						||
	TMovimentoPN pn;
 | 
						||
	pn.curr().put(MOV_NUMREG, nreg);
 | 
						||
	if (pn.read() == NOERR)
 | 
						||
	{
 | 
						||
		const TRectype& movfat = pn.curr();
 | 
						||
 | 
						||
		real totdoc_cms;
 | 
						||
		real totdoc, totdoc_netto;
 | 
						||
		TAssoc_array commesse;
 | 
						||
 | 
						||
		//Movimenti CON SALDACONTO
 | 
						||
		//se movimento IVA..
 | 
						||
		if (pn.iva_items() > 0)
 | 
						||
		{
 | 
						||
    	//trova le RMOVANA del MOVANA corrente che hanno il conto = a quello della i-esima rigaiva
 | 
						||
			for (int j = 0; j < pn.iva_items(); j++)
 | 
						||
			{
 | 
						||
				const TRectype& rmoviva = pn.iva(j);
 | 
						||
				const TBill zio(rmoviva);
 | 
						||
				//il tutto si fa solo se l'indicatore di bilancio del conto nella riga iva e' != 5
 | 
						||
				if (zio.indicatore_bilancio() != 5)
 | 
						||
				{
 | 
						||
					//e vediamo 'sto conto della riga iva..
 | 
						||
					const int gruppo_iva = zio.gruppo();
 | 
						||
					const int conto_iva = zio.conto();
 | 
						||
					const long sottoconto_iva = zio.sottoconto();
 | 
						||
 | 
						||
					real imponibile_iva = rmoviva.get_real(RMI_IMPONIBILE);
 | 
						||
					real imposta_iva = rmoviva.get_real(RMI_IMPOSTA);
 | 
						||
					const TString& tipodet = rmoviva.get(RMI_TIPODET);
 | 
						||
					//controlla se l'imposta va sommata (tipo detrazione iva non nulla)
 | 
						||
					if (tipodet.full())
 | 
						||
						imponibile_iva += imposta_iva;
 | 
						||
 | 
						||
					//distributore per il lordo iva (che sara' distribuito successivamente in base..
 | 
						||
					//..agli importi delle righe analitiche corretti per le % iva
 | 
						||
					TGeneric_distrib agip (imponibile_iva, TCurrency::get_firm_dec());
 | 
						||
 | 
						||
					for (int k = 1; k <= anal_rows.rows(); k++)	//scansiona righe analitiche..
 | 
						||
					{
 | 
						||
						real perc_ded_iva = UNO;	//%iva deducibile (di default 100, a meno del prorata)
 | 
						||
						if (imposta_iva != ZERO)
 | 
						||
						{
 | 
						||
							//controllo prorata
 | 
						||
							const TString80 commessa_riga_anal = anal_rows[k].get(RMOVANA_CODCMS);
 | 
						||
							const TRectype& pla = cache().get(LF_COMMESSE, commessa_riga_anal);
 | 
						||
							const bool prorata = pla.get_bool("PRORATA");
 | 
						||
							if (prorata)
 | 
						||
							{
 | 
						||
								const TDate datareg = pn.curr().get_date(MOV_DATAREG);
 | 
						||
								const int anno = datareg.year();
 | 
						||
								TRegistro registro(pn.curr().get(MOV_REG), anno);
 | 
						||
								//%deducibilit<69> iva rivista con il prorata
 | 
						||
								perc_ded_iva = (CENTO - registro.prorata(anno))/CENTO;
 | 
						||
								imposta_iva.round(TCurrency::get_firm_dec()); //ci vanno i decimali della ditta
 | 
						||
							}
 | 
						||
						}	//if imposta_iva...
 | 
						||
 | 
						||
						//prende il conto sulla riga analitica e lo confronta con quello della riga iva
 | 
						||
						const int gruppo_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).left(3)); 
 | 
						||
						const int conto_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).mid(3,3));
 | 
						||
						const long sottoconto_anal = atol(anal_rows[k].get(RMOVANA_CODCONTO).mid(6,6));
 | 
						||
 | 
						||
						//il codconto anale e iva coincidono?..
 | 
						||
						if (gruppo_iva == gruppo_anal && conto_iva == conto_anal && sottoconto_iva == sottoconto_anal)
 | 
						||
						{
 | 
						||
							//..in tal caso aggiunge l'importo della riga analitica al distributore, dopo..
 | 
						||
							//..averlo corretto in base alle % precedentemente calcolate
 | 
						||
							real importo_anal = anal_rows[k].get_real(RMOVANA_IMPORTO);
 | 
						||
							const real perc_iva = imposta_iva / imponibile_iva;
 | 
						||
							const real perc_corretta_iva = perc_iva * (UNO - perc_ded_iva);
 | 
						||
							importo_anal = importo_anal * (UNO - perc_corretta_iva);
 | 
						||
 | 
						||
							agip.add(importo_anal);
 | 
						||
						}	//if(gruppo_iva==...
 | 
						||
					}	//for (anal_rows...
 | 
						||
 | 
						||
					for (int l = 1; l <= anal_rows.rows(); l++)	//..allora le scansiona..
 | 
						||
					{
 | 
						||
						//prende il conto sulla riga analitica e lo confronta con quello della riga iva
 | 
						||
						const int gruppo_anal = atoi(anal_rows[l].get(RMOVANA_CODCONTO).left(3)); 
 | 
						||
						const int conto_anal = atoi(anal_rows[l].get(RMOVANA_CODCONTO).mid(3,3));
 | 
						||
						const long sottoconto_anal = atol(anal_rows[l].get(RMOVANA_CODCONTO).mid(6,6));
 | 
						||
 | 
						||
						//il codconto anale e iva coincidono?
 | 
						||
						if (gruppo_iva == gruppo_anal && conto_iva == conto_anal && sottoconto_iva == sottoconto_anal)
 | 
						||
						{
 | 
						||
							//impoerto 
 | 
						||
							real importo = agip.get();
 | 
						||
							//commessa,cdc,fase della riga analitica devono essere coincidenti con quelle dello sheet
 | 
						||
							if (check_cms_cdc_fsc(anal_rows[l]))
 | 
						||
							{
 | 
						||
								//costruzione dell'assoc_array 'commesse' con cms/cdc/fsc ed importi
 | 
						||
								TToken_string cms_cdc_fsc;
 | 
						||
								cms_cdc_fsc.add(anal_rows[l].get(RMOVANA_CODCMS));
 | 
						||
								cms_cdc_fsc.add(anal_rows[l].get(RMOVANA_CODCCOSTO));
 | 
						||
								cms_cdc_fsc.add(anal_rows[l].get(RMOVANA_CODFASE));
 | 
						||
 | 
						||
								real* imp = (real*)commesse.objptr(cms_cdc_fsc);
 | 
						||
								//aggiunge un elemento all'assoc_array...
 | 
						||
								if (imp == NULL)
 | 
						||
								{
 | 
						||
									imp = new real;
 | 
						||
									commesse.add(cms_cdc_fsc, imp);
 | 
						||
								}
 | 
						||
								*imp += importo;
 | 
						||
								totdoc_cms += importo;
 | 
						||
 | 
						||
							}	//if check_cms_cdc_fsc...
 | 
						||
 | 
						||
						}	//if(gruppo_iva==...
 | 
						||
 | 
						||
					}	//for (anal_rows...
 | 
						||
 | 
						||
				}	//if indicatore_bilancio!=5...
 | 
						||
 | 
						||
			}	//for (pn.iva_items(...
 | 
						||
 | 
						||
			totdoc = totale_documento(pn.curr()); //tot doc con ritenute fiscali + ritenute sociali (da stampare)
 | 
						||
			totdoc_netto = pn.curr().get_real(MOV_TOTDOC); //questo si usa solo per il calcolo del residuo
 | 
						||
		}	//if(pn.iva_items(...
 | 
						||
		else  //..movimento NON iva (sempre con saldaconto)
 | 
						||
		{
 | 
						||
			for (int j = 0; j < pn.cg_items(); j++)
 | 
						||
			{
 | 
						||
				const TRectype& rmov = pn.cg(j);
 | 
						||
				const TBill zio_cg(rmov);
 | 
						||
 | 
						||
				TImporto importo(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO));
 | 
						||
				importo.normalize('D');
 | 
						||
 | 
						||
				if (zio_cg.tipo() > ' ')
 | 
						||
				{
 | 
						||
					totdoc -= importo.valore(); 
 | 
						||
					totdoc_netto -= importo.valore(); //valore per il calcolo del residuo
 | 
						||
				}
 | 
						||
				else
 | 
						||
					if (cerca_fiscali(zio_cg) || cerca_sociali(zio_cg))
 | 
						||
						totdoc -= importo.valore(); //valore da stampare nella colonna Tot.fattura con ritenute
 | 
						||
			}	//for j < pn.cg_items...
 | 
						||
 | 
						||
			for (int k = 1; k <= anal_rows.rows(); k++)	//..allora le scansiona..
 | 
						||
			{
 | 
						||
				//prende gr/co/sott sulla riga analitica...
 | 
						||
				const int gruppo_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).left(3)); 
 | 
						||
				const int conto_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).mid(3,3));
 | 
						||
				const long sottoconto_anal = atol(anal_rows[k].get(RMOVANA_CODCONTO).mid(6,6));
 | 
						||
				//..e crea il conto contabile corrispondente
 | 
						||
				TBill conto_cg(gruppo_anal, conto_anal, sottoconto_anal);
 | 
						||
 | 
						||
				//l'indicatore di bilancio del conto contabile appena creato e' valido?
 | 
						||
				if (conto_cg.indicatore_bilancio() != 5)
 | 
						||
				{ 
 | 
						||
					const real importo_anal = anal_rows[k].get_real(RMOVANA_IMPORTO);
 | 
						||
 
 | 
						||
					//costruzione dell'assoc_array 'commesse' con cms/cdc/fsc ed importi
 | 
						||
					TToken_string cms_cdc_fsc;
 | 
						||
					cms_cdc_fsc.add(anal_rows[k].get(RMOVANA_CODCMS));
 | 
						||
					cms_cdc_fsc.add(anal_rows[k].get(RMOVANA_CODCCOSTO));
 | 
						||
					cms_cdc_fsc.add(anal_rows[k].get(RMOVANA_CODFASE));
 | 
						||
 | 
						||
					real* imp = (real*)commesse.objptr(cms_cdc_fsc);
 | 
						||
 | 
						||
					if (imp == NULL)
 | 
						||
					{
 | 
						||
						imp = new real;
 | 
						||
						commesse.add(cms_cdc_fsc, imp);
 | 
						||
					}
 | 
						||
 | 
						||
					TImporto importo(anal_rows[k].get_char(RMOVANA_SEZIONE), anal_rows[k].get_real(RMOVANA_IMPORTO));
 | 
						||
					importo.normalize('D');
 | 
						||
 | 
						||
					*imp += importo.valore();
 | 
						||
					totdoc_cms += importo.valore();
 | 
						||
				}	//if(conto_cg.indicatore...
 | 
						||
			}	//for(k<anal_rows...
 | 
						||
		}	//else (pn.iva_items(...
 | 
						||
 | 
						||
		//parte comune a movimenti IVA e non (vengono anche qui considerate le ritenute fiscali
 | 
						||
		//e sociali perche' possono essere state inserite direttamente nella partita e non nel movimento
 | 
						||
		//(quindi non si puo' in questo caso applicare la totale_documento()
 | 
						||
		//Le ritenute fiscali vanno sempre sommate..
 | 
						||
		real totpagato = riga_pag.get_real(PART_IMPORTO) + riga_pag.get_real(PART_RITENUTE);
 | 
						||
		//Le ritenute sociali invece vanno testate con la test_swap..
 | 
						||
		const real ritsoc = riga_pag.get_real(PART_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;
 | 
						||
		}
 | 
						||
 | 
						||
		const real percentuale = totpagato / totdoc_netto;
 | 
						||
 | 
						||
		//calcolo del residuo (solo movimenti saldacontati)
 | 
						||
		//mi servono,dalla riga partita che viene passata,i valori dei campi per la chiave del
 | 
						||
		//file delle scadenze
 | 
						||
		const TPartita match(riga_pag);
 | 
						||
		//ci serve la riga di fattura che origina la nostra riga pagamento
 | 
						||
		const int riga_fatt = cerca_riga_fattura_origine(match, riga_pag);
 | 
						||
		//quanto era stato pagato del documento prima della attuale riga_pag
 | 
						||
		const real totpagato_prec = calcola_pagato_prec(match, riga_fatt, riga_pag);
 | 
						||
		const real perc_prec = totpagato_prec / totdoc_netto;
 | 
						||
 | 
						||
		TGeneric_distrib distributore(totdoc_cms * percentuale, TCurrency::get_firm_dec());
 | 
						||
		TGeneric_distrib distributore_prec(totdoc_cms * perc_prec, TCurrency::get_firm_dec());
 | 
						||
		{
 | 
						||
			FOR_EACH_ASSOC_OBJECT(commesse, h, k, imp)
 | 
						||
			{
 | 
						||
				const real& impcms = *(real*)imp;
 | 
						||
				distributore.add(impcms);
 | 
						||
				distributore_prec.add(impcms);  //distributore di importo pagato sulle commesse
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		FOR_EACH_ASSOC_OBJECT(commesse, h, k, imp)
 | 
						||
		{
 | 
						||
			const real& impcms = *(real*)imp;
 | 
						||
 | 
						||
			// campi del pagamento che vanno spediti nel file temporaneo
 | 
						||
			//codice fornitore e descrizione
 | 
						||
			const long codforn = riga_pag.get_long(PART_SOTTOCONTO);
 | 
						||
			tmpcurr.put("CODFORN", codforn);
 | 
						||
			TString16 keyclifo;
 | 
						||
			keyclifo.format("F|%ld", codforn);
 | 
						||
			const TRectype& rec_clifo = cache().get(LF_CLIFO, keyclifo);
 | 
						||
			tmpcurr.put("DESFORN", rec_clifo.get(CLI_RAGSOC));
 | 
						||
 | 
						||
			//nreg,data pagamento,descrizione pagamento
 | 
						||
			tmpcurr.put("NREG", nreg);
 | 
						||
			tmpcurr.put("DATAPAG", riga_pag.get_date(PART_DATAPAG));
 | 
						||
			tmpcurr.put("DATAREG", riga_pag.get_date(PART_DATAREG));
 | 
						||
			tmpcurr.put("DESCRPAG", riga_pag.get(PART_DESCR));
 | 
						||
 | 
						||
			//documento origine
 | 
						||
			tmpcurr.put("NDOC", movfat.get_long(MOV_NUMDOC));
 | 
						||
			tmpcurr.put("DATADOC", movfat.get_date(MOV_DATADOC));
 | 
						||
			tmpcurr.put("PROT", movfat.get_long(MOV_PROTIVA));
 | 
						||
			tmpcurr.put("TOTDOC", totdoc);
 | 
						||
			tmpcurr.put("TOTPAG", distributore.get());	//pagamento nella partita
 | 
						||
			//totres = importo da pagare (sulla fattura) - pagamenti precedenti al
 | 
						||
			tmpcurr.put("TOTRES", impcms - distributore_prec.get());
 | 
						||
			
 | 
						||
			//campi relativi a cdc,commessa,fase
 | 
						||
			TToken_string cdc_cms_fsc = k;
 | 
						||
			tmpcurr.put("CMS",cdc_cms_fsc.get(0));
 | 
						||
			tmpcurr.put("CDC",cdc_cms_fsc.get(1));
 | 
						||
			tmpcurr.put("FSC",cdc_cms_fsc.get(2));
 | 
						||
 | 
						||
			//e finalmente aggiunge il record al file temporaneo
 | 
						||
			_tmp->write();
 | 
						||
		} //FOR_EACH_...
 | 
						||
 | 
						||
	} //pn.read()...
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
bool TPag_per_cms_recordset::part_callback(const TRelation& rel, void* pJolly)
 | 
						||
{
 | 
						||
	TPag_per_cms_recordset* recordset = (TPag_per_cms_recordset*)pJolly;
 | 
						||
  const TRectype& riga_part_pag = rel.curr();
 | 
						||
  
 | 
						||
  const long nreg = recordset->find_movimento(riga_part_pag); //prima cerco un movimento della fattura...
 | 
						||
  if (nreg > 0) //..se ne trovo almeno uno cerco la commessa corrispondente
 | 
						||
    recordset->find_commesse(nreg, riga_part_pag);
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_recordset::scan_pags()
 | 
						||
{
 | 
						||
//costruzione filtro
 | 
						||
  TRectype dafiltrec(LF_PARTITE);
 | 
						||
  dafiltrec.put(PART_TIPOCF, 'F');
 | 
						||
  dafiltrec.put(PART_GRUPPO, 0);
 | 
						||
  dafiltrec.put(PART_CONTO, 0);
 | 
						||
	dafiltrec.put(PART_SOTTOCONTO, _dacodfor);
 | 
						||
 | 
						||
	TRectype afiltrec(dafiltrec); 
 | 
						||
	afiltrec.put(PART_SOTTOCONTO, _acodfor);
 | 
						||
  
 | 
						||
  TString filtro = "(TIPOMOV>=\"3\")";  //deve essere un pagamento a fornitore!!!
 | 
						||
 | 
						||
  if (_dadata.ok())
 | 
						||
  {
 | 
						||
    TString80 f;
 | 
						||
    f.format("&&(ANSI(%s)>=\"%s\")", (const char*)_campodata, _dadata.string(ANSI));
 | 
						||
    filtro << f;
 | 
						||
  }
 | 
						||
  if (_adata.ok())
 | 
						||
  {
 | 
						||
    TString80 f;
 | 
						||
    f.format("&&(ANSI(%s)<=\"%s\")", (const char*)_campodata, _adata.string(ANSI));
 | 
						||
    filtro << f;
 | 
						||
  }
 | 
						||
//applica il filtro alla relazione
 | 
						||
  TRelation rel(LF_PARTITE);
 | 
						||
  TCursor cur(&rel, filtro, 1, &dafiltrec, &afiltrec);
 | 
						||
  cur.scan(part_callback, this, "Movimenti con saldaconto...");
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms_recordset::set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata)
 | 
						||
{
 | 
						||
	//se esiste il file temporano con tracciato persomalizzato lo cancella e lo ricrea vuoto
 | 
						||
  TFilename trr;	//file tracciato record 
 | 
						||
	trr.tempdir();
 | 
						||
	trr.add("paid");
 | 
						||
	TFilename dbf(trr);	//file dati
 | 
						||
 | 
						||
  trr.ext("trr");   
 | 
						||
	dbf.ext("dbf");
 | 
						||
 | 
						||
	//scelta tipo data di estrazione (registrazione, documento, pagamento)
 | 
						||
	//deve stare qui per poter generare la chiave del file temporaneo in base al tipo di data di estrazione
 | 
						||
	_campodata = campodata;
 | 
						||
	//stessa cosa per il simpatico codice fornitore
 | 
						||
	_dacodfor = dacodfor;
 | 
						||
	_acodfor = acodfor;
 | 
						||
 | 
						||
	//crea il file .trr in base ai parametri del metodo
 | 
						||
	crea_trr(trr);
 | 
						||
	//svuota la memoria dal vecchio file temporaneo
 | 
						||
	if (_tmp != NULL)
 | 
						||
		delete _tmp;
 | 
						||
 | 
						||
	//crea in memoria il nuovo file temporaneo e lo azzera (non si sa mai..)
 | 
						||
	_tmp = new TExternisamfile(dbf, trr);
 | 
						||
	_tmp->zap();
 | 
						||
 | 
						||
	//prende un po' di dati dalla maschera
 | 
						||
	_codcosto = _codcms = _codfas = "";
 | 
						||
  if (cms_row >= 0)
 | 
						||
  {
 | 
						||
    TSheet_field& sf = msk.sfield(F_RIGHE);
 | 
						||
    TMask& sm = sf.sheet_mask();	//metodo ingannatore per ottenere tutti i campi dallo sheet..
 | 
						||
    sf.update_mask(cms_row);			//..delle cms/fsc/cdc senza rifare il giro della configurazione..
 | 
						||
    TRelation rel(LF_RMOVANA);		//..anale
 | 
						||
    sm.autosave(rel);
 | 
						||
    _codcosto = rel.curr().get(RMOVANA_CODCCOSTO);
 | 
						||
    _codcms = rel.curr().get(RMOVANA_CODCMS);
 | 
						||
    _codfas = rel.curr().get(RMOVANA_CODFASE);
 | 
						||
  }
 | 
						||
 | 
						||
	//lettura eventuali date limite (il controllo sul loro valore sara' nei metodi di costruzione
 | 
						||
	//dei filtri
 | 
						||
  _dadata = msk.get_date(F_DATAINI);
 | 
						||
	_adata = msk.get_date(F_DATAFIN);
 | 
						||
 | 
						||
 | 
						||
	//carica i conti memorizzati nel ca3600.ini,registrandoli negli assoc_array _costi ecc...
 | 
						||
	lettura_conti(_costi, 'C');
 | 
						||
	lettura_conti(_pagamenti, 'P');
 | 
						||
	lettura_conti(_fiscali, 'F');
 | 
						||
	lettura_conti(_sociali, 'S');
 | 
						||
 | 
						||
	//scansione movimenti con saldaconto
 | 
						||
	scan_pags();
 | 
						||
 | 
						||
  //se c'e' un filtro sui fornitori, non si fa lo scan dei movimenti senza saldaconto
 | 
						||
  if (dacodfor <= 0 && acodfor <= 0)
 | 
						||
    scan_movs();
 | 
						||
}
 | 
						||
 | 
						||
////////////////////////////////////////////////////////
 | 
						||
//	REPORT
 | 
						||
////////////////////////////////////////////////////////
 | 
						||
class TPag_per_cms_rep : public TAnal_report
 | 
						||
{
 | 
						||
 | 
						||
protected:
 | 
						||
	virtual bool set_recordset(const TString& sql);
 | 
						||
	virtual bool get_usr_val(const TString& name, TVariant& var) const;
 | 
						||
 | 
						||
public:
 | 
						||
	void set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata);
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
bool TPag_per_cms_rep::get_usr_val(const TString& name, TVariant& var) const
 | 
						||
{
 | 
						||
	return TAnal_report::get_usr_val(name, var);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TPag_per_cms_rep::set_recordset(const TString& sql)
 | 
						||
{
 | 
						||
  TPag_per_cms_recordset* rs = new TPag_per_cms_recordset(sql);
 | 
						||
  return TAnal_report::set_recordset(rs);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TPag_per_cms_rep::set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata)
 | 
						||
{
 | 
						||
	TAnal_report::set_recordset(NULL);
 | 
						||
 | 
						||
	const char* query ="USE 1000"; //\nJOIN MOVANA INTO NUMREG==NUMRD\nJOIN RMOVANA INTO NUMREG==NUMRD NUMRIG==NRIGA";
 | 
						||
 | 
						||
	TPag_per_cms_recordset* recset = new TPag_per_cms_recordset(query); 
 | 
						||
 | 
						||
  recset->set_filter(msk, cms_row, dacodfor, acodfor, campodata);
 | 
						||
	TAnal_report::set_recordset(recset);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
//===============================================================================================
 | 
						||
////////////////////////////////////////////////////////
 | 
						||
//	APPLICAZIONE
 | 
						||
////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TPag_per_cms : public TSkeleton_application
 | 
						||
{
 | 
						||
public:
 | 
						||
	void stampa_per_commessa(const TPag_per_cms_mask& mask, TReport_book& book, 
 | 
						||
													 TPag_per_cms_rep& rep, const long dacodfor, const long acodfor, 
 | 
						||
													 const TString& campodata);
 | 
						||
	const TMultilevel_code_info& get_level_one() const;
 | 
						||
  virtual void main_loop();
 | 
						||
};
 | 
						||
 | 
						||
//metodo per accattarsi o' primo livello della configurazione CA
 | 
						||
const TMultilevel_code_info& TPag_per_cms::get_level_one() const
 | 
						||
{
 | 
						||
	TConfig& cfg = ca_config();
 | 
						||
	const TString& first_lev = cfg.get("Level(1)");
 | 
						||
	const int logic = first_lev == "CDC" ? LF_CDC : LF_COMMESSE;
 | 
						||
	return ca_multilevel_code_info(logic);
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms::stampa_per_commessa(const TPag_per_cms_mask& mask, TReport_book& book, TPag_per_cms_rep& rep, 
 | 
						||
																			 const long dacodfor, const long acodfor, 
 | 
						||
																			 const TString& campodata)
 | 
						||
{
 | 
						||
	TSheet_field& sheet = mask.sfield(F_RIGHE);
 | 
						||
	TString video_string;	//stringa che compare nella progind
 | 
						||
  if (sheet.empty())	//se non ci sono righe sullo sheet (selezione su tutte le cms/cdc)...
 | 
						||
	{
 | 
						||
		TToken_string& row = sheet.row(-1);	//crea la prima riga dello sheet
 | 
						||
 | 
						||
		const TMultilevel_code_info& liv1 = get_level_one();	//stabilisce quale <20> il primo livello (tra CDC e CMS)..
 | 
						||
		TISAM_recordset set(liv1.logic() == LF_CDC ? "USE CDC" : "USE COMMESSE");	//..e di conseguenza scrive la use giusta
 | 
						||
 | 
						||
		TProgind pi(set.items(), video_string, true, true);
 | 
						||
		for (int i = 0; set.move_to(i); i++)	//fighissimo metodo per scandire un file in 1 riga!
 | 
						||
		{
 | 
						||
			pi.addstatus(1);
 | 
						||
			if (pi.iscancelled())
 | 
						||
				break;
 | 
						||
			row = set.get((unsigned int)0).as_string();	//prende il valore del primo campo del file (CDC o CMS code)
 | 
						||
 | 
						||
			video_string = TR("Scansione");
 | 
						||
			video_string << " " << row;	//completa la stringa da visualizzare sulla progind
 | 
						||
			pi.set_text(video_string);
 | 
						||
 | 
						||
			for (int l = liv1.levels()-2; l >= 0; l--)	//se la struttura <20> a pi<70> livelli costruisce la tokenstring
 | 
						||
				row.insert("|", liv1.total_len(l));
 | 
						||
 | 
						||
			rep.set_filter(mask, 0, dacodfor, acodfor, campodata);	//fa la set filter sulla prima riga (che <20> quella usata)	
 | 
						||
			book.add(rep);
 | 
						||
		}
 | 
						||
		sheet.destroy();	//cancella le commesse aggiunte in automatico sullo sheet
 | 
						||
	}
 | 
						||
	else	//se ha almeno una riga sullo sheet delle cms/cdc...
 | 
						||
	{
 | 
						||
		FOR_EACH_SHEET_ROW(sheet, r, row)	//per ogni cdc/cms che appare nello sheet di pag.1 della msk..
 | 
						||
		{
 | 
						||
			rep.set_filter(mask, r, dacodfor, acodfor, campodata);	//..chiama il metodone globale che crea e compila il file.. 
 | 
						||
  																//..temporaneo i cui dati riempiranno il report
 | 
						||
			book.add(rep);	//aggiunge il report relativo alla cdc/cms corrente al book
 | 
						||
		}
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
void TPag_per_cms::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;
 | 
						||
	}
 | 
						||
 | 
						||
	TPag_per_cms_mask mask;
 | 
						||
  while (mask.run() == K_ENTER)
 | 
						||
  {
 | 
						||
		//report e book dei report
 | 
						||
		TReport_book book;
 | 
						||
		TString path = mask.get(F_REPORT);
 | 
						||
		if (path.empty())
 | 
						||
			path = "ca3600a";
 | 
						||
		TPag_per_cms_rep rep;
 | 
						||
		rep.load(path);
 | 
						||
 | 
						||
		//scelta tipo data di estrazione (registrazione, documento, pagamento)
 | 
						||
		//viene presa qui perche' serve subito alla set_filter del report prima che venga..
 | 
						||
		//..utilizzata nel recordset
 | 
						||
		TString16 campodata = PART_DATAREG;
 | 
						||
		switch(mask.get_int(F_TIPODATA))
 | 
						||
		{
 | 
						||
		case 1:campodata = PART_DATADOC;break;
 | 
						||
		case 2:campodata = PART_DATAPAG;break;
 | 
						||
		default:break;
 | 
						||
		}
 | 
						||
 | 
						||
		//scansione su tutti i fornitori selezionati; questa opzione e' praticamente utile solo..
 | 
						||
		//..quando il numero di fornitori selezionati non e' elevato;infatti,per ogni fornitore..
 | 
						||
		//..selezionato, viene eseguito tutto il giro del programma
 | 
						||
		const long dacodfor = mask.get_long(F_DACODFOR);
 | 
						||
		const long acodfor = mask.get_long(F_ACODFOR);
 | 
						||
 | 
						||
		stampa_per_commessa(mask, book, rep, dacodfor, acodfor, campodata);	//se non si specifica alcun clifo...
 | 
						||
 | 
						||
		book.print_or_preview();	//stampa il book dei report
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
int ca3600(int argc, char* argv[])
 | 
						||
{
 | 
						||
  TPag_per_cms a;
 | 
						||
  a.run(argc,argv,TR("Stampa pagato per commessa"));
 | 
						||
  return 0;
 | 
						||
}
 |