Files correlati : mg4.exe Ricompilazione Demo : [ ] Commento : Corretto ed ottimizzato programma controllo coerenza tra documenti e movimenti git-svn-id: svn://10.65.10.50/branches/R_10_00@22495 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			252 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			252 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <applicat.h>
 | ||
| #include <mask.h>
 | ||
| #include <progind.h>
 | ||
| #include <reputils.h>
 | ||
| 
 | ||
| #include "mg4400.h"
 | ||
| 
 | ||
| #include "../ve/velib.h"
 | ||
| 
 | ||
| class TCheckdoc_mask: public TMask 
 | ||
| {
 | ||
| public:
 | ||
|   TCheckdoc_mask() : TMask("mg4400") {}
 | ||
| };
 | ||
| 
 | ||
| class TCheckdoc_app : public TSkeleton_application 
 | ||
| {
 | ||
| protected:
 | ||
|   void segnala_documento(TRecordset& doc, TLog_report& rep, const char* msg) const;
 | ||
|   bool cerca_articolo(const TMov_mag& mov, const TString& codart) const;
 | ||
|   void elabora_mov(int anno, TAssoc_array& duplicati, TLog_report& log) const;
 | ||
|   void elabora_doc(int anno, TAssoc_array& duplicati, TLog_report& log) const;
 | ||
| 
 | ||
| public:
 | ||
|   virtual void main_loop();
 | ||
| };
 | ||
| 
 | ||
| void TCheckdoc_app::segnala_documento(TRecordset& doc, TLog_report& rep, const char* msg) const
 | ||
| {
 | ||
|   TString s;
 | ||
|   s << TR("Il doc. ") << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) << '/' << doc.get(DOC_NDOC) 
 | ||
|     << TR(" del ") << doc.get(DOC_DATADOC) << ' ' << msg;
 | ||
|   rep.log(0, "");
 | ||
|   rep.log(2, s);
 | ||
| }
 | ||
| 
 | ||
| bool TCheckdoc_app::cerca_articolo(const TMov_mag& mov, const TString& codart) const
 | ||
| {
 | ||
|   const TRecord_array& rmov = mov.body();
 | ||
|   int i = 0;
 | ||
|   for (i = rmov.last_row(); i > 0; i = rmov.pred_row(i))
 | ||
|   {
 | ||
|     const TRectype& rowi = rmov.row(i);
 | ||
|     const TString& art = rowi.get(RMOVMAG_CODART);
 | ||
|     if (codart == art)
 | ||
|       break;
 | ||
|   }
 | ||
|   return i > 0;
 | ||
| }
 | ||
| 
 | ||
| void TCheckdoc_app::elabora_mov(int anno, TAssoc_array& duplicati, TLog_report& log) const
 | ||
