Files correlati : ce1.exe Ricompilazione Demo : [ ] Commento : Coretta gestione specie e categoria git-svn-id: svn://10.65.10.50/trunk@18204 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1350 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1350 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <automask.h>
 | ||
| #include <defmask.h> 
 | ||
| #include <recarray.h> 
 | ||
| #include <relapp.h> 
 | ||
| #include <sheet.h> 
 | ||
| #include <utility.h> 
 | ||
| 
 | ||
| #include "ce1.h"
 | ||
| #include "ce1500a.h" 
 | ||
| #include "ce2101.h" 
 | ||
| #include "celib.h" 
 | ||
| #include "../cg/cglib01.h" 
 | ||
| 
 | ||
| #include <causali.h>
 | ||
| #include <mov.h>
 | ||
| #include <pconti.h>
 | ||
| #include <rmov.h>
 | ||
| 
 | ||
| #include "ammce.h"
 | ||
| #include "ammmv.h"
 | ||
| #include "cespi.h"
 | ||
| #include "movce.h"
 | ||
| #include "salce.h"
 | ||
| 
 | ||
| 
 | ||
| //--------------------------------------------------
 | ||
| // DICHIARAZIONE APPLICAZIONE
 | ||
| //--------------------------------------------------
 | ||
| class TMov_qmask;
 | ||
| class TMov_emask;
 | ||
| 
 | ||
| class TMovicespi : public TRelation_application
 | ||
| {         
 | ||
|   TRelation* _rel;
 | ||
|   TMov_qmask* _qmask;
 | ||
|   TMov_emask* _emask;
 | ||
|   TFilename _prima_nota;
 | ||
| 
 | ||
| private:
 | ||
|   void kill_mov(const TString& idcespite, const TString& idmov, int lfile);
 | ||
|   void kill_rett(const TString& id, const TString& idmov);
 | ||
| 
 | ||
|   void set_prompt(TMask_field& fld, bool plus);
 | ||
|   void show_plus_minus(TMask& m);
 | ||
| 
 | ||
| protected:
 | ||
|   virtual bool changing_mask(int mode) { return true; }
 | ||
|   virtual TMask* get_mask(int mode);
 | ||
|   virtual const char* get_next_key();
 | ||
|   virtual bool protected_record(TRelation &r);
 | ||
|   virtual bool user_create();
 | ||
|   virtual bool user_destroy();
 | ||
|   virtual void init_query_mode(TMask& m);
 | ||
|   virtual void init_insert_mode(TMask& m);
 | ||
|   virtual void init_modify_mode(TMask& m);
 | ||
|   virtual int write(const TMask& m);
 | ||
|   virtual int rewrite(const TMask& m);
 | ||
|   virtual bool remove();
 | ||
| 
 | ||
| public:  
 | ||
|   virtual TRelation* get_relation() const { return _rel; }
 | ||
| 
 | ||
|   void calc_residuo(long numreg);
 | ||
|   void cg_mode();
 | ||
|   int init_mask(TMask& m);
 | ||
|   
 | ||
|   void save_if_dirty();
 | ||
| };
 | ||
| 
 | ||
| TMovicespi& app() { return (TMovicespi&)main_app(); }
 | ||
| 
 | ||
| 
 | ||
| //---------------------------------------------------------
 | ||
| // MASCHERA DI RICERCA (ce1500a)
 | ||
| //---------------------------------------------------------
 | ||
| class TMov_qmask : public TAutomask
 | ||
| {      
 | ||
|   int _staat;
 | ||
| 
 | ||
| protected:
 | ||
|   virtual bool can_be_closed() const;
 | ||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|   void on_user_search(TOperable_field& o);
 | ||
|   virtual void on_firm_change();
 | ||
|   int calcola_stato_attivita();
 | ||
|   int create_fields(int x, int y, short key_id);
 | ||
| 
 | ||
| public:
 | ||
|   int stato_attivita() const { return _staat; } 
 | ||
|   TMov_qmask();
 | ||
| };
 | ||
| 
 | ||
| void TMov_qmask::on_user_search(TOperable_field& o)
 | ||
