#include #include #include #include "fplib.h" #include #include #include #include "../ve/velib05.h" #include "../cg/cglib03.h" #include "../fe/felib.h" #include "fp0.h" #include "fp0500a.h" ///////////////////////////////////////////////////////////////////////////////////// // Globals ///////////////////////////////////////////////////////////////////////////////////// #define LEN_HFATT 20 #define LEN_BFATT 50 ///////////////////////////////////////////////////////////////////////////////////// // TMancati_mask ///////////////////////////////////////////////////////////////////////////////////// class TMancati_mask : public TAutomask { int _idx; protected: enum {_codnum, _tipodoc, _dastato, _astato, _tiposdi}; 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_doc_filter(const TDocumentoEsteso& td) const; void fill(); void load_all_fields(); bool _filter_changed; friend class TMancati_app; public: TMancati_mask() : TAutomask("fp0500a"), _filter_changed(true) { disable(DLG_OK); _idx = -1; load_all_fields(); } void save_all_fields() const; }; void TMancati_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)); // Salvo lo sheet TFP_selected_docs selected_docs; selected_docs.save_sheet(sfield(F_DOCUMENTI_TIPO)); // Salvo messaggio corpo mail TToken_string msg(get(F_BODYMAIL), '\n'); int idx = 0; for(const char* row = msg.get(); row; row = msg.get()) fp_settings().set_body_mail(row, idx++); if(idx < _idx) { for(int i=idx; i<_idx; i++) { fp_settings().remove_para_ini(idx); } } } void TMancati_mask::load_all_fields() { set(F_DATAINI, ini_get_string(CONFIG_DITTA, "fp", "dataini")); set(F_DATAEND, ini_get_string(CONFIG_DITTA, "fp", "dataend")); const TToken_string s_accepted_docs(ini_get_string(CONFIG_DITTA, "fp", "accepted_docs"), ';'); // auto& sheet = sfield(F_DOCUMENTI_TIPO); sheet.hide(); TFP_selected_docs selected_docs; if (selected_docs.has_selected_docs()) { // Super nuova gestione super avanzata! selected_docs.fill_sheet(sheet); } else if(s_accepted_docs.full()) { // Nuova gestione avanzata! FOR_EACH_STR_TOKEN(s_accepted_docs, tok) { TToken_string& row = sheet.row(-1); row.add(tok); row.add(TTipo_documento(TToken_string(tok).get(1)).tipo_doc_sdi()); } } else { // Vecchia gestione ): const TString& codnum = ini_get_string(CONFIG_DITTA, "fp", "codnum"); TToken_string tipidocs(ini_get_string(CONFIG_DITTA, "fp", "tipodocs")); FOR_EACH_STR_TOKEN(tipidocs, tok) { TToken_string& row = sheet.row(-1); row.add(codnum); row.add(tok); // Considero 1 e 9 come stati default? row.add(1); row.add(9); row.add(TTipo_documento(tok).tipo_doc_sdi()); } } sheet.force_update(); sheet.show(); // Carico messaggio corpo mail già salvato o vuoto se mai inserito TString msg; int idx = 0; for(TString row = fp_settings().get_body_mail(idx); row != "STOpsTOP"; row = fp_settings().get_body_mail(idx)) { if (idx++ > 0) msg << '\n'; msg << row; } _idx = idx; set(F_BODYMAIL, msg); } void TMancati_mask::fill() { // Salvo subito su file le impostazioni di esportazione, in fplib accedo ai file save_all_fields(); TSheet_field& docs = sfield(F_DOCS); TString_array& sht = docs.rows_array(); docs.hide(); sht.destroy(); const TDate dal = get(F_DATAINI); const TDate al = get(F_DATAEND); TString filter_selected = get(F_FATTSEL); // 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 \n" << "SELECT 33.TIPOCF==\"C\" \n" << "JOIN 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("#DADATADOC", dal); rec.set_var("#ADATADOC", al); TProgress_monitor pi(rec.items(), nullptr); bool first, show, ask = !((show = (first = true))); int fat_no_cod = 0; 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 la numerazione sia tra quelle giuste // Controllo che il tipo documento sia OK if(!check_doc_filter(doc)) continue; if (!chiave_paf(doc, hfatt, bfatt) || !paf0100f.search(nullptr, hfatt, bfatt) || paf0100f.sq_get("P1_GESTIONE") != "N") { continue; } if (paf0100f.sq_get("P1_ERREST") == "M" && ( filter_selected.empty() && paf0100f.sq_get("P1_ERRINT") != MANCATA_SEND || filter_selected == "S" && paf0100f.sq_get("P1_ERRINT") == MANCATA_SEND || filter_selected == "A") ) { TToken_string& row = docs.row(-1); row = ""; 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(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()); row.add(rec.get("20." CLI_COFI).as_string()); row.add(rec.get("20." CLI_DOCMAIL).as_string()); // Indirizzo email row.add(rec.get("20." CLI_BYMAIL).as_string()); // Consenso invio email row.add(paf0100f.sq_get("P1_ERRINT") == MANCATA_SEND? "X" : ""); } } docs.force_update(); docs.show(); } void TMancati_mask::set_filter_changed() { _filter_changed = true; } bool TMancati_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-2019")); 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_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 TMancati_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(); _filter_changed = false; } } if (ok) { TAutomask::next_page(p); if (curr_page() == 1) enable(DLG_OK); else enable(DLG_OK, false); } } bool TMancati_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 TMancati_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 TMancati_mask::check_doc_filter(const TDocumentoEsteso& d) const { const TString codnum = d.get(DOC_CODNUM); const TString tipodoc = d.get(DOC_TIPODOC); const char stato = d.stato(); const TTipo_documento& td = cached_tipodoc(d.get(DOC_TIPODOC)); // Mi precarico la tabella dei documenti scelti FOR_EACH_SHEET_ROW(sfield(F_DOCUMENTI_TIPO), nr, row) { if (codnum.compare(row->get(_codnum)) == 0 && // Codice numerazione tipodoc.compare(row->get(_tipodoc)) == 0 && // Tipo documento td.reg_fisc().full() && // Regime fiscale row->get_char(_dastato) <= stato && // Da stato row->get_char(_astato) >= stato) // A stato return true; } return false; } ///////////////////////////////////////////////////////////////////////////////////// // TMancati_app ///////////////////////////////////////////////////////////////////////////////////// class TMancati_app : public TSkeleton_application { public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); TMancati_app() {} }; void TMancati_app::main_loop() { TMancati_mask mask; while (mask.run() == K_ENTER) { TString_array& sht = mask.sfield(F_DOCS).rows_array(); TFp_mail_sender mail_sender; const TString& msg = mask.get(F_BODYMAIL); if ( !mail_sender.set_alleg(fp_settings().get_allega_fat()) ) { TString msg; msg << "Non è possibile allegare alla fattura:\nAllega in fattura disabilitato nelle impostazioni.\n" << "Inviare lo stesso la mail\nNotifica Mancata Consegna senza allegato?"; if (!noyes_box(msg)) // Se non sono abilitati gli allegati in fattura avviso e chiedo se procedere lo stesso continue; // Esco senza inviare (se risponde no) } // Altrimenti procedo lo stesso con l'invio mail senza pdf FOR_EACH_ARRAY_ROW(sht, nr, row) { const TString mail = row->get(mask.sfield(F_DOCS).cid2index(S_DOCMAIL)); bool accord = TString(row->get(mask.sfield(F_DOCS).cid2index(S_BYMAIL))) == "X"; if (row->starts_with("X") && (mail.blank() || !accord)) { error_box("Attenzione: c'è almeno un cliente senza indirizzo email o senza il consenso per l'invio email."); break; } } 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))); const TFixed_string tipodoc(riga->get(mask.sfield(F_DOCS).cid2index(S_TIPODOC))); const long codcf = riga->get_long(mask.sfield(F_DOCS).cid2index(S_CLIENTE)); const TString mail = riga->get(mask.sfield(F_DOCS).cid2index(S_DOCMAIL)); bool accord = TString(riga->get(mask.sfield(F_DOCS).cid2index(S_BYMAIL))) == "X"; TString ragsoc = riga->get(mask.sfield(F_DOCS).cid2index(S_RAGSOC)); bool sent = TString(riga->get(mask.sfield(F_DOCS).cid2index(S_SENT))) == "X"; mail_sender.set_doc(anno, ndoc, codnum, tipodoc, codcf, mail, accord, ragsoc, sent); if (mail_sender.send(msg)) { riga->add("", 0); // Se l'invio avviene con successo sfleggo la riga riga->add("X", 11); // E segno inviata } } } } } bool TMancati_app::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 TMancati_app::destroy() { fp_db().sq_disconnect(); return TSkeleton_application::destroy(); } int fp0500(int argc, char* argv[]) { TMancati_app d2p; d2p.run(argc, argv, TR("Elenco Fatture Mancata Consegna")); return 0; }