Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.2 patch 1092 git-svn-id: svn://10.65.10.50/trunk@16297 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			496 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			496 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <applicat.h>
 | ||
| #include <automask.h>
 | ||
| #include <progind.h>
 | ||
| #include <sheet.h>
 | ||
| #include <tabutil.h>
 | ||
| #include <urldefid.h>
 | ||
| 
 | ||
| #include "cg2200.h"
 | ||
| #include "cg2101.h"
 | ||
| #include "cglib01.h"
 | ||
| #include "cglib02.h"
 | ||
| 
 | ||
| #include <causali.h>
 | ||
| 
 | ||
| class TProvvisori_msk : public TAutomask
 | ||
| { 
 | ||
|   char _provv;                      // Tipo provvisori da cancellare
 | ||
|   TString16 _from_date, _to_date;   // Range date da considerare
 | ||
|   TString16 _from_caus, _to_caus;   // Causali movimenti da considerare
 | ||
|   long _from_numreg, _to_numreg;    // Range movimenti da considerare
 | ||
| 
 | ||
|   TCursor_sheet* _sheet;
 | ||
|   TRelation* _rel;
 | ||
|   TCursor* _cur;
 | ||
|   
 | ||
|   bool _update_cursor;
 | ||
|   
 | ||
|   static TProvvisori_msk* _msk;
 | ||
| 
 | ||
| protected:
 | ||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
| 
 | ||
|   static bool filter(const TRelation* rel);
 | ||
|   void update_search(short id, const TString& fil);
 | ||
|   
 | ||
| public:
 | ||
|   TCursor& update_cursor(bool use_argv = FALSE);
 | ||
|   TCursor_sheet* get_selection_sheet();
 | ||
|   TCursor& get_cursor() { return _cur ? *_cur : update_cursor(); }
 | ||
|   void notify_update_needed() { _update_cursor = TRUE; }
 | ||
|   
 | ||
|   TProvvisori_msk();
 | ||
|   ~TProvvisori_msk();
 | ||
| };
 | ||
| 
 | ||
| TProvvisori_msk* TProvvisori_msk::_msk = NULL;
 | ||
| 
 | ||
| bool TProvvisori_msk::filter(const TRelation* rel)
 | ||
| {                     
 | ||
|   TProvvisori_msk& a = *_msk;
 | ||
|   const TRectype& mov = rel->curr();
 | ||
| 
 | ||
|   const char provv = mov.get_char(MOV_PROVVIS);
 | ||
|   bool ok = (a._provv <= ' ' && provv > ' ') || (a._provv > ' ' && a._provv == provv);
 | ||
|   
 | ||
|   if (ok)
 | ||
|   {
 | ||
|     const char* caus = mov.get(MOV_CODCAUS);
 | ||
|     ok = a._from_caus <= caus && (a._to_caus.empty() || a._to_caus >= caus);
 | ||
|   }
 | ||
|   
 | ||
|   if (ok)
 | ||
|   {
 | ||
|     const long numreg = mov.get_long(MOV_NUMREG);
 | ||
|     ok = numreg >= a._from_numreg && (a._to_numreg == 0 || numreg <= a._to_numreg);
 | ||
|   }
 | ||
|   
 | ||
|   return ok;
 | ||
| }   
 | ||
| 
 | ||
| // Filtra il cursore in base ai campi della maschera o i parametri da linea di comando
 | ||
| TCursor& TProvvisori_msk::update_cursor(bool use_argv)
 | ||
| {
 | ||
|   _provv = ' ';
 | ||
|   _from_date = _to_date = "";
 | ||
|   _from_caus = _to_caus = "";
 | ||
|   _from_numreg = _to_numreg = 0;
 | ||
|   
 | ||
|   if (!use_argv)
 | ||
|   {
 | ||
|     _provv       = get(F_PROVV)[0];
 | ||
|     _from_date   = get(F_FROMDATE);
 | ||
|     _to_date     = get(F_TODATE);
 | ||
|     _from_caus   = get(F_FROMCAUS);
 | ||
|     _to_caus     = get(F_TOCAUS);
 | ||
|     _from_numreg = get_long(F_FROMREG);
 | ||
|     _to_numreg   = get_long(F_TOREG);
 | ||
|   }  
 | ||
|   else
 | ||
|   {
 | ||
|     if (main_app().argc() > 2)
 | ||
|       _provv = main_app().argv(2)[0];
 | ||
|   }
 | ||
|   
 | ||
|   if (_rel == NULL)
 | ||
|     _rel = new TRelation(LF_MOV);
 | ||
|   if (_cur == NULL)
 | ||
|     _cur = new TCursor(_rel, "", 2);
 | ||
|     
 | ||
|   TRectype from_rec(LF_MOV), to_rec(LF_MOV);
 | ||
|   if (_from_date.not_empty())
 | ||
|     from_rec.put(MOV_DATAREG, _from_date);
 | ||
|   if (_to_date.not_empty())
 | ||
|     to_rec.put(MOV_DATAREG, _to_date);
 | ||
|   
 | ||
|   _cur->freeze(FALSE);
 | ||
|   _cur->set_filterfunction(filter);
 | ||
|   _cur->setregion(from_rec, to_rec);
 | ||
|   _cur->items();
 | ||
|   _cur->freeze(TRUE);
 | ||
| 
 | ||
|   _update_cursor = FALSE;
 | ||
| 
 | ||
|   if (_sheet)
 | ||
|     _sheet->uncheck(-1);   // Annulla la selezione corrente
 | ||
|   return *_cur;
 | ||
| } 
 | ||
