Files correlati : ve6.exe Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 979 git-svn-id: svn://10.65.10.50/trunk@15623 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1069 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1069 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| // gestione livelli di giacenza e articoli
 | ||
| // oggetto movimento di magazzino
 | ||
| // funzione di ricostruzione saldi
 | ||
| 
 | ||
| #include <applicat.h>
 | ||
| #include <execp.h>
 | ||
| #include <msksheet.h>
 | ||
| #include <tabutil.h>
 | ||
| 
 | ||
| #include "mglib.h"
 | ||
| 
 | ||
| // *******************************
 | ||
| // *******************************
 | ||
| #define MAXSIMBOLS 256
 | ||
| #define MAXSTATES 25
 | ||
| class TStateset
 | ||
| {
 | ||
|   unsigned char _container[MAXSTATES];
 | ||
|   int _current;
 | ||
| public:
 | ||
|   TStateset & empty();
 | ||
|   TStateset & enclose(int e);
 | ||
|   TStateset & singleton(int e);
 | ||
|   TStateset & cap(TStateset & s);
 | ||
|   int get_first() ;
 | ||
|   int get_next() ;
 | ||
|   bool is_empty() const;
 | ||
|   bool is_member(int e) const;
 | ||
|   TStateset();  
 | ||
|   ~TStateset() {};  
 | ||
| };
 | ||
| 
 | ||
| struct TAutoma_state
 | ||
| {
 | ||
|   short _transaction[MAXSIMBOLS];
 | ||
|   TString80 * _label;
 | ||
|   bool _final;
 | ||
| };
 | ||
| 
 | ||
| // *******************************
 | ||
| // *******************************
 | ||
| // automa per il riconoscimento di metacaratteri
 | ||
| #define EPSILON 0
 | ||
| #define FIRST_STATE 1
 | ||
| #define FIRST_NEMPTY_SYMBOL 1
 | ||
| 
 | ||
| // *******************************
 | ||
| // *******************************
 | ||
| // automa per il riconoscimento di metacaratteri
 | ||
| class TR_automa
 | ||
