campo-sirio/lv/lv2900.cpp

1047 lines
29 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <utility.h>
#include "lvlib.h"
#include "lvcondv.h"
#include "lvrcondv.h"
#include "lvrconsplan.h"
#include "../mg/clifogiac.h"
#include "../ve/pacchi.h"
#include "lv2900a.h"
///////////////////////////
//// TRIGA_PACCO ////
///////////////////////////
//classe TRiga_pacco
class TRiga_pacco: public TRectype
{
public:
TRiga_pacco & operator =(const TRiga_pacco& rpacco);
bool read(const TString& codpacco, const long codriga = 1);
const TString& codpacco() const;
const TToken_string& key() const;
const TString& articolo() const;
const real quantita() const;
const TString& um() const;
const TDate data() const;
const long cliente() const;
const TDate databo() const;
const bool annullato() const;
const TToken_string& rigabolla() const;
const long movmag() const;
void set_key(const char* codpacco, const int codriga = 1);
void set_articolo(const char* codart);
void set_quantita(const real qta);
void set_um(const char* um);
void set_data(const TDate& data);
void set_cliente(const long codcf);
void set_databo(const TDate& data);
void set_annullato(const bool ann);
void set_rigabolla(const int anno, const char* codnum, const long ndoc, const long idriga);
void set_movmag(const long movmag);
bool is_annullato();
bool is_associato();
TRiga_pacco(const TRectype& rec);
TRiga_pacco(const TRiga_pacco& rpacco);
TRiga_pacco(const char* codpacco, const long codriga = 1);
TRiga_pacco();
};
//READ: cerca una riga pacco in base alla chiave primaria
bool TRiga_pacco::read(const TString& codpacco, const long codriga)
{
if (codpacco.full()) // Campo obbligatorio!
{
TString80 key; key.format("%s|%ld", codpacco, codriga);
*((TRectype*)this) = cache().get(LF_PACCHI, key);
}
else
zero();
return ok();
}
//CODPACCO: metodo che restituisce il codice univoco del pacco
const TString& TRiga_pacco::codpacco() const
{
return get(PACCHI_CODPACCO);
}
//KEY: metodo che restiuisce la chiave univoca del record analizzato (per le lavanderie CODRIGA sempre 1)
const TToken_string& TRiga_pacco::key() const
{
TToken_string& k = get_tmp_string();
k.add(get(PACCHI_CODPACCO));
k.add(get(PACCHI_CODRIGA));
return k;
}
//ARTICOLO: metodo che restituisce il codice articolo specificato in questa riga
const TString& TRiga_pacco::articolo() const
{
return get(PACCHI_CODART);
}
//QUANTITA: metodo che restituisce il numero dei pezzi nella confezione
const real TRiga_pacco::quantita() const
{
return get_real(PACCHI_QTA);
}
//UM: metodo che restituisce l'unit<69> di misura
const TString& TRiga_pacco::um() const
{
return get(PACCHI_UM);
}
//DATA: metodo che restituisce la data in cui il pacco <20> creato
const TDate TRiga_pacco::data() const
{
return get_date(PACCHI_DATA);
}
//CLIENTE; metodo che restituisce il codice del cliente a cui <20> stato assegnato il pacco
const long TRiga_pacco::cliente() const
{
return get_long(PACCHI_CODCF);
}
//DATA: metodo che restituisce la data in cui il pacco <20> stato assegnato a qualcuno
const TDate TRiga_pacco::databo() const
{
return get_date(PACCHI_DATABO);
}
//ANNULLATO: metodo che ritorna true se il pacco <20> stato annullato
const bool TRiga_pacco::annullato() const
{
return get_bool(PACCHI_ANNULLATO);
}
//RIGABOLLA: metodo che restituisce una TToken_string contenete alla riga del documento che ha consegnato il pacco
const TToken_string& TRiga_pacco::rigabolla() const
{
TToken_string& bolla = get_tmp_string();
bolla.add(get_char(PACCHI_PROVV));
bolla.add(get_int(PACCHI_ANNO));
bolla.add(get(PACCHI_CODNUM));
bolla.add(get_int(PACCHI_NDOC));
bolla.add(get_int(PACCHI_IDRIGA));
return bolla;
}
//MOVMAG: metodo che restituisce i riferimenti al movimento di magazzino generato dal pacco
const long TRiga_pacco::movmag() const
{
return get_long(PACCHI_MGNUMREG);
}
//SET_KEY: metodo che setta la chiave (da usare su un TRiga_pacco vuota)
void TRiga_pacco::set_key(const char* codpacco, const int codriga)
{
put(PACCHI_CODPACCO, codpacco);
put(PACCHI_CODRIGA, codriga);
}
//SET_ARTICOLO: metodo che setta il codice articolo sul record corrente
void TRiga_pacco::set_articolo(const char* codart)
{
put(PACCHI_CODART, codart);
}
//SET_QUANTITA: metodo che setta la quantita sul record corrente
void TRiga_pacco::set_quantita(const real qta)
{
put(PACCHI_QTA, qta);
}
//SET_UM: metodo che setta l'unit<69> di misura
void TRiga_pacco::set_um(const char* um)
{
put(PACCHI_UM, um);
}
//SET_DATA: metodo che setta la data di creazione del record corrente
void TRiga_pacco::set_data(const TDate& data)
{
put(PACCHI_DATA, data);
}
//SET_CLIENTE: metodo che setta il codice cliente sul record corrente
void TRiga_pacco::set_cliente(const long codcf)
{
put(PACCHI_CODCF, codcf);
}
//SET_DATA: metodo che setta la data di evasione sul record corrente
void TRiga_pacco::set_databo(const TDate& data)
{
put(PACCHI_DATABO, data);
}
//SET_ANNULLATO: metodo che setta il flag di annullato
void TRiga_pacco::set_annullato(const bool ann)
{
put(PACCHI_ANNULLATO, ann);
}
//SET_RIGABOLLA: metodo che setta i riferimenti alla riga di bolla che evade il pacco sul record corrente
void TRiga_pacco::set_rigabolla(const int anno, const char* codnum, const long ndoc, const long idriga)
{
put(PACCHI_PROVV, 'D');
put(PACCHI_ANNO, anno);
put(PACCHI_CODNUM, codnum);
put(PACCHI_NDOC, ndoc);
put(PACCHI_IDRIGA, idriga);
}
//SET_MOVMAG: metodo che setta il movimento di magazzino generato dal pacco
void TRiga_pacco::set_movmag(const long movmag)
{
put(PACCHI_MGNUMREG, movmag);
}
//IS_ANNULATO: metodo che restituisce "true" se il campo annullato sul record attuale <20> 'S'
bool TRiga_pacco::is_annullato()
{
return get_bool(PACCHI_ANNULLATO);
}
//IS_ASSOCIATO: metodo che restitusce "true" se il campo cliente <20> valorizzato
bool TRiga_pacco::is_associato()
{
return get_int(PACCHI_CODCF) && 1;
}
//Metodi costruttori
TRiga_pacco::TRiga_pacco(const TRectype& rec)
: TRectype(rec)
{
}
TRiga_pacco::TRiga_pacco(const TRiga_pacco& rpacco)
: TRectype(rpacco)
{
}
TRiga_pacco::TRiga_pacco(const char* codpacco, const long codriga)
: TRectype(LF_PACCHI)
{
read(codpacco, codriga);
}
TRiga_pacco::TRiga_pacco()
: TRectype(LF_PACCHI)
{
zero();
}
////////////////////////
//// TDOC_KEY ////
////////////////////////
//classe TDoc_key
class TDoc_key: public TToken_string
{
public:
const char provv();
const int anno();
const char* codnum();
const long ndoc();
TDoc_key(const int anno, const TString& codnum, const long ndoc, const char provv = 'D');
TDoc_key(const char* key);
};
//CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti
const char TDoc_key::provv()
{
return get(0)[0];
}
//ANNO: metodo che restituisce l'anno dalla TToken_string chiave dei documenti
const int TDoc_key::anno()
{
return get_int(1);
}
//CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti
const char* TDoc_key::codnum()
{
return get(2);
}
//NDOC: metodo che restituisce il numero documento dalla TToken_string chiave dei documenti
const long TDoc_key::ndoc()
{
return get_int(3);
}
//metodi costruttori
TDoc_key::TDoc_key(const int anno, const TString& codnum, const long ndoc, const char provv)
{
add(provv);
add(anno);
add(codnum);
add(ndoc);
}
TDoc_key::TDoc_key(const char* key):TToken_string(key)
{
}
////////////////////////////
//// TBUONI_CACHE ////
////////////////////////////
//classe TBuoni_cache
class TBuoni_cache : public TCache
{
TString4 _codnum, _tipodoc, _stato;
long _ndoc;
protected:
virtual void discarding(const THash_object* obj);
virtual TObject* key2obj(const char* key);
public:
TDocumento& doc(const TDate& gg, const long cc);
TBuoni_cache();
};
//DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache
void TBuoni_cache::discarding(const THash_object* obj)
{
TDocumento& doc = (TDocumento&)obj->obj();
int err = doc.rewrite();
}
//KEY2OBJ: metodo che sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'<27>
TObject* TBuoni_cache::key2obj(const char* key)
{
TToken_string chiave(key);
TDate datadoc = chiave.get();
const TDate datagen(TODAY);
TDate dadata = datadoc;
TDate adata = datagen;
adata.addmonth();
const long codcf = chiave.get_long();
if(_ndoc == 0)
{
TString query2;
query2 << "USE DOC\n"
<< "FROM PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\"\n"
<< "TO PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\"";
TISAM_recordset sporco(query2);
sporco.move_last();
_ndoc = sporco.get(DOC_NDOC).as_int();
}
TString query = "USE DOC KEY 2\n";
query << "SELECT (TIPODOC=\"" << _tipodoc << "\")&&(STATO=\"" << _stato <<"\")\n";
query << "FROM TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n";
query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n";
TISAM_recordset rset(query);
TDocumento* doc = NULL;
if (rset.move_first())
doc = new TDocumento(rset.cursor()->curr());
else
{
TLaundry_contract cont(codcf, 0, datadoc);
const TString8 codcont = cont.get(LVCONDV_CODCONT);
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();
doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc);
doc->put(DOC_TIPODOC, _tipodoc);
doc->put(DOC_STATO, _stato);
doc->put(DOC_DATADOC, datadoc);
doc->put(DOC_TIPOCF, 'C');
doc->put(DOC_CODCF, codcf);
doc->put(DOC_CODCONT, codcont);
doc->put("DATACON", datadoc); //data conteggio
doc->put("DATAGEN", datagen); //data generazione del documento
doc->put("DATAPRCO", dataprco); //data prevista consegna
doc->put("CODITI", coditi); //codice itinerario
}
return doc;
}
//DOC: metodo che restituisce un puntatore ad un documento identificato dalla coppia data - cliente
TDocumento& TBuoni_cache::doc(const TDate& gg, const long cc)
{
TString16 key;
key << gg.date2ansi() << '|' << cc;
return *(TDocumento*)objptr(key);
}
//metodo costruttore di una cache di 17 elementi
TBuoni_cache::TBuoni_cache() : TCache(17)
{
_codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN");
_tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN");
_stato = cache().get("%TIP", _tipodoc, "S2").left(1);
_ndoc = 0;
}
/////////////////////////////////
//// TCONTA_PULITO_MSK ////
/////////////////////////////////
//classe TConta_pulito_msk
class TConta_pulito_msk: public TAutomask
{
TString4 _auto;
TString4 _giri;
bool _percli;
bool _permag;
long _codcf;
TString4 _print;
protected:
virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly);
bool elabora_file(const TFilename& file);
void sposta_file(const TFilename& file);
bool genera_documenti(const TFilename& file, TAssoc_array& documenti);
void prepara_movimenti(const TFilename& file, TAssoc_array& movimenti);
bool genera_movmag(TAssoc_array& movimenti);
public:
TConta_pulito_msk();
};
//ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera
bool TConta_pulito_msk::on_field_event(TOperable_field& f,TField_event e,long jolly)
{
//prendo il path dalla maschera
const TString& path = get(F_PATH);
const TString& fname = get(F_FNAME);
TFilename file = path;
file.add(fname);
TAssoc_array documenti;
TAssoc_array movimenti;
//a seconda del bottone premuto esegui un metodo diverso
switch (f.dlg())
{
case DLG_IMPORT:
if(e == fe_button)
{
if (elabora_file(file))
{
sposta_file(file);
message_box(TR("Importazione dei dati terminata"));
}
}
break;
case DLG_PACKTCLI:
if(e == fe_button)
{
genera_documenti(file, documenti);
if (documenti.items() > 0)
{
//capisci se devi stampare dalla maschera se non <20> stato lanciato da linea di comando
char print = _print[0];
if (_print.empty())
print = get_bool(F_STAMPA) ? 'S' : 'N';
if (print == 'S')
{
//preparo il pezzo fisso della linea di comando per richiamare la stampa dei documenti
TDoc_key kd(documenti.get_hashobj()->key());
const TString4 codnum = kd.codnum();
const int anno = kd.anno();
const char provv = kd.provv();
//lancia la stampa dei documenti ve1 -2 per ogni documento preparato
TString str;
str << "ve1 -2 " << codnum << ' ' << anno << ' ' << provv << ' ';
FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm)
{
TDoc_key kdoc(key);
const int ndoc = kdoc.ndoc();
str.cut(18);
str << ndoc << ' ' << ndoc << " S";
TExternal_app stampa(str);
}
}
message_box(TR("Generazione dei documenti terminata"));
}
else
message_box(TR("Non <20> stato possibile generare nessun documento con i parametri fissati"));
}
break;
case DLG_PACKTMAG:
if(e == fe_button)
{
prepara_movimenti(file, movimenti);
if (genera_movmag(movimenti))
message_box(TR("Generazione dei movimenti di magazzino terminata terminata"));
}
break;
default: break;
}
return true;
}
//ELABORA_FILE: metodo che importa il file e prepara la tabella pacchi
bool TConta_pulito_msk::elabora_file(const TFilename& file)
{
if (!file.exist())
{
warning_box(TR("ATTENZIONE: il file che si desidera importare non esiste!"));
return false;
}
TBaseisamfile f(LF_PACCHI);
TScanner s(file);
while (s.ok())
{
TString riga = s.line();
if (riga.blank())
continue;
TRiga_pacco* rp = new TRiga_pacco();
rp->set_key(riga.left(50));
rp->set_articolo(riga.mid(50, 20));
rp->set_quantita(atoi(riga.mid(70, 8)));
rp->set_data((TDate)riga.mid(78, 8));
int codcf = atoi(riga.mid(86, 6));
if(codcf > 0)
{
rp->set_cliente(codcf); //eventualmente vuoto
rp->set_databo((TDate)riga.mid(92, 8)); //eventualmente vuoto
}
const bool ann = riga.mid(100, 1) == 'S' ? true : false;
rp->set_annullato(ann);
//recupero l'unit<69> di misura principale di quest'articolo
TToken_string key;
key.add(riga.mid(50, 20));
key.add(1);
const TRectype& umart = cache().get(LF_UMART, key);
TString4 um = umart.get(UMART_UM);
rp->set_um(um);
rp->write(f);
}
return true;
}
//SPOSTA_FILE: metodo che sposta il file elaborato in una sottocartella e gli cambia nome
//aggiungendo data e ora dell'elaborazione
void TConta_pulito_msk::sposta_file(const TFilename& file)
{
TFilename fileori = file;
TFilename path = fileori.path();
path.add("elaborati");
make_dir(path);
TString strname;
strname.format("%06d_%06d_%s", TDate(TODAY).date2ansi(), daytime(), (const char*)fileori.name());
TFilename filedest = path;
filedest.add(strname);
if (fcopy(fileori, filedest))
fileori.fremove();
}
//GENERA_DOCUMENTI: metodo che genera i documenti partendo dal file pacchi
bool TConta_pulito_msk::genera_documenti(const TFilename& file, TAssoc_array& documenti)
{
//se esite un file da importare, lo importo e lo sposto
if (file.exist())
{
elabora_file(file);
sposta_file(file);
}
TBuoni_cache ca;
//inizializzo le variabili di interesse
TDate dadata(TODAY);
TDate adata(TODAY);
long codcf = _codcf;
//se non l'ho lanciato da linea di comando, inizializzo le variabili
//ai dati presi dalla maschera
if (_auto != 'A')
{
dadata = get_date(F_DADATA);
adata = get_date(F_ADATA);
codcf = get_long(F_CODCF);
}
//seleziona tutti i record del file pacchi da data a data e eventualmente filtrati per cliente
//che risultano associati a un cliente ma che non hanno una bolla associata
TString query;
query << "USE PACCHI KEY 2\n";
query << "SELECT NDOC=0\n";
query << "FROM DATA=#DADATA";
if (codcf > 0)
query << " CODCF=" << codcf;
query << "\n";
query << "TO DATA=#ADATA";
if (codcf > 0)
query << " CODCF=" << codcf;
TISAM_recordset selrighe(query);
selrighe.set_var("#DADATA", dadata);
selrighe.set_var("#ADATA", adata);
selrighe.move_first();
TLocalisamfile& pacchi = selrighe.cursor()->file();
//scorro tutti i pacchi trovati
for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next())
{
TRiga_pacco rp = selrighe.cursor()->curr();
//se il pacco risulta annullato, lo elimino
if(rp.is_annullato())
{
rp.remove(pacchi);
continue;
}
//recupero i dati di interesse dal pacco
const long codcf = rp.cliente();
const TDate datadoc = rp.databo();
const TString& codart = rp.articolo();
const real quantita = rp.quantita();
//instanzio un contratto e la corrispondente riga contratto per l'articolo che sto analizzando
TLaundry_contract cont(codcf, 0, datadoc);
const TRectype rcont = cont.row(codart);
bool dtmp = false;
if (datadoc >= rcont.get_date(LVRCONDV_INDTTMP) && datadoc <= rcont.get_date(LVRCONDV_FIDTTMP))
dtmp = true;
//leggo la causale (quella su contratto ha precedenza)
TString4 causale = rcont.get(LVRCONDV_CAUSLAV);
if (causale.blank() || atoi(causale) == 0)
causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV");
//leggo se devo scrivere il prezzo sulla bolla
const bool prinbo = cont.get_bool(LVCONDV_STPRZBOL);
//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 TString80 descr = anamag.get(ANAMAG_DESCR);
//recupero i valori delle dotazione temporanea dal magazzino del cliente
TLocalisamfile magcli(LF_CLIFOGIAC);
magcli.put(CLIFOGIAC_ANNOES, datadoc.year());
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, codcf);
magcli.put(CLIFOGIAC_INDSPED, 0); //in realt<6C> <20> da leggere dal contratto
magcli.put(CLIFOGIAC_CODART, codart);
magcli.put(CLIFOGIAC_NRIGA, 1);
//leggo il record corrispondente
magcli.read();
long dottmp = magcli.get_long(CLIFOGIAC_DOTTM);
long dotod = magcli.get_long(CLIFOGIAC_DOTOD);
//preparo il documento
TDocumento& doc = ca.doc(datadoc, codcf);
//tengo traccia di tutti i documenti che sto generando
TDoc_key kdoc(doc.get_int(DOC_ANNO), doc.get(DOC_CODNUM), doc.get_int(DOC_NDOC));
if (!documenti.is_key(kdoc))
documenti.add(kdoc, kdoc);
//azzero coditi e metto dataprco alla datadoc se non sto generando per giri
if(!_giri || !get_bool(F_GIRI))
{
doc.put("DATAPRCO", datadoc);
doc.put("CODITI", 0);
}
bool found = false;
//cerco eventualmente una riga documento che contiene gi<67> questo articolo;
//se la trovo sommo le quantit<69>, altrimento preparo una riga nuova
for (int i = 0; i <= doc.rows(); i++)
{
TRiga_documento& rdoc = doc[i];
if(codart == rdoc.get(RDOC_CODART))
{
rdoc.add(RDOC_QTA, quantita);
rdoc.add(RDOC_QTAGG1, quantita);
rdoc.add("DOTOD", quantita);
if(dtmp)
rdoc.add("DOTMP", quantita);
found = true;
//scrivo i riferimenti alla bolla sul pacco
rp.set_rigabolla(datadoc.year(), doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC), i);
rp.rewrite(pacchi);
}
}
if(!found)
{
TRiga_documento& rdoc = doc.new_row("21");
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, quantita);
rdoc.put(RDOC_QTAGG1, quantita);
rdoc.put("DOTOD", dotod);
rdoc.add("DOTOD", quantita);
if(dtmp)
{
rdoc.put("DOTMP", dottmp);
rdoc.add("DOTMP", quantita);
}
rdoc.put(RDOC_CODAGG1, causale);
//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,rcont.get_real(LVRCONDV_PRZDTTMP));
rdoc.put(RDOC_SCONTO,rcont.get(LVRCONDV_SCONTPERC)); //sconto
}
//scrivo il magazzino
TString8 magazzino;
TString8 magazzinoc;
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN");
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);
//scrivo i riferimenti alla bolla sul pacco
rp.set_rigabolla(datadoc.year(), doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC), doc.rows() + 1);
rp.rewrite(pacchi);
}
}
ca.destroy();
return true;
}
//PREPARA_MOVIMENTI: questo metodo prepara il TAssoc_array che contiene i movimenti da generare
void TConta_pulito_msk::prepara_movimenti(const TFilename& file, TAssoc_array& movimenti)
{
//se esite un file da importare, lo importo e lo sposto
if (file.exist())
{
elabora_file(file);
sposta_file(file);
}
//inizializzo le variabili di interesse
TDate dadata(TODAY);
TDate adata(TODAY);
long codcf = _codcf;
//se non ho lanciato il programma da linea di comando, leggo i paramtri dalla maschera
if (_auto != 'A')
{
dadata = get_date(F_DADATA);
adata = get_date(F_ADATA);
codcf = get_long(F_CODCF);
}
//seleziona tutti i record del file pacchi da data a data che non hanno una bolla associata
TString query;
query << "USE PACCHI KEY 2\n";
query << "SELECT NDOC=0\n";
query << "FROM DATABO=#DADATA\n";
query << "TO DATABO=#ADATA";
TISAM_recordset selrighe(query);
selrighe.set_var("#DADATA", dadata);
selrighe.set_var("#ADATA", adata);
selrighe.move_first();
TLocalisamfile& pacchi = selrighe.cursor()->file();
//scorro tutti i pacchi trovato
for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next())
{
TRiga_pacco rp = selrighe.cursor()->curr();
//se il pacco risulta annullato, lo elimino
if(rp.is_annullato())
{
rp.remove(pacchi);
continue;
}
//recupero i dati di interesse dalla riga pacchi
const real quantita = rp.quantita();
const TString80 codart = rp.articolo();
TString8 ansidate;
ansidate << rp.data().date2ansi();
//preparo un TAssoc_array di TAssoc_array;
//il primo ha per chiave la data (in ansi) e come contenuto un TAssoc_array degli articoli
//il secondo ha per chiave il codart e come contenuto le quantit<69>
TAssoc_array* articoli = (TAssoc_array*)movimenti.objptr(ansidate);
if(articoli == NULL)
{
articoli = new TAssoc_array();
movimenti.add(ansidate, articoli);
}
if(articoli->is_key(codart))
{
real& qta = *(real*)articoli->objptr(codart);
qta += quantita;
}
else
articoli->add(codart, quantita);
}
}
//GENERA_MOVMAG: metodo che genera i movimenti di magazzino dai pacchi
bool TConta_pulito_msk::genera_movmag(TAssoc_array& movimenti)
{
const TString4 causale = ini_get_string(CONFIG_DITTA, "lv", "CAUCARPA");
TString8 magazzino;
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGP");
//cerco l'ultimo numero di chiave in movmag
TISAM_recordset mov("USE MOVMAG");
long nummov = 0;
if(!mov.move_first())
nummov += mov.get(MOVMAG_NUMREG).as_int();
TLocalisamfile movi(LF_MOVMAG);
//per ogni oggetto salvato in movimenti, creo un movimento di magazzino
FOR_EACH_ASSOC_OBJECT(movimenti, hobj, ansidate, obj)
{
TEsercizi_contabili es;
TDate data = (TDate)ansidate;
int annoes = es.date2esc(data);
TMov_mag movmag(++nummov);
movmag.put(MOVMAG_ANNOES, annoes);
movmag.put(MOVMAG_DATAREG, data);
TAssoc_array& articoli = *(TAssoc_array*)obj;
//per ogni articolo contenuto nel secondo TAssoc_array, faccio una riga movimento di magazzino
FOR_EACH_ASSOC_OBJECT(articoli, hobj1, codart, qta)
{
//recupero l'unit<69> di misura principale di quest'articolo
TToken_string key;
key.add(codart);
key.add(1);
const TRectype& umart = cache().get(LF_UMART, key);
TString4 um = umart.get(UMART_UM);
const real& quantita = *(real*)qta;
//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_CODCAUS, causale);
rmovmag.put(RMOVMAG_UM, um);
rmovmag.put(RMOVMAG_QUANT, quantita);
}
movmag.write(movi);
}
return true;
}
//metodo costruttore che precarica i campi di interesse sulla maschera
TConta_pulito_msk::TConta_pulito_msk():TAutomask("lv2900a")
{
TConfig configlv(CONFIG_DITTA, "lv");
const TString& path = configlv.get("PathPulito");
const TString& file = configlv.get("FilePulito");
set(F_PATH, path);
set(F_FNAME, file);
//se ho pi<70> di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto
if (main_app().argc() > 2)
{
_auto = main_app().argv(2);
_auto = _auto.right(1);
TString16 tmp = main_app().argv(3);
if (tmp.left(2) == "-C")
{
_percli = true;
if (tmp.len() > 2)
_codcf = atoi(tmp.sub(2));
else
_codcf = 0;
_permag = false;
}
else
{
_percli = false;
_permag = true;
}
_giri = main_app().argv(4);
_giri = _giri.right(1);
_print = main_app().argv(5);
_print = _print.right(1);
}
else
{
_auto = "N";
_percli = false;
_permag = false;
_codcf = 0;
_giri = "";
_print = "";
}
}
/////////////////////////////////
//// TCONTA_PULITO_APP ////
/////////////////////////////////
//classe TConta_pulito_app
class TConta_pulito_app : public TSkeleton_application
{
TConta_pulito_msk* _msk;
TString4 _auto;
char _cliormag;
protected:
virtual bool create();
virtual bool destroy();
public:
bool transfer();
virtual void main_loop();
};
//CREATE: metodo costruttore
bool TConta_pulito_app::create()
{
_msk = new TConta_pulito_msk();
//se ho pi<70> di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto
if (argc() > 2)
{
_auto = argv(2);
_auto = _auto.right(1);
TString16 tmp = argv(3);
char c = tmp.mid(1,1)[0];
switch (c)
{
case 'C': _cliormag = 'C'; break;
case 'M': _cliormag = 'M'; break;
case 'I': _cliormag = 'I'; break;
default: break;
}
}
else
{
_auto = "";
_cliormag = ' ';
}
open_files(LF_DOC, LF_RIGHEDOC);
return TSkeleton_application::create();
}
//DESTROY: metodo distruttore
bool TConta_pulito_app::destroy()
{
delete _msk;
return TApplication::destroy();
}
//TRANSFER: metodo che decide cosa effettivamente far fare al programma a seconda delle indicazioni ricevute
bool TConta_pulito_app::transfer()
{
return true;
}
void TConta_pulito_app::main_loop()
{
//lo lancio in automatico da linea di comando
if (_auto == "A")
switch(_cliormag)
{
case 'C': _msk->send_key(K_SPACE, DLG_PACKTCLI); break;
case 'M': _msk->send_key(K_SPACE, DLG_PACKTMAG); break;
case 'I': _msk->send_key(K_SPACE, DLG_IMPORT); break;
default: break;
}
while (_msk->run() == K_ENTER)
transfer();
}
int lv2900(int argc, char *argv[])
{
TConta_pulito_app a;
a.run (argc, argv, "Elaborazioni pulito");
return TRUE;
}