#include <applicat.h>
#include <automask.h>
#include <execp.h>
#include <progind.h>
#include <relation.h>

#include "baeur.h"
#include "../mg/mglib.h"
#include "../cg/cglib01.h"
#include "../ve/velib.h"

#include <doc.h>
#include <rdoc.h>

class TArticolo_euro : public TArticolo_giacenza
{          
public:                                                       
  bool adjust_storico(const int anno);

  TArticolo_euro(const char* codice = NULL) : TArticolo_giacenza(codice) {}
  TArticolo_euro(const TRectype& rec) : TArticolo_giacenza(rec) {}
  virtual ~TArticolo_euro() {}
};
  
bool TArticolo_euro::adjust_storico(const int anno)
{
  bool updated = FALSE;             
  TAssoc_array values;              
  TString16 annoes; annoes << anno;
  TRecord_array & s = storico(annoes);
  const int sto_items = s.rows();
  for (int i = 1; i <= sto_items; i++)
  {          
    TRectype & rec = s[i];
    TString16 codmag(rec.get(STOMAG_CODMAG));
    real val = rec.get_real(STOMAG_VALORE);
    val *= rec.get_real(STOMAG_QUANT);
    real * tot = (real *)values.objptr(codmag);
    
    if (tot == NULL)
    {
      tot = new real;
      values.add(codmag, tot);
    }    
    *tot += val;
  }

  TRecord_array& m = mag(annoes);
  const int mag_items = m.rows();
  for (i = 1; i <= mag_items; i++)
  {
    TRectype & rec = m[i];
    TString16 codmag(rec.get(MAG_CODMAG));
    const real val = rec.get_real(MAG_VALRIM);
    real * tot = (real *)values.objptr(codmag);
      
    if (tot == NULL)
    {
      tot = new real;
      values.add(codmag, tot);
    }    
    *tot -= val;
  }        
  
  for (i = 1; i <= mag_items; i++)
  {          
    TRectype & rec = m[i];
    TString16 codmag(rec.get(MAG_CODMAG));
    real val = rec.get_real(MAG_VALRIM);
    real * corr = (real *)values.objptr(codmag);
    
    if (corr != NULL && *corr != ZERO)
    {
      corr->round(TCurrency::get_firm_dec(FALSE));
      val += *corr;                           
      rec.put(MAG_VALRIM, val);            
      updated = TRUE;
      *corr = ZERO;
    }    
  }

  return updated;
}   

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

class TEuro06_app : public TEuro_app
{ 
protected:
  virtual bool create();
  virtual void main_loop();
  void update_stomag();

public:
};

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

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

bool TEuro06_app::create()
{        
  if (!dbf_exists(LF_ANAMAG) || !dbf_exists(LF_STOMAG) || !dbf_exists(LF_MOVMAG))
    return FALSE;

  TEuro_app::create();
  bool ok = goto_euro(get_firm());
  open_files(LF_TAB, LF_TABCOM, LF_STOMAG, LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG, 0);
  open_files(LF_SCONTI, LF_UMART, LF_CLIFO, LF_CFVEN, LF_INDSP, LF_OCCAS, LF_PCON, 0);
  open_files(LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, LF_ATTIV, LF_CAUSALI, 0);
  return ok;
}

void TEuro06_app::update_stomag()
{                               
  TEsercizi_contabili e;
  
  TRelation amag(LF_ANAMAG);
  TCursor c(&amag);        
  TArticolo_euro * a = new TArticolo_euro();
  TString str;
  str << "Aggiornamento storico di magazzino ...";

  amag.lfile().set_curr(a);
  const long items = c.items();
  TProgind pi(items, str, FALSE, TRUE);
        
  for (c = 0L; c.pos() < items; ++c)
  {
    pi.addstatus(1);
    TArticolo_euro& curr_art = (TArticolo_euro &) c.curr();
    for (int codes = e.first(); codes > 0; codes = e.next(codes))
    {
      if (curr_art.adjust_storico(codes))
        curr_art.rewrite();
    }
  }
}

void TEuro06_app::main_loop()
{   
  TDate apertura(1,1,2002);
  const long firm = get_firm();
  TFilename dati, datie;
  get_aree_dati(dati, datie);
  
  TString8 ditta; 
  ditta.format("%05ldA", firm);
  
  TFilename inie = datie;
  inie.add(ditta);
  inie.add("prassid.ini");
  
  bool adotta = FALSE, inizio = FALSE;
  if (inie.exist())
    adotta = data_adozione_euro(firm, apertura, inizio);
  TEsercizi_contabili esc;
  TString16 command(argv(2));
  
  if (command == "A") 
  {
    update_stomag();
    TExternal_app app("mg1 -3");
    
    app.run();
  }
  else
    if (command == "S") 
    {
      const int annoes = esc.date2esc(apertura);
      TString16 codes; codes << annoes;

      update_stomag();
      rebuild_balances(codes); 
    }
    else
      if (command == "D") 
      { 
        TRelation doc(LF_DOC);
        TCursor c(&doc);        
        TDocumento * d = new TDocumento();

        TString str;
        str << "Riesamina " << doc.lfile().description() << " ...";
  
        doc.lfile().set_curr(d);
        const long items = c.items();
        TProgind pi(items, str, FALSE, TRUE);
        
        for (c = 0L; c.pos() < items; ++c)
        {
          pi.addstatus(1);
          TDocumento & curr_doc = (TDocumento &) c.curr();
        
          if (curr_doc.in_valuta())
          {                   
            TString16 val(curr_doc.get("CODVAL"));
            const int dec = atoi(cache().get("%VAL", val, "I2"));
                         
            if (dec < 6)
            {                                                                         
              real change = curr_doc.get_real(DOC_CAMBIO);
              change.round(dec);
              curr_doc.put(DOC_CAMBIO, change);
            }
          }
          else
            if (curr_doc.get_bool(DOC_CONTROEURO))
            {
              curr_doc.dirty_fields();
              curr_doc.put(DOC_CONTROEURO, "");
            }    
          real tot = curr_doc.totale_doc();
          curr_doc.dirty_fields();
          curr_doc.rewrite();
        }
      }
}

int baeur06(int argc, char* argv[])
{  
  TEuro06_app ma;
  ma.run(argc, argv, "");
  
  return 0;
}