#include <applicat.h>
#include <printer.h>
#include <progind.h>

#include "provv.h"
#include "pr1300a.h"
#include "..\ve\velib.h"

class TStampa_schedeprovv_form : public TForm
{               
  TString _basecalcolo;
  TPagamento _pagamento;

protected:  
  virtual bool validate(TForm_item &, TToken_string &); 

public:
  void set_basecalcolo(const TString& s) { _basecalcolo = s; }
  TStampa_schedeprovv_form(const char* name);
  virtual ~TStampa_schedeprovv_form(){};
};

TStampa_schedeprovv_form::TStampa_schedeprovv_form(const char* name) : TForm(name)
{ }

bool TStampa_schedeprovv_form::validate(TForm_item &cf, TToken_string &s)
{
  const TString code = s.get(0);      
  if (code == "_BASECALCOLO")
  {                             
    real valore;
    if (_basecalcolo.empty())
    { 
      const real cambio = TForm::find_field('B', odd_page, 666).get();
      valore = TForm::cursor()->curr().get_real(PROV_IMPRATA)*cambio;
    }
    else
    {                                  
      const int nriga = TForm::cursor()->curr().get_int(PROV_NRIGA);
      if (nriga == 1)
      {
        TDocumento doc(TForm::cursor()->curr(LF_DOC));
        _pagamento = doc.pagamento();
        real importo = doc.get(_basecalcolo);
        if (doc.tipo().nota_credito())
          importo = -importo;
        const TCurrency zero;
        _pagamento.set_total(importo,zero,zero);
        _pagamento.set_rate_auto();
      } 
      const int nrata = TForm::cursor()->curr().get_int(PROV_NRATA);
      if (nrata > 0 && nrata <= _pagamento.n_rate())
        valore = _pagamento.importo_rata(nrata-1);
      else
        valore = ZERO;  
    }  
    cf.set(valore.string());
  }  
  return TForm::validate(cf, s);
}

class TStampa_schedeprovv : public TSkeleton_application
{
  TMask * _m;
  void riporta_pagamenti(TCursor &cur);

protected:
  virtual bool create(); 
  virtual bool destroy(); 
  virtual void main_loop();
};

bool TStampa_schedeprovv::create()
{
  open_files(LF_CFVEN, LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG,
             LF_SCONTI, LF_UMART, LF_TAB, LF_TABCOM, LF_CLIFO,  LF_INDSP,
             LF_OCCAS, LF_PCON, LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, 
             LF_AGENTI, LF_PERCPROV, LF_ATTIV, LF_CAUSALI, 0);

  _m= new TMask ("pr1300a");    
  
  return TSkeleton_application::create();
}

bool TStampa_schedeprovv::destroy()
{
  delete _m;
  return TSkeleton_application::destroy();
}

void TStampa_schedeprovv::riporta_pagamenti(TCursor &cur)
{
  if (cur.items()==0) return;
  const TRelation * r = cur.relation();
  TLocalisamfile& prov = r->lfile();
  TProgind barra(cur.items(),TR("Registro le provvigioni pagate"));
  for (int c=0; c<cur.items(); c++)
  {
    cur=c;
    barra.setstatus(c);
    // stampa definitiva: riporta le provvigioni maturate sulle provv. pagate
    real provv_pag, pag_pag;
    provv_pag = prov.get_real(PROV_PROVVMAT);
    pag_pag   = prov.get_real(PROV_PAGMAT);
    if (!provv_pag.is_zero() && 
      !prov.get_bool(PROV_SALDATA)) // this should never happen!
    {
      prov.reread(_lock);
      provv_pag += prov.get_real(PROV_PROVVPAG);
      pag_pag   += prov.get_real(PROV_PAGATO);
      prov.put(PROV_PROVVPAG,provv_pag);
      prov.put(PROV_PROVVMAT,0);
      prov.put(PROV_PAGATO,pag_pag);
      prov.put(PROV_PAGMAT,0);
      if (provv_pag>=prov.get_real(PROV_IMPPROVV))
        prov.put(PROV_SALDATA,"X");
      prov.rewrite();
    }
  }
}

