campo-sirio/lv/lv3700.cpp

667 lines
17 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include "lvlib.h"
#include "lv3700a.h"
///////////////////////////////
//// 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<69> 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<69>
void TPacchi_contati::set_qta(const real& qta)
{
_qta = qta;
}
//SET_UM: metodo che setta l'unit<69> 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<69> 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<69> 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);
TLocalisamfile fdoc(LF_DOC);
int err = inv.read(fdoc, _isequal, _testandlock);
if(err != NOERR)
{
warning_box(TR("L'inventario gi<67> in uso"));
return false;
}
if (inv.empty())
{
warning_box(TR("L'inventario cercato <20> 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) << " <20> gi<67> stato stampato e non pu<70> 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<6F> com'<27>
void TInventario_ter_msk::registra()
{
//se sto salvando un documento nuovo, allora lo genero,
//altrimenti aggiorno quello esiete gi<67>
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)
{
TString8 codcau = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_INV", NULL), "S9");
inv.put(DOC_TIPODOC, get(F_TPDOC));
inv.put(DOC_DATADOC, get_date(F_DATAINV));
inv.put(DOC_CAUSMAG, codcau);
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 <20> stato possibile sommare il pacco a nessuna riga del buono"));
}
else
{
//leggo i dati di interesse dal pacco
if(rp.is_associato())
{
warning_box(TR("Il pacco pistolato <20> un pacco a cliente"));
return;
}
TToken_string tmp = rp.rigabolla();
if(tmp.get_long(3) > 0)
{
warning_box(TR("Il pacco pistolato <20> gi<67> associato a un buono"));
return;
}
TString80 codart = rp.articolo();
const real qtapacco = rp.quantita();
//se <20> la prima volta, creo il nuovo TPacchi_contati,
//altrimenti aggiorno quello che gi<67> esiste
if(!_ria.is_key(codart))
{
TPacchi_contati& pc = *(_ria.quantita(codart, true));
pc.set_qta(qtapacco);
//recupero l'unit<69> 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<67> 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 <20> 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)
{
TDoc_key kinv(get_int(F_ANNO), ini_get_string(CONFIG_DITTA, "lv", "NUM_INV", NULL), get_long(F_NINV));
TDoc_inventario inv(kinv);
TLocalisamfile fdoc(LF_DOC);
inv.read(fdoc);
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;
}