#include <progind.h>
#include <recset.h>
#include <textset.h>
#include <utility.h>

#include "pd6342.h"
#include "pd6342200a.h"

#include "../ca/movana.h"
#include "../ca/rmovana.h"
#include "../ca/calib01.h"
#include "../ca/calib02.h"

class TImporta_da_BCS_rec : public TAS400_recordset
{
public:
	TImporta_da_BCS_rec(const char* filename);
};

TImporta_da_BCS_rec::TImporta_da_BCS_rec(const char* filename)
                   : TAS400_recordset(TString("AS400(130)\n") << filename)
{
	create_field("ANNO",      0, 4,  _intfld);                //anno di competenza
  create_field("MESE",      5, 2,  _intfld);                //mese di competenza
  create_field("GIORNO",    8, 2,  _intfld);                //giorno di competenza
	create_field("CODCOSTO", 11, 15, _alfafld);               //centro di costo
  create_field("PCONTI",   27, 15, _alfafld);               //centro di ricavo (o piano dei conti)
	create_field("IMPORTO",  43, 12, _realfld);               //importo lordo della prestazione moltiplicato per quantit�
	create_field("SEGNO",    56, 1,  _alfafld);               //segno importo (+ o -)
	create_field("PROV",     59, 3,  _alfafld, true, "FAT");  //provenienza (valore fisso FAT)
	create_field("IDPROC",   62, 15, _alfafld);               //ID della procedura inviante
	create_field("CODPRES",  78, 8,  _alfafld);               //codice della prestazione
  create_field("DESPRES",  87, 40, _alfafld);               //descrizione della prestazione
}

static int sort_by_date(const TObject** o1, const TObject** o2)
{
  const TString& r1 = *(TString*)*o1;
  const TString& r2 = *(TString*)*o2;

  const long d1 = (atol(r1.left(4)) * 10000) + (atol(r1.mid(5, 2)) * 100) + (atol(r1.mid(8, 2)));
  const long d2 = (atol(r2.left(4)) * 10000) + (atol(r2.mid(5, 2)) * 100) + (atol(r2.mid(8, 2)));;

  return d1 - d2;
}


///////////////////////////////////////////////////////////
//  MASCHERA
///////////////////////////////////////////////////////////
class TImporta_da_BCS_msk : public TAutomask
{
protected:


  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); 
	
public:
  TImporta_da_BCS_msk();
  virtual ~TImporta_da_BCS_msk() {}
};

bool TImporta_da_BCS_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  /*switch(o.dlg())
  {
  default:
    break;
  }*/
  return true;
}

TImporta_da_BCS_msk::TImporta_da_BCS_msk() : TAutomask("pd6342200a")
{
}

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

class TImporta_da_BCS_app : public TSkeleton_application
{
  TImporta_da_BCS_msk* _mask;
  TConfig*					   _configfile;
  bool _has_ca;

protected:
  virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "ca";}

  virtual bool create(void);
  virtual bool destroy(void);

  void sposta_file(const TString& file);
  void genera_movana(const TFilename& file);

  void ini2mask();
  void mask2ini();

  bool elabora();

public:
  virtual void main_loop();

};

void TImporta_da_BCS_app::mask2ini()
{
	//carica i parametri del file di configurazione
	_configfile->set_paragraph("MAIN");
  for (int i = 0; i < _mask->fields() ; i++)
	{
		TMask_field& f = _mask->fld(i);
		const TFieldref* fr = f.field();
		if (fr != NULL)
			_configfile->set(fr->name(), f.get());
	}
}

void TImporta_da_BCS_app::ini2mask()
{
	//carica i parametri del file di configurazione
	_configfile->set_paragraph("MAIN");
  for (int i = 0; i < _mask->fields() ; i++)
	{
		TMask_field& f = _mask->fld(i);
		const TFieldref* fr = f.field();
		if (fr != NULL)
		{
			const TString& val = _configfile->get(fr->name());
			f.set(val);
		}
	}
}

void TImporta_da_BCS_app::sposta_file(const TString& file)
{
  TFilename fileori = file;
  TFilename path = fileori.path();
  path.add("elaborati");
  make_dir(path);

  TString strname;
  strname.format("%06d_%06d_%s", TDate(TODAY).date2ansi(), daytime(), (const char*)fileori.name());  
  TFilename filedest = path;
  filedest.add(strname);
  fcopy(fileori, filedest);
  fileori.fremove();
  
}

