#include #include #include #include #include #include #include #include #include "pt0002.h" #include "pt0002100a.h" #include "../cg/cglib01.h" #include "clifo.h" #include "comuni.h" /////////////////////////////////////////////////////////// // TClient_textset /////////////////////////////////////////////////////////// class TClifo_recset : public TCSV_recordset { TAssoc_array _index; protected: virtual TRecnotype new_rec(const char* buf = NULL); public: const TString& rag_sociale() const; TClifo_recset(const char * query); }; TRecnotype TClifo_recset::new_rec(const char* buf) { TToken_string str(256,'\t'); //nuovo record tab separator if(buf && *buf) { bool apici=false; for (const char* c = buf; *c ; c++) { if (*c == '"') { apici = !apici; } else { if (*c == ',') { if (!apici) str << str.separator(); else str << *c; } else str << *c; } } } const TRecnotype n = TText_recordset::new_rec(str); if (n >= 0) row(n).separator(str.separator()); return n; } //funzione che crea il campo ragione sociale dai primi 2 campi del file csv const TString& TClifo_recset::rag_sociale() const { const TString& nome = get(1).as_string(); TString ragsoc = get(0).as_string(); if (nome.full()) { ragsoc.cut(30); ragsoc.left_just(30); ragsoc << nome; } ragsoc.cut(50); return get_tmp_string() = ragsoc; } TClifo_recset::TClifo_recset(const char * fileName) : TCSV_recordset("CSV(,)\n") { load_file(fileName); } /////////////////////////////////////////////////////////// // TAutomask /////////////////////////////////////////////////////////// class TImportaClifo_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TImportaClifo_mask(); }; TImportaClifo_mask::TImportaClifo_mask() :TAutomask ("pt0002100a") { } bool TImportaClifo_mask::on_field_event(TOperable_field& f, TField_event e, long jolly) { switch (f.dlg()) { //giochetto per avere la lista dei files validi nella directory di trasferimento! case F_NAME: if (e == fe_button) { TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@32"); TFilename path = get(F_PATH); path.add("*.csv"); //files delle testate list_files(path, as.rows_array()); TFilename name; FOR_EACH_ARRAY_ROW(as.rows_array(), i, row) { name = *row; *row = name.name(); } if (as.run() == K_ENTER) { f.set(as.row(as.selected())); } } break; default: break; } return true; } /////////////////////////////////////// // TSkeleton_application /////////////////////////////////////// class TClifoCSV : public TSkeleton_application { virtual bool check_autorization() const {return false;} virtual const char * extra_modules() const {return "ve";} TImportaClifo_mask* _msk; TConfig* _configfile; protected: long find_clifo(const char tipo, const TString& cofi, const TString& paiv, const TString& ragsoc) const; bool safe_put(TLocalisamfile& clienti, const char* field, const char* val) const; long find_last_clifo(const char tipo) const; void pulisci_cap(TString& cap) const; public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); virtual void ini2mask(); virtual void mask2ini(); bool transfer(const TFilename& file); TClifoCSV() {}; }; TClifoCSV& app() { return (TClifoCSV&) main_app(); } ///////////////////////////////// // ricerca clifo ///////////////////////////////// //funzione che ricerca un cliente o un fornitore nel file clifo di campo //restituisce 0 (zero) se non lo trova, se no cerca il pių simile possibile long TClifoCSV::find_clifo(const char tipo, const TString& cofi, const TString& paiv, const TString& ragsoc) const { long found=0; TRelation clifo(LF_CLIFO); TRectype& rec = clifo.curr(); TString up_ragsoc = ragsoc; up_ragsoc.upper(); for (int key = 4; key<=5 && !found; key++) { bool good_key = false; // Assumiamo che la chiave sia icompleta rec.zero(); rec.put(CLI_TIPOCF,tipo); switch (key) { case 4: rec.put(CLI_COFI,cofi); good_key = cofi.full(); break; case 5: rec.put(CLI_PAIV,paiv); good_key = paiv.full(); break; default: break; } if (good_key) // Se la chiave e' completa ... cerco bene { TCursor cur(&clifo,"", key, &rec, &rec); const TRecnotype items = cur.items(); if (items > 0) { double best = -1; TString80 cur_ragsoc; cur.freeze(); for (cur=0; cur.pos() < items; ++cur) { cur_ragsoc = rec.get(CLI_RAGSOC); cur_ragsoc.upper(); // funzione che mi dice quanto due stringhe si assomiglino const double var = xvt_str_fuzzy_compare(up_ragsoc, cur_ragsoc); if (var > best) { best = var; found = rec.get_long(CLI_CODCF); } } } } } return found; } ///////////////////////////////// // aggiornamento clifo ///////////////////////////////// //funzione che effettua la put solo se non cerco di inserire un campo vuoto bool TClifoCSV::safe_put(TLocalisamfile& file, const char* field, const char* val) const { const bool ok = val && *val; if (ok) file.put(field, val); return ok; } //funzione che trova il primo codice libero di un cliento o di un fornitore long TClifoCSV::find_last_clifo(const char tipo) const { TLocalisamfile clifo(LF_CLIFO); long codcf = 1L ; if (tipo == 'C') { clifo.put(CLI_TIPOCF, 'F'); if (clifo.read(_isgteq) == NOERR) clifo.prev(); else clifo.last(); if (clifo.get_char(CLI_TIPOCF) == 'C') codcf += clifo.get_long(CLI_CODCF); } else { clifo.last(); if (clifo.get_char(CLI_TIPOCF) == 'F') codcf+=clifo.get_long(CLI_CODCF); } return codcf; } void TClifoCSV::pulisci_cap(TString& cap) const { TString8 str; for (int i = 0; cap[i] && str.len() < 5; i++) if (isdigit(cap[i])) str << cap[i]; cap = str; } bool TClifoCSV::transfer(const TFilename& file) { const char tipo = _msk->get(F_TIPO)[0]; const char* head = tipo == 'C' ? TR("Trasferimento clienti") : TR("Trasferimento fornitori"); TLog_report log(head); TClifo_recset s(file); TLocalisamfile clifo(LF_CLIFO); TProgind pi(s.items(),head,true,true); for (bool ok=s.move_first();ok;ok=s.move_next()) { if (!pi.addstatus(1)) break; const TString ragsoc = s.rag_sociale(); if (ragsoc.full()) { const TString16 cofi = s.get(2).as_string(); //get da file del cod. fisc. const TString16 paiv = s.get(3).as_string(); //get da file della p. iva const long var = find_clifo(tipo,cofi,paiv,ragsoc); //controllo se il clifo esiste giā clifo.zero(); clifo.put(CLI_TIPOCF, tipo); if (var) { //se esiste leggo il record corrispondente clifo.put(CLI_CODCF,var); clifo.read(); } else { //se no ne creo uno nuovo long codcf = find_last_clifo(tipo); clifo.put(CLI_CODCF, codcf); } safe_put(clifo, CLI_RAGSOC, ragsoc); //ragsoc if (!var) safe_put(clifo, CLI_TIPOAPER, s.get(1).is_empty() ? "G" : "F"); safe_put(clifo, CLI_PAIV, paiv); //p.iva safe_put(clifo, CLI_COFI, cofi); //cod. fisc. safe_put(clifo, CLI_INDCF, s.get(4).as_string()); //indirizzo safe_put(clifo, CLI_CIVCF, s.get(5).as_string()); //num. civico if (s.get(6).as_string().empty()) //italiano { TString cap = s.get(9).as_string(); pulisci_cap(cap); TString80 comune = s.get(11).as_string(); //comune o localita' comune.trim(); safe_put(clifo, CLI_CAPCF, cap); //cap const TString& codcom = cap2comune(cap, comune); if (codcom.blank()) { if (s.get(10).as_string().full()) comune << " (" << s.get(10).as_string() << ')'; //inserisce la localitā se non trova un comune safe_put(clifo, CLI_LOCCF, comune); } else safe_put(clifo, CLI_COMCF, codcom); } else { TString comune = s.get(7).as_string(); comune << ", " << s.get(8).as_string() << '(' << s.get(6).as_string() <<')'; //inserisce la localitā estera safe_put(clifo, CLI_LOCCF, comune); if (!var) safe_put(clifo, CLI_ALLEG, "5"); // Cliente/Fornitore Estero } const char* tp = tipo == 'C' ? TR("Cliente") : TR("Fornitore"); TString str; str << "Il "<< tp << " codice (" << clifo.get(CLI_CODCF) <<") " << ragsoc << " "; if (var) { const int err = clifo.rewrite(); if (err == NOERR) { str << "č stato aggiornato"; log.log(0, str); } else { str << "NON č stato aggiornato. Errore " << err; log.log(2, str); } } else { const int err = clifo.write(); if (err == NOERR) { str << "č stato inserito"; log.log(0, str); } else { str << "NON č stato inserito. Errore " << err; log.log(2, str); } } if (cofi.empty() && paiv.empty()) { TString str; str << "Il " << tp << ' ' << ragsoc << " non ha nč CODICE FISCALE nč PARTITA IVA"; log.log(1, str); } } } TReport_book buc; buc.add(log); buc.preview(); return true; } void TClifoCSV::mask2ini() { //carica i parametri del file di configurazione _configfile->set_paragraph("MAIN"); for (int i = 0; i < _msk->fields() ; i++) { TMask_field& f = _msk->fld(i); const TFieldref* fr = f.field(); if (fr != NULL) _configfile->set(fr->name(), f.get()); } } void TClifoCSV::ini2mask() { //carica i parametri del file di configurazione _configfile->set_paragraph("MAIN"); for (int i = 0; i < _msk->fields() ; i++) { TMask_field& f = _msk->fld(i); const TFieldref* fr = f.field(); if (fr != NULL) f.set(_configfile->get(fr->name())); } } bool TClifoCSV::create() { _configfile = new TConfig("pt0002conf.ini"); _msk = new TImportaClifo_mask(); return TSkeleton_application::create(); } bool TClifoCSV::destroy() { delete _msk; delete _configfile; return TApplication::destroy(); } void TClifoCSV::main_loop() { KEY tasto; ini2mask(); tasto = _msk->run(); if (tasto == K_ENTER) { mask2ini(); //genero il nome del file da caricare TFilename name = _msk->get(F_PATH); name.add(_msk->get(F_NAME)); if (transfer(name)) { message_box(TR("Importazione documenti completata")); } } } int pt0002100 (int argc, char* argv[]) { TClifoCSV main_app; main_app.run(argc, argv, TR("Importazione Clienti/Fornitori")); return true; }