#ifndef __FPLIB_H #define __FPLIB_H #include #include #include #include "../ve/velib05.h" #include "../fe/felib.h" #include #include #include #include "cg2103.h" #include #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 _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 _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> _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 _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 _articoli; vector _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 _customs; std::map _cli_custom; std::unique_ptr _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 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 _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 _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