497 lines
13 KiB
C++
497 lines
13 KiB
C++
#include <applicat.h>
|
||
#include <automask.h>
|
||
#include <config.h>
|
||
#include "fplib.h"
|
||
#include <progind.h>
|
||
#include <cfven.h>
|
||
#include <doc.h>
|
||
|
||
#include "../ve/velib05.h"
|
||
#include "../cg/cglib03.h"
|
||
#include "../fe/felib.h"
|
||
|
||
#include "fp0.h"
|
||
#include "fp0500a.h"
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// Globals
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
#define LEN_HFATT 20
|
||
#define LEN_BFATT 50
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// TMancati_mask
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
class TMancati_mask : public TAutomask
|
||
{
|
||
protected:
|
||
enum {_codnum, _tipodoc, _dastato, _astato, _tiposdi};
|
||
|
||
void set_filter_changed();
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
void next_page(int p);
|
||
bool check_not_empty();
|
||
bool check_full_fields() const;
|
||
bool check_doc_filter(const TDocumentoEsteso& td) const;
|
||
void fill();
|
||
|
||
void load_all_fields();
|
||
|
||
bool _filter_changed;
|
||
|
||
public:
|
||
TMancati_mask() : TAutomask("fp0500a"), _filter_changed(true)
|
||
{
|
||
disable(DLG_OK);
|
||
load_all_fields();
|
||
}
|
||
void save_all_fields() const;
|
||
};
|
||
|
||
void TMancati_mask::save_all_fields() const
|
||
{
|
||
ini_set_string(CONFIG_DITTA, "fp", "dataini", get(F_DATAINI));
|
||
ini_set_string(CONFIG_DITTA, "fp", "dataend", get(F_DATAEND));
|
||
|
||
// Salvo lo sheet
|
||
TFP_selected_docs selected_docs;
|
||
selected_docs.save_sheet(sfield(F_DOCUMENTI_TIPO));
|
||
}
|
||
|
||
void TMancati_mask::load_all_fields()
|
||
{
|
||
set(F_DATAINI, ini_get_string(CONFIG_DITTA, "fp", "dataini"));
|
||
set(F_DATAEND, ini_get_string(CONFIG_DITTA, "fp", "dataend"));
|
||
|
||
const TToken_string s_accepted_docs(ini_get_string(CONFIG_DITTA, "fp", "accepted_docs"), ';');
|
||
//
|
||
auto& sheet = sfield(F_DOCUMENTI_TIPO);
|
||
sheet.hide();
|
||
|
||
TFP_selected_docs selected_docs;
|
||
|
||
if (selected_docs.has_selected_docs())
|
||
{
|
||
// Super nuova gestione super avanzata!
|
||
selected_docs.fill_sheet(sheet);
|
||
}
|
||
else if(s_accepted_docs.full())
|
||
{
|
||
// Nuova gestione avanzata!
|
||
FOR_EACH_STR_TOKEN(s_accepted_docs, tok)
|
||
{
|
||
TToken_string& row = sheet.row(-1);
|
||
row.add(tok);
|
||
row.add(TTipo_documento(TToken_string(tok).get(1)).tipo_doc_sdi());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Vecchia gestione ):
|
||
const TString& codnum = ini_get_string(CONFIG_DITTA, "fp", "codnum");
|
||
TToken_string tipidocs(ini_get_string(CONFIG_DITTA, "fp", "tipodocs"));
|
||
FOR_EACH_STR_TOKEN(tipidocs, tok)
|
||
{
|
||
TToken_string& row = sheet.row(-1);
|
||
row.add(codnum);
|
||
row.add(tok);
|
||
// Considero 1 e 9 come stati default?
|
||
row.add(1);
|
||
row.add(9);
|
||
row.add(TTipo_documento(tok).tipo_doc_sdi());
|
||
}
|
||
}
|
||
sheet.force_update();
|
||
sheet.show();
|
||
}
|
||
|
||
void TMancati_mask::fill()
|
||
{
|
||
// Salvo subito su file le impostazioni di esportazione, in fplib accedo ai file
|
||
save_all_fields();
|
||
|
||
TSheet_field& docs = sfield(F_DOCS);
|
||
TString_array& sht = docs.rows_array();
|
||
docs.hide();
|
||
|
||
sht.destroy();
|
||
|
||
const TDate dal = get(F_DATAINI);
|
||
const TDate al = get(F_DATAEND);
|
||
|
||
#ifdef DBG
|
||
enable(DLG_OK);
|
||
#else
|
||
enable(DLG_OK, false);
|
||
#endif
|
||
|
||
// Record di controllo per eventuali elaborazioni precedenti
|
||
TString hfatt(LEN_HFATT), bfatt(LEN_BFATT);
|
||
TPaf_record paf0100f("PAF0100F");
|
||
|
||
TString query;
|
||
|
||
query << "USE 33 KEY 3 \n" <<
|
||
"SELECT 33.TIPOCF==\"C\" \n" <<
|
||
"JOIN 20 INTO TIPOCF==TIPOCF CODCF==CODCF \n" <<
|
||
"JOIN 17 TO 33 INTO TIPOCF==TIPOCF CODCF==CODCF \n" <<
|
||
"JOIN %TIP TO 33 ALIAS 400 INTO CODTAB==TIPODOC \n" <<
|
||
"FROM DATADOC=#DADATADOC \n" <<
|
||
"TO DATADOC=#ADATADOC";
|
||
|
||
TISAM_recordset rec(query);
|
||
|
||
rec.set_var("#DADATADOC", dal);
|
||
rec.set_var("#ADATADOC", al);
|
||
|
||
TProgress_monitor pi(rec.items(), nullptr);
|
||
|
||
bool first, show, ask = !((show = (first = true)));
|
||
int fat_no_cod = 0;
|
||
|
||
for (bool okc = rec.move_first(); okc; okc = rec.move_next())
|
||
{
|
||
if (!pi.add_status())
|
||
break;
|
||
const TRectype& doc = rec.cursor()->curr();
|
||
const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
|
||
|
||
// Controllo che la numerazione sia tra quelle giuste
|
||
|
||
// Controllo che il tipo documento sia OK
|
||
if(!check_doc_filter(doc))
|
||
continue;
|
||
|
||
if (!chiave_paf(doc, hfatt, bfatt) || !paf0100f.search(nullptr, hfatt, bfatt) || paf0100f.sq_get("P1_GESTIONE") != "N" && paf0100f.sq_get("P1_ERRINT") != "M")
|
||
{
|
||
continue;
|
||
}
|
||
TToken_string& row = docs.row(-1);
|
||
row = "";
|
||
row.add(rec.get(DOC_ANNO).as_int(), 1);
|
||
row.add(rec.get(DOC_CODNUM).as_string());
|
||
row.add(rec.get(DOC_TIPODOC).as_string());
|
||
row.add(rec.get(DOC_NDOC).as_int());
|
||
row.add(rec.get(DOC_DATADOC).as_date());
|
||
row.add(rec.get(CFV_CODCF).as_int());
|
||
row.add(rec.get("20." CLI_RAGSOC).as_string());
|
||
row.add(rec.get("20." CLI_COFI).as_string());
|
||
|
||
row.add(rec.get("20." CLI_DOCMAIL).as_string()); // Indirizzo email
|
||
row.add(rec.get("20." CLI_BYMAIL).as_string()); // Consenso invio email
|
||
}
|
||
|
||
docs.force_update();
|
||
docs.show();
|
||
}
|
||
|
||
void TMancati_mask::set_filter_changed()
|
||
{
|
||
_filter_changed = true;
|
||
}
|
||
|
||
bool TMancati_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case DLG_RECALC:
|
||
if (e == fe_button)
|
||
next_page(1);
|
||
break;
|
||
case F_DATAINI:
|
||
if (e == fe_init)
|
||
o.set(ini_get_string(CONFIG_DITTA, "fp", "LastXML", "01-01-2019"));
|
||
else if (e == fe_close)
|
||
ini_set_string(CONFIG_DITTA, "fp", "LastXML", o.get());
|
||
break;
|
||
case F_DATAEND:
|
||
if (e == fe_init)
|
||
o.set(TDate(TODAY));
|
||
case F_DOCS:
|
||
if (e == se_query_add || e == se_query_del)
|
||
return false;
|
||
break;
|
||
case DLG_ALL:
|
||
{
|
||
if (e == fe_button)
|
||
{
|
||
TSheet_field& docs = sfield(F_DOCS);
|
||
TString_array& sht = docs.rows_array();
|
||
const int items = sht.items();
|
||
|
||
if (items > 0)
|
||
{
|
||
const TString4 select = *(sht.row(0).get(0)) == 'X' ? "" : "X";
|
||
for (int i = 0; i < items; i++)
|
||
sht.row(i).add(select, 0);
|
||
docs.force_update();
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
if((e == fe_modify || e >= se_enter) && jolly == 0)
|
||
{
|
||
if (o.dlg() >= START_MASK && o.dlg() <= END_MASK)
|
||
{
|
||
set_filter_changed();
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TMancati_mask::next_page(int p)
|
||
{
|
||
bool ok = true;
|
||
if (_filter_changed && p != 1000)
|
||
{
|
||
if ((ok = _filter_changed = check_full_fields()))
|
||
{
|
||
TSheet_field& sf = sfield(F_DOCS);
|
||
fill();
|
||
_filter_changed = false;
|
||
}
|
||
}
|
||
if(ok)
|
||
TAutomask::next_page(p);
|
||
}
|
||
|
||
bool TMancati_mask::check_not_empty()
|
||
{
|
||
TSheet_field& sheet = sfield(F_DOCS);
|
||
TString msg;
|
||
|
||
if (sheet.empty())
|
||
msg = "La tabella dei movimenti <20> vuota, vuoi caricarla con i filtri selezionati?";
|
||
else if (_filter_changed)
|
||
msg = "I filtri sono stati cambiati, vuoi ricaricare la tabella con i nuovi filtri selezionati?";
|
||
|
||
if (msg.full() && yesno_box(msg))
|
||
{
|
||
next_page(1);
|
||
}
|
||
return sheet.full();
|
||
}
|
||
|
||
bool TMancati_mask::check_full_fields() const
|
||
{
|
||
// Controllo ogni campo che sia valorizzato
|
||
FOR_EACH_MASK_FIELD(*this, i, f)
|
||
{
|
||
if (!f->on_key(K_ENTER))
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TMancati_mask::check_doc_filter(const TDocumentoEsteso& d) const
|
||
{
|
||
const TString codnum = d.get(DOC_CODNUM);
|
||
const TString tipodoc = d.get(DOC_TIPODOC);
|
||
const char stato = d.stato();
|
||
const TTipo_documento& td = cached_tipodoc(d.get(DOC_TIPODOC));
|
||
// Mi precarico la tabella dei documenti scelti
|
||
FOR_EACH_SHEET_ROW(sfield(F_DOCUMENTI_TIPO), nr, row)
|
||
{
|
||
if (codnum.compare(row->get(_codnum)) == 0 && // Codice numerazione
|
||
tipodoc.compare(row->get(_tipodoc)) == 0 && // Tipo documento
|
||
td.reg_fisc().full() && // Regime fiscale
|
||
row->get_char(_dastato) <= stato && // Da stato
|
||
row->get_char(_astato) >= stato) // A stato
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// TMancati_app
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
class TMancati_app : public TSkeleton_application
|
||
{
|
||
int _anno;
|
||
TString16 _codnum, _tipodoc;
|
||
long _ndoc, _codcf;
|
||
char _tipocf;
|
||
|
||
void set_next_pdf(const int anno, const TFixed_string& codnum, const TFixed_string& tipodoc, const long ndoc, const long codcf);
|
||
bool get_next_pdf(int anno, long ditta, const char* codnum, long ndoc, long codcf, TFilename& pdf) const override;
|
||
bool get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, TString& subj, TString& text,
|
||
TToken_string& attach, short& ui) const override;
|
||
bool get_mail_address(TToken_string& to, TToken_string& cc) const;
|
||
|
||
public:
|
||
virtual bool create();
|
||
|
||
virtual bool destroy();
|
||
virtual void main_loop();
|
||
|
||
TMancati_app() {}
|
||
};
|
||
|
||
void TMancati_app::main_loop()
|
||
{
|
||
TMancati_mask mask;
|
||
while (mask.run() == K_ENTER)
|
||
{
|
||
TString_array& sht = mask.sfield(F_DOCS).rows_array();
|
||
TFp_mail_sender mail_sender;
|
||
|
||
FOR_EACH_ARRAY_ROW(sht, r, riga)
|
||
{
|
||
//if (!pi.add_status(1))
|
||
//break;
|
||
|
||
if (riga->starts_with("X"))
|
||
{
|
||
const int anno = riga->get_int(mask.sfield(F_DOCS).cid2index(S_ANNO));
|
||
const long ndoc = riga->get_long(mask.sfield(F_DOCS).cid2index(S_NDOC));
|
||
const TFixed_string codnum(riga->get(mask.sfield(F_DOCS).cid2index(S_CODNUM)));
|
||
const TFixed_string tipodoc(riga->get(mask.sfield(F_DOCS).cid2index(S_TIPODOC)));
|
||
const long codcf = riga->get_long(mask.sfield(F_DOCS).cid2index(S_CLIENTE));
|
||
|
||
|
||
mail_sender.set_doc(anno, ndoc, codnum, tipodoc, codcf);
|
||
mail_sender.send();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TMancati_app::create()
|
||
{
|
||
open_files(LF_TAB, LF_TABCOM, LF_TABMOD, LF_ANAG,
|
||
LF_CLIFO, LF_CFVEN, LF_CFBAN, LF_NDITTE,
|
||
LF_DOC, LF_RIGHEDOC, 0);
|
||
|
||
TRectype cfven(LF_CFVEN);
|
||
if (cfven.length(CFV_PADESTIN) != 7) // Nuova lunghezza per privati
|
||
return error_box(TR("Database non convertito per fatturazione F.P."));
|
||
|
||
return check_tables() && TSkeleton_application::create();
|
||
|
||
}
|
||
|
||
void TMancati_app::set_next_pdf(const int anno, const TFixed_string& codnum, const TFixed_string& tipodoc, const long ndoc, const long codcf)
|
||
{
|
||
_anno = anno;
|
||
_codnum = codnum;
|
||
_ndoc = ndoc;
|
||
_tipodoc = tipodoc;
|
||
_tipocf = 'C';
|
||
_codcf = codcf;
|
||
}
|
||
|
||
bool TMancati_app::get_next_pdf(int anno, long ditta, const char* codnum, long ndoc, long codcf, TFilename& pdf) const
|
||
{
|
||
bool ok = false;
|
||
if (_anno > 0 && _codnum.full() && _ndoc > 0 && _codcf > 0)
|
||
ok = TSkeleton_application::get_next_pdf(_anno, ditta, _codnum, _ndoc, _codcf, pdf);
|
||
return ok;
|
||
}
|
||
|
||
|
||
bool TMancati_app::get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn,
|
||
TString& subj, TString& text, TToken_string& attach, short& ui) const
|
||
{
|
||
bool ok = TApplication::get_next_mail(to, cc, ccn, subj, text, attach, ui);
|
||
|
||
if (_ndoc > 0L)
|
||
{
|
||
ok = get_mail_address(to, cc);
|
||
if (ok)
|
||
{
|
||
const TDocumento doc('D', _anno, _codnum, _ndoc);
|
||
doc.riferimento(subj);
|
||
if (subj.blank())
|
||
subj = doc.tipo().descrizione();
|
||
subj << ' ' << _ndoc << TR(" del ") << doc.get(DOC_DATADOC)
|
||
<< ' ' << prefix().firm().ragione_sociale();
|
||
|
||
TString saluti = esc(ini_get_string(CONFIG_USER, "Mail", "Signature"));
|
||
if (saluti.full())
|
||
{
|
||
if (saluti.find('\n') < 0 && fexist(saluti))
|
||
{
|
||
TScanner s(saluti);
|
||
while (!s.eof())
|
||
text << s.line() << '\n';
|
||
}
|
||
else
|
||
text << saluti << '\n';
|
||
}
|
||
else
|
||
{
|
||
text << TR("Cordiali Saluti ") << prefix().firm().ragione_sociale();
|
||
}
|
||
text.trim();
|
||
if (to.full())
|
||
ui &= ~0x1; // No user interface
|
||
ui |= 0x2; // Query receipt
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TMancati_app::get_mail_address(TToken_string& to, TToken_string& cc) const
|
||
{
|
||
if (_tipodoc.full())
|
||
{
|
||
const TTipo_documento& tipo = cached_tipodoc(_tipodoc);
|
||
TFilename report; tipo.mail_print_profile(report);
|
||
report = report.name_only();
|
||
|
||
TString8 clifo; clifo.format("%c%06ld", _tipocf, _codcf);
|
||
TISAM_recordset contacts("USE MULTIREL\nFROM COD=BACON FIRST=#CLIFO\nTO COD=BACON FIRST=#CLIFO");
|
||
contacts.set_var("#CLIFO", clifo);
|
||
|
||
TToken_string data;
|
||
for (bool ok = contacts.move_first(); ok; ok = contacts.move_next())
|
||
{
|
||
data = contacts.get("DATA").as_string();
|
||
FOR_EACH_TOKEN(data, tok)
|
||
{
|
||
if (_tipodoc.match(tok, true) || report.match(tok, true))
|
||
{
|
||
const TRectype& rub = cache().get(LF_CONTACT, contacts.get("SECOND").as_int());
|
||
TString80 mail = rub.get("MAIL");
|
||
if (mail.blank())
|
||
mail = rub.get("MAIL2");
|
||
if (mail.full())
|
||
{
|
||
if (to.blank())
|
||
to = mail;
|
||
else
|
||
cc.add(mail);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (to.blank())
|
||
{
|
||
TString8 key; key << _tipocf << '|' << _codcf;
|
||
to = cache().get(LF_CLIFO, key, CLI_DOCMAIL);
|
||
}
|
||
return to.full();
|
||
}
|
||
|
||
bool TMancati_app::destroy()
|
||
{
|
||
fp_db().sq_disconnect();
|
||
return TSkeleton_application::destroy();
|
||
}
|
||
|
||
int fp0500(int argc, char* argv[])
|
||
{
|
||
TMancati_app d2p;
|
||
d2p.run(argc, argv, TR("Elenco Fatture Mancata Consegna"));
|
||
return 0;
|
||
}
|