Files correlati : ve0, ve6 Ricompilazione Demo : [ ] Commento : Adeguato utilizzo nuovi alberi in evasione ordini. Migliorate alcune indentazioni fuori standard git-svn-id: svn://10.65.10.50/trunk@16000 c028cbd2-c16b-5b4b-a496-9718f37d4682
534 lines
17 KiB
C++
Executable File
534 lines
17 KiB
C++
Executable File
#include "velib04.h"
|
|
#include "velib04d.h"
|
|
|
|
#include <automask.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TConsegna ordini mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TConsegna_mask : public TAutomask
|
|
{
|
|
bool _ordina_per_codice;
|
|
bool _ignora_descrizioni;
|
|
const TDocumento* _doc;
|
|
|
|
protected:
|
|
virtual bool on_field_event(class TOperable_field& f, TField_event e, long jolly);
|
|
|
|
public:
|
|
void doc2mask(const TDocumento& doc, const TString & articolo);
|
|
|
|
TConsegna_mask(int header_code = 0, bool per_codice = false, bool ignora_descrizioni = false);
|
|
virtual ~TConsegna_mask() { }
|
|
};
|
|
|
|
bool TConsegna_mask::on_field_event(class TOperable_field& f, TField_event e, long jolly)
|
|
{
|
|
bool update_row = false;
|
|
switch (f.dlg())
|
|
{
|
|
case S_QTADAEVADERE:
|
|
if (e == fe_modify && jolly > 0)
|
|
{
|
|
TMask& m = f.mask();
|
|
const real qta_residua = m.get_real(S_QTARESIDUA);
|
|
const real qta_daevadere = m.get_real(S_QTADAEVADERE);
|
|
if (qta_daevadere > ZERO)
|
|
{
|
|
m.set(S_RIGACONSEGNATA, "X");
|
|
if (qta_daevadere >= qta_residua)
|
|
{
|
|
m.set(S_RIGAEVASA, "X");
|
|
m.disable(S_RIGAEVASA);
|
|
}
|
|
else
|
|
m.enable(S_RIGAEVASA);
|
|
}
|
|
else
|
|
{
|
|
m.set(S_RIGAEVASA, " ");
|
|
m.enable(S_RIGAEVASA);
|
|
}
|
|
update_row = !m.is_running();
|
|
}
|
|
break;
|
|
case S_RIGAEVASA:
|
|
if (e == fe_modify && jolly > 0 && f.get().not_empty())
|
|
{
|
|
TMask& m = f.mask();
|
|
const real qta_daevadere = m.get_real(S_QTADAEVADERE);
|
|
if (qta_daevadere.is_zero())
|
|
{
|
|
const TString& residuo = m.get(S_QTARESIDUA);
|
|
m.set(S_QTADAEVADERE, residuo, true);
|
|
update_row = !m.is_running();
|
|
}
|
|
}
|
|
break;
|
|
case F_CONSEGNA:
|
|
if (e == fe_button)
|
|
{
|
|
TSheet_field& s = sfield(F_ROWS);
|
|
FOR_EACH_SHEET_ROW(s, n, row) if (!s.cell_disabled(n,S_RIGACONSEGNATA-FIRST_FIELD))
|
|
{
|
|
bool select = true;
|
|
const real residuo = row->get(S_QTARESIDUA-FIRST_FIELD);
|
|
const real evaso = row->get(S_QTADAEVADERE-FIRST_FIELD);
|
|
if (evaso == ZERO && residuo > ZERO)
|
|
{
|
|
row->add(residuo.string(), S_QTADAEVADERE-FIRST_FIELD);
|
|
row->add("X", S_RIGAEVASA-FIRST_FIELD);
|
|
s.disable_cell(n, S_RIGAEVASA-FIRST_FIELD);
|
|
}
|
|
if (evaso == ZERO && residuo == ZERO)
|
|
{
|
|
const int nriga = row->get_int(S_NUMRIGA-FIRST_FIELD);
|
|
const TRiga_documento& rdoc = (*_doc)[nriga];
|
|
select = rdoc.quantita().is_zero();
|
|
}
|
|
if (select)
|
|
row->add("X", S_RIGACONSEGNATA-FIRST_FIELD);
|
|
}
|
|
s.force_update();
|
|
}
|
|
break;
|
|
case F_ROWS:
|
|
if (e == se_query_add || e == se_query_del)
|
|
return false;
|
|
default:break;
|
|
}
|
|
|
|
if (update_row)
|
|
{
|
|
TSheet_field& s = sfield(F_ROWS);
|
|
const int riga = s.selected();
|
|
s.update_row(riga);
|
|
s.force_update(riga);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int rows_sort_func(TSheet_field& s, int i, int j)
|
|
{
|
|
const TToken_string& s1 = s.row(i);
|
|
const TToken_string& s2 = s.row(j);
|
|
TString ss1, ss2;
|
|
TDate dd1, dd2;
|
|
real rr1, rr2;
|
|
const int fields[] = { S_CODART, S_LIVGIAC1, S_LIVGIAC2, S_LIVGIAC3, S_LIVGIAC4,
|
|
S_CODMAG, S_CODDEP, S_RIGAEVASA, S_DATACONS, S_QTARESIDUA, -1 };
|
|
int ret = 0, field = 0;
|
|
while (fields[field] >= 0)
|
|
{
|
|
if (fields[field] == S_QTARESIDUA)
|
|
{
|
|
s1.get(fields[field]-FIRST_FIELD, rr1);
|
|
s2.get(fields[field]-FIRST_FIELD, rr2);
|
|
ret = rr2 < rr1 ? -1 : (rr2 > rr1 ? 1 : 0);
|
|
}
|
|
else
|
|
{
|
|
s1.get(fields[field]-FIRST_FIELD ,ss1);
|
|
s2.get(fields[field]-FIRST_FIELD ,ss2);
|
|
if (fields[field] == S_DATACONS)
|
|
{
|
|
dd1 = ss1;
|
|
dd2 = ss2;
|
|
ret = int (dd1.date2ansi() - dd2.date2ansi());
|
|
}
|
|
else
|
|
ret = ss1.compare(ss2);
|
|
}
|
|
if (ret != 0)
|
|
break;
|
|
field++;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void TConsegna_mask::doc2mask(const TDocumento& doc, const TString & articolo)
|
|
{
|
|
TWait_cursor hourglass;
|
|
_doc = &doc;
|
|
|
|
for (int n = fields()-1; n >= 0; n--)
|
|
{
|
|
TMask_field& f = fld(n);
|
|
const TFieldref* fr = f.field();
|
|
if (fr)
|
|
{
|
|
const TString& val = doc.get(fr->name());
|
|
f.set(val);
|
|
}
|
|
}
|
|
|
|
const bool show_evaded = doc.tipo().mostra_righe_evase_in_elaborazione();
|
|
|
|
TSheet_field& s = sfield(F_ROWS);
|
|
s.destroy();
|
|
const int rows = doc.physical_rows();
|
|
for (int i = 0; i < rows; i++)
|
|
{
|
|
const TRiga_documento& rec = doc[i+1];
|
|
const real residuo = rec.qtaresidua();
|
|
const bool evasa = residuo.is_zero();
|
|
bool show_line = show_evaded || !evasa;
|
|
if (rec.is_descrizione())
|
|
show_line = !_ignora_descrizioni;
|
|
|
|
if ( show_line && (articolo.empty() || articolo == rec.get(RDOC_CODART)))
|
|
{
|
|
TToken_string& r = s.row(-1);
|
|
r = " ";
|
|
if (evasa)
|
|
r.add(" ");
|
|
else
|
|
r.add(residuo.string());
|
|
r.add(" "); // Da evadere
|
|
if (evasa)
|
|
{
|
|
s.disable_cell(i, -1); // Disbilita tutta la riga ...
|
|
s.enable_cell(i, 0); // ... tranne il flag di consegna
|
|
r.add("X"); // La considera evasa
|
|
}
|
|
else
|
|
r.add(" ");
|
|
r.add(rec.get(RDOC_CODMAG).left(3));
|
|
r.add(rec.get(RDOC_CODMAG).mid(3));
|
|
r.add(rec.get(RDOC_CODART));
|
|
const TString& livello = rec.get(RDOC_LIVELLO);
|
|
for (int l = 1; l <= 4; l++)
|
|
r.add(livelli_giacenza().unpack_grpcode(livello, l));
|
|
if (rec.get_date(RDOC_DATACONS).ok())
|
|
r.add(rec.get_date(RDOC_DATACONS));
|
|
else
|
|
r.add(doc.get_date(DOC_DATACONS));
|
|
r.add(rec.get(RDOC_PREZZO), s.cid2index(S_PREZZO));
|
|
r.add(rec.get(RDOC_DESCR), s.cid2index(S_DESCR));
|
|
r.add(rec.get(RDOC_TIPORIGA), s.cid2index(S_TIPORIGA));
|
|
r.add(rec.get(RDOC_NRIGA),s.cid2index(S_NUMRIGA));
|
|
}
|
|
}
|
|
if (_ordina_per_codice)
|
|
s.sort(rows_sort_func);
|
|
}
|
|
|
|
TConsegna_mask::TConsegna_mask(int header_code, bool per_codice, bool ignora_descrizioni)
|
|
: TAutomask("velib04d") , _ordina_per_codice(per_codice), _doc(NULL),
|
|
_ignora_descrizioni(ignora_descrizioni)
|
|
{
|
|
TCodgiac_livelli cl;
|
|
TSheet_field& s = sfield(F_ROWS);
|
|
cl.set_sheet_columns(s, S_LIVGIAC1);
|
|
if (header_code == 1)
|
|
{
|
|
TString h;
|
|
h = "Quantita'\nconsegnata";
|
|
s.set_column_header(S_QTARESIDUA, h);
|
|
s.sheet_mask().field(S_QTARESIDUA).set_prompt("Q.ta' consegnata");
|
|
|
|
h = "Quantita'\nda fatturare";
|
|
s.set_column_header(S_QTADAEVADERE, h);
|
|
s.sheet_mask().field(S_QTADAEVADERE).set_prompt("Q.ta' da fatturare");
|
|
}
|
|
else
|
|
if (header_code == 2)
|
|
{
|
|
TString h;
|
|
h = "Residuo";
|
|
s.set_column_header(S_QTARESIDUA, h);
|
|
s.sheet_mask().field(S_QTARESIDUA).set_prompt("Residuo ");
|
|
|
|
h = "Da evadere";
|
|
s.set_column_header(S_QTADAEVADERE, h);
|
|
s.sheet_mask().field(S_QTADAEVADERE).set_prompt("Da evadere ");
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TConsegna ordini
|
|
///////////////////////////////////////////////////////////
|
|
|
|
bool TConsegna_ordini::calcola_ncolli_tara_pnetto(const TString& codart, const real& qta,
|
|
real& ncolli, real& tara, real& pnetto) const
|
|
{
|
|
const TRectype& articolo = cache().get(LF_ANAMAG, codart);
|
|
const real ppcollo = articolo.get_real(ANAMAG_PPCOLLO);
|
|
const bool ok = ppcollo > ZERO;
|
|
if (ok)
|
|
{
|
|
ncolli = qta / ppcollo;
|
|
ncolli.ceil(0);
|
|
|
|
tara = ncolli * articolo.get_real(ANAMAG_TARA);
|
|
pnetto = qta * articolo.get_real(ANAMAG_PESO);
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TConsegna_ordini::aggiorna_ncolli_tara_pnetto(TRiga_documento& r) const
|
|
{
|
|
const TString& codart = r.get(RDOC_CODARTMAG);
|
|
TArticolo articolo(codart);
|
|
const real qta = articolo.convert_to_um(r.quantita(), NULL, r.get(RDOC_UMQTA));
|
|
real ncolli, tara, pnetto;
|
|
|
|
const bool ok = calcola_ncolli_tara_pnetto(codart, qta, ncolli, tara, pnetto);
|
|
if (ok)
|
|
{
|
|
r.put(RDOC_NCOLLI, ncolli);
|
|
r.put(RDOC_TARA, tara);
|
|
r.put(RDOC_PNETTO, pnetto);
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TConsegna_ordini::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
|
const TDate& data_elab, bool interattivo)
|
|
{
|
|
const int items_in = doc_in.items();
|
|
const int items_out = doc_out.items();
|
|
CHECK(items_in > 0, "Nessun documento da elaborare");
|
|
CHECK(items_out> 0, "Nessun documento da generare");
|
|
CHECK(items_in == 1 || items_out == 1 || items_out == items_in,
|
|
"Numero di documenti da elaborare 'strano'");
|
|
|
|
bool ok = true;
|
|
|
|
const int header_code = intestazioni_sheet();
|
|
|
|
TConsegna_mask m(header_code, ordina_per_codice(), get_bool("B3"));
|
|
|
|
const int items_max = items_in > items_out ? items_in : items_out;
|
|
for (int d = 0; d < items_max && ok; d++)
|
|
{
|
|
TDocumento& indoc = doc_in[d < items_in ? d : 0];
|
|
TDocumento& outdoc = doc_out[d < items_out ? d : 0];
|
|
const TString& articolo = params().get("ARTICOLO");
|
|
|
|
m.doc2mask(indoc, articolo);
|
|
TArticolo art;
|
|
if (articolo.full())
|
|
{
|
|
art.read(articolo);
|
|
params().set("QUANTITA", ZERO);
|
|
}
|
|
ok = m.run() == K_ENTER;
|
|
if (ok)
|
|
{
|
|
if (gestione_riferimenti())
|
|
{
|
|
// Determina ed eventualmente crea la riga di riferimento
|
|
const int riga_rif = riferimenti_in_testa() ? 1 : outdoc.physical_rows()+1;
|
|
if (riga_rif > outdoc.physical_rows())
|
|
{
|
|
TRiga_documento& rout = outdoc.new_row();
|
|
rout.forza_sola_descrizione();
|
|
}
|
|
|
|
TRiga_documento& rout = outdoc[riga_rif];
|
|
|
|
// Costruisce la stringa di riferimento
|
|
TString riferimento;
|
|
indoc.riferimento(riferimento);
|
|
if (riferimento.empty())
|
|
riferimento = indoc.tipo().descrizione();
|
|
if (usa_doc_rif() && indoc.get(DOC_NUMDOCRIF).not_empty())
|
|
{
|
|
riferimento << " n. " << indoc.get(DOC_NUMDOCRIF);
|
|
riferimento << " del " << indoc.get(DOC_DATADOCRIF);
|
|
}
|
|
else
|
|
{
|
|
riferimento << " n. " << indoc.numero();
|
|
riferimento << " del " << indoc.data().string();
|
|
}
|
|
|
|
|
|
// Setta la descrizione se vuota
|
|
if (rout.get(RDOC_DESCR).empty())
|
|
rout.put(RDOC_DESCR, riferimento);
|
|
else
|
|
{
|
|
// Altrimenti aggiungi il riferimento al memo
|
|
TString memo(1024);
|
|
memo = rout.get(RDOC_DESCEST);
|
|
if (memo.empty())
|
|
{
|
|
TString80 rif(rout.get(RDOC_DESCR));
|
|
|
|
rif << '\n';
|
|
rout.put(RDOC_DESCR, rif);
|
|
rout.put(RDOC_DESCLUNGA, "X");
|
|
}
|
|
else
|
|
memo << '\n';
|
|
memo << riferimento;
|
|
rout.put(RDOC_DESCEST, memo);
|
|
}
|
|
}
|
|
|
|
TToken_string campi_riga(80);
|
|
const bool ragg_rig = raggruppa_righe();
|
|
|
|
if (ragg_rig)
|
|
{
|
|
campi_riga = "CODART|LIVELLO|UMQTA"; // Uguali sempre
|
|
// Uguali opzionalmente
|
|
if (riga_uguale(0)) campi_riga.add("CODMAG");
|
|
if (riga_uguale(1)) campi_riga.add("CODIVA");
|
|
if (riga_uguale(2)) campi_riga.add("PREZZO|SCONTO");
|
|
}
|
|
|
|
const bool evadi = outdoc.tipo().da_evadere();
|
|
|
|
TAssoc_array scarti;
|
|
|
|
TSheet_field& s = m.sfield(F_ROWS);
|
|
FOR_EACH_SHEET_ROW(s, n, row)
|
|
{
|
|
const int r = row->get_int(S_NUMRIGA - FIRST_FIELD);
|
|
if (*row->get(0) > ' ') // E' da consegnare?
|
|
{
|
|
TRiga_documento& inrec = indoc[r];
|
|
const real daeva = row->get(S_QTADAEVADERE - FIRST_FIELD);
|
|
const bool eva = row->get_char(S_RIGAEVASA-FIRST_FIELD) > ' ';
|
|
if (evadi && (daeva > ZERO || eva))
|
|
{
|
|
const char* fqe = inrec.field_qtaevasa();
|
|
inrec.add(fqe, daeva); // nuovo modo di incrementare
|
|
inrec.put(RDOC_RIGAEVASA, eva ? "X" : "");
|
|
|
|
if (eva && calcola_scarti())
|
|
{
|
|
real scarto = inrec.quantita() - inrec.qtaevasa();
|
|
if (scarto > ZERO)
|
|
{
|
|
const TString& articolo = inrec.get(RDOC_CODARTMAG);
|
|
if (articolo.full())
|
|
{
|
|
TToken_string* ska = (TToken_string*)scarti.objptr(articolo);
|
|
if (ska == NULL)
|
|
{
|
|
ska = new TToken_string(inrec.get(RDOC_UMQTA));
|
|
ska->add(scarto.string(), 1);
|
|
scarti.add(articolo, ska);
|
|
}
|
|
else
|
|
{
|
|
scarto = art.convert_to_um(scarto, inrec.get(RDOC_UMQTA), ska->get(0));
|
|
real s = ska->get(1); s += scarto;
|
|
ska->add(s.string(), 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (articolo.not_empty())
|
|
{
|
|
const TString4 um(inrec.get(RDOC_UMQTA));
|
|
const real qta = art.convert_to_um(daeva, params().get("UM"), um);
|
|
params().set("QUANTITA", qta + params().get_real("QUANTITA"));
|
|
}
|
|
|
|
bool elaborata = false;
|
|
if (ragg_rig)
|
|
{
|
|
for (int i = 1; i <= outdoc.physical_rows(); i++)
|
|
{
|
|
TRiga_documento& outrec = outdoc[i];
|
|
if (outrec.sola_descrizione()) // Ignora le righe descrittive
|
|
continue;
|
|
if (inrec.raggruppabile(outrec, campi_riga)) // Se esiste una riga compatibile ...
|
|
{
|
|
if (!daeva.is_zero())
|
|
{
|
|
const TString& qta_field = outrec.field_qta();
|
|
outrec.add(qta_field, daeva); // nuovo modo di incrementare
|
|
|
|
real ncolli, tara, pnetto;
|
|
calcola_ncolli_tara_pnetto(outrec.get(RDOC_CODARTMAG), daeva, ncolli, tara, pnetto);
|
|
outrec.add(RDOC_NCOLLI, ncolli);
|
|
outrec.add(RDOC_TARA, tara);
|
|
outrec.add(RDOC_PNETTO, pnetto);
|
|
|
|
outrec.dirty_fields(); // Forza ricalcolo formule
|
|
}
|
|
elaborata = true; // Ricorda di averla gia' elaborata
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!elaborata) // Se la riga non e' stata gia' sommata ...
|
|
{
|
|
const TString4 tiporiga = inrec.get(RDOC_TIPORIGA);
|
|
TRiga_documento& outrec = outdoc.new_row(tiporiga);
|
|
const TString& qta_field_orig = inrec.field_qta();
|
|
const TString& qta_field = outrec.field_qta();
|
|
const TString& qtaevasa_field = inrec.field_qtaevasa();
|
|
|
|
TDocumento::copy_data(outrec, inrec);
|
|
if (qta_field_orig != RDOC_QTA)
|
|
{
|
|
outrec.put(RDOC_QTA, UNO);
|
|
outrec.put(qta_field_orig, daeva);
|
|
}
|
|
else
|
|
{
|
|
outrec.put(qta_field, daeva);
|
|
if (qta_field != RDOC_QTA)
|
|
outrec.put(RDOC_QTA, UNO);
|
|
}
|
|
aggiorna_ncolli_tara_pnetto(outrec);
|
|
if (kill_descrizione_estesa()) // Cancello eventualmente la descrizione estesa
|
|
{
|
|
outrec.zero(RDOC_DESCLUNGA);
|
|
outrec.zero(RDOC_DESCEST);
|
|
}
|
|
|
|
outrec.dirty_fields(); // Forza ricalcolo peso etc.
|
|
outrec.zero(qtaevasa_field); // Azzera quantita' evasa erroneamente copiata dall'ordine
|
|
outrec.zero(RDOC_RIGAEVASA); // Azzera flag di evasa erroneamente copiata dall'ordine
|
|
outrec.set_original_rdoc_key(inrec);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Inserisce le eventuali righe di scarto al posto giusto
|
|
FOR_EACH_ASSOC_OBJECT(scarti, h, codart, obj)
|
|
{
|
|
TString4 tiporiga = "01"; // Riga merce standard
|
|
int i = 0;
|
|
// Cerca l'ultima riga del documento avente lo stesso articolo dello scarto
|
|
for (i = outdoc.physical_rows(); i > 0; i--)
|
|
{
|
|
const TRiga_documento& or = outdoc[i];
|
|
if (or.get(RDOC_CODARTMAG) == codart && or.is_articolo())
|
|
{
|
|
tiporiga = or.get(RDOC_TIPORIGA); // Memorizza tipo riga preferito dall'utente
|
|
break;
|
|
}
|
|
}
|
|
// Crea una nuova riga merce senza articolo e con sola descrizione, qta ed um
|
|
TRiga_documento& outrec = outdoc.insert_row(i+1, tiporiga);
|
|
TString descr;
|
|
descr << TR("Scarto") << ' ' << codart;
|
|
outrec.put(RDOC_DESCR, descr);
|
|
TToken_string& ska = *(TToken_string*)obj;
|
|
outrec.put(RDOC_UMQTA, ska.get(0));
|
|
outrec.put(RDOC_QTA, ska.get());
|
|
}
|
|
}
|
|
|
|
if (indoc.is_evaso())
|
|
{
|
|
indoc.stato(stato_finale_doc_iniziale()[0]);
|
|
}
|
|
}
|
|
return ok;
|
|
}
|