From bed115929678f089d5c8d782b93cc3b80d6d9456 Mon Sep 17 00:00:00 2001 From: luca83 Date: Tue, 13 Oct 2009 11:01:47 +0000 Subject: [PATCH] Patch level : 10.0 patch 466 Files correlati : lv2 Ricompilazione Demo : [ ] Commento : Aggiunto il programma di conta del pulito (pacchi) git-svn-id: svn://10.65.10.50/trunk@19419 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- lv/lv2.cpp | 19 +- lv/lv2.h | 9 +- lv/lv2900.cpp | 1052 ++++++++++++++++++++++++++++++++++++++++++++++++ lv/lv2900a.h | 10 + lv/lv2900a.uml | 112 ++++++ 5 files changed, 1189 insertions(+), 13 deletions(-) create mode 100755 lv/lv2900.cpp create mode 100755 lv/lv2900a.h create mode 100755 lv/lv2900a.uml diff --git a/lv/lv2.cpp b/lv/lv2.cpp index 262af3aa3..b52836cf3 100755 --- a/lv/lv2.cpp +++ b/lv/lv2.cpp @@ -7,15 +7,16 @@ int main(int argc, char** argv) const int r = (argc > 1) ? argv[1][1] - '0' : 0; switch (r) { - case 0: lv2100(argc, argv); break; //generazione automatica del planning - case 1: lv2200(argc, argv); break; //manipolazione e stampa del planning - case 2: lv2300(argc, argv); break; //Stampa Giri Giornaliero/Settimanale - case 3: lv2400(argc, argv); break; //generazione automatica bolle di consegna - case 4: lv2500(argc, argv); break; //fatturazione - case 5: lv2600(argc, argv); break; //acquisizione bolle di rientro - case 6: lv2700(argc, argv); break; //Riepilogo Bolle di Lavanderie - case 7: lv2800(argc, argv); break; //Venduto Per Cliente nei 12 Mesi - default: lv2100(argc, argv); break; //generazione automatica del planning + case 0: lv2100(argc, argv); break; //generazione automatica del planning + case 1: lv2200(argc, argv); break; //manipolazione e stampa del planning + case 2: lv2300(argc, argv); break; //Stampa Giri Giornaliero/Settimanale + case 3: lv2400(argc, argv); break; //generazione automatica bolle di consegna + case 4: lv2500(argc, argv); break; //fatturazione + case 5: lv2600(argc, argv); break; //acquisizione da contapezzi + case 6: lv2700(argc, argv); break; //Riepilogo Bolle di Lavanderie + case 7: lv2800(argc, argv); break; //Venduto Per Cliente nei 12 Mesi + case 8: lv2900(argc, argv); break; //acquisizione del pulito + default: lv2100(argc, argv); break; //generazione automatica del planning } return 0; } \ No newline at end of file diff --git a/lv/lv2.h b/lv/lv2.h index 6fbcd1005..1d5e2f1d7 100755 --- a/lv/lv2.h +++ b/lv/lv2.h @@ -3,11 +3,12 @@ int lv2100(int argc, char* argv[]); int lv2200(int argc, char* argv[]); -int lv2300(int argc, char* argv[]);//Stampa Giri -2 +int lv2300(int argc, char* argv[]); //Stampa Giri -2 int lv2400(int argc, char* argv[]); -int lv2500(int argc, char* argv[]);//Fatturazione +int lv2500(int argc, char* argv[]); //Fatturazione int lv2600(int argc, char* argv[]); -int lv2700(int argc, char* argv[]);//Riepilogo Bolle di Lavanderie -6 -int lv2800(int argc, char* argv[]);//Venduto Per Cliente nei 12 Mesi -7 +int lv2700(int argc, char* argv[]); //Riepilogo Bolle di Lavanderie -6 +int lv2800(int argc, char* argv[]); //Venduto Per Cliente nei 12 Mesi -7 +int lv2900(int argc, char* argv[]); #endif // __LV2_H \ No newline at end of file diff --git a/lv/lv2900.cpp b/lv/lv2900.cpp new file mode 100755 index 000000000..6df2d4a30 --- /dev/null +++ b/lv/lv2900.cpp @@ -0,0 +1,1052 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lvlib.h" +#include "../ve/velib.h" + +#include "lvcondv.h" +#include "lvrcondv.h" +#include "lvrconsplan.h" +#include "../mg/anamag.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à di misura +const TString& TRiga_pacco::um() const +{ + return get(PACCHI_UM); +} + +//DATA: metodo che restituisce la data in cui il pacco è creato +const TDate TRiga_pacco::data() const +{ + return get_date(PACCHI_DATA); +} + +//CLIENTE; metodo che restituisce il codice del cliente a cui è 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 è stato assegnato a qualcuno +const TDate TRiga_pacco::databo() const +{ + return get_date(PACCHI_DATABO); +} + +//ANNULLATO: metodo che ritorna true se il pacco è 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à 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 è 'S' +bool TRiga_pacco::is_annullato() +{ + return get_bool(PACCHI_ANNULLATO); +} + +//IS_ASSOCIATO: metodo che restitusce "true" se il campo cliente è 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'è +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 è 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 -3 per ogni documento preparato + TString str; + str << "ve1 -3 " << 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 è 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à 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à è 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à questo articolo; + //se la trovo sommo le quantità, 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à + 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à 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ù 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ù 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; +} diff --git a/lv/lv2900a.h b/lv/lv2900a.h new file mode 100755 index 000000000..907ec5fbc --- /dev/null +++ b/lv/lv2900a.h @@ -0,0 +1,10 @@ +//Acquisizione da contapezzi +//Campi Maschera lv2900a +#define F_DADATA 201 +#define F_ADATA 202 +#define F_CODCF 203 +#define F_RAGSOC 204 +#define F_GIRI 205 +#define F_STAMPA 206 +#define F_PATH 207 +#define F_FNAME 208 \ No newline at end of file diff --git a/lv/lv2900a.uml b/lv/lv2900a.uml new file mode 100755 index 000000000..248dc14da --- /dev/null +++ b/lv/lv2900a.uml @@ -0,0 +1,112 @@ +#include "lv2900a.h" + +TOOLBAR "Topbar" 0 0 0 2 + +BUTTON DLG_IMPORT 2 2 +BEGIN + PROMPT 1 1 "Importa" + PICTURE TOOL_IMPORT +END + +BUTTON DLG_PACKTCLI 2 2 +BEGIN + PROMPT 1 1 "A cliente" + PICTURE TOOL_PACK2CLI +END + +BUTTON DLG_PACKTMAG 2 2 +BEGIN + PROMPT 1 1 "A magazzino" + PICTURE TOOL_PACK2MAG +END + +#include + +ENDPAGE + +PAGE "Conta del pulito" -1 -1 80 10 + +GROUPBOX DLG_NULL 78 3 +BEGIN + PROMPT 1 1 "@bDate Ricezione" +END + +DATE F_DADATA +BEGIN + PROMPT 2 2 "Elabora dal " + CHECKTYPE REQUIRED + FLAGS "A" +END + +DATE F_ADATA +BEGIN + PROMPT 28 2 "a data " + CHECKTYPE REQUIRED + FLAGS "A" +END + +GROUPBOX DLG_NULL 78 4 +BEGIN + PROMPT 1 4 "@bParametri Ricezione" +END + +NUMBER F_CODCF 6 +BEGIN + PROMPT 2 5 "Cliente " + FLAGS "U" + USE LF_CLIFO + INPUT TIPOCF "C" + INPUT CODCF F_CODCF + DISPLAY "Codice " CODCF + DISPLAY "Ragione sociale@50" RAGSOC + OUTPUT F_CODCF CODCF + OUTPUT F_RAGSOC RAGSOC + CHECKTYPE NORMAL +END + +STRING F_RAGSOC 50 +BEGIN + PROMPT 23 5 "" + USE LF_CLIFO KEY 2 + INPUT TIPOCF "C" + INPUT RAGSOC F_RAGSOCC + DISPLAY "Ragione sociale@50" RAGSOC + DISPLAY "Codice" CODCF + COPY OUTPUT F_CODCF + CHECKTYPE NORMAL +END + +BOOLEAN F_GIRI +BEGIN + PROMPT 2 6 "Ricezione conteggi in base ai giri" +END + +GROUPBOX DLG_NULL 78 3 +BEGIN + PROMPT 1 8 "@bOpzioni stampa" +END + +BOOLEAN F_STAMPA +BEGIN + PROMPT 2 9 "Stampa diretta dei documenti (solo per associazione a cliente)" +END + +GROUPBOX DLG_NULL 78 4 +BEGIN + PROMPT 1 11 "@bSorgente" +END + +STRING F_PATH 255 50 +BEGIN + PROMPT 2 12 "Cartella " + FLAGS "D" +END + +STRING F_FNAME 50 +BEGIN + PROMPT 2 13 "File " + FLAGS "D" +END + +ENDPAGE +ENDMASK \ No newline at end of file