#include <applicat.h>
#include <automask.h>
#include <dongle.h>
#include <execp.h>
#include <modaut.h>
#include <prefix.h>
#include <progind.h>
#include <relation.h>

#include <nditte.h>
#include <partite.h>
#include <scadenze.h>
#include <pagsca.h>
#include <saldi.h>

#include "baeur.h"
#include "baeur10.h"
#include "baeur11.h"

#include "../cg/cglib01.h"
#include "../mg/mag.h"
#include "../mg/movmag.h"
#include "../mg/rmovmag.h"
#include "../mg/mglib.h"

///////////////////////////////////////////////////////////
// Main app
///////////////////////////////////////////////////////////

class TEuro01_app : public TEuro_app
{ 
  TAssoc_array _schede_passate;
  
protected:
  void convert_saldi(const TDate& adozione, const TBill& arrotino);
  void convert_partite();
  
  virtual bool create();

public:
  KEY convert_firm(long ditta);
  bool has_mag() const;
  bool has_percip() const;
  TAssoc_array & passate() { return _schede_passate;}

  virtual void main_loop();
};

inline TEuro01_app& app() { return (TEuro01_app&)main_app(); }

///////////////////////////////////////////////////////////
// Step 3
///////////////////////////////////////////////////////////

class TEuro03_mask : public TAutomask
{ 
  void fill_ditte();
  
public:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  TEuro03_mask() : TAutomask("baeur10") { }
};

void TEuro03_mask::fill_ditte()
{
  TFilename lit, eur;
  app().get_aree_dati(lit, eur);

  TRelation rel(LF_NDITTE);
  TCursor cur(&rel); 
  const TRectype& curr = rel.curr();
  const long items = cur.items();
  cur.freeze();
  
  TSheet_field& ditte = sfield(F10_DITTE);
  ditte.destroy();
  
  for (cur = 0L; cur.pos() < items; ++cur)
  {
    const long ditta = curr.get_long(NDT_CODDITTA);
    if (prefix().exist(ditta))
    {
      TToken_string& row = ditte.row(-1);
      row.add(ditta);
      row.add(curr.get(NDT_RAGSOC));
      
      TFilename firm; 
      firm.format("%s/%05ldA", (const char*)eur, ditta);
      
      COLOR col = COLOR_BLACK;
      if (firm.exist())
      {
        firm.add("prassid.ini");
        TConfig ini(firm, "Euro");
        TString16 dde = ini.get("DataAdozione");
        if (dde.empty())
        {
          row.add("Creata direttamente in Euro");
          col = COLOR_RED;
        }
        else
        {   
          TString str;
          if (ini.get("ConversionOK").not_empty())
          {
            str << "Adotta l'Euro dal " << dde;
            col = COLOR_GREEN;
          }
          else
          {
            str << "Conversione incompleta: ripetere l'operazione";
            col = COLOR_CYAN;
          }
          row.add(str);
        }
      }
      else
      {
        row.add("Non presente in Euro");
        if (field(F10_DITTA).empty())
        {
          set(F10_DITTA, ditta);
          set(F10_RAGSOC, row.get(1));
        }
      }
      if (col != COLOR_BLACK)
      {
        int i = ditte.items()-1;
        ditte.set_back_and_fore_color(col, -1, i);
      }
    }
  }
  
  ditte.force_update();
}

bool TEuro03_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {              
  case F10_DITTA:
    if (e == fe_modify || e == fe_close)
    {
      TSheet_field& s = sfield(F10_DITTE);
      TEdit_field& f = efield(F10_DITTA);
      const long ditta = atol(o.get());
      for (int r = s.items()-1; r >= 0; r--)
      {
        TToken_string& row = s.row(r);
        const long d = row.get_long(0);
        if (d == ditta)
        {
          set(F10_RAGSOC, row.get());
          break;
        }
      }
      if (r < 0)
        return error_box(f.get_warning());
    }
    break;
  case F10_DITTE:
    if (e == fe_init)
      fill_ditte();
    if (e == se_query_add || e == se_query_del)
      return FALSE;
    if (e == se_enter)  
    {
      TSheet_field& s = sfield(F10_DITTE);
      TToken_string& r = s.row((int)jolly);
      set(F10_DITTA, r.get(0));
      set(F10_RAGSOC, r.get());
    }
    break;
  default: 
    break;
  }
  return TRUE;
} 

