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
This commit is contained in:
mtollari 2016-10-21 10:43:42 +00:00
parent eff14c298e
commit 550794c12a
5 changed files with 500 additions and 4 deletions

View File

@ -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;

View File

@ -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

421
src/ca/ca2600.cpp Normal file
View File

@ -0,0 +1,421 @@
#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <odbcrset.h>
#include <relation.h>
#include <utility.h>
#include <doc.h>
#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;
}

3
src/ca/ca2600a.h Normal file
View File

@ -0,0 +1,3 @@
#define F_DSN 250
#define F_DATA_INI 251
#define F_DATA_FIN 252

70
src/ca/ca2600a.uml Normal file
View File

@ -0,0 +1,70 @@
#include "ca2600a.h"
TOOLBAR "topbar" 0 0 0 2
#include <elabar.h>
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