// OMASA

#include <applicat.h>
#include <automask.h>
#include <config.h>
#include <execp.h>
#include <filetext.h>
#include <progind.h>
#include <recarray.h>
#include <utility.h>

#include "pd0777.h"
#include "pd0777100a.h"
#include "pd0777100b.h"
#include "pd0777100C.h"
#include "../cg/cglib01.h"

#include <causali.h>
#include <mov.h>
#include <pconti.h>
#include <rmov.h>


#define MAX_CG_ROWS 98

// tabella per la conversione dei numeri negativi (schede perforate????)
static unsigned char _tabella[10] = {'p','q','r','s','t','u','v','w','x','y'};

//////////////////////////
//		TAutomask
//////////////////////////
class TOmasa_mask : public TAutomask
{
protected:
  bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
  TOmasa_mask();
  virtual ~TOmasa_mask(){};
};
  
TOmasa_mask::TOmasa_mask() :TAutomask ("pd0777100a")
{
}  

bool TOmasa_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
{ 
  return true;
}

/////////////////////////
//		TFile_text
/////////////////////////
class TOmasa_file: public TFile_text
{ 
protected:
  virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str);

public:
  TOmasa_file(const TString& file_name);
  virtual ~TOmasa_file() { }
};

TOmasa_file::TOmasa_file(const TString& file_name)
          : TFile_text(file_name, "pd0777100a.ini")
{
}

void TOmasa_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str)
{
  const TString code(s.get(0));
  TString valore = str;
  if (code == "_UPPERCASE")
  {
    valore.upper(); 
  }
  else NFCHECK("Macro non definita: %s", (const char *)code);
  str = valore;
} 

// TSkeleton_application

class TOmasa : public TSkeleton_application
{
	TOmasa_mask*		_msk;
	TOmasa_file*    _trasfile;
	TConfig*		    _configfile;
  TRelation*      _rel;
  TCursor*        _cur;
  TProgind*       _prog;  
  TEsercizi_contabili* _esc;

  long    _numreg;

	virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "cg";}

public:           
  virtual bool create();
  virtual bool destroy();
  virtual void main_loop();
  virtual void ini2mask();
  virtual void mask2ini();
	bool transfer();
	void negativo(TString& importo);
  int  strip_zero(TString& importo);
  bool my_isdigit(unsigned char ch);
  int  look(unsigned char carattere);
 
  TOmasa() {}
};

TOmasa& app() { return (TOmasa&) main_app(); }
                                      
bool TOmasa::create()
{
  open_files(LF_TABCOM, LF_TAB, LF_SALDI, LF_PCON, LF_MOV, LF_RMOV, LF_RMOVIVA,
						 LF_PARTITE, LF_SCADENZE, LF_PAGSCA, 0);

	TFilename configname = "pd0777conf.ini";
	configname.custom_path();
  _configfile = new TConfig(configname);
  _msk = new TOmasa_mask();
	_rel   = new TRelation (LF_PCON);
  _cur   = new TCursor(_rel,"((GRUPPO!=\"\")&&(CONTO!=\"\")&&(SOTTOCONTO==\"\"))",1);
	_esc   = new TEsercizi_contabili;
         
  return TSkeleton_application::create();
}

bool TOmasa::destroy()
{
  delete _esc;
  delete _cur;
  delete _rel;
	delete _msk;
	delete _configfile;
  
  return TApplication::destroy();
}

int TOmasa::strip_zero(TString& importo)
{
  TString16 app;
  
  int size = importo.len();
  
  int i;
  for (i = 0; i < size; i++)
    if (importo[i] != '0') break;
    
  if (i > 0)
  {
    app = importo.mid(importo[i] == '.' ? i - 1 : i);
    importo = app;
  }               
  
  return (i ? i - 1 : i);
}

bool TOmasa::my_isdigit(unsigned char ch)
{
  return (ch >= '0' && ch <= '9');
}

int TOmasa::look(unsigned char carattere)
{
  for (int i = 0; i < 10; i++)
    if (_tabella[i] == carattere)
      return i;
      
  return -1;
}                                                             

void TOmasa::negativo(TString& importo)
{                           
  strip_zero(importo);
  int size = importo.len(); 
  if (!size) return;
  unsigned char last = importo[size - 1]; 
  if (!my_isdigit(last))
  {     
    int new_last = look(last);
    TString16 dep; dep << new_last;
    if (new_last >= 0) 
    {
      importo[size - 1] = dep[0];
      importo.insert("-");  
    }
  }
}

