#include "pg0214100a.h"

#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <recarray.h>
#include <reprint.h>
#include <reputils.h> 
#include <textset.h>

#include "../cg/cg2103.h"
#include "../cg/cglib02.h"
#include "../cg/cgsaldac.h"
#include "../ve/velib.h"

#include "clifo.h"
#include "comuni.h"

#include <causali.h>
#include <mov.h>
#include <pconti.h>
#include <rmov.h>
#include <rmoviva.h>


#include "../ve/velib.h"

///////////////////////////////////////////////////////////
//  MASCHERA
///////////////////////////////////////////////////////////
class TCertificazioni_mask : public TAutomask
{
protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); 
	
public:
  TCertificazioni_mask();
  virtual ~TCertificazioni_mask() {}
};

TCertificazioni_mask::TCertificazioni_mask() : TAutomask("pg0214100a")
{
}

bool TCertificazioni_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  return true;
}

/////////////////////////////////////////////////////////////
//  REPORT
/////////////////////////////////////////////////////////////
class TCertificazioni_report : public TReport
{
protected:
virtual bool use_mask() { return false; }
public:
  TCertificazioni_report() {}
};

/////////////////////////////////////////////////////////////
//	CSV RECORDSET
/////////////////////////////////////////////////////////////

class TCertificazioni_csv_recordset : public TCSV_recordset
{
protected:
  virtual const TVariant& get(const char* name) const;

public:
	TCertificazioni_csv_recordset();
};

const TVariant& TCertificazioni_csv_recordset::get(const char* name) const
{
	if (*name != '#')
	{
		const TFixed_string fname(name);
		const int dot = fname.find('.');
		if (dot > 0)
		{
			const int logicnum = table2logic(fname.left(dot));
  		TString8 c; 
			switch (logicnum)
			{
			case LF_CLIFO : c << "F|" << TCSV_recordset::get(0L).as_int(); break;
			case LF_COMUNI:	c << " |" << get("CLIFO.COMCF"); break;
			default: break;
			}
			if (c.full())
			{
				const TString& fld = fname.mid(dot+1);
				return get_tmp_var() = cache().get(logicnum, c, fld);
			}
		}
	}
	return TRecordset::get(name);
}

TCertificazioni_csv_recordset::TCertificazioni_csv_recordset() 
                             : TCSV_recordset("CSV(,)\n")
{ }


///////////////////////////////////////////////////////////
// APPLICAZIONE
///////////////////////////////////////////////////////////

class TCertificazioni : public TSkeleton_application
{

	virtual bool check_autorization() const {return false;}
	virtual const char * extra_modules() const {return "cg";}

protected:
  void elabora(const TMask& mask) const;
 void scrivi_csv(const TRectype& prima_riga, 
		              TCertificazioni_csv_recordset& csv) const;

public:
	virtual bool create();
  virtual void main_loop();

};

// scorre le righe di movimento e fa i calcoli per stampare la riga di report 
// scorre le righe di movimento e fa i calcoli per stampare la riga di report 
void TCertificazioni::scrivi_csv(const TRectype& prima_riga, 
																 TCertificazioni_csv_recordset& csv) const
{
	const long numreg = prima_riga.get_long(RMV_NUMREG);
	const TBill rit_gcs(prima_riga);
 
	TMovimentoPN movpn;
	movpn.lfile().setkey(1);
	TRectype& mov = movpn.curr();
	mov.put(MOV_NUMREG, numreg);
	if (movpn.read() == NOERR)
	{
		long fornitore = 0;
		real lordo, imponibile, ritenute, netto;

		for (int i=0; i < movpn.cg_items(); i++)
		{
			const TRectype& rmov = movpn.cg(i);
     	const TBill gcs(rmov);
			const char sez = rmov.get_char(RMV_SEZIONE);
			const real imp = rmov.get_real(RMV_IMPORTO);
			if (sez =='A')
			{
				if (gcs == rit_gcs) // ritenuta
			    ritenute += imp; 
				else
				{
			    netto += imp; // imponibile
					if (gcs.tipo() == 'F')
						fornitore = gcs.codclifo();
				}
			}
			else
			  lordo += imp;
		}


		if (fornitore > 0)
		{
			csv.new_rec("");

			csv.set(0, TVariant(fornitore));
			const TString& causale = cache().get(LF_CAUSALI, mov.get(MOV_CODCAUS), CAU_DESCR);
			csv.set(1, TVariant(causale));
			csv.set(2, TVariant(lordo));    // compenso lordo
			csv.set(3, TVariant(ZERO));     // somme non soggette
			csv.set(4, TVariant(ZERO));     // imponibile
			csv.set(5, TVariant(ritenute)); // ritenute
      csv.set(6, TVariant(netto));    // netto
		}
	}
}