///////////////////////////////////////////////////////////
// Step 4 - Conversione ditta
///////////////////////////////////////////////////////////

class TEuro11_mask : public TAutomask
{ 
public:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  TEuro11_mask() : TAutomask("baeur11") { }
};

bool TEuro11_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {
  case F11_ADOZIONE:
    if (e == fe_modify || e == fe_close)
    {
      TEsercizi_contabili esc;
      TDate d = o.get();
      if (!d.ok())
        return error_box("E' necessario specificare la data di adozione dell'Euro");
      const int codesc = esc.date2esc(d);
      if (codesc <= 0)
        return error_box("E' necessario aprire l'esercizio per l'anno %d", d.year());
      if (d.day() != 1)
        warning_box("Si consiglia di specificare una data di inizio mese/trimestre");
      if (d != esc[codesc].inizio())
      {
        if (app().has_percip() && get_bool(F11_SOLOAPERTE))
          return error_box("Se sono presenti percipienti e si convertono solo le schede aperte\nla conversione deve essere effettuata a inizio esercizio.");
        if (d != esc[codesc].inizio() && app().has_mag())
        {   
          const int prevesc = esc.date2prevesc(d);
          if (prevesc > 0)
          {
            const TDate& cm = esc[prevesc].chiusura_mag();
            if (!cm.ok())
             return error_box("E' necessario chiudere il magazzino nell'esercizio %d", prevesc);
          }
        }
      }
    }
    break;
    case F11_DIFF_S:
      if (e == fe_close && o.empty())
      {
        TLocalisamfile pcon(LF_PCON);
        if (pcon.first() == NOERR)
          return error_box("E' necessario specificare un conto per gli arrotondamenti");
      }
      break;
    default: break;
  }
  return TRUE;
}

///////////////////////////////////////////////////////////
// Conversione ditta
///////////////////////////////////////////////////////////

struct TMag_data
{  
  int _annoesrif;
  TString _fields;
  TString _zero_fields;
};

struct TPerc_data
{  
  bool  _soloaperte;
  TDate _adozione;
};

static bool mag_handler(TRectype& rec, void* jolly)
{          
  TMag_data& mag = *(TMag_data*)jolly;
  const int annoesrif = *((int *) jolly);
  const int annoes = rec.get_int(MAG_ANNOES);
  if (annoes >= mag._annoesrif)
    zero_import(rec, mag._zero_fields);
  else
    convert_import(rec, mag._fields);
  return TRUE;
}

static bool movmag_handler(TRectype& rec, void* jolly)
{          
  TMag_data& mag = *(TMag_data*)jolly;
  const int annoesrif = *((int *) jolly);
  const int annoes = rec.get_int(MOVMAG_ANNOES);
  return annoes >= annoesrif;  
}

static bool righemovmag_handler(TRectype& rec, void* jolly)
{          
  TMag_data& mag = *(TMag_data*)jolly;
  const int annoesrif = *((int *) jolly);
  TString16 key; key << rec.get_long(RMOVMAG_NUMREG);
  const int annoes = atoi(cache().get(LF_MOVMAG, key, MOVMAG_ANNOES));
  return annoes >= annoesrif;  
}

struct TTab_data
{
  int _codes_rif, _annoes_rif;
};

static bool perc_handler(TRectype& rec, void* jolly)
{
  return app().get_firm() ==  rec.get_long("CODDITTA");
}

