#include "f90.h" #include "applicat.h" #include "automask.h" #include "f90200a.h" #include "tsdb.h" #include "../fp/fplib.h" #include "f901tab.h" #include "f90100.h" #include "urldefid.h" TString escape(const char* str); /////////////////////////////////////////////////////////////// // TF9_categorie_doc_msk /////////////////////////////////////////////////////////////// class TF9_categorie_doc_msk : public TAutomask { class TNew_annesso_msk : public TMask { public: void edit_mode(const bool edit = true) { enable(101, !edit); } void fill_field(const TString& nome_ann, const TString& descr, const TString& tipo_ann, const bool obblig) { set(101, nome_ann); set(102, descr); set(103, tipo_ann); set(104, obblig); } TNew_annesso_msk(const char* title) : TMask(title, 1, 78, 13) { add_button_tool(DLG_OK, "~Conferma", TOOL_OK); add_button_tool(DLG_NULL, "", 0); add_button_tool(DLG_CANCEL, "~Annulla", TOOL_CANCEL); add_string (101, 0, "Nome tipo annesso:", 1, 1, 10); add_string (102, 0, "Descrizione: ", 1, 2, 30); add_list (103, 0, "Tipologia annesso:", 1, 3, 21, "", "DC|RC", "Annesso Cartaceo|Prospetto Rev. Charge"); add_boolean (104, 0, "Obbligatorio: ", 1, 4); } }; std::shared_ptr _annessi_sheet; TRecord_categorie _categorie_doc; bool on_field_event(TOperable_field& o, TField_event e, long jolly) override; bool on_key(KEY key) override; void check_spell() const; void check_duplicate_tipodoc() const; void delete_annesso(const TString& catdoc_padre); void edit_annesso(const TString& catdoc_padre); void fill_annessi(const TString& catdoc); void load_table() const; void new_annesso(const TString& catdoc_padre); void salva_tabella() const; public: static void correct_spell_catdoc(TString& catdoc); TF9_categorie_doc_msk() : TAutomask("f90200a") { load_table(); } }; bool TF9_categorie_doc_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch(o.dlg()) { case DLG_OK: if (e == fe_button) salva_tabella(); break; case B_DELETE: if (e == fe_button) { TSheet_field& sf = sfield(S_CLASSDOC); sf.hide(); FOR_EACH_SHEET_ROW(sf, nr, row) { if (row->starts_with("X")) { sf.destroy(nr); --nr; } } sf.show(); } break; case DLG_USER: if (e == fe_button) { TSheet_field& sf = sfield(S_CLASSDOC); const TString catdoc_padre(sf.row(sf.selected()).get(1)); fill_annessi(catdoc_padre); int key; while ((key = _annessi_sheet->run()) != K_ESC) { switch (key) { case K_INS: new_annesso(catdoc_padre); break; case K_DEL: delete_annesso(catdoc_padre); break; case K_ENTER: edit_annesso(catdoc_padre); default: break; } } } default: break; } return true; } bool TF9_categorie_doc_msk::on_key(KEY key) { if (key == K_DEL) { TSheet_field& sf = sfield(S_CLASSDOC); sf.hide(); TString_array& arr = sf.rows_array(); arr.destroy(sf.selected(), true); sf.force_update(); sf.show(); } return TAutomask::on_key(key); } void TF9_categorie_doc_msk::check_spell() const { TSheet_field& sf = sfield(S_CLASSDOC); sf.hide(); FOR_EACH_SHEET_ROW(sf, nr, row) { TString catdoc = row->get(F_CATDOC - 101); correct_spell_catdoc(catdoc); row->add(catdoc, 1); } sf.force_update(); sf.show(); } void TF9_categorie_doc_msk::check_duplicate_tipodoc() const { TSheet_field& sf = sfield(S_CLASSDOC); map lookup_table; vector dup; FOR_EACH_SHEET_ROW(sf, nr, row) { if(TString(row->get(5)).empty()) // Se non ha specificato una causale { const char* tipodoc = row->get(6); auto it = lookup_table.find({ tipodoc }); if (it == lookup_table.end()) // Se non lo trovo vuol dire che e' il primo. lookup_table.insert({ tipodoc, 0 }); else { ++it->second; dup.emplace_back(it->first); } } } if (!dup.empty()) warning_box("Ci sono molteplici categorie con lo stesso tipo documento.\nPer una corretta assegnazione della categoria doc. si consiglia\ndi specificare il tipo di causale o rimuovere i duplicati."); } void TF9_categorie_doc_msk::delete_annesso(const TString& catdoc_padre) { if (_annessi_sheet->items() > 0) { const int r = _annessi_sheet->selected(); if (yesno_box("Eliminare l'annesso N. %d?", r + 1)) { _categorie_doc.del_annesso(catdoc_padre, _annessi_sheet->row(r).get(0)); fill_annessi(catdoc_padre); } } } void TF9_categorie_doc_msk::edit_annesso(const TString& catdoc_padre) { if (_annessi_sheet->items() > 0) { TString title; title << "Modifica annesso per " << catdoc_padre; TNew_annesso_msk new_ann(title); new_ann.edit_mode(); TToken_string& r = _annessi_sheet->row(_annessi_sheet->selected()); new_ann.fill_field(r.get(0), r.get(1), r.get(2), r.get_bool(3)); if (new_ann.run() == K_ENTER) { const TString& catann = new_ann.get(101); const TString& descr = new_ann.get(102); const TString& tipo = new_ann.get(103); const bool obblig = new_ann.get_bool(104); _categorie_doc.del_annesso(catdoc_padre, catann); _categorie_doc.add_annesso(catdoc_padre, catann, descr, tipo, obblig); fill_annessi(catdoc_padre); } } } void TF9_categorie_doc_msk::fill_annessi(const TString& catdoc) { TCategorie_doc d; d.set_mode_sheet(0x1E); _annessi_sheet = d.get_sheet_ann(catdoc); _annessi_sheet->add_button(DLG_EDIT, TR("~Modifica"), K_ENTER, TOOL_EDIT); } void TF9_categorie_doc_msk::load_table() const { TSheet_field& sf = sfield(S_CLASSDOC); sf.hide(); sf.destroy(); int idx = 0; while (true) { TToken_string appo(ini_get_string(CONFIG_DITTA, "F9", "CATDOC", "", idx++)); if (appo == "STOP" || appo.empty()) /* STOP: Riga terminatrice */ break; TToken_string& row = sf.row(-1); row = appo; } sf.show(); sf.force_update(); check_duplicate_tipodoc(); } void TF9_categorie_doc_msk::new_annesso(const TString& catdoc_padre) { _categorie_doc.reload(); TString title; title << "Nuovo annesso per " << catdoc_padre; TNew_annesso_msk new_ann(title); while (new_ann.run() == K_ENTER) { TString catann = new_ann.get(101); if (catann.empty()) { warning_box("Inserire il nome tipo annesso"); continue; } TCategorie_doc::annesso ann; if (!_categorie_doc.get_ann(catann, ann)) { const TString& descr = new_ann.get(102); const TString& tipo = new_ann.get(103); const bool obblig = new_ann.get_bool(104); correct_spell_catdoc(catann); _categorie_doc.add_annesso(catdoc_padre, catann, descr, tipo, obblig); fill_annessi(catdoc_padre); } else warning_box("E' gia' presente un annesso con lo stesso nome per la categoria %s", (const char*)catdoc_padre); break; } } void TF9_categorie_doc_msk::salva_tabella() const { check_spell(); int idx = 0; TString iget = "start"; while (iget != "STOP" && !iget.empty()) { iget = ini_get_string(CONFIG_DITTA, "F9", "CATDOC", "", idx); ini_remove(CONFIG_DITTA, "F9", "CATDOC", idx++); } idx = 0; TSheet_field& sf = sfield(S_CLASSDOC); FOR_EACH_SHEET_ROW(sf, nr, row) { if(row->get(1) && TString(row->get(1)).full()) ini_set_string(CONFIG_DITTA, "F9", "CATDOC", *row, idx++); } ini_set_string(CONFIG_DITTA, "F9", "CATDOC", "STOP", idx); // Riga terminatrice // Reload load_table(); } void TF9_categorie_doc_msk::correct_spell_catdoc(TString& catdoc) { catdoc.trim(); catdoc.upper(); std::string ss = (const char*)catdoc; for (size_t i = 0; i < ss.size(); ++i) { if (!(ss[i] >= 'A' && ss[i] <= 'Z' || ss[i] >= '0' && ss[i] <= '9' || ss[i] == '_')) ss.erase(i--, 1); } catdoc = ss.c_str(); } /////////////////////////////////////////////////////////////// // TF9_categorie_doc /////////////////////////////////////////////////////////////// class TF9_categorie_doc : public TSkeleton_application { TString _log; void add_error_log(TString& query); static void precarica_tabella_default(); void main_loop() override; public: TF9_categorie_doc() = default; }; void TF9_categorie_doc::add_error_log(TString& query) { _log << "\n" << query << "\n" << fp_db().sq_get_text_error() << "\n" << fp_db().sq_get_string_error(); } void TF9_categorie_doc::precarica_tabella_default() { TCategorie_doc preload; if (preload.get_array_rows().items() == 0 || noyes_box("Attenzione questa procedura cancellera' le categorie documentali gia' presenti\ne carichera' quelle di default. Continuare?")) { preload.remove_all(); preload.reload(); preload.add_categoria("FATTACQ", "FATTURE DI ACQUISTI", "FTA", "TD01", "", "FA"); preload.add_categoria("FATTVEN", "FATTURE DI VENDITA", "FTV", "TD01", "", "FV"); preload.add_categoria("FATTREV", "Fattura acq. con rev. charge", "FTA", "TD01", "", "FA"); // Da aggiungere causale preload.add_categoria("NOTCREDACQ", "Nota credito di acquisto", "FTA", "TD04", "", "NC"); preload.add_categoria("NOTDEBVEN", "Nota debito di vendita", "FTV", "TD05", "", "ND"); preload.add_categoria("FATTCORR", "Fattura corrispettivi", "FTA", "TD01", "", "CR"); preload.add_categoria("BOLLADOGAC", "Bolla doganale", "FTA", "TD01", "", "BD"); preload.add_annesso("FATTREV", "INTREVC", "Prosp. integr. rev.ch.", "RC", true); } } void TF9_categorie_doc::main_loop() { if(argc() > 2 && argv()[2][0] == '-' && argv()[2][1] == 'd') precarica_tabella_default(); TF9_categorie_doc_msk msk; // Il costruttore carica subito la tabella... while(msk.run() == K_ENTER) { TSheet_field& sf = msk.sfield(S_CLASSDOC); TString query; query << "TRUNCATE TABLE " F9_DRT ";\n"; bool ok = fp_db().sq_set_exec(query, false) && fp_db().sq_commit(); if (ok) { FOR_EACH_SHEET_ROW(sf, nr, row) { query.cut(0); query << "INSERT INTO " F9_DRT "(" DRT_CODSOC ", " DRT_CATDOC ", " DRT_DESCR ", " DRT_CLASSO ", " DRT_CAUSSO ", " DRT_CAUSCON ", " DRT_TIPOCAU ", " DRT_OPCEE ")\nVALUES('" << F9CONF.get_ambiente() << "', '" << row->get(1) << "', '" << // Catdoc escape(row->get(2)) << "', '" << // Descr row->get(3) << "', '" << // Classe doc sost. row->get(4) << "', '" << // Causale sost. escape(row->get(5)) << "', '" << // Causale cont escape(row->get(6)) << "', '" << // Tipo caus. cont row->get(8) << "');\n"; // "Operat. CEE" ok &= fp_db().sq_set_exec(query, false) && fp_db().sq_commit(); if (!ok) break; } } if (!ok) { add_error_log(query); ofstream fout; fout.open("f9.catdoc.dberror.txt"); fout << _log << "\n"; error_box("Errore nel salvataggio dei dati.\nControllare file di errore f9.catdoc.dberror.txt"); } } } TString escape(const char* str) { TString string; string << str; for (int pos = string.find('\''); pos != -1; pos = string.find('\'', pos + 2)) string.insert("'", pos); return string; } int f90200(const int argc, char* argv[]) { TF9_categorie_doc app; app.run(argc, argv, TR("Configurazione Categorie Documentali.")); return 0; }