#include "gvlib.h"

#include <diction.h>
#include <relation.h>
#include <mov.h>
#include <rmov.h>

#include "../cg/cg2101.h"
#include "../cg/cglib02.h"


///////////////////////////////////////////////////////////
// TRigheF24_set
///////////////////////////////////////////////////////////

// 0=tutte 1=libere 2=assegnate 3=tutte
TRigheF24_set::TRigheF24_set(int flags)
             : TISAM_recordset("USE RIGHEF24 KEY 2")
{
  switch ((flags & 0x3) % 3)
  {
  case  1: set("USE RIGHEF24 KEY 2\nTO PROGR=999999"); break;
  case  2: set("USE RIGHEF24 KEY 2\nFROM F24=1"); break;
  default: break;
  }
}


///////////////////////////////////////////////////////////
// TF24_set
///////////////////////////////////////////////////////////

bool TF24_set::contabilizza(TLog_report & log) 
{
	bool ok = true;
	TMovimentoPN mov;
	TSaldo_agg saldo;
	TEsercizi_contabili esc;
	long numreg = get(F24_NUMREG).as_int();
	const TDate datareg = get(F24_DATAVERS).as_date();
	const int codes = esc.date2esc(datareg);
	TString16 codbnp = get(F24_ABI).as_string();
	TString msg;

	msg.format(FR("Distinta F24 n.ro %ld"), get(F24_F24).as_int());
	log.log(0, msg);
	codbnp << get(F24_CAB).as_string();

	if (numreg > 0L)
	{
		msg.format(FR("Distinta gi� contabilizzata, reg. numero %ld"), numreg);
		log.log(1, msg);
		return false;
	}

	if (mov.lfile().last() == NOERR)
    numreg = mov.lfile().get_long(MOV_NUMREG);
	
	numreg++;
	mov.zero();
	mov.lfile().put(MOV_ANNOES, codes);
	mov.lfile().put(MOV_NUMREG, numreg);
	mov.lfile().put(MOV_DATAREG, datareg);
	mov.lfile().put(MOV_DATAREG, datareg);
	mov.lfile().put(MOV_DATACOMP, datareg);
	mov.lfile().put(MOV_DESCR, msg);

	saldo.set_anno_es(codes);
  saldo.set_tipo_saldo(normale);
  saldo.set_movprovv(false);
  saldo.set_movimentato(true);
  saldo.set_data_ulmov(datareg);
  saldo.set_num_ulmov (numreg);


	real totale;
	int nrow = 0;

	for (bool cont = move_first(); ok && cont; cont = move_next())
	{
		const TString & codtrib = get(F24_TRIBUTO).as_string();
		const TRectype & trib = cache().get("%TRB", codtrib);
		const TBill c(trib.get_int("I0"), trib.get_int("I1"), trib.get_long("I2"));

		ok = c.ok();

		if (ok)
		{
			const real importo = get(F24_IMPORTODEB).as_real() - get(F24_IMPORTOCRE).as_real();
			
			if (importo > ZERO)
			{
				TRectype & cgrec = mov.cg(nrow++);
		
				cgrec.put(RMV_ANNOES, codes);
				cgrec.put(RMV_NUMREG, numreg);
				cgrec.put(RMV_NUMRIG, nrow);
				cgrec.put(RMV_DATAREG, datareg);
				cgrec.put(RMV_GRUPPO, c.gruppo());
				cgrec.put(RMV_CONTO, c.conto());
				cgrec.put(RMV_SOTTOCONTO, c.sottoconto());
				cgrec.put(RMV_SEZIONE, "D");
				cgrec.put(RMV_IMPORTO, importo);
				totale += importo;
				saldo.aggiorna(c, importo, 'D');
			}
		}
		else
		{
			msg.format("Tributo %s : Conto %d %d %ld assente", codtrib, c.gruppo(), c.conto(), c.sottoconto());
			log.log(2, msg);
			return false;
		}
	}

	if (totale > ZERO)
	{
		const TRectype & bnp = cache().get("BNP", codbnp);
		const TBill c(bnp.get_int("I9"), bnp.get_int("I10"), bnp.get_long("I11"));

		ok = c.ok();

		if (ok)
		{
			TRectype & cgrec = mov.cg(nrow++);

			cgrec.put(RMV_ANNOES, codes);
			cgrec.put(RMV_NUMREG, numreg);
			cgrec.put(RMV_NUMRIG, nrow);
			cgrec.put(RMV_DATAREG, datareg);
			cgrec.put(RMV_GRUPPO, c.gruppo());
			cgrec.put(RMV_CONTO, c.conto());
			cgrec.put(RMV_SOTTOCONTO, c.sottoconto());
			cgrec.put(RMV_SEZIONE, "A");
			cgrec.put(RMV_IMPORTO, totale);
			saldo.aggiorna(c, totale, 'A');
		}
		else
		{
			msg.format(FR("Banca %s : Conto %d %d %ld assente"), codbnp, c.gruppo(), c.conto(), c.sottoconto());
			log.log(2, msg);
			return false;
		}
		
		const int err = mov.write(true);
		
		if (err == NOERR)
		{
			TRelation & r = *relation();
			
			msg.format(FR("Movimento di prima nota %ld"), numreg);
			log.log(0, msg);
	    saldo.registra();
			for (bool cont = move_first(); ok && cont; cont = move_next())
			{
				r.curr().put(F24_NUMREG, numreg);
				r.rewrite();
			}
		}
		else
		{
			msg.format(FR("Scrittura movimento di prima nota %d"), err);
			log.log(2, msg);
			ok = false;
		}

	}
	else
		log.log(0 ,TR("Nessun movimento generato"));

	return ok;
}