static bool sch_handler(TRectype& rec, void* jolly)
{            
  bool ok = perc_handler(rec, jolly);
  if (ok)  
  {               
    TPerc_data & d = *(TPerc_data*)jolly;
    
    if (d._soloaperte)
    {
      real pagato = ZERO;
      TRectype keypag(LF_RPAG);
      TLocalisamfile sch(LF_SCPERC);
      TRectype recsch(rec);
      recsch.read(sch);
      real totale = recsch.get_real("COMPENSO");
  
      totale += recsch.get_real("SPESE");
      keypag.put("CODDITTA", rec.get("CODDITTA"));
      keypag.put("TIPOA", rec.get("TIPOA"));
      keypag.put("CODANAGR", rec.get("CODANAGR"));
      keypag.put("NPROG", rec.get("NPROG"));
  
      TRecord_array pag_scheda(keypag, "NRIGA");
      const int rows = pag_scheda.rows();           
      TDate& adozione = d._adozione;
  
      for (int i = 1 ; i <= rows; i++)
      {
        const TRectype & rpag = pag_scheda[i];
        const TDate datapag = rpag.get_date("DATAPAG");
        const int rver = rpag.get_int("NUMVERS");
  
        if (datapag <= adozione && rver > 0) 
        {
          pagato += rpag.get_real("COMPENSO");
          pagato += rpag.get_real("SPESA");
        }
        
      }
      ok = totale > pagato;
    }
    if (ok)
    {
      TString80 key(rec.get("CODDITTA"));
      key << "|" << rec.get("TIPOA");
      key << "|" << rec.get("CODANAGR");
      key << "|" << rec.get("NPROG");
      app().passate().add(key, key);
    }
    
  }
  return ok;
}

static bool to_sch_handler(TRectype& rec, void* jolly)
{            
  bool ok = perc_handler(rec, jolly);
  if (ok)  
  {                                                  
    TString80 key(rec.get("CODDITTA"));

    key << "|" << rec.get("TIPOA");
    key << "|" << rec.get("CODANAGR");
    key << "|" << rec.get("NPROG");

    ok = app().passate().objptr(key) != NULL;
  }
  return ok;
}

static bool tab_handler(TRectype& rec, void* jolly)
{
  const TString& cod = rec.get("COD");

  if (cod == "CAM")
    return FALSE;

  if (cod == "REG")
  {
    TTab_data* data = (TTab_data*)jolly;
    const int annoes = atoi(rec.get("CODTAB").left(4));
    zero_import(rec, "R0|R1|R2");
    return annoes >= data->_annoes_rif;  
  }
  if (cod == "SPP" || cod == "PRS")
  {
    const TString16 val = rec.get("S4");
    if (is_firm_value(val))
    {
      rec.zero("S4");
      convert_import(rec, "R0");
    }
    else
    {
      if (is_euro_value(val))
        rec.zero("S4");
    }
    return TRUE;    
  }
  if (cod == "RFA")
  {
    zero_import(rec, "R1|R2");
    return TRUE;
  }
  if (cod == "LAM" || cod == "LIM" || cod == "PIM" || cod == "PUM" || cod == "PAM" || 
      cod == "POM" || cod == "PLM" || cod == "PPA" || cod == "PRM")
    return FALSE;

  return TRUE;
}

static bool conv_condv(TRectype& rec, void* jolly)
{
  const TString16 val = rec.get("CODVAL");
  
  if (is_firm_value(val) || is_euro_value(val))
  {
    rec.zero("CODVAL");
    rec.zero("CAMBIO");
    rec.zero("CONTROEURO");
  }
  else
    if (!rec.get_bool("CONTROEURO"))
    {
      real contro_change = EURO / rec.get_real("CAMBIO");
      rec.put("CAMBIO", contro_change);
      rec.put("CONTROEURO", "X");
    }
  return TRUE;  
}

