#include #include "applicat.h" #include "lffiles.h" #include "isam.h" #include "mov.h" #include "../f1/f1lib.h" #include "../fp/fplib.h" #include "urldefid.h" #include "progind.h" #include "f90100.h" #include "f901tab.h" #include "f90100c.h" #include "f90100b.h" /* * - Per aggiornare le tabelle f9 aggiungere nella cartella "sql\f9\" il file sql cosi' fatto: * f9xxxx.sql dove xxxx e' il numero zero-filled della versione delle tabelle, che INCREMENTA DI DUE COME CON LE PATCH, IMPORTANTE! * - Aggiornare la definizione qui sotto di SQL_VERSION mettendo la nuova versione. * - Fare patch del file sql e dell'eseguibile f90.exe * - Lanciare il programma per eseguire l'aggiornamento. */ #define TABMOD_TABVER "S0" // Campo per la memorizzazione della versione attuale delle tabelle #define TAB_BASE_VERSION 100 // Versione base delle tabelle #define SQL_VERSION 100 // Utilizzo questo per controllare la versione attuale delle tabelle e nel caso aggiornarle SSimple_query& db() { static SSimple_query* db = nullptr; if (db == nullptr) { db = new SSimple_query(); set_connection(*db); } return *db; } TMask** esclusi_mask() { static TMask* _esclusi_mask = nullptr; if(_esclusi_mask == nullptr) { _esclusi_mask = new TMask("f90100c.msk"); TMask& m = *_esclusi_mask; ((TSheet_field&)m.field(S_ESCL)).set_notify(TF9_app::select_escl_notify); // Handler dello sheet per selezione singola m.set_handler(DLG_FINDREC, TF9_app::controllo_escl_handler); // Bottone per aprire maschera di controllo movimenti m.set_handler(B_ESTRAI, TF9_app::estrai_escl_handler); // Bottone estrai TMask& sheet_m = ((TSheet_field&)m.field(S_ESCL)).sheet_mask(); // Maschera dei campi dello sheet sheet_m.set_handler(DLG_USER, TF9_app::mov_handler); // Bottone collega movimento m.field(DLG_FINDREC).disable(); } return &_esclusi_mask; } 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; } //////////////////////////////////////////////////////// // TEstrai_mask //////////////////////////////////////////////////////// TEstrai_mask::TEstrai_mask() : TMask("Estrazione", 1, 60, 16) { add_button_tool(DLG_ELABORA, "Estrai", TOOL_ELABORA); add_button_tool(DLG_NULL, "", 0); add_button_tool(DLG_QUIT, "Esci", TOOL_QUIT); add_groupbox(ES_DATEGROUP, 0, "Inserire periodo per estrazione:", 1, 0, 59, 3, ""); add_date(ES_DATAINI, 0, "dal", 4, 1, ""); add_date(ES_DATAEND, 0, " al", 33, 1, ""); add_groupbox(ES_FLAGGROUP, 0, "Selezionare tipo di estrazione:", 1, 3, 28, 3, ""); add_list(ES_FLAGPROV, 0, "Flag provvisorio", 2, 4, 1, "", "P|D", "Provvisorio|Definitivo"); add_groupbox(ES_TIPOGROUP, 0, "Selezionare documenti da estrarre:", 32, 3, 28, 3, ""); add_list(ES_TIPODOC, 0, "Tipi documento", 33, 4, 1, "", "A|V", "Acquisti|Vendite"); add_groupbox(ES_DESCGROUP, 0, "Inserire descrizione estrazione:", 1, 6, 59, 3, ""); add_string(ES_DESCR, 0, "Descrizione", 2, 7, 250, "", 40); TMask::set_handler(DLG_ELABORA, estrai_handler); TMask::set_handler(ES_DATAINI, dataini_handler); TMask::set_handler(ES_DATAEND, dataend_handler); TDate dt(TODAY); dt.set_day(1); dt.set_month(1); set(ES_DATAINI, dt); set(ES_DATAEND, today); } bool TEstrai_mask::estrai_handler(TMask_field& f, KEY key) { auto& msk = (TEstrai_mask&)f.mask(); // this estrai_mask const int stato = app().estrai(); if (stato == 1) { message_box("Estrazione avvenuta con successo!"); app().segna_estratti(); } if (!stato) { app().segna_in_errore(); warning_box("L'estrazione non e' stata completata. Controllare il log degli errori."); } msk.field(ES_DESCR).set(""); msk.stop_run(K_FORCE_CLOSE); return true; } void TEstrai_mask::enable_fields(bool en) { enable(ES_DATAINI, en); enable(ES_DATAEND, en); enable(ES_FLAGPROV, en); enable(ES_TIPODOC, en); } bool TEstrai_mask::enable_handler(TMask_field& f, KEY key) { ((TEstrai_mask&)f.mask()).enable_fields(); return true; } bool TEstrai_mask::dataini_handler(TMask_field& f, KEY key) { TMask& msk = f.mask(); if (key == K_TAB) { if(msk.get(ES_DATAINI).full() && msk.get(ES_DATAEND).full() && msk.get_date(ES_DATAINI) > msk.get_date(ES_DATAEND)) return f.error_box("La data di inizio non puo' essere maggiore di quella di fine"); } return true; } bool TEstrai_mask::dataend_handler(TMask_field& f, KEY key) { TMask& msk = f.mask(); if (key == K_TAB) { if (msk.get(ES_DATAINI).full() && msk.get(ES_DATAEND).full() && msk.get_date(ES_DATAINI) > msk.get_date(ES_DATAEND)) return f.error_box("La data di fine non puo' essere minore di quella di inizio"); } return true; } //////////////////////////////////////////////////////// // TMonitor_mask //////////////////////////////////////////////////////// bool TMonitor_mask::save_conf_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); TF9_app& a = app(); a.set_ambiente(m.get(CF_CODSOC)); a.set_addr_doc(m.get(CF_ADDRDOC)); if(a.get_ambiente().full()) ini_set_string(CONFIG_DITTA, "F9", AMBIENTE_F9, a.get_ambiente()); if(a.get_addr_doc().full()) ini_set_string(CONFIG_DITTA, "F9", ADDRCART_F9, a.get_addr_doc()); m.close(); a.edit_wa(); return true; } void TMonitor_mask::controllo_errori() const { TString id_estr; TSheet_field& sf = sfield(S_ELAB); bool flag = false; FOR_EACH_SHEET_ROW(sf, nr, row) { if (row->get(0)[0] == 'X') { id_estr << row->get(cid2index(F_IDESTR)); flag = true; break; } } if (flag) { TControllo_mask controllo(id_estr); controllo.run(); } else warning_box("Selezionare un'estrazione."); } bool TMonitor_mask::on_key(const KEY key) { return true; } void TMonitor_mask::open_win_estr() { if (!app().get_ambiente().full()) warning_box("Inserire codice ambiente societa' in configurazione"); else app().run_estr_msk(); } void TMonitor_mask::open_win_conf() const { static TMask* m = nullptr; if (m == nullptr) { m = new TMask("Configurazione Archiviazione Sostitutiva", 1, 60, 10); m->add_button_tool(DLG_OK, "Conferma", TOOL_OK); m->add_button_tool(DLG_NULL, "", 0); m->add_button_tool(DLG_QUIT, "Esci", TOOL_QUIT); m->add_groupbox(CF_CODGROUP, 0, "Codice Ambiente Societa' (WEBAPP):", 1, 0, 59, 3, ""); m->add_string(CF_CODSOC, 0, "Codice ambiente", 4, 1, 10, "", 10); m->add_groupbox(CF_ADDRGROUP, 0, "Indicare percorso documenti cartacei:", 1, 3, 59, 3, ""); m->add_string(CF_ADDRDOC, 0, "Percorso", 2, 4, 256, "", 40); m->set_handler(DLG_OK, save_conf_handler); m->set(CF_CODSOC, ini_get_string(CONFIG_DITTA, PAR_MOD, AMBIENTE_F9)); m->set(CF_ADDRDOC, ini_get_string(CONFIG_DITTA, PAR_MOD, ADDRCART_F9)); } m->run(); } void TMonitor_mask::fill() const { app()._ambiente = ini_get_string(CONFIG_DITTA, PAR_MOD, AMBIENTE_F9); app()._addr_doc = ini_get_string(CONFIG_DITTA, PAR_MOD, ADDRCART_F9); TString query; query << "SELECT * FROM F9DRD00K ORDER BY " << DRD_TIME << " DESC;"; db().sq_set_exec(query, false); TSheet_field& sf = sfield(S_ELAB); sf.hide(); sf.destroy(); int i = 0; for (bool ok = db().sq_next(); ok; ok = db().sq_next()) { TString tipo; TToken_string& row = sf.row(i++); row.add(" "); row.add(db().sq_get(DRD_STATO) == "09" ? "X" : ""); row.add(db().sq_get(DRD_ID_EST)); row.add(db().sq_get_date(DRD_TIME)); row.add(db().sq_get(DRD_FLAG_PD) == "P" ? "X" : ""); tipo << db().sq_get(DRD_TIPODOC); if (tipo == "A") tipo << "cquisti"; if (tipo == "V") tipo << "endite"; if (tipo == "C") tipo << "orrispettivi"; row.add(tipo); row.add(db().sq_get_date(DRD_DATADA)); row.add(db().sq_get_date(DRD_DATAA)); row.add(db().sq_get(DRD_UTENTE)); row.add(TF9_app::traduci_stato(db().sq_get(DRD_STATO))); row.add(db().sq_get(DRD_DESC)); } sf.force_update(); sf.show(); } void TMonitor_mask::delete_pack(const bool all) const { bool flag = false; TSheet_field& sf = sfield(S_ELAB); FOR_EACH_SHEET_ROW(sf, nr, row) { if(row->get(0)[0] == 'X' || all) { flag = true; const TString id_estr(row->get(cid2index(F_IDESTR))); TString query; query << "BEGIN\n" " DECLARE @stato CHAR(2);\n\n" " SELECT @stato = " DRD_STATO "\n" " FROM " F9_DRD "\n" " WHERE " DRD_ID_EST " = '" << id_estr << "';\n\n" " IF(@stato = '" D_GEST_ERR "') BEGIN\n" " DELETE FROM " F9_ERR " WHERE IDESTR = '" << id_estr << "';\n" " END\n" " ELSE BEGIN\n" " SELECT @stato AS STATO;\n" " END\n" "END"; db().sq_set_exec(query); // Elimino testata in DRD, solo se provvis. query.cut(0) << "BEGIN\n" " DECLARE @flag_prov CHAR(1), @stato CHAR(2);\n\n" " SELECT @flag_prov = " DRD_FLAG_PD ", @stato = " DRD_STATO "\n" " FROM " F9_DRD "\n" " WHERE " DRD_ID_EST " = '" << id_estr << "';\n\n" " IF (@flag_prov = 'P' OR @stato = '" D_GEST_ERR "') BEGIN\n" " DELETE FROM " F9_DRD " WHERE " DRD_ID_EST " = '" << id_estr << "';\n" " DELETE FROM " F9_IVA " WHERE " IVA_IDLAN " = '" << id_estr << "';\n" " END\n" " SELECT @flag_prov AS FLAG, @stato AS STATO;\n" "END"; db().sq_set_exec(query); if(db().sq_get("FLAG") != "P" && db().sq_get("STATO") != "02" && !all) { warning_box("E' possibile eliminare solo un'estrazione provvisoria o in stato di errore diagnostica gestionale."); return; } if (!all) break; } } if(!flag) { if(noyes_box("Eliminare tutti i pacchetti provvisori o in stato di errore gestionale?")) delete_pack(true); } fill(); } void TMonitor_mask::sel() const { TSheet_field& sf = sfield(S_ELAB); sf.hide(); FOR_EACH_SHEET_ROW(sf, nr, row) { if (*row->get(0) == 'X') row->add("", 0); } sf.force_update(); sf.show(); } bool TMonitor_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_DELREC: if (e == fe_button) delete_pack(); break; case DLG_ELABORA: if (e == fe_button) { enable_page(1, false); open_win_estr(); } break; case DLG_CONFIG: if (e == fe_button) open_win_conf(); break; case DLG_FINDREC: if (e == fe_button) controllo_errori(); break; case DLG_RECALC: fill(); break; case B_SHOWESCL: if(e == fe_button) { app().open_esclusi(); } break; case F_SEL: if(e == fe_modify) { sel(); } default: break; } return true; } ////////////////////////////////////////////////////// // TF9_dberr ////////////////////////////////////////////////////// void TF9_dberr::add_str(const TString& string) { _insert.rtrim(1); if (_insert[_insert.len() - 1] != '(') _insert << ", "; _insert << string << ")"; } void TF9_dberr::add(const TString& string) { TString str; add_str(str << "'" << string << "'"); } void TF9_dberr::add(const long num) { TString app; app << num; add(app); } void TF9_dberr::send() { db().sq_set_exec(_insert); _insert.cut(0) << "INSERT INTO " F9_ERR " VALUES ()"; } void TF9_dberr::del_err(const TString& id_estr, int numreg) { TString query; query << "DELETE FROM " F9_ERR " WHERE IDESTR = '" << id_estr << "' AND NUMREG = '" << numreg << "';"; db().sq_set_exec(query); } char TF9_dberr::get_errori(const TString& id_estr, vector& movs) { TString query; query << "SELECT * FROM " F9_ERR " WHERE IDESTR = '" << id_estr << "';"; db().sq_set_exec(query, false); for (bool ok = db().sq_next(); ok; ok = db().sq_next()) { TToken_string row("", '|'); row.add("X", 0); for (int i = 1; i < 15; i++) { if (db().sq_get_type_field(i) == _datefld) row.add(db().sq_get_date(db().sq_get_name_field(i))); else row.add(db().sq_get(i)); } movs.insert(movs.end(), row); } query.cut(0) << "SELECT " DRD_TIPODOC " FROM " F9_DRD "\n" << "WHERE " DRD_ID_EST " = '" << id_estr << "'"; db().sq_set_exec(query); return db().sq_get((unsigned)0)[0]; } TF9_dberr::TF9_dberr() { _insert.cut(0) << "INSERT INTO " F9_ERR " VALUES ()"; } //////////////////////////////////////////////////////// // TF9_app //////////////////////////////////////////////////////// // Estrazione esclusi bool TF9_app::select_escl_notify(TSheet_field& s, int row, KEY key) { TMask_field& field = s; const TMask& mask = field.mask(); TSheet_field& sf = mask.sfield(S_ESCL); sf.hide(); FOR_EACH_SHEET_ROW(sf, nr, riga) { if (*riga->get(0) == 'X') riga->add("", 0); } sf.force_update(); sf.show(); return true; } bool TF9_app::controllo_escl_handler(TMask_field& field, KEY key) { TControllo_mask controllo(app()._head.id_estr, true); controllo.run(); return true; } bool TF9_app::year_handler(TMask_field& field, KEY key) { if (key == K_TAB) { const int year = real(field.get()).integer(); if (year <= 2001 || year >= 2100) { error_box("Anno non corretto"); field.mask().set(501, today.year()); } } return true; } int TF9_app::estrai_single(TToken_string& row, char flagprov, char tipodoc) { const int numreg = row.get_int(cid2index(F_NUMREG)); const char tipo = flagprov; TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); mov.read(); _head.flag_prov = flagprov == 'P'; _head.dal = mov.get(MOV_DATAREG); _head.al = _head.dal; _head.tipo_doc = tipodoc; _head.cod_soc = _ambiente; // X indica che e' un'estrazione di un escluso _head.id_estr.cut(0) << today.date2ansi() << _estr_msk->get(ES_FLAGPROV) << "X" << next_estr_today(tipo); descr_msk().run(); _head.descr = descr_msk().get(DES_TEXT); descr_msk().set(DES_TEXT, ""); _head.user = user(); _head.addr_cart = _addr_doc; TString err; _head.stato_estr = prepara_movimenti_escl(get_tipoiva(), numreg, err); const bool ok = esporta(); if (!ok) { error_box(db().sq_get_text_error(false)); return -99; } else { _esclusi.clear(); _esclusi.insert(_esclusi.end(), row); if (_head.stato_estr == D_GEST_ERR) { warning_box("Attenzione l'estrazione ha prodotto degli errori. \nControllare e correggere eventuali problemi \npremendo il pulsante 'Controllo Estr.'"); return -2; } if (_head.stato_estr == D_GEST_OK) return estrazione_iva(true) ? 1 : 0; return -3; } } void TF9_app::open_esclusi() { /* Prima chiedo quale mese e anno visualizzare */ // FINESTRA static TMask* ym_msk = nullptr; if (ym_msk == nullptr) { ym_msk = new TMask("Mostra esclusi", 1, 25, 16); ym_msk->add_button_tool(DLG_OK, "Conferma", TOOL_OK); ym_msk->add_button_tool(DLG_NULL, "", 0); ym_msk->add_button_tool(DLG_QUIT, "Esci", TOOL_QUIT); ym_msk->add_groupbox(507, 0, "Movimenti da visualizzare:", 0, 0, 25, 6); ym_msk->add_number(501, 0, "Anno", 1, 1, 4); ym_msk->add_list(502, 0, "Mese", 1, 2, 8, "", "01|02|03|04|05|06|07|08|09|10|11|12", "Gennaio|Febbraio|Marzo|Aprile|Maggio|Giugno|Luglio|Agosto|Settembre|Ottobre|Novembre|Dicembre"); ym_msk->add_list(503, 0, "Fino al", 1, 3, 9, "", " |01|02|03|04|05|06|07|08|09|10|11|12", " |Gennaio|Febbraio|Marzo|Aprile|Maggio|Giugno|Luglio|Agosto|Settembre|Ottobre|Novembre|Dicembre"); ym_msk->add_groupbox(506, 0, "Selezionare il tipo di estrazione", 0, 6, 25); ym_msk->add_list(504, 0, "Flag Provvisorio", 1, 7, 1, "", "P|D", "Provvisorio|Definitivo"); ym_msk->add_list(505, 0, "Tipo doc.", 1, 4, 1, "", "A|V", "Acquisti|Vendite"); ym_msk->set(501, today.year()); ym_msk->set_handler(501, year_handler); } ym_msk->run(); if (ym_msk->last_key() == K_QUIT) return; _flagprov_escl = ym_msk->get(504)[0]; _tipodoc_escl = ym_msk->get(505)[0]; // Caricamento esclusi /* LOADING DI QUEL MESE E ANNO */ app()._esclusi_vect.clear(); const int anno = ym_msk->get_int(501); const int mese = ym_msk->get_int(502); const int to_m = ym_msk->get_int(503); TLocalisamfile movs(LF_MOV); movs.setkey(2); const TDate from(1, mese, anno); TDate to(from); if (to_m != 0) to.set_month(to_m); to.set_end_month(); movs.put(MOV_DATAREG, from); movs.read(); if(movs.get_date(MOV_DATAREG) >= from && movs.get_date(MOV_DATAREG) <= to) { for(bool ok = true; ok && movs.get_date(MOV_DATAREG) <= to; ok = movs.next() == NOERR) { TToken_string stato(movs.get(MOV_ELABF9), ';'); if(stato.items() == 3 && stato.get(2)[0] == 'X') { TToken_string m("", '|'); m.add("", 0); m.add(movs.get_int(MOV_NUMREG)); m.add(movs.get_date(MOV_DATAREG)); m.add(movs.get_date(MOV_DATADOC)); m.add(movs.get(MOV_CODCAUS)); m.add(movs.get(MOV_MESELIQ)); m.add(movs.get(MOV_NUMDOC)); const real imptot = movs.get_real(MOV_TOTDOC) + movs.get_real(MOV_RITFIS) + movs.get_real(MOV_RITSOC); m.add(imptot); m.add(movs.get_int(MOV_CODCF)); TLocalisamfile clifo(LF_CLIFO); TString ragsoc; ragsoc = clifo.get(CLI_RAGSOC); m.add(ragsoc); m.add(TString(movs.get(MOV_REG)) << "/" << movs.get(MOV_PROTIVA)); m.add(movs.get(MOV_DESCR)); app()._esclusi_vect.insert(app()._esclusi_vect.end(), m); } } } if(app()._esclusi_vect.empty()) { warning_box("Non ci sono movimenti esclusi da mostrare"); return; } // Esclusi mask //////////////////////////////// fill_esclusi(); while((*esclusi_mask())->run() == K_ENTER) { } } void TF9_app::fill_esclusi() { vector& esclusi = app()._esclusi_vect; TSheet_field& sf = (*esclusi_mask())->sfield(S_ESCL); sf.hide(); sf.destroy(); for (auto it = esclusi.begin(); it != esclusi.end(); ++it) sf.row(-1) = *it; sf.force_update(); sf.show(); } bool TF9_app::estrai_escl_handler(TMask_field&, KEY key) { TMask* msk = *esclusi_mask(); vector& _esclusi = app()._esclusi_vect; TSheet_field& sf = msk->sfield(S_ESCL); // Prendo la riga selezionata (e controllo che sia selezionato qualcosa) bool flag = false; FOR_EACH_SHEET_ROW(sf, nr, row) { if ((*row)[0] == 'X') { const int stato = app().estrai_single(*row, app()._flagprov_escl, app()._tipodoc_escl); if (stato == 1) { _esclusi.erase(_esclusi.begin() + nr); // Tolto il movimento estratto dal vettore e setto come estratto su elabf9 di mov app().segna_estratti(true, row->get_int(cid2index(F_NUMREG))); } flag = true; break; } } if (!flag) message_box("Selezionare almeno un movimento"); fill_esclusi(); return true; } bool TF9_app::mov_handler(TMask_field&, KEY key) { TSheet_field& sf = (*esclusi_mask())->sfield(S_ESCL); TToken_string& row = sf.row(sf.selected()); TRectype mov(LF_MOV); mov.put(MOV_NUMREG, row.get(sf.cid2index(F_NUMREG))); return open_mov(mov); } TMask& TF9_app::descr_msk() { static TMask* m = nullptr; if (m == nullptr) { m = new TMask("Estrazione", 1, 60, 5); m->add_button_tool(DLG_OK, "Conferma", TOOL_OK); m->add_groupbox(DES_GROUP, 0, "Inserire descrizione estrazione:", 1, 0, 59, 3, ""); m->add_string(DES_TEXT, 0, "Descrizione", 4, 1, 250, "", 40); } return *m; } void TF9_app::edit_wa() const { TString query; query << "DELETE FROM F9WA00K WHERE true;" << "INSERT INTO F9WA00K (F9PCSOC, F9PPCDC0) VALUES (" << _ambiente << ", " << _addr_doc << ");"; } void TF9_app::export_error_list(bool esclusi) { TF9_dberr dberr; vector& movs = esclusi ? _esclusi : _movs; for(auto it = movs.begin(); it != movs.end(); ++it) { if(it->get(0)[0] == 'X') { dberr.add(_head.id_estr); for(int i = 1; i < 15; i++) { TString string(it->get(i)); if (i == 2 || i == 3) // Sono obbligato a far cosi' per aggiungere le date dberr.add(TDate(it->get(i))); else if (string.full()) dberr.add(string); else dberr.add(); // Se vuoto metto NULL } dberr.send(); } } } void TF9_app::load() { const TDate dataini = get_dataini(); const TDate dataend = get_dataend(); const char tipodoc = get_tipodoc(); const bool flagpro = is_provviso(); TLocalisamfile mov(LF_MOV); mov.setkey(2); mov.put(MOV_DATAREG, dataini); int items = 0; TDate datareg; for (bool ok = mov.read(); ok && (datareg = mov.get_date(MOV_DATAREG)) >= dataini && datareg <= dataend; ok = mov.next() == NOERR) items++; TProgress_monitor progr(items, "Acquisizione movimenti"); int i = 0; mov.zero(); mov.setkey(2); mov.put(MOV_DATAREG, dataini); const TipoIVA tipo = tipodoc == 'A' ? iva_acquisti : iva_vendite; TLocalisamfile clifo(LF_CLIFO); // Prendo tutti i movimenti a partire da una data e li carico tutti fino alla data finale _movs.clear(); for (bool ok = mov.read(); ok && (datareg = mov.get_date(MOV_DATAREG)) >= dataini && datareg <= dataend; ok = mov.next() == NOERR) { if (!progr.add_status()) break; TToken_string elab_f9(mov.get(MOV_ELABF9), ';'); // Se definitivo controllo il flag di stampato REGST if (mov.get_bool(MOV_REGST) != flagpro && mov.get(MOV_NUMDOC).full() && TCausale(mov.get(MOV_CODCAUS)).reg().iva() == tipo && (elab_f9.items() == 3 && elab_f9.get(2)[0] != 'X' || elab_f9.empty())) // Controllo che non sia escluso { TToken_string t("", '|'); t.add(""); t.add(mov.get(MOV_NUMREG)); t.add(mov.get(MOV_DATAREG)); t.add(mov.get(MOV_DATADOC)); t.add(mov.get(MOV_CODCAUS)); t.add(mov.get(MOV_MESELIQ)); t.add(mov.get(MOV_NUMDOC)); const real tot = mov.get_real(MOV_TOTDOC) + mov.get_real(MOV_RITFIS) + mov.get_real(MOV_RITSOC); t.add(tot); t.add(mov.get(MOV_CODCF)); clifo.zero(); clifo.put(CLI_TIPOCF, "F"); clifo.put(CLI_CODCF, mov.get(MOV_CODCF)); t.add(clifo.read() == NOERR ? clifo.get(CLI_RAGSOC) : " "); t.add(TString(mov.get(MOV_REG)) << "/" << mov.get(MOV_PROTIVA)); t.add(mov.get(MOV_DESCR)); _movs.insert(_movs.end(), t); i++; } } _tot_movs = i; } const char* TF9_app::traduci_stato(const TString& cod) { static TString stato; static TString last_cod; if (last_cod != cod) { last_cod = cod; stato.cut(0); if (cod == "01") stato << "in diagnostica"; // Deprecated else if (cod == "02") stato << "errore diagnostica gestionale"; else if (cod == "03") stato << "diagnostica gestionale passata"; else if (cod == "04") stato << "controllo WebApp"; else if (cod == "05") stato << "errore diagnostica WebApp"; else if (cod == "06") stato << "diagnostica WebApp passata"; else if (cod == "07") stato << "in elaborazione da sostitutiva"; else if (cod == "08") stato << "errore diagnostica da sostitutiva"; else if (cod == "09") stato << "Archiviato"; } return (const char*)stato; } state_fppro TF9_app::check_fppro(int numreg) const { TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); if (mov.read() == NOERR && check_causale(mov.get(MOV_CODCAUS))) { // 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; 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; } /** Controlla lo stato delle fatture * per le fatt. acquisto non collegate a fppro cerca di agganciarle */ const char * TF9_app::prepara_movimenti(TipoIVA tipo) { bool ok = true; if (tipo == iva_acquisti) { // Controlli per le fatture di acquisto prepara_movimenti TProgress_monitor bar(_movs.size(), "Controllo stato movimenti di acquisto"); for (auto it = _movs.begin(); it != _movs.end(); ++it) { if (!bar.add_status()) break; TToken_string& row = *it; const int numreg = row.get_int(cid2index(F_NUMREG)); switch (check_fppro(numreg)) { case guessed: ok &= fppro_db().associa_mov(numreg); //row.add(fppro_db().get_keys_fppro()); case correct: ok &= true; break; case not_fa: row.add("Non fattura", cid2index(F_DESCRERR)); case reg_with_err: row.add("Registrazione con errori", cid2index(F_DESCRERR)); case no_guessed: ok &= false; row.add("X", 0); // Mi segno il movimento che ha un problema row.add("Non associato a fattura elettr. abbinamento automatico non riuscito. Abbinare manualmente, o escludere", cid2index(F_DESCRERR)); default: break; } } } else if (tipo == iva_vendite) { // Controlli per le fatture di vendita TProgress_monitor bar(_movs.size(), "Controllo stato movimenti di vendita"); for (auto it = _movs.begin(); it != _movs.end(); ++it) { if (!bar.add_status()) break; TToken_string& row = *it; TString numreg(row.get(1)); TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); mov.read(); // Controllo che abbia il riferimento al documento originale generatore del movimento if (mov.get(MOV_DPROVV).empty() || mov.get(MOV_DANNO).empty() || mov.get(MOV_DCODNUM).empty() || mov.get(MOV_DNDOC).empty()) { row.add("X", 0); row.add("Movimento non collegato a un documento originale. Impossibile estrarre. Escludere?", cid2index(F_DESCRERR)); ok &= false; } else if(!is_doc_xml(mov)) // Quindi controllo che sia un documento xml, se no lo metto in errore e te lo escludi a mano se e' da escludere { row.add("X", 0); row.add("Movimento collegato a un documento senza fatturazione elettronica. Escludere?", cid2index(F_DESCRERR)); ok &= false; } } } return ok ? D_GEST_OK : D_GEST_ERR; } // todo: Codice ripetuto andrebbe accorpata con la precedente const char * TF9_app::prepara_movimenti_escl(TipoIVA tipo, int numreg, TString& err) const { bool ok = true; if (tipo == iva_acquisti) { // Controlli per le fatture di acquisto prepara_movimenti switch (check_fppro(numreg)) { case guessed: ok &= fppro_db().associa_mov(numreg); //row.add(fppro_db().get_keys_fppro()); case correct: ok &= true; break; case not_fa: err << "Non fattura"; case reg_with_err: err << "Registrazione con errori"; case no_guessed: ok &= false; err.cut(0) << "Non associato a fattura elettr.; abbinamanto automatico non riuscito. Abbinare manualmente."; default: break; } } else if (tipo == iva_vendite) { // Controlli per le fatture di vendita TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, numreg); mov.read(); // Controllo che abbia il riferimento al documento originale generatore del movimento if (mov.get(MOV_DPROVV).empty() || mov.get(MOV_DANNO).empty() || mov.get(MOV_DCODNUM).empty() || mov.get(MOV_DNDOC).empty()) { err << "Movimento non collegato a un documento originale. Impossibile estrarre."; ok &= false; } else if (!is_doc_xml(mov)) // Quindi controllo che sia un documento xml, se no lo metto in errore e te lo escludi a mano se e' da escludere { err << "Movimento collegato a un documento senza fatturazione elettronica."; ok &= false; } } return ok ? D_GEST_OK : D_GEST_ERR; } bool TF9_app::is_doc_xml(const TLocalisamfile& mov) { const char provv = mov.get(MOV_DPROVV)[0]; const int anno = mov.get_int(MOV_DANNO); const TString& codnum = mov.get(MOV_DCODNUM); const int numdoc = mov.get_int(MOV_DNDOC); const TDocumento doc(provv, anno, codnum, numdoc); TString hfatt(20), bfatt(50), query; if(chiave_paf(doc, hfatt, bfatt)) { query << "SELECT * FROM PAF0100F WHERE P1_KEYHEADERFATT = '" << hfatt << "' AND P1_KEYBODYFATT = '" << bfatt << "';"; db().sq_set_exec(query); return db().sq_items() > 0; } return false; } TString TF9_app::next_estr_today(const char tipo) const { char estr[] = {0,0,0,0,0,0,0,0,0}; TString query; query << "SELECT TOP 1 " DRD_ID_EST " AS IDESTR\n" "FROM " F9_DRD "\n" "WHERE " DRD_ID_EST " LIKE '" << today.date2ansi() << tipo << "%'\n" << "ORDER BY " DRD_ID_EST " DESC"; db().sq_set_exec(query); const int last_estr = db().sq_items() > 0 ? real(db().sq_get("IDESTR").ltrim(10)).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 estr; } bool TF9_app::check_periodo_def(const drd& head) { 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 F9DRD00K\n" << "WHERE " << 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 << "';"; db().sq_set_exec(query); return db().sq_items() == 0; } bool TF9_app::esporta() const { const bool ok = new_extr(); _msk->fill(); return ok; } TString& TF9_app::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& TF9_app::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 TF9_app::new_extr() const { TString query; query << "INSERT INTO " F9_DRD " ( " << drd_attr() << " ) \nVALUES ( " << drd_tovalues() << " );"; bool ok = db().sq_set_exec(query); ok = ok && db().sq_commit(); return ok; } int TF9_app::estrai() { // Carico i movimenti load(); if (_movs.empty()) { warning_box("Non esistono movimenti estraibili per il periodo selezionato."); return -1; } const char tipo = _estr_msk->get(ES_FLAGPROV)[0]; _head.flag_prov = is_provviso(); _head.dal = get_dataini(); _head.al = get_dataend(); _head.tipo_doc = get_tipodoc(); if(!_head.flag_prov) // Se estrazione definitiva controllo il periodo che non si sovrapponga alle altre estrazioni def. { if (!check_periodo_def(_head)) { error_box("Attenzione e' stato inserito un periodo che si sovrappone\nad un'estrazione definitiva gia' esistente."); return -1; } } _head.cod_soc = _ambiente; _head.id_estr.cut(0) << today.date2ansi() << _estr_msk->get(ES_FLAGPROV) << "N" << next_estr_today(tipo); _head.descr = get_descr(); _head.user = user(); _head.addr_cart = _addr_doc; _head.stato_estr = prepara_movimenti(get_tipoiva()); const bool ok = esporta(); if (!ok) error_box("Errore database: impossibile scrivere nuova estrazione."); else { if (_head.stato_estr == D_GEST_ERR) { export_error_list(); warning_box("Attenzione l'estrazione ha prodotto degli errori. \nControllare e correggere eventuali problemi \ndal Controllo Estrazione."); } else if (_head.stato_estr == D_GEST_OK) return estrazione_iva() ? 1 : 0; } return -2; } bool TF9_app::estrazione_iva(const bool escluso) { bool stato = true; TString& codsoc = _ambiente; TString query; vector& movs = escluso ? _esclusi : _movs; TProgress_monitor bar(movs.size(), "Estrazione dati IVA"); for(auto it = movs.begin(); it != movs.end(); ++it) { if (!bar.add_status()) break; TLocalisamfile mov(LF_MOV); mov.put(MOV_NUMREG, it->get(1)); mov.read(); TLocalisamfile cli(LF_CLIFO); cli.put(CLI_TIPOCF, mov.get(MOV_TIPO)); cli.put(CLI_CODCF, mov.get(MOV_CODCF)); cli.read(); TString statopaiv; statopaiv << cli.get(CLI_STATOPAIV); TString idfisc; TString numdoc; numdoc << (mov.get(MOV_NUMDOCEXT).full() ? mov.get(MOV_NUMDOCEXT) : mov.get(MOV_NUMDOC)); if (statopaiv == "IT" || statopaiv.empty()) idfisc << (cli.get(CLI_PAIV).empty() ? cli.get(CLI_COFI) : TString("IT") << cli.get(CLI_PAIV)); else idfisc << statopaiv << cli.get(CLI_COFI); // Esteri query.cut(0) << "INSERT INTO " F9_IVA " (\n" IVA_CODSOC ", " IVA_IDLAN ", " IVA_FLAG_PD ",\n" IVA_ANNOES ", " IVA_GIVA ", " IVA_TIPOG ",\n" IVA_DOCXML ", " IVA_TIPOCF ", " IVA_CODCF ",\n" IVA_RAGSOC ", " IVA_IDFISC ", " IVA_PIVA ",\n" IVA_CODFIS ", " IVA_CATDOC ", " IVA_CAUSSOS ",\n" IVA_NUMDOC ", " IVA_DATADOC ", " IVA_SEZIVA ",\n" IVA_TIPOREG ", " IVA_NPROT ", " IVA_DATPROT; /*if(is_autofattura(mov)) { query << ",\n" IVA_FORNOR ", " IVA_REGOR ", " IVA_NUMOR ", " IVA_DATAOR; }*/ query << ",\n" IVA_CLASDOC ", " IVA_USERELA ", " IVA_TIMEELA; if (_head.tipo_doc == 'A') { query << ",\n" IVA_TIPPROT ", " IVA_NUMPROT ", " IVA_ANNPROT ", " IVA_TIMERIC; } const long datadoc = mov.get_date(MOV_DATADOC).date2ansi(); const long datareg = mov.get_date(MOV_DATAREG).date2ansi(); ; const TString& name_reg = TRegistro(TCausale(mov.get(MOV_CODCAUS)).reg()).name(); query << "\n)\n" << "VALUES (\n" << "'" << codsoc << "', '" << _head.id_estr << "', '" << (_head.flag_prov ? "P" : "D") << "',\n" << "'" << mov.get(MOV_ANNOES) << "', '" << _head.tipo_doc << "', '" << name_reg << "',\n" << "'" << 'S' << "', '" << mov.get(MOV_TIPO) << "', '" << mov.get(MOV_CODCF) << "',\n" << "'" << check_str(cli.get(CLI_RAGSOC)) << "', '" << idfisc << "', '" << cli.get(CLI_PAIV) << "',\n" << "'" << cli.get(CLI_COFI) << "', '" << categoria_doc() << "', '" << caus_sos(mov, get_tipoiva()) << "',\n" << "'" << numdoc << "', '" << datadoc << "', '" << mov.get(MOV_REG) << "',\n" << "'" << "" << "', '" << mov.get(MOV_PROTIVA) << "', '" << datareg << "'"; //if (is_autofattura(mov)) //{ // query << ",\n" << // "'" << "" << "', '" << "" << "', '" << "N ORI" << "', '" << "20010101" << "'"; //} query << ",\n" << "'" << (_head.tipo_doc == 'A' ? "FTA" : "FTV") << "', '" << user() << "', " << "GETDATE()"; if (_head.tipo_doc == 'A') { TToken_string keys(mov.get(MOV_KEYFPPRO), ';'); fppro_db().set_keys(keys); query << ",\n" << "'" << fppro_db().get_tipoprot() << "', '" << fppro_db().get_numprot() << "', '" << fppro_db().get_annoprot() << "', '" << fppro_db().get_dataoraric() << "'"; } query << "\n)"; const bool ok = db().sq_set_exec(query); if(!ok) { ofstream fout; fout.open("f9exp_err.txt"); fout << query << endl; fout << db().sq_get_string_error() << endl; fout << db().sq_get_text_error() << endl << endl; } stato &= ok; } return stato; } const char* TF9_app::categoria_doc() { return ""; // todo: } const char* TF9_app::caus_sos(const TLocalisamfile& mov, TipoIVA acquisti) { if (acquisti == iva_acquisti) { TToken_string keys(mov.get(MOV_KEYFPPRO)); fppro_db().set_keys(keys); return fppro_db().get_tipodoc(); } if (acquisti == 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 ""; } bool TF9_app::is_autofattura(const TLocalisamfile& mov) { return TCausale(mov.get(MOV_CODCAUS)).tipo_doc() == "AF"; } bool TF9_app::segna_estratti(const bool escluso, const int numreg) { bool ok = true; vector escl; if (escluso) escl.insert(escl.begin(), TToken_string(TString("|") << numreg << "|", '|')); vector& movs_v = escluso ? escl : _movs; TLocalisamfile mov(LF_MOV); TToken_string elab("", ';'); elab.add("X", 0); elab.add(today.date2ansi()); elab.add(" "); // "[flag estratto];[data estrazione];[flag escluso]" for(auto it = movs_v.begin(); it != movs_v.end(); ++it) { TString8 num_reg = it->get(cid2index(F_NUMREG)); mov.zero(); mov.put(MOV_NUMREG, num_reg); mov.read(); mov.put(MOV_ELABF9, elab); ok &= mov.rewrite() == NOERR; } return ok; } void TF9_app::segna_in_errore() const { TString query; query << "UPDATE " F9_DRD "\n" "SET " DRD_STATO " = '" D_GEST_ERR "'\n" "WHERE " DRD_ID_EST " = '" << _head.id_estr << "'\n"; db().sq_set_exec(query); } #ifdef DBG void pulisci_mov() { TLocalisamfile mov(LF_MOV); mov.setkey(2); mov.put(MOV_DATAREG, TDate("01-01-2019")); mov.read(); do { mov.put(MOV_ELABF9, ""); mov.write(); mov.rewrite(); }while (mov.next() == NOERR); } #endif void TF9_app::main_loop() { if(!check_table()) fatal_box("Controllo tabelle modulo fallito."); #ifdef DBG // Per sicurezza che non venga inserito in release //pulisci_mov(); #endif _msk = new TMonitor_mask(); _estr_msk = new TEstrai_mask(); _msk->fill(); while (_msk->run() != K_QUIT){ } delete _msk; delete _estr_msk; } bool TF9_app::create_tables() const { bool ok = aggiorna_tab_f9(100); TLocalisamfile tabmod(LF_TABMOD); tabmod.put("MOD", "F9"); tabmod.put("COD", "SQL"); tabmod.put("CODTAB", "VERSION"); char ver[5] = "0000"; sprintf_s(ver, 5, "%04d", 100); tabmod.put(TABMOD_TABVER, ver); tabmod.write(); ok &= tabmod.rewrite() == NOERR; return ok; } bool TF9_app::check_tabelle_f9() const { bool ok = true; TString query; query << "IF (EXISTS (\n" << "SELECT * FROM INFORMATION_SCHEMA.TABLES\n" << "WHERE TABLE_NAME = '" F9_DRD "'))\n" << "SELECT 1 AS EXIST ELSE SELECT 0 AS EXIST"; db().sq_set_exec(query); if (db().sq_get("EXIST") != "1") // Se non esiste la tabella la creo ok &= create_tables(); return ok; } bool TF9_app::aggiorna_tab_f9(int version) const { bool ok = true; TString file; string sql; char ver[5] = "0000"; sprintf_s(ver, 5, "%04d", version); TString name; name << "f9" << ver << ".sql"; file << "sql\\f90\\" << name; std::ifstream fin; fin.open(file); if(ok &= fin.is_open()) { while (!fin.eof() && ok) { std::string appo_line; std::getline(fin, appo_line); if (appo_line[0] == '-' && appo_line[1] == '-') // Se è una riga di commento la salto continue; sql += "\n" + appo_line; const int end = sql.find(';'); // Se trovo un comma lancio la query if(end != int(std::string::npos)) { TString query; query << sql.c_str(); ok &= db().sq_set_exec(query); ok &= db().sq_commit(); sql.erase(); } } } else { TString msg; msg << "Impossibile trovare il file di aggiornamento tabelle: " << file; error_box(msg); } return ok; } bool TF9_app::check_tab_version() const { bool ok = true; TLocalisamfile tabmod(LF_TABMOD); tabmod.put("MOD", "F9"); tabmod.put("COD", "SQL"); tabmod.put("CODTAB", "VERSION"); const bool exists = tabmod.read() == NOERR; int version = exists ? real(tabmod.get(TABMOD_TABVER)).integer() : TAB_BASE_VERSION - 2; if(version < SQL_VERSION) // Controllo la versione { for(; version < SQL_VERSION; version += 2) // Effettuo le modifiche per ogni avanzamento di versione { if (ok &= aggiorna_tab_f9(version + 2)) { char ver[5] = "0000"; sprintf_s(ver, 5, "%04d", version + 2); tabmod.put(TABMOD_TABVER, ver); // Avanzo il contatore della versione in TABMOD if (!exists) { tabmod.zero(); tabmod.put("MOD", "F9"); tabmod.put("COD", "SQL"); tabmod.put("CODTAB", "VERSION"); tabmod.put(TABMOD_TABVER, ver); // Avanzo il contatore della versione in TABMOD tabmod.write(); } tabmod.rewrite(); } else break; } } return ok; } bool TF9_app::check_table() const { if (!check_tab_version()) { TString msg; std::ofstream fout; fout.open("f9checktaberr.txt"); fout << db().sq_get_text_error(false) << std::endl; fout.close(); msg << "! Errore controllo database F9: creazione/aggiornamento tabelle.\n" << db().sq_get_text_error() << "\n" << db().sq_get_string_error(); fatal_box(msg); return false; } return true; } TF9_app& app() { static TF9_app* app = nullptr; if(app == nullptr) app = (TF9_app*)&main_app(); return *app; } int f90100(int argc, char* argv[]) { TF9_app app; app.run(argc, argv, TR("Archiviazione Sostitutiva")); return 0; } ///////////////////////////////////////////// // TControllo_mask ///////////////////////////////////////////// vector& TControllo_mask::import_error_list() { static vector movs; movs.clear(); TF9_dberr dberr; _tipo_doc_err = dberr.get_errori(_id_estr, movs); return movs; } void TControllo_mask::fill() { TSheet_field& sf = sfield(S_CONTROLLO); sf.hide(); sf.destroy(); vector& movs = !_is_escluso ? import_error_list() : app()._esclusi; // Prendo da _esclusi se sto aprendo il controllo dalla maschera degli esclusi for (auto it = movs.begin(); it != movs.end(); ++it) { TToken_string& row = sf.row(-1); if (*it->get(0) == 'X') { row = *it; row[0] = (char&)" "; if (!_is_escluso && _tipo_doc_err == 'A' || _is_escluso && app().get_tipoiva_escl() == iva_acquisti) row.add("", cid2index(F_CESCLUDI)); else row.add("X", cid2index(F_CESCLUDI)); } } sf.force_update(); sf.show(); // Fill fppro sheet if (!_is_escluso && _tipo_doc_err == 'A' || _is_escluso && app().get_tipoiva_escl() == iva_acquisti) fill_fppro_sheet(); } void TControllo_mask::fill_fppro_sheet() const { TSheet_field& sf = sfield(S_FPPRO); sf.hide(); sf.destroy(); const char* order; switch (_ordin) { default: case 'D': order = "P7_DATA"; break; case 'N': order = "P7_NUMERO"; break; case 'F': order = "FORNITORE"; break; case 'R': order = "P2_ANADENOMIN"; break; case 'P': order = "P2_FISCIVACOD"; break; } TString query; query << "SELECT PQ_KEYPRGINVIO AS KEYPRGINVIO, PQ_KEYHEADERFATT AS KEYHEADERFATT, PQ_KEYBODYFATT AS KEYBODYFATT,\n" << "PZ_TIPODOC AS TIPODOC, P7_DATA AS DATA, P7_NUMERO AS NUMDOC, PQ_IMPTOTDOC AS IMPTOTDOC,\n" << "CASE\n" << "WHEN PZ_CLIFOR <> '' THEN CAST(PZ_CLIFOR AS NUMERIC(10, 0))\n" << "WHEN PZ_CLIFOR = '' THEN 0\n" << "END AS FORNITORE, " << "P2_ANADENOMIN AS RAGSOC, P2_FISCIVAPAESE AS STATOPIVA, P2_FISCIVACOD AS PIVA FROM PAA2700F\n" << "JOIN PAA0700F ON PQ_KEYPRGINVIO = P7_KEYPRGINVIO AND PQ_KEYHEADERFATT = P7_KEYHEADERFATT AND PQ_KEYBODYFATT = P7_KEYBODYFATT\n" << "JOIN PAA0200F ON PQ_KEYPRGINVIO = P2_KEYPRGINVIO AND PQ_KEYHEADERFATT = P2_KEYHEADERFATT AND PQ_KEYBODYFATT = P2_KEYBODYFATT\n" << "JOIN FPPRO00F ON PQ_KEYPRGINVIO = PZ_KEYPRGINVIO AND PQ_KEYHEADERFATT = PZ_KEYHEADERFATT AND PQ_KEYBODYFATT = PZ_KEYBODYFATT\n" << "WHERE PZ_NUMREGCONT = '0' AND PZ_DATAREGCONT = '2001-01-01'\n" << "ORDER BY " << order << " " << (_verso == 'A' ? "ASC" : "DESC") << "\n"; fp_db().sq_set_exec(query, false); for (bool ok = fp_db().sq_next(); ok; ok = fp_db().sq_next()) { TToken_string& row = sf.row(-1); row.add(fp_db().sq_get("TIPODOC"), 1); row.add(fp_db().sq_get_date("DATA")); row.add(fp_db().sq_get("NUMDOC")); row.add(fp_db().sq_get("IMPTOTDOC")); row.add(fp_db().sq_get("FORNITORE")); row.add(fp_db().sq_get("RAGSOC")); row.add(fp_db().sq_get("STATOPIVA")); row.add(fp_db().sq_get("PIVA")); row.add(fp_db().sq_get("KEYPRGINVIO") << ";" << fp_db().sq_get("KEYHEADERFATT") << ";" << fp_db().sq_get("KEYBODYFATT")); } sf.force_update(); sf.show(); } TMask& TControllo_mask::get_win_order() { static TMask* m = nullptr; if (m == nullptr) { m = new TMask("Configurazione Archiviazione Sostitutiva", 1, 60, 10); // TOOLBAR m->add_button_tool(DLG_OK, "Conferma", TOOL_OK); m->add_button_tool(DLG_NULL, "", 0); m->add_button_tool(DLG_QUIT, "Esci", TOOL_QUIT); // Ordinatori m->add_radio(F_ORDER, 0, "Ordina per:", 1, 0, 59, "D|N|F|R|P", "DATA|NUMDOC|FORNITORE|RAGSOC|PIVA", "Z"); m->add_radio(F_VERSO, 0, "Verso:", 1, 3, 59, "A|D", "Crescente|Decrescente", "Z"); //m->set_handler(DLG_OK, save_conf_handler); _ordin = ini_get_string(CONFIG_DITTA, PAR_MOD, "ORDINAM", "D")[0]; _verso = ini_get_string(CONFIG_DITTA, PAR_MOD, "VERSO", "A")[0]; m->set(F_ORDER, &_ordin); m->set(F_VERSO, &_verso); /*m->set(CF_CODSOC, ini_get_string(CONFIG_DITTA, PAR_MOD, AMBIENTE_F9)); m->set(CF_ADDRDOC, ini_get_string(CONFIG_DITTA, PAR_MOD, ADDRCART_F9));*/ } return *m; } void TControllo_mask::open_win_order() { TMask& m = get_win_order(); m.run(); _ordin = m.get(F_ORDER)[0]; _verso = m.get(F_VERSO)[0]; ini_set_string(CONFIG_DITTA, PAR_MOD, "ORDINAM", &_ordin); ini_set_string(CONFIG_DITTA, PAR_MOD, "VERSO", &_verso); } TToken_string* TControllo_mask::selected_mov() { TSheet_field& movs = sfield(S_CONTROLLO); FOR_EACH_SHEET_ROW(movs, nr, row) { if (row->get(0)[0] == 'X') { _selected_mov = nr; return row; } } return nullptr; } TToken_string* TControllo_mask::selected_fat() const { TSheet_field& fppro = sfield(S_FPPRO); FOR_EACH_SHEET_ROW(fppro, nr, row) { if (row->get(0)[0] == 'X') return row; } return nullptr; } void TControllo_mask::associa() // todo: levare gli ultimi residui del vecchio funzionamento del controllo errori { TToken_string* mov_sel = selected_mov(); TToken_string* fat_sel = selected_fat(); if (mov_sel == nullptr || fat_sel == nullptr) { warning_box("Selezionare prima un movimento e una fattura elettronica."); return; } TToken_string keys(fat_sel->get(cid2index(F_FPROKEYS)), ';'); fppro_db().set_keys(keys); const bool ok = fppro_db().associa_mov(mov_sel->get_int(cid2index(F_CNUMREG))); if (ok) { // Tolgo il flag di in errore sul vettore in modo da rifare la fill e non venir piu' contato come da controllare vector& movs = _is_escluso ? app()._esclusi : app()._movs; auto it = movs.begin(); int count = -1; while (count < _selected_mov && it != movs.end()) { if (it->get(0)[0] == 'X') // Devo saltare tutti quelli che non hanno il flag e contare solo quelli che ce l'hanno count++; if(count < _selected_mov) ++it; } it->add(" ", 0); TF9_dberr::del_err(_id_estr, mov_sel->get_int(cid2index(F_CNUMREG))); } } void TControllo_mask::selfatt(TOperable_field& o, const long jolly) const { const TMask& mask = *this; TSheet_field* sf; if (jolly == 1) // Sheet controllo sf = &mask.sfield(S_CONTROLLO); else sf = &mask.sfield(S_FPPRO); sf->hide(); FOR_EACH_SHEET_ROW(*sf, nr, row) { if (*row->get(0) == 'X') row->add("", 0); } sf->force_update(); sf->show(); } void TControllo_mask::conferma_esclusi() const { const TMask& mask = *this; TSheet_field& sf = mask.sfield(S_CONTROLLO); sf.hide(); FOR_EACH_SHEET_ROW(sf, nr, row) { TLocalisamfile movs(LF_MOV); movs.put(MOV_NUMREG, row->get_int(cid2index(F_CNUMREG))); movs.read(); if (*row->get(cid2index(F_CESCLUDI)) == 'X') { const TDate today(TODAY); TToken_string stato("", ';'); stato.add("", 0); stato.add(today.date2ansi()); stato.add("X"); movs.put(MOV_ELABF9, stato); movs.rewrite(); row->add("Si", cid2index(F_CESCLUSO)); } else { if (movs.get(MOV_ELABF9).full()) { movs.put(MOV_ELABF9, ""); row->add("", cid2index(F_CESCLUSO)); movs.rewrite(); } } } sf.force_update(); sf.show(); } bool TControllo_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_USER: if (e == fe_button && jolly > 0) { TSheet_field& sf = sfield(S_CONTROLLO); TToken_string& row = sf.row(sf.selected()); TRectype mov(LF_MOV); mov.put(MOV_NUMREG, row.get(sf.cid2index(F_NUMREG))); if (open_mov(mov)) fill(); } break; case B_ORDER: if (e == fe_button) { open_win_order(); fill_fppro_sheet(); } break; case B_ASSOC: if (e == fe_button) { associa(); fill(); // Ricarico gli sheet } break; case B_ESCL: if (e == fe_button) conferma_esclusi(); break; case B_SELESCL: if (e == fe_button) { _sel_esclusi = !_sel_esclusi; field(B_ASSOC).enable(!_sel_esclusi); field(B_ESCL).enable(_sel_esclusi); sfield(S_CONTROLLO).enable_column(cid2index(F_CESCLUDI), _sel_esclusi); sfield(S_CONTROLLO).force_update(); } break; case S_CONTROLLO: if (e == fe_init) sfield(S_CONTROLLO).enable_column(cid2index(F_CESCLUDI), false); break; case F_CSEL: if (e == fe_modify) selfatt(o, jolly); break; default: break; } return true; } TControllo_mask::TControllo_mask(const char* id_estr, bool esclusi) : TAutomask("f90100b"), _ordin('D'), _verso('A'), _selected_mov(0), _sel_esclusi(false) { _id_estr = id_estr; field(B_ESCL).disable(); get_win_order(); _is_escluso = esclusi; // Fill controllo sheet fill(); }