| {
 | ||
|   TToken_string order, fields, header;
 | ||
|   const TFieldref* campo = o.field();
 | ||
|   //ordinare per campo personalizzato/idcespite/descrizione
 | ||
|   order.format("%d->%s", LF_CESPI, (const char*)campo->name());
 | ||
|   TString prompt = o.prompt();
 | ||
|   prompt << "@" << o.size();  //lunghezza del prompt del campo
 | ||
|   header.add(prompt);
 | ||
|   order.add(MOVCE_IDMOV); 
 | ||
|   header.add(TR("Movimento@11"));
 | ||
| 
 | ||
|   fields = order;
 | ||
|   fields.add(MOVCE_DESC);
 | ||
|   header.add(FR("Descrizione@50"));
 | ||
| 
 | ||
|   fields.add(MOVCE_IDCESPITE); 
 | ||
|   header.add(TR("Cespite@10"));
 | ||
| 
 | ||
|   TString desc_cesp;
 | ||
|   desc_cesp.format("%d->%s", LF_CESPI, "DESC");
 | ||
|   fields.add(desc_cesp);
 | ||
|   header.add(FR("Descrizione cespite@50"));
 | ||
| 
 | ||
|   TRelation rel(LF_MOVCE);
 | ||
|   rel.add(LF_CESPI, "IDCESPITE==IDCESPITE");
 | ||
| 
 | ||
|   TSorted_cursor cur(&rel, order);
 | ||
|   TCursor_sheet sht(&cur, fields, TR("Movimenti"), header, 0, 1);
 | ||
|   if (sht.run() == K_ENTER)
 | ||
|   { 
 | ||
|     TToken_string& row = sht.row();
 | ||
|     set(F_IDMOV, row.get(1), true);
 | ||
|     stop_run(K_AUTO_ENTER);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| int TMov_qmask::calcola_stato_attivita()
 | ||
| {
 | ||
|   const int ese = get_int(F_ESERCIZIO);
 | ||
|   const int gru = get_int(F_GRUPPO);
 | ||
|   const char* spe = get(F_SPECIE);
 | ||
| 
 | ||
|   TString16 str;  
 | ||
|   str.format("%04d%02d%-4s", ese, gru, spe);
 | ||
| 
 | ||
|   const TRectype& curr_ccb = cache().get("CCB", str);
 | ||
|   if (curr_ccb.get_bool("B1")) // Bollato stampato
 | ||
|     _staat = 3;
 | ||
|   else
 | ||
|   {  
 | ||
|     TEsercizi_contabili esc;
 | ||
|     str.format("%04d%02d%-4s", esc.pred(ese), gru, spe);
 | ||
|     const TRectype& prev_ccb = cache().get("CCB", str);
 | ||
|     _staat = prev_ccb.get_bool("B1") ? 2 : 1;
 | ||
|   }
 | ||
|   
 | ||
|   ditta_cespiti().set_attivita(ese, gru, spe);
 | ||
|   return _staat;
 | ||
| }
 | ||
| 
 | ||
| bool TMov_qmask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   switch (o.dlg())
 | ||
|   {
 | ||
|   case F_ESERCIZIO:
 | ||
|     if ((e == fe_close || e == fe_modify) && efield(F_INIZIO_ES).empty())
 | ||
|       return error_box(TR("Inserire un esercizio valido"));
 | ||
|     if (e == fe_init || e == fe_modify)
 | ||
|     { 
 | ||
|       int esercizio = get_int(F_ESERCIZIO);
 | ||
|       TString4 gruppo, specie;
 | ||
|       TDitta_cespiti& dc = ditta_cespiti();
 | ||
|       dc.set_attivita(esercizio, atoi(gruppo), specie);
 | ||
|       dc.get_attivita(esercizio, gruppo, specie);
 | ||
|       if (gruppo.full())
 | ||
|       {
 | ||
|         set(F_GRUPPO, gruppo);
 | ||
|         set(F_SPECIE, specie.rtrim(), 0x3);
 | ||
|       }
 | ||
|     }   //niente break!!!!! <20> fatto apposta per far scattare i successivi controlli su gruppo e specie
 | ||
|   case F_GRUPPO:
 | ||
|   case F_SPECIE:
 | ||
|     if (e == fe_init || e == fe_modify)
 | ||
|     {
 | ||
|       const int sa = calcola_stato_attivita();
 | ||
|       enable(DLG_NEWREC, sa != 3);
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_IMPIANTO:
 | ||
|   case F_IDCESPITE: 
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       const TString& ces = get(F_IDCESPITE);
 | ||
|       const TString& imp = get(F_IMPIANTO);
 | ||
|       const bool cesok = !real::is_null(ces);
 | ||
|       const bool impok = !real::is_null(imp);
 | ||
|       TString80 filter;
 | ||
|       if (cesok)
 | ||
|         filter << MOVCE_IDCESPITE << "==\"" << ces << '"';
 | ||
|       if (impok)
 | ||
|       {
 | ||
|         if (cesok)
 | ||
|           filter << ")&&(";
 | ||
|         filter << LF_CESPI << "->" << CESPI_CODIMP << "==\"" << imp << '"';
 | ||
|         if (cesok)
 | ||
|         {
 | ||
|           filter << ')';
 | ||
|           filter.insert("(", 0);
 | ||
|         }
 | ||
|       }
 | ||
|       TEdit_field& m = efield(F_IDMOV);
 | ||
|       m.browse()->set_filter(filter);
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_NUMREG: 
 | ||
|     if (e == fe_modify)
 | ||
|     {      
 | ||
|       TEdit_field& m = efield(F_IDMOV);
 | ||
|       if (!m.empty())
 | ||
|         m.on_key(K_TAB);
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_CGROWS:
 | ||
|     if (e == se_query_add || e == se_query_del)
 | ||
|       return false;
 | ||
|     break;
 | ||
|   case DLG_QUIT:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       TMask_field& f = efield(F_TOTRES);
 | ||
|       if (f.shown() && !f.empty())
 | ||
|         return yesno_box(TR("Attenzione: la registrazione contabile non <20> ancora del tutto evasa:\n"
 | ||
|                          "Si desidera uscire ugualmente?"));
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_USER:
 | ||
|   case F_USER+1:
 | ||
|   case F_USER+2:
 | ||
|   case F_USER+3:
 | ||
|   case F_USER+4:
 | ||
|   case F_USER+5:
 | ||
|     if (e == fe_button)
 | ||
|       on_user_search(o);
 | ||
|     break;
 | ||
|   default: 
 | ||
|     break;
 | ||
|   }
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TMov_qmask::can_be_closed() const
 | ||
| {
 | ||
|   TButton_field& f = (TButton_field&)field(DLG_QUIT);
 | ||
|   return ((TMov_qmask*)this)->on_field_event(f, fe_button, 0);
 | ||
| }
 | ||
| 
 | ||
| void TMov_qmask::on_firm_change()
 | ||
| {
 | ||
|   TAutomask::on_firm_change();
 | ||
|   ditta_cespiti().init_mask(*this);
 | ||
| }
 | ||
| 
 | ||
| TMov_qmask::TMov_qmask() : TAutomask("ce1500a") 
 | ||
| {
 | ||
|   first_focus(F_IDMOV);
 | ||
|   create_fields(1, 9, F_USER);
 | ||
| }
 | ||
| 
 | ||
| //metodo per la generazione dei campi di ricerca personalizzati
 | ||
| int TMov_qmask::create_fields(int x, int y, short key_id)
 | ||
| {
 | ||
|   TRectype rec_cespi(LF_CESPI);
 | ||
|   //cicla sui campi user (se ci sono) nel ditta.ini facendoli apparire sulla pagine Personalizz.
 | ||
|   TConfig config (CONFIG_DITTA, "ce");
 | ||
| 
 | ||
|   int i = 0;
 | ||
|   //valuta il valore massimo in orizzontale per il prompt, in modo da allineare i campi in verticale
 | ||
|   int maxprompt = 0;
 | ||
|   for (i = 0; config.exist("USER", i); i++)
 | ||
|   {
 | ||
|     TToken_string riga = config.get("USER", NULL, i);
 | ||
|     const TString80 prompt = riga.get(1);
 | ||
|     const int len = prompt.len();
 | ||
|     if (len > maxprompt)
 | ||
|       maxprompt = len;
 | ||
|   }
 | ||
|   maxprompt++;
 | ||
| 
 | ||
|   for (i = 0; config.exist("USER", i); i++)
 | ||
|   {
 | ||
|     TToken_string riga = config.get("USER", NULL, i);
 | ||
| 
 | ||
|     //siamo in pagina di ricerca! se il campo non e' di ricerca lo salta!
 | ||
|     const bool search = riga.get_char(3) == 'X';
 | ||
|     if (!search)
 | ||
|       continue;
 | ||
|     //tutto il resto lo fa comunque,settandondolo nella page corretta
 | ||
|     const short kid = key_id+i; //numero del campo come definito nel .h della maschera
 | ||
|     const TString16 name = riga.get(0); //nome campo
 | ||
|     TString80 prompt = riga.get(1); prompt.left_just(maxprompt);  //prompt sulla maschera    
 | ||
|     const TString80 picture = riga.get(2);  //picture del campo(se c'e')
 | ||
|     //se la lunghezza del campo non e' definita nella picture la prende dal tracciato
 | ||
|     const int len = picture.blank() ? rec_cespi.length(name) : picture.len();
 | ||
| 
 | ||
|     //chiede al record di che tipo e' il campo chiamato name...
 | ||
|     const TFieldtypes tipo_campo = rec_cespi.type(name);
 | ||
|     //..quanto e' lungo...(maniaca!)
 | ||
|     const int length_campo = rec_cespi.length(name);
 | ||
|     //...e quanti decimali ha nel caso sia un real
 | ||
|     int ndec_campo = 0;
 | ||
|     if (tipo_campo == _realfld)
 | ||
|       ndec_campo = rec_cespi.ndec(name);
 | ||
| 
 | ||
|     //crea finalmente i nuovi campi sulla pagina 1 (Personalizzazioni)
 | ||
|     switch(tipo_campo)
 | ||
|     {
 | ||
|     case _wordfld:      add_number (kid, 0, prompt, x, i+y, len, search ? "BU" : "U");  break;
 | ||
| 
 | ||
|     case _intfld :
 | ||
|     case _longfld:      add_number (kid, 0, prompt, x, i+y, len, search ? "B" : "");  break;
 | ||
| 
 | ||
|     case _intzerofld:
 | ||
|     case _longzerofld:  add_number (kid, 0, prompt, x, i+y, len, search ? "BZ" : "Z");  break;
 | ||
| 
 | ||
|     case _realfld:      add_number (kid, 0, prompt, x, i+y, len, "", ndec_campo);  break;
 | ||
| 
 | ||
|     case _datefld:      add_date (kid, 0, prompt, x, i+y, search ? "B" : "");  break;
 | ||
| 
 | ||
|     case _memofld:      add_zoom(kid, 0, prompt, x, i+y, 50);  break;
 | ||
|       
 | ||
|     default      :      add_string (kid, 0, prompt, x, i+y, len, search ? "BU" : "");  break;
 | ||
|     }
 | ||
| 
 | ||
|     //deve poter salvare il contenuto nei campi!! (e' il FIELD delle maschere)
 | ||
|     TEdit_field& efld = efield(kid);
 | ||
|     efld.set_field(name); //la set_field lo fa
 | ||
|   }
 | ||
|   //deve accendere gli handler di questa maschera perche' funzionino
 | ||
|   set_handlers();
 | ||
|   
 | ||
|   return i;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| //---------------------------------------------------------
 | ||
| // MASCHERA DI MODIFICA (ce1500b)
 | ||
| //---------------------------------------------------------
 | ||
| class TMov_emask : public TAutomask
 | ||
| {      
 | ||
|   int _staat;
 | ||
|   TCespite _cespite;
 | ||
|   TString _s5;
 | ||
| 
 | ||
| private:
 | ||
|   void set_inputability(short id, char flag);
 | ||
|   void set_inputability(const short* id, char flag);
 | ||
|   bool test_inputability(const short* id, char flag);
 | ||
|   void set_fondi_inputability();
 | ||
| 
 | ||
|   real calc_riv(const TRectype& salpro, int tipo) const;
 | ||
|   real calc_vnonamm(const TRectype& salpro, int tipo) const;
 | ||
|   bool calc_amm(int tipo);
 | ||
|   void calc_plus_minus(int tipo, real& plus, real& minus) const;
 | ||
|   
 | ||
|   bool cespite_nuovo() const;
 | ||
|   TCurrency sum_fields(const short* f) const;
 | ||
|   void super_polish();
 | ||
| 	void enable_fabbricato();
 | ||
| 
 | ||
| protected:
 | ||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|   virtual bool on_key(KEY k);
 | ||
| 
 | ||
| public:
 | ||
|   void set_stato_attivita(int s) { _staat = s; }
 | ||
|   void recalc_amm();
 | ||
| 
 | ||
|   TMov_emask();
 | ||
| };
 | ||
| 
 | ||
| // Determina se siamo in presenza di un cespite nuovo
 | ||
| bool TMov_emask::cespite_nuovo() const
 | ||
| {
 | ||
|   const TDate dtacq = _cespite.get_date(CESPI_DTCOMP);
 | ||
|   const TDate dtmov(get(F_DTMOV));
 | ||
|   return !dtacq.ok() || dtacq >= dtmov;
 | ||
| }
 | ||
| 
 | ||
| TCurrency TMov_emask::sum_fields(const short* f) const
 | ||
| {
 | ||
|   TCurrency sum, val;
 | ||
|   for (int i = 0; f[i] != 0; i++)
 | ||
|   {
 | ||
|     get_currency(abs(f[i]), val);
 | ||
|     if (f[i] > 0)
 | ||
|       sum += val;
 | ||
|     else
 | ||
|       sum -= val;  
 | ||
|   }
 | ||
|   return sum;
 | ||
| }
 | ||
| 
 | ||
| // Toglie tutti i dirty
 | ||
| void TMov_emask::super_polish()
 | ||
| {
 | ||
|   for (int f = fields()-1; f >= 0; f--)
 | ||
|   {
 | ||
|     TMask_field& c = fld(f);
 | ||
|     c.set_dirty(false);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| //metodo per accendere/spegnere campi relativi ai fabbricati scorporabili
 | ||
| void TMov_emask::enable_fabbricato()
 | ||
| {
 | ||
| 	const TDate dtmov = get(F_DTMOV);
 | ||
| 	const TTipoFabbricato tipo_fabbr = _cespite.fabbricato();
 | ||
| 	if (tipo_fabbr != tf_nessuno && dtmov >= TDate(4,7,2006) && field(F_VNONAMM).active())
 | ||
| 	{
 | ||
| 		enable(-13);
 | ||
| 		set(F_FABBR06, tipo_fabbr);
 | ||
| 		set(F_DATASCORP06, dtmov);
 | ||
| 		if (mode() == MODE_INS)
 | ||
|       set(F_PERCALC06, tipo_fabbr == tf_industriale ? 30 : 20);
 | ||
| 	}
 | ||
| 	else
 | ||
| 	{
 | ||
| 		reset(-13);
 | ||
| 		disable(-13);
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| void TMov_emask::set_inputability(short id, char flag)
 | ||
| {
 | ||
|   TMask_field& f = field(id);
 | ||
|   if  (flag=='S' || flag=='O')
 | ||
|     f.enable();
 | ||
|   else
 | ||
|   {
 | ||
|     f.reset();
 | ||
|     f.disable();  
 | ||
|   }
 | ||
|   f.check_type(flag=='O' ? CHECK_REQUIRED : CHECK_NORMAL);
 | ||
| }
 | ||
| 
 | ||
| void TMov_emask::set_inputability(const short* id, char flag)
 | ||
| {
 | ||
|   if (flag == 'O') 
 | ||
|     flag = 'S';
 | ||
|   for (; *id > 0; id++)
 | ||
|     set_inputability(*id, flag);
 | ||
| }
 | ||
| 
 | ||
| bool TMov_emask::test_inputability(const short* id, char flag)
 | ||
| {
 | ||
|   bool ok = flag != 'O';
 | ||
|   if (!ok)
 | ||
|   {
 | ||
|     for (int i = 0; id[i] > 0; i++)
 | ||
|     {
 | ||
|       if (!field(id[i]).empty())  
 | ||
|       {
 | ||
|         ok = true;
 | ||
|         break;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   if (!ok)
 | ||
|     error_box(TR("E' necessario specificare almeno uno dei valori previsti dal tipo movimento"));
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| HIDDEN const short doc_ids[] = { F_TPDOC, F_NDOC, F_DTDOC, 0 };
 | ||
| HIDDEN const short riv_ids[] = { F_RIV75, F_RIV83, F_RIV90, F_RIV91, 0 };
 | ||
| HIDDEN const short fis_ids[] = { F_NORMALE, F_ACCELERATO, F_ANTICIPATO, 0 };
 | ||
| HIDDEN const short civ_ids[] = { F_NORMALE2, F_ACCELERATO2, F_ANTICIPATO2, 0 };
 | ||
| HIDDEN const short prv_ids[] = { F_FPRIVATO, F_QPERSEPRIV, 0 };
 | ||
| 
 | ||
| bool TMov_emask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   switch (o.dlg())
 | ||
|   {
 | ||
|   case F_CODMOV:
 | ||
|     if ((e == fe_modify || e == fe_init))
 | ||
|     {
 | ||
|       const TRectype& tpmov = cache().get("%TMC", o.get());
 | ||
|       const bool insert_rett = tpmov.get_int("I0") == 2 && insert_mode();
 | ||
|       enable(F_IDRET, insert_rett);
 | ||
|       if (insert_rett)
 | ||
|       {
 | ||
|         TString filter; // Filtro su movimenti rettificabili
 | ||
|         filter << '(' << MOVCE_CODMOV << "=\"" << tpmov.get("S8") << "\")";
 | ||
|         filter << "&&(ANSI(" << MOVCE_DTMOV << ")>=" << get_date(F_INIZIO_ES).string(ANSI) << ')';
 | ||
|         filter << "&&(ANSI(" << MOVCE_DTMOV << ")<=" << get_date(F_FINE_ES).string(ANSI) << ')';
 | ||
|         efield(F_IDRET).browse()->set_filter(filter);
 | ||
|       }
 | ||
|       _s5 = tpmov.get("S5");
 | ||
|       if (_s5.empty())
 | ||
|         _s5.spaces(16);
 | ||
|       set_inputability(doc_ids,    _s5[0]);
 | ||
|       set_inputability(F_IMPVEN,   _s5[2]);
 | ||
|       set_inputability(F_ELEMENTI, _s5[3]);
 | ||
|       set_inputability(F_COSTO,    _s5[4]);
 | ||
| 
 | ||
|       set_inputability(F_VNONAMM,  _s5[5]);
 | ||
|       set_inputability(F_VNONAMMC, _s5[5]);
 | ||
| 
 | ||
|       set_inputability(F_PLUSREIN, _s5[6]);
 | ||
|       set_inputability(riv_ids,    _s5[7]);
 | ||
|       set_inputability(F_RIVGF,    _s5[8]);
 | ||
|       set_inputability(F_RIVGC,    _s5[9]);
 | ||
|       // Determina segni possibili
 | ||
|       switch (tpmov.get_char("S7"))
 | ||
|       {        
 | ||
|       case '+': disable(F_SEGNO); set(F_SEGNO, "+"); break;
 | ||
|       case '-': disable(F_SEGNO); set(F_SEGNO, "-"); break;
 | ||
|       default : enable(F_SEGNO); break;
 | ||
|       }
 | ||
| 			//solo se e' in modifica abilita il test sul fabbricato;se fosse in fe_init non potrebbe conoscere in..
 | ||
| 			//..questo momento l'idcespite e quindi non potrebbe riconoscerlo come fabbricato anche se lo fosse e..
 | ||
| 			//..resetterebbe i campi della pagina fabbricato!
 | ||
| 			if (e == fe_modify)
 | ||
| 				enable_fabbricato();
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_IDRET:
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       TString16 ces;
 | ||
|       if (!o.empty())
 | ||
|       {
 | ||
|         TEdit_field& e = (TEdit_field&)o;
 | ||
|         ces = e.browse()->cursor()->curr().get(MOVCE_IDCESPITE);
 | ||
|         TEdit_field& c = efield(F_IDCESPITE);
 | ||
|         c.set(ces); 
 | ||
|         c.check();
 | ||
|       }
 | ||
|       enable(F_IDCESPITE, ces.empty()); // Dis/abilita codice cespite
 | ||
|       enable(F_DESC_CES, ces.empty());  // Dis/abilita descrizione cespite
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_IDCESPITE:
 | ||
| 
 | ||
|     if (e == fe_init || e == fe_modify || e == fe_close)
 | ||
|     {
 | ||
|       const TString& id = o.get();
 | ||
|       if (_cespite.get(CESPI_IDCESPITE) != id)
 | ||
|         _cespite.read(id);                    
 | ||
|       enable_page(4, id.not_empty()); 
 | ||
|       if (id.not_empty())
 | ||
|       {
 | ||
|         const TRectype& cat = _cespite.categoria();
 | ||
|         set(F_CATEGORIA, _cespite.get(CESPI_CODCAT), true);
 | ||
|         set(F_DESC_CAT, cat.get("S0"), true);
 | ||
|         if (e != fe_init && o.enabled())
 | ||
|         {
 | ||
|           const TRectype& tpmov = cache().get("%TMC", get(F_CODMOV));
 | ||
| 
 | ||
|           switch (_cespite.tipo())
 | ||
|           {
 | ||
|           case tc_immateriale:
 | ||
|             if (!tpmov.get_bool("B1")) 
 | ||
|               return error_box(TR("Movimento non applicabile a beni immateriali"));
 | ||
|             break;
 | ||
|           case tc_pluriennale:
 | ||
|             if (!tpmov.get_bool("B2")) 
 | ||
|               return error_box(TR("Movimento non applicabile a costi pluriennali"));
 | ||
|             break;
 | ||
|           default:
 | ||
|             if (!tpmov.get_bool("B0")) 
 | ||
|               return error_box(TR("Movimento non applicabile a beni materiali"));
 | ||
|             break;    
 | ||
|           }
 | ||
|         }
 | ||
| 				//gestione fabbricati scorporabili da d.l. 223/06
 | ||
| 				enable_fabbricato();
 | ||
|       }	//if(id.not_empty...
 | ||
|       else
 | ||
|       {
 | ||
|         reset(F_CATEGORIA);
 | ||
|         reset(F_DESC_CAT);
 | ||
|       }
 | ||
|       const TDate dtcomp = _cespite.get_date(CESPI_DTCOMP);
 | ||
|       if (dtcomp.ok())
 | ||
|       {
 | ||
|         const TDate dtmov(get(F_DTMOV));
 | ||
|         if (dtcomp > dtmov)
 | ||
|           return error_box(TR("La data di acquisizione del cespite non pu<70> precedere quella del movimento"));
 | ||
|       }
 | ||
|     }
 | ||
|     break;  
 | ||
|   case F_DTMOV:
 | ||
|     if (e == fe_init || e == fe_modify || e == fe_close)
 | ||
|     {
 | ||
|       TEdit_field& dd = efield(F_DTDOC);
 | ||
|       if (dd.required() && dd.empty())
 | ||
|         dd.set(o.get());
 | ||
| 
 | ||
| // Inserimento nuovo cespite da gestione movimenti cespiti
 | ||
| // Se il campo cespite e' vuoto e non sono in uscita di programma (sto quindi inserendo un
 | ||
| // cespite nuovo..) prendo la data movimento dal file di configurazione ditta..
 | ||
|       if (field(F_IDCESPITE).empty() && e != fe_close)
 | ||
|       {
 | ||
|         TConfig ini(CONFIG_DITTA,"ce");
 | ||
|         ini.set("DataMovimento", o.get());
 | ||
|       }
 | ||
| // ..se invece sono in uscita di programma (avro' gia' inserito il cespite) la data movimento
 | ||
| // sul file di configurazione deve essere svuotata 
 | ||
|       if (e == fe_close)
 | ||
|       {
 | ||
|         TConfig ini(CONFIG_DITTA,"ce");
 | ||
|         ini.set("DataMovimento", "");
 | ||
|       }
 | ||
|         
 | ||
| 			const TDate dtmov(o.get());
 | ||
|       const TDate dtret(get(F_DTMOV_RET));
 | ||
|       if (dtret.ok() && dtmov < dtret)
 | ||
|         return error_box(TR("La data del movimento di rettifica deve seguire la data del movimento rettificato"));
 | ||
| 
 | ||
| //gestione campi per fabbricati scorporati
 | ||
| 			if (e == fe_modify)
 | ||
| 				enable_fabbricato();
 | ||
| 
 | ||
|     }
 | ||
|     break;  
 | ||
|   case F_TPDOC:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       TArray_sheet sci(3, 3, -3, -3, o.prompt(), HR("Tipo|Descrizione@20"));
 | ||
|       sci.add(TR("FA|Fattura d'acquisto"));
 | ||
|       sci.add(TR("FV|Fattura di vendita"));
 | ||
|       sci.add(TR("NC|Nota di credito"));
 | ||
|       sci.add(TR("ND|Nota di debito"));
 | ||
|       if (sci.run() == K_ENTER)
 | ||
|       {       
 | ||
|         TToken_string& str = sci.row(-1);
 | ||
|         o.set(str.get(0));
 | ||
|       }
 | ||
|     }
 | ||
|     if (e == fe_close)
 | ||
|       return test_inputability(doc_ids, _s5[0]);
 | ||
|     break;
 | ||
|   case F_RIV75:
 | ||
|     if (e == fe_close)
 | ||
|       return test_inputability(riv_ids, _s5[7]);
 | ||
|     break;
 | ||
|   case F_ELEMENTI:
 | ||
|     if (e == fe_modify || e == fe_close)
 | ||
|     {
 | ||
|       if (o.empty() && cespite_nuovo())
 | ||
|         return error_box(TR("<EFBFBD> necessario inserire il numero di elementi del nuovo cespite"));
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_VNONAMM:
 | ||
|     if (e == fe_modify || e == fe_close)
 | ||
|     { 
 | ||
|       TCurrency csto, vnon;
 | ||
|       get_currency(F_COSTO, csto);
 | ||
|       get_currency(F_VNONAMM, vnon);
 | ||
|       if (vnon > csto)
 | ||
|         return error_box(FR("Il valore non ammortizzabile non puo' superare %s"), csto.string(true));
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_PLUSREIN:
 | ||
|     if (e == fe_modify || e == fe_close)
 | ||
|     { 
 | ||
|       TCurrency csto, vnon, plus;
 | ||
|       get_currency(F_COSTO, csto);
 | ||
|       get_currency(F_VNONAMM, vnon);
 | ||
|       get_currency(F_PLUSREIN, plus);
 | ||
|       const TCurrency val = csto-vnon;
 | ||
|       if (plus > val)
 | ||
|         return error_box(FR("La plusvalenza reinvestita non puo' superare %s"), val.string(true));
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_NORMALE:
 | ||
|     if (e == fe_close)
 | ||
|     {        
 | ||
|       if (!test_inputability(fis_ids, _s5[10]))
 | ||
|         return false;
 | ||
|       const short fv[] = { F_COSTO, -F_VNONAMM, -F_VNONAMM06, 
 | ||
|                            F_RIV75, F_RIV83, F_RIV90, F_RIV91, F_RIVGF, 0 };
 | ||
|       const short fa[] = { F_NORMALE, F_ACCELERATO, F_ANTICIPATO, F_QPERSE, F_FPRIVATO, F_QPERSEPRIV, 0 };
 | ||
|       const TCurrency val_amm = sum_fields(fv);
 | ||
|       const TCurrency fon_amm = sum_fields(fa);
 | ||
|       if (fon_amm > val_amm)
 | ||
|       {
 | ||
|         TString msg;
 | ||
|         msg << TR("Il fondo ammortamento fiscale (") << fon_amm.string(true) << ')';
 | ||
|         msg << TR("non puo' superare il valore da ammortizzare (") << val_amm.string(true) << ')';
 | ||
| 
 | ||
|         // Per i fabbricati scorporati non e' un errore
 | ||
|         if (_cespite.fabbricato() != tf_nessuno && !field(F_VNONAMM06).empty())  
 | ||
|           warning_box(msg);  
 | ||
|         else
 | ||
|           return error_box(msg);      }
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_NORMALE2:
 | ||
|     if (e == fe_close)
 | ||
|     { 
 | ||
|       if (!test_inputability(civ_ids, _s5[11]))
 | ||
|         return false;
 | ||
|       const short fv[] = { F_COSTO, F_RIV75, F_RIV83, F_RIV90, F_RIV91, F_RIVGC, 0 };
 | ||
|       const short fa[] = { F_NORMALE2, F_ACCELERATO2, F_ANTICIPATO2, 0 };
 | ||
|       const TCurrency val_amm = sum_fields(fv);
 | ||
|       const TCurrency fon_amm = sum_fields(fa);
 | ||
|       if (fon_amm > val_amm)
 | ||
|       {
 | ||
|         TString msg;
 | ||
|         msg << TR("Il fondo ammortamento civilistico (") << fon_amm.string(true) << ')';
 | ||
|         msg << TR("non puo' superare il valore da ammortizzare (") << val_amm.string(true) << ')';
 | ||
|         return error_box(msg);
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case S_TIPO:
 | ||
|     if (e == fe_init || e == fe_modify)
 | ||
|       calc_amm(atoi(o.get()));
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;  
 | ||
|   }
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| real TMov_emask::calc_riv(const TRectype& salpro, int tipo) const
 | ||
| {
 | ||
|   const char* riv_ids[] = { SALCE_RIV75, SALCE_RIV83, SALCE_RIV90, SALCE_RIV91, NULL };
 | ||
|   real riv;
 | ||
|   for (int i = 0; riv_ids[i]; i++)
 | ||
|     riv += salpro.get_real(riv_ids[i]);
 | ||
|   if (tipo == 1 || _cespite.get_bool(CESPI_LEASING))
 | ||
|     riv += salpro.get_real(SALCE_RIVGF); else
 | ||
|   if (tipo == 2 && !_cespite.get_bool(CESPI_LEASING))
 | ||
|     riv += salpro.get_real(SALCE_RIVGC);
 | ||
|   return riv;  
 | ||
| }
 | ||
| 
 | ||
| real TMov_emask::calc_vnonamm(const TRectype& salpro, int tipo) const
 | ||
| {
 | ||
|   real vnonamm;
 | ||
| 
 | ||
|   if (tipo == 2)
 | ||
|     vnonamm += salpro.get_real(SALCE_VNONAMMC);
 | ||
|   else
 | ||
|     vnonamm += salpro.get_real(SALCE_VNONAMM);
 | ||
| 
 | ||
|   if (_cespite.fabbricato() != tf_nessuno)
 | ||
|     vnonamm += salpro.get_real(SALCE_VNONAMM06);
 | ||
| 
 | ||
|   return vnonamm;  
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMov_emask::calc_plus_minus(int tipo, real& plus, real& minus) const
 | ||
| {
 | ||
|   TDitta_cespiti& cce = ditta_cespiti();
 | ||
|   TDate inies, fines;
 | ||
|   cce.esercizio_corrente(inies, fines);
 | ||
|   const TDate dtlim(get(F_DTMOV));
 | ||
|     
 | ||
|   TRelation rel(LF_MOVCE);
 | ||
|   TRectype& movsem = rel.curr();
 | ||
|   const TString& idcespite = get(F_IDCESPITE);
 | ||
|   movsem.put(MOVCE_IDCESPITE, idcespite);
 | ||
|   TString filtro;
 | ||
|   filtro << "(ANSI(DTMOV)>=\"" << inies.string(ANSI) << "\")";
 | ||
|   filtro << "&&(ANSI(DTMOV)<=\"" << dtlim.string(ANSI) << "\")";
 | ||
|   TCursor cur(&rel, filtro, 2, &movsem, &movsem);
 | ||
|   const long items = cur.items();
 | ||
|   plus = minus = ZERO;
 | ||
|   if (items > 0)  // Continua solo se esistono movimenti
 | ||
|   {
 | ||
|     cur.freeze();
 | ||
|     
 | ||
|     // Astutamente aggiungo solo ora il file collegato
 | ||
|     TString expr; expr << "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==\"" << tipo << '"';
 | ||
|     rel.add(LF_AMMMV, expr);
 | ||
|     const TRectype& ammmv = rel.curr(LF_AMMMV);
 | ||
|     
 | ||
|     for (cur = 0L; cur.pos() < items; ++cur)
 | ||
|     {
 | ||
|       plus += ammmv.get_real(AMMMV_PLUS);
 | ||
|       minus += ammmv.get_real(AMMMV_MINUS);
 | ||
|     }
 | ||
|   }
 | ||
| } 
 | ||
| 
 | ||
| bool TMov_emask::calc_amm(int tipo)
 | ||
| {   
 | ||
|   const TString& idcespite = _cespite.get(CESPI_IDCESPITE);
 | ||
|   if (idcespite.blank())
 | ||
|     return false;
 | ||
| 
 | ||
|   const TDate dtlim(get(F_DTMOV));
 | ||
|   _cespite.calc_amm(tipo, dtlim);
 | ||
|   set(S_DATAMOV, dtlim);                 
 | ||
|   
 | ||
|   const TRectype& s = _cespite.sal_pro();
 | ||
|   set(S_ELEMENTI, s.get(SALCE_NUMELE));  
 | ||
|   set(S_COSTO,    s.get_real(SALCE_CSTO));
 | ||
|   set(S_PLUSREIN, s.get(SALCE_PLUSREIN));
 | ||
|   set(S_TOTRIV,   calc_riv(s, tipo));
 | ||
|   set(S_VNONAMM,  calc_vnonamm(s, tipo));
 | ||
| 
 | ||
|   real tot_val;
 | ||
|   tot_val += get_real(S_COSTO); 
 | ||
|   tot_val += get_real(S_TOTRIV); 
 | ||
|   tot_val -= get_real(S_PLUSREIN); 
 | ||
|   tot_val -= get_real(S_VNONAMM);
 | ||
|   set(S_TOTVAL, tot_val);
 | ||
|   
 | ||
|   const TRectype& a = _cespite.amm_pro();
 | ||
|   set(S_NORMALE,    a.get(AMMCE_QNORP));
 | ||
|   set(S_ACCELERATO, a.get(AMMCE_QACCP));
 | ||
|   set(S_ANTICIPATO, a.get(AMMCE_QANTP));
 | ||
|   set(S_QPERSE,     a.get(AMMCE_QPERSEP));
 | ||
|   set(S_FPRIVATO,   a.get(AMMCE_FPRIVATOP));
 | ||
|   set(S_QPERSEP,    a.get(AMMCE_QPPRIVATEP));
 | ||
|   real tot_fon;
 | ||
|   tot_fon += get_real(S_NORMALE);    tot_fon += get_real(S_ACCELERATO);
 | ||
|   tot_fon += get_real(S_ANTICIPATO); tot_fon += get_real(S_QPERSE);
 | ||
|   tot_fon += get_real(S_FPRIVATO);   tot_fon += get_real(S_QPERSEP);
 | ||
|   set(S_TOTFON, tot_fon);
 | ||
|   
 | ||
|   const real tot_res = tot_val - tot_fon;
 | ||
|   set(S_RESIDUO, tot_res);
 | ||
|   
 | ||
|   real plus, minus;
 | ||
|   calc_plus_minus(tipo, plus, minus);
 | ||
|   set(S_PLUS, plus);
 | ||
|   set(S_MINUS, minus);
 | ||
|   
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| void TMov_emask::set_fondi_inputability()
 | ||
| {          
 | ||
|   set_inputability(fis_ids,  _s5[10]);
 | ||
|   set_inputability(civ_ids,  _s5[11]);
 | ||
|   set_inputability(F_QPERSE, _s5[12]);
 | ||
| 
 | ||
|   bool should_be_on = _s5[10] == 'S' || _s5[10] == 'O';     // Test preliminare basato su %TMC
 | ||
|   if (should_be_on)
 | ||
|     should_be_on = _cespite.get_int(CESPI_USOPROM) > 1;     // Test aggiuntivo su uso promiscuo
 | ||
|   set_inputability(prv_ids, should_be_on ? _s5[10] : ' ');  // Dis/abilita fondo privato e quote perse private
 | ||
| }
 | ||
| 
 | ||
| void TMov_emask::recalc_amm()
 | ||
| {
 | ||
|   const TDate dtlim(get(F_FINE_ES));
 | ||
|   for (int tipo = 1; tipo <= 3; tipo++)
 | ||
|     _cespite.calc_amm(tipo, dtlim);
 | ||
| }
 | ||
| 
 | ||
| bool TMov_emask::on_key(KEY k)
 | ||
| { 
 | ||
|   // Try to predict next page!
 | ||
|   const int old_page = curr_page()+1;
 | ||
|   int new_page = old_page;
 | ||
|   switch (k)
 | ||
|   {
 | ||
|   case K_CTRL+K_F1: new_page = 1; break;
 | ||
|   case K_CTRL+K_F2: new_page = 2; break;
 | ||
|   case K_CTRL+K_F3: new_page = 3; break;
 | ||
|   case K_CTRL+K_F4: new_page = 4; break;
 | ||
|   case K_PREV     : new_page--; break;
 | ||
|   case K_NEXT     : new_page++; break;
 | ||
|   default: break;
 | ||
|   }
 | ||
|   
 | ||
|   // If page will change ...
 | ||
|   if (old_page != new_page) 
 | ||
|   {
 | ||
|     switch(new_page)
 | ||
|     {
 | ||
|     case 3: 
 | ||
|       set_fondi_inputability();
 | ||
|       break;
 | ||
|     case 4:
 | ||
|       if (dirty() < S_TIPO)
 | ||
|       {
 | ||
|         app().save_if_dirty();
 | ||
|         super_polish();
 | ||
|       }
 | ||
|       set(S_TIPO, 1, true); 
 | ||
|       break;
 | ||
|     default: break;
 | ||
|     }
 | ||
|     if (old_page == 4)
 | ||
|     {
 | ||
|       recalc_amm();
 | ||
|       TRelation& rel = *app().get_relation();
 | ||
|       if (rel.read() == NOERR)
 | ||
|       {
 | ||
|         autoload(rel);
 | ||
|         super_polish();
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   return TAutomask::on_key(k);
 | ||
| }
 | ||
| 
 | ||
| TMov_emask::TMov_emask() : TAutomask("ce1500b") 
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Applicazione principale
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| TMask* TMovicespi::get_mask(int mode)
 | ||
| {
 | ||
|   return mode == MODE_QUERY ? (TMask*)_qmask : (TMask*)_emask;
 | ||
| }
 | ||
| 
 | ||
| bool TMovicespi::user_create()
 | ||
| {                   
 | ||
|   open_files(LF_TAB, LF_TABCOM, LF_PCON, LF_CLIFO, 0);
 | ||
|   open_files(LF_CESPI, LF_AMMCE, LF_SALCE, LF_MOVCE, LF_MOVAM, LF_AMMMV, 0);
 | ||
| 
 | ||
|   _rel = new TRelation(LF_MOVCE);
 | ||
|   _rel->add(LF_MOVAM, "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==1");
 | ||
|   _rel->add(LF_MOVAM, "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==2", 1, 0, 2);
 | ||
|   _rel->add(LF_MOVAM, "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==3", 1, 0, 3);
 | ||
|   _rel->write_enable(); 
 | ||
|   
 | ||
|   _qmask = new TMov_qmask;
 | ||
|   _emask = new TMov_emask;
 | ||
|   
 | ||
|   // Collegamento da prima nota
 | ||
|   if (argc() > 2 && strncmp(argv(2), "/c", 2) == 0)
 | ||
|   {
 | ||
|     _prima_nota = argv(2); 
 | ||
|     _prima_nota.ltrim(2);
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     _prima_nota.cut(0);
 | ||
|   }
 | ||
|   
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TMovicespi::user_destroy()
 | ||
| {
 | ||
|   delete _emask;
 | ||
|   delete _qmask;
 | ||
|   delete _rel;
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| const char* TMovicespi::get_next_key()
 | ||
| {
 | ||
|   real num = 1;
 | ||
|   TLocalisamfile cespi(LF_MOVCE);
 | ||
|   if (cespi.last() == NOERR)
 | ||
|     num += cespi.get_real(MOVCE_IDMOV);
 | ||
|   return format("%d|%s", F_IDMOV, num.string());
 | ||
| }
 | ||
| 
 | ||
| bool TMovicespi::protected_record(TRelation &r)
 | ||
| {
 | ||
|   bool stampato = r.curr().get_bool(MOVCE_STAMPATO);
 | ||
|   return stampato;
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::calc_residuo(long numreg)
 | ||
| {                                        
 | ||
|   TSheet_field& s = _qmask->sfield(F_CGROWS);
 | ||
| 
 | ||
|   // Mette tutti i residui uguali importi
 | ||
|   real tot_imp = ZERO;
 | ||
|   for (int r = s.items()-1; r >= 0; r--)
 | ||
|   {
 | ||
|     TToken_string& row = s.row(r);
 | ||
|     real imp = row.get(0);
 | ||
|     row.add(imp.string(), 1);
 | ||
|     tot_imp += imp;
 | ||
|   }
 | ||
|   real tot_res = tot_imp;
 | ||
| 
 | ||
|   TRelation rel(LF_MOVCE);
 | ||
|   TString filter; filter << MOV_NUMREG << "==" << numreg;
 | ||
|   TCursor cur(&rel, filter, 3);
 | ||
|   const long items = cur.items();
 | ||
|   if (items > 0)
 | ||
|   {
 | ||
|     cur.freeze();
 | ||
|     TRectype& movce = cur.curr();
 | ||
|     
 | ||
|     TAssoc_array ignore;
 | ||
|     // Prima cerca movimenti con importo identico ...
 | ||
|     for (cur = 0L; cur.pos() < items; ++cur)
 | ||
|     {            
 | ||
|   //    const char segno = movce.get_char(MOVCE_SEGNO);
 | ||
|       real imp = movce.get_real(MOVCE_IMPVEN);
 | ||
|       if (imp.is_zero())
 | ||
|         imp = movce.get_real(MOVCE_CSTO);
 | ||
|       if (imp > ZERO)   // Cerca una riga con lo stesso importo
 | ||
|       {
 | ||
|         for (int r = 0; r < s.items(); r++)
 | ||
|         {
 | ||
|           TToken_string& row = s.row(r);
 | ||
|           const real res = row.get(1);
 | ||
|           if (imp == res)
 | ||
|           {
 | ||
|             imp = ZERO;
 | ||
|             row.add(" ", 1);
 | ||
|             tot_res -= res;
 | ||
|             ignore.add(movce.get(MOVCE_IDMOV));
 | ||
|             break;
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|     // ... poi scala dalle varie righe l'importo fino ad esaurimento
 | ||
|     for (cur = 0L; cur.pos() < items && tot_res > ZERO; ++cur)
 | ||
|     {            
 | ||
|       if (ignore.is_key(movce.get(MOVCE_IDMOV)))
 | ||
|         continue;
 | ||
| //      const char segno = movce.get_char(MOVCE_SEGNO);
 | ||
|       real imp = movce.get_real(MOVCE_IMPVEN);
 | ||
|       if (imp.is_zero())
 | ||
|         imp = movce.get_real(MOVCE_CSTO);
 | ||
|       for (int r = 0; r < s.items() && imp > ZERO; r++)
 | ||
|       {
 | ||
|         TToken_string& row = s.row(r);
 | ||
|         real res = row.get(1);
 | ||
|         if (res > ZERO)
 | ||
|         {
 | ||
|           const real quota = (res > imp) ? imp : res;
 | ||
|           res -= quota;
 | ||
|           imp -= quota;
 | ||
|           row.add(res.string(), 1);
 | ||
|           tot_res -= quota;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   // s.force_update();
 | ||
|   _qmask->set(F_TOTIMP, tot_imp);
 | ||
|   _qmask->set(F_TOTRES, tot_res);
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::set_prompt(TMask_field& fld, bool plus)
 | ||
| {
 | ||
|   TString str = fld.prompt();
 | ||
|   if (plus)
 | ||
|   {
 | ||
|     if (str[0] != 'P')
 | ||
|     {
 | ||
|       str.ltrim(3);
 | ||
|       str.insert("Pl");
 | ||
|     }
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     if (str[0] != 'M')
 | ||
|     {
 | ||
|       str.ltrim(2);
 | ||
|       str.insert("Min");
 | ||
|     }
 | ||
|   }
 | ||
|   fld.set_prompt(str);
 | ||
| }        
 | ||
| 
 | ||
| void TMovicespi::show_plus_minus(TMask& m)
 | ||
| {   
 | ||
|   TToken_string key;          
 | ||
|   short id_txt = F_PLUSMIN_FIS_TXT;
 | ||
|   short id_fld = F_PLUSMIN_FIS;
 | ||
|   for (int tipo = 1; tipo <= 3; tipo++, id_txt+= 2, id_fld+=2)
 | ||
|   {
 | ||
|     key = m.get(F_IDCESPITE);
 | ||
|     key.add(m.get(F_IDMOV));
 | ||
|     key.add(tipo);
 | ||
|     const TRectype& ammmv = cache().get(LF_AMMMV, key);
 | ||
|     const real plus = ammmv.get_real(AMMMV_PLUS);
 | ||
|     const real minus = ammmv.get_real(AMMMV_MINUS);
 | ||
|     const bool on = !plus.is_zero() || !minus.is_zero();
 | ||
|     if (on)
 | ||
|     {
 | ||
|       if (!plus.is_zero())
 | ||
|       {
 | ||
|         set_prompt(m.field(id_txt), true);
 | ||
|         m.set(id_fld, plus);
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         set_prompt(m.field(id_txt), false);
 | ||
|         m.set(id_fld, minus);
 | ||
|       }
 | ||
|     }
 | ||
|     m.show(id_txt, on);
 | ||
|     m.show(id_fld, on);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::cg_mode()
 | ||
| {
 | ||
|   TConfig ini(_prima_nota, "Transaction");
 | ||
|   const char action = ini.get("Action")[0];
 | ||
|   
 | ||
|   TString8 para;
 | ||
|   para.format("%d", LF_MOV);
 | ||
|   ini.set_paragraph(para); 
 | ||
|   const long numreg = ini.get_long(MOV_NUMREG);
 | ||
|   _qmask->set(F_NUMREG, numreg);
 | ||
|   
 | ||
|   // Al primo inserimento devo impostare anche l'anno
 | ||
|   _qmask->set(F_ESERCIZIO, ini.get(MOV_ANNOES), true);
 | ||
| 
 | ||
|   if (action != 'I' && action != 'M')
 | ||
|   {       
 | ||
|     _qmask->hide(-8);
 | ||
|     return;
 | ||
|   }
 | ||
|   else
 | ||
|     _qmask->show(-8);
 | ||
| 
 | ||
|   TSheet_field& s = _qmask->sfield(F_CGROWS);
 | ||
|   for (int i = 1; ; i++)
 | ||
|   {
 | ||
|     para.format("%d,%d", LF_RMOV, i);
 | ||
|     if (ini.set_paragraph(para))
 | ||
|     {          
 | ||
|       const int gruppo = ini.get_int(RMV_GRUPPO);
 | ||
|       const int conto = ini.get_int(RMV_CONTO);
 | ||
|       const long sottoconto = ini.get_long(RMV_SOTTOCONTO);
 | ||
|       const TBill zio(gruppo, conto, sottoconto);
 | ||
|       const int tipo = zio.tipo_cr();
 | ||
|       if (tipo == 2 || tipo == 3 || tipo == 4 || tipo == 8)
 | ||
|       {
 | ||
|         TToken_string& row = s.row(-1);
 | ||
|         row = ini.get(RMV_IMPORTO);
 | ||
|         row.add(""); 
 | ||
|         row.add(zio.string(0x2));
 | ||
|       }
 | ||
|     }
 | ||
|     else
 | ||
|       break;
 | ||
|   }
 | ||
|   calc_residuo(numreg);
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::init_query_mode(TMask& m)
 | ||
| {
 | ||
|   TDitta_cespiti& dc = ditta_cespiti();
 | ||
|   dc.init_mask(m);
 | ||
|   
 | ||
|   // Collegamento da prima nota
 | ||
|   if (_prima_nota.not_empty())
 | ||
|     cg_mode();
 | ||
|   else
 | ||
|     m.hide(-8);  // Nascondi campi collegamento prima nota
 | ||
| }
 | ||
| 
 | ||
| int TMovicespi::init_mask(TMask& m)
 | ||
| {
 | ||
|   TDitta_cespiti& dc = ditta_cespiti();
 | ||
|   dc.init_mask(m);
 | ||
|   
 | ||
|   const int staat = _qmask->stato_attivita();
 | ||
|   _emask->set_stato_attivita(staat);
 | ||
|   m.enable(DLG_NEWREC, staat != 3);
 | ||
|   
 | ||
|   return staat;
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::init_insert_mode(TMask& m)
 | ||
| { 
 | ||
|   const int staat = init_mask(m);
 | ||
|   m.enable(F_IDCESPITE);
 | ||
|   m.enable(F_DESC_CES);
 | ||
|   m.enable(DLG_SAVEREC, staat != 3);
 | ||
|   
 | ||
|   if (_prima_nota.not_empty())
 | ||
|   {
 | ||
|     m.disable(DLG_QUIT); // Altrimenti non riesco a controllare il residuo
 | ||
|   
 | ||
|     TString16 para;
 | ||
|     para.format("%d", LF_MOV);
 | ||
|     TConfig ini(_prima_nota, para);  
 | ||
|     
 | ||
|     const TRectype& cau = cache().get(LF_CAUSALI, ini.get(MOV_CODCAUS));
 | ||
|     m.set(F_CODMOV, cau.get(CAU_COLLCESP), true);
 | ||
|     if (m.field(F_TPDOC).active())
 | ||
|       m.set(F_TPDOC, ini.get(MOV_TIPODOC), true);
 | ||
|     if (m.field(F_NDOC).active())
 | ||
|       m.set(F_NDOC, ini.get(MOV_NUMDOC), true);
 | ||
|     if (m.field(F_DTDOC).active())
 | ||
|       m.set(F_DTDOC, ini.get(MOV_DATADOC), true);
 | ||
| 
 | ||
|     TString desc = ini.get(MOV_DESCR);
 | ||
|     desc.strip("\"");
 | ||
|     if (desc.empty())
 | ||
|       desc = cau.get(CAU_DESCR);
 | ||
|     m.set(F_DESC_MOV, desc, true);
 | ||
| 
 | ||
|     TString16 codreg = ini.get(MOV_REG);
 | ||
|     if (codreg.not_empty())
 | ||
|     {
 | ||
|       codreg.insert(format("%04d", ini.get_int(MOV_ANNOIVA)));
 | ||
|       const int iva = atoi(cache().get("REG", codreg, "I0"));
 | ||
|       TSheet_field& s = _qmask->sfield(F_CGROWS);
 | ||
|       for (int r = 0; r < s.items(); r++)
 | ||
|       {
 | ||
|         const real res = s.row(r).get(1);
 | ||
|         if (res > ZERO)
 | ||
|         {
 | ||
|           m.set(iva==1 ? F_IMPVEN : F_COSTO, res);
 | ||
|           break;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   show_plus_minus(m);
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::init_modify_mode(TMask& m)
 | ||
| {
 | ||
|   const int staat = init_mask(m);
 | ||
|   TEsercizi_contabili esc;
 | ||
|   
 | ||
|   m.disable(F_IDCESPITE);
 | ||
|   m.disable(F_DESC_CES);
 | ||
|   
 | ||
|   const TRectype& rec = get_relation()->curr();
 | ||
|   const TDate dtmov = rec.get_date(MOVCE_DTMOV);
 | ||
|   bool bollato = rec.get_bool(MOVCE_STAMPATO);
 | ||
|   if (!bollato) // Se proprio non ci fidiamo del flag
 | ||
|   {
 | ||
|     const TEsercizio& e = esc[m.get_int(F_ESERCIZIO)];
 | ||
|     const TDate dtini = e.inizio();
 | ||
|     const TDate dtfin = e.fine();
 | ||
|     bollato = (staat == 3 && dtmov <= dtfin) || (staat == 2 && dtmov < dtini);
 | ||
|   }  
 | ||
|   if (bollato)
 | ||
|   {
 | ||
|     m.disable(DLG_SAVEREC);
 | ||
|     m.disable(DLG_DELREC);
 | ||
|     TString msg = TR("Movimento gi<67> stampato sul Bollato dell'esercizio ");
 | ||
|     msg << esc.date2esc(dtmov);
 | ||
|     xvtil_statbar_set(msg);
 | ||
|   }
 | ||
|   if (_prima_nota.not_empty())
 | ||
|     m.disable(DLG_QUIT); // Altrimenti non riesco a controllare il residuo
 | ||
|   
 | ||
|   show_plus_minus(m);
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::kill_mov(const TString& idcespite, const TString& idmov, int lfile)
 | ||
| {
 | ||
|   CHECKD(lfile == LF_MOVAM || lfile == LF_AMMMV, "Invalid file ", lfile);
 | ||
|   TRelation rel(lfile);
 | ||
|   TRectype filter(rel.curr()); 
 | ||
|   filter.zero();
 | ||
|   filter.put("IDCESPITE", idcespite);
 | ||
|   filter.put("IDMOV", idmov);
 | ||
|   TCursor cur(&rel, "", 1, &filter, &filter);
 | ||
|   const long items = cur.items();
 | ||
|   if (items > 0)
 | ||
|   {
 | ||
|     cur.freeze();
 | ||
|     for (cur = 0L; cur.pos() < items; ++cur)
 | ||
|     { 
 | ||
|       int err = rel.remove();
 | ||
|       if (err != NOERR)
 | ||
|       {
 | ||
|         const int tpamm = rel.curr().get_int("TPAMM");
 | ||
|         error_box(FR("Errore %d nella cancellazione dell'ammortamento (%d) del movimento %s"), err, tpamm, (const char*)idmov);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::kill_rett(const TString& id, const TString& idmov)
 | ||
| {
 | ||
|   TRelation rel(LF_MOVCE);
 | ||
|   
 | ||
|   // Il cursore delle rettifiche usa la chiave 2: IDCESPITE+IDMOV
 | ||
|   // Per cui parto a selezionare le possibili rettifiche dal movimento da rettificare ...
 | ||
|   TRectype fromret(LF_MOVCE);
 | ||
|   fromret.put(MOVCE_IDCESPITE, id);
 | ||
|   fromret.put(MOVCE_IDMOV, idmov); 
 | ||
|   
 | ||
|   // ... in poi
 | ||
|   TRectype toret(LF_MOVCE);
 | ||
|   toret.put(MOVCE_IDCESPITE, id);
 | ||
|   
 | ||
|   TString filtro; 
 | ||
|   filtro << MOVCE_IDRET << "==" << idmov;   // Confronto numerico!
 | ||
|   TCursor movcur(&rel, filtro, 2, &fromret, &toret);
 | ||
|   const long items = movcur.items();
 | ||
|   if (items > 0)  // Se ci sono rettifiche
 | ||
|   {
 | ||
|     const TRectype& curr = movcur.curr();
 | ||
|     movcur.freeze();
 | ||
|     for (movcur = 0L; movcur.pos() < items; ++movcur)
 | ||
|     {
 | ||
|       const TString16 idmov = curr.get(MOVCE_IDMOV);
 | ||
|       if (rel.remove() == NOERR)
 | ||
|       {
 | ||
|         kill_mov(id, idmov, LF_MOVAM);
 | ||
|         kill_mov(id, idmov, LF_AMMMV);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| int TMovicespi::write(const TMask& m)
 | ||
| {
 | ||
|   int err = TRelation_application::write(m);
 | ||
|   if (err == NOERR)
 | ||
|     _emask->recalc_amm();
 | ||
|   return err;
 | ||
| }
 | ||
| 
 | ||
| int TMovicespi::rewrite(const TMask& m)
 | ||
| {
 | ||
|   int err = TRelation_application::rewrite(m);
 | ||
|   if (err == NOERR)
 | ||
|     _emask->recalc_amm();
 | ||
|   return err;
 | ||
| }
 | ||
| 
 | ||
| void TMovicespi::save_if_dirty() 
 | ||
| { 
 | ||
|   if (save(true))
 | ||
|     set_mode(MODE_MOD);
 | ||
| }
 | ||
| 
 | ||
| bool TMovicespi::remove()
 | ||
| {
 | ||
|   const TRectype& curr = get_relation()->curr();
 | ||
| 
 | ||
|   const TString16 idcespite = curr.get(MOVCE_IDCESPITE);
 | ||
|   const TString16 idmov = curr.get(MOVCE_IDMOV);
 | ||
|   kill_mov(idcespite, idmov, LF_MOVAM);
 | ||
|   kill_mov(idcespite, idmov, LF_AMMMV);
 | ||
|   kill_rett(idcespite, idmov);
 | ||
|   TRelation_application::remove();
 | ||
|    
 | ||
|   _emask->recalc_amm();
 | ||
| 
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| int ce1500(int argc, char* argv[])
 | ||
| {
 | ||
|   TMovicespi mc;
 | ||
|   mc.run(argc, argv, TR("Movimenti cespiti"));
 | ||
|   return 0;
 | ||
| }
 |