static bool conv_rcondv(TRectype& rec, void* jolly)
{
  TString80 key;
  
  key << rec.get("TIPO");
  key << "|" << rec.get("CATVEN");
  key << "|" << rec.get("TIPOCF");
  key << "|" << rec.get("CODCF");
  key << "|" << rec.get("COD");
  
  const TString16 val = cache().get(LF_CONDV, key, "CODVAL");
  
  if (is_firm_value(val))
    convert_import(rec, "PREZZO|PROMAGGIO", TRUE);
  return TRUE;  
} 

bool TEuro01_app::has_mag() const
{                            
  TConfig c(CONFIG_DITTA, "mg");
  bool yes = c.get_bool("GESMAG") && dbf_exists(LF_MOVMAG);
  if (yes)
  {
    TLocalisamfile mm(LF_MOVMAG);
    yes = mm.first() == NOERR;
  }
  return yes;
}

bool TEuro01_app::has_percip() const
{                            
  bool yes = dbf_exists(LF_SCPERC);
  if (yes)
  {
    TLocalisamfile sp(LF_SCPERC);
    yes = sp.first() == NOERR;
  }

  return yes;
}

KEY TEuro01_app::convert_firm(long ditta)
{          
  TFilename lit, eur;
  get_aree_dati(lit, eur);
  prefix().set_studio(lit, ditta);

  TString16 firm; firm.format("%05ldA", ditta);
  TFilename litf = lit; litf.add(firm);
  TFilename eurf = eur; eurf.add(firm);
  
  TFilename europrassid;
  europrassid = eurf; europrassid.add("prassid.ini");
  
  bool already_present = eurf.exist();
  if (already_present)
  {
    TConfig prassid(europrassid, "Euro");
    already_present = prassid.get("ConversionOK").not_empty();
  }
  
  bool do_copy    = !already_present;
  bool do_saldi   = !already_present;
  bool do_partite = !already_present;
  bool do_vendite = !already_present;
  bool do_magazzino = !already_present;
  bool do_percip = !already_present;
  bool solo_aperte = FALSE;

  TDate adozione;
  TBill arrotino;

  KEY k = K_ENTER;
  if (k == K_ENTER)
  {
    TEuro11_mask m;
    m.set(F11_DITTA, ditta, TRUE);
    m.set(F11_DATI, lit);
    m.set(F11_DATIE, eur);
    m.set(F11_COPY, do_copy ? "X" : "");
    m.set(F11_SALDI, do_saldi ? "X" : "");
    m.set(F11_PARTITE, do_partite ? "X" : "");
    m.set(F11_VENDITE, do_vendite ? "X" : "");
    m.set(F11_MAGAZZINO, do_magazzino ? "X" : "");
    m.set(F11_PERCIPIENTI, do_percip ? "X" : "");
    
    if (already_present)
    {
      TConfig prassid(europrassid, "Euro");
      adozione = prassid.get("DataAdozione");
      m.set(F11_ADOZIONE, adozione);
    }
    m.enable(-1, already_present);  // Abilita i vari checkbox

    if (load_round_bill(arrotino))
      arrotino.set(m, F11_DIFF_G, F11_DIFF_C, F11_DIFF_S);
    else  
    {
      m.reset(F11_DIFF_G);
      m.reset(F11_DIFF_C);
      m.reset(F11_DIFF_S);
    }
    
    k = m.run();
    adozione = m.get(F11_ADOZIONE);
    arrotino.get(m, F11_DIFF_G, F11_DIFF_C, F11_DIFF_S);
    do_copy = m.get_bool(F11_COPY);
    do_saldi = m.get_bool(F11_SALDI);
    do_partite = m.get_bool(F11_PARTITE);
    do_vendite = m.get_bool(F11_VENDITE);
    do_magazzino = m.get_bool(F11_MAGAZZINO);
    do_percip = m.get_bool(F11_PERCIPIENTI);
    solo_aperte = m.get_bool(F11_SOLOAPERTE);
  }
  if (k == K_ENTER)
  {
    if (already_present && !yesno_box("Si conferma la sovrascrittura della ditta %ld in Euro?", ditta))
      return k;
      
    TEsercizi_contabili esc;
    const int codes_rif = esc.date2prevesc(adozione);
    const int annoes_rif = adozione.year()-1;
      
    TTab_data data;
    data._codes_rif = codes_rif;
    data._annoes_rif = annoes_rif;
    
    if (do_copy)  
    {                    
      TCurrency::force_cache_update();  // Chiude cache valute     
      prefix().set(NULL);               // Chiude files ditta
      copy_dir(litf, eurf);
      
      if (adozione.ok())  // Dummy test
      {
        TFilename ini = eurf; ini.add("prassid.ini");
        TConfig prassid(ini, "Euro");
        prassid.set("DataAdozione", adozione.string());
      }
      save_round_bill(arrotino);
      
//      prefix().set(".");  // Riapre files ditta
      set_firm(ditta);
      
      convert_file(LF_TAB, NULL, NULL, NULL, tab_handler, (void*)&data);

      if (is_firm_file(LF_CLIFO))
      {
        convert_file(LF_CLIFO, NULL, "FIDO", NULL, NULL);
        convert_file(LF_CFVEN, "IMPMINEFF", "MINORD|MAXORD", NULL, NULL);
      }
      
      zap_file(LF_MOV, TRUE);     // Cancella movimenti di prima nota dell'area euro
      zap_file(LF_RMOV, TRUE);    // Cancella righe di prima nota dell'area euro
      zap_file(LF_RMOVIVA, TRUE); // Cancella righe iva dell'area euro
 
      zap_file(LF_INTRA, TRUE);     
      zap_file(LF_RINTRA, TRUE);     
      zap_file(LF_RIEPRETT, TRUE);     
    }
    
    if (do_saldi)
    {                                    
      const int eser = esc.date2esc(adozione);
      const TDate iniz_eser = esc[eser].inizio();

      if (adozione == iniz_eser)
      {
        convert_saldi(adozione, arrotino); // Converti saldi anno precedente 
      }
      else
      {
        zap_file(LF_SALDI, TRUE);
        
        TString16 cmd; cmd.format("baeur -2 %ld", ditta);
        TExternal_app app(cmd); // Conversione saldi infrannuale
        app.run();
      }
    }

    if (do_partite)
      convert_partite();                 // Converti partite

    if (do_vendite)
    {
      zap_file(LF_REFFETTI, TRUE);
      zap_file(LF_EFFETTI, TRUE);
      zap_file(LF_CESS, TRUE);
      
      zap_file(LF_PROVV, TRUE);

      zap_file(LF_DOC, TRUE);
      zap_file(LF_RIGHEDOC, TRUE);     

      convert_file(LF_ANAMAG, NULL, NULL, "COSTSTD|ULTCOS1|ULTCOS2|VALSTATUN");
      convert_file(LF_UMART, NULL, NULL, "PREZZO");
      
      // cvrt condv codval cambio
      // cvrt rcondv prezzo
      convert_file(LF_RCONDV, NULL, NULL, NULL, conv_rcondv);
      convert_file(LF_CONDV, NULL, NULL, NULL, conv_condv);
      convert_file(LF_SVRIEP, "VALORE");
    }
 
    if (do_magazzino)
    {
      TMag_data mag;
      mag._annoesrif = esc.date2esc(adozione);
      mag._zero_fields << "RIM|VALRIM|ACQ|VALACQ|ENT|VALENT|VEN|VALVEN|USC|VALUSC|GIAC|ORDF|VALORDF|";
      mag._zero_fields << "ORDC|VALORDC|INCL|ACL|PRODCOMP|PRODFIN|NLABEL|NDIST|SCARTI|VALSCARTI|";
      mag._zero_fields << "USER1|USERVAL1|USER2|USERVAL2|USER3|USERVAL3|";
      mag._zero_fields << "USER4|USERVAL4|USER5|USERVAL5|USER6|USERVAL6";
      
      mag._fields << "VALRIM|VALACQ|VALENT|VALVEN|VALUSC|VALORDF|VALORDC|VALSCARTI|";
      mag._fields << "USERVAL1|USERVAL2|USERVAL3|USERVAL4|USERVAL5|USERVAL6";
      
      convert_file(LF_MAG, "", "ORDC|VALORDC|ORDF|VALORDF", NULL, mag_handler, (void*)&mag);
      convert_file(LF_MOVMAG, NULL, NULL, NULL, movmag_handler, (void*)&mag);
      convert_file(LF_RMOVMAG, NULL, NULL, "PREZZO", righemovmag_handler, (void*)&mag);

      convert_file(LF_STOMAG, NULL, NULL, "VALORE|ULTCOS1|ULTCOS2|COSTSTD|COSTOMEDIO|PRZLIST");     
      convert_file(LF_DIST, NULL, NULL, "PREZZO");
      
      if (dbf_exists(LF_ANAMAG) && dbf_exists(LF_STOMAG) && dbf_exists(LF_MOVMAG))
      {
        TExternal_app app("baeur -6 S");
        app.run();
      }
    }

    if (do_percip)
    {                           
      TString16 filter;
      filter << "CODDITTA=" << get_firm();
    
      TLocalisamfile rp(LF_RPAG);
      TPerc_data d;
      
      d._soloaperte = solo_aperte;
      d._adozione = adozione;
      _schede_passate.destroy();  
      convert_file(LF_PERC, "FATTBIL", NULL, NULL, perc_handler, NULL, filter);
      convert_file(LF_SCPERC,"COMPENSO|SPESE|IVA|TOTALE|TOTRIT|RITSOC|RITOPE|RITVER", NULL, NULL, sch_handler, (void*)&d, filter);
      convert_file(LF_RVER, "RITENUTA", NULL, NULL, to_sch_handler, NULL, filter);
      TString flds;
      
      flds << "IMPONIBILE|RITENUTA|COMPENSO|NETTO|SPESA|CTSSNPERC|CTSSNCOMP|RITLORDA|CONTROBB|DETFAMIL|DETLAVDIP|TOTDET|";
      flds << "IMPCPA|SOMREGCONV|UTPAGATI|UTSPETT|RITUTPAG|RITUTSPE|SOMNSRIT|AMMLORDO|QUOTAPROV|IMPNETTO|COMNETTO";
      convert_file(LF_RPAG, flds, NULL, NULL, to_sch_handler, NULL, filter);
    }
    if (adozione.ok())  // Dummy test
    {
      TConfig prassid(europrassid, "Euro");
      prassid.set("ConversionOK", "X");
    }
  }
  
  return k;
}

