8836353570
git-svn-id: svn://10.65.10.50/branches/R_10_00@22963 c028cbd2-c16b-5b4b-a496-9718f37d4682
561 lines
16 KiB
C++
561 lines
16 KiB
C++
#include "../ve/velib04.h"
|
||
#include "../ca/calib01.h"
|
||
#include "pe1400.h"
|
||
#include "pe1500.h"
|
||
|
||
#include "../ca/fasi.h"
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utilities
|
||
///////////////////////////////////////////////////////////
|
||
|
||
int pe_numero_fasi(const TRecord_array& preventivo)
|
||
{
|
||
static const TString4 strFasi = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaFase", "05");
|
||
int level = 0;
|
||
for (int i = preventivo.last_row(); i > 0; i = preventivo.pred_row(i))
|
||
{
|
||
const TRectype& rdoc = preventivo.row(i);
|
||
const TString& tr = rdoc.get(RDOC_TIPORIGA);
|
||
if (tr == strFasi)
|
||
{
|
||
const int p = rdoc.get_int(RPRV_LEVEL) + 1;
|
||
if (p > level)
|
||
level = p;
|
||
}
|
||
}
|
||
return level;
|
||
}
|
||
|
||
int pe_numero_fasi(const TDocumento& preventivo)
|
||
{ return pe_numero_fasi(preventivo.body()); }
|
||
|
||
int pe_crea_fasi_preventivo(TDocumento& din)
|
||
{
|
||
const TString4 _strFasi = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaFase", "05");
|
||
const TString4 _strDist = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDist", "P1");
|
||
|
||
const int doc_levels = pe_numero_fasi(din);
|
||
if (doc_levels <= 0)
|
||
return 0; // Should never happen
|
||
|
||
TConfig& cfg = ca_config();
|
||
TString_array picture_fasi;
|
||
for (int i = 1; i <= 4; i++)
|
||
{
|
||
const TString& pic = cfg.get("Fsc", "ca", i);
|
||
if (pic.full())
|
||
picture_fasi.add(pic);
|
||
else
|
||
break;
|
||
}
|
||
|
||
const int cfg_levels = picture_fasi.items();
|
||
if (cfg_levels <= 0)
|
||
{
|
||
error_box(TR("Occorre configurare le fasi analitiche"));
|
||
return 0;
|
||
}
|
||
|
||
const bool faseart = din.get_bool(DOC_ADDBOLLI);
|
||
|
||
TLocalisamfile fasi(LF_FASI);
|
||
|
||
TString16 fase[4], curfase; // Livelli delle fasi (max 4)
|
||
int curliv = 0;
|
||
|
||
/* Vedere in futuro come gestire numero di fasi incoerente con la configurazione di CA
|
||
// Crea gli eventuali livelli iniziali mancanti
|
||
const int delta_levels = cfg_levels-doc_levels;
|
||
if (delta_levels > 0)
|
||
{
|
||
TString80 descr;
|
||
for (int lev = 0; lev < delta_levels; lev++)
|
||
{
|
||
fase[lev].format("%0*ld", picture_fasi.row(lev).len(), 0);
|
||
fasi.put(FASI_CODCMSFAS, din.get(DOC_CODCMS));
|
||
|
||
int tot_len = 0;
|
||
for (int l = 0; l <= lev; l++)
|
||
tot_len += picture_fasi.row(lev).len();
|
||
descr.format("%0*ld", tot_len, 0);
|
||
fasi.put(FASI_CODFASE, descr);
|
||
|
||
descr.format(FR("FASE%d"), lev);
|
||
fasi.put(FASI_DESCRIZ, descr);
|
||
|
||
fasi.write_rewrite();
|
||
}
|
||
}
|
||
*/
|
||
|
||
const int nrows = din.physical_rows();
|
||
FOR_EACH_PHYSICAL_RDOC(din, r, rdoc)
|
||
{
|
||
const TString& tr = rdoc->get(RDOC_TIPORIGA);
|
||
if (tr == _strFasi)
|
||
{
|
||
const int level = rdoc->get_int(RPRV_LEVEL); // Livello logico della riga [0,3]
|
||
if (r >= nrows || (level == (cfg_levels-1) && din[r+1].is_descrizione()))
|
||
continue; // Salta fasi vuote
|
||
|
||
if (level >= 0 && level < cfg_levels)
|
||
{
|
||
const int fase_len = picture_fasi.row(level).len();
|
||
TString& cod = fase[level];
|
||
cod = rdoc->get(RDOC_CODART).left(10);
|
||
const int delta_len = fase_len - cod.len();
|
||
if (delta_len != 0)
|
||
{
|
||
if (delta_len > 0)
|
||
cod.rpad(fase_len, ' ');
|
||
else
|
||
cod.cut(fase_len);
|
||
}
|
||
curliv = level;
|
||
curfase.cut(0);
|
||
for (int i = 0; i <= level; i++)
|
||
curfase << fase[i];
|
||
fasi.put(FASI_CODCMSFAS, din.get(DOC_CODCMS));
|
||
fasi.put(FASI_CODFASE, curfase);
|
||
fasi.put(FASI_DESCRIZ, rdoc->get(RDOC_DESCR));
|
||
fasi.write_rewrite();
|
||
}
|
||
} else
|
||
if (tr == _strDist)
|
||
{
|
||
if (faseart && curliv == cfg_levels-2)
|
||
{
|
||
fasi.put(FASI_CODCMSFAS, din.get(DOC_CODCMS));
|
||
TString80 fase = curfase; fase << rdoc->get(RDOC_CODART);
|
||
fasi.put(FASI_CODFASE, fase);
|
||
fasi.put(FASI_DESCRIZ, rdoc->get(RDOC_DESCR));
|
||
fasi.write_rewrite();
|
||
}
|
||
}
|
||
|
||
// Aggiorna codice fase anche nella riga di input
|
||
const TString& lastfase = fasi.get(FASI_CODFASE);
|
||
if (lastfase.full() && rdoc->get(RDOC_FASCMS) != lastfase)
|
||
rdoc->put(RDOC_FASCMS, lastfase);
|
||
}
|
||
|
||
return cfg_levels;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TOrdinazione
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TOrdinazione : public TElaborazione_esterna
|
||
{
|
||
TString4 _strFasi, _strDist;
|
||
|
||
public:
|
||
virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo = false);
|
||
TOrdinazione(const TString& cod);
|
||
};
|
||
|
||
const TRectype& find_precedente(const TDocumento& doc, const TString& codnum, bool& bEvaso)
|
||
{
|
||
TString query, limit;
|
||
limit << RDOC_DAPROVV << '=' << doc.get(DOC_PROVV) << ' '
|
||
<< RDOC_DAANNO << '=' << doc.get_int(DOC_ANNO) << ' '
|
||
<< RDOC_DACODNUM << '=' << doc.get(DOC_CODNUM) << ' '
|
||
<< RDOC_DANDOC << '=' << doc.get_long(DOC_NDOC);
|
||
query << "USE 34 KEY 4"
|
||
<< "\nSELECT CODNUM=\"" << codnum << '"'
|
||
<< "\nFROM " << limit << "\nTO " << limit;
|
||
|
||
bEvaso = false;
|
||
TISAM_recordset recset(query);
|
||
const TRectype& rdoc = recset.cursor()->curr();
|
||
TToken_string key;
|
||
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
|
||
{
|
||
key = rdoc.get(RDOC_PROVV);
|
||
key.add(rdoc.get(RDOC_ANNO));
|
||
key.add(rdoc.get(RDOC_CODNUM));
|
||
key.add(rdoc.get(RDOC_NDOC));
|
||
if (rdoc.get_bool(RDOC_RIGAEVASA))
|
||
{
|
||
bEvaso = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return cache().get(LF_DOC, key);
|
||
}
|
||
|
||
bool TOrdinazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
const TString80 codart = ini_get_string(CONFIG_DITTA, "ci", "CODARTPR");
|
||
|
||
for (int i = 0; i < doc_in.items(); i++)
|
||
{
|
||
TDocumento& din = doc_in[i];
|
||
|
||
// Mi assicuro che ad ogni documento in ingresso ne corrisponda uno in uscita
|
||
if (i >= doc_out.items())
|
||
{
|
||
const TString4 codnum = codice_numerazione_finale();
|
||
bool bEvaso = false;
|
||
const TRectype& ord = find_precedente(din, codnum, bEvaso);
|
||
|
||
if (!ord.empty())
|
||
{
|
||
if (bEvaso)
|
||
{
|
||
if (interattivo)
|
||
error_box("Il preventivo <20> collegato all'ordine gi<67> evaso %s %d/%ld",
|
||
(const char*)ord.get(DOC_CODNUM), ord.get_int(DOC_ANNO), ord.get_long(DOC_NDOC));
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
if (interattivo)
|
||
warning_box("Il preventivo aggiorner<65> l'ordine %s %d/%ld",
|
||
(const char*)ord.get(DOC_CODNUM), ord.get_int(DOC_ANNO), ord.get_long(DOC_NDOC));
|
||
}
|
||
}
|
||
|
||
TDocumento* doc = NULL;
|
||
if (ord.empty())
|
||
{
|
||
doc = new TDocumento('D', data_elab.year(), codnum, 0L);
|
||
doc->put(DOC_TIPODOC, tipo_finale());
|
||
}
|
||
else
|
||
{
|
||
doc = new TDocumento(ord);
|
||
doc->destroy_rows();
|
||
}
|
||
doc_out.add(doc);
|
||
}
|
||
|
||
const int cfg_levels = pe_crea_fasi_preventivo(din);
|
||
if (cfg_levels <= 0)
|
||
return false;
|
||
|
||
TDocumento& don = doc_out[i];
|
||
|
||
din.put(DOC_STATO, stato_finale_doc_iniziale());
|
||
|
||
don.put(DOC_TIPOCF, din.get(DOC_TIPOCF));
|
||
don.put(DOC_CODCF, din.get(DOC_CODCF));
|
||
don.put(DOC_DATADOC, data_elab);
|
||
don.put(DOC_NOTE, din.get(DOC_NOTE));
|
||
don.put(DOC_CODCMS, din.get(DOC_CODCMS));
|
||
don.put(DOC_STATO, stato_finale());
|
||
don.put(DOC_NUMDOCRIF, din.get(DOC_NDOC));
|
||
don.put(DOC_DATADOCRIF, din.get(DOC_DATADOC));
|
||
|
||
const int doc_levels = pe_numero_fasi(din);
|
||
if (doc_levels <= 0)
|
||
continue; // Should never happen
|
||
|
||
const int nrows = din.physical_rows();
|
||
FOR_EACH_PHYSICAL_RDOC(din, r, rdoc)
|
||
{
|
||
const TString& tr = rdoc->get(RDOC_TIPORIGA);
|
||
if (tr == _strFasi)
|
||
{
|
||
const int level = rdoc->get_int(RPRV_LEVEL); // Livello logico della riga [0,3]
|
||
if (r >= nrows || (level == (cfg_levels-1) && din[r+1].is_descrizione()))
|
||
continue; // Salta fasi vuote
|
||
|
||
TRiga_documento& rout = don.new_row(_strFasi);
|
||
TDocumento::copy_data(rout, *rdoc);
|
||
rout.set_original_rdoc_key(*rdoc);
|
||
rout.put(RDOC_CODCMS, din.get(DOC_CODCMS));
|
||
} else
|
||
if (tr == _strDist)
|
||
{
|
||
TRiga_documento& rout = don.new_row(_strDist);
|
||
TDocumento::copy_data(rout, *rdoc);
|
||
rout.set_original_rdoc_key(*rdoc);
|
||
rout.put(RDOC_CODCMS, din.get(DOC_CODCMS));
|
||
rout.put(RDOC_CODARTMAG, codart);
|
||
}
|
||
}
|
||
don.write(); // Salva ordine
|
||
}
|
||
return true;
|
||
}
|
||
|
||
TOrdinazione::TOrdinazione(const TString& cod) : TElaborazione_esterna(cod)
|
||
{
|
||
_strFasi = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaFase", "05");
|
||
_strDist = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDist", "P1");
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Generazione fabbisogno
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TFabbisognazione : public TElaborazione_esterna
|
||
{
|
||
TString4 _strFasi, _strDett, _strDist;
|
||
|
||
public:
|
||
virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo = false);
|
||
|
||
TFabbisognazione(const TString& cod);
|
||
};
|
||
|
||
|
||
bool TFabbisognazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
for (int i = 0; i < doc_in.items(); i++)
|
||
{
|
||
TDocumento& din = doc_in[i];
|
||
if (i >= doc_out.items())
|
||
{
|
||
const TString4 codnum = codice_numerazione_finale();
|
||
bool bEvaso = false;
|
||
const TRectype& fabb = find_precedente(din, codnum, bEvaso);
|
||
|
||
if (!fabb.empty())
|
||
{
|
||
if (bEvaso)
|
||
{
|
||
if (interattivo)
|
||
error_box("Il preventivo <20> collegato al fabbisogno gi<67> evaso %s %d/%ld",
|
||
(const char*)fabb.get(DOC_CODNUM), fabb.get_int(DOC_ANNO), fabb.get_long(DOC_NDOC));
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
if (interattivo)
|
||
warning_box("Il preventivo aggiorner<65> il fabbisogno %s %d/%ld",
|
||
(const char*)fabb.get(DOC_CODNUM), fabb.get_int(DOC_ANNO), fabb.get_long(DOC_NDOC));
|
||
}
|
||
}
|
||
|
||
TDocumento* doc = new TDocumento('D', data_elab.year(), codnum, 0L);
|
||
doc->put(DOC_TIPODOC, tipo_finale());
|
||
doc_out.add(doc);
|
||
}
|
||
|
||
const int cfg_levels = pe_crea_fasi_preventivo(din);
|
||
if (cfg_levels <= 0)
|
||
continue;
|
||
|
||
TDocumento& don = doc_out[i];
|
||
|
||
din.put(DOC_STATO, stato_finale_doc_iniziale());
|
||
|
||
don.zero(DOC_TIPOCF);
|
||
don.zero(DOC_CODCF); // NO clifo
|
||
don.put(DOC_DATADOC, data_elab);
|
||
don.put(DOC_NOTE, din.get(DOC_NOTE));
|
||
don.put(DOC_CODCMS, din.get(DOC_CODCMS));
|
||
don.put(DOC_STATO, stato_finale());
|
||
don.put(DOC_NUMDOCRIF, din.get(DOC_NDOC));
|
||
don.put(DOC_DATADOCRIF, din.get(DOC_DATADOC));
|
||
|
||
const int doc_levels = pe_numero_fasi(din);
|
||
if (doc_levels <= 0)
|
||
continue; // Should never happen
|
||
|
||
bool dettagliato = false;
|
||
real qta = UNO;
|
||
const int nrows = din.rows();
|
||
FOR_EACH_PHYSICAL_RDOC(din, r, rdoc)
|
||
{
|
||
const TString& tr = rdoc->get(RDOC_TIPORIGA);
|
||
if (tr == _strFasi)
|
||
{
|
||
// Nothig to do
|
||
} else
|
||
if (tr == _strDist)
|
||
{
|
||
// Aggiorna quantit<69>
|
||
qta = rdoc->get_real(RDOC_QTA);
|
||
if (qta <= ZERO)
|
||
qta = UNO;
|
||
} else
|
||
if (tr == _strDett)
|
||
{
|
||
TRiga_documento& rout = don.new_row(_strDett);
|
||
TDocumento::copy_data(rout, *rdoc);
|
||
rout.set_original_rdoc_key(*rdoc);
|
||
rout.put(RDOC_CODCMS, din.get(DOC_CODCMS));
|
||
rout.put(RDOC_QTA, real(qta * rdoc->get_real(RDOC_QTA)));
|
||
rout.put(RDOC_PREZZO, rdoc->get(RDOC_QTAGG5));
|
||
dettagliato = true;
|
||
}
|
||
}
|
||
|
||
if (dettagliato)
|
||
don.write(); // Salva nuovo documento
|
||
else
|
||
{
|
||
if (interattivo)
|
||
error_box(FR("Il preventivo %s %d/%ld non ha articoli: impossibile generare il fabbisogno"),
|
||
(const char*)din.get(DOC_CODNUM), din.get_int(DOC_ANNO), din.get_long(DOC_NDOC));
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
TFabbisognazione::TFabbisognazione(const TString& cod) : TElaborazione_esterna(cod)
|
||
{
|
||
_strFasi = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaFase", "05");
|
||
_strDist = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDist", "P1");
|
||
_strDett = ini_get_string(CONFIG_DITTA, "pe", "TipoRigaDett", "01");
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utility pubbliche
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const TString& pe_trova_elaborazione(const TRectype& doc, char tipo)
|
||
{
|
||
TString16 cod;
|
||
|
||
const TString& codnum = doc.get(DOC_CODNUM);
|
||
TString str;
|
||
if (tipo == 'F')
|
||
str << "USE %ELD SELECT (STR(I0=\"0\"))&&(S3=\"pe1 -5\")&&(S5=\"" << codnum << "\")"; // Fabbisogni
|
||
else
|
||
str << "USE %ELD SELECT (STR(I0=\"0\"))&&(S3=\"pe1 -4\")&&(S5=\"" << codnum << "\")"; // Ordini
|
||
|
||
TRecordset* eld = create_recordset(str);
|
||
if (eld != NULL)
|
||
{
|
||
for (bool ok = eld->move_first(); ok; ok = eld->move_next())
|
||
{
|
||
const TString& c = eld->get("CODTAB").as_string();
|
||
const TElaborazione e(c);
|
||
if (e.is_document_ok(doc))
|
||
{
|
||
cod = c;
|
||
break;
|
||
}
|
||
}
|
||
delete eld;
|
||
}
|
||
return get_tmp_string() = cod;
|
||
}
|
||
|
||
const TString& pe_trova_elaborazione(const TMask& m, char tipo)
|
||
{
|
||
TRectype doc(LF_DOC);
|
||
doc.put(DOC_PROVV, 'D');
|
||
doc.put(DOC_ANNO, m.get(DOC_ANNO));
|
||
doc.put(DOC_CODNUM, m.get(DOC_CODNUM));
|
||
doc.put(DOC_NDOC, m.get(DOC_NDOC));
|
||
doc.put(DOC_TIPODOC, m.get(DOC_TIPODOC));
|
||
doc.put(DOC_STATO, m.get(DOC_STATO));
|
||
return pe_trova_elaborazione(doc, tipo);
|
||
}
|
||
|
||
bool pe_genera_documento(TRectype& doc, const TString& cod, char tipo)
|
||
{
|
||
TString16 codelab = cod;
|
||
if (codelab.blank())
|
||
codelab = pe_trova_elaborazione(doc, tipo);
|
||
|
||
const TString& app = cache().get("%ELD", codelab, "S3");
|
||
tipo = app.find("-5") > 0 ? 'F' : 'O';
|
||
|
||
TElaborazione* e = NULL;
|
||
if (tipo == 'F')
|
||
e = new TFabbisognazione(codelab);
|
||
else
|
||
e = new TOrdinazione(codelab);
|
||
if (e->empty())
|
||
{
|
||
delete e;
|
||
return error_box(FR("Impossibile trovare l'elaborazione %s"), (const char*)cod);
|
||
}
|
||
|
||
const TDate oggi(TODAY);
|
||
TLista_documenti doc_in, doc_out;
|
||
doc_in.add(new TDocumento(doc));
|
||
|
||
bool ok = e->elabora(doc_in, doc_out, oggi, true);
|
||
if (ok)
|
||
{
|
||
int err = doc_in.rewrite();
|
||
if (err == NOERR)
|
||
{
|
||
const TRectype& idoc = doc_in[0];
|
||
for (int i = 0; i < idoc.items(); i++)
|
||
{
|
||
const char* fld = idoc.fieldname(i);
|
||
const TString& val = idoc.get(fld);
|
||
if (val.full())
|
||
doc.put(fld, val);
|
||
}
|
||
|
||
err = doc_out.write();
|
||
if (err != NOERR)
|
||
error_box(TR("Errore %d in scrittura del documento"), err);
|
||
}
|
||
}
|
||
delete e;
|
||
|
||
return ok;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TOrdinazione_app
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TOrdinazione_app : public TSkeleton_application
|
||
{
|
||
protected:
|
||
virtual void main_loop();
|
||
};
|
||
|
||
void TOrdinazione_app::main_loop()
|
||
{
|
||
TFilename ininame;
|
||
if (argc() >= 2)
|
||
{
|
||
const TFixed_string arg = argv(2);
|
||
ininame = arg.starts_with("-i", true) ? arg.mid(2) : arg;
|
||
}
|
||
|
||
TConfig ini(ininame, "Transaction");
|
||
const TString8 codelab = ini.get("Action");
|
||
|
||
ini.set_paragraph("33");
|
||
TRectype doc(LF_DOC);
|
||
doc.put(DOC_PROVV, ini.get(DOC_PROVV));
|
||
doc.put(DOC_ANNO, ini.get(DOC_ANNO));
|
||
doc.put(DOC_CODNUM, ini.get(DOC_CODNUM));
|
||
doc.put(DOC_NDOC, ini.get(DOC_NDOC));
|
||
|
||
if (pe_genera_documento(doc, codelab, 'O'))
|
||
{
|
||
ini.set_paragraph("Transaction");
|
||
ini.set("Result", "OK");
|
||
ini.set("Error", "0");
|
||
|
||
ini.set_paragraph("33");
|
||
for (int i = 0; i < doc.items(); i++)
|
||
{
|
||
const char* fld = doc.fieldname(i);
|
||
const TString& val = doc.get(fld);
|
||
if (val.full())
|
||
ini.set(fld, val);
|
||
}
|
||
}
|
||
}
|
||
|
||
int pe1500(int argc, char* argv[])
|
||
{
|
||
TOrdinazione_app a;
|
||
a.run(argc, argv, TR("Generazione ordini"));
|
||
return 0;
|
||
}
|
||
|
||
|