Files correlati : ve6.exe Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 979 git-svn-id: svn://10.65.10.50/trunk@15623 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1251 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1251 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <applicat.h>
 | |
| #include <automask.h>
 | |
| #include <dongle.h>
 | |
| #include <progind.h>
 | |
| #include <recarray.h>
 | |
| #include <relapp.h>
 | |
| #include <reprint.h>
 | |
| #include <tabutil.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #include <anagr.h>
 | |
| #include <anafis.h>
 | |
| #include <anagiu.h>
 | |
| #include <clifo.h>
 | |
| #include <comuni.h>
 | |
| #include <nditte.h>
 | |
| 
 | |
| #include "../ba/ba0100a.h"
 | |
| 
 | |
| #include "li0.h"
 | |
| #include "li0600a.h"
 | |
| #include "li0600b.h"
 | |
| 
 | |
| #include "letint.h"
 | |
| 
 | |
| //--------------------------------------------------------------
 | |
| //    MASCHERA
 | |
| //--------------------------------------------------------------
 | |
| class TSend_letint_mask : public TAutomask
 | |
| {
 | |
| protected:
 | |
|   bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | |
|   bool ask_service_pwd();
 | |
| 
 | |
| public:
 | |
|   TSend_letint_mask();
 | |
|   virtual ~TSend_letint_mask() {}
 | |
| };
 | |
| 
 | |
| TSend_letint_mask::TSend_letint_mask()
 | |
| 								:TAutomask("li0600a")
 | |
| {
 | |
| }
 | |
| 
 | |
| static TDate _da_data, _a_data;
 | |
| static bool filtra_per_date(const TRelation* rel)
 | |
| {
 | |
|   const TDate data = rel->curr().get(LETINT_DATAREG);
 | |
|   return data >= _da_data && data <= _a_data;
 | |
| }
 | |
| 
 | |
| bool TSend_letint_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) 
 | |
