Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 01.05 patch 282 git-svn-id: svn://10.65.10.50/trunk@8058 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1033 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1033 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "dblib.h"
 | ||
| 
 | ||
| #include <automask.h>
 | ||
| #include <relapp.h>
 | ||
| #include <sheet.h>
 | ||
| #include <tabutil.h>
 | ||
| 
 | ||
| #include "db0.h"
 | ||
| #include "../mg/mglib.h"
 | ||
| #include "../mg/anamag.h"
 | ||
| 
 | ||
| #include "db0500a.h"
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Funzione di richiesta stringa che andra' in libreria
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| #include <defmask.h>
 | ||
| 
 | ||
| bool query_string(const char* prompt, TString& str, int width = 50, const char* flags= "")
 | ||
| {
 | ||
|   int maskwidth = width+2;
 | ||
|   if (maskwidth < 26) 
 | ||
|     maskwidth = 26;
 | ||
|   if (maskwidth > 78) 
 | ||
|     maskwidth = 78;
 | ||
| 
 | ||
|   TMask m(prompt, 1, maskwidth, 5);
 | ||
|   m.add_string(DLG_USER, 0, "", 1, 1, width, flags, width > 76 ? 76 : width);
 | ||
|   m.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
 | ||
|   m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
 | ||
|   m.set(DLG_USER, str);
 | ||
|   bool ok = m.run() == K_ENTER;
 | ||
|   if (ok)
 | ||
|     str = m.get(DLG_USER);
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TDistinta_app
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| class TQuery_mask;
 | ||
| class TDistinta_mask;
 | ||
| 
 | ||
| class TDistinta_app : public TRelation_application
 | ||
| {
 | ||
|   TDistinta_tree _tree;
 | ||
|   TRelation* _therel;
 | ||
|   TQuery_mask* _querymask;
 | ||
|   TDistinta_mask* _themask;
 | ||
|   int _mode;
 | ||
| 
 | ||
|   void parms2rel(const TMask& m);
 | ||
| 
 | ||
| protected:
 | ||
|   virtual void init_insert_mode(TMask &);
 | ||
|   virtual bool user_create();
 | ||
|   virtual bool user_destroy();
 | ||
|   virtual TRelation* get_relation() const { return _therel; }
 | ||
|   virtual bool changing_mask(int mode);
 | ||
|   virtual TMask* get_mask(int mode);
 | ||
|   virtual void init_query_mode(TMask& m);
 | ||
|   virtual int read(TMask& m);
 | ||
|   virtual int write(const TMask& m);
 | ||
|   virtual int rewrite(const TMask& m);
 | ||
|   virtual bool remove();
 | ||
| 
 | ||
| public:
 | ||
|   TRelation & relation() {return *_therel;}
 | ||
| };
 | ||
| 
 | ||
| TDistinta_app& app() 
 | ||
| { return (TDistinta_app&)main_app();}
 | ||
| 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TDistinta_sheet
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| 
 | ||
| class TDistinta_sheet : public TSheet
 | ||
| {
 | ||
|   TArray _data;
 | ||
| 
 | ||
| protected:
 | ||
|   virtual void get_row(long n, TToken_string& row);
 | ||
|   virtual long get_items() const { return _data.items(); }
 | ||
| 
 | ||
| public:
 | ||
|   TArray& rows_array() { return _data; }
 | ||
|   TDistinta_sheet();
 | ||
|   virtual ~TDistinta_sheet() { }
 | ||
| };
 | ||
| 
 | ||
| void TDistinta_sheet::get_row(long n, TToken_string& row)
 | ||
| {
 | ||
|   const TRiga_esplosione& re = (const TRiga_esplosione&)_data[int(n)];
 | ||
|   row.cut(0);
 | ||
|   row.add(re.tipo());
 | ||
|   row.add(re.articolo());
 | ||
|   row.add(re.giacenza());
 | ||
|   row.add(re.um());
 | ||
|   row.add(re.val().string(0, 5));
 | ||
|   row.add(re.livello());
 | ||
|   row.add(re.ordinamento());
 | ||
| }
 | ||
| 
 | ||
| TDistinta_sheet::TDistinta_sheet()
 | ||
| : TSheet(-1, -1, 0, 20, "Esplosione", "Tipo|Codice@20|Liv. Giacenza@15|UM|Quantita'@18R|Liv.@R|Sort@8R")
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TQuery_mask
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TQuery_mask : public TAutomask
 | ||
| {
 | ||
|   TDistinta_tree& _tree;
 | ||
|   TToken_string _curr;
 | ||
| 
 | ||
| protected:
 | ||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
| 
 | ||
| public:
 | ||
|   const TToken_string& curr() const { return _curr; }
 | ||
|   void restart_tree();
 | ||
| 
 | ||
|   TQuery_mask(TDistinta_tree& tree);
 | ||
|   virtual ~TQuery_mask() { }
 | ||
| };
 | ||
| 
 | ||
| void TQuery_mask::restart_tree()
 | ||
| {
 | ||
|   _tree.restart();
 | ||
|   while (!_tree.is_leaf())
 | ||
|   {
 | ||
|     _tree.expand();
 | ||
|     _tree.goto_firstson();
 | ||
|     if (_tree.has_rbrother())
 | ||
|       break;
 | ||
|   }
 | ||
| 
 | ||
|   TTree_field& tf = tfield(F_TREE);
 | ||
|   tf.win().update_thumb(0, 0);
 | ||
|   tf.win().force_update();
 | ||
| }
 | ||
| 
 | ||
| bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   switch (o.dlg())
 | ||
|   {
 | ||
|   case F_CODICE:
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       TTree_field& tf = tfield(F_TREE);
 | ||
|       const TCodice_articolo val = o.get();
 | ||
|       if (val.not_empty() && _tree.has_root())
 | ||
|       {
 | ||
|         long pos = _tree.find_node(val);
 | ||
|         if (pos <= 0)
 | ||
|         {
 | ||
|           if (_tree.set_root(val))
 | ||
|             restart_tree();
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|           tf.select_current();
 | ||
|           do { _tree.expand(); } while (_tree.goto_father());
 | ||
|           pos = _tree.find_node(val, SCAN_PRE_ORDER | SCAN_IGNORING_UNEXPANDED);
 | ||
| 
 | ||
|           TField_window& win = tf.win();
 | ||
|           const TPoint& range = win.range();
 | ||
|           if (pos > range.y)
 | ||
|             win.set_scroll_max(win.columns(), pos+win.rows());
 | ||
| 
 | ||
|           win.update_thumb(-1, pos-1);
 | ||
|           win.force_update();
 | ||
|           tf.set_focus();
 | ||
|         }
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         if (_tree.set_root(val))
 | ||
|           restart_tree();
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_SORT:
 | ||
|     if (e == fe_init || e == fe_modify)
 | ||
|     {
 | ||
|       int sk = atoi(o.get());
 | ||
|       if (sk >= 0 && sk <= 5)
 | ||
|       {
 | ||
|         _tree.set_sort_key(sk);
 | ||
|         if (e == fe_modify)
 | ||
|           restart_tree();
 | ||
|       }
 | ||
|       else
 | ||
|         error_box("Chiave di ordinamento errata: %d", sk);
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_TREE:
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       _tree.curr_id(_curr);
 | ||
|       TCodice_articolo code; _tree.curr_code(code);
 | ||
|       set(F_CODICE, code);
 | ||
|     }
 | ||
|     break;
 | ||
|   case DLG_SELECT:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       const TString& str = get(F_CODICE);
 | ||
|       if (str.not_empty())
 | ||
|         set(F_CODICEQ, str);
 | ||
|       else
 | ||
|         return FALSE;
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_COPY:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       const TString oldcode = get(F_CODICE); 
 | ||
|       TLocalisamfile dist(LF_DIST);
 | ||
|       dist.put("CODDIST", oldcode);
 | ||
|       if (dist.read() == NOERR)
 | ||
|       {
 | ||
|         TString newcode;
 | ||
|         if (query_string("Nuovo codice", newcode, 20, "U"))
 | ||
|         {
 | ||
|           if (newcode.not_empty() && newcode != oldcode)  
 | ||
|           {
 | ||
|             dist.put("CODDIST", newcode);
 | ||
|             TString environment=dist.get("PARAMETRI");
 | ||
|             const int err = dist.write();
 | ||
|             if (err == NOERR)
 | ||
|             {                
 | ||
|               // copia le righe di distinta
 | ||
|               TRecord_array rdist(LF_RDIST, "NRIG");
 | ||
|               rdist.renum_key("CODDIST", oldcode);
 | ||
|               if (rdist.read(rdist.key()) == NOERR)
 | ||
|               {
 | ||
|                 rdist.renum_key("CODDIST", newcode);
 | ||
|                 rdist.write();
 | ||
|               }
 | ||
|               // copia le righe delle UM
 | ||
|               TRecord_array um(LF_UMART, "NRIGA");
 | ||
|               um.renum_key("CODART", newcode);
 | ||
|               int err=um.read(um.key()) ;
 | ||
|               if (um.rows() == 0)
 | ||
|                 err = _iskeynotfound;
 | ||
|               switch (err)
 | ||
|               {
 | ||
|                 case _isemptyfile:
 | ||
|                 case _iskeynotfound:
 | ||
|                   um.renum_key("CODART", oldcode);
 | ||
|                   if (um.read(um.key()) == NOERR )
 | ||
|                   {
 | ||
|                     um.renum_key("CODART", newcode);
 | ||
|                     um.write();
 | ||
|                   }
 | ||
|                   break;
 | ||
|                 case NOERR:
 | ||
|                   dist.put("UM", um.row(1).get("UM"));
 | ||
|                   break;
 | ||
|               } 
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|               if (err == _isreinsert)
 | ||
|                 error_box("La distinta '%s' e' gia' stata inserita", (const char*)newcode);
 | ||
|               else
 | ||
|                 error_box("Errore %d durante la registrazione della distinta '%s'", err, (const char*)newcode);
 | ||
|             }
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|       else
 | ||
|         error_box("Il codice '%s' non corrisponde ad una distinta valida", (const char*)oldcode);
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_EXPLODE:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       TCodice_articolo art = get(F_CODICE);
 | ||
|       if (art.not_empty())
 | ||
|       {
 | ||
|         _tree.set_root(art);
 | ||
|         restart_tree();
 | ||
|       }
 | ||
|       if (_tree.goto_root())
 | ||
|       {
 | ||
|         _tree.curr_code(art);
 | ||
|         TString80 caption;
 | ||
|         caption << "Esplosione " << art;
 | ||
|         
 | ||
|         TMask m("db0500c");
 | ||
|         m.set_caption(caption);
 | ||
|         m.set(F_SORT, get(F_SORT));
 | ||
|         m.set(F_ARTICOLI, "X");
 | ||
|         m.set(F_LAVORAZIONI, "X");
 | ||
|         m.set(F_VIRTUALI, "X");
 | ||
|         if (m.run() == K_ENTER)
 | ||
|         {   
 | ||
|           TDistinta_sheet a;
 | ||
|           a.set_caption(caption);
 | ||
|           int sk = m.get_int(F_SORT);
 | ||
|           int md = m.get_int(F_MAXDEPTH);
 | ||
|           TExplosion_grouping gr = TExplosion_grouping(m.get_int(F_GROUPMODE));
 | ||
|           bool mb = m.get_bool(F_MATBASE);
 | ||
|           
 | ||
|           TString16 fi;
 | ||
|           if (m.get_bool(F_ARTICOLI))    fi << 'A';
 | ||
|           if (m.get_bool(F_LAVORAZIONI)) fi << 'L';
 | ||
|           if (m.get_bool(F_VIRTUALI))    fi << 'V';
 | ||
|           if (m.get_bool(F_GHOST))       fi << 'G';
 | ||
|           
 | ||
|           _tree.explode(a.rows_array(), mb, gr, md, fi, sk);
 | ||
|           a.run();
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_VAR_IMPIANTO:
 | ||
|     if (e == fe_modify || e == fe_init)
 | ||
|     {
 | ||
|       _tree.set_global("_IMPIANTO",o.get());
 | ||
|       if (_tree.goto_root())
 | ||
|         restart_tree();
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_HIDE_GHOST:
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       const char ig=*o.get();
 | ||
|       _tree.set_ignore_ghost(ig > ' ');
 | ||
|       if (_tree.goto_root())
 | ||
|         restart_tree();
 | ||
|     }
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| TQuery_mask::TQuery_mask(TDistinta_tree& dt) 
 | ||
|            : TAutomask("db0500a"), _tree(dt)
 | ||
| { 
 | ||
|   TTree_field& tree = tfield(F_TREE);
 | ||
|   tree.set_tree(&_tree);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TDistinta_mask
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TDistinta_mask : public TAutomask
 | ||
| {
 | ||
|   TDistinta_tree& _tree;
 | ||
| 
 | ||
|   void set_um_rif(int row);
 | ||
|  
 | ||
|   bool on_distsheet_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|   bool on_unitsheet_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|   bool on_parmsheet_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|  
 | ||
| protected:
 | ||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|   bool test_row(const TToken_string& row);
 | ||
|   void load_um();
 | ||
| 
 | ||
| public:
 | ||
|   TDistinta_mask(TDistinta_tree& dt);
 | ||
|   virtual ~TDistinta_mask() { }
 | ||
| };
 | ||
| 
 | ||
| void TDistinta_mask::load_um()
 | ||
| {
 | ||
|   // *****************************
 | ||
|   // LETTURA SHEET UNITA' DI MISURA
 | ||
|   char tree_type=_tree.get_type(get(F_CODICE));
 | ||
| 
 | ||
|   TSheet_field &units= (TSheet_field &)field(F_UNITA); // prende lo sheet delle unit<69> di misura
 | ||
|   if (tree_type=='L')
 | ||
|   {
 | ||
|     units.destroy();
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     app().relation().lfile().put("CODDIST",get(F_CODICE));
 | ||
|     units.record()->read(*units.putkey(app().relation()));
 | ||
|     units.autoload(app().relation());
 | ||
|   }
 | ||
|   units.disable_cell(0, units.cid2index(FU_FC));
 | ||
|   const bool virtuale=tree_type!='A' && tree_type !='L';
 | ||
|   units.enable_column(units.cid2index(FU_UM),virtuale);
 | ||
|   units.enable_column(units.cid2index(FU_DESC),virtuale);
 | ||
|   units.enable_column(units.cid2index(FU_FC),virtuale);
 | ||
|   units.enable_column(units.cid2index(FU_PREZZO),virtuale);
 | ||
|   if (units.items()==0)
 | ||
|     units.row(0) << get(F_UM) << "|1"; // aggiunge una riga allo sheet
 | ||
|   if (units.items()==1)
 | ||
|   {
 | ||
|     set(F_UM,units.cell(0,units.cid2index(FU_UM)));
 | ||
|     set(F_UMART1ST,get(F_UM));
 | ||
|   }
 | ||
|   TString16 um;
 | ||
|   FOR_EACH_SHEET_ROW_BACK(units, u, urow)
 | ||
|   {
 | ||
|     urow->get(units.cid2index(FU_UM), um);
 | ||
|     if (!um.blank() && um == get(F_UM))
 | ||
|     {
 | ||
|       set_um_rif(u);
 | ||
|       break;
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| bool TDistinta_mask::test_row(const TToken_string& row)
 | ||
| {
 | ||
|   const TCodice_articolo father = get(F_CODICE);
 | ||
| 
 | ||
|   TCodice_articolo code; row.get(1, code);
 | ||
|   bool ok = code != father;
 | ||
|   if (ok && _tree.find_node(father) > 0)
 | ||
|   {
 | ||
|     TToken_string path; _tree.curr_id(path);
 | ||
|     path.add(code);
 | ||
|     ok = !_tree.is_cyclic(path);
 | ||
|   }
 | ||
|   if (!ok)
 | ||
|     error_box("Il codice '%s' non puo' essere utilizzato\n"
 | ||
|               "in quanto la distinta risulterebbe ciclica.", (const char*)code);
 | ||
| 
 | ||
|   // Se e' una lavorazione
 | ||
|   if (get(F_TIPO)[0] == 'L')
 | ||
|   {
 | ||
|     ok = row[0] == 'L' && _tree.is_lav(code);
 | ||
|     if (!ok)
 | ||
|       error_box("Il codice '%s' non e' una lavorazione", (const char*)code);
 | ||
|   }
 | ||
| 
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| // Forza la riga row ad essere quella dell'unita' di distinta
 | ||
| void TDistinta_mask::set_um_rif(int row)
 | ||
| {
 | ||
|   TSheet_field& sht = sfield(F_UNITA);
 | ||
|   const int chk = sht.cid2index(FU_RIF);
 | ||
|   const int fc = sht.cid2index(FU_FC);
 | ||
|   const int cod = sht.cid2index(FU_UM);
 | ||
|   TToken_string& first = sht.row(row);
 | ||
|   first.add("X", chk);
 | ||
|   set(F_UM, first.get(cod), TRUE);
 | ||
|   set(F_FCUMART, first.get(fc), TRUE);
 | ||
|   sht.force_update(row);
 | ||
| }
 | ||
| 
 | ||
| bool TDistinta_mask::on_unitsheet_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   static bool was_checked = FALSE;
 | ||
| 
 | ||
|   TSheet_field& sht = (TSheet_field&)o;
 | ||
|   const int chk = sht.cid2index(FU_RIF);
 | ||
|   const int cod = sht.cid2index(FU_UM);
 | ||
| 
 | ||
|   switch(e)
 | ||
|   {
 | ||
|   case se_query_modify:
 | ||
|     sht.sheet_mask().enable(DLG_DELREC, jolly > 0L);
 | ||
|     was_checked = *sht.cell(int(jolly), chk) > ' ';
 | ||
|     break;
 | ||
|   case se_query_del:
 | ||
|     return get_bool(F_VIRTUALE) && jolly > 0L;  // Impedisce di cancellare l'unita' di misura base
 | ||
|   case se_notify_del:
 | ||
|     if (was_checked)
 | ||
|       set_um_rif(0);
 | ||
|     break;
 | ||
|   case se_notify_modify:
 | ||
|     {
 | ||
|       const bool is_checked = *sht.cell(int(jolly), chk) > ' ';
 | ||
|       if (is_checked != was_checked)
 | ||
|       {
 | ||
|         if (was_checked)
 | ||
|           set_um_rif(0);
 | ||
|         else
 | ||
|         {
 | ||
|           FOR_EACH_SHEET_ROW(sht, r, row)
 | ||
|           {
 | ||
|             if (r == jolly)
 | ||
|               set_um_rif(r);
 | ||
|             else
 | ||
|             {
 | ||
|               if (*row->get(chk) > ' ')
 | ||
|               {
 | ||
|                 row->add(" ", chk);
 | ||
|                 sht.force_update(r);
 | ||
|               }
 | ||
|             }
 | ||
|           }
 | ||
|         }
 | ||
|         was_checked = is_checked;
 | ||
|       }
 | ||
|       if (jolly == 0L)
 | ||
|         set(F_UMART1ST,sht.cell(0,sht.cid2index(FU_UM)));
 | ||
|     }
 | ||
|     break;
 | ||
|   case se_query_add:
 | ||
|     if (!get_bool(F_VIRTUALE))
 | ||
|       return FALSE;
 | ||
|     break;
 | ||
|   case se_notify_add:
 | ||
|     if (jolly == 0L)
 | ||
|     {
 | ||
|       const int fc = sht.cid2index(FU_FC);
 | ||
|       sht.disable_cell(0, fc);
 | ||
|       sht.row(0).add("1", fc);
 | ||
|     }
 | ||
|     break;
 | ||
|   case fe_close:
 | ||
|     if (sht.items() == 0 || *sht.cell(0,0)<=' ')
 | ||
|       return sht.error_box("E' necessario specificare l'unita' di misura principale");
 | ||
|     break;
 | ||
|   default: break;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TDistinta_mask::on_distsheet_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   const short id = o.dlg();
 | ||
|   switch (id)
 | ||
|   {
 | ||
|   case F_SHEET:
 | ||
|     if (e == se_notify_add || e == se_notify_modify || e == fe_close)
 | ||
|     {
 | ||
|       TSheet_field& sheet = (TSheet_field&)o;
 | ||
|       const int nrig = int(jolly);
 | ||
|       TToken_string& row = sheet.row(nrig);
 | ||
|       switch(e)
 | ||
|       {
 | ||
|       case se_notify_add:
 | ||
|         row.add("A", F_TIPOCOMP-FIRST_FIELD); // Forza il listbox ad articolo
 | ||
|         row.add("", F_EXPR-FIRST_FIELD);     // Forza la quantita' ad 1
 | ||
|         row.add(nrig+1, F_SORT0-FIRST_FIELD); // Inizializza numero riga
 | ||
|         sheet.set_focus_cell(nrig,F_TIPOCOMP-FIRST_FIELD);
 | ||
|         break;
 | ||
|       case se_notify_modify:
 | ||
|         return test_row(row);
 | ||
|       case fe_close:
 | ||
|         {
 | ||
|           TString80 code;
 | ||
|           for (int n = sheet.items()-1; n >= 0; n--)
 | ||
|           {
 | ||
|             const TToken_string& row = sheet.row(n);
 | ||
|             row.get(F_CODART-FIRST_FIELD, code);
 | ||
|             if (!code.blank())
 | ||
|             {
 | ||
|               if (!test_row(row))
 | ||
|                 return FALSE;
 | ||
|             }
 | ||
|             else
 | ||
|               sheet.destroy(n);
 | ||
|           }
 | ||
|         }
 | ||
|         if (sheet.items() == 0)
 | ||
|           error_box("E' necessario inserire almeno una riga nella distinta");
 | ||
|         break;
 | ||
|       default:
 | ||
|         break;
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_CODART:
 | ||
|   case F_CODLAV:
 | ||
|   case F_CODDIS:
 | ||
|   case F_CODVAR:
 | ||
|     if (e == fe_modify || e == fe_init)
 | ||
|     {
 | ||
|       TMask& m = o.mask();
 | ||
|       const TEdit_field& ef = (const TEdit_field&)o;
 | ||
|       const TRectype& rec = ef.browse()->cursor()->curr();
 | ||
|       switch(rec.num())
 | ||
|       {
 | ||
|       case LF_ANAMAG:
 | ||
|         m.set(F_DESCOMP, rec.get(ANAMAG_DESCR));
 | ||
|         if (m.get(F_UMEXPR).empty())
 | ||
|         {
 | ||
|           const TCodice_articolo art = o.get();
 | ||
|           if (art.not_empty() && _tree.is_mag(art))
 | ||
|           {
 | ||
|             TCodice_um um = "$$"; // Unita' distinta
 | ||
|             TQuantita qta(art, um, ZERO);    
 | ||
|             m.set(F_UMEXPR, qta.um());
 | ||
|           }
 | ||
|         }
 | ||
|         break;
 | ||
|       case LF_DIST  :
 | ||
|         m.set(F_DESCOMP, rec.get("DESCR"));
 | ||
|         //m.set(F_UMEXPR, rec.get("UM"));
 | ||
|         break;
 | ||
|       default       :
 | ||
|         m.set(F_DESCOMP, rec.get("S0"));
 | ||
|         m.set(F_UMEXPR, rec.get("S6"));
 | ||
|         break;
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_EXPR:
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       TAutomask& m = (TAutomask&)o.mask();
 | ||
|       const TString& str = o.get();
 | ||
|       if (str.not_empty())
 | ||
|       {
 | ||
|         TDistinta_expr expr;
 | ||
|         if (expr.set(str))
 | ||
|         {
 | ||
|           if (expr.numvar() > 0)
 | ||
|           {
 | ||
|             TDecoder var("VAR");
 | ||
|             for (int v = expr.numvar()-1; v >= 0; v--)
 | ||
|             {
 | ||
|               const char* name = expr.varname(v);
 | ||
|               if (var.decode(name).empty())
 | ||
|                 return m.error_box("La variabile %s non e' definita in tabella", name);
 | ||
|             }
 | ||
|           }
 | ||
|           else
 | ||
|             o.set(expr.as_string());
 | ||
|         }
 | ||
|         else
 | ||
|           return m.error_box("Errore di sintassi: %s", expr.last_token());
 | ||
|       }
 | ||
|       else
 | ||
|         return m.error_box("L'espressione deve essere specificata");
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_SORT1:
 | ||
|   case F_SORT2:
 | ||
|   case F_SORT3:
 | ||
|   case F_SORT4:
 | ||
|   case F_SORT5:
 | ||
|     if ((fe_modify || fe_close) && o.empty())
 | ||
|     {
 | ||
|       TString16 key; key << (o.dlg() - F_SORT1 + 1);
 | ||
|       bool completo = cache().get("ORD", key).get_bool("B0");
 | ||
|       if (completo)
 | ||
|       {
 | ||
|         TAutomask& m = (TAutomask&)o.mask();
 | ||
|         TSheet_field& s = *m.get_sheet();
 | ||
|         return m.error_box("Specificare l'ordinamento %s alla riga %d",
 | ||
|                            (const char*)key, s.selected()+1);
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TDistinta_mask::on_parmsheet_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   const short id = o.dlg();
 | ||
|   switch (id)
 | ||
|   {
 | ||
|   case FV_PARAM:
 | ||
|     if (e == fe_modify || e == fe_close)
 | ||
|     {
 | ||
|       const TString& str = o.get();
 | ||
|       if (!isalpha(str[0]) && str[0] != '_')
 | ||
|         return error_box("Il nome del parametro deve iniziare con un carattere alfabetico o con _");
 | ||
|       for (const char* s = str; *s; s++)
 | ||
|       {
 | ||
|         if (!isalnum(*s) && *s != '_')
 | ||
|           return error_box("Il nome del parametro puo' contenere solo caratteri alfanumerici o _");
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| static _sort_key = 0;
 | ||
| 
 | ||
| static int compare_sheet_rows(const TObject** o1, const TObject** o2)
 | ||
| {
 | ||
|   TToken_string* s1 = (TToken_string*)*o1;
 | ||
|   TToken_string* s2 = (TToken_string*)*o2;
 | ||
| 
 | ||
|   const int key_pos = (_sort_key ? (F_SORT1+_sort_key-1) : F_SORT0) - FIRST_FIELD;
 | ||
|   long k1 = s1->get_long(key_pos);
 | ||
|   long k2 = s2->get_long(key_pos);
 | ||
| 
 | ||
|   if (k1 == 0) k1 = 100000000L;
 | ||
|   if (k2 == 0) k2 = 100000000L;
 | ||
| 
 | ||
|   return k1 == k2 ? 0 : (k1 > k2 ? +1 : -1);
 | ||
| }
 | ||
| 
 | ||
| bool TDistinta_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   const short id = o.dlg();
 | ||
|   switch (id)
 | ||
|   {
 | ||
|   case F_CODICE:
 | ||
|     if (e == fe_init)
 | ||
|     {
 | ||
|       const TString& code = o.get();
 | ||
|       if (code.not_empty())
 | ||
|       {
 | ||
|         const char type = _tree.get_type(code);
 | ||
|         switch(type)
 | ||
|         {
 | ||
|         case 'A':
 | ||
|           {
 | ||
|             set(F_TIPO, "A", TRUE);     
 | ||
|           
 | ||
|             TArticolo mag (code);        
 | ||
|             set(F_DESCR, mag.get(ANAMAG_DESCR));
 | ||
|             set(F_PREZZO, mag.get(ANAMAG_COSTSTD));
 | ||
|             set(F_PESO, mag.get(ANAMAG_PESO));
 | ||
|             set(F_UMP, mag.get(ANAMAG_UMP));
 | ||
|           }
 | ||
|           break;
 | ||
|         case 'L':
 | ||
|           {
 | ||
|             set(F_TIPO, "L", TRUE);     
 | ||
|             TTable lav("LAV");
 | ||
|             lav.put("CODTAB", code);
 | ||
|             if (lav.read() == NOERR)
 | ||
|             {
 | ||
|               set(F_DESCR, lav.get("S0"));
 | ||
|               set(F_UM, lav.get("S6"));
 | ||
|               set(F_PREZZO, lav.get("R0"));
 | ||
|             }
 | ||
|           }
 | ||
|           break;
 | ||
|         default:
 | ||
|           set(F_TIPO, "V", TRUE);     
 | ||
|           break;
 | ||
|         }
 | ||
|         load_um();
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_SORT:
 | ||
|     if (e == fe_modify || e == fe_close)
 | ||
|     {
 | ||
|       TSheet_field& sf = sfield(F_SHEET);
 | ||
|       _sort_key = atoi(o.get());
 | ||
|       if (e == fe_close && _sort_key > 0)
 | ||
|       {
 | ||
|         if (yesno_box("Attenzione, l'ordine di immissione verra' modificato:\n"
 | ||
|                       "Si desidera registrare secondo l'ordinamento %d?", _sort_key))
 | ||
|           break;
 | ||
|         else
 | ||
|           _sort_key = 0;
 | ||
|         o.reset();
 | ||
|       }
 | ||
|       TString_array& a = sf.rows_array();
 | ||
|       a.TArray::sort(compare_sheet_rows);
 | ||
|       sf.force_update();
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_UNITA:
 | ||
|     return on_unitsheet_event(o, e, jolly);
 | ||
|   case F_SHEET:
 | ||
|     return on_distsheet_event(o, e, jolly);
 | ||
|   default:
 | ||
|     if (id >= 101 && id < 500)   // E' in uno sheet?
 | ||
|     {
 | ||
|       switch (jolly)
 | ||
|       {
 | ||
|       case 1 : return on_distsheet_event(o, e, jolly);
 | ||
|       case 2 : return on_parmsheet_event(o, e, jolly);
 | ||
|       default: break;
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| TDistinta_mask::TDistinta_mask(TDistinta_tree& dt) 
 | ||
|               : TAutomask("db0500b"), _tree(dt)
 | ||
| { 
 | ||
|   TSheet_field& sf = sfield(F_SHEET);
 | ||
|   sf.set_append(FALSE);
 | ||
|   TMask& sm = sf.sheet_mask();
 | ||
|   TString16 key;
 | ||
|   int i;
 | ||
|   for (i = 4; i >= 0; i--)
 | ||
|   {
 | ||
|     key.format("%d", i+1);
 | ||
|     const bool kill = cache().get("ORD",key).empty();
 | ||
|     if (kill)
 | ||
|     {
 | ||
|       const short id = F_SORT1+i;
 | ||
|       sm.hide(id);
 | ||
|       sf.delete_column(id);
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   TCodgiac_livelli cgl;
 | ||
|   for (i = 4; i > 0; i--)
 | ||
|   {
 | ||
|     const short id = F_LIV1+i-1;
 | ||
|     cgl.set_sheetcolumn(sf,id,i);
 | ||
|   }
 | ||
|   TSheet_field& su = sfield(F_UNITA);
 | ||
|   su.set_lines_record(*(new TRecord_array(LF_UMART, "NRIGA")));
 | ||
| 
 | ||
|   cache().test_file_changes(LF_TAB);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TDistinta_app
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| bool TDistinta_app::user_create()
 | ||
| {
 | ||
|   _therel = new TRelation(LF_DIST);
 | ||
|   _querymask = new TQuery_mask(_tree);
 | ||
|   _themask = new TDistinta_mask(_tree);
 | ||
| 
 | ||
| /*
 | ||
|   if (noyes_box("Rinumero le righe delle distinte?"))
 | ||
|   if (noyes_box("Sicuro?"))
 | ||
|   if (noyes_box("Sicuro sicuro?"))
 | ||
|   if (noyes_box("Sicuro sicuro sicuro?"))
 | ||
|   {
 | ||
|     int err;
 | ||
|     TString cod="";int nrig;
 | ||
|     TLocalisamfile rdist(LF_RDIST);
 | ||
|     err = rdist.read(_isfirst);
 | ||
|     while (err == NOERR)  
 | ||
|     {
 | ||
|       if (cod != rdist.get("CODDIST"))
 | ||
|       {
 | ||
|         cod = rdist.get("CODDIST");
 | ||
|         nrig=1;
 | ||
|       }
 | ||
|       rdist.put("SORT1",nrig);
 | ||
|       rdist.rewrite();
 | ||
|       rdist.put("NRIG",rdist.get_int("NRIG")+1);
 | ||
|       err = rdist.read(_isgteq);
 | ||
|       nrig++;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   if (noyes_box("Rinumero le unita' di misura articoli?"))
 | ||
|   if (noyes_box("Sicuro?"))
 | ||
|   if (noyes_box("Sicuro sicuro?"))
 | ||
|   if (noyes_box("Sicuro sicuro sicuro?"))
 | ||
|   {
 | ||
|     int err;
 | ||
|     TString cod="";int nrig;
 | ||
|     TLocalisamfile umart(LF_UMART);
 | ||
|     err = umart.read(_isfirst);
 | ||
|     while (err == NOERR)  
 | ||
|     {
 | ||
|       if (cod != umart.get("CODART"))
 | ||
|       {
 | ||
|         cod = umart.get("CODART");
 | ||
|         nrig=1;
 | ||
|       }
 | ||
|       umart.put("PREZZO",nrig);
 | ||
|       umart.rewrite();
 | ||
|       umart.put("NRIGA",umart.get_int("NRIGA")+1);
 | ||
|       err = umart.read(_isgteq);
 | ||
|       nrig++;
 | ||
|     }
 | ||
|   }
 | ||
| */
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TDistinta_app::user_destroy()
 | ||
| {
 | ||
|   delete _themask;
 | ||
|   delete _querymask;
 | ||
|   delete _therel;
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| void TDistinta_app::init_insert_mode(TMask &m)
 | ||
| {
 | ||
|   TSheet_field &f= (TSheet_field &)m.field(F_UNITA);
 | ||
|   if (f.items() == 0)
 | ||
|     f.row(0) = " |1"; // aggiunge una riga allo sheet
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| bool TDistinta_app::changing_mask(int mode)
 | ||
| {
 | ||
|   bool was_query = _mode == MODE_QUERY || _mode == MODE_QUERYINS;
 | ||
|   bool is_query = mode == MODE_QUERY || mode == MODE_QUERYINS;
 | ||
|   return was_query != is_query;
 | ||
| }
 | ||
| 
 | ||
| TMask* TDistinta_app::get_mask(int mode)
 | ||
| {
 | ||
|   const bool is_query = mode == MODE_QUERY || mode == MODE_QUERYINS;
 | ||
|   _mode = mode;
 | ||
|   return is_query ? (TMask*)_querymask : (TMask*)_themask;
 | ||
| }
 | ||
| 
 | ||
| void TDistinta_app::init_query_mode(TMask& m)
 | ||
| {
 | ||
|   ((TQuery_mask&)m).restart_tree();
 | ||
| }
 | ||
| 
 | ||
| int TDistinta_app::read(TMask& m)
 | ||
| {
 | ||
|   const int err = TRelation_application::read(m);
 | ||
| 
 | ||
|   if (err == NOERR)
 | ||
|   {
 | ||
|     TSheet_field& sheet = m.sfield(F_SHEET);
 | ||
|     FOR_EACH_SHEET_ROW(sheet, nrig, row)
 | ||
|     {
 | ||
|       sheet.check_row(nrig);
 | ||
|       sheet.row(nrig).add(nrig+1, sheet.cid2index(F_SORT0));
 | ||
|     }
 | ||
| 
 | ||
|     TToken_string memo(1024, '\n');
 | ||
|     memo = _therel->curr().get("PARAMETRI");
 | ||
|     const int righe = memo.items();
 | ||
|     TSheet_field& params = m.sfield(F_PARAMS);
 | ||
|     params.destroy();
 | ||
|     for (int i = 0; i < righe; i++)
 | ||
|     {
 | ||
|       TToken_string& row = params.row(i);
 | ||
|       memo.get(i, row);
 | ||
|       int equal = row.find('=');
 | ||
|       if (equal > 0)
 | ||
|         row[equal] = '|';
 | ||
|     }
 | ||
|   }
 | ||
|   
 | ||
|   return err;
 | ||
| }
 | ||
| 
 | ||
| void TDistinta_app::parms2rel(const TMask& m)
 | ||
| {
 | ||
|   TToken_string memo(1024, '\n');
 | ||
|   TSheet_field& parms = m.sfield(F_PARAMS);
 | ||
|   TString var;
 | ||
|   FOR_EACH_SHEET_ROW(parms, r, row)
 | ||
|   {
 | ||
|     var = row->get(0);
 | ||
|     if (!var.blank())
 | ||
|     {
 | ||
|       memo.add(var);
 | ||
|       memo << '=';
 | ||
|       memo << row->get();
 | ||
|     }
 | ||
|   }
 | ||
|   _therel->curr().put("PARAMETRI", memo);
 | ||
| 
 | ||
|   // Azzera albero per rispecchiare eventuali modifiche
 | ||
|   _querymask->restart_tree();
 | ||
| }
 | ||
| 
 | ||
| int TDistinta_app::write(const TMask& m)
 | ||
| {
 | ||
|   parms2rel(m);
 | ||
|   int err = TRelation_application::write(m);
 | ||
|   if (err == NOERR)
 | ||
|   {
 | ||
|     TSheet_field& f = m.sfield(F_UNITA); // prende lo sheet delle unit<69> di misura
 | ||
|     err = f.record()->write(FALSE);
 | ||
|   }
 | ||
|   return err;  
 | ||
| }
 | ||
| 
 | ||
| int TDistinta_app::rewrite(const TMask& m)
 | ||
| {
 | ||
|   parms2rel(m);
 | ||
|   int err = TRelation_application::rewrite(m);
 | ||
|   if (err == NOERR)
 | ||
|   {
 | ||
|     TSheet_field& f= m.sfield(F_UNITA); // prende lo sheet delle unit<69> di misura
 | ||
|     err = f.record()->write(TRUE);
 | ||
|   }
 | ||
|   return err;  
 | ||
| }
 | ||
| 
 | ||
| bool TDistinta_app::remove()
 | ||
| {
 | ||
|   bool ok = TRelation_application::remove();
 | ||
|   if (ok)
 | ||
|   {
 | ||
|     TMask &m=curr_mask();
 | ||
|     TSheet_field &f= (TSheet_field &)m.field(F_UNITA); // prende lo sheet delle unit<69> di misura
 | ||
|     TLocalisamfile anamag(LF_ANAMAG);
 | ||
|     anamag.put("CODART",m.get(F_CODICE));
 | ||
|     int err=anamag.read();// esiste l'articolo
 | ||
|     switch(err)
 | ||
|     { 
 | ||
|       case _iskeynotfound :
 | ||
|       case _isemptyfile :
 | ||
|       case _iseof:
 | ||
|         ok = f.record()->remove()==NOERR;
 | ||
|         break;
 | ||
|       default:
 | ||
|         break;
 | ||
|     }
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // db0500 gestione distinte
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| int db0500(int argc, char* argv[])
 | ||
| {
 | ||
|   TDistinta_app a;
 | ||
|   a.run(argc, argv, "Distinta base");
 | ||
|   return 0;
 | ||
| }
 |