Files correlati : in0.exe in0700a.msk Ricompilazione Demo : [ ] Commento : Corretta modifica e caricamento rettifiche con anni aventi diverse frequenze di versamento git-svn-id: svn://10.65.10.50/trunk@13736 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			517 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			517 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <currency.h>
 | |
| #include <defmask.h>
 | |
| #include <diction.h>
 | |
| #include <prefix.h>
 | |
| #include <progind.h>
 | |
| #include <recarray.h>
 | |
| #include <relation.h>
 | |
| 
 | |
| #include "inlib01.h"
 | |
| #include "in0500a.h"
 | |
| 
 | |
| #include <mov.h>
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TIntra_frequency
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| char TIntra_frequency::frequenza(int a, char t) const
 | |
| {
 | |
|   switch (t)
 | |
|   {
 | |
|   case 'A': break;
 | |
|   case 'C': break;
 | |
|   case 'B': t = 'A'; break; // Rettifiche su Acquisti
 | |
|   case 'D': t = 'C'; break; // Rettifiche su Cessioni
 | |
|   default : break;
 | |
|   }
 | |
|   
 | |
|   const TDate d(TODAY);
 | |
|   if (a <= 0)
 | |
|     a = d.year(); 
 | |
|   if (a < d.year())
 | |
|   {
 | |
|     TLocalisamfile riep(LF_RIEPRETT);  
 | |
|     riep.put("TIPO", t);
 | |
|     riep.put("ANNO", a);
 | |
|     if (riep.read(_isgteq) == NOERR)
 | |
|     {                     
 | |
|       if (riep.get_char("TIPO") == t && riep.get_int("ANNO") == a)
 | |
|       {
 | |
|         const char freq = riep.get_char("FREQUENZA");
 | |
|         if (freq > ' ')
 | |
|           return freq;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (t == 'A') ? _freq_acq : _freq_ces;
 | |
| }
 | |
| 
 | |
| int TIntra_frequency::date2periodo(const TDate& d, char tipo) const
 | |
| {
 | |
|   const char freq = frequenza(d.year(), tipo);
 | |
|   
 | |
|   if (freq == 'A')
 | |
|     return 1;
 | |
|   const int month = d.month();
 | |
|     
 | |
|   if (freq == 'T')
 | |
|     return (month / 3) + 1;
 | |
|   
 | |
|   return month;
 | |
| }
 | |
| 
 | |
| int TIntra_frequency::compare_periodo(const TDate& dtcomp, const TDate& dtreg, char tipo) const
 | |
| {
 | |
|   int cmp = dtcomp.year() - dtreg.year();
 | |
|   if (cmp == 0)
 | |
|   {
 | |
|     const int pc = date2periodo(dtcomp, tipo);
 | |
|     const int pr = date2periodo(dtreg, tipo);
 | |
|     cmp = pc - pr;
 | |
|   }
 | |
|   return cmp;
 | |
| }
 | |
| 
 | |
| 
 | |
| void TIntra_frequency::update()
 | |
| {
 | |
|   const long firm = prefix().get_codditta();
 | |
|   const TRectype& ditta = cache().get(LF_NDITTE, firm);
 | |
|   _freq_ces = ditta.get_char("FREQCES");
 | |
|   _freq_acq = ditta.get_char("FREQACQ");
 | |
|   if (_freq_ces <= ' ') _freq_ces = 'T';
 | |
|   if (_freq_acq <= ' ') _freq_acq = 'T';
 | |
| }
 | |
| 
 | |
| TIntra_frequency::TIntra_frequency()
 | |
| {
 | |
|   update();
 | |
| }
 | |
| 
 | |
|  ///////////////////////////////////////////////////////////
 | |
| // TIntra_mask
 | |
| // Maschera generica con dati utili a tutte quelle intra
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| void TIntra_mask::on_firm_change()
 | |
| {
 | |
|   if (is_running())
 | |
|     TAutomask::on_firm_change();
 | |
|   _freq.update();
 | |
| }
 | |
| 
 | |
| short TIntra_mask::type_field() const
 | |
| { 
 | |
|   NFCHECK("Non e' stato specificato il campo del tipo");
 | |
|   return DLG_NULL; 
 | |
| }
 | |
| 
 | |
| short TIntra_mask::period_field() const 
 | |
| { return DLG_NULL; }
 | |
| 
 | |
| char TIntra_mask::tipo() const
 | |
| {
 | |
|   short id = type_field();
 | |
|   char t = get(id)[0];
 | |
|   return t;
 | |
| }
 | |
| 
 | |
| char TIntra_mask::frequenza(int a, char t) const
 | |
| {
 | |
|   if (a <= 0) 
 | |
|     a = anno();
 | |
|   if (t < 'A' || t > 'D')
 | |
|     t = tipo(); 
 | |
|   return _freq.frequenza(a, t);
 | |
| }
 | |
| 
 | |
| int TIntra_mask::date2periodo(const TDate& d) const
 | |
| { return _freq.date2periodo(d, tipo()); } 
 | |
| 
 | |
| const char* TIntra_mask::periodo_str() const
 | |
| {
 | |
|   const short id = period_field();
 | |
|   const char* pe = "01";
 | |
|   if (id != DLG_NULL)
 | |
|   {
 | |
|     switch(frequenza(anno()))
 | |
|     {
 | |
|     case 'M': pe = get(id); break;
 | |
|     case 'T': pe = get(id+1); break;
 | |
|     default : break;
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|     NFCHECK("Non e' stato specificato il campo del periodo");
 | |
|   return pe;
 | |
| }
 | |
| 
 | |
| int TIntra_mask::periodo() const
 | |
| {
 | |
|   return atoi(periodo_str());
 | |
| }
 | |
| 
 | |
| bool TIntra_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | |
| {
 | |
|   if (jolly == 0 && o.dlg() == type_field())
 | |
|   {
 | |
|     if (e == fe_modify || e == fe_init)
 | |
|     {
 | |
|       const short id = period_field();
 | |
| 
 | |
|       if (id != DLG_NULL)
 | |
|       {
 | |
|         const char freq = frequenza(anno());
 | |
|         show(id+0, freq == 'M');
 | |
|         show(id+1, freq == 'T');
 | |
|         show(id+2, freq == 'A');
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| TIntra_mask::TIntra_mask(const char* name)
 | |
| : TAutomask(name)
 | |
| {
 | |
|   on_firm_change();
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TDati_riepilogo
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TDati_riepilogo : public TSortable
 | |
| {
 | |
|   TToken_string _key;
 | |
|   TCurrency _ammlire, _ammvaluta;
 | |
|   real _valstat, _massakg, _massaums;
 | |
| 
 | |
| protected:
 | |
|   virtual TObject* dup() const { return new TDati_riepilogo(*this); }
 | |
|   virtual int compare(const TSortable& s) const;
 | |
| 
 | |
| public:
 | |
|   TDati_riepilogo& operator +=(const TDati_riepilogo& r);
 | |
|   void write(TRectype& rec) const;
 | |
| 
 | |
|   const TString& stato(TString& c) const { _key.get(0, c); return c; }
 | |
|   const TString& partita_iva(TString& c) const { _key.get(1, c); return c; }
 | |
|   const TString& natura(TString& c) const { _key.get(3, c); return c; }
 | |
|   const TString& nomenclatura(TString& c) const { _key.get(4, c); return c; }
 | |
|   const TString& consegna(TString& c) const { _key.get(5, c); return c; }
 | |
|   const TString& trasporto(TString& c) const { _key.get(6, c); return c; }
 | |
|   const TString& paese(TString& c) const { _key.get(7, c); return c; }
 | |
|   const TString& paese_orig(TString& c) const { _key.get(8, c); return c; }
 | |
|   const TString& provincia(TString& c) const { _key.get(9, c); return c; }
 | |
| 
 | |
|   TDati_riepilogo(const TDati_riepilogo& r);
 | |
|   TDati_riepilogo(const TToken_string& key, const TRectype& rec, const TString& codval);
 | |
|   virtual ~TDati_riepilogo() { }
 | |
| };
 | |
| 
 | |
| int TDati_riepilogo::compare(const TSortable& s) const
 | |
| {
 | |
|   const TDati_riepilogo& r = (const TDati_riepilogo&)s;
 | |
|   return _key.compare(r._key);
 | |
| }
 | |
| 
 | |
| TDati_riepilogo& TDati_riepilogo::operator +=(const TDati_riepilogo& r)
 | |
| {
 | |
|   _ammlire   += r._ammlire;
 | |
|   _ammvaluta += r._ammvaluta;
 | |
|   _valstat   += r._valstat;
 | |
|   _massakg   += r._massakg;
 | |
|   _massaums  += r._massaums;
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| void TDati_riepilogo::write(TRectype& rec) const
 | |
| {
 | |
|   TString str;
 | |
|   rec.put("STATO",     stato(str));
 | |
|   rec.put("PIVA",      partita_iva(str));
 | |
|   rec.put("NATURA",    natura(str));
 | |
|   rec.put("NOMENCL",   nomenclatura(str));
 | |
|   rec.put("CONSEGNA",  consegna(str));
 | |
|   rec.put("TRASPORTO", trasporto(str));
 | |
|   rec.put("PAESE",     paese(str));
 | |
|   rec.put("PAESEORIG", paese_orig(str));
 | |
|   rec.put("PROV",      provincia(str));
 | |
|   
 | |
|   rec.put("AMMLIRE", _ammlire.get_num());
 | |
|   if (_ammvaluta.is_zero())
 | |
|   {
 | |
|     rec.zero("CODVAL");     // Altrimenti genera falsi codici valuta EUR ...
 | |
|     rec.zero("AMMVALUTA");  // ... con importi nulli
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     rec.put("CODVAL", _ammvaluta.get_value());
 | |
|     rec.put("AMMVALUTA", _ammvaluta.get_num());
 | |
|   }
 | |
|   rec.put("VALSTAT",   _valstat);
 | |
|   rec.put("MASSAKG",   _massakg);
 | |
|   rec.put("MASSAUMS",  _massaums);
 | |
| }
 | |
| 
 | |
| TDati_riepilogo::TDati_riepilogo(const TDati_riepilogo& r)
 | |
| : _key(r._key), _valstat(r._valstat), 
 | |
|   _ammlire(r._ammlire), _ammvaluta(r._ammvaluta),
 | |
|   _massakg(r._massakg), _massaums(r._massaums)
 | |
| { }
 | |
| 
 | |
| TDati_riepilogo::TDati_riepilogo(const TToken_string& key, 
 | |
|                                  const TRectype& rec, 
 | |
|                                  const TString& codval)
 | |
| : _key(key), _ammlire(rec.get_real("AMMLIRE")),
 | |
|   _ammvaluta(rec.get_real("AMMVALUTA"), codval),
 | |
|   _valstat(rec.get_real("VALSTAT")),
 | |
|   _massakg(rec.get_real("MASSAKG")),
 | |
|   _massaums(rec.get_real("MASSAUMS"))
 | |
| { }
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TRiepiloghi
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TRiepiloghi : public TObject
 | |
| {
 | |
|   TPointer_array _arr;
 | |
|   TAssoc_array _ass;
 | |
| 
 | |
| public:
 | |
|   void add(const TRectype& rec, const TRectype& mov);
 | |
| 
 | |
|   int items() const { return _arr.items(); }
 | |
|   int sort() { _arr.sort(); return items(); }
 | |
|   
 | |
|   const TDati_riepilogo& operator[](int r) const 
 | |
|   { return (const TDati_riepilogo&)_arr[r]; }
 | |
| };
 | |
| 
 | |
| void TRiepiloghi::add(const TRectype& rec, const TRectype& mov)
 | |
| {
 | |
|   TString16 cod;
 | |
|   const char tipocf = mov.get_char("TIPOCF");
 | |
|   cod << tipocf << '|' << mov.get("CODCF");
 | |
|   const TRectype& clifo = cache().get(LF_CLIFO, cod);
 | |
| 
 | |
|   cod = mov.get("CODVAL");
 | |
|   
 | |
|   TToken_string key;
 | |
|   key.add(clifo.get("STATOPAIV"));
 | |
|   key.add(clifo.get("PAIV"));
 | |
|   key.add(cod); // Non e' chiaro se raggruppare per valuta!
 | |
|   key.add(rec.get("NATURA"));
 | |
|   key.add(rec.get("NOMENCL"));
 | |
|   key.add(rec.get("CONSEGNA"));
 | |
|   key.add(rec.get("TRASPORTO"));
 | |
|   key.add(rec.get("PAESE"));
 | |
|   key.add(rec.get("PAESEORIG")); // Campo solo per Acquisti
 | |
|   key.add(rec.get("PROV"));
 | |
| 
 | |
|   TDati_riepilogo* data = (TDati_riepilogo*)_ass.objptr(key);
 | |
|   if (data == NULL)
 | |
|   {
 | |
|     data = new TDati_riepilogo(key, rec, cod);
 | |
|     _ass.add(key, data);
 | |
|     _arr.add(data);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     const TDati_riepilogo dr(key, rec, cod);
 | |
|     *data += dr;
 | |
|   }
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TGenerazione_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TGenerazione_mask : public TIntra_mask
 | |
| {
 | |
|   TRiepiloghi _riep;
 | |
| 
 | |
| protected:
 | |
|   virtual short type_field() const { return R_TIPO; }
 | |
|   virtual short period_field() const { return R_PERIODO_M; }
 | |
|   virtual int anno() const { return get_int(R_ANNO); }
 | |
|  
 | |
| public:
 | |
|   bool genera_riepiloghi();
 | |
| 
 | |
|   TGenerazione_mask();
 | |
|   virtual ~TGenerazione_mask() { }
 | |
| };
 | |
| 
 | |
| bool TGenerazione_mask::genera_riepiloghi()
 | |
| {
 | |
|   const char tipo = get(R_TIPO)[0]; 
 | |
|   const int anno_r = anno();
 | |
|   const int peri = periodo();
 | |
|   int da_mese, a_mese;
 | |
|   const char freq = frequenza(anno_r, tipo);
 | |
|   
 | |
|   if (is_riepilogo(tipo, anno_r, peri) && 
 | |
|       !yesno_box(TR("Attenzione esiste gia' il riepilogo\nper il periodo indicato, si desidera continuare")))
 | |
|     return false;
 | |
| 
 | |
|   switch (freq)
 | |
|   {
 | |
|   case 'T': 
 | |
|     da_mese = (peri-1) * 3 + 1;
 | |
|     a_mese = da_mese+2;
 | |
|     break;
 | |
|   case 'A': 
 | |
|     da_mese = 1; a_mese = 12;
 | |
|     break;
 | |
|   default: 
 | |
|     da_mese = a_mese = peri;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   // Range delle date di competenza (o registrazione) intra
 | |
|   const TDate da_data(1, da_mese, anno_r);
 | |
|   const TDate a_data(TDate::last_day(a_mese, anno_r), a_mese, anno_r);
 | |
| 
 | |
|   // Range delle date di registrazione intra
 | |
|   const TDate filtro_da_data(1, 1, anno_r-1);
 | |
|   const TDate filtro_a_data(31,12, anno_r+1);
 | |
| 
 | |
|   TRectype filter_da(LF_INTRA), filter_a(LF_INTRA);
 | |
|   filter_da.put("DATAREG", filtro_da_data);
 | |
|   filter_a.put("DATAREG", filtro_a_data);
 | |
| 
 | |
|   TRelation rel(LF_INTRA);
 | |
|   rel.add(LF_RINTRA, "NUMREG==NUMREG");
 | |
|   rel.add(LF_MOV, "NUMREG==NUMREG");
 | |
| 
 | |
|   const TRectype& head = rel.curr(LF_INTRA);
 | |
|   const TRectype& row = rel.curr(LF_RINTRA);
 | |
|   const TRectype& mov = rel.curr(LF_MOV);
 | |
| 
 | |
|   TString filter; filter << "TIPOMOV==\"" << tipo << '"';
 | |
|   TCursor cur(&rel, filter, 2, &filter_da, &filter_a);  // Cursore ordinato per data
 | |
|   const long items = cur.items();
 | |
|   if (items > 0)
 | |
|   {
 | |
|     TProgind pi(items, TR("Lettura movimenti intra..."), TRUE, TRUE);
 | |
|     cur.freeze();
 | |
|     for (cur = 0; cur.pos() < items; ++cur)
 | |
|     {
 | |
|       pi.addstatus(1);
 | |
|       if (pi.iscancelled())
 | |
|         return warning_box(TR("Operazione annullata"));
 | |
| 
 | |
|       TDate datacomp = mov.get(MOV_DATACOMPI);
 | |
|       if (!datacomp.ok())
 | |
|         datacomp = head.get_date(MOV_DATAREG);
 | |
|       if (datacomp >= da_data && datacomp <= a_data)
 | |
|       {
 | |
|         bool rowok = rel.is_first_match(LF_RINTRA);
 | |
|         while (rowok)
 | |
|         {
 | |
|           _riep.add(row, head);
 | |
|           rowok = rel.next_match(LF_RINTRA);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|     return warning_box(TR("Non ci sono movimenti nel periodo specificato")); 
 | |
| 
 | |
|   const int riepiloghi = _riep.sort();
 | |
|   if (riepiloghi > 0)
 | |
|   {
 | |
|     TProgind pi(riepiloghi, TR("Scrittura riepiloghi intra..."), false, TRUE);
 | |
|     TLocalisamfile riep(LF_RIEPRETT);
 | |
|     riep.put("TIPO",    tipo);
 | |
|     riep.put("ANNO",    anno_r);
 | |
|     riep.put("PERIODO", peri);
 | |
|     riep.put("NUMRIG",  1);
 | |
|     int err = riep.read();
 | |
|     for (int r = 0; r < riepiloghi; r++)
 | |
|     {
 | |
|       pi.addstatus(1);
 | |
|       riep.put("TIPO",    tipo);
 | |
|       riep.put("ANNO",    anno_r);
 | |
|       riep.put("PERIODO", peri);
 | |
|       riep.put("NUMRIG",  r+1);
 | |
|       _riep[r].write(riep.curr());
 | |
|       riep.put("FREQUENZA", freq);
 | |
|       
 | |
|       const int werr = err == NOERR ? riep.rewrite() : riep.write();
 | |
|       if (werr != NOERR)
 | |
|         return error_box(FR("Errore %d durante la scrittura dei riepiloghi"), werr);
 | |
|       
 | |
|       if (err == NOERR)
 | |
|       {
 | |
|         err = riep.next();
 | |
|         if (err == NOERR && riep.get_long("NUMRIG") == 1)
 | |
|           err = _iseof;
 | |
|       }
 | |
|     }
 | |
|     while (err == NOERR)
 | |
|     {
 | |
|       riep.remove();
 | |
|       err = riep.next();
 | |
|       if (err == NOERR && riep.get_long("NUMRIG") == 1)
 | |
|         err = _iseof;
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| TGenerazione_mask::TGenerazione_mask()
 | |
|                  : TIntra_mask("in0500b")
 | |
| { }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Generazione riepiloghi
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| void genera_riepiloghi(char tipo, int anno, int periodo)
 | |
| {
 | |
|   TGenerazione_mask m;
 | |
| 
 | |
|   int num_fields = 0;
 | |
|   if (tipo > ' ' )
 | |
|   {      
 | |
|     TString16 t; t << tipo;
 | |
|     m.set(R_TIPO, t);
 | |
|     num_fields++;
 | |
|   }
 | |
|   if (anno > 0)
 | |
|   {
 | |
|     m.set(R_ANNO, anno);
 | |
|     num_fields++;
 | |
|   }
 | |
|   if (periodo > 0)
 | |
|   {
 | |
|     m.set(R_PERIODO_M, periodo);
 | |
|     m.set(R_PERIODO_T, periodo);
 | |
|     num_fields++;
 | |
|   }
 | |
| 
 | |
|   if (num_fields == 3 || m.run() == K_ENTER)
 | |
|     m.genera_riepiloghi();
 | |
| }
 | |
| 
 | |
| bool is_riepilogo(char tipo, int anno, int periodo)
 | |
| {
 | |
|   TLocalisamfile riep(LF_RIEPRETT);
 | |
|   
 | |
|   riep.put("TIPO",    tipo);
 | |
|   riep.put("ANNO",    anno);
 | |
|   riep.put("PERIODO", periodo);
 | |
|   riep.put("NUMRIG",  1);
 | |
|   int err = riep.read();
 | |
|   return err == NOERR;                 
 | |
| }
 | |
| 
 |