Files correlati : cg0200a.msk cg3.exe Ricompilazione Demo : [ ] Commento : Migliorata esportazione in Excel dei campi Partita IVA in cui scomparivano gli zeri iniziali git-svn-id: svn://10.65.10.50/trunk@20182 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1777 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1777 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, bool prorata100) 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);
 | |
|   const bool prorata100 = caus.reg().prorata100(annoiva);
 | |
| 
 | |
|   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;
 | |
| }
 |