#include <applicat.h>
#include <automask.h>
#include <execp.h>
#include <lffiles.h>
#include <progind.h>
#include <real.h>
#include <recarray.h>
#include <reputils.h>
#include <utility.h>
#include <relation.h>
#include <reprint.h>
#include <textset.h>
#include <tabutil.h>

#include "../cg/cglib01.h"

#include "pe0001.h"
#include "pe0001100.h"
#include "pe0001100a.h"

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

	#define AT01CM   0 // Record attivo/sospeso/annullato                       DIZSMAS    - ATTI
	#define DT01CM   1 // Data stampa per G.Gen.le                              DIZSMAS    - DATS
	#define NR01CM   2 // Numero azione di aggiornamento                        DIZSMAS    - NRAZ
	#define TPMVCM   3 // Flag IVA I=IVA   =no IVA                              DIZSMAS    - TPMV
	#define CDDTCM   4 // Codice Ditta                                          DIZSMAS    - CDDT
	#define AAPRCM   5 // Anno Operazione                                       DIZSMAS    - AAPR
	#define ANNPCM   6 // Anno Reg.DA GESTIRE                                   DIZSMAS    - ANNP
	#define TPGICM	 7 // Giornale IVA  TB=GI                                   DIZSMAS    - TPGI
	#define DTOPCM	 8 // Data operazione                                       DIZSMAS    - DATS
	#define NONPCM	 9 // Nr. Operaz./Nr. Prot.                                 DIZSMAS    - NONP
	#define NRRGCM	10 // Numero Riga 2                                         DIZSMAS    - NRR2
	#define NRGICM	11 // Nr Riga Giornale                                      DIZSMAS    - NRGI
	#define CONTCM	12 // Gr. Conto Sottoconto                                  DIZSMAS    - CONT
	#define DIVICM	13 // Divisione  TB=DI                                      DIZSMAS    - DIVI
	#define NPARCM	14 // Nr Partita                                            DIZSMAS    - NPAR
	#define AAOPCM	15 // Anno partita                                          DIZSMAS    - ANNO
	#define DTRGCM	16 // Data registrazione                                    DIZSMAS    - DATS
	#define CAUSCM	17 // Causale  TB=CA                                        DIZSMAS    - CAUS
	#define DSUPCM	18 // Descrizione Supplementare                             DIZSMAS    - DSUP
	#define IMPOCM	19 // Importo  "-"=Avere                                    DIZSMAS    - IMPO
	#define CDVACM	20 // Codice Valuta  TB=VA                                  DIZSMAS    - CDVA
	#define CAMBCM	21 // Cambio                                                DIZSMAS    - CAMB
	#define IMVACM	22 // Importo Valuta                                        DIZSMAS    - IMVA
	#define CDPGCM	23 // Codice di Pagamento TB=CP                             DIZSMAS    - CDPG
	#define DT1SCM	24 // Data I^ scadenza                                      DIZSMAS    - DATS
	#define DTDOCM	25 // Data documento                                        DIZSMAS    - DATS
	#define NRDOCM	26 // N� Documento                                          DIZSMAS    - NUDO
	#define CCTPCM	27 // Centri Costo Tipico TB=CC                             DIZSMAS    - CCTP
	#define NCOMCM	28 // Numero Commessa                                       DIZSMAS    - NCOM
	#define CDSCCM	29 // Codice Sottocommessa                                  DIZSMAS    - CDSC
	#define INDECM	30 // Indetraibilit� %                                      DIZSMAS    - INDE
	#define CDIVCM	31 // Codice IVA                                            DIZSMAS    - CDIV
	#define IMPSCM	32 // Imposta                                               DIZSMAS    - IMPS
	#define CDAGCM	33 // Codice Agente                                         DIZSMAS    - CDAG
	#define DTVBCM	34 // Data Liquidazione Iva Sospesa                         DIZSMAS    - DATS
	#define FLSBCM	35 // Flag *=Stampato Bollato                               DIZSMAS    - FLSB
	#define FSBICM	36 // Flag *=Stampato Boll.IVA                              DIZSMAS    - FSBI
	#define FLVZCM	37 // V=Var.S=Storno P=Liq.prec. E=Esig.Sosp.               DIZSMAS    - FLVZ
	#define FLIICM	38 // Flag IVA Irrecup. " "=I irr.                          DIZSMAS    - FLII
	#define FLTSCM	39 // Flag Tipo Sollecito                                   DIZSMAS    - FLTS
	#define FLEPCM	40 // *=Est.EP Non � pi� usato                              DIZSMAS    - FLEP
	#define DPERCM	41 // Dati Personalizzabili                                 DIZSMAS    - DPER
	#define CONSCM	42 // Gr.Co.Sottoc.Sostitutivo                              DIZSMAS    - CONS
	#define DTSTCM	43 // Nr.progr. rateo/risconto                                         -
	#define USERCM	44 // Utente                                                DIZSMAS    - NOMU
	#define DTUMCM	45 // Data ultima manutenzione                              DIZSMAS    - DATS
	#define TPUMCM	46 // Tipo ultima manutenzione                              DIZSMAS    - FLAG
	#define FL01CM	47 // Flag Generico                                         DIZSMAS    - FLAG
	#define FL02CM	48 // Flag Generico                                         DIZSMAS    - FLAG
	#define FL03CM	49 // Flag Generico                                         DIZSMAS    - FLAG
	#define FL04CM	50 // Flag Generico                                         DIZSMAS    - FLAG
	#define FL05CM	51 // Flag Generico                                         DIZSMAS    - FLAG
	#define CMBECM	52 // Cambio EURO                                           DIZSMAS    - CAME
	#define IMVACM2	53 // Importo Val 2                                         DIZSMAS    - IMPO
	#define IMPSCM2	54 // Imposta 2                                             DIZSMAS    - IMPS

