Patch level : 12.0 no-patch
Files correlati : f90.exe Commento : - F9 ARCHIVIAZIONE SOSTITUTIVA: - Corretta multivalues insert in f9movestr: se troppi valori TString non poteva contenerli tutti. Separate in singole insert. - Aggiunta barra progresso per salvataggio movimenti estratti. - Modificato controllo per movimenti di vendita: guardo flag in configurazione (fatturazione esterna), controllo la cat.doc., e distinzione attraverso cat. doc. se si tratta di un doc. cartaceo. - Aggiunti controllo di aiuto all'utente: avvisa se viene lasciato un gap di tempo vuoto tra un'estrazione e l'altra, e avvisa se si sta facendo un'estrazione definitiva senza aver mai fatto una provvisora dello stesso tipo e periodo.
This commit is contained in:
parent
496bf39046
commit
89590b09fc
@ -153,7 +153,7 @@ bool TEstrai_mask::estrai_handler(TMask_field& f, KEY key)
|
||||
{
|
||||
warning_box("L'estrazione non e' stata completata. Controllare il log degli errori.");
|
||||
if (stato == 0) // Errore scrittura F9IVA, non segno in errore in testata...
|
||||
a.segna_in_errore(); // ... se l'errore e' dovuto alla scrittura sul db
|
||||
TF9_app::segna_in_errore(); // ... se l'errore e' dovuto alla scrittura sul db
|
||||
}
|
||||
a.print_log();
|
||||
msk.field(ES_DESCR).set("");
|
||||
@ -1116,14 +1116,15 @@ int TF9_app::estrai()
|
||||
|
||||
// Vero e proprio oggetto estrazione
|
||||
_estrazione = make_unique<TEstrazione>(
|
||||
get_ambiente(), // Codice ambiente
|
||||
flagpro, // Flag prov.
|
||||
tipodoc, // Tipo doc.
|
||||
get_descr(), // Descrizione estrazione
|
||||
get_addr_doc(), // Cartella documenti
|
||||
false, // Estrazione di un escluso
|
||||
&dataini, // Data estr. mov dal
|
||||
&dataend // Data estr. mov al
|
||||
get_ambiente(), // Codice ambiente
|
||||
flagpro, // Flag prov.
|
||||
tipodoc, // Tipo doc.
|
||||
get_descr(), // Descrizione estrazione
|
||||
get_addr_doc(), // Cartella documenti
|
||||
false, // Estrazione di un escluso
|
||||
&dataini, // Data estr. mov dal
|
||||
&dataend, // Data estr. mov al
|
||||
get_has_vendext() // Flag in configurazione per staltare controlli vendite
|
||||
);
|
||||
|
||||
// Leggo i movimenti e li carico nell'estrazione. /////////////
|
||||
|
@ -127,21 +127,23 @@ bool TEstrazione::insert_into_drd() const
|
||||
bool TEstrazione::insert_into_f9movestr() const
|
||||
{
|
||||
TString query;
|
||||
query << "INSERT INTO " F9_MOVESTR " (IDESTR, NUMREG, DATAREG, ESTRATTO, DESCR_ERR)\nVALUES ";
|
||||
bool ok = true;
|
||||
for(auto it = _movs.begin(); it != _movs.end(); ++it)
|
||||
{
|
||||
query << " ('" << _head.id_estr << "', '" << it->numreg << "', '" << it->datareg.date2ansi() << "', " <<
|
||||
(it->estratto ? "1" : "0") << ", '" << check_str(it->get_descr_estr()) << "'),\n";
|
||||
query.cut(0) << "INSERT INTO " F9_MOVESTR " (IDESTR, NUMREG, DATAREG, ESTRATTO, DESCR_ERR)\nVALUES " <<
|
||||
" ('" << _head.id_estr << "', '" << it->numreg << "', '" << it->datareg.date2ansi() << "', " <<
|
||||
(it->estratto ? "1" : "0") << ", '" << check_str(it->get_descr_estr()) << "')";
|
||||
#ifdef DBG
|
||||
if (TString(check_str(it->get_descr_estr())).empty())
|
||||
bool simo = true;
|
||||
#endif
|
||||
ok &= fp_db().sq_set_exec(query) && fp_db().sq_commit();
|
||||
if (!ok)
|
||||
{
|
||||
write_errorsql_log(query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
query.rtrim(2);
|
||||
bool ok = fp_db().sq_set_exec(query);
|
||||
ok = ok && fp_db().sq_commit();
|
||||
if (!ok)
|
||||
write_errorsql_log(query);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -151,8 +153,12 @@ bool TEstrazione::export_error_list() const
|
||||
const vector<movimento_t>& movs = _movs;
|
||||
bool ok = true;
|
||||
int count = 0;
|
||||
TProgress_monitor pg(movs.size(), "Scrittura movimenti in errore");
|
||||
for (auto it = movs.begin(); it != movs.end(); ++it)
|
||||
{
|
||||
if (!pg.add_status())
|
||||
break;
|
||||
|
||||
if (it->err)
|
||||
{
|
||||
#ifdef DBG
|
||||
@ -347,24 +353,55 @@ const char* TEstrazione::diagnostica_mov()
|
||||
if (!bar.add_status())
|
||||
break;
|
||||
//TToken_string& row = *it;
|
||||
movimento_t& row = *it;
|
||||
TString numreg(row.numreg);
|
||||
movimento_t& mov_i = *it;
|
||||
TString numreg(mov_i.numreg);
|
||||
TLocalisamfile mov(LF_MOV);
|
||||
mov.put(MOV_NUMREG, numreg);
|
||||
mov.read();
|
||||
// Controllo che abbia il riferimento al documento originale generatore del movimento
|
||||
// todo: modificare controllo in base al flag in configurazione
|
||||
if (mov.get(MOV_DPROVV).empty() || mov.get(MOV_DANNO).empty() || mov.get(MOV_DCODNUM).empty() || mov.get(MOV_DNDOC).empty())
|
||||
|
||||
/* Categorie documentali. Come per gli acquisti. */
|
||||
if (!mov_i.err && mov_i.estratto)
|
||||
{
|
||||
row.err = true;
|
||||
row.descr_err = "Movimento non collegato a un documento originale. Impossibile estrarre. Escludere?";
|
||||
ok &= false;
|
||||
std::shared_ptr<TCategorie_doc::classe_doc> cd = categorie_doc().causcont2cat(mov_i.codcaus);
|
||||
mov_i.estratto = cd.get();
|
||||
mov_i.descr_estr = cd ? movimento_t::no_err : movimento_t::no_catdoc;
|
||||
mov_i.catdoc = cd;
|
||||
}
|
||||
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
|
||||
if (mov_i.catdoc && !mov_i.catdoc->is_cartaceo())
|
||||
{
|
||||
row.err = true;
|
||||
row.descr_err = "Movimento collegato a un documento senza fatturazione elettronica. Escludere?";
|
||||
ok &= false;
|
||||
// Che controlli devo fare per essere sicuro di tirare fuori mov di vendita che siano corretti (sicuramente da estrarre)?
|
||||
// Dovrei essere sicuro che sia un documento che abbia bisogno della fatturazione e che sia stato spedito.
|
||||
// Nel caso in cui la fatturazione/invio/contabilita' venga fatta in Campo/WebApp posso capire se e' una fattura elettronica,
|
||||
// nel caso in cui le fatture vengono fatte da un altro gestionale e importate nella webapp dopo, non ho modo di capire dal mov
|
||||
// se deriva da un vero documento di fatturazione elettronica.
|
||||
// E se il movimento fosse per qualche motivo esente dalla fatturazione elettronica? Nel caso in cui venga fatto in campo avrei
|
||||
// il documento generatore e, o da questo vedo che il numeratore non ha il flag di fattura xml (salto),
|
||||
// o non lo trovo sui paf (devi escludere), ma nell'altro caso non so dir nulla, ma a questo punto io lo estrarrei normalmente, e
|
||||
// poi la WebApp mi darebbe errore, ma io non sono in grado di escludere la fattura al prossimo tentativo.
|
||||
// Possibili soluzioni:
|
||||
// - Fare in modo di escludere anche movimenti che apparentemente sono passati per buoni;
|
||||
// - In corso di estrazione mostrare la lista dei movimenti che sarebbero estratti e casellare quelli da escludere.
|
||||
|
||||
// Controllo che abbia il riferimento al documento originale generatore del movimento solo se non ha flag di vendite esterne
|
||||
if (!_has_vendext)
|
||||
{
|
||||
if (mov.get(MOV_DPROVV).empty() || mov.get(MOV_DANNO).empty() || mov.get(MOV_DCODNUM).empty() || mov.get(MOV_DNDOC).empty())
|
||||
{
|
||||
mov_i.err = true;
|
||||
mov_i.estratto = false;
|
||||
mov_i.descr_estr = movimento_t::no_doc;
|
||||
mov_i.descr_err = "Movimento non collegato a un documento originale. Impossibile estrarre. Escludere?";
|
||||
ok &= mov_i.estratto;
|
||||
}
|
||||
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
|
||||
{
|
||||
mov_i.err = true;
|
||||
mov_i.descr_err = "Movimento collegato a un documento senza fatturazione elettronica. Escludere?";
|
||||
mov_i.estratto = false;
|
||||
mov_i.descr_estr = movimento_t::notfound_elet;
|
||||
ok &= mov_i.estratto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -382,10 +419,26 @@ result_estr TEstrazione::estrai()
|
||||
warning_box("Non esistono movimenti estraibili per il periodo selezionato.");
|
||||
return estr_stop;
|
||||
}
|
||||
if (!_escluso && !_head.flag_prov && !check_periodo_def())
|
||||
if (!_escluso && !_head.flag_prov)
|
||||
{
|
||||
error_box("Attenzione e' stato inserito un periodo che si sovrappone\nad un'estrazione definitiva gia' esistente. Impossibile procedere.");
|
||||
return estr_stop;
|
||||
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...
|
||||
@ -518,6 +571,24 @@ bool TEstrazione::estrazione_iva(bool escluso)
|
||||
return stato;
|
||||
}
|
||||
|
||||
bool TEstrazione::exist_prov() const
|
||||
{
|
||||
TString query; query << "SELECT * FROM " F9_DRD "\n" <<
|
||||
"WHERE " 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 F9RIDES AS ID, F9RUESA AS DATA_A FROM " F9_DRD "\n"
|
||||
"WHERE " DRD_ID_EST " LIKE '%N%' AND " DRD_FLAG_PD " = 'D' AND " DRD_TIPODOC " = '" << _head.tipo_doc << "'\n"
|
||||
"ORDER BY F9RUESA 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)
|
||||
@ -528,7 +599,8 @@ void TEstrazione::set_dates()
|
||||
}
|
||||
|
||||
TEstrazione::TEstrazione(const TString& ambiente, const bool flag_prov, const char tipodoc, const TString& descr,
|
||||
const TString& addrcart, const bool escluso, const TDate* const dal, const TDate* const al) : _descr(descr)
|
||||
const TString& addrcart, const bool escluso, const TDate* const dal, const TDate* const al, const bool has_vendext)
|
||||
: _descr(descr), _has_vendext(has_vendext)
|
||||
{
|
||||
_head.cod_soc = ambiente;
|
||||
_head.flag_prov = flag_prov;
|
||||
@ -642,6 +714,11 @@ TF9_dberr::TF9_dberr()
|
||||
// TCategorie_doc
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TCategorie_doc::classe_doc::is_cartaceo() const
|
||||
{
|
||||
return !opcee.empty();
|
||||
}
|
||||
|
||||
vector<TCategorie_doc::classe_doc>::iterator TCategorie_doc::find(const TString& class_sost, const TString& caus_sost,
|
||||
const TString& op_cee)
|
||||
{
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
TString tipocaus;
|
||||
TString tipomov;
|
||||
TString opcee;
|
||||
|
||||
bool is_cartaceo() const;
|
||||
};
|
||||
private:
|
||||
vector<classe_doc> _rows;
|
||||
@ -88,9 +90,11 @@ struct movimento_t
|
||||
{
|
||||
enum err_mov
|
||||
{
|
||||
no_err, // Estratto normalmente
|
||||
escluso, // Movimento con flag escluso
|
||||
no_catdoc // Nessuna cat. doc. riconosciuta per questo movimento, o non e' una fattura
|
||||
no_err, // Estratto normalmente
|
||||
escluso, // Movimento con flag escluso
|
||||
no_catdoc, // Nessuna cat. doc. riconosciuta per questo movimento, o non e' una fattura
|
||||
no_doc, // Il mov. di vendita non ha un documento generatore
|
||||
notfound_elet // Non trovata fatt. elettronica mov vendita
|
||||
};
|
||||
|
||||
bool err;
|
||||
@ -121,6 +125,10 @@ struct movimento_t
|
||||
return "Il movimemnto e' segnato come escluso. Saltato.";
|
||||
case no_catdoc:
|
||||
return "Nessuna categoria documentale riconosciuta per questo movimento, o non e' una fattura.";
|
||||
case no_doc:
|
||||
return "Il mov. di vendita non ha un documento generatore";
|
||||
case notfound_elet:
|
||||
return "Non trovata fatt. elettronica mov vendita";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
@ -161,9 +169,10 @@ class TEstrazione : public TObject
|
||||
{
|
||||
drd _head;
|
||||
vector<movimento_t> _movs;
|
||||
ofstream* _error_sql;
|
||||
ofstream* _error_sql;
|
||||
bool _escluso;
|
||||
const TString _descr;
|
||||
bool _has_vendext;
|
||||
|
||||
/** Aggiorna stato estrazione. Utilizzato ad esempio dopo la diagnostica per riportare
|
||||
* il nuovo stato sul db.
|
||||
@ -225,6 +234,9 @@ public:
|
||||
* \return true Scrittura sul db senza errori.
|
||||
* \return false Errore scrittura db. */
|
||||
bool estrazione_iva(bool escluso = false);
|
||||
bool exist_prov() const; /**< Controllo che esista per questo stesso periodo una estrazione provvisoria. */
|
||||
/** Controllo se esiste un periodo antecedente a questa estrazione che non e' mai stato estratto definitivamente. */
|
||||
bool gap_periodo() const;
|
||||
|
||||
// Getters
|
||||
TString get_id_estr() const { return _head.id_estr; }
|
||||
@ -242,12 +254,10 @@ public:
|
||||
void set_addrcart(const TString& addrcart) { _head.addr_cart = addrcart; }
|
||||
|
||||
TEstrazione(const TString& ambiente, bool flag_prov, char tipodoc, const TString& descr, const TString& addrcart,
|
||||
bool escluso, const TDate* dal = nullptr, const TDate* al = nullptr);
|
||||
bool escluso, const TDate* dal = nullptr, const TDate* al = nullptr, bool has_vendext = false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class TF9_dberr
|
||||
{
|
||||
TString _str;
|
||||
|
Loading…
x
Reference in New Issue
Block a user