#include #include #include #include #include #include "lvlib.h" #include "../ve/velib.h" #include "lvcondv.h" #include "lvrcondv.h" #include "lvrconsplan.h" #include "lv2600a.h" ///////////////////////////////// //// 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) { 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; } TAcquisizione_msk::TAcquisizione_msk():TAutomask("lv2600a") { } /////////////////////////////////// //// 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(); 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* TAcquisizione_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(); if(_ndoc == 0) { TString query2; query2 << "USE DOC\n" << "FROM PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\"\n" << "TO PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\""; TISAM_recordset sporco(query2); sporco.move_last(); _ndoc = sporco.get(DOC_NDOC).as_int(); } TString query = "USE DOC KEY 2\n"; query << "SELECT (TIPODOC=\"" << _tipodoc << "\")&&(STATO=\"" << _stato <<"\")\n"; query << "FROM TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n"; query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n"; TISAM_recordset rset(query); TDocumento* doc = NULL; if (rset.move_first()) doc = new TDocumento(rset.cursor()->curr()); else { TLaundry_contract cont(codcf, 0, datadoc); const TString8 codcont = cont.get(LVCONDV_CODCONT); TString query1 = "USE LVRCONSPLAN KEY 3\n"; query1 << "FROM CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#DADATA\n"; query1 << "TO CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#ADATA\n"; TISAM_recordset consegne(query1); consegne.set_var("#DADATA", ++datadoc); 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); doc->put(DOC_DATADOC, datadoc); doc->put(DOC_TIPOCF, 'C'); doc->put(DOC_CODCF, codcf); doc->put(DOC_CODCONT, codcont); doc->put("DATACON", datadoc); //data conteggio doc->put("DATAGEN", datagen); //data generazione del documento doc->put("DATAPRCO", dataprco); //data prevista consegna } 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; } //////////////////////////////////////////// //// TACQUISIZIONE_LAVANDERIE_APP //// //////////////////////////////////////////// //classe TAcquisizione_lavanderie_app class TAcquisizione_lavanderie_app : public TSkeleton_application { TAcquisizione_msk* _msk; protected: virtual bool create(); virtual bool destroy(); void elabora_file(const TString& file, TLog_report &rep); 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(); open_files(LF_DOC, LF_RIGHEDOC); 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, creando i documenti void TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report &rep) { TAcquisizione_cache ca; bool sovrascrivi = true; bool nuovo_cliente = true; TAssoc_array deleted_docs; TAssoc_array clienti; //scandisco il file TScanner s(file); while (s.ok()) { TString80 riga = s.line(); if (riga.blank()) continue; TDate datadoc; long codcf = 0; TString8 codcf_str; TString80 codart; long qta; long rotti; long ndoc = 0; TString16 tipo_conteggio; TString80 operatore; //controllo quale tracciato record devo seguire if (riga.len() == 34) // -> MONTANARI { //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); 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; } else if (riga.len() == 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) { codcf_str = riga.mid(28,20); 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)); 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); if(!clienti.is_key(codcf_str)) { clienti.add(codcf_str,codcf_str); nuovo_cliente = true; } } else continue; } bool found = false; 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) { 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"; 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; } } 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); } } nuovo_cliente = false; //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)) { 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()) { long qtardoc = rdoc.get_long(RDOC_QTAGG1); qtardoc += qta; rdoc.put(RDOC_QTAGG1,qtardoc); found = true; break; } } if (!found) { const TRectype& anamag = cache().get(LF_ANAMAG, codart); TRiga_documento& rdoc = doc.new_row("22"); rdoc.put(RDOC_CODART, codart); rdoc.put(RDOC_DESCR, anamag.get(ANAMAG_DESCR)); 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); } } //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 { ca.destroy(); deleted_docs.destroy(); } } //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("Aquisizione da contapezzi"); logrep.kill_duplicates(true); //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 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) elabora_file(*row2, logrep); } else elabora_file(file, logrep); } } 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() { while (_msk->run() == K_ENTER) transfer(); } int lv2600(int argc, char *argv[]) { TAcquisizione_lavanderie_app a; a.run (argc, argv, "Acquisizione bolle di rientro/ritiro"); return TRUE; }