const TVariant& TImporta_galileo_recset::get(unsigned int column) const
{
	TString str = TCSV_recordset::get(column).as_string();
  TVariant& var = get_tmp_var();
	int len = str.len();
			
	if (len == 0)
		return NULL_VARIANT;
	if (str[len -1] == '"')
		str.rtrim(1);
	if (str[0] == '"')
		str.ltrim(1);
	var.set(str);
	return var;
}
///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////

class TImporta_mov_mask : public TAutomask
{
protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);

public:
  TImporta_mov_mask();
};
  
TImporta_mov_mask::TImporta_mov_mask() :TAutomask ("pe0001100a")
{
}  

bool TImporta_mov_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
{ 
	switch (f.dlg())
	{
		//giochetto per avere la lista dei files validi nella directory di trasferimento!
		case F_NAME:
			if (e == fe_button)
			{
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), 
                           "File@32");
				TFilename path = get(F_PATH);
				path.add("*.txt");	//files delle testate
				list_files(path, as.rows_array());
				TFilename name;
				FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
				{
					name = *row;
					*row = name.name();
				}
				if (as.run() == K_ENTER)
				{
					f.set(as.row(as.selected()));
				}
			}
			break;
		default:
			break;
	}
  return true;
}


///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TImporta_mov : public TSkeleton_application
{
	virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "ba";}

	TImporta_mov_mask*				  _msk;

//protected:


public:           
  virtual bool create();
  virtual bool destroy();
  virtual void main_loop();
	void build_IVA(TConfig & conf, TArray & rows, TString_array & concg, TArray & impcg);
	void transfer(const TFilename& file);
 
  TImporta_mov() {};
};

void TImporta_mov::build_IVA(TConfig & conf, TArray & rows, TString_array & concg, TArray & impcg)
{
	const int items = rows.items();
	TString paragraph;

	if (items > 0)
	{
		int nrigai = 1;
		int i = 0;
		TString *gcs = (TString *)concg.first_item();
		real imptot = *((real *) impcg.first_item());
		TString4 gruppo = gcs->left(2);
		TString4 conto = gcs->mid(2, 2);
		TString8 sottoconto = gcs->right(6);

		while (i < items)
		{
			TRectype & rec = (TRectype &)rows[i];
			real imp = rec.get(RMI_IMPONIBILE);
			real iva = rec.get(RMI_IMPOSTA);
			if (imp <= imptot)
				i++;
			else
			{
				TCodiceIVA	codiva(rec.get(RMI_CODIVA));
				
				imp -= imptot;
				rec.put(RMI_IMPONIBILE, imp);
				imp = imptot;
				real iv = codiva.imposta(imptot);
				iva -= iv;
				rec.put(RMI_IMPOSTA, iva);
				iva = iv;
			}
			imptot -= imp;
			paragraph.format("%d,%d",LF_RMOVIVA,nrigai++);
			conf.set_paragraph(paragraph);
			conf.set(RMI_CODIVA, rec.get(RMI_CODIVA));
			conf.set(RMI_TIPODET, rec.get(RMI_TIPODET));
			conf.set(RMI_IMPONIBILE, imp.string());
			conf.set(RMI_IMPOSTA, iva.string());
			conf.set(RMI_GRUPPO, gruppo);
			conf.set(RMI_CONTO, conto);
			conf.set(RMI_SOTTOCONTO, sottoconto);
			if (imptot <= 0)
			{
				gcs = (TString *)concg.succ_item();
				if (gcs == NULL)
					break;
				imptot = *((real *) impcg.succ_item());
				gruppo = gcs->left(2);
				conto = gcs->mid(2, 2);
				sottoconto = gcs->right(6);
			}
		}
	}
}