///////////////////////////////////////////////////////////
// Conversione saldi
///////////////////////////////////////////////////////////

struct TSaldi_data
{  
  int _annoes;
  TBill _arrot;
  TImporto _sld;
};

static bool saldi_handler(TRectype& rec, void* jolly)
{ 
  TSaldi_data& sld = *(TSaldi_data*)jolly;
  const int annoes = rec.get_int(SLD_ANNOES);
  if (annoes == sld._annoes)
  {
    const TImporto iniz(rec.get_char(SLD_FLAGSALINI), rec.get_real(SLD_SALDO));
    const TImporto pdare('D', rec.get_real(SLD_PDARE));
    const TImporto pavere('A', rec.get_real(SLD_PAVERE));
    TImporto saldo = iniz; saldo += pdare; saldo += pavere; 
    if (!saldo.is_zero())
    {
      saldo.normalize();
      rec.put(SLD_FLAGSALINI, saldo.sezione());
      rec.put(SLD_SALDO, saldo.valore());
      convert_import(rec, SLD_SALDO);
      zero_import(rec, "PDARE|PAVERE|PDAREPRO|PAVEREPRO|FLAGSALFIN|SALDOFIN|DATAULMOV|NUMULTMOV");
      sld._sld += TImporto(saldo.sezione(), rec.get_real(SLD_SALDO));  // Somma saldo in euro
      return TRUE;
    }
  }  
  
  return FALSE;           
}