| 
 | ||
| // Ritorma lo sheet con i movimenti selezionati
 | ||
| // Se non si seleziona nulla equivale ad aver selezionato tutto e torna NULL
 | ||
| // come quando non si fa nessuna selezione
 | ||
| // Aggiorna anche il campo F_SELECTED
 | ||
| TCursor_sheet* TProvvisori_msk::get_selection_sheet()
 | ||
| {  
 | ||
|   if (_sheet && _update_cursor)
 | ||
|     update_cursor();                         // Update cursor and uncheck all selection
 | ||
|   
 | ||
|   const long total = get_cursor().items();   // Numero totale di movimenti provvisori
 | ||
|   long sel_items = total;                    // Per default li considero tutti selezionati
 | ||
|   if (_sheet)                                // Controllo se c'e' selezione parziale
 | ||
|     sel_items = _sheet->checked();           
 | ||
|   if (sel_items == 0L || sel_items > total)  // Nessuna selezione = tutti selezionati
 | ||
|     sel_items = total;
 | ||
|   set(F_SELECTED, sel_items);                // Aggiorno campo a video
 | ||
|   
 | ||
|   return sel_items < total ? _sheet : NULL; // Ritorno NULL se tutti selezionati
 | ||
| }
 | ||
| 
 | ||
| void TProvvisori_msk::update_search(short id, const TString& fil)
 | ||
| { 
 | ||
|   TBrowse* b = efield(id).browse();
 | ||
|   b->set_filter(fil);
 | ||
|   b->cursor()->update();
 | ||
| }
 | ||
| 
 | ||
| bool TProvvisori_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   switch (o.dlg())
 | ||
|   { 
 | ||
|   case F_PROVV:            
 | ||
|     if (e == fe_init || e == fe_modify)
 | ||
|     {
 | ||
|       TString16 fil = "PROVVIS";
 | ||
|       switch (o.get()[0])
 | ||
|       {
 | ||
|       case 'C': fil << "=\"C\""; break;
 | ||
|       case 'P': fil << "=\"P\""; break;
 | ||
|       default : fil << "!=\"\""; break;
 | ||
|       }
 | ||
|       update_search(F_FROMDATE, fil);
 | ||
|       update_search(F_TODATE, fil);
 | ||
|       update_search(F_FROMREG, fil);
 | ||
|       update_search(F_TOREG, fil);
 | ||
|       notify_update_needed();
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_FROMDATE:   
 | ||
|   case F_TODATE:   
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       notify_update_needed();
 | ||
|     } else
 | ||
|     if (e == fe_close) 
 | ||
|     {
 | ||
|       // Non <20> carino lasciare vuote le date se non si seleziona nulla esplicitamente
 | ||
|       if (get(F_TODATE).empty() && get(F_FROMDATE).empty() && get_long(F_SELECTED) == 0L)
 | ||
|         return error_box(TR("E' necessario specificare almeno una data"));
 | ||
|     }
 | ||
|     break;
 | ||
|   case DLG_SELECT:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       if (_sheet == NULL)     // Devo creare sheet di delezione
 | ||
|       {
 | ||
|         TBrowse* br = efield(F_FROMREG).browse(); // Copia intestazione dal campo della maschera!
 | ||
|         TToken_string head = br->head(); head.insert("@1|"); // Aggiunge prima colonna di selezione
 | ||
|         TToken_string flds = br->items(); flds.insert(" |"); // Aggiunge prima colonna vuota
 | ||
|         _sheet = new TCursor_sheet(&get_cursor(), flds, TR("Selezione"), head, 0, 1);
 | ||
|       }
 | ||
|       if (_update_cursor)     // Aggiorna filtri cursore se necessario
 | ||
|         update_cursor();      
 | ||
|       _sheet->run();          // Mostra sheet di selezione
 | ||
|       get_selection_sheet();  // Aggiorna F_SELECTED
 | ||
|       return FALSE;
 | ||
|     }
 | ||
