campo-sirio/ps/ps0920500.cpp
guy 0063fc1077 Personalizzazioni DBService
git-svn-id: svn://10.65.10.50/branches/R_10_00@22840 c028cbd2-c16b-5b4b-a496-9718f37d4682
2013-04-09 15:07:43 +00:00

877 lines
22 KiB
C++
Raw Blame History

#include <applicat.h>
#include <progind.h>
#include <reputils.h>
#include <tabmod.h>
#include <textset.h>
#include <utility.h>
#include "../ve/velib04.h"
#include "ps0920500a.h"
///////////////////////////////////////////////////////////
// TClosure_set
///////////////////////////////////////////////////////////
class TClosure_set : public TCSV_recordset
{
public:
TClosure_set(const TFilename& n) : TCSV_recordset("CSV(\"|\")") { load_file(n); }
};
///////////////////////////////////////////////////////////
// TEvasione_mmag
///////////////////////////////////////////////////////////
class TEvasione_mmag : public TConsegna_ordini
{
TLog_report* m_log;
TString_array m_e;
int m_scelta, m_lotto, m_pallet, m_spezzoni;
protected:
virtual bool run_consegna_mask(TMask& cm);
virtual void post_process(TLista_documenti& doc_out, TLista_documenti& doc_in);
public:
const TString& get_choice_desc(long codcf, int s) const;
void restart(TLog_report& log, int s);
bool evade(const TString& codart, int idriga, int qty, bool sld, int lotto, int pall, int spez);
TEvasione_mmag(const char* codelab) : TConsegna_ordini(codelab) {}
};
void TEvasione_mmag::restart(TLog_report& log, int s)
{
CHECKD(s == 1 || s == 2, "Scelta non valida ", s);
m_log = &log;
m_e.destroy();
m_scelta = s;
m_lotto = m_pallet = m_spezzoni = 0;
}
bool TEvasione_mmag::evade(const TString& codart, int idriga, int qty, bool sld, int lotto, int pall, int spez)
{
const bool good = (qty > 0 || sld) && idriga > 0 && codart.full();
if (good)
{
TToken_string* e = new TToken_string;
e->add(codart);
e->add(idriga);
e->add(qty);
e->add(sld ? "X" : " ");
m_e.add(e);
// Uguali per tutti
m_lotto = lotto;
m_pallet = pall;
m_spezzoni = spez;
}
return good;
}
bool TEvasione_mmag::run_consegna_mask(TMask& cm)
{
if (m_e.empty())
return false;
TSheet_field* sheet = NULL;
for (int i = cm.fields()-1; i > 0; i--)
{
const TMask_field& f = cm.fld(i);
if (f.is_sheet())
{
sheet = (TSheet_field*)&f;
break;
}
}
if (sheet == NULL)
{
TString msg;
msg.format(FR("Maschera di consegna %s priva di spreadsheet"), (const char*)cm.source_file());
m_log->log(2, msg);
return false;
}
bool good = true;
FOR_EACH_ARRAY_ROW(m_e, r, row)
{
const TString80 codart = row->get(0);
const int idriga = row->get_int();
const int qty = row->get_int();
bool sld = row->get_char() > ' ';
bool found = false;
FOR_EACH_SHEET_ROW(*sheet, s, sow)
{
const char* art = sow->get(6);
const int idr = sow->get_int(15);
found = codart == art && idriga == idr;
if (found)
{
if (sow->get_char(0) <= ' ')
sow->add("X", 0);
if (qty)
{
const int residuo = sow->get_int(1);
const int qta = sow->get_int(2) + qty;
sow->add(qta, 2);
if (qta >= residuo)
sld = true;
}
if (sld)
sow->add("X", 3);
break;
}
}
if (found)
{
row->add("OK", 4); // success
}
else
{
TString msg;
msg.format(FR("Impossibile trovare l'articolo %s sulla riga %d dell'ordine"),
(const char*)codart, idriga);
m_log->log(1, msg);
good = false;
}
}
return good;
}
const TString& TEvasione_mmag::get_choice_desc(long codcf, int s) const
{
TString8 key; key.format("%06ld", codcf);
const TRectype& rec = cache().get("&PS0920SCE", key);
TString& tmp = get_tmp_string();
if (s < 2)
{
tmp = rec.get("S1");
if (tmp.blank())
tmp = "1";
}
else
{
tmp = rec.get("S2");
if (tmp.blank())
tmp = "2";
}
return tmp;
}
void TEvasione_mmag::post_process(TLista_documenti& doc_out, TLista_documenti& /*doc_in*/)
{
for (int d = 0; d < doc_out.items(); d++)
{
TDocumento& mmag = doc_out[d];
const long codcf = mmag.get_long(DOC_CODCF);
const TString4 scelta = get_choice_desc(codcf, m_scelta);
FOR_EACH_PHYSICAL_RDOC(mmag, r, row)
{
TRiga_documento& riga = *row;
if (riga.is_articolo() && riga.get_int(RDOC_QTAGG5) == 0) // Riga articolo non post-processata
{
const int qta = riga.get_int(RDOC_QTA);
if (qta > 0)
{
int np = m_pallet;
if (m_spezzoni > 0)
np++;
if (np <= 0)
{
// Calcolo pezzi per pallet: ppcollo * ppstrato * nstrati
const TRectype& anamag = cache().get(LF_ANAMAG, riga.get(RDOC_CODART));
const int ppp = anamag.get_int(ANAMAG_PPCOLLO) * anamag.get_int(ANAMAG_USER1) * anamag.get_int(ANAMAG_USER2);
// Calcolo numero di pallet
np = 1;
if (ppp > 0)
{
np = qta / ppp;
if (qta % ppp) // l'eventuale resto va tutto su di un nuovo pallet
np++;
}
}
riga.put(RDOC_IMPFISSO, np);
riga.put(RDOC_ASPBENI, scelta);
riga.put(RDOC_QTAGG4, m_lotto);
riga.put(RDOC_QTAGG5, 1); // Segna riga come post-processata
}
}
}
}
}
///////////////////////////////////////////////////////////
// TClosure_msk
///////////////////////////////////////////////////////////
class TClosure_msk : public TAutomask
{
bool _dirty;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e , long jolly);
const TRectype& get_doc(TToken_string& key, TLog_report& log) const;
bool check_file(TClosure_set& recset);
bool import_file(TClosure_set& recset);
bool elabora(TString_array& records, TLog_report& log);
bool chiudi_righe(TString_array& records, TLog_report& log);
public:
void load_sheet();
bool seleziona();
bool cancella();
bool salva();
bool elabora();
TClosure_msk() : TAutomask("ps0920500a") {}
};
const TRectype& TClosure_msk::get_doc(TToken_string& rdoc, TLog_report& log) const
{
TToken_string key;
key = "D";
key.add(rdoc.get(1));
key.add(rdoc.get(0));
key.add(rdoc.get(2));
const TRectype& doc = cache().get(LF_DOC, key);
TString msg; msg << rdoc << " : ";
bool is_bad = doc.empty();
if (is_bad)
{
msg << "Documento inesistente";
}
else
{
is_bad = doc.get_bool(DOC_DOCEVASO);
if (is_bad)
msg << TR("Ordine gi<67> evaso");
}
if (is_bad)
{
log.log(2, msg);
return cache().get(LF_DOC, "");
}
else
{
msg << "OK";
log.log(0, msg);
}
return doc;
}
bool TClosure_msk::check_file(TClosure_set& recset)
{
TLog_report log;
int errors = 0;
TToken_string rdoc("", '.');
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
rdoc = recset.get(0).as_string(); // NUM.YYYY.NDOC.NRIGA
if (rdoc.blank())
break;
const TRectype& doc = get_doc(rdoc, log);
if (doc.empty())
errors++;
}
if (errors > 0)
log.preview();
return errors == 0;
}
bool TClosure_msk::import_file(TClosure_set& recset)
{
TLog_report log;
TRecnotype r = 0;
TModule_table mag("&PS0920MAG");
long idrec = 1;
if (mag.last() == NOERR)
idrec += atol(mag.get("CODTAB"));
TProgind pi(recset.items(), main_app().title());
TToken_string rdoc(31, '.');
TString16 str;
TString key;
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
if (!pi.addstatus(1))
break;
rdoc = recset.get(0).as_string(); // NUM.YYYY.NDOC.NRIGA
if (rdoc.blank())
break;
const TRectype& doc = get_doc(rdoc, log);
if (doc.empty())
continue;
const int indsped = doc.get_int(DOC_CODINDSP);
mag.zero();
str.format("%010ld", idrec++);
mag.put("CODTAB", str);
// Riformatta il numero documento
str = rdoc.get(2); str.right_just(7, '0');
rdoc.add(str, 2);
// Riformatta il numero riga
str = rdoc.get(3); str.right_just(4, '0');
rdoc.add(str, 3);
// Inserisco l'indirizzo di spedizione
str.format("%03d", indsped);
rdoc.insert(".");
rdoc.insert(str);
// Inserisco il codice cliente davanti
str = recset.get(1).as_string().left(3);
rdoc.insert(".");
rdoc.insert(str);
key.format("C|%d", atoi(str));
if (cache().get(LF_CLIFO, key).empty())
{
TString msg; msg << rdoc << " : ";
msg << TR("Codice cliente non valido ") << str;
log.log(2, msg);
continue;
}
key = recset.get(1).as_string();
const TRectype& anamag = cache().get(LF_ANAMAG, key);
if (anamag.empty())
{
TString msg; msg << rdoc << " : ";
msg << TR("Codice articolo non valido ") << key;
log.log(2, msg);
continue;
}
const int ppp = anamag.get_int(ANAMAG_PPCOLLO) * anamag.get_int(ANAMAG_USER1) * anamag.get_int(ANAMAG_USER2);
if (ppp <= 0)
{
TString msg; msg << rdoc << " : ";
msg << TR("Articolo senza informazioni di palettizzazione ") << key;
log.log(1, msg);
}
mag.put("S0", rdoc);
mag.put("S1", key); // Articolo
mag.put("I0", rdoc.get_int(0)); // Cliente
mag.put("I1", recset.get(2).as_int()); // Palette di prima
mag.put("I2", recset.get(3).as_int()); // Spezzoni di prima
mag.put("I3", recset.get(4).as_int()); // Palette di seconda
mag.put("I4", recset.get(5).as_int()); // Spezzoni di seconda
mag.put("B0", recset.get(6).as_string() > " "); // Saldo
mag.put("B1", false); // Riga evasa
mag.put("S6", recset.get(7).as_string()); // Lotto
TDate ril(TODAY);
str = recset.get(8).as_string().left(10);
if (TDate::isdate(str))
ril = TDate(str);
mag.put("D0", ril); // Data rilevazione
const int err = mag.write();
if (err != NOERR)
{
TString msg; msg << rdoc << " : ";
msg << TR("Impossibile registrare la riga: errore ") << err;
log.log(2, msg);
break;
}
else
r++;
}
TString msg;
msg << "Sono stati importati " << r << " record";
log.log(0, "");
log.log(0, msg);
log.preview();
return r > 0;
}
void TClosure_msk::load_sheet()
{
TSheet_field& s = sfield(F_SHEET);
s.hide();
s.destroy();
TRelation r("&PS0920MAG");
TString filter;
filter = "(B1!=\"X\")";
if (get_bool(F_SHOWALL))
filter << "||(D0==\"" << get(F_DATADOC) << "\")";
TCursor c(&r, filter, 2);
const TRecnotype n = c.items();
c.freeze();
const TRectype& rec = c.curr();
TToken_string rif("", '.');
for (c = 0; c.pos() < n; ++c)
{
rif = rec.get("S0");
if (rif.full())
{
TToken_string& row = s.row(-1);
row = " ";
FOR_EACH_TOKEN(rif, tok)
row.add(tok);
row.add(rec.get("S1"), s.cid2index(F_CODART));
row.add(rec.get("I1"), s.cid2index(F_PALET1));
row.add(rec.get("I2"), s.cid2index(F_SPEZZ1));
row.add(rec.get("I3"), s.cid2index(F_PALET2));
row.add(rec.get("I4"), s.cid2index(F_SPEZZ2));
row.add(rec.get("B0"), s.cid2index(F_SALDO));
row.add(rec.get("S6"), s.cid2index(F_LOTTO));
row.add(rec.get("D0"), s.cid2index(F_DATA));
row.add(rec.get("CODTAB"), s.cid2index(F_RECORD));
s.check_row(s.items()-1, 0x3); // Do outputs and checks
}
}
const bool e = !s.empty();
enable(DLG_DELREC, e);
enable(DLG_RECALC, e);
enable(DLG_ELABORA, e);
enable(DLG_SAVEREC, _dirty = false);
s.show();
s.force_update();
}
bool TClosure_msk::chiudi_righe(TString_array& records, TLog_report& log)
{
int err = NOERR;
TFast_isamfile mmag(LF_TABMOD);
FOR_EACH_ARRAY_ROW(records, r, row) if (row->get_char(0) > ' ')
{
const TString16 rec = row->get(F_RECORD-101);
mmag.put("MOD", "PS");
mmag.put("CUST", 920);
mmag.put("COD", "MAG");
mmag.put("CODTAB", rec);
err = mmag.read(_isequal, _lock);
if (err == NOERR)
{
mmag.put("B1", true);
err = mmag.rewrite();
}
if (err != NOERR)
{
TString msg;
msg.format(FR("Errore %d in aggiornamento record %s"), err, (const char*)rec);
log.log(2, msg);
break;
}
}
return err == NOERR;
}
bool TClosure_msk::elabora(TString_array& records, TLog_report& log)
{
if (records.empty())
return false;
TEvasione_mmag jail(get(F_CODELAB));
TLista_documenti doc_in, doc_out;
const TDate data_doc = get(F_DATADOC);
const int anno = data_doc.year();
const TString4 codnum = jail.codice_numerazione_finale();
const long codcf = records.row(0).get_long(1);
const int indsped = records.row(0).get_int(2);
TDocumento* mmag = new TDocumento('D', anno, codnum, 0L);
mmag->put(DOC_TIPODOC, jail.tipo_finale());
mmag->put(DOC_STATO, jail.stato_finale());
mmag->put(DOC_DATADOC, data_doc);
mmag->put(DOC_TIPOCF, 'C');
mmag->put(DOC_CODCF, codcf);
mmag->put(DOC_CODINDSP, indsped);
doc_out.add(mmag);
long last_ndoc = 0;
FOR_EACH_ARRAY_ROW(records, r, row)
{
const char provv = 'D';
const int anno = row->get_int (F_ANNO -101);
const TString4 codnum = row->get (F_CODNUM-101);
const long ndoc = row->get_long(F_NDOC -101);
if (!doc_in.find(provv, anno, codnum, ndoc))
{
TDocumento* orc = new TDocumento(provv, anno, codnum, ndoc);
doc_in.add(orc);
TString msg; msg << TR("Caricamento ") << anno << '/' << codnum << '/' << ndoc;
log.log(0, msg);
if (last_ndoc == 0)
{
mmag->copy_data(mmag->head(), orc->head());
mmag->put(DOC_TIPODOC, jail.tipo_finale());
mmag->put(DOC_STATO, jail.stato_finale());
mmag->put(DOC_DATADOC, data_doc);
mmag->put(DOC_CAUSMAG, mmag->tipo().caus_mov());
}
last_ndoc = ndoc;
}
}
for (int scelta = 1; scelta <= 2; scelta++)
{
jail.restart(log, scelta);
bool some_row = false;
FOR_EACH_ARRAY_ROW(records, r, row)
{
const int pall = row->get_int((scelta == 1 ? F_PALET1 : F_PALET2) - 101);
const int spez = row->get_int((scelta == 1 ? F_SPEZZ1 : F_SPEZZ2) - 101);
const int pezzi = row->get_int((scelta == 1 ? F_PEZZ1 : F_PEZZ2 ) - 101);
bool sld = false;
if (row->get_char(F_SALDO - 101) > ' ')
{
if (scelta == 1)
sld = row->get_int(F_PEZZ2 - 101) <= 0;
else
sld = pezzi > 0;
}
if (pezzi > 0 || sld)
{
const TString codart = row->get(F_CODART - 101);
const int idriga = row->get_int(F_IDRIGA - 101);
const int lotto = row->get_long(F_LOTTO - 101);
some_row |= jail.evade(codart, idriga, pezzi, sld, lotto, pall, spez);
}
}
if (some_row)
{
TString msg;
msg << TR("Elaborazione scelta ") << jail.get_choice_desc(codcf, scelta);
log.log(0, msg);
const bool good = jail.elabora(doc_in, doc_out, data_doc);
if (!good)
{
FOR_EACH_ARRAY_ROW(records, r1, row1) if (row1->get_char(0) > ' ')
row1->add(" ", 0);
log.log(2, TR("Elaborazione annullata"));
break;
}
}
}
int err = doc_out.write();
if (err == NOERR)
{
chiudi_righe(records, log);
doc_in.rewrite();
}
else
{
TString80 msg;
msg << TR("Impossibile registrare il documento ") << anno << '/' << codnum << '/' << mmag->get(DOC_NDOC);
log.log(2, msg);
}
return err == NOERR;
}
bool TClosure_msk::elabora()
{
TRecnotype c = 0;
TSheet_field&s = sfield(F_SHEET);
FOR_EACH_SHEET_ROW(s, r1, row1)
c += row1->get_char(0) > ' ';
if (c == 0 || !yesno_box(FR("Confermare l'elaborazione di %ld righe"), c))
return false;
TLog_report log;
TString_array records;
long last_cf = 0;
int last_ind = 0;
FOR_EACH_SHEET_ROW(s, r, row) if (row->get_char(0) > ' ')
{
const long codcf = row->get_long(s.cid2index(F_CLIFO));
const int indsped = row->get_int(s.cid2index(F_INDSPED));
if (codcf != last_cf || indsped != last_ind)
{
elabora(records, log);
last_cf = codcf;
last_ind = indsped;
records.destroy();
}
records.add(*row); // Attenzione: NON records.add(row)
}
elabora(records, log);
log.preview();
return true;
}
bool TClosure_msk::seleziona()
{
bool one_checked = false;
TSheet_field&s = sfield(F_SHEET);
FOR_EACH_SHEET_ROW(s, r1, row1)
{
if (row1->get_char(0) > ' ')
{
one_checked = true;
break;
}
}
FOR_EACH_SHEET_ROW(s, r2, row2)
row2->add(one_checked ? " " : "X", 0);
s.force_update();
return !one_checked;
}
bool TClosure_msk::cancella()
{
int err = NOERR;
TSheet_field&s = sfield(F_SHEET);
// Conta reord selezionati
TRecnotype k = 0;
FOR_EACH_SHEET_ROW(s, r1, row1)
k += row1->starts_with("X");
// Elminazione su richiesta
if (k > 0 && noyes_box(FR("Confermare l'eliminazione di %ld record?"), k))
{
const int nRec = s.cid2index(F_RECORD);
TFast_isamfile mmag(LF_TABMOD);
TString16 n;
FOR_EACH_SHEET_ROW(s, r2, row2) if (row2->starts_with("X"))
{
n.format("%010ld", row2->get_long(nRec));
mmag.put("MOD", "PS");
mmag.put("CUST", 920);
mmag.put("COD", "MAG");
mmag.put("CODTAB", n);
err = mmag.remove();
if (err != NOERR)
{
error_box(FR("Errore %d durante la cancellazione del record %ld"), err, atol(n));
break;
}
}
load_sheet();
}
return err == NOERR;
}
bool TClosure_msk::salva()
{
int err = NOERR;
TSheet_field&s = sfield(F_SHEET);
const int nRec = s.cid2index(F_RECORD);
const int nPa1 = s.cid2index(F_PALET1);
const int nSp1 = s.cid2index(F_SPEZZ1);
const int nPa2 = s.cid2index(F_PALET2);
const int nSp2 = s.cid2index(F_SPEZZ2);
const int nSld = s.cid2index(F_SALDO);
const int nLot = s.cid2index(F_LOTTO);
TFast_isamfile mmag(LF_TABMOD);
TString16 n;
FOR_EACH_SHEET_ROW(s, r, row)
{
n.format("%010ld", row->get_long(nRec));
mmag.put("MOD", "PS");
mmag.put("CUST", 920);
mmag.put("COD", "MAG");
mmag.put("CODTAB", n);
err = mmag.read(_isequal, _lock);
if (err == NOERR)
{
mmag.put("I1", row->get(nPa1));
mmag.put("I2", row->get(nSp1));
mmag.put("I3", row->get(nPa2));
mmag.put("I4", row->get(nSp2));
mmag.put("B0", row->get(nSld));
mmag.put("S6", row->get(nLot));
err = mmag.rewrite();
}
if (err != NOERR)
{
error_box(FR("Errore %d durante l'aggiornamento del record %ld"), err, atol(n));
break;
}
}
if (err == NOERR)
enable(DLG_SAVEREC, _dirty = false);
return err == NOERR;
}
bool TClosure_msk::on_field_event(TOperable_field& o, TField_event e , long jolly)
{
switch (o.dlg())
{
case DLG_IMPORT:
if (e == fe_button)
{
TFilename file = get(F_PATH);
file.add("*.dat");
if (!input_filename(file))
return false;
TClosure_set recset(file);
const TRecnotype n = recset.items();
if (n > 0) // Prima valutazione del numero di elementi
{
// Controllo degli ordini validi
if (!check_file(recset) && !noyes_box(TR("Si desidera proseguire nonostante i problemi rilevati?")))
return false;
if (!yesno_box(FR("Confermare la lettura di %ld righe"), n))
return false;
if (import_file(recset))
{
save_profile();
if (yesno_box(FR("Si desidera eliminare il file %s"), (const char*)file))
file.fremove();
}
load_sheet();
}
else
cantread_box(file);
}
break;
case F_SHOWALL:
if (e == fe_button)
load_sheet();
break;
case DLG_RECALC:
if (e == fe_button)
seleziona();
break;
case DLG_DELREC:
if (e == fe_button)
{
cancella();
return false; // Altrimenti esce dalla maschera
}
break;
case DLG_SAVEREC:
if (e == fe_button)
{
salva();
return false; // Altrimenti esce dalla maschera
}
break;
case DLG_ELABORA:
if (e == fe_button)
{
elabora();
load_sheet();
}
break;
case F_CODELAB:
case F_DATADOC:
case F_SHEET:
if (e == fe_init || e == fe_modify)
{
short ids[4] = { F_CODELAB, F_DATADOC, F_SHEET, 0 };
bool one_empty = false;
for (int i = 0; ids[i]; i++)
one_empty |= field(ids[i]).empty();
enable(DLG_ELABORA, !one_empty);
}
break;
case F_PALET1:
case F_SPEZZ1:
case F_PALET2:
case F_SPEZZ2:
if (e == fe_modify || e == fe_init)
{
TMask& sm = o.mask();
const TRectype& art = cache().get(LF_ANAMAG, sm.get(F_CODART));
const int pps = art.get_int(ANAMAG_PPCOLLO); // Pezzi per spezzone
const int ppp = art.get_int(ANAMAG_USER1) * art.get_int(ANAMAG_USER2) * pps; // Pezzi per pallet
const real peso = art.get(ANAMAG_PESO);
const int id = o.dlg() < F_PALET2 ? F_PALET1 : F_PALET2;
sm.set(id+2, sm.get_int(id)*ppp + sm.get_int(id+1)*pps);
sm.set(id+3, real(peso * sm.get_int(id+2)));
if (e == fe_modify && !_dirty && is_running())
enable(DLG_SAVEREC, _dirty = true);
}
break;
case F_SALDO:
case F_LOTTO:
if (e == fe_modify && !_dirty && is_running())
enable(DLG_SAVEREC, _dirty = true);
break;
default: break;
}
return true;
}
///////////////////////////////////////////////////////////
// TClosure_app
///////////////////////////////////////////////////////////
class TClosure_app : public TSkeleton_application
{
protected:
virtual bool check_autorization() const { return false; }
virtual const char* extra_modules() const { return "ve"; }
virtual void main_loop();
};
void TClosure_app::main_loop()
{
open_files(LF_TABCOM, LF_TAB, LF_TABMOD,
LF_CLIFO, LF_ANAMAG,
LF_DOC, LF_RIGHEDOC, 0);
TClosure_msk m;
m.load_sheet();
while (m.run() == K_ENTER);
}
int ps0920500(int argc, char* argv[])
{
TClosure_app a;
a.run(argc, argv, TR("Ordini da terminale"));
return 0;
}