git-svn-id: svn://10.65.10.50/branches/R_10_00@22935 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1504 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1504 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <applicat.h>
 | 
						|
#include <automask.h>
 | 
						|
#include <colors.h>
 | 
						|
#include <defmask.h>
 | 
						|
#include <modaut.h>
 | 
						|
#include <progind.h>
 | 
						|
#include <recarray.h>
 | 
						|
#include <relation.h>
 | 
						|
#include <reputils.h>
 | 
						|
#include <tabmod.h>
 | 
						|
#include <utility.h>
 | 
						|
 | 
						|
#include <alleg.h>
 | 
						|
#include <attiv.h>
 | 
						|
#include <causali.h>
 | 
						|
#include <clifo.h>
 | 
						|
#include <mov.h>
 | 
						|
#include <nditte.h>
 | 
						|
#include <occas.h>
 | 
						|
#include <partite.h>
 | 
						|
#include <pconti.h>
 | 
						|
#include <rmoviva.h>
 | 
						|
 | 
						|
#include "fe0100a.h"
 | 
						|
#include "felib.h"
 | 
						|
#include "../cg/cglib01.h"
 | 
						|
 | 
						|
const char* const INVALID_NUMDOC = "???????";
 | 
						|
long MANUAL_ROW = 900000L;
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utility
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
enum TExclusion_mode { em_normale, em_importo_limite, em_no_allegato, 
 | 
						|
                       em_fiscalita_agevolata, em_estero, em_intra,
 | 
						|
                       em_art8, em_data_limite, em_passaggi_interni,
 | 
						|
                       em_inviato, em_altro };
 | 
						|
 | 
						|
