#include #include #include "f9lib.h" #include "applicat.h" #include "docf9.h" #include "annessif9.h" #include "f901tab.h" #include "mov.h" #include "anagr.h" #include "comuni.h" #include "clifo.h" #include "report.h" #define AMBIENTE_F9 "CODSOC" // Codice ambiente (codsoc) #define ADDRCART_F9 "ADDRCART" #define ADDRDOC_F9 "ADDDOC" // Indirizzo documenti cartacei Server #define ADDRDOCLOC_F9 "ADDDOCLOC" // Indirizzo documenti cartacei Locale #define ESTENSIONI_F9 "DOCUMENTI_EXT" // #define CARTEXP_F9 "CARTEXP" // Flag esporta documenti cartacei #define CHECKVEND_F9 "CHECKVEND" // Flag controlli per vendite (quando hai fatt. con Campo) #define VIEWMOV_F9 "VIEWMOVPRE" // Flag visualizza movimenti prima di estrarre TF9_config F9CONF; void TF9_config::set_ambiente(const TString& cod_amb) { ini_set_string(CONFIG_DITTA, "F9", AMBIENTE_F9, cod_amb); _ambiente = cod_amb; } void TF9_config::set_addr_doc(const TString& path) { ini_set_string(CONFIG_DITTA, "F9", ADDRDOC_F9, path); _addr_doc = path; } void TF9_config::set_addr_doc_loc(const TString& path) { ini_set_string(CONFIG_DITTA, "F9", ADDRDOCLOC_F9, path); _addr_doc_loc = path; } void TF9_config::set_has_cartexp(const bool flag) { ini_set_bool(CONFIG_DITTA, "F9", CARTEXP_F9, flag); _cartexp = flag; } void TF9_config::set_addr_cart(const TString& path) { ini_set_string(CONFIG_DITTA, "F9", ADDRCART_F9, path); _addr_cart = path; } void TF9_config::set_estensioni(const TString& ext) { ini_set_string(CONFIG_DITTA, "F9", ESTENSIONI_F9, ext); _estensioni = ext; } TF9_config::TF9_config() { _ambiente = ini_get_string(CONFIG_DITTA, "F9", AMBIENTE_F9); _addr_cart = ini_get_string(CONFIG_DITTA, "F9", ADDRCART_F9); _addr_doc = ini_get_string(CONFIG_DITTA, "F9", ADDRDOC_F9); _addr_doc_loc = ini_get_string(CONFIG_DITTA, "F9", ADDRDOCLOC_F9); _cartexp = ini_get_bool (CONFIG_DITTA, "F9", CARTEXP_F9); _estensioni = ini_get_string(CONFIG_DITTA, "F9", ESTENSIONI_F9); } /////////////////////////////////////////////////////////////////////////////// // TF9_doccart /////////////////////////////////////////////////////////////////////////////// bool TF9_doccart::add_cart(const TFilename& file, long numreg, const bool is_annesso, const TString& catannpadre, const TString& catdocann, bool suppress_errors) { long numreg_old; bool annesso_found; TF9_doccart f9cart; TLocalisamfile f9docs(LF_F9DOCS); TLocalisamfile f9annessi(LF_F9ANNESSI); if (f9cart.doc_already_exists(file, numreg_old, annesso_found)) { if(!suppress_errors) warning_box("Attenzione: esiste gia' un %s con questo nome associato al num. di registrazione %d", annesso_found ? "annesso" : "documento", numreg_old); return false; } if (!is_annesso) { TFilename doc; if (f9cart.mov2doc(numreg, doc) && !doc.empty()) { if (!suppress_errors) warning_box("Attenzione: la registrazione num. %s ha gia' un documento associato: %s.\n" "Se si tratta di un annesso inserire le informazioni per la cat. documentale.", (const char*)numreg, (const char*)doc); return false; } f9docs.zero(); f9docs.put(F9C_FILENAME, file.name()); f9docs.put(F9C_NUMREG, numreg); f9docs.put(F9C_LOADDATE, TDate(TODAY)); f9docs.put(F9C_USER, user()); } else { // Controllo che non sto gia' utilizzando questa categoria di annesso per questa registrazione // Prendo la lista degli annessi per questa registrazione e li controllo in cerca della categoria TF9_doccart doccart; TArray list_annessi; doccart.mov2listann_vect(numreg, list_annessi); bool exist = false; FOR_EACH_ARRAY_ITEM(list_annessi, row, obj) { TAnnesso_mov * ann_mov = (TAnnesso_mov *) obj; if (ann_mov->catdocann() == catdocann) exist = true; } if (exist) { if (!suppress_errors) message_box("Attenzione: la registrazione num. %s ha gia' un annesso associato con questo tipo di annesso.", (const char*)numreg); return false; } f9annessi.zero(); f9annessi.put(F9A_NUMREG, numreg); f9annessi.put(F9A_FILENAME, file.name()); f9annessi.put(F9A_CATDOCPAD, catannpadre); f9annessi.put(F9A_CATDOCANN, catdocann); f9annessi.put(F9C_LOADDATE, TDate(TODAY)); f9annessi.put(F9C_USER, user()); } TFilename fdestin = F9CONF.get_addr_cart(); const TString filename = file.name(); fdestin << filename; bool ok = true; if ((!suppress_errors) && ( fdestin.exist() )) ok = yesno_box("Esiste già un file con questo nome, devo continuare?"); if (ok) ok = fcopy(file, fdestin); if (!ok) { if (!suppress_errors) warning_box("Errore nel copiare il file nella cartella di destinazione. Ritentare."); f9docs.zero(); return false; } if (!is_annesso) { f9docs.write(); f9docs.rewrite(); } else { f9annessi.write(); f9annessi.rewrite(); } return true; } bool TF9_doccart::doc_already_exists(const TFilename& file, long& numreg, bool& annesso) { annesso = false; const TRectype & tdocs = cache().get(LF_F9DOCS, file.name(), 2); bool ok = tdocs.full(); if (ok) numreg = tdocs.get_long(F9C_NUMREG); else { numreg = 0L; _tannessi.zero(); _tannessi.setkey(2); _tannessi.put(F9A_FILENAME, file.name()); ok = _tannessi.read() == NOERR; if (ok) { numreg = _tannessi.get_long(F9A_NUMREG); annesso = true; } } return ok; } bool TF9_doccart::mov2doc(long numreg, TFilename& doc) { const TRectype & tdocs = cache().get(LF_F9DOCS, numreg); const bool ok = tdocs.full(); doc.cut(0); if (ok) doc << TFilename(F9CONF.get_addr_cart()).slash_terminate() << tdocs.get(F9C_FILENAME); return ok; } bool TF9_doccart::mov2listann(const TString& numreg, _Out_ TString_array& list_annessi) { list_annessi.destroy(); _tannessi.zero(); _tannessi.setkey(1); _tannessi.put(F9A_NUMREG, numreg); TString numreg_fetched; bool ok = false; // Si posiziona nl primo record giusto. Poi per sapere quando terminare guardo se la chiave e' ancora quella giusta. for (_tannessi.read(_isgteq); (numreg_fetched = _tannessi.get(F9A_NUMREG)) == numreg; _tannessi.next()) { ok = true; TString filename = _tannessi.get(F9A_FILENAME); TToken_string t; t.add(numreg_fetched); t.add(_tannessi.get(F9A_FILENAME)); t.add(_tannessi.get(F9A_CATDOCPAD)); t.add(_tannessi.get(F9A_CATDOCANN)); t.add(_tannessi.get(F9A_LOADDATE)); t.add(_tannessi.get(F9A_USER)); list_annessi.add(t); #ifdef DBG CHECK(numreg_fetched == numreg_fetched, "*Maledetooo*"); #endif } return ok; } bool TF9_doccart::mov2listann_vect(const long numreg, TArray & list_annessi) { list_annessi.destroy(); _tannessi.zero(); _tannessi.setkey(1); _tannessi.put(F9A_NUMREG, numreg); bool ok = false; // Si posiziona nl primo record giusto. Poi per sapere quando terminare guardo se la chiave e' ancora quella giusta. for (int err = _tannessi.read(_isgteq) == NOERR; err == NOERR; err = _tannessi.next()) { long numreg_fetched = _tannessi.get_long(F9A_NUMREG); if (numreg_fetched == numreg) { ok = true; TString filename = _tannessi.get(F9A_FILENAME); TAnnesso_mov t(numreg_fetched, _tannessi.get(F9A_FILENAME), _tannessi.get(F9A_CATDOCPAD), _tannessi.get(F9A_CATDOCANN), _tannessi.get_date(F9A_LOADDATE), _tannessi.get(F9A_USER)); list_annessi.add(t); } else break; } return ok; } /////////////////////////////////////////////////////////////////////////////// // TIva_insert_prepared_stat /////////////////////////////////////////////////////////////////////////////// void TIva_insert_prepared_stat::write() { TString vals_appo; _query.cut(0) << "INSERT INTO " F9_IVA " (\n"; int count = 0; bool first = true; FOR_EACH_ASSOC_OBJECT(_fields, hash, key, obj) { if (!first) { _query << ", "; vals_appo << ", "; } if (!first && count == 0) { _query << "\n"; vals_appo << "\n"; } _query << key; vals_appo << *(TString *) obj; first = false; count = ++count % 3; } _query << "\n)\nVALUES (\n" << vals_appo << "\n)"; } void TIva_insert_prepared_stat::add(const char* field, const TString& str, const int len) { if (len == -1 || str.len() <= len) { TString v; v << "'" << check_str(str) << "'"; add_value(field, v); } else _ok &= false; } void TIva_insert_prepared_stat::add(const char* field, const TDate& date) { TString v; if (date.ok()) v << "'" << date.date2ansi() << "'"; else v << "'00010101'"; add_value(field, v); } void TIva_insert_prepared_stat::add(const char* field, const char* str, const int len) { add(field, TString(str), len); } void TIva_insert_prepared_stat::add(const char* field, char c) { TString v; v << "'" << c << "'"; add_value(field, v); } void TIva_insert_prepared_stat::add(const char* field, long l) { TString v; v << l; add_value(field, v); } bool TIva_insert_prepared_stat::get(TString& query) { if (_query.empty()) write(); query.cut(0) << _query; return _ok; } void TIva_insert_prepared_stat::reset() { _fields.destroy(); _ok = true; _query.cut(0); } /////////////////////////////////////////////////////////////////////////////// // TProspetto_recset /////////////////////////////////////////////////////////////////////////////// void TProspetto_recset::precarica_tabelle() { TString sql; const char* v[] = { "RMOVIVA", "MOV", "PCON", "TABCOM" }; for (auto& i : v) { sql.cut(0) << "SELECT * FROM " << i; set(sql); items(); } } void TProspetto_recset::get_sum_imponibile_imposta(const char* numreg_ven, real& s_imponibili, real& s_imposte) { TRecord_array iva(LF_RMOVIVA, RMI_NUMRIG); TRectype* ivafilter = new TRectype(LF_RMOVIVA); ivafilter->put(RMI_NUMREG, numreg_ven); iva.read(ivafilter); s_imponibili = ZERO; s_imposte = ZERO; for (int i = iva.first_row(); i <= iva.rows(); ++i) { TRectype& r = iva[i]; s_imponibili += r.get_real("IMPONIBILE"); s_imposte += r.get_real("IMPOSTA"); } } TProspetto_recset::TProspetto_recset(const char* numreg_acq, const char* numreg_ven) : TSQL_recordset("") { _numreg = new TString; _today = new TString; _ragsoc = new TString; _address = new TString; _cap = new TString; _citta = new TString; _provin = new TString; _codfisc = new TString; _partiva = new TString; _ndoc = new TString; _datadoc = new TString; _totdoc = new TString; _codforn = new TString; _ragsocforn = new TString; _addrforn = new TString; _capforn = new TString; _cittaforn = new TString; _provinforn = new TString; _partivaforn = new TString; _regacq = new TString; _protivaacq = new TString; _dataregacq = new TString; // In modo da dare la possibilita' a SQLite di caricare le tabelle di campo, // altrimenti con tutte le join e from concatenate non ce la fa e fallirebbe. precarica_tabelle(); TLocalisamfile anagraf(LF_ANAG), clifo(LF_CLIFO), comuni(LF_COMUNI), mov_acq(LF_MOV), mov_ven(LF_MOV), rmoviva(LF_RMOVIVA); mov_acq.put(MOV_NUMREG, numreg_acq); mov_acq.read(); anagraf.put(ANA_TIPOA, "G"); anagraf.put(ANA_CODANAGR, prefix().get_codditta()); anagraf.read(); format_string(*_numreg, TString(numreg_ven)); format_string(*_today, TDate(TODAY)); // DATI SOCIETA': format_string(*_ragsoc, anagraf.get(ANA_RAGSOC)); format_string(*_address, TString(anagraf.get(ANA_INDRES)) << ", " << anagraf.get(ANA_CIVRES)); format_string(*_cap, anagraf.get(ANA_CAPRES)); comuni.put(COM_COM, anagraf.get(ANA_COMRES)); if (comuni.read() == NOERR) { format_string(*_citta, comuni.get(COM_DENCOM)); format_string(*_provin, comuni.get(COM_PROVCOM)); } else { format_string(*_citta, TString("")); format_string(*_provin, TString("")); } format_string(*_codfisc, anagraf.get(ANA_COFI)); format_string(*_partiva, anagraf.get(ANA_PAIV)); TString ndoc_s; ndoc_s << mov_acq.get(MOV_NUMDOCEXT); if (ndoc_s.empty()) ndoc_s << mov_acq.get(MOV_NUMDOC); format_string(*_ndoc, ndoc_s); format_string(*_datadoc, mov_acq.get(MOV_DATADOC)); format_string(*_totdoc, mov_acq.get(MOV_TOTDOC)); TString codforn_s; codforn_s << mov_acq.get(MOV_CODCF); clifo.zero(); clifo.put(CLI_TIPOCF, "F"); clifo.put(CLI_CODCF, codforn_s); bool ok = clifo.read() == NOERR; format_string(*_codforn, codforn_s); format_string(*_ragsocforn, ok ? clifo.get(CLI_RAGSOC) : ""); format_string(*_addrforn, ok ? TString(clifo.get(CLI_INDCF)) << ", " << clifo.get(CLI_CIVCF) : ""); format_string(*_capforn, ok ? clifo.get(CLI_CAPCF) : ""); if (ok) { comuni.zero(); comuni.put(COM_COM, clifo.get(CLI_COMCF)); comuni.read(); } format_string(*_cittaforn, ok ? comuni.get(COM_DENCOM) : ""); format_string(*_provinforn, ok ? comuni.get(COM_PROVCOM) : ""); format_string(*_partivaforn, ok ? clifo.get(CLI_PAIV) : ""); // Info registrazioni format_string(*_regacq, mov_acq.get(MOV_REG)); format_string(*_protivaacq, mov_acq.get(MOV_PROTIVA)); format_string(*_dataregacq, mov_acq.get(MOV_DATAREG)); // Calcolo dal rmoviva real s_imponibili, s_imposte; get_sum_imponibile_imposta(numreg_ven, s_imponibili, s_imposte); _totale= s_imponibili + s_imposte; _totimponibile= s_imponibili; _totimposta= s_imposte; TString sql; sql << "SELECT COD, CODTAB, S0, R0,\n" "B.GRUPPO, B.CONTO, B.SOTTOCONTO, B.DESCR,\n" "B.NUMREG, B.CODIVA, B.IMPONIBILE, B.IMPOSTA, B.GRUPPO, B.CONTO, B.SOTTOCONTO, B.DATAREG, B.DATADOC, B.REG, B.PROTIVA, B.TOTDOC,\n" << *_today << " AS TODAY, " << *_ragsoc << " AS RAGSOC, " << *_address << " AS ADDRSEDE, " << *_cap << " AS CAP, " << *_citta << " AS CITTA, " << *_provin << " AS PROVIN,\n" << *_codfisc << " AS CODFISC, " << *_partiva << " AS PARTIVA,\n" << *_ndoc << " AS NDOC, " << *_datadoc << " AS DATADOC,\n" << *_codforn << " AS CODFORN, " << *_ragsocforn << " AS RAGSOCFORN, " << *_addrforn << " AS ADDRFORN, " << *_capforn << " AS CAPFORN, " << *_cittaforn << " AS CITTAFORN, " << *_provinforn << " AS PROVINFORN, " << *_partivaforn << " AS PARTIVAFORN,\n" << *_totdoc << " AS TOTDOC,\n" << *_regacq << " AS REGACQ, " << *_protivaacq << " AS PROTIVAACQ, " << *_dataregacq << " AS DATAREGACQ,\n" << _totale << " AS TOTALE, " << _totimponibile << " AS TOTIMPONIBILE, " << _totimposta << " AS TOTIMPOSTA\n" "FROM(\n" "\n" " SELECT PCON.GRUPPO, PCON.CONTO, PCON.SOTTOCONTO, PCON.DESCR,\n" " A.NUMREG AS NUMREG, A.CODIVA, A.IMPONIBILE, A.IMPOSTA, A.GRUPPO, A.CONTO, A.SOTTOCONTO, A.DATAREG, A.DATADOC, A.REG, A.PROTIVA, A.TOTDOC\n" " FROM(\n" " SELECT RMOVIVA.NUMREG AS NUMREG, CODIVA, IMPONIBILE, IMPOSTA, GRUPPO, CONTO, SOTTOCONTO, DATAREG, DATADOC, REG, PROTIVA, TOTDOC\n" " FROM RMOVIVA\n" " JOIN MOV\n" " ON MOV.NUMREG = RMOVIVA.NUMREG\n" " WHERE MOV.NUMREG = " << *_numreg << "\n" "\n" " ) A\n" " JOIN PCON\n" " ON PCON.GRUPPO = A.GRUPPO AND PCON.CONTO = A.CONTO AND PCON.SOTTOCONTO = A.SOTTOCONTO\n" ") B\n" "JOIN TABCOM\n" "ON COD = 'IVA' AND CODTAB = B.CODIVA"; _query = sql; set(sql); } TProspetto_recset::~TProspetto_recset() { delete _numreg; delete _today; delete _ragsoc; delete _address; delete _cap; delete _citta; delete _provin; delete _codfisc; delete _partiva; delete _ndoc; delete _datadoc; delete _totdoc; delete _codforn; delete _ragsocforn; delete _addrforn; delete _capforn; delete _cittaforn; delete _provinforn; delete _partivaforn; delete _regacq; delete _protivaacq; delete _dataregacq; } /////////////////////////////////////////////////////////////////////////////// // TF9Prospetto_integr /////////////////////////////////////////////////////////////////////////////// TFilename TF9Prospetto_integr::get_path_rep() { // Guardo prima nella custom, altrimenti nella root di Campo TFilename freport = firm2dir(-1); freport.add("custom"); freport.add(_name); freport.ext("rep"); if (!freport.exist()) { freport.currdir().slash_terminate() << _name; freport.ext("rep"); } return freport; } bool TF9Prospetto_integr::export_pdf(TFilename& tmp) { return _book.export_pdf(tmp, false); } const char* TF9Prospetto_integr::make_name_rep() { return "prosp_rev.pdf"; } bool TF9Prospetto_integr::preview() { return _book.preview(); } bool TF9Prospetto_integr::operator()(const char* numreg_acq, const char* numreg_ven) { if (_rep.load(_f_report)) { TFilename fprosp; fprosp.tempdir().slash_terminate() << make_name_rep(); TProspetto_recset* _prosp_rs = new TProspetto_recset(numreg_acq, numreg_ven); _items = _prosp_rs->items(); if (_items == 0) { FILE* log; fopen_s(&log, "TF9Prospetto_integr_error.txt", "a"); if (!_prosp_rs->last_exec()) { if (log != nullptr) { TString msg("\n"); msg << _prosp_rs->get_err_msg() << "\n"; fwrite((const char*)msg, sizeof(char), msg.len(), log); } fclose(log); return false; } else if (log != nullptr) { TString msg("\n"); msg << _prosp_rs->get_query() << "\n - Nessun record trovato!\n\n"; fwrite(msg, sizeof(char), msg.len(), log); } fclose(log); return false; } _rep.set_recordset(_prosp_rs); _book.add(_rep); } else { warning_box("Impossibile trovare il report %s per la generazione\ndel prospetto di integrazione Reverse Charge", _name); return false; } return true; } TF9Prospetto_integr::TF9Prospetto_integr() : _f_report(get_path_rep()), _items(0) { }