void TImporta_da_BCS_app::genera_movana(const TFilename& file)
{
  TLocalisamfile fmov(LF_MOVANA);  
  
  TDate dataold(NULLDATE);
  
  const TDate oggi(TODAY);
  const TString4 codcau = _mask->get(F_CODCAU);

  TAnal_mov ana(0);

  TImporta_da_BCS_rec recset(file);
  recset.sort(sort_by_date);

  TImporto totale;

  TProgind pi(recset.items(), "Importazione in corso...", true, true);

  for(bool ok = recset.move_first(); ok; ok = recset.move_next())
  {
    if (!pi.addstatus(1)) 
		  break;
    
    const int anno   = recset.get("ANNO").as_int();

    if(anno <= 0)
      continue;

    const int mese   = recset.get("MESE").as_int();
    const int giorno = recset.get("GIORNO").as_int();
    const TDate data(recset.get("GIORNO").as_int(), recset.get("MESE").as_int(), anno);

    if(data != dataold)
    {
      if (!ana.empty())
      {
        ana.put(MOVANA_SEZIONE, totale.sezione());
        ana.put(MOVANA_TOTDOC,  totale.valore());
        ana.rewrite_write(fmov);

        totale.reset();
      }
      
      ana.zero();
      ana.put(MOVANA_ANNOES,    anno);
      ana.put(MOVANA_DATAREG,   oggi);
      ana.put(MOVANA_DATACOMP,  data);
      ana.put(MOVANA_CODCAUS,   codcau);
      ana.put(MOVANA_DESCR,     "Movimento Importato");
      ana.put(MOVANA_TRASFERITO, true);

      dataold = data;
    }

    TRectype& riga = ana.new_row();

    TString16 impstr;
    impstr << recset.get("SEGNO").as_string()[0] << recset.get("IMPORTO").as_string();
    const real imp(impstr);

    TImporto importo('A', imp);
    importo.normalize();

    TString16 cod = recset.get("CODPRES").as_string();  cod.trim();
    TString80 descrizione;
    descrizione << cod << '-' << recset.get("DESPRES").as_string();

    TString80 codcosto = recset.get("CODCOSTO").as_string();

    //il codcosto va formattato in base alla configurazione dell'analitica
    const TMultilevel_code_info& cdcinfo = ca_multilevel_code_info(LF_CDC);
    const TMultilevel_code_info& cominfo = ca_multilevel_code_info(LF_COMMESSE);
    const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
    
    int par_level;
    int from = 0;
    int len = 0;

    //centro di costo
    switch(cdcinfo.parent())
    {
    case LF_COMMESSE: par_level = cominfo.levels(); break;
    case LF_FASI    : par_level = fasinfo.levels(); break;
    default         : par_level = 0;                break;
    }
    const int livcdc = cdcinfo.levels() - par_level;

    if(livcdc > 0)
    {
      for(int i = 0; i < livcdc; i++)
        len += cdcinfo.len(i);
      riga.put(RMOVANA_CODCCOSTO, codcosto.mid(from, len));
    }
    from += len;
    len = 0;

    //commesse
    switch(cominfo.parent())
    {
    case LF_CDC  : par_level = cdcinfo.levels(); break;
    case LF_FASI : par_level = fasinfo.levels(); break;
    default      : par_level = 0;                break;
    }
    const int livcom = cominfo.levels() - par_level;
    
    if(livcom > 0)
    {
      for(int i = 0; i < livcom; i++)
        len += cominfo.len(i);
      riga.put(RMOVANA_CODCMS, codcosto.mid(from, len));
    }
    from += len;
    len = 0;

    //fasi
    switch(fasinfo.parent())
    {
    case LF_CDC      : par_level = cdcinfo.levels(); break;
    case LF_COMMESSE : par_level = cominfo.levels(); break;
    default          : par_level = 0;                break;
    }
    const int livfas = fasinfo.levels() - par_level;

    if(livfas > 0)
    {
      for(int i = 0; i < livfas; i++)
        len += fasinfo.len(i);
      riga.put(RMOVANA_CODFASE, codcosto.mid(from, len));
    }
    from += len;

    riga.put(RMOVANA_ANNOES, anno);
    riga.put(RMOVANA_SEZIONE, importo.sezione());
    riga.put(RMOVANA_DATACOMP, data);
    riga.put(RMOVANA_CODCONTO, recset.get("PCONTI").as_string());
    riga.put(RMOVANA_DESCR, descrizione);
    riga.put(RMOVANA_IMPORTO, importo.valore());

    totale += importo;
  }

  if (!ana.empty())
  {
    ana.put(MOVANA_SEZIONE, totale.sezione());
    ana.put(MOVANA_TOTDOC,  totale.valore());
    ana.rewrite_write(fmov);
  }  
}


bool TImporta_da_BCS_app::elabora()
{
  TFilename file = _mask->get(F_FILE);

  if(file.exist())
  {
    genera_movana(file);
    sposta_file(file);
  }
  else
  {
    error_box(TR("Il file selezionato non esiste; si prega di controllare"));
    return false;
  }

  return true;
}

bool TImporta_da_BCS_app::create()
{      
	_configfile = new TConfig("pd6342conf.ini", "MAIN");
  return TSkeleton_application::create();
}

bool TImporta_da_BCS_app::destroy()
{             
 	delete _configfile;
  return TSkeleton_application::destroy();
}

void TImporta_da_BCS_app::main_loop()
{

  _mask = new TImporta_da_BCS_msk;

  ini2mask();
	
  if (_mask->run() == K_ENTER)
  {		
		mask2ini();
    if (elabora())
		  message_box(TR("Importazione righe terminata"));
  }
}

int pd6342200(int argc, char* argv[])
{
  TImporta_da_BCS_app imp_anal;
  imp_anal.run(argc, argv, TR("Importa Movimenti Analitici"));
  return 0;
}