void TEuro01_app::convert_saldi(const TDate& adozione, const TBill& arrotino)
{
  TEsercizi_contabili esc;

  TSaldi_data sld;
  sld._annoes = esc.date2prevesc(adozione);
  sld._arrot = arrotino;
  convert_file(LF_SALDI, NULL, NULL, NULL, saldi_handler, &sld);
  
  TImporto& saldo = sld._sld;
  saldo.valore().round(2);
  if (!saldo.is_zero())
  {       
    TLocalisamfile saldi_lire(LF_SALDI); // Open trc
    TEuroisamfile saldi(LF_SALDI, TRUE);
  
    TRectype& curr = saldi.curr();
    curr.zero();
    curr.put(SLD_ANNOES, sld._annoes);
    curr.put(SLD_GRUPPO, arrotino.gruppo());
    curr.put(SLD_CONTO, arrotino.conto());
    curr.put(SLD_SOTTOCONTO, arrotino.sottoconto());
    
    saldo.normalize();
    saldo.swap_section();
    curr.put(SLD_FLAGSALINI, saldo.sezione());
    curr.put(SLD_SALDO, saldo.valore());
    saldi.write();
  }
}

///////////////////////////////////////////////////////////
// Conversione partite
///////////////////////////////////////////////////////////

struct TSaldac_data
{ 
  real _totrate;
};

