1095 lines
28 KiB
C++
1095 lines
28 KiB
C++
#include <execp.h>
|
||
#include <progind.h>
|
||
#include <tabutil.h>
|
||
|
||
#include "velib04.h"
|
||
|
||
TElaborazione * find_elab(TDocumento & doc, TTipo_elaborazione tipo)
|
||
{
|
||
HIDDEN TArray __recs;
|
||
HIDDEN TArray __elabs;
|
||
TElaborazione * elab = nullptr;
|
||
|
||
if (__elabs.items() == 0)
|
||
{
|
||
TCursor c(new TRelation("ELD"));
|
||
int items = c.items();
|
||
|
||
for (c = 0L; c.pos() < items; ++c)
|
||
__recs.add(c.curr());
|
||
}
|
||
FOR_EACH_ARRAY_ITEM(__elabs, r, o)
|
||
{
|
||
TRectype * rec = (TRectype *) o;
|
||
|
||
if (tipo == (TTipo_elaborazione)rec->get_int("I0"))
|
||
{
|
||
TString8 codice = rec->get("CODTAB");
|
||
|
||
elab = (TElaborazione *) __elabs.objptr(r);
|
||
if (elab == nullptr)
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case _esterna:
|
||
elab = new TElaborazione_esterna(codice);
|
||
break;
|
||
case _consegna_ordini:
|
||
elab = new TConsegna_ordini(codice);
|
||
break;
|
||
case _fatturazione_bolle:
|
||
elab = new TFatturazione_bolle(codice);
|
||
break;
|
||
case _contabilizzazione:
|
||
elab = new TContabilizzazione(codice);
|
||
break;
|
||
case _copia_documento:
|
||
elab = new TCopia_documento(codice);
|
||
break;
|
||
case _generazione_effetti:
|
||
elab = new TGenerazione_effetti(codice);
|
||
break;
|
||
case _consuntivazione_produzione:
|
||
elab = new TConsuntivazione_produzione(codice);
|
||
break;
|
||
case _contabilizzazione_analitica:
|
||
elab = new TContabilizzazione_analitica(codice);
|
||
break;
|
||
case _raggruppamento_documento:
|
||
elab = new TRaggruppamento_documento(codice);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if (elab != nullptr)
|
||
__elabs.add(elab, r);
|
||
if (elab->codice_numerazione_iniziale().blank() || elab->codice_numerazione_iniziale() == doc.numerazione())
|
||
{
|
||
int i = 0;
|
||
|
||
for (TString tipoi = elab->tipo_iniziale(i); i < 10 && tipoi.full(); tipoi = elab->tipo_iniziale(++i))
|
||
if (doc.tipo().codice() == tipoi && doc.stato() == elab->stato_iniziale(i))
|
||
return elab;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return elab;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Lista di documenti
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TDate TLista_documenti::num2date(char provv, int anno, const char* codnum, long num) const
|
||
{
|
||
TLocalisamfile doc(LF_DOC);
|
||
CHECK(num > 0, "Numero documento nullo.");
|
||
TDocumento::set_key(doc.curr(), provv, anno, codnum, num);
|
||
|
||
if (doc.read(_isgteq) != NOERR) // In caso d'errore ...
|
||
doc.last(); // prendi l'ultimo
|
||
|
||
return doc.get_date(DOC_DATADOC);
|
||
}
|
||
|
||
int TLista_documenti::find(char provv, int anno, const char* codnum, long ndoc) const
|
||
{
|
||
const int it = items();
|
||
|
||
if (ndoc > 0 && it > 0)
|
||
{
|
||
for (int i = 0; i < it; i++)
|
||
{
|
||
const TRectype& head = doc(i).head();
|
||
|
||
if ((head.get_long(DOC_NDOC) == ndoc) &&
|
||
(head.get_char(DOC_PROVV) == provv) &&
|
||
(head.get_int(DOC_ANNO) == anno) &&
|
||
(head.get(DOC_CODNUM) == codnum))
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
int TLista_documenti::find(const TDocumento & doc) const
|
||
{
|
||
const char provv = doc.get_char(DOC_PROVV);
|
||
const int anno = doc.get_int(DOC_ANNO);
|
||
const TString& codnum = doc.get(DOC_CODNUM);
|
||
const long ndoc = doc.get_long(DOC_NDOC);
|
||
|
||
return find(provv, anno, codnum, ndoc);
|
||
}
|
||
|
||
int TLista_documenti::read(char provv, char tipocf, long clifo, int anno,
|
||
TToken_string& tipidoc, TToken_string& statidoc, const char * docfilter,
|
||
const TDate& dd, const TDate& ad, const char* codnum, long dn, long an)
|
||
{
|
||
CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?");
|
||
CHECK(tipocf == 'C' || tipocf == 'F' || tipocf == ' ', "Il tipo deve essere Cliente o Fornitore o Entrambi");
|
||
CHECKD(tipocf == ' ' || clifo > 0L, "Codice cliente non valido", clifo);
|
||
CHECKD(anno > 2000, "Anno non valido: ", anno);
|
||
|
||
const int key = (tipocf == ' ' && clifo == 0L) ? 1:2;
|
||
TRelation doc(LF_DOC);
|
||
TRectype start(LF_DOC), stop(LF_DOC);
|
||
int anno_start, anno_stop;
|
||
|
||
if (key == 2)
|
||
{
|
||
start.put(DOC_TIPOCF, tipocf);
|
||
stop.put(DOC_TIPOCF, tipocf);
|
||
|
||
start.put(DOC_CODCF, clifo);
|
||
stop.put(DOC_CODCF, clifo);
|
||
}
|
||
start.put(DOC_PROVV, provv);
|
||
stop.put(DOC_PROVV, provv);
|
||
|
||
anno_start = anno_stop = anno;
|
||
|
||
if (dd.ok())
|
||
{
|
||
anno_start = dd.year();
|
||
start.put(DOC_ANNO, anno_start);
|
||
}
|
||
|
||
if (ad.ok())
|
||
{
|
||
anno_stop = ad.year();
|
||
stop.put(DOC_ANNO, anno_stop);
|
||
}
|
||
|
||
TString filter;
|
||
|
||
if (dn > 0)
|
||
{
|
||
const TDate d(num2date(provv, anno_start, codnum, dn));
|
||
|
||
start.put(DOC_DATADOC, d);
|
||
start.put(DOC_ANNO, d.year());
|
||
start.put(DOC_NDOC, dn);
|
||
}
|
||
else
|
||
{
|
||
if (dd.ok() && dd > botime)
|
||
{
|
||
if (key == 2)
|
||
start.put(DOC_DATADOC, dd);
|
||
|
||
if (anno_start <= anno_stop)
|
||
start.put(DOC_ANNO, anno_start);
|
||
}
|
||
}
|
||
|
||
if (an > 0)
|
||
{
|
||
const TDate d(num2date(provv, anno_stop, codnum, an));
|
||
stop.put(DOC_DATADOC, d);
|
||
stop.put(DOC_ANNO, d.year());
|
||
stop.put(DOC_NDOC, an);
|
||
}
|
||
else
|
||
{
|
||
if (ad.ok() && ad < eotime)
|
||
{
|
||
if (key == 2)
|
||
stop.put(DOC_DATADOC, ad);
|
||
|
||
stop.put(DOC_ANNO, anno_stop);
|
||
}
|
||
}
|
||
if (key == 1 && (dd.ok() || ad.ok()))
|
||
filter << "(BETWEEN(" << DOC_DATADOC << ",\"" << dd.stringa() << "\",\"" << ad.stringa() << "\"))";
|
||
if (docfilter && *docfilter)
|
||
{
|
||
if (filter.full())
|
||
filter << "&&";
|
||
filter << '(' << docfilter << ")";
|
||
}
|
||
if (codnum && *codnum > ' ')
|
||
{
|
||
if (!start.get(DOC_DATADOC).empty())
|
||
start.put(DOC_CODNUM, codnum);
|
||
|
||
if (!stop.get(DOC_DATADOC).empty())
|
||
stop.put(DOC_CODNUM, codnum);
|
||
if (filter.full())
|
||
filter << "&&";;
|
||
filter << '(' << DOC_CODNUM << "=\"" << codnum << '"' << ')';
|
||
}
|
||
|
||
TCursor cur(&doc, filter, key, &start, &stop);
|
||
const TRectype& head = cur.curr();
|
||
|
||
_documenti.destroy();
|
||
const long items = cur.items();
|
||
for (cur = 0L; cur.pos() < items; ++cur)
|
||
{
|
||
const TString4 tipodoc = head.get(DOC_TIPODOC);
|
||
const TString4 statodoc = head.get(DOC_STATO);
|
||
bool match = (tipidoc.items() == 0);
|
||
|
||
for (int i = tipidoc.items()-1; i>=0; i--)
|
||
{
|
||
const TString & tipo = tipidoc.get(i);
|
||
|
||
if (tipo.blank() || tipodoc == tipo)
|
||
{
|
||
const TString & stato = statidoc.get(i);
|
||
|
||
if (stato.blank() || statodoc == stato)
|
||
{
|
||
match = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (match)
|
||
{
|
||
TDocumento* d = new TDocumento(head);
|
||
_documenti.add(d);
|
||
}
|
||
}
|
||
|
||
return _documenti.items();
|
||
}
|
||
|
||
int TLista_documenti::write(bool re) const
|
||
{
|
||
const int docs = _documenti.items();
|
||
TString msg;
|
||
if (re)
|
||
msg.format(FR("Aggiornamento di %d documenti"), docs);
|
||
else
|
||
msg.format(FR("Creazione di %d documenti"), docs);
|
||
|
||
TProgress_monitor pi(docs, msg, true);
|
||
int err = NOERR;
|
||
for (int i = 0; i < docs && err == NOERR; i++)
|
||
{
|
||
TDocumento& d = (TDocumento&)doc(i);
|
||
err = d.write(re);
|
||
d.flush_rows();
|
||
if (!pi.add_status(1))
|
||
break;
|
||
}
|
||
|
||
return err;
|
||
}
|
||
|
||
static int doc_cmp(const TSortable& o1, const TSortable& o2, void* jolly)
|
||
{
|
||
const TDocumento& d1 = (const TDocumento&)o1;
|
||
const TDocumento& d2 = (const TDocumento&)o2;
|
||
TToken_string& order_by = *(TToken_string*)jolly;
|
||
|
||
int cmp = 0;
|
||
FOR_EACH_TOKEN(order_by, fld)
|
||
{
|
||
const TFieldtypes ft = d1.type(fld);
|
||
switch(ft)
|
||
{
|
||
case _intfld :
|
||
case _longfld :
|
||
case _intzerofld :
|
||
case _longzerofld: cmp = d1.get_long(fld) - d2.get_long(fld); break;
|
||
case _datefld : cmp = d1.get_date(fld) - d2.get_date(fld); break;
|
||
default : cmp = d1.get(fld).compare(d2.get(fld), -1, true); break;
|
||
}
|
||
if (cmp != 0)
|
||
break;
|
||
}
|
||
return cmp;
|
||
}
|
||
|
||
int TLista_documenti::add(const TLista_documenti & docs, const bool no_dups)
|
||
{
|
||
const int ndocs = docs.items();
|
||
|
||
for (int i = 0; i < ndocs; i++)
|
||
if (!no_dups || !exist(docs[i].get_char(DOC_PROVV), docs[i].anno(), docs[i].codice_numerazione().codice(), docs[i].numero()))
|
||
add(docs[i]);
|
||
return items();
|
||
}
|
||
|
||
int TLista_documenti::sort(const char* fields)
|
||
{
|
||
TToken_string orderby = fields;
|
||
|
||
if (orderby.blank())
|
||
{
|
||
orderby.add(DOC_PROVV);
|
||
orderby.add(DOC_ANNO);
|
||
orderby.add(DOC_CODNUM);
|
||
orderby.add(DOC_NDOC);
|
||
}
|
||
_documenti.sort(doc_cmp, &orderby);
|
||
return items();
|
||
}
|
||
|
||
const TLista_documenti & TLista_documenti::merge(const TLista_documenti & d)
|
||
{
|
||
const int ndocs = d.items();
|
||
|
||
for (int i = 0; i < ndocs; i++)
|
||
{
|
||
const TDocumento & doc = d[i];
|
||
|
||
if (find(doc) == -1)
|
||
add(doc);
|
||
}
|
||
sort();
|
||
return *this;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TLista_clifo
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void TLista_clifo::TClifo::init(const TRectype& rec, const TRectype& ven)
|
||
{
|
||
_codice = rec.get_long(CLI_CODCF);
|
||
CHECK(_codice > 0, "Codice cliente nullo");
|
||
|
||
if (!ven.empty())
|
||
{
|
||
_agente = ven.get_long(CLI_CODAG);
|
||
_zona = ven.get_long(CLI_CODZONA);
|
||
}
|
||
else
|
||
_agente = _zona = 0;
|
||
}
|
||
|
||
bool TLista_clifo::TClifo::read(char tipo, long cod)
|
||
{
|
||
TRelation clifo(LF_CLIFO);
|
||
clifo.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF");
|
||
|
||
TRectype& curr = clifo.curr();
|
||
curr.put(CLI_TIPOCF, tipo);
|
||
curr.put(CLI_CODCF, cod);
|
||
if (clifo.read() == NOERR)
|
||
init(curr, clifo.curr(LF_CFVEN));
|
||
else
|
||
zero();
|
||
|
||
return ok();
|
||
}
|
||
|
||
TLista_clifo::TClifo::TClifo(const TRectype& rec)
|
||
{
|
||
CHECK(rec.num() == LF_CLIFO || rec.num() == LF_DOC, "Record senza TIPOCF e CODCF");
|
||
const char tipo = rec.get_char(CLI_TIPOCF);
|
||
const long codice = rec.get_long(CLI_CODCF);
|
||
read(tipo, codice);
|
||
}
|
||
|
||
int TLista_clifo::leggi(long dc, long ac, long da, long aa, const char * dz, const char * az)
|
||
{
|
||
TRelation clifo(LF_CLIFO);
|
||
clifo.add(LF_CFVEN, "TIPOCF==TIPOCF|CODCF==CODCF");
|
||
|
||
TRectype start(LF_CLIFO), stop(LF_CLIFO);
|
||
|
||
start.put(CLI_TIPOCF, tipo());
|
||
if (dc > 0)
|
||
start.put(CLI_CODCF, dc);
|
||
|
||
stop.put(CLI_TIPOCF, tipo());
|
||
if (ac > 0)
|
||
stop.put(CLI_CODCF, ac);
|
||
|
||
TString filter(32);
|
||
if (da > 0)
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODAG << ">=" << da << ')';
|
||
if (aa > 0)
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODAG << "<=" << aa << ')';
|
||
}
|
||
if (dz && (*dz !='\0'))
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=\"" << dz << "\")";
|
||
}
|
||
if (az && (*az !='\0'))
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=\"" << az << "\")";
|
||
}
|
||
|
||
TCursor cur(&clifo, "", 1, &start, &stop);
|
||
if (filter.not_empty())
|
||
cur.setfilter(filter, TRUE);
|
||
const TRectype& cli = cur.curr();
|
||
const TRectype& ven = cur.curr(LF_CFVEN);
|
||
for (cur = 0; cur.ok(); ++cur)
|
||
{
|
||
TClifo* c = new TClifo(cli, ven);
|
||
_clifo.add(c);
|
||
}
|
||
|
||
if (dc > 0 || ac > 0)
|
||
ordina_per_codice();
|
||
else
|
||
if (da > 0 || aa > 0)
|
||
ordina_per_agente();
|
||
else
|
||
if ((dz && (*dz !='\0')) || (az && (*dz !='\0')))
|
||
ordina_per_zona();
|
||
|
||
return _clifo.items();
|
||
}
|
||
|
||
static bool add_filter(TString& filter, const char* name, long da, long al)
|
||
{
|
||
if (!(da > 0 || al > da))
|
||
return false;
|
||
if (filter.full()) filter << "&&";
|
||
|
||
TString16 field = name;
|
||
if (xvt_str_compare_ignoring_case(name, DOC_CODCF) != 0)
|
||
field.insert("17->");
|
||
|
||
if (da == al)
|
||
filter << "(" << field << "==" << da << ")"; else
|
||
if (da <= 0 && al > 0)
|
||
filter << "(" << field << "<=" << al << ")"; else
|
||
if (da > 0 && al < da)
|
||
filter << "(" << field << ">=" << da << ")";
|
||
else
|
||
filter << "(BETWEEN(" << field << ',' << da << ',' << al << "))";
|
||
return true;
|
||
}
|
||
|
||
int TLista_clifo::leggi_doc(const TElaborazione& eld, const TDate& dd, const TDate& ad,
|
||
long dc, long ac, long da, long aa, const char* dz, const char* az)
|
||
{
|
||
if (!dd.ok())
|
||
return leggi(dc, ac, da, aa, dz, az);
|
||
|
||
TRelation doc(LF_DOC);
|
||
doc.add(LF_CFVEN, "TIPOCF==TIPOCF|CODCF==CODCF");
|
||
const TRectype& rec = doc.curr();
|
||
|
||
TRectype start(rec), stop(rec);
|
||
start.put(DOC_DATADOC, dd);
|
||
stop.put (DOC_DATADOC, ad);
|
||
|
||
TString filter(127);
|
||
add_filter(filter, DOC_CODCF, dc, ac);
|
||
add_filter(filter, CLI_CODAG, da, aa);
|
||
|
||
if (dz && (*dz !='\0'))
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=\"" << dz << "\")";
|
||
}
|
||
if (az && (*az !='\0'))
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=\"" << az << "\")";
|
||
}
|
||
|
||
TCursor cur(&doc, filter, 3, &start, &stop);
|
||
TBit_array buoni;
|
||
for (cur = 0; cur.ok(); ++cur)
|
||
{
|
||
const char tipocf = rec.get_char(DOC_TIPOCF);
|
||
const long codcf = rec.get_long(DOC_CODCF);
|
||
if (tipocf == tipo() && !buoni[codcf])
|
||
{
|
||
if (eld.is_document_ok(rec))
|
||
{
|
||
TClifo* c = new TClifo(tipocf, codcf);
|
||
_clifo.add(c, codcf);
|
||
buoni.set(codcf);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (da > 0 || aa > 0)
|
||
ordina_per_agente();
|
||
else
|
||
{
|
||
if ((dz && (*dz !='\0')) || (az && (*dz !='\0')))
|
||
ordina_per_zona();
|
||
else
|
||
ordina_per_codice();
|
||
}
|
||
|
||
return _clifo.items();
|
||
}
|
||
|
||
|
||
int TLista_clifo::leggi_ragsoc(const char *dr, const char * ar, long da, long aa, const char * dz, const char * az)
|
||
{
|
||
TRelation clifo(LF_CLIFO);
|
||
clifo.add(LF_CFVEN, "TIPOCF==TIPOCF|CODCF==CODCF");
|
||
|
||
TRectype start(LF_CLIFO), stop(LF_CLIFO);
|
||
|
||
start.put(CLI_TIPOCF, tipo());
|
||
if (dr && *dr)
|
||
start.put(CLI_RAGSOC, dr);
|
||
|
||
stop.put(CLI_TIPOCF, tipo());
|
||
if (ar && *ar)
|
||
stop.put(CLI_RAGSOC, ar);
|
||
|
||
TString filter(32);
|
||
if (da > 0)
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODAG << ">=" << da << ')';
|
||
if (aa > 0)
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODAG << "<=" << aa << ')';
|
||
}
|
||
if (dz && (*dz !='\0'))
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=\"" << dz << "\")";
|
||
}
|
||
if (az && (*az !='\0'))
|
||
{
|
||
if (filter.not_empty()) filter << "&&";
|
||
filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=\"" << az << "\")";
|
||
}
|
||
|
||
TCursor cur(&clifo, "", 2, &start, &stop);
|
||
if (filter.not_empty())
|
||
cur.setfilter(filter, TRUE);
|
||
const TRectype& cli = cur.curr();
|
||
const TRectype& ven = cur.curr(LF_CFVEN);
|
||
for (cur = 0; cur.ok(); ++cur)
|
||
{
|
||
TClifo* c = new TClifo(cli, ven);
|
||
_clifo.add(c);
|
||
}
|
||
|
||
return _clifo.items();
|
||
}
|
||
|
||
int TLista_clifo::sort_by_code(const TObject** o1, const TObject** o2)
|
||
{
|
||
TLista_clifo::TClifo* c1 = (TLista_clifo::TClifo*)*o1;
|
||
TLista_clifo::TClifo* c2 = (TLista_clifo::TClifo*)*o2;
|
||
const long d = c1->codice() - c2->codice();
|
||
return d == 0L ? 0 : (d > 0 ? +1 : -1);
|
||
}
|
||
|
||
int TLista_clifo::sort_by_agent(const TObject** o1, const TObject** o2)
|
||
{
|
||
TLista_clifo::TClifo* c1 = (TLista_clifo::TClifo*)*o1;
|
||
TLista_clifo::TClifo* c2 = (TLista_clifo::TClifo*)*o2;
|
||
const long d = c1->agente() - c2->agente();
|
||
return d == 0L ? 0 : (d > 0 ? +1 : -1);
|
||
}
|
||
|
||
int TLista_clifo::sort_by_zone(const TObject** o1, const TObject** o2)
|
||
{
|
||
TLista_clifo::TClifo* c1 = (TLista_clifo::TClifo*)*o1;
|
||
TLista_clifo::TClifo* c2 = (TLista_clifo::TClifo*)*o2;
|
||
const long d = c1->zona() - c2->zona();
|
||
return d == 0L ? 0 : (d > 0 ? +1 : -1);
|
||
}
|
||
|
||
int TLista_clifo::ordina_per_codice()
|
||
{
|
||
_clifo.sort(sort_by_code);
|
||
return _clifo.items();
|
||
}
|
||
|
||
int TLista_clifo::ordina_per_agente()
|
||
{
|
||
_clifo.sort(sort_by_agent);
|
||
return _clifo.items();
|
||
}
|
||
|
||
int TLista_clifo::ordina_per_zona()
|
||
{
|
||
_clifo.sort(sort_by_zone);
|
||
return _clifo.items();
|
||
}
|
||
|
||
int TLista_clifo::find(long cod) const
|
||
{
|
||
int i;
|
||
|
||
for (i = items()-1; i >= 0; i--)
|
||
if (clifo(i).codice() == cod) break;
|
||
return i;
|
||
}
|
||
|
||
int TLista_clifo::add(long cod)
|
||
{
|
||
int pos = find(cod);
|
||
if (pos < 0)
|
||
{
|
||
TClifo* c = new TClifo(tipo(), cod);
|
||
pos = _clifo.add(c);
|
||
}
|
||
return pos;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TParametri_elaborazione
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void TParametri_elaborazione::set(const char* name, const char* val)
|
||
{
|
||
_par.add(name, new TString(val), true);
|
||
}
|
||
|
||
const TString & TParametri_elaborazione::get(const char * name) const
|
||
{
|
||
const TObject* val = _par.objptr(name);
|
||
return val ? *(const TString*)val : EMPTY_STRING;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TElaborazione
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const TString& TElaborazione::tipo_iniziale(int i) const
|
||
{
|
||
if (i >= 0 && i < 10)
|
||
{
|
||
const TString& t = get("S2").smid(i*4, 4);
|
||
if (t.full())
|
||
return ((TString&)t).rtrim();
|
||
}
|
||
return EMPTY_STRING;
|
||
}
|
||
|
||
const char TElaborazione::stato_iniziale(int i) const
|
||
{
|
||
if (i < 5)
|
||
{
|
||
const TString s = get("S7").smid(i, 1);
|
||
|
||
return s[0];
|
||
}
|
||
else
|
||
if (i < 10)
|
||
{
|
||
const TString s = get("S10").smid(i - 5 , 1);
|
||
|
||
return s[0];
|
||
}
|
||
return '\0';
|
||
}
|
||
|
||
|
||
bool TElaborazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo)
|
||
{
|
||
SORRY_BOX();
|
||
return false;
|
||
}
|
||
|
||
bool TElaborazione::elabora_lista(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab)
|
||
{
|
||
SORRY_BOX();
|
||
return false;
|
||
}
|
||
|
||
TElaborazione::TElaborazione(const char* cod) : TRectype(LF_TABCOM)
|
||
{
|
||
settab("ELD");
|
||
if (cod && *cod)
|
||
read(cod);
|
||
}
|
||
|
||
int TElaborazione::read(const char* cod)
|
||
{
|
||
int err = NOERR;
|
||
TRectype::operator=(cache().get("%ELD", cod));
|
||
if (empty())
|
||
err = _iskeynotfound;
|
||
return err;
|
||
}
|
||
|
||
bool TElaborazione::is_document_ok(const TRectype& doc) const
|
||
{
|
||
bool ok = false;
|
||
const TString4 codnum = doc.get(DOC_CODNUM);
|
||
const TString& codnumel = codice_numerazione_iniziale();
|
||
if (codnumel.blank() || codnum == codnumel)
|
||
{
|
||
const TString4 tipodoc = doc.get(DOC_TIPODOC);
|
||
const char stato = doc.get_char(DOC_STATO);
|
||
for (int i = 0; !ok && i < TElaborazione::_max_tipi_doc_elab; i++)
|
||
{
|
||
const TString& tipel = tipo_iniziale(i);
|
||
if (tipel.blank())
|
||
break;
|
||
const char stael = stato_iniziale(i);
|
||
ok = tipodoc == tipel && stato == stael;
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void TElaborazione::tipi_stati_iniziali(TToken_string& tipi, TToken_string& stati) const
|
||
{
|
||
TString4 t;
|
||
TString codnum = codice_numerazione_iniziale();
|
||
TToken_string all_tipi;
|
||
if (codnum.full())
|
||
all_tipi = TCodice_numerazione(codnum).tipi_doc();
|
||
|
||
tipi.cut(0);
|
||
stati.cut(0);
|
||
for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++)
|
||
{
|
||
t = tipo_iniziale(i);
|
||
const char s = stato_iniziale(i);
|
||
|
||
if (t.blank() && s > ' ' && all_tipi.full())
|
||
{
|
||
tipi.add(all_tipi);
|
||
for (int j = 0; j < all_tipi.items(); j++)
|
||
stati.add(s);
|
||
}
|
||
else
|
||
if (t.full() && s > ' ')
|
||
{
|
||
tipi.add(t);
|
||
stati.add(s);
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
CHECK(!tipi.empty_items(), "Nessun tipo documento valido");
|
||
CHECK(!stati.empty_items(), "Nessuno stato documento valido");
|
||
}
|
||
|
||
bool TElaborazione::doc_ok(const TRectype & rec) const
|
||
{
|
||
TString4 t;
|
||
const TString4 tipo = rec.get(DOC_TIPODOC);
|
||
const char stato = rec.get_char(DOC_STATO);
|
||
for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++)
|
||
{
|
||
t = tipo_iniziale(i);
|
||
const char s = stato_iniziale(i);
|
||
if (t.blank() && s == '\0')
|
||
break;
|
||
else
|
||
if (t.full() || s > ' ')
|
||
{
|
||
if ((t == tipo) && (s == stato))
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TElaborazione_esterna
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TElaborazione_esterna::TElaborazione_esterna(const char* cod)
|
||
: TElaborazione(cod)
|
||
{ }
|
||
|
||
bool TElaborazione_esterna::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
if (applicazione_esterna().blank())
|
||
return error_box("Non <20> stato specificato il nome del'applicazione esterna");
|
||
CHECK(doc_in.items() == 1, "Si deve specificare un solo documento in entrata");
|
||
CHECK(doc_out.items() <= 1, "Si deve specificare un solo documento in uscita");
|
||
TDocumento& d = doc_in[0];
|
||
|
||
TFilename name; name.temp("ext");
|
||
TString16 par;
|
||
|
||
{
|
||
TConfig c(name, "Transaction");
|
||
c.set("Action", codice());
|
||
c.set("DataElab", data_elab.string());
|
||
c.set("Interattivo", interattivo);
|
||
|
||
if (doc_out.items() == 1)
|
||
{
|
||
c.set("ProvvOut", doc_out[0].get(DOC_PROVV));
|
||
c.set("AnnoOut", doc_out[0].get(DOC_ANNO));
|
||
c.set("CodNumOut", doc_out[0].get(DOC_CODNUM));
|
||
c.set("NDocOut", doc_out[0].get(DOC_NDOC));
|
||
}
|
||
else if (codice_numerazione_finale().full())
|
||
{
|
||
c.set("ProvvOut", d.get(DOC_PROVV));
|
||
c.set("AnnoOut", d.get(DOC_ANNO));
|
||
c.set("CodNumOut", codice_numerazione_finale());
|
||
c.set("NDocOut", 0L);
|
||
}
|
||
|
||
par.format("%d", LF_DOC);
|
||
|
||
const int doc_fields = d.items();
|
||
for (int i = 0; i < doc_fields; i++)
|
||
{
|
||
const char* fname = d.fieldname(i);
|
||
const TFieldref f(fname, LF_DOC);
|
||
f.write(c, par, d.get(fname));
|
||
}
|
||
for (TVariable_field* v = d.first_variable_field(); v ; v = d.succ_variable_field())
|
||
c.set(v->name(), v->get(), par);
|
||
|
||
FOR_EACH_PHYSICAL_RDOC(d, r, row)
|
||
{
|
||
par.format("%d,%d", LF_RIGHEDOC, r);
|
||
const int row_fields = row->items();
|
||
for (int i = 0; i < row_fields; i++)
|
||
{
|
||
const char* fname = row->fieldname(i);
|
||
const TFieldref f(fname, LF_RIGHEDOC);
|
||
f.write(c, par, row->get(fname));
|
||
}
|
||
for (TVariable_field * v = row->first_variable_field(); v ; v = row->succ_variable_field())
|
||
c.set(v->name(), v->get(), par);
|
||
}
|
||
}
|
||
|
||
TString command_line; command_line << applicazione_esterna() << " /i" << name;
|
||
TExternal_app app(command_line);
|
||
if (app.run() == 0)
|
||
{
|
||
TConfig c(name, "Transaction");
|
||
const TString & res = c.get("Result");
|
||
if (res == "SUCCESS")
|
||
{
|
||
TDocumento& d = doc_in[0];
|
||
const int doc_fields = d.items();
|
||
|
||
par.format("%d", LF_DOC);
|
||
for (int i = 0; i < doc_fields; i++)
|
||
{
|
||
const char* fname = d.fieldname(i);
|
||
TFieldref f(fname, LF_DOC);
|
||
d.put(fname, f.read(c, par));
|
||
}
|
||
for (TVariable_field * v = d.first_variable_field(); v ; v = d.succ_variable_field())
|
||
v->put(c.get(v->name(), par));
|
||
|
||
TString_array p;
|
||
c.list_paragraphs(p);
|
||
d.destroy_rows();
|
||
|
||
for (int r = 1; ; r++)
|
||
{
|
||
par.format("%d,%d", LF_RIGHEDOC, r);
|
||
if (p.find(par) < 0)
|
||
break;
|
||
|
||
const TString& tiporiga = c.get(RDOC_TIPORIGA, par, -1, "01");
|
||
TRiga_documento& row = d.new_row(tiporiga);
|
||
|
||
for (int i = row.items()-1; i >= 0; i--)
|
||
{
|
||
const char* fname = row.fieldname(i);
|
||
const TFieldref f(fname, LF_RIGHEDOC);
|
||
const TString& val = f.read(c, par);
|
||
if (val.full())
|
||
row.put(fname, val);
|
||
}
|
||
}
|
||
|
||
const char final = stato_finale_doc_iniziale()[0];
|
||
if (final > '0' && d.stato() != final)
|
||
d.stato(final);
|
||
|
||
return true;
|
||
} else
|
||
if (res == "OUTDOC")
|
||
{
|
||
if (doc_out.items())
|
||
{
|
||
const TString& ndoc = c.get("NDocOut", "Transaction");
|
||
if (ndoc != doc_out[0].get(DOC_NDOC))
|
||
doc_out[0].put(DOC_NDOC, ndoc);
|
||
doc_out[0].read();
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TCopia_documento
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TCopia_documento::TCopia_documento(const char* cod)
|
||
: TElaborazione(cod), _preserve_original_rif(false)
|
||
{ }
|
||
|
||
bool TCopia_documento::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool /*interattivo*/)
|
||
{
|
||
// CHECK(doc_in.items() == doc_out.items(), "Si deve specificare un numero uguale di documenti in entrata ed in uscita");
|
||
|
||
pre_process_input(doc_in);
|
||
for (int d = 0; d < doc_in.items(); d++)
|
||
{
|
||
TDocumento& doc_src = doc_in[d];
|
||
if (doc_out.items() <= d)
|
||
{
|
||
const TString4 codnum = codice_numerazione_finale();
|
||
doc_out.add(new TDocumento('D', doc_src.get_int(DOC_ANNO), codnum, 0L));
|
||
}
|
||
|
||
TDocumento& doc_dest = doc_out[d];
|
||
|
||
doc_dest.copy_contents(doc_src);
|
||
|
||
const TString& tipodoc = tipo_finale();
|
||
|
||
doc_dest.put(DOC_TIPODOC, tipodoc);
|
||
|
||
const TString& stato = stato_finale();
|
||
|
||
doc_dest.put(DOC_STATO, stato);
|
||
doc_dest.zero(DOC_STATO_SDI);
|
||
doc_dest.zero(DOC_XML_NAME);
|
||
doc_dest.zero(DOC_PRG_INVIO);
|
||
|
||
// Scancello tutti gli inutili riferimenti al documento origine
|
||
if (!_preserve_original_rif)
|
||
{
|
||
FOR_EACH_PHYSICAL_RDOC(doc_dest, r, rdoc)
|
||
{
|
||
rdoc->reset_original_rdoc_key();
|
||
rdoc->reset_final_rdoc_key();
|
||
}
|
||
}
|
||
|
||
if (data_elab.ok())
|
||
doc_dest.put(DOC_DATADOC, data_elab);
|
||
doc_src.put(DOC_STATO, stato_finale_doc_iniziale());
|
||
}
|
||
post_process_input(doc_in);
|
||
post_process(doc_out, doc_in);
|
||
|
||
return true;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TRaggruppamento_documento
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TRaggruppamento_documento::TRaggruppamento_documento(const char* cod)
|
||
: TElaborazione(cod)
|
||
{ }
|
||
|
||
bool TRaggruppamento_documento::raggruppabile(const TRiga_documento & rin, const TRiga_documento & rout) const
|
||
{
|
||
bool ok = true;
|
||
TToken_string campi= RDOC_TIPORIGA "|" RDOC_CODIVA;
|
||
TString campo;
|
||
|
||
for (const char* c = campi.get(0); c && ok; c = campi.get())
|
||
{
|
||
campo = rin.get(c);
|
||
ok &= campo == rout.get(c);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TRaggruppamento_documento::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
pre_process_input(doc_in);
|
||
const TString4 codnum = codice_numerazione_finale();
|
||
|
||
for (int d = 0; d < doc_in.items(); d++)
|
||
{
|
||
TDocumento& doc_src = doc_in[d];
|
||
|
||
doc_out.add(new TDocumento('D', doc_src.get_int(DOC_ANNO), codnum, doc_src.get_long(DOC_NDOC)));
|
||
|
||
TDocumento& doc_dest = doc_out[d];
|
||
|
||
TDocumento::copy_data(doc_dest,doc_src);
|
||
|
||
if (interattivo)
|
||
doc_dest.put(DOC_TIPODOC, doc_src.get(DOC_TIPODOC) );
|
||
|
||
if (doc_dest.physical_rows() > 0)
|
||
doc_dest.destroy_rows();
|
||
|
||
FOR_EACH_PHYSICAL_RDOC(doc_src, nr_input, rin) // ... cerca una riga compatibile
|
||
{
|
||
bool found = false;
|
||
|
||
if (!rin->sola_descrizione())
|
||
{
|
||
FOR_EACH_PHYSICAL_RDOC(doc_dest, nr_output, rout)
|
||
{
|
||
if (raggruppabile(*rin, *rout))
|
||
{
|
||
rout->add(RDOC_PREZZO,rin->get_real(RDOC_PREZZO));
|
||
found = true;
|
||
rout->add(RDOC_QTAGG1, rin->get_real(RDOC_QTAGG1));
|
||
rout->add(RDOC_QTAGG2, rin->get_real(RDOC_QTAGG2));
|
||
rout->add(RDOC_QTAGG3, rin->get_real(RDOC_QTAGG3));
|
||
rout->add(RDOC_QTAGG4, rin->get_real(RDOC_QTAGG4));
|
||
rout->add(RDOC_QTAGG5, rin->get_real(RDOC_QTAGG5));
|
||
if (rout->get(RDOC_RIGAEVASA) && (!rin->get_bool(RDOC_RIGAEVASA)))
|
||
{
|
||
rout->put(RDOC_RIGAEVASA, false);
|
||
rout->put(RDOC_QTAEVASA, ZERO);
|
||
}
|
||
rout->add(RDOC_TARA, rin->get_real(RDOC_TARA));
|
||
rout->add(RDOC_PNETTO, rin->get_real(RDOC_PNETTO));
|
||
rout->add(RDOC_NCOLLI, rin->get_real(RDOC_NCOLLI));
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (!found)
|
||
{
|
||
TRiga_documento & row = doc_dest.new_row(); // ... crea una riga nuova e
|
||
|
||
TDocumento::copy_data(row, *rin);
|
||
|
||
row.zero(RDOC_CODMAG);
|
||
row.zero(RDOC_CODART);
|
||
row.zero(RDOC_CODARTMAG);
|
||
row.put(RDOC_CHECKED, true);
|
||
row.zero(RDOC_LIVELLO);
|
||
row.zero(RDOC_RIDPREZZO);
|
||
row.zero(RDOC_UMQTA);
|
||
row.put(RDOC_QTA,UNO);
|
||
if (row.get(RDOC_RIGAEVASA))
|
||
row.put(RDOC_QTAEVASA, UNO);
|
||
else
|
||
row.put(RDOC_QTAEVASA, ZERO);
|
||
|
||
row.zero(RDOC_DATACONS);
|
||
row.zero(RDOC_SCONTO);
|
||
row.zero(RDOC_CAUSMAG);
|
||
row.zero(RDOC_CODMAGC);
|
||
row.zero(RDOC_IMPIANTO);
|
||
row.zero(RDOC_LINEA);
|
||
}
|
||
}
|
||
|
||
const TString & stato = stato_finale();
|
||
|
||
doc_dest.put(DOC_STATO, stato);
|
||
doc_src.put(DOC_STATO, stato_finale_doc_iniziale());
|
||
}
|
||
post_process_input(doc_in);
|
||
post_process(doc_out, doc_in);
|
||
return true;
|
||
}
|