//metodo di base per la ricerca delle righe movimento che soddisfano le condizioni
void TCertificazioni::elabora(const TMask& mask) const
{
	// date
  const TDate dataini = mask.get_date(F_DADATA);
  const TDate datafin = mask.get_date(F_ADATA);
  
  TConfig ditta_ini(CONFIG_DITTA, "ve");

  //Adesso prende i conti da verificare
  TSheet_field& sf = mask.sfield(F_CONTI);

  //la query e' sulle righe movimento
  TString query;
  query << "USE RMOV KEY 2\n";
  query << "SELECT (NUM(ANSI(23.DATACOMP))>=NUM(ANSI(#DADATA)))&&(NUM(ANSI(23.DATACOMP))<=NUM(ANSI(#ADATA)))\n";
  query << "JOIN MOV INTO NUMREG==NUMREG\n";
	query << "JOIN CLIFO TO MOV INTO TIPOCF==TIPO CODCF==CODCF\n";
  query << "JOIN COMUNI TO CLIFO INTO STATO==STATOCF COM==COMCF\n";
  query << "FROM GRUPPO=#GRUPPO CONTO=#CONTO SOTTOCONTO=#SOTTOCONTO\n";
  query << "TO GRUPPO=#GRUPPO CONTO=#CONTO SOTTOCONTO=#SOTTOCONTO\n";
  query << "BY MOV.CODCF\n";

  TISAM_recordset rmov(query);

	// filtro per date
	rmov.set_var("#DADATA", dataini);
	rmov.set_var("#ADATA", datafin);

  //creazione del csv recordset che verra' riempito dalla elaborazione
  TCertificazioni_csv_recordset* csv = new TCertificazioni_csv_recordset;

  //Visto che e' possibile avere una secchiata di conti, gli tocca fare un giro per ogni conto
	// in realta' secondo me si potrebbe avere un conto solo (quello delle ritenute)
  FOR_EACH_SHEET_ROW(sf, r, row)
  {
    //estrazione definitiva dei record che soddisfano il casino di parametri richiesti
    rmov.set_var("#GRUPPO", row->get(0));
    rmov.set_var("#CONTO", row->get(1));
    rmov.set_var("#SOTTOCONTO", row->get(2));

    //quanti record validi ha trovato?
    const long items = rmov.items();

    //E crea pure la progind..
    TProgind pi(items, TR("Generazione righe ritenute..."), true, true);

    long last_nmov = 0;

    //Scansione del recordset trovato
    for (bool ok = rmov.move_first(); ok; ok = rmov.move_next())
	  {
      if (!pi.addstatus(1))
        break;
      
      const long nmov = rmov.get(RMV_NUMREG).as_int();
			const int gruppo = rmov.get(RMV_GRUPPO).as_int();
			const int conto = rmov.get(RMV_CONTO).as_int();
			const long sottoconto = rmov.get(RMV_SOTTOCONTO).as_int();
      if (nmov != last_nmov)
      {
        scrivi_csv(rmov.cursor()->curr(), *csv, gruppo, conto, sottoconto);
        last_nmov = nmov;
      }

    } //for(bool ok = rmov.move_first(..

  } //FOR_EACH...
  
  
#ifdef DBG
	csv->save_as_text("c:/tmp/admin/bonomo.txt");
#endif

  //creazione del report di stampa
	TCertificazioni_report rep;
	bool ok = rep.load("pg0214100a");
  //setta il recordset...
  //deve settare almeno un campo manualmente perche' funzioni la mask2report
  csv->set_var("#EMAIL", TVariant(TR("Manca la e-mail")), true);
  rep.set_recordset(csv);
  //..e poi carica i valori sulla maschera nel report!!!!
  rep.mask2report(mask);

	if (ok)
	{
		TReport_book book;
		ok = book.add(rep);
		if (ok)
			book.print_or_preview();
  }
}

void TCertificazioni::main_loop()
{
  TCertificazioni_mask mask;
  mask.field(F_CODDITTA).check(RUNNING_CHECK);
  while (mask.run() == K_ENTER)
    elabora(mask);
} 

bool TCertificazioni::create()
{
 	return TSkeleton_application::create();
}

int pg0214100(int argc, char* argv[])
{
  TCertificazioni dc;
  dc.run(argc, argv, TR("Stampa certificazioni"));
  return 0;
}