#include #include #include #include #include #include #include "../cg/cglib01.h" #include "ps0430400a.h" #include "../ve/velib.h" #include "../cg/cfban.h" #include "cfven.h" /////////////////////////////////////////////////////////// // TCBA_recset /////////////////////////////////////////////////////////// class TCBA_recset : public TCSV_recordset { public: virtual const TVariant& get(unsigned int column) const; TDate get_date(unsigned int column) const; TCBA_recset() : TCSV_recordset("CSV(;)") {} }; const TVariant& TCBA_recset::get(unsigned int column) const { const TVariant& var = TCSV_recordset::get(column); if (var.is_string()) { const TString& str = var.as_string(); if (str[0] == '"') ((TString&)str).strip("\""); } return var; } TDate TCBA_recset::get_date(unsigned int column) const { const TVariant& var = TCSV_recordset::get(column); const long v = var.as_int(); const int d = v / 1000000; const int m = (v / 10000) % 100; const int y = v % 10000; return TDate(d, m, y); } /////////////////////////////////////////////////////////// // TImport_mask /////////////////////////////////////////////////////////// class TImport_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TImport_mask() : TAutomask("ps0430400a") {} }; bool TImport_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_CLI: case F_FAT: if (e == fe_button) { TFilename n = get(F_DIR); n.add("*.csv"); if (input_filename(n)) o.set(n.name()); } else if (e == fe_close) { TFilename n = get(F_DIR); n.add(o.get()); if (!n.exist()) return cantread_box(n); } break; default: break; } return true; } /////////////////////////////////////////////////////////// // TImport_app /////////////////////////////////////////////////////////// class TImport_app : public TSkeleton_application { protected: virtual const char* extra_modules() const { return "cm|ve"; } virtual void main_loop(); public: void cli_ragsoc(const TCBA_recset& cli, TString& ragsoc) const; long find_customer(const TString& cf_pi, const TString& codpag, const TString& ragsoc) const; const TRectype& find_codart(TString& codart) const; bool find_or_create_clifo(const TCBA_recset& cli, TLocalisamfile& clifo, const TString& cdc, TLog_report& log) const; const TString& get_periodo(const TCBA_recset& fat) const; void aggiorna_referente(long codcf, const char* ospite) const; bool importa_clienti(const TFilename& fname, const TString& cdc, TLog_report& log) const; bool importa_fatture(const TFilename& fname, const TString& codnum, const TString& cdc, TLog_report& log) const; }; static void normalize_code(TString& code) { code.trim(); if (code.not_empty()) { code.upper(); if (code.len() < 11 && real::is_natural(code)) code.right_just(11, '0'); } } long TImport_app::find_customer(const TString& cf_pi, const TString& codpag, const TString& ragsoc) const { long codice = 0L; if (cf_pi.blank() || cf_pi.len() < 9) return codice; TString20 cod = cf_pi; normalize_code(cod); const bool numeric = cod.len() < 16 && real::is_natural(cod); // Tento prima il codice fiscale o la partita IVA? const char* const cofi_paiv = numeric ? "PC" : "CP"; for (int t = 0; t < 2 && codice <= 0; t++) { const int key = cofi_paiv[t] == 'C' ? 4 : 5; TString query; query << "USE " << LF_CLIFO << " KEY " << key; for (int f = 0; f < 2; f++) query << (f ? "\nTO " : "\nFROM ") << CLI_TIPOCF << "=C " << (key==4 ? CLI_COFI : CLI_PAIV) << '=' << cod; TISAM_recordset recset(query); if (recset.move_first()) { codice = recset.get(CLI_CODCF).as_int(); const TRecnotype candidates = recset.items(); if (candidates > 1) // Cliente ambiguo { if (ragsoc.full()) // Ricerca da clifo { codice = 0; for (TRecnotype i = 0; recset.move_to(i); i++) { TString80 kr; recset.get(CLI_RAGSOC).as_string(kr); if (ragsoc == kr) { codice = recset.get(CLI_CODCF).as_int(); break; } } } else if (codpag.full()) // Ricerca da fatt { TRecnotype best = -1; for (TRecnotype i = 0; recset.move_to(i); i++) { TString4 kp; recset.get(CLI_CODPAG).as_string(kp); if (codpag == kp || (kp.blank() && best < 0)) { best = i; if (codpag == kp) break; } } if (best > 0) { recset.move_to(best); codice = recset.get(CLI_CODCF).as_int(); } } } } } return codice; } const TRectype& TImport_app::find_codart(TString& cod) const { cod.trim(); cod.upper(); const TRectype& anamag = cache().get(LF_ANAMAG, cod); return anamag; } void TImport_app::cli_ragsoc(const TCBA_recset& cli, TString& ragsoc) const { TString80 rs1, rs2; cli.get(6).as_string(rs1); rs1.trim(); cli.get(7).as_string(rs2); rs2.trim(); TString80 str; if (rs2.blank()) { const int spc = rs1.find(' '); if (spc > 0) { str = rs1.left(spc); str.left_just(30); str << rs1.mid(spc+1); } } if (str.blank()) { str << rs1 << ' ' << rs2; str.strip_double_spaces(); } TParagraph_string ps(str, 50); ragsoc = ps.get(); } bool TImport_app::find_or_create_clifo(const TCBA_recset& cli, TLocalisamfile& clifo, const TString& cdc, TLog_report& log) const { TString16 piva; cli.get(1).as_string(piva); TString20 cofi; cli.get(2).as_string(cofi); TString80 ragsoc; cli_ragsoc(cli, ragsoc); TString4 codpag; cli.get(20).as_string(codpag); if (piva.blank() && cofi.blank()) { TString msg; msg << ragsoc << TR(" non ha nč codice fiscale nč partita IVA") << TR(" alla riga ") << (cli.current_row()+1); log.log(2, msg); return false; } long codcf = 0; if (cofi.full()) codcf = find_customer(cofi, codpag, ragsoc); if (codcf <= 0 && piva.full()) codcf = find_customer(piva, codpag, ragsoc); if (codcf > 0) { clifo.setkey(1); clifo.zero(); clifo.put(CLI_TIPOCF, 'C'); clifo.put(CLI_CODCF, codcf); return clifo.read() == NOERR; } long next_clifo = 1; TISAM_recordset recset("USE CLIFO\tTO TIPOCF=C"); if (recset.move_last()) next_clifo += recset.get(CLI_CODCF).as_int(); clifo.setkey(1); clifo.zero(); clifo.put(CLI_TIPOCF, 'C'); clifo.put(CLI_CODCF, next_clifo); clifo.put(CLI_RAGSOC, ragsoc); normalize_code(cofi); clifo.put(CLI_COFI, cofi); normalize_code(piva); clifo.put(CLI_PAIV, piva); const int err = clifo.write(); if (err != NOERR) { TString msg; msg << TR("Impossibile creare l'anagrafica di ") << ragsoc << TR(" alla riga ") << (cli.current_row()+1); log.log(2, msg); } return err == 0; } bool TImport_app::importa_clienti(const TFilename& fname, const TString& cdc, TLog_report& log) const { TString str = TR("Importazione clienti"); log.log(0, str); TLocalisamfile clifo(LF_CLIFO); TLocalisamfile cfven(LF_CFVEN); TCBA_recset cli; cli.load_file(fname); long clifos = 0; bool done = true; TProgress_monitor pi(cli.items(), str); for (bool ok = cli.move_first(); ok && done; ok = cli.move_next()) { if (cli.get(0).is_empty()) // Salta righe vuote continue; done = find_or_create_clifo(cli, clifo, cdc, log); if (!done) break; // Aggiorna dati cliente TString16 piva; cli.get(1).as_string(piva); normalize_code(piva); TString20 cofi; cli.get(2).as_string(cofi); normalize_code(cofi); const int privato = cli.get(27).as_int(); TRectype& curr = clifo.curr(); curr.put(CLI_PAIV, piva); curr.put(CLI_COFI, cofi); if (cofi.len() == 16) { curr.put(CLI_SESSO, cofi[9] > '3' ? 'F': 'M'); curr.put(CLI_COMNASC, cofi.mid(11, 4)); } TString80 ragsoc; cli_ragsoc(cli, ragsoc); curr.put(CLI_RAGSOC, ragsoc); curr.put(CLI_REFERENTE, curr.get(CLI_RAGSOC)); const TString& indir = cli.get(8).as_string(); curr.put(CLI_INDCF, indir); if (isdigit(indir.right(1)[0])) curr.zero(CLI_CIVCF); const TString80 loc = cli.get(10).as_string(); curr.put(CLI_LOCCF, loc); const TString8 cap = cli.get(9).as_string(); curr.put(CLI_CAPCF, cap); const int naz = cli.get(16).as_int(); if (naz == 0) { const TString& com = cap2comune(cap, loc); curr.put(CLI_COMCF, com); } int alleg = 0; if (privato == 1) alleg = 6; else { if (naz > 0) alleg = naz == 1 ? 5 : 9; else { if (piva.blank()) alleg = real::is_natural(cofi) ? 7 : 6; } } curr.put(CLI_ALLEG, alleg); const TString8 abi = cli.get(17).as_string(); const TString8 cab = cli.get(18).as_string(); const TString80 numcc = cli.get(23).as_string(); if (abi.len() == 5 && cab.len() == 5) { TToken_string key; key = "C"; key.add(curr.get(CLI_CODCF)); key.add("N"); TRecord_array nsban(key, LF_CFBAN); TRectype& rec = nsban.row(1, true); rec.put(CFBAN_ABI, abi); rec.put(CFBAN_CAB, cab); rec.put(CFBAN_NUMCC, numcc); key.cut(0) << abi << cab; const TString& iban = cache().get("BNP", key, "S3"); rec.put(CFBAN_IBAN, iban); const int err = nsban.rewrite(); if (err != NOERR) { ragsoc.strip_double_spaces(); str.cut(0) << TR("Impossibile aggiornare la banca di ") << ragsoc << TR(" alla riga ") << (cli.current_row()+1); log.log(1, str); } // Copialo anche sul cliente per tradizione curr.put(CLI_CODABI, abi); curr.put(CLI_CODCAB, cab); curr.put(CLI_NUMCC, numcc); } curr.put(CLI_CODPAG, cli.get(20).as_string()); curr.put(CLI_MAIL, cli.get(28).as_string()); const int err = clifo.rewrite(); if (err == NOERR) { clifos++; } else { ragsoc.strip_double_spaces(); str.cut(0) << TR("Impossibile aggiornare l'anagrafica di ") << ragsoc << TR(" alla riga ") << (cli.current_row()+1); log.log(2, str); break; } if (cdc.full()) { cfven.setkey(1); cfven.zero(); cfven.put(CFV_TIPOCF, 'C'); cfven.put(CFV_CODCF, curr.get(CLI_CODCF)); if (cfven.read() != NOERR) { cfven.zero(); cfven.put(CFV_TIPOCF, 'C'); cfven.put(CFV_CODCF, curr.get(CLI_CODCF)); cfven.write(); } cfven.put(CFV_CODPRCF, cdc.right(3)); cfven.rewrite(); } done = pi.add_status(); } log.log(0, str.cut(0)); str << TR("Sono state importate/aggiornate ") << clifos << TR(" anagrafiche"); log.log(0, str); log.log(0, str.cut(0)); return done; } void TImport_app::aggiorna_referente(long codcf, const char* ospite) const { TLocalisamfile clifo(LF_CLIFO); clifo.put(CLI_TIPOCF, 'C'); clifo.put(CLI_CODCF, codcf); if (clifo.read(_isequal, _lock) == NOERR) { clifo.put(CLI_REFERENTE, ospite); clifo.rewrite(); } } const TString& TImport_app::get_periodo(const TCBA_recset& fat) const { TString80 periodo; fat.get(10).as_string(periodo); if (periodo[0] >= '0' && periodo[0] <= '9' && periodo.len() > 4) { const int mese = atoi(periodo.left(periodo.len()-4)); if (mese >= 1 && mese < 12) { int anno = atoi(periodo.right(4)); periodo = itom(mese); if (anno < 2000) anno = fat.get(9).as_int(); periodo << ' ' << anno; } } return get_tmp_string() = periodo; } static bool save_doc(TDocumento& doc, long& ndocs, long& mindoc, long& maxdoc, TLog_report& log) { const int err = doc.write(); if (err == NOERR) { ndocs++; maxdoc = doc.get_long(DOC_NDOC); if (ndocs == 1) mindoc = maxdoc; } else { TString str; str.format("Impossibile registrare il documento %s/%ld", (const char*)doc.get(DOC_CODNUM), maxdoc+1); log.log(2, str); } return err == 0; } static void save_rdoc_desc(const TString& desc, TRiga_documento& rdoc) { if (desc.len() > 50) { TParagraph_string p(desc, 50); rdoc.put(RDOC_DESCR, p.get()); const int sep = p.find(p.separator()); if (sep > 0) { rdoc.put(RDOC_DESCLUNGA, "X"); TString tmp = p.mid(sep+1); tmp.replace(p.separator(), ' '); tmp.strip_double_spaces(); tmp.insert("\n"); rdoc.put(RDOC_DESCEST, tmp); } } else rdoc.put(RDOC_DESCR, desc); } bool TImport_app::importa_fatture(const TFilename& fname, const TString& codnum, const TString& cdc, TLog_report& log) const { TString str = TR("Importazione documenti"); log.log(0, str); TCBA_recset fat; fat.load_file(fname); long ndocs = 0; long mindoc = 0; long maxdoc = 0; bool done = true; long codcf = 0; TString80 cofi_paiv; TString4 codpag; TString periodo; TToken_string ospiti(256, '@'); TDocumento* doc = NULL; TProgress_monitor pi(fat.items(), str); for (bool ok = fat.move_first(); ok && done; ok = fat.move_next()) { const char tipo = fat.get(8).as_string()[0]; if (tipo == 'T') { if (doc != NULL) { save_doc(*doc, ndocs, mindoc, maxdoc, log); delete doc; doc = NULL; } fat.get(11).as_string(codpag); fat.get(14).as_string(cofi_paiv); normalize_code(cofi_paiv); codcf = find_customer(cofi_paiv, codpag, EMPTY_STRING); if (codcf <= 0) { str.format("Impossibile associare un cliente al codice '%s' alla riga %ld", (const char*)cofi_paiv, fat.current_row()+1); log.log(2, str); } periodo = get_periodo(fat); // 10 + 9 fat.get(15).as_string(ospiti); const char* ospite = ospiti.get(0); if (codcf > 0 && ospite && *ospite > ' ') aggiorna_referente(codcf, ospite); continue; } if (tipo != 'N' || codcf <= 0) continue; // Considera solo le righe articolo di clienti validi const TDate datadoc = fat.get_date(5); const long ndoc = fat.get(6).as_int(); if (!datadoc.ok() || ndoc <= 0) { str.format("Data o numero documento nulli alla riga %ld", fat.current_row()+1); log.log(2, str); continue; } TCodice_articolo codart; codart << fat.get(12); codart.trim(); codart << '.' << cdc.right(3); const TRectype& anamag = find_codart(codart); if (anamag.empty()) { str.format("Articolo non valido '%s' alla riga %ld", (const char*)codart, fat.current_row()+1); log.log(1, str); continue; } str = codart; str << "|1"; const TString4 um = cache().get(LF_UMART, str, UMART_UM); if (doc == NULL) { TString4 numerazione = codnum; TToken_string key; key << "C|" << codcf; TString4 tipo_doc = cache().get(LF_CFVEN, key, CFV_TIPODOCFAT); if (tipo_doc.full()) { TString_array num_doc; const int nd = numerazioni_documenti(num_doc, tipo_doc); if (nd > 0 && num_doc.find(numerazione) < 0) numerazione = num_doc.row(0); } else { const TCodice_numerazione& cn = cached_numerazione(codnum); tipo_doc = "F01"; if (cn.find_tipo_doc(tipo_doc) < 0) tipo_doc = cn.tipo_doc(0); } doc = new TDocumento('D', datadoc.year(), numerazione, 0); doc->put(DOC_TIPODOC, tipo_doc); doc->put(DOC_STATO, 2); // Stampato doc->put(DOC_TIPOCF, 'C'); doc->put(DOC_CODCF, codcf); doc->put(DOC_DATADOC, datadoc); doc->put(DOC_DOC1, ndoc); doc->put(DOC_CODPAG, codpag); doc->put(DOC_STATO, 1); doc->put(DOC_CODCMS, cdc); key = "C"; key.add(codcf); key.add("N"); TRecord_array nsban(key, LF_CFBAN); if (nsban.rows() > 0) { const TRectype& rec = nsban.row(1); doc->put(DOC_CODABIP, rec.get(CFBAN_ABI)); doc->put(DOC_CODCABP, rec.get(CFBAN_CAB)); } key.add("V", 2); TRecord_array vsban(key, LF_CFBAN); if (vsban.rows() > 0) { const TRectype& rec = vsban.row(1); doc->put(DOC_CODABIA, rec.get(CFBAN_ABI)); doc->put(DOC_CODCABA, rec.get(CFBAN_CAB)); doc->put(DOC_IBAN, rec.get(CFBAN_IBAN)); } } TRiga_documento& rdoc = doc->new_row("01"); rdoc.put(RDOC_CODART, codart); rdoc.put(RDOC_CODARTMAG, codart); rdoc.checked(true); rdoc.put(RDOC_UMQTA, um); rdoc.put(RDOC_QTA, UNO); rdoc.put(RDOC_PREZZO, fat.get(19).as_real()); rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA)); TString desc = anamag.get(ANAMAG_DESCR); desc << ' ' << periodo; if (!ospiti.empty_items()) { const char* sep = " "; FOR_EACH_TOKEN(ospiti, o) if (o && *o > ' ') { desc << sep << o; sep = ", "; } } save_rdoc_desc(desc, rdoc); desc = fat.get(23).as_string(); if (desc.full()) { TRiga_documento& rdesc = doc->new_row("05"); save_rdoc_desc(desc, rdesc); } done = pi.add_status(); } if (doc != NULL) { save_doc(*doc, ndocs, mindoc, maxdoc, log); delete doc; doc = NULL; } log.log(0, str.cut(0)); str << TR("Sono stati importati ") << ndocs << TR(" documenti ") << codnum << TR(" dal ") << mindoc << TR(" al ") << maxdoc; log.log(0, str); return done; } void TImport_app::main_loop() { open_files(LF_TAB, LF_TABCOM, LF_CLIFO, LF_CFVEN, LF_DOC, LF_RIGHEDOC, LF_ANAMAG, LF_UMART, 0); TImport_mask mask; while (mask.run() == K_ENTER) { TLog_report log; TFilename fname = mask.get(F_DIR); fname.add(mask.get(F_CLI)); if (!fname.exist()) { cantread_box(fname); continue; } const TString& cdc = mask.get(F_CDC); if (importa_clienti(fname, cdc, log)) { const TString& codnum = mask.get(F_NUM); fname = mask.get(F_DIR); fname.add(mask.get(F_FAT)); if (fname.exist()) importa_fatture(fname, codnum, cdc, log); else cantread_box(fname); } else { log.log(2, TR("E' necessario correggere i problemi segnalati prima di importare le fatture")); } log.preview(); } } int ps0430400(int argc, char* argv[]) { TImport_app a; a.run(argc, argv, TR("Importazione CBA")); return 0; }