void TStampa_schedeprovv::main_loop()
{
  while (_m->run()!=K_QUIT)
  {
    TStampa_schedeprovv_form frm("pr1300a");

    const int hh = 7;
    const int fh = 1;
    const int fl = printer().formlen();
    
    int rows[4];         // Righe orizzontali
    rows[0] = hh-3;
    rows[1] = hh;
    rows[2] = fl-1;
    rows[3] = 0;
    frm.genera_intestazioni(odd_page, hh-2);
    frm.genera_fincatura(odd_page, hh-3, fl-1, rows);
  
    // filtro e regione
    TString filter;
    
    if (_m->get(F_FILTRO).not_empty())
    {
     filter = PROV_SALDATA;
     if (_m->get(F_FILTRO)[0]=='P')
       filter << "==\"X\"" ;
     else
       filter << "!=\"X\"" ;         
    }  
    if (_m->get_bool(F_NOZERO))
    {
      bool not_empty = filter.not_empty();
      if (not_empty)       
      {
        filter.insert("(");
        filter << ") && (";
      }                                                                  
      filter << "(" << PROV_IMPPRDOC << "!= 0)";
      if (not_empty)
        filter << ")";
    }
    if (_m->get(F_DADATA).not_empty() || _m->get(F_ADATA).not_empty())
    {   
      TDate datam;
      bool not_empty = filter.not_empty();
      if (not_empty)       
      {
        filter.insert("(");
        filter << ") && (";
      }                                                                  
      if (_m->get(F_DADATA).not_empty())
      {                                                         
        datam = _m->get_date(F_DADATA);
        filter << "(ANSI(" << PROV_DATADOC << ")>=\"" << datam.string(ANSI) << "\")";
        if (_m->get(F_ADATA).not_empty())
          filter << " && ";
      } 
      if (_m->get(F_ADATA).not_empty())
      {
        datam = _m->get_date(F_ADATA);
        filter << "(ANSI(" << PROV_DATADOC << ")<=\"" << datam.string(ANSI) << "\")";
      } 
      if (not_empty)
        filter << ")";
    }      
    
    // aggiungo comunque il file alla relazione perche' mi serve avere il documento sempre
    frm.cursor()->relation()->add(LF_DOC, "CODNUM==CODNUM|ANNO==ANNO|PROVV==\"D\"|NDOC==NDOC");
    
    const TString & tipodoc = _m->get(F_TIPODOC);
    if (tipodoc.not_empty())
    {
      //frm.cursor()->relation()->add(LF_DOC, "CODNUM==CODNUM|ANNO==ANNO|PROVV==\"D\"|NDOC==NDOC");
      bool not_empty = filter.not_empty();
        
      if (not_empty)       
      {
        filter.insert("(");
        filter << ") && (";
      }
        
      filter << LF_DOC << "->TIPODOC == \"" << tipodoc << "\"";
        
      if (not_empty)
        filter << ")";
                                     
      frm.cursor()->setfilter(filter, TRUE);
    }
    else
      frm.cursor()->setfilter(filter);

    TRectype start(LF_PROVV),end(LF_PROVV);
    if (_m->get(F_DAAGE).not_empty())
      start.put(PROV_CODAGE,_m->get(F_DAAGE));
    if (_m->get(F_AAGE).not_empty())
      end.put(PROV_CODAGE,_m->get(F_AAGE));
    frm.cursor()->setregion(start,end);
    
    frm.set_basecalcolo(_m->get(F_FORMULA));

    // abilita le sezioni dei totali
    frm.find_field('B',odd_page,"CLIENTI").show(!_m->get_bool(F_RAGGCLI));
    frm.find_field('B',odd_page,"HCLIENTI").show(!_m->get_bool(F_RAGGDOC));
    frm.find_field('B',odd_page,"DOCUMENTI").show(!_m->get_bool(F_RAGGDOC));
    frm.find_field('B',odd_page,"HDOCUMENTI").show(!_m->get_bool(F_RAGGRATE));
    frm.find_field('B',odd_page,"RATEDOC").show(!_m->get_bool(F_RAGGRATE));
    frm.print();
    if (_m->get(F_DEFINITIVA)[0]=='D')
    {
      riporta_pagamenti(*frm.cursor());
    }
  }
}

int pr1300(int argc, char* argv[])
{
  TStampa_schedeprovv a;
  a.run(argc,argv,TR("Stampa schede di provvigione"));
  return 0;
}