| {
 | ||
|   TISAM_recordset mov("USE MOVMAG KEY 2\nFROM ANNOES=#ANNO\nTO ANNOES=#ANNO");
 | ||
|   mov.set_var("#ANNO", long(anno));
 | ||
| 
 | ||
|   TString msg;
 | ||
|   msg << TR("Controllo duplicati su ") << mov.items() << TR(" movimenti di magazzino del ") << anno;
 | ||
| 
 | ||
|   log.log(0, "");
 | ||
|   log.log(0, msg);
 | ||
|   log.log(0, "");
 | ||
|  
 | ||
|   TProgind pi(mov.items(), msg);
 | ||
|   const TRectype& curr = mov.cursor()->curr();
 | ||
|   TAssoc_array ass;
 | ||
|   for (bool ok = mov.move_first(); ok; ok = mov.move_next())
 | ||
|   {
 | ||
|     if (!pi.addstatus(1))
 | ||
|       break;
 | ||
|     const TDoc_key k(curr);
 | ||
|     if (k.ndoc() > 0)
 | ||
|     {
 | ||
|       TToken_string* d = (TToken_string*)ass.objptr(k);
 | ||
|       if (d != NULL)
 | ||
|       {
 | ||
|         const TRectype& doc = cache().get(LF_DOC, k);
 | ||
|         const TString& tipodoc = doc.get(DOC_TIPODOC);
 | ||
|         const TTipo_documento& td = cached_tipodoc(tipodoc);
 | ||
|         if (!td.is_ordine() && !td.scarica_residuo())
 | ||
|         {
 | ||
|           const long numreg = curr.get_long(MOVMAG_NUMREG);
 | ||
|           d->add(numreg);
 | ||
|           msg.cut(0) << TR("Il mov. ") << numreg << TR(" ed il mov. ") << d->get(0) 
 | ||
|                      << TR(" si riferiscono allo stesso doc. ")
 | ||
|                      << k.codnum() << ' ' << k.anno() << '/' << k.ndoc();
 | ||
|           log.log(d->items() == 2 ? 1 : 2, msg);
 | ||
|           duplicati.add(k, *d, true);
 | ||
|         }
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         d = new TToken_string(curr.get(MOVMAG_NUMREG));
 | ||
|         ass.add(k, d);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| } 
 | ||
| 
 | ||
| void TCheckdoc_app::elabora_doc(int anno, TAssoc_array& duplicati, TLog_report& log) const
 | ||
| {
 | ||
|   TISAM_recordset doc("USE DOC SELECT CAUSMAG!=\"\"\nFROM PROVV=D ANNO=#ANNO\nTO PROVV=D ANNO=#ANNO");
 | ||
|   doc.set_var("#ANNO", long(anno));
 | ||
| 
 | ||
|   TString msg;
 | ||
|   msg << TR("Controllo di ") << doc.items() << TR(" documenti che movimentano il magazzino del ") << anno;
 | ||
|   
 | ||
|   log.log(0, "");
 | ||
|   log.log(0, msg);
 | ||
|   
 | ||
|   TProgind pi(doc.items(), msg);
 | ||
| 
 | ||
|   for (bool ok = doc.move_first(); ok; ok = doc.move_next())
 | ||
|   {
 | ||
|     if (!pi.addstatus(1))
 | ||
|       break;
 | ||
|   
 | ||
|     bool good = false;
 | ||
|     const TString& tipodoc = doc.get(DOC_TIPODOC).as_string();
 | ||
|     const TTipo_documento& td = cached_tipodoc(tipodoc);
 | ||
|     if (td.mov_mag() && !td.is_ordine() && !td.scarica_residuo())
 | ||
|     {
 | ||
|       const char stato = doc.get(DOC_STATO).as_string()[0];
 | ||
|       good = stato >= td.stato_mov_iniziale();
 | ||
|     }
 | ||
|     if (!good) // Inutile controllare documenti nello stato che NON abbia ancora generato movimenti
 | ||
|       continue;
 | ||
| 
 | ||
|     const long numreg = doc.get(DOC_MOVMAG).as_int();
 | ||
|     if (numreg <= 0)
 | ||
|     {
 | ||
|       segnala_documento(doc, log, "Nessun movimento associato");
 | ||
|       continue;
 | ||
|     }
 | ||
| 
 | ||
|     TMov_mag mov(numreg);
 | ||
|     if (mov.get_int(MOVMAG_ANNOES) <= 0)
 | ||
|     {
 | ||
|       msg.cut(0) << TR("Non esiste il movimento associato ") << numreg;
 | ||
|       segnala_documento(doc, log, msg);
 | ||
|       continue;
 | ||
|     }
 | ||
| 
 | ||
|     TToken_string key; 
 | ||
|     key.add(doc.get(DOC_CODNUM).as_string());
 | ||
|     key.add(doc.get(DOC_ANNO).as_int());
 | ||
|     key.add(doc.get(DOC_PROVV).as_string());
 | ||
|     key.add(doc.get(DOC_NDOC).as_int());
 | ||
|     TRecord_array rdoc(key, LF_RIGHEDOC);
 | ||
| 
 | ||
|     TAssoc_array qtardoc;
 | ||
|     for (int r = rdoc.last_row(); r > 0; r = rdoc.pred_row(r))
 | ||
|     {
 | ||
|       const TRectype& row = rdoc.row(r);
 | ||
|       const TString80 codart = row.get(RDOC_CODARTMAG);
 | ||
|       const real qta = row.get(td.field_qta());
 | ||
|       if (codart.full() && !qta.is_zero())
 | ||
|       {
 | ||
|         TArticolo art(codart);
 | ||
|         real* q = (real*)qtardoc.objptr(codart);
 | ||
|         //se non esiste
 | ||
|         if (q == NULL)
 | ||
|         {
 | ||
|           //per ora memorizzo zero
 | ||
|           q = new real;
 | ||
|           qtardoc.add(codart,q);
 | ||
|         }        
 | ||
|         //aggiorno la quantit<69> convertendola all'unit<69> di misura di base
 | ||
|         *q += art.convert_to_um(qta, EMPTY_STRING, row.get(RDOC_UMQTA));
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     if (!qtardoc.empty())
 | ||
|     {
 | ||
|       TAssoc_array qtarmov;
 | ||
|       const TRecord_array& rmov = mov.body();
 | ||
|       int i = 0;
 | ||
|       for (i = rmov.last_row(); i > 0; i = rmov.pred_row(i))
 | ||
|       {
 | ||
|         const TRectype& rowi = rmov.row(i);
 | ||
|         const TString& codart = rowi.get(RMOVMAG_CODART);
 | ||
|         const real qta = rowi.get(RMOVMAG_QUANT);
 | ||
|         if (codart.full() && !qta.is_zero())
 | ||
|         {
 | ||
|           real* q = (real*)qtarmov.objptr(codart);
 | ||
|           if (q == NULL)
 | ||
|             qtarmov.add(codart, qta);
 | ||
|           else
 | ||
|             *q += qta;
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       bool signalled = false;   
 | ||
|       FOR_EACH_ASSOC_OBJECT(qtardoc, h, codart, q)
 | ||
|       {
 | ||
|         const real& qd = *(const real*)q;
 | ||
|         const real* qm = (const real*)qtarmov.objptr(codart);
 | ||
|         if (qm == NULL || qd != *qm)
 | ||
|         {
 | ||
|           if (!signalled)
 | ||
|           {
 | ||
|             msg.cut(0) << TR("non corrisponde al mov. ") << numreg;
 | ||
|             segnala_documento(doc, log, msg);
 | ||
|             signalled = true;
 | ||
|           }
 | ||
|           msg.cut(0) << TR("Articolo ") << codart << TR(" quantit<69> ") << qd << " <> " << (qm ? *qm : ZERO);
 | ||
| 
 | ||
|           if (qm == NULL)
 | ||
|           {
 | ||
|             const TDoc_key dk(mov);
 | ||
|             TToken_string* movs = (TToken_string*)duplicati.objptr(dk);
 | ||
|             if (movs != NULL)
 | ||
|             {
 | ||
|               FOR_EACH_TOKEN(*movs, tok) if (mov.get(MOVMAG_NUMREG) != tok)
 | ||
|               {
 | ||
|                 const long nreg = atol(tok);
 | ||
|                 TMov_mag mov_doppio(nreg);
 | ||
|                 if (cerca_articolo(mov_doppio, codart))
 | ||
|                 {
 | ||
|                   msg << TR(" ritrovato nel movimento ") << nreg;
 | ||
|                   break;
 | ||
|                 }
 | ||
|               }
 | ||
|             }
 | ||
|           }
 | ||
|           log.log(0, msg);
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TCheckdoc_app::main_loop()
 | ||
| {
 | ||
|   TCheckdoc_mask m;
 | ||
|   while (m.run()==K_ENTER)
 | ||
|   {
 | ||
|     const int anno = m.get_int(F_ANNO);
 | ||
|     TLog_report log;
 | ||
|     TAssoc_array duplicati;
 | ||
|     elabora_mov(anno, duplicati, log);
 | ||
|     elabora_doc(anno, duplicati, log);
 | ||
|     log.preview();
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| int mg4400(int argc, char* argv[])
 | ||
| {
 | ||
|   TCheckdoc_app a;
 | ||
|   a.run(argc, argv, TR("Controllo documenti/movimenti"));
 | ||
|   return 0;
 | ||
| }
 |