bool partite_handler(TRectype& rec, void* jolly)
{
  if (rec.get_bool(PART_CHIUSA) || rec.get_int(PART_NRIGA) == 9999)
    return FALSE;
    
  TSaldac_data* data = (TSaldac_data*)jolly;
  
  const TString16 codval = rec.get(PART_CODVAL);
  if (::is_firm_value(codval))
  {
    convert_import(rec, PART_ABBUONI);
    zero_import(rec, "CODVAL|IMPORTOVAL|DIFFCAM");
  } else
  if (::is_euro_value(codval))
  {
    zero_import(rec, "CODVAL|IMPORTOVAL|DIFFCAM");
  } else
  if (::is_true_value(codval))
  {
    const real impval = rec.get(PART_IMPORTOVAL);
    if (impval != ZERO)
    {
      const real impeur = rec.get(PART_IMPORTO);
      const real old_cambio = rec.get(PART_CAMBIO);
      real new_cambio = impval / impeur;
      new_cambio.round(5);
      if (abs(old_cambio - new_cambio) > 0.001) // Non era gi� contro euro
        rec.put(PART_CAMBIO, new_cambio);
    }
  }
  
  if (rec.get_int(PART_TIPOMOV) > 1)            
  {
    // Riempe il campo totale documento per i pagamenti (In contabilit� viene lasciato vuoto)
    rec.put(PART_IMPTOTDOC, rec.get(PART_IMPORTO));
  }
  
  rec.put(PART_INVIATA, "X");
                                   
  return TRUE;  
}

bool scadenze_handler(TRectype& rec, void* jolly)
{ 
  TSaldac_data* sd = (TSaldac_data*)jolly;
  
  // Controlla se la riga di partita corrispondente esiste in euro
  TEuroisamfile part(LF_PARTITE, TRUE);
  TRectype& curr = part.curr();
  curr.zero();
  curr.put(PART_TIPOCF, rec.get(SCAD_TIPOCF));
  curr.put(PART_GRUPPO, rec.get(SCAD_GRUPPO));
  curr.put(PART_CONTO, rec.get(SCAD_CONTO));
  curr.put(PART_SOTTOCONTO, rec.get(SCAD_SOTTOCONTO));
  curr.put(PART_ANNO, rec.get(SCAD_ANNO));
  curr.put(PART_NUMPART, rec.get(SCAD_NUMPART));
  curr.put(PART_NRIGA, rec.get(SCAD_NRIGA));
  if (part.read() != NOERR)
    return FALSE;
  
  if (!rec.get_real(SCAD_IMPORTOVAL).is_zero())
  {
    const TString4 codval = part.get(PART_CODVAL);
    if (::is_firm_value(codval) || ::is_euro_value(codval)) 
      rec.zero(SCAD_IMPORTOVAL);
  }
    
  const int nrata = rec.get_int(SCAD_NRATA);
  if (nrata == 1)
    sd->_totrate = ZERO;
  sd->_totrate += rec.get_real(SCAD_IMPORTO);
  
  // I problemi di arrotondamento dovrei averli solo con tante rate
  if (nrata > 1)
  {
    TLocalisamfile scad(LF_SCADENZE);
    scad.curr() = rec;
    scad.curr().put(SCAD_NRATA, nrata+1);
    if (scad.read() != NOERR)   // Sono l'ultima rata
    {
      const real toteur = part.get(PART_IMPTOTDOC); 
      const real diff = toteur - sd->_totrate; 
      if (diff != ZERO)
      {
        real rata = rec.get(SCAD_IMPORTO);
        rata += diff;
        rec.put(SCAD_IMPORTO, rata);
      }
    }
  }  
  return TRUE;  
}