|     break;
 | ||
|   default:
 | ||
|     if (e == fe_modify)       // Se viene modificato un campo qualsiasi ... 
 | ||
|       notify_update_needed(); // ... ricorda che devi aggiornare il cursore la prossima volta
 | ||
|     break;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| TProvvisori_msk::TProvvisori_msk() 
 | ||
|                : TAutomask("cg2200a"), _sheet(NULL), _rel(NULL), _cur(NULL), _update_cursor(TRUE)
 | ||
| { 
 | ||
|   _msk = this;
 | ||
| }
 | ||
| 
 | ||
| TProvvisori_msk::~TProvvisori_msk() 
 | ||
| {     
 | ||
|   _msk = NULL;
 | ||
|   if (_sheet != NULL)
 | ||
|     delete _sheet;
 | ||
|   if (_cur)  
 | ||
|     delete _cur;
 | ||
|   if (_rel)  
 | ||
|     delete _rel;
 | ||
| }
 | ||
| 
 | ||
| class TProvvisori_app : public TSkeleton_application
 | ||
| {    
 | ||
|   TSaldo_agg _saldi;
 | ||
| 
 | ||
| protected:                   // TApplication
 | ||
|   virtual bool create();
 | ||
|   virtual bool destroy();
 | ||
|   virtual void main_loop();  
 | ||
|   
 | ||
| protected:
 | ||
|   TCursor& create_cursor(TMask* m);
 | ||
| 
 | ||
| public:
 | ||
|   void inizia_saldi(const TRectype& mov);
 | ||
|   void aggiungi_saldi(const TRectype& rmov, bool lettura);
 | ||
|   void aggiorna_saldi();
 | ||
| 
 | ||
|   bool confirm_provv(TCursor& cur, TProgind& pi, TCursor_sheet* sheet= NULL);
 | ||
|   bool delete_provv(TCursor& cur, TProgind& pi, TCursor_sheet* sheet= NULL);
 | ||
| 
 | ||
|   void auto_delete(TCursor& cur);
 | ||
| 
 | ||
|   TProvvisori_app() {};  
 | ||
|   virtual ~TProvvisori_app() {}  
 | ||
| };
 | ||
| 
 | ||
| inline TProvvisori_app& app() 
 | ||
| { return (TProvvisori_app&)main_app(); }
 | ||
| 
 | ||
| 
 | ||
| bool TProvvisori_app::create()
 | ||
| {
 | ||
|   open_files(LF_TAB, LF_MOV, LF_CAUSALI, LF_SALDI, NULL);
 | ||
|   return TSkeleton_application::create();      
 | ||
| }
 | ||
| 
 | ||
| bool TProvvisori_app::destroy()
 | ||
| {
 | ||
|   return TSkeleton_application::destroy();
 | ||
| }
 | ||
| 
 | ||
| void TProvvisori_app::inizia_saldi(const TRectype& r)
 | ||
| {
 | ||
|   CHECK(r.num() == LF_MOV, "Voglio un movimento");
 | ||
|   
 | ||
|   _saldi.reset();
 | ||
|   
 | ||
|   tiposal tsal = normale;
 | ||
|   const TString4 c = r.get(MOV_CODCAUS);
 | ||
|   if (c.not_empty())
 | ||
|   {
 | ||
|     const TRectype& cau = cache().get(LF_CAUSALI, c);
 | ||
|     if (!cau.empty())  
 | ||
|     {                           
 | ||
|       const char movap = cau.get_char(CAU_MOVAP);
 | ||
|       if (movap == 'A') tsal = apertura; else
 | ||
|       if (movap == 'C') tsal = chiusura;
 | ||
|     }
 | ||
|   }    
 | ||
|   _saldi.set_tipo_saldo(tsal);                      
 | ||
| 
 | ||
|   _saldi.set_anno_es(r.get_int(MOV_ANNOES));
 | ||
|   _saldi.set_num_ulmov(r.get_long(MOV_NUMREG));
 | ||
|   _saldi.set_data_ulmov(r.get_date(MOV_DATAREG));
 | ||
| }  
 | ||
| 
 | ||
| void TProvvisori_app::aggiungi_saldi(const TRectype& r, bool lettura)
 | ||
