campo-sirio/lv/lv3400.cpp
luca83 8b32b59892 Patch level : 10.0 patch 706
Files correlati     : lv3
Ricompilazione Demo : [ ]
Commento            :
Segnalazioni Paolo 13/04/2010:
1) Quando consegno più roba del dovuto, e poi annullo il pacco in più, questo viene tolto due volte

2)Se evado un buono consegnando più roba del dovuto, nel buono di consegna non risulta la riba in più ma solo quella giusta per l'evasione


git-svn-id: svn://10.65.10.50/trunk@20330 c028cbd2-c16b-5b4b-a496-9718f37d4682
2010-04-13 13:52:40 +00:00

1526 lines
41 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <reputils.h>
#include <reprint.h>
#include <toolfld.h>
#include <utility.h>
#include "lvlib.h"
#include "../mg/clifogiac.h"
#include "../ve/velib.h"
#include "clifo.h"
#include "lvcondv.h"
#include "lvrcondv.h"
#include "lvrconsplan.h"
#include "lv3400a.h"
//////////////////////////////
//// TQUANTITA_RIGA ////
//////////////////////////////
//Classe TQuantita_riga
class TQuantita_riga: public TObject
{
int _nriga;
bool _evaso;
real _qtarit;
real _qtadacon;
real _qtacon;
int _pacchi;
public:
int get_nriga() const;
bool get_evaso() const;
real get_qta_rit() const;
real get_qta_da_con() const;
real get_qta_con() const;
int get_pacchi() const;
void set_nriga(const int nriga);
void set_evaso(const bool evaso);
void set_qta_rit(const real qta);
void set_qta_da_con(const real qta);
void set_qta_con(const real qta);
void set_pacchi(const int pacchi);
void add_qta_con(const real qta);
void add_pacchi(const int pacchi = 1);
TQuantita_riga(bool evaso = false, long qtadc = 0, long qtac = 0, int pacchi = 0);
};
//GET_NRIGA: metodo che restituisce il numero di riga
int TQuantita_riga::get_nriga() const
{
return _nriga;
}
//GET_EVASO: metodo che restituisce il booleano evaso
bool TQuantita_riga::get_evaso() const
{
return _evaso;
}
//GET_QTA_RIT: metodo che restituisce la qunatita ritirata
real TQuantita_riga::get_qta_rit() const
{
return _qtarit;
}
//GET_QTA_DA_CON: metodo che restituisce la quantità da consegnare
real TQuantita_riga::get_qta_da_con() const
{
return _qtadacon;
}
//GET_QTA_CON: metodo che restituisce la quantità consegnata
real TQuantita_riga::get_qta_con() const
{
return _qtacon;
}
//GET_PACCHI: metodo che restituisce il humero dei pacchi consegnati
int TQuantita_riga::get_pacchi() const
{
return _pacchi;
}
//SET_NRIGA: metodo che setta il numero di riga
void TQuantita_riga::set_nriga(const int nriga)
{
_nriga = nriga;
}
//SET_EVASO: metodo che setta il booleano evaso
void TQuantita_riga::set_evaso(const bool evaso)
{
_evaso = evaso;
}
//SET_QTA_RIT: metodo che setta la quantità ritirata
void TQuantita_riga::set_qta_rit(const real qta)
{
_qtarit = qta;
}
//SET_QTA_DA_CON: metodo che setta la quantità da consegnare
void TQuantita_riga::set_qta_da_con(const real qta)
{
_qtadacon = qta;
}
//SET_QTA_CON: metodo che setta la quantità consegnata
void TQuantita_riga::set_qta_con(const real qta)
{
_qtacon = qta;
}
//SET_PACCHI: metodo che setta il hnumero di pacchi consegnato
void TQuantita_riga::set_pacchi(const int pacchi)
{
_pacchi = pacchi;
}
//ADD_QTA_CON: metodo che aggiunge un quantitativo di roba alla quantità consegnata
void TQuantita_riga::add_qta_con(const real qta)
{
_qtacon += qta;
}
//ADD_PACCHI: metodo che aggiunge un certo numero di pacchi a quelli consegnati (default = 1)
void TQuantita_riga::add_pacchi(const int pacchi)
{
_pacchi += pacchi;
}
//metodo costruttore
TQuantita_riga::TQuantita_riga(bool evaso, long qtadc, long qtac, int pacchi)
{
set_evaso(evaso);
set_qta_da_con(qtadc);
set_qta_con(qtac);
set_pacchi(pacchi);
}
////////////////////////////
//// TRIGHE_ARRAY ////
////////////////////////////
//Classe TRighe_array
class TRighe_array: public TAssoc_array
{
public:
TQuantita_riga* quantita(TString& codart, TDate& data, TString& cau, bool create);
};
//QUANTITA: metodo che cerca nel TAssoc_array le quantità della riga interessata in base ai parametri passati
//e lo crea in automatico se il parametro create vale "true"
TQuantita_riga* TRighe_array::quantita(TString& codart, TDate& data, TString& cau, bool create)
{
TToken_string key;
key.add(codart);
key.add(data);
key.add(cau);
TQuantita_riga* qr = (TQuantita_riga*)objptr(key);
if(qr == NULL && create)
{
qr = new TQuantita_riga();
add(key, qr);
}
return qr;
}
/////////////////////////////////
//// TEVASIONE_TER_MSK ////
/////////////////////////////////
//Classe TEvasione_ter_msk
class TEvasione_ter_msk: public TAutomask
{
int _autoselect;
TString4 _tpev;
TAssoc_array _pacchi;
TRighe_array _ra;
protected:
void campi_cliente();
bool precarica_righe();
void genera_buono();
void evadi();
void registra();
void riempi_sheet();
int arrotonda(int quantita);
void spezza_riga();
bool controlla();
void evadi_da_terminale();
virtual void on_idle();
virtual bool on_key(KEY key);
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TEvasione_ter_msk();
};
//ON_KEY: metodo che gestisce i tatsi funzione
bool TEvasione_ter_msk::on_key(KEY key)
{
if (key >= K_F3 && key <= K_F7)
{
FOR_EACH_MASK_FIELD(*this, i, f)
{
if (f->is_kind_of(CLASS_BUTTON_TOOL) && f->active())
{
TButton_tool& tf = (TButton_tool&)*f;
if (tf.exit_key() == key)
{
send_key(K_SPACE, f->dlg());
return true;
}
}
}
}
return TAutomask::on_key(key);
}
//PRECARICA_RIGHE: metodo che carica in un TAssoc_array le righe fisiche del documento
bool TEvasione_ter_msk::precarica_righe()
{
TDoc_key kdoc(get_int(F_TANNO), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC));
TBuono_prelievo doc(kdoc);
if (doc.empty())
{
warning_box(TR("Il documento cercato è inesistente"));
return false;
}
const TString4 stato = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0), "S2").mid(2,1);
if (doc.get(DOC_STATO) == stato)
{
TString str;
str << "Il documento " << get_long(F_TNDOC) << " è già stato evaso";
warning_box(str);
reset(F_TCHIAVE);
return false;
}
TDate oggi(TODAY);
FOR_EACH_PHYSICAL_RDOC(doc, i, row)
{
TBuono_prelievo_row rdoc(*row);
TString80 codart = rdoc.codart();
if (codart.blank())
continue;
if (rdoc.qta_dacons() > 0)
{
TString4 cau = rdoc.causale();
TQuantita_riga* qr = _ra.quantita(codart, oggi, cau, true);
qr->set_nriga(i);
qr->set_evaso(rdoc.evaso());
qr->set_qta_rit(rdoc.qta_ritirata());
qr->set_qta_da_con(rdoc.qta_dacons());
qr->set_qta_con(rdoc.qta_consegnata());
qr->set_pacchi(rdoc.num_pacchi());
}
else
rdoc.set_evaso(true);
}
return true;
}
//GENERA_BUONO: metodo che genera il buono di consegna partendo dal buono di ritiro
void TEvasione_ter_msk::genera_buono()
{
//per prima cosa salva il buono di prelievo
registra();
TDoc_key kdoc(get_date(F_TDATADOC).year(), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC));
TBuono_prelievo bpre(kdoc);
const long codcf = bpre.codcf();
const int codcont = bpre.codcont();
TLaundry_contract cont(codcf, codcont);
//leggo se devo scrivere il prezzo sulla bolla
//const bool prinbo = cont.get_bool(LVCONDV_STPRZBOL);
const bool prinbo = true; //sempre a true; verrà gestita a video in futuro (27/10/2009)
//dati documento da generare
TString4 codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN");
TString4 tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN");
char stato = cache().get("%TIP", tipodoc, "S2").left(1)[0];
const TDate databpre = bpre.datadoc();
const TDate databolla = get_date(F_TDATADOC);
const TDate datagen(TODAY);
TDate dadata = databpre;
TDate adata = datagen;
adata.addmonth();
//recupero i dati di interesse dal planning
TString query1 = "USE LVRCONSPLAN KEY 3\n";
query1 << "FROM CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#DADATA\n";
query1 << "TO CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#ADATA\n";
TISAM_recordset consegne(query1);
consegne.set_var("#DADATA", ++dadata);
consegne.set_var("#ADATA", adata);
consegne.move_first();
const TDate dataprco = consegne.get(LVRCONSPLAN_DTCONS).as_date();
const int coditi = consegne.get(LVRCONSPLAN_CODITI).as_int();
TString8 codaut = consegne.get(LVRCONSPLAN_CODAUT).as_string().right(5); codaut.trim();
//recupero il codpag e i codici banca
TToken_string key;
key.add('C');
key.add(codcf);
const TRectype& clifo = cache().get(LF_CLIFO, key);
const TString4 codpag = clifo.get(CLI_CODPAG);
const long codabi = clifo.get_long(CLI_CODABI);
const long codcab = clifo.get_long(CLI_CODCAB);const TString80 iban = clifo.get(CLI_IBAN);
//reupero la cuasale di magazzino di testata
const TString16 causmag = cache().get("%TIP", tipodoc, "S9");
//recupero i dati di interesse dal file CFVEN
const TRectype& cfven = cache().get(LF_CFVEN, key);
const long codabipr = cfven.get_long(CFV_CODABIPR);
const long codcabpr = cfven.get_long(CFV_CODCABPR);
const bool ragdoc = cfven.get_bool(CFV_RAGGDOC);
const int codindsp = cfven.get_int(CFV_CODINDSP);
const TString8 codag1 = cfven.get(CFV_CODAG1);
const TString4 codmez = cfven.get(CFV_CODSPMEZZO);
const TString4 codporto = cfven.get(CFV_CODPORTO);
const TString4 codnote1 = cfven.get(CFV_CODNOTESP1);
const TString4 codnote2 = cfven.get(CFV_CODNOTESP2);
const TString4 codnote = cfven.get(CFV_CODNOTE);
const TString8 codvet1 = cfven.get(CFV_CODVETT1);
const TString8 codvet2 = cfven.get(CFV_CODVETT2);
const TString8 codvet3 = cfven.get(CFV_CODVETT3);
const real speseinc = cfven.get_real(CFV_PERCSPINC);
const TString4 catven = cfven.get(CFV_CATVEN);
const bool addbolli = cfven.get_bool(CFV_ADDBOLLI);
const TString8 codlist = cfven.get(CFV_CODLIST);
const TString4 codzona = cfven.get(CFV_CODZONA);
if(codaut.empty())
codaut = cfven.get(CFV_CODAG);
//gestione sconto
TString sconto;
const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0];
switch(tpgest)
{
case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente
case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti
case 'A': //Gestione archivio sconti
{
TConfig ditta(CONFIG_DITTA, "ve");
TLocalisamfile sconti(LF_SCONTI);
sconti.put("TIPO", "I");
if(ditta.get_bool("SCOKEY", "ve", 1))
sconti.put("CODCAT", cfven.get(CFV_CATVEN));
TString16 cod;
if(ditta.get_bool("SCOKEY", "ve", 2))
cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC));
else
cod = " ";
if(ditta.get_bool("SCOKEY", "ve", 3))
{
TString8 tmp;
tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA));
cod << tmp;
}
else
cod << " ";
if(ditta.get_bool("SCOKEY", "ve", 4))
cod << clifo.get(CLI_CODPAG);
sconti.put("CODART", cod);
if (sconti.read() == NOERR)
sconto = sconti.get("SCONTO");
}
case 'N': //sconto non gestito
default: break;
}
//preparo la testata del documento
TDocumento doc('D', kdoc.anno(), codnum, 0);
doc.put(DOC_TIPODOC, tipodoc);
doc.put(DOC_STATO, stato);
if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon"))
{
doc.put(DOC_DATADOC, datagen);
doc.put(DOC_DATAPART, databolla);
}
else
doc.put(DOC_DATADOC, databolla);
doc.put(DOC_TIPOCF, 'C');
doc.put(DOC_CODCF, codcf);
doc.put(DOC_CODCONT, codcont);
if(codindsp > 0)
doc.put(DOC_CODINDSP, codindsp);
doc.put(DOC_CODPAG, codpag);
doc.put(DOC_CODABIA, codabi);
doc.put(DOC_CODCABA, codcab);
doc.put(DOC_IBAN, iban);
doc.put(DOC_CODABIP, codabipr);
doc.put(DOC_CODCABP, codcabpr);
doc.put(DOC_CODAG, codaut);
doc.put(DOC_CODAGVIS, codag1);
doc.put(DOC_CODSPMEZZO, codmez);
doc.put(DOC_ZONA, codzona);
doc.put(DOC_CODPORTO, codporto);
doc.put(DOC_CODNOTESP1, codnote1);
doc.put(DOC_CODNOTESP2, codnote2);
doc.put(DOC_CODNOTE, codnote);
doc.put(DOC_CODVETT1, codvet1);
doc.put(DOC_CODVETT2, codvet2);
doc.put(DOC_CODVETT3, codvet3);
doc.put(DOC_CATVEN, catven);
doc.put(DOC_CODLIST, codlist);
doc.put(DOC_CAUSMAG, causmag);
doc.put(DOC_PERCSPINC, speseinc);
doc.put(DOC_ADDBOLLI, addbolli);
doc.put(DOC_SCONTOPERC, sconto);
doc.put("DATAGEN", datagen); //data generazione del documento
doc.put("DATAPRCO", dataprco); //data prevista consegna
doc.put("CODITI", coditi); //codice itinerario
for (int i = 1; i <= bpre.rows(); i++)
{
TRiga_documento& row = bpre[i];
TBuono_prelievo_row rbpre(row);
//nella bolla ci vanno solo le righe evase e non associate
if (!rbpre.evaso())
continue;
TDoc_key kbuono = rbpre.rifbcon();
if (kbuono.full())
continue;
const TString80 codart = rbpre.codart();
TString descr = rbpre.desart();
const TRectype& rcont = cont.row(codart);
//recupero i valori delle dotazione temporanea dal magazzino del cliente
TLocalisamfile magcli(LF_CLIFOGIAC);
magcli.put(CLIFOGIAC_ANNOES, datagen.year());
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, codcf);
magcli.put(CLIFOGIAC_INDSPED, 0); //in realtà è da leggere dal contratto
magcli.put(CLIFOGIAC_CODART, codart);
magcli.put(CLIFOGIAC_NRIGA, 1);
//leggo il record corrispondente
magcli.read();
real dottmp = magcli.get_real(CLIFOGIAC_DOTTM);
real dotod = magcli.get_real(CLIFOGIAC_DOTOD);
//recupero l'unità di misura principale di quest'articolo
TToken_string key;
key.add(codart);
key.add(1);
const TString4 um = cache().get(LF_UMART, key, UMART_UM);
//creo la nuova riga documento
TRiga_documento& rdoc = doc.new_row("21");
TDocumento::copy_data(rdoc, row);
rdoc.put(RDOC_CODART, codart);
rdoc.put(RDOC_CODARTMAG,codart);
rdoc.put(RDOC_CHECKED,'X');
rdoc.put(RDOC_GENERATA, true);
if(descr.len() <= 50)
rdoc.put(RDOC_DESCR, descr);
else
{
rdoc.put(RDOC_DESCR, descr.left(50));
rdoc.put(RDOC_DESCEST, descr.sub(50));
rdoc.put(RDOC_DESCLUNGA, true);
}
rdoc.put(RDOC_QTA, rbpre.qta_consegnata()); //consegnato
rdoc.put(RDOC_QTAGG1, rbpre.qta_ritirata()); //ritirato
dotod += (rbpre.qta_consegnata() - rbpre.qta_ritirata());
rdoc.put("DOTOD", dotod);
bool dtmp = false;
if (datagen >= rcont.get_date(LVRCONDV_INDTTMP) && datagen <= rcont.get_date(LVRCONDV_FIDTTMP))
dtmp = true;
if(dtmp)
{
rdoc.put("DOTMP", dottmp);
rdoc.add("DOTMP", rbpre.qta_consegnata() - rbpre.qta_ritirata());
}
const TCausale_lavanderie cau(rbpre.causale());
rdoc.put(RDOC_CODAGG1, cau.codice());
const TRectype& anamag = cache().get(LF_ANAMAG, codart);
//gestione prezzo
if (prinbo)
{
real prezzo;
if (cont.get_int(LVCONDV_TIPOLIS) == 0)
prezzo = rcont.get_real(LVRCONDV_PREZZO);
else
prezzo = anamag.get_real(ANAMAG_COSTSTD);
rdoc.put(RDOC_PREZZO, prezzo);
rdoc.put(RDOC_SCONTO, rcont.get(LVRCONDV_SCONTPERC)); //sconto
}
rdoc.put(RDOC_UMQTA, um);
rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA));
//scrivo il magazzino
TCausale_magazzino rit(cau.causale_ritiro());
TCausale_magazzino con(cau.causale_consegna());
TString8 magazzino;
TString8 magazzinoc;
if(rit.get("S10").full())
magazzino = rit.get("S10").mid(0,5);
else
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN");
if(con.get("S10").full())
magazzinoc = con.get("S10").mid(0,5);
else
magazzinoc << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC");
rdoc.put(RDOC_CODMAG, magazzino);
rdoc.put(RDOC_CODMAGC, magazzinoc);
}
//salva la bolla solo se ha almeno una riga
int err = 1;
if (doc.rows() > 0)
{
TToken_string orderkey;
orderkey.add(RDOC_CODART);
doc.sort_rows(orderkey);
err = doc.write();
for (int i = 1; i <= bpre.rows(); i++)
{
TRiga_documento& row = bpre[i];
TBuono_prelievo_row rbpre(row);
//nella bolla ci vanno solo le righe evase e non associate
if (!rbpre.evaso())
continue;
TDoc_key kbuono = rbpre.rifbcon();
if (kbuono.full())
continue;
//salvo i riferimenti
TDoc_key rifbcon(datagen.year(), codnum, doc.get_long(DOC_NDOC));
rbpre.set_rifbcon(rifbcon);
}
if(controlla())
{
const TString4 stato = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0), "S2").mid(2,1);
bpre.put(DOC_STATO, stato);
}
bpre.rewrite();
}
if (err == NOERR && yesno_box(TR("Il buono di consegna è stato generato correttamente; si desidera stamaprlo?")))
{
//stampa automatica
TFilename tmp;
tmp.temp("", "ini");
// Ensure that the ofstream is well closed before ve1 call
if (tmp.full()) // dummy test
{
ofstream outf(tmp);
outf << "[Transaction]" << endl; // Transaction header
outf << "Action=S" << endl; // 'S'tampa o 'A'nteprima
outf << "Mode=D" << endl; // Definitive (always?)
outf << "NoPrintDlg=X" << endl; // Dont' prompt the user with the print dialog
outf << endl;
outf << "[33]" << endl; // Transaction body
outf << "Doc(0)=";
outf << "D|" << datagen.year() << '|' << codnum << '|' << doc.get_long(DOC_NDOC) << endl;
}
if (tmp.exist())
{
TString cmdline; cmdline << "ve1 -2 -i" << tmp;
TExternal_app app(cmdline);
app.run();
tmp.fremove();
}
}
else
warning_box(TR("Non è stato possibile generare nessun documento"));
//riazzero ndoc
set(F_TNDOC, 0L, 1);
//nascondo i campi che non mi servono
reset(F_TCODCF); hide(F_TCODCF);
reset(F_TRAGSOC); hide(F_TRAGSOC);
reset(F_TBARCODE); hide(F_TBARCODE);
reset(F_TPACCHI); hide(F_TPACCHI);
reset(F_TQTAPACCO); hide(F_TQTAPACCO);
reset(F_TQTACON); hide(F_TQTACON);
reset(F_TQTADACON); hide(F_TQTADACON);
reset(F_CODART); hide(F_CODART);
//mostro i campi che servono per la selezione del documento
show(F_TCODNUM);
show(F_TTPDOC);
show(F_TDESCR);
show(F_TCHIAVE); reset(F_TCHIAVE);
show(F_TANNO);
show(F_TDATAPRCO);
//disabilito i bottoni
disable(DLG_SELECT);
disable(DLG_PREVIEW);
disable(DLG_ELABORA);
disable(DLG_SAVEREC);
disable(DLG_CANCEL);
enable(F_TNDOC);
}
//EVADI: metodo che setta a evaso tutte le righe del documento
void TEvasione_ter_msk::evadi()
{
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
TQuantita_riga* qr = (TQuantita_riga*)itm;
qr->set_evaso(true);
}
}
//REGISTRA: metodo che salva il buono di prelievo così com'è
void TEvasione_ter_msk::registra()
{
TDoc_key kdoc(get_date(F_TDATADOC).year(), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC));
TBuono_prelievo doc(kdoc);
TDate oggi(TODAY);
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
TQuantita_riga* qr = (TQuantita_riga*)itm;
int nriga = qr->get_nriga();
//se nriga > 0 vuol dire che si è aggiornata una riga già esistente;
//altrimenti significa che ho spezzato una riga
if (nriga > 0)
{
TRiga_documento& row = doc[nriga];
TBuono_prelievo_row rdoc(row);
rdoc.set_evaso(qr->get_evaso());
rdoc.set_qta_ritirata(qr->get_qta_rit());
rdoc.set_qta_consegnata(qr->get_qta_con());
rdoc.set_qta_dacons(qr->get_qta_da_con());
rdoc.set_num_pacchi(qr->get_pacchi());
rdoc.set_dataeva(oggi);
}
else
{
//trovo la riga con quel codart
TToken_string chiave(key);
TString80 codart = chiave.get(0);
int i;
for(i = 1; i <= doc.rows(); i++)
{
TRiga_documento& row = doc[i];
if(codart == row.get(RDOC_CODART))
break;
}
//creo una copia di questa riga
TRiga_documento& row1 = doc[i];
TRiga_documento& row2 = doc.new_row("24");
TDocumento::copy_data(row2, row1);
TBuono_prelievo_row rdoc(row2);
//setto le quantità corrette
rdoc.set_evaso(qr->get_evaso());
rdoc.set_qta_ritirata(qr->get_qta_rit());
rdoc.set_qta_consegnata(qr->get_qta_con());
rdoc.set_qta_dacons(qr->get_qta_da_con());
rdoc.set_num_pacchi(qr->get_pacchi());
rdoc.set_dataeva(oggi);
}
}
for(int i = 1; i <= doc.rows(); i++)
{
TRiga_documento& row = doc[i];
TBuono_prelievo_row rdoc(row);
if (rdoc.qta_dacons() <= ZERO)
{
rdoc.set_evaso(true);
rdoc.set_dataeva(oggi);
}
}
doc.rewrite();
//visto che sto evadendo tramite barcode quando salvo salvo anche tutti i pacchi associati
//generando i movimenti di magazzino di scarico
TLocalisamfile pacchi(LF_PACCHI);
TLocalisamfile movi(LF_MOVMAG);
//cerco l'ultimo numero di chiave in movmag
TISAM_recordset mov("USE MOVMAG");
long nummov = 0;
if(mov.move_last())
nummov += mov.get(MOVMAG_NUMREG).as_int();
const TCausale_magazzino causale((ini_get_string(CONFIG_DITTA, "lv", "CAUSCARMAG")));
TString8 magazzino;
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGP");
TEsercizi_contabili es;
int annoes = es.date2esc(oggi);
TMov_mag movmag(++nummov);
movmag.put(MOVMAG_ANNOES, annoes);
movmag.put(MOVMAG_DATAREG, oggi);
movmag.put(MOVMAG_CODCAUS, causale.codice());
FOR_EACH_ASSOC_OBJECT(_pacchi, o, codpacco, rifdoc)
{
TToken_string& tmp = *(TToken_string*)rifdoc;
TDoc_key kdoc(tmp.get_int(0), tmp.get(1), tmp.get_long(2));
TRiga_pacco rp(codpacco);
const TString80 codart = rp.articolo();
const long qta = rp.quantita().integer();
//recupero l'unità di misura principale di quest'articolo
TToken_string key;
key.add(codart);
key.add(1);
const TString4 um = cache().get(LF_UMART, key, UMART_UM);
rp.set_rigabolla(kdoc.anno(), kdoc.codnum(), kdoc.ndoc(), 0); //SOLUZIONE MOMENTANEA PER VEDERE SE FUNZIONA TUTTO
rp.rewrite(pacchi);
//faccio la nuova riga del movimento di magazzino
TRectype& rmovmag = movmag.new_row();
rmovmag.put(RMOVMAG_CODMAG, magazzino);
rmovmag.put(RMOVMAG_CODART, codart);
rmovmag.put(RMOVMAG_UM, um);
rmovmag.put(RMOVMAG_QUANT, qta);
}
movmag.write(movi);
}
//RIEMPI_SHEET: metodo che riempie lo sheet di riepilogo delle righe documento ancora da evadere
void TEvasione_ter_msk::riempi_sheet()
{
TSheet_field& sheet = sfield(F_TRIGHE);
sheet.destroy();
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
TToken_string chiave(key);
TQuantita_riga& qr = *(TQuantita_riga*)itm;
if(!qr.get_evaso())
{
TToken_string& riga = sheet.row(-1);
riga.add(chiave.get(0), 0);
riga.add(qr.get_qta_da_con().string(), 1);
riga.add(qr.get_qta_con().string(), 2);
}
}
sheet.force_update();
}
int TEvasione_ter_msk::arrotonda(const int quantita)
{
int perarr = ini_get_int(CONFIG_DITTA, "lv", "Perarr");
int qta = quantita;
const TString& codart = get(FR_CODART);
//instanzio una cache sulla tabella del magazzino
const TRectype& anamag = cache().get(LF_ANAMAG,codart);
//recupero i dati di interesse dall'anagrafica di magazzino
const long ppconf = anamag.get_long(ANAMAG_PPCONF);
if (ppconf > 0)
{
//recupero dal documento i dati di interesse per recuperare...
//...i dati dalla riga contratto
const long codcf = get_long(F_TCODCF);
const TDate data = get_date(F_TDATADOC);
TToken_string key;
key.add('C');
key.add(codcf);
const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP));
const TLaundry_contract cont(codcf, codindsp, data);
const long codcn = cont.get_int(LVCONDV_CODCONT);
//leggo la riga del contratto per l'articolo corrente
const TRectype& rcont = cont.row(codart);
//recupero i dati di interesse dalla riga del contratto
if (rcont.get_int(LVRCONDV_CALCCONS) == 1)
{
//calcolo di quanti pezzi sforo
long arr = quantita % ppconf;
//calcolo quanti pezzi in più o in meno gli devo dare e aggiorno la quantità
if (arr > ppconf * perarr / 100) //arr <= ppconf*perarr/100 -> formula calcolo congualgio di Tassan
{
arr = ppconf - arr;
qta += arr;
}
else
qta -= arr;
}
}
return qta;
}
//SPEZZA_RIGHE: metodo che spezza le righe documento se richiesto
void TEvasione_ter_msk::spezza_riga()
{
const TDate oggi(TODAY);
const TDate nulla(NULLDATE);
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
TToken_string chiave(key);
TQuantita_riga& qr = *(TQuantita_riga*)itm;
if((TDate)chiave.get() == oggi && !qr.get_evaso())
{
real qtarit = qr.get_qta_rit();
real qtadacon = qr.get_qta_da_con();
real qtacon = qr.get_qta_con();
real pacchi = qr.get_pacchi();
qr.set_evaso(true);
qr.set_qta_da_con(qtacon);
qr.set_qta_rit(qtacon);
TToken_string chiave1;
chiave1.add(chiave.get(0), 0);
chiave1.add(nulla, 1);
TQuantita_riga qr1;
qr1.set_evaso(false);
qr1.set_qta_rit(qtadacon - qtacon);
qr1.set_qta_da_con(arrotonda(qtadacon.integer() - qtacon.integer()));
qr1.set_qta_con(ZERO);
qr1.set_pacchi(0);
_ra.add(chiave1, qr1);
}
}
}
//CONTROLLA: metodo che controlla se tutte le righe del buono sono evase
bool TEvasione_ter_msk::controlla()
{
bool evaso = true;
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
TQuantita_riga* qr = (TQuantita_riga*)itm;
if(!qr->get_evaso())
{
evaso = false;
break;
}
}
return evaso;
}
//EVADI_DA_TERMINALE: metodo che somma alla riga corretta un pacco (quello pistolato) e lo assegna a un cliente,
//sottraendolo dal magazzino del pulito
void TEvasione_ter_msk::evadi_da_terminale()
{
const TString80 codpacco = get(F_TBARCODE);
if (codpacco.full())
{
TRiga_pacco rp(codpacco);
if (rp.empty())
{
warning_box(TR("Il pacco non esiste a magazzino"));
warning_box(TR("Non è stato possibile sommare il pacco a nessuna riga del buono"));
}
else
{
if (rp.rigabolla().full())
{
TToken_string riga = rp.rigabolla();
int numdoc = riga.get_int(3);
if(numdoc > 0)
{
TString msg;
msg << "Il pacco risulta già associato al buono numero " << numdoc;
warning_box(msg);
return;
}
}
const TDate oggi(TODAY);
const TString80 codart = rp.articolo();
const real qtapacco = rp.quantita();
TToken_string key;
key.add(codart);
key.add(oggi);
TToken_string kdoc;
kdoc.add(get_date(F_TDATADOC).year());
kdoc.add(ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0));
kdoc.add(get_int(F_TNDOC));
//se il pacco è già stato pistolettato lo tolgo dai pacchi da evadere, altrimenti cerco di sommarlo
//a una riga documento esistente
if (_pacchi.is_key(codpacco))
{
if(yesno_box(TR("Si desidera annullare il pacco selezionato?")))
{
TToken_string& tmp = *(TToken_string*)_pacchi.objptr(codpacco);
key.add(tmp.get(3));
_pacchi.remove(codpacco);
if (_ra.is_key(key))
{
TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(key);
qr.add_pacchi(-1);
qr.add_qta_con(-1 * qtapacco);
if (qr.get_evaso())
qr.set_evaso(false);
set(F_TPACCHI, qr.get_pacchi());
set(F_TQTAPACCO, qtapacco);
set(F_TQTACON, qr.get_qta_con());
set(F_TQTADACON, qr.get_qta_da_con());
set(F_CODART, rp.articolo());
}
}
else
return;
}
else
{
bool trovato = false;
bool trovato2 = false;
bool associato = false;
bool evaso1 = false;
bool evaso2 = false;
TToken_string chiave1;
TToken_string chiave2;
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
chiave1 = key;
//se trovo una riga di quell'artticolo allora
TString cod = chiave1.get(0);
if(cod == codart)
{
trovato = true;
TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(key);
//se la riga trovata non è già evasa e manca da consegnare almeno la qta
//di un pacco, allora lo associo
evaso1 = qr.get_evaso();
if (!evaso1 && qr.get_qta_da_con() >= qtapacco)
{
associato = true;
qr.add_pacchi();
qr.add_qta_con(qtapacco);
if(qr.get_qta_con() == qr.get_qta_da_con())
qr.set_evaso(true);
kdoc.add(chiave1.get(2));
_pacchi.add(codpacco, kdoc);
set(F_TPACCHI, qr.get_pacchi());
set(F_TQTAPACCO, qtapacco);
set(F_TQTACON, qr.get_qta_con());
set(F_TQTADACON, qr.get_qta_da_con());
set(F_CODART, rp.articolo());
break;
}
break;
}
}
//se ho trovato la riga di quell'articolo ma non l'ho associato,
//cerco un eventuale altra riga per quell'articolo
if(trovato && !associato)
{
FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm)
{
chiave2 = key;
//se trovo una riga di quell'artticolo allora
if(chiave2.get(0) == codart && chiave1 != chiave2)
{
trovato2 = true;
TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(key);
//se la riga trovata non è già evasa e manca da consegnare almeno la qta
//di un pacco, allora lo associo
evaso2= qr.get_evaso();
if (!evaso2 && qr.get_qta_da_con() >= qtapacco)
{
associato = true;
qr.add_pacchi();
qr.add_qta_con(qtapacco);
if(qr.get_qta_con() == qr.get_qta_da_con())
qr.set_evaso(true);
kdoc.add(chiave2.get(2));
_pacchi.add(codpacco, kdoc);
set(F_TPACCHI, qr.get_pacchi());
set(F_TQTAPACCO, qtapacco);
set(F_TQTACON, qr.get_qta_con());
set(F_TQTADACON, qr.get_qta_da_con());
set(F_CODART, rp.articolo());
break;
}
}
}
}
//se risulta ancora trovato, ma non associato, allora lo associo alla riga non ancora evasa
if(trovato2 && !associato)
{
if(!evaso1)
{
TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(chiave1);
kdoc.add(chiave1.get(2));
qr.add_pacchi();
qr.add_qta_con(qtapacco);
if(qr.get_qta_con() >= qr.get_qta_da_con())
qr.set_evaso(true);
_pacchi.add(codpacco, kdoc);
set(F_TPACCHI, qr.get_pacchi());
set(F_TQTAPACCO, qtapacco);
set(F_TQTACON, qr.get_qta_con());
set(F_TQTADACON, qr.get_qta_da_con());
set(F_CODART, rp.articolo());
}
else if(!evaso2)
{
TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(chiave2);
kdoc.add(chiave2.get(2));
qr.add_pacchi();
qr.add_qta_con(qtapacco);
if(qr.get_qta_con() >= qr.get_qta_da_con())
qr.set_evaso(true);
_pacchi.add(codpacco, kdoc);
set(F_TPACCHI, qr.get_pacchi());
set(F_TQTAPACCO, qtapacco);
set(F_TQTACON, qr.get_qta_con());
set(F_TQTADACON, qr.get_qta_da_con());
set(F_CODART, rp.articolo());
}
}
//se non è ancora associato e entrambe le righe risultano evase oppure c'è una riga sola
//allora sommo alla prima (o unica) riga se l'utente lo desidera
if(!associato && ((evaso1 && evaso2)||!trovato2))
{
if(yesno_box(TR("Si desidera sommare il pacco ad un riga già evasa?")))
{
TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(chiave1);
kdoc.add(chiave1.get(2));
qr.add_pacchi();
qr.add_qta_con(qtapacco);
if(qr.get_qta_con() >= qr.get_qta_da_con())
qr.set_evaso(true);
_pacchi.add(codpacco, kdoc);
set(F_TPACCHI, qr.get_pacchi());
set(F_TQTAPACCO, qtapacco);
set(F_TQTACON, qr.get_qta_con());
set(F_TQTADACON, qr.get_qta_da_con());
set(F_CODART, rp.articolo());
}
else
return;
}
if(!trovato)
{
TDoc_key kdoc(get_date(F_TDATADOC).year(), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC));
TBuono_prelievo bpre(kdoc);
const long codcf = bpre.codcf();
const int codcont = bpre.codcont();
TLaundry_contract cont(codcf, codcont);
const TRectype& rcont = cont.row(rp.articolo());
if (rcont.empty())
{
TString msg;
msg << "L'articolo " << rp.articolo() << " non è previsto per questo cliente";
warning_box(msg);
}
else
{
TString msg;
msg << "L'articolo " << rp.articolo() << " non è previsto sul buono in evasione";
warning_box(msg);
}
}
}
}
}
}
//ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera
bool TEvasione_ter_msk::on_field_event(TOperable_field& f, TField_event e, long jolly)
{
//a seconda del bottone premuto esegui un metodo diverso
switch (f.dlg())
{
case DLG_SELECT:
if (e == fe_button)
{
if(yesno_box(TR("ATTENZIONE: non tutte le righe sono evase. Si desidera continuare ugualmente?")))
{
evadi();
genera_buono();
}
return false;
}
break;
case DLG_PREVIEW:
if (e == fe_button)
{
hide(F_TBARCODE);
hide(F_TPACCHI);
hide(F_TQTAPACCO);
hide(F_TQTACON);
hide(F_TQTADACON);
hide(F_CODART);
show(F_TRIGHE);
disable(DLG_SELECT);
disable(DLG_ELABORA);
riempi_sheet();
return false;
}
break;
case DLG_ELABORA:
if (e == fe_button)
if (controlla())
genera_buono();
else
{
if(yesno_box(TR("ATTENZIONE: non tutte le righe sono evase. Si desidera continuare ugualmente?")))
{
if(yesno_box(TR("Si desidera considerare evase tutte le righe?"
"(in caso contrario le righe evase parzialmente verranno spezzate su due righe)")))
{
evadi();
genera_buono();
}
else
{
spezza_riga();
genera_buono();
}
}
else
send_key(K_SPACE, DLG_CANCEL);
}
return false;
break;
case DLG_CANCEL:
if (e == fe_button && jolly == 0)
{
if(field(F_TRIGHE).shown())
{
show(F_TBARCODE);
show(F_TPACCHI);
show(F_TQTAPACCO);
show(F_TQTACON);
show(F_TQTADACON);
show(F_CODART);
enable(DLG_SELECT);
enable(DLG_ELABORA);
hide(F_TRIGHE);
field(F_TBARCODE).set_focus();
_autoselect = 1;
return false;
}
else
{
show(F_TCHIAVE);
show(F_TCODNUM);
show(F_TDESCR);
show(F_TTPDOC);
show(F_TANNO);
show(F_TDATAPRCO);
reset(F_TCODCF); hide(F_TCODCF);
reset(F_TRAGSOC); hide(F_TRAGSOC);
reset(F_TBARCODE); hide(F_TBARCODE);
reset(F_TPACCHI); hide(F_TPACCHI);
reset(F_TQTAPACCO); hide(F_TQTAPACCO);
reset(F_TQTACON); hide(F_TQTACON);
reset(F_TQTADACON); hide(F_TQTADACON);
reset(F_CODART); hide(F_CODART);
disable(DLG_SELECT);
disable(DLG_PREVIEW);
disable(DLG_ELABORA);
disable(DLG_SAVEREC);
disable(DLG_CANCEL);
reset(F_TDATADOC);
reset(F_TNDOC);
reset(F_TCHIAVE);
enable(F_TNDOC);
_ra.destroy();
field(F_TCHIAVE).set_focus();
return false;
}
}
break;
case DLG_SAVEREC:
if (e == fe_button)
{
registra();
return false;
}
break;
case F_TCHIAVE:
{
if (e == fe_modify)
{
TString kdoc = f.get();
if (kdoc.full())
{
set(F_TANNO, atol(kdoc.left(4)));
set(F_TNDOC, atol(kdoc.mid(4)));
field(F_TNDOC).check();
if(!precarica_righe())
return false;
hide(F_TCODNUM);
hide(F_TTPDOC);
hide(F_TDESCR);
hide(F_TANNO);
hide(F_TDATAPRCO);
show(F_TCODCF);
show(F_TRAGSOC);
show(F_TBARCODE);
show(F_TPACCHI);
show(F_TQTAPACCO);
show(F_TQTACON);
show(F_TQTADACON);
show(F_CODART);
enable(DLG_SELECT);
enable(DLG_PREVIEW);
enable(DLG_ELABORA);
enable(DLG_SAVEREC);
enable(DLG_CANCEL);
disable(F_TNDOC);
_autoselect = 1;
field(F_TBARCODE).set_focus();
f.hide();
}
}
}
break;
case F_TNDOC:
{
if (e == fe_modify)
if (f.get_long() != 0 && get(F_TCHIAVE).empty())
{
field(F_TNDOC).check();
if(!precarica_righe())
return false;
hide(F_TCODNUM);
hide(F_TTPDOC);
hide(F_TDESCR);
hide(F_TANNO);
hide(F_TDATAPRCO);
hide(F_TCHIAVE);
show(F_TCODCF);
show(F_TRAGSOC);
show(F_TBARCODE);
show(F_TPACCHI);
show(F_TQTAPACCO);
show(F_TQTACON);
show(F_TQTADACON);
show(F_CODART);
enable(DLG_SELECT);
enable(DLG_PREVIEW);
enable(DLG_ELABORA);
enable(DLG_SAVEREC);
enable(DLG_CANCEL);
disable(F_TNDOC);
_autoselect = 1;
field(F_TBARCODE).set_focus();
}
else
{
show(F_TCHIAVE);
show(F_TCODNUM);
show(F_TDESCR);
show(F_TTPDOC);
show(F_TANNO);
show(F_TDATAPRCO);
reset(F_TCODCF); hide(F_TCODCF);
reset(F_TRAGSOC); hide(F_TRAGSOC);
reset(F_TBARCODE); hide(F_TBARCODE);
reset(F_TPACCHI); hide(F_TPACCHI);
reset(F_TQTAPACCO); hide(F_TQTAPACCO);
reset(F_TQTACON); hide(F_TQTACON);
reset(F_TQTADACON); hide(F_TQTADACON);
reset(F_CODART); hide(F_CODART);
disable(DLG_SELECT);
disable(DLG_PREVIEW);
disable(DLG_ELABORA);
disable(DLG_SAVEREC);
disable(DLG_CANCEL);
reset(F_TDATADOC);
enable(F_TNDOC);
_ra.destroy();
}
}
break;
case F_TBARCODE:
{
if (e == fe_modify && f.get().full())
{
_autoselect = 1;
evadi_da_terminale();
if (controlla())
send_key(K_SPACE, DLG_ELABORA);
}
}
break;
default:break;
}
return true;
}
void TEvasione_ter_msk:: on_idle()
{
TMask::on_idle();
if (_autoselect >= 0 && get(F_TBARCODE).full())
{
reset(F_TBARCODE);
field(F_TBARCODE).set_focus();
_autoselect = -1;
}
}
TEvasione_ter_msk::TEvasione_ter_msk():TAutomask("lv3400a")
{
//precarico i campi fissi
set(F_TCODNUM, ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0));
set(F_TTPDOC, ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0));
const TRectype& tpdoc = cache().get("%NUM", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0));
set(F_TDESCR, tpdoc.get("S0"));
TDate data(TODAY);
TEsercizi_contabili es;
int annoes = es.date2esc(data);
set(F_TANNO, annoes);
hide(F_TCODCF);
hide(F_TRAGSOC);
hide(F_TBARCODE);
hide(F_TPACCHI);
hide(F_TQTAPACCO);
hide(F_TQTACON);
hide(F_TQTADACON);
hide(F_CODART);
hide(F_TRIGHE);
disable(DLG_SELECT);
disable(DLG_PREVIEW);
disable(DLG_ELABORA);
disable(DLG_SAVEREC);
disable(DLG_CANCEL);
}
/////////////////////////////////
//// TEVASIONE_TER_APP ////
/////////////////////////////////
//classe TEvasione_ter_app
class TEvasione_ter_app : public TSkeleton_application
{
TEvasione_ter_msk* _msk;
protected:
virtual bool create();
virtual bool destroy();
public:
bool transfer();
virtual void main_loop();
};
//CREATE: metodo costruttore
bool TEvasione_ter_app::create()
{
_msk = new TEvasione_ter_msk();
open_files(LF_DOC, LF_RIGHEDOC);
return TSkeleton_application::create();
}
//DESTROY: metodo distruttore
bool TEvasione_ter_app::destroy()
{
delete _msk;
return TApplication::destroy();
}
//TRANSFER: metodo che scorre i campi nome e, se sono pieni, richiama il metodo
//ELABORA_FILE(), che effettivamente fa l'elaborazione
bool TEvasione_ter_app::transfer()
{
return true;
}
void TEvasione_ter_app::main_loop()
{
while (_msk->run() == K_ENTER)
transfer();
}
int lv3400(int argc, char *argv[])
{
TEvasione_ter_app a;
a.run (argc, argv, "Evasione Buoni di Prelievo");
return TRUE;
}