Files correlati : f90.exe d181.des f181.dir/.trr f9ProspIntegr.rep masks f90104.sql Commento : - Rimosso controllo vendite in ogni caso. Incompatibilita' con diverse situazioni tra cui note di credito interne che non sono fatture elettroniche. - Rimosso flag check vendite e il suo utilizzo nel codice. - Aggiornamento stato estrazione solo dopo scrittura f9iva. - Migliorata e resa piu' sicura query per iva aggiungendo tipi diversi e controllo lunghezza colonna. - Corretti nomi campi, che venivano invertiti IVA_ANNPROT e IVA_NUMPROT. - Aggiunto controllo in apertura controllo estrazione solo se il pacchetto e' in errore diag. gest. - Spostata in una classe separata la maschera per l'apertura del pacchetto (Apri estr.). - Corretta modifica f9wa rimaneva vuoto il record in alcuni casi. - Aggiunta possibilita' di esclusione movimenti dall'Apri estr. - Aggiunto controllo esistenza categorie documentali, caricamento cat. doc. di default e controllo tipi documento duplicati. - Aggiunta colonna a F9DRT in caso mancasse (Dovuta a creazione da fp). - Aggiunta funzione provvisoria per calcolo somma imponibili e imposte da rmoviva. - Aggiunto filtro datadoc per sheet fatture elettorniche (FPPRO) nel controllo estrazione: precarica automaticamente minimo e massimo secondo i movimenti in errore, e aggiunti i cambi nella finestra di ordinamento per impostare le date a mano. - Modificato messaggio dopo importazione categorie di default.
410 lines
12 KiB
C++
410 lines
12 KiB
C++
#include "f90.h"
|
|
#include "applicat.h"
|
|
#include "automask.h"
|
|
#include "f90200a.h"
|
|
#include "tsdb.h"
|
|
#include "../fp/fplib.h"
|
|
#include "f901tab.h"
|
|
#include "f90100.h"
|
|
#include "urldefid.h"
|
|
|
|
TString escape(const char* str);
|
|
|
|
class TNew_annesso_msk : public TMask
|
|
{
|
|
public:
|
|
void edit_mode(const bool edit = true) { enable(101, !edit); }
|
|
|
|
void fill_field(const TString& nome_ann, const TString& descr, const TString& tipo_ann, const bool obblig)
|
|
{ set(101, nome_ann); set(102, descr); set(103, tipo_ann); set(104, obblig); }
|
|
|
|
TNew_annesso_msk(const char* title) : TMask(title, 1, 78, 13)
|
|
{
|
|
add_button_tool (DLG_OK, "~Conferma", TOOL_OK);
|
|
add_button_tool (DLG_NULL, "", 0);
|
|
add_button_tool (DLG_CANCEL, "~Annulla", TOOL_CANCEL);
|
|
add_string (101, 0, "Nome tipo annesso:", 1, 1, 10);
|
|
add_string (102, 0, "Descrizione: ", 1, 2, 30);
|
|
add_list (103, 0, "Tipologia annesso:", 1, 3, 21, "", "DC|RC", "Annesso Cartaceo|Prospetto Rev. Charge");
|
|
add_boolean (104, 0, "Obbligatorio: ", 1, 4);
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// TF9_categorie_doc_msk
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
class TF9_categorie_doc_msk : public TAutomask
|
|
{
|
|
std::shared_ptr<TArray_sheet> _annessi_sheet;
|
|
TRecord_categorie _categorie_doc;
|
|
bool _mod_precaricate;
|
|
|
|
bool on_field_event(TOperable_field& o, TField_event e, long jolly) override;
|
|
bool on_key(KEY key) override;
|
|
|
|
void check_spell() const;
|
|
void check_duplicate_tipodoc() const;
|
|
void delete_annesso(const TString& catdoc_padre);
|
|
void edit_annesso(const TString& catdoc_padre);
|
|
void fill_annessi(const TString& catdoc);
|
|
void load_table() const;
|
|
void new_annesso(const TString& catdoc_padre);
|
|
void salva_tabella() const;
|
|
|
|
public:
|
|
static void correct_spell_catdoc(TString& catdoc);
|
|
|
|
explicit TF9_categorie_doc_msk(bool precarica)
|
|
: TAutomask("f90200a"), _mod_precaricate(precarica)
|
|
{ load_table(); }
|
|
};
|
|
|
|
bool TF9_categorie_doc_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch(o.dlg())
|
|
{
|
|
case DLG_OK:
|
|
if (e == fe_button)
|
|
salva_tabella();
|
|
break;
|
|
case B_DELETE:
|
|
if (e == fe_button)
|
|
{
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
sf.hide();
|
|
FOR_EACH_SHEET_ROW(sf, nr, row)
|
|
{
|
|
if (row->starts_with("X"))
|
|
{
|
|
sf.destroy(nr);
|
|
--nr;
|
|
}
|
|
}
|
|
sf.show();
|
|
}
|
|
break;
|
|
case DLG_USER:
|
|
if (e == fe_button)
|
|
{
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
const TString catdoc_padre(sf.row(sf.selected()).get(1));
|
|
fill_annessi(catdoc_padre);
|
|
int key;
|
|
while ((key = _annessi_sheet->run()) != K_ESC)
|
|
{
|
|
switch (key)
|
|
{
|
|
case K_INS:
|
|
new_annesso(catdoc_padre);
|
|
break;
|
|
case K_DEL:
|
|
delete_annesso(catdoc_padre);
|
|
break;
|
|
case K_ENTER:
|
|
edit_annesso(catdoc_padre);
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
default: break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TF9_categorie_doc_msk::on_key(KEY key)
|
|
{
|
|
if (key == K_DEL)
|
|
{
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
sf.hide();
|
|
TString_array& arr = sf.rows_array();
|
|
arr.destroy(sf.selected(), true);
|
|
sf.force_update();
|
|
sf.show();
|
|
}
|
|
return TAutomask::on_key(key);
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::check_spell() const
|
|
{
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
sf.hide();
|
|
FOR_EACH_SHEET_ROW(sf, nr, row)
|
|
{
|
|
TString catdoc = row->get(F_CATDOC - 101);
|
|
correct_spell_catdoc(catdoc);
|
|
row->add(catdoc, 1);
|
|
}
|
|
sf.force_update();
|
|
sf.show();
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::check_duplicate_tipodoc() const
|
|
{
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
map<TString, int> lookup_table;
|
|
vector<TString> dup;
|
|
FOR_EACH_SHEET_ROW(sf, nr, row)
|
|
{
|
|
if(TString(row->get(5)).empty()) // Se non ha specificato una causale
|
|
{
|
|
const char* tipodoc = row->get(6);
|
|
auto it = lookup_table.find({ tipodoc });
|
|
if (it == lookup_table.end()) // Se non lo trovo vuol dire che e' il primo.
|
|
lookup_table.insert({ tipodoc, 0 });
|
|
else
|
|
{
|
|
++it->second;
|
|
dup.emplace_back(it->first);
|
|
}
|
|
}
|
|
}
|
|
if (!dup.empty() && !_mod_precaricate)
|
|
warning_box("Ci sono molteplici categorie con lo stesso tipo documento.\nPer una corretta assegnazione della categoria doc. si consiglia\ndi specificare il tipo di causale o rimuovere i duplicati.");
|
|
if (_mod_precaricate)
|
|
message_box("Si prega di completare la tabella per la riga di fattura acquisti\nreverse charge andando a inserire il corrispondente codice causale.");
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::delete_annesso(const TString& catdoc_padre)
|
|
{
|
|
if (_annessi_sheet->items() > 0)
|
|
{
|
|
const int r = _annessi_sheet->selected();
|
|
if (yesno_box("Eliminare l'annesso N. %d?", r + 1))
|
|
{
|
|
_categorie_doc.del_annesso(catdoc_padre, _annessi_sheet->row(r).get(0));
|
|
fill_annessi(catdoc_padre);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::edit_annesso(const TString& catdoc_padre)
|
|
{
|
|
if (_annessi_sheet->items() > 0)
|
|
{
|
|
TString title; title << "Modifica annesso per " << catdoc_padre;
|
|
TNew_annesso_msk new_ann(title);
|
|
new_ann.edit_mode();
|
|
TToken_string& r = _annessi_sheet->row(_annessi_sheet->selected());
|
|
new_ann.fill_field(r.get(0), r.get(1), r.get(2), r.get_bool(3));
|
|
if (new_ann.run() == K_ENTER)
|
|
{
|
|
const TString& catann = new_ann.get(101);
|
|
const TString& descr = new_ann.get(102);
|
|
const TString& tipo = new_ann.get(103);
|
|
const bool obblig = new_ann.get_bool(104);
|
|
_categorie_doc.del_annesso(catdoc_padre, catann);
|
|
_categorie_doc.add_annesso(catdoc_padre, catann, descr, tipo, obblig);
|
|
fill_annessi(catdoc_padre);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::fill_annessi(const TString& catdoc)
|
|
{
|
|
TCategorie_doc d;
|
|
d.set_mode_sheet(0x1E);
|
|
_annessi_sheet = d.get_sheet_ann(catdoc);
|
|
_annessi_sheet->add_button(DLG_EDIT, TR("~Modifica"), K_ENTER, TOOL_EDIT);
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::load_table() const
|
|
{
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
sf.hide();
|
|
sf.destroy();
|
|
int idx = 0;
|
|
while (true)
|
|
{
|
|
TToken_string appo(ini_get_string(CONFIG_DITTA, "F9", "CATDOC", "", idx++));
|
|
if (appo == "STOP" || appo.empty()) /* STOP: Riga terminatrice */
|
|
break;
|
|
TToken_string& row = sf.row(-1);
|
|
row = appo;
|
|
}
|
|
sf.show();
|
|
sf.force_update();
|
|
|
|
check_duplicate_tipodoc();
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::new_annesso(const TString& catdoc_padre)
|
|
{
|
|
_categorie_doc.reload();
|
|
TString title;
|
|
title << "Nuovo annesso per " << catdoc_padre;
|
|
TNew_annesso_msk new_ann(title);
|
|
while (new_ann.run() == K_ENTER)
|
|
{
|
|
TString catann = new_ann.get(101);
|
|
if (catann.empty())
|
|
{
|
|
warning_box("Inserire il nome tipo annesso");
|
|
continue;
|
|
}
|
|
TCategorie_doc::annesso ann;
|
|
if (!_categorie_doc.get_ann(catann, ann))
|
|
{
|
|
const TString& descr = new_ann.get(102);
|
|
const TString& tipo = new_ann.get(103);
|
|
const bool obblig = new_ann.get_bool(104);
|
|
correct_spell_catdoc(catann);
|
|
_categorie_doc.add_annesso(catdoc_padre, catann, descr, tipo, obblig);
|
|
fill_annessi(catdoc_padre);
|
|
}
|
|
else
|
|
warning_box("E' gia' presente un annesso con lo stesso nome per la categoria %s", (const char*)catdoc_padre);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::salva_tabella() const
|
|
{
|
|
check_spell();
|
|
int idx = 0;
|
|
TString iget = "start";
|
|
while (iget != "STOP" && !iget.empty())
|
|
{
|
|
iget = ini_get_string(CONFIG_DITTA, "F9", "CATDOC", "", idx);
|
|
ini_remove(CONFIG_DITTA, "F9", "CATDOC", idx++);
|
|
}
|
|
|
|
idx = 0;
|
|
TSheet_field& sf = sfield(S_CLASSDOC);
|
|
FOR_EACH_SHEET_ROW(sf, nr, row)
|
|
{
|
|
if(row->get(1) && TString(row->get(1)).full())
|
|
ini_set_string(CONFIG_DITTA, "F9", "CATDOC", *row, idx++);
|
|
}
|
|
ini_set_string(CONFIG_DITTA, "F9", "CATDOC", "STOP", idx); // Riga terminatrice
|
|
|
|
// Reload
|
|
load_table();
|
|
}
|
|
|
|
void TF9_categorie_doc_msk::correct_spell_catdoc(TString& catdoc)
|
|
{
|
|
catdoc.trim();
|
|
catdoc.upper();
|
|
std::string ss = (const char*)catdoc;
|
|
for (size_t i = 0; i < ss.size(); ++i)
|
|
{
|
|
if (!(ss[i] >= 'A' && ss[i] <= 'Z' || ss[i] >= '0' && ss[i] <= '9' || ss[i] == '_'))
|
|
ss.erase(i--, 1);
|
|
}
|
|
catdoc = ss.c_str();
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// TF9_categorie_doc
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
class TF9_categorie_doc : public TSkeleton_application
|
|
{
|
|
TString _log;
|
|
void add_error_log(TString& query);
|
|
static bool precarica_tabella_default();
|
|
void main_loop() override;
|
|
public:
|
|
TF9_categorie_doc() = default;
|
|
};
|
|
|
|
|
|
void TF9_categorie_doc::add_error_log(TString& query)
|
|
{
|
|
_log << "\n" << query << "\n" << fp_db().sq_get_text_error() << "\n" << fp_db().sq_get_string_error();
|
|
}
|
|
|
|
bool TF9_categorie_doc::precarica_tabella_default()
|
|
{
|
|
TCategorie_doc preload;
|
|
if (preload.get_array_rows().items() == 0 ||
|
|
noyes_box("Attenzione questa procedura cancellera' le categorie documentali gia' presenti\ne carichera' quelle di default. Si desidera continuare?"))
|
|
{
|
|
preload.remove_all();
|
|
preload.reload();
|
|
preload.add_categoria("FATTACQ", "FATTURE DI ACQUISTI", "FTA", "TD01", "", "FA");
|
|
preload.add_categoria("FATTVEN", "FATTURE DI VENDITA", "FTV", "TD01", "", "FV");
|
|
preload.add_categoria("FATTREV", "Fattura acq. con rev. charge", "FTA", "TD01", "", "FA"); // Da aggiungere causale
|
|
preload.add_categoria("NOTCREDACQ", "Nota credito di acquisto", "FTA", "TD04", "", "NC");
|
|
preload.add_categoria("NOTDEBVEN", "Nota debito di vendita", "FTV", "TD05", "", "ND");
|
|
preload.add_categoria("FATTCORR", "Fattura corrispettivi", "FTA", "TD01", "", "CR");
|
|
preload.add_categoria("BOLLADOGAC", "Bolla doganale", "FTA", "TD01", "", "BD");
|
|
|
|
preload.add_annesso("FATTREV", "INTREVC", "Prosp. integr. rev.ch.", "RC", true);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TF9_categorie_doc::main_loop()
|
|
{
|
|
bool precarica = false;
|
|
if(argc() > 2 && argv()[2][0] == '-' && argv()[2][1] == 'd')
|
|
precarica = precarica_tabella_default();
|
|
|
|
TF9_categorie_doc_msk msk(precarica); // Il costruttore carica subito la tabella...
|
|
while(msk.run() == K_ENTER)
|
|
{
|
|
TSheet_field& sf = msk.sfield(S_CLASSDOC);
|
|
TString query;
|
|
query << "TRUNCATE TABLE " F9_DRT ";\n";
|
|
bool ok = fp_db().sq_set_exec(query, false) && fp_db().sq_commit();
|
|
if (ok)
|
|
{
|
|
FOR_EACH_SHEET_ROW(sf, nr, row)
|
|
{
|
|
query.cut(0);
|
|
query << "INSERT INTO " F9_DRT "("
|
|
DRT_CODSOC ", "
|
|
DRT_CATDOC ", "
|
|
DRT_DESCR ", "
|
|
DRT_CLASSO ", "
|
|
DRT_CAUSSO ", "
|
|
DRT_CAUSCON ", "
|
|
DRT_TIPOCAU ", "
|
|
DRT_OPCEE ")\nVALUES('" <<
|
|
F9CONF.get_ambiente() << "', '" <<
|
|
row->get(1) << "', '" << // Catdoc
|
|
escape(row->get(2)) << "', '" << // Descr
|
|
row->get(3) << "', '" << // Classe doc sost.
|
|
row->get(4) << "', '" << // Causale sost.
|
|
escape(row->get(5)) << "', '" << // Causale cont
|
|
escape(row->get(6)) << "', '" << // Tipo caus. cont
|
|
row->get(8) << "');\n"; // "Operat. CEE"
|
|
ok &= fp_db().sq_set_exec(query, false) && fp_db().sq_commit();
|
|
if (!ok)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!ok)
|
|
{
|
|
add_error_log(query);
|
|
ofstream fout;
|
|
fout.open("f9.catdoc.dberror.txt");
|
|
fout << _log << "\n";
|
|
error_box("Errore nel salvataggio dei dati.\nControllare file di errore f9.catdoc.dberror.txt");
|
|
}
|
|
}
|
|
}
|
|
|
|
TString escape(const char* str)
|
|
{
|
|
TString string; string << str;
|
|
for (int pos = string.find('\''); pos != -1; pos = string.find('\'', pos + 2))
|
|
string.insert("'", pos);
|
|
return string;
|
|
}
|
|
|
|
int f90200(const int argc, char* argv[])
|
|
{
|
|
TF9_categorie_doc app;
|
|
app.run(argc, argv, TR("Configurazione Categorie Documentali."));
|
|
return 0;
|
|
}
|