void TImporta_mov::transfer(const TFilename& file)
{
	TFilename outdir(_msk->get(F_PATHOUT));
  TImporta_galileo_recset s(file);
  TProgind pi(s.items(),"Importazione movimenti in corso ...",true,true);
	TConfig * conf = NULL;
	long nmov = - 1;
	int anno = 0;
	TString8 reg;
	TDate dataop;
	int nrigac = 1;
	long ntran = 1L;
	bool iva = false;
	TString4 gruppo;
	TString4 conto;
	TString8 sottoconto;
	TString descr(50);
	const int codes = _msk->get_int(F_ANNOES);
	const long ditta = _msk->get_long(F_CODITTA);
	const TEsercizi_contabili esc;
	TArray rows;
	TArray impcg;
	TString_array concg;

  for (bool ok=s.move_first();ok;ok=s.move_next())
  {
    if (!pi.addstatus(1)) 
      break;
		
		const long dt = s.get(CDDTCM).as_int();

		if (ditta != dt)
			continue;
		const TDate datareg(s.get(DTRGCM).as_int());
		if (datareg.year() == 2009)
			int i = 1;
		const int es = esc.date2esc(datareg);

		if (codes != es)
			continue;
		const int a = s.get(AAPRCM).as_int();
	  const TString8 r = s.get(TPGICM).as_string();
		const TDate d(s.get(DTOPCM).as_int());
		const long n = s.get(NONPCM).as_int();

		if (anno != a || reg != r || dataop != d || n != nmov )
		{
			if (iva && conf != NULL)
				build_IVA(*conf, rows, concg, impcg);
			anno = a;
			reg = r;
			dataop = d;
			nmov = n;


			if (conf != NULL)
				delete conf;
			conf = NULL;
			TFilename temp(outdir);

			temp << '/' << format("%05ld", ntran++);
			temp.ext("ini");
			if (fexist(temp))
				remove_file(temp);
			conf = new TConfig(temp);
			conf->set_paragraph("Transaction"); //setto il paragrafo [Transaction] del file ini
			conf->set("Action","INSERT");
			conf->set("Mode","AUTO");

			conf->set_paragraph("23"); //setto il paragrafo [23] del file ini (testata)
			TString8 codcaus = s.get(CAUSCM).as_string();
			if (atoi(codcaus) != 0)
				codcaus << '0';
			conf->set(MOV_CODCAUS, codcaus);
			conf->set(MOV_DATAREG, datareg.string());
			const int codpag = s.get(CDPGCM).as_int();
			if (codpag != 0)
				conf->set(MOV_CODPAG, format("%03d", codpag));
			
			TDate datadoc(s.get(DTDOCM).as_int());
			
			conf->set(MOV_DATADOC,	datadoc.string());

			TString16 ndoc = s.get(NRDOCM).as_string();
			
			if (ndoc == "0")
				ndoc.cut(0);
			conf->set(MOV_NUMDOC, ndoc);
			conf->set(MOV_STAMPATO, "X");
			conf->set(MOV_REGST, "X");

			descr == s.get(DSUPCM).as_string();
			iva = s.get(TPMVCM).as_string() == "I";

			if (iva)
			{
				TToken_string key(25, ',');

				key.add(s.get(NPARCM).as_int());
				key.add(s.get(AAOPCM).as_int());
				descr << " Part. " << key;
				conf->set(MOV_REG, s.get(TPGICM).as_string());
				conf->set(MOV_PROTIVA, n);
			}
			conf->set(MOV_DESCR, descr);
			nrigac = 1;
			rows.destroy();
			impcg.destroy();
			concg.destroy();
		}

		const TString gcs = s.get(CONTCM).as_string();
		TString4 sez("D");
		
		if (gcs.full())
		{
	    TString8 paragraph;
			real importo = s.get(IMPOCM).as_real();

			if (importo < ZERO)
			{
				importo = -importo;
				sez = "A";
			}
			gruppo = gcs.left(2);
			conto = gcs.mid(2, 2);
			sottoconto = gcs.right(6);
			if (iva)
			{
				TToken_string key;

				key.add(gruppo);
				key.add(conto);
				const TString4 tipocf = cache().get(LF_PCON, key, PCN_TMCF);

				if (tipocf.full())
				{
					conf->set_paragraph("23"); //setto il paragrafo [23] del file ini (testata)
					conf->set(MOV_TIPO, tipocf);  
					conf->set(MOV_CODCF, sottoconto);
					conf->set(MOV_TOTDOC, importo.string());
					paragraph.format("%d,%d",LF_RMOV,nrigac++);
					conf->set_paragraph(paragraph);
					conf->set(RMV_SEZIONE, sez);
					conf->set(RMV_TIPOC, tipocf); 
					conf->set(RMV_IMPORTO, importo.string());
					conf->set(RMV_GRUPPO, gruppo);
					conf->set(RMV_CONTO, conto);
					conf->set(RMV_SOTTOCONTO, sottoconto);
					conf->set(RMV_ROWTYPE, "T");
				}
				else
				{
					concg.add(gcs);
					impcg.add(importo);
				}
			}
			else
			{
				paragraph.format("%d,%d",LF_RMOV,nrigac++);
				conf->set_paragraph(paragraph);
				conf->set(RMV_SEZIONE, sez);
				conf->set(RMV_IMPORTO, importo.string());
				conf->set(RMV_GRUPPO, gruppo);
				conf->set(RMV_CONTO, conto);
				conf->set(RMV_SOTTOCONTO, sottoconto);
			}
		}
		else
			if (iva)
			{
				TString8 paragraph;
				real importo = s.get(IMPOCM).as_real();
				real imposta = s.get(IMPSCM).as_real();

				if (importo < ZERO)
				{
					importo = -importo;
					sez = "A";
				}
				if (imposta < ZERO)  // giusto ?
					imposta = -imposta;

				const real ind = s.get(INDECM).as_real();
				const TString4 codiva = s.get(CDIVCM).as_string();

				if (ind > ZERO && ind < CENTO)
				{
					TRectype rec(LF_RMOVIVA);

					real impind = importo * ind / 100;
					real ivaind = importo * ind / 100;
					impind.round(2);
					ivaind.round(2);
					importo -= impind;
					imposta -= ivaind;
					rec.put(RMI_CODIVA, codiva);
					rec.put(RMI_TIPODET, "9");
					rec.put(RMI_IMPONIBILE, impind.string());
					rec.put(RMI_IMPOSTA, ivaind.string());
					rec.put(RMI_GRUPPO, gruppo);
					rec.put(RMI_CONTO, conto);
					rec.put(RMI_SOTTOCONTO, sottoconto);
					rows.add(rec);
				}
				TRectype rec(LF_RMOVIVA);

				rec.put(RMI_CODIVA, codiva);
				if (ind >= CENTO)
					rec.put(RMI_TIPODET, "9");
				rec.put(RMI_IMPONIBILE, importo.string());
				rec.put(RMI_IMPOSTA, imposta.string());
				rec.put(RMI_GRUPPO, gruppo);
				rec.put(RMI_CONTO, conto);
				rec.put(RMI_SOTTOCONTO, sottoconto);
				rows.add(rec);
			}
	}
	if (conf != NULL)
		delete conf;

	if (yesno_box(FR("Si desidera confermare l'importazione di %ld movimenti"), ntran -1))
	{
		TString app;

		app << "cg2 -0 -i" << outdir << "/*.ini"; 
		TExternal_app primanota(app);
		primanota.run(true);
	}
}


bool TImporta_mov::create()
{
  _msk = new TImporta_mov_mask();
         
  return TSkeleton_application::create();
}

bool TImporta_mov::destroy()
{
	delete _msk;
  return TApplication::destroy();
}

void TImporta_mov::main_loop()
{
  KEY	tasto;
	tasto = _msk->run();
  if (tasto == K_ENTER)
  {
    //genero il nome del file da caricare
    TFilename name = _msk->get(F_PATH);
    name.add(_msk->get(F_NAME));
		transfer(name);
  }   
}


TImporta_mov& app() { return (TImporta_mov&) main_app(); }


int pe0001100 (int argc, char* argv[])
{
  TImporta_mov main_app;
  main_app.run(argc, argv, TR("Importazione contabilit� Galileo"));
  return true;
}