campo-sirio/src/f9/f90100.cpp
Simone Palacino 06c561dc28 Patch level : 12.0 890
Files correlati     : f90.exe
Commento            : Corretto caricamento moviementi utilizzando un recordset invece che leggere dal file direttamente: non tutti i moviementi venivano letti
2019-10-16 14:23:36 +02:00

1728 lines
50 KiB
C++
Raw Blame History

#include <automask.h>
#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"
#include "sqlset.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(db().sq_get(DRD_STATO) << " - " << 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<TToken_string>& 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<TToken_string>& 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<TToken_string>& _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<TToken_string>& 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();
TDate datareg;
TString query; query << "SELECT * FROM MOV WHERE DATAREG>=" << dataini.date2ansi() << " AND DATAREG<=" << dataend.date2ansi() << ";";
TSQL_recordset mov(query);
int items = mov.items();
TProgress_monitor progr(items, "Acquisizione movimenti");
int i = 0;
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.move_first(); ok; ok = mov.move_next())
{
if (!progr.add_status())
break;
TToken_string elab_f9(recset_get_string(mov, MOV_ELABF9), ';');
TCausale caus(recset_get_string(mov, MOV_CODCAUS, 3));
// Se definitivo controllo il flag di stampato REGST
if ((flagpro || recset_get_bool(mov, MOV_REGST)) && recset_get_string(mov, MOV_NUMDOC).full() && caus.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(recset_get_string(mov, MOV_NUMREG));
t.add(recset_get_string(mov, MOV_DATAREG));
t.add(recset_get_string(mov, MOV_DATADOC));
t.add(recset_get_string(mov, MOV_CODCAUS));
t.add(recset_get_string(mov, MOV_MESELIQ));
t.add(recset_get_string(mov, MOV_NUMDOC));
const real tot = recset_get_real(mov, MOV_TOTDOC) + recset_get_real(mov, MOV_RITFIS) + recset_get_real(mov, MOV_RITSOC);
t.add(tot);
t.add(recset_get_string(mov, MOV_CODCF));
clifo.zero();
clifo.put(CLI_TIPOCF, tipo == iva_acquisti ? "F" : "C");
clifo.put(CLI_CODCF, recset_get_string(mov, MOV_CODCF));
t.add(clifo.read() == NOERR ? clifo.get(CLI_RAGSOC) : " ");
t.add(TString(recset_get_string(mov, MOV_REG)) << "/" << recset_get_string(mov, MOV_PROTIVA));
t.add(recset_get_string(mov, 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<TToken_string>& 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<TToken_string> escl;
if (escluso)
escl.insert(escl.begin(), TToken_string(TString("|") << numreg << "|", '|'));
vector<TToken_string>& 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 <20> 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<TToken_string>& TControllo_mask::import_error_list()
{
static vector<TToken_string> 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<TToken_string>& 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<TToken_string>& 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();
}
const TString& recset_get_string(const TRecordset& rec, const char* field, const int zero_filled)
{
const TString& str = rec.get(rec.find_column(field)).as_string();
if (zero_filled == -1)
return str;
static TString c;
c.cut(0);
const int len = str.len();
for (int i = len; i < zero_filled; i++) // Sistemo il codcaus per via del TVariant che non restituisce la stringa esattamente come l'originale
c << "0";
c << str;
return c;
}
bool recset_get_bool(const TRecordset& rec, const char* field)
{
return rec.get(rec.find_column(field)).as_bool();
}
real recset_get_real(const TRecordset& rec, const char* field)
{
return rec.get(rec.find_column(field)).as_real();
}