From 3c7e9a5c69b99ed9c7368ec7f2acf3b99c800ceb Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 15 Apr 2016 08:17:44 +0000 Subject: [PATCH] git-svn-id: svn://10.65.10.50/branches/R_10_00@23191 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- lv/lv0200b.rep | 30 +- lv/lv0200b.uml | 6 + lv/lv0200c.rep | 109 ++- lv/lv0200c.uml | 6 + lv/lv1100.cpp | 3 +- lv/lv1200.cpp | 1 + lv/lv1300.cpp | 2 + lv/lv2100.cpp | 1 + lv/lv2200.cpp | 1 + lv/lv2400.cpp | 61 +- lv/lv2400a.uml | 2 +- lv/lv2600.cpp | 2453 +++++++++++++++++++++++++----------------------- lv/lv2600a.uml | 8 +- lv/lv2900.cpp | 1 + lv/lv4100.cpp | 2 + lv/lv4200.cpp | 2 + lv/lv4300.cpp | 4 +- lv/lvlib.cpp | 14 + lv/lvlib.h | 3 + 19 files changed, 1436 insertions(+), 1273 deletions(-) diff --git a/lv/lv0200b.rep b/lv/lv0200b.rep index e578cbf6b..6ded17115 100644 --- a/lv/lv0200b.rep +++ b/lv/lv0200b.rep @@ -1,30 +1,26 @@ - + Stampa valore convenzionale per articolo
#SYSTEM.RAGSOC - - + + MESSAGE _PAGENO - + - "Stampa riepilogo consegne del " -"#DATA" @ -+ -#THIS ! RDOC.CODART - + ANAMAG.DESCR - - + + RDOC.QTA
@@ -36,15 +32,15 @@
VALCONV - + 201@-E;R0 MESSAGE ADD,F2.102 - - RDOC.CODART + + CODART - + ANAMAG.DESCR
@@ -52,8 +48,8 @@
- USE ANAMAG -JOIN LV047 INTO CODTAB==CODART ALIAS 201 + USE ANAMAG SELECT (STR(201@-E;R0!=0)||(#ALL="X")) +JOIN LV047 ALIAS 201 INTO CODTAB==CODART FROM CODART=#DACODART TO CODART=#ACODART diff --git a/lv/lv0200b.uml b/lv/lv0200b.uml index d04f9ef16..740eb0134 100644 --- a/lv/lv0200b.uml +++ b/lv/lv0200b.uml @@ -61,6 +61,12 @@ BEGIN CHECKTYPE SEARCH END +BOOLEAN 400 +BEGIN + PROMPT 2 8 "Stampa tutti gli articoli" + FIELD ALL +END + ENDPAGE ENDMASK diff --git a/lv/lv0200c.rep b/lv/lv0200c.rep index d49535992..f45ea7f47 100644 --- a/lv/lv0200c.rep +++ b/lv/lv0200c.rep @@ -1,21 +1,17 @@ - + Stampa valore convenzionale per articolo
#SYSTEM.RAGSOC - - + + MESSAGE _PAGENO - + - "Stampa riepilogo consegne del " -"#DATA" @ -+ -#THIS ! RDOC.CODART @@ -23,54 +19,99 @@ ANAMAG.DESCR - - + + RDOC.QTA - + RDOC.QTA - + RDOC.QTA
- 0 #F1.101 ! -0 #F1.102 ! -0 #F1.103 ! + MESSAGE RESET,F1 +
+
- - #ART.DOTOD + - - UMART.PREZZO + + MESSAGE ISAMREAD,20,TIPOCF=#10!CODCF=#20,RAGSOC - + + CLIFOGIAC.TIPOCF + + + CLIFOGIAC.CODCF + + + CLIFOGIAC.DOTOD + MESSAGE ADD,F2.100 + + + 201@.R0 + + #100*#101 - MESSAGE ADD,F1.102 - - - - CODART - - - ANAMAG.DESCR + MESSAGE ADD,F2.102
- + - + + MESSAGE ADD,F1.102 + + + MESSAGE ADD,F1.102
- USE ANAMAG -JOIN UMART INTO CODART==CODART NRIGA==1 -FROM CODART=#DACODART -TO CODART=#ACODART +
+ + + MESSAGE ADD,F1.100 + + + #H2.203 + + + MESSAGE ADD,F1.102 + + + + #H2.201 + + + #H2.202 + +
+ USE CLIFOGIAC KEY 3 SELECT STR(DOTOD!=0)STR(CODCF!=0)(ANAMAG.DESCR!="")(CLIFO.RAGSOC!="") +JOIN ANAMAG INTO CODART==CODART +JOIN LV047 ALIAS 201 INTO CODTAB==CODART +JOIN CLIFO INTO TIPOCF==TIPOCF CODCF==CODCF +FROM ANNOES=#ANNO CODART=#DACODART +TO ANNOES=#ANNO CODART=#ACODART + \ No newline at end of file diff --git a/lv/lv0200c.uml b/lv/lv0200c.uml index 0dd8d1b82..ea6691131 100644 --- a/lv/lv0200c.uml +++ b/lv/lv0200c.uml @@ -61,6 +61,12 @@ BEGIN CHECKTYPE SEARCH END +BOOLEAN 400 +BEGIN + PROMPT 2 9 "Stampa dettaglio clienti" + FIELD DETT +END + ENDPAGE ENDMASK diff --git a/lv/lv1100.cpp b/lv/lv1100.cpp index 29cdaea24..7664889a2 100755 --- a/lv/lv1100.cpp +++ b/lv/lv1100.cpp @@ -1,8 +1,9 @@ #include #include +#include #include -#include #include +#include #include "lv1100a.h" #include "../ve/velib.h" diff --git a/lv/lv1200.cpp b/lv/lv1200.cpp index db3c5e1d6..d4cb5211b 100755 --- a/lv/lv1200.cpp +++ b/lv/lv1200.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/lv/lv1300.cpp b/lv/lv1300.cpp index 70ab82ce4..1cedb224e 100755 --- a/lv/lv1300.cpp +++ b/lv/lv1300.cpp @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include "lvlib.h" diff --git a/lv/lv2100.cpp b/lv/lv2100.cpp index 7ac1fd9c9..01a938848 100755 --- a/lv/lv2100.cpp +++ b/lv/lv2100.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/lv/lv2200.cpp b/lv/lv2200.cpp index 81db6938d..7c1d53b18 100755 --- a/lv/lv2200.cpp +++ b/lv/lv2200.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/lv/lv2400.cpp b/lv/lv2400.cpp index 5169d67c3..8a8f51212 100755 --- a/lv/lv2400.cpp +++ b/lv/lv2400.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -28,7 +29,7 @@ class TGenera_documenti_msk : public TAutomask { public: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); - TGenera_documenti_msk (const char* name) : TAutomask(name) {set(F_STAMPA, 'X');} + TGenera_documenti_msk (const char* name) : TAutomask(name) {} }; //ON_FIELD_EVENT: questo metodo gestisce i vari eventi che si verificano sui campi della maschera @@ -64,6 +65,7 @@ class TGenera_documenti_app : public TSkeleton_application TConfig* _configlv; char _buono; long _ndoc; + bool _has_gui; private: //Metodi per la generazione dei documenti @@ -338,7 +340,8 @@ bool TGenera_documenti_app::crea_documento_ritiro(const TISAM_recordset& ritiro, const long old_ndoc = doc.get_long(DOC_NDOC); doc.renum_ndoc(); const long new_ndoc = doc.get_long(DOC_NDOC); - message_box("Attenzione documento numero %ld rinumerato in %ld", old_ndoc, new_ndoc); + if (_has_gui) + lv_popup_msg("Attenzione documento numero %ld rinumerato in %ld", old_ndoc, new_ndoc); } ++numdocgen; } @@ -1287,27 +1290,29 @@ bool TGenera_documenti_app::transfer() } } - if (documenti.items() == 0) - warning_box(TR("Non è stato possibile generare alcun documento:\nprobabilmente i documenti richiesti esistono già.")); - else + if (_has_gui) { - if (adata < TDate(TODAY) && _msk->get_int(F_TPGEN) == 0) - warning_box(TR("Non è stato possibile generare documenti con data prevista consegna nel passato")); + if (documenti.items() == 0) + lv_popup_msg(TR("Non è stato possibile generare alcun documento:\nprobabilmente i documenti richiesti esistono già.")); else { - TReport_book buc; - buc.add(rep); - if (buc.pages() > 0) - buc.preview(); + if (adata < TDate(TODAY) && _msk->get_int(F_TPGEN) == 0) + lv_popup_msg(TR("Non è stato possibile generare documenti con data prevista consegna nel passato")); else { - TString str; - if (numdocgen > 1) - str << TR("Sono stati generati ") << numdocgen << TR(" buoni."); + TReport_book buc; + buc.add(rep); + if (buc.pages() > 0) + buc.preview(); else - str << TR("E' stato generato ") << numdocgen << TR(" buono."); - message_box(str); - message_box(TR("Generazione terminata")); + { + TString str; + if (numdocgen > 1) + str << TR("Sono stati generati ") << numdocgen << TR(" buoni."); + else + str << TR("E' stato generato un buono."); + lv_popup_msg(str); + } } } } @@ -1317,11 +1322,23 @@ bool TGenera_documenti_app::transfer() void TGenera_documenti_app::main_loop() { - _msk->set(F_NOTPLAN, "X"); - while (_msk->run() == K_ENTER) - { - transfer(); - _msk->set(F_NOTPLAN, "X"); + _has_gui = !(argc() >= 4 && xvt_str_same(argv(3), "-A")); + _msk->set(F_STAMPA, true); + _msk->set(F_NOTPLAN, true); + if (_has_gui) + { + while (_msk->run() == K_ENTER) + { + transfer(); + _msk->set(F_NOTPLAN, true); + } + } + else + { + _msk->set(F_DTCONS, TDate(TODAY)); + _msk->send_key(K_SPACE, DLG_OK); + if (_msk->run() == K_ENTER) + transfer(); } } diff --git a/lv/lv2400a.uml b/lv/lv2400a.uml index 72d4774a1..4da772b98 100755 --- a/lv/lv2400a.uml +++ b/lv/lv2400a.uml @@ -132,7 +132,7 @@ END DATE F_DTDOC BEGIN - PROMPT 30 11 "Data documento " + PROMPT 30 11 "Data documento " FLAGS "A" CHECKTYPE REQUIRED END diff --git a/lv/lv2600.cpp b/lv/lv2600.cpp index 9c658b1a8..86d8592e8 100755 --- a/lv/lv2600.cpp +++ b/lv/lv2600.cpp @@ -1,1192 +1,1261 @@ -#include -#include -#include -#include -#include -#include - -#include "lvlib.h" - -#include "../mg/clifogiac.h" -#include "../ve/velib.h" - -#include "clifo.h" -#include "cfven.h" -#include "lvcondv.h" -#include "lvrcondv.h" -#include "lvrconsplan.h" -#include "lv2600a.h" - - ///////////////////////////// - //// TARTICOLI_KEY //// - ///////////////////////////// - -//classe TArticoli_key -class TArticoli_key: public TToken_string -{ -public: - const long codcf(); - const char* codart(); - const TDate data(); - TArticoli_key& operator=(const char* key) { set(key); return *this; } - TArticoli_key(long codcf, const TString& codart, const TDate& data); - TArticoli_key(const TArticoli_key& key) : TToken_string(key) {} - TArticoli_key(const char* key) : TToken_string(key) {} -}; - -//CODCF: metodo che restituisce il codcf dalla TToken_string chiave degli articoli -const long TArticoli_key::codcf() -{ - return get_int(0); -} - -//CODART: metodo che restituisce il codart dalla TToken_string chiave degli articoli -const char* TArticoli_key::codart() -{ - return get(1); -} - -//DATA: metodo che restituisce la data dalla TToken_string chiave degli articoli -const TDate TArticoli_key::data() -{ - return (TDate)get(2); -} - -//metodi costruttori -TArticoli_key::TArticoli_key(long codcf, const TString& codart, const TDate& data) -{ - add(codcf); - add(codart); - add(data.date2ansi()); - strip(" "); -} - - ////////////////////////////// - //// TDOCUMENTI_KEY //// - ////////////////////////////// - -//classe TDocumenti_key -class TDocumenti_key : public TToken_string -{ -public: - const char* codnum(); - const int anno(); - const long ndoc(); - const int idriga(); - const long codcf(); - const char* codart(); - const TDate data(); - - TDocumenti_key(int anno, long ndoc, int idriga, long codcf, const TString& codart, const TDate& data); - TDocumenti_key(const char* key); -}; - -//CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti -const char* TDocumenti_key::codnum() -{ - return get(0); -} - -//ANNO: metodo che restituisce l'anno dalla TToken_string chiave dei documenti -const int TDocumenti_key::anno() -{ - return get_int(1); -} - -//NDOC: metodo che restituisce il numero documento dalla TToken_string chiave dei documenti -const long TDocumenti_key::ndoc() -{ - return get_long(2); -} - -//IDRIGA: metodo che restituisce l'idriga dalla TToken_string chiave dei documenti -const int TDocumenti_key::idriga() -{ - return get_int(3); -} - -//CODCF: metodo che restituisce il codcf dalla TToken_string chiave dei documenti -const long TDocumenti_key::codcf() -{ - return get_int(4); -} - -//CODART: metodo che restituisce il codart dalla TToken_string chiave dei documenti -const char* TDocumenti_key::codart() -{ - return get(5); -} - -//DATA: metodo che restituisce la data dalla TToken_string chiave dei documenti -const TDate TDocumenti_key::data() -{ - return (TDate)get(6); -} - -//metodi costruttori -TDocumenti_key::TDocumenti_key(int anno, long ndoc, int idriga, long codcf, const TString& codart, const TDate& data) -{ - add(ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)")); - add(anno); - add(ndoc); - add(idriga); - add(codcf); - add(codart); - add(data.date2ansi()); - strip(" "); -} - -TDocumenti_key::TDocumenti_key(const char* key):TToken_string(key) -{ -} - - ////////////////////////////////// - //// TQUANTITA_CONATATE //// - ////////////////////////////////// - -//classe TQuantita_contate -class TQuantita_contate: public TObject -{ - real _numpezzi; - real _numrotti; - -public: - const real get_pezzi() const; - const real get_rotti() const; - - void set_pezzi(const real qta); - void set_rotti(const real qta); - - void add_pezzi(const real qta); - void add_rotti(const real qta); - - bool is_empty(); - - TQuantita_contate(real pezzi = ZERO, real = ZERO); -}; - -//GET_PEZZI: metodo che restituisce il numero di pezzi contati -const real TQuantita_contate::get_pezzi() const -{ - return _numpezzi; -} - -//GET_ROTTI: metodo che restituisce il numero di pezzi rotti contati -const real TQuantita_contate::get_rotti() const -{ - return _numrotti; -} - -//SET_PEZZI: metodo che setta il numero di pezzi contati -void TQuantita_contate::set_pezzi(const real qta) -{ - _numpezzi = qta; -} - -//SET_ROTTI: metodo che setta il numero di pezzi rotti contati -void TQuantita_contate::set_rotti(const real qta) -{ - _numrotti = qta; -} - -//ADD_PEZZI: metodo che somma i pezzi contati alla quantià che già esisteva -void TQuantita_contate::add_pezzi(const real qta) -{ - _numpezzi += qta; -} - -//ADD_PEZZI: metodo che somma i pezzi rotti contati alla quantià che già esisteva -void TQuantita_contate::add_rotti(const real qta) -{ - _numrotti += qta; -} - -//IS_EMPTY: metodo che resituisce true se entrambe le quantità sono a zero -bool TQuantita_contate::is_empty() -{ - return _numpezzi == 0 && _numrotti == 0; -} - -//metodo costruttore -TQuantita_contate::TQuantita_contate(real pezzi, real rotti) -{ - set_pezzi(pezzi); - set_rotti(rotti); -} - - ///////////////////////////////// - //// TARTICOLI_CONTATI //// - ///////////////////////////////// - - -//classe TArticoli_contati -class TArticoli_contati: public TAssoc_array -{ -public: - TQuantita_contate* quantita(long codcf, const TString& codart, const TDate& data, bool create = false); -}; - -//QUANTITA: metodo che cerca nel TAssoc_array le quantità contate in base ai parametri passati -//e lo crea in automatico se il parametro create vale "true" -TQuantita_contate* TArticoli_contati::quantita(long codcf, const TString& codart, const TDate& data, bool create) -{ - TArticoli_key key(codcf, codart, data); - - TQuantita_contate* qc = (TQuantita_contate*)objptr(key); - - if(qc == NULL && create) - { - qc = new TQuantita_contate(); - add(key, qc); - } - return qc; -} - - - ///////////////////////////////// - //// TACQUISIZIONE_MSK //// - ///////////////////////////////// - -//classe TAcquisizione_msk -class TAcquisizione_msk: public TAutomask -{ -protected: - virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly); -public: - TAcquisizione_msk(); -}; - -//ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera -bool TAcquisizione_msk::on_field_event(TOperable_field& f,TField_event e,long jolly) -{ - return true; -} - -//metodo costruttore che precarica i campi di interesse sulla maschera -TAcquisizione_msk::TAcquisizione_msk():TAutomask("lv2600a") -{ - TConfig configlv(CONFIG_DITTA, "lv"); - - const TString& path = configlv.get("PathContapezzi"); - set(F_PATH, path); - - TSheet_field& sheet = sfield(F_SHEET_NAME); - for (int i = 0; ; i++) - { - const TString& nomefile = configlv.get("FileName", NULL, i); - if (nomefile.blank()) - break; - - TToken_string& row = sheet.row(-1); - row = nomefile; - } - - sheet.force_update(); -} - - /////////////////////////////////// - //// TACQUISIZIONE_CACHE //// - /////////////////////////////////// - -//classe TAcquisizione_cache -class TAcquisizione_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); - TAcquisizione_cache(); -}; - -//DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache -void TAcquisizione_cache::discarding(const THash_object* obj) -{ - TDocumento& doc = (TDocumento&)obj->obj(); - doc.sort_rows(RDOC_CODART); - int err = doc.rewrite(); - if (err != NOERR) - error_box(FR("Errore %d di scrittura del documento"), err); -} - -//KEY2OBJ: metodo che sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'è -TObject* TAcquisizione_cache::key2obj(const char* key) -{ - TToken_string chiave(key); - const TDate datadoc = chiave.get(0); - const long codcf = chiave.get_long(); - const TDate datagen(TODAY); - TDate dadata = datadoc; - TDate adata = datagen; - adata.addmonth(1); - - 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); - if (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 - { - TToken_string key; - key.add('C'); - key.add(codcf); - const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); - TLaundry_contract cont(codcf, codindsp, 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(); - TString8 codaut = consegne.get(LVRCONSPLAN_CODAUT).as_string().right(5); codaut.trim(); - - //recupero i dati di interesse dal cliente - const TRectype& clifo = cache().get(LF_CLIFO, key); - const TString4 codpag = clifo.get(CLI_CODPAG); - const long codabi = clifo.get_long(CLI_CODABI); - const long codcab = clifo.get_long(CLI_CODCAB); - const TString80 iban = clifo.get(CLI_IBAN); - - //reupero la cuasale di magazzino di testata - const TString16 causmag = cache().get("%TIP", _tipodoc, "S9"); - - //recupero i dati di interesse dal file CFVEN - const TRectype& cfven = cache().get(LF_CFVEN, key); - const long codabipr = cfven.get_long(CFV_CODABIPR); - const long codcabpr = cfven.get_long(CFV_CODCABPR); - const bool ragdoc = cfven.get_bool(CFV_RAGGDOC); - const TString8 codag1 = cfven.get(CFV_CODAG1); - const TString4 codmez = cfven.get(CFV_CODSPMEZZO); - const TString4 codporto = cfven.get(CFV_CODPORTO); - const TString4 codnote1 = cfven.get(CFV_CODNOTESP1); - const TString4 codnote2 = cfven.get(CFV_CODNOTESP2); - const TString4 codnote = cfven.get(CFV_CODNOTE); - const TString8 codvet1 = cfven.get(CFV_CODVETT1); - const TString8 codvet2 = cfven.get(CFV_CODVETT2); - const TString8 codvet3 = cfven.get(CFV_CODVETT3); - const real speseinc = cfven.get_real(CFV_PERCSPINC); - const TString4 catven = cfven.get(CFV_CATVEN); - const bool addbolli = cfven.get_bool(CFV_ADDBOLLI); - const TString8 codlist = cfven.get(CFV_CODLIST); - const TString4 codzona = cfven.get(CFV_CODZONA); - - if(codaut.empty()) - codaut = cfven.get(CFV_CODAG); - - //gestione sconto - TString sconto; - - const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0]; - switch(tpgest) - { - case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente - case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti - case 'A': //Gestione archivio sconti - { - TConfig ditta(CONFIG_DITTA, "ve"); - - TLocalisamfile sconti(LF_SCONTI); - sconti.put("TIPO", "I"); - - if(ditta.get_bool("SCOKEY", "ve", 1)) - sconti.put("CODCAT", cfven.get(CFV_CATVEN)); - - TString16 cod; - if(ditta.get_bool("SCOKEY", "ve", 2)) - cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC)); - else - cod = " "; - - if(ditta.get_bool("SCOKEY", "ve", 3)) - { - TString8 tmp; - tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA)); - cod << tmp; - } - else - cod << " "; - - if(ditta.get_bool("SCOKEY", "ve", 4)) - cod << clifo.get(CLI_CODPAG); - - sconti.put("CODART", cod); - - if (sconti.read() == NOERR) - sconto = sconti.get("SCONTO"); - } - case 'N': //sconto non gestito - default: break; - } - - if (cont.get(LVCONDV_CODNUM).empty()) - { - doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc); - doc->put(DOC_TIPODOC, _tipodoc); - } - else - { - doc = new TDocumento('D', datadoc.year(), cont.get(LVCONDV_CODNUM), ++_ndoc); - doc->put(DOC_TIPODOC, cont.get(LVCONDV_TPDOC)); - } - - 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); - if(codindsp > 0) - doc->put(DOC_CODINDSP, codindsp); - doc->put(DOC_CODPAG, codpag); - doc->put(DOC_CAUSMAG, causmag); - doc->put(DOC_CODABIA, codabi); - doc->put(DOC_CODCABA, codcab); - doc->put(DOC_IBAN, iban); - doc->put(DOC_CODABIP, codabipr); - doc->put(DOC_CODCABP, codcabpr); - doc->put(DOC_CODAG, codaut); - doc->put(DOC_CODAGVIS, codag1); - doc->put(DOC_CODSPMEZZO, codmez); - doc->put(DOC_ZONA, codzona); - doc->put(DOC_CODPORTO, codporto); - doc->put(DOC_CODNOTESP1, codnote1); - doc->put(DOC_CODNOTESP2, codnote2); - doc->put(DOC_CODNOTE, codnote); - doc->put(DOC_CODVETT1, codvet1); - doc->put(DOC_CODVETT2, codvet2); - doc->put(DOC_CODVETT3, codvet3); - doc->put(DOC_CATVEN, catven); - doc->put(DOC_CODLIST, codlist); - doc->put(DOC_CAUSMAG, causmag); - doc->put(DOC_PERCSPINC, speseinc); - doc->put(DOC_ADDBOLLI, addbolli); - doc->put(DOC_SCONTOPERC, sconto); - 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& TAcquisizione_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 -TAcquisizione_cache::TAcquisizione_cache() : TCache(17) -{ - _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)"); - _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); - _stato = cache().get("%TIP", _tipodoc, "S2").left(1); - - _ndoc = 0; -} - - /////////////////////////////////// - //// TCONFRONTO_CACHE //// - /////////////////////////////////// - -//classe TConfronto_cache -class TConfronto_cache : public TCache -{ - TString4 _codnum, _tipodoc, _stato; - -protected: - virtual void discarding(const THash_object* obj); - virtual TObject* key2obj(const char* key); - -public: - TDocumento& doc(const TDate& gg, const long cc); - TConfronto_cache(); -}; - -//DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache -void TConfronto_cache::discarding(const THash_object* obj) -{ - TDocumento& doc = (TDocumento&)obj->obj(); - if (!doc.empty()) - 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* TConfronto_cache::key2obj(const char* key) -{ - TToken_string chiave(key); - TDate datadoc = chiave.get(); - const TDate datagen(TODAY); - TDate adata = datagen; - adata.addmonth(); - const long codcf = chiave.get_long(); - - 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 - doc = new TDocumento(); - - return doc; -} - -//DOC: metodo che restituisce un puntatore ad un documento identificato dalla coppia data - cliente -TDocumento& TConfronto_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 -TConfronto_cache::TConfronto_cache() : TCache(17) -{ - _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)"); - _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); - _stato = cache().get("%TIP", _tipodoc, "S2").left(1); -} - - //////////////////////////////////////////// - //// TACQUISIZIONE_LAVANDERIE_APP //// - //////////////////////////////////////////// - -//classe TAcquisizione_lavanderie_app -class TAcquisizione_lavanderie_app : public TSkeleton_application -{ - TAcquisizione_msk* _msk; - TString4 _auto; - TString4 _gr; - -protected: - virtual bool create(); - virtual bool destroy(); - - bool elabora_file(const TString& file, TLog_report &rep, TArticoli_contati& articoli, int& nrighe, int& nrsalt); - void controlla_documenti(TLog_report& rep, TArticoli_contati& articoli, TAssoc_array& documenti); - void genera_documenti(TLog_report& rep, TAssoc_array& documenti); - void sposta_file(const TString& file); - -public: - bool transfer(); - virtual void main_loop(); -}; - -//CREATE: metodo costruttore -bool TAcquisizione_lavanderie_app::create() -{ - _msk = new TAcquisizione_msk(); - TSheet_field& sheet = _msk->sfield(F_SHEET_NAME); - sheet.set_auto_append(); - - //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); - - _gr = argv(3); - _gr = _gr.right(1); - - } - else - { - _auto = "N"; - _gr = ""; - } - - if (_gr == "S" || _gr.empty()) - _msk->set(F_RICGIRI, "X"); - else - _msk->reset(F_RICGIRI); - - open_files(LF_DOC, LF_RIGHEDOC, LF_CLIFO, LF_CFVEN, LF_SCONTI, - LF_TAB, LF_TABCOM, LF_ANAMAG, LF_UMART, 0); - - return TSkeleton_application::create(); -} - -//DESTROY: metodo distruttore -bool TAcquisizione_lavanderie_app::destroy() -{ - delete _msk; - return TApplication::destroy(); -} - -//ELABORA_FILE: metodo che effettivamente fa l'elaborazione del file -bool TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report& rep, TArticoli_contati& articoli, int& nrighe, int& nrsalt) -{ - //fisso l'anno esercizio - TEsercizi_contabili& esc = esercizi(); - const int last_esc = esc.last(); - - //scandisco il file solo se esiste - TScanner s(file); - while (s.ok()) - { - const TString& riga = s.line(); - if (riga.blank()) - continue; - - const int reclen = riga.len(); - - TDate datadoc; - long codcf = 0; - TCodice_articolo codart; - long qta; - long rotti; - long ndoc = 0; - TString16 tipo_conteggio; - TString80 operatore; - - //controllo quale tracciato record devo seguire - if (reclen == 34) // -> MONTANARI - { - nrighe++; - //leggo i campi dalla riga del file - const int d = atoi(riga.mid(0,2)); - const int m = atoi(riga.mid(2,2)); - const int y = atoi(riga.mid(4,4)); - if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) - { - datadoc = TDate(d, m, y); - if (datadoc < _msk->get_date(F_DADATA) || datadoc > _msk->get_date(F_ADATA)) - { - nrsalt++; - continue; - } - - const TString& codcf_str = riga.mid(8,6); codcf = atol(codcf_str); - codart = riga.mid(14,8); - qta = atol(riga.mid(22,6)); - rotti = atol(riga.mid(28,6)); - } - else - continue; - } - else if (reclen == 81 || reclen == 121) // ->SKEMA - { - //leggo i campi dalla riga del file - const int y = atoi(riga.mid(0,4)); - const int m = atoi(riga.mid(4,2)); - const int d = atoi(riga.mid(6,2)); - if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) - { - const TString& codcf_str = riga.mid(28,20); codcf = atol(codcf_str); - datadoc = TDate(d, m, y); - codart = riga.mid(8,20); - qta = atoi(riga.mid(48,11)); - ndoc = atoi(riga.mid(59,11)); - - switch (atoi(riga.mid(70,11))) - { - case 1: tipo_conteggio = "Automatico"; break; - case 2: tipo_conteggio = "Manuale"; break; - case 3: tipo_conteggio = "Scarto"; break; - default: break; - } - operatore = riga.mid(81,40); - } - else - continue; - } - - TToken_string key; key.format("C|%ld", codcf); - const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); - TLaundry_contract cont(codcf, codindsp, datadoc); - const TRectype& rcont = cont.row(codart.trim()); - - if (rcont.empty()) - { - TString str; - str << "L'articolo " << codart << " non è previsto nel contratto del cliente " << codcf; - warning_box(str); - - //ATTENZIONE: DEVE CHIEDERE CHE COSA FARE (Aggiungerlo o Ignorarlo) - } - - TArticolo_lavanderie& artrec = cached_article_laundry(codart, 'C', codcf, 0); - - //estraggo il record corrispondente su LF_CLIFOGIAC - const TRecmag_lavanderie& reclav = artrec.find_rec(last_esc); - - //leggo il record corrispondente - if(!reclav.empty()) - { - const real dotod = reclav.get_real(CLIFOGIAC_DOTOD); - - if (qta > dotod) - { - TString str; - str << "Attenzione! Il cliente " << codcf << " per l'articolo " << codart << " ha una dotazione di " - << dotod << " pezzi e ne sono stati ritirati " << qta << " (" << real(qta - dotod) << " in più)."; - warning_box(str); - } - } - - TQuantita_contate* qc = articoli.quantita(codcf, codart.trim(), datadoc, true); - - //se la chiave è già presente nel TAssoc_array, chiedi cosa fare delle quantità - //altrimenti aggiungila con la rispettiva al TAssoc_array con la quantità appena conteggiata - if (!qc->is_empty()) - { - if(codcf == 1184) - int cazzone = 1; - TString str; - str << "ATTENZIONE: è già presente un conteggio per il cliente " << codcf << " sull'articolo " << codart << "\n" - << "Quantità conteggio attuale: " << qta << " Quantità conteggio precedente: " << qc->get_pezzi() << "\n" - << "Si desidera sommare le quantità?\n" - << "(SI -> Somma NO -> Ignora Conteggio ANNULLA -> Sosituisci il conteggio precedente)\n"; - - KEY k = yesnocancel_box(str); - - switch (k) - { - case K_YES: qc->add_pezzi(qta); qc->add_rotti(rotti); break; //sommo le quantità - case K_NO: break; //lascio tutto com'è - default: qc->set_pezzi(qta); qc->set_rotti(rotti); break; //sostituisco le quantità - } - } - else - { - qc->set_pezzi(qta); - qc->set_rotti(rotti); - } - } - return true; -} - -//CONTROLLA_DOCUMENTI: metodo che si occupa di controllare se i dati che sto inserendo in questo momento sono -//già stati inseriti in documenti precedenti, chiedendo cosa fare di volta in volta -void TAcquisizione_lavanderie_app::controlla_documenti(TLog_report& rep, TArticoli_contati& articoli, TAssoc_array& documenti) -{ - TConfronto_cache ca; - bool found = false; - FOR_EACH_ASSOC_OBJECT(articoli, obj, key, itm) - { - const TQuantita_contate* qc = (TQuantita_contate*)itm; - - //recupero i dati dalla chiave del TAssoc_array degli articoli - TArticoli_key keyart(key); - const long codcf = keyart.codcf(); - const TString80 codart = keyart.codart(); - const TDate datadoc = keyart.data(); - - //recupero i dati dal contenuto del TAssoc_array degli articoli - TQuantita_contate* quantita = new TQuantita_contate(qc->get_pezzi(), qc->get_rotti()); - - TDocumento& doc = ca.doc(datadoc, codcf); - if (doc.empty()) - { - //preparo la chiave per il TAssoc_array dei documenti - TDocumenti_key keydoc(datadoc.year(), 0, 0, codcf, codart, datadoc); - - //aggiungo la riga corrispondente - documenti.add(keydoc, quantita); - } - else - { - int idriga = 0; - FOR_EACH_PHYSICAL_RDOC(doc, r, prdoc) - { - //cerco se esiste già una riga sul documento selezionato per quell'articolo - const TRiga_documento& rdoc = *prdoc; - const TString& codart_doc = rdoc.get(RDOC_CODART); - - if (codart_doc == codart) - { - found = true; - idriga = r; - - TString str; - str << "ATTENZIONE: è già presente un buono di ritiro per il cliente " << codcf << " sull'articolo " << codart << "\n" - << "Quantità conteggio: " << quantita->get_pezzi() << " Quantità buono di ritiro: " << rdoc.get_int(RDOC_QTAGG1) << "\n" - << "Si desidera sommare le quantità?\n" - << "(SI -> Somma NO -> Ignora Conteggio ANNULLA -> Modifica Buono)\n"; - - const KEY k = yesnocancel_box(str); - switch (k) - { - case K_YES: quantita->add_pezzi(rdoc.get_real(RDOC_QTAGG1)); quantita->add_rotti(rdoc.get_real(RDOC_QTAGG2)); break; //sommo le quantità - case K_NO: break; //lascio tutto com'è - default: quantita->set_pezzi(rdoc.get_real(RDOC_QTAGG1)); quantita->set_rotti(rdoc.get_real(RDOC_QTAGG2)); break; //sostituisco le quantità - } - break; - } - } - - if (!found) idriga = 0; // Mi pare implicito!!! - //preparo la chiave per il TAssoc_array dei documenti - const TDocumenti_key keydoc(datadoc.year(), doc.get_long(DOC_NDOC), idriga, codcf, codart, datadoc); - documenti.add(keydoc, quantita); - found = false; - } - } - ca.destroy(); -} - -//metodo che effettivamente genera i buoni di ritiro, se l'utente ha confermato la sua intenzione a crearli -void TAcquisizione_lavanderie_app::genera_documenti(TLog_report& rep, TAssoc_array& documenti) -{ - TAcquisizione_cache ca; - - const bool giri = _msk->get_bool(F_RICGIRI); - FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) - { - TDocumenti_key keydoc(key); - const TString4 codnum = keydoc.codnum(); - const int anno = keydoc.anno(); - const int ndoc = keydoc.ndoc(); - int idriga = keydoc.idriga(); // May change - const int codcf = keydoc.codcf(); - const TString80 codart = keydoc.codart(); - const TDate datadoc = keydoc.data(); - - TQuantita_contate* qc = (TQuantita_contate*)itm; - const real qtacon = qc->get_pezzi(); - const real qtarotti = qc->get_rotti(); - - TToken_string key; - key.add('C'); - key.add(codcf); - const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); - const TLaundry_contract cont(codcf, codindsp, datadoc); - const TString8 codcont = cont.get(LVCONDV_CODCONT); - const TRectype& rcont = cont.row(codart); - - - TDocumento& doc = ca.doc(datadoc, codcf); - if (!giri) - { - const TDate oggi(TODAY); - doc.put("DATAPRCO", oggi); - } - - const TDate dtcons = doc.get_date("DATAPRCO"); - - TString4 causale = rcont.get(LVRCONDV_CAUSLAV); - if (causale.blank()) - causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"); - - // idriga NON è affidabile, per cui ricerco per codart - if (idriga > 0 && doc.body().exist(idriga) && doc[idriga].get(RDOC_CODARTMAG) != codart) - { - idriga = 0; // Invalidate by now - FOR_EACH_PHYSICAL_RDOC(doc, r, row) - { - if (row->get(RDOC_CODARTMAG) == codart) - { - idriga = r; - break; - } - } - } - - if (idriga > 0 && doc.body().exist(idriga)) - { - TRiga_documento& rdoc = doc[idriga]; - rdoc.put(RDOC_QTAGG1, qtacon); - rdoc.put(RDOC_QTAGG2, qtarotti); - } - else - { - const TRectype& anamag = cache().get(LF_ANAMAG, codart); - TString descrart; - descrart << anamag.get(ANAMAG_DESCR) << anamag.get(ANAMAG_DESCRAGG); - - TRiga_documento& rdoc = doc.new_row("22"); - rdoc.put(RDOC_CODART, codart); - if (descrart.len() > 50) - { - rdoc.put(RDOC_DESCR, descrart.left(50)); - rdoc.put(RDOC_DESCLUNGA, true); - rdoc.put(RDOC_DESCEST, descrart.sub(50)); - } - else - rdoc.put(RDOC_DESCR, descrart); - rdoc.put(RDOC_CODARTMAG, codart); - rdoc.put(RDOC_CHECKED, 'X'); - rdoc.put(RDOC_CODAGG1, causale); - rdoc.put(RDOC_QTAGG1, qtacon); - rdoc.put(RDOC_QTAGG2, qtarotti); - rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA)); - - //scrivo il magazzino - const TCausale_lavanderie cau(causale); - TCausale_magazzino rit(cau.causale_ritiro()); - TCausale_magazzino con(cau.causale_consegna()); - - TString8 magazzino, magazzinoc; - - if(rit.get("S10").full()) - magazzino = rit.get("S10").mid(0,5); - else - magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN"); - - if(con.get("S10").full()) - magazzinoc = con.get("S10").mid(0,5); - else - 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 l'unità di misura - TToken_string key; - key.add(codart); - key.add(1); - const TRectype& umart = cache().get(LF_UMART, key); - rdoc.put(RDOC_UMQTA, umart.get(UMART_UM)); - } - - if (giri && !doc.get_date("DATAPRCO").ok()) - { - TString msg; - msg << TR("Il documento ") << doc.get(DOC_NDOC) << TR(" del ") << doc.get(DOC_DATADOC) - << TR(" del cliente ") << codcf << TR(" non ha data di prevista consegna."); - rep.log(1,msg); - } - } - - if (ca.empty()) - warning_box(TR("ATTENZIONE: il file importato non ha generato nessun documento.\n" - "controllare che il tracciato record sia coerente")); - else - ca.destroy(); -} - -//SPOSTA_FILE: metodo che sposta cambiando nome i file elaborati durante la generazione dei buoni -void TAcquisizione_lavanderie_app::sposta_file(const TString& 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); - - //se la copia è andata a buon fine, creo un file .old vuoto e cancello il file .dat - if (fcopy(fileori, filedest)) - { - TFilename fileold; - fileold = fileori.path(); - - TString strn = fileori.name_only(); - strn << ".old"; - - fileold.add(strn); - - fclose(fopen(fileold, "w")); - - fileori.fremove(); - } -} - -//TRANSFER: metodo che scorre i campi nome e, se sono pieni, richiama il metodo -//ELABORA_FILE(), che effettivamente fa l'elaborazione -bool TAcquisizione_lavanderie_app::transfer() -{ - //prendo il path dalla maschera - const TString& path = _msk->get(F_PATH); - TSheet_field& sheet = _msk->sfield(F_SHEET_NAME); - TFilename file; - - TLog_report logrep(TR("Acquisizione da contapezzi")); - logrep.kill_duplicates(true); - - TArticoli_contati articoli; - TAssoc_array documenti; - int nrighe = 0; - int nrsalt = 0; - - //per ogni riga dello sheet, leggo il suo contenuto, se contiene dei caratteri jolly - //preparo la lista dei file che soddisfano la maschera in quella directory e li elaboro - //tutti, altrimenti elaboro esattamente il file che è scritto sullo sheet - bool elaborato = false; - bool esiste = false; - FOR_EACH_SHEET_ROW(sheet, r1, row1) if (!row1->empty_items()) - { - if (row1->find('/') >= 0 || row1->find('\\') >= 0) - file = *row1; - else - { - file = path; - file.add(*row1); - } - - if (file.find('*') >= 0 || file.find('?') >= 0) - { - TString_array lista_file; - list_files(file, lista_file); - - FOR_EACH_ARRAY_ROW(lista_file, r2, row2) - { - const TFilename strname = *row2; - if (strname.exist()) - { - esiste = true; - elaborato = elabora_file(strname, logrep, articoli, nrighe, nrsalt); - } - } - - } - else if (file.exist()) - { - esiste = true; - elaborato = elabora_file(file, logrep, articoli, nrighe, nrsalt); - } - - if (!esiste) - warning_box(TR("ATTENZIONE: non è stato trovato nessun file da elaborare")); - } - - if (elaborato) - { - controlla_documenti(logrep, articoli, documenti); - - bool genera = true; - - if (_auto == "A") - { - if (nrsalt > 0) - { - TString str; - str << "Sono stati ricevuti " << nrighe << " record, di cui " << nrighe - nrsalt - << " sono stati elaborati correttamente" << " e " << nrsalt - << " ignorati.\nSi desidera procedere con la generazione dei buoni di ritiro?"; - - if (!yesno_box(str)) - genera = false; - } - } - else - { - TString str; - str << "Sono stati ricevuti " << nrighe << " record, di cui " << nrighe - nrsalt - << " sono stati elaborati correttamente" << " e " << nrsalt - << " ignorati.\nSi desidera procedere con la generazione dei buoni di ritiro?"; - - if (!yesno_box(str)) - genera = false; - } - - if (nrsalt == 0 || genera) - { - - genera_documenti(logrep, documenti); - - //diagnostica - TAssoc_array buoni; - FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) - { - TDocumenti_key tmp = key; - TDoc_key kdoc(tmp.anno(), tmp.codnum(), tmp.ndoc()); - - if (!buoni.is_key(kdoc)) - buoni.add(kdoc, kdoc); - } - - switch (buoni.items()) - { - case 0: warning_box(TR("Non è stato generato alcun buono di ritiro.")); break; - case 1: message_box(TR("E' stato generato un buono di ritiro.")); break; - default: message_box(FR("Sono stati generati %d buoni di ritiro."), buoni.items()); break; - } - - FOR_EACH_SHEET_ROW(sheet, r1, row1) - { - if(row1->full()) - { - if (row1->find('/') >= 0 || row1->find('\\') >= 0) - file = *row1; - else - { - file = path; - file.add(*row1); - } - - if (file.find('*') >= 0 || file.find('?') >= 0) - { - TString_array lista_file; - list_files(file, lista_file); - - FOR_EACH_ARRAY_ROW(lista_file, r2, row2) - { - const TFilename strname(*row2); - if (strname.exist()) - sposta_file(strname); - } - } - else if (file.exist()) - sposta_file(file); - } - } - } - - if (_auto != "A") - { - TReport_book buc; - buc.add(logrep); - if (buc.pages() > 0) - buc.preview(); - - if (genera) - message_box(TR("Generazione terminata")); - else - warning_box(TR("Generazione interrotta")); - } - _msk->send_key(K_SPACE, DLG_QUIT); - } - return true; -} - -void TAcquisizione_lavanderie_app::main_loop() -{ - //lo lancio in automatico da linea di comando - if (_auto == "A") - _msk->send_key(K_SPACE, DLG_OK); - while (_msk->run() == K_ENTER) - transfer(); -} - -int lv2600(int argc, char *argv[]) -{ - TAcquisizione_lavanderie_app a; - a.run (argc, argv, TR("Acquisizione da contapezzi")); - return 0; -} +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lvlib.h" + +#include "../mg/clifogiac.h" +#include "../ve/velib.h" + +#include "clifo.h" +#include "cfven.h" +#include "lvcondv.h" +#include "lvrcondv.h" +#include "lvrconsplan.h" +#include "lv2600a.h" + + ///////////////////////////// + //// TARTICOLI_KEY //// + ///////////////////////////// + +//classe TArticoli_key +class TArticoli_key : public TToken_string +{ +public: + const long codcf(); + const char* codart(); + const TDate data(); + TArticoli_key& operator=(const char* key) { set(key); return *this; } + TArticoli_key(long codcf, const TString& codart, const TDate& data); + TArticoli_key(const TArticoli_key& key) : TToken_string(key) {} + TArticoli_key(const char* key) : TToken_string(key) {} +}; + +//CODCF: metodo che restituisce il codcf dalla TToken_string chiave degli articoli +const long TArticoli_key::codcf() +{ + return get_long(0); +} + +//CODART: metodo che restituisce il codart dalla TToken_string chiave degli articoli +const char* TArticoli_key::codart() +{ + return get(1); +} + +//DATA: metodo che restituisce la data dalla TToken_string chiave degli articoli +const TDate TArticoli_key::data() +{ + return TDate(get(2)); +} + +//metodi costruttori +TArticoli_key::TArticoli_key(long codcf, const TString& codart, const TDate& data) +{ + add(codcf); + add(codart); + add(data.date2ansi()); + strip(" "); +} + + ////////////////////////////// + //// TDOCUMENTI_KEY //// + ////////////////////////////// + +//classe TDocumenti_key +class TDocumenti_key : public TToken_string +{ +public: + const char* codnum(); + const int anno(); + const long ndoc(); + const int idriga(); + const long codcf(); + const char* codart(); + const TDate data(); + + TDocumenti_key(int anno, long ndoc, int idriga, long codcf, const TString& codart, const TDate& data); + TDocumenti_key(const char* key); +}; + +//CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti +const char* TDocumenti_key::codnum() +{ + return get(0); +} + +//ANNO: metodo che restituisce l'anno dalla TToken_string chiave dei documenti +const int TDocumenti_key::anno() +{ + return get_int(1); +} + +//NDOC: metodo che restituisce il numero documento dalla TToken_string chiave dei documenti +const long TDocumenti_key::ndoc() +{ + return get_long(2); +} + +//IDRIGA: metodo che restituisce l'idriga dalla TToken_string chiave dei documenti +const int TDocumenti_key::idriga() +{ + return get_int(3); +} + +//CODCF: metodo che restituisce il codcf dalla TToken_string chiave dei documenti +const long TDocumenti_key::codcf() +{ + return get_int(4); +} + +//CODART: metodo che restituisce il codart dalla TToken_string chiave dei documenti +const char* TDocumenti_key::codart() +{ + return get(5); +} + +//DATA: metodo che restituisce la data dalla TToken_string chiave dei documenti +const TDate TDocumenti_key::data() +{ + return TDate(get(6)); +} + +//metodi costruttori +TDocumenti_key::TDocumenti_key(int anno, long ndoc, int idriga, long codcf, const TString& codart, const TDate& data) +{ + add(ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)")); + add(anno); + add(ndoc); + add(idriga); + add(codcf); + add(codart); + add(data.date2ansi()); + strip(" "); +} + +TDocumenti_key::TDocumenti_key(const char* key):TToken_string(key) +{ +} + + ////////////////////////////////// + //// TQUANTITA_CONATATE //// + ////////////////////////////////// + +//classe TQuantita_contate +class TQuantita_contate: public TObject +{ + real _numpezzi; + real _numrotti; + +public: + const real get_pezzi() const; + const real get_rotti() const; + + void set_pezzi(const real qta); + void set_rotti(const real qta); + + void add_pezzi(const real qta); + void add_rotti(const real qta); + + bool is_empty(); + + TQuantita_contate(real pezzi = ZERO, real = ZERO); +}; + +//GET_PEZZI: metodo che restituisce il numero di pezzi contati +const real TQuantita_contate::get_pezzi() const +{ + return _numpezzi; +} + +//GET_ROTTI: metodo che restituisce il numero di pezzi rotti contati +const real TQuantita_contate::get_rotti() const +{ + return _numrotti; +} + +//SET_PEZZI: metodo che setta il numero di pezzi contati +void TQuantita_contate::set_pezzi(const real qta) +{ + _numpezzi = qta; +} + +//SET_ROTTI: metodo che setta il numero di pezzi rotti contati +void TQuantita_contate::set_rotti(const real qta) +{ + _numrotti = qta; +} + +//ADD_PEZZI: metodo che somma i pezzi contati alla quantià che già esisteva +void TQuantita_contate::add_pezzi(const real qta) +{ + _numpezzi += qta; +} + +//ADD_PEZZI: metodo che somma i pezzi rotti contati alla quantià che già esisteva +void TQuantita_contate::add_rotti(const real qta) +{ + _numrotti += qta; +} + +//IS_EMPTY: metodo che resituisce true se entrambe le quantità sono a zero +bool TQuantita_contate::is_empty() +{ + return _numpezzi == 0 && _numrotti == 0; +} + +//metodo costruttore +TQuantita_contate::TQuantita_contate(real pezzi, real rotti) +{ + set_pezzi(pezzi); + set_rotti(rotti); +} + + ///////////////////////////////// + //// TARTICOLI_CONTATI //// + ///////////////////////////////// + + +//classe TArticoli_contati +class TArticoli_contati: public TAssoc_array +{ +public: + TQuantita_contate* quantita(long codcf, const TString& codart, const TDate& data, bool create = false); +}; + +//QUANTITA: metodo che cerca nel TAssoc_array le quantità contate in base ai parametri passati +//e lo crea in automatico se il parametro create vale "true" +TQuantita_contate* TArticoli_contati::quantita(long codcf, const TString& codart, const TDate& data, bool create) +{ + TArticoli_key key(codcf, codart, data); + + TQuantita_contate* qc = (TQuantita_contate*)objptr(key); + + if(qc == NULL && create) + { + qc = new TQuantita_contate(); + add(key, qc); + } + return qc; +} + + + ///////////////////////////////// + //// TACQUISIZIONE_MSK //// + ///////////////////////////////// + +//classe TAcquisizione_msk +class TAcquisizione_msk: public TAutomask +{ +protected: + virtual long handler(WINDOW task, EVENT* ep); + virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly); + +public: + bool some_file() const; + int file_list(TString_array& fl) const; + + TAcquisizione_msk(); +}; + +int TAcquisizione_msk::file_list(TString_array& lista_file) const +{ + const TFilename path = get(F_PATH); + TSheet_field& sheet = sfield(F_SHEET_NAME); + TFilename file; + + FOR_EACH_SHEET_ROW(sheet, r1, row1) if (!row1->empty_items()) + { + if (row1->find('/') >= 0 || row1->find('\\') >= 0) + file = *row1; + else + { + file = path; + file.add(*row1); + } + + if (file.find('*') >= 0 || file.find('?') >= 0) + list_files(file, lista_file); + else + { + if (file.exist()) + lista_file.add(file); + } + } + for (int i = lista_file.last(); i >= 0; i--) + { + file = lista_file.row(i); + if (fsize(file) < 8) // Contapezzi a volte genera file vuoti + { + lista_file.destroy(i, true); + file.fremove(); + } + } + return lista_file.items(); +} + +bool TAcquisizione_msk::some_file() const +{ + const TFilename path = get(F_PATH); + TSheet_field& sheet = sfield(F_SHEET_NAME); + TFilename file; + bool found = false; + FOR_EACH_SHEET_ROW(sheet, r1, row1) if (!(found || row1->empty_items())) + { + if (row1->find('/') >= 0 || row1->find('\\') >= 0) + file = *row1; + else + { + file = path; + file.add(*row1); + } + + if (file.find('*') >= 0 || file.find('?') >= 0) + { + TString_array a; + found = list_files(file, a) > 0; + } + else + found = file.exist(); + } + + return found; +} + + +long TAcquisizione_msk::handler(WINDOW task, EVENT* ep) +{ + if (ep->type == E_TIMER) + { + if (is_running() && some_file()) + stop_run(K_ENTER); + } + return TAutomask::handler(task, ep); +} + + + +//ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera +bool TAcquisizione_msk::on_field_event(TOperable_field& f,TField_event e,long jolly) +{ + return true; +} + +//metodo costruttore che precarica i campi di interesse sulla maschera +TAcquisizione_msk::TAcquisizione_msk():TAutomask("lv2600a") +{ + TConfig configlv(CONFIG_DITTA, "lv"); + + const TString& path = configlv.get("PathContapezzi"); + set(F_PATH, path); + + TSheet_field& sheet = sfield(F_SHEET_NAME); + for (int i = 0; ; i++) + { + const TString& nomefile = configlv.get("FileName", NULL, i); + if (nomefile.blank()) + break; + + TToken_string& row = sheet.row(-1); + row = nomefile; + } + + sheet.force_update(); +} + + /////////////////////////////////// + //// TACQUISIZIONE_CACHE //// + /////////////////////////////////// + +//classe TAcquisizione_cache +class TAcquisizione_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); + TAcquisizione_cache(); +}; + +//DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache +void TAcquisizione_cache::discarding(const THash_object* obj) +{ + TDocumento& doc = (TDocumento&)obj->obj(); + doc.sort_rows(RDOC_CODART); + int err = doc.rewrite(); + if (err != NOERR) + error_box(FR("Errore %d di scrittura del documento"), err); +} + +//KEY2OBJ: metodo che sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'è +TObject* TAcquisizione_cache::key2obj(const char* key) +{ + TToken_string chiave(key); + const TDate datadoc = chiave.get(0); + const long codcf = chiave.get_long(); + const TDate datagen(TODAY); + TDate dadata = datadoc; + TDate adata = datagen; + adata.addmonth(1); + + 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); + if (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 + { + TToken_string key; + key.add('C'); + key.add(codcf); + const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); + TLaundry_contract cont(codcf, codindsp, 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(); + TString8 codaut = consegne.get(LVRCONSPLAN_CODAUT).as_string().right(5); codaut.trim(); + + //recupero i dati di interesse dal cliente + const TRectype& clifo = cache().get(LF_CLIFO, key); + const TString4 codpag = clifo.get(CLI_CODPAG); + const long codabi = clifo.get_long(CLI_CODABI); + const long codcab = clifo.get_long(CLI_CODCAB); + const TString80 iban = clifo.get(CLI_IBAN); + + //reupero la cuasale di magazzino di testata + const TString16 causmag = cache().get("%TIP", _tipodoc, "S9"); + + //recupero i dati di interesse dal file CFVEN + const TRectype& cfven = cache().get(LF_CFVEN, key); + const long codabipr = cfven.get_long(CFV_CODABIPR); + const long codcabpr = cfven.get_long(CFV_CODCABPR); + const bool ragdoc = cfven.get_bool(CFV_RAGGDOC); + const TString8 codag1 = cfven.get(CFV_CODAG1); + const TString4 codmez = cfven.get(CFV_CODSPMEZZO); + const TString4 codporto = cfven.get(CFV_CODPORTO); + const TString4 codnote1 = cfven.get(CFV_CODNOTESP1); + const TString4 codnote2 = cfven.get(CFV_CODNOTESP2); + const TString4 codnote = cfven.get(CFV_CODNOTE); + const TString8 codvet1 = cfven.get(CFV_CODVETT1); + const TString8 codvet2 = cfven.get(CFV_CODVETT2); + const TString8 codvet3 = cfven.get(CFV_CODVETT3); + const real speseinc = cfven.get_real(CFV_PERCSPINC); + const TString4 catven = cfven.get(CFV_CATVEN); + const bool addbolli = cfven.get_bool(CFV_ADDBOLLI); + const TString8 codlist = cfven.get(CFV_CODLIST); + const TString4 codzona = cfven.get(CFV_CODZONA); + + if(codaut.empty()) + codaut = cfven.get(CFV_CODAG); + + //gestione sconto + TString sconto; + + const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0]; + switch(tpgest) + { + case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente + case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti + case 'A': //Gestione archivio sconti + { + TConfig ditta(CONFIG_DITTA, "ve"); + + TLocalisamfile sconti(LF_SCONTI); + sconti.put("TIPO", "I"); + + if(ditta.get_bool("SCOKEY", "ve", 1)) + sconti.put("CODCAT", cfven.get(CFV_CATVEN)); + + TString16 cod; + if(ditta.get_bool("SCOKEY", "ve", 2)) + cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC)); + else + cod = " "; + + if(ditta.get_bool("SCOKEY", "ve", 3)) + { + TString8 tmp; + tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA)); + cod << tmp; + } + else + cod << " "; + + if(ditta.get_bool("SCOKEY", "ve", 4)) + cod << clifo.get(CLI_CODPAG); + + sconti.put("CODART", cod); + + if (sconti.read() == NOERR) + sconto = sconti.get("SCONTO"); + } + case 'N': //sconto non gestito + default: break; + } + + if (cont.get(LVCONDV_CODNUM).empty()) + { + doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc); + doc->put(DOC_TIPODOC, _tipodoc); + } + else + { + doc = new TDocumento('D', datadoc.year(), cont.get(LVCONDV_CODNUM), ++_ndoc); + doc->put(DOC_TIPODOC, cont.get(LVCONDV_TPDOC)); + } + + 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); + if(codindsp > 0) + doc->put(DOC_CODINDSP, codindsp); + doc->put(DOC_CODPAG, codpag); + doc->put(DOC_CAUSMAG, causmag); + doc->put(DOC_CODABIA, codabi); + doc->put(DOC_CODCABA, codcab); + doc->put(DOC_IBAN, iban); + doc->put(DOC_CODABIP, codabipr); + doc->put(DOC_CODCABP, codcabpr); + doc->put(DOC_CODAG, codaut); + doc->put(DOC_CODAGVIS, codag1); + doc->put(DOC_CODSPMEZZO, codmez); + doc->put(DOC_ZONA, codzona); + doc->put(DOC_CODPORTO, codporto); + doc->put(DOC_CODNOTESP1, codnote1); + doc->put(DOC_CODNOTESP2, codnote2); + doc->put(DOC_CODNOTE, codnote); + doc->put(DOC_CODVETT1, codvet1); + doc->put(DOC_CODVETT2, codvet2); + doc->put(DOC_CODVETT3, codvet3); + doc->put(DOC_CATVEN, catven); + doc->put(DOC_CODLIST, codlist); + doc->put(DOC_CAUSMAG, causmag); + doc->put(DOC_PERCSPINC, speseinc); + doc->put(DOC_ADDBOLLI, addbolli); + doc->put(DOC_SCONTOPERC, sconto); + 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& TAcquisizione_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 +TAcquisizione_cache::TAcquisizione_cache() : TCache(17) +{ + _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)"); + _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); + _stato = cache().get("%TIP", _tipodoc, "S2").left(1); + + _ndoc = 0; +} + + /////////////////////////////////// + //// TCONFRONTO_CACHE //// + /////////////////////////////////// + +//classe TConfronto_cache +class TConfronto_cache : public TCache +{ + TString4 _codnum, _tipodoc, _stato; + +protected: + virtual void discarding(const THash_object* obj); + virtual TObject* key2obj(const char* key); + +public: + TDocumento& doc(const TDate& gg, const long cc); + TConfronto_cache(); +}; + +//DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache +void TConfronto_cache::discarding(const THash_object* obj) +{ + TDocumento& doc = (TDocumento&)obj->obj(); + if (!doc.empty()) + 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* TConfronto_cache::key2obj(const char* key) +{ + TToken_string chiave(key); + TDate datadoc = chiave.get(); + const TDate datagen(TODAY); + TDate adata = datagen; + adata.addmonth(); + const long codcf = chiave.get_long(); + + 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 + doc = new TDocumento(); + + return doc; +} + +//DOC: metodo che restituisce un puntatore ad un documento identificato dalla coppia data - cliente +TDocumento& TConfronto_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 +TConfronto_cache::TConfronto_cache() : TCache(17) +{ + _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)"); + _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); + _stato = cache().get("%TIP", _tipodoc, "S2").left(1); +} + + //////////////////////////////////////////// + //// TACQUISIZIONE_LAVANDERIE_APP //// + //////////////////////////////////////////// + +//classe TAcquisizione_lavanderie_app +class TAcquisizione_lavanderie_app : public TSkeleton_application +{ + TAcquisizione_msk* _msk; + + enum TalpMode { alpGUI, alpAUTO, alpMONITOR }; + TalpMode _mode; + TString4 _gr; + +protected: + virtual bool create(); + virtual bool destroy(); + + bool elabora_file(const TString& file, TLog_report &rep, TArticoli_contati& articoli, int& nrighe, int& nrsalt); + void controlla_documenti(TLog_report& rep, TArticoli_contati& articoli, TAssoc_array& documenti); + void genera_documenti(TLog_report& rep, TAssoc_array& documenti); + void sposta_file(const TString& file); + +public: + bool transfer(); + virtual void main_loop(); + TAcquisizione_lavanderie_app() : _msk(NULL) {} +}; + +//CREATE: metodo costruttore +bool TAcquisizione_lavanderie_app::create() +{ + if (xvt_vobj_get_attr(NULL_WIN, ATTR_APPL_ALREADY_RUNNING)) + { + TString msg; msg.format(FR("%s già in esecuzione!"), name()); + xvt_dm_popup_error(msg); + return false; + } + + _msk = new TAcquisizione_msk(); + TSheet_field& sheet = _msk->sfield(F_SHEET_NAME); + sheet.set_auto_append(); + + _mode = alpGUI; + _gr = ""; + + + //se ho più di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto + if (argc() > 2) + { + const TFixed_string a(argv(2)); + switch (toupper(a[1])) + { + case 'A': _mode = alpAUTO; break; + case 'M': _mode = alpMONITOR; break; + default: break; + } + + if (argc() > 3) + { + _gr = argv(3); + _gr = _gr.right(1); + } + } + + if (_gr == "S" || _gr.blank()) + _msk->set(F_RICGIRI, "X"); + else + _msk->reset(F_RICGIRI); + + open_files(LF_DOC, LF_RIGHEDOC, LF_CLIFO, LF_CFVEN, LF_SCONTI, + LF_TAB, LF_TABCOM, LF_ANAMAG, LF_UMART, 0); + + return TSkeleton_application::create(); +} + +//DESTROY: metodo distruttore +bool TAcquisizione_lavanderie_app::destroy() +{ + delete _msk; + return TSkeleton_application::destroy(); +} + +//ELABORA_FILE: metodo che effettivamente fa l'elaborazione del file +bool TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report& rep, TArticoli_contati& articoli, int& nrighe, int& nrsalt) +{ + //fisso l'anno esercizio + TEsercizi_contabili& esc = esercizi(); + const int last_esc = esc.last(); + + //scandisco il file solo se esiste + TScanner s(file); + while (s.ok()) + { + const TString& riga = s.line(); + if (riga.blank()) + continue; + + const int reclen = riga.len(); + + TDate datadoc; + long codcf = 0; + TCodice_articolo codart; + long qta; + long rotti; + long ndoc = 0; + TString16 tipo_conteggio; + TString80 operatore; + + //controllo quale tracciato record devo seguire + if (reclen == 34) // -> MONTANARI + { + nrighe++; + //leggo i campi dalla riga del file + const int d = atoi(riga.mid(0,2)); + const int m = atoi(riga.mid(2,2)); + const int y = atoi(riga.mid(4,4)); + if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) + { + datadoc = TDate(d, m, y); + if (datadoc < _msk->get_date(F_DADATA) || datadoc > _msk->get_date(F_ADATA)) + { + nrsalt++; + continue; + } + + const TString& codcf_str = riga.mid(8,6); codcf = atol(codcf_str); + codart = riga.mid(14,8); + qta = atol(riga.mid(22,6)); + rotti = atol(riga.mid(28,6)); + } + else + continue; + } + else if (reclen == 81 || reclen == 121) // ->SKEMA + { + //leggo i campi dalla riga del file + const int y = atoi(riga.mid(0,4)); + const int m = atoi(riga.mid(4,2)); + const int d = atoi(riga.mid(6,2)); + if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) + { + const TString& codcf_str = riga.mid(28,20); codcf = atol(codcf_str); + datadoc = TDate(d, m, y); + codart = riga.mid(8,20); + qta = atoi(riga.mid(48,11)); + ndoc = atoi(riga.mid(59,11)); + + switch (atoi(riga.mid(70,11))) + { + case 1: tipo_conteggio = "Automatico"; break; + case 2: tipo_conteggio = "Manuale"; break; + case 3: tipo_conteggio = "Scarto"; break; + default: break; + } + operatore = riga.mid(81,40); + } + else + continue; + } + + TToken_string key; key.format("C|%ld", codcf); + const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); + TLaundry_contract cont(codcf, codindsp, datadoc); + const TRectype& rcont = cont.row(codart.trim()); + + if (rcont.empty()) + { + TString str; + str << "L'articolo " << codart << " non è previsto nel contratto del cliente " << codcf; + lv_popup_msg(str); + + //ATTENZIONE: DEVE CHIEDERE CHE COSA FARE (Aggiungerlo o Ignorarlo) + } + + TArticolo_lavanderie& artrec = cached_article_laundry(codart, 'C', codcf, 0); + + //estraggo il record corrispondente su LF_CLIFOGIAC + const TRecmag_lavanderie& reclav = artrec.find_rec(last_esc); + + //leggo il record corrispondente + if(!reclav.empty()) + { + const real dotod = reclav.get_real(CLIFOGIAC_DOTOD); + + if (qta > dotod) + { + TString str; + str << "Attenzione! Il cliente " << codcf << " per l'articolo " << codart << " ha una dotazione di " + << dotod << " pezzi e ne sono stati ritirati " << qta << " (" << real(qta - dotod) << " in più)."; + lv_popup_msg(str); + } + } + + TQuantita_contate* qc = articoli.quantita(codcf, codart.trim(), datadoc, true); + + //se la chiave è già presente nel TAssoc_array, chiedi cosa fare delle quantità + //altrimenti aggiungila con la rispettiva al TAssoc_array con la quantità appena conteggiata + if (!qc->is_empty()) + { + TString str; + str << "ATTENZIONE: è già presente un conteggio per il cliente " << codcf << " sull'articolo " << codart << "\n" + << "Quantità conteggio attuale: " << qta << " Quantità conteggio precedente: " << qc->get_pezzi() << "\n" + << "Si desidera sommare le quantità?\n" + << "(SI -> Somma NO -> Ignora Conteggio ANNULLA -> Sosituisci il conteggio precedente)\n"; + + KEY k = yesnocancel_box(str); + + switch (k) + { + case K_YES: qc->add_pezzi(qta); qc->add_rotti(rotti); break; //sommo le quantità + case K_NO: break; //lascio tutto com'è + default: qc->set_pezzi(qta); qc->set_rotti(rotti); break; //sostituisco le quantità + } + } + else + { + qc->set_pezzi(qta); + qc->set_rotti(rotti); + } + } + return true; +} + +//CONTROLLA_DOCUMENTI: metodo che si occupa di controllare se i dati che sto inserendo in questo momento sono +//già stati inseriti in documenti precedenti, chiedendo cosa fare di volta in volta +void TAcquisizione_lavanderie_app::controlla_documenti(TLog_report& rep, TArticoli_contati& articoli, TAssoc_array& documenti) +{ + TConfronto_cache ca; + bool found = false; + FOR_EACH_ASSOC_OBJECT(articoli, obj, key, itm) + { + const TQuantita_contate* qc = (TQuantita_contate*)itm; + + //recupero i dati dalla chiave del TAssoc_array degli articoli + TArticoli_key keyart(key); + const long codcf = keyart.codcf(); + const TCodice_articolo codart = keyart.codart(); + const TDate datadoc = keyart.data(); + + //recupero i dati dal contenuto del TAssoc_array degli articoli + TQuantita_contate* quantita = new TQuantita_contate(qc->get_pezzi(), qc->get_rotti()); + + TDocumento& doc = ca.doc(datadoc, codcf); + if (doc.empty()) + { + //preparo la chiave per il TAssoc_array dei documenti + TDocumenti_key keydoc(datadoc.year(), 0, 0, codcf, codart, datadoc); + + //aggiungo la riga corrispondente + documenti.add(keydoc, quantita); + } + else + { + int idriga = 0; + FOR_EACH_PHYSICAL_RDOC(doc, r, prdoc) + { + //cerco se esiste già una riga sul documento selezionato per quell'articolo + const TRiga_documento& rdoc = *prdoc; + const TString& codart_doc = rdoc.get(RDOC_CODART); + + if (codart_doc == codart) + { + found = true; + idriga = r; + + TString str; + str << "ATTENZIONE: è già presente un buono di ritiro per il cliente " << codcf << " sull'articolo " << codart << "\n" + << "Quantità conteggio: " << quantita->get_pezzi() << " Quantità buono di ritiro: " << rdoc.get_int(RDOC_QTAGG1) << "\n" + << "Si desidera sommare le quantità?\n" + << "(SI -> Somma NO -> Ignora Conteggio ANNULLA -> Modifica Buono)\n"; + + const KEY k = yesnocancel_box(str); + switch (k) + { + case K_YES: quantita->add_pezzi(rdoc.get_real(RDOC_QTAGG1)); quantita->add_rotti(rdoc.get_real(RDOC_QTAGG2)); break; //sommo le quantità + case K_NO: break; //lascio tutto com'è + default: quantita->set_pezzi(rdoc.get_real(RDOC_QTAGG1)); quantita->set_rotti(rdoc.get_real(RDOC_QTAGG2)); break; //sostituisco le quantità + } + break; + } + } + + if (!found) idriga = 0; // Mi pare implicito!!! + //preparo la chiave per il TAssoc_array dei documenti + const TDocumenti_key keydoc(datadoc.year(), doc.get_long(DOC_NDOC), idriga, codcf, codart, datadoc); + documenti.add(keydoc, quantita); + found = false; + } + } + ca.destroy(); +} + +//metodo che effettivamente genera i buoni di ritiro, se l'utente ha confermato la sua intenzione a crearli +void TAcquisizione_lavanderie_app::genera_documenti(TLog_report& rep, TAssoc_array& documenti) +{ + TAcquisizione_cache ca; + + const bool giri = _msk->get_bool(F_RICGIRI); + FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) + { + TDocumenti_key keydoc(key); + const TString4 codnum = keydoc.codnum(); + const int anno = keydoc.anno(); + const int ndoc = keydoc.ndoc(); + int idriga = keydoc.idriga(); // May change + const int codcf = keydoc.codcf(); + const TString80 codart = keydoc.codart(); + const TDate datadoc = keydoc.data(); + + TQuantita_contate* qc = (TQuantita_contate*)itm; + const real qtacon = qc->get_pezzi(); + const real qtarotti = qc->get_rotti(); + + TToken_string key; + key.add('C'); + key.add(codcf); + const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); + const TLaundry_contract cont(codcf, codindsp, datadoc); + const TString8 codcont = cont.get(LVCONDV_CODCONT); + const TRectype& rcont = cont.row(codart); + + + TDocumento& doc = ca.doc(datadoc, codcf); + if (!giri) + { + const TDate oggi(TODAY); + doc.put("DATAPRCO", oggi); + } + + const TDate dtcons = doc.get_date("DATAPRCO"); + + TString4 causale = rcont.get(LVRCONDV_CAUSLAV); + if (causale.blank()) + causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"); + + // idriga NON è affidabile, per cui ricerco per codart + if (idriga > 0 && doc.body().exist(idriga) && doc[idriga].get(RDOC_CODARTMAG) != codart) + { + idriga = 0; // Invalidate by now + FOR_EACH_PHYSICAL_RDOC(doc, r, row) + { + if (row->get(RDOC_CODARTMAG) == codart) + { + idriga = r; + break; + } + } + } + + if (idriga > 0 && doc.body().exist(idriga)) + { + TRiga_documento& rdoc = doc[idriga]; + rdoc.put(RDOC_QTAGG1, qtacon); + rdoc.put(RDOC_QTAGG2, qtarotti); + } + else + { + const TRectype& anamag = cache().get(LF_ANAMAG, codart); + TString descrart; + descrart << anamag.get(ANAMAG_DESCR) << anamag.get(ANAMAG_DESCRAGG); + + TRiga_documento& rdoc = doc.new_row("22"); + rdoc.put(RDOC_CODART, codart); + if (descrart.len() > 50) + { + rdoc.put(RDOC_DESCR, descrart.left(50)); + rdoc.put(RDOC_DESCLUNGA, true); + rdoc.put(RDOC_DESCEST, descrart.sub(50)); + } + else + rdoc.put(RDOC_DESCR, descrart); + rdoc.put(RDOC_CODARTMAG, codart); + rdoc.put(RDOC_CHECKED, 'X'); + rdoc.put(RDOC_CODAGG1, causale); + rdoc.put(RDOC_QTAGG1, qtacon); + rdoc.put(RDOC_QTAGG2, qtarotti); + rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA)); + + //scrivo il magazzino + const TCausale_lavanderie cau(causale); + TCausale_magazzino rit(cau.causale_ritiro()); + TCausale_magazzino con(cau.causale_consegna()); + + TString8 magazzino, magazzinoc; + + if(rit.get("S10").full()) + magazzino = rit.get("S10").mid(0,5); + else + magazzino <file_list(files) > 0) + { + TFilename strname; + FOR_EACH_ARRAY_ROW(files, r1, row1) + { + strname = *row1; + elaborato |= elabora_file(strname, logrep, articoli, nrighe, nrsalt); + } + } + else + lv_popup_msg(TR("ATTENZIONE: non è stato trovato nessun file da elaborare")); + + bool genera = false; + if (elaborato) + { + controlla_documenti(logrep, articoli, documenti); + + genera = true; + + if (_mode >= alpAUTO) + { + if (nrsalt > 0) + { + TString str; + str << "Sono stati ricevuti " << nrighe << " record, di cui " << nrighe - nrsalt + << " sono stati elaborati correttamente" << " e " << nrsalt + << " ignorati."; + lv_popup_msg(str); + } + } + else + { + TString str; + str << "Sono stati ricevuti " << nrighe << " record, di cui " << nrighe - nrsalt + << " sono stati elaborati correttamente" << " e " << nrsalt + << " ignorati.\nSi desidera procedere con la generazione dei buoni di ritiro?"; + + genera = yesno_box(str); + } + + if (nrsalt == 0 || genera) + { + genera_documenti(logrep, documenti); + + //diagnostica + TAssoc_array buoni; + FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) + { + TDocumenti_key tmp = key; + TDoc_key kdoc(tmp.anno(), tmp.codnum(), tmp.ndoc()); + + if (!buoni.is_key(kdoc)) + buoni.add(kdoc, kdoc); + } + + if (_mode == alpGUI) + { + switch (buoni.items()) + { + case 0: warning_box(TR("Non è stato generato alcun buono di ritiro.")); break; + case 1: message_box(TR("E' stato generato un buono di ritiro.")); break; + default: message_box(FR("Sono stati generati %d buoni di ritiro."), buoni.items()); break; + } + } + FOR_EACH_ARRAY_ROW(files, r1, row1) + sposta_file(*row1); + } + + if (_mode == alpGUI) + { + TReport_book buc; + buc.add(logrep); + if (buc.pages() > 0) + buc.preview(); + + if (genera) + message_box(TR("Generazione terminata")); + else + warning_box(TR("Generazione interrotta")); + } + } + return genera; +} + +void TAcquisizione_lavanderie_app::main_loop() +{ + //lo lancio in automatico da linea di comando + if (_mode == alpAUTO) + { + if (_msk->some_file()) + { + _msk->send_key(K_SPACE, DLG_OK); + if (_msk->run() == K_ENTER) + transfer(); + } + } else + if (_mode == alpMONITOR) + { + const WINDOW task =TASK_WIN; + WINDOW tray = xvt_trayicon_create(task, 10220, name()); // Washing machine + if (tray != NULL_WIN) + xvt_vobj_set_visible(task, FALSE); + + xvt_timer_create(_msk->win(), 60 * 1000L); + while (_msk->run() == K_ENTER) + { + // potrebbe essere passata mezzanotte + const TDate d(TODAY); _msk->set(F_DADATA, d); _msk->set(F_ADATA, d); + xvt_vobj_set_visible(task, TRUE); + if (transfer()) + { + TExternal_app prelievo("lv2 -3 P -A"); + prelievo.run(); + } + xvt_vobj_set_visible(task, FALSE); + } + xvt_trayicon_destroy(tray); + } + else + while (_msk->run() == K_ENTER) + transfer(); +} + +int lv2600(int argc, char *argv[]) +{ + TAcquisizione_lavanderie_app a; + a.run (argc, argv, TR("Acquisizione da contapezzi")); + return 0; +} diff --git a/lv/lv2600a.uml b/lv/lv2600a.uml index 230f7eba4..cecae774e 100755 --- a/lv/lv2600a.uml +++ b/lv/lv2600a.uml @@ -48,9 +48,9 @@ BEGIN FLAGS "D" END -SPREADSHEET F_SHEET_NAME 78 10 +SPREADSHEET F_SHEET_NAME 78 -1 BEGIN - PROMPT 1 9 "Nomi" + PROMPT 1 10 "Nomi" ITEM "Nome file" END @@ -64,7 +64,7 @@ BEGIN PROMPT 1 1 "@bNome file" END -STRING F_S_NAME 255 66 +STRING F_S_NAME 260 66 BEGIN PROMPT 3 2 "File " FLAGS "D" @@ -98,4 +98,4 @@ BEGIN END ENDPAGE -ENDMASK \ No newline at end of file +ENDMASK diff --git a/lv/lv2900.cpp b/lv/lv2900.cpp index e2871bfbe..fe059f520 100755 --- a/lv/lv2900.cpp +++ b/lv/lv2900.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/lv/lv4100.cpp b/lv/lv4100.cpp index f4e3a6fb1..7411e9ac0 100755 --- a/lv/lv4100.cpp +++ b/lv/lv4100.cpp @@ -1,7 +1,9 @@ #include #include +#include #include #include +#include #include #include "../cg/cglib01.h" diff --git a/lv/lv4200.cpp b/lv/lv4200.cpp index 2495a2276..80c82353b 100755 --- a/lv/lv4200.cpp +++ b/lv/lv4200.cpp @@ -1,9 +1,11 @@ #include #include +#include #include #include #include #include +#include #include #include "../cg/cglib01.h" diff --git a/lv/lv4300.cpp b/lv/lv4300.cpp index cd10991ef..6c1999271 100755 --- a/lv/lv4300.cpp +++ b/lv/lv4300.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "../ce/ammce.h" @@ -85,8 +86,7 @@ bool TImporta_cesp_mask::on_field_event(TOperable_field& f, TField_event e, long case F_NAME: if (e == fe_button) { - TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), - "File@32"); + TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@32"); TFilename path = get(F_PATH); path.add("*.txt"); //files delle testate list_files(path, as.rows_array()); diff --git a/lv/lvlib.cpp b/lv/lvlib.cpp index ddafc9c8c..2ad6d8472 100755 --- a/lv/lvlib.cpp +++ b/lv/lvlib.cpp @@ -117,6 +117,20 @@ long lv_find_contract(const long codcf, const long indsped, const TDate& data) return cod; } +bool lv_popup_msg(const char* fmt, ...) +{ + char buff[256] = { 0 }; + va_list arg; + va_start(arg, fmt); + vsprintf_s(buff, sizeof(buff), fmt, arg); + va_end(arg); + if (strchr(buff, '!')) + xvt_dm_popup_warning(buff); + else + xvt_dm_popup_message(buff); + return false; +} + /////////////////////////////////////////////////////////// // TCache_articoli_lavanderie /////////////////////////////////////////////////////////// diff --git a/lv/lvlib.h b/lv/lvlib.h index 30d0358a3..d9318399c 100755 --- a/lv/lvlib.h +++ b/lv/lvlib.h @@ -402,4 +402,7 @@ public: TDoc_inventario(TDoc_inventario& dinv): TDocumento(dinv){}; }; +// Finestra di notifica per messaggi non troppo critici, tipice nelle elaborazioni batch +bool lv_popup_msg(const char* fmt, ...); + #endif