static const char* mode2string(TExclusion_mode motivo)
 | 
						|
{
 | 
						|
  const char* msg = "";
 | 
						|
  switch (motivo)
 | 
						|
  {
 | 
						|
  case em_importo_limite     : msg = TR("Importo non rilevante"); break;
 | 
						|
  case em_no_allegato        : msg = TR("Soggetto da non inserire in allegato"); break;
 | 
						|
  case em_fiscalita_agevolata: msg = TR("Soggetto residente in stato a fiscalità agevolata"); break;
 | 
						|
  case em_estero             : msg = TR("Soggetto residente all'estero"); break;
 | 
						|
  case em_intra              : msg = TR("Movimento intra"); break;
 | 
						|
  case em_data_limite        : msg = TR("Data fuori dal limite della comunicazione"); break;
 | 
						|
  case em_art8               : msg = TR("Soggetto all'articolo 8 (del dpr 26-10-1972)"); break;
 | 
						|
  case em_passaggi_interni   : msg = TR("Passaggi interni"); break;
 | 
						|
  case em_inviato            : msg = TR("Inviato in definitivo"); break;
 | 
						|
  default                    : msg = TR("Altri motivi"); break;
 | 
						|
  }
 | 
						|
  return msg;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TSpesometro_msk
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TSpesometro_msk : public TAutomask
 | 
						|
{
 | 
						|
  TMaskmode _mode;
 | 
						|
  bool _sheet_dirty;
 | 
						|
  TExclusion_mode _why;
 | 
						|
  TLog_report* _log;
 | 
						|
  TString16 _partita_IVA, _codice_fiscale;
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						|
  void alleg_sort(TSheet_field& s) const;
 | 
						|
  void load_sheet();
 | 
						|
  bool save_sheet();
 | 
						|
  bool save_if_dirty();
 | 
						|
  void set_dirty(bool d = true);
 | 
						|
 | 
						|
  bool send_fatt(const TRectype& alleg, const TAnagrafica& anag, TSpesometro_set& operaz) const;
 | 
						|
  bool send_nota_variazione(const TRectype& alleg, const TAnagrafica& anag, TSpesometro_set& operaz) const;
 | 
						|
  bool send_estero(const TRectype& alleg, const TAnagrafica& anag, TSpesometro_set& operaz) const;
 | 
						|
 | 
						|
  void build_outname(TFilename& n) const;
 | 
						|
  int get_date_range(TDate& dal, TDate& al) const;
 | 
						|
 | 
						|
protected:
 | 
						|
  TRecnotype last_user_progr() const;
 | 
						|
  TRecnotype nuovo_progr() const;
 | 
						|
  bool check_rows(bool show_error);
 | 
						|
  void enable_buttons();
 | 
						|
 | 
						|
  void save_anagr(const TAnagrafica& anag, TSpesometro_set& operaz) const;
 | 
						|
  bool send_rec(const TRectype& alleg, TSpesometro_set& operaz);
 | 
						|
  TExclusion_mode segnala_movimento(const TRectype& mov, TExclusion_mode motivo);
 | 
						|
  
 | 
						|
  //bool fattura_associata(long numreg_var, TDate& datafatt, TString& numdoc) const;
 | 
						|
  bool azzera_alleg(TAssoc_array& manuali) const;
 | 
						|
 | 
						|
public:
 | 
						|
  TRecnotype genera_alleg();
 | 
						|
  bool elabora_alleg();
 | 
						|
  bool send_alleg();
 | 
						|
  bool recall_alleg() const;
 | 
						|
    
 | 
						|
  TExclusion_mode elabora_movimento(const TRectype& mov, TBaseisamfile& falleg);
 | 
						|
 | 
						|
  bool salva_allegato(const TRectype& mov, TBaseisamfile& falleg, TRecnotype& progr, 
 | 
						|
                      const real& corrispettivo, const real& imposta, int tipope);
 | 
						|
 | 
						|
  TExclusion_mode validate_clifo(const TRectype& mov);
 | 
						|
  TExclusion_mode validate_mov(const TRectype& mov);
 | 
						|
 | 
						|
  TSpesometro_msk();
 | 
						|
  ~TSpesometro_msk() { save_profile(); }
 | 
						|
};
 | 
						|
 | 
						|
TSpesometro_msk::TSpesometro_msk() : TAutomask("fe0100a"), _mode(MODE_QUERY), _log(NULL) 
 | 
						|
{ 
 | 
						|
  load_profile(); 
 | 
						|
  set_dirty(false); 
 | 
						|
  const long codditta = prefix().get_codditta();
 | 
						|
  const TAnagrafica ditta(LF_NDITTE, codditta);
 | 
						|
  _partita_IVA = ditta.partita_IVA();
 | 
						|
  if (_partita_IVA.blank())
 | 
						|
    _codice_fiscale = ditta.codice_fiscale();
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (_partita_IVA[0] == '8' || _partita_IVA[0] == '9')
 | 
						|
    {
 | 
						|
      _codice_fiscale = _partita_IVA;
 | 
						|
      _partita_IVA.cut(0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TExclusion_mode TSpesometro_msk::segnala_movimento(const TRectype& mov, TExclusion_mode motivo)
 | 
						|
{
 | 
						|
  if (_why == em_normale) // Aggiorna motivo esclusione se normale
 | 
						|
  {
 | 
						|
    _why = motivo;
 | 
						|
 | 
						|
    bool segnala = true;
 | 
						|
    if (_why != em_fiscalita_agevolata && get(F_TIPO) == "BL") //  Segnalo solo black list
 | 
						|
      segnala = false;
 | 
						|
    if (segnala)
 | 
						|
    {
 | 
						|
      const long numreg = mov.get_long(MOV_NUMREG);
 | 
						|
      const char tipocf = mov.get_char(MOV_TIPO);
 | 
						|
      const long codcf = mov.get_long(MOV_CODCF);
 | 
						|
      const TAnagrafica a(tipocf, codcf, mov.get(MOV_OCFPI));
 | 
						|
      TString msg; 
 | 
						|
      msg.format(FR("Mov. %7ld %s %s: "), numreg, 
 | 
						|
                  tipocf=='F' ? TR("For.") : TR("Cli."), (const char*)a.ragione_sociale());
 | 
						|
      msg << mode2string(motivo);
 | 
						|
 | 
						|
      if (a.estero() && a.stato_estero_UNICO().blank())
 | 
						|
        msg << " (Codice UNICO non specificato)";
 | 
						|
 | 
						|
      msg.strip_double_spaces();
 | 
						|
      _log->log(1, msg);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return motivo;
 | 
						|
}
 | 
						|
 | 
						|
TExclusion_mode TSpesometro_msk::validate_clifo(const TRectype& mov)
 | 
						|
{
 | 
						|
  const char tipocf = mov.get_char(MOV_TIPO);
 | 
						|
  const long codcf = mov.get_long(MOV_CODCF);
 | 
						|
  const TString16 ocfpi = mov.get(MOV_OCFPI);
 | 
						|
  if (tipocf <= ' ' || (codcf <= 0 && ocfpi.blank()))
 | 
						|
    return segnala_movimento(mov, em_no_allegato);
 | 
						|
 | 
						|
  TString8 key; key.format("%c|%ld", tipocf, codcf);
 | 
						|
  const TRectype& rec_clifo = cache().get(LF_CLIFO, key);
 | 
						|
  const int alleg = rec_clifo.get_int(CLI_ALLEG);
 | 
						|
  TString4 stato = rec_clifo.get(CLI_STATOCF); // Può cambiare per occasionali
 | 
						|
 | 
						|
  if (alleg == 4)
 | 
						|
  {
 | 
						|
    const long codalleg = rec_clifo.get_long(CLI_CODALLEG);
 | 
						|
    if (codalleg > 0L)
 | 
						|
    {
 | 
						|
      key.format("%c|%ld", tipocf, codalleg);
 | 
						|
      const TRectype& rec_alleg = cache().get(LF_CLIFO, key);
 | 
						|
      if (!rec_alleg.empty())
 | 
						|
      {
 | 
						|
        ((TRectype&)mov).put(MOV_CODCF, codalleg);
 | 
						|
        return validate_clifo(mov);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (ocfpi.full())
 | 
						|
  {
 | 
						|
    const TRectype& rec_occas = cache().get(LF_OCCAS, ocfpi);
 | 
						|
    stato = rec_occas.get(OCC_STATO);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (alleg == 1)
 | 
						|
      return segnala_movimento(mov, em_no_allegato);
 | 
						|
 | 
						|
    if (alleg == 5)
 | 
						|
      return segnala_movimento(mov, em_intra);
 | 
						|
 | 
						|
    if (stato.blank() && alleg == 9) // Flag extra CEE incoerente
 | 
						|
      return segnala_movimento(mov, em_estero);
 | 
						|
  }
 | 
						|
 | 
						|
  if (stato.full())
 | 
						|
  {
 | 
						|
    // I clienti privati vanno inclusi anche se residenti in stati esteri in black list
 | 
						|
    if (ocfpi.blank() && alleg != 6)
 | 
						|
    {
 | 
						|
      const TRectype& rec_sta = cache().get("%STA", stato);
 | 
						|
      if (rec_sta.get_bool("B0") || rec_sta.get_bool("B1"))  // Black list o San Marino
 | 
						|
        return segnala_movimento(mov, em_fiscalita_agevolata);
 | 
						|
    }
 | 
						|
    return segnala_movimento(mov, em_estero);
 | 
						|
  }
 | 
						|
  
 | 
						|
  return em_normale;  // se arriva qui il clifo è da considerare
 | 
						|
}
 | 
						|
 | 
						|
TExclusion_mode TSpesometro_msk::validate_mov(const TRectype& mov)
 | 
						|
{
 | 
						|
  // Ignora eventuale vecchio movimento IVA (ANNOIVA < 2012)
 | 
						|
  const int anno = mov.get_int(MOV_ANNOIVA);
 | 
						|
  if (anno < 2012)
 | 
						|
    return segnala_movimento(mov, em_data_limite);
 | 
						|
 | 
						|
  if (mov.get_long(MOV_NUMREG) == 57503)
 | 
						|
    int cazzone = 1;
 | 
						|
 | 
						|
  TExclusion_mode em = validate_clifo(mov);
 | 
						|
  if (em != em_normale)
 | 
						|
    return em;
 | 
						|
 | 
						|
  // Trova i movimenti  INTRA
 | 
						|
  if (!mov.get_real(MOV_CORRLIRE).is_zero() || !mov.get_real(MOV_CORRVALUTA).is_zero())
 | 
						|
    em = segnala_movimento(mov, em_intra);
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const TString& keytok = mov.get(MOV_NUMREG);
 | 
						|
    const char tipocf = mov.get_char(MOV_TIPO);
 | 
						|
    TRecord_array righe_iva(keytok, LF_RMOVIVA);
 | 
						|
    real tot_imponibile, tot_imposta;
 | 
						|
    //calcolo di imponibile ed imposta di tutte le righe iva del movimento
 | 
						|
    for (int r = righe_iva.last_row(); r > 0; r = righe_iva.pred_row(r))
 | 
						|
    {
 | 
						|
      const TRectype& rmi = righe_iva.row(r);
 | 
						|
      const TCodiceIVA ci(rmi.get(RMI_CODIVA));
 | 
						|
      const int natura_operazione = ci.allegato(tipocf);
 | 
						|
      if (natura_operazione <= 0 || natura_operazione > 5)
 | 
						|
        continue;
 | 
						|
      tot_imponibile += rmi.get_real(RMI_IMPONIBILE);
 | 
						|
      tot_imposta += rmi.get_real(RMI_IMPOSTA);
 | 
						|
    }
 | 
						|
    if (tot_imponibile.is_zero() && tot_imposta.is_zero())
 | 
						|
      em = segnala_movimento(mov, em_importo_limite);
 | 
						|
  }
 | 
						|
  
 | 
						|
  return em;
 | 
						|
}
 | 
						|
 | 
						|
TExclusion_mode TSpesometro_msk::elabora_movimento(const TRectype& mov, TBaseisamfile& falleg)
 | 
						|
{
 | 
						|
  TExclusion_mode em = validate_mov(mov);
 | 
						|
 | 
						|
  const char tipocf = mov.get_char(MOV_TIPO);
 | 
						|
  const long codcf = mov.get_long(MOV_CODCF);
 | 
						|
  const TString4 tipodoc = mov.get(MOV_TIPODOC);
 | 
						|
  const TDate datareg = mov.get_date(MOV_DATAREG);
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
 | 
						|
  TString4 tipope = "FE";  // Default = Fattura emessa
 | 
						|
 | 
						|
  if (em == em_fiscalita_agevolata)
 | 
						|
  {
 | 
						|
    tipope = "BL";
 | 
						|
  } else
 | 
						|
  if (em == em_estero)
 | 
						|
  {
 | 
						|
    if (tipocf == 'C')
 | 
						|
      tipope = "FN";
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const bool is_nota = fe_is_nota_variazione(mov);
 | 
						|
    if (tipocf == 'F')
 | 
						|
    {
 | 
						|
      tipope = is_nota ? "NR" : "FR";
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      tipope = is_nota ? "NE" : "FE";
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const TString& keytok = mov.get(MOV_NUMREG);
 | 
						|
  TRecord_array righe_iva(keytok, LF_RMOVIVA);
 | 
						|
  int tipo_iva = 1; // Normale
 | 
						|
  real tot_imponibile, tot_imposta;
 | 
						|
  real ser_imponibile, mer_imponibile;
 | 
						|
  //calcolo di imponibile ed imposta di tutte le righe iva del movimento
 | 
						|
  for (int r = righe_iva.last_row(); r > 0; r = righe_iva.pred_row(r))
 | 
						|
  {
 | 
						|
    const TRectype& rmi = righe_iva.row(r);
 | 
						|
    const TCodiceIVA ci(rmi.get(RMI_CODIVA));
 | 
						|
    int natura_operazione = ci.allegato(tipocf);
 | 
						|
    if (natura_operazione <= 0 || natura_operazione > 5)
 | 
						|
      continue; // Scarta codici IVA non rilevanti
 | 
						|
    if (natura_operazione > tipo_iva)
 | 
						|
      tipo_iva = natura_operazione;
 | 
						|
    // Esportazioni
 | 
						|
    const bool art_8 = ci.get("S2") == "20" && ci.get("S3") == "1";
 | 
						|
    if (art_8)
 | 
						|
      segnala_movimento(mov, em_art8);
 | 
						|
 | 
						|
    const TString4 cod_det = rmi.get(RMI_TIPODET);
 | 
						|
    const int tip_det = cod_det == "3" ? 3 : atoi(cache().get("%DET", cod_det, "I0"));
 | 
						|
    if (tip_det == 3)
 | 
						|
      segnala_movimento(mov, em_passaggi_interni);
 | 
						|
 | 
						|
    real rmi_imponibile = rmi.get_real(RMI_IMPONIBILE);
 | 
						|
    real rmi_imposta = rmi.get_real(RMI_IMPOSTA);
 | 
						|
 | 
						|
    if (natura_operazione == 4 && rmi_imposta.is_zero()) // se l'imposta non è specificata sullo scontrino ...
 | 
						|
      rmi_imposta = ci.scorpora(rmi_imponibile);         // ... scorporo il lordo
 | 
						|
 | 
						|
    tot_imponibile += rmi_imponibile;
 | 
						|
    tot_imposta += rmi_imposta;
 | 
						|
 | 
						|
    if (tipope == "SE")
 | 
						|
    {
 | 
						|
      const TBill zio(rmi); 
 | 
						|
      const TRectype& rec = cache().get(LF_PCON, zio.string());
 | 
						|
      if (rec.get_int(PCN_RICSER) == 1) // 0=Altro; 1=Servizi; 2=Merce
 | 
						|
        ser_imponibile += rmi_imponibile;
 | 
						|
      else
 | 
						|
        mer_imponibile += rmi_imponibile;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const long numreg = mov.get_long(MOV_NUMREG);
 | 
						|
 | 
						|
  // Registro tutti i dati del cliente e gli importi
 | 
						|
  falleg.zero();
 | 
						|
 | 
						|
  switch (em)
 | 
						|
  {
 | 
						|
  case em_normale:
 | 
						|
    {
 | 
						|
      TString8 key; key << tipocf << '|' << codcf;
 | 
						|
      const TRectype& clifo = cache().get(LF_CLIFO, key);
 | 
						|
      if (clifo.get_char(CLI_ALLEG) == 'C') // Carta carburanti
 | 
						|
        falleg.put(ALL_CARBURAN, true); 
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if (tipocf == 'C')
 | 
						|
        {
 | 
						|
          bool af = false;
 | 
						|
          if (_partita_IVA.full())
 | 
						|
            af = _partita_IVA == clifo.get(CLI_PAIV);
 | 
						|
          else
 | 
						|
            af = _codice_fiscale == clifo.get(CLI_COFI) && clifo.get(CLI_PAIV).blank(); // Agriturismo
 | 
						|
          if (af)
 | 
						|
          {
 | 
						|
            falleg.put(ALL_AUTOFATT, af);
 | 
						|
            if (tot_imponibile.is_zero() && !tot_imposta.is_zero())
 | 
						|
              tot_imponibile = tot_imposta.sign();
 | 
						|
          }
 | 
						|
        }
 | 
						|
        if (mov.get_int(MOV_UPROTIVA) > mov.get_int(MOV_PROTIVA))
 | 
						|
          falleg.put(ALL_RIEPILOG, true);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case em_fiscalita_agevolata: 
 | 
						|
    if (abs(tot_imponibile) <= 500)
 | 
						|
      falleg.put(ALL_IGNORA, em = em_importo_limite); // Ignora importo <= 500 Euro
 | 
						|
    break; // Non ignorare!
 | 
						|
  case em_estero:
 | 
						|
    if (tot_imponibile.is_zero())
 | 
						|
      falleg.put(ALL_IGNORA, em = em_importo_limite); // Ignora importo nullo
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (tipocf == 'F') // Considera solo fatture servizi
 | 
						|
      {
 | 
						|
        if (ser_imponibile > mer_imponibile)
 | 
						|
          falleg.put(ALL_SERVIZI, true);
 | 
						|
        else
 | 
						|
          falleg.put(ALL_IGNORA, em); // Ignora importazioni di merce    
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case em_intra:
 | 
						|
    if (tipocf == 'C' && !tot_imposta.is_zero())
 | 
						|
    {
 | 
						|
      tipope = "FN";
 | 
						|
      em = em_estero;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  default: 
 | 
						|
    falleg.put(ALL_IGNORA, em); // Ignora
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  if (mov.get_date(MOV_INVIOFE).ok())
 | 
						|
  {
 | 
						|
    falleg.put(ALL_IGNORA, em_inviato);
 | 
						|
    segnala_movimento(mov, em_inviato);
 | 
						|
  }
 | 
						|
 | 
						|
  if (em == em_normale || em_intra)
 | 
						|
  {
 | 
						|
    if (tipocf == 'F')
 | 
						|
    {
 | 
						|
      const TRectype& caus = cache().get(LF_CAUSALI, mov.get(MOV_CODCAUS));
 | 
						|
      const int reg_spec = caus.get_int(CAU_REGSPIVA);
 | 
						|
      if (reg_spec == 13 || reg_spec == 50 || reg_spec == 51) // reverse charge
 | 
						|
        falleg.put(ALL_REVERSE, true);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (tipope == "SE")
 | 
						|
  {
 | 
						|
    const TAnagrafica anag(mov);
 | 
						|
    bool good = anag.comune_residenza().full();
 | 
						|
    if (good)
 | 
						|
    {
 | 
						|
      if (anag.fisica())
 | 
						|
        good = anag.cognome().full() && anag.data_nascita().ok();
 | 
						|
      else
 | 
						|
        good = anag.ragione_sociale().full();
 | 
						|
    }
 | 
						|
    if (!good)
 | 
						|
    {
 | 
						|
      TString8 key; key << tipocf << '|' << codcf;
 | 
						|
      const TRectype& clifo = cache().get(LF_CLIFO, key);
 | 
						|
      if (clifo.get_int(CLI_ALLEG) == 9) // Extra CEE con dati anagrafici insufficienti
 | 
						|
      {
 | 
						|
        falleg.put(ALL_AUTOFATT, true);
 | 
						|
        if (tot_imponibile.is_zero() && !tot_imposta.is_zero())
 | 
						|
          tot_imponibile = tot_imposta.sign();
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  falleg.put(ALL_ANNO,    anno);
 | 
						|
  falleg.put(ALL_PROGR,   numreg);
 | 
						|
  falleg.put(ALL_TIPOPE,  tipope);
 | 
						|
  falleg.put(ALL_TIPOCF,  tipocf);
 | 
						|
  falleg.put(ALL_CODCF,   codcf);
 | 
						|
  falleg.put(ALL_OCFPI,   mov.get(MOV_OCFPI));
 | 
						|
  falleg.put(ALL_DATAREG, mov.get(MOV_DATAREG));
 | 
						|
  falleg.put(ALL_NUMDOC,  mov.get(MOV_NUMDOC));
 | 
						|
  falleg.put(ALL_DATADOC, mov.get(MOV_DATADOC));
 | 
						|
  falleg.put(ALL_NOLEGGIO,mov.get(MOV_NOLEGGIO));
 | 
						|
  falleg.put(ALL_TIPOIVA, tipo_iva);
 | 
						|
  falleg.put(ALL_IMPORTO, tot_imponibile);
 | 
						|
  falleg.put(ALL_IMPOSTA, tot_imposta);
 | 
						|
 | 
						|
  const int err = falleg.rewrite_write();
 | 
						|
  if (err != NOERR)
 | 
						|
  {
 | 
						|
    TString msg; 
 | 
						|
    msg.format(FR("Errore %d di aggiornamento del record %d/%ld sul file %s"), 
 | 
						|
               err, anno, numreg, (const char*)falleg.name());
 | 
						|
    _log->log(2, msg);
 | 
						|
  }
 | 
						|
 | 
						|
  return _why;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::azzera_alleg(TAssoc_array& manuali) const
 | 
						|
{
 | 
						|
  TDate dataini, datafin;
 | 
						|
  const int anno = get_date_range(dataini, datafin);
 | 
						|
  if (!delete_box(FR("Si desiderano eliminare le righe dal %s al %s"), 
 | 
						|
                  dataini.stringa(), datafin.stringa()))
 | 
						|
    return false;
 | 
						|
 | 
						|
  TFast_isamfile fast_alleg(LF_ALLEG);
 | 
						|
  TFast_isamfile fast_mov(LF_MOV);
 | 
						|
 | 
						|
  TString query;
 | 
						|
  query << "USE " << LF_ALLEG 
 | 
						|
        << "\nSELECT BETWEEN(DATAREG," << dataini.date2ansi() << ',' << datafin.date2ansi() << ')'
 | 
						|
        << "\nJOIN MOV INTO NUMREG==PROGR"
 | 
						|
        << "\nFROM ANNO=" << anno
 | 
						|
        << "\nTO ANNO=" << anno << " PROGR=" << MANUAL_ROW;
 | 
						|
  TISAM_recordset alleg(query);
 | 
						|
 | 
						|
  TLocalisamfile& falleg = alleg.cursor()->file();
 | 
						|
  TRectype& arec = falleg.curr();
 | 
						|
 | 
						|
  TLocalisamfile& fmov = alleg.cursor()->file(LF_MOV);
 | 
						|
  TRectype& mrec = fmov.curr();
 | 
						|
 | 
						|
  TString msg; msg << TR("Azzeramento ") << falleg.description() << ' ' << anno;
 | 
						|
  TProgind pi(alleg.items(), msg, false);
 | 
						|
 | 
						|
  manuali.destroy();
 | 
						|
  for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
 | 
						|
  {
 | 
						|
    pi.addstatus(1);
 | 
						|
 | 
						|
    const long progr = arec.get_long(ALL_PROGR);
 | 
						|
    const long numreg = mrec.get_long(MOV_NUMREG);
 | 
						|
    const TDate datareg = mrec.get_long(MOV_DATAREG);
 | 
						|
    const int annoiva = mrec.get_long(MOV_ANNOIVA);
 | 
						|
    
 | 
						|
    bool kill = numreg != progr || annoiva < anno; 
 | 
						|
    if (!kill)
 | 
						|
    {
 | 
						|
      const bool forzata = arec.get_bool(ALL_FORZATURA);
 | 
						|
      if (forzata)
 | 
						|
        manuali.add(arec.get(ALL_PROGR));
 | 
						|
      else
 | 
						|
        kill = annoiva == anno;
 | 
						|
    }
 | 
						|
    if (kill)
 | 
						|
      falleg.remove(); // Riga generata dalla vecchia versione
 | 
						|
  }
 | 
						|
  return !manuali.empty();
 | 
						|
}
 | 
						|
 | 
						|
// Cerca l'ultimo numero di riga immesso manualmente
 | 
						|
TRecnotype TSpesometro_msk::last_user_progr() const
 | 
						|
{
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
 | 
						|
  TRecnotype progr = MANUAL_ROW;
 | 
						|
  TString query;
 | 
						|
  query << "USE " << LF_ALLEG
 | 
						|
        << "\nFROM " << ALL_ANNO << '=' << anno << ' ' << ALL_PROGR << '=' << MANUAL_ROW
 | 
						|
        << "\nTO "   << ALL_ANNO << '=' << anno;
 | 
						|
  TISAM_recordset alleg(query);
 | 
						|
  if (alleg.move_last())
 | 
						|
    progr = alleg.get(ALL_PROGR).as_int();
 | 
						|
  return progr;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TSpesometro_msk::nuovo_progr() const
 | 
						|
{
 | 
						|
  TRecnotype progr = last_user_progr();
 | 
						|
 | 
						|
  TSheet_field& righe = sfield(F_RIGHE);
 | 
						|
  const int items = righe.items();
 | 
						|
  if (items > 0)
 | 
						|
  {
 | 
						|
    const int col = righe.cid2index(A_RIGA); 
 | 
						|
    for (int i = items-1; i >= 0; i--)
 | 
						|
    {
 | 
						|
      const TRecnotype sheet_progr = atol(righe.cell(i,col));
 | 
						|
      if (sheet_progr > progr)
 | 
						|
        progr = sheet_progr;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return progr+1;
 | 
						|
}
 | 
						|
 | 
						|
static int sort_alleg(const TSortable& s1, const TSortable& s2, void* jolly)
 | 
						|
{
 | 
						|
  const TRectype& a1 = (const TRectype&)s1;
 | 
						|
  const TRectype& a2 = (const TRectype&)s2;
 | 
						|
 | 
						|
  const TDate d1 = a1.get(ALL_DATAREG);
 | 
						|
  const TDate d2 = a2.get(ALL_DATAREG);
 | 
						|
  int cmp = d1 - d2;
 | 
						|
 | 
						|
  return cmp;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TSpesometro_msk::genera_alleg()
 | 
						|
{
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
 | 
						|
  TString str_pi;
 | 
						|
  str_pi << TR("Movimenti");
 | 
						|
  str_pi << ' ' << anno;
 | 
						|
  _log = new TLog_report(str_pi);
 | 
						|
 | 
						|
  TAssoc_array manuali;
 | 
						|
  azzera_alleg(manuali);
 | 
						|
  
 | 
						|
  TRecnotype nprog = 1;
 | 
						|
 | 
						|
  if (anno >= 2012) // Dummy test for bracing TFast_isamfiles
 | 
						|
  {
 | 
						|
    TFast_isamfile falleg(LF_ALLEG);
 | 
						|
    TFast_isamfile fmov(LF_MOV);
 | 
						|
 | 
						|
    const TDate dal(1,1,anno);
 | 
						|
    const TDate al(31,12,anno);
 | 
						|
 | 
						|
    TString query;
 | 
						|
    query << "USE MOV KEY 3 SELECT (BETWEEN(DATAREG," 
 | 
						|
          << dal.date2ansi() << ',' << al.date2ansi() << "))&&(REG!=\"\")"
 | 
						|
          << "\nFROM TIPO=C\nTO TIPO=F";
 | 
						|
    TISAM_recordset mov(query);
 | 
						|
    TRectype& mov_rec = mov.cursor()->curr();
 | 
						|
    const TRecnotype items = mov.items();
 | 
						|
 | 
						|
    TProgind pi(items, str_pi);
 | 
						|
    for (bool ok = mov.move_first(); ok; ok = mov.move_next())
 | 
						|
    {
 | 
						|
      if (!pi.addstatus(1))
 | 
						|
        break;
 | 
						|
      _why = em_normale;
 | 
						|
 | 
						|
      const TDate datafe = mov_rec.get(MOV_INVIOFE);
 | 
						|
      if (datafe.ok()) // Non elaborare i movimenti già inviati in definitivo!
 | 
						|
      {
 | 
						|
        segnala_movimento(mov_rec, em_inviato);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      const TString& key = mov_rec.get(MOV_NUMREG);
 | 
						|
      if (manuali.is_key(key))
 | 
						|
      {
 | 
						|
        manuali.remove(key);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      elabora_movimento(mov_rec, falleg); 
 | 
						|
    }   
 | 
						|
  }
 | 
						|
 | 
						|
  _log->preview();
 | 
						|
  delete _log;
 | 
						|
  _log = NULL;
 | 
						|
 | 
						|
  return nprog;
 | 
						|
}
 | 
						|
 | 
						|
// Analizza tutti i movimenti dell'anno dell'attività corrente e genera i record rilevanti
 | 
						|
bool TSpesometro_msk::elabora_alleg()
 | 
						|
{
 | 
						|
  if (!check_fields()) // Controlla che l'anno sia valido
 | 
						|
    return false;
 | 
						|
 | 
						|
  const TRecnotype prog = genera_alleg();
 | 
						|
  return prog > 1;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::send_nota_variazione(const TRectype& alleg, const TAnagrafica& anag, TSpesometro_set& operaz) const
 | 
						|
{
 | 
						|
  const real imp = alleg.get_real(ALL_IMPORTO);
 | 
						|
  operaz.set(11, imp > ZERO ? "ND" : "NC");
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::send_fatt(const TRectype& alleg, const TAnagrafica& anag, TSpesometro_set& operaz) const
 | 
						|
{ 
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::send_estero(const TRectype& alleg, const TAnagrafica& anag, TSpesometro_set& operaz) const
 | 
						|
{
 | 
						|
  const char tipocf = alleg.get_char(ALL_TIPOCF);
 | 
						|
  const bool is_nota = fe_is_nota_variazione(alleg);
 | 
						|
  
 | 
						|
  if (is_nota) // Le istruzioni dicono di ignorarla, ma Sirio non ha ancora deciso
 | 
						|
    send_nota_variazione(alleg, anag, operaz);  // Imposta solamente il campo 11 a ND o NC
 | 
						|
 | 
						|
  const char cayman = anag.is_black_list(alleg.get_date(ALL_DATAREG));
 | 
						|
  const bool servizi = tipocf == 'F' && alleg.get_bool(ALL_SERVIZI);
 | 
						|
 | 
						|
  if (servizi && alleg.get_bool(ALL_AUTOFATT))
 | 
						|
  {
 | 
						|
    // Trasforma la fattura da non residente ad autofattura
 | 
						|
    operaz.set(0, "FR");
 | 
						|
    // Azzera campi anagrafici e sostituiscili con quelli del dichiarante
 | 
						|
    const long codditta = prefix().get_codditta();
 | 
						|
    const TAnagrafica ditta(LF_NDITTE, codditta);
 | 
						|
    for (int f = 14; f <= 26; f++)
 | 
						|
      operaz.set(f, "");
 | 
						|
    save_anagr(ditta, operaz);
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  
 | 
						|
  // I flag 27,28,29 sono obbligatori e mutuamente esclusivi
 | 
						|
  if (cayman > ' ') // Residente in paese a fiscalità agevolata (o San Marino)
 | 
						|
  {
 | 
						|
    const char str[2] = { cayman, '\0' };  // Convert char to string
 | 
						|
    operaz.set(27, str);     
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (servizi)
 | 
						|
      operaz.set(29, true);   // Acquisto servizi all'estero
 | 
						|
    else
 | 
						|
      operaz.set(28, true);   // Residente all'estero
 | 
						|
  }
 | 
						|
 | 
						|
  const char* sez = "BL30";
 | 
						|
  if (cayman > ' ')
 | 
						|
  {
 | 
						|
    if (is_nota)
 | 
						|
      sez = "BL50";
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (alleg.get_int(ALL_TIPOIVA) == 4) // Non esposta
 | 
						|
        sez = "BL41";
 | 
						|
    }
 | 
						|
  }
 | 
						|
  operaz.set(30, sez);   // Tipologia imponibile BL
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_msk::save_anagr(const TAnagrafica& anag, TSpesometro_set& operaz) const
 | 
						|
{
 | 
						|
  // Partita IVA e Codice fiscale sono alternativi
 | 
						|
  const TString& piva = anag.partita_IVA();
 | 
						|
  if (piva.full())
 | 
						|
  {
 | 
						|
    if (piva[0] >= '8' && piva.len() == 11 && anag.italiano()) // Ente pubblico!
 | 
						|
      operaz.set(2, piva);  // In realtà trattasi di codice fiscale speciale!
 | 
						|
    else
 | 
						|
      operaz.set(1, piva);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    operaz.set( 2, anag.codice_fiscale());
 | 
						|
 | 
						|
  if (anag.fisica())
 | 
						|
  {
 | 
						|
    operaz.set(14, anag.cognome());
 | 
						|
    operaz.set(15, anag.nome());
 | 
						|
    operaz.set(16, anag.data_nascita());
 | 
						|
    operaz.set(17, anag.comune_nascita());
 | 
						|
    operaz.set(18, anag.provincia_nascita());
 | 
						|
    operaz.set(19, anag.stato_estero_UNICO());
 | 
						|
    operaz.set(20, anag.comune_residenza());
 | 
						|
    operaz.set(21, anag.indirizzo_residenza());
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    operaz.set(22, anag.ragione_sociale());
 | 
						|
    operaz.set(23, anag.comune_residenza());
 | 
						|
    operaz.set(24, anag.stato_estero_UNICO());
 | 
						|
    operaz.set(25, anag.indirizzo_residenza());
 | 
						|
    operaz.set(26, piva);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::send_rec(const TRectype& alleg, TSpesometro_set& operaz)
 | 
						|
{
 | 
						|
  bool done = false;
 | 
						|
 | 
						|
  const real importo = abs(alleg.get_real(ALL_IMPORTO));
 | 
						|
  const real imposta = abs(alleg.get_real(ALL_IMPOSTA));
 | 
						|
  if (importo.is_zero() && imposta.is_zero())
 | 
						|
    return false; // should never happen
 | 
						|
 | 
						|
  const TAnagrafica anag(alleg);
 | 
						|
  if (!anag.ok())
 | 
						|
    return false; // should never happen
 | 
						|
 | 
						|
  const char tipocf = alleg.get_char(ALL_TIPOCF);
 | 
						|
 | 
						|
  const TString4 tipo = alleg.get(ALL_TIPOPE);
 | 
						|
  operaz.new_rec(tipo); 
 | 
						|
 | 
						|
  operaz.set(31, alleg.get_int(ALL_ATTAGG));   // Provoca nascita dei 34 campi vuoti precedenti
 | 
						|
  operaz.set(32, alleg.get_int(ALL_PASAGG));
 | 
						|
  operaz.set(33, alleg.get_bool(ALL_RIEPILOG)); 
 | 
						|
  operaz.set(34, alleg.get_bool(ALL_CARBURAN)); 
 | 
						|
 | 
						|
  operaz.set( 3, alleg.get_int(ALL_TIPOIVA) == 4);    // IVA non esposta in fattura
 | 
						|
  operaz.set( 4, alleg.get(ALL_NOLEGGIO));            // Noleggio 
 | 
						|
  operaz.set( 5, alleg.get_bool(ALL_AUTOFATT));       // Autofattura
 | 
						|
  operaz.set( 6, alleg.get_bool(ALL_REVERSE));        // Reverse charge
 | 
						|
  
 | 
						|
  operaz.set( 7, alleg.get(ALL_DATADOC));  
 | 
						|
  operaz.set( 8, alleg.get(ALL_DATAREG));  
 | 
						|
  operaz.set( 9, alleg.get(ALL_NUMDOC));  
 | 
						|
  operaz.set(10, tipocf == 'F' ? "A" : "C");  // Acquisto o Cessione
 | 
						|
  
 | 
						|
  operaz.set(12, importo);
 | 
						|
  operaz.set(13, imposta);
 | 
						|
  save_anagr(anag, operaz);
 | 
						|
 | 
						|
  if (anag.estero())
 | 
						|
    done = send_estero(alleg, anag, operaz); 
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (fe_is_nota_variazione(alleg))
 | 
						|
      done = send_nota_variazione(alleg, anag, operaz);
 | 
						|
    else
 | 
						|
      done = send_fatt(alleg, anag, operaz);
 | 
						|
  }
 | 
						|
  return done;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::recall_alleg() const
 | 
						|
{
 | 
						|
  TDate dal, al;
 | 
						|
  const int anno = get_date_range(dal, al);
 | 
						|
 | 
						|
  if (!delete_box(FR("Si desidera annullare l'invio definitivo dal %s al %s?"), 
 | 
						|
                     dal.stringa(), al.stringa()))
 | 
						|
    return false;
 | 
						|
 | 
						|
  TFast_isamfile mov(LF_MOV);
 | 
						|
 | 
						|
  TString query;
 | 
						|
  query << "USE MOV KEY 2";
 | 
						|
  query << "\nFROM DATAREG=" << dal;
 | 
						|
  query << "\nTO DATAREG=" << al;
 | 
						|
  TISAM_recordset recset(query);
 | 
						|
  TLocalisamfile& file = recset.cursor()->file();
 | 
						|
 | 
						|
  TString msg;
 | 
						|
  msg << TR("Aggiornamento movimenti di prima nota dal ") 
 | 
						|
      << dal.stringa() << TR(" al ") << al.stringa();
 | 
						|
  TProgind pi(recset.items(), msg);
 | 
						|
  for (bool ok = recset.move_first(); ok; ok = recset.move_next())
 | 
						|
  {
 | 
						|
    if (!pi.addstatus(1))
 | 
						|
      break;
 | 
						|
    if (file.get_date(MOV_INVIOFE).ok())
 | 
						|
    {
 | 
						|
      file.zero(MOV_INVIOFE);
 | 
						|
      file.rewrite();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_msk::build_outname(TFilename& n) const
 | 
						|
{
 | 
						|
  TDate dal, al;
 | 
						|
  const int anno = get_date_range(dal,al);
 | 
						|
  n = get(F_OUTFOLDER);
 | 
						|
  if (n.blank())  
 | 
						|
    n.tempdir(); 
 | 
						|
  
 | 
						|
  TString80 f; 
 | 
						|
  if (get(F_TIPO) == "BL")
 | 
						|
  {
 | 
						|
    const int dm = dal.month(), am = al.month();
 | 
						|
    if (dm == am)
 | 
						|
    {
 | 
						|
      TString16 m = itom(dal.month()); m.cut(3);
 | 
						|
      f.format("BlackList%05ld%s%04d", prefix().get_codditta(), (const char*)m, anno);
 | 
						|
    } else
 | 
						|
    if (am-dm == 2)
 | 
						|
    {
 | 
						|
      TString16 m; m << TR("Trim") << itor(am/3);
 | 
						|
      f.format("BlackList%05ld%s%04d", prefix().get_codditta(), (const char*)m, anno);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      f.format("BlackList%05ld%04d", prefix().get_codditta(), anno);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    f.format("Spesometro%05ld%04d", prefix().get_codditta(), anno);
 | 
						|
  n.add(f);
 | 
						|
  n.ext("csv");
 | 
						|
}
 | 
						|
 | 
						|
// Genera file per invio telematico
 | 
						|
bool TSpesometro_msk::send_alleg()
 | 
						|
{
 | 
						|
  const TString& tipo = get(F_TIPO);
 | 
						|
 | 
						|
  TDate dal, al;
 | 
						|
  const int anno = get_date_range(dal, al);
 | 
						|
 | 
						|
  TString query;
 | 
						|
  query << "USE ALLEG KEY 2\nSELECT ";
 | 
						|
  if (tipo == "BL")
 | 
						|
  {
 | 
						|
    query << "(BETWEEN(DATAREG," << dal.date2ansi() << ',' << al.date2ansi() << "))&&"
 | 
						|
          << "(TIPOPE==\"BL\")";
 | 
						|
  }
 | 
						|
  else
 | 
						|
    query << "(TIPOPE!=\"BL\")";
 | 
						|
 | 
						|
  query << "\nFROM " << ALL_ANNO << '=' << anno
 | 
						|
        << "\nTO " << ALL_ANNO << '=' << anno;
 | 
						|
  
 | 
						|
  TISAM_recordset alleg(query);
 | 
						|
  const TRectype& rec = alleg.cursor()->curr();
 | 
						|
  const TRecnotype tot_alleg = alleg.items();
 | 
						|
 | 
						|
  bool done = tot_alleg > 0;
 | 
						|
  if (done)
 | 
						|
  {
 | 
						|
    TSpesometro_set recset;
 | 
						|
    recset.add_header(*this);
 | 
						|
  
 | 
						|
    TFilename temp; build_outname(temp);
 | 
						|
    _log = new TLog_report(temp);
 | 
						|
 | 
						|
    TProgind pi(tot_alleg, temp);
 | 
						|
    for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
 | 
						|
    {
 | 
						|
      if (!pi.addstatus(1))
 | 
						|
        break;
 | 
						|
 | 
						|
      const int ignora = alleg.get(ALL_IGNORA).as_int(); // Non mi fido di "", " " e "0" per questo campo
 | 
						|
      if (ignora == 0)
 | 
						|
        send_rec(rec, recset);
 | 
						|
    }
 | 
						|
    recset.add_footer(*this);
 | 
						|
    done = recset.save_as(temp);
 | 
						|
    
 | 
						|
    if (_log->recordset()->items())
 | 
						|
      _log->preview();
 | 
						|
    delete _log;
 | 
						|
    _log = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  const char* const jar = "spesometro.jar";
 | 
						|
  if (xvt_fsys_file_exists(jar))
 | 
						|
    xvt_sys_goto_url(jar, "run"); // open doesn't work right now
 | 
						|
 | 
						|
  if (done && get_bool(F_DEFINITIVO) && yesno_box(TR("Si conferma l'invio definitivo della comunicazione?")))
 | 
						|
  {
 | 
						|
    TFast_isamfile mov(LF_MOV);
 | 
						|
    TProgind pi(tot_alleg, TR("Aggiornamento movimenti di prima nota"), false);
 | 
						|
    for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
 | 
						|
    {
 | 
						|
      if (!pi.addstatus(1))
 | 
						|
        break;
 | 
						|
      const int ignora = rec.get_int(ALL_IGNORA);
 | 
						|
      if (ignora)
 | 
						|
        continue;
 | 
						|
      
 | 
						|
      const long numreg = rec.get_long(ALL_PROGR);
 | 
						|
      if (numreg > 0 && numreg < MANUAL_ROW)
 | 
						|
      {
 | 
						|
        mov.put(MOV_NUMREG, numreg);
 | 
						|
        int err = mov.read(_isequal, _lock);
 | 
						|
        if (err == NOERR)
 | 
						|
        {
 | 
						|
          if (!mov.get_date(MOV_INVIOFE).ok())
 | 
						|
          {
 | 
						|
            mov.put(MOV_INVIOFE, al);
 | 
						|
            err = mov.rewrite();
 | 
						|
          }
 | 
						|
          else
 | 
						|
            mov.reread(_unlock);
 | 
						|
        }
 | 
						|
        if (err != NOERR)
 | 
						|
        {
 | 
						|
          error_box(FR("Impossibile aggiornare il movimento %ld: errore %d"), numreg, err);
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }  
 | 
						|
      if (numreg > 0)
 | 
						|
      {
 | 
						|
        TLocalisamfile& fall = alleg.cursor()->file();
 | 
						|
        fall.put(ALL_IGNORA, em_inviato);
 | 
						|
        fall.rewrite();
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return done;
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_msk::set_dirty(bool d)
 | 
						|
{
 | 
						|
  _sheet_dirty = d;
 | 
						|
  enable(DLG_SAVEREC, d);
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_msk::alleg_sort(TSheet_field& s) const
 | 
						|
{
 | 
						|
  s.sort();
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_msk::load_sheet()
 | 
						|
{
 | 
						|
  TWait_cursor hourglass;
 | 
						|
  const char tipocf = get(F_TIPOCF)[0];
 | 
						|
  const long codcf = get_long(F_CODCF);
 | 
						|
  const TString& ocfpi = get(F_OCFPI);
 | 
						|
 | 
						|
  TSheet_field& s = sfield(F_RIGHE);
 | 
						|
  s.hide();   // Nascondo lo sheet per guadagnare un 20% di velocità di caricamento
 | 
						|
  s.destroy(); 
 | 
						|
 | 
						|
  _mode = MODE_QUERY;
 | 
						|
 | 
						|
  const TString& tipope = get(F_TIPO);
 | 
						|
  TDate dal, al;
 | 
						|
  const int anno = get_date_range(dal, al);
 | 
						|
 | 
						|
  TString limit; limit << ALL_ANNO << '=' << anno;
 | 
						|
  if (codcf > 0)
 | 
						|
    limit << ' ' << ALL_TIPOCF << '=' << tipocf << ' ' << ALL_CODCF << '=' << codcf;
 | 
						|
 | 
						|
  TString sel;
 | 
						|
  if (ocfpi.full())
 | 
						|
    sel << "&&(" << ALL_OCFPI << "='" << ocfpi << "')";
 | 
						|
 | 
						|
  if (tipope != "**") // Tutto
 | 
						|
  {
 | 
						|
    if (tipope == "XX")
 | 
						|
    {
 | 
						|
      sel << "&&(STR(IGNORA>0))";
 | 
						|
    } else
 | 
						|
    if (tipope == "IN")
 | 
						|
    {
 | 
						|
      sel << "&&(STR(IGNORA==9))";
 | 
						|
    } 
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (tipope == "BL")
 | 
						|
        sel << "&&(TIPOPE=\"BL\")";  // Black List
 | 
						|
      else
 | 
						|
        sel << "&&(TIPOPE!=\"BL\")"; // Spesometro
 | 
						|
      sel << "&&(STR(IGNORA==0))";
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (dal.month() != 1 || al.month() != 12)
 | 
						|
    sel << "&&(BETWEEN(DATAREG," << dal.date2ansi() << ',' << al.date2ansi() << "))";
 | 
						|
  
 | 
						|
  TString query;
 | 
						|
  query << "USE " << LF_ALLEG << " KEY 2";
 | 
						|
  if (sel.full())
 | 
						|
  {
 | 
						|
    sel.ltrim(2);
 | 
						|
    query << " SELECT " << sel;
 | 
						|
  }
 | 
						|
  if (limit.full())
 | 
						|
    query << "\nFROM " << limit << "\nTO " << limit;
 | 
						|
 | 
						|
  TISAM_recordset alleg(query);
 | 
						|
  const TRecnotype items = alleg.items();
 | 
						|
  if (items > 0)
 | 
						|
  {
 | 
						|
    TString pi_str; 
 | 
						|
    pi_str << TR("Caricamento ") << items << TR(" movimenti ");
 | 
						|
    if (dal.month() != 1 || al.month() != 12)
 | 
						|
    {
 | 
						|
      if (dal.month() == al.month())
 | 
						|
        pi_str << itom(dal.month()) << ' ';
 | 
						|
      else
 | 
						|
        pi_str << itom(dal.month()) << '/' << itom(al.month()) << ' ';
 | 
						|
 | 
						|
    }
 | 
						|
    pi_str << anno;
 | 
						|
    TProgind pi(items, pi_str);
 | 
						|
    TRectype& curr = alleg.cursor()->curr();
 | 
						|
    int rec = 0;
 | 
						|
    for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
 | 
						|
    {
 | 
						|
      if (!pi.addstatus(1)) 
 | 
						|
        break;
 | 
						|
      if (anno <= 2012)
 | 
						|
      {
 | 
						|
        const int t = curr.get_int(ALL_TIPOPE);
 | 
						|
        switch (t)
 | 
						|
        {
 | 
						|
        case  1: curr.put(ALL_TIPOPE, "FE"); break;
 | 
						|
        case  2: curr.put(ALL_TIPOPE, "FR"); break;
 | 
						|
        default: break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      s.autoload_line(++rec, curr);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //alleg_sort(s);
 | 
						|
 | 
						|
  s.force_update();
 | 
						|
  s.show();
 | 
						|
  set_dirty(false);
 | 
						|
 | 
						|
  if (s.items() > 0)
 | 
						|
  {
 | 
						|
    _mode = MODE_MOD;
 | 
						|
    disable(-1);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    _mode = MODE_QUERY;
 | 
						|
    enable(-1);
 | 
						|
  }
 | 
						|
  enable_buttons();
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::save_sheet()
 | 
						|
{
 | 
						|
  if (!check_rows(false))
 | 
						|
    return false;
 | 
						|
  
 | 
						|
  bool done = true;
 | 
						|
  
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
 | 
						|
  TSheet_field& s = sfield(F_RIGHE);
 | 
						|
  const TRecnotype items = s.items();
 | 
						|
 | 
						|
  if (items > 0)
 | 
						|
  {
 | 
						|
    TFast_isamfile alleg(LF_ALLEG);
 | 
						|
    TRectype& rec = alleg.curr();
 | 
						|
    TProgind pi(items, TR("Registrazione righe"), false);
 | 
						|
 | 
						|
    FOR_EACH_SHEET_ROW(s, r, row)
 | 
						|
    {
 | 
						|
      if (!pi.addstatus(1)) 
 | 
						|
        break;
 | 
						|
 | 
						|
      alleg.zero();
 | 
						|
      rec.put(ALL_ANNO, anno);
 | 
						|
      s.autosave_line(r+1, rec);
 | 
						|
      const int err = alleg.rewrite_write();
 | 
						|
      if (err != NOERR)
 | 
						|
      {
 | 
						|
        done = cantwrite_box(alleg.name());
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (done)
 | 
						|
  {
 | 
						|
    set_dirty(false);
 | 
						|
  }
 | 
						|
 | 
						|
  return done;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::check_rows(bool show_error)
 | 
						|
{
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
  bool ok = anno >= 2012;
 | 
						|
  if (!ok)
 | 
						|
  {
 | 
						|
    if (show_error)
 | 
						|
      check_fields(); // Provoco segnalazione automatica
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  long codcf = 0L;
 | 
						|
  TString16 ocfpi;
 | 
						|
  TSheet_field& s = sfield(F_RIGHE);
 | 
						|
  FOR_EACH_SHEET_ROW(s, i, row)
 | 
						|
  {
 | 
						|
    row->get(s.cid2index(A_CODCF), codcf);
 | 
						|
    row->get(s.cid2index(A_OCFPI), ocfpi);
 | 
						|
    if (codcf <= 0L && ocfpi.blank())
 | 
						|
    {
 | 
						|
      ok = show_error && error_box(FR("Soggetto mancante alla riga %d"), i+1);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::save_if_dirty()
 | 
						|
{
 | 
						|
  bool done = true;
 | 
						|
  if (_sheet_dirty && yesno_box(TR("Si desiderano registrare le modifiche?")))
 | 
						|
  {
 | 
						|
    done = check_rows(true);
 | 
						|
    if (done)
 | 
						|
      done = save_sheet();
 | 
						|
  }
 | 
						|
  return done;
 | 
						|
}
 | 
						|
 | 
						|
int TSpesometro_msk::get_date_range(TDate& dal, TDate& al) const
 | 
						|
{
 | 
						|
  const TDate oggi(TODAY);
 | 
						|
  int anno = get_int(F_ANNO); 
 | 
						|
  if (anno < 2012) 
 | 
						|
    anno = oggi.year();
 | 
						|
 | 
						|
  dal = TDate( 1,  1, anno);
 | 
						|
  al  = TDate(31, 12, anno);
 | 
						|
 | 
						|
  if (get(F_TIPO) == "BL")
 | 
						|
  {
 | 
						|
    const TString& m = get(F_PERIODO);
 | 
						|
    if (m[0] == 'T')
 | 
						|
    {
 | 
						|
      const int t = m[1]-'1';
 | 
						|
      dal = TDate( 1, 3*t+1, anno);
 | 
						|
       al = TDate(28, 3*t+3, anno);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      const int mese = atoi(m);
 | 
						|
      if (mese > 0)
 | 
						|
        dal = al = TDate(1, mese, anno);
 | 
						|
    }
 | 
						|
    al.set_end_month();
 | 
						|
  }
 | 
						|
 | 
						|
  return anno;
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_msk::enable_buttons()
 | 
						|
{
 | 
						|
  TSheet_field& s = sfield(F_RIGHE);
 | 
						|
  TDate dal, al;
 | 
						|
  const int anno = get_date_range(dal, al);
 | 
						|
  const bool good_year = anno >= 2012;
 | 
						|
  const bool def = get_bool(F_DEFINITIVO);
 | 
						|
  const bool full_rows = good_year && !s.empty();
 | 
						|
 | 
						|
  bool one_sent = false; // Ho spedito almeno un movimento in definitivo
 | 
						|
  if (good_year)
 | 
						|
  {
 | 
						|
    TString query;
 | 
						|
    query << "USE MOV KEY 2 SELECT INVIOFE!=\"\"";
 | 
						|
    query << "\nFROM DATAREG=" << dal;
 | 
						|
    query << "\nTO DATAREG=" << al;
 | 
						|
    TISAM_recordset recset(query);
 | 
						|
    one_sent = recset.move_first();
 | 
						|
  }
 | 
						|
 | 
						|
  enable(DLG_CANCEL, full_rows);
 | 
						|
  enable(DLG_SAVEREC,full_rows && _sheet_dirty);
 | 
						|
  enable(DLG_EXPORT, full_rows);
 | 
						|
  enable(DLG_RECALC, !full_rows && good_year && !one_sent);
 | 
						|
  enable(DLG_ELABORA, good_year && !(one_sent && def));
 | 
						|
  enable(DLG_DELREC, one_sent);
 | 
						|
  enable(F_DEFINITIVO, !def);
 | 
						|
  if (def) reset(F_DEFINITIVO);
 | 
						|
 | 
						|
  TFilename temp; build_outname(temp);
 | 
						|
  enable(DLG_PREVIEW, temp.exist());
 | 
						|
}
 | 
						|
 | 
						|
bool TSpesometro_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
  case DLG_OK: // Salva
 | 
						|
    if (e == fe_button  && jolly == 0) // Selezione su maschera principale
 | 
						|
    {
 | 
						|
      if (_mode == MODE_QUERY || save_if_dirty())
 | 
						|
        load_sheet();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_CANCEL:
 | 
						|
    if (e == fe_button && jolly == 0)
 | 
						|
    {
 | 
						|
      if (_mode != MODE_QUERY && save_if_dirty())
 | 
						|
      {
 | 
						|
        TSheet_field& s = sfield(F_RIGHE);
 | 
						|
        s.destroy();
 | 
						|
        s.force_update();
 | 
						|
        _mode = MODE_QUERY;
 | 
						|
        enable(-1);
 | 
						|
        enable_buttons();
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_LINK: // Ditta
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      TRectype ndt(LF_NDITTE);
 | 
						|
      ndt.put(NDT_CODDITTA, prefix().get_codditta());
 | 
						|
      if (ndt.edit(LF_NDITTE, NULL, "ba4 -2"))
 | 
						|
        prefix().notify_change(LF_NDITTE);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_SAVEREC:
 | 
						|
    if (e == fe_button)
 | 
						|
      save_if_dirty();
 | 
						|
    break;
 | 
						|
  case DLG_EXPORT:
 | 
						|
    if (e == fe_button)
 | 
						|
      return sfield(F_RIGHE).esporta();
 | 
						|
    break;
 | 
						|
  case DLG_RECALC:
 | 
						|
    if (e == fe_button && check_fields())
 | 
						|
    {
 | 
						|
      if (elabora_alleg())
 | 
						|
        load_sheet();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_ELABORA:
 | 
						|
    if (e == fe_button && check_fields())
 | 
						|
    {
 | 
						|
      const TString& tipo = get(F_TIPO);
 | 
						|
      if (tipo != "FE" && tipo != "BL")
 | 
						|
        return error_box("Non è possibile inviare i record che verrebbero scartati");
 | 
						|
      TDate dal, al;
 | 
						|
      get_date_range(dal, al);
 | 
						|
      if (tipo == "BL" && (al-dal) > 93)
 | 
						|
        return error_box("E' necessario specificare il mese o il trimestre per la Black List");
 | 
						|
      send_alleg();
 | 
						|
      enable_buttons(); // Disabilita bottone se definitivo
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_DELREC:
 | 
						|
    if (e == fe_button && o.active())
 | 
						|
    {
 | 
						|
      if (jolly == 0) // Toolbar principale
 | 
						|
      {
 | 
						|
        recall_alleg();
 | 
						|
        enable_buttons(); // Disabilita bottone
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
      else // Maschera di riga
 | 
						|
      {
 | 
						|
        const long progr = o.mask().get_long(A_RIGA);
 | 
						|
        if (progr >= MANUAL_ROW)
 | 
						|
        {
 | 
						|
          TLocalisamfile alleg(LF_ALLEG);
 | 
						|
          alleg.put(ALL_ANNO, get(F_ANNO));
 | 
						|
          alleg.put(ALL_PROGR, progr);
 | 
						|
          const int err = alleg.remove();
 | 
						|
          if (err != NOERR)
 | 
						|
            return error_box(FR("Errore di cancellazione: %d"), err);
 | 
						|
        }
 | 
						|
        else
 | 
						|
          return error_box(TR("Riga non cancellabile"));
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_PREVIEW:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      TFilename temp; build_outname(temp);
 | 
						|
      if (temp.exist())
 | 
						|
      {
 | 
						|
        TSpesometro_rep rep(temp);
 | 
						|
        rep.preview();
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_ANNO:
 | 
						|
    if (e == fe_init || e == fe_modify)
 | 
						|
    {
 | 
						|
      int anno = atoi(o.get());
 | 
						|
      if (anno < 2012)
 | 
						|
      {
 | 
						|
        anno = TDate(TODAY).year()-1;
 | 
						|
        o.set(anno);
 | 
						|
      }
 | 
						|
      enable_buttons();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_OUTFOLDER:
 | 
						|
    if (e == fe_init && o.empty())
 | 
						|
    {
 | 
						|
      TFilename tmp; tmp.tempdir();
 | 
						|
      o.set(tmp);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_RIGHE:
 | 
						|
    if (e == fe_init)
 | 
						|
      load_sheet(); else
 | 
						|
    if (e == se_query_modify)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)o;
 | 
						|
      TToken_string& row = s.row(jolly);
 | 
						|
      const TRecnotype progr = row.get_long(0);
 | 
						|
      s.sheet_mask().enable(DLG_DELREC, progr >= MANUAL_ROW);
 | 
						|
      s.sheet_mask().enable(DLG_USER, progr < MANUAL_ROW);
 | 
						|
    } else
 | 
						|
    if (e == se_notify_modify)
 | 
						|
    {
 | 
						|
      set_dirty(true); 
 | 
						|
      enable_buttons();
 | 
						|
    } else
 | 
						|
    if (e == se_query_add)
 | 
						|
    {
 | 
						|
      if (!check_rows(false))
 | 
						|
        return false;
 | 
						|
    } else
 | 
						|
    if (e == se_notify_add)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)o;
 | 
						|
      TToken_string& row = s.row(jolly);
 | 
						|
      row.add(nuovo_progr(), s.cid2index(A_RIGA));
 | 
						|
    } else
 | 
						|
    if (e == se_query_del)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)o;
 | 
						|
      TToken_string& row = s.row(jolly);
 | 
						|
      const TRecnotype progr = row.get_long(0);
 | 
						|
      return progr >= MANUAL_ROW;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case A_CODCF:
 | 
						|
  case A_OCFPI:
 | 
						|
    if (e == fe_modify || (e == fe_init && !o.empty()))
 | 
						|
    {
 | 
						|
      TMask& m = o.mask();
 | 
						|
      const TAnagrafica anag(m.get(A_TIPOCF)[0], m.get_long(A_CODCF), m.get(A_OCFPI));
 | 
						|
      m.set(A_RAGSOC, anag.ragione_sociale());
 | 
						|
      m.set(A_PAIV, anag.partita_IVA());
 | 
						|
      m.set(A_COFI, anag.codice_fiscale());
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_USER:
 | 
						|
    if (e == fe_button || e == fe_init)
 | 
						|
    {
 | 
						|
      const long numreg = o.mask().get_long(A_RIGA);
 | 
						|
      const bool enab = (numreg > 0) && (numreg < MANUAL_ROW);
 | 
						|
      if (e == fe_button && enab)
 | 
						|
      {
 | 
						|
        o.disable(); // Tecnica anti doppio click!
 | 
						|
        TRectype mov(LF_MOV); 
 | 
						|
        mov.put(MOV_NUMREG, numreg);
 | 
						|
        mov.edit();
 | 
						|
        o.enable();
 | 
						|
      }
 | 
						|
      else
 | 
						|
        o.enable(enab);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (e == fe_modify && jolly == 1 && _mode == MODE_MOD)
 | 
						|
  {
 | 
						|
    const short id = o.dlg();
 | 
						|
    if (id >= A_RIGA && id < A_COFI && id != A_FORZATA)
 | 
						|
    {
 | 
						|
      o.mask().set(A_FORZATA, true);
 | 
						|
      set_dirty();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TSpesometro_app
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TSpesometro_app : public TSkeleton_application
 | 
						|
{
 | 
						|
protected:
 | 
						|
  virtual bool create();
 | 
						|
 | 
						|
public:
 | 
						|
  virtual void main_loop();
 | 
						|
};
 | 
						|
 | 
						|
bool TSpesometro_app::create()
 | 
						|
{
 | 
						|
  if (!has_module(F3AUT))
 | 
						|
  {
 | 
						|
    TString html;
 | 
						|
    html << "<html><body>"
 | 
						|
          << "<h5>Attenzione: Il modulo FE deve essere attivato in congiunzione a F3.</h5>\n" 
 | 
						|
          << "<p align=justify>Al fine di poter attivare l'utilizzo della Comunicazione Polivalente 2013 "
 | 
						|
          << "La preghiamo di contattare <b>Sirio informatica e sistemi</b> al seguente riferimento:</p><br/>"
 | 
						|
          << "<ul>"
 | 
						|
          << "<li>Casella vocale Hotline Campo: <br /><a href=mailto:hotlinecampo@sirio-is.it>hotlinecampo@sirio-is.it</a> Tel. 02-36583540</li>"
 | 
						|
          << "</ul>"
 | 
						|
          << "</body></html>";
 | 
						|
    return warning_box(html);
 | 
						|
  }
 | 
						|
 | 
						|
  // Controllo preventivo dell'avvenuta conversione del tracciato record
 | 
						|
  TRectype alleg(LF_ALLEG);
 | 
						|
  if (alleg.type(ALL_CARBURAN) == _nullfld)
 | 
						|
    return error_box(TR("Database non convertito per la Comunicazione Polivalente"));
 | 
						|
 | 
						|
  TLocalisamfile mov(LF_MOV);
 | 
						|
  if (mov.last() == NOERR)
 | 
						|
  {
 | 
						|
    const long numreg = mov.get_long(MOV_NUMREG);
 | 
						|
    while (numreg > MANUAL_ROW)
 | 
						|
      MANUAL_ROW *= 10;
 | 
						|
  }
 | 
						|
    
 | 
						|
  // Teoricamente è possibile visualizzare tutti i movimenti di un anno, per cui allargo il numero riga
 | 
						|
  TSheet_field::set_line_number_width(7); 
 | 
						|
 | 
						|
  return TSkeleton_application::create();
 | 
						|
}
 | 
						|
 | 
						|
void TSpesometro_app::main_loop()
 | 
						|
{
 | 
						|
  TSpesometro_msk msk;
 | 
						|
  msk.run();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// main
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
int fe0100(int argc, char* argv[])
 | 
						|
{
 | 
						|
  TSpesometro_app app;
 | 
						|
  app.run(argc, argv, TR("Comunicazione Polivalente"));
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 |