void TOmasa::mask2ini()
{
	TSheet_field& sheet = (TSheet_field&)_msk->field(F_SHEET_CONTI);
	for (int i=0;i<sheet.items();i++)
	{
		TToken_string& row = sheet.row(i);
		TString16 contoomasa = row.get(0);
		TString16 conto;
		const int gr = atoi(row.get(1));
		const int co = atoi(row.get(2));
		const long so = atol(row.get(3));
		conto.format("%d|%d|%ld", gr, co, so);
		_configfile->set(contoomasa, conto, "CONTI");
	}
	TSheet_field& sheetcms = (TSheet_field&)_msk->field(F_SHEET_CMS);
	for (int i=0;i<sheetcms.items();i++)
	{
		TToken_string& row = sheetcms.row(i);
		TString16 cmsomasa = row.get(0);
		TString80 cms = row.get(1);
		_configfile->set(cmsomasa, cms, "COMMESSE");
	}
	_configfile->set_paragraph("CONTI");
}

void TOmasa::ini2mask()
{
	TString_array vl;
	_configfile->list_variables(vl,TRUE, "CONTI", TRUE);
	TSheet_field& sheet = (TSheet_field&)_msk->field(F_SHEET_CONTI);
	sheet.destroy();
	int i=0;
	FOR_EACH_ARRAY_ROW(vl,r,s)
	{
		TToken_string& riga = sheet.row(i);
		TString16 contoomasa = (*s).get();
		TToken_string conto = _configfile->get(contoomasa, "CONTI");
		riga.add(contoomasa);
		riga.add(conto.get(0));
		riga.add(conto.get(1));
		riga.add(conto.get(2));
		sheet.check_row(i);
		i++;
	}
	_configfile->list_variables(vl,TRUE, "COMMESSE", TRUE);
	TSheet_field& sheetcms = (TSheet_field&)_msk->field(F_SHEET_CMS);
	sheetcms.destroy();
	i=0;
	FOR_EACH_ARRAY_ROW(vl,rc,sc)
	{
		TToken_string& riga = sheetcms.row(i);
		TString16 cmsomasa = (*sc).get();
		TString80 cms = (*sc).get();
		riga.add(cmsomasa);
		riga.add(cms);
		sheetcms.check_row(i);
		i++;
	}
}

void TOmasa::main_loop()
{
  KEY	tasto;
  _msk->set(F_PERCORSO,	_configfile->get("PERCORSO", "MAIN"));
  _msk->set(F_CODCAUS,	_configfile->get("CODCAUS", "MOVIMENTO"));
	ini2mask();
  tasto = _msk->run();
  if (tasto == K_ENTER)
  {
		mask2ini();
    _numreg = 0;
		if (transfer())
		{
			_configfile->set("PERCORSO", _msk->get(F_PERCORSO), "MAIN");
			_configfile->set("CODCAUS", _msk->get(F_CODCAUS), "MOVIMENTO");
			message_box(TR("Importazione stipendi completata"));
		}
  }   
}