bool pagamenti_handler(TRectype& rec, void* jolly)
{ 
  TSaldac_data* sd = (TSaldac_data*)jolly;

  // Controlla se la partita di appartenenza esiste in euro
  TEuroisamfile part(LF_PARTITE, TRUE);
  TRectype& curr = part.curr();
  curr.zero();
  curr.put(PART_TIPOCF, rec.get(PAGSCA_TIPOC));
  curr.put(PART_GRUPPO, rec.get(PAGSCA_GRUPPO));
  curr.put(PART_CONTO, rec.get(PAGSCA_CONTO));
  curr.put(PART_SOTTOCONTO, rec.get(PAGSCA_SOTTOCONTO));
  curr.put(PART_ANNO, rec.get(PAGSCA_ANNO));
  curr.put(PART_NUMPART, rec.get(PAGSCA_NUMPART)); 
  const TRectype sample(curr);
  if (part.read(_isgteq) != NOERR || part.curr() != sample)
    return FALSE;
  
  // Ero in lire (ora sono in euro) devo convertire gli abbuoni a lire ad euro
  // Se ero in valuta devo lasciar stare gli abbuoni
  if (curr.get_real(PART_IMPORTOVAL) == ZERO)  
    convert_import(rec, PAGSCA_ABBUONI);
  else
  {  
    // Le differenze cambio sono gi� convertite sempre automaticamente in quanto erano sempre in lire
  }
  
  return TRUE;  
}

void TEuro01_app::convert_partite()
{                  
  TLocalisamfile partlit(LF_PARTITE);  // Serve ad avere disponibile il tracciato record

  TSaldac_data data;

  convert_file(LF_PARTITE, "IMPTOTDOC|IMPORTO|IMPOSTA|SPESE|RITENUTE|DIFFCAM", PART_NREG, NULL, partite_handler, &data);
  convert_file(LF_SCADENZE, "IMPORTO", NULL, NULL, scadenze_handler, &data);
  convert_file(LF_PAGSCA, "IMPORTO|RITENUTE|DIFFCAM", NULL, NULL, pagamenti_handler, &data);
}

///////////////////////////////////////////////////////////
// Main 
///////////////////////////////////////////////////////////

bool TEuro01_app::create()
{                
  TFilename lit, eur;
  if (!app().get_aree_dati(lit, eur))
    return error_box("Non esiste lo studio in Euro di destinazione");
  return TEuro_app::create();  
}

void TEuro01_app::main_loop()
{ 
  long ditta = 0L;
  if (goto_lire())
  {
    TEuro03_mask m;
    if (m.run() == K_ENTER)
      ditta = m.get_long(F10_DITTA);
  }
  if (ditta > 0L)
    convert_firm(ditta);
}

int baeur01(int argc, char* argv[])
{  
  TEuro01_app ma;
  ma.run(argc, argv, "Conversione Ditte Euro");
  
  return 0;
}