#include #include #include #include "fplib01.h" #include #include #include "../ve/velib05.h" #include "../cg/cglib03.h" #include "../fe/felib.h" #include "fp0.h" #include "fp0300a.h" #include ///////////////////////////////////////////////////////////////////////////////////// // Globals ///////////////////////////////////////////////////////////////////////////////////// #define LEN_HFATT 20 #define LEN_BFATT 50 ///////////////////////////////////////////////////////////////////////////////////// // TPa_mask ///////////////////////////////////////////////////////////////////////////////////// class TPA_mask : public TAutomask { protected: void set_filter_changed(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void next_page(int p); bool check_not_empty(); bool check_full_fields() const; bool check_tipo_doc(const TTipo_documento& td); void fill(); void init(); bool is_fattura(const TRectype& doc) const; void load_all_fields(); bool _filter_changed; unique_ptr _tipi_doc_scelti; public: TPA_mask() : TAutomask("fp0300a"), _filter_changed(true) { disable(DLG_OK); load_all_fields(); } void save_all_fields() const; }; bool TPA_mask::is_fattura(const TRectype& doc) const { const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC)); if (!td.is_fattura()) // Tengo per buone solo le fatture e le note di credito return false; const TCodice_numerazione& cn = cached_numerazione(doc.get(DOC_CODNUM)); return cn.tipo() == 2 && !cn.get_bool("B10"); // Controlla se fattura provvisioria esclusa da P.A. } void TPA_mask::save_all_fields() const { ini_set_string(CONFIG_DITTA, "fp", "dataini", get(F_DATAINI)); ini_set_string(CONFIG_DITTA, "fp", "dataend", get(F_DATAEND)); ini_set_string(CONFIG_DITTA, "fp", "codnum", get(F_CODNUM)); TToken_string tipidocs = get_tmp_string(); FOR_EACH_SHEET_ROW(sfield(F_DOCUMENTI_TIPO), n, r) { tipidocs.add(r->get(0)); } ini_set_string(CONFIG_DITTA, "fp", "tipodocs", tipidocs); } void TPA_mask::load_all_fields() { set(F_DATAINI, ini_get_string(CONFIG_DITTA, "fp", "dataini")); set(F_DATAEND, ini_get_string(CONFIG_DITTA, "fp", "dataend")); set(F_CODNUM, ini_get_string(CONFIG_DITTA, "fp", "codnum")); TToken_string tipidocs(ini_get_string(CONFIG_DITTA, "fp", "tipodocs")); auto& sheet = sfield(F_DOCUMENTI_TIPO); sheet.hide(); FOR_EACH_STR_TOKEN(tipidocs, tok) { TToken_string& row = sheet.row(-1); row.add(tok); row.add(TTipo_documento(tok).tipo_doc_sdi()); } sheet.force_update(); sheet.show(); } TString& add_filter(const TString& field, const TString& from, const TString& to) { TString& query = get_tmp_string(); const TString qf = field.find('.') < 0 ? field : field.sub(field.find('.') + 1); if (from.full() && to.full()) { query << "&&(BETWEEN(" << field << ", #DA" << qf << ", #A" << qf << "))"; } else if (from.full()) { query << "&&(" << field << ">=#DA" << qf << ")"; } else if (to.full()) { query << "&&(" << field << "<=#A" << qf << ")"; } return query; } void TPA_mask::fill() { save_all_fields(); // Pulisco i tipi documento _tipi_doc_scelti.reset(); TSheet_field& docs = sfield(F_DOCS); TString_array& sht = docs.rows_array(); docs.hide(); sht.destroy(); const TDate dal = get(F_DATAINI); TString filter_selected = get(F_FATTSEL); enable(DLG_OK, filter_selected != "X"); // Record di controllo per eventuali elaborazioni precedenti TString hfatt(LEN_HFATT), bfatt(LEN_BFATT); TPaf_record paf0100f("PAF0100F"); TString query; query << "USE 33 KEY 3" << "\nSELECT (33.TIPOCF=='C')&&" << "(33.CODNUM==#CODNUM)"; query << "\nJOIN 20 INTO TIPOCF==TIPOCF CODCF==CODCF \n" << "JOIN 17 TO 33 INTO TIPOCF==TIPOCF CODCF==CODCF \n" << "JOIN %TIP TO 33 ALIAS 400 INTO CODTAB==TIPODOC\n" << "FROM DATADOC=#DADATADOC\n" << "TO DATADOC=#ADATADOC"; TISAM_recordset rec(query); rec.set_var("#CODNUM", get(F_CODNUM)); rec.set_var("#DADATADOC", get_date(F_DATAINI)); rec.set_var("#ADATADOC", get_date(F_DATAEND)); TProgress_monitor pi(rec.items(), nullptr); bool first, show, ask = !((show = (first = true))); int fat_no_cod = 0; // Disabilito la colonna del codice ufficio docs.enable_column(docs.cid2index(S_UFFICIO), false); for (bool okc = rec.move_first(); okc; okc = rec.move_next()) { if (!pi.add_status()) break; const TRectype& doc = rec.cursor()->curr(); const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC)); // Controllo che il tipo documento sia OK if(!check_tipo_doc(td)) continue; bool sent = false; if (chiave_paf(doc, hfatt, bfatt)) { if (paf0100f.search(nullptr, hfatt, bfatt)) { if (paf0100f.sq_get("P1_GESTIONE") != filter_selected) continue; sent = true; } else if (filter_selected.not_empty()) continue; } TToken_string& row = docs.row(-1); row = sent ? " " : "X"; row.add(rec.get(DOC_ANNO).as_int(), 1); row.add(rec.get(DOC_CODNUM).as_string()); row.add(rec.get(DOC_TIPODOC).as_string()); row.add(td.tipo_doc_sdi()); row.add(rec.get(DOC_NDOC).as_int()); row.add(rec.get(DOC_DATADOC).as_date()); row.add(rec.get(CFV_CODCF).as_int()); row.add(rec.get("20." CLI_RAGSOC).as_string()); TString rif = rec.get("17." CFV_PADESTIN).as_string(); if (rif.empty()) rif = rec.get("20.PEC").as_string(); // Se è ancora vuoto potrebbe essere estero if(rif.empty()) { static TString codcf; codcf.cut(0) << "C|" << rec.get(CFV_CODCF).as_string(); TAnagrafica a(LF_CLIFO, codcf); if (a.estero()) rif = "XXXXXXX"; else { // Segno la riga errata if (first) { first = false; // Abilito la colonna del codice ufficio per segnalare l'errore docs.enable_column(docs.cid2index(S_UFFICIO)); } docs.set_back_and_fore_color(COLOR_RED, COLOR_WHITE, rec.current_row(), docs.cid2index(S_UFFICIO)); fat_no_cod++; } } if(rif.full()) docs.set_back_and_fore_color(COLOR_WHITE, COLOR_BLACK, rec.cursor()->pos(), docs.cid2index(S_UFFICIO)); row.add(rif); row.add(rec.get("17." CFV_PARIFAMM).as_string()); row.add(rec.get("20." CLI_COFI).as_string()); bool split = rec.get("20." CLI_SPLITPAY).as_bool(); if (split) { const long numreg = rec.get(DOC_NUMREG).as_int(); if (numreg > 0) { const TRectype& mov = cache().get(LF_MOV, numreg); split = is_split_payment(mov); } } row.add(split ? "X" : " "); const bool attach = !rec.get("COLL_GOLEM").is_empty(); row.add(attach ? "X" : " "); row.add(!td.invio_xml() ? "X" : ""); } docs.force_update(); docs.show(); if (fat_no_cod > 0) warning_box("Sono state trovate una o più fatture senza codice destinatario nè pec"); } void TPA_mask::set_filter_changed() { _filter_changed = true; } bool TPA_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_RECALC: if (e == fe_button) next_page(1); break; case F_DATAINI: if (e == fe_init) o.set(ini_get_string(CONFIG_DITTA, "fp", "LastXML", "01-01-2018")); else if (e == fe_close) ini_set_string(CONFIG_DITTA, "fp", "LastXML", o.get()); break; case F_DATAEND: if (e == fe_init) o.set(TDate(TODAY)); case F_DOCS: if (e == se_query_add || e == se_query_del) return false; break; case DLG_USER: if (e == fe_button && jolly > 0) { TSheet_field& docs = sfield(F_DOCS); TToken_string& row = docs.row(docs.selected()); TRectype doc(LF_DOC); doc.put(DOC_PROVV, 'D'); doc.put(DOC_ANNO, row.get(1)); doc.put(DOC_CODNUM, row.get(2)); doc.put(DOC_TIPODOC, row.get(3)); doc.put(DOC_NDOC, row.get(5)); if (doc.edit()) fill(); } break; case DLG_ALL: { if (e == fe_button) { TSheet_field& docs = sfield(F_DOCS); TString_array& sht = docs.rows_array(); const int items = sht.items(); if (items > 0) { const TString4 select = *(sht.row(0).get(0)) == 'X' ? "" : "X"; for (int i = 0; i < items; i++) sht.row(i).add(select, 0); docs.force_update(); } } } break; default: break; } if((e == fe_modify || e >= se_enter) && jolly == 0) { if (o.dlg() >= START_MASK && o.dlg() <= END_MASK) { set_filter_changed(); } } return true; } void TPA_mask::next_page(int p) { bool ok = true; if (_filter_changed && p != 1000) { if ((ok = _filter_changed = check_full_fields())) { TSheet_field& sf = sfield(F_DOCS); fill(); sf.force_update(); _filter_changed = false; } } if(ok) TAutomask::next_page(p); } bool TPA_mask::check_not_empty() { TSheet_field& sheet = sfield(F_DOCS); TString msg; if (sheet.empty()) msg = "La tabella dei movimenti è vuota, vuoi caricarla con i filtri selezionati?"; else if (_filter_changed) msg = "I filtri sono stati cambiati, vuoi ricaricare la tabella con i nuovi filtri selezionati?"; if (msg.full() && yesno_box(msg)) { next_page(1); } return sheet.full(); } bool TPA_mask::check_full_fields() const { // Controllo ogni campo che sia valorizzato FOR_EACH_MASK_FIELD(*this, i, f) { if (!f->on_key(K_ENTER)) return false; } return true; } bool TPA_mask::check_tipo_doc(const TTipo_documento& td) { // Mi precarico la tabella dei documenti scelti if(_tipi_doc_scelti == nullptr) { _tipi_doc_scelti.reset(new TToken_string()); FOR_EACH_SHEET_ROW(sfield(F_DOCUMENTI_TIPO), n, r) { _tipi_doc_scelti->add(r->get(0)); } } // Controllo innanzitutto che sia tra quelli scelti return _tipi_doc_scelti->find(td.codice()) >= 0 && td.tipo_doc_sdi().full() && td.reg_fisc().full(); } ///////////////////////////////////////////////////////////////////////////////////// // TDoc2Paf ///////////////////////////////////////////////////////////////////////////////////// class TDoc2Paf : public TSkeleton_application { public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); TDoc2Paf() {} }; void TDoc2Paf::main_loop() { int ndocs = 0; TPA_mask mask; while (mask.run() == K_ENTER) { TString_array& sht = mask.sfield(F_DOCS).rows_array(); TDoc_fp elab; //elab.set_cache_insert(true); if (!sht.empty()) { TProgress_monitor pi(sht.items(), "Esportazione Fatture"); ndocs = 0; FOR_EACH_ARRAY_ROW(sht, r, riga) { if (riga->starts_with("X")) { const int anno = riga->get_int(mask.sfield(F_DOCS).cid2index(S_ANNO)); const long ndoc = riga->get_long(mask.sfield(F_DOCS).cid2index(S_NDOC)); const TFixed_string codnum(riga->get(mask.sfield(F_DOCS).cid2index(S_CODNUM))); // lascio sapientemente per ultima la get di una stringa const TDoc_key key(anno, codnum, ndoc); if (elab.doc_to_paf(key)) ndocs++; } if (!pi.add_status(1)) break; } } if (ndocs > 0) { if (elab.commit() > 0) { mask.save_all_fields(); message_box(FR("Sono stati elaborati %d documenti"), ndocs); } else error_box("Errore durante il salvataggio"); elab.show_log(); } } } bool TDoc2Paf::create() { open_files(LF_TAB, LF_TABCOM, LF_TABMOD, LF_ANAG, LF_CLIFO, LF_CFVEN, LF_CFBAN, LF_NDITTE, LF_DOC, LF_RIGHEDOC, 0); TRectype cfven(LF_CFVEN); if (cfven.length(CFV_PADESTIN) != 7) // Nuova lunghezza per privati return error_box(TR("Database non convertito per fatturazione F.P.")); return check_tables() && TSkeleton_application::create(); } bool TDoc2Paf::destroy() { fp_db().sq_disconnect(); return TSkeleton_application::destroy(); } int fp0300(int argc, char* argv[]) { TDoc2Paf d2p; d2p.run(argc, argv, TR("Fatturazione F.P.")); return 0; }