#include "halib.h"
#include "hacnvlib.h"
#include "hacnv300a.h"

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <progind.h>
#include <reprint.h>
#include <reputils.h>
#include <tabutil.h>
#include <utility.h>

#include "../cg/cglib01.h"
#include "../cg/cg2103.h"
#include "../cg/cgsaldac.h"
#include "../cg/cgpagame.h"

#include <scadenze.h>

const char* const APPNAME = TR("Importazione scadenze"); 

///////////////////////////////////////////////////////////
// THardy_scadenze
///////////////////////////////////////////////////////////

class THardy_scadenze : public THardy_transfer
{
  int _anno;              // parametri per la query
protected:
  void conto2billcampo(const TString& hd_tipoc, const TString& hd_key, TBill& conto);
public:
  virtual bool trasferisci();
  THardy_scadenze(const int anno);
};

// calcola conto campo a partire da conto hardy
void THardy_scadenze::conto2billcampo(const TString& hd_tipoc, const TString& hd_key, TBill& conto)
{
  TConfig& ini = config();
  int gr, co;
  long so;
  char tipoc;
  char tipocc = hd_tipoc[0];
  switch (tipocc)
  {      
  case 'S':
    {
      tipoc = ' ';
      hd_key2conto(hd_key, gr, co, so);
    }
    break;
  case 'C':
    {       
      tipoc = 'C';
      so = hd_key2cli(hd_key);
      TToken_string key("C");
      key.add(so);
      const TRectype rec_cf = cache().get(LF_CLIFO, key);
      gr = rec_cf.get_int(CLI_GRUPPO);
      co = rec_cf.get_int(CLI_CONTO);
      if (gr == 0)
      {
        gr = ini.get_int("CLI_GRUPPO", "Parametri");
        co = ini.get_int("CLI_CONTO", "Parametri");
      }
    }
    break;
  case 'F':
    {
      tipoc = 'F';
      so = hd_key2for(hd_key);
      TToken_string key("F");
      key.add(so);
      const TRectype rec_cf = cache().get(LF_CLIFO, key);
      gr = rec_cf.get_int(CLI_GRUPPO);
      co = rec_cf.get_int(CLI_CONTO);
      if (gr == 0)
      {
        gr = ini.get_int("FOR_GRUPPO", "Parametri");
        co = ini.get_int("FOR_CONTO", "Parametri");
      }
    }
    break;
  default:
    {
      tipoc = ' ';
      gr = co = so = 0;
    }
    break;
  }
  conto.set(gr, co, so, tipoc);
}

bool THardy_scadenze::trasferisci()
{
  TString query = "SELECT * FROM dbo.Scadenze WHERE Esercizio=";
  query << _anno;
  query << " AND dbo.Scadenze.FlStato=0 ORDER BY dbo.Scadenze.Esercizio, dbo.Scadenze.Protocollo ";

  TRecordset& recset = create_recordset(query);
  THardy_iterator hi(this);

  int curr_ese = 0;
  int curr_pro = 0;
  const TDate datareg(TODAY);
  TDate datascad, datadoc;
  TString16 numdoc, tipomovimento, idpagamento, curr_tipomov, curr_idpag, codag;
  TString80 descr;
  TImporto importo;
  TBill clifo;
  curr_tipomov = "RD";
  curr_idpag = " ";
  codag = "";
  while (++hi)
  {
    const int esercizio = get_long("Esercizio");
    const int protocollo = get_long("Protocollo");
    if ((esercizio != curr_ese) || (protocollo != curr_pro))
    {
      // se la partita non � a zero, scrivo una scadenza
      if (!importo.is_zero())
      {
        TPartita game(clifo, curr_ese, format("%7d", curr_pro));   
        TRiga_partite& partita = game.new_row();
			  partita.put(PART_TIPOMOV, tm_fattura); 
        int tpm = ini_get_int("hacnv100a.ini", "IdTipoMovimento", curr_tipomov, 1);
			  partita.put(PART_TIPOPAG, tpm);
			  partita.put(PART_TIPOREG, 'E'); 
			  partita.put(PART_DATAREG, datareg); 
			  partita.put(PART_DATADOC, datadoc);
			  partita.put(PART_NUMDOC, numdoc);
        importo.normalize();
  			partita.add(PART_IMPTOTDOC, importo.valore());
	  		partita.put(PART_IMPORTO, importo.valore());    
        partita.put(PART_SEZ, importo.sezione());
        if (descr.empty())
          descr = "RIPRESA SCADENZE APERTE";
        partita.put(PART_DESCR, descr);
		  	TRiga_scadenze& scadenza = partita.new_row(); 
       	scadenza.put(SCAD_DATASCAD, datascad);
        scadenza.put(SCAD_IMPORTO, importo.valore());
       	scadenza.put(SCAD_TIPOPAG, tpm);
       	scadenza.put(SCAD_CODPAG, curr_idpag);
        scadenza.put(SCAD_DESCR, descr);
        scadenza.put(SCAD_CODAG, codag);
        game.write();
      }
      importo.reset();
      curr_ese = esercizio;
      curr_pro = protocollo;
      curr_tipomov = "RD";
      curr_idpag = " ";
      descr.cut(0);
      codag = "";
    }
    const TString& key = get_str("IdConto"); 
    TString4 hdtipoc = get_str("IdContoTp");
    conto2billcampo(hdtipoc, key, clifo);
    datascad = TDate(get_str("DataScadenza"));
    datadoc = TDate(get_str("DataDocumento"));
    numdoc = get_str("NumDocumento");
    numdoc = numdoc.right(7);
    idpagamento = get_str("IdPagamento");
    if (idpagamento.not_empty())
    {
      curr_idpag = idpagamento;
      descr = get_str("Descrizione2");
    }
    tipomovimento = get_str("TipoMovimento");
    if (tipomovimento.not_empty())
      curr_tipomov = tipomovimento;
    if (codag.blank())
      codag = get_str("IdAgente1");
    const TImporto dare('D', get_real("Dare"));
    const TImporto avere('A', get_real("Avere")); 
    importo+=dare;
    importo+=avere;
  }
  // scrivo ultima scadenza se necessario
  // fare una funzione altrimenti guy mi strozza
  if (!importo.is_zero())
  {
    TPartita game(clifo, curr_ese, format("%7d", curr_pro));   
    TRiga_partite& partita = game.new_row();
	  partita.put(PART_TIPOMOV, tm_fattura); 
    int tpm = ini_get_int("hacnv100a.ini", "IdTipoMovimento", curr_tipomov, 1);
	  partita.put(PART_TIPOPAG, tpm);
	  partita.put(PART_TIPOREG, 'E'); 
	  partita.put(PART_DATAREG, datareg); 
	  partita.put(PART_DATADOC, datadoc);
	  partita.put(PART_NUMDOC, numdoc);
    importo.normalize();
		partita.add(PART_IMPTOTDOC, importo.valore());
		partita.put(PART_IMPORTO, importo.valore());    
    partita.put(PART_SEZ, importo.sezione());
    if (descr.empty())
      descr = "RIPRESA SCADENZE APERTE";
    partita.put(PART_DESCR, descr);
  	TRiga_scadenze& scadenza = partita.new_row(); 
   	scadenza.put(SCAD_DATASCAD, datascad);
    scadenza.put(SCAD_IMPORTO, importo.valore());
   	scadenza.put(SCAD_TIPOPAG, tpm);
   	scadenza.put(SCAD_CODPAG, curr_idpag);
    scadenza.put(SCAD_DESCR, descr);
    scadenza.put(SCAD_CODAG, codag);
    game.write();
  }
  return write_enabled();
}

