215ba5dafc
Files correlati : lvmenu lv2 Ricompilazione Demo : [ ] Commento : Aggiunta la chiamata a menu del programma di importazione del pulito Corretta la chiamata a ve1 per las stampa dei documenti git-svn-id: svn://10.65.10.50/trunk@19428 c028cbd2-c16b-5b4b-a496-9718f37d4682
1047 lines
29 KiB
C++
Executable File
1047 lines
29 KiB
C++
Executable File
#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;
|
||
}
|