From 04f6d8525a4b47370179e6b64d6f172ff2a2957b Mon Sep 17 00:00:00 2001 From: luca83 Date: Tue, 6 Oct 2009 16:51:30 +0000 Subject: [PATCH] Patch level : 10.0 patch 45? Files correlati : lv2 Ricompilazione Demo : [ ] Commento : Corretto il programma tenendo conto di tutti i cambiamenti riportati nel documento redatto in occasione della riunione del 16/09 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aggiunta la gestione da linea di comando; per poter lanciare correttamente il programma la linea è lv2 -5 -A -G[s/n] /uUTENTE A seguito della G o S (tieni conto dei giri) o N (non tener conto dei giri) git-svn-id: svn://10.65.10.50/trunk@19388 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- lv/lv2600.cpp | 697 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 570 insertions(+), 127 deletions(-) diff --git a/lv/lv2600.cpp b/lv/lv2600.cpp index 40263ca96..c88c3e38b 100755 --- a/lv/lv2600.cpp +++ b/lv/lv2600.cpp @@ -14,6 +14,233 @@ #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(long codcf, TString& codart, TDate& data); + TArticoli_key(const char* 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, TString& codart, TDate& data) +{ + add(codcf); + add(codart.trim()); + add(data.date2ansi()); +} + +TArticoli_key::TArticoli_key(const char* key):TToken_string(key) +{ +} + + ////////////////////////////// + //// 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, TString& codart, 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_int(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, TString& codart, TDate& data) +{ + add(ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)")); + add(anno); + add(ndoc); + add(idriga); + add(codcf); + add(codart.trim()); + add(data.date2ansi()); +} + +TDocumenti_key::TDocumenti_key(const char* key):TToken_string(key) +{ +} + + ////////////////////////////////// + //// TQUANTITA_CONATATE //// + ////////////////////////////////// + +//classe TQuantita_contate +class TQuantita_contate: public TObject +{ + long _numpezzi; + long _numrotti; + +public: + const long get_pezzi() const; + const long get_rotti() const; + + void set_pezzi(const long qta); + void set_rotti(const long qta); + + void add_pezzi(const long qta); + void add_rotti(const long qta); + + bool is_empty(); + + TQuantita_contate(long pezzi = 0, long rotti = 0); +}; + +//GET_PEZZI: metodo che restituisce il numero di pezzi contati +const long TQuantita_contate::get_pezzi() const +{ + return _numpezzi; +} + +//GET_ROTTI: metodo che restituisce il numero di pezzi rotti contati +const long TQuantita_contate::get_rotti() const +{ + return _numrotti; +} + +//SET_PEZZI: metodo che setta il numero di pezzi contati +void TQuantita_contate::set_pezzi(const long qta) +{ + _numpezzi = qta; +} + +//SET_ROTTI: metodo che setta il numero di pezzi rotti contati +void TQuantita_contate::set_rotti(const long qta) +{ + _numrotti = qta; +} + +//ADD_PEZZI: metodo che somma i pezzi contati alla quantià che già esisteva +void TQuantita_contate::add_pezzi(const long qta) +{ + _numpezzi += qta; +} + +//ADD_PEZZI: metodo che somma i pezzi rotti contati alla quantià che già esisteva +void TQuantita_contate::add_rotti(const long 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(long pezzi, long rotti) +{ + set_pezzi(pezzi); + set_rotti(rotti); +} + + ////////////////////////////////// + //// TARTICOLI_CONTATI //// + ////////////////////////////////// + + +//classe TArticoli_contati +class TArticoli_contati: public TAssoc_array +{ +public: + TQuantita_contate* quantita(long codcf, TString& codart, 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, TString& codart, 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 //// ///////////////////////////////// @@ -30,35 +257,29 @@ public: //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) { - switch (f.dlg()) - { - case F_PATH: - //se il campo è vuoto, provo a scriverlo dalla configurazione - if (e == fe_init && f.empty()) - { - const TString& path = ini_get_string(CONFIG_DITTA, "lv", "PathContapezzi"); - if (path.full()) - f.set(path); - } - break; - case F_S_NAME: - if (e == fe_modify) - { - TFilename n = f.get(); - if (sfield(F_SHEET_NAME).items() == 1) - set(F_PATH, n.path()); - if (n.starts_with(get(F_PATH), true)) - f.set(n.name()); - } - break; - default: - break; - } return true; } +//metodo costruttore che precarica i campi di interesse sulla maschera TAcquisizione_msk::TAcquisizione_msk():TAutomask("lv2600a") { + TConfig* configlv = new TConfig(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++) + { + TString nomefile = configlv->get("FileName", NULL, i); + if (nomefile.empty()) + break; + + TToken_string& row = sheet.row(-1); + row.add(nomefile); + } + + sheet.force_update(); } /////////////////////////////////// @@ -93,6 +314,7 @@ TObject* TAcquisizione_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(); @@ -127,12 +349,11 @@ TObject* TAcquisizione_cache::key2obj(const char* key) 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", ++datadoc); + consegne.set_var("#DADATA", ++dadata); consegne.set_var("#ADATA", adata); consegne.move_first(); const TDate dataprco = consegne.get(LVRCONSPLAN_DTCONS).as_date(); - doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc); doc->put(DOC_TIPODOC, _tipodoc); doc->put(DOC_STATO, _stato); @@ -165,6 +386,74 @@ TAcquisizione_cache::TAcquisizione_cache() : TCache(17) _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 //// //////////////////////////////////////////// @@ -172,13 +461,18 @@ TAcquisizione_cache::TAcquisizione_cache() : TCache(17) //classe TAcquisizione_lavanderie_app class TAcquisizione_lavanderie_app : public TSkeleton_application { - TAcquisizione_msk* _msk; + TAcquisizione_msk* _msk; + TString4 _auto; + TString4 _gr; protected: virtual bool create(); virtual bool destroy(); - void elabora_file(const TString& file, TLog_report &rep); + 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(); @@ -192,6 +486,27 @@ bool TAcquisizione_lavanderie_app::create() 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() > 1) + { + _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->set(F_RICGIRI, ""); + open_files(LF_DOC, LF_RIGHEDOC); return TSkeleton_application::create(); @@ -204,16 +519,19 @@ bool TAcquisizione_lavanderie_app::destroy() return TApplication::destroy(); } -//ELABORA_FILE: metodo che effettivamente fa l'elaborazione del file, creando i documenti -void TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report &rep) +//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) { - TAcquisizione_cache ca; + //scandisco il file solo se esiste + TFilename strname = file; + if (!strname.exist()) + { + TString str; + str << "ATTENZIONE: il file " << strname << " non esiste!"; + warning_box(str); + return false; + } - bool sovrascrivi = true; - bool nuovo_cliente = true; - TAssoc_array deleted_docs; - TAssoc_array clienti; - //scandisco il file TScanner s(file); while (s.ok()) { @@ -233,24 +551,24 @@ void TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report //controllo quale tracciato record devo seguire if (riga.len() == 34) // -> MONTANARI { + nrighe += 1; //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) { - codcf_str = riga.mid(8,6); datadoc = TDate(d, m, y); - codcf = atol(codcf_str); + if (datadoc < _msk->get_date(F_DADATA) || datadoc > _msk->get_date(F_ADATA)) + { + nrsalt += 1; + continue; + } + + 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)); - - if(!clienti.is_key(codcf_str)) - { - clienti.add(codcf_str,codcf_str); - nuovo_cliente = true; - } } else continue; @@ -263,10 +581,9 @@ void TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report const int d = atoi(riga.mid(6,2)); if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) { - codcf_str = riga.mid(28,20); + codcf_str = riga.mid(28,20); codcf = atol(codcf_str); datadoc = TDate(d, m, y); codart = riga.mid(8,20); - codcf = atol(codcf_str); qta = atoi(riga.mid(48,11)); ndoc = atoi(riga.mid(59,11)); @@ -278,84 +595,152 @@ void TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report default: break; } operatore = riga.mid(81,40); - - if(!clienti.is_key(codcf_str)) - { - clienti.add(codcf_str,codcf_str); - nuovo_cliente = true; - } } else continue; } - bool found = false; + TQuantita_contate* qc = articoli.quantita(codcf, codart.trim(), datadoc, true); - TDocumento& doc = ca.doc(datadoc,codcf); - - //se sto elaborando un nuovo file, ma i documenti che sto importando esistono già, chiedi cosa devo fare - if (doc.rows() > 0 && nuovo_cliente) + //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: i dati per il cliente " << codcf << " erano già stati importati in precedenza!\n" - << "Si desidera continuare?\n" - << "Premendo SI il documento verrà sovrascritto;\n" - << "Premendo NO le quantità verranno sommate a quelle esistenti\n" - << "Premendo ANNULLA il documento non verrà modificato"; + 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" + << "Premendo SI le quatità verranno sommate;\n" + << "Premendo NO il conteggio precedente verrà sostituito con quello attuale\n" + << "Premendo ANNULLA verrà mantenuto il conteggio precedente"; KEY k = yesnocancel_box(str); + switch (k) { - case K_YES: sovrascrivi = true; break; - case K_NO: sovrascrivi = false; break; - default: //in questo modo viene chiesto una sola volta per cliente - { - nuovo_cliente = false; - continue; - } - break; - } + case K_YES: qc->add_pezzi(qta); qc->add_rotti(rotti); break; //sommo le quantità + case K_NO: qc->set_pezzi(qta); qc->set_rotti(rotti); break; //sostituisco le quantità + default: break; //lascio tutto com'è + } } else { - if (!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); - } + qc->set_pezzi(qta); + qc->set_rotti(rotti); } + } + return true; +} - nuovo_cliente = false; +//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) + { + TArticoli_key keyart(key); + const TQuantita_contate* qc = (TQuantita_contate*)itm; - //se voglio sovrascrivere i file, e non l'ho mai cancellato, allora svuotalo effettivamente - const TString8 numdoc = doc.get(DOC_NDOC); - if (sovrascrivi && !deleted_docs.is_key(numdoc)) + //recupero i dati dalla chiave del TAssoc_array degli articoli + int codcf = keyart.codcf(); + TString80 codart = keyart.codart(); + TDate datadoc = keyart.data(); + + //recupero i dati dal contenuto del TAssoc_array degli articoli + TQuantita_contate* quantita = new TQuantita_contate(0, 0); + quantita->set_pezzi(qc->get_pezzi()); + quantita->set_rotti(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 { - doc.destroy_rows(); - deleted_docs.add(numdoc, numdoc); - } - - for (int i = 1; i <= doc.rows(); i++) - { - //cerco se esiste già una riga sul documento selezionato per quell'articolo; - //se la trovo sommo la quantità appena letta a quella già esistente, - //altrimenti creo una nuova riga documento - TRiga_documento& rdoc = doc[i]; - TString80 codart_doc = rdoc.get(RDOC_CODART); - codart_doc.trim(); - - if (codart_doc == codart.trim()) + int idriga; + for (idriga = 1; idriga <= doc.rows(); idriga++) { - long qtardoc = rdoc.get_long(RDOC_QTAGG1); - qtardoc += qta; - rdoc.put(RDOC_QTAGG1,qtardoc); - found = true; - break; + //cerco se esiste già una riga sul documento selezionato per quell'articolo + TRiga_documento& rdoc = doc[idriga]; + TString80 codart_doc = rdoc.get(RDOC_CODART); codart_doc.trim(); + + if (codart_doc == codart) + { + found = true; + + 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" + << "Premendo SI le quatità verranno sommate;" + << "Premendo NO la quantità sul buono verrà sostitiuita con quella conteggiata;" + << "Premendo ANNULLA il buono non verrà modificato"; + KEY k = yesnocancel_box(str); + + switch (k) + { + case K_YES: quantita->add_pezzi(rdoc.get_int(RDOC_QTAGG1)); quantita->add_rotti(rdoc.get_int(RDOC_QTA)); break; //sommo le quantità + case K_NO: break; //sostituisco le quantità + default: quantita->set_pezzi(rdoc.get_int(RDOC_QTAGG1)); quantita->set_rotti(rdoc.get_int(RDOC_QTA)); break; //lascio tutto com'è + } + break; + } } + + if (!found) + idriga = 0; + //preparo la chiave per il TAssoc_array dei documenti + TDocumenti_key keydoc(datadoc.year(), doc.get_long(DOC_NDOC), idriga, codcf, codart, datadoc); + + documenti.add(keydoc, quantita); } + } + ca.destroy(); +} - if (!found) +//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(); + const int idriga = keydoc.idriga(); + const int codcf = keydoc.codcf(); + const TString80 codart = keydoc.codart(); + const TDate datadoc = keydoc.data(); + + TQuantita_contate* qc = (TQuantita_contate*)itm; + const long qtacon = qc->get_pezzi();; + const long qtarotti = qc->get_rotti(); + + TLaundry_contract cont(codcf, 0, datadoc); + const TString8 codcont = cont.get(LVCONDV_CODCONT); + + TDate oggi(TODAY); + + TDocumento& doc = ca.doc(datadoc, codcf); + if (!giri) + doc.put("DATAPRCO", oggi); + + if (doc.rows() > 0 && (idriga > 0 && idriga <= doc.rows())) + { + TRiga_documento& rdoc = doc[idriga]; + rdoc.put(RDOC_QTAGG1, qtacon); + rdoc.put(RDOC_QTA, qtarotti); + } + else { const TRectype& anamag = cache().get(LF_ANAMAG, codart); @@ -365,31 +750,43 @@ void TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report rdoc.put(RDOC_CODARTMAG, codart); rdoc.put(RDOC_CHECKED, 'X'); rdoc.put(RDOC_CODAGG1, ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV")); - rdoc.put(RDOC_QTAGG1, qta); - rdoc.put(RDOC_QTA, rotti); + rdoc.put(RDOC_QTAGG1, qtacon); + rdoc.put(RDOC_QTA, qtarotti); + } + + if (!doc.get_date("DATAPRCO").ok() && giri) + { + 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); } } - //rinomino il file in uso - TFilename fnameini(file); - TFilename fnamefin = fnameini; - fnamefin.insert("_sav", fnameini.find(".dat")); - - //se non faccio la close non posso rimuovere il file - s.close(); - fcopy(fnameini, fnamefin); - fnameini.fremove(); - if (ca.empty()) { warning_box(TR("ATTENZIONE: il file importato non ha generato nessun documento; controllare che il tracciato record sia coerente")); return; } - else - { + else ca.destroy(); - deleted_docs.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); + + if (fcopy(fileori, filedest)) + fileori.fremove(); } //TRANSFER: metodo che scorre i campi nome e, se sono pieni, richiama il metodo @@ -403,10 +800,16 @@ bool TAcquisizione_lavanderie_app::transfer() TLog_report logrep("Aquisizione 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; FOR_EACH_SHEET_ROW(sheet, r1, row1) { if(row1->full()) @@ -425,25 +828,65 @@ bool TAcquisizione_lavanderie_app::transfer() list_files(file, lista_file); FOR_EACH_ARRAY_ROW(lista_file, r2, row2) - elabora_file(*row2, logrep); + elaborato = elabora_file(*row2, logrep, articoli, nrighe, nrsalt); } else - elabora_file(file, logrep); + elaborato = elabora_file(file, logrep, articoli, nrighe, nrsalt); } } - - TReport_book buc; - buc.add(logrep); - if (buc.pages() > 0) - buc.preview(); - else - message_box(TR("Generazione terminata")); + + if(elaborato) + { + controlla_documenti(logrep, articoli, documenti); + 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_documenti(logrep, documenti); + + 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) + sposta_file(*row2); + } + else + sposta_file(file); + } + } + } + + TReport_book buc; + buc.add(logrep); + if (buc.pages() > 0) + buc.preview(); + else + message_box(TR("Generazione terminata")); + } 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(); }