Files correlati : Ricompilazione Demo : [ ] Commento : personalizzazione dinamica git-svn-id: svn://10.65.10.50/trunk@20325 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			439 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			439 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						||
#include <automask.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <reputils.h>
 | 
						||
#include <relation.h>
 | 
						||
#include <textset.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "../ca/calib01.h"
 | 
						||
#include "../ca/movana.h"
 | 
						||
#include "../ca/rmovana.h"
 | 
						||
#include "../cg/cglib01.h"
 | 
						||
 | 
						||
#include "ps1001.h"
 | 
						||
#include "ps1001100a.h"
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TAutomask
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TImporta_movana_mask : public TAutomask
 | 
						||
{
 | 
						||
protected:
 | 
						||
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						||
 | 
						||
public:
 | 
						||
  TImporta_movana_mask();
 | 
						||
};
 | 
						||
  
 | 
						||
TImporta_movana_mask::TImporta_movana_mask() :TAutomask ("ps1001100a")
 | 
						||
{
 | 
						||
}  
 | 
						||
 | 
						||
bool TImporta_movana_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						||
{ 
 | 
						||
	switch (o.dlg())
 | 
						||
	{
 | 
						||
		//giochetto per avere la lista dei files validi nella directory di trasferimento!
 | 
						||
		case F_NAME:
 | 
						||
			if (e == fe_button)
 | 
						||
			{
 | 
						||
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@32");
 | 
						||
				TFilename path = get(F_PATH);
 | 
						||
				path.add("*.csv");	//files delle testate
 | 
						||
				list_files(path, as.rows_array());
 | 
						||
				TFilename name;
 | 
						||
				FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
 | 
						||
				{
 | 
						||
					name = *row;
 | 
						||
					*row = name.name();
 | 
						||
				}
 | 
						||
				if (as.run() == K_ENTER)
 | 
						||
				{
 | 
						||
					o.set(as.row(as.selected()));
 | 
						||
				}
 | 
						||
			}
 | 
						||
			break;
 | 
						||
//controlli sui campi della testata documento
 | 
						||
    case F_DATAREG:
 | 
						||
      if ((e == fe_modify || e == fe_close) && !query_mode())
 | 
						||
      {
 | 
						||
        const TDate datareg = o.get();
 | 
						||
        const TEsercizi_contabili ec;
 | 
						||
        if (ec.date2esc(datareg) <= 0)
 | 
						||
          return error_box(((TEdit_field&)o).get_warning());
 | 
						||
        if (e == fe_close && field(F_DATACOMP).empty())
 | 
						||
          set(F_DATACOMP, datareg);
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case F_DATACOMP:
 | 
						||
      if ((e == fe_modify || e == fe_close) && !query_mode())
 | 
						||
      {
 | 
						||
        const TDate datareg = get(F_DATAREG);
 | 
						||
        TDate datacomp = o.get();
 | 
						||
        if (!datacomp.ok())
 | 
						||
          datacomp = datareg;
 | 
						||
 | 
						||
        const bool preventivo = get(F_TIPO).full();
 | 
						||
        //i movimenti normali devono avere data competenza nel presente o passato!!
 | 
						||
        if (!preventivo && datacomp > datareg)
 | 
						||
          return error_box(TR("La data di competenza non puo' superare la data di registrazione"));
 | 
						||
 | 
						||
        const TEsercizi_contabili ec;
 | 
						||
        int ae = ec.date2esc(datacomp);
 | 
						||
 | 
						||
        //movimenti preventivi in esercizi futuri
 | 
						||
        if (ae <= 0 && preventivo && datacomp > datareg)
 | 
						||
          ae = ec.date2esc(datareg) + datacomp.year() - datareg.year();
 | 
						||
 | 
						||
        if (ae > 0)
 | 
						||
          set(F_ANNOES, ae, 0x1);
 | 
						||
        else
 | 
						||
          return error_box(((TEdit_field&)o).get_warning());
 | 
						||
 | 
						||
        const int ar = ec.date2esc(datareg);
 | 
						||
        const int ap = ec.pred(ar);
 | 
						||
        
 | 
						||
        //preventivi un anno indietro, nel presente o nel futuro
 | 
						||
        if (preventivo)
 | 
						||
        {
 | 
						||
          if (ae < ap)
 | 
						||
            return error_box(FR("La data di competenza non pu<70> precedere l'esercizio %d"), ap);
 | 
						||
        }
 | 
						||
        else  //normali solo un anno indietro o nel presente
 | 
						||
        {
 | 
						||
          if (ae != ar && ae != ap)
 | 
						||
            return error_box(FR("La data di competenza deve appartenere all'esercizio in corso o al precedente"));
 | 
						||
        }
 | 
						||
 | 
						||
      }
 | 
						||
      break;
 | 
						||
    case F_DATAFCOMP:
 | 
						||
      if (e == fe_modify || e == fe_close)
 | 
						||
      {
 | 
						||
        const TDate datacomp = get(F_DATACOMP);
 | 
						||
        const TDate datafcomp = o.get();
 | 
						||
        if (datafcomp.ok())
 | 
						||
        {
 | 
						||
          if (datafcomp < datacomp)
 | 
						||
            return error_box(((TEdit_field&)o).get_warning());
 | 
						||
        }
 | 
						||
        else
 | 
						||
          o.set(datacomp.string()); //se la data fine competenza viene lasciata vuota -> e' uguale alla datacomp
 | 
						||
      }
 | 
						||
      
 | 
						||
      break;
 | 
						||
		default:
 | 
						||
			break;
 | 
						||
	}
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 
 | 
						||
/////////////////////////////////////////////////////////////
 | 
						||
//	Recordset specifici per i dati da trasferire
 | 
						||
/////////////////////////////////////////////////////////////
 | 
						||
class TImporta_movana_recordset : public TCSV_recordset
 | 
						||
{
 | 
						||
  char _sep_field;
 | 
						||
 | 
						||
  protected:
 | 
						||
    virtual TRecnotype new_rec(const char* buf = NULL);    
 | 
						||
  
 | 
						||
  public:
 | 
						||
    TImporta_movana_recordset(const char * fileName, char sep);
 | 
						||
};
 | 
						||
 | 
						||
TRecnotype TImporta_movana_recordset::new_rec(const char* buf)
 | 
						||
{
 | 
						||
  TToken_string str(256,'\t'); //nuovo record tab separator
 | 
						||
 | 
						||
  if(buf && *buf)
 | 
						||
  {
 | 
						||
    bool apici = false;
 | 
						||
 | 
						||
    for (const char* c = buf; *c ; c++)
 | 
						||
    {
 | 
						||
      if (*c == '"')
 | 
						||
      {
 | 
						||
        apici = !apici;
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if (*c == _sep_field)  //tipo di separatore dei campi che si trova nel record di origine
 | 
						||
        {
 | 
						||
          if (!apici)
 | 
						||
            str << str.separator();
 | 
						||
          else
 | 
						||
            str << *c;
 | 
						||
        }
 | 
						||
        else
 | 
						||
          str << *c;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  const TRecnotype n = TText_recordset::new_rec(str);
 | 
						||
 | 
						||
  if (n >= 0)
 | 
						||
    row(n).separator(str.separator());
 | 
						||
  
 | 
						||
  return n;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TImporta_movana_recordset::TImporta_movana_recordset(const char * filename, char sep_field)
 | 
						||
                        : TCSV_recordset("CSV(;)"), _sep_field(sep_field)  //separatore campi
 | 
						||
{
 | 
						||
  load_file(filename);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////
 | 
						||
// TSkeleton_application
 | 
						||
///////////////////////////////////////
 | 
						||
class TImporta_movana : public TSkeleton_application
 | 
						||
{
 | 
						||
	virtual bool check_autorization() const { return false; }
 | 
						||
  virtual const char * extra_modules() const { return "ca"; }
 | 
						||
 | 
						||
	TImporta_movana_mask* _msk;
 | 
						||
 | 
						||
protected:
 | 
						||
 | 
						||
public:           
 | 
						||
  virtual bool create();
 | 
						||
  virtual bool destroy();
 | 
						||
  virtual void main_loop();
 | 
						||
	bool transfer(const TFilename& file);
 | 
						||
 
 | 
						||
  TImporta_movana() {};
 | 
						||
};
 | 
						||
 | 
						||
bool TImporta_movana::transfer(const TFilename& file)
 | 
						||
{
 | 
						||
  //roba dalla maschera
 | 
						||
  //parametri di importazione
 | 
						||
  const char sep_field = _msk->get(F_SEP_FIELD)[0]; //separatore dei campi
 | 
						||
  const char sep_dec = _msk->get(F_SEP_DEC)[0]; //separatore decimali
 | 
						||
  //parametri del movana
 | 
						||
  const long numreg = _msk->get_long(F_NUMREGCA);
 | 
						||
  const int annoes = _msk->get_int(F_ANNOES);
 | 
						||
  const TDate datareg = _msk->get_date(F_DATAREG);
 | 
						||
  const TDate datacomp = _msk->get_date(F_DATACOMP);
 | 
						||
  const TDate datafcomp = _msk->get_date(F_DATAFCOMP);
 | 
						||
  const bool autofcomp = _msk->get_bool(F_AUTOFCOMP);
 | 
						||
  const TString descrizione = _msk->get(F_DESCR);
 | 
						||
  const char tipomov = _msk->get(F_TIPO)[0];
 | 
						||
  const TString4 codcaus = _msk->get(F_CODCAUS);
 | 
						||
  const real ori_totimp = _msk->get_real(F_TOTMOV);
 | 
						||
  const char ori_totsez = _msk->get(F_TOTMOV_SEZ)[0];
 | 
						||
 | 
						||
 | 
						||
  //crea il recordset sul file di input utilizzando il separatore
 | 
						||
  TImporta_movana_recordset s(file, sep_field);
 | 
						||
  const long recset_items = s.items();
 | 
						||
 | 
						||
  //un po' di roba iniziale
 | 
						||
  TProgind pi(s.items(),"Importazione movimento in corso ...",true,true);
 | 
						||
  TLog_report log("ERRORI DI TRASFERIMENTO");
 | 
						||
  int curr_line = 0;
 | 
						||
 | 
						||
  //testata
 | 
						||
  //-------
 | 
						||
  //movimento analitico che sar<61> generato
 | 
						||
  TAnal_mov movana;
 | 
						||
  //il movana esisteva gi<67> o <20> nuovo?
 | 
						||
  const int err = movana.read(numreg);
 | 
						||
  //se esisteva gi<67> deve accoppare tutte le righe visto che le sostituir<69>
 | 
						||
  if (err == NOERR)
 | 
						||
    movana.destroy_rows(LF_RMOVANA);
 | 
						||
  else
 | 
						||
    movana.put(MOVANA_NUMREG, numreg);
 | 
						||
 | 
						||
  movana.put(MOVANA_DATAREG, datareg);
 | 
						||
  movana.put(MOVANA_DATACOMP, datacomp);
 | 
						||
  movana.put(MOVANA_DATAFCOMP, datafcomp);
 | 
						||
  movana.put(MOVANA_ANNOES, annoes);
 | 
						||
  movana.put(MOVANA_DESCR, descrizione);
 | 
						||
  movana.put(MOVANA_TIPOMOV, tipomov);
 | 
						||
  movana.put(MOVANA_CODCAUS, codcaus);
 | 
						||
  movana.put(MOVANA_AUTOFCOMP, autofcomp);
 | 
						||
 | 
						||
  TImporto totale;
 | 
						||
  //giro su tutti i record del recordset per importarli; ogni record <20> una riga
 | 
						||
  //righe analitiche
 | 
						||
  //----------------
 | 
						||
  for (bool ok = s.move_first(); ok; ok = s.move_next())
 | 
						||
  {
 | 
						||
    if (!pi.addstatus(1)) 
 | 
						||
      break;
 | 
						||
    curr_line ++;
 | 
						||
 | 
						||
    //prende i dati dal record di input del file csv
 | 
						||
    //----------------------------------------------
 | 
						||
    //codcms ci deve essere e va maiuscolizzato; se non c'<27> va segnalato sul log..
 | 
						||
    //..ed impedir<69> la write del movana
 | 
						||
    TString80 codcms = s.get(0).as_string();
 | 
						||
    if (codcms.blank())
 | 
						||
    {
 | 
						||
      TString msg;
 | 
						||
      msg.format("Manca la commessa nella riga %ld", curr_line);
 | 
						||
      log.log(2, msg);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
    codcms.upper();
 | 
						||
    //cdc ci deve essere e va maiuscolizzato; se non c'<27> va segnalato sul log..
 | 
						||
    //..ed impedir<69> la write del movana
 | 
						||
    TString80 cdc = s.get(1).as_string();
 | 
						||
    if (cdc.blank())
 | 
						||
    {
 | 
						||
      TString msg;
 | 
						||
      msg.format("Manca la sede nella riga %ld", curr_line);
 | 
						||
      log.log(2, msg);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
    cdc.upper();
 | 
						||
 | 
						||
    //importo (inizialmente come stringa x poter fare le replace); se nullo va segnalato..
 | 
						||
    //..ma niente bloccaggio della write
 | 
						||
    TString80 str_importo = s.get(2).as_string();
 | 
						||
    if (sep_dec == ',')
 | 
						||
    {
 | 
						||
      str_importo.strip(".");  //togle il separatore delle migliaia
 | 
						||
      str_importo.replace(',','.'); //sostituisce il separatore decimale
 | 
						||
    }
 | 
						||
    else
 | 
						||
      str_importo.strip(",");
 | 
						||
 | 
						||
    const real importo = str_importo;
 | 
						||
    /*if (importo == ZERO)
 | 
						||
    {
 | 
						||
      TString msg;
 | 
						||
      msg.format("Importo nullo nella riga %ld", curr_line);
 | 
						||
      log.log(0, msg);
 | 
						||
    }*/
 | 
						||
 | 
						||
    //sezione
 | 
						||
    TString8 str_sezione = s.get(3).as_string();
 | 
						||
    if (str_sezione.blank())
 | 
						||
    {
 | 
						||
      TString msg;
 | 
						||
      msg.format("Manca la sezione nella riga %ld", curr_line);
 | 
						||
      log.log(2, msg);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
    str_sezione.upper();
 | 
						||
    const char sezione = str_sezione[0];
 | 
						||
 | 
						||
    //conto
 | 
						||
    const int gr = s.get(4).as_int();
 | 
						||
    const int co = s.get(5).as_int();
 | 
						||
    const long so = s.get(6).as_int();
 | 
						||
    TString80 conto;
 | 
						||
    conto.format("%03d%03d%06ld", gr, co, so);
 | 
						||
    if (conto.blank())
 | 
						||
    {
 | 
						||
      TString msg;
 | 
						||
      msg.format("Manca il conto nella riga %ld", curr_line);
 | 
						||
      log.log(2, msg);
 | 
						||
      continue;
 | 
						||
    }
 | 
						||
 | 
						||
    //riempie la riga analitica
 | 
						||
    //-------------------------
 | 
						||
    //nuova riga del movana (sfrutta il fatto che <20> un multiple rectype)
 | 
						||
    TRectype& rmovana = movana.new_row();
 | 
						||
 | 
						||
    rmovana.put(RMOVANA_DESCR, "Riga importata");
 | 
						||
    rmovana.put(RMOVANA_CODCONTO, conto);
 | 
						||
    rmovana.put(RMOVANA_CODCMS, codcms);
 | 
						||
    rmovana.put(RMOVANA_CODCCOSTO, cdc);
 | 
						||
    rmovana.put(RMOVANA_SEZIONE, sezione);
 | 
						||
    rmovana.put(RMOVANA_IMPORTO, importo);
 | 
						||
    //aggiorna anche il totale documento..
 | 
						||
    TImporto importo_riga(sezione, importo);
 | 
						||
    totale += importo_riga;
 | 
						||
  }
 | 
						||
 | 
						||
  //completa la testata
 | 
						||
  //-------------------
 | 
						||
  totale.normalize();
 | 
						||
  const char totsez = totale.sezione();
 | 
						||
  const real totimp = totale.valore();
 | 
						||
 | 
						||
  //controllo sul totmov in caso di riscrittura
 | 
						||
  if (ori_totimp != totimp || (ori_totimp == ZERO && ori_totsez != totsez))
 | 
						||
  {
 | 
						||
    TString str_totimp;
 | 
						||
    str_totimp << totimp;
 | 
						||
    TString str_ori_totimp;
 | 
						||
    str_ori_totimp << ori_totimp;
 | 
						||
    TString msg;
 | 
						||
    msg.format("Il totale movimento originale e' %s %c, quello importato e' %s %c.\n"
 | 
						||
               "Registrare il movimento con il totale delle righe importate?", 
 | 
						||
               (const char*)str_totimp, totsez, (const char*)str_ori_totimp, ori_totsez);
 | 
						||
    if (!yesno_box(msg))
 | 
						||
      log.log(2, "Totale movimento originale NON coincidente con quello importato !");
 | 
						||
  }
 | 
						||
  movana.put(MOVANA_SEZIONE, totale.sezione());
 | 
						||
  movana.put(MOVANA_TOTDOC, totale.valore());
 | 
						||
 | 
						||
  //solo se non ci sono errori procede alla registrazione del movimento
 | 
						||
	const int items = log.recordset()->items();
 | 
						||
  if (items > 0)
 | 
						||
    log.preview();
 | 
						||
  else
 | 
						||
  {
 | 
						||
    TLocalisamfile fmovana(LF_MOVANA);
 | 
						||
    int err = movana.rewrite_write(fmovana);
 | 
						||
    if (err != NOERR)
 | 
						||
      error_box("Impossibile registrare il movimento analitico !");
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TImporta_movana::create()
 | 
						||
{
 | 
						||
  _msk = new TImporta_movana_mask();
 | 
						||
  return TSkeleton_application::create();
 | 
						||
}
 | 
						||
 | 
						||
bool TImporta_movana::destroy()
 | 
						||
{
 | 
						||
	delete _msk;
 | 
						||
  return TApplication::destroy();
 | 
						||
}
 | 
						||
 | 
						||
void TImporta_movana::main_loop()
 | 
						||
{
 | 
						||
  KEY	tasto;
 | 
						||
	tasto = _msk->run();
 | 
						||
  TConfig& cfg = ca_config();
 | 
						||
  const bool use_pdcc =  cfg.get_bool("UsePdcc");
 | 
						||
  if (use_pdcc)
 | 
						||
  {
 | 
						||
    if (tasto == K_ENTER)
 | 
						||
    {
 | 
						||
      //genero il nome del file da caricare
 | 
						||
      TFilename name = _msk->get(F_PATH);
 | 
						||
      name.add(_msk->get(F_NAME));
 | 
						||
		  if (transfer(name))
 | 
						||
		  {
 | 
						||
        message_box(TR("Elaborazione completata"));
 | 
						||
		  }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
    error_box("Il programma richiede che sia impostato l'uso del piano dei conti contabile in analitica!");
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
TImporta_movana& app() { return (TImporta_movana&) main_app(); }
 | 
						||
 | 
						||
 | 
						||
int ps1001100 (int argc, char* argv[])
 | 
						||
{
 | 
						||
  TImporta_movana main_app;
 | 
						||
  main_app.run(argc, argv, TR("Importazione movimento analitico da CSV"));
 | 
						||
  return true;
 | 
						||
} |