| {
 | |
|   switch (o.dlg())
 | |
|   {
 | |
|   case F_ANNO:	
 | |
|   if (e == fe_modify || e == fe_init) //propone il mese corrispondente al primo record NON inviato
 | |
| 	{
 | |
| 
 | |
|     int mese = 1;
 | |
| 		TLocalisamfile letint(LF_LETINT);
 | |
| 		const int anno(get_int(F_ANNO));
 | |
| 		letint.put(LETINT_ANNO, anno);
 | |
| 	  int err = letint.read(_isgteq);
 | |
|     if (err == NOERR && letint.get_int(LETINT_ANNO) == anno)
 | |
|     {
 | |
| 		  for ( ; err == NOERR && letint.get_int(LETINT_ANNO) == anno; err = letint.next())
 | |
|       {
 | |
|         const TDate first_rip = letint.get_date(LETINT_DATAREG);
 | |
|         const int m = first_rip.month();
 | |
| 			  if (letint.get_bool(LETINT_INVIATO) == false)
 | |
|         {
 | |
|           mese = m;
 | |
|           break;
 | |
|         }
 | |
|         else  //caso in cui l'ultimo mese è tutto inviato (ripropone lo stesso mese)
 | |
|         {
 | |
|           if (m > mese)
 | |
|             mese = m;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     TString4 str_mese; str_mese.format("%02d", mese);
 | |
|     o.mask().set(F_MESE, str_mese);
 | |
| 
 | |
| 		//riempie i campi dei progressivi e totali inviati
 | |
| 		TISAM_recordset reg_dich("USE REG SELECT (I0==10)&&(CODTAB[1,4]=#ANNO)");
 | |
| 		reg_dich.set_var("#ANNO", TVariant(long(anno)));
 | |
| 		if (reg_dich.move_first())
 | |
| 		{
 | |
| 			set(F_PROGINV, reg_dich.get("I3").as_int());
 | |
| 			set(F_TOTINV, reg_dich.get("I4").as_int());
 | |
| 			set(F_REGISTRO, reg_dich.get("CODTAB[5,7]").as_string());
 | |
| 			enable(DLG_OK);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			reset(F_PROGINV);
 | |
| 			reset(F_TOTINV);
 | |
| 			disable(DLG_OK);
 | |
| 			error_box(TR("Non esiste il registro delle dichiarazioni d'intento per l'anno selezionato."));
 | |
| 		}
 | |
| 	}
 | |
|     break;
 | |
| 
 | |
|   case F_RIPRISTINA:
 | |
|   if (e == fe_button)
 | |
|   {
 | |
|     if (ask_service_pwd())  //chiede la pwd di servizio x ripristinare
 | |
|     {
 | |
|       TMask mask("li0600b");  //maschera per selezionare il mese ed anno da ripristinare
 | |
|       if (mask.run() == K_ENTER)
 | |
|       {
 | |
|         //ripristinare solo dichiarazioni del mese/anno selezionato
 | |
|         const int anno_rip = mask.get_int(F_ANNO);
 | |
|         const int mese_rip = mask.get_int(F_MESE);
 | |
|         
 | |
|         TRectype darec(LF_LETINT), arec(LF_LETINT);    
 | |
|         darec.put(LETINT_ANNO, anno_rip);
 | |
|         arec.put(LETINT_ANNO, anno_rip);
 | |
|         
 | |
|         TRelation rel_letint(LF_LETINT);
 | |
| 
 | |
|         _da_data = TDate(1, mese_rip, anno_rip);
 | |
|         _a_data = TDate(31, 12, anno_rip);
 | |
| 
 | |
|         TCursor cur_letint(&rel_letint, "", 1, &darec, &arec);
 | |
|         cur_letint.set_filterfunction(filtra_per_date);
 | |
| 
 | |
|         const long items = cur_letint.items();
 | |
|         //ripristinare solo se c'è qualcosa
 | |
|         if (items > 0)
 | |
|         {
 | |
|           if (yesno_box(TR("Si desidera ripristinare %ld dichiarazioni inviate?"), items))
 | |
|             if (yesno_box(TR("Si desidera veramente ripristinare %ld dichiarazioni inviate?"), items))
 | |
|             {
 | |
|               cur_letint.freeze();
 | |
|               TProgind pi(items, "Ripristino dichiarazioni inviate", false);
 | |
|               TRectype& rec_letint = rel_letint.curr();
 | |
| 
 | |
|               for (cur_letint = 0; cur_letint.pos() < items; ++cur_letint)
 | |
|               {
 | |
|                 pi.addstatus(1);
 | |
|                 rec_letint.zero(LETINT_INVIATO); //svuota il campo
 | |
|                 rel_letint.rewrite(); //aggiorna fisicamente il file
 | |
|               }
 | |
| 							field(F_ANNO).set_focusdirty();
 | |
| 							field(F_ANNO).on_hit();
 | |
| 
 | |
|             }
 | |
|             else
 | |
|               return true;
 | |
|           else
 | |
|             return true;
 | |
|         } //end if(items>0)
 | |
|         else
 | |
|           message_box(TR("Non ci sono dichiarazioni inviate da ripristinare nel periodo selezionato"));
 | |
|       } //end mask.run()
 | |
|     } //end ask_service_pwd()
 | |
|   } //end if(e==fe_button)
 | |
|     break;
 | |
| 
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TSend_letint_mask::ask_service_pwd()
 | |
| {    
 | |
|   bool ok = false;
 | |
|   
 | |
|   TMask mask("ba0100a");
 | |
|   mask.disable(F_USER);
 | |
|   mask.set(F_USER, "SERVIZIO");
 | |
| 
 | |
|   if (mask.run() == K_ENTER)
 | |
|   {                    
 | |
|     const TDate oggi(TODAY);
 | |
|     TString16 pwd; pwd << dongle().administrator() << (oggi.month() + oggi.day());
 | |
|     ok = pwd == mask.get(F_PASSWORD);
 | |
|   }
 | |
|   if (!ok) 
 | |
|     error_box(TR("Password di servizio errata!\nAccesso negato."));
 | |
| 
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------
 | |
| //    REPORT
 | |
| //---------------------------------------------------------------
 | |
| class TSend_letint_report : public TReport   
 | |
| {
 | |
| 	word _last_printed_page;
 | |
| 
 | |
| protected:
 | |
|   virtual bool use_mask() { return false;}
 | |
| 	virtual word last_printed_page() const { return _last_printed_page; }
 | |
| 
 | |
| public:
 | |
| 	TSend_letint_report(int last_printed_page) : _last_printed_page(last_printed_page) {}
 | |
| 	~TSend_letint_report() {}
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| //  RECORD TRecord_DI
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| enum { CODE_SIZE = 8, FIELD_SIZE = 16, BLOCK_SIZE = 24, HEADER_SIZE = 89, USEABLE_SIZE = 1800, TOTAL_SIZE = 1900 };
 | |
| 
 | |
| struct TField_DI : public TObject
 | |
| {
 | |
|   TString   _desc;
 | |
|   int       _pos;   // Base 1
 | |
|   int       _len;
 | |
|   char      _type;  // A/N
 | |
|   TString16 _dflt;
 | |
| };
 | |
| 
 | |
| ////////////////////////////////////////////////////////////
 | |
| //  RIEMPITORE CAMPI TRACCIATO TTracciato_DI
 | |
| //////////////////////////////////////////////////////////// 
 | |
| class TTracciato_DI : public TObject
 | |
| {
 | |
|   char _tipo;
 | |
|   TArray _fields;
 | |
| 
 | |
| protected:
 | |
|   int add_field(const int numfield, const char* name, const char type, const int pos, const int len, const char* dflt = NULL);
 | |
|   int add_filler(const int numfield, const int pos, const int len, const char tipo = 'A')
 | |
|   { return add_field(numfield, "Filler", tipo, pos, len); }
 | |
| 
 | |
| public:
 | |
|   const TField_DI& field(int pos) const;
 | |
|   void auto_fill(TString& buffer) const;
 | |
| 
 | |
|   TTracciato_DI(char tipo);
 | |
|   virtual ~TTracciato_DI();
 | |
| };
 | |
| 
 | |
| 
 | |
| int TTracciato_DI::add_field(const int numfield, const char* name, const char type, const int pos, const int len, const char* dflt)
 | |
| {
 | |
|   TField_DI* info = new TField_DI;
 | |
|   info->_desc = name;
 | |
|   info->_type = type;
 | |
|   info->_pos  = pos;
 | |
|   info->_len  = len;
 | |
|   info->_dflt = dflt;
 | |
|   _fields.add(info, numfield);
 | |
|   return _fields.items();
 | |
| }
 | |
| 
 | |
| const TField_DI& TTracciato_DI::field(int pos) const
 | |
| {
 | |
|   TField_DI* info = (TField_DI*)_fields.objptr(pos);
 | |
|   CHECKD(info, "Campo non valido ", pos);
 | |
|   return *info;
 | |
| }
 | |
| 
 | |
| void TTracciato_DI::auto_fill(TString& buffer) const
 | |
| {
 | |
|   buffer.fill(' ', TOTAL_SIZE);
 | |
|   for (int f = _fields.last(); f > 0; f = _fields.pred(f))
 | |
|   {
 | |
|     const TField_DI& info = (const TField_DI&)_fields[f];
 | |
|     if (info._desc == "Filler")
 | |
|     {
 | |
|       const char fill = info._type == 'N' ? '0' : ' ';
 | |
|       char* index = buffer.get_buffer();
 | |
|       index += info._pos - 1;
 | |
|       memset(index, fill, info._len);
 | |
|     }
 | |
|     else  //riempitore dei campi con valore fisso di default
 | |
|     {
 | |
|       const TString& dflt = info._dflt;
 | |
|       if (!dflt.blank())
 | |
|       {
 | |
|         char* index = buffer.get_buffer();
 | |
|         index += info._pos - 1;
 | |
|         memcpy(index, dflt, dflt.len());
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   buffer[0] = _tipo;
 | |
|   buffer.overwrite("A\r\n", TOTAL_SIZE-3);
 | |
| }
 | |
| 
 | |
| TTracciato_DI::TTracciato_DI(char tipo) : _tipo(tipo)
 | |
| {
 | |
|   if (strchr("ABCZ", tipo) == NULL)
 | |
|     NFCHECK("Tipo record non valido: %c", tipo);
 | |
|   
 | |
|   TString4 header; header << _tipo;
 | |
|   add_field(1, "Tipo record", 'A', 1, 1, header);
 | |
| 
 | |
|   TConfig config("li0600a.ini", header);
 | |
|   TString_array variables;  //array con tutte le righe che trova nel paragrafo header del .ini
 | |
|   config.list_variables(variables, false, header, true);  //l'array viene riempito in modo ordinato
 | |
|   
 | |
|   TToken_string field_descr(15, ',');
 | |
| 
 | |
|   FOR_EACH_ARRAY_ROW(variables, r, numriga)
 | |
|   {
 | |
|     field_descr = config.get(*numriga);
 | |
|     const int num = atoi(*numriga);  //ordinale del campo nel record
 | |
|     const int pos = field_descr.get_int(0); //posizione iniziale del campo nel record (base 1)
 | |
|     const int len = field_descr.get_int(1); //lunghezza del campo
 | |
|     const TString4 tc = field_descr.get(2); //tipo campo
 | |
|     const char type = (tc=="AN" || tc=="CF" || tc=="CN") ? 'A' : 'N';
 | |
|     const char* dflt = field_descr.get(3);  //valore di default
 | |
| 
 | |
|     add_field(num, *numriga, type, pos, len, dflt);
 | |
|   }
 | |
|   
 | |
| }
 | |
| 
 | |
| TTracciato_DI::~TTracciato_DI()
 | |
| {
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////
 | |
| class TTracciati_DI : public TObject
 | |
| {
 | |
|   TArray _trc;
 | |
|   TAssoc_array _form;
 | |
| 
 | |
| public:
 | |
|   const TTracciato_DI& tracciato(char tipo);
 | |
| 
 | |
|   void destroy();
 | |
|   
 | |
|   TTracciati_DI();
 | |
|   virtual ~TTracciati_DI();
 | |
| } _trc_DI;
 | |
| 
 | |
| 
 | |
| const TTracciato_DI& TTracciati_DI::tracciato(char tipo)
 | |
| {
 | |
|   const int pos = tipo-'A';
 | |
|   TTracciato_DI* trc = (TTracciato_DI*)_trc.objptr(pos);
 | |
|   if (trc == NULL)
 | |
|   {
 | |
|     trc = new TTracciato_DI(tipo);
 | |
|     _trc.add(trc, pos);
 | |
|   }
 | |
|   return *trc;
 | |
| }
 | |
| 
 | |
| void TTracciati_DI::destroy()
 | |
| {
 | |
|   _trc.destroy();
 | |
|   _form.destroy();
 | |
| }
 | |
| 
 | |
| TTracciati_DI::TTracciati_DI()
 | |
| {
 | |
| }
 | |
|  
 | |
| TTracciati_DI::~TTracciati_DI()
 | |
| {
 | |
|   destroy();   // Non viene mai chiamato!
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////////
 | |
| //  RECORD
 | |
| /////////////////////////////////////////////////////////////
 | |
| class TRecord_DI : public TObject
 | |
| {
 | |
|   TString _buffer;
 | |
| 
 | |
| protected: // TObject
 | |
|   virtual TObject* dup() const { return new TRecord_DI(*this); }
 | |
|   virtual void print_on(ostream& outs) const;
 | |
|   virtual void read_from(istream& ins);
 | |
| 
 | |
| protected: // TObject
 | |
|   const TTracciato_DI& tracciato() const 
 | |
|   { return _trc_DI.tracciato(tipo_record()); }
 | |
|   
 | |
|   const TField_DI& get_field(int pos) const
 | |
|   { return tracciato().field(pos); }
 | |
| 
 | |
|   void set(const TField_DI& fld, const char* val);
 | |
|   int calculate_blocks(const char* val) const;
 | |
| 
 | |
| public:
 | |
|   void set(int pos, const char* val);
 | |
|   void set(int pos, int val);
 | |
|   void set(int pos, long val);
 | |
|   void set(int pos, const real& val);
 | |
|   void set(int pos, const TDate& val);
 | |
|   void set(int pos, char val);
 | |
|   void set(int pos, bool val);
 | |
|   bool add(const char* code, const char* val);
 | |
| 
 | |
|   const char* get(int pos, TString& str) const;
 | |
|   int get_int(int pos) const;
 | |
|   char get_char(int pos) const;
 | |
| 
 | |
|   const TRecord_DI& operator=(const TRecord_DI& rec) 
 | |
|   { _buffer = rec._buffer; return *this; }
 | |
|   
 | |
|   char tipo_record() const { return _buffer[0]; }
 | |
|   void tipo_record(char tipo) 
 | |
|   { _buffer[0] = tipo; tracciato().auto_fill(_buffer); }
 | |
|   const char* readable_buffer() const { return _buffer; }
 | |
|   char* writeable_buffer() { return _buffer.get_buffer(); }
 | |
| 
 | |
|   void azzera_campi_non_posizionali();
 | |
|   bool ha_campi_non_posizionali() const { return strchr("C", tipo_record()) != NULL; }
 | |
|   bool ha_campi_non_posizionali_compilati() const
 | |
|   { return _buffer[90] > ' '; }
 | |
| 
 | |
|   bool valid() const;
 | |
| 
 | |
|   TRecord_DI();
 | |
|   TRecord_DI(char tipo);
 | |
|   TRecord_DI(const TRecord_DI& rec);
 | |
|   TRecord_DI(const TRectype& rec);
 | |
|   virtual ~TRecord_DI();
 | |
| };
 | |
| 
 | |
| void TRecord_DI::print_on(ostream& outs) const
 | |
| {
 | |
|   outs.write((const char*) _buffer, TOTAL_SIZE);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::read_from(istream& ins)
 | |
| {
 | |
|   _buffer.fill(' ', TOTAL_SIZE);
 | |
|   ins.read(_buffer.get_buffer(), TOTAL_SIZE);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(const TField_DI& fld, const char* val)
 | |
| {
 | |
|   TString80 str(val); str.upper();
 | |
|   int lenstr = str.len();
 | |
|   if (lenstr > fld._len)
 | |
|   {
 | |
| #ifdef DBG
 | |
|     NFCHECK("Campo troppo lungo: %s (max. %d)", val, fld._len);
 | |
| #endif
 | |
|     str.cut(lenstr = fld._len);
 | |
|   }
 | |
|   if (lenstr != fld._len)
 | |
|   {
 | |
|     str.trim();
 | |
|     if (fld._type == 'N')
 | |
|       str.right_just(fld._len);
 | |
|     else
 | |
|       str.left_just(fld._len);
 | |
|   }
 | |
|   _buffer.overwrite(str, fld._pos-1);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, const char* val)
 | |
| {
 | |
|   const TField_DI& fld = tracciato().field(pos);
 | |
|   set(fld, val);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, int val)
 | |
| {
 | |
|   const TField_DI& fld = tracciato().field(pos);
 | |
|   CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
 | |
|   TString16 str; str.format("%d", val);
 | |
|   set(fld, str);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, long val)
 | |
| {
 | |
|   const TField_DI& fld = tracciato().field(pos);
 | |
|   CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
 | |
|   TString16 str; str.format("%ld", val);
 | |
|   set(fld, str);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, const real& val)
 | |
| {
 | |
|   const TField_DI& fld = tracciato().field(pos);
 | |
|   CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
 | |
|   const char* str = val.string(fld._len, 0);
 | |
|   set(fld, str);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, const TDate& val)
 | |
| {
 | |
|   const TField_DI& fld = tracciato().field(pos);
 | |
|   CHECKD(fld._type == 'N' && (fld._len == 6 || fld._len == 8), 
 | |
|          "Invalid date field ", pos);
 | |
|   const char* str;
 | |
|   if (fld._len == 8)
 | |
|     str = val.string(full, '\0', full, full, gma_date);
 | |
|   else
 | |
|     str = val.string(brief, '\0', full, full, gma_date);
 | |
|   set(fld, str);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, char val)
 | |
| {
 | |
|   const TField_DI& fld = get_field(pos);
 | |
|   CHECKD(fld._type == 'A' && fld._len == 1, 
 | |
|          "Invalid char field ", pos);
 | |
|   const char str[2] = { val, '\0' };
 | |
|   set(fld, str);
 | |
| }
 | |
| 
 | |
| void TRecord_DI::set(int pos, bool val)
 | |
| {
 | |
|   const TField_DI& fld = get_field(pos);
 | |
|   CHECKD(fld._type == 'N' && fld._len == 1, 
 | |
|          "Invalid boolean field ", pos);
 | |
|   const char str[2] = { val ? '1' : '0', '\0' };
 | |
|   set(fld, str);
 | |
| }
 | |
| 
 | |
| const char* TRecord_DI::get(int pos, TString& str) const
 | |
| {
 | |
|   const TField_DI& fld = get_field(pos);
 | |
|   str = _buffer.mid(fld._pos-1, fld._len);
 | |
|   return str.trim();
 | |
| }
 | |
| 
 | |
| int TRecord_DI::get_int(int pos) const
 | |
| {
 | |
|   TString16 str; get(pos, str);
 | |
|   return atoi(str);
 | |
| }
 | |
| 
 | |
| char TRecord_DI::get_char(int pos) const
 | |
| {
 | |
|   const TField_DI& fld = get_field(pos);
 | |
|   CHECKD(fld._type == 'A', "Invalid char field ", pos);
 | |
|   return _buffer[fld._pos-1];
 | |
| }
 | |
| 
 | |
| // Calcola i blocchi necessari per contenere la stringa val
 | |
| int TRecord_DI::calculate_blocks(const char* val) const
 | |
| {                
 | |
|   // Il primo blocco contiene 16 caratteri, 
 | |
|   // gli altri solo 15 perche' c'e' anche il +
 | |
|   int blocks = 1;
 | |
|   const int len = strlen(val);
 | |
|   if (len > FIELD_SIZE)
 | |
|     blocks += (len-FIELD_SIZE-1) / (FIELD_SIZE-1) + 1;
 | |
|   return blocks;
 | |
| }
 | |
| 
 | |
| // Azzera tutti i campi non posizionali dei record di tipo C
 | |
| void TRecord_DI::azzera_campi_non_posizionali()
 | |
| {
 | |
|   CHECK(ha_campi_non_posizionali(), "Impossibile azzerare un record senza campi non posizionali");
 | |
|   char* buf = _buffer.get_buffer() + HEADER_SIZE;
 | |
|   memset(buf, ' ', USEABLE_SIZE);
 | |
| }
 | |
| 
 | |
| // Aggiunge un campo non posizionale ai record di tipo C
 | |
| bool TRecord_DI::add(const char* code, const char* val)
 | |
| {
 | |
|   CHECK(ha_campi_non_posizionali(), "Impossibile aggiungere campi non posizionali");
 | |
|   CHECKS(code && strlen(code) == CODE_SIZE, "Invalid field code ", code);
 | |
|   CHECKS(val && *val, "Can't add empty field ", code);
 | |
|   
 | |
|   // Cerca il primo posto libero
 | |
|   int pos;
 | |
|   for (pos = HEADER_SIZE; pos < HEADER_SIZE+USEABLE_SIZE; pos += BLOCK_SIZE)
 | |
|   {
 | |
|     if (_buffer[pos] == ' ')
 | |
|       break;
 | |
|   }
 | |
|   const int free_blocks = (USEABLE_SIZE - pos) / BLOCK_SIZE;
 | |
|   const int needed_blocks = calculate_blocks(val);
 | |
|   const bool ok = free_blocks >= needed_blocks;
 | |
| 
 | |
|   if (ok)  // Se ci sono abbastanza blocchi liberi
 | |
|   {
 | |
|     TString80 str(val); str.upper();
 | |
|     const int lenstr = str.len();
 | |
|     for (int i = 0; i < lenstr; )
 | |
|     {
 | |
|       _buffer.overwrite(code, pos);
 | |
|       pos += CODE_SIZE;
 | |
|       if (i != 0)
 | |
|       {
 | |
|         _buffer.overwrite("+", pos);
 | |
|         pos++;
 | |
|       }
 | |
|       const int maxlen = FIELD_SIZE-1 + (i == 0);
 | |
|       const TString& substr = str.mid(i, maxlen);
 | |
|       _buffer.overwrite(substr, pos);
 | |
|       pos += maxlen;
 | |
|       i += maxlen;
 | |
|     }
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TRecord_DI::valid() const
 | |
| {
 | |
|   char tipo = tipo_record();
 | |
|   bool ok = (tipo > ' ') && (strchr("ABCZ", tipo) != NULL);
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TRecord_DI::TRecord_DI() : _buffer(TOTAL_SIZE, ' ')
 | |
| {
 | |
| }
 | |
| 
 | |
| TRecord_DI::TRecord_DI(char tipo) : _buffer(TOTAL_SIZE, ' ')
 | |
| {
 | |
|   tipo_record(tipo);
 | |
| }
 | |
| 
 | |
| TRecord_DI::TRecord_DI(const TRecord_DI& rec) : _buffer(rec._buffer)
 | |
| { }
 | |
| 
 | |
| TRecord_DI::~TRecord_DI()
 | |
| { }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////
 | |
| //  CLASSE PER IL TRASFERIMENTO EFFETTIVO SUL FILE
 | |
| ///////////////////////////////////////////////////////////////
 | |
| class TTrasferimento_DI : public TObject
 | |
| {
 | |
|   TFilename _name;
 | |
| 
 | |
|   FILE* _io_stream;
 | |
|   
 | |
| public:
 | |
|   bool open(const char* path = "", char mode = 'r');
 | |
|   bool close();
 | |
|   bool write(const TRecord_DI& rec);
 | |
|   bool read(TRecord_DI& rec);
 | |
|   bool eof() const { return feof(_io_stream) != 0; }
 | |
| 
 | |
|   TTrasferimento_DI& operator<<(const TRecord_DI& rec)
 | |
|   { write(rec);  return *this; }
 | |
|   TTrasferimento_DI& operator>>(TRecord_DI& rec)
 | |
|   { read(rec); return *this; }
 | |
| 
 | |
|   bool split(const char* dest_path);
 | |
|   void remove();
 | |
| 
 | |
|   TTrasferimento_DI(const char* name = "", char mode = 'r');
 | |
|   virtual ~TTrasferimento_DI();
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| bool TTrasferimento_DI::open(const char* path, char mode)
 | |
| {
 | |
|   CHECK(mode == 'r' || mode == 'w', "Invalid open mode");
 | |
|   close();
 | |
| 
 | |
|   _name = path;
 | |
|   _io_stream = fopen(_name, mode == 'r' ? "rb" : "wb");
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TTrasferimento_DI::close()
 | |
| {
 | |
|   if (_io_stream != NULL)
 | |
|   {
 | |
|     fclose(_io_stream);
 | |
|     _io_stream = NULL;
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool TTrasferimento_DI::write(const TRecord_DI& rec)
 | |
| {
 | |
|   bool ok = _io_stream != NULL;
 | |
|   if (ok)
 | |
|     fwrite(rec.readable_buffer(), 1, TOTAL_SIZE, _io_stream);
 | |
| 
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TTrasferimento_DI::read(TRecord_DI& rec)
 | |
| {
 | |
|   bool ok = _io_stream != NULL && !feof(_io_stream);
 | |
|   if (ok)
 | |
|   {
 | |
|     fread(rec.writeable_buffer(), 1, TOTAL_SIZE, _io_stream);
 | |
|     ok = rec.valid();
 | |
|   }
 | |
| 
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TTrasferimento_DI::split(const char* path)
 | |
| {
 | |
|   close();
 | |
| 
 | |
|   const long records = fsize(_name) / TOTAL_SIZE;
 | |
|   long totale[26]; memset(totale, 0, sizeof(totale));
 | |
|   totale['A' - 'A'] = 1;
 | |
|   totale['B' - 'A'] = 1;
 | |
|   totale['C' - 'A'] = records;
 | |
|   totale['Z' - 'A'] = 1;
 | |
| 
 | |
|   TRecord_DI rec;
 | |
|   long records_per_disk = 0;
 | |
|   int volumes = 1;
 | |
|   const bool magnetic = ::xvt_fsys_is_removable_drive(path) !=0;
 | |
|   if (magnetic)
 | |
|   {
 | |
|     if (!yesno_box("Inserire il primo disco del trasferimento nell'unita' %s\n"
 | |
|                    "Tutti i dischi devono essere vuoti ed avere la stesso formato.\n"
 | |
|                    "Si desidera iniziare il trasferimento?", path))
 | |
|       return false;
 | |
| 
 | |
|     unsigned long disk_size = ::xvt_fsys_get_disk_size(path, 'b');
 | |
|     records_per_disk = long(disk_size / TOTAL_SIZE) - 3;  // Tolgo A,B,Z
 | |
|     volumes = int((records-1)/records_per_disk)+1;
 | |
|   }
 | |
| 
 | |
|   TProgind pi(records, "Trasferimento records", false, true);
 | |
|   
 | |
|   // Read from start
 | |
|   open("", 'r');
 | |
|   
 | |
|   for (int volume = 1; volume <= volumes; volume++)
 | |
|   {
 | |
|     if (magnetic && volume > 1)
 | |
|     {
 | |
|       if (!yesno_box("Inserire il disco %d di %d:\n"
 | |
|                      "Si desidera proseguire il trasferimento?",
 | |
|                      volume, volumes))
 | |
|       {
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   
 | |
|     TTrasferimento_DI outfile(path, 'w');    
 | |
|     long written = 0;
 | |
|   
 | |
|     if (records > 0)
 | |
|     {
 | |
|       while (read(rec))
 | |
|       {
 | |
|         pi.addstatus(1);
 | |
|   
 | |
|         const char tipo_rec = rec.tipo_record();
 | |
|         if (tipo_rec <= 'B' || tipo_rec == 'Z')
 | |
|           continue;
 | |
|   
 | |
|         outfile << rec;
 | |
|         totale[tipo_rec - 'A']++;
 | |
|         written++;
 | |
|   
 | |
|         if (magnetic && written >= records_per_disk)
 | |
|           break;
 | |
|       }
 | |
|     }  
 | |
|   }  
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| // Cancella il file
 | |
| void TTrasferimento_DI::remove()
 | |
| {
 | |
|   close();
 | |
|   ::remove(_name);
 | |
| }
 | |
| 
 | |
| TTrasferimento_DI::TTrasferimento_DI(const char* path, char  mode)
 | |
| //: _in_stream(NULL), _out_stream(NULL)
 | |
| :_io_stream(NULL)
 | |
| {
 | |
|   open(path, mode);
 | |
| }
 | |
| 
 | |
| TTrasferimento_DI::~TTrasferimento_DI()
 | |
| {
 | |
|   close();
 | |
| }
 | |
| 
 | |
| //---------------------------------------------------------------
 | |
| //    APPLICAZIONE
 | |
| //---------------------------------------------------------------
 | |
| class TSend_letint : public TSkeleton_application
 | |
| {
 | |
|   TRectype* _rec_anagrafica;
 | |
| 
 | |
| protected:
 | |
| 	bool create();
 | |
| 
 | |
| public:
 | |
|   void read_dati_dic();
 | |
|   const TString& get_anagr_field(const TString field_name) { return _rec_anagrafica->get(field_name); }
 | |
| 
 | |
|   void fill_a_rec(const TMask& mask, TRecord_DI& rec);
 | |
|   void fill_b_rec(const TMask& mask, const int items, TRecord_DI& rec);
 | |
|   void fill_c_rec(const int modulo, TRecord_DI& rec);
 | |
|   void fill_z_rec(const int items, TRecord_DI& rec);
 | |
|   void fill_non_positional(const int modulo, const int rigo, const TRectype& let_int, TRecord_DI& rec, 
 | |
|                            TTrasferimento_DI& t, int &written_c_records);
 | |
| 
 | |
|   virtual void main_loop();
 | |
| };
 | |
| 
 | |
| void TSend_letint::read_dati_dic()
 | |
| {
 | |
|   TString80 key;  // Stringa multiuso
 | |
| 
 | |
|   key << main_app().get_firm();
 | |
|   const TRectype& rec_nditte = cache().get(LF_NDITTE, key);
 | |
|  
 | |
|   const char tipoa = rec_nditte.get_char(NDT_TIPOA);  //tipo persona fisica/giuridica
 | |
|   const long codan = rec_nditte.get_long(NDT_CODANAGR);
 | |
| 
 | |
|   key.cut(0);
 | |
|   key << tipoa << '|' << rec_nditte.get(NDT_CODANAGR);
 | |
|   const TRectype& rec_anagr = cache().get(LF_ANAG, key);
 | |
|   if (rec_anagr.empty())
 | |
|   {
 | |
|     error_box("Non esiste la persona %s", (const char*)key);
 | |
|   }
 | |
| 
 | |
|   if (_rec_anagrafica != NULL)
 | |
|     delete _rec_anagrafica;
 | |
| 
 | |
|   _rec_anagrafica = new TRectype(rec_anagr);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| void TSend_letint::fill_a_rec(const TMask& mask, TRecord_DI& rec)
 | |
| {
 | |
|   TString80 key;
 | |
| 	key << main_app().get_firm();
 | |
|   const TRectype& rec_nditte = cache().get(LF_NDITTE, key);	//legge la ditta..
 | |
| 
 | |
| 	const char dichp = rec_nditte.get_char(NDT_DICHP);	//se ha un intermediario..
 | |
| 	if (dichp == 'I')
 | |
| 		rec.set(4, 10);
 | |
| 	else
 | |
| 		rec.set(4, 01);
 | |
| 		
 | |
|   rec.set(5, get_anagr_field(ANA_COFI));  //codice fiscale del dichiarante
 | |
| 
 | |
| 	rec.set(7, mask.get_int(F_PROGINV));	//progressivo invio nella fornitura
 | |
| 	rec.set(8, mask.get_int(F_TOTINV)+1);	//totale inviii incrementato dell'attuale
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| void TSend_letint::fill_b_rec(const TMask& mask, const int items, TRecord_DI& rec)
 | |
| {
 | |
|   const bool persona_fisica = get_anagr_field(ANA_TIPOA) == "F";
 | |
| 
 | |
|   rec.set(2, get_anagr_field(ANA_COFI));  //codice fiscale del dichiarante
 | |
| 
 | |
|   if (persona_fisica)  //se persona fisica..
 | |
|   {
 | |
|     rec.set(25, get_anagr_field(ANA_RAGSOC).left(24)); //cognome dichiarante
 | |
|     rec.set(26, get_anagr_field(ANA_RAGSOC).mid(30,20));  //nome
 | |
|   }
 | |
|   else  //..altrimenti..
 | |
|     rec.set(27, get_anagr_field(ANA_RAGSOC)); //ragsoc dichiarante
 | |
| 
 | |
|   rec.set(28, get_anagr_field(ANA_PAIV)); //p.iva dichiarante
 | |
|   // periodo inviato
 | |
|   rec.set(36, mask.get_int(F_ANNO));
 | |
|   rec.set(37, mask.get(F_MESE));
 | |
| 
 | |
|   TToken_string chiave_comuni;
 | |
| 
 | |
|   if (persona_fisica)  //se persona fisica..
 | |
|   {
 | |
|     const TRectype& rec_fis = cache().get(LF_ANAGFIS, get_anagr_field(ANA_CODANAGR));  //record della persona fisica
 | |
|     // dati nascita
 | |
|     chiave_comuni.add(rec_fis.get(ANF_STATONASC));
 | |
|     chiave_comuni.add(rec_fis.get(ANF_COMNASC));
 | |
|     const TRectype& rec_nasc = cache().get(LF_COMUNI, chiave_comuni);
 | |
|     rec.set(38, rec_nasc.get(COM_DENCOM));
 | |
|     rec.set(39, rec_nasc.get(COM_PROVCOM));
 | |
|     rec.set(40, rec_fis.get_date(ANF_DATANASC).string(def, '\0'));
 | |
|     rec.set(41, rec_fis.get(ANF_SESSO));
 | |
|     // dati residenza anagrafica
 | |
|     chiave_comuni.cut(0);
 | |
|     chiave_comuni.add(get_anagr_field(ANA_STATORES));
 | |
|     chiave_comuni.add(get_anagr_field(ANA_COMRES));
 | |
|     const TRectype& rec_res = cache().get(LF_COMUNI, chiave_comuni);
 | |
|     rec.set(45, rec_res.get(COM_DENCOM));
 | |
|     rec.set(46, rec_res.get(COM_PROVCOM));
 | |
|     TString address = get_anagr_field(ANA_INDRES);
 | |
|     address << ", " << get_anagr_field(ANA_CIVRES);
 | |
|     rec.set(47, address);
 | |
|     rec.set(48, get_anagr_field(ANA_CAPRES));  
 | |
|   }
 | |
|   else  //se persona giuridica..
 | |
|   {
 | |
|     // dati residenza
 | |
|     chiave_comuni.add(get_anagr_field(ANA_STATORES));
 | |
|     chiave_comuni.add(get_anagr_field(ANA_COMRES));
 | |
|     const TRectype& rec_res = cache().get(LF_COMUNI, chiave_comuni);
 | |
|     rec.set(69, rec_res.get(COM_DENCOM));
 | |
|     rec.set(70, rec_res.get(COM_PROVCOM));
 | |
|     TString address = get_anagr_field(ANA_INDRES);
 | |
|     address << ", " << get_anagr_field(ANA_CIVRES);
 | |
|     rec.set(71, address);
 | |
|     rec.set(72, get_anagr_field(ANA_CAPRES)); 
 | |
|     //dati residenza fiscale
 | |
|     chiave_comuni.cut(0);
 | |
|     chiave_comuni.add(" ");
 | |
|     chiave_comuni.add(get_anagr_field(ANA_COMRF));
 | |
|     const TRectype& rec_rfi = cache().get(LF_COMUNI, chiave_comuni);
 | |
|     rec.set(74, rec_rfi.get(COM_DENCOM));
 | |
|     rec.set(75, rec_rfi.get(COM_PROVCOM));
 | |
|     address = get_anagr_field(ANA_INDRF);
 | |
|     address << ", " << get_anagr_field(ANA_CIVRF);
 | |
|     rec.set(76, address);
 | |
|     rec.set(77, get_anagr_field(ANA_CAPRF));
 | |
|     // natura giuridica
 | |
|     const TRectype& rec_giu = cache().get(LF_ANAGGIU, get_anagr_field(ANA_CODANAGR));  //record della persona giuridica
 | |
|     rec.set(83, rec_giu.get_int(ANG_NATGIU));
 | |
|   }
 | |
|   //parte con dati del rappresentante
 | |
|   TString80 key;
 | |
| 	key << main_app().get_firm();
 | |
|   const TRectype& rec_nditte = cache().get(LF_NDITTE, key);	//legge la ditta..
 | |
| 
 | |
| 	const char dichp = rec_nditte.get_char(NDT_DICHP);	//se ha un intermediario..
 | |
| 	if (dichp == 'I')
 | |
| 	{
 | |
| 		const long firmat = rec_nditte.get_long(NDT_FIRMAT);	//..ne prende il codice..
 | |
| 		//..e ricava la sua partita iva o codice fiscale
 | |
| 		//..e tutti i suoi dati in anagrafica
 | |
| 		TToken_string chiave_anagr;
 | |
| 		chiave_anagr.add("F");
 | |
| 		chiave_anagr.add(firmat);
 | |
|     const TRectype& rec_anagr = cache().get(LF_ANAG, chiave_anagr);  //record di anagr
 | |
| 		
 | |
| 		if (!rec_anagr.empty())	//se l'intermediario esiste come persona fisica...
 | |
| 		{
 | |
| 			rec.set(98, rec_anagr.get(ANA_COFI));
 | |
| 
 | |
| 			//impegno alla presentazione telematica
 | |
| 			rec.set(198, rec_anagr.get(ANA_COFI));	//questo va nella sezione di impegno alla presentazione telematica
 | |
| 			TString8 intcaf = rec_nditte.get(NDT_INTCAF).left(5);
 | |
| 			rec.set(199, intcaf);	//..e questo pure(e' qui x comodita')
 | |
| 			rec.set(201, 1);
 | |
| 
 | |
| 			const int carica_rapp = rec_nditte.get_int(NDT_CARRAPP);
 | |
| 			if (carica_rapp != 0)	//solo se il rappresentante ha una carica...
 | |
| 			{
 | |
| 				const long rappr = rec_nditte.get_long(NDT_RAPPR);	//..prende codice rappresentante
 | |
| 				chiave_anagr.add(rappr, 1);
 | |
| 				const TRectype& rec_anag_rappr = cache().get(LF_ANAG, chiave_anagr);  //..e ricava tutti i suoi dati
 | |
| 				rec.set(99, rec_anag_rappr.get(ANA_COFI));
 | |
| 				rec.set(101, carica_rapp);
 | |
| 
 | |
| 				const TString& ragsoc_rappr = rec_anag_rappr.get(ANA_RAGSOC);
 | |
| 				rec.set(104, ragsoc_rappr.left(24));
 | |
| 				rec.set(105, ragsoc_rappr.mid(30));
 | |
| 				const TRectype& rec_anag_rappr_fis = cache().get(LF_ANAGFIS, rappr);	//..anche quelli personali
 | |
| 				rec.set(106, rec_anag_rappr_fis.get(ANF_SESSO));
 | |
| 				rec.set(107, rec_anag_rappr_fis.get_date(ANF_DATANASC).string(def, '\0'));
 | |
| 
 | |
| 				chiave_comuni.cut(0);
 | |
| 				chiave_comuni.add(" ");
 | |
| 				chiave_comuni.add(rec_anag_rappr_fis.get(ANF_COMNASC));	//comune,provincia di nascita
 | |
| 				const TRectype& com_nasc_rappr = cache().get(LF_COMUNI, chiave_comuni);
 | |
| 				rec.set(108, com_nasc_rappr.get(COM_DENCOM));
 | |
| 				rec.set(109, com_nasc_rappr.get(COM_PROVCOM));
 | |
| 
 | |
| 				chiave_comuni.add(rec_anag_rappr.get(ANA_COMRES), 1);	//comune,provincia di residenza
 | |
| 				const TRectype& com_res_rappr = cache().get(LF_COMUNI, chiave_comuni);
 | |
| 				rec.set(110, com_res_rappr.get(COM_DENCOM));
 | |
| 				rec.set(111, com_res_rappr.get(COM_PROVCOM));
 | |
| 				rec.set(112, com_res_rappr.get(COM_CAPCOM));
 | |
| 				
 | |
| 				if (!com_res_rappr.get(COM_PROVCOM).empty())
 | |
| 				{
 | |
| 					TString address_rapp = rec_anag_rappr.get(ANA_INDRES);	//indirizzo,civico di residenza
 | |
| 					address_rapp << ", " << rec_anag_rappr.get(ANA_CIVRES);
 | |
| 					rec.set(113, address_rapp);
 | |
| 				}
 | |
| 
 | |
| 				rec.set(114, rec_anag_rappr.get(ANA_TELRF));
 | |
| 			}	//endif carica_rappr!=0
 | |
| 
 | |
| 		}	//endif !rec_anagr.empty()
 | |
| 
 | |
| 	}	//endif dichp==I
 | |
| 	if (dichp == 'C')
 | |
| 		rec.set(200, 1);
 | |
| 
 | |
|   //comunicazione dichiarazioni d'intento
 | |
|   rec.set(197, items);
 | |
| 	rec.set(202, rec_nditte.get_date(NDT_DECCARINT).string(def, '\0'));
 | |
| 
 | |
| }
 | |
| 
 | |
| void TSend_letint::fill_c_rec(const int modulo, TRecord_DI& rec)
 | |
| {
 | |
|   rec.set(2, get_anagr_field(ANA_COFI));  //codice fiscale del dichiarante
 | |
|   rec.set(3, modulo); //modulo del corrente record C
 | |
|   rec.azzera_campi_non_posizionali();
 | |
| 
 | |
| }
 | |
| 
 | |
| void TSend_letint::fill_z_rec(const int written_c_records, TRecord_DI& rec)
 | |
| {
 | |
|   rec.set(4, written_c_records);
 | |
| }
 | |
| 
 | |
| void TSend_letint::fill_non_positional(const int modulo, const int rigo, const TRectype& let_int, TRecord_DI& c_rec, 
 | |
|                                    TTrasferimento_DI& t, int &written_c_records)
 | |
| {
 | |
|   //cache del file CLIFO per riempire alcuni val; prende il cliente dal record corrente di LETINT
 | |
|   const long cod = let_int.get_long(LETINT_CODCLI);
 | |
|   TString16 key; key.format("C|%ld", cod);
 | |
|   const TRectype& rec_cli = cache().get(LF_CLIFO, key);  //record del cliente
 | |
| 
 | |
|   TToken_string chiave_comuni;
 | |
|   chiave_comuni.add(rec_cli.get(CLI_STATOCF));
 | |
|   chiave_comuni.add(rec_cli.get(CLI_COMCF));
 | |
|   const TRectype& rec_com = cache().get(LF_COMUNI, chiave_comuni);
 | |
| 
 | |
|   for (int i = 1; i <= 17; i++)
 | |
|   {
 | |
|     //costruzione dei valori da assegnare ai campi non posizionali (auguri..)
 | |
|     TString80 val;  //stringa generica di lavoro
 | |
|     switch (i)
 | |
|     {
 | |
|     case 1:
 | |
|       val = let_int.get(LETINT_NUMPROT);
 | |
|       break;
 | |
|     case 2:
 | |
|       val = let_int.get(LETINT_VSPROT);
 | |
|       break;
 | |
|     case 3:
 | |
|       val = rec_cli.get(CLI_COFI);
 | |
|       break;
 | |
|     case 4:
 | |
|       val = rec_cli.get(CLI_PAIV);
 | |
|       break;
 | |
|     case 5: 
 | |
|       val = rec_cli.get(CLI_RAGSOC).left(30);
 | |
| 			val.trim();
 | |
|       break;
 | |
|     case 6:
 | |
|       val = rec_cli.get(CLI_RAGSOC).mid(30);
 | |
|       break;
 | |
|     case 7:
 | |
|       {
 | |
|         val = rec_cli.get(CLI_INDCF);
 | |
|         const TString& civico = rec_cli.get(CLI_CIVCF);
 | |
|         if (civico.not_empty())
 | |
|           val << ", " << civico;
 | |
|       }
 | |
|       break;
 | |
|     case 8:
 | |
|       val = rec_com.get(COM_DENCOM);
 | |
|       break;
 | |
|     case 9:
 | |
|       val = rec_com.get(COM_PROVCOM);
 | |
|       break;
 | |
|     case 10:
 | |
| 			val = rec_cli.get(CLI_STATOCF);
 | |
|       break;
 | |
|     case 11:
 | |
| 			if (let_int.get_int(LETINT_TIPOOP) == 1)
 | |
| 				val.format("%16d", 1);
 | |
|       break;
 | |
|     case 12:
 | |
|       if (let_int.get_int(LETINT_TIPOOP) == 1)
 | |
| 				val = let_int.get_real(LETINT_IMPORTO).stringa(16,2);
 | |
|       break;
 | |
|     case 13:
 | |
| 			if (let_int.get_int(LETINT_TIPOOP) == 2)
 | |
| 				val.format("%16d", 1);
 | |
|       break;
 | |
|     case 14:
 | |
|       if (let_int.get_int(LETINT_TIPOOP) == 2)
 | |
| 				val = let_int.get_real(LETINT_IMPORTO).stringa(16,2);
 | |
|       break;
 | |
| 		case 15:
 | |
| 			if (let_int.get_int(LETINT_TIPOOP) == 3)
 | |
| 				val.format("%16d", 1);
 | |
|       break;
 | |
| 		case 16:
 | |
| 			if (let_int.get_int(LETINT_TIPOOP) == 3)
 | |
| 			{
 | |
| 				const TDate dataini = let_int.get_date(LETINT_DAL);
 | |
| 				val.format("%8s%02d%02d%04d", "", dataini.day(), dataini.month(), dataini.year());
 | |
| 			}
 | |
| 			break;
 | |
| 		case 17:
 | |
| 			if (let_int.get_int(LETINT_TIPOOP) == 3)
 | |
| 			{
 | |
| 				const TDate datafin = let_int.get_date(LETINT_AL);
 | |
| 				val.format("%8s%02d%02d%04d", "", datafin.day(), datafin.month(), datafin.year());
 | |
| 			}
 | |
| 			break;
 | |
|     default: break;
 | |
|     }
 | |
|     if (!val.blank())
 | |
|     {
 | |
|       TString8 code; 
 | |
|       code.format("DI%03d%03d", rigo, i); //codice del campo non posizionale
 | |
|       bool ok = c_rec.add(code, val);
 | |
|       if (!ok)
 | |
|       {
 | |
|         t.write(c_rec); //scrive quello che ci sta..
 | |
|         written_c_records++;
 | |
|         fill_c_rec(modulo, c_rec);  //riempie un nuovo C record..
 | |
| 				c_rec.add(code, val);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TSend_letint::create()
 | |
| {
 | |
|   return TSkeleton_application::create();
 | |
| }
 | |
| 
 | |
| void TSend_letint::main_loop()
 | |
| {
 | |
|   _rec_anagrafica = NULL;
 | |
|   TFilename path;
 | |
|   TSend_letint_mask m;
 | |
| 
 | |
|   while (m.run() == K_ENTER)
 | |
|   {
 | |
| 
 | |
|     TFilename output_filename = m.get(F_PATH);
 | |
| 		output_filename.add(m.get(F_FILE));
 | |
|     TTrasferimento_DI t(output_filename, 'w');
 | |
| 
 | |
|     TRectype darec(LF_LETINT), arec(LF_LETINT);
 | |
|     const int anno = m.get_int(F_ANNO);
 | |
|     const int mese = m.get_int(F_MESE);
 | |
|     darec.put(LETINT_ANNO, anno);
 | |
|     arec.put(LETINT_ANNO, anno);
 | |
|   
 | |
|     TRelation rel_letint(LF_LETINT);
 | |
|     _da_data = TDate(1, mese, anno);
 | |
|     _a_data = _da_data,
 | |
|     _a_data.set_end_month();
 | |
| 
 | |
| 		TString filtro;
 | |
| 		filtro = "(STAMPATO==\"X\")&&(INVIATO!=\"X\")";	//si possono inviare solo dichiarazioni stampate in definitivo
 | |
| 
 | |
|     TCursor cur_letint(&rel_letint, filtro, 1, &darec, &arec);
 | |
|     cur_letint.set_filterfunction(filtra_per_date);
 | |
| 
 | |
|     const long items = cur_letint.items();
 | |
|     
 | |
|     if (items > 0)
 | |
|     {
 | |
|       read_dati_dic();  //legge i dati del dichiarante;
 | |
| 
 | |
|       cur_letint.freeze();
 | |
|       TProgind pi(items, "Generazione file di trasferimento", false);
 | |
|       TRectype& rec_letint = rel_letint.curr();
 | |
| 
 | |
| 			bool go_on = true;	//bool per controllare il corretto avanzamento della creazione record
 | |
|       //istanziamento record di tipo A e B (testate) e loro scrittura
 | |
|       TRecord_DI a_rec('A');
 | |
|       fill_a_rec(m, a_rec);
 | |
| 		  if (!t.write(a_rec))
 | |
| 			  go_on = false;
 | |
| 
 | |
| 		  TRecord_DI b_rec('B');
 | |
| 		  fill_b_rec(m, items, b_rec);
 | |
| 		  if (!t.write(b_rec))
 | |
| 				go_on = false;
 | |
| 			
 | |
|       //record di tipo C (righe)
 | |
| 			int written_c_records = 0;
 | |
| 			int modulo = 1;
 | |
| 			int rigo = 1;
 | |
| 			//parte posizionale del primo record di tipo C
 | |
| 			TRecord_DI c_rec('C');
 | |
| 			fill_c_rec(modulo, c_rec);
 | |
| 
 | |
| 			for (cur_letint = 0; cur_letint.pos() < items; ++cur_letint)
 | |
| 			{
 | |
| 				pi.addstatus(1);       
 | |
| 				//parte non posizionale;va compilata sul record C
 | |
| 				fill_non_positional(modulo, rigo, rec_letint, c_rec, t, written_c_records);
 | |
|     
 | |
| 				rigo++; //avanza di un rigo
 | |
| 
 | |
| 				if (rigo > 4) //ogni 4 righi di tipo C..
 | |
| 				{
 | |
| 					t.write(c_rec); //..si scrive sul file..
 | |
| 					written_c_records++;
 | |
| 					rigo = 1;
 | |
| 					modulo++;
 | |
| 					fill_c_rec(modulo, c_rec);  //..ci vuole una nuova parte posizionale..
 | |
| 				}
 | |
| 
 | |
| 				//registra i record inviati
 | |
| 				rec_letint.put(LETINT_INVIATO, 'X'); //riempie il campo
 | |
| 				rel_letint.rewrite(); //aggiorna fisicamente il file       
 | |
| 			}
 | |
| 
 | |
| 			//caso base in cui il numero di righi non è multiplo di 4
 | |
| 			if (c_rec.ha_campi_non_posizionali_compilati())
 | |
| 			{
 | |
| 				t.write(c_rec); //..si scrive sul file..
 | |
| 				written_c_records++;
 | |
| 			}
 | |
| 
 | |
| 
 | |
| 			TRecord_DI z_rec('Z');
 | |
| 			fill_z_rec(written_c_records, z_rec);
 | |
| 			if (!t.write(z_rec))
 | |
| 			  go_on = false;
 | |
| 			
 | |
| 			//incrementa di 1 il numero totale degli invii sulla tabella registri
 | |
| 			if (go_on)
 | |
| 			{
 | |
| 				TTable tabreg("REG");
 | |
| 				TString8 key;
 | |
| 				key << anno << m.get(F_REGISTRO);
 | |
| 				tabreg.put("CODTAB", key);
 | |
| 				if (tabreg.read() == NOERR)
 | |
| 				{
 | |
| 					tabreg.put("I4", m.get_int(F_TOTINV)+1);
 | |
| 					tabreg.rewrite();
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
|     }
 | |
| 		
 | |
| 
 | |
|   }
 | |
|   if (_rec_anagrafica != NULL)
 | |
|     delete _rec_anagrafica;
 | |
| }
 | |
| 
 | |
| int li0600(int argc, char* argv[])
 | |
| {
 | |
|   TSend_letint a;
 | |
|   a.run(argc, argv, TR("Invio dichiarazioni d'intento"));
 | |
|   return 0;
 | |
| }
 |