Tale campo ora viene determinato euristicamente dalla contabilità analitica, mentre nella versione 3.x era fisicamente nelle righe di prima nota. git-svn-id: svn://10.65.10.50/branches/R_10_00@22774 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1776 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1776 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "cg3.h"
 | 
						|
#include "cg2103.h"
 | 
						|
#include "cg3900a.h"
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <automask.h>
 | 
						|
#include <defmask.h>
 | 
						|
#include <progind.h>
 | 
						|
#include <recarray.h>
 | 
						|
#include <reprint.h>
 | 
						|
#include <reputils.h>
 | 
						|
#include <textset.h>
 | 
						|
#include <validate.h>
 | 
						|
#include <utility.h>
 | 
						|
 | 
						|
#include <anafis.h>
 | 
						|
#include <anagr.h>
 | 
						|
#include <anagiu.h>
 | 
						|
#include <causali.h>
 | 
						|
#include <clifo.h>
 | 
						|
#include <comuni.h>
 | 
						|
#include <mov.h>
 | 
						|
#include <nditte.h>
 | 
						|
#include <occas.h>
 | 
						|
#include <rmoviva.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAllegato_info
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct TAllegato_importi : public TObject
 | 
						|
{
 | 
						|
  real _imp, _iva;             // Imponibile ed imposta
 | 
						|
  real _impNI, _impES, _ivaNE; // Non imponibili, esenti, Non esposti
 | 
						|
  real _ind;   // Valore indecifrabile valido solo per i fornitori fino al 2008
 | 
						|
  real _impNA; // Pattumiera per tutti valori NON in allegato
 | 
						|
  bool is_not_null(bool strict) const;
 | 
						|
};
 | 
						|
 | 
						|
bool TAllegato_importi::is_not_null(bool strict) const 
 | 
						|
{ 
 | 
						|
  if (!strict && !_impNA.is_zero())
 | 
						|
    return true;
 | 
						|
  return !(_imp.is_zero() && _iva.is_zero() && _ind.is_zero() &&
 | 
						|
           _impNI.is_zero() && _impES.is_zero() && _ivaNE.is_zero()); 
 | 
						|
}
 | 
						|
 | 
						|
class TAllegato_info : public TObject
 | 
						|
{
 | 
						|
  char _tipo;
 | 
						|
  long _codice;
 | 
						|
  TString80 _occas; // Eventuale codice cliente occasionale
 | 
						|
 | 
						|
  TAllegato_importi _curr, _prec;
 | 
						|
 | 
						|
public:
 | 
						|
  bool occasionale() const { return _tipo == 'C' && _occas.full(); }
 | 
						|
  char tipo() const { return _tipo; }
 | 
						|
  long codice() const { return _codice; }
 | 
						|
	const TString & occas_code() const { return _occas;}
 | 
						|
  TVariant get(const TString& field) const;
 | 
						|
  void key(TString& str) const;
 | 
						|
 | 
						|
  TAllegato_importi& importi(bool prec) { return prec ? _prec : _curr; }
 | 
						|
  const TAllegato_importi& importi(bool prec) const { return prec ? _prec : _curr; }
 | 
						|
 | 
						|
  bool is_not_null(bool strict) const { return _curr.is_not_null(strict) || _prec.is_not_null(strict); }
 | 
						|
	void set_codice(long codice, const char* occas) { _codice = codice; _occas = occas; }
 | 
						|
 | 
						|
  TAllegato_info(const TRecordset& mov);
 | 
						|
};
 | 
						|
 | 
						|
// Legge un campo dal record virtuale del cliente / fornitore
 | 
						|
