Files correlati : f9lib01.cpp Commento: - Bugfix al giro di archiviazione dei cartacei - Aggiunti due campi virtuali ai doc
2147 lines
61 KiB
C++
2147 lines
61 KiB
C++
#include "f9lib.h"
|
|
|
|
#include <dongle.h>
|
|
#include <execp.h>
|
|
|
|
#include "../f1/f1lib.h"
|
|
#include "f901tab.h"
|
|
#include "progind.h"
|
|
#include "clifo.h"
|
|
#include "../cg/cglib.h"
|
|
#include "mov.h"
|
|
#include "../fp/fplib.h"
|
|
#include "annessif9.h"
|
|
#include "f90100c.h"
|
|
|
|
#define MODE_SHEETS 0xC
|
|
|
|
statistics _stats = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
|
const TString & get_numdoc_exp_fp(const int numreg)
|
|
{
|
|
TRectype & mov = (TRectype&)cache().get(LF_MOV, numreg);
|
|
TString & numdoc = get_tmp_string();
|
|
|
|
if (mov.full())
|
|
{
|
|
const TString& codnum = mov.get(MOV_DCODNUM);
|
|
const int ndoc = mov.get_int(MOV_DNDOC);
|
|
|
|
if (codnum.full() && ndoc != 0)
|
|
numdoc = complete_num_fp(cached_numerazione(codnum), ndoc);
|
|
}
|
|
return numdoc;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// TMovimento_estr
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
const char* TMovimento_estr::err_mov2name(const err_mov descr_estr)
|
|
{
|
|
switch (descr_estr)
|
|
{
|
|
case mov_no_error:
|
|
return "OK";
|
|
case mov_escluso:
|
|
return "Il movimento e' segnato come escluso. Saltato.";
|
|
case mov_no_catdoc:
|
|
return "Nessuna categoria documentale riconosciuta per questo movimento, o non e' una fattura.";
|
|
case mov_no_doc:
|
|
return "Il mov. di vendita non ha un documento generatore";
|
|
case mov_notfound_elet:
|
|
return "Non trovata fatt. elettronica mov vendita";
|
|
case mov_no_fa:
|
|
return "Questo movimento di acquisto non e' una fattura";
|
|
case mov_no_fv:
|
|
return "Movimento di vendita non e' una fattura.";
|
|
case mov_no_cartaceo:
|
|
return "Movimento cartaceo che non ha bisogno di essere estratto";
|
|
case mov_pura_iva:
|
|
return "Movimento di sola IVA. (Le integrazioni Rev. Charge sono gestite come annessi alle vendite)";
|
|
case mov_annesso_nexist:
|
|
return "Un annesso obbligatorio e' mancante.";
|
|
case mov_nocat_butok:
|
|
return "OK (Nessuna categoria documentale trovata ma l'abbinamento è riuscito)";
|
|
case mov_no_sdi:
|
|
return "Tipo documento SDI non identificato";
|
|
default: return "";
|
|
}
|
|
}
|
|
|
|
TMovimento_estr & TMovimento_estr::copy(const TMovimento_estr & m)
|
|
{
|
|
_err = m._err;
|
|
_state = m._state;
|
|
_estratto = m._estratto;
|
|
_descr_estr = m._descr_estr;
|
|
_documenti_allegati = m._documenti_allegati;
|
|
_numreg = m._numreg;
|
|
_datareg = m._datareg;
|
|
_datadoc = m._datadoc;
|
|
_codcaus = m._codcaus;
|
|
_meseliq = m._meseliq;
|
|
_numdoc = m._numdoc;
|
|
_tot = m._tot;
|
|
_codcf = m._codcf;
|
|
_ragsoc = m._ragsoc;
|
|
_reg_protiva = m._reg_protiva;
|
|
_descr = m._descr;
|
|
_cat_doc_padre = m._cat_doc_padre;
|
|
_data_estr = m._data_estr;
|
|
_user = m._user;
|
|
return *this;
|
|
}
|
|
|
|
TMovimento_estr::TMovimento_estr(TSheet_field& sf, int row) : _err(false), _state(null_state), _estratto(true),
|
|
_descr_estr(mov_no_error), _data_estr(today), _user(user())
|
|
{
|
|
_numreg = sf.get_long_row_cell(row, FE_NUMREG);
|
|
_datareg = sf.get_date_row_cell(row, FE_DATAREG);
|
|
_datadoc = sf.get_date_row_cell(row, FE_DATADOC);
|
|
_codcaus = sf.get_str_row_cell(row, FE_CODCAUS);
|
|
_meseliq = sf.get_int_row_cell(row, FE_MESELIQ);
|
|
_numdoc = sf.get_str_row_cell(row, FE_NUMDOC);
|
|
_tot = sf.get_real_row_cell(row, FE_IMPTOTDOC);
|
|
_codcf = sf.get_long_row_cell(row, FE_FORN);
|
|
_ragsoc = sf.get_long_row_cell(row, FE_RAGSOC);
|
|
_reg_protiva = sf.get_str_row_cell(row, FE_PROTIVA);
|
|
_descr = sf.get_long_row_cell(row, FE_DESCR);
|
|
TClasse_doc * classe = catdoc(categorie_doc());
|
|
|
|
if (classe != nullptr)
|
|
{
|
|
_cat_doc_padre = classe->catdoc();
|
|
}
|
|
}
|
|
|
|
void TMovimento_estr::set_err(const char * descr, err_mov descr_estr)
|
|
{
|
|
bool error = descr && *descr;
|
|
|
|
_err = error ;
|
|
_estratto = !error || (descr_estr != mov_no_fa && descr_estr != mov_no_cartaceo);
|
|
_descr_err = descr;
|
|
if (descr_estr != mov_no_error)
|
|
_descr_estr = descr_estr;
|
|
else
|
|
_descr_estr = error ? mov_annesso_nexist : mov_no_error;
|
|
}
|
|
|
|
bool TMovimento_estr::load_docs()
|
|
{
|
|
TLocalisamfile annessi(LF_F9ANNESSI);
|
|
bool found = false;
|
|
|
|
documenti_allegati().destroy();
|
|
const TRectype & mov = cache().get(LF_MOV, numreg());
|
|
TToken_string cartacei(mov.get(MOV_CARTACEI), '\n');
|
|
|
|
FOR_EACH_STR_TOKEN(cartacei, str)
|
|
{
|
|
TToken_string orig(str);
|
|
TToken_string row(orig.get());
|
|
|
|
row.add(cat_doc_padre());
|
|
row.add(orig.get(4));
|
|
row.add(data_estr());
|
|
row.add(user());
|
|
documenti_allegati().add(row);
|
|
found = true;
|
|
}
|
|
annessi.put(F9A_NUMREG, numreg());
|
|
// Si posiziona nl primo record giusto. Poi per sapere quando terminare guardo se la chiave e' ancora quella giusta.
|
|
for (int err = annessi.read(_isgteq) == NOERR; err == NOERR && annessi.get_long(F9A_NUMREG) == numreg(); err = annessi.next())
|
|
{
|
|
if (!found)
|
|
{
|
|
set_cat_doc_padre(annessi.get(F9A_CATDOCPAD));
|
|
set_data_estr(annessi.get_date(F9A_LOADDATE));
|
|
set_user(annessi.get(F9A_USER));
|
|
}
|
|
|
|
TToken_string row(annessi.get(F9A_FILENAME));
|
|
|
|
row.add(cat_doc_padre());
|
|
row.add(annessi.get(F9A_CATDOCANN));
|
|
row.add(data_estr());
|
|
row.add(user());
|
|
documenti_allegati().add(row);
|
|
found = true;
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
bool TMovimento_estr::fill_doc_list(TString_array& list_docs)
|
|
{
|
|
bool ok = load_docs();
|
|
|
|
list_docs.destroy();
|
|
if (ok)
|
|
{
|
|
// Si posiziona nl primo record giusto. Poi per sapere quando terminare guardo se la chiave e' ancora quella giusta.
|
|
FOR_EACH_ARRAY_ROW(_documenti_allegati, r, str)
|
|
{
|
|
TToken_string t;
|
|
|
|
t.add(numreg());
|
|
t.add(str->get());
|
|
t.add(str->get());
|
|
t.add(str->get());
|
|
t.add(str->get());
|
|
t.add(str->get());
|
|
list_docs.add(t);
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
TMovimento_estr::TMovimento_estr(const long numreg) : _err(false), _state(null_state), _estratto(true), _descr_estr(mov_no_error),
|
|
_data_estr(today), _user(user())
|
|
{
|
|
const TRectype & mov = cache().get(LF_MOV, numreg);
|
|
TToken_string key(mov.get(MOV_TIPO));
|
|
|
|
key.add(mov.get(MOV_CODCF));
|
|
|
|
const TRectype & clifo = cache().get(LF_CLIFO, key);
|
|
|
|
_numreg = numreg;
|
|
_datareg = mov.get_date(MOV_DATAREG);
|
|
_datadoc = mov.get_date(MOV_DATADOC);
|
|
_codcaus = mov.get(MOV_CODCAUS);
|
|
_meseliq = mov.get_int(MOV_MESELIQ);
|
|
_numdoc = mov.get(MOV_NUMDOCEXT).full() ? mov.get(MOV_NUMDOCEXT) : mov.get(MOV_NUMDOC);
|
|
_tot = mov.get_real(MOV_TOTDOC); // perchè no ? +mov.get_real(MOV_RITFIS) + mov.get_real(MOV_RITSOC);
|
|
_codcf = mov.get_long(MOV_CODCF);
|
|
_ragsoc = clifo.get(CLI_RAGSOC);
|
|
_reg_protiva = mov.get(MOV_REG);
|
|
_reg_protiva << "/" << mov.get(MOV_PROTIVA); // perchè c'era solo mov_reg ?
|
|
_descr = mov.get(MOV_DESCR);
|
|
}
|
|
|
|
TMovimento_estr::TMovimento_estr(TISAM_recordset & mov, TipoIVA tipo, bool escl) : _err(false), _state(null_state), _estratto(true),
|
|
_descr_estr(mov_no_error), _data_estr(today), _user(user())
|
|
{
|
|
_numreg = mov.get_long(MOV_NUMREG);
|
|
_datareg = mov.get_date(MOV_DATAREG);
|
|
_datadoc = mov.get_date(MOV_DATADOC);
|
|
_codcaus = mov.get_string(MOV_CODCAUS).left(3); // perchè 3 caratteri ?
|
|
_meseliq = mov.get_int(MOV_MESELIQ);
|
|
if (tipo == iva_vendite)
|
|
_numdoc = get_numdoc_exp_fp(_numreg);
|
|
if (_numdoc.blank())
|
|
_numdoc = mov.get_string(MOV_NUMDOCEXT);
|
|
if (_numdoc.blank())
|
|
_numdoc = mov.get_string(MOV_NUMDOC);
|
|
_tot = mov.get_real(MOV_TOTDOC) + mov.get_real(MOV_RITFIS) + mov.get_real(MOV_RITSOC);
|
|
_codcf = mov.get_long(MOV_CODCF);
|
|
|
|
TToken_string key(tipo == iva_acquisti ? "F" : "C");
|
|
|
|
key.add(_codcf);
|
|
_ragsoc = cache().get(LF_CLIFO, key, CLI_RAGSOC);
|
|
_reg_protiva = mov.get_string(MOV_REG);
|
|
_reg_protiva << "/" << mov.get_string(MOV_PROTIVA);
|
|
_descr = mov.get_string(MOV_DESCR);
|
|
if (escl)
|
|
{
|
|
_estratto = false;
|
|
_descr_estr = mov_escluso;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// TEstrazione
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
long find_movcoll(long numreg) // ma serve ?
|
|
{
|
|
TLocalisamfile mov(LF_MOV);
|
|
mov.put(MOV_NUMREG, numreg);
|
|
mov.read();
|
|
|
|
const TCausale& cau = cached_causale(mov.get(MOV_CODCAUS), mov.get_int(MOV_ANNOES));
|
|
const TString4 cau_reg = cau.causale_reg_iva();
|
|
const TString numdoc = mov.get(MOV_NUMDOC);
|
|
TString query("USE ");
|
|
|
|
query << LF_MOV << " KEY 1 SELECT " << MOV_CODCAUS << "==\"" << cau_reg << "\"\nFROM " << MOV_NUMREG << "==" << numreg;
|
|
TISAM_recordset mov_rs(query);
|
|
long movcoll = 0L;
|
|
|
|
for (bool ok = mov_rs.move_first(); ok; ok = mov_rs.move_next())
|
|
{
|
|
TRectype& curr = (TRectype&)mov_rs.cursor()->curr();
|
|
const long movcoll_found = curr.get_long(MOV_MOVCOLL);
|
|
|
|
if (curr.get(MOV_NUMDOC) == numdoc && (movcoll_found == 0L || movcoll_found == numreg))
|
|
{
|
|
movcoll = mov_rs.get_long(MOV_NUMREG);
|
|
curr.put(MOV_MOVCOLL, numreg);
|
|
break;
|
|
}
|
|
}
|
|
return movcoll;
|
|
}
|
|
|
|
const char* TEstrazione::caus_sos(const TLocalisamfile& mov, const TipoIVA iva)
|
|
{
|
|
if (iva == iva_acquisti)
|
|
{
|
|
TToken_string keys(mov.get(MOV_KEYFPPRO));
|
|
fppro_db().set_keys(keys);
|
|
return fppro_db().get_tipodoc();
|
|
}
|
|
if (iva == 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 "";
|
|
}
|
|
|
|
void TEstrazione::check_annessi(TMovimento_estr& mov)
|
|
{
|
|
TToken_string ann_nexist;
|
|
|
|
if (!check_annessi_oblig(mov, ann_nexist))
|
|
{
|
|
TString msg_annessi_mancanti("Annessi obligatori mancanti: ");
|
|
|
|
for (int i = 0; i < ann_nexist.items(); ++i)
|
|
msg_annessi_mancanti << ann_nexist.get() << " ";
|
|
|
|
mov.set_err(msg_annessi_mancanti);
|
|
}
|
|
else
|
|
load_docs(mov);
|
|
}
|
|
|
|
bool TEstrazione::check_annessi_oblig(TMovimento_estr& mov, TToken_string& ann_nexist)
|
|
{
|
|
TF9_doccart file_cart;
|
|
TString_array list_file_ann; // Lista file annessi
|
|
TClasse_doc * classe = mov.catdoc(categorie_doc());
|
|
TString catdoc;
|
|
|
|
if (classe != nullptr)
|
|
catdoc = classe->catdoc();
|
|
|
|
const TString_array lista_cat_annessi = categorie_doc().get_array_ann(catdoc); // Lista cat annessi
|
|
|
|
ann_nexist.cut(0);
|
|
mov.fill_doc_list(list_file_ann);
|
|
|
|
bool ok_ann = true;
|
|
|
|
FOR_EACH_ARRAY_ITEM(lista_cat_annessi, nr, obj_name)
|
|
{
|
|
TString & ann_name = (TString &)*obj_name;
|
|
TAnnesso * ann = categorie_doc().get_ann(catdoc, ann_name);
|
|
|
|
const bool ok_cat = ann != nullptr;
|
|
// Ignoro il flag obbligatorio per il prospetto di reverse charge
|
|
if (ok_cat && ann->obblig() && ann->opcee() != "RC")
|
|
{
|
|
// Controllo che esista l'annesso per questo mov.
|
|
bool exist = false;
|
|
|
|
FOR_EACH_ARRAY_ROW(list_file_ann, r, row)
|
|
{
|
|
TString catdocann = row->get(3);
|
|
|
|
if (catdocann == ann_name)
|
|
{
|
|
exist = true;
|
|
break;
|
|
}
|
|
}
|
|
ok_ann &= exist;
|
|
if (!exist)
|
|
ann_nexist.add(ann_name);
|
|
}
|
|
else
|
|
if(ok_cat && ann->opcee() == "RC")
|
|
{
|
|
// Generazione prospetto integrativo.
|
|
const bool ok = make_prosp_int_revc(mov.numreg(), ann);
|
|
|
|
if (!ok)
|
|
{
|
|
TString msg(TR("Prospetto integrativo"));
|
|
|
|
msg << "(" << ann->catdoc() << ")";
|
|
ann_nexist.add(msg);
|
|
}
|
|
ok_ann &= ok;
|
|
}
|
|
}
|
|
return ok_ann;
|
|
}
|
|
|
|
bool TEstrazione::check_cartaceo_acq(TMovimento_estr& movimento)
|
|
{
|
|
bool ok = movimento.load_docs();
|
|
|
|
if (ok)
|
|
{
|
|
FOR_EACH_ARRAY_ROW(movimento.documenti_allegati(), r, str)
|
|
{
|
|
TFilename file = str->get();
|
|
|
|
ok &= file.exist();
|
|
if (!ok)
|
|
break;
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TEstrazione::check_documento_vendita(const TLocalisamfile& mov, _Out_ bool& exist_doc)
|
|
{
|
|
if (!mov.get(MOV_DPROVV).empty() && !mov.get(MOV_DANNO).empty() && !mov.get(MOV_DCODNUM).empty() && !mov.get(MOV_DNDOC).empty())
|
|
{
|
|
TString hfatt(20), bfatt(50), query;
|
|
const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC));
|
|
|
|
exist_doc = true;
|
|
if (chiave_paf_doc(doc, hfatt, bfatt))
|
|
{
|
|
query << "SELECT * FROM PAF0100F WHERE P1_KEYHEADERFATT = '" << hfatt << "' AND P1_KEYBODYFATT = '" << bfatt << "';";
|
|
fp_db().sq_set_exec(query);
|
|
return fp_db().sq_items() > 0;
|
|
}
|
|
}
|
|
else
|
|
exist_doc = false;
|
|
return false;
|
|
}
|
|
|
|
state_fppro TEstrazione::check_fppro(int numreg)
|
|
{
|
|
TLocalisamfile mov(LF_MOV);
|
|
mov.put(MOV_NUMREG, numreg);
|
|
if (mov.read() == NOERR && check_causale(mov.get(MOV_CODCAUS), mov.get_date(MOV_DATAREG).year()))
|
|
{
|
|
// 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;
|
|
TString err(fppro_db().get_last_error());
|
|
if (!err.empty())
|
|
{
|
|
error_box(err.cut(0) << "Errore durante il controllo del movimento n. " << numreg << "\n" << err);
|
|
return err_read_db;
|
|
}
|
|
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;
|
|
}
|
|
|
|
bool TEstrazione::check_periodo_def() const
|
|
{
|
|
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 " F9_DRD "\n"
|
|
"WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND " 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 << "';";
|
|
fp_db().sq_set_exec(query);
|
|
return fp_db().sq_items() == 0;
|
|
}
|
|
|
|
void TEstrazione::copy_file_to_webapp_fld(TMovimento_estr& movimento) const
|
|
{
|
|
// f9pwa + ambiente + idlancio(ID drd) + categoria_documento(drt) + nome_documento
|
|
TFilename base(F9CONF.get_addr_doc_loc());
|
|
base.add(_head.cod_soc).add(_head.id_estr).slash_terminate();
|
|
TClasse_doc * cd = movimento.catdoc(categorie_doc());
|
|
const bool has_allegati = movimento.allegati();
|
|
|
|
if (has_allegati)
|
|
{
|
|
TString_array & docs = movimento.documenti_allegati();
|
|
|
|
FOR_EACH_ARRAY_ROW(docs, r, str)
|
|
{
|
|
TFilename file = str->get(0);
|
|
|
|
if (file.full())
|
|
{
|
|
TFilename dest(base);
|
|
|
|
if (file.is_relative_path())
|
|
{
|
|
const TString studio = prefix().get_studio();
|
|
file.insert(studio);
|
|
}
|
|
|
|
if (cd != nullptr && file.full())
|
|
dest.add(cd->catdoc());
|
|
else
|
|
dest.add("cartaceo");
|
|
dest.add(file.name());
|
|
make_dir(dest.path());
|
|
if (!fcopy(file, dest))
|
|
error_box(FR("Errore nel copiare il %s in %s"), (const char*)file, (const char*)dest);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TEstrazione::fill_id(const TRectype& clifo, TString& statopaiv, TString& idfisc, TString& paiv, TString& codfis)
|
|
{
|
|
idfisc.cut(0);
|
|
statopaiv = clifo.get(CLI_STATOPAIV);
|
|
paiv = clifo.get(CLI_PAIV);
|
|
codfis = clifo.get(CLI_COFI);
|
|
|
|
if (IS_ITALIANO(statopaiv))
|
|
{
|
|
// Se ho un codice fiscale che inizia per 8 o 9 e' come un privato e devo considerarlo solo come codice fiscale senza partita IVA.
|
|
if (paiv.full())
|
|
{
|
|
if (paiv.len() == 11 && (paiv[0] == '8' || paiv[0] == '9'))
|
|
{
|
|
codfis = paiv;
|
|
paiv.cut(0);
|
|
}
|
|
}
|
|
else if (codfis.full() && codfis.len() == 11 && (codfis[0] == '8' || codfis[0] == '9'))
|
|
paiv.cut(0);
|
|
}
|
|
|
|
if (paiv == "0")
|
|
paiv.cut(0);
|
|
if (IS_ITALIANO(statopaiv))
|
|
{
|
|
idfisc << "IT";
|
|
if (paiv.full()) // Se non ho la partita IVA e' privato quindi non metto niente solo cod. ISO
|
|
{
|
|
const int len = paiv.len();
|
|
for (int i = 0; i < 11 - len; ++i) // Siccome e' numerico mi trancia via le prime cifre 0.
|
|
paiv.add_front("0");
|
|
idfisc << paiv;
|
|
}
|
|
}
|
|
else // Esteri
|
|
{
|
|
idfisc << statopaiv;
|
|
if (codfis.full())
|
|
idfisc << codfis;
|
|
else
|
|
idfisc << paiv;
|
|
}
|
|
}
|
|
|
|
bool TEstrazione::is_doc_xml(const TRectype& mov)
|
|
{
|
|
TToken_string key(mov.get(MOV_TIPO));
|
|
|
|
key.add(mov.get(MOV_CODCF));
|
|
|
|
const TRectype & clifo= cache().get(LF_CLIFO, key);
|
|
const TString& statopaiv = clifo.get(CLI_STATOPAIV);
|
|
|
|
return (IS_ITALIANO(statopaiv)) && clifo.get(CLI_COMCF) != "B513"; // Campione d'Italia
|
|
}
|
|
|
|
/* bool TEstrazione::stampa_documento(const TMovimento_estr& movimento, TFilename& file)
|
|
{
|
|
bool ok = false;
|
|
// Se il movimento e' di vendita e ha i riferimenti al documento generatore provo a stamparlo con ve, e lo inserisco tra i cartacei F9.
|
|
TLocalisamfile mov(LF_MOV);
|
|
mov.put(MOV_NUMREG, movimento.numreg());
|
|
if (mov.read() == NOERR &&
|
|
!mov.get(MOV_DPROVV).empty() && !mov.get(MOV_DANNO).empty() && !mov.get(MOV_DCODNUM).empty() && !mov.get(MOV_DNDOC).empty())
|
|
{
|
|
const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC));
|
|
if(doc.ok() && dongle().active(RSAUT))
|
|
{
|
|
// ve1 -2 {CODNUM} {ANNO} {PROVV} {NDOC}(-{ANDOC}) {TIPO_ELABORAZIONE} {TIPO_STAMPA} {NUM_COPIE} {ARCHIVIAZIONE}
|
|
static TString commandline;
|
|
commandline.cut(0) << "ve1 -2 " << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO)
|
|
<< ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << " X P 1 D"; // X: stampa su disco, P: provvisorio, 1: 1 copia, D: disabilita archiviazione
|
|
TExternal_app interattivo(commandline);
|
|
if (interattivo.run() == NOERR)
|
|
{
|
|
TFilename pdf; pdf.tempdir();
|
|
pdf << SLASH << doc.get(DOC_ANNO) << '_' << doc.get(DOC_CODNUM) << '_' << doc.get(DOC_NDOC) << ".pdf";
|
|
if (pdf.exist())
|
|
{
|
|
file.cut(0) << pdf;
|
|
// Controllo anche se false perche' potrebbe esistere gia'.
|
|
if(!TF9_doccart::add_cart(file, movimento.numreg()))
|
|
{
|
|
TFilename fdoc;
|
|
|
|
ok = movimento.load_docs() && fdoc.name() == file.name();
|
|
}
|
|
else
|
|
ok = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
} */
|
|
|
|
bool TEstrazione::grab_pdf_from_spotlite(const TMovimento_estr& movimento, TFilename& file) const
|
|
{
|
|
TLocalisamfile mov(LF_MOV);
|
|
|
|
mov.put(MOV_NUMREG, movimento.numreg());
|
|
if (mov.read() == NOERR &&
|
|
!mov.get(MOV_DPROVV).empty() && !mov.get(MOV_DANNO).empty() && !mov.get(MOV_DCODNUM).empty() && !mov.get(MOV_DNDOC).empty())
|
|
{
|
|
const TDocumento doc(mov.get(MOV_DPROVV)[0], mov.get_int(MOV_DANNO), mov.get(MOV_DCODNUM), mov.get_int(MOV_DNDOC));
|
|
if (doc.ok())
|
|
{
|
|
char buffer[34];
|
|
TString f_pdf; f_pdf << "ve1300_" << mov.get(MOV_DCODNUM) << "_";
|
|
sprintf_s(buffer, 34, "%010d", mov.get_long(MOV_DNDOC));
|
|
f_pdf << buffer << "_";
|
|
sprintf_s(buffer, 34, "%07d", doc.clifor().codice());
|
|
f_pdf << buffer << ".pdf";
|
|
TFilename doccart(_spotlite_path);
|
|
doccart.add(mov.get(MOV_DANNO));
|
|
doccart.add(prefix().name());
|
|
doccart.add(f_pdf);
|
|
if (doccart.exist())
|
|
{
|
|
file.cut(0);
|
|
file = doccart;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TEstrazione::make_prosp_int_revc(const int numreg, TAnnesso * annesso)
|
|
{
|
|
TLocalisamfile mov(LF_MOV);
|
|
mov.put(MOV_NUMREG, numreg);
|
|
mov.read();
|
|
|
|
long rev_vend = mov.get_long(MOV_MOVCOLL);
|
|
|
|
if (rev_vend == 0)
|
|
rev_vend = find_movcoll(numreg);
|
|
if (rev_vend > 0)
|
|
{
|
|
TF9Prospetto_integr prosp;
|
|
const long acq = numreg;
|
|
|
|
if (prosp(acq, rev_vend))
|
|
{
|
|
// [ NUMREG][ CAT.ANN.].pdf
|
|
// [0000000][AAAAAAAAAA].pdf
|
|
TFilename tmp_file; tmp_file.tempdir();
|
|
TString name; name << format("%07d%10s", numreg, (const char*)annesso->catdoc());
|
|
|
|
name.replace(' ', '_');
|
|
tmp_file.add(name);
|
|
tmp_file.ext("pdf");
|
|
if (prosp.export_pdf(tmp_file))
|
|
{
|
|
// Sposto il file nella cartella dei documenti cartacei.
|
|
const TFilename newfile(get_full_path_file_cartaceo(tmp_file.name()));
|
|
// if (newfile.exist())
|
|
// DeleteFile(newfile);
|
|
fcopy(tmp_file, newfile);
|
|
// Controllo che non esista gia' altrimenti elimino il record
|
|
TF9_doccart doccart;
|
|
long numreg_old;
|
|
|
|
if (doc_already_exists(newfile, numreg_old))
|
|
{
|
|
TLocalisamfile lf_ann(LF_F9ANNESSI);
|
|
lf_ann.setkey(2);
|
|
lf_ann.put(F9A_FILENAME, newfile.name());
|
|
lf_ann.read();
|
|
lf_ann.remove();
|
|
lf_ann.zero();
|
|
}
|
|
|
|
// Registro il file come annesso RC
|
|
TLocalisamfile lf_ann(LF_F9ANNESSI);
|
|
lf_ann.put(F9A_NUMREG, numreg);
|
|
lf_ann.put(F9A_FILENAME, newfile.name());
|
|
lf_ann.put(F9A_CATDOCPAD, annesso->catdocpadre());
|
|
lf_ann.put(F9A_CATDOCANN, annesso->catdoc());
|
|
lf_ann.put(F9A_LOADDATE, today);
|
|
lf_ann.put(F9A_USER, user());
|
|
bool ok = lf_ann.write() == NOERR;
|
|
ok &= lf_ann.rewrite() == NOERR;
|
|
if (!ok)
|
|
ok = yesno_box("Impossibile creare il prospetto integrativo per la registrazione n. %s.\nContinuare con l'estrazione?", (const char*)TString(numreg));
|
|
return ok;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TString& TEstrazione::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& TEstrazione::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 TEstrazione::insert_into_drd()
|
|
{
|
|
TString query;
|
|
query << "INSERT INTO " F9_DRD " ( " << drd_attr() << " ) \nVALUES ( " << drd_tovalues() << " );";
|
|
bool ok = fp_db().sq_set_exec(query);
|
|
ok = ok && fp_db().sq_commit();
|
|
if (!ok)
|
|
write_errorsql_log(query);
|
|
return ok;
|
|
}
|
|
|
|
bool TEstrazione::insert_into_f9movestr()
|
|
{
|
|
TString query;
|
|
bool ok = true;
|
|
|
|
TProgress_monitor prog(_movs.size(), "Salvataggio informazioni estrazione", false);
|
|
|
|
//QUI ANDRA' CONTROLLATO IL PAFW300
|
|
|
|
FOR_EACH_ARRAY_ITEM(_movs, r, obj)
|
|
{
|
|
if(prog.add_status())
|
|
{
|
|
TMovimento_estr & mov = (TMovimento_estr &)*obj;
|
|
|
|
query.cut(0) << "INSERT INTO " F9_MOVESTR " (" MES_CODSOC ", IDESTR, NUMREG, DATAREG, ESTRATTO, DESCR_ERR)\nVALUES " <<
|
|
" ('" << _head.cod_soc << "', '" << _head.id_estr << "', '" << mov.numreg() << "', '" << mov.datareg().date2ansi() << "', " <<
|
|
(mov.estratto() ? "1" : "0") << ", '" << check_str(mov.get_descr_estr()) << "')";
|
|
ok &= fp_db().sq_set_exec(query) && fp_db().sq_commit();
|
|
if (!ok)
|
|
{
|
|
write_errorsql_log(query);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TEstrazione::export_error_list()
|
|
{
|
|
TF9_dberr dberr(_log);
|
|
const TArray & movs = _movs; // <TMovimento_estr>
|
|
bool ok = true;
|
|
int count = 0;
|
|
TProgress_monitor pg(movs.items(), "Scrittura movimenti in errore");
|
|
|
|
FOR_EACH_ARRAY_ITEM(movs, r ,obj)
|
|
{
|
|
TMovimento_estr & mov = (TMovimento_estr &)*obj;
|
|
|
|
if (pg.add_status())
|
|
{
|
|
if (mov.err())
|
|
{
|
|
dberr.add(_head.cod_soc);
|
|
dberr.add(_head.id_estr);
|
|
dberr.add(mov.numreg());
|
|
dberr.add(mov.datareg());
|
|
dberr.add(mov.datadoc());
|
|
dberr.add(mov.codcaus());
|
|
dberr.add(mov.meseliq());
|
|
dberr.add(mov.numdoc());
|
|
dberr.add(mov.totale().string_point());
|
|
dberr.add(mov.codcf());
|
|
dberr.add(mov.ragsoc());
|
|
dberr.add(mov.protiva());
|
|
dberr.add(mov.descr());
|
|
dberr.add(mov.descr_err());
|
|
if (!(ok &= dberr.send()))
|
|
break;
|
|
++count;
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
TString TEstrazione::next_estr_today(char tipo) const
|
|
{
|
|
char estr[] = { 0,0,0,0,0,0,0,0,0 };
|
|
TString query;
|
|
query << "SELECT TOP 1 SUBSTRING(" DRD_ID_EST ", 11, 8) AS IDESTR\n"
|
|
"FROM " F9_DRD "\n"
|
|
"WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND\n"
|
|
DRD_ID_EST " LIKE '" << today.date2ansi() << "%'\n"
|
|
"ORDER BY IDESTR DESC";
|
|
fp_db().sq_set_exec(query);
|
|
|
|
const int last_estr = fp_db().sq_items() > 0 ? real(fp_db().sq_get("IDESTR")).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 TString(estr);
|
|
}
|
|
|
|
bool TEstrazione::pura_iva(const TRectype& mov)
|
|
{
|
|
if (TCausale(mov.get(MOV_CODCAUS), mov.get_date(MOV_DATAREG).year()).soloiva())
|
|
return true;
|
|
TMovimento_contabile* rel = new TMovimento_contabile();
|
|
rel->put(MOV_NUMREG, mov.get(MOV_NUMREG));
|
|
return rel->cg_rows() == 0;
|
|
}
|
|
|
|
void TEstrazione::write_errorsql_log(const TString& query)
|
|
{
|
|
_log->log(2, query);
|
|
_log->log(2, fp_db().sq_get_string_error());
|
|
_log->log(2, fp_db().sq_get_text_error());
|
|
_log->line();
|
|
}
|
|
|
|
// Public methods /////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TEstrazione::update_drd_stato_estr()
|
|
{
|
|
bool ok;
|
|
do
|
|
{
|
|
TString query;
|
|
query << "UPDATE " F9_DRD "\n" \
|
|
"SET " DRD_STATO " = '" << _head.stato_estr << "'\n"
|
|
"WHERE " DRD_CODSOC " = '" << _head.cod_soc << "'"
|
|
" AND " DRD_ID_EST " = '" << _head.id_estr << "'"
|
|
" AND " DRD_FLAG_PD " = '" << (_head.flag_prov ? "P" : "D") << "'";
|
|
ok = fp_db().sq_set_exec(query);
|
|
ok = ok && fp_db().sq_commit();
|
|
if (!ok)
|
|
write_errorsql_log(query);
|
|
} while (!ok && yesno_box("Impossibile aggiornare stato dell'estrazione.\nRiprovare?"));
|
|
return ok;
|
|
}
|
|
|
|
const char* TEstrazione::diagnostica_mov()
|
|
{
|
|
categorie_doc(true);
|
|
bool ok = true;
|
|
const TipoIVA tipo = get_tipoiva();
|
|
_stats.total = _movs.size();
|
|
if (tipo == iva_acquisti)
|
|
{
|
|
// Controlli per le fatture di acquisto
|
|
TProgress_monitor bar(_movs.items(), "Controllo stato movimenti di acquisto");
|
|
|
|
FOR_EACH_ARRAY_ITEM(_movs, r, obj)
|
|
{
|
|
if (bar.add_status())
|
|
{
|
|
TMovimento_estr & mov_i = (TMovimento_estr &)*obj;
|
|
|
|
// Se gia' escluso passo avanti
|
|
|
|
if (!mov_i.estratto() && mov_i.descr_estr() == mov_escluso)
|
|
continue;
|
|
|
|
if (mov_i.no_err() && mov_i.estratto())
|
|
{
|
|
|
|
const long numreg = mov_i.numreg();
|
|
const TRectype & mov =cache().get(LF_MOV, numreg);
|
|
|
|
mov_i.set_cartaceo(!is_doc_xml(mov));
|
|
|
|
const state_fppro res = check_fppro(numreg);
|
|
switch (res)
|
|
{
|
|
// OK
|
|
case guessed:
|
|
ok &= fppro_db().associa_mov(numreg);
|
|
++_stats.fa_estr;
|
|
break;
|
|
case correct:
|
|
ok &= true;
|
|
mov_i.reset_err();
|
|
mov_i.set_numdoc(fppro_db().get_numdoc());
|
|
++_stats.fa_estr;
|
|
break;
|
|
|
|
// ERRORS
|
|
// Errore non bloccante (skip)
|
|
case not_fa:
|
|
ok &= true;
|
|
mov_i.set_err("", mov_no_fa);
|
|
mov_i.set_estratto(false);
|
|
++_stats.fa_skip;
|
|
break;
|
|
|
|
// ERRORI BLOCCANTI
|
|
case reg_with_err:
|
|
ok &= false;
|
|
mov_i.set_err("Errore controllo movimento: associazione movimento con fattura elettronica passiva sbagliato.");
|
|
break;
|
|
case err_read_db:
|
|
ok &= false;
|
|
mov_i.set_err("Errore controllo movimento: errore lettura db.");
|
|
break;
|
|
case no_guessed:
|
|
// Controllo se esiste il cartaceo es. forfettari => la considero cartacea.
|
|
// Ma poi devo comunque avere il flag per l'esportazione dei cartacei
|
|
if(check_cartaceo_acq(mov_i))
|
|
{
|
|
ok &= true;
|
|
mov_i.set_err("");
|
|
mov_i.set_cartaceo(true);
|
|
mov_i.set_state(correct);
|
|
}
|
|
else
|
|
{
|
|
ok &= false;
|
|
mov_i.set_err("Non associato a fattura elettr. abbinamento automatico non riuscito. Abbinare manualmente, o escludere");
|
|
}
|
|
default: break;
|
|
}
|
|
if(mov_i.state() == null_state)
|
|
mov_i.set_state(res);
|
|
|
|
if (mov_i.err())
|
|
++_stats.fa_err;
|
|
|
|
/* Per quelli che hanno passato il primo controllo errori controllo che debba essere estratto
|
|
* secondo le categorie documentali. */
|
|
if (mov_i.estratto())
|
|
{
|
|
if (mov_i.no_err())
|
|
{
|
|
// Cerco la categoria documentale
|
|
TClasse_doc * cd = categorie_doc().mov2cat(mov_i.numreg());
|
|
const bool found = cd != nullptr;
|
|
|
|
if (found)
|
|
mov_i.set_descr_estr(mov_no_error);
|
|
else
|
|
mov_i.set_descr_estr(mov_nocat_butok);
|
|
|
|
mov_i.set_estratto(true);
|
|
|
|
// DA CONTROLLARE
|
|
if (found)
|
|
check_annessi(mov_i);
|
|
}
|
|
|
|
// Se cartaceo preparo il file.
|
|
if (F9CONF.get_has_cartexp()) // Se e' abilitata l'esportazione dei cartacei, altrimenti skip...
|
|
mov_i.load_docs();
|
|
copy_file_to_webapp_fld(mov_i);
|
|
}
|
|
}
|
|
ok &= mov_i.no_err();
|
|
}
|
|
}
|
|
}
|
|
else if (tipo == iva_vendite)
|
|
{
|
|
// Controlli per le fatture di vendita (AGGIORNARE STATS QUI)
|
|
TProgress_monitor bar(_movs.items(), "Controllo stato movimenti di vendita");
|
|
|
|
FOR_EACH_ARRAY_ITEM(_movs, r, obj)
|
|
{
|
|
if (bar.add_status())
|
|
{
|
|
TMovimento_estr & mov_i = (TMovimento_estr &) *obj;
|
|
|
|
// Se escluso passo avanti
|
|
if (!mov_i.estratto() && mov_i.descr_estr() == mov_escluso)
|
|
continue;
|
|
|
|
const long numreg = mov_i.numreg();
|
|
const TRectype & mov = cache().get(LF_MOV, numreg);
|
|
/* Controlli per vendite cambiati:
|
|
* Elettroniche solo quelle agli italiani, tutti gli altri sono cartacei
|
|
*/
|
|
if (!mov_i.err() && mov_i.estratto())
|
|
{
|
|
mov_i.set_cartaceo(false); // ci deve essere ?
|
|
|
|
unsigned short skip = 0;
|
|
|
|
if (_has_cartacei && mov_i.cartaceo())
|
|
skip |= 0x1;
|
|
else if (pura_iva(mov))
|
|
skip |= 0x2;
|
|
else if (mov_i.datadoc().empty() || mov_i.numdoc().empty())
|
|
skip |= 0x4;
|
|
|
|
if(skip)
|
|
{
|
|
++_stats.fv_cart_skip;
|
|
mov_i.reset_err();
|
|
mov_i.set_estratto(false);
|
|
switch(skip)
|
|
{
|
|
case 0x1: mov_i.set_descr_estr(mov_no_cartaceo); break;
|
|
case 0x2: mov_i.set_descr_estr(mov_pura_iva); break;
|
|
case 0x4: mov_i.set_descr_estr(mov_no_fv); break;
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TClasse_doc* cd = categorie_doc().mov2cat(mov_i.numreg());
|
|
const bool found = cd != nullptr;
|
|
|
|
if (found)
|
|
mov_i.reset_err();
|
|
else
|
|
mov_i.set_err("Categoria assente", mov_no_catdoc);
|
|
if (cd != nullptr)
|
|
check_annessi(mov_i);
|
|
|
|
if (!mov_i.catdoc(categorie_doc()))
|
|
++_stats.fv_nocatdoc;
|
|
if (mov_i.err())
|
|
++_stats.fv_err;
|
|
else if (mov_i.estratto())
|
|
++_stats.fv_estr;
|
|
}
|
|
|
|
if (mov_i.estratto())
|
|
{
|
|
if (mov_i.numreg() == 41400) {
|
|
int here = 0;
|
|
}
|
|
if (mov_i.cartaceo())
|
|
{
|
|
TFilename file;
|
|
|
|
// if (filecart.mov2doc(mov_i.numreg(), file) && file.exist() || grab_pdf_from_spotlite(mov_i, file) && file.exist())
|
|
if (grab_pdf_from_spotlite(mov_i, file) && file.exist())
|
|
mov_i.set_nomefiledoc(file);
|
|
else
|
|
mov_i.set_err("Non e' stato possibile reperire il file del documento cartaceo per questo movimento.", mov_no_filecart);
|
|
}
|
|
|
|
TToken_string cartacei(mov.get(MOV_CARTACEI), '\n');
|
|
|
|
FOR_EACH_STR_TOKEN(cartacei, s)
|
|
{
|
|
TFilename file(s);
|
|
|
|
if (file.exist())
|
|
mov_i.documenti_allegati().add(file);
|
|
else
|
|
mov_i.set_err(format(FR("Non e' stato possibile reperire il file cartaceo %s per questo movimento."), (const char *) file), mov_no_filecart);
|
|
}
|
|
copy_file_to_webapp_fld(mov_i);
|
|
}
|
|
|
|
}
|
|
ok &= mov_i.no_err();
|
|
}
|
|
}
|
|
}
|
|
_head.stato_estr = ok ? D_GEST_OK : D_GEST_ERR;
|
|
return _head.stato_estr;
|
|
}
|
|
|
|
result_estr TEstrazione::estrai()
|
|
{
|
|
// Se non c'e' nessun movimento non sto nemmeno a scrivere il record di estrazione.
|
|
// Se estrazione definitiva controllo che il periodo non si sovrapponga alle altre estrazioni def.
|
|
// Do' errore ed esco subito.
|
|
result_estr res = estr_ok;
|
|
if (_movs.empty())
|
|
{
|
|
warning_box("Non esistono movimenti estraibili per il periodo selezionato.");
|
|
return estr_stop;
|
|
}
|
|
if (!_escluso && !_head.flag_prov)
|
|
{
|
|
/* if (!check_periodo_def())
|
|
{
|
|
error_box("Attenzione e' stato inserito un periodo che si sovrappone\nad un'estrazione definitiva gia' esistente. Impossibile procedere.");
|
|
return estr_stop;
|
|
}
|
|
if (gap_periodo())
|
|
{
|
|
if (!noyes_box("Attenzione, e' stato saltato un periodo rispetto all'ultimo\n"
|
|
"estratto e quello selezionato, il quale rimarrebbe vuoto.\nContinuare comunque?"))
|
|
return estr_stop;
|
|
} */
|
|
// Avviso nel caso in cui si stia facendo un'estrazione definitiva di un periodo di cui non si e' mai fatta
|
|
// una prova provvisoria.
|
|
if(!exist_prov())
|
|
{
|
|
if (!noyes_box("Attenzione, non e' mai stata fatta alcuna\nestrazione provvisoria per questo periodo.\nContinuare comunque?"))
|
|
return estr_stop;
|
|
}
|
|
}
|
|
|
|
// Non so come usare questi 18 caratteri...
|
|
// Uso dati anche se gia' noti in altri campi (I know..) + un numero incrementale.
|
|
_head.id_estr.cut(0) << today.date2ansi() << (_head.flag_prov ? "P" : "D") << (!_escluso ? "N" : "X") << next_estr_today(_head.tipo_doc);
|
|
_head.user = user();
|
|
// Eseguo controllo sui movimenti e segno in testata lo stato
|
|
_head.stato_estr = IN_DIAGN; // "01" che verra' quasi subito rimpiazzato dal risultato della diagnostica.
|
|
if (_escluso)
|
|
set_dates(); // Se escluso imposto data inizio e fine uguali
|
|
|
|
// Scrivo record estrazione (in stato '01': in diagnostica).
|
|
const bool ok = insert_into_drd();
|
|
|
|
if (!ok)
|
|
{
|
|
TString msg;
|
|
|
|
msg << "Errore database: impossibile scrivere nuova estrazione.\n"
|
|
<< fp_db().sq_get_text_error(false);
|
|
error_box(msg);
|
|
return estr_err_db_drd;
|
|
}
|
|
|
|
// Faccio partire la diagnostica e mi salvo il nuovo stato.
|
|
diagnostica_mov();
|
|
insert_into_f9movestr();
|
|
|
|
if (_head.stato_estr == D_GEST_ERR)
|
|
{
|
|
warning_box("Attenzione l'estrazione ha prodotto degli errori.\n"
|
|
"Controllare e correggere eventuali problemi\ndal Controllo Estrazione.");
|
|
// Se in errore, esporto lista errori sul db
|
|
if (!export_error_list())
|
|
warning_box("Errore scrittura db. Controllare log errori.");
|
|
res = estr_diag_err; // Errore diagnostica gestionale
|
|
}
|
|
|
|
// Se va tutto ben fino a qui, posso andare a scrivere nella
|
|
// tabella IVA i movimenti. F9IVA
|
|
if (res == estr_ok)
|
|
{
|
|
res = estrazione_iva() ? estr_ok : estr_err_db_iva;
|
|
if (res == estr_err_db_iva)
|
|
_head.stato_estr = D_GEST_ERR;
|
|
}
|
|
update_drd_stato_estr();
|
|
return res;
|
|
}
|
|
|
|
bool TEstrazione::estrazione_iva(bool escluso)
|
|
{
|
|
TString statopaiv, idfisc, paiv, codfis;
|
|
bool stato = true;
|
|
|
|
TProgress_monitor bar(_movs.items(), "Estrazione dati IVA");
|
|
|
|
FOR_EACH_ARRAY_ITEM(_movs, r, obj)
|
|
{
|
|
TMovimento_estr & mov_i = (TMovimento_estr &)*obj;
|
|
|
|
if (bar.add_status() && mov_i.estratto())
|
|
{
|
|
const TRectype& mov = cache().get(LF_MOV, mov_i.numreg());
|
|
TToken_string key = mov.get(MOV_TIPO);
|
|
|
|
key.add(mov.get(MOV_CODCF));
|
|
|
|
const TRectype& cli = cache().get(LF_CLIFO, key);
|
|
const char tipodoc = _head.tipo_doc;
|
|
const TCausale & caus = cached_causale(mov.get(MOV_CODCAUS), mov.get_date(MOV_DATAREG).year());
|
|
const TString& name_registro = caus.reg().name();;
|
|
fill_id(cli, statopaiv, idfisc, paiv, codfis);
|
|
TDate datadoc = mov.get_date(MOV_DATADOC);
|
|
TDate datareg = mov.get_date(MOV_DATAREG);
|
|
|
|
TIva_insert_prepared_stat iva_query; /////////QUIIIIIII///
|
|
|
|
iva_query.add(IVA_CODSOC, _head.cod_soc, 10);
|
|
iva_query.add(IVA_IDLAN, _head.id_estr, 18);
|
|
iva_query.add(IVA_FLAG_PD, _head.flag_prov ? 'P' : 'D');
|
|
iva_query.add(IVA_ANNOES, mov.get_int(MOV_ANNOES));
|
|
iva_query.add(IVA_GIVA, tipodoc);
|
|
iva_query.add(IVA_TIPOG, name_registro, 10);
|
|
iva_query.add(IVA_DOCXML, mov_i.cartaceo() ? 'N' : 'S');
|
|
iva_query.add(IVA_TIPOCF, mov.get_char(MOV_TIPO));
|
|
iva_query.add(IVA_CODCF, mov.get_long(MOV_CODCF));
|
|
iva_query.add(IVA_NUMOR, mov.get_long(MOV_NUMREG));
|
|
|
|
iva_query.add(IVA_RAGSOC, cli.get(CLI_RAGSOC), 60);
|
|
iva_query.add(IVA_IDFISC, idfisc, 30);
|
|
iva_query.add(IVA_PIVA, paiv, 28);
|
|
iva_query.add(IVA_CODFIS, codfis, 16);
|
|
iva_query.add(IVA_CATDOC, mov_i.catdoc(categorie_doc())->catdoc(), 10);
|
|
|
|
const TRegistro& reg = cached_registro(mov.get(MOV_REG), mov.get_int(MOV_ANNOIVA));
|
|
|
|
if (reg.iva() == iva_vendite)
|
|
{
|
|
|
|
int anno = mov.get_int(MOV_DANNO);
|
|
TString tipodocsdi;
|
|
|
|
if (anno > 0)
|
|
{
|
|
const char provv = mov.get(MOV_DPROVV)[0];
|
|
const TString& codnum = mov.get(MOV_DCODNUM);
|
|
const long ndoc = mov.get_long(MOV_DNDOC);
|
|
|
|
TDocumento doc(provv, anno, codnum, ndoc);
|
|
iva_query.add(IVA_CAUSSOS, tipo_doc_sdi(doc), 6);
|
|
}
|
|
else
|
|
tipodocsdi = caus.tipodocsdi();
|
|
if (tipodocsdi.blank())
|
|
tipodocsdi = mov_i.catdoc(categorie_doc())->caus_sost();
|
|
|
|
if (tipodocsdi.full())
|
|
iva_query.add(IVA_CAUSSOS, tipodocsdi, 6);
|
|
}
|
|
else
|
|
{
|
|
TToken_string key(mov.get((MOV_KEYFPPRO)), ';');
|
|
|
|
if (key.full())
|
|
{
|
|
TFppro fppro(key);
|
|
const TString& tipodoc = fppro.get_tipodoc();
|
|
|
|
if(tipodoc.full())
|
|
iva_query.add(IVA_CAUSSOS, tipodoc, 6);
|
|
else
|
|
iva_query.add(IVA_CAUSSOS, mov_i.catdoc(categorie_doc())->caus_sost(), 6);
|
|
}
|
|
else
|
|
iva_query.add(IVA_CAUSSOS, mov_i.catdoc(categorie_doc())->caus_sost(), 6);
|
|
}
|
|
iva_query.add(IVA_NUMDOC, mov_i.numdoc(), 20);
|
|
iva_query.add(IVA_DATADOC, datadoc);
|
|
iva_query.add(IVA_SEZIVA, mov.get(MOV_REG), 10);
|
|
iva_query.add(IVA_TIPOREG, "", 6);
|
|
iva_query.add(IVA_NPROT, mov.get(MOV_PROTIVA), 20);
|
|
iva_query.add(IVA_DATPROT, datareg);
|
|
|
|
/*if(is_autofattura(mov))
|
|
{
|
|
iva_query.add(IVA_FORNOR, "");
|
|
iva_query.add(IVA_REGOR, "");
|
|
iva_query.add(IVA_NUMOR, N ORI);
|
|
iva_query.add(IVA_DATAOR, TDate(20010101));
|
|
}*/
|
|
|
|
iva_query.add(IVA_CLASDOC, mov_i.catdoc(categorie_doc())->class_sost(), 10);
|
|
iva_query.add(IVA_NOMFD, mov_i.nomefiledoc().name(), 100);
|
|
|
|
// Load annessi...
|
|
if(mov_i.allegati())
|
|
{
|
|
TString_array & docs = mov_i.documenti_allegati();
|
|
int i = 0;
|
|
const int size = docs.items();
|
|
|
|
iva_query.add(IVA_CLASAN1, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF1, docs.row(i++).get(0), 100);
|
|
// HOW DID MY LIFE COME TO THIS?...
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN2, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF2, docs.row(i++).get(0), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN3, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF3, docs.row(i++).get(0), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN4, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF4, docs.row(i++).get(0), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN5, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF5, docs.row(i++).get(0), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN6, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF6, docs.row(i++).get(0), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN7, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF7, docs.row(i++).get(0), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN8, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF8, docs.row(i++), 100);
|
|
}
|
|
if (size > i)
|
|
{
|
|
iva_query.add(IVA_CLASAN9, docs.row(i).get(2), 10);
|
|
iva_query.add(IVA_NOMF9, docs.row(i++).get(0), 100);
|
|
}
|
|
}
|
|
|
|
iva_query.add(IVA_USERELA, user(), 10);
|
|
iva_query.add_getdate(IVA_TIMEELA);
|
|
|
|
if (_head.tipo_doc == 'A' && !mov_i.cartaceo())
|
|
{
|
|
TToken_string keys(mov.get(MOV_KEYFPPRO), ';');
|
|
fppro_db().set_keys(keys);
|
|
iva_query.add(IVA_TIPPROT, fppro_db().get_tipoprot(), 2);
|
|
iva_query.add(IVA_ANNPROT, TVariant(fppro_db().get_annoprot()).as_int());
|
|
iva_query.add(IVA_NUMPROT, fppro_db().get_numprot(), 10); // Non controllo che sia in realta' un numero...
|
|
iva_query.add(IVA_TIMERIC, TDate(fppro_db().get_dataoraric()));
|
|
}
|
|
TString sql;
|
|
|
|
//DA MIGLIORARE IL LOG DI ERRORE
|
|
long a = mov_i.numreg();
|
|
|
|
bool ok = iva_query.get(sql);
|
|
|
|
if (ok)
|
|
ok = fp_db().sq_set_exec(sql);
|
|
if (ok)
|
|
ok = fp_db().sq_commit();
|
|
if (!ok)
|
|
write_errorsql_log(sql);
|
|
|
|
stato &= ok;
|
|
}
|
|
}
|
|
return stato;
|
|
}
|
|
|
|
bool TEstrazione::exist_prov() const
|
|
{
|
|
TString query; query << "SELECT * FROM " F9_DRD "\n" <<
|
|
"WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND " DRD_DATADA " = '" << _head.dal.date2ansi() << "'"
|
|
" AND " DRD_DATAA " = '" << _head.al.date2ansi() << "' AND " DRD_FLAG_PD " = 'P' AND " DRD_TIPODOC " = '" << _head.tipo_doc << "'";
|
|
const bool ok = fp_db().sq_set_exec(query);
|
|
return ok && fp_db().sq_items() > 0;
|
|
}
|
|
|
|
bool TEstrazione::gap_periodo() const
|
|
{
|
|
TString query; query << "SELECT " DRD_ID_EST " AS ID, " DRD_DATAA " AS DATA_A\n"
|
|
"FROM " F9_DRD "\n"
|
|
"WHERE " DRD_CODSOC " = '" << _head.cod_soc << "' AND " DRD_ID_EST " LIKE '%N%' AND " // '%N%' = Pacchetto normale
|
|
DRD_FLAG_PD " = 'D' AND " DRD_TIPODOC " = '" << _head.tipo_doc << "'\n"
|
|
"ORDER BY " DRD_DATAA " DESC";
|
|
const bool ok = fp_db().sq_set_exec(query);
|
|
return ok && fp_db().sq_items() > 0 && _head.dal - fp_db().sq_get_date("DATA_A") > 1;
|
|
}
|
|
|
|
void TEstrazione::set_dates()
|
|
{
|
|
if (_escluso)
|
|
{
|
|
set_dataini(((TMovimento_estr &)_movs[0]).datareg());
|
|
set_dataend(((TMovimento_estr &)_movs[0]).datareg());
|
|
}
|
|
}
|
|
|
|
TEstrazione::TEstrazione(const TString& ambiente, const bool flag_prov, const char tipodoc, const TString& descr,
|
|
const TString& addrcart, const bool escluso, TFilename& spotlite_path, TLog_report * log, const TDate* const dal, const TDate* const al, const bool has_cartacei)
|
|
: _descr(descr), _has_cartacei(has_cartacei), _spotlite_path(spotlite_path), _log(log)
|
|
{
|
|
_head.cod_soc = ambiente;
|
|
_head.flag_prov = flag_prov;
|
|
_head.descr = descr;
|
|
_head.tipo_doc = tipodoc;
|
|
if (!escluso && dal != nullptr && al != nullptr)
|
|
{
|
|
_head.dal = *dal;
|
|
_head.al = *al;
|
|
}
|
|
_head.addr_cart = addrcart;
|
|
|
|
_escluso = escluso;
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// TF9_dberr
|
|
//////////////////////////////////////////////////////
|
|
|
|
void TF9_dberr::add_str(const TString& string)
|
|
{
|
|
_insert.rtrim(1);
|
|
if (_insert[_insert.len() - 1] != '(')
|
|
_insert << ", ";
|
|
_insert << string << ")";
|
|
}
|
|
|
|
void TF9_dberr::write_sqlerrlog(const TString& query) const
|
|
{
|
|
_log->log_error(query);
|
|
_log->log_error(fp_db().sq_get_string_error());
|
|
_log->log_error(fp_db().sq_get_text_error());
|
|
_log->line();
|
|
}
|
|
|
|
void TF9_dberr::add(const TString& string)
|
|
{
|
|
TString str = string;
|
|
|
|
str.replace("'", "''");
|
|
str.insert("'");
|
|
str << "'";
|
|
add_str(str);
|
|
}
|
|
|
|
|
|
|
|
void TF9_dberr::add(const TDate& date)
|
|
{
|
|
if (date.ok())
|
|
add(date.date2ansi());
|
|
|
|
else
|
|
add("00010101");
|
|
}
|
|
|
|
void TF9_dberr::add(const long num)
|
|
{
|
|
TString app;
|
|
app << num;
|
|
add(app);
|
|
}
|
|
|
|
bool TF9_dberr::send()
|
|
{
|
|
const bool ok = fp_db().sq_set_exec(_insert) && fp_db().sq_commit();
|
|
if(!ok)
|
|
write_sqlerrlog(_insert);
|
|
_insert.cut(0) << "INSERT INTO " F9_ERR " ("
|
|
ERR_CODSOC ", "
|
|
ERR_IDESTR ", "
|
|
ERR_NUMREG ", "
|
|
ERR_DATAREG ", "
|
|
ERR_DATADOC ", "
|
|
ERR_CODCAUS ", "
|
|
ERR_MESELIQ ", "
|
|
ERR_NUMDOC ", "
|
|
ERR_IMPTDOC ", "
|
|
ERR_FORN ", "
|
|
ERR_RAGSOC ", "
|
|
ERR_PROTIVA ", "
|
|
ERR_DESCR ", "
|
|
ERR_DESCERR ") VALUES ()";
|
|
return ok;
|
|
}
|
|
|
|
bool dberr_del_err(const TString& codsoc, const TString& id_estr, const int numreg)
|
|
{
|
|
TString query;
|
|
|
|
query << "DELETE FROM " F9_ERR
|
|
"\nWHERE " ERR_CODSOC " = '" << codsoc << "'"
|
|
"\nAND " ERR_IDESTR " = '" << id_estr << "' AND " ERR_NUMREG " = '" << numreg << "';";
|
|
return fp_db().sq_set_exec(query) && fp_db().sq_commit();
|
|
}
|
|
|
|
char dberr_get_err(const TString& codsoc, const TString& id_estr, TArray& controllo_mov)
|
|
{
|
|
TString query;
|
|
|
|
query << "SELECT * FROM " F9_ERR
|
|
"\nWHERE " ERR_CODSOC " = '" << codsoc << "' AND "
|
|
ERR_IDESTR " = '" << id_estr << "';";
|
|
fp_db().sq_set_exec(query, false);
|
|
controllo_mov.destroy();
|
|
for (bool ok = fp_db().sq_next(); ok; ok = fp_db().sq_next())
|
|
{
|
|
TToken_string row("", '|');
|
|
row.add("X");
|
|
for (int i = 1; i < 15; i++)
|
|
{
|
|
if (fp_db().sq_get_type_field(i) == _datefld)
|
|
row.add(fp_db().sq_get_date(fp_db().sq_get_name_field(i)));
|
|
else
|
|
row.add(fp_db().sq_get(i));
|
|
}
|
|
|
|
controllo_mov.add(row);
|
|
}
|
|
query.cut(0) << "SELECT " DRD_TIPODOC " FROM " F9_DRD "\n" <<
|
|
"WHERE " DRD_CODSOC " = '" << codsoc << "' AND " DRD_ID_EST " = '" << id_estr << "'";
|
|
fp_db().sq_set_exec(query);
|
|
return fp_db().sq_get((unsigned)0)[0];
|
|
}
|
|
|
|
TF9_dberr::TF9_dberr(TLog_report * log) : _log(log)
|
|
{
|
|
_insert.cut(0) << "INSERT INTO " F9_ERR " ("
|
|
ERR_CODSOC ", "
|
|
ERR_IDESTR ", "
|
|
ERR_NUMREG ", "
|
|
ERR_DATAREG ", "
|
|
ERR_DATADOC ", "
|
|
ERR_CODCAUS ", "
|
|
ERR_MESELIQ ", "
|
|
ERR_NUMDOC ", "
|
|
ERR_IMPTDOC ", "
|
|
ERR_FORN ", "
|
|
ERR_RAGSOC ", "
|
|
ERR_PROTIVA ", "
|
|
ERR_DESCR ", "
|
|
ERR_DESCERR ") VALUES ()";
|
|
}
|
|
;
|
|
TString _user;
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// TAnnesso_mov
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TAnnesso_mov::TAnnesso_mov(TToken_string & row, int start)
|
|
{
|
|
_numreg = row.get_long(start);
|
|
_filename = row.get();
|
|
_catdocpad = row.get();
|
|
_catdocann = row.get();
|
|
_loaddate = row.get_date(0);
|
|
_user = row.get();
|
|
}
|
|
|
|
TAnnesso_mov & TAnnesso_mov::copy(const TAnnesso_mov & a)
|
|
{
|
|
_numreg = a._numreg;
|
|
_filename = a._filename;
|
|
_catdocpad = a._catdocpad;
|
|
_catdocann = a._catdocann;
|
|
_loaddate = a._loaddate;
|
|
_user = a._user;
|
|
return *this;
|
|
}
|
|
|
|
void TAnnesso_mov::ann2row(TToken_string & row)
|
|
{
|
|
row.cut(0);
|
|
row.add(_numreg);
|
|
row.add(_filename);
|
|
row.add(_catdocpad);
|
|
row.add(_catdocann);
|
|
row.add(_loaddate);
|
|
row.add(_user);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// TClasse_doc
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TClasse_doc::TClasse_doc(TToken_string & row, int start)
|
|
{
|
|
|
|
_catdoc = row.get(start);
|
|
_descr = row.get();
|
|
_class_sost = row.get();
|
|
_caus_sost = row.get();
|
|
_causcont = row.get();
|
|
_tipocaus = row.get();
|
|
}
|
|
|
|
TClasse_doc & TClasse_doc::copy(const TClasse_doc & c)
|
|
{
|
|
_catdoc = c._catdoc;
|
|
_descr = c._descr;
|
|
_class_sost = c._class_sost;
|
|
_caus_sost = c._caus_sost;
|
|
_causcont = c._causcont;
|
|
_tipocaus = c._tipocaus;
|
|
return *this;
|
|
}
|
|
|
|
void TClasse_doc::ann2row(TToken_string & row)
|
|
{
|
|
row.cut(0);
|
|
row.add(_catdoc);
|
|
row.add(_descr);
|
|
row.add(_class_sost);
|
|
row.add(_caus_sost);
|
|
row.add(_causcont);
|
|
row.add(_tipocaus);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// TAnnesso
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TAnnesso::TAnnesso(TToken_string & row, int start)
|
|
{
|
|
_catdocpadre = row.get(start);
|
|
_catdoc = row.get();
|
|
_descr = row.get();
|
|
_opcee = row.get();
|
|
_obblig = row.get_bool();
|
|
}
|
|
|
|
TAnnesso & TAnnesso::copy(const TAnnesso & a)
|
|
{
|
|
_catdocpadre = a._catdocpadre;
|
|
_catdoc = a._catdoc;
|
|
_descr = a._descr;
|
|
_opcee = a._opcee;
|
|
_obblig = a._obblig;
|
|
return *this;
|
|
}
|
|
|
|
void TAnnesso::ann2row(TToken_string & row)
|
|
{
|
|
row.cut(0);
|
|
row.add(_catdocpadre);
|
|
row.add(_catdoc);
|
|
row.add(_descr);
|
|
row.add(_opcee);
|
|
row.add(_obblig);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// TCategorie_doc
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TClasse_doc * TCategorie_doc::find_causcont(const TString& caus)
|
|
{
|
|
FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj)
|
|
{
|
|
TClasse_doc * classe = (TClasse_doc *)obj;
|
|
|
|
if (classe->causcont() == caus)
|
|
return classe;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
TClasse_doc * TCategorie_doc::find_tipodoc(const TString& tipodoc)
|
|
{
|
|
FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj)
|
|
{
|
|
TClasse_doc * classe = (TClasse_doc *)obj;
|
|
|
|
if (classe->causcont().blank() && classe->tipocaus() == tipodoc)
|
|
return classe;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
TClasse_doc * TCategorie_doc::find_tipodocsdi(const TString& tipodocsdi, const char * tipocaus)
|
|
{
|
|
FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj)
|
|
{
|
|
TClasse_doc * classe = (TClasse_doc *)obj;
|
|
|
|
if ((classe->caus_sost() == tipodocsdi) && (classe->tipocaus() == tipocaus))
|
|
return classe;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void TCategorie_doc::load_all()
|
|
{
|
|
_rows.destroy();
|
|
_rows_annessi.destroy();
|
|
int idx = 0;
|
|
while (true)
|
|
{
|
|
const TString& appo = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, "", idx++);
|
|
|
|
if (appo == "STOP" || appo.blank()) /* STOP: Riga terminatrice */
|
|
break;
|
|
|
|
TToken_string row(appo);
|
|
const TString catdoc(row.get(1));
|
|
TClasse_doc cd(row, 1);
|
|
_rows.add(catdoc, cd);
|
|
}
|
|
|
|
idx = 0;
|
|
while (true)
|
|
{
|
|
const TString& appo = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, "", idx++);
|
|
|
|
if (appo == "STOP" || appo.blank()) /* STOP: Riga terminatrice */
|
|
break;
|
|
|
|
TToken_string row(appo);
|
|
TAnnesso ann(row);
|
|
TToken_string key = row.get(0);
|
|
|
|
key.add(row.get(1));
|
|
_rows_annessi.add(key, ann);
|
|
}
|
|
}
|
|
|
|
void TCategorie_doc::save_ann()
|
|
{
|
|
remove_all_ann();
|
|
|
|
int idx = 0;
|
|
|
|
FOR_EACH_ASSOC_OBJECT(_rows_annessi, hash, key, obj)
|
|
{
|
|
TToken_string row;
|
|
TAnnesso & ann = (TAnnesso &) *obj;
|
|
|
|
if(ann.catdocpadre().full())
|
|
row.add(ann.catdocpadre(), 0);
|
|
if (ann.catdoc().full())
|
|
row.add(ann.catdoc(), 1);
|
|
if (ann.descr().full())
|
|
row.add(ann.descr(), 2);
|
|
if (ann.opcee().full())
|
|
row.add(ann.opcee(), 3);
|
|
row.add(ann.obblig(), 4);
|
|
ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, row, idx++);
|
|
}
|
|
ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, "STOP", idx); // Riga terminatrice
|
|
reload();
|
|
}
|
|
|
|
void TCategorie_doc::save_cat()
|
|
{
|
|
remove_all_cat();
|
|
|
|
int idx = 0;
|
|
|
|
FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj)
|
|
{
|
|
TClasse_doc& cd = (TClasse_doc &) *obj;
|
|
TToken_string row;
|
|
|
|
if (cd.catdoc().full())
|
|
row.add(cd.catdoc(), 1);
|
|
if (cd.descr().full())
|
|
row.add(cd.descr(), 2);
|
|
if (cd.class_sost().full())
|
|
row.add(cd.class_sost(), 3);
|
|
if (cd.caus_sost().full())
|
|
row.add(cd.caus_sost(), 4);
|
|
if (cd.causcont().full())
|
|
row.add(cd.causcont(), 5);
|
|
if (cd.tipocaus().full())
|
|
row.add(cd.tipocaus(), 6);
|
|
ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, row, idx++);
|
|
}
|
|
ini_set_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, "STOP", idx); // Riga terminatrice
|
|
|
|
reload();
|
|
}
|
|
|
|
const char* TCategorie_doc::traduci_caus_sost(const TString& caus)
|
|
{
|
|
if (caus == "TD01") return "TD01 Fattura";
|
|
if (caus == "TD02") return "TD02 Acconto/Anticipo su fattura";
|
|
if (caus == "TD03") return "TD03 Acconto/Anticipo su parcella";
|
|
if (caus == "TD04") return "TD04 Nota di credito";
|
|
if (caus == "TD05") return "TD05 Nota di debito";
|
|
if (caus == "TD06") return "TD06 Parcella";
|
|
if (caus == "TD16") return "TD16 Integraz. fatt. rev.ch. interno";
|
|
if (caus == "TD17") return "TD17 Integ./autof. acq. servizi estero";
|
|
if (caus == "TD18") return "TD18 Integ. acq. beni intracomunitari";
|
|
if (caus == "TD19") return "TD19 Integ./autof. acq. beni ex art. 17";
|
|
if (caus == "TD20") return "TD20 Autofattura";
|
|
if (caus == "TD21") return "TD21 Autofattura per splafonamento";
|
|
if (caus == "TD22") return "TD22 Estrazione beni da Deposito IVA";
|
|
if (caus == "TD23") return "TD23 Estr. beni Deposito IVA vers. IVA";
|
|
if (caus == "TD24") return "TD24 Fatt. differita art.21 c.4 lett. a";
|
|
if (caus == "TD25") return "TD25 Fatt. differita art. 21 c.4 per.3 b";
|
|
if (caus == "TD26") return "TD26 Cess. beni ammort./passaggi interni";
|
|
if (caus == "TD27") return "TD27 Fatt. autoconsumo/cessioni gratuite";
|
|
return "";
|
|
}
|
|
|
|
const char* TCategorie_doc::traduci_class_ann(const TString& class_ann)
|
|
{
|
|
if (class_ann == "RC") return "Reverse Charge";
|
|
if (class_ann == "DC") return "ANN. cartaceo";
|
|
return "";
|
|
}
|
|
|
|
const char* TCategorie_doc::traduci_class_sost(const TString& class_sost)
|
|
{
|
|
if (class_sost == "FTA") return "FTA - Fattura Acquisti";
|
|
if (class_sost == "FTV") return "FTV - Fattura di Vendita";
|
|
return "";
|
|
}
|
|
|
|
TAnnesso * TCategorie_doc::find_annesso(const TString& catdoc_padre, const char* catdoc_ann)
|
|
{
|
|
TToken_string key = catdoc_padre;
|
|
|
|
key.add(catdoc_ann);
|
|
return (TAnnesso *)_rows_annessi.objptr(key);
|
|
}
|
|
|
|
void TCategorie_doc::add_annesso(const TString& catdoc_padre, const TString& catdoc_ann, const TString& descr,
|
|
const TString& class_ann, const bool obblig)
|
|
{
|
|
if(!(catdoc_padre && *catdoc_padre && catdoc_ann && *catdoc_ann && class_ann && *class_ann))
|
|
fatal_box("add_annesso failed: some parameters are NULL or keys are empty");
|
|
|
|
TToken_string key = catdoc_padre;
|
|
|
|
key.add(catdoc_ann);
|
|
_rows_annessi.add(key, new TAnnesso(catdoc_padre, catdoc_ann, descr, class_ann, obblig));
|
|
save_ann();
|
|
}
|
|
|
|
void TCategorie_doc::edit_annesso(const TString& catdoc_padre, const TString& catdoc_ann, const TString& descr,
|
|
const TString& class_ann, const bool obblig)
|
|
{
|
|
if (!(catdoc_padre && *catdoc_padre && catdoc_ann && *catdoc_ann && class_ann && *class_ann))
|
|
fatal_box("add_annesso failed: some parameters are NULL or keys are empty");
|
|
if (find_annesso(catdoc_padre,catdoc_ann) != nullptr)
|
|
del_annesso(catdoc_padre,catdoc_ann);
|
|
|
|
TToken_string key = catdoc_padre;
|
|
|
|
key.add(catdoc_ann);
|
|
_rows_annessi.add( key, new TAnnesso(catdoc_padre, catdoc_ann, descr, class_ann, obblig));
|
|
save_ann();
|
|
}
|
|
|
|
void TCategorie_doc::add_categoria(const TString& catdoc, const TString& descr, const TString& class_sost, const TString& caus_sost,
|
|
const TString& causcont, const TString& tipocaus)
|
|
{
|
|
if(!(catdoc && *catdoc && class_sost && *class_sost && caus_sost && *caus_sost))
|
|
fatal_box("add_categoria failed: some parameters are NULL or keys are empty");
|
|
_rows.add(catdoc, TClasse_doc(catdoc, descr, class_sost, caus_sost, causcont, tipocaus));
|
|
save_cat();
|
|
}
|
|
|
|
void TCategorie_doc::del_annesso(const TString& catdoc, const char* catdoc_ann)
|
|
{
|
|
if (find_annesso(catdoc, catdoc_ann) != nullptr)
|
|
{
|
|
TToken_string key = catdoc;
|
|
|
|
key.add(catdoc_ann);
|
|
_rows_annessi.remove(key);
|
|
save_ann();
|
|
}
|
|
}
|
|
|
|
TAnnesso * TCategorie_doc::get_ann(const TString & catdoc ,const TString& catann)
|
|
{
|
|
TToken_string key = catdoc;
|
|
|
|
key.add(catann);
|
|
|
|
TAnnesso * ann = (TAnnesso *) _rows_annessi.objptr(key);
|
|
|
|
return ann;
|
|
}
|
|
|
|
TString_array TCategorie_doc::get_array_ann(const TString& catdoc)
|
|
{
|
|
TString_array sa(0);
|
|
|
|
FOR_EACH_ASSOC_OBJECT(_rows_annessi, hash, key, obj)
|
|
{
|
|
TAnnesso & ann = (TAnnesso &) *obj;
|
|
|
|
if (ann.catdocpadre() == catdoc)
|
|
{
|
|
TToken_string row(ann.catdoc());
|
|
|
|
sa.add(row);
|
|
}
|
|
}
|
|
return sa;
|
|
}
|
|
|
|
TString_array TCategorie_doc::get_array_rows(const bool traduci)
|
|
{
|
|
TString_array sa(_rows.items());
|
|
|
|
FOR_EACH_ASSOC_OBJECT(_rows, hash, key, obj)
|
|
{
|
|
TClasse_doc & row = (TClasse_doc &)*obj;
|
|
TToken_string ts;
|
|
|
|
ts.add(row.catdoc());
|
|
ts.add(row.descr());
|
|
ts.add(!traduci ? row.class_sost() : traduci_class_sost(row.class_sost()));
|
|
ts.add(!traduci ? row.caus_sost() : traduci_caus_sost(row.caus_sost()));
|
|
ts.add(row.causcont());
|
|
ts.add(row.tipocaus());
|
|
sa.add(ts);
|
|
}
|
|
return sa;
|
|
}
|
|
|
|
TArray_sheet * TCategorie_doc::get_sheet_catdocs()
|
|
{
|
|
if (_sheet_catdocs == nullptr)
|
|
{
|
|
_sheet_catdocs = new TArray_sheet(-1, -1, 125, 20, "Categorie Documentali",
|
|
"Categoria\nDocumento(Codice)@15|Descrizione\nDocumento@26|"
|
|
"Classe Documentale\nSostitutiva@13|Causale per\nSostitutiva (TD01...)@13|"
|
|
"Causale\nContabile@8|Tipo\nDocumento@8",
|
|
MODE_SHEETS);
|
|
safe_delete(_name_catdocs);
|
|
_name_catdocs = new TString_array;
|
|
//_sheet_catdocs->add_button(DLG_CANCEL, "Annulla", K_ESC, TOOL_CANCEL, TOOL_CANCEL);
|
|
const TString_array ar = get_array_rows();
|
|
FOR_EACH_ARRAY_ITEM(ar, nr, row)
|
|
{
|
|
_sheet_catdocs->add(*(TToken_string*)row);
|
|
_name_catdocs->add(((TToken_string*)row)->get(0));
|
|
}
|
|
}
|
|
return _sheet_catdocs;
|
|
}
|
|
|
|
TArray_sheet * TCategorie_doc::get_sheet_ann(const TString& catdoc)
|
|
{
|
|
TArray_sheet * sheet = find_sheet_annessi(catdoc);
|
|
|
|
if (sheet != nullptr)
|
|
_sheets_annessi.remove(catdoc);
|
|
sheet = find_sheet_annessi(catdoc);
|
|
if (find_sheet_annessi(catdoc) == nullptr)
|
|
{
|
|
TString title; title << "Annessi della Categoria " << catdoc;
|
|
|
|
sheet = new TArray_sheet(-1, -1, 78, 13, title, "Categoria\nAnnesso(Codice)@15|Descrizione\nDocumento@26|"
|
|
"Classificazione\nAnnesso@14|Obbligatorio@8", _mode_sheet);
|
|
|
|
const auto inserted = _sheets_annessi.add(catdoc, sheet);
|
|
const TString_array & aann = get_array_ann(catdoc);
|
|
|
|
FOR_EACH_ARRAY_ITEM(aann, nr, r)
|
|
{
|
|
TToken_string & row = *(TToken_string*)r;
|
|
TAnnesso * ann = find_annesso(catdoc, row.get(0));
|
|
|
|
if(ann != nullptr)
|
|
{
|
|
TToken_string t;
|
|
|
|
t.add(ann->catdoc());
|
|
t.add(ann->descr());
|
|
t.add(ann->opcee());
|
|
t.add(ann->obblig());
|
|
sheet->add(t);
|
|
}
|
|
}
|
|
}
|
|
return sheet;
|
|
}
|
|
|
|
TClasse_doc * TCategorie_doc::mov2cat(const long numreg)
|
|
{
|
|
// Leggo la causale e cerco la corrispondente nelle categorie documentali, se c'e'.
|
|
// Guardo le colonne causale cont., tipodoc, class. cat. (opcee)
|
|
const TRectype & mov = cache().get(LF_MOV, numreg);
|
|
const TString& caus = mov.get(MOV_CODCAUS);
|
|
const TCausale & c = cached_causale(caus, mov.get_date(MOV_DATAREG).year());
|
|
const TString& tipodoc = c.tipo_doc();
|
|
|
|
// Cerco se ho un record che abbia specificata quella caus. contabile
|
|
TClasse_doc * cat = find_causcont(caus);
|
|
if (cat != nullptr)
|
|
return cat;
|
|
// Altrimenti cerco per tipo documento
|
|
return find_tipodoc(tipodoc);
|
|
}
|
|
|
|
void TCategorie_doc::reload()
|
|
{
|
|
load_all();
|
|
}
|
|
|
|
void TCategorie_doc::remove_all()
|
|
{
|
|
remove_all_ann();
|
|
remove_all_cat();
|
|
}
|
|
|
|
void TCategorie_doc::remove_all_ann()
|
|
{
|
|
int idx = 0;
|
|
TString iget = "start";
|
|
while (iget != "STOP" && !iget.blank())
|
|
{
|
|
iget = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, "", idx);
|
|
ini_remove(CONFIG_DITTA, INI_PAR_MOD, INI_ANNESSI, idx++);
|
|
}
|
|
}
|
|
|
|
void TCategorie_doc::remove_all_cat()
|
|
{
|
|
int idx = 0;
|
|
TString iget = "start";
|
|
while (iget != "STOP" && !iget.blank())
|
|
{
|
|
iget = ini_get_string(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, "", idx);
|
|
ini_remove(CONFIG_DITTA, INI_PAR_MOD, INI_CATDOC, idx++);
|
|
}
|
|
}
|
|
|
|
TCategorie_doc::TCategorie_doc() : _mode_sheet(MODE_SHEETS)
|
|
{
|
|
load_all();
|
|
}
|
|
|
|
|
|
|
|
TCategorie_doc& categorie_doc(const bool reload)
|
|
{
|
|
static TCategorie_doc* _doc_cats = nullptr;
|
|
|
|
if (_doc_cats == nullptr)
|
|
_doc_cats = new TCategorie_doc();
|
|
else if (reload)
|
|
_doc_cats->reload();
|
|
return *_doc_cats;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// TRecord_categorie
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
TString TRecord_categorie::get(const char* field)
|
|
{
|
|
recordtype& rec = _table == 0 ? _categorie : _annessi;
|
|
const int i = rec.head.find(field);
|
|
if (i != -1)
|
|
return rec.record.get(i);
|
|
return "";
|
|
}
|
|
|
|
bool TRecord_categorie::next()
|
|
{
|
|
recordtype& rec = _table == 0 ? _categorie : _annessi;
|
|
TToken_string* p = (TToken_string*)_result_set.objptr(_next_pos++);
|
|
rec.record = p ? *p : "";
|
|
return p;
|
|
}
|
|
|
|
void TRecord_categorie::put(const char* field, const char* value)
|
|
{
|
|
recordtype& rec = _table == 0 ? _categorie : _annessi;
|
|
const int i = rec.head.find(field);
|
|
if (i != -1)
|
|
rec.record.add(value, i);
|
|
}
|
|
|
|
bool TRecord_categorie::read(bool traduci)
|
|
{
|
|
_next_pos = 0;
|
|
_result_set.destroy();
|
|
if (_table == 0)
|
|
{
|
|
const TString_array sa = get_array_rows(traduci);
|
|
FOR_EACH_ARRAY_ITEM(sa, nr, str)
|
|
{
|
|
TString s = (*(TToken_string*)str).get(0);
|
|
if (s == _categorie.record.get(0))
|
|
_result_set.add(*(TToken_string*)str);
|
|
}
|
|
return next();
|
|
}
|
|
else
|
|
{
|
|
const TString catdoc = _annessi.record.get(0);
|
|
const TString name = _annessi.record.get(1);
|
|
const TString_array sa = get_array_ann(catdoc);
|
|
|
|
FOR_EACH_ARRAY_ITEM(sa, nr, str)
|
|
{
|
|
TString n = (*(TToken_string*)str).get(0);
|
|
|
|
if (name.blank() || n == name) // Se name vuoto perche' sto cercando solo per catdoc
|
|
{
|
|
TAnnesso * ann = find_annesso(catdoc, n);
|
|
|
|
if (ann != nullptr)
|
|
{
|
|
TToken_string t;
|
|
t.add(ann->catdocpadre());
|
|
t.add(ann->catdoc());
|
|
t.add(ann->descr());
|
|
t.add(ann->opcee());
|
|
t.add(ann->obblig());
|
|
_result_set.add(t);
|
|
}
|
|
}
|
|
}
|
|
return next();
|
|
}
|
|
}
|
|
|
|
TRecord_categorie::TRecord_categorie(type table): _table(table)
|
|
{
|
|
_categorie.head.add("NAME");
|
|
_categorie.head.add("DESCR");
|
|
_categorie.head.add("CLASSDOCSOS");
|
|
_categorie.head.add("CAUSSOS");
|
|
_categorie.head.add("CAUSCONT");
|
|
_categorie.head.add("TIPODOC");
|
|
|
|
_annessi.head.add("CATDOC");
|
|
_annessi.head.add("NAME");
|
|
_annessi.head.add("DESCR");
|
|
_annessi.head.add("TIPOANN");
|
|
_annessi.head.add("OBBLIG");
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
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;
|
|
}
|