campo-sirio/src/fp/fp0500.cpp
Simone Palacino 71aad42a8a Patch level : 12.0 740
Files correlati     : fp0500, fplib
Commento            : Aggiunta possibilità di aggiungere nota in piede fattura
2019-03-20 09:41:44 +01:00

471 lines
14 KiB
C++
Raw Blame History

#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
{
int _idx;
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;
friend class TMancati_app;
public:
TMancati_mask() : TAutomask("fp0500a"), _filter_changed(true)
{
disable(DLG_OK);
_idx = -1;
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));
// Salvo messaggio corpo mail
TToken_string msg(get(F_BODYMAIL), '\n');
int idx = 0;
for(const char* row = msg.get(); row; row = msg.get())
fp_settings().set_body_mail(row, idx++);
if(idx < _idx)
{
for(int i=idx; i<_idx; i++)
{
fp_settings().remove_para_ini(idx);
}
}
}
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();
// Carico messaggio corpo mail gi<67> salvato o vuoto se mai inserito
TString msg;
int idx = 0;
for(TString row = fp_settings().get_body_mail(idx); row != "STOpsTOP"; row = fp_settings().get_body_mail(idx))
{
if (idx++ > 0)
msg << '\n';
msg << row;
}
_idx = idx;
set(F_BODYMAIL, msg);
}
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);
TString filter_selected = get(F_FATTSEL);
// 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")
{
continue;
}
if (paf0100f.sq_get("P1_ERREST") == "M" && (
filter_selected.empty() && paf0100f.sq_get("P1_ERRINT") != MANCATA_SEND
|| filter_selected == "S" && paf0100f.sq_get("P1_ERRINT") == MANCATA_SEND
|| filter_selected == "A") )
{
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
row.add(paf0100f.sq_get("P1_ERRINT") == MANCATA_SEND? "X" : "");
}
}
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);
if (curr_page() == 1)
enable(DLG_OK);
else enable(DLG_OK, false);
}
}
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
{
public:
virtual bool create();
virtual bool destroy();
virtual void main_loop();
TMancati_app() {}
};
void TMancati_app::main_loop()
{
////////////////////////////////////////////////////////////////////////////
// TEST PER TDB_recordset
////////////////////////////////////////////////////////////////////////////
TString qq;
qq << "CONNECT(localhost@fp_cortelezzi, fp, fp, MSSQL)\n\
SELECT PZ_TIPOPROT AS TIPO_PROT, YEAR(P7_DATA) AS ANNO, P7_TIPODOC AS[TIPO_SDI], P7_NUMERO AS[NUM_DOC], P7_DATA AS[DATA_DOC], PQ_IMPTOTDOC AS[TOT_DOC], P2_ANADENOMIN AS[RAG_SOC], P2_ANANOME AS NOME, P2_ANACOGNOME AS COGNOME, P2_FISCIVACOD AS[P_IVA], P2_CODFISCALE AS[COD_FISC], P2_FISCIVAPAESE AS[COD_PAESE],\n\
COUNT(PP_ATTACHMENT) AS ATTACHMENT, P1_CODDEST AS[COD_SDI], PU_PEC AS PEC, P1_KEYPRGINVIO AS KEYPROG, P1_KEYHEADERFATT AS KEYHEAD, P1_KEYBODYFATT AS KEYFATT, PZ_TIPOPROT AS[TIPO_PROT], PZ_NUMPROT AS[NUM_PROT], PZ_ANNOPROT AS[ANNO_PROT], PZ_TIPOCF AS[TIPO_CF], PZ_CLIFOR AS[COD_CLIFOR]\n\
FROM PAA0100F PAA01\n\
JOIN PAA0200F PAA02 ON P1_KEYPRGINVIO = P2_KEYPRGINVIO and P1_KEYHEADERFATT = P2_KEYHEADERFATT and P1_KEYBODYFATT = P2_KEYBODYFATT\n\
JOIN PAA0700F PAA07 ON P1_KEYPRGINVIO = P7_KEYPRGINVIO and P1_KEYHEADERFATT = P7_KEYHEADERFATT and P1_KEYBODYFATT = P7_KEYBODYFATT\n\
JOIN PAA2700F PAA27 ON P1_KEYPRGINVIO = PQ_KEYPRGINVIO and P1_KEYHEADERFATT = PQ_KEYHEADERFATT and P1_KEYBODYFATT = PQ_KEYBODYFATT\n\
LEFT JOIN PAA2600F PAA26 ON P1_KEYPRGINVIO = PP_KEYPRGINVIO and P1_KEYHEADERFATT = PP_KEYHEADERFATT and P1_KEYBODYFATT = PP_KEYBODYFATT\n\
LEFT JOIN PAA3200F PAA32 ON P1_KEYPRGINVIO = PU_KEYPRGINVIO and P1_KEYHEADERFATT = PU_KEYHEADERFATT and P1_KEYBODYFATT = PU_KEYBODYFATT\n\
LEFT JOIN FPPRO00F FPPRO ON P1_KEYPRGINVIO = PZ_KEYPRGINVIO and P1_KEYHEADERFATT = PZ_KEYHEADERFATT and P1_KEYBODYFATT = PZ_KEYBODYFATT\n\
WHERE P7_DATA >= '20190301' AND P7_DATA <= '20190315'\n\
GROUP BY YEAR(P7_DATA), P7_TIPODOC, P7_NUMERO, P7_DATA, PQ_IMPTOTDOC, P2_ANADENOMIN, P2_ANANOME, P2_ANACOGNOME, P2_FISCIVACOD, P2_CODFISCALE, P2_FISCIVAPAESE,\n\
P1_CODDEST, PU_PEC, P1_KEYPRGINVIO, P1_KEYHEADERFATT, P1_KEYBODYFATT, PZ_TIPOPROT, PZ_NUMPROT, PZ_ANNOPROT, PZ_TIPOCF, PZ_CLIFOR\n\
ORDER BY PZ_ANNOPROT DESC, PZ_TIPOPROT ASC, PZ_NUMPROT DESC;";
TDB_recordset my_rec(qq, true);
my_rec.set("SELECT * FROM PAA0100F;");
int n = my_rec.items();
my_rec.move_to(0);
TRecordset_column_info info = my_rec.column_info(1);
bool conn = my_rec.is_connected();
int col = my_rec.columns();
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
TMancati_mask mask;
while (mask.run() == K_ENTER)
{
TString_array& sht = mask.sfield(F_DOCS).rows_array();
TFp_mail_sender mail_sender;
const TString& msg = mask.get(F_BODYMAIL);
if ( !mail_sender.set_alleg(fp_settings().get_allega_fat()) )
{
TString msg; msg << "Non <20> possibile allegare alla fattura:\nAllega in fattura disabilitato nelle impostazioni.\n"
<< "Inviare lo stesso la mail\nNotifica Mancata Consegna senza allegato?";
if (!noyes_box(msg)) // Se non sono abilitati gli allegati in fattura avviso e chiedo se procedere lo stesso
continue; // Esco senza inviare (se risponde no)
} // Altrimenti procedo lo stesso con l'invio mail senza pdf
FOR_EACH_ARRAY_ROW(sht, nr, row)
{
const TString mail = row->get(mask.sfield(F_DOCS).cid2index(S_DOCMAIL));
bool accord = TString(row->get(mask.sfield(F_DOCS).cid2index(S_BYMAIL))) == "X";
if (row->starts_with("X") && (mail.blank() || !accord)) {
error_box("Attenzione: c'<27> almeno un cliente senza indirizzo email o senza il consenso per l'invio email.");
break;
}
}
FOR_EACH_ARRAY_ROW(sht, r, riga)
{
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));
const TString mail = riga->get(mask.sfield(F_DOCS).cid2index(S_DOCMAIL));
bool accord = TString(riga->get(mask.sfield(F_DOCS).cid2index(S_BYMAIL))) == "X";
TString ragsoc = riga->get(mask.sfield(F_DOCS).cid2index(S_RAGSOC));
bool sent = TString(riga->get(mask.sfield(F_DOCS).cid2index(S_SENT))) == "X";
mail_sender.set_doc(anno, ndoc, codnum, tipodoc, codcf, mail, accord, ragsoc, sent);
if (mail_sender.send(msg)) {
riga->add("", 0); // Se l'invio avviene con successo sfleggo la riga
riga->add("X", 11); // E segno inviata
}
}
}
}
}
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();
}
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;
}