bool TOmasa::transfer()
{
	TString_array transactions;
	TFilename tempdir;
	tempdir.tempdir();

	TString80 listfiles = tempdir;
	listfiles << "\\oo*.ini";
  list_files(listfiles, transactions);
  FOR_EACH_ARRAY_ROW(transactions, row, name)
    remove(*name);

	TConfig* movpn=NULL;

  _trasfile = new TOmasa_file(_msk->get(F_PERCORSO));
  _trasfile->open(_msk->get(F_PERCORSO),'r');

	// creazione file temporanei per commessa e conto dare e avere
  const long dimension = fsize(_msk->get(F_PERCORSO));
  TProgind pi(dimension,"Importazione in corso...");

  TRecord_text curr;
  while (_trasfile->read(curr) == NOERR) 
  {
    pi.setstatus(_trasfile->read_file()->tellg());
		TString impstr = curr.get(F_VALOREVOCE);
		impstr.insert(".",11);
		negativo(impstr);
		const real importo(impstr);
		TString16 contodare = curr.get(F_CONTODARE);
		TString16 contoavere = curr.get(F_CONTOAVERE);
		if ((!real::is_null(impstr)) && (!contodare.blank() || !contoavere.blank()))
		{
			TString16 codcms = curr.get(F_CENTROCOSTO);
			codcms.trim();
			TString80 cms = _configfile->get(codcms, "COMMESSE");
			if (cms.empty())
			{
				TMask mskcms("pd0777100c");		
				mskcms.set(F_CMSOMASA, codcms);
				if (mskcms.run() == K_ENTER)
					_configfile->set(codcms, mskcms.get(F_CODCMS), "COMMESSE");
				else
					return TRUE;
			}
			TFilename name;
			name.tempdir();
			name.add(format("oo%s", (const char*) codcms));
			name.ext(".ini");
			movpn = new TConfig(name);
			movpn->set_paragraph("MAIN");
			movpn->set("CODCMS",codcms);
			if (!contodare.blank())
			{
				movpn->set_paragraph("IMPORTI");
				contodare.trim();
				impstr = movpn->get(contodare, "IMPORTI");
				real importomem(impstr);
				importomem+=importo;
				movpn->set(contodare, importomem.string());
			}
			if (!contoavere.blank())
			{
				movpn->set_paragraph("IMPORTI");
				contoavere.trim();
				impstr = movpn->get(contoavere, "IMPORTI");
				real importomem(impstr);
				importomem-=importo;
				movpn->set(contoavere, importomem.string());
			}
			delete movpn;
			if (pi.iscancelled())
				return TRUE;
		}
	}
  _trasfile->close();
	delete _trasfile;

	// creazione .ini per la prima nota
	const TDate datareg = _msk->get_date(F_DATAREG);
	const int annoes = _esc->date2esc(datareg);
	const TString8 codcaus = _msk->get(F_CODCAUS);

	listfiles = tempdir;
	listfiles << "\\oo*.ini";
  list_files(listfiles, transactions);
  FOR_EACH_ARRAY_ROW(transactions, row_oo, name_oo)
	{
	  TConfig* movpn=NULL;
		TConfig file_oo(*name_oo);
		TString16 codcms = file_oo.get("CODCMS", "MAIN");
		codcms.trim();
		TFilename name;
		name.tempdir();
		name.add(format("ooo%s", (const char*) codcms));
		name.ext(".ini");
		movpn = new TConfig(name);

		movpn->set_paragraph("Transaction");
		movpn->set("Action","INSERT");
		movpn->set("Mode","AUTO");
 
		movpn->set_paragraph(format("%d",LF_MOV));
		movpn->set("ANNOES", annoes);
		movpn->set("DATACOMP", datareg);
		movpn->set("DATAREG", datareg);
		movpn->set("DESCR", cache().get(LF_CAUSALI, codcaus, CAU_DESCR));
		movpn->set("CODCAUS", codcaus);
		
		int numrig = 0;
		
		TString_array vl;
	  file_oo.list_variables(vl,TRUE, "IMPORTI", TRUE);
		FOR_EACH_ARRAY_ROW(vl,r,s)
		{
			TString16 contoomasa = (*s).get();
			TString16 importos = (*s).get();
			TToken_string conto = _configfile->get(contoomasa, "CONTI");
			if (conto.empty())
			{
				TMask mskconto("pd0777100b");		
				mskconto.set(F_CONTOOMASA, contoomasa);
				if (mskconto.run() == K_ENTER)
				{
					const int gr = mskconto.get_int(F_GRUPPO);
					const int co = mskconto.get_int(F_CONTO);
					const long so = mskconto.get_long(F_SOTTOCONTO);
					conto.format("%d|%d|%ld", gr, co, so);
					_configfile->set(contoomasa, conto, "CONTI");
				}
				else
					return TRUE;
			}
			numrig++;
			movpn->set_paragraph(format("%d,%d",LF_RMOV, numrig));
			movpn->set("ANNOES", annoes);
			movpn->set("DATAREG", datareg);
			movpn->set("NUMRIG", numrig);
			real importo(importos);
			if (importo > 0)
				movpn->set("SEZIONE", "D");
			else
				movpn->set("SEZIONE", "A");
			importos.strip("-");
			movpn->set("IMPORTO", importos);
			TString16 contoindbil;
			contoindbil.format("%s|%s", conto.get(0), conto.get(1));
			const char indbil = cache().get(LF_PCON, contoindbil, PCN_INDBIL)[0]; 
			if ((indbil != '1') && (indbil != '2'))
				movpn->set("CODCMS", _configfile->get(codcms, "COMMESSE"));
			movpn->set("GRUPPO", conto.get(0));
			movpn->set("CONTO", conto.get(1));
			movpn->set("SOTTOCONTO", conto.get(2));
		}
		delete movpn;
	}
	
	tempdir.tempdir();
	TString80 applicat = "cg2.exe -0 -i";
	applicat << tempdir;
	applicat << "\\ooo*.ini";
	TExternal_app primanota(applicat);
  primanota.run();
	
	listfiles = tempdir;
	listfiles << "\\oo*.ini";
  list_files(listfiles, transactions);
  FOR_EACH_ARRAY_ROW(transactions, rowf, namef)
		remove(*namef);
	return TRUE;
}

int pd0777100 (int argc, char* argv[])
{
  TOmasa main_app;
  main_app.run(argc, argv, TR("Importazione stipendi"));
  return TRUE;
}