TF24_set::TF24_set(long codice) 
        : TISAM_recordset("USE RIGHEF24 KEY 2\nFROM F24=#DIST\nTO F24=#DIST")
{
  CHECKD(codice > 0, "Distinta ma sospetta:", codice);
  set_var("#DIST", TVariant(codice));
}

///////////////////////////////////////////////////////////
// TElencoF24_set
///////////////////////////////////////////////////////////

const TElencoF24_set* TElencoF24_set::_currentF24 = NULL;

bool TElencoF24_set::f24killer(const TRelation* rel)
{
  // Il record e' buono se il bit corrispondente e' settato
  return _currentF24->_good[rel->file().recno()]; 
}

TCursor* TElencoF24_set::cursor() const
{
  _currentF24 = this;

  TCursor* c = TISAM_recordset::cursor();
  if (c != NULL && c->filterfunction() == NULL)
  {
    TBit_array& goodies = ((TElencoF24_set*)this)->_good;
    goodies.reset();

    long last = 0;
		TDate last_date(eotime);
		TRecnotype last_recno = 0L;
    
    TRecnotype tot = c->items();
    const TRectype& curr = c->curr();
    for (*c = 0; c->pos() < tot; ++*c)
    {
      const long f24 = curr.get_long(F24_F24);
			const TDate f24scad = curr.get_date(F24_DATASCAD);
      bool good = f24 > last || (f24 == last && last_date > f24scad);
      if (good)
      {
        if (_flags != 0) // Non voglio tutto?
        {
          const TDate inv = curr.get(F24_DATAVERS);
          good = (_flags == 1) ^ inv.ok();
        }
        if (good)
				{
					const TRecnotype recno = c->file().recno();

					if (f24 == last)
						goodies.reset(last_recno);
          goodies.set(recno);
	        last = f24;
					last_date = f24scad;
					last_recno = recno;
				}
      }
    }
    c->freeze(false);
    c->set_filterfunction(f24killer);
    tot = c->items();
    c->freeze(true);
  }
  return c;
}

// 0=tutte 1=da inviare 2=inviate 3=tutte
TElencoF24_set::TElencoF24_set(int flags)
              : TRigheF24_set(0x2)
{
  _flags = (flags & 0x3) % 3;  // isolo i flag = 1 o flag = 2
}

long get_next_f24()
{
  long f24 = 1;
  TRigheF24_set deleghe(0x2);
  if (deleghe.move_last())
    f24 += deleghe.get(F24_F24).as_int();
  return f24;
}

long get_next_progr_f24()
{
	TLocalisamfile righef24(LF_RIGHEF24);
  long next_progr = 1;
	
  if (righef24.read(_islast) == NOERR)
    next_progr += righef24.get_long(F24_PROGR);
	return next_progr;
}