#include #include #include #include #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à convertendola all'unità 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à ") << 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; }