THardy_scadenze::THardy_scadenze(const int anno) : _anno(anno)
{
}

///////////////////////////////////////////////////////////
// TImpScadHardy_mask
///////////////////////////////////////////////////////////

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

public:
  void trasferisci();

  TImpScadHardy_mask();
  virtual ~TImpScadHardy_mask();
};

// Funzione di trasferimento dati da/verso file .ini con lo stesso nome della maschera
// Andrebbe messo in libreria
void TImpScadHardy_mask::serialize(bool bSave)
{
  TFilename n = source_file(); n.ext("ini");  // Construisce il nome del .ini in base al .msk
  TConfig cfg(n, "Main");                     // Crea il file di configurazione
  TString4 id; 
  for (int i = fields()-1; i >= 0; i--)       // Scandisce tutti i campi della maschera ...   
  {
    TMask_field& f = fld(i);
    if (f.active() && f.is_loadable())        // ... selezionando solo quelli editabili
    {
      id.format("%d", f.dlg());
      if (bSave)                              // A seconda del flag di scrittura ... 
        cfg.set(id, f.get());                 // ... o scrive sul .ini 
      else 
        f.set(cfg.get(id));                   // ... o legge dal .ini
    }
  }
}

void TImpScadHardy_mask::trasferisci()
{
  TString query_header;
  query_header << "ODBC(" << get(F_DSN) << ',' << get(F_USR) << ',' << get(F_PWD) << ")\n";

  const int anno = get_int(F_ANNO);
  if (anno!=0)
  {
    THardy_log log;
    THardy_scadenze pc(anno);
    pc.init(TR("Scadenze aperte"), query_header, log);
    pc.trasferisci();
  }
}

bool TImpScadHardy_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {
  case DLG_OK:
    if (e == fe_button)
      serialize(true);
    break;
  default:
    break;
  }
  return true;
}

TImpScadHardy_mask::TImpScadHardy_mask() : TAutomask("hacnv300a")
{
  serialize(false);
}

TImpScadHardy_mask::~TImpScadHardy_mask()
{ }

///////////////////////////////////////////////////////////
// TImpScadHardy
///////////////////////////////////////////////////////////

class TImpScadHardy : public TSkeleton_application
{
protected:
  virtual void main_loop();
};

void TImpScadHardy::main_loop()
{
  TImpScadHardy_mask mask;
  while (mask.run() == K_ENTER)
    mask.trasferisci();
}

int hacnv300(int argc, char* argv[])
{
  TImpScadHardy ih;
  ih.run(argc, argv, APPNAME);
  return 0;
}