| {
 | ||
|   CHECK(r.num() == LF_RMOV, "Voglio la riga di un movimento");
 | ||
|   
 | ||
|   TBill conto; conto.get(r);
 | ||
|   TImporto importo(r.get_char(RMV_SEZIONE), r.get_real(RMV_IMPORTO));
 | ||
|   
 | ||
|   _saldi.set_movprovv(lettura);               // In lettura sono tutti provvisori
 | ||
|   _saldi.aggiorna(conto, importo, !lettura);  // In lettura devo sottrarre l'importo
 | ||
| }
 | ||
| 
 | ||
| void TProvvisori_app::aggiorna_saldi()
 | ||
| {                       
 | ||
|   _saldi.registra();
 | ||
| }
 | ||
| 
 | ||
| bool TProvvisori_app::confirm_provv(TCursor& cur, TProgind& pi, TCursor_sheet* sheet)
 | ||
| {
 | ||
|   TLocalisamfile& mov = cur.file(LF_MOV);
 | ||
|   TLocalisamfile rmov(LF_RMOV);
 | ||
|   
 | ||
|   if (sheet && sheet->checked() == 0)
 | ||
|     sheet = NULL;
 | ||
| 
 | ||
|   for (cur = 0; cur.pos() < cur.items(); ++cur)
 | ||
|   {                    
 | ||
|     if (sheet && !sheet->checked(cur.pos()))
 | ||
|       continue;
 | ||
| 
 | ||
|     const long numreg = mov.get_long(MOV_NUMREG);
 | ||
|     inizia_saldi(mov.curr());
 | ||
|     
 | ||
|     int err = cur.lock();
 | ||
|     for (int rig = 1; err == NOERR; rig++)
 | ||
|     {
 | ||
|       rmov.put(RMV_NUMREG, numreg);
 | ||
|       rmov.put(RMV_NUMRIG, rig);
 | ||
|       if (rmov.read(_isequal, _lock) != NOERR) break;
 | ||
|       aggiungi_saldi(rmov.curr(), TRUE);
 | ||
|       aggiungi_saldi(rmov.curr(), FALSE);
 | ||
|     }  
 | ||
|     
 | ||
|     if (err == NOERR)
 | ||
|     {
 | ||
|       mov.zero(MOV_PROVVIS);
 | ||
|       err = mov.rewrite();
 | ||
|       if (err == NOERR)
 | ||
|       {
 | ||
|         aggiorna_saldi();
 | ||
|         pi.addstatus(1);
 | ||
|       }  
 | ||
|     }
 | ||
|     
 | ||
|     if (err != NOERR)
 | ||
|       return error_box(FR("Errore nella conferma del movimento %ld"), numreg);
 | ||
|   }  
 | ||
|   
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TProvvisori_app::delete_provv(TCursor& cur, TProgind& pi, TCursor_sheet* sheet)
 | ||
| {
 | ||
|   TLocalisamfile& mov = cur.file(LF_MOV);
 | ||
|   TLocalisamfile rmov(LF_RMOV);
 | ||
|   TLocalisamfile rmoviva(LF_RMOVIVA); 
 | ||
|   
 | ||
|   if (sheet && sheet->checked() == 0)
 | ||
|     sheet = NULL;
 | ||
| 
 | ||
|   TString error(256);
 | ||
| 
 | ||
|   for (cur = 0; cur.pos() < cur.items(); ++cur)
 | ||
|   {                  
 | ||
|     if (sheet && !sheet->checked(cur.pos()))
 | ||
|       continue;
 | ||
|   
 | ||
|     const long numreg = mov.get_long(MOV_NUMREG);
 | ||
|     
 | ||
|     mov.setkey(1);         // Isam bug on remove with key != 1
 | ||
|     mov.put(MOV_NUMREG, numreg);
 | ||
|     int err = mov.read(_isequal, _lock);
 | ||
|     if (err != NOERR)
 | ||
|       return error_box(FR("Errore %d nel bloccare il record %ld"), err, numreg);
 | ||
|     
 | ||
|     inizia_saldi(mov.curr());
 | ||
|     
 | ||
|     int rig;
 | ||
|     for (rig = 1; err == NOERR; rig++)
 | ||
|     {
 | ||
|       rmov.put(RMV_NUMREG, numreg);
 | ||
|       rmov.put(RMV_NUMRIG, rig);
 | ||
|       if (rmov.read(_isequal, _lock) != NOERR) break;
 | ||
|       
 | ||
|       aggiungi_saldi(rmov.curr(), TRUE);
 | ||
|       err = rmov.remove();
 | ||
|       if (err != NOERR)
 | ||
|         error.format(FR("riga contabile %d"), rig);
 | ||
|     }  
 | ||
|     for (rig = 1; err == NOERR; rig++)
 | ||
|     {
 | ||
|       rmoviva.put(RMI_NUMREG, numreg);
 | ||
|       rmoviva.put(RMI_NUMRIG, rig);
 | ||
|       if (rmoviva.read(_isequal, _lock) != NOERR) break;
 | ||
|       err = rmov.remove();
 | ||
|       if (err != NOERR)
 | ||
|         error.format(FR("riga IVA %d"), rig);
 | ||
|     }  
 | ||
|     
 | ||
|     if (err == NOERR)
 | ||
|     {            
 | ||
|       err = mov.remove(); 
 | ||
|       if (err != NOERR)
 | ||
|         error = TR("testata");
 | ||
|     }  
 | ||
| 
 | ||
|     if (err == NOERR)
 | ||
|     {
 | ||
|       aggiorna_saldi();
 | ||
|       pi.addstatus(1);
 | ||
|       if (pi.iscancelled())
 | ||
|         return warning_box(TR("Procedura interrotta dall'utente"));
 | ||
|     }  
 | ||
|     else
 | ||
|       return error_box(FR("Errore %d nella cancellazione della %s del movimento %ld"), 
 | ||
|                        err, (const char*)error, numreg);
 | ||
|   }
 | ||
|   
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| void TProvvisori_app::auto_delete(TCursor& cur)
 | ||
| {
 | ||
|   const long total = cur.items();
 | ||
|   TProgind pi(total, TR("Cancellazione movimenti provvisori"), TRUE, TRUE);
 | ||
|   delete_provv(cur, pi);
 | ||
| }
 | ||
| 
 | ||
| void TProvvisori_app::main_loop()
 | ||
| {
 | ||
|   TProvvisori_msk m;
 | ||
| 
 | ||
|   if (argc() > 2)
 | ||
|   {                  
 | ||
|     TCursor& cur = m.update_cursor(TRUE);
 | ||
|     auto_delete(cur);
 | ||
|     return;
 | ||
|   }
 | ||
| 
 | ||
|   m.reset();
 | ||
|   while (TRUE) 
 | ||
|   {             
 | ||
|     KEY key = m.run();
 | ||
|     if (key != K_ENTER && key != K_DEL)
 | ||
|       break;
 | ||
|     
 | ||
|     TString16 from_d = m.get(F_FROMDATE);    
 | ||
|     if (key == K_ENTER)
 | ||
|     {            
 | ||
|       const TDate da(from_d);
 | ||
|       const TLibro_giornale lg(da.year());
 | ||
|       const TDate lp(lg.last_print());
 | ||
|       if (da < lp)
 | ||
|       {         
 | ||
|         from_d = lp.string();
 | ||
|         error_box(FR("Il libro giornale e stato stampato il %s:\n" 
 | ||
|                   "La data inizio elaborazione deve essere almeno il %s"), 
 | ||
|                   (const char*)from_d, (const char*)from_d);
 | ||
|         m.set(F_FROMDATE, from_d);
 | ||
|         continue;
 | ||
|       }
 | ||
|     }
 | ||
|     
 | ||
|     // Recupera sheet dei selezionati ed aggiorna F_SELECTED
 | ||
|     TCursor_sheet* sheet = m.get_selection_sheet();
 | ||
|     const long total = m.get_long(F_SELECTED);
 | ||
|     if (total <= 0)
 | ||
|     {
 | ||
|       warning_box(TR("Nessun movimento selezionato"));
 | ||
|       continue;
 | ||
|     }  
 | ||
|                                      
 | ||
|     TString action;
 | ||
|     if (key == K_ENTER)
 | ||
|       action.format(FR("Conferma di %ld movimenti."), total);
 | ||
|     else
 | ||
|       action.format(FR("Cancellazione di %ld movimenti."), total);
 | ||
| 
 | ||
|     TString caption;
 | ||
|     caption << action << TR("\nSi desidera continuare?");
 | ||
|     if (!yesno_box(caption)) 
 | ||
|       continue;
 | ||
|     
 | ||
|     action[0] = toupper(action[0]);                         
 | ||
|     TProgind pi(total, action, TRUE, TRUE);
 | ||
|     
 | ||
|     if (key == K_ENTER)
 | ||
|       confirm_provv(m.get_cursor(), pi, sheet);
 | ||
|     else  
 | ||
|       delete_provv(m.get_cursor(), pi, sheet);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| int cg2200(int argc, char** argv)
 | ||
| {
 | ||
|   TProvvisori_app a;
 | ||
|   a.run(argc, argv, TR("Gestione provvisori"));
 | ||
|   return 0;
 | ||
| }
 |