| {
 | ||
|   TAutoma_state st[MAXSTATES];
 | ||
|   short _maxstate;
 | ||
| protected:  
 | ||
|   TStateset union_of_closures(TStateset &s);
 | ||
| 
 | ||
|   bool is_final(int statenum) const;
 | ||
|   bool is_final(TStateset states) const;
 | ||
| 
 | ||
|   TR_automa & set_label(int statenum, const char *label);
 | ||
|   bool is_state(int statenum);
 | ||
|   const char *label(int statenum);
 | ||
|   int label2state(const char * label);
 | ||
| 
 | ||
|   void del_trans(int statenum,unsigned char symbol);
 | ||
|   int trans_to(int statenum,unsigned char symbol);
 | ||
|   bool _isdeterministic;
 | ||
|   
 | ||
| public:
 | ||
|   TR_automa & reset_state(int statenum=-1);
 | ||
| 
 | ||
|   void add_tran(int statenum,unsigned char symbol,int next);// aggiunge una transizione
 | ||
|   int add_state(const char * label);// aggiunge uno stato
 | ||
|   TR_automa & set_final(int statenum,bool v=TRUE); // pone lo stato come finale
 | ||
| 
 | ||
|   bool is_deterministic() {return _isdeterministic;}; // 
 | ||
|   bool recognized(const char * s);          // tenta di riconoscere la stringa passata
 | ||
| 
 | ||
|   TR_automa(TR_automa *a=NULL,bool makedet=FALSE); // duplica un automa (e lo rende deterministico)
 | ||
|   ~TR_automa();
 | ||
|   static void set2label(const TStateset ss,TString & label);
 | ||
|   static void label2set(const TString & label,TStateset & ss);
 | ||
| 
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| // *******************************
 | ||
| TStateset::TStateset()
 | ||
| { 
 | ||
|   empty();
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::empty()
 | ||
| {
 | ||
|   _current=0;
 | ||
|   for (int i= 0; i< MAXSTATES; _container[i++]=0);
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::enclose(int el)
 | ||
| {
 | ||
|   if (el< MAXSTATES && el>=0)
 | ||
|     _container[el]=1;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::singleton(int el)
 | ||
| {
 | ||
|   empty();
 | ||
|   _container[el]=1;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::cap(TStateset & s)
 | ||
| {
 | ||
|   for (int i= 0; i< MAXSTATES; i++)
 | ||
|     _container[i]|=s._container[i];
 | ||
|   return *this;
 | ||
| }
 | ||
|   
 | ||
| bool TStateset::is_empty() const
 | ||
| { 
 | ||
|   for (int i= 0; i< MAXSTATES; i++)
 | ||
|     if (_container[i])
 | ||
|       return FALSE;
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TStateset::is_member(int e)    const
 | ||
| { 
 | ||
|   return (e >= 0 && e < MAXSTATES) ?  (_container[e] != 0) : FALSE;
 | ||
| }
 | ||
| 
 | ||
| int TStateset::get_first()
 | ||
| {
 | ||
|   _current=-1;
 | ||
|   return(get_next());
 | ||
| }
 | ||
| 
 | ||
| int TStateset::get_next()
 | ||
| {
 | ||
|   while (_current+1 < MAXSTATES)
 | ||
|     if (_container[++_current])
 | ||
|       return _current;
 | ||
|   return (-1);  
 | ||
| }
 | ||
| 
 | ||
| // labels and states
 | ||
| bool TR_automa::is_state(int statenum)
 | ||
| {
 | ||
|   return(statenum<=_maxstate && statenum>0);
 | ||
| }
 | ||
| 
 | ||
| // restituisce il numero dello stato con quella etichetta
 | ||
| int TR_automa::label2state(const char *label)
 | ||
| {
 | ||
|   for (int s=0; s<_maxstate;s++)
 | ||
|     if (*(st[s]._label)==label)
 | ||
|       return(s+1);
 | ||
|   return(0);  
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // resetta uno stato dell'automa (senza eliminarlo)
 | ||
| TR_automa & TR_automa::reset_state(int statenum)
 | ||
| {
 | ||
|   int _from,_to;
 | ||
|   if (statenum>0 && statenum<=_maxstate)
 | ||
|   {
 | ||
|     _from=statenum;
 | ||
|     _to=statenum;
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     _maxstate=0;
 | ||
|     _isdeterministic=TRUE;
 | ||
|     _from=1;
 | ||
|     _to=MAXSTATES;
 | ||
|   } 
 | ||
|   for (int i=_from; i<=_to;i++)
 | ||
|   {
 | ||
|     set_label(i,"");
 | ||
|     set_final(i,FALSE);
 | ||
|     for (int j=0; j<MAXSIMBOLS;j++)
 | ||
|       del_trans(i,j); 
 | ||
|   }     
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| // aggiunge una label
 | ||
| int TR_automa::add_state(const char * label)
 | ||
| {
 | ||
|   _maxstate++;
 | ||
|   reset_state(_maxstate);
 | ||
|   set_label(_maxstate,label);
 | ||
|   return _maxstate;
 | ||
| }
 | ||
| 
 | ||
| TR_automa & TR_automa::set_label(int statenum, const char * name)
 | ||
| {
 | ||
|   (*(st[statenum-1]._label))=name;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| const char * TR_automa::label(int statenum)
 | ||
| {
 | ||
|   return (*(st[statenum-1]._label));
 | ||
| }
 | ||
| 
 | ||
| bool TR_automa::is_final(int statenum) const
 | ||
| { 
 | ||
|   return (st[statenum-1]._final);
 | ||
| }
 | ||
| 
 | ||
| bool TR_automa::is_final(TStateset ss ) const
 | ||
| { 
 | ||
|   bool retv=FALSE;
 | ||
|   int statenum=ss.get_first();
 | ||
|   do
 | ||
|   {
 | ||
|     retv=retv || is_final(statenum);
 | ||
|   } while ((statenum=ss.get_next())>0);
 | ||
|     
 | ||
|   return retv;
 | ||
| }
 | ||
| 
 | ||
| TR_automa & TR_automa::set_final(int statenum,bool v)
 | ||
| {
 | ||
|   st[statenum-1]._final=v;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| //*******************
 | ||
| // bows
 | ||
| void TR_automa::add_tran(int statenum, unsigned char symbol,int next)
 | ||
| {
 | ||
|   st[statenum-1]._transaction[symbol]=next;   
 | ||
|   if (symbol==EPSILON)
 | ||
|     _isdeterministic=FALSE;
 | ||
| }
 | ||
| 
 | ||
| void TR_automa::del_trans(int statenum, unsigned char symbol)
 | ||
| {
 | ||
|   st[statenum-1]._transaction[symbol]=0;
 | ||
| }
 | ||
| 
 | ||
| int TR_automa::trans_to(int statenum, unsigned char symbol)
 | ||
| {
 | ||
|   return (st[statenum-1]._transaction[symbol]);   
 | ||
| }
 | ||
| 
 | ||
| // costruttore "di copi": crea un automa non deterministico 
 | ||
| // (transazioni Epsilon ma nessuna transazione multipla)
 | ||
| // o ne crea l'equivalente automa deterministico
 | ||
| TR_automa::TR_automa(TR_automa * aa,bool makedet) 
 | ||
| {
 | ||
|   TStateset arrival;
 | ||
|   TStateset newstateset;
 | ||
|   TString80  tmplabel;
 | ||
|   int curr_new_state;
 | ||
| 
 | ||
|   for (int i=0; i<MAXSTATES;i++)
 | ||
|     st[i]._label = new TString80;
 | ||
|   if (aa==NULL)
 | ||
|   {
 | ||
|     reset_state();
 | ||
|     return;
 | ||
|   }
 | ||
|   if (makedet)
 | ||
|   {
 | ||
|     reset_state();
 | ||
|     // crea il primo stato nell'automa deterministico
 | ||
|     set2label(aa->union_of_closures(newstateset.singleton(FIRST_STATE)),tmplabel);
 | ||
|     add_state(tmplabel);
 | ||
|     curr_new_state=FIRST_STATE;
 | ||
|     while (is_state(curr_new_state))
 | ||
|     {
 | ||
|       // determina l'insieme degli stati dell'automa non deterministico
 | ||
|       // che corrispondono a questo stato dell'automa deterministico
 | ||
|       label2set(label(curr_new_state),newstateset);
 | ||
|       // lo stato <20> finale se include stati finali dell'automa non det.
 | ||
|       set_final(curr_new_state,aa->is_final(newstateset));
 | ||
|       // determina tutte le transazioni 
 | ||
|       for (short symbol=FIRST_NEMPTY_SYMBOL; symbol<MAXSIMBOLS; symbol++)
 | ||
|       {
 | ||
|         // determina lo stato di arrivo nell'automa det.:
 | ||
|         // esso <20> pari all'insieme degli stati raggiunti col questo simbolo 
 | ||
|         // dal sottoinsieme degli stati dell'automa non det. che etichetta il nuovo stato nell'automa det.
 | ||
|         arrival.empty();
 | ||
|         int new_next,old_next;
 | ||
|         int old_state=newstateset.get_first() ;
 | ||
|         do
 | ||
|         {
 | ||
|           if ((old_next = aa->trans_to(old_state,(unsigned char)symbol)))
 | ||
|             arrival.enclose(old_next);
 | ||
|         } while ((old_state=newstateset.get_next())>0);
 | ||
|         if (!arrival.is_empty())
 | ||
|         {
 | ||
|             // crea il nuovo arco nell'automa deterministico
 | ||
|           set2label(aa->union_of_closures(arrival),tmplabel);
 | ||
|           if (!(new_next=label2state(tmplabel)))
 | ||
|             new_next=add_state(tmplabel);
 | ||
|           add_tran(curr_new_state,(unsigned char)symbol,new_next);
 | ||
|         }
 | ||
|       } // loop symbol
 | ||
|       curr_new_state++;
 | ||
|     }
 | ||
|     _isdeterministic=TRUE;
 | ||
|   } // fine  conversione
 | ||
|   else 
 | ||
|   {
 | ||
|     *this=*aa;
 | ||
|     for (int i=0; i<MAXSTATES;i++)
 | ||
|       st[i]._label= aa->st[i]._label;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TR_automa::~TR_automa()
 | ||
| { 
 | ||
|   for (int i=0; i<MAXSTATES;i++)
 | ||
|     delete (st[i]._label);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TR_automa::set2label(const TStateset ss,TString & label)
 | ||
| {
 | ||
|   char coded[MAXSTATES];
 | ||
|   unsigned char c = 0;
 | ||
|   for (int i= 0; i< MAXSTATES; i++)
 | ||
|     if (ss.is_member(i)) 
 | ||
|       coded[c++]=(char)(i+'0');
 | ||
|   coded[c]='\0';
 | ||
|   label=coded;    
 | ||
| }
 | ||
| 
 | ||
| void TR_automa::label2set(const TString & label,TStateset & ss)
 | ||
| {
 | ||
|   ss.empty();
 | ||
|   for (int i= 0; i<= label.len();i++)
 | ||
|     ss.enclose(int(label[i]-'0'));
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // costruisce l'unione delle epslilon closures
 | ||
| TStateset TR_automa::union_of_closures(TStateset &start_set)
 | ||
| {
 | ||
|   TStateset u_of_clo,clo;
 | ||
|   int _state,_next;
 | ||
|   bool toadd;
 | ||
|   
 | ||
|   
 | ||
|   u_of_clo.empty();
 | ||
|   _state=start_set.get_first() ;
 | ||
|   do
 | ||
|   {
 | ||
|     // la chiusura <20> composta dallo stato e tutte le sue transazioni epsilon
 | ||
|     clo.singleton(_state);
 | ||
|     do
 | ||
|     {
 | ||
|       int _state2=clo.get_first();
 | ||
|       do
 | ||
|       {
 | ||
|         toadd=((_next=trans_to(_state2,EPSILON)) && (!clo.is_member(_next)));
 | ||
|         if (toadd)
 | ||
|           clo.enclose(_next);
 | ||
|       } while ((_state2=clo.get_next())>0);
 | ||
|     } while (toadd) ;
 | ||
|     u_of_clo.cap(clo);
 | ||
|   } while ((_state=start_set.get_next())>0);
 | ||
|   return u_of_clo;
 | ||
| }
 | ||
| 
 | ||
| // tenta di riconoscere la stringa passata
 | ||
| bool TR_automa::recognized(const char * t_str) 
 | ||
| {
 | ||
|   if (_isdeterministic)
 | ||
|   {
 | ||
|     // ricoNosce la stringa di token
 | ||
|     int curr_state=FIRST_STATE;
 | ||
|     for (int i=0; t_str[i]; i++)
 | ||
|       if (!(curr_state=trans_to(curr_state,t_str[i])))
 | ||
|         return FALSE; // fine per mancanza di trasizioni
 | ||
|     // fine per mancanza di caratteri di input della stringa
 | ||
|     return (is_final(curr_state));
 | ||
|   }
 | ||
|    else
 | ||
|     return FALSE; //  ??
 | ||
| }
 | ||
| 
 | ||
| // *******************************
 | ||
| // gestione di stringhe di metacaratteri
 | ||
| // *******************************
 | ||
| #define C_ESCAPEMETA '\\'
 | ||
| #define S_BLANK 1
 | ||
| #define S_DIGIT 2
 | ||
| #define S_LETTER 3
 | ||
| #define S_ANY 4
 | ||
| 
 | ||
| // *******************************
 | ||
| // *******************************
 | ||
| // riconoscimento di metacaratteri
 | ||
| class TR_automa;
 | ||
| 
 | ||
|   
 | ||
| bool TMetachar::recognized(const char * s)
 | ||
| {
 | ||
|   return(_au->recognized(s));
 | ||
| }
 | ||
|         
 | ||
| void TMetachar::add_tran(int s,unsigned char metasymbol, int nextstate)
 | ||
| {
 | ||
|   unsigned char c;
 | ||
|   switch (metasymbol)
 | ||
|   {
 | ||
|     case EPSILON:// blank
 | ||
|       _au->add_tran(s,EPSILON,nextstate);
 | ||
|     break;
 | ||
|     case S_BLANK:// blank
 | ||
|       _au->add_tran(s,' ',nextstate);
 | ||
|     break;
 | ||
|     case S_DIGIT:// cifra 
 | ||
|       for (c='0';c<='9';c++)
 | ||
|         _au->add_tran(s,c,nextstate);
 | ||
|     break;
 | ||
|     case S_LETTER: // lettera 
 | ||
|       for (c='a';c<='z';c++)
 | ||
|         _au->add_tran(s,c,nextstate);
 | ||
|       for (c='A';c<='Z';c++)
 | ||
|         _au->add_tran(s,c,nextstate);
 | ||
|     break;
 | ||
|     case S_ANY: // qualsiasi carattere 
 | ||
|       for (c=MAXSIMBOLS-1;c>=FIRST_NEMPTY_SYMBOL;c--)
 | ||
|         _au->add_tran(s,c,nextstate);
 | ||
|     break;
 | ||
|     default:
 | ||
|         _au->add_tran(s,metasymbol,nextstate);
 | ||
|     break;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // restituisce la stringa di metacaratteri del linguaggio riconosciuto
 | ||
| const char * TMetachar::language() const
 | ||
| {
 | ||
|   return(_language);
 | ||
| }
 | ||
| 
 | ||
| void TMetachar::set_language(const char * language)
 | ||
| {
 | ||
|   int s;
 | ||
|   bool escaped_char=FALSE;
 | ||
|   TString label("-"),nextlabel("-");
 | ||
|  
 | ||
|   _language=language;
 | ||
|   // crea l'automa 
 | ||
|   _au->reset_state();
 | ||
|   for (int i=0; language[i]; i++)
 | ||
|   {
 | ||
|     label[0]='a'+i;
 | ||
|     nextlabel[0]='a'+i+1;
 | ||
|     if (language[i]!=C_ESCAPEMETA)
 | ||
|     {
 | ||
|       if (!escaped_char)
 | ||
|       {
 | ||
|       // meta-caratteri e literal fuori set
 | ||
|         s=_au->add_state(label);
 | ||
|         switch (language[i])
 | ||
|         {
 | ||
|           case '#':// cifra o blank opzionale
 | ||
|             add_tran(s,S_BLANK,s+1);
 | ||
|             add_tran(s,'-',s+1);
 | ||
|             add_tran(s,'+',s+1);
 | ||
|           case '9':// cifra opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case '0':// cifra obbligatoria
 | ||
|             add_tran(s,S_DIGIT,s+1);
 | ||
|           break;
 | ||
|           case '?': // lettera opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case 'L': // lettera obbligatoria
 | ||
|             add_tran(s,S_LETTER,s+1);
 | ||
|           break;
 | ||
|           case 'a': // lettera o numero opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case 'A': // lettera o numero obbligatorio
 | ||
|             add_tran(s,S_LETTER,s+1);
 | ||
|             add_tran(s,S_DIGIT,s+1);
 | ||
|           break;
 | ||
|           case 'c': // qualsiasi carattere opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case '&': // qualsiasi carattere obbligatorio
 | ||
|             add_tran(s,S_ANY,s+1);
 | ||
|           break;
 | ||
|           default:
 | ||
|             _au->add_tran(s,language[i],s+1);
 | ||
|           break;
 | ||
|         }
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|       // escaped char
 | ||
|           s=_au->add_state(label);
 | ||
|         _au->add_tran(s,language[i],s+1);
 | ||
|       }
 | ||
|     }
 | ||
|     escaped_char=(language[i]==C_ESCAPEMETA);
 | ||
|   } // end of loop
 | ||
|   // aggiunge lo stato finale
 | ||
|   s=_au->add_state(nextlabel);
 | ||
|   _au->set_final(s);
 | ||
| 
 | ||
| }
 | ||
| 
 | ||
| // ricerca caratteri del set opzionale
 | ||
| bool TMetachar::has_opzchars(const char * pattern)
 | ||
| {
 | ||
|   int i=0; 
 | ||
|   bool next_literal=FALSE;
 | ||
|   
 | ||
|   while (pattern[i])
 | ||
|   {           
 | ||
|     if (!next_literal && strchr(opz_chars(),pattern[i]))
 | ||
|       return(TRUE);
 | ||
|     next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA);
 | ||
|     i++;
 | ||
|   }
 | ||
|   return(FALSE);
 | ||
| }
 | ||
| 
 | ||
| // ricerca caratteri del set opzionale
 | ||
| bool TMetachar::has_mandchars(const char * pattern)
 | ||
| {
 | ||
|   int i=0; 
 | ||
|   bool next_literal=FALSE;
 | ||
|   
 | ||
|   while (pattern[i])
 | ||
|   {
 | ||
|     if (next_literal || strchr(mand_chars(),pattern[i]))
 | ||
|       return(TRUE);
 | ||
|     next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA);
 | ||
|     i++;
 | ||
|   }
 | ||
|   return(FALSE);
 | ||
| }
 | ||
| 
 | ||
| // stabilisce la lunghezza della stringa di metacaratteri
 | ||
| int TMetachar::maxstrlen(const char * pattern) 
 | ||
| {
 | ||
|   int i=0,l=0; 
 | ||
|   bool next_literal=FALSE;
 | ||
|   
 | ||
|   while (pattern[i])
 | ||
|   {
 | ||
|     if (!next_literal)
 | ||
|       l++;
 | ||
|     next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA);
 | ||
|     i++;
 | ||
|   }
 | ||
|   return(l);
 | ||
| }
 | ||
| 
 | ||
| // costruttore e distruttore
 | ||
| TMetachar::TMetachar ()
 | ||
| {
 | ||
|   _au = new TR_automa;       
 | ||
|   set_language("");
 | ||
| }
 | ||
| 
 | ||
| TMetachar::TMetachar (const char * metastr)
 | ||
| {
 | ||
|   // crea l'automa e lo trasforma in deterministico
 | ||
| //  TR_automa auxau;
 | ||
| //  set_language(&auxau,metastr);
 | ||
|   _au=new TR_automa;
 | ||
|   set_language(metastr);
 | ||
|   if (!_au->is_deterministic())
 | ||
|   {
 | ||
|     TR_automa * auxau = new TR_automa(_au,TRUE);       
 | ||
|     delete _au;
 | ||
|     _au=auxau;
 | ||
|   } 
 | ||
| }
 | ||
| 
 | ||
| TMetachar::~TMetachar ()
 | ||
| {
 | ||
|   delete _au;
 | ||
| }
 | ||
| 
 | ||
| // **************************
 | ||
| // classe codice a livelli 
 | ||
| 
 | ||
| 
 | ||
| void TCodice_livelli::update_firm()
 | ||
| {
 | ||
|   _last_firm = prefix().get_codditta();
 | ||
| }
 | ||
| 
 | ||
| void TCodice_livelli::test_firm()
 | ||
| {
 | ||
|   long firm = prefix().get_codditta();
 | ||
|   if (firm > 0 && firm != _last_firm)
 | ||
|   {                   
 | ||
|     init();
 | ||
|     update_firm();  // Lo dovrebbe gia' fare la init
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TCodice_livelli::load(bool enabled, const char *tabname,const char *tabgrp) 
 | ||
| {
 | ||
|   TTable _tabformato(tabname);  
 | ||
|   
 | ||
|   _lev_enabled = enabled;
 | ||
|   _last_level=0;
 | ||
|   for (int i=0; i <  max_levels(); i++)
 | ||
|   {
 | ||
|     _name[i]="";
 | ||
|     _code_length[i]=0;
 | ||
|     _picture[i]="";
 | ||
|     _autoinsert[i]=FALSE;
 | ||
|     _codiceadata[i]=FALSE;
 | ||
|   }
 | ||
|   if (_lev_enabled)
 | ||
|   {
 | ||
|     int e = _tabformato.first(); 
 | ||
|     for (int i=0; e == NOERR && i < max_levels(); i++)
 | ||
|     {
 | ||
|       _name[i]=_tabformato.get("S0");
 | ||
|       _picture[i]=_tabformato.get("S1");
 | ||
|       _autoinsert[i]=_tabformato.get_bool("B0");
 | ||
|       _codiceadata[i]=_tabformato.get_bool("B1");
 | ||
|       _code_length[i]=TMetachar::maxstrlen(_picture[i]);
 | ||
|       _last_level=i+1;
 | ||
|       e = _tabformato.next();
 | ||
|     }
 | ||
|   }
 | ||
|   
 | ||
|   if (_gruppi == NULL)
 | ||
|     _gruppi = new TDecoder(tabgrp);
 | ||
| }
 | ||
| 
 | ||
| const char *TCodice_livelli::code_format(int levnum) const 
 | ||
| {
 | ||
|   if (levnum<0)
 | ||
|     levnum=last_level();
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   CHECK(enabled(), "iu chent get de code format if levels ar disebold");
 | ||
| 
 | ||
|   ((TCodice_livelli *)this)->add_metachar(levnum);
 | ||
|   return ((TMetachar*)_metachars.objptr(levnum-1))->language();
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| bool TCodice_livelli::fit_to_format(const char *codepart,int levnum) const 
 | ||
| {
 | ||
|   if (levnum<0)
 | ||
|     levnum=last_level();
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   CHECK(enabled(), "iu chent cec ueter de format fits if levels ar disebold");
 | ||
|   ((TCodice_livelli *)this)->add_metachar(levnum);
 | ||
|   return ((TMetachar*)_metachars.objptr(levnum-1))->recognized(codepart);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TCodice_livelli::add_metachar(int levnum)
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   if (_metachars.objptr(levnum-1)==NULL)
 | ||
|     _metachars.add(new TMetachar(picture(levnum)),levnum-1);
 | ||
| }
 | ||
| 
 | ||
| const bool TCodice_livelli::enabled() const
 | ||
| {
 | ||
|   return _lev_enabled && enabled(1);
 | ||
| }
 | ||
| 
 | ||
| const bool TCodice_livelli::enabled(int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return (_lev_enabled && levnum<=max_levels() &&  levnum>0 && levnum<=_last_level);
 | ||
| }
 | ||
| 
 | ||
| const int TCodice_livelli::code_start(int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return packed_length(levnum-1)+1;
 | ||
| }
 | ||
| 
 | ||
| const int TCodice_livelli::code_length(int levnum)   const
 | ||
| {           
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
| /*
 | ||
|   if (_lev_enabled && levnum <= max_levels() && levnum > 0)
 | ||
|     return(_code_length[levnum-1]);
 | ||
|   else
 | ||
|     return(0);
 | ||
| */
 | ||
|   return enabled(levnum) ? _code_length[levnum-1] : 0;
 | ||
| }
 | ||
| 
 | ||
| const int TCodice_livelli::packed_length(int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() ,"I codici livello arrivano fino a max_levels()") ;
 | ||
|   int start=0;
 | ||
|   for (int i=0; _lev_enabled && i<levnum && levnum<max_levels(); i++) 
 | ||
|     start+= _code_length[i];
 | ||
|   return start;
 | ||
| }
 | ||
| 
 | ||
| const TString & TCodice_livelli::name(int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return(_name[levnum-1]);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| const bool TCodice_livelli::autoinsert(int levnum) const
 | ||
| { 
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return _autoinsert[levnum-1];
 | ||
| }
 | ||
| 
 | ||
| const bool TCodice_livelli::codiceadata(int levnum) const
 | ||
| { 
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return _codiceadata[levnum-1];
 | ||
| }
 | ||
| 
 | ||
| const bool TCodice_livelli::autoinsert( int levnum, TMask_field & fld) const
 | ||
| { 
 | ||
|   TString16 value(fld.get());
 | ||
|   if (!fit_to_format(value,levnum))
 | ||
|   {
 | ||
|     fld.error_box(FR("Codice non corrispondente al formato previsto (%s)"),(const char *)code_format(levnum));
 | ||
|     return FALSE;  
 | ||
|   }
 | ||
|   bool result = autoinsert( levnum, value);
 | ||
|   fld.set_focus();
 | ||
|   return result;
 | ||
| }
 | ||
| 
 | ||
| const bool TCodice_livelli::autoinsert(int levnum, TString & newcode) const
 | ||
| { 
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   const int result=group_search(newcode, levnum);
 | ||
|   if (result == _iskeynotfound || result == _iseof || result == _iskeyerr)
 | ||
|   { 
 | ||
|     TString grpcode;
 | ||
|     grpcode << levnum;
 | ||
|     grpcode << newcode;
 | ||
|     // auto inserimento
 | ||
|     TFilename ininame;
 | ||
|     ininame.tempdir();
 | ||
|     ininame.add("mglib01g.ini");
 | ||
|     { 
 | ||
|       remove(ininame);
 | ||
|       TConfig action(ininame,"Transaction");
 | ||
|       action.set("Action","INSERT");
 | ||
|       action.set("Firm", main_app().get_firm());
 | ||
|       action.set("CODTAB", grpcode , "5");
 | ||
|     }
 | ||
|     TString cmd("mg0.exe -0 GCG -i");
 | ||
|     cmd << ininame;
 | ||
|     TExternal_app gesttab(cmd);
 | ||
|     gesttab.run();
 | ||
|     TConfig action(ininame,"Transaction");
 | ||
|     if (action.get("Result")!="OK")
 | ||
|     {
 | ||
|       newcode="";
 | ||
|       return FALSE;
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       newcode=action.get("CODTAB","5").sub(1);
 | ||
|     }
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| const TString & TCodice_livelli::picture(int levnum)   const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return(_picture[levnum-1]);
 | ||
| }
 | ||
| 
 | ||
| void TCodice_livelli::pack_maskgrpcodes(TString & pc, const TMask & mask, int field1, int levnum)
 | ||
| {
 | ||
|   for (int l=0 ; l<levnum; l++)
 | ||
|     pack_grpcode(pc,mask.get(field1+l),1+l);
 | ||
| }
 | ||
| 
 | ||
| void TCodice_livelli::pack_grpcode(TString & pc, const TString &codlev, const int levnum)
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   pc.overwrite(codlev.left(_code_length[levnum-1]),packed_length(levnum-1));
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TString TCodice_livelli::unpack_grpcode(const TString& pc, const int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   int start=0;
 | ||
|   for (int i=1; _lev_enabled && i<levnum; i++) 
 | ||
|     start+= _code_length[i-1];
 | ||
|   if (start >= pc.len() || levnum < 1 || levnum > _last_level)
 | ||
|     return EMPTY_STRING;
 | ||
|   return pc.mid(start,levnum == _last_level ? -1 : _code_length[levnum-1]);
 | ||
| }
 | ||
| 
 | ||
| TString TCodice_livelli::build_tabcode(const TString & gcode, const int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   TString valore;
 | ||
|   valore << levnum;
 | ||
|   valore << gcode;
 | ||
|   if (!(_lev_enabled && valore.len()>1)) 
 | ||
|     valore.cut(0);
 | ||
|   return valore;
 | ||
| }
 | ||
| 
 | ||
| TString TCodice_livelli::build_tabcode_packed(const TString & pack, const int levnum) const
 | ||
| {
 | ||
|   CHECK(levnum<=max_levels() && levnum>0,"I codici livello partono da 1") ;
 | ||
|   return build_tabcode(unpack_grpcode(pack,levnum),levnum);
 | ||
| }
 | ||
| 
 | ||
| const TString & TCodice_livelli::group_descr(const char * group_code, int levnum) const
 | ||
| {
 | ||
|   return _gruppi->decode(build_tabcode(group_code,levnum));
 | ||
| }
 | ||
| 
 | ||
| const TString & TCodice_livelli::group_descr_packed(const char * packed_code, int levnum) const
 | ||
| {
 | ||
|   return _gruppi->decode(build_tabcode_packed(packed_code,levnum));
 | ||
| }
 | ||
| 
 | ||
| const int TCodice_livelli::group_search(const char * group_code, int levnum) const
 | ||
| {
 | ||
|   int res;
 | ||
|   _gruppi->decode(build_tabcode(group_code,levnum)).empty();
 | ||
|   res=_gruppi->io_result();
 | ||
|   if (res!=NOERR)
 | ||
|     _gruppi->discard(build_tabcode(group_code,levnum));
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| const int TCodice_livelli::group_search_packed(const char * packed_code, int levnum) const
 | ||
| {
 | ||
|   _gruppi->decode(build_tabcode_packed(packed_code,levnum));
 | ||
|   return _gruppi->io_result();
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TCodice_livelli::set_sheetcolumn(TSheet_field &fld_righe,int field, int lev) const
 | ||
| {
 | ||
|   TMask& sm = fld_righe.sheet_mask();
 | ||
|   TEdit_field& fld = sm.efield(field);
 | ||
|   if (enabled(lev)) 
 | ||
|   {
 | ||
|     const TString& header = name(lev);
 | ||
|     fld.set_prompt(header);
 | ||
|     fld.show();
 | ||
| 
 | ||
|     const int len = header.len() + 1;
 | ||
|     const int f_len = code_length(lev);
 | ||
|     fld_righe.set_column_header(field, header);
 | ||
|     fld_righe.set_column_width(field, (len > f_len ? len : f_len) * 8);
 | ||
|   } 
 | ||
|   else 
 | ||
|   {
 | ||
|     fld.hide();
 | ||
|     fld_righe.delete_column(field);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TCodice_livelli::set_sheet_columns(TSheet_field &sht, short dlg) const
 | ||
| {
 | ||
|   for (int l = 0; l < max_levels(); l++)
 | ||
|     set_sheetcolumn(sht, dlg+l, l+1);
 | ||
| }
 | ||
| 
 | ||
| void TCodice_livelli::set_mask_fields(TMask &m,int firstfield) const
 | ||
| {
 | ||
|   for (int l = max_levels(); l>=1 ; l--)
 | ||
|     set_mask_field(m,firstfield+l-1,l) ;
 | ||
| }  
 | ||
| 
 | ||
| void TCodice_livelli::set_mask_field(TMask &m,int field, int l) const
 | ||
| {
 | ||
|   if (enabled(l))
 | ||
|   {
 | ||
|     if (strlen(m.field(field).prompt()) > (unsigned int)name(l).len())
 | ||
|       m.field(field).set_prompt(name(l));
 | ||
|   }
 | ||
|   m.field(field).show(enabled(l));
 | ||
| }
 | ||
| 
 | ||
| TCodice_livelli::TCodice_livelli() 
 | ||
|                : _last_firm(-1), _gruppi(NULL) {}  
 | ||
| 
 | ||
| TCodice_livelli::~TCodice_livelli() 
 | ||
| {
 | ||
|   if (_gruppi) 
 | ||
|     delete _gruppi;
 | ||
| }               
 | ||
| 
 | ||
| void TCodart_livelli::init()
 | ||
| {
 | ||
|   TConfig mgconfig(CONFIG_DITTA, "mg");
 | ||
|   load(mgconfig.get_bool("GESLIVART"), "FCA","GCA");
 | ||
|   // imposta il riconoscimento dei  caratteri del formato dell'ultima parte dell'articolo
 | ||
|   TString80 format;
 | ||
|   TTable tabfca("FCA");
 | ||
|   if (tabfca.last() == NOERR)
 | ||
|     format = tabfca.get("S1");
 | ||
|   
 | ||
|   _metachars.destroy();
 | ||
|   _metachars.add(new TMetachar(format),max(last_level()-1,0));
 | ||
|   
 | ||
|   update_firm();
 | ||
| }
 | ||
| 
 | ||
| TCodart_livelli ::TCodart_livelli() 
 | ||
| {   
 | ||
|   init();
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TCodart_livelli::~TCodart_livelli() 
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| void TCodgiac_livelli::init()
 | ||
| {
 | ||
|   TConfig mgconfig(CONFIG_DITTA, "mg");
 | ||
|   load(mgconfig.get_bool("GESLIVGIAC"),"FCG","GCG");
 | ||
|   update_firm();
 | ||
| }
 | ||
| 
 | ||
| TCodgiac_livelli::TCodgiac_livelli()
 | ||
| {
 | ||
|   init();
 | ||
| }
 | ||
| 
 | ||
| static TCodgiac_livelli *_livelli_giacenza=NULL;
 | ||
| static TCodart_livelli *_livelli_articolo=NULL;
 | ||
| 
 | ||
| TCodgiac_livelli& livelli_giacenza()
 | ||
| {
 | ||
|   if (_livelli_giacenza==NULL)
 | ||
|     _livelli_giacenza=new TCodgiac_livelli();
 | ||
|   return *_livelli_giacenza;
 | ||
| } 
 | ||
| 
 | ||
| TCodart_livelli& livelli_articolo()
 | ||
| {
 | ||
|   if (_livelli_articolo==NULL)
 | ||
|     _livelli_articolo=new TCodart_livelli();
 | ||
|   return *_livelli_articolo;
 | ||
| } 
 | ||
| 
 | ||
| TMagazzini::TMagazzini() : 
 | ||
|   TRecord_cache("MAG") , _mgconfig(NULL),_last_firm(-1)
 | ||
| {
 | ||
|   init();
 | ||
| }
 | ||
| 
 | ||
| TMagazzini::~TMagazzini() 
 | ||
| {
 | ||
|   if (_mgconfig) delete _mgconfig;
 | ||
| }
 | ||
| 
 | ||
| void TMagazzini::init()
 | ||
| {
 | ||
|   if (_mgconfig) delete _mgconfig;
 | ||
|   _mgconfig = new TConfig(CONFIG_DITTA, "mg");
 | ||
|   _gestmag=_mgconfig->get_bool("GESMAG");
 | ||
|   
 | ||
|   _gestdep=_gestmag && _mgconfig->get_bool("GESDEPOSITI");
 | ||
|   _gestmultimag=_gestmag && _mgconfig->get_bool("GESMULTIMAG");
 | ||
|   _gestubi=_mgconfig->get_char("GESUBICAZ");
 | ||
| 
 | ||
|   TTable mag("MAG");
 | ||
|   mag.first();
 | ||
|   // look for standard mag & dep
 | ||
|   while (!mag.eof() && !mag.get_bool("B1"))
 | ||
|     mag.next();
 | ||
|   if (!mag.eof()) 
 | ||
|   { 
 | ||
|     const TString& codtab = mag.get("CODTAB");
 | ||
|     _stdmag = codtab.left(3);
 | ||
|     _stddep = codtab.mid(3);
 | ||
|   }
 | ||
|   else
 | ||
|     _stdmag.cut(0);
 | ||
| 
 | ||
|   _last_firm = prefix().get_codditta();
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMagazzini::test_firm() const
 | ||
| {
 | ||
|   long firm = prefix().get_codditta();
 | ||
|   if (firm > 0 && firm != _last_firm)
 | ||
|     ((TMagazzini *)this)->init();
 | ||
| }
 | ||
| 
 | ||
| bool TMagazzini::gestmag(bool verbose) const 
 | ||
| {
 | ||
|   test_firm() ;  
 | ||
|   if (!_gestmag && verbose)
 | ||
|     warning_box("La ditta corrente non gestisce il magazzino");
 | ||
|   return _gestmag;
 | ||
| }
 | ||
| bool TMagazzini::gestdep() const 
 | ||
| {
 | ||
|   test_firm() ; return _gestdep;
 | ||
| }
 | ||
| bool TMagazzini::gestubi_man() const 
 | ||
| {
 | ||
|   test_firm() ; return _gestubi=='M';
 | ||
| }
 | ||
| bool TMagazzini::gestubi_tab() const 
 | ||
| {
 | ||
|   test_firm() ; return _gestubi=='T';
 | ||
| }
 | ||
| bool TMagazzini::gestmultimag() const 
 | ||
| {
 | ||
|   test_firm() ; return _gestmultimag;
 | ||
| }
 | ||
| 
 | ||
| const char * add_magcode(TString & str, const char * m)
 | ||
| {
 | ||
|   str = m; 
 | ||
|   str.rpad(3);
 | ||
|   return str;
 | ||
| }
 | ||
| 
 | ||
| const char * add_depcode(TString & str, const char * d)
 | ||
| {
 | ||
|   str << d;
 | ||
|   return str.trim();
 | ||
| }
 | ||
| 
 | ||
| bool riporta_ordinato()
 | ||
| {      
 | ||
| 	static bool __riporta_ordinato = FALSE;
 | ||
| 	static long __firm = -883;
 | ||
|   const long cur_firm = prefix().get_codditta();
 | ||
| 
 | ||
|   if (__firm != cur_firm)
 | ||
|   {               
 | ||
|   	__firm = cur_firm;
 | ||
|   	TConfig c(CONFIG_DITTA, "mg");
 | ||
|   	__riporta_ordinato = c.get_bool("RIPORD");
 | ||
|   }      
 | ||
|   return __riporta_ordinato;
 | ||
| }
 | ||
| 
 | ||
| const char * get_magcode(TString & codmagdep)
 | ||
| {
 | ||
|   return codmagdep.left(3);
 | ||
| }
 | ||
| 
 | ||
| const char * get_depcode(TString & codmagdep)
 | ||
| {
 | ||
|   return codmagdep.mid(3);
 | ||
| }
 |