campo-sirio/lv/lv3700.cpp
luca83 6a08b145cb Patch level : 10.0 patch ???
Files correlati     : lv3
Ricompilazione Demo : [ ]
Commento            :
Corretto salvataggio documenti di inventario


git-svn-id: svn://10.65.10.50/trunk@20399 c028cbd2-c16b-5b4b-a496-9718f37d4682
2010-04-29 15:25:24 +00:00

849 lines
22 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include "lvlib.h"
#include "lv3700a.h"
///////////////////////////////////
//// TDOC_INVENTARIO_ROW ////
///////////////////////////////////
//Classe TDoc_inventario_row
class TDoc_inventario_row: public TObject
{
TRiga_documento& _rinv;
public:
const TString& codart() const;
const TString& desart() const;
const real qta() const;
const TString& um() const;
const int num_pacchi() const;
const TToken_string& cod_pacchi() const;
const TString& magazzino() const;
const TString& magazzinoc() const;
void set_codart(const char* codart);
void set_desart(const TString& desart);
void set_qta(const real qta);
void set_um(const char* um);
void set_num_pacchi(const int numpacchi);
void set_cod_pacchi(const char* codpacchi);
void set_magazzino(const char* mag);
void set_magazzinoc(const char* magc);
TDoc_inventario_row(TRiga_documento& rinv):_rinv(rinv){}
};
//CODART: metodo che restituisce il codice articolo della riga documento
const TString& TDoc_inventario_row::codart() const
{
return _rinv.get(RDOC_CODART);
}
//DESART: metodo che restiruisce la descrizione dell'articolo
const TString& TDoc_inventario_row::desart() const
{
TString& str = get_tmp_string();
str = _rinv.get(RDOC_DESCR);
if (_rinv.get_bool(RDOC_DESCLUNGA))
str << _rinv.get(RDOC_DESCEST);
return str;
}
//QTA: metodo che restiruisce la quantità salvata sulla riga
const real TDoc_inventario_row::qta() const
{
return _rinv.get_real(RDOC_QTA);
}
//UM: metodo che restiruisce l'unità di misura utilizzata sulla riga documento
const TString& TDoc_inventario_row::um() const
{
return _rinv.get(RDOC_UMQTA);
}
//NUM_PACCHI: metodo che resituisce il numero dei pacchi presenti per quell'articolo
const int TDoc_inventario_row::num_pacchi() const
{
return _rinv.get_int(RDOC_NCOLLI);
}
//COD_PACCHI: metodo che restiuisce l'elenco dei pacchi salvati su quella riga
const TToken_string& TDoc_inventario_row::cod_pacchi() const
{
TToken_string& tmp = get_tmp_string();
tmp = _rinv.get("CODPACCHI");
return tmp;
}
//MAGAZZINO: metodo che restituisce il codice del magazzino/deposito
const TString& TDoc_inventario_row::magazzino() const
{
return _rinv.get(RDOC_CODMAG);
}
//MAGAZZINOC: metodo che restituisce il codice del magazzino/deposito collegato
const TString& TDoc_inventario_row::magazzinoc() const
{
return _rinv.get(RDOC_CODMAGC);
}
//SET_CODART: metodo che setta il codice articolo
void TDoc_inventario_row::set_codart(const char* codart)
{
_rinv.put(RDOC_CODART, codart);
_rinv.put(RDOC_CODARTMAG, codart);
}
//SET_DESART: metodo che setta la descrizione
void TDoc_inventario_row::set_desart(const TString& desart)
{
if (desart.len() > 50)
{
_rinv.put(RDOC_DESCR, desart.left(50));
_rinv.put(RDOC_DESCLUNGA, true);
_rinv.put(RDOC_DESCEST, desart.mid(50));
}
else
_rinv.put(RDOC_DESCR, desart);
}
//SET_QTA_RITIRATA: metodo che setta la quantità ritirata sulla riga
void TDoc_inventario_row::set_qta(const real qta)
{
_rinv.put(RDOC_QTA, qta);
}
//SET_UM: metodo che setta l'unità di misura
void TDoc_inventario_row::set_um(const char* um)
{
_rinv.put(RDOC_UMQTA, um);
}
//SET_NUM_PACCHI: metodo che setta il numero dei pacchi
void TDoc_inventario_row::set_num_pacchi(const int numpacchi)
{
_rinv.put(RDOC_NCOLLI, numpacchi);
}
//SET_COD_PACCHI: metodo che setta l'elenco dei pacchi salvati su quella riga
void TDoc_inventario_row::set_cod_pacchi(const char* codpacchi)
{
_rinv.put("CODPACCHI", codpacchi);
}
//SET_MAGAZZINO: metodo che setta il codice del magazzino/deposito
void TDoc_inventario_row::set_magazzino(const char* mag)
{
_rinv.put(RDOC_CODMAG, mag);
}
//SET_MAGAZZINOC: metodo che setta il codice del magazzino/deposito collegato
void TDoc_inventario_row::set_magazzinoc(const char* magc)
{
_rinv.put(RDOC_CODMAGC, magc);
}
///////////////////////////////
//// TDOC_INVENTARIO ////
///////////////////////////////
//Classe TDoc_inventario
class TDoc_inventario: public TDocumento
{
public:
const TToken_string& chiave() const;
const TDate datadoc() const;
TDoc_inventario_row find_or_create_row(const char* codart);
void set_difinv(const bool difinv = true);
TDoc_inventario& operator= (const TDoc_inventario dinv){dinv;}
TDoc_inventario(TDoc_key& key): TDocumento(key.provv(), key.anno(), key.codnum(), key.ndoc()){};
TDoc_inventario(TDoc_inventario& dinv): TDocumento(dinv){};
};
//CHIAVE: metodo che restituisce la chiave del documento
const TToken_string& TDoc_inventario::chiave() const
{
TToken_string& k = get_tmp_string();
k.add(get(DOC_PROVV));
k.add(get(DOC_ANNO));
k.add(get(DOC_CODNUM));
k.add(get(DOC_NDOC));
return k;
}
//DATADOC: metodo che restiruisce la data documento
const TDate TDoc_inventario::datadoc() const
{
return get_date(DOC_DATADOC);
}
//FIND_OR_CREATE_ROW: metodo che cerca una riga con un certo codart e se non esiste la crea
TDoc_inventario_row TDoc_inventario::find_or_create_row(const char* codart)
{
//scorro tutte le righe documento; se ne trovo una con quel codart
//allora la restituisco
for(int i = 1; i <= rows(); i++)
{
TRiga_documento& row = (*(TDocumento*)this)[i];
const TString& cod = row.get(RDOC_CODART);
if(cod == codart)
{
TDoc_inventario_row rinv(row);
return rinv;
}
}
//se sono arrivato qui non ho trovato neanche una riga con quel codart;
//in queto caso ne aggiungo una
TRiga_documento& row = (*(TDocumento*)this).new_row("21");
TDoc_inventario_row rinv(row);
return rinv;
}
void TDoc_inventario::set_difinv(const bool difinv)
{
put("DIFINV", difinv);
}
///////////////////////////////
//// TPACCHI_CONTATI ////
///////////////////////////////
//Classe TPacchi_contati
class TPacchi_contati: public TObject
{
real _qta;
TString4 _um;
int _npacchi;
TToken_string _codpacchi;
public:
const real qta() const;
const TString& um() const;
const int npacchi() const;
const TToken_string& codpacchi() const;
void set_qta(const real& qta);
void set_um(const char* um);
void set_npacchi(const int npacchi = 1);
void set_codpacchi(const TToken_string& codpacchi);
void add_qta(const real& qta);
void add_pacchi(const int pacchi = 1);
void add_codpacco(const TString& codpacco);
void sub_codpacco(const TString& codpacco);
TPacchi_contati(const real& qta = ZERO, const char* um = "", const int npacchi = 0, const char* codpacco = "");
};
//QTA: metodo che restituisce la quantita
const real TPacchi_contati::qta() const
{
return _qta;
}
//UM: metodo che restituisce l'unità di misura
const TString& TPacchi_contati::um() const
{
return _um;
}
//NPACCHI: metodo che restituisce il numero dei pacchi pistolati
const int TPacchi_contati::npacchi() const
{
return _npacchi;
}
//CODPACCHI: metodo che restituisce i codici dei pacchi pistolati
const TToken_string& TPacchi_contati::codpacchi() const
{
return _codpacchi;
}
//SET_QTA: metodo che setta la quantità
void TPacchi_contati::set_qta(const real& qta)
{
_qta = qta;
}
//SET_UM: metodo che setta l'unità di misura
void TPacchi_contati::set_um(const char* um)
{
_um = um;
}
//SET_NPACCHI: metodo che setta il numero di pacchi
void TPacchi_contati::set_npacchi(const int npacchi)
{
_npacchi = npacchi;
}
//SET_CODPACCHI: metodo che setta i codici dei pacchi
void TPacchi_contati::set_codpacchi(const TToken_string& codpacchi)
{
TToken_string tmp(codpacchi, '-');
_codpacchi = tmp;
}
//ADD_QTA_CON: metodo che aggiunge un quantitativo di roba alla quantità consegnata
void TPacchi_contati::add_qta(const real& qta)
{
_qta += qta;
}
//ADD_PACCHI: metodo che aggiunge un certo numero di pacchi a quelli consegnati (default = 1)
void TPacchi_contati::add_pacchi(const int pacchi)
{
_npacchi += pacchi;
}
//ADD_CODPACCO: metodo che aggiunge un codice di un pacco alla TToken_string che li contiene
void TPacchi_contati::add_codpacco(const TString& codpacco)
{
_codpacchi.add(codpacco);
}
//SUB_CODPACCO: metodo che toglie un codice di un pacco alla TToken_string che li contiene
void TPacchi_contati::sub_codpacco(const TString& codpacco)
{
int pos = _codpacchi.get_pos(codpacco);
_codpacchi.destroy(pos);
}
//metodo costruttore
TPacchi_contati::TPacchi_contati(const real& qta, const char* um, const int npacchi, const char* codpacco)
{
set_qta(qta);
set_um(um);
set_npacchi(npacchi);
TToken_string tmp(codpacco, '-');
set_codpacchi(tmp);
}
////////////////////////////////
//// TRIGHE_INV_ARRAY ////
////////////////////////////////
//Classe TRighe_inv_array
class TRighe_inv_array: public TAssoc_array
{
public:
TPacchi_contati* quantita(TString& codart, 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"
TPacchi_contati* TRighe_inv_array::quantita(TString& codart, bool create)
{
TPacchi_contati* pc = (TPacchi_contati*)objptr(codart);
if(pc == NULL && create)
{
pc = new TPacchi_contati();
add(codart, pc);
}
return pc;
}
///////////////////////////////////
//// TINVENTARIO_TER_MSK ////
///////////////////////////////////
//Classe TInventario_ter_msk
class TInventario_ter_msk: public TAutomask
{
TRighe_inv_array _ria;
bool _nuovo;
int _autoselect;
protected:
bool precarica_righe();
void registra();
void aggiorna_campi(const char* codart, const TPacchi_contati& pc, const real& qtapacco);
void inventario_da_terminale();
virtual void on_idle();
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TInventario_ter_msk();
};
//PRECARICA_RIGHE: metodo che carica in un TAssoc_array le righe fisiche del documento
bool TInventario_ter_msk::precarica_righe()
{
//instanzio il documento inventario
TDoc_key kinv(get_int(F_ANNO), ini_get_string(CONFIG_DITTA, "lv", "NUM_INV", NULL), get_long(F_NINV));
TDoc_inventario inv(kinv);
if (inv.empty())
{
warning_box(TR("L'inventario cercato è inesistente"));
return false;
}
//controllo lo stato del documento
const TString4 stato = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_INV", NULL), "S2").mid(2,1);
if (inv.get(DOC_STATO) == stato)
{
TString str;
str << "L'inventario " << get_long(F_NINV) << " è già stato stampato e non può essere aggiornato";
warning_box(str);
reset(F_CHIAVE);
return false;
}
TDate oggi(TODAY);
//metto ogni riga del documento nel TAssoc_array che contiene gli oggetti TPacchi_contati
//e che ha per chiave il codice articolo
FOR_EACH_PHYSICAL_RDOC(inv, i, row)
{
TDoc_inventario_row rinv(*row);
TString80 codart = rinv.codart();
if (codart.blank())
continue;
TPacchi_contati* pc = _ria.quantita(codart, true);
pc->set_qta(rinv.qta());
pc->set_um(rinv.um());
pc->set_npacchi(rinv.num_pacchi());
pc->set_codpacchi(rinv.cod_pacchi());
}
return true;
}
//REGISTRA: metodo che salva il buono di prelievo così com'è
void TInventario_ter_msk::registra()
{
//se sto salvando un documento nuovo, allora lo genero,
//altrimenti aggiorno quello esiete già
TDoc_key kinv(get_date(F_DATAINV).year(), get(F_CODNUM), get_long(F_NINV));
if (_nuovo)
kinv.set_ndoc(0);
//instanzio il documento e salvo i dati di interesse sulle testate
//se necessario
TDoc_inventario inv(kinv);
if(_nuovo)
{
inv.put(DOC_TIPODOC, get(F_TPDOC));
inv.put(DOC_DATADOC, get_date(F_DATAINV));
inv.set_difinv();
}
//per ogni oggetto dell'array cerco o creo una riga merce del documento
FOR_EACH_ASSOC_OBJECT(_ria, obj, key, itm)
{
const TPacchi_contati& pc = *(TPacchi_contati*)itm;
const TString80 codart(key);
const TString& desart = cache().get(LF_ANAMAG, codart, "DESCR");
TString8 magazzino;
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGP");
TDoc_inventario_row& rinv = inv.find_or_create_row(codart);
rinv.set_codart(codart);
rinv.set_desart(desart);
rinv.set_qta(pc.qta());
rinv.set_um(pc.um());
rinv.set_num_pacchi(pc.npacchi());
rinv.set_cod_pacchi(pc.codpacchi());
rinv.set_magazzino(magazzino); //DA CONTROLLARE
rinv.set_magazzinoc(magazzino); //DA CONTROLLARE
}
inv.write();
if(_nuovo)
{
//aggiorno il numero documento con quello sicuramente corretto
TToken_string tmp = inv.chiave();
TDoc_key chiave(tmp);
set(F_NINV, chiave.ndoc());
_nuovo = false;
}
}
//AGGIORNA_CAMPI: metodo che aggiorna i campi della maschera
void TInventario_ter_msk::aggiorna_campi(const char* codart, const TPacchi_contati& pc, const real& qtapacco)
{
set(F_CODART, codart);
set(F_PACCHI, pc.npacchi());
set(F_QTACON, pc.qta());
set(F_QTAPACCO, qtapacco);
}
//INVENTARIO_DA_TERMINALE: metodo che somma alla riga corretta un pacco (quello pistolato) e lo assegna a un cliente,
//sottraendolo dal magazzino del pulito
void TInventario_ter_msk::inventario_da_terminale()
{
//leggo il codice del pacco pistolato
const TString80 codpacco = get(F_BARCODE);
if (codpacco.full())
{
//se posso instanzio la riga pacco
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
{
//leggo i dati di interesse dal pacco
TString80 codart = rp.articolo();
const real qtapacco = rp.quantita();
//se è la prima volta, creo il nuovo TPacchi_contati,
//altrimenti aggiorno quello che già esiste
if(!_ria.is_key(codart))
{
TPacchi_contati& pc = *(_ria.quantita(codart, true));
pc.set_qta(qtapacco);
//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);
pc.set_um(um);
pc.set_npacchi();
key.cut(0);
key.add(codpacco);
pc.set_codpacchi(key);
aggiorna_campi(codart, pc, qtapacco);
}
else
{
TPacchi_contati& pc = *(TPacchi_contati*)_ria.objptr(codart);
TToken_string codpacchi(pc.codpacchi());
int pos = codpacchi.get_pos(codpacco);
if(pos >= 0)
{
if(yesno_box(TR("Il pacco risulta già nell'inventario; si desidera annullarlo?")))
{
pc.add_qta(-qtapacco);
pc.add_pacchi(-1);
pc.sub_codpacco(codpacco);
}
else
return;
}
pc.add_qta(qtapacco);
pc.add_pacchi();
pc.add_codpacco(codpacco);
aggiorna_campi(codart, pc, qtapacco);
}
}
}
}
//ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera
bool TInventario_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_NEWREC:
//se viene premuto nuovo, cerco il prossimo numero di inventario
//e mostro/nascondo i campi corretti
if (e == fe_button)
{
_nuovo = true;
int ninv = 0;
TString query;
query << "USE DOC\n"
<< "FROM PROVV=\"D\" ANNO=" << get_int(F_ANNO) << " CODNUM=\"" << get(F_CODNUM) << "\"\n"
<< "TO PROVV=\"D\" ANNO=" << get_int(F_ANNO) << " CODNUM=\"" << get(F_CODNUM) << "\"";
TISAM_recordset inventari(query);
if (inventari.move_last())
ninv = inventari.get(DOC_NDOC).as_int();
ninv++;
set(F_NINV, ninv); disable(F_NINV);
show(F_BARCODE);
show(F_CODART);
show(F_PACCHI);
show(F_QTAPACCO);
show(F_QTACON);
hide(F_CHIAVE);
hide(F_ANNO);
hide(F_DATAINV);
enable(DLG_SAVEREC);
enable(DLG_DELREC);
enable(DLG_CANCEL);
field(F_BARCODE).set_focus();
_autoselect = 1;
return false;
}
break;
case DLG_SAVEREC:
//se viene premuto salva, registro l'inventario
if (e == fe_button)
{
registra();
return false;
}
break;
case DLG_DELREC:
//se viene premutop cancella, elimino l'inventario corrente, poi mostro/nascondo i campi corretti
if (e == fe_button && yesno_box(TR("Si vuole veramente cancellare l'inventario corrente?")))
{
//se non è nuovo, lo rimuovo anche dagli archivi
if (!_nuovo)
{
TLocalisamfile doc(LF_DOC);
TDoc_key kinv(get_int(F_ANNO), get(F_CODNUM), get_long(F_NINV));
TDoc_inventario inv(kinv);
inv.destroy_rows();
inv.remove(doc);
}
_ria.destroy();
reset(F_BARCODE); hide(F_BARCODE);
reset(F_CODART); hide(F_CODART);
reset(F_PACCHI); hide(F_PACCHI);
reset(F_QTAPACCO); hide(F_QTAPACCO);
reset(F_QTACON); hide(F_QTACON);
enable(F_NINV); reset(F_NINV);
show(F_CHIAVE); reset(F_CHIAVE);
show(F_ANNO);
show(F_DATAINV); reset(F_DATAINV);
disable(DLG_SAVEREC);
disable(DLG_DELREC);
disable(DLG_CANCEL);
}
break;
case DLG_CANCEL:
//se viene premuto annulla, lascio perdere quello che stavo facendo
//e torno alla situazione iniziale
if (e == fe_button)
{
reset(F_BARCODE); hide(F_BARCODE);
reset(F_CODART); hide(F_CODART);
reset(F_PACCHI); hide(F_PACCHI);
reset(F_QTAPACCO); hide(F_QTAPACCO);
reset(F_QTACON); hide(F_QTACON);
enable(F_NINV); reset(F_NINV);
show(F_CHIAVE); reset(F_CHIAVE);
show(F_ANNO);
show(F_DATAINV); reset(F_DATAINV);
disable(DLG_SAVEREC);
disable(DLG_DELREC);
disable(DLG_CANCEL);
_ria.destroy();
return false;
}
break;
case F_CHIAVE:
{
//se viene riempito il campo chiave, cerca di caricare un documento
if (e == fe_modify)
{
TString kinv = f.get();
if (kinv.full())
{
set(F_ANNO, atol(kinv.left(4)));
set(F_NINV, atol(kinv.mid(4)));
field(F_NINV).check();
if(!precarica_righe())
return false;
hide(F_ANNO);
hide(F_DATAINV);
show(F_BARCODE);
show(F_CODART);
show(F_PACCHI);
show(F_QTAPACCO);
show(F_QTACON);
enable(DLG_SAVEREC);
enable(DLG_DELREC);
enable(DLG_CANCEL);
disable(F_NINV);
_autoselect = 1;
field(F_BARCODE).set_focus();
f.hide();
}
}
}
break;
case F_NINV:
{
//se viene riempito il campo NINV, cerca di caricare un documento
if (e == fe_modify && f.get_long() != 0 && get(F_CHIAVE).empty())
{
field(F_NINV).check();
_nuovo = false;
if(!precarica_righe())
return false;
hide(F_ANNO);
hide(F_DATAINV);
show(F_BARCODE);
show(F_CODART);
show(F_PACCHI);
show(F_QTAPACCO);
show(F_QTACON);
enable(DLG_SAVEREC);
enable(DLG_DELREC);
enable(DLG_CANCEL);
f.disable();
_autoselect = 1;
field(F_BARCODE).set_focus();
}
}
break;
case F_BARCODE:
{
//se viene riempito il campo barcode, lanco la procedura dell'inventario
if (e == fe_modify && f.get().full())
{
_autoselect = 1;
inventario_da_terminale();
}
}
break;
default:break;
}
return true;
}
void TInventario_ter_msk:: on_idle()
{
TMask::on_idle();
if (_autoselect >= 0 && get(F_BARCODE).full())
{
reset(F_BARCODE);
field(F_BARCODE).set_focus();
_autoselect = -1;
}
}
TInventario_ter_msk::TInventario_ter_msk():TAutomask("lv3700a")
{
//precarico i campi fissi
set(F_CODNUM, ini_get_string(CONFIG_DITTA, "lv", "NUM_INV", NULL));
set(F_TPDOC, ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_INV", NULL));
const TRectype& tpdoc = cache().get("%NUM", ini_get_string(CONFIG_DITTA, "lv", "NUM_INV", NULL));
set(F_DESCR, tpdoc.get("S0"));
TDate data(TODAY);
TEsercizi_contabili es;
int annoes = es.date2esc(data);
set(F_ANNO, annoes);
hide(F_CODCF);
hide(F_RAGSOC);
hide(F_BARCODE);
hide(F_CODART);
hide(F_PACCHI);
hide(F_QTAPACCO);
hide(F_QTACON);
disable(DLG_SAVEREC);
disable(DLG_DELREC);
disable(DLG_CANCEL);
}
///////////////////////////////////
//// TINVENTARIO_TER_APP ////
///////////////////////////////////
//classe TInventario_ter_app
class TInventario_ter_app : public TSkeleton_application
{
TInventario_ter_msk* _msk;
protected:
virtual bool create();
virtual bool destroy();
public:
bool transfer();
virtual void main_loop();
};
//CREATE: metodo costruttore
bool TInventario_ter_app::create()
{
_msk = new TInventario_ter_msk();
open_files(LF_DOC, LF_RIGHEDOC);
return TSkeleton_application::create();
}
//DESTROY: metodo distruttore
bool TInventario_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 TInventario_ter_app::transfer()
{
return true;
}
void TInventario_ter_app::main_loop()
{
while (_msk->run() == K_ENTER)
transfer();
}
int lv3700(int argc, char *argv[])
{
TInventario_ter_app a;
a.run (argc, argv, "Evasione Buoni di Prelievo");
return TRUE;
}