TVariant TAllegato_info::get(const TString& field) const
 | 
						|
{
 | 
						|
  TVariant var;
 | 
						|
 | 
						|
  if (field.starts_with("C_") || field.starts_with("P_"))
 | 
						|
  {
 | 
						|
    const bool anno_prec = field[0] == 'P';
 | 
						|
    const TAllegato_importi& allimp = importi(anno_prec);
 | 
						|
    if (allimp.is_not_null(false)) 
 | 
						|
    {
 | 
						|
      const TString& impfield = field.mid(2);
 | 
						|
      real euro;
 | 
						|
      if (impfield == "IMP")
 | 
						|
        euro = allimp._imp;   else
 | 
						|
      if (impfield == "IVA")
 | 
						|
        euro = allimp._iva;   else
 | 
						|
      if (impfield == "NI")
 | 
						|
        euro = allimp._impNI; else
 | 
						|
      if (impfield == "ES")
 | 
						|
        euro = allimp._impES; else
 | 
						|
      if (impfield == "NE")
 | 
						|
        euro = allimp._ivaNE; else
 | 
						|
      if (impfield == "IND")
 | 
						|
        euro = allimp._ind; else
 | 
						|
      if (impfield == "NA")
 | 
						|
        euro = allimp._impNA;
 | 
						|
      euro.round(0);
 | 
						|
      var = euro;
 | 
						|
    }
 | 
						|
  } else
 | 
						|
  if (field == CLI_TIPOCF)
 | 
						|
  {
 | 
						|
    const char t[2] = { _tipo, '\0' };
 | 
						|
    var = t;
 | 
						|
  } else
 | 
						|
  if (field == CLI_CODCF)
 | 
						|
  {
 | 
						|
    var = _codice;
 | 
						|
  } else
 | 
						|
  if (field == COM_DENCOM || field == COM_PROVCOM)
 | 
						|
  {
 | 
						|
    TToken_string key;
 | 
						|
    key << get(CLI_STATOCF);
 | 
						|
    const bool italy = key.blank() || key == "IT";
 | 
						|
    key << '|' << get(CLI_COMCF);
 | 
						|
    var = cache().get(LF_COMUNI, key, field);
 | 
						|
    if (var.is_empty() && italy)  // Ritento col CAP per gli Italiani
 | 
						|
    {
 | 
						|
      key = " |"; 
 | 
						|
      key << cap2comune(get(CLI_CAPCF).as_string(), get(CLI_LOCCF).as_string());
 | 
						|
      var = cache().get(LF_COMUNI, key, field);
 | 
						|
    }
 | 
						|
    if (var.is_empty() && field == COM_PROVCOM)
 | 
						|
    {
 | 
						|
      if (!italy || key.get_char(1) == 'Z')
 | 
						|
        var = "EE";
 | 
						|
    }
 | 
						|
  } 
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (occasionale())
 | 
						|
    {
 | 
						|
      const TRectype& occas = cache().get(LF_OCCAS, _occas);
 | 
						|
 | 
						|
      // Tratto a parte COFI e PAIV degli occasionali
 | 
						|
      if (field == CLI_COFI || field == CLI_PAIV)
 | 
						|
      {
 | 
						|
        // Questi campi sono nel tracciato solo dalla versione 3.1 in poi
 | 
						|
        if (occas.type(field) != _nullfld) 
 | 
						|
          var = occas.get(field);
 | 
						|
 | 
						|
/* Troppo astuto per "Sirio il Dragone"
 | 
						|
        // Se non compilato cerco di desumerlo da codice occasionale
 | 
						|
        if (var.is_empty()) 
 | 
						|
        {
 | 
						|
          if (field == CLI_COFI)
 | 
						|
          {
 | 
						|
            if (cf_check("", _occas))
 | 
						|
              var = _occas;
 | 
						|
          }
 | 
						|
          else
 | 
						|
          {
 | 
						|
            if (pi_check("", _occas))
 | 
						|
              var = _occas;
 | 
						|
          }
 | 
						|
        }
 | 
						|
*/
 | 
						|
      }
 | 
						|
      else // Tutti gli altri campi a parte COFI e PAIV
 | 
						|
      {
 | 
						|
        // Converto opportunamente il nome del campo da CLIFO ad OCCAS
 | 
						|
        const char* const cli[] = { CLI_RAGSOC, CLI_STATOCF, CLI_COMCF,    CLI_STATOPAIV,
 | 
						|
                                    CLI_INDCF,  CLI_CAPCF,   CLI_LOCCF,    NULL, };
 | 
						|
        const char* const occ[] = { OCC_RAGSOC, OCC_STATO,   OCC_COM,      OCC_STATO, 
 | 
						|
                                    OCC_INDIR,  OCC_CAP,     OCC_LOCALITA, NULL, };
 | 
						|
        for (int f = 0; cli[f]; f++)
 | 
						|
        {
 | 
						|
          if (field == cli[f])
 | 
						|
          {
 | 
						|
            var = occas.get(occ[f]);
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else // Clienti/Fornitori "normali" (non occasionali)
 | 
						|
    {
 | 
						|
      TString16 key; key.format("%c|%ld", _tipo, _codice);
 | 
						|
      const TRectype& clifo = cache().get(LF_CLIFO, key);
 | 
						|
      var = clifo.get(field);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return var;
 | 
						|
}
 | 
						|
 | 
						|
void TAllegato_info::key(TString& tmp) const
 | 
						|
{
 | 
						|
  tmp = get(CLI_PAIV).as_string();
 | 
						|
  if (tmp.blank())
 | 
						|
  {
 | 
						|
    tmp = get(CLI_COFI).as_string();
 | 
						|
    if (tmp.blank())
 | 
						|
      tmp.cut(0) << _codice;
 | 
						|
  }
 | 
						|
  tmp.insert(_tipo == 'F' ? "F|" : "C|");
 | 
						|
}
 | 
						|
 | 
						|
TAllegato_info::TAllegato_info(const TRecordset& mov)
 | 
						|
              : _tipo(mov.get(MOV_TIPO).as_string()[0]), 
 | 
						|
                _codice(mov.get(MOV_CODCF).as_int()),
 | 
						|
                _occas(mov.get(MOV_OCFPI).as_string())
 | 
						|
{ 
 | 
						|
  CHECK(_tipo == 'C' || _tipo == 'F', "Tipo C/F errato");
 | 
						|
  CHECKD(_codice > 0, "Codice C/F errato ", _codice);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAllegati_set
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TAllegati_set : public TAS400_recordset 
 | 
						|
{
 | 
						|
protected:
 | 
						|
  const TString& comune(const TRectype& clifo, const char* field) const;
 | 
						|
 | 
						|
public:
 | 
						|
  void add(const TAllegato_info& info);
 | 
						|
  TAllegati_set();
 | 
						|
};
 | 
						|
 | 
						|
void TAllegati_set::add(const TAllegato_info& info)
 | 
						|
{
 | 
						|
  new_rec();
 | 
						|
 | 
						|
  for (unsigned int i = 0; i < columns(); i++)
 | 
						|
  {
 | 
						|
    const TString& field = column_info(i)._name;
 | 
						|
    set(field, info.get(field));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TAllegati_set::TAllegati_set() 
 | 
						|
             : TAS400_recordset("AS400(512)")
 | 
						|
{
 | 
						|
  const char* const campi[] = { CLI_TIPOCF, CLI_CODCF, CLI_RAGSOC, CLI_COFI,  CLI_PAIV, 
 | 
						|
                                CLI_INDCF,  CLI_CIVCF, CLI_CAPCF,  CLI_LOCCF, CLI_COMCF, 
 | 
						|
                                NULL };
 | 
						|
  TRectype clifo(LF_CLIFO);
 | 
						|
  for (int i = 0; campi[i]; i++)
 | 
						|
  {
 | 
						|
    const char* f = campi[i];
 | 
						|
    create_field(f, -1, clifo.length(f), clifo.type(f));
 | 
						|
  }
 | 
						|
  create_field(COM_DENCOM, -1, 50, _alfafld);
 | 
						|
  create_field(COM_PROVCOM, -1, 2, _alfafld);
 | 
						|
 | 
						|
  for (int j = 0; j < 2; j++)
 | 
						|
  {
 | 
						|
    create_field(j ? "P_IMP" : "C_IMP", -1, 16, _longfld);
 | 
						|
    create_field(j ? "P_IVA" : "C_IVA", -1, 16, _longfld);
 | 
						|
    create_field(j ? "P_IND" : "C_IND", -1, 16, _longfld);
 | 
						|
    create_field(j ? "P_NI"  : "C_NI",  -1, 16, _longfld);
 | 
						|
    create_field(j ? "P_ES"  : "C_ES",  -1, 16, _longfld);
 | 
						|
    create_field(j ? "P_NE"  : "C_NE",  -1, 16, _longfld);
 | 
						|
    create_field(j ? "P_NA"  : "C_NA",  -1, 16, _longfld);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TPadoaSchioppa_set
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
enum TPs_type { AN, CF, DT, NU, PI, PR };
 | 
						|
enum TPs_campi_non_posizionali { npCode = 8, npValue = 16, npSize = 24, npCount = 70 };
 | 
						|
 | 
						|
class TPadoaSchioppa_set : public TAS400_recordset
 | 
						|
{
 | 
						|
  void add_field(const int trc, int da, int a, int lung, const char* name, 
 | 
						|
                 TPs_type ft, bool required = false, const char* def = NULL);
 | 
						|
  void add_trc(int trc);
 | 
						|
 | 
						|
protected:
 | 
						|
  int primo_campo_libero(); // Posizione primo campo libero per record 1 e 2
 | 
						|
  void init_trc();          // Constructor helper
 | 
						|
 | 
						|
public:
 | 
						|
  long new_rec(int tiporec);  // 0, 1, 2, 3, 9, -1 (1 o 2 a seconda del tipo corrente)
 | 
						|
  const TString& curr_row() const { return row(-1); }
 | 
						|
 | 
						|
  // Campi posizionali (record 0, 3 e 9)
 | 
						|
  bool set(const char* name, const TVariant& value);
 | 
						|
  bool set(const char* name, const TString& value);
 | 
						|
  bool set(const char* name, const TDate& value);
 | 
						|
 | 
						|
  // Campi non posizionali (record 1 e 2)
 | 
						|
  bool set(int fldcode, const TString& val);
 | 
						|
  bool set(int fldcode, long val);
 | 
						|
  bool set(int fldcode, const TVariant& val);
 | 
						|
  
 | 
						|
  TPadoaSchioppa_set();
 | 
						|
  TPadoaSchioppa_set(const TFilename& name);
 | 
						|
};
 | 
						|
 | 
						|
long TPadoaSchioppa_set::new_rec(int tiporec)
 | 
						|
{
 | 
						|
  if (tiporec < 0)
 | 
						|
  {
 | 
						|
    tiporec = atoi(rec_type());
 | 
						|
    CHECKD(tiporec == 1 || tiporec == 2, "Tipo record non duplicabile ", tiporec);
 | 
						|
  }
 | 
						|
  CHECKD(tiporec >= 0 && tiporec <= 3 || tiporec == 9, "Tipo record errato ", tiporec);
 | 
						|
  char tr[2] = { '0'+tiporec, '\0' };
 | 
						|
  return TAS400_recordset::new_rec(tr);
 | 
						|
}
 | 
						|
 | 
						|
void TPadoaSchioppa_set::add_field(int trc, int da, int a, int lung, const char* name, 
 | 
						|
                                   TPs_type tc, bool required, const char* def)
 | 
						|
{
 | 
						|
  CHECKS(da > 0 && a >= da, "Posizioni incoerenti sul campo ", name);
 | 
						|
  CHECKS(lung == a-da+1, "Lunghezza incoerente sul campo ", name);
 | 
						|
  
 | 
						|
  TString80 field; field.format("%d.%s", trc, (const char*)name);
 | 
						|
  TFieldtypes ft = _alfafld;
 | 
						|
  switch (tc)
 | 
						|
  {
 | 
						|
  case DT:
 | 
						|
    CHECKS(lung == 8, "Lunghezza incoerente data ", name);
 | 
						|
    ft = _longzerofld;
 | 
						|
    break;
 | 
						|
  case NU:
 | 
						|
    ft = _longfld;
 | 
						|
    break;
 | 
						|
  case CF:
 | 
						|
    CHECKS(lung == 16, "Lunghezza incoerente codice fiscale ", name);
 | 
						|
    ft = _alfafld; 
 | 
						|
    break;
 | 
						|
  case PI:
 | 
						|
    CHECKS(lung == 11, "Lunghezza incoerente partita IVA ", name);
 | 
						|
    ft = _longzerofld;
 | 
						|
    break;
 | 
						|
  case PR:
 | 
						|
    CHECKS(lung == 2, "Lunghezza incoerente provincia ", name);
 | 
						|
    ft = _alfafld; 
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    ft = _alfafld; 
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  bool ok = false;
 | 
						|
  if (def && *def)
 | 
						|
    ok = create_field(field, da-1, lung, ft, required, TVariant(def));
 | 
						|
  else
 | 
						|
    ok = create_field(field, da-1, lung, ft, required);
 | 
						|
  CHECKS(ok, "Impossibile creare il campo ", (const char*)field);
 | 
						|
}
 | 
						|
 | 
						|
void TPadoaSchioppa_set::add_trc(int trc)
 | 
						|
{
 | 
						|
  TString4 str; str << trc;
 | 
						|
  add_field(trc, 1, 1, 1, "TipoRecord", NU, true, str);
 | 
						|
 | 
						|
  switch (trc)
 | 
						|
  {
 | 
						|
  case 0: // Testata
 | 
						|
  case 9: // Coda
 | 
						|
    add_field(trc,   2,   4,  3, "IdentificativoFornitura" , AN, true, "ECF");
 | 
						|
    add_field(trc,   5,   6,  2, "IdentificativoAnno"      , AN, true, "00");
 | 
						|
    add_field(trc,   7,   8,  2, "CodiceFornitura"         , NU, true, "38");
 | 
						|
    add_field(trc,   9,  24, 16, "CodiceFiscale"           , CF, true);
 | 
						|
    add_field(trc,  25,  35, 11, "PartitaIVA"              , PI, true);
 | 
						|
    add_field(trc,  36,  61, 26, "Cognome"                 , AN); // Persone fisiche
 | 
						|
    add_field(trc,  62,  86, 25, "Nome"                    , AN);
 | 
						|
    add_field(trc,  87,  87,  1, "Sesso"                   , AN);
 | 
						|
    add_field(trc,  88,  95,  8, "DataNascita"             , DT);
 | 
						|
    add_field(trc,  96, 135, 40, "ComuneNascita"           , AN);
 | 
						|
    add_field(trc, 136, 137,  2, "ProvinciaNascita"        , PR);
 | 
						|
    add_field(trc, 138, 207, 70, "Denominazione"           , AN); // Persone NON fisiche
 | 
						|
    add_field(trc, 208, 247, 40, "ComuneSedeLegale"        , AN);
 | 
						|
    add_field(trc, 248, 249,  2, "ProvinciaSedeLegale"     , AN);
 | 
						|
    add_field(trc, 250, 265, 16, "CodiceSoggettoObbligato" , CF);
 | 
						|
    add_field(trc, 266, 269,  4, "AnnoRiferimento"         , NU, true);
 | 
						|
    add_field(trc, 270, 273,  4, "ProgressivoTelematico"   , NU);
 | 
						|
    add_field(trc, 274, 277,  4, "NumeroTotaleInvii"       , NU);
 | 
						|
    add_field(trc, 278, 293, 16, "CodiceIntermediario"     , CF);
 | 
						|
    add_field(trc, 294, 298,  5, "NumeroIscrizioneAlboCAF" , NU);
 | 
						|
    add_field(trc, 299, 299,  1, "ImpegnoAllaTrasmissione" , NU);
 | 
						|
    add_field(trc, 300, 307,  8, "DataImpegno"             , DT);
 | 
						|
    break;
 | 
						|
  case 1: // Clienti
 | 
						|
  case 2: // Fornitori
 | 
						|
    // NESSUN CAMPO POSIZIONALE!
 | 
						|
    break;
 | 
						|
  case 3:
 | 
						|
    add_field(trc,   2,   9,  8, "Clienti"   , NU); // 2
 | 
						|
    add_field(trc,  10,  17,  8, "Fornitori" , NU);
 | 
						|
    add_field(trc,  18,  37, 20, "CL004001"  , NU); // 4
 | 
						|
    add_field(trc,  38,  57, 20, "CL004002"  , NU);
 | 
						|
    add_field(trc,  58,  77, 20, "CL005001"  , NU);
 | 
						|
    add_field(trc,  78,  97, 20, "CL006001"  , NU);
 | 
						|
    add_field(trc,  98, 117, 20, "CL007001"  , NU);
 | 
						|
    add_field(trc, 118, 137, 20, "CL008001"  , NU); // 9
 | 
						|
    add_field(trc, 138, 157, 20, "CL008002"  , NU);
 | 
						|
    add_field(trc, 158, 177, 20, "CL009001"  , NU);
 | 
						|
    add_field(trc, 178, 197, 20, "CL010001"  , NU);
 | 
						|
    add_field(trc, 198, 217, 20, "CL011001"  , NU); // 13
 | 
						|
    add_field(trc, 218, 237, 20, "FR004001"  , NU); // 14
 | 
						|
    add_field(trc, 238, 257, 20, "FR004002"  , NU);
 | 
						|
    add_field(trc, 258, 277, 20, "FR005001"  , NU);
 | 
						|
    add_field(trc, 278, 297, 20, "FR006001"  , NU);
 | 
						|
    add_field(trc, 298, 317, 20, "FR007001"  , NU);
 | 
						|
    add_field(trc, 318, 337, 20, "FR008001"  , NU);
 | 
						|
    add_field(trc, 338, 357, 20, "FR009001"  , NU); // 20
 | 
						|
    add_field(trc, 358, 377, 20, "FR009002"  , NU);
 | 
						|
    add_field(trc, 378, 397, 20, "FR010001"  , NU);
 | 
						|
    add_field(trc, 398, 417, 20, "FR011001"  , NU);
 | 
						|
    add_field(trc, 418, 437, 20, "FR012001"  , NU);
 | 
						|
    add_field(trc, 438, 457, 20, "FR013001"  , NU); // 25
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    CHECKD(false, "Tipo record non valido ", trc);
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  add_field(trc,1798,1798,  1, "CarattereControllo"    , AN, true, "A");
 | 
						|
  add_field(trc,1799,1800,  2, "FineRiga"              , AN, true, "\r\n"); // 0D 0A
 | 
						|
}
 | 
						|
 | 
						|
int TPadoaSchioppa_set::primo_campo_libero()
 | 
						|
{
 | 
						|
  const TToken_string& curr = row(-1); // Record corrente
 | 
						|
  int i = 0, pos = 1;
 | 
						|
  for (i = 0; i < npCount; i++, pos += npSize) // Scandice i 70 campi non posizionali
 | 
						|
  {
 | 
						|
    // if (curr.mid(pos, fld_size).blank())
 | 
						|
    if (curr[pos] == ' ' && curr[pos+npSize-1] == ' ') // Campo vuoto!
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (i >= npCount) // Non c'e' piu' posto!
 | 
						|
  {
 | 
						|
    new_rec(-1); // Creo un nuovo record del tipo corrente (1 o 2)
 | 
						|
    pos = 1;     // Vado a colpo "sicuro"
 | 
						|
  }
 | 
						|
 | 
						|
  return pos;
 | 
						|
}
 | 
						|
 | 
						|
bool TPadoaSchioppa_set::set(const char* name, const TVariant& value)
 | 
						|
{
 | 
						|
  bool ok = false;
 | 
						|
  const int tiporec = atoi(rec_type());
 | 
						|
  if (tiporec == 1 || tiporec == 2) // Gestione campi non posizionali
 | 
						|
  {
 | 
						|
    CHECKS(name!=NULL && strlen(name) == npCode, 
 | 
						|
           "Lunghezza nome campo non posizionale errata ", name);
 | 
						|
    CHECKS((tiporec==1 && *name=='C') || (tiporec==2 && *name=='F'), 
 | 
						|
           "Campo non posizionale incompatibile col tipo record (1/2=C/F) ", name);
 | 
						|
    const long codice = atol(name+2);
 | 
						|
    CHECKS(codice >= 1001 && codice <= 13001, "Campo non posizionale errato ", name);
 | 
						|
    if (value.is_empty())
 | 
						|
    {
 | 
						|
      ok = codice > 4000;
 | 
						|
      CHECKS(ok, "Campo obbligatorio non specificato ", name);
 | 
						|
      return ok;
 | 
						|
    }
 | 
						|
 | 
						|
    const int pos = primo_campo_libero();
 | 
						|
    TString80 str = name;
 | 
						|
    if (codice < 4000) // Campi alfanumerici (1001,2001,3001) allineati a sinistra
 | 
						|
    {
 | 
						|
      str << value.as_string();
 | 
						|
      str.rpad(npSize);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {                  // Importi interi allineati a destra
 | 
						|
      real r = value.as_real();
 | 
						|
      r.round(0);      // Inutile in quanto gia' arrotondato all'origine: ma non si sa mai 
 | 
						|
      str << r.string(npValue, 0);
 | 
						|
    }
 | 
						|
    CHECKS(str.len() == npSize, "Lunghezza campo non posizionale codice(8)+valore(16) <> 24 ", (const char*)str);
 | 
						|
    row(-1).overwrite(str, pos, npSize);
 | 
						|
    ok = true;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    // Gestisco le date solo nei record 0,3,9
 | 
						|
    if (value.is_date() && !value.is_empty()) 
 | 
						|
    {
 | 
						|
      const TDate date = value.as_date();
 | 
						|
      TString8 str;
 | 
						|
      str.format("%02d%02d%04d", date.day(), date.month(), date.year());
 | 
						|
      ok = TAS400_recordset::set(name, TVariant(str));
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (value.is_string())
 | 
						|
      {
 | 
						|
        TString80 str = value.as_string();
 | 
						|
        str.upper();
 | 
						|
        ok = TAS400_recordset::set(name, TVariant(str));
 | 
						|
      }
 | 
						|
      else
 | 
						|
        ok = TAS400_recordset::set(name, value);
 | 
						|
    }
 | 
						|
    CHECKS(ok, "Campo non valido ", name);
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TPadoaSchioppa_set::set(const char* name, const TString& value)
 | 
						|
{
 | 
						|
  return set(name, value.full() ? TVariant(value) : NULL_VARIANT);
 | 
						|
}
 | 
						|
 | 
						|
bool TPadoaSchioppa_set::set(const char* name, const TDate& value)
 | 
						|
{
 | 
						|
  return set(name, value.ok() ? TVariant(value) : NULL_VARIANT);
 | 
						|
}
 | 
						|
 | 
						|
// Usata per 1001, 2001 e 3001
 | 
						|
bool TPadoaSchioppa_set::set(int fldcode, const TString& val)
 | 
						|
{
 | 
						|
  CHECKD(fldcode >= 1001 && fldcode <= 3001, "Codice campo non valido ", fldcode);
 | 
						|
  CHECKD(val.full(), "Campo non posizionale vuoto ", fldcode);
 | 
						|
  
 | 
						|
  const int tiporec = atoi(rec_type());
 | 
						|
 | 
						|
  TString8 field;
 | 
						|
  field.format("%2s%06d", tiporec == 1 ? "CL" : "FR", fldcode);
 | 
						|
  return set(field, val);
 | 
						|
}
 | 
						|
 | 
						|
// Usata solo per 1001
 | 
						|
bool TPadoaSchioppa_set::set(int fldcode, long val)
 | 
						|
{
 | 
						|
  CHECKD(fldcode == 1001, "Codice campo non valido ", fldcode);
 | 
						|
  CHECKD(val > 0, "Campo non posizionale vuoto ", fldcode);
 | 
						|
  TString16 value; 
 | 
						|
  value.format("%16ld", val);
 | 
						|
  return set(fldcode, value);
 | 
						|
}
 | 
						|
 | 
						|
// Usata dal 4001 in poi
 | 
						|
bool TPadoaSchioppa_set::set(int fldcode, const TVariant& val)
 | 
						|
{
 | 
						|
  CHECKD(fldcode >= 4001 && fldcode <= 13001, "Codice campo non valido ", fldcode);
 | 
						|
  if (val.is_zero())
 | 
						|
    return true;
 | 
						|
  
 | 
						|
  const int tiporec = atoi(rec_type());
 | 
						|
  TString8 field;
 | 
						|
  field.format("%2s%06d", tiporec == 1 ? "CL" : "FR", fldcode);
 | 
						|
  return set(field, val);
 | 
						|
}
 | 
						|
 | 
						|
void TPadoaSchioppa_set::init_trc()
 | 
						|
{
 | 
						|
  add_trc(0);
 | 
						|
  add_trc(1);
 | 
						|
  add_trc(2);
 | 
						|
  add_trc(3);
 | 
						|
  add_trc(9);
 | 
						|
}
 | 
						|
 | 
						|
TPadoaSchioppa_set::TPadoaSchioppa_set() 
 | 
						|
                  : TAS400_recordset("AS400(1800,1)")
 | 
						|
{ 
 | 
						|
  init_trc(); 
 | 
						|
}
 | 
						|
 | 
						|
TPadoaSchioppa_set::TPadoaSchioppa_set(const TFilename& name)
 | 
						|
                  : TAS400_recordset("AS400(1800,1)")
 | 
						|
{
 | 
						|
  init_trc();
 | 
						|
  load_file(name);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TCodiva_cache
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TCodiva_cache : public TCache
 | 
						|
{
 | 
						|
protected:
 | 
						|
  virtual TObject* key2obj(const char* key);
 | 
						|
 | 
						|
public:
 | 
						|
  const TCodiceIVA& codiva(const char* codice);
 | 
						|
};
 | 
						|
 | 
						|
TObject* TCodiva_cache::key2obj(const char* key)
 | 
						|
{
 | 
						|
  return new TCodiceIVA(key);
 | 
						|
}
 | 
						|
 | 
						|
const TCodiceIVA& TCodiva_cache::codiva(const char* codice)
 | 
						|
{
 | 
						|
  return *(TCodiceIVA*)objptr(codice);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TCusali_cache
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TCausali_cache : public TCache
 | 
						|
{
 | 
						|
protected:
 | 
						|
  virtual TObject* key2obj(const char* key);
 | 
						|
 | 
						|
public:
 | 
						|
  const TCausale& causale(const char* codice, int annoiva);
 | 
						|
};
 | 
						|
 | 
						|
TObject* TCausali_cache::key2obj(const char* key)
 | 
						|
{
 | 
						|
  // Metodo bastardo per evitare TToken_string temporanee "a randa"
 | 
						|
  // sfrutto chiave a lunghezza fissa
 | 
						|
  const int anno = atoi(key);
 | 
						|
  const char* codice = key+5;
 | 
						|
  TCausale* pcaus = new TCausale(codice, anno);
 | 
						|
  return pcaus;
 | 
						|
}
 | 
						|
 | 
						|
const TCausale& TCausali_cache::causale(const char* codice, int annoiva)
 | 
						|
{
 | 
						|
  // Metodo bastardo per evitare TToken_string temporanee "a randa"
 | 
						|
  // creo chiave a lunghezza fissa anno+codice = 9999|AAA
 | 
						|
  TString8 key;
 | 
						|
  key.format("%04d|%s", annoiva, codice);
 | 
						|
  return *(const TCausale*)objptr(key);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAlleg_report
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TAlleg_report : public TReport
 | 
						|
{
 | 
						|
  TAssoc_array _vars;
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual bool use_mask() { return false; }
 | 
						|
  virtual bool set_usr_val(const TString& name, const TVariant& var);
 | 
						|
  virtual bool get_usr_val(const TString& name, TVariant& var) const;
 | 
						|
 | 
						|
public:
 | 
						|
  TAlleg_report(TRecordset* rs, const TMask& am, bool hide_not_alleg = false);
 | 
						|
};
 | 
						|
 | 
						|
bool TAlleg_report::set_usr_val(const TString& name, const TVariant& var)
 | 
						|
{
 | 
						|
  if (!TReport::set_usr_val(name, var))
 | 
						|
    _vars.add(name, new TVariant(var));
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
bool TAlleg_report::get_usr_val(const TString& name, TVariant& var) const
 | 
						|
{
 | 
						|
  if (name[0] == '#')
 | 
						|
  {
 | 
						|
    TVariant* v = (TVariant*)_vars.objptr(name);
 | 
						|
    if (v != NULL)
 | 
						|
    {
 | 
						|
      var = *v;
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return TReport::get_usr_val(name, var);
 | 
						|
}
 | 
						|
 | 
						|
TAlleg_report::TAlleg_report(TRecordset* rs, const TMask& am, bool hide_not_alleg)
 | 
						|
{
 | 
						|
  load("cg3900a");
 | 
						|
  mask2report(am);
 | 
						|
	TString4 filtro;
 | 
						|
 | 
						|
	if (!hide_not_alleg)
 | 
						|
		filtro = am.get(F_FILTRO);
 | 
						|
  set_usr_val("#FILTRO", TVariant(filtro));
 | 
						|
 | 
						|
 | 
						|
  if (hide_not_alleg)
 | 
						|
  {
 | 
						|
    const char* const fields[] = { "H0.107", "B1.107", "B1.207", "F1.107", "F1.207", NULL };
 | 
						|
    for (int i = 0; fields[i]; i++)
 | 
						|
    {
 | 
						|
      TReport_field* rf = field(fields[i]);
 | 
						|
      if (rf != NULL) 
 | 
						|
        rf->deactivate();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  set_recordset(rs);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAlleg_log
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TAlleg_log : public TLog_report
 | 
						|
{
 | 
						|
  bool _red_alert;
 | 
						|
 | 
						|
public:
 | 
						|
  virtual bool log(int severity, const char* msg);
 | 
						|
  bool red_alert() const { return _red_alert; }
 | 
						|
  TAlleg_log() : TLog_report(TR("Errori riscontrati")), _red_alert(false) {}
 | 
						|
};
 | 
						|
 | 
						|
bool TAlleg_log::log(int severity, const char* msg)
 | 
						|
{
 | 
						|
  if (severity > 0)
 | 
						|
    _red_alert = true;
 | 
						|
  return TLog_report::log(severity, msg);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAlleg_mask
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TAlleg_mask : public TAutomask
 | 
						|
{
 | 
						|
  TCodiva_cache _codiva;
 | 
						|
  TCausali_cache _causali;
 | 
						|
 | 
						|
protected: // TAutomask
 | 
						|
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						|
  virtual void on_firm_change();
 | 
						|
 | 
						|
protected: // Elaborazione
 | 
						|
  const TRectype& contribuente() const;
 | 
						|
  bool documento_corrispettivi(const TString& tipodoc) const;
 | 
						|
  int imp_iva(char tipocf, bool non_esposti, const TRecordset& riga, real& imp, real& iva);
 | 
						|
  real indetraibile_al(const TRecordset& riga) const;
 | 
						|
  bool scan_iva_rows(const TRecordset& mov, TAssoc_array& clifi, bool invio, bool ministeriale);
 | 
						|
  TRecordset* new_recordset(char tipocf = ' ', bool strict = false);
 | 
						|
 | 
						|
  void log_error(const char* ragsoc, const char* msg1, const char* msg2,
 | 
						|
                 TAlleg_log& errlog, int severity = 2);
 | 
						|
  void log_error(const TRecordset& clifo, const char* msg1, const char* msg2,
 | 
						|
                 TAlleg_log& errlog, int severity = 2);
 | 
						|
  void copia_importo(const TRecordset& clifo, const char* fldname,
 | 
						|
                     TPadoaSchioppa_set& pss, int fldcode) const;
 | 
						|
 | 
						|
protected: // Generazione
 | 
						|
  bool build_output_name(TFilename& fname) const;
 | 
						|
  void add_0_9(int trc, TPadoaSchioppa_set& pss, TAlleg_log& log);
 | 
						|
  void add_1_2(int trc, TRecordset& clifo, TPadoaSchioppa_set& pss, TAlleg_log& log);
 | 
						|
  void add_3(TPadoaSchioppa_set& pss);
 | 
						|
  bool show_errors(TAlleg_log& log) const;
 | 
						|
  void generazione();
 | 
						|
 | 
						|
protected: // Fusione
 | 
						|
  bool test_file(const TFilename& name, TString& error) const;
 | 
						|
  void import_clifo(const TFilename& name, TAssoc_array& clips, TAssoc_array& forps, TAlleg_log& log);
 | 
						|
  TRecnotype export_clifo(int tiporec, TAssoc_array& clifo, TAllegati_set& all, TPadoaSchioppa_set& pss);
 | 
						|
  void fusione();
 | 
						|
 | 
						|
public:
 | 
						|
  TAlleg_mask();
 | 
						|
  ~TAlleg_mask();
 | 
						|
};
 | 
						|
 | 
						|
bool TAlleg_mask::documento_corrispettivi(const TString& tipodoc) const
 | 
						|
{
 | 
						|
  const TRectype& tpd = cache().get("%TPD", tipodoc);
 | 
						|
  bool corrisp = tpd.get_bool("B0");
 | 
						|
  if (corrisp)
 | 
						|
  {
 | 
						|
    const int natura_doc = tpd.get_int("I0");
 | 
						|
    corrisp = natura_doc == 1 || natura_doc == 9;
 | 
						|
  }
 | 
						|
  return corrisp;
 | 
						|
}
 | 
						|
 | 
						|
int TAlleg_mask::imp_iva(char tipocf, bool non_esposti, const TRecordset& riga, real& imp, real& iva)
 | 
						|
{
 | 
						|
  // Estraggo imponibile ed imposta dalla riga IVA ed
 | 
						|
  // inizialmente fingo che non ci sia una parte indetraibile
 | 
						|
  imp = riga.get(RMI_IMPONIBILE).as_real();
 | 
						|
  iva = riga.get(RMI_IMPOSTA).as_real();
 | 
						|
 | 
						|
  int allegato = 0;
 | 
						|
  if (non_esposti)
 | 
						|
  {
 | 
						|
    allegato = 4;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const TString& codice = riga.get(RMI_CODIVA).as_string();
 | 
						|
    const TCodiceIVA& codiva = _codiva.codiva(codice);
 | 
						|
    allegato = codiva.allegato(tipocf);
 | 
						|
 | 
						|
    if (allegato == 5 && get_int(F_ANNO) >= 2008) // FR005001 non esiste piu' nel 2008
 | 
						|
      allegato = 1;
 | 
						|
	}
 | 
						|
 | 
						|
  if (allegato != 1 && !iva.is_zero()) // Succede col Reverse Charge
 | 
						|
  {
 | 
						|
    imp += iva;
 | 
						|
    iva = ZERO;
 | 
						|
  }
 | 
						|
 | 
						|
  return allegato;
 | 
						|
}
 | 
						|
 | 
						|
bool TAlleg_mask::scan_iva_rows(const TRecordset& mov, TAssoc_array& clifi, 
 | 
						|
                                bool invio, bool ministeriale)
 | 
						|
{
 | 
						|
  // Informazioni base sul cliente in testata: vengono ignorati gli importi
 | 
						|
  const TAllegato_info clifo(mov);
 | 
						|
	const int tipalleg = clifo.get(CLI_ALLEG).as_int();
 | 
						|
 | 
						|
  if (invio)
 | 
						|
  {
 | 
						|
    // Ignoro da subito chi non va in allegato
 | 
						|
    if (tipalleg != 0 && tipalleg != 4)
 | 
						|
      return false;
 | 
						|
 | 
						|
    // Gli occasionali meritano solo di essere ignorati
 | 
						|
    if (clifo.occasionale())
 | 
						|
      return false;
 | 
						|
 | 
						|
    const TVariant stato = clifo.get(CLI_STATOPAIV);
 | 
						|
    if (!stato.is_empty() && stato.as_string() != "IT") // Scarto gli esteri
 | 
						|
      return false;
 | 
						|
  }
 | 
						|
	else
 | 
						|
	{
 | 
						|
    // Per efficienza andrebbe nella funzione chiamante
 | 
						|
		const int filtro = get_int(F_FILTRO);
 | 
						|
		if (filtro >= 0 && tipalleg != filtro)
 | 
						|
			return false;
 | 
						|
	}
 | 
						|
 | 
						|
  TString80 clifo_key; clifo.key(clifo_key);
 | 
						|
  TAllegato_info* ai = (TAllegato_info*)clifi.objptr(clifo_key);
 | 
						|
  if (ai == NULL)
 | 
						|
  {
 | 
						|
    ai = new TAllegato_info(mov);
 | 
						|
    clifi.add(clifo_key, ai);
 | 
						|
  }
 | 
						|
	else
 | 
						|
  {
 | 
						|
    // Se questa partita IVA esiste gia' deve prevalere la ragione sociale con tipalleg=0
 | 
						|
		if (tipalleg == 0) 
 | 
						|
		{
 | 
						|
			const long codcf = clifo.codice();   // Codice corrente
 | 
						|
			const long old_codcf = ai->codice(); // Codice su fornitura
 | 
						|
			if (codcf != old_codcf)
 | 
						|
				ai->set_codice(codcf, clifo.occas_code());
 | 
						|
		}
 | 
						|
  }
 | 
						|
 | 
						|
  const TDate datareg = mov.get(MOV_DATAREG).as_date();
 | 
						|
  const TDate datadoc = mov.get(MOV_DATADOC).as_date();
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
  const int annoiva = datareg.year();
 | 
						|
  const TString& codcaus = mov.get(MOV_CODCAUS).as_string();
 | 
						|
  const TCausale& caus = _causali.causale(codcaus, annoiva);
 | 
						|
  const bool vendite = clifo.tipo() == 'C';
 | 
						|
  const bool movintra = caus.intra();
 | 
						|
  const int reg_spec = caus.regime_speciale();
 | 
						|
  const bool reverse_charge = (reg_spec == 13) || (reg_spec == 50) || (reg_spec == 51);
 | 
						|
  const bool non_esposti = vendite && (movintra || reverse_charge);
 | 
						|
 | 
						|
  TISAM_recordset righe_iva("USE RMOVIVA\nFROM NUMREG=#NR\nTO NUMREG=#NR");
 | 
						|
  righe_iva.set_var("#NR", mov.get(MOV_NUMREG));
 | 
						|
 | 
						|
  real imponibile, imposta, indecifrabile;
 | 
						|
  for (bool ok = righe_iva.move_first(); ok; ok = righe_iva.move_next())
 | 
						|
  {
 | 
						|
    bool anno_prec = false; 
 | 
						|
    if (ministeriale)
 | 
						|
      anno_prec = righe_iva.get(RMI_NAVP).as_bool();
 | 
						|
    else
 | 
						|
      anno_prec = datadoc.year() == anno-1; // Serve per quadrature
 | 
						|
    TAllegato_importi& allimp = ai->importi(anno_prec);
 | 
						|
 | 
						|
    const int allegato = imp_iva(clifo.tipo(), non_esposti, righe_iva, imponibile, imposta);
 | 
						|
    switch (allegato)
 | 
						|
    {
 | 
						|
    case  1: allimp._imp   += imponibile; allimp._iva += imposta; break;
 | 
						|
    case  2: allimp._impNI += imponibile; break;
 | 
						|
    case  3: allimp._impES += imponibile; break;
 | 
						|
    case  4: allimp._ivaNE += imponibile; break; // Importi con IVA non esposta
 | 
						|
    case  5: allimp._ind   += imponibile; break; // Importi INDecifrabili
 | 
						|
    default: allimp._impNA += imponibile; break; // same as case 0
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
// algo: R=data Registrazione; D=data Documento
 | 
						|
TRecordset* TAlleg_mask::new_recordset(char tipocf, bool invio)
 | 
						|
{
 | 
						|
  const bool ministeriale = get(F_ALGO) == "D";
 | 
						|
 | 
						|
  // Compito: tradurre in ISAM la seguente query:
 | 
						|
  // SELECT * FROM MOV 
 | 
						|
  // WHERE TIPO=#TYPE AND ANNOIVA=#ANNO
 | 
						|
  // ORDER BY TIPO,CODCF;
 | 
						|
  TString query = "USE MOV KEY 3";           // La chiave 3 e' TIPO+CODCF+DATAREG+NUMREG
 | 
						|
  query << "\nSELECT ";
 | 
						|
  if (ministeriale)
 | 
						|
    query << "(ANNOIVA>=#ANNO)";             // Seleziona dall'anno desiderato in poi
 | 
						|
  else
 | 
						|
    query << "(ANNOIVA==#ANNO)";             // Seleziona solo l'anno desiderato
 | 
						|
 | 
						|
  query << "\nFROM TIPO=#TYPE CODCF=1";      // Salta tutti movimenti senza CODCF
 | 
						|
  query << "\nTO TIPO=#TYPE";                // Inutile dire CODCF=999999
 | 
						|
  TISAM_recordset mov(query);
 | 
						|
 | 
						|
  if (tipocf <= ' ') tipocf = get(F_TIPO)[0];
 | 
						|
  
 | 
						|
	const char tipo[2] = { tipocf, '\0' };
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
 | 
						|
  mov.set_var("#ANNO", TVariant(long(anno)));
 | 
						|
  mov.set_var("#TYPE", TVariant(tipo));
 | 
						|
 | 
						|
  const TRecnotype movs = mov.items();
 | 
						|
  TString msg;
 | 
						|
  msg << TR("Elaborazione") << ' ' << movs << ' ' << TR("Movimenti") << ' '
 | 
						|
      << (tipocf == 'C' ? TR("Clienti") : TR("Fornitori"));
 | 
						|
  TProgind pi(movs, msg, true, true);
 | 
						|
 | 
						|
  TAssoc_array clifi;
 | 
						|
 | 
						|
  for (bool ok = mov.move_first(); ok; ok = mov.move_next())
 | 
						|
  {
 | 
						|
    if (!pi.addstatus(1))
 | 
						|
      break;
 | 
						|
 | 
						|
    const int annoiva = mov.get(MOV_ANNOIVA).as_int();
 | 
						|
    const TString& codcaus = mov.get(MOV_CODCAUS).as_string();
 | 
						|
    const TCausale& caus = _causali.causale(codcaus, annoiva);
 | 
						|
 | 
						|
    if (caus.esclusione_allegati()) // Controllo il flag di esclusione dagli allegati
 | 
						|
      continue;
 | 
						|
    
 | 
						|
    // Scarta trasferimento movimenti intra prima del 2008
 | 
						|
    if (invio && anno < 2008 && caus.intra())
 | 
						|
      continue;
 | 
						|
 | 
						|
    // Controllo inutilmente anche il tipo documento
 | 
						|
    const TString& tipodoc = caus.tipodoc();
 | 
						|
    if (documento_corrispettivi(tipodoc))
 | 
						|
      continue;
 | 
						|
 | 
						|
    // Controllo se registro e' compatibile
 | 
						|
    const TRegistro& reg = caus.reg();
 | 
						|
    if (reg.corrispettivi())
 | 
						|
      continue;
 | 
						|
 | 
						|
    const TipoIVA tipoiva = reg.iva();
 | 
						|
    bool keep = tipoiva == iva_vendite || tipoiva == iva_acquisti; // Voglio solo registri IVA
 | 
						|
    if (keep)
 | 
						|
      keep = (tipocf == 'C') ^ (tipoiva == iva_acquisti);  // compatibile
 | 
						|
 | 
						|
    if (keep && ministeriale)
 | 
						|
    {
 | 
						|
      const int annodoc = mov.get(MOV_DATADOC).as_date().year();
 | 
						|
      const bool is_nota = (tipodoc=="NC") || (tipodoc=="ND");
 | 
						|
      keep = (annodoc == anno) ; // || (is_nota && (annodoc == anno-1));
 | 
						|
    }
 | 
						|
 | 
						|
    if (!keep) 
 | 
						|
      continue;
 | 
						|
    
 | 
						|
    scan_iva_rows(mov, clifi, invio, ministeriale);
 | 
						|
  }
 | 
						|
 | 
						|
  TAllegati_set* hullygully = new TAllegati_set;
 | 
						|
  FOR_EACH_ASSOC_OBJECT(clifi, h, k, o)
 | 
						|
  {
 | 
						|
    const TAllegato_info& ai = *(TAllegato_info*)o;
 | 
						|
    if (ai.is_not_null(invio))
 | 
						|
      hullygully->add(ai);
 | 
						|
  }
 | 
						|
  hullygully->sort();
 | 
						|
  
 | 
						|
  return hullygully;
 | 
						|
}
 | 
						|
 | 
						|
const TRectype& TAlleg_mask::contribuente() const
 | 
						|
{
 | 
						|
  const char tipoa = prefix().firm().get(NDT_TIPOA)[0];
 | 
						|
  const long codanagr = prefix().firm().get_long(NDT_CODANAGR);
 | 
						|
  TToken_string key;
 | 
						|
  key.add(tipoa, 0); key.add(codanagr, 1);
 | 
						|
  const TRectype& anag = cache().get(LF_ANAG, key);
 | 
						|
  return anag;
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::add_0_9(int trc, TPadoaSchioppa_set& pss, TAlleg_log& log)
 | 
						|
{
 | 
						|
  pss.new_rec(trc);
 | 
						|
 | 
						|
  const TRectype& anag = contribuente();
 | 
						|
  const char tipoa = anag.get_char(ANA_TIPOA);
 | 
						|
  const long codanagr = anag.get_long(ANA_CODANAGR);
 | 
						|
  const TString ragsoc = anag.get(ANA_RAGSOC); // Non fidarsi ad usare TString&
 | 
						|
  
 | 
						|
  TString16 pariva = anag.get(ANA_PAIV); pariva.right_just(11, '0');
 | 
						|
  if (!pi_check("", pariva))
 | 
						|
    log_error(ragsoc, TR("*** Ditta con partita IVA errata"), pariva, log, 2);
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (pariva[0] == '8' || pariva[0] == '9')
 | 
						|
      log_error(ragsoc, TR("* Verificare esenzione dall'invio degli elenchi"), pariva, log, 2);
 | 
						|
  }
 | 
						|
 | 
						|
  const TString16 codfis = anag.get(ANA_COFI);
 | 
						|
  if (!cf_check("", codfis))
 | 
						|
    log_error(ragsoc, TR("** Ditta con codice fiscale errato"), codfis, log, 2);
 | 
						|
 | 
						|
  pss.set("CodiceFiscale", codfis.full() ? codfis : pariva);
 | 
						|
  pss.set("PartitaIVA",    pariva.full() ? pariva : codfis);
 | 
						|
  if (tipoa == 'F')
 | 
						|
  {
 | 
						|
    pss.set("Cognome", ragsoc.left(30));
 | 
						|
    pss.set("Nome",    ragsoc.mid(30));
 | 
						|
 | 
						|
    const TRectype& anafis = cache().get(LF_ANAGFIS, codanagr);
 | 
						|
    pss.set("Sesso",       anafis.get(ANF_SESSO));
 | 
						|
    pss.set("DataNascita", anafis.get_date(ANF_DATANASC));
 | 
						|
 | 
						|
    const TString4 stato = anafis.get(ANF_STATONASC);
 | 
						|
    const TString4 comun = anafis.get(ANF_COMNASC);
 | 
						|
    TString8 key; key << stato << '|' << comun;
 | 
						|
    const TRectype& comnas = cache().get(LF_COMUNI, key);
 | 
						|
    pss.set("ComuneNascita", comnas.get(COM_DENCOM));
 | 
						|
 | 
						|
    if (stato.full() || comun[0] >= 'Z') // Nato all'estero
 | 
						|
      pss.set("ProvinciaNascita", TVariant("EE")); 
 | 
						|
    else
 | 
						|
      pss.set("ProvinciaNascita", comnas.get(COM_PROVCOM));
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const TString4 stato = anag.get(ANA_STATORES);
 | 
						|
    const TString4 comun = anag.get(ANA_COMRES);
 | 
						|
    TString8 key; key << stato << '|' << comun;
 | 
						|
    const TRectype& comres = cache().get(LF_COMUNI, key);
 | 
						|
 | 
						|
    pss.set("Denominazione", ragsoc);
 | 
						|
    pss.set("ComuneSedeLegale", comres.get(COM_DENCOM));
 | 
						|
    pss.set("ProvinciaSedeLegale", comres.get(COM_PROVCOM));
 | 
						|
  }
 | 
						|
 | 
						|
  const long anno = get_int(F_ANNO);
 | 
						|
  pss.set("AnnoRiferimento", TVariant(anno));          // 2006, 2007, 2008, ...
 | 
						|
 | 
						|
  // Compilare solo se diverso da dichiarante
 | 
						|
  pss.set("CodiceSoggettoObbligato", get(F_SOGG)); 
 | 
						|
 | 
						|
  // Dati dell'intermediario che si cucca 50 Euro senza fare una mazza!
 | 
						|
  const TString& inter = get(F_INTR);
 | 
						|
  if (inter.full() && codfis != inter)
 | 
						|
  {
 | 
						|
    pss.set("CodiceIntermediario"    , inter); 
 | 
						|
    pss.set("NumeroIscrizioneAlboCAF", get(F_CAF)); 
 | 
						|
    pss.set("ImpegnoAllaTrasmissione", get(F_COMP)); 
 | 
						|
    pss.set("DataImpegno",             get_date(F_DATA)); 
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::add_3(TPadoaSchioppa_set& pss)
 | 
						|
{
 | 
						|
  long num_cli = 0;
 | 
						|
  long num_for = 0;
 | 
						|
  TAssoc_array totali;
 | 
						|
  TString8 code;
 | 
						|
 | 
						|
  for (bool ok = pss.move_first(); ok; ok = pss.move_next())
 | 
						|
  {
 | 
						|
    const int tipo = atoi(pss.rec_type());
 | 
						|
    if (tipo == 1 || tipo == 2)
 | 
						|
    {
 | 
						|
      const TString& curr = pss.curr_row();
 | 
						|
      int pos = 1;
 | 
						|
      // Scansione dei 70 campi non posizionali
 | 
						|
      for (int i = 0; i < npCount; i++, pos += npSize)  
 | 
						|
      {
 | 
						|
        code = curr.mid(pos, npCode);   // Codice campo
 | 
						|
        if (code.blank()) // Campo nullo = Fine record, "certamente" ultimo di questo tipo
 | 
						|
          break;
 | 
						|
        const int subcode = atoi(code.mid(2));         // CL004001 -> 4001
 | 
						|
        if (subcode == 1001) // Numero progressivo ...
 | 
						|
        {
 | 
						|
          if (tipo == 1)     // ... cliente
 | 
						|
            num_cli++;
 | 
						|
          else
 | 
						|
            num_for++;       // ... fornitore
 | 
						|
        } else
 | 
						|
        if (subcode >= 4001 && subcode <= 13001)         // Cosidera solo gli importi
 | 
						|
        {
 | 
						|
          real* tot = (real*)totali.objptr(code);
 | 
						|
          if (tot == NULL)
 | 
						|
          {
 | 
						|
            tot = new real;
 | 
						|
            totali.add(code, tot);
 | 
						|
          }
 | 
						|
          const real val(curr.mid(pos+npCode, npValue)); // Importo sicuramente NON nullo
 | 
						|
          *tot += val;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  pss.new_rec(3);
 | 
						|
  pss.set("Clienti",   TVariant(num_cli));
 | 
						|
  pss.set("Fornitori", TVariant(num_for));
 | 
						|
  FOR_EACH_ASSOC_OBJECT(totali, hash, key, v)
 | 
						|
  {
 | 
						|
    const real& val = *(real*)v;
 | 
						|
    pss.set(key, val);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::copia_importo(const TRecordset& clifo, const char* fldname,
 | 
						|
                                TPadoaSchioppa_set& pss, int fldcode) const
 | 
						|
{
 | 
						|
  const TVariant& val = clifo.get(fldname);
 | 
						|
  if (!val.is_zero())
 | 
						|
  {
 | 
						|
    CHECKS(!val.is_string(), "Campo importo di tipo errato", fldname);
 | 
						|
    pss.set(fldcode, val);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::log_error(const char* ragsoc, const char* msg1, const char* msg2,
 | 
						|
                            TAlleg_log& errlog, int severity) 
 | 
						|
{
 | 
						|
  TString str;
 | 
						|
  str << ragsoc << " - " << msg1;
 | 
						|
  if (msg2 && *msg2)
 | 
						|
    str << " : " << msg2;
 | 
						|
  errlog.log(severity, str);
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::log_error(const TRecordset& clifo, const char* msg1, const char* msg2,
 | 
						|
                            TAlleg_log& errlog, int severity) 
 | 
						|
{
 | 
						|
  TString str;
 | 
						|
  str << clifo.get("#RECORD.NUMBER") << ". " 
 | 
						|
      << clifo.get(CLI_TIPOCF) << clifo.get(CLI_CODCF)  
 | 
						|
      << ' ' << clifo.get(CLI_RAGSOC);
 | 
						|
  str.strip_double_spaces();
 | 
						|
  log_error(str, msg1, msg2, errlog, severity);
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::add_1_2(int trc, TRecordset& clifo, TPadoaSchioppa_set& pss, TAlleg_log& log)
 | 
						|
{
 | 
						|
  const int anno = get_int(F_ANNO);
 | 
						|
  const bool coffee = get_bool(F_COFI); // Codice fiscale voluto o obbligatorio
 | 
						|
 | 
						|
  long np = 0;     // Prossimo numero progressivo clifo
 | 
						|
  for (bool ok = clifo.move_first(); ok; ok = clifo.move_next())
 | 
						|
  {
 | 
						|
    if (np == 0)             // Se sto per scrivere il primo elemento ... 
 | 
						|
      pss.new_rec(trc);      // ... creo un nuovo record per accoglierlo
 | 
						|
    
 | 
						|
    pss.set(1001, ++np);     // Incremento il numero progressivo
 | 
						|
 | 
						|
    // Gestione automagica del codice fiscale e della partita IVA
 | 
						|
    TString16 paiv = clifo.get(CLI_PAIV).as_string(); paiv.trim();
 | 
						|
    if (paiv.full() && real::is_natural(paiv)) 
 | 
						|
      paiv.right_just(11, '0');
 | 
						|
    
 | 
						|
    TString16 cofi = clifo.get(CLI_COFI).as_string(); cofi.trim();
 | 
						|
 | 
						|
    /* Troppo astuto per "Sirio il Dragone"
 | 
						|
 | 
						|
    // Se il codice fiscale e' vuoto prendo la partita IVA numerica
 | 
						|
    if (cofi.blank() && pi_check("", paiv)) 
 | 
						|
      cofi = paiv;
 | 
						|
 | 
						|
    // Se la partita IVA e' vuota ed il codice fiscale e' numerico ...
 | 
						|
    if (paiv.blank() && pi_check("", cofi))
 | 
						|
      paiv = cofi; // ... allora copia nella partita IVA il codice fiscale 
 | 
						|
      
 | 
						|
    */
 | 
						|
    
 | 
						|
 | 
						|
    // Voglio o devo salvare il codice fiscale del tizio
 | 
						|
    if (coffee)
 | 
						|
    {
 | 
						|
      if (cofi.blank())
 | 
						|
      {
 | 
						|
        log_error(clifo, TR("* Codice fiscale mancante"), cofi, log, 2);
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if (!real::is_natural(cofi) && !cf_check("", cofi))
 | 
						|
          log_error(clifo, TR("** Codice fiscale errato"), cofi, log, 1);
 | 
						|
        pss.set(2001, cofi);           // Codice fiscale (obbligatorio dal 2008)
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (real::is_null(paiv))
 | 
						|
    {
 | 
						|
      if (anno < 2008 || cofi.blank())
 | 
						|
        log_error(clifo, TR("** Partita IVA mancante"), NULL, log, 2);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {   
 | 
						|
      if (!pi_check("", paiv))
 | 
						|
        log_error(clifo, TR("** Partita IVA errata"), paiv, log, 1);
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if (paiv[0] == '8' || paiv[0] == '9')
 | 
						|
          log_error(clifo, TR("* Verificare esclusione della Partita IVA"), paiv, log, 1);
 | 
						|
      }
 | 
						|
 | 
						|
      pss.set(3001, paiv);           // Partita IVA (obbligatoria dal 2006)
 | 
						|
    }
 | 
						|
 | 
						|
    if (trc == 1)  // Clienti
 | 
						|
    {
 | 
						|
      // Importi anno corrente
 | 
						|
      copia_importo(clifo, "C_IMP", pss, 4001);
 | 
						|
      copia_importo(clifo, "C_IVA", pss, 4002);
 | 
						|
      copia_importo(clifo, "C_NI" , pss, 5001);
 | 
						|
      copia_importo(clifo, "C_ES" , pss, 6001);
 | 
						|
      copia_importo(clifo, "C_NE" , pss, 7001);
 | 
						|
 | 
						|
      // Importi anno precedente
 | 
						|
      copia_importo(clifo, "P_IMP", pss, 8001);
 | 
						|
      copia_importo(clifo, "P_IVA", pss, 8002);
 | 
						|
      copia_importo(clifo, "P_NI" , pss, 9001);
 | 
						|
      copia_importo(clifo, "P_ES" , pss,10001);
 | 
						|
      copia_importo(clifo, "P_NE" , pss,11001);
 | 
						|
    } 
 | 
						|
    else           // Fornitori
 | 
						|
    {
 | 
						|
      // Importi anno corrente
 | 
						|
      copia_importo(clifo, "C_IMP", pss, 4001);
 | 
						|
      copia_importo(clifo, "C_IVA", pss, 4002);
 | 
						|
      copia_importo(clifo, "C_IND", pss, 5001);  // Indecifrabile
 | 
						|
      copia_importo(clifo, "C_NI" , pss, 6001);
 | 
						|
      copia_importo(clifo, "C_ES" , pss, 7001);
 | 
						|
      copia_importo(clifo, "C_NE" , pss, 8001);
 | 
						|
 | 
						|
      // Importi anno precedente
 | 
						|
      copia_importo(clifo, "P_IMP", pss, 9001);
 | 
						|
      copia_importo(clifo, "P_IVA", pss, 9002);
 | 
						|
      copia_importo(clifo, "P_IND", pss,10001);
 | 
						|
      copia_importo(clifo, "P_NI" , pss,11001);
 | 
						|
      copia_importo(clifo, "P_ES" , pss,12001);
 | 
						|
      copia_importo(clifo, "P_NE" , pss,13001);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TAlleg_mask::show_errors(TAlleg_log& log) const
 | 
						|
{
 | 
						|
  if (yesno_box(TR("Sono stati rilevati errori sulla fornitura:\nSi desidera visualizzarli?")))
 | 
						|
  {
 | 
						|
    TReport_book errbuc;
 | 
						|
    errbuc.add(log);
 | 
						|
    errbuc.preview();
 | 
						|
  }
 | 
						|
  return yesno_box(TR("Si desidera generare ugualmente la fornitura?"));
 | 
						|
}
 | 
						|
 | 
						|
// Pulisce e normalizza un nome di file
 | 
						|
static bool normalize_name(TFilename& name)
 | 
						|
{
 | 
						|
  name.trim();
 | 
						|
  if (name.not_empty())
 | 
						|
  {
 | 
						|
    name.lower();
 | 
						|
    name.replace('\\', '/');
 | 
						|
  }
 | 
						|
  return name.not_empty();
 | 
						|
}
 | 
						|
 | 
						|
// Estrae un nome di file pulito da una riga di spreadsheet
 | 
						|
static bool row2name(const TToken_string& row, TFilename& name)
 | 
						|
{
 | 
						|
  row.get(0, name);
 | 
						|
  return normalize_name(name);
 | 
						|
}
 | 
						|
 | 
						|
bool TAlleg_mask::build_output_name(TFilename& fname) const
 | 
						|
{
 | 
						|
  fname = get(F_DIR); 
 | 
						|
  fname.add(get(F_NAME));
 | 
						|
  return normalize_name(fname);
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::generazione()
 | 
						|
{
 | 
						|
  TPadoaSchioppa_set pss;
 | 
						|
  TAlleg_log log;
 | 
						|
 | 
						|
  add_0_9(0, pss, log);         // Testa 
 | 
						|
  
 | 
						|
  TRecordset* cli = new_recordset('C', true);
 | 
						|
  if (cli != NULL && cli->items())
 | 
						|
  {
 | 
						|
    log.log(0, TR("CLIENTI"));
 | 
						|
    add_1_2(1, *cli, pss, log); // Clienti
 | 
						|
  }
 | 
						|
 | 
						|
  TRecordset* acq = new_recordset('F', true);
 | 
						|
  if (acq != NULL && acq->items() > 0)
 | 
						|
  {
 | 
						|
    log.log(0, TR("FORNITORI"));
 | 
						|
    add_1_2(2, *acq, pss, log); // Fornitori 
 | 
						|
  }
 | 
						|
 | 
						|
  add_3(pss);                   // Totali Clienti e Fornitori
 | 
						|
  
 | 
						|
  add_0_9(9, pss, log);         // Piede (= Testa)
 | 
						|
 | 
						|
  bool go_on = true;
 | 
						|
  if (log.red_alert())
 | 
						|
    go_on = show_errors(log);
 | 
						|
  if (go_on)
 | 
						|
  {
 | 
						|
    TFilename fname; 
 | 
						|
    if (build_output_name(fname))
 | 
						|
      pss.save_as(fname);
 | 
						|
 | 
						|
    TReport_book book;
 | 
						|
    TAlleg_report clirep(cli, *this, true);
 | 
						|
    book.add(clirep);
 | 
						|
    TAlleg_report acqrep(acq, *this, true);
 | 
						|
    book.add(acqrep);
 | 
						|
    book.preview();
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    delete cli;
 | 
						|
    delete acq;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::import_clifo(const TFilename& name, 
 | 
						|
                               TAssoc_array& clips, TAssoc_array& forps, 
 | 
						|
                               TAlleg_log& log)
 | 
						|
{
 | 
						|
  TString error;
 | 
						|
  if (test_file(name, error))
 | 
						|
  {
 | 
						|
    TPadoaSchioppa_set inps(name);
 | 
						|
 | 
						|
    TProgind pi(inps.items(), name, true, true);
 | 
						|
    TAssoc_array* cur_clifo = NULL;
 | 
						|
    for (bool ok = inps.move_first(); ok; ok = inps.move_next())
 | 
						|
    {
 | 
						|
      if (!pi.addstatus(1))
 | 
						|
        break;
 | 
						|
      const int trc = inps.rec_type()[0]-'0';
 | 
						|
      if (trc == 1 || trc == 2)
 | 
						|
      {
 | 
						|
        TAssoc_array& clifo = trc == 1 ? clips : forps;
 | 
						|
        int i = 0, pos = 1;
 | 
						|
        const TString& rec = inps.curr_row();
 | 
						|
        for (i = 0; i < npCount; i++, pos += npSize) // Scandisce i 70 campi non posizionali
 | 
						|
        {
 | 
						|
          const TString& fld = rec.mid(pos, npSize);
 | 
						|
          const TString8 code = fld.mid(2,6);
 | 
						|
          const int ncode = atoi(code);
 | 
						|
          if (ncode > 1000)
 | 
						|
          {
 | 
						|
            switch (ncode)
 | 
						|
            {
 | 
						|
            case 1001: // Inizia una nuova anagrafica
 | 
						|
              cur_clifo = NULL; 
 | 
						|
              break;
 | 
						|
            case 3001: // Ho trovato la Partita IVA della nuova anagrafica
 | 
						|
              if (cur_clifo == NULL)
 | 
						|
              {
 | 
						|
                // Cerco l'anagrafica corrispondente alla Partita IVA
 | 
						|
                const TString16 piva = fld.mid(8);
 | 
						|
                cur_clifo = (TAssoc_array*)clifo.objptr(piva);
 | 
						|
                if (cur_clifo == NULL)          // Se non la trovo ...
 | 
						|
                {
 | 
						|
                  cur_clifo = new TAssoc_array; // ... allora la creo nuova     
 | 
						|
                  clifo.add(piva, cur_clifo);  
 | 
						|
                }
 | 
						|
              }
 | 
						|
              else
 | 
						|
                log.log(2, "Dati inconsistenti");
 | 
						|
              break;
 | 
						|
            default  :
 | 
						|
              if (cur_clifo != NULL)
 | 
						|
              {
 | 
						|
                if (ncode > 4000) // Importi
 | 
						|
                {
 | 
						|
                  const real imp = fld.mid(8);
 | 
						|
                  const TVariant value(imp);   // Impossibile fondere con riga precedente :-?
 | 
						|
                  TVariant* tot = (TVariant*)cur_clifo->objptr(code);
 | 
						|
                  if (tot != NULL)
 | 
						|
                    tot->add(value);             // Incremento importo precedente
 | 
						|
                  else
 | 
						|
                    cur_clifo->add(code, value); // Creo nuovo importo
 | 
						|
                }
 | 
						|
                else // Non importi: praticamente solo Codice Fiscale
 | 
						|
                {
 | 
						|
                  const TVariant value(fld.mid(8));
 | 
						|
                  cur_clifo->add(code, value); 
 | 
						|
                }
 | 
						|
              }
 | 
						|
              else
 | 
						|
                log.log(2, "Dati inconsistenti");
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    error.replace('\n', ' ');
 | 
						|
    log.log(1, error);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TRecnotype TAlleg_mask::export_clifo(int tiporec, TAssoc_array& clifo, 
 | 
						|
                                     TAllegati_set& all, TPadoaSchioppa_set& pss)
 | 
						|
{
 | 
						|
  TRecnotype count = 0; 
 | 
						|
  if (!clifo.empty())
 | 
						|
  {
 | 
						|
    pss.new_rec(tiporec);
 | 
						|
    FOR_EACH_ASSOC_OBJECT(clifo, cash, ckey, cobj)
 | 
						|
    {
 | 
						|
      const TVariant piva = ckey;
 | 
						|
      pss.set(1001, ++count);
 | 
						|
      pss.set(3001, piva.as_string());
 | 
						|
 | 
						|
      all.new_rec();
 | 
						|
      all.set(CLI_TIPOCF, tiporec == 1 ? "C" : "F");
 | 
						|
      all.set(CLI_CODCF, count);
 | 
						|
      all.set(CLI_PAIV, piva);
 | 
						|
 | 
						|
      TString80 str = tiporec == 1 ? TR("Cliente") : TR("Fornitore");
 | 
						|
      str << ' ' << count;
 | 
						|
      all.set(CLI_RAGSOC, (const char*)str);
 | 
						|
 | 
						|
      TAssoc_array& data = *(TAssoc_array*)cobj;
 | 
						|
      FOR_EACH_ASSOC_OBJECT(data, dash, dkey, dobj)
 | 
						|
      {
 | 
						|
        const int code = atoi(dkey);
 | 
						|
        const TVariant& var = *(TVariant*)dobj;
 | 
						|
        if (code > 4000)
 | 
						|
        {
 | 
						|
          pss.set(code, var);
 | 
						|
          if (tiporec == 1) // Clienti
 | 
						|
          {
 | 
						|
            switch (code)
 | 
						|
            {
 | 
						|
            case 4001: all.set("C_IMP", var); break;
 | 
						|
            case 4002: all.set("C_IVA", var); break;
 | 
						|
            case 5001: all.set("C_NI",  var); break;
 | 
						|
            case 6001: all.set("C_ES",  var); break;
 | 
						|
            case 7001: all.set("C_NE",  var); break;
 | 
						|
            default  : break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else             // Fornitori
 | 
						|
          {
 | 
						|
            switch (code)
 | 
						|
            {
 | 
						|
            case 4001: all.set("C_IMP", var); break;
 | 
						|
            case 4002: all.set("C_IVA", var); break;
 | 
						|
            case 5001: all.set("C_IND", var); break;
 | 
						|
            case 6001: all.set("C_NI",  var); break;
 | 
						|
            case 7001: all.set("C_ES",  var); break;
 | 
						|
            case 8001: all.set("C_NE",  var); break;
 | 
						|
            default  : break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          if (code != 1001 && code != 3001) // Gia' scritti da prima
 | 
						|
            pss.set(code, var.as_string());
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return count;
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::fusione()
 | 
						|
{
 | 
						|
  TPadoaSchioppa_set pss;
 | 
						|
  TAlleg_log log;
 | 
						|
 | 
						|
  add_0_9(0, pss, log);  // Testa 
 | 
						|
 | 
						|
  TAssoc_array clips, forps;
 | 
						|
  TSheet_field& sheet = sfield(F_FUSION);
 | 
						|
  TFilename name;
 | 
						|
  FOR_EACH_SHEET_ROW(sheet, r, row) if (row2name(*row, name))
 | 
						|
  {
 | 
						|
    TString error;
 | 
						|
    if (test_file(name, error))
 | 
						|
      import_clifo(name, clips, forps, log);
 | 
						|
    else
 | 
						|
      log.log(1, error);
 | 
						|
  }
 | 
						|
 | 
						|
  TAllegati_set* all = new TAllegati_set;
 | 
						|
  export_clifo(1, clips, *all, pss); // Clienti
 | 
						|
  export_clifo(2, forps, *all, pss); // Fornitori
 | 
						|
 | 
						|
  add_3(pss);           // Totali Clienti e Fornitori
 | 
						|
  add_0_9(9, pss, log); // Piede (= Testa)
 | 
						|
 | 
						|
  bool go_on = all->items() > 0;
 | 
						|
  if (log.red_alert())
 | 
						|
    go_on = show_errors(log);
 | 
						|
 | 
						|
  if (go_on)
 | 
						|
  {
 | 
						|
    TFilename fname; 
 | 
						|
    if (build_output_name(fname))
 | 
						|
      pss.save_as(fname);
 | 
						|
 | 
						|
    TReport_book book;
 | 
						|
    TAlleg_report rep(all, *this, true);
 | 
						|
    book.add(rep);
 | 
						|
    book.preview();
 | 
						|
  }
 | 
						|
  else
 | 
						|
    delete all;
 | 
						|
}
 | 
						|
 | 
						|
bool TAlleg_mask::test_file(const TFilename& name, TString& error) const
 | 
						|
{
 | 
						|
  TToken_string errors(80, ';');
 | 
						|
  
 | 
						|
  error.cut(0);
 | 
						|
  if (!name.exist())
 | 
						|
    errors = TR("non e' accessibile o inesistente");
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const TFixed_string ecf_ext("ecf");
 | 
						|
    if (ecf_ext.compare(name.ext(), true) != 0)
 | 
						|
      errors.add(TR("non ha un'estensione valida (ECF)"));
 | 
						|
 | 
						|
    TFilename outname; build_output_name(outname);
 | 
						|
    if (name == outname)
 | 
						|
      errors.add(TR("ha lo stesso nome del file totale"));
 | 
						|
    
 | 
						|
    const long sz = fsize(name);
 | 
						|
    if (sz % 1800)
 | 
						|
      errors.add(TR("non ha una dimensione valida (multipla di 1800)"));
 | 
						|
 | 
						|
    ifstream ecf_file(name);
 | 
						|
    TString4 head; head.spaces();
 | 
						|
    ecf_file.read(head.get_buffer(), head.size());
 | 
						|
    if (!head.starts_with("0ECF"))
 | 
						|
      errors.add(TR("non ha un record di testata valido (0ECF)"));
 | 
						|
  }
 | 
						|
 | 
						|
  if (errors.full())
 | 
						|
  {
 | 
						|
    error << '\'' << name << "' " << TR("non e' una fornitura valida") 
 | 
						|
          << ":\n" << errors;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return errors.empty();
 | 
						|
}
 | 
						|
 | 
						|
bool TAlleg_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						|
{
 | 
						|
  switch (o.dlg())
 | 
						|
  {
 | 
						|
  case F_ANNO:
 | 
						|
    if (e == fe_init || e == fe_modify)
 | 
						|
    {
 | 
						|
      int anno = atoi(o.get());
 | 
						|
      if (anno < 2006)
 | 
						|
      {
 | 
						|
        const TDate oggi(TODAY);
 | 
						|
        anno = oggi.year()-1;
 | 
						|
        set(F_ANNO, anno);
 | 
						|
      }
 | 
						|
      if (anno >= 2008)
 | 
						|
      {
 | 
						|
        set(F_COFI, "X");
 | 
						|
        disable(F_COFI);
 | 
						|
      }
 | 
						|
      else
 | 
						|
        enable(F_COFI);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_DIR:
 | 
						|
    if (e == fe_init || e == fe_modify)
 | 
						|
    {
 | 
						|
      if (o.empty())
 | 
						|
      {
 | 
						|
        TFilename fdir; fdir.tempdir();
 | 
						|
        o.set(fdir);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_NAME:
 | 
						|
    if (e == fe_init || e == fe_modify)
 | 
						|
    {
 | 
						|
      if (e == fe_init || o.empty())
 | 
						|
      {
 | 
						|
        const TRectype& anag = contribuente();
 | 
						|
        TFilename ecf = anag.get(ANA_PAIV);
 | 
						|
        ecf.right_just(11, '0');
 | 
						|
        ecf << "_ECF00.ecf";
 | 
						|
        set(F_NAME, ecf);
 | 
						|
        o.set(ecf);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_CONT:
 | 
						|
    if (e == fe_init)
 | 
						|
    {
 | 
						|
      const TRectype& anag = contribuente();
 | 
						|
      o.set(anag.get(ANA_COFI));
 | 
						|
      o.disable();
 | 
						|
      set(F_PIVA, anag.get(ANA_PAIV));
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_INTR:
 | 
						|
    if (e == fe_init && o.empty())
 | 
						|
    {
 | 
						|
      TString16 key = prefix().firm().get(NDT_FIRMAT);
 | 
						|
      if (key.full())
 | 
						|
      {
 | 
						|
        key.insert("F|");
 | 
						|
        o.set(cache().get(LF_ANAG, key, ANA_COFI));
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_CAF:
 | 
						|
    if (o.empty())
 | 
						|
    {
 | 
						|
      if (e == fe_init)
 | 
						|
        o.set(prefix().firm().get(NDT_INTCAF));
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_SELECT:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      TRecordset* rs = new_recordset();
 | 
						|
      TRecordset_sheet sheet(*rs, TR("Elenco di controllo"), 0x8);
 | 
						|
      while (sheet.run() == K_ENTER)
 | 
						|
      {
 | 
						|
        const long sel = sheet.selected();
 | 
						|
        TToken_string& row = sheet.row(sel);
 | 
						|
        TRectype clifo(LF_CLIFO);
 | 
						|
        clifo.put(CLI_TIPOCF, row.get(0));
 | 
						|
        clifo.put(CLI_CODCF, row.get(1));
 | 
						|
        clifo.edit();
 | 
						|
      }
 | 
						|
      delete rs;
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_EDIT:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      TRecordset* rs = new_recordset();
 | 
						|
      TFilename fname = get(F_DIR);
 | 
						|
      fname.add("clifo.xls");
 | 
						|
      if (rs->save_as(fname))
 | 
						|
        xvt_sys_goto_url(fname, "open");
 | 
						|
      delete rs;
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_PRINT:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      TRecordset* rs = new_recordset();
 | 
						|
      TAlleg_report rep(rs, *this);
 | 
						|
      TReport_book book;
 | 
						|
      book.add(rep);
 | 
						|
      book.print_or_preview();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case DLG_ELABORA:
 | 
						|
    if (e == fe_button)
 | 
						|
    {
 | 
						|
      if (check_fields())
 | 
						|
      {
 | 
						|
        if (curr_page() == 0)
 | 
						|
          generazione();
 | 
						|
        else
 | 
						|
          fusione();
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case F_FUSION:
 | 
						|
    if (e == se_notify_modify)
 | 
						|
    {
 | 
						|
      TFilename name; 
 | 
						|
      if (row2name(((TSheet_field&)o).row(jolly), name))
 | 
						|
      {
 | 
						|
        TString error;
 | 
						|
        if (!test_file(name, error))
 | 
						|
          return error_box(error);
 | 
						|
      }
 | 
						|
    } else
 | 
						|
    if (e == fe_close)
 | 
						|
    {
 | 
						|
      TSheet_field& s = (TSheet_field&)o;
 | 
						|
      TString error;
 | 
						|
      TFilename name1, name2;
 | 
						|
      FOR_EACH_SHEET_ROW(s, i, row1) if (row2name(*row1, name1))
 | 
						|
      {
 | 
						|
        if (!test_file(name1, error))
 | 
						|
          return error_box(error);
 | 
						|
 | 
						|
        FOR_EACH_SHEET_ROW(s, j, row2) if (j > i && row2name(*row2, name2))
 | 
						|
        {
 | 
						|
          if (name1 == name2)
 | 
						|
          {
 | 
						|
            error.format("La riga %d e' duplicata nella riga %d", i+1, j+1);
 | 
						|
            return error_box(error);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default: 
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TAlleg_mask::on_firm_change()
 | 
						|
{
 | 
						|
  set(F_NAME, "", 3);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TAlleg_mask::TAlleg_mask() : TAutomask("cg3900a") 
 | 
						|
{ }
 | 
						|
 | 
						|
TAlleg_mask::~TAlleg_mask()
 | 
						|
{ 
 | 
						|
  save_profile();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TClifo_alleg_app
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TClifo_alleg_app : public TSkeleton_application
 | 
						|
{
 | 
						|
public:
 | 
						|
  virtual void main_loop();
 | 
						|
};
 | 
						|
 | 
						|
void TClifo_alleg_app::main_loop()
 | 
						|
{
 | 
						|
  // Roba anagrafica
 | 
						|
  open_files(LF_ANAG, LF_ANAGFIS, LF_COMUNI, LF_NDITTE, LF_OCCAS, LF_TAB, LF_TABCOM, 0); 
 | 
						|
  // Roba contabile
 | 
						|
  open_files(LF_CAUSALI, LF_CLIFO, LF_MOV, LF_RMOVIVA, 0);         
 | 
						|
  TAlleg_mask m;
 | 
						|
  m.run();
 | 
						|
}
 | 
						|
 | 
						|
int cg3900(int argc, char* argv[])
 | 
						|
{
 | 
						|
  TClifo_alleg_app app;
 | 
						|
  app.run(argc, argv, TR("Elenco clienti/fornitori"));
 | 
						|
  return 0;
 | 
						|
}
 |