From 550794c12ac1e5fa1e1739cfbea24df7a1aaa674 Mon Sep 17 00:00:00 2001 From: mtollari Date: Fri, 21 Oct 2016 10:43:42 +0000 Subject: [PATCH] Patch level : 12.0 no-patch Files correlati : Commento : Inizio sviluppo personalizzazione Campo/Compass Caricamento tabelle O02A O03A P01A git-svn-id: svn://10.65.10.50/branches/R_10_00@23384 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- src/ca/ca2.cpp | 9 +- src/ca/ca2.h | 1 + src/ca/ca2600.cpp | 421 +++++++++++++++++++++++++++++++++++++++++++++ src/ca/ca2600a.h | 3 + src/ca/ca2600a.uml | 70 ++++++++ 5 files changed, 500 insertions(+), 4 deletions(-) create mode 100644 src/ca/ca2600.cpp create mode 100644 src/ca/ca2600a.h create mode 100644 src/ca/ca2600a.uml diff --git a/src/ca/ca2.cpp b/src/ca/ca2.cpp index 533b83171..db8319360 100755 --- a/src/ca/ca2.cpp +++ b/src/ca/ca2.cpp @@ -7,10 +7,11 @@ int main(int argc, char** argv) const int r = (argc > 1) ? argv[1][1] - '0' : 0; switch (r) { - case 1: ca2200(argc, argv); break; // ripartizione movimenti analitica - case 2: ca2300(argc, argv); break; // ricalcolo saldi - case 3: ca2400(argc, argv); break; // ricalcolo righe competenza - case 4: ca2500(argc, argv); break; // esportazione a Board + case 1: ca2200(argc, argv); break; // ripartizione movimenti analitica + case 2: ca2300(argc, argv); break; // ricalcolo saldi + case 3: ca2400(argc, argv); break; // ricalcolo righe competenza + case 4: ca2500(argc, argv); break; // esportazione a Board + case 5: ca2600(argc, argv); break; // esportazione su Compass default: ca2100(argc, argv); break; // gestione movimenti } return 0; diff --git a/src/ca/ca2.h b/src/ca/ca2.h index 844471f28..d07618d0d 100755 --- a/src/ca/ca2.h +++ b/src/ca/ca2.h @@ -6,5 +6,6 @@ int ca2200(int argc, char* argv[]); int ca2300(int argc, char* argv[]); int ca2400(int argc, char* argv[]); int ca2500(int argc, char* argv[]); +int ca2600(int argc, char* argv[]); #endif // __CA2_H diff --git a/src/ca/ca2600.cpp b/src/ca/ca2600.cpp new file mode 100644 index 000000000..8396d0592 --- /dev/null +++ b/src/ca/ca2600.cpp @@ -0,0 +1,421 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "ca2600a.h" + +class TCampass_msk : public TAutomask +{ +protected: + virtual long handler(WINDOW task, EVENT* ep); + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + //void update_sheet(); +public: + TCampass_msk(); +}; + +/* +void TCampass_msk::update_sheet() +{ + TSheet_field& s = sfield(F_FILES); + + if (s.empty()) + { + const TPrefix& prf = prefix(); + const TIsam_handle ff[] = { + LF_ANAMAG, LF_CLIFO, LF_DIST, LF_DOC, LF_RDIST, + LF_RIGHEDOC, LF_RILPROD, LF_TAB, LF_UMART, 0 + }; + for (int i = 0; ff[i]; i++) + { + const TIsam_handle lf = ff[i]; + const TFilename fn = prf.get_filename(lf); + TToken_string& row = s.row(-1); + row.format(" |%d", lf); + row.add(fn.name_only()); + } + } + + TString query; + FOR_EACH_SHEET_ROW(s, r, row) + { + if (row->get_int(1) != 5) + { + query.format("USE %d", row->get_int(1)); + TISAM_recordset c(query); + row->add(c.items(), 3); + } + } + s.force_update(); +} +*/ + +long TCampass_msk::handler(WINDOW task, EVENT* ep) +{ + if (ep->type == E_TIMER) + { + if (is_running()) + stop_run(K_ENTER); + } + return TAutomask::handler(task, ep); +} + +bool TCampass_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_DATA_INI: + case F_DATA_FIN: + if (e == fe_modify) + //update_sheet(); + break; + /* + case F_FILES: + if (e == se_query_add || e == se_query_del) + return false; + */ + default: + break; + } + return true; +} + +TCampass_msk::TCampass_msk() : TAutomask("ca2600a") +{ + TDate d(TODAY); + set(F_DATA_FIN, d); + d.set_day(1); + set(F_DATA_INI, d, true); +//7 update_sheet(); +} + +class TCampass_app : public TSkeleton_application +{ +protected: + TToken_string tables; + const TString getFam(TString codArt) const {TString app; app << codArt[3] << codArt[4] << codArt[5]; return app; } // Restituisce la famiglia di un prodotto CODART[3,5] + const TString toEscape(TString val) const; // Prende una stringa e sistema i caratteri di escape + bool create_table(const TString& DSN, TIsam_handle lf) const; + bool emptyTables(const TString& DSN) const; + bool esporta(const TString& DSN, const TDate& datef, const TDate& datet) const; + // Funzioni di esportazione + bool o02a(const TString& DSN) const; + bool o03a(const TString& DSN) const; + bool p01a(const TString& DSN) const; + +public: + virtual void main_loop(); + void setTable(TToken_string s) { tables = s; } +}; + +const TString TCampass_app::toEscape(TString val) const +{ + TString app; + for(int k = 0; k < val.len(); k++) + { + switch (val[k]) + { + case '\'': + app << "''"; + break; + default: + app << val[k]; + break; + } + } + return app; +} +bool TCampass_app::emptyTables(const TString& DSN) const +{ + TODBC_recordset sqlset(""); + TString table; + + if (!sqlset.connect(DSN)) + return false; + + for (int i = 0; i < tables.size(); i++) + { + TString theQuery; // The query: una tabella (donna) per cui uccidere + + tables.get(i, table); + theQuery << "DELETE FROM "<< table << ";"; + sqlset.exec(theQuery); + } + // Committo i cambiamenti + sqlset.exec("COMMIT;"); + return true; +} + +bool TCampass_app::esporta(const TString& DSN, const TDate& datef, const TDate& datet) const +{ + // Innanzitutto svuoto le tabelle + if(!emptyTables(DSN)) return false; + + // Adesso inizio a riempirle + // O02A + if(!o02a(DSN)) return false; + // O03A + if(!o03a(DSN)) return false; + // P01A + if(!p01a(DSN)) return false; + + + return true; +} +bool TCampass_app::o02a(const TString& DSN) const +{ + TODBC_recordset sqlset("", true); + // Controllo la connessione + if (!sqlset.connect(DSN)) + return false; + TRelation doc(LF_DOC),rdoc(LF_RIGHEDOC); + int items; + TString msg("Esportazione tabella "); msg << "O02A"; + // Creo il filtro per la chiave del cursore, da quel che ho capito le chiavi sono più veloci di un filtro (come è possibile?) + TRectype filtroRDoc(rdoc.curr()); filtroRDoc.put("CODNUM", "ORC"); + TCursor curRDoc(&rdoc, "", 1, &filtroRDoc, &filtroRDoc); + items = curRDoc.items(); + TProgress_monitor p(items, msg); + // Adesso inserisco tutta la bella roba + for (curRDoc = 0; curRDoc.pos() < items && !p.is_cancelled(); ++curRDoc) + { + int num = curRDoc.pos(); + // Aggiorno il Progress Monitor + if (!p.add_status()) + break; + // Dichiaro la stringa + TString sqlQuery; + // Prendo la riga di RDOC + TRectype rowRDoc = curRDoc.curr(); + + // Vado a prendere il documento di riferimento + TRectype filtroDoc(doc.curr()); + TString a,b,c,d; + a << rowRDoc.get("PROVV"); + b << rowRDoc.get("ANNO"); + c << rowRDoc.get("CODNUM"); + d << rowRDoc.get("NDOC"); + filtroDoc.put(DOC_PROVV, rowRDoc.get("PROVV")); + filtroDoc.put(DOC_ANNO, rowRDoc.get("ANNO")); + filtroDoc.put(DOC_CODNUM, rowRDoc.get("CODNUM")); + filtroDoc.put(DOC_NDOC, rowRDoc.get("NDOC")); + TCursor curDoc(&doc, "", 1, &filtroDoc, &filtroDoc); + curDoc.items(); + // Forzo a 0, sennò ci sono problemi di sporcizia + curDoc = 0; + TRectype rowDoc = (curDoc.curr()); + + // Inserisco IKRUNIMP, FAZI, CStr, CMAG, CCLIH, CCLIR, CCLI + sqlQuery << "INSERT INTO O02A ( IKRUNIMP, FAZI, CStr, CMAG, CCLIH, CCLIR, CCLI, FLGSTA, XRIFCLI, XNOTE, CART, QCORD, QCSPE, DCCONF ) \ + VALUES('1','U','DBS','" << rowRDoc.get("CODMAG") << "','" << rowRDoc.get("NDOC") << "','" << rowRDoc.get("NRIGA") << "','" << rowDoc.get("CODCF") << "','"; + // Inserisco FLGSTA + sqlQuery << (rowRDoc.get("RIGAEVASA") == "X" ? "C" : "A"); + // Inserisco XRIFCLI, XNOTE, CART, QCORD, QCSPE, DCCONF + sqlQuery << "','" << rowDoc.get("NUMDOCRIF") << "-" << rowDoc.get("DATADOCRIF") << "','" << toEscape(rowRDoc.get("DESCEST")) << "','" << toEscape(rowRDoc.get("CODARTMAG")) + << "','" << rowRDoc.get("QTA") << "','" << rowRDoc.get("QTAEVASA") << "','" << rowRDoc.get("DATACONS") << "');"; + + if(sqlset.exec(sqlQuery) != 1) + return false; + } + return sqlset.commit() == -1 ? false : true; +} +bool TCampass_app::o03a(const TString& DSN) const +{ + TODBC_recordset sqlset("", true); + // Controllo la connessione + if (!sqlset.connect(DSN)) + return false; + TRelation clifo(LF_CLIFO); + int items; + TString msg("Esportazione tabella "); msg << "O03A"; + // Creo il filtro per la chiave del cursore, da quel che ho capito le chiavi sono più veloci di un filtro (come è possibile?) + TRectype filtro(clifo.curr()); filtro.put("TIPOCF", "C"); + TCursor curClifo(&clifo, "", 1, &filtro, &filtro); + items = curClifo.items(); + TProgress_monitor p(items, msg); + // Adesso inserisco tutta la bella roba + for (curClifo = 0; curClifo.pos() < items && !p.is_cancelled(); ++curClifo) + { + int num = curClifo.pos(); + // Aggiorno il Progress Monitor + if (!p.add_status()) + break; + // Dichiaro la stringa + TString sqlQuery; + // Prendo la riga di RDOC + TRectype rowClifo = curClifo.curr(); + // Inserisco tutto in un colpo (yeeeeeeeee) + sqlQuery << "INSERT INTO O03A ( IKRUNIMP, FAZI, CStr, CCLI, RCLI ) \ + VALUES('1','U','DBS','" << rowClifo.get("CODCF") << "','" << toEscape(rowClifo.get("RAGSOC")) << "');"; + + if(sqlset.exec(sqlQuery) != 1) + return false; + } + return sqlset.commit() == -1 ? false : true; +} +bool TCampass_app::p01a(const TString& DSN) const +{ + TODBC_recordset sqlset("", true); + // Controllo la connessione + if (!sqlset.connect(DSN)) + return false; + TRelation anamag(LF_ANAMAG), rdist(LF_RDIST), umart(LF_UMART); + int items; + TString msg("Esportazione tabella "); msg << "P01A"; + TCursor curAna(&anamag), curRDist(&rdist), curUmart(&umart); + items = curAna.items(); curRDist.items();curUmart.items(); + TString artRDist, artUmart; + TProgress_monitor p(items, msg); + // Adesso inserisco tutta la bella roba + for (curAna = 0; curAna.pos() < items && !p.is_cancelled(); ++curAna) + { + int num = curAna.pos(); + // Aggiorno il Progress Monitor + if (!p.add_status()) + break; + // Dichiaro la stringa + TString sqlQuery; + // Prendo la riga di ANAMAG + TRectype rowAna = curAna.curr(); + // Inserisco IKRUNIMP,CART,RPART,CFAM + sqlQuery << "INSERT INTO P01A (IKRUNIMP,CART,RART,CFAM,CTART,CUDMP,CUDMM,CUDMA,CUDMV,PCONVPMN,PCONVPMD,PCONVPVN,PCONVPVD,PCONVPAN,PCONVPAD,FOBS) \ + VALUES('1','" << toEscape(rowAna.get("CODART")) << "','" << toEscape(rowAna.get("DESCR")) << "','" << getFam(rowAna.get("CODART")) <<"','"; + + + /**************************************************************************** + * Senza ricreare il cursore ogni volta lo scorro insieme a DIST e RDIST + * spostandomi solo quando trovo le righe interessate. + * Con questo ragionamento risparmio circa 1 secondo + *****************************************************************************/ + TRectype rowRDist = curRDist.curr(); + // Carico il codice attuale + artRDist = rowRDist.get("CODDIST"); + // Controllo se il cursore punta allo stesso articolo + // Inserisco CTART + if(artRDist == rowAna.get("CODART")) + { + bool trovato = false; + while(rowRDist.get("CODDIST") == rowAna.get("CODART")) + { + if(rowRDist.get("CODCOMP") == rowAna.get("CODART")) + trovato = true; + ++curRDist; + rowRDist = curRDist.curr(); + } + sqlQuery << (trovato ? "SL" : "PF"); + } + else + sqlQuery << "MP"; + sqlQuery << "','"; + + /**************************************************************************** + * Parto dal presupposto che tutti gli articoli sono presenti in UMART. + * Senza ricreare il cursore ogni volta lo scorro insieme a ANAMAG + * spostandomi solo quando trovo le righe interessate. + * Con questo ragionamento risparmio circa 1 secondo + *****************************************************************************/ + + TRectype rowUmart = curUmart.curr(); + // Carico il codice attuale + artUmart = rowUmart.get("CODART"); + // Controllo se il cursore punta allo stesso articolo, + // siccome a volte possono esserci righe delle distinte senza articolo mi sposto finchè non lo trovo + while(artUmart != rowAna.get("CODART")) + { + ++curUmart; + rowUmart = curUmart.curr(); + artUmart = rowUmart.get("CODART"); + } + TString UM; UM << rowUmart.get("UM"); + TString UM2; + // Inserisco CUDMP,CUDMM,CUDMA,CUDMV + sqlQuery << UM <<"','" << UM <<"','" << UM <<"','"; + // Mi sposto per prendere la seconda riga + ++curUmart; + rowUmart = curUmart.curr(); + if(artUmart == rowUmart.get("CODART")) // Controllo di essere sulla seconda riga + { + UM2 << rowUmart.get("UM"); + ++curUmart; + } + else + UM2 << UM; + sqlQuery << UM2 <<"','"; + + // Inserisco PCONVPMN,PCONVPMD,PCONVPVN,PCONVPVD,PCONVPAN,PCONVPAD + // Se siamo alla riga 2 di UMART prendo il valore, altrimenti passo 1 + TString FC; FC << (curUmart.items() > 1 ? rowUmart.get_real("FC") : "1"); + sqlQuery << FC << "','" << FC << "','" << FC << "','" << FC << "','" << FC << "','" << FC << "','"; + + // Inserisco FOBS + sqlQuery << rowAna.get_bool("SOSPESO") ? "1" : "0"; + // Chiudo la query + sqlQuery << "');"; + if(sqlset.exec(sqlQuery) != 1) + return false; + } + return sqlset.commit() == -1 ? false : true; +} + +void TCampass_app::main_loop() +{ + TCampass_msk m; + bool batch = false; + int mins = 1; + + if (argc() > 2) + { + const TFixed_string a(argv(2)); + + batch = toupper(a[1]) == 'M'; + mins = atoi(a.right(1)); + if (mins <1) + mins = 1; + } + + if (batch) + { + const WINDOW task =TASK_WIN; + WINDOW tray = xvt_trayicon_create(task, 10212, name()); // Washing machine + + if (tray != NULL_WIN) + xvt_vobj_set_visible(task, FALSE); + xvt_timer_create(m.win(), mins * 60 * 1000L); + while (m.run() == K_ENTER) + { + const TString& DSN = m.get(F_DSN); + const TDate datef = m.get(F_DATA_INI); + const TDate datet = m.get(F_DATA_FIN); + // Non ho la più pallida idea di cosa siano ste robe + xvt_vobj_set_visible(task, TRUE); + esporta(DSN, datef, datet); + xvt_vobj_set_visible(task, FALSE); + } + xvt_trayicon_destroy(tray); + } + else + { + while (m.run() == K_ENTER) + { + const TString& DSN = m.get(F_DSN); + const TDate datef = m.get(F_DATA_INI); + const TDate datet = m.get(F_DATA_FIN); + // Chiamo la funzione globale esporta + esporta(DSN, datef, datet); + } + } +} + + +int ca2600(int argc, char* argv[]) +{ + TCampass_app app; + // Imposto le tabelle da utilizzare + app.setTable("A01A|O01A|O01B|O01C|O02A|O02C|O03A|P01A|P01B|P02A"); + app.run(argc, argv, TR("Collegamento Campo/Compass")); + return 0; +} diff --git a/src/ca/ca2600a.h b/src/ca/ca2600a.h new file mode 100644 index 000000000..ec6ba4335 --- /dev/null +++ b/src/ca/ca2600a.h @@ -0,0 +1,3 @@ +#define F_DSN 250 +#define F_DATA_INI 251 +#define F_DATA_FIN 252 diff --git a/src/ca/ca2600a.uml b/src/ca/ca2600a.uml new file mode 100644 index 000000000..bc99538d6 --- /dev/null +++ b/src/ca/ca2600a.uml @@ -0,0 +1,70 @@ +#include "ca2600a.h" + +TOOLBAR "topbar" 0 0 0 2 + +#include + +ENDPAGE + +PAGE "Invio a Board" 0 2 0 0 + +STRING F_DSN 260 40 +BEGIN + PROMPT 1 0 "ODBC DSN " +END + +DATE F_DATA_INI +BEGIN + PROMPT 1 2 "Data iniziale " + FLAGS "H" +END + +DATE F_DATA_FIN +BEGIN + PROMPT 1 3 "Data finale " + FLAGS "H" +END + +STRING DLG_PROFILE 260 50 +BEGID + PROMPT 1 -1 "Profilo " + PSELECT +END + +ENDPAGE + +ENDMASK + +PAGE "Riga" -1 -1 60 5 + +BOOLEAN 101 +BEGIN + PROMPT 1 1 "Selezionato per invio" +END + +NUMBER 102 2 +BEGIN + PROMPT 1 3 "File " + FLAGS "L" +END + +STRING 103 32 +BEGIN + PROMPT 10 2 "" + FLAGS "L" +END + +NUMBER 104 8 +BEGIN + PROMPT 30 1 "" + FLAGS "L" +END + +BUTTON DLG_CANCEL 8 2 +BEGIN + PROMPT -11 -1 "" +END + +ENDPAGE + +ENDMASK