campo-sirio/src/fp/fplib.h
Simone Palacino bb4c48b9de Patch level : 12.0 854
Files correlati     : fp0.exe fp0400a.msk
Commento            : Aggiunta associazione automatica all'avvio
2019-07-08 11:54:19 +02:00

544 lines
19 KiB
C++

#ifndef __FPLIB_H
#define __FPLIB_H
#include <tsdb.h>
#include <utility.h>
#include <config.h>
#include "../ve/velib05.h"
#include "../fe/felib.h"
#include <reputils.h>
#include <vector>
#include <memory>
#include "cg2103.h"
#include <map>
#define SQL_FLD "sql/"
#define MANCATA_SEND "S" // Se la mail di mancata consegna è già stata inviata P1_ERRINT è segnato con "S"
// Typedef per aiutare a capire cosa sono le chiavi
typedef TString MCodice_riga;
typedef TString MTipo_documento;
class TDoc_fp;
enum { no_pdf = -1, pdf_ok = 0, no_alleg = -2};
bool set_connection(SSimple_query& s);
// Ritorna la connessione al DB paf secondo i parametri impostati nel programma di configurazione
SSimple_query& fp_db();
// Lancia una maschera di password FP
bool run_fp_psw_mask();
// Controlla il livello di patch installato e aggiorna le tabelle se necessario
bool check_tables();
// Compila il numero di documento per la scrittura sui paf
TString& complete_num_fp(const TCodice_numerazione& codnum, const int numdoc);
// Genera la chiave per i paf
bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt);
bool chiave_paf(const TRectype& doc, TString& hfatt, TString& bfatt);
// Ritorna cod sdi, pec o vuoto. Chiama get_coddest()
TString get_dest_sdi(const char tipocf, const long codcf);
// Valorizza codice sdi e pec in base alle configurazioni del monitor
bool get_coddest(const char tipocf, const long codcf, TString& coddest, TString& pec);
const TString& tipo_doc_sdi(const TDocumento& doc);
// Controlli comuni
bool is_fattura(const TRectype& doc);
// Si potrebbe standardizzare in TISAM_recordset
TString& add_filter(const TString& field, const TString& from, const TString& to);
// Contenitore di campi di un record di database MSSQLServer
class TPaf_record : public TObject
{
TString8 _table;
TToken_string _key;
TAssoc_array _fields;
protected:
void copy(const TPaf_record& rec)
{
_table = rec._table;
_key = rec._key;
_fields = rec._fields;
}
const TString& var2str(const TString& fld, const TVariant& var) const;
const TVariant& get(const char* fld) const;
public:
void reset() { _fields.destroy(); }
void set(const char* fld, const TVariant& var);
void set(const char* fld, long var);
void set(const char* fld, const char* var);
void set(const char* fld, const real& var);
void set(const char* fld, const TString& var);
void set(const char* fld, const TDate& var);
void set(const char* fld, bool var);
const TString sq_get(const char* fld) const;
bool is_full() const { return _fields.items() > _key.items(); }
const TString& get_table() const { return _table; }
TString& insert_string();
bool insert();
TString& remove_string(bool id_riga = false);
bool remove();
bool search();
bool search(const char* k1, const char* k2, const char* k3 = NULL);
virtual TObject* dup() const { return new TPaf_record(*this); }
virtual bool ok() const { return _table.not_empty(); }
TPaf_record& operator=(const TPaf_record& rec)
{
copy(rec);
return *this;
}
TPaf_record() { };
TPaf_record(const TPaf_record& rec) { copy(rec); }
TPaf_record(const char* table);
};
class TPaf_container : public TObject
{
std::map<const char *, TPaf_record> _pafs;
static const char* paf_to_prefix(const char * paf);
public:
TPaf_record& get_paf(const char * paf);
bool clean_and_erase_paf(const TString& hfatt, const TString& bfatt);
static void set_keys_paf(TPaf_record& paf, const TString& hfatt, const TString& bfatt, const bool reset = true);
TPaf_container();
};
class TFP_nota_piede_f
{
std::map<TString, TString> _nota_piede_fattura;
bool _loaded;
TToken_string _tipi_doc; // Array di stringhe dei tipi doc caricati (per capire se ne elimino)
const TString _null_string;
static void write_ini_npf(const TString& tipodoc, TToken_string& msg); // Salva sul file ini la n.p.f. di quel tipodoc
static void delete_ini_npf(const TString& tipodoc); // Rimuove i tipidoc in eccesso (quando si modifica lo spreadsheet)
static TString get_ini_npf(const TString& tipodoc); // Legge dal file ini e restituisce la n.p.f. di quel tipodoc
void get_load(); // Carica la mappa
void save_npf_spredsheet(TSheet_field& sheet_field);
void save_new_tipidoc(TSheet_field& sheet_field);
public:
void load_sheet(TSheet_field& sheet_field);
void save_sheet(TSheet_field& sheet_field);
const TString& get_nota_piede(const TString& tipo_doc);
TFP_nota_piede_f();
};
class TFP_settings : public TObject
{
public:
// Getters
const TString& get_db_indirizzo() const;
const TString& get_db_database() const;
const TString& get_db_str_con() const;
const TString& get_db_user() const;
const TString& get_db_password() const;
const TString& get_fld_dest() const;
const TString& get_fld_dest_usr() const;
const TString& get_cofi_tras() const;
const TString& get_data_start_fatt() const;
const bool get_gest_alleg() const;
const bool get_allega_fat() const;
const bool get_esp_pri_empty() const;
const bool get_esp_est() const;
const TString& get_esp_est_cod() const;
const bool is_f8() const;
const bool get_check_not_block() const;
const TString& get_body_mail(int idx = -1) const;
const TString& get_npf(const char* tipodoc, int idx) const;
const bool get_no_sconti_fatt() const;
bool get_no_export_pronto() const;
// Get tipidoc per NotaPiedeFattura
const TString get_npf_tipodoc(int indx) const;
// Setters
void set_db_indirizzo(const TString& ind) const;
void set_db_database(const TString& db) const;
void set_db_user(const TString& usr) const;
void set_db_password(const TString& psw) const;
void set_fld_dest(const TString& fld_dest) const;
void set_fld_dest_usr(const TString& fld_dest_usr) const;
void set_cofi_tras(const TString& cofi) const;
void set_gest_alleg(bool gest_alleg) const;
void set_allega_fat(bool allega_fatt) const;
void set_esp_pri_empty(bool esp_pri) const;
void set_esp_est(bool esp_est) const;
void set_esp_est_cod(const TString& esp_est_cod) const;
void set_f8(bool f8) const;
void set_check_not_block(bool not_block) const;
void set_body_mail(const char* msg, int idx = -1) const;
void set_no_sconti_fatt(const bool no_sconti_fatt) const;
void set_no_export_pronto(const bool no_export_pronto) const;
void set_data_start_fatt(const char* date) const;
void set_npf(const char * tipodoc, const char* msg, int idx) const;
void set_npf_tipodoc(const TString& tipodoc, int indx) const;
void remove_para_ini(int idx);
void remove_npf_ini(const char* tipodoc, int idx);
void remove_tipodoc_npf(int idx) const;
};
inline TFP_settings& fp_settings()
{
static TFP_settings* erbuggo = nullptr;
if(erbuggo == nullptr)
{
erbuggo = new TFP_settings();
}
return *erbuggo;
}
// Mannaggia il fruttivendolo
class TFP_righe_custom : public TObject
{
bool _loaded;
struct TCustCol
{
TString _col_qta;
// Le colonne prezzo e imp non sono lette se di default
TString _col_prezzo;
TString _col_imponibile;
TString _col_nota_piede;
};
// Mappa con in chiave COD_RIGA, TIPO_DOC
std::map<MCodice_riga, std::map<MTipo_documento, TCustCol>> _custom_table;
void load_map();
static TCustCol& get_no_custom();
TCustCol& get(const TString& codriga, const TString& tipodoc);
public:
static void save_sheet(TSheet_field& sheet_field);
static void load_sheet(TSheet_field& sheet_field);
const TString& get_qta(const TString& codriga, const TString& tipodoc) { return get(codriga, tipodoc)._col_qta; }
const TString& get_prezzo(const TString& codriga, const TString& tipodoc) { return get(codriga, tipodoc)._col_prezzo; }
const TString& get_imponibile(const TString& codriga, const TString& tipodoc) { return get(codriga, tipodoc)._col_imponibile; }
TFP_righe_custom();
};
class TFP_selected_docs : public TObject
{
TRelation _r_tabmod;
TRectype _flt;
std::unique_ptr<TCursor> _cur;
TRectype fill_rectype() const;
enum { _codnum, _tipodoc, _dastato, _astato, _tiposdi };
public:
void fill_sheet(TSheet_field& sheet) const;
inline bool has_selected_docs() const { return _cur->items() > 0; }
void save_sheet(const TSheet_field& sheet) const;
TFP_selected_docs();
};
class TFp_mail_sender : public TObject
{
int _anno;
TString16 _codnum;
const TTipo_documento* _tipodoc;
long _ndoc;
long _codcf;
TString _mail;
TString _pdf_path;
TString _pdf_name;
bool _alleg;
bool _accord;
TString _ragsoc;
int _error;
bool _sent;
public:
void set_doc(const int anno, const long ndoc, const TFixed_string& codnum, const TFixed_string& tipodoc, const long codcf, TString mail, bool accord, TString ragsoc, bool sent);
bool genera_pdf();
bool send(const TString& msg);
bool get_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, TString& subj, TString& text, TToken_string& attach, short& flags);
bool spotlite_send_mail(const TFilename& pdf, const TString& msg);
bool spotlite_send_mail(const TString& msg);
bool set_alleg(const bool allega_fat);
TFp_mail_sender() { _error = -1; }
TFp_mail_sender(const int anno, const long ndoc, const TFixed_string& codnum, const TFixed_string& tipodoc, const long codcf, TString mail, bool accord, TString ragsoc, bool sent)
{ set_doc(anno, ndoc, codnum, tipodoc, codcf, mail, accord, ragsoc, sent); }
};
class TFPRiga_documento : public TRiga_documento
{
public:
real prezzo(bool scontato, bool lordo, int ndec = AUTO_DECIMALS) const;
real imponibile(const bool lordo) const;
real quantita() const;
TString& quantita_string() const;
TFPRiga_documento(const TRiga_documento& rd) : TRiga_documento(rd) {}
};
#define FOR_EACH_PHYSICAL_FPRDOC(__doc, __r, __rdoc) TFPRiga_documento* __rdoc=NULL; \
TRecord_array& bodyof##__rdoc = (__doc).body(); \
for (int __r = bodyof##__rdoc.first_row(); bodyof##__rdoc.exist(__r) && (__rdoc=&(TFPRiga_documento&)bodyof##__rdoc.row(__r))!=NULL; __r=bodyof##__rdoc.succ_row(__r))
/***********************************************************************************************************************************************************************
* PERSONALIZZAZIONI FP
***********************************************************************************************************************************************************************/
struct TFP_row_art
{
TString _codice_tipo;
TString _codice_valore;
TFP_row_art(const TString& codice_tipo, const TString& codice_valore) : _codice_tipo(codice_tipo), _codice_valore(codice_valore) {}
};
struct TFP_adg
{
TString _tipo_dato;
TString _riferimento_testo;
int _riferimento_numero;
TDate _riferimento_data;
TFP_adg(const TString& tipo_dato, const TString& riferimento_testo, const int riferimento_numero,
const TDate& riferimento_data)
: _tipo_dato(tipo_dato),
_riferimento_testo(riferimento_testo),
_riferimento_numero(riferimento_numero),
_riferimento_data(riferimento_data){}
};
/**<
* Classe per la gestione di personalizzazioni FP
*/
class TFP_custom : public TMultiple_rectype
{
protected:
TString _codcust;
TString_array _causale;
vector<TFP_row_art> _articoli;
vector<TFP_adg> _altri_dati_gestionali;
bool _loaded;
void init();
int write_rewrite(TBaseisamfile& f, bool re = FALSE) const override;
bool load(const char* codcust);
public:
bool set_codcust(const char* codcust, const bool to_load) { return to_load ? load(codcust) : _codcust = codcust; }
const TString& get_codcust() const { return _codcust; }
void autoload(const TSheet_field& sf, const int file) const;
bool load_caus_paf(TPaf_record& paf3400f, TDocumento& doc, TDoc_fp& doc_fp) const;
bool load_articolo_paf(TPaf_record& paf1900f, TRiga_documento& rdoc, const long row_num, TDoc_fp& doc_fp) const;
bool load_adg_paf(TPaf_record& paf2100f, TRiga_documento& rdoc, TDoc_fp& doc_fp, const long row_num, const bool split = false) const;
bool has_adg_split();
TFP_custom();
explicit TFP_custom(const TRectype& rec);
explicit TFP_custom(const char* codcust);
};
#define FOR_EACH_FPCAUS_ROW(__fpcust, __r, __rcaus) TRectype* __rcaus=NULL; \
TRecord_array& bodyof##__rcaus = (__fpcust).body(LF_FPCCAUS); \
for (int __r = bodyof##__rcaus.first_row(); bodyof##__rcaus.exist(__r) && (__rcaus=&(TRectype&)bodyof##__rcaus.row(__r))!=NULL; __r=bodyof##__rcaus.succ_row(__r))
#define FOR_EACH_FPART_ROW(__fpcust, __r, __rart) TRectype* __rart=NULL; \
TRecord_array& bodyof##__rart = (__fpcust).body(LF_FPCART); \
for (int __r = bodyof##__rart.first_row(); bodyof##__rart.exist(__r) && (__rart=&(TRectype&)bodyof##__rart.row(__r))!=NULL; __r=bodyof##__rart.succ_row(__r))
#define FOR_EACH_FPADG_ROW(__fpcust, __r, __radg) TRectype* __radg=NULL; \
TRecord_array& bodyof##__radg = (__fpcust).body(LF_FPCADG); \
for (int __r = bodyof##__radg.first_row(); bodyof##__radg.exist(__r) && (__radg=&(TRectype&)bodyof##__radg.row(__r))!=NULL; __r=bodyof##__radg.succ_row(__r))
class TFP_custom_cache
{
std::map<TString, TFP_custom> _customs;
std::map<long, TString> _cli_custom;
std::unique_ptr<TFP_custom> _global_custom;
public:
bool has_custom(const TDocumento& doc);
TFP_custom& get_custom(const TDocumento& doc);
TFP_custom_cache();
};
inline TFP_custom_cache& cached_custom_fp()
{
static std::shared_ptr<TFP_custom_cache> carmelo;
if(carmelo == nullptr)
{
carmelo.reset(new TFP_custom_cache);
}
return *carmelo;
}
class TFP_expression : public TObject
{
private:
enum TFP_operator { error, eq, neq, gt, ls, gteq, lseq, and, or };
// Etrattori
static void extract_info(const TString& expr, TString& tabella, TString& campo);
static void extract_info(const TString& expr, TString& tabella, TString& campo, TToken_string& search, int& key);
static bool calc_table(const TString& tabella, int& file);
static void split_condition(const TString& cond, TString& cond_sx, TString& cond_dx, TFP_operator& symb);
static TVariant& get_value(const TRectype& rec, const TString& campo);
static TVariant& parse_var(const TString& str);
// Calcolatori
static TVariant& parse_read(const TString& str, TRiga_documento& rdoc);
static TVariant& do_read(const TString& tabella, const TString& campo, TRiga_documento& rdoc);
static TVariant& parse_search(const TString& str, TRiga_documento& rdoc);
public:
static const TVariant parse_expression(const TString& expr, TRiga_documento& rdoc);
static const TVariant parse_expression(const TString& expr, TDocumento& doc) { return parse_expression(expr, doc[1]); }
static bool check_condition(const TString& cond, TRiga_documento& rdoc);
static bool check_condition(const TString& cond, TDocumento& doc) { return check_condition(cond, doc[1]); }
TFP_expression() = default;
virtual ~TFP_expression() = default;
};
// Gestione PAF
class TDoc_fp : public TObject
{
friend class TFP_custom;
private:
TRectype* _doc_rec;
TCli_for _rec_clifo;
TAnagrafica _ditta;
TString16 _cofi;
TFilename _dbname;
TLog_report* _log;
TString _logpaf;
bool _gestioneallegati;
bool _allegafattura;
TString _def_fld;
TString _def_usr_fld;
bool _to_commit;
bool _cache_insert;
vector<TString> _query;
TString8 _hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. o di 7 caratteri per un privato
TString _bfatt; // Codice univoco di 20 caratteri del documento
TString _conai_str;
TString _paese;
bool _enapec;
bool _privato;
TString _coddest;
TString _pec;
TCausale _caus;
bool _is_pa;
bool _has_bolla;
TString _codivadefault;
long _idx_cassa_previdenziale;
long _idx_adg_doc_row; // Indice per la tabella altri dati gestionali della riga
int _num_linea;
int _counter;
TPaf_container _paf_container;
int _count_r_conai;
bool _nascondi_sconti_righe_fatt;
TFP_nota_piede_f _riga_npf;
bool _has_cust;
// Classe interna per gestire righe aggiuntive in riepilogo
class TRiepilogo_agg
{
public:
real imponibile;
real imposta;
TRiepilogo_agg() : imponibile(ZERO), imposta(ZERO) {}
};
std::map<TString, TRiepilogo_agg> _riepilogo_agg;
struct
{
bool _is_valuta_estera{ false }; // Se il documento è in valuta estera
TString4 _cod_val;
real _cambio;
} _doc_cambio;
//int parse_line(const TString& line, TString& var, TString& val) const;
//bool create_table(TScanner& paf, const TString& table);
const TRectype* find_parent_row(const TRectype& rdoc) const;
int find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const;
bool insert(TPaf_record& p);
bool remove(TPaf_record& p);
void reset(TPaf_record& p) const { TPaf_container::set_keys_paf(p, _hfatt, _bfatt); }
bool save_paf();
protected:
/**< Funzioni di controllo */
/**< Controlli di testata, non è const per il calcolo della codizione di pagamento */
bool check_initial(TDocumentoEsteso& doc);
/**< Controllo di riga */
bool check_row(const TRiga_documento& rdoc);
/**< Controllo riepilogo IVA */
bool check_riepilogo(const TDocumentoEsteso& doc, const TRiepilogo_iva& riva);
bool initialize(TDocumentoEsteso& doc);
bool parse_sconto(const TString& formula, TToken_string& sconti) const;
static bool get_bnp_iban(const TString& abi, const TString& cab, int prg, TString& iban);
bool get_bank(TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const;
bool get_bank_presentazione(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const;
bool get_bank_appoggio(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const;
const TString& descrizione(const TRiga_documento& rdoc);
const TRectype& cco(const TRectype& doc) const; // Contratto/Convenzione/Offerta
void log(int severity, const char* msg);
static const char* natura(const TString& codiva);
static const char* get_esigibilita_iva(const TDocumentoEsteso& doc);
void set_IVA(TString codiva, TPaf_record& paf) const;
void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const;
bool add_row_art(long& riga_art, const TString& codice_tipo, const TString& codice_valore, TPaf_record& paf);
bool add_row_alleg(TFilename& file, long& nprogr, TPaf_record& paf);
const TString& converti_prezzo(const real& prezzo) const;
void set_qta_prezzo(TPaf_record& paf1800f, TFPRiga_documento* rdoc) const;
void add_ritenuta(const TDocumentoEsteso& doc, const TSpesa_prest& sp, TPaf_record& paf0700f) const;
bool add_riepilogo_iva(TPaf_record& paf2200f, const TCodiceIVA& cod_iva, const char* eiva, const real& imponibile = ZERO, const real& imposta = ZERO);
bool add_cassa_previdenziale(TRiga_documento& rdoc);
bool export_info_articolo(TFPRiga_documento* rdoc, TPaf_record& paf1900f, TPaf_record& paf2100f, const long riga_xml, const int riga_doc);
const TFirm& get_firm();
bool export_paf0100f();
bool export_paf3200f();
// Record clifo
//void set_rec_clifo(char tipocf, long codcf);
public:
bool doc_to_paf(TDocumentoEsteso& doc);
bool doc_to_paf(const TRectype& rec);
bool doc_to_paf(const TDoc_key& key);
bool doc_to_paf(const TFilename& ini);
bool doc_to_paf();
TRectype& key_to_doc(const TDoc_key& key);
// Mostra il log a fine esecuzione
bool show_log();
int commit();
int force_commit();
void set_cache_insert(const bool v) { _cache_insert = v; }
TDoc_fp();
~TDoc_fp();
};
#endif // __FPLIB_H