#include "f9lib.h" #include #include #include "../f1/f1lib.h" #include "f901tab.h" #include "progind.h" #include "clifo.h" #include "../cg/cglib.h" #include "mov.h" #include "../fp/fplib.h" #include "annessif9.h" #include "f90100c.h" #define MODE_SHEETS 0xC statistics _stats = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const TString & get_numdoc_exp_fp(const int numreg) { TRectype & mov = (TRectype&)cache().get(LF_MOV, numreg); TString & numdoc = get_tmp_string(); if (mov.full()) { const TString& codnum = mov.get(MOV_DCODNUM); const int ndoc = mov.get_int(MOV_DNDOC); if (codnum.full() && ndoc != 0) numdoc = complete_num_fp(cached_numerazione(codnum), ndoc); } return numdoc; } /////////////////////////////////////////////////////////////////////////////// // TMovimento_estr /////////////////////////////////////////////////////////////////////////////// const char* TMovimento_estr::err_mov2name(const err_mov descr_estr) { switch (descr_estr) { case mov_no_error: return "OK"; case mov_escluso: return "Il movimento e' segnato come escluso. Saltato."; case mov_no_catdoc: return "Nessuna categoria documentale riconosciuta per questo movimento, o non e' una fattura."; case mov_no_doc: return "Il mov. di vendita non ha un documento generatore"; case mov_notfound_elet: return "Non trovata fatt. elettronica mov vendita"; case mov_no_fa: return "Questo movimento di acquisto non e' una fattura"; case mov_no_fv: return "Movimento di vendita non e' una fattura."; case mov_no_cartaceo: return "Movimento cartaceo che non ha bisogno di essere estratto"; case mov_pura_iva: return "Movimento di sola IVA. (Le integrazioni Rev. Charge sono gestite come annessi alle vendite)"; case mov_annesso_nexist: return "Un annesso obbligatorio e' mancante."; case mov_nocat_butok: return "OK (Nessuna categoria documentale trovata ma l'abbinamento è riuscito)"; case mov_no_sdi: return "Tipo documento SDI non identificato"; default: return ""; } } TMovimento_estr & TMovimento_estr::copy(const TMovimento_estr & m) { _err = m._err; _state = m._state; _estratto = m._estratto; _descr_estr = m._descr_estr; _documenti_allegati = m._documenti_allegati; _numreg = m._numreg; _datareg = m._datareg; _datadoc = m._datadoc; _codcaus = m._codcaus; _meseliq = m._meseliq; _numdoc = m._numdoc; _tot = m._tot; _codcf = m._codcf; _ragsoc = m._ragsoc; _reg_protiva = m._reg_protiva; _descr = m._descr; _cat_doc_padre = m._cat_doc_padre; _data_estr = m._data_estr; _user = m._user; return *this; } TMovimento_estr::TMovimento_estr(TSheet_field& sf, int row) : _err(false), _state(null_state), _estratto(true), _descr_estr(mov_no_error), _data_estr(today), _user(user()) { _numreg = sf.get_long_row_cell(row, FE_NUMREG); _datareg = sf.get_date_row_cell(row, FE_DATAREG); _datadoc = sf.get_date_row_cell(row, FE_DATADOC); _codcaus = sf.get_str_row_cell(row, FE_CODCAUS); _meseliq = sf.get_int_row_cell(row, FE_MESELIQ); _numdoc = sf.get_str_row_cell(row, FE_NUMDOC); _tot = sf.get_real_row_cell(row, FE_IMPTOTDOC); _codcf = sf.get_long_row_cell(row, FE_FORN); _ragsoc = sf.get_long_row_cell(row, FE_RAGSOC); _reg_protiva = sf.get_str_row_cell(row, FE_PROTIVA); _descr = sf.get_long_row_cell(row, FE_DESCR); TClasse_doc * classe = catdoc(categorie_doc()); if (classe != nullptr) { _cat_doc_padre = classe->catdoc(); } } void TMovimento_estr::set_err(const char * descr, err_mov descr_estr) { bool error = descr && *descr; _err = error ; _estratto = !error || (descr_estr != mov_no_fa && descr_estr != mov_no_cartaceo); _descr_err = descr; if (descr_estr != mov_no_error) _descr_estr = descr_estr; else _descr_estr = error ? mov_annesso_nexist : mov_no_error; } bool TMovimento_estr::load_docs() { TLocalisamfile annessi(LF_F9ANNESSI); bool found = false; documenti_allegati().destroy(); const TRectype & mov = cache().get(LF_MOV, numreg()); TToken_string cartacei(mov.get(MOV_CARTACEI), '\n'); FOR_EACH_STR_TOKEN(cartacei, str) { TToken_string orig(str); TToken_string row(orig.get()); row.add(cat_doc_padre()); row.add(orig.get(4)); row.add(data_estr()); row.add(user()); documenti_allegati().add(row); found = true; } annessi.put(F9A_NUMREG, numreg()); // Si posiziona nl primo record giusto. Poi per sapere quando terminare guardo se la chiave e' ancora quella giusta. for (int err = annessi.read(_isgteq) == NOERR; err == NOERR && annessi.get_long(F9A_NUMREG) == numreg(); err = annessi.next()) { if (!found) { set_cat_doc_padre(annessi.get(F9A_CATDOCPAD)); set_data_estr(annessi.get_date(F9A_LOADDATE)); set_user(annessi.get(F9A_USER)); } TToken_string row(annessi.get(F9A_FILENAME)); row.add(cat_doc_padre()); row.add(annessi.get(F9A_CATDOCANN)); row.add(data_estr()); row.add(user()); documenti_allegati().add(row); found = true; } return found; } bool TMovimento_estr::fill_doc_list(TString_array& list_docs) { bool ok = load_docs(); list_docs.destroy(); if (ok) { // Si posiziona nl primo record giusto. Poi per sapere quando terminare guardo se la chiave e' ancora quella giusta. FOR_EACH_ARRAY_ROW(_documenti_allegati, r, str) { TToken_string t; t.add(numreg()); t.add(str->get()); t.add(str->get()); t.add(str->get()); t.add(str->get()); t.add(str->get()); list_docs.add(t); } } return ok; } TMovimento_estr::TMovimento_estr(const long numreg) : _err(false), _state(null_state), _estratto(true), _descr_estr(mov_no_error), _data_estr(today), _user(user()) { const TRectype & mov = cache().get(LF_MOV, numreg); TToken_string key(mov.get(MOV_TIPO)); key.add(mov.get(MOV_CODCF)); const TRectype & clifo = cache().get(LF_CLIFO, key); _numreg = numreg; _datareg = mov.get_date(MOV_DATAREG); _datadoc = mov.get_date(MOV_DATADOC); _codcaus = mov.get(MOV_CODCAUS); _meseliq = mov.get_int(MOV_MESELIQ); _numdoc = mov.get(MOV_NUMDOCEXT).full() ? mov.get(MOV_NUMDOCEXT) : mov.get(MOV_NUMDOC); _tot = mov.get_real(MOV_TOTDOC); // perchè no ? +mov.get_real(MOV_RITFIS) + mov.get_real(MOV_RITSOC); _codcf = mov.get_long(MOV_CODCF); _ragsoc = clifo.get(CLI_RAGSOC); _reg_protiva = mov.get(MOV_REG); _reg_protiva << "/" << mov.get(MOV_PROTIVA); // perchè c'era solo mov_reg ? _descr = mov.get(MOV_DESCR); } TMovimento_estr::TMovimento_estr(TISAM_recordset & mov, TipoIVA tipo, bool escl) : _err(false), _state(null_state), _estratto(true), _descr_estr(mov_no_error), _data_estr(today), _user(user()) { _numreg = mov.get_long(MOV_NUMREG); _datareg = mov.get_date(MOV_DATAREG); _datadoc = mov.get_date(MOV_DATADOC); _codcaus = mov.get_string(MOV_CODCAUS).left(3); // perchè 3 caratteri ? _meseliq = mov.get_int(MOV_MESELIQ); if (tipo == iva_vendite) _numdoc = get_numdoc_exp_fp(_numreg); if (_numdoc.blank()) _numdoc = mov.get_string(MOV_NUMDOCEXT); if (_numdoc.blank()) _numdoc = mov.get_string(MOV_NUMDOC); _tot = mov.get_real(MOV_TOTDOC) + mov.get_real(MOV_RITFIS) + mov.get_real(MOV_RITSOC); _codcf = mov.get_long(MOV_CODCF); TToken_string key(tipo == iva_acquisti ? "F" : "C"); key.add(_codcf); _ragsoc = cache().get(LF_CLIFO, key, CLI_RAGSOC); _reg_protiva = mov.get_string(MOV_REG); _reg_protiva << "/" << mov.get_string(MOV_PROTIVA); _descr = mov.get_string(MOV_DESCR); if (escl) { _estratto = false; _descr_estr = mov_escluso; } } /////////////////////////////////////////////////////////////////////////////// // TEstrazione /////////////////////////////////////////////////////////////////////////////// long find_movcoll(long numreg) // ma serve ? { TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); mov.read(); const TCausale& cau = cached_causale(mov.get(MOV_CODCAUS), mov.get_int(MOV_ANNOES)); const TString4 cau_reg = cau.causale_reg_iva(); const TString numdoc = mov.get(MOV_NUMDOC); TString query("USE "); query << LF_MOV << " KEY 1 SELECT " << MOV_CODCAUS << "==\"" << cau_reg << "\"\nFROM " << MOV_NUMREG << "==" << numreg; TISAM_recordset mov_rs(query); long movcoll = 0L; for (bool ok = mov_rs.move_first(); ok; ok = mov_rs.move_next()) { TRectype& curr = (TRectype&)mov_rs.cursor()->curr(); const long movcoll_found = curr.get_long(MOV_MOVCOLL); if (curr.get(MOV_NUMDOC) == numdoc && (movcoll_found == 0L || movcoll_found == numreg)) { movcoll = mov_rs.get_long(MOV_NUMREG); curr.put(MOV_MOVCOLL, numreg); break; } } return movcoll; } const char* TEstrazione::caus_sos(const TLocalisamfile& mov, const TipoIVA iva) { if (iva == iva_acquisti) { TToken_string keys(mov.get(MOV_KEYFPPRO)); fppro_db().set_keys(keys); return fppro_db().get_tipodoc(); } if (iva == iva_vendite) { const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC)); static TString tipo_doc_sdi; return tipo_doc_sdi = doc.tipo().tipo_doc_sdi(); } return ""; } void TEstrazione::check_annessi(TMovimento_estr& mov) { TToken_string ann_nexist; if (!check_annessi_oblig(mov, ann_nexist)) { TString msg_annessi_mancanti("Annessi obligatori mancanti: "); for (int i = 0; i < ann_nexist.items(); ++i) msg_annessi_mancanti << ann_nexist.get() << " "; mov.set_err(msg_annessi_mancanti); } else load_docs(mov); } bool TEstrazione::check_annessi_oblig(TMovimento_estr& mov, TToken_string& ann_nexist) { TF9_doccart file_cart; TString_array list_file_ann; // Lista file annessi TClasse_doc * classe = mov.catdoc(categorie_doc()); TString catdoc; if (classe != nullptr) catdoc = classe->catdoc(); const TString_array lista_cat_annessi = categorie_doc().get_array_ann(catdoc); // Lista cat annessi ann_nexist.cut(0); mov.fill_doc_list(list_file_ann); bool ok_ann = true; FOR_EACH_ARRAY_ITEM(lista_cat_annessi, nr, obj_name) { TString & ann_name = (TString &)*obj_name; TAnnesso * ann = categorie_doc().get_ann(catdoc, ann_name); const bool ok_cat = ann != nullptr; // Ignoro il flag obbligatorio per il prospetto di reverse charge if (ok_cat && ann->obblig() && ann->opcee() != "RC") { // Controllo che esista l'annesso per questo mov. bool exist = false; FOR_EACH_ARRAY_ROW(list_file_ann, r, row) { TString catdocann = row->get(3); if (catdocann == ann_name) { exist = true; break; } } ok_ann &= exist; if (!exist) ann_nexist.add(ann_name); } else if(ok_cat && ann->opcee() == "RC") { // Generazione prospetto integrativo. const bool ok = make_prosp_int_revc(mov.numreg(), ann); if (!ok) { TString msg(TR("Prospetto integrativo")); msg << "(" << ann->catdoc() << ")"; ann_nexist.add(msg); } ok_ann &= ok; } } return ok_ann; } bool TEstrazione::check_cartaceo_acq(TMovimento_estr& movimento) { bool ok = movimento.load_docs(); if (ok) { FOR_EACH_ARRAY_ROW(movimento.documenti_allegati(), r, str) { TFilename file = str->get(); ok &= file.exist(); if (!ok) break; } } return ok; } bool TEstrazione::check_documento_vendita(const TLocalisamfile& mov, _Out_ bool& exist_doc) { if (!mov.get(MOV_DPROVV).empty() && !mov.get(MOV_DANNO).empty() && !mov.get(MOV_DCODNUM).empty() && !mov.get(MOV_DNDOC).empty()) { TString hfatt(20), bfatt(50), query; const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC)); exist_doc = true; if (chiave_paf_doc(doc, hfatt, bfatt)) { query << "SELECT * FROM PAF0100F WHERE P1_KEYHEADERFATT = '" << hfatt << "' AND P1_KEYBODYFATT = '" << bfatt << "';"; fp_db().sq_set_exec(query); return fp_db().sq_items() > 0; } } else exist_doc = false; return false; } state_fppro TEstrazione::check_fppro(int numreg) { TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); if (mov.read() == NOERR && check_causale(mov.get(MOV_CODCAUS), mov.get_date(MOV_DATAREG).year())) { // Controllo se ho i riferimenti all'FPPRO e verifico che sia tutto ok const TString& keys_fppro = mov.get(MOV_KEYFPPRO); if (keys_fppro.full()) { TToken_string keys(keys_fppro, ';'); if (fppro_db().check_reg(keys, numreg)) return correct; TString err(fppro_db().get_last_error()); if (!err.empty()) { error_box(err.cut(0) << "Errore durante il controllo del movimento n. " << numreg << "\n" << err); return err_read_db; } return reg_with_err; } else // Se non ho i riferimenti faccio guessing { if (fppro_db().guess_the_doc(mov)) return guessed; return no_guessed; } } return not_fa; } bool TEstrazione::check_periodo_def() const { TString query; // Controllo se ci sono estrazioni (definitive) che si sovrappongono di periodo (con lo stesso tipo) e che non siano in stato di errore // Nel caso di stato di errore e' invece possibile la ri-estrazione query << "SELECT *\nFROM " F9_DRD "\n" "WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND " DRD_DATAA " >= '" << _head.dal.date2ansi() << "' AND " DRD_DATADA " <= '" << _head.al.date2ansi() << "' AND " DRD_FLAG_PD " = 'D' AND\n " DRD_STATO " <> '" D_GEST_ERR "' AND " DRD_STATO " <> '" D_WA_ERR "' AND " DRD_STATO " <> '" D_ERR_SOS "' AND " DRD_TIPODOC " = '" << _head.tipo_doc << "';"; fp_db().sq_set_exec(query); return fp_db().sq_items() == 0; } void TEstrazione::copy_file_to_webapp_fld(TMovimento_estr& movimento) const { // f9pwa + ambiente + idlancio(ID drd) + categoria_documento(drt) + nome_documento TFilename base(F9CONF.get_addr_doc_loc()); base.add(_head.cod_soc).add(_head.id_estr).slash_terminate(); TClasse_doc * cd = movimento.catdoc(categorie_doc()); const bool has_allegati = movimento.allegati(); if (has_allegati) { TString_array & docs = movimento.documenti_allegati(); FOR_EACH_ARRAY_ROW(docs, r, str) { TFilename file = str->get(0); if (file.full()) { TFilename dest(base); if (file.is_relative_path()) { const TString studio = prefix().get_studio(); file.insert(studio); } if (cd != nullptr && file.full()) dest.add(cd->catdoc()); else dest.add("cartaceo"); dest.add(file.name()); make_dir(dest.path()); if (!fcopy(file, dest)) error_box(FR("Errore nel copiare il %s in %s"), (const char*)file, (const char*)dest); } } } } void TEstrazione::fill_id(const TRectype& clifo, TString& statopaiv, TString& idfisc, TString& paiv, TString& codfis) { idfisc.cut(0); statopaiv = clifo.get(CLI_STATOPAIV); paiv = clifo.get(CLI_PAIV); codfis = clifo.get(CLI_COFI); if (IS_ITALIANO(statopaiv)) { // Se ho un codice fiscale che inizia per 8 o 9 e' come un privato e devo considerarlo solo come codice fiscale senza partita IVA. if (paiv.full()) { if (paiv.len() == 11 && (paiv[0] == '8' || paiv[0] == '9')) { codfis = paiv; paiv.cut(0); } } else if (codfis.full() && codfis.len() == 11 && (codfis[0] == '8' || codfis[0] == '9')) paiv.cut(0); } if (paiv == "0") paiv.cut(0); if (IS_ITALIANO(statopaiv)) { idfisc << "IT"; if (paiv.full()) // Se non ho la partita IVA e' privato quindi non metto niente solo cod. ISO { const int len = paiv.len(); for (int i = 0; i < 11 - len; ++i) // Siccome e' numerico mi trancia via le prime cifre 0. paiv.add_front("0"); idfisc << paiv; } } else // Esteri { idfisc << statopaiv; if (codfis.full()) idfisc << codfis; else idfisc << paiv; } } bool TEstrazione::is_doc_xml(const TRectype& mov) { TToken_string key(mov.get(MOV_TIPO)); key.add(mov.get(MOV_CODCF)); const TRectype & clifo= cache().get(LF_CLIFO, key); const TString& statopaiv = clifo.get(CLI_STATOPAIV); return (IS_ITALIANO(statopaiv)) && clifo.get(CLI_COMCF) != "B513"; // Campione d'Italia } /* bool TEstrazione::stampa_documento(const TMovimento_estr& movimento, TFilename& file) { bool ok = false; // Se il movimento e' di vendita e ha i riferimenti al documento generatore provo a stamparlo con ve, e lo inserisco tra i cartacei F9. TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, movimento.numreg()); if (mov.read() == NOERR && !mov.get(MOV_DPROVV).empty() && !mov.get(MOV_DANNO).empty() && !mov.get(MOV_DCODNUM).empty() && !mov.get(MOV_DNDOC).empty()) { const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC)); if(doc.ok() && dongle().active(RSAUT)) { // ve1 -2 {CODNUM} {ANNO} {PROVV} {NDOC}(-{ANDOC}) {TIPO_ELABORAZIONE} {TIPO_STAMPA} {NUM_COPIE} {ARCHIVIAZIONE} static TString commandline; commandline.cut(0) << "ve1 -2 " << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << " X P 1 D"; // X: stampa su disco, P: provvisorio, 1: 1 copia, D: disabilita archiviazione TExternal_app interattivo(commandline); if (interattivo.run() == NOERR) { TFilename pdf; pdf.tempdir(); pdf << SLASH << doc.get(DOC_ANNO) << '_' << doc.get(DOC_CODNUM) << '_' << doc.get(DOC_NDOC) << ".pdf"; if (pdf.exist()) { file.cut(0) << pdf; // Controllo anche se false perche' potrebbe esistere gia'. if(!TF9_doccart::add_cart(file, movimento.numreg())) { TFilename fdoc; ok = movimento.load_docs() && fdoc.name() == file.name(); } else ok = true; } } } } return ok; } */ bool TEstrazione::grab_pdf_from_spotlite(const TMovimento_estr& movimento, TFilename& file) const { TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, movimento.numreg()); if (mov.read() == NOERR && !mov.get(MOV_DPROVV).empty() && !mov.get(MOV_DANNO).empty() && !mov.get(MOV_DCODNUM).empty() && !mov.get(MOV_DNDOC).empty()) { const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC)); if (doc.ok()) { char buffer[34]; TString f_pdf; f_pdf << "ve1300_" << mov.get(MOV_DCODNUM) << "_"; sprintf_s(buffer, 34, "%010d", mov.get_long(MOV_DNDOC)); f_pdf << buffer << "_"; sprintf_s(buffer, 34, "%07d", doc.clifor().codice()); f_pdf << buffer << ".pdf"; TFilename doccart(_spotlite_path); doccart.add(mov.get(MOV_DANNO)); doccart.add(prefix().name()); doccart.add(f_pdf); if (doccart.exist()) { file.cut(0); file = doccart; return true; } } } return false; } bool TEstrazione::make_prosp_int_revc(const int numreg, TAnnesso * annesso) { TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); mov.read(); long rev_vend = mov.get_long(MOV_MOVCOLL); if (rev_vend == 0) rev_vend = find_movcoll(numreg); if (rev_vend > 0) { TF9Prospetto_integr prosp; const long acq = numreg; if (prosp(acq, rev_vend)) { // [ NUMREG][ CAT.ANN.].pdf // [0000000][AAAAAAAAAA].pdf TFilename tmp_file; tmp_file.tempdir(); TString name; name << format("%07d%10s", numreg, (const char*)annesso->catdoc()); name.replace(' ', '_'); tmp_file.add(name); tmp_file.ext("pdf"); if (prosp.export_pdf(tmp_file)) { // Sposto il file nella cartella dei documenti cartacei. const TFilename newfile(get_full_path_file_cartaceo(tmp_file.name())); // if (newfile.exist()) // DeleteFile(newfile); fcopy(tmp_file, newfile); // Controllo che non esista gia' altrimenti elimino il record TF9_doccart doccart; long numreg_old; if (doc_already_exists(newfile, numreg_old)) { TLocalisamfile lf_ann(LF_F9ANNESSI); lf_ann.setkey(2); lf_ann.put(F9A_FILENAME, newfile.name()); lf_ann.read(); lf_ann.remove(); lf_ann.zero(); } // Registro il file come annesso RC TLocalisamfile lf_ann(LF_F9ANNESSI); lf_ann.put(F9A_NUMREG, numreg); lf_ann.put(F9A_FILENAME, newfile.name()); lf_ann.put(F9A_CATDOCPAD, annesso->catdocpadre()); lf_ann.put(F9A_CATDOCANN, annesso->catdoc()); lf_ann.put(F9A_LOADDATE, today); lf_ann.put(F9A_USER, user()); bool ok = lf_ann.write() == NOERR; ok &= lf_ann.rewrite() == NOERR; if (!ok) ok = yesno_box("Impossibile creare il prospetto integrativo per la registrazione n. %s.\nContinuare con l'estrazione?", (const char*)TString(numreg)); return ok; } } } return false; } TString& TEstrazione::drd_attr() { static TString attr; attr.cut(0) << DRD_CODSOC ", " DRD_ID_EST ", " DRD_FLAG_PD ", " DRD_DESC ", " DRD_TIPODOC ", " DRD_DATADA ", " DRD_DATAA ", " DRD_UTENTE ", " DRD_TIME ", " DRD_STATO ", " DRD_PERC; return attr; } TString& TEstrazione::drd_tovalues() const { static TString str; return str.cut(0) << "'" << _head.cod_soc << "', '" << _head.id_estr << "', '" << (_head.flag_prov ? "P" : "D") << "', '" << _head.descr << "', '" << _head.tipo_doc << "', '" << _head.dal.date2ansi() << "', '" << _head.al.date2ansi() << "', '" << _head.user << "', CURRENT_TIMESTAMP, '" << _head.stato_estr << "', '" << _head.addr_cart << "'"; } bool TEstrazione::insert_into_drd() { TString query; query << "INSERT INTO " F9_DRD " ( " << drd_attr() << " ) \nVALUES ( " << drd_tovalues() << " );"; bool ok = fp_db().sq_set_exec(query); ok = ok && fp_db().sq_commit(); if (!ok) write_errorsql_log(query); return ok; } bool TEstrazione::insert_into_f9movestr() { TString query; bool ok = true; TProgress_monitor prog(_movs.size(), "Salvataggio informazioni estrazione", false); //QUI ANDRA' CONTROLLATO IL PAFW300 FOR_EACH_ARRAY_ITEM(_movs, r, obj) { if(prog.add_status()) { TMovimento_estr & mov = (TMovimento_estr &)*obj; query.cut(0) << "INSERT INTO " F9_MOVESTR " (" MES_CODSOC ", IDESTR, NUMREG, DATAREG, ESTRATTO, DESCR_ERR)\nVALUES " << " ('" << _head.cod_soc << "', '" << _head.id_estr << "', '" << mov.numreg() << "', '" << mov.datareg().date2ansi() << "', " << (mov.estratto() ? "1" : "0") << ", '" << check_str(mov.get_descr_estr()) << "')"; ok &= fp_db().sq_set_exec(query) && fp_db().sq_commit(); if (!ok) { write_errorsql_log(query); break; } } } return ok; } bool TEstrazione::export_error_list() { TF9_dberr dberr(_log); const TArray & movs = _movs; // bool ok = true; int count = 0; TProgress_monitor pg(movs.items(), "Scrittura movimenti in errore"); FOR_EACH_ARRAY_ITEM(movs, r ,obj) { TMovimento_estr & mov = (TMovimento_estr &)*obj; if (pg.add_status()) { if (mov.err()) { dberr.add(_head.cod_soc); dberr.add(_head.id_estr); dberr.add(mov.numreg()); dberr.add(mov.datareg()); dberr.add(mov.datadoc()); dberr.add(mov.codcaus()); dberr.add(mov.meseliq()); dberr.add(mov.numdoc()); dberr.add(mov.totale().string_point()); dberr.add(mov.codcf()); dberr.add(mov.ragsoc()); dberr.add(mov.protiva()); dberr.add(mov.descr()); dberr.add(mov.descr_err()); if (!(ok &= dberr.send())) break; ++count; } } } return ok; } TString TEstrazione::next_estr_today(char tipo) const { char estr[] = { 0,0,0,0,0,0,0,0,0 }; TString query; query << "SELECT TOP 1 SUBSTRING(" DRD_ID_EST ", 11, 8) AS IDESTR\n" "FROM " F9_DRD "\n" "WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND\n" DRD_ID_EST " LIKE '" << today.date2ansi() << "%'\n" "ORDER BY IDESTR DESC"; fp_db().sq_set_exec(query); const int last_estr = fp_db().sq_items() > 0 ? real(fp_db().sq_get("IDESTR")).integer() : -1; if (last_estr < -1 || last_estr == 99999999) { ofstream fout; fout.open("f9err_nextestr.txt"); if (fout.is_open()) { fout << "Errore progressivo nuova estrazione!\n" << today << "\nn:" << last_estr << "\n" << query << "\n"; fout.close(); } TString msg; fatal_box(msg << "database error: progressivo nuova estrazione. Ultima estrazione: " << last_estr); } sprintf_s(estr, 9, "%08d", last_estr + 1); return TString(estr); } bool TEstrazione::pura_iva(const TRectype& mov) { if (TCausale(mov.get(MOV_CODCAUS), mov.get_date(MOV_DATAREG).year()).soloiva()) return true; TMovimento_contabile* rel = new TMovimento_contabile(); rel->put(MOV_NUMREG, mov.get(MOV_NUMREG)); return rel->cg_rows() == 0; } void TEstrazione::write_errorsql_log(const TString& query) { _log->log(2, query); _log->log(2, fp_db().sq_get_string_error()); _log->log(2, fp_db().sq_get_text_error()); _log->line(); } // Public methods ///////////////////////////////////////////////////////////////////////////////////////////// bool TEstrazione::update_drd_stato_estr() { bool ok; do { TString query; query << "UPDATE " F9_DRD "\n" \ "SET " DRD_STATO " = '" << _head.stato_estr << "'\n" "WHERE " DRD_CODSOC " = '" << _head.cod_soc << "'" " AND " DRD_ID_EST " = '" << _head.id_estr << "'" " AND " DRD_FLAG_PD " = '" << (_head.flag_prov ? "P" : "D") << "'"; ok = fp_db().sq_set_exec(query); ok = ok && fp_db().sq_commit(); if (!ok) write_errorsql_log(query); } while (!ok && yesno_box("Impossibile aggiornare stato dell'estrazione.\nRiprovare?")); return ok; } const char* TEstrazione::diagnostica_mov() { categorie_doc(true); bool ok = true; const TipoIVA tipo = get_tipoiva(); _stats.total = _movs.size(); if (tipo == iva_acquisti) { // Controlli per le fatture di acquisto TProgress_monitor bar(_movs.items(), "Controllo stato movimenti di acquisto"); FOR_EACH_ARRAY_ITEM(_movs, r, obj) { if (bar.add_status()) { TMovimento_estr & mov_i = (TMovimento_estr &)*obj; // Se gia' escluso passo avanti if (!mov_i.estratto() && mov_i.descr_estr() == mov_escluso) continue; if (mov_i.no_err() && mov_i.estratto()) { const long numreg = mov_i.numreg(); const TRectype & mov =cache().get(LF_MOV, numreg); mov_i.set_cartaceo(!is_doc_xml(mov)); const state_fppro res = check_fppro(numreg); switch (res) { // OK case guessed: ok &= fppro_db().associa_mov(numreg); ++_stats.fa_estr; break; case correct: ok &= true; mov_i.reset_err(); mov_i.set_numdoc(fppro_db().get_numdoc()); ++_stats.fa_estr; break; // ERRORS // Errore non bloccante (skip) case not_fa: ok &= true; mov_i.set_err("", mov_no_fa); mov_i.set_estratto(false); ++_stats.fa_skip; break; // ERRORI BLOCCANTI case reg_with_err: ok &= false; mov_i.set_err("Errore controllo movimento: associazione movimento con fattura elettronica passiva sbagliato."); break; case err_read_db: ok &= false; mov_i.set_err("Errore controllo movimento: errore lettura db."); break; case no_guessed: // Controllo se esiste il cartaceo es. forfettari => la considero cartacea. // Ma poi devo comunque avere il flag per l'esportazione dei cartacei if(check_cartaceo_acq(mov_i)) { ok &= true; mov_i.set_err(""); mov_i.set_cartaceo(true); mov_i.set_state(correct); } else { ok &= false; mov_i.set_err("Non associato a fattura elettr. abbinamento automatico non riuscito. Abbinare manualmente, o escludere"); } default: break; } if(mov_i.state() == null_state) mov_i.set_state(res); if (mov_i.err()) ++_stats.fa_err; /* Per quelli che hanno passato il primo controllo errori controllo che debba essere estratto * secondo le categorie documentali. */ if (mov_i.estratto()) { if (mov_i.no_err()) { // Cerco la categoria documentale TClasse_doc * cd = categorie_doc().mov2cat(mov_i.numreg()); const bool found = cd != nullptr; if (found) mov_i.set_descr_estr(mov_no_error); else mov_i.set_descr_estr(mov_nocat_butok); mov_i.set_estratto(true); // DA CONTROLLARE if (found) check_annessi(mov_i); } // Se cartaceo preparo il file. if (F9CONF.get_has_cartexp()) // Se e' abilitata l'esportazione dei cartacei, altrimenti skip... mov_i.load_docs(); copy_file_to_webapp_fld(mov_i); } } ok &= mov_i.no_err(); } } } else if (tipo == iva_vendite) { // Controlli per le fatture di vendita (AGGIORNARE STATS QUI) TProgress_monitor bar(_movs.items(), "Controllo stato movimenti di vendita"); FOR_EACH_ARRAY_ITEM(_movs, r, obj) { if (bar.add_status()) { TMovimento_estr & mov_i = (TMovimento_estr &) *obj; // Se escluso passo avanti if (!mov_i.estratto() && mov_i.descr_estr() == mov_escluso) continue; const long numreg = mov_i.numreg(); const TRectype & mov = cache().get(LF_MOV, numreg); /* Controlli per vendite cambiati: * Elettroniche solo quelle agli italiani, tutti gli altri sono cartacei */ if (!mov_i.err() && mov_i.estratto()) { mov_i.set_cartaceo(false); // ci deve essere ? unsigned short skip = 0; if (_has_cartacei && mov_i.cartaceo()) skip |= 0x1; else if (pura_iva(mov)) skip |= 0x2; else if (mov_i.datadoc().empty() || mov_i.numdoc().empty()) skip |= 0x4; if(skip) { ++_stats.fv_cart_skip; mov_i.reset_err(); mov_i.set_estratto(false); switch(skip) { case 0x1: mov_i.set_descr_estr(mov_no_cartaceo); break; case 0x2: mov_i.set_descr_estr(mov_pura_iva); break; case 0x4: mov_i.set_descr_estr(mov_no_fv); break; default: break; } } else { TClasse_doc* cd = categorie_doc().mov2cat(mov_i.numreg()); const bool found = cd != nullptr; if (found) mov_i.reset_err(); else mov_i.set_err("Categoria assente", mov_no_catdoc); if (cd != nullptr) check_annessi(mov_i); if (!mov_i.catdoc(categorie_doc())) ++_stats.fv_nocatdoc; if (mov_i.err()) ++_stats.fv_err; else if (mov_i.estratto()) ++_stats.fv_estr; } if (mov_i.estratto()) { if (mov_i.numreg() == 41400) { int here = 0; } if (mov_i.cartaceo()) { TFilename file; // if (filecart.mov2doc(mov_i.numreg(), file) && file.exist() || grab_pdf_from_spotlite(mov_i, file) && file.exist()) if (grab_pdf_from_spotlite(mov_i, file) && file.exist()) mov_i.set_nomefiledoc(file); else mov_i.set_err("Non e' stato possibile reperire il file del documento cartaceo per questo movimento.", mov_no_filecart); } TToken_string cartacei(mov.get(MOV_CARTACEI), '\n'); FOR_EACH_STR_TOKEN(cartacei, s) { TFilename file(s); if (file.exist()) mov_i.documenti_allegati().add(file); else mov_i.set_err(format(FR("Non e' stato possibile reperire il file cartaceo %s per questo movimento."), (const char *) file), mov_no_filecart); } copy_file_to_webapp_fld(mov_i); } } ok &= mov_i.no_err(); } } } _head.stato_estr = ok ? D_GEST_OK : D_GEST_ERR; return _head.stato_estr; } result_estr TEstrazione::estrai() { // Se non c'e' nessun movimento non sto nemmeno a scrivere il record di estrazione. // Se estrazione definitiva controllo che il periodo non si sovrapponga alle altre estrazioni def. // Do' errore ed esco subito. result_estr res = estr_ok; if (_movs.empty()) { warning_box("Non esistono movimenti estraibili per il periodo selezionato."); return estr_stop; } if (!_escluso && !_head.flag_prov) { /* if (!check_periodo_def()) { error_box("Attenzione e' stato inserito un periodo che si sovrappone\nad un'estrazione definitiva gia' esistente. Impossibile procedere."); return estr_stop; } if (gap_periodo()) { if (!noyes_box("Attenzione, e' stato saltato un periodo rispetto all'ultimo\n" "estratto e quello selezionato, il quale rimarrebbe vuoto.\nContinuare comunque?")) return estr_stop; } */ // Avviso nel caso in cui si stia facendo un'estrazione definitiva di un periodo di cui non si e' mai fatta // una prova provvisoria. if(!exist_prov()) { if (!noyes_box("Attenzione, non e' mai stata fatta alcuna\nestrazione provvisoria per questo periodo.\nContinuare comunque?")) return estr_stop; } } // Non so come usare questi 18 caratteri... // Uso dati anche se gia' noti in altri campi (I know..) + un numero incrementale. _head.id_estr.cut(0) << today.date2ansi() << (_head.flag_prov ? "P" : "D") << (!_escluso ? "N" : "X") << next_estr_today(_head.tipo_doc); _head.user = user(); // Eseguo controllo sui movimenti e segno in testata lo stato _head.stato_estr = IN_DIAGN; // "01" che verra' quasi subito rimpiazzato dal risultato della diagnostica. if (_escluso) set_dates(); // Se escluso imposto data inizio e fine uguali // Scrivo record estrazione (in stato '01': in diagnostica). const bool ok = insert_into_drd(); if (!ok) { TString msg; msg << "Errore database: impossibile scrivere nuova estrazione.\n" << fp_db().sq_get_text_error(false); error_box(msg); return estr_err_db_drd; } // Faccio partire la diagnostica e mi salvo il nuovo stato. diagnostica_mov(); insert_into_f9movestr(); if (_head.stato_estr == D_GEST_ERR) { warning_box("Attenzione l'estrazione ha prodotto degli errori.\n" "Controllare e correggere eventuali problemi\ndal Controllo Estrazione."); // Se in errore, esporto lista errori sul db if (!export_error_list()) warning_box("Errore scrittura db. Controllare log errori."); res = estr_diag_err; // Errore diagnostica gestionale } // Se va tutto ben fino a qui, posso andare a scrivere nella // tabella IVA i movimenti. F9IVA if (res == estr_ok) { res = estrazione_iva() ? estr_ok : estr_err_db_iva; if (res == estr_err_db_iva) _head.stato_estr = D_GEST_ERR; } update_drd_stato_estr(); return res; } bool TEstrazione::estrazione_iva(bool escluso) { TString statopaiv, idfisc, paiv, codfis; bool stato = true; TProgress_monitor bar(_movs.items(), "Estrazione dati IVA"); FOR_EACH_ARRAY_ITEM(_movs, r, obj) { TMovimento_estr & mov_i = (TMovimento_estr &)*obj; if (bar.add_status() && mov_i.estratto()) { const TRectype& mov = cache().get(LF_MOV, mov_i.numreg()); TToken_string key = mov.get(MOV_TIPO); key.add(mov.get(MOV_CODCF)); const TRectype& cli = cache().get(LF_CLIFO, key); const char tipodoc = _head.tipo_doc; const TCausale & caus = cached_causale(mov.get(MOV_CODCAUS), mov.get_date(MOV_DATAREG).year()); const TString& name_registro = caus.reg().name();; fill_id(cli, statopaiv, idfisc, paiv, codfis); TDate datadoc = mov.get_date(MOV_DATADOC); TDate datareg = mov.get_date(MOV_DATAREG); TIva_insert_prepared_stat iva_query; /////////QUIIIIIII/// iva_query.add(IVA_CODSOC, _head.cod_soc, 10); iva_query.add(IVA_IDLAN, _head.id_estr, 18); iva_query.add(IVA_FLAG_PD, _head.flag_prov ? 'P' : 'D'); iva_query.add(IVA_ANNOES, mov.get_int(MOV_ANNOES)); iva_query.add(IVA_GIVA, tipodoc); iva_query.add(IVA_TIPOG, name_registro, 10); iva_query.add(IVA_DOCXML, mov_i.cartaceo() ? 'N' : 'S'); iva_query.add(IVA_TIPOCF, mov.get_char(MOV_TIPO)); iva_query.add(IVA_CODCF, mov.get_long(MOV_CODCF)); iva_query.add(IVA_NUMOR, mov.get_long(MOV_NUMREG)); iva_query.add(IVA_RAGSOC, cli.get(CLI_RAGSOC), 60); iva_query.add(IVA_IDFISC, idfisc, 30); iva_query.add(IVA_PIVA, paiv, 28); iva_query.add(IVA_CODFIS, codfis, 16); iva_query.add(IVA_CATDOC, mov_i.catdoc(categorie_doc())->catdoc(), 10); const TRegistro& reg = cached_registro(mov.get(MOV_REG), mov.get_int(MOV_ANNOIVA)); if (reg.iva() == iva_vendite) { int anno = mov.get_int(MOV_DANNO); TString tipodocsdi; if (anno > 0) { const char provv = mov.get(MOV_DPROVV)[0]; const TString& codnum = mov.get(MOV_DCODNUM); const long ndoc = mov.get_long(MOV_DNDOC); TDocumento doc(provv, anno, codnum, ndoc); iva_query.add(IVA_CAUSSOS, tipo_doc_sdi(doc), 6); } else tipodocsdi = caus.tipodocsdi(); if (tipodocsdi.blank()) tipodocsdi = mov_i.catdoc(categorie_doc())->caus_sost(); if (tipodocsdi.full()) iva_query.add(IVA_CAUSSOS, tipodocsdi, 6); } else { TToken_string key(mov.get((MOV_KEYFPPRO)), ';'); if (key.full()) { TFppro fppro(key); const TString& tipodoc = fppro.get_tipodoc(); if(tipodoc.full()) iva_query.add(IVA_CAUSSOS, tipodoc, 6); else iva_query.add(IVA_CAUSSOS, mov_i.catdoc(categorie_doc())->caus_sost(), 6); } else iva_query.add(IVA_CAUSSOS, mov_i.catdoc(categorie_doc())->caus_sost(), 6); } iva_query.add(IVA_NUMDOC, mov_i.numdoc(), 20); iva_query.add(IVA_DATADOC, datadoc); iva_query.add(IVA_SEZIVA, mov.get(MOV_REG), 10); iva_query.add(IVA_TIPOREG, "", 6); iva_query.add(IVA_NPROT, mov.get(MOV_PROTIVA), 20); iva_query.add(IVA_DATPROT, datareg); /*if(is_autofattura(mov)) { iva_query.add(IVA_FORNOR, ""); iva_query.add(IVA_REGOR, ""); iva_query.add(IVA_NUMOR, N ORI); iva_query.add(IVA_DATAOR, TDate(20010101)); }*/ iva_query.add(IVA_CLASDOC, mov_i.catdoc(categorie_doc())->class_sost(), 10); iva_query.add(IVA_NOMFD, mov_i.nomefiledoc().name(), 100); // Load annessi... if(mov_i.allegati()) { TString_array & docs = mov_i.documenti_allegati(); int i = 0; const int size = docs.items(); iva_query.add(IVA_CLASAN1, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF1, docs.row(i++).get(0), 100); // HOW DID MY LIFE COME TO THIS?... if (size > i) { iva_query.add(IVA_CLASAN2, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF2, docs.row(i++).get(0), 100); } if (size > i) { iva_query.add(IVA_CLASAN3, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF3, docs.row(i++).get(0), 100); } if (size > i) { iva_query.add(IVA_CLASAN4, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF4, docs.row(i++).get(0), 100); } if (size > i) { iva_query.add(IVA_CLASAN5, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF5, docs.row(i++).get(0), 100); } if (size > i) { iva_query.add(IVA_CLASAN6, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF6, docs.row(i++).get(0), 100); } if (size > i) { iva_query.add(IVA_CLASAN7, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF7, docs.row(i++).get(0), 100); } if (size > i) { iva_query.add(IVA_CLASAN8, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF8, docs.row(i++), 100); } if (size > i) { iva_query.add(IVA_CLASAN9, docs.row(i).get(2), 10); iva_query.add(IVA_NOMF9, docs.row(i++).get(0), 100); } } iva_query.add(IVA_USERELA, user(), 10); iva_query.add_getdate(IVA_TIMEELA); if (_head.tipo_doc == 'A' && !mov_i.cartaceo()) { TToken_string keys(mov.get(MOV_KEYFPPRO), ';'); fppro_db().set_keys(keys); iva_query.add(IVA_TIPPROT, fppro_db().get_tipoprot(), 2); iva_query.add(IVA_ANNPROT, TVariant(fppro_db().get_annoprot()).as_int()); iva_query.add(IVA_NUMPROT, fppro_db().get_numprot(), 10); // Non controllo che sia in realta' un numero... iva_query.add(IVA_TIMERIC, TDate(fppro_db().get_dataoraric())); } TString sql; //DA MIGLIORARE IL LOG DI ERRORE long a = mov_i.numreg(); bool ok = iva_query.get(sql); if (ok) ok = fp_db().sq_set_exec(sql); if (ok) ok = fp_db().sq_commit(); if (!ok) write_errorsql_log(sql); stato &= ok; } } return stato; } bool TEstrazione::exist_prov() const { TString query; query << "SELECT * FROM " F9_DRD "\n" << "WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND " DRD_DATADA " = '" << _head.dal.date2ansi() << "'" " AND " DRD_DATAA " = '" << _head.al.date2ansi() << "' AND " DRD_FLAG_PD " = 'P' AND " DRD_TIPODOC " = '" << _head.tipo_doc << "'"; const bool ok = fp_db().sq_set_exec(query); return ok && fp_db().sq_items() > 0; } bool TEstrazione::gap_periodo() const { TString query; query << "SELECT " DRD_ID_EST " AS ID, " DRD_DATAA " AS DATA_A\n" "FROM " F9_DRD "\n" "WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND " DRD_ID_EST " LIKE '%N%' AND " // '%N%' = Pacchetto normale DRD_FLAG_PD " = 'D' AND " DRD_TIPODOC " = '" << _head.tipo_doc << "'\n" "ORDER BY " DRD_DATAA " DESC"; const bool ok = fp_db().sq_set_exec(query); return ok && fp_db().sq_items() > 0 && _head.dal - fp_db().sq_get_date("DATA_A") > 1; } void TEstrazione::set_dates() { if (_escluso) { set_dataini(((TMovimento_estr &)_movs[0]).datareg()); set_dataend(((TMovimento_estr &)_movs[0]).datareg()); } } TEstrazione::TEstrazione(const TString& ambiente, const bool flag_prov, const char tipodoc, const TString& descr, const TString& addrcart, const bool escluso, TFilename& spotlite_path, TLog_report * log, const TDate* const dal, const TDate* const al, const bool has_cartacei) : _descr(descr), _has_cartacei(has_cartacei), _spotlite_path(spotlite_path), _log(log) { _head.cod_soc = ambiente; _head.flag_prov = flag_prov; _head.descr = descr; _head.tipo_doc = tipodoc; if (!escluso && dal != nullptr && al != nullptr) { _head.dal = *dal; _head.al = *al; } _head.addr_cart = addrcart; _escluso = escluso; } ////////////////////////////////////////////////////// // TF9_dberr ////////////////////////////////////////////////////// void TF9_dberr::add_str(const TString& string) { _insert.rtrim(1); if (_insert[_insert.len() - 1] != '(') _insert << ", "; _insert << string << ")"; } void TF9_dberr::write_sqlerrlog(const TString& query) const { _log->log_error(query); _log->log_error(fp_db().sq_get_string_error()); _log->log_error(fp_db().sq_get_text_error()); _log->line(); } void TF9_dberr::add(const TString& string) { TString str = string; str.replace("'", "''"); str.insert("'"); str << "'"; add_str(str); } void TF9_dberr::add(const TDate& date) { if (date.ok()) add(date.date2ansi()); else add("00010101"); } void TF9_dberr::add(const long num) { TString app; app << num; add(app); } bool TF9_dberr::send() { const bool ok = fp_db().sq_set_exec(_insert) && fp_db().sq_commit(); if(!ok) write_sqlerrlog(_insert); _insert.cut(0) << "INSERT INTO " F9_ERR " (" ERR_CODSOC ", " ERR_IDESTR ", " ERR_NUMREG ", " ERR_DATAREG ", " ERR_DATADOC ", " ERR_CODCAUS ", " ERR_MESELIQ ", " ERR_NUMDOC ", " ERR_IMPTDOC ", " ERR_FORN ", " ERR_RAGSOC ", " ERR_PROTIVA ", " ERR_DESCR ", " ERR_DESCERR ") VALUES ()"; return ok; } bool dberr_del_err(const TString& codsoc, const TString& id_estr, const int numreg) { TString query; query << "DELETE FROM " F9_ERR "\nWHERE " ERR_CODSOC " = '" << codsoc << "'" "\nAND " ERR_IDESTR " = '" << id_estr << "' AND " ERR_NUMREG " = '" << numreg << "';"; return fp_db().sq_set_exec(query) && fp_db().sq_commit(); } char dberr_get_err(const TString& codsoc, const TString& id_estr, TArray& controllo_mov) { TString query; query << "SELECT * FROM " F9_ERR "\nWHERE " ERR_CODSOC " = '" << codsoc << "' AND " ERR_IDESTR " = '" << id_estr << "';"; fp_db().sq_set_exec(query, false); controllo_mov.destroy(); for (bool ok = fp_db().sq_next(); ok; ok = fp_db().sq_next()) { TToken_string row("", '|'); row.add("X"); for (int i = 1; i < 15; i++) { if (fp_db().sq_get_type_field(i) == _datefld) row.add(fp_db().sq_get_date(fp_db().sq_get_name_field(i))); else row.add(fp_db().sq_get(i)); } controllo_mov.add(row); } query.cut(0) << "SELECT " DRD_TIPODOC " FROM " F9_DRD "\n" << "WHERE " DRD_CODSOC " = '" << codsoc << "' AND " DRD_ID_EST " = '" << id_estr << "'"; fp_db().sq_set_exec(query); return fp_db().sq_get((unsigned)0)[0]; } TF9_dberr::TF9_dberr(TLog_report * log) : _log(log) { _insert.cut(0) << "INSERT INTO " F9_ERR " (" ERR_CODSOC ", " ERR_IDESTR ", " ERR_NUMREG ", " ERR_DATAREG ", " ERR_DATADOC ", " ERR_CODCAUS ", " ERR_MESELIQ ", " ERR_NUMDOC ", " ERR_IMPTDOC ", " ERR_FORN ", " ERR_RAGSOC ", " ERR_PROTIVA ", " ERR_DESCR ", " ERR_DESCERR ") VALUES ()"; } ; TString _user; /////////////////////////////////////////////////////////////////////////////////////////// // TAnnesso_mov /////////////////////////////////////////////////////////////////////////////////////////// TAnnesso_mov::TAnnesso_mov(TToken_string & row, int start) { _numreg = row.get_long(start); _filename = row.get(); _catdocpad = row.get(); _catdocann = row.get(); _loaddate = row.get_date(0); _user = row.get(); } TAnnesso_mov & TAnnesso_mov::copy(const TAnnesso_mov & a) { _numreg = a._numreg; _filename = a._filename; _catdocpad = a._catdocpad; _catdocann = a._catdocann; _loaddate = a._loaddate; _user = a._user; return *this; } void TAnnesso_mov::ann2row(TToken_string & row) { row.cut(0); row.add(_numreg); row.add(_filename); row.add(_catdocpad); row.add(_catdocann); row.add(_loaddate); row.add(_user); } /////////////////////////////////////////////////////////////////////////////////////////// // TClasse_doc /////////////////////////////////////////////////////////////////////////////////////////// TClasse_doc::TClasse_doc(TToken_string & row, int start) { _catdoc = row.get(start); _descr = row.get(); _class_sost = row.get(); _caus_sost = row.get(); _causcont = row.get(); _tipocaus = row.get(); } TClasse_doc & TClasse_doc::copy(const TClasse_doc & c) { _catdoc = c._catdoc; _descr = c._descr; _class_sost = c._class_sost; _caus_sost = c._caus_sost; _causcont = c._causcont; _tipocaus = c._tipocaus; return *this; } void TClasse_doc::ann2row(TToken_string & row) { row.cut(0); row.add(_catdoc); row.add(_descr); row.add(_class_sost); row.add(_caus_sost); row.add(_causcont); row.add(_tipocaus); } /////////////////////////////////////////////////////////////////////////////////////////// // TAnnesso /////////////////////////////////////////////////////////////////////////////////////////// TAnnesso::TAnnesso(TToken_string & row, int start) { _catdocpadre = row.get(start); _catdoc = row.get(); _descr = row.get(); _opcee = row.get(); _obblig = row.get_bool(); } TAnnesso & TAnnesso::copy(const TAnnesso & a) { _catdocpadre = a._catdocpadre; _catdoc = a._catdoc; _descr = a._descr; _opcee = a._opcee; _obblig = a._obblig; return *this; } void TAnnesso::ann2row(TToken_string & row) { row.cut(0); row.add(_catdocpadre); row.add(_catdoc); row.add(_descr); row.add(_opcee); row.add(_obblig); } /////////////////////////////////////////////////////////////////////////////////////////// // TCategorie_doc /////////////////////////////////////////////////////////////////////////////////////////// TClasse_doc * TCategorie_doc::find_causcont(const TString& caus) { FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj) { TClasse_doc * classe = (TClasse_doc *)obj; if (classe->causcont() == caus) return classe; } return nullptr; } TClasse_doc * TCategorie_doc::find_tipodoc(const TString& tipodoc) { FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj) { TClasse_doc * classe = (TClasse_doc *)obj; if (classe->causcont().blank() && classe->tipocaus() == tipodoc) return classe; } return nullptr; } TClasse_doc * TCategorie_doc::find_tipodocsdi(const TString& tipodocsdi, const char * tipocaus) { FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj) { TClasse_doc * classe = (TClasse_doc *)obj; if ((classe->caus_sost() == tipodocsdi) && (classe->tipocaus() == tipocaus)) return classe; } return nullptr; } void TCategorie_doc::load_all() { _rows.destroy(); _rows_annessi.destroy(); int idx = 0; while (true) { const TString& appo = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, "", idx++); if (appo == "STOP" || appo.blank()) /* STOP: Riga terminatrice */ break; TToken_string row(appo); const TString catdoc(row.get(1)); TClasse_doc cd(row, 1); _rows.add(catdoc, cd); } idx = 0; while (true) { const TString& appo = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, "", idx++); if (appo == "STOP" || appo.blank()) /* STOP: Riga terminatrice */ break; TToken_string row(appo); TAnnesso ann(row); TToken_string key = row.get(0); key.add(row.get(1)); _rows_annessi.add(key, ann); } } void TCategorie_doc::save_ann() { remove_all_ann(); int idx = 0; FOR_EACH_ASSOC_OBJECT(_rows_annessi, hash, key, obj) { TToken_string row; TAnnesso & ann = (TAnnesso &) *obj; if(ann.catdocpadre().full()) row.add(ann.catdocpadre(), 0); if (ann.catdoc().full()) row.add(ann.catdoc(), 1); if (ann.descr().full()) row.add(ann.descr(), 2); if (ann.opcee().full()) row.add(ann.opcee(), 3); row.add(ann.obblig(), 4); ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, row, idx++); } ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, "STOP", idx); // Riga terminatrice reload(); } void TCategorie_doc::save_cat() { remove_all_cat(); int idx = 0; FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj) { TClasse_doc& cd = (TClasse_doc &) *obj; TToken_string row; if (cd.catdoc().full()) row.add(cd.catdoc(), 1); if (cd.descr().full()) row.add(cd.descr(), 2); if (cd.class_sost().full()) row.add(cd.class_sost(), 3); if (cd.caus_sost().full()) row.add(cd.caus_sost(), 4); if (cd.causcont().full()) row.add(cd.causcont(), 5); if (cd.tipocaus().full()) row.add(cd.tipocaus(), 6); ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, row, idx++); } ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, "STOP", idx); // Riga terminatrice reload(); } const char* TCategorie_doc::traduci_caus_sost(const TString& caus) { if (caus == "TD01") return "TD01 Fattura"; if (caus == "TD02") return "TD02 Acconto/Anticipo su fattura"; if (caus == "TD03") return "TD03 Acconto/Anticipo su parcella"; if (caus == "TD04") return "TD04 Nota di credito"; if (caus == "TD05") return "TD05 Nota di debito"; if (caus == "TD06") return "TD06 Parcella"; if (caus == "TD16") return "TD16 Integraz. fatt. rev.ch. interno"; if (caus == "TD17") return "TD17 Integ./autof. acq. servizi estero"; if (caus == "TD18") return "TD18 Integ. acq. beni intracomunitari"; if (caus == "TD19") return "TD19 Integ./autof. acq. beni ex art. 17"; if (caus == "TD20") return "TD20 Autofattura"; if (caus == "TD21") return "TD21 Autofattura per splafonamento"; if (caus == "TD22") return "TD22 Estrazione beni da Deposito IVA"; if (caus == "TD23") return "TD23 Estr. beni Deposito IVA vers. IVA"; if (caus == "TD24") return "TD24 Fatt. differita art.21 c.4 lett. a"; if (caus == "TD25") return "TD25 Fatt. differita art. 21 c.4 per.3 b"; if (caus == "TD26") return "TD26 Cess. beni ammort./passaggi interni"; if (caus == "TD27") return "TD27 Fatt. autoconsumo/cessioni gratuite"; return ""; } const char* TCategorie_doc::traduci_class_ann(const TString& class_ann) { if (class_ann == "RC") return "Reverse Charge"; if (class_ann == "DC") return "ANN. cartaceo"; return ""; } const char* TCategorie_doc::traduci_class_sost(const TString& class_sost) { if (class_sost == "FTA") return "FTA - Fattura Acquisti"; if (class_sost == "FTV") return "FTV - Fattura di Vendita"; return ""; } TAnnesso * TCategorie_doc::find_annesso(const TString& catdoc_padre, const char* catdoc_ann) { TToken_string key = catdoc_padre; key.add(catdoc_ann); return (TAnnesso *)_rows_annessi.objptr(key); } void TCategorie_doc::add_annesso(const TString& catdoc_padre, const TString& catdoc_ann, const TString& descr, const TString& class_ann, const bool obblig) { if(!(catdoc_padre && *catdoc_padre && catdoc_ann && *catdoc_ann && class_ann && *class_ann)) fatal_box("add_annesso failed: some parameters are NULL or keys are empty"); TToken_string key = catdoc_padre; key.add(catdoc_ann); _rows_annessi.add(key, new TAnnesso(catdoc_padre, catdoc_ann, descr, class_ann, obblig)); save_ann(); } void TCategorie_doc::edit_annesso(const TString& catdoc_padre, const TString& catdoc_ann, const TString& descr, const TString& class_ann, const bool obblig) { if (!(catdoc_padre && *catdoc_padre && catdoc_ann && *catdoc_ann && class_ann && *class_ann)) fatal_box("add_annesso failed: some parameters are NULL or keys are empty"); if (find_annesso(catdoc_padre,catdoc_ann) != nullptr) del_annesso(catdoc_padre,catdoc_ann); TToken_string key = catdoc_padre; key.add(catdoc_ann); _rows_annessi.add( key, new TAnnesso(catdoc_padre, catdoc_ann, descr, class_ann, obblig)); save_ann(); } void TCategorie_doc::add_categoria(const TString& catdoc, const TString& descr, const TString& class_sost, const TString& caus_sost, const TString& causcont, const TString& tipocaus) { if(!(catdoc && *catdoc && class_sost && *class_sost && caus_sost && *caus_sost)) fatal_box("add_categoria failed: some parameters are NULL or keys are empty"); _rows.add(catdoc, TClasse_doc(catdoc, descr, class_sost, caus_sost, causcont, tipocaus)); save_cat(); } void TCategorie_doc::del_annesso(const TString& catdoc, const char* catdoc_ann) { if (find_annesso(catdoc, catdoc_ann) != nullptr) { TToken_string key = catdoc; key.add(catdoc_ann); _rows_annessi.remove(key); save_ann(); } } TAnnesso * TCategorie_doc::get_ann(const TString & catdoc ,const TString& catann) { TToken_string key = catdoc; key.add(catann); TAnnesso * ann = (TAnnesso *) _rows_annessi.objptr(key); return ann; } TString_array TCategorie_doc::get_array_ann(const TString& catdoc) { TString_array sa(0); FOR_EACH_ASSOC_OBJECT(_rows_annessi, hash, key, obj) { TAnnesso & ann = (TAnnesso &) *obj; if (ann.catdocpadre() == catdoc) { TToken_string row(ann.catdoc()); sa.add(row); } } return sa; } TString_array TCategorie_doc::get_array_rows(const bool traduci) { TString_array sa(_rows.items()); FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj) { TClasse_doc & row = (TClasse_doc &)*obj; TToken_string ts; ts.add(row.catdoc()); ts.add(row.descr()); ts.add(!traduci ? row.class_sost() : traduci_class_sost(row.class_sost())); ts.add(!traduci ? row.caus_sost() : traduci_caus_sost(row.caus_sost())); ts.add(row.causcont()); ts.add(row.tipocaus()); sa.add(ts); } return sa; } TArray_sheet * TCategorie_doc::get_sheet_catdocs() { if (_sheet_catdocs == nullptr) { _sheet_catdocs = new TArray_sheet(-1, -1, 125, 20, "Categorie Documentali", "Categoria\nDocumento(Codice)@15|Descrizione\nDocumento@26|" "Classe Documentale\nSostitutiva@13|Causale per\nSostitutiva (TD01...)@13|" "Causale\nContabile@8|Tipo\nDocumento@8", MODE_SHEETS); safe_delete(_name_catdocs); _name_catdocs = new TString_array; //_sheet_catdocs->add_button(DLG_CANCEL, "Annulla", K_ESC, TOOL_CANCEL, TOOL_CANCEL); const TString_array ar = get_array_rows(); FOR_EACH_ARRAY_ITEM(ar, nr, row) { _sheet_catdocs->add(*(TToken_string*)row); _name_catdocs->add(((TToken_string*)row)->get(0)); } } return _sheet_catdocs; } TArray_sheet * TCategorie_doc::get_sheet_ann(const TString& catdoc) { TArray_sheet * sheet = find_sheet_annessi(catdoc); if (sheet != nullptr) _sheets_annessi.remove(catdoc); sheet = find_sheet_annessi(catdoc); if (find_sheet_annessi(catdoc) == nullptr) { TString title; title << "Annessi della Categoria " << catdoc; sheet = new TArray_sheet(-1, -1, 78, 13, title, "Categoria\nAnnesso(Codice)@15|Descrizione\nDocumento@26|" "Classificazione\nAnnesso@14|Obbligatorio@8", _mode_sheet); const auto inserted = _sheets_annessi.add(catdoc, sheet); const TString_array & aann = get_array_ann(catdoc); FOR_EACH_ARRAY_ITEM(aann, nr, r) { TToken_string & row = *(TToken_string*)r; TAnnesso * ann = find_annesso(catdoc, row.get(0)); if(ann != nullptr) { TToken_string t; t.add(ann->catdoc()); t.add(ann->descr()); t.add(ann->opcee()); t.add(ann->obblig()); sheet->add(t); } } } return sheet; } TClasse_doc * TCategorie_doc::mov2cat(const long numreg) { // Leggo la causale e cerco la corrispondente nelle categorie documentali, se c'e'. // Guardo le colonne causale cont., tipodoc, class. cat. (opcee) const TRectype & mov = cache().get(LF_MOV, numreg); const TString& caus = mov.get(MOV_CODCAUS); const TCausale & c = cached_causale(caus, mov.get_date(MOV_DATAREG).year()); const TString& tipodoc = c.tipo_doc(); // Cerco se ho un record che abbia specificata quella caus. contabile TClasse_doc * cat = find_causcont(caus); if (cat != nullptr) return cat; // Altrimenti cerco per tipo documento return find_tipodoc(tipodoc); } void TCategorie_doc::reload() { load_all(); } void TCategorie_doc::remove_all() { remove_all_ann(); remove_all_cat(); } void TCategorie_doc::remove_all_ann() { int idx = 0; TString iget = "start"; while (iget != "STOP" && !iget.blank()) { iget = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, "", idx); ini_remove(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, idx++); } } void TCategorie_doc::remove_all_cat() { int idx = 0; TString iget = "start"; while (iget != "STOP" && !iget.blank()) { iget = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, "", idx); ini_remove(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, idx++); } } TCategorie_doc::TCategorie_doc() : _mode_sheet(MODE_SHEETS) { load_all(); } TCategorie_doc& categorie_doc(const bool reload) { static TCategorie_doc* _doc_cats = nullptr; if (_doc_cats == nullptr) _doc_cats = new TCategorie_doc(); else if (reload) _doc_cats->reload(); return *_doc_cats; } /////////////////////////////////////////////////////////////////////////////// // TRecord_categorie /////////////////////////////////////////////////////////////////////////////// TString TRecord_categorie::get(const char* field) { recordtype& rec = _table == 0 ? _categorie : _annessi; const int i = rec.head.find(field); if (i != -1) return rec.record.get(i); return ""; } bool TRecord_categorie::next() { recordtype& rec = _table == 0 ? _categorie : _annessi; TToken_string* p = (TToken_string*)_result_set.objptr(_next_pos++); rec.record = p ? *p : ""; return p; } void TRecord_categorie::put(const char* field, const char* value) { recordtype& rec = _table == 0 ? _categorie : _annessi; const int i = rec.head.find(field); if (i != -1) rec.record.add(value, i); } bool TRecord_categorie::read(bool traduci) { _next_pos = 0; _result_set.destroy(); if (_table == 0) { const TString_array sa = get_array_rows(traduci); FOR_EACH_ARRAY_ITEM(sa, nr, str) { TString s = (*(TToken_string*)str).get(0); if (s == _categorie.record.get(0)) _result_set.add(*(TToken_string*)str); } return next(); } else { const TString catdoc = _annessi.record.get(0); const TString name = _annessi.record.get(1); const TString_array sa = get_array_ann(catdoc); FOR_EACH_ARRAY_ITEM(sa, nr, str) { TString n = (*(TToken_string*)str).get(0); if (name.blank() || n == name) // Se name vuoto perche' sto cercando solo per catdoc { TAnnesso * ann = find_annesso(catdoc, n); if (ann != nullptr) { TToken_string t; t.add(ann->catdocpadre()); t.add(ann->catdoc()); t.add(ann->descr()); t.add(ann->opcee()); t.add(ann->obblig()); _result_set.add(t); } } } return next(); } } TRecord_categorie::TRecord_categorie(type table): _table(table) { _categorie.head.add("NAME"); _categorie.head.add("DESCR"); _categorie.head.add("CLASSDOCSOS"); _categorie.head.add("CAUSSOS"); _categorie.head.add("CAUSCONT"); _categorie.head.add("TIPODOC"); _annessi.head.add("CATDOC"); _annessi.head.add("NAME"); _annessi.head.add("DESCR"); _annessi.head.add("TIPOANN"); _annessi.head.add("OBBLIG"); } /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// const char* check_str(const TString& str) { static TString n_str; n_str.cut(0) << str; n_str.replace("'", "''"); n_str.replace(" ", " "); return (const char*)n_str; }