Files correlati : tf0.exe tff.ini Commento : Eliminato il controllo sui nuovi tipi documenti e nature Interno : La natura è già a 4 caratteri bisogna controllare se il database TF<ditta> viene aggiornato.
322 lines
11 KiB
C++
322 lines
11 KiB
C++
#pragma once
|
|
|
|
#include <applicat.h>
|
|
#include <automask.h>
|
|
#include <config.h>
|
|
#include <execp.h>
|
|
#include <golem.h>
|
|
#include <progind.h>
|
|
#include <reputils.h>
|
|
#include <tabutil.h>
|
|
#include <utility.h>
|
|
#include <agasys.h>
|
|
#include <printer.h>
|
|
#include <dongle.h> // dongle()
|
|
#include <odbcrset.h> // Oracle Recset
|
|
|
|
#include <map> // std::map
|
|
|
|
#include "../ve/velib05.h"
|
|
#include "../cg/cglib.h"
|
|
#include "../fe/felib.h"
|
|
|
|
#include "tf0100a.h"
|
|
#include "tfutility.h"
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// Globals
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static XVT_SQLDB _db = NULL; // TFF sqlite db
|
|
enum return_code
|
|
{
|
|
found, // Trovato
|
|
foundcust, // Trovato in trasfatt
|
|
foundidcust,// Trovato ma con id customizzato
|
|
nextmov, // Trovato ma cambiato movimento
|
|
eof, // EOF rmoviva
|
|
eofcust, // EOF trasfatt
|
|
after // File mov su un movimento dopo rispetto a rmoviva
|
|
};
|
|
|
|
// Su DB: X o ''->Da inviare, F->Forzato, I->Inviato, N->Non inviare
|
|
enum filter_fatt
|
|
{
|
|
to_send = 0, // "", "X", "F", "E"
|
|
sent = 1, // "I"
|
|
untouched = 2, // "", "X"
|
|
forced = 3, // "F"
|
|
disabled = 5, // "N"
|
|
err = 4, // "E"
|
|
all = 6 // Nessun controllo
|
|
};
|
|
|
|
#define SHEET_GAP 101
|
|
#define DTE_PROVV "DTE0000001"
|
|
#define DTR_PROVV "DTR0000001"
|
|
#define TOLLARANZA 0.05
|
|
// Flag invio
|
|
#define FLAG_INVIO "X"
|
|
#define FLAG_ERRORE "E"
|
|
#define FLAG_NINVIO "N"
|
|
#define FLAG_FORZATO "F"
|
|
#define FLAG_INVIATO "I"
|
|
#define SPESOMETROBASE "ModuliSirio"
|
|
|
|
#ifndef CARATTERI_SPECIALI
|
|
#define CARATTERI_SPECIALI "àèéìòù°"
|
|
#endif
|
|
|
|
/* Così facendo basta modificare la maschera (e le dichiarazioni di conseguenza)
|
|
* per avere l'inserimento nello sheet corretto */
|
|
enum spesometro_fields{
|
|
_spedita = A_SPEDITA - SHEET_GAP,
|
|
_invio = A_INVIO - SHEET_GAP,
|
|
_forzata = A_FORZATA - SHEET_GAP,
|
|
_numero = A_NUMERO - SHEET_GAP,
|
|
_datareg = A_DATAREG - SHEET_GAP,
|
|
_tipocf = A_TIPOCF - SHEET_GAP,
|
|
_codcf = A_CODCF - SHEET_GAP,
|
|
_occas = A_OCFPI - SHEET_GAP,
|
|
_ragsoc = A_RAGSOC - SHEET_GAP,
|
|
_rfso = A_RFSO - SHEET_GAP,
|
|
_ragsocrfso = A_RAGSOCRFSO - SHEET_GAP,
|
|
_codnum = A_TIPODOC - SHEET_GAP,
|
|
_codnumAE = A_TIPODOCAE - SHEET_GAP,
|
|
_numdoc = A_NUMDOC - SHEET_GAP,
|
|
_datadoc = A_DATADOC - SHEET_GAP,
|
|
_natura = A_NATURA - SHEET_GAP,
|
|
_aliquota = A_ALIQUOTA - SHEET_GAP,
|
|
_detraibile = A_DETRAIB - SHEET_GAP,
|
|
_imponibile = A_IMPONIBILE - SHEET_GAP,
|
|
_importoIVA = A_IMPOSTA - SHEET_GAP, // Imposta è già preso
|
|
_reverse = A_REVERSE - SHEET_GAP,
|
|
_autofatt = A_AUTOFATT - SHEET_GAP,
|
|
_paiv = A_PAIV - SHEET_GAP,
|
|
_codfis = A_COFI - SHEET_GAP,
|
|
_coderr = A_CODERR - SHEET_GAP
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// Utilities
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Da un id ritorna il tipo doc corrispondente
|
|
TString get_tipo_doc(int id);
|
|
int get_tipo_doc(TString id);
|
|
|
|
// Cerca una stringa all'interno di una SLIST (Potrebbe diventare una funzione di XVT.h)
|
|
//static SLIST_ELT xvt_slist_find_str(SLIST list, const char* str);
|
|
// Aggiorna il file dst se più vecchio di src (Potrebbe diventare una funzione di XVT.h)
|
|
//bool xvt_fsys_fupdate(const char* src, const char* dst);
|
|
// Decodifica il tipo di documento per il trasferimento fatture
|
|
const char * decod_tipo(TToken_string & strarr);
|
|
// Salvo un singolo record
|
|
bool save_rec(TToken_string row, bool esportato = false);
|
|
// Ritorno una data in formato ANSI
|
|
inline TDate to_date(const char * date) { return TDate(date).string(); }
|
|
// Salto se la riga non è abilitata
|
|
#define IF_IS_ENABLED(strarr) if(strcmp(strarr->get(_invio), FLAG_INVIO) != 0 && strcmp(strarr->get(_invio), FLAG_FORZATO) != 0 && strcmp(strarr->get(_invio), FLAG_INVIATO) != 0) continue;
|
|
// Ritorno il carattere senza accento maiuscolo
|
|
inline const char * no_special(char a);
|
|
// Ritorno se è ancora valida la bolla doganale senza informazioni fornitore
|
|
bool bd2017();
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// TTrFa_record
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Contenitore di campi di un record di database SQLite
|
|
class TTrFa_record : public TObject
|
|
{
|
|
TString8 _table;
|
|
TToken_string _key;
|
|
TAssoc_array _fields;
|
|
|
|
protected:
|
|
void copy(const TTrFa_record& rec) { _table = rec._table; _key = rec._key; _fields = rec._fields; }
|
|
const TString& var2str(const TString& fld, const TVariant& var) 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 TVariant& get(const char* fld) const;
|
|
|
|
bool insert();
|
|
bool remove();
|
|
bool search();
|
|
bool search(const char* k1, const char* k2 = NULL, const char* k3 = NULL);
|
|
|
|
TObject* dup() const override { return new TTrFa_record(*this); }
|
|
bool ok() const override { return _table.not_empty(); }
|
|
|
|
TTrFa_record& operator=(const TTrFa_record& rec) { copy(rec); return *this; }
|
|
TTrFa_record(const TTrFa_record& rec) { copy(rec); }
|
|
TTrFa_record(const char* table);
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// TTrFa_cursors
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*
|
|
* Classe per la gestione di RMOVIVA, MOV, TFCUST
|
|
*/
|
|
class TTrFa_cursors : TObject
|
|
{
|
|
friend class TCursor;
|
|
TISAM_recordset* _c_rmoviva;
|
|
TISAM_recordset* _c_trasfatt;
|
|
bool _new_mov;
|
|
bool _new_cust;
|
|
// Se trovo un record custom devo saltare tutti quelli che trovo successivamente, per fare ciò utilizzo una TToken_string
|
|
TToken_string _alq_cust;
|
|
bool _esterometro;
|
|
// paf non inviati
|
|
bool _paf_ns;
|
|
// paf inviati
|
|
bool _paf_s;
|
|
// paf sogg. fatt
|
|
bool _paf_sf;
|
|
// paf esteri
|
|
bool _paf_e;
|
|
// paa non inviati
|
|
bool _paa_ns;
|
|
// paa inviati
|
|
bool _paa_s;
|
|
// paa sogg. fatt
|
|
bool _paa_sf;
|
|
// paa esteri
|
|
bool _paa_e;
|
|
|
|
|
|
TRectype _next(return_code& code, TString& tipocf, TString& codcf, TString& ocfpi); // Si sposta avanti di un elemento
|
|
TRectype _next_cust(return_code& code, TString& tipocf, TString& codcf, TString& ocfpi); // Si sposta avanti di un elemento tra quelli custom
|
|
bool check_enabled(TISAM_recordset* orig_cur);
|
|
void reset_esterometro();
|
|
public:
|
|
TTrFa_cursors();
|
|
~TTrFa_cursors();
|
|
long int get_iva_items() const { return _c_rmoviva->items(); }
|
|
long int get_iva_pos() const { return _c_rmoviva->cursor()->pos(); }
|
|
TRectype get_iva() const { return _c_rmoviva->cursor()->curr(); }
|
|
int next(TAssoc_array& recimposte, bool& ok, TString& tipocf, TString& codcf, TString& ocfpi); // Legge tutto il prossimo movimento, in importi mette per ogni codiva la somma
|
|
|
|
int update_filters(const char tipocf, const long codcf, TDate dal, TDate al, int cod = to_send);
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// TTrFa_mask
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class TTrFa_mask : public TAutomask
|
|
{
|
|
friend class TTrFa_cursors;
|
|
|
|
TMaskmode _mode;
|
|
bool _sheet_dirty;
|
|
bool _filter_changed;
|
|
bool _has_fp;
|
|
|
|
protected:
|
|
void next_page(int p) override;
|
|
static TRecnotype nuovo_progr();
|
|
void change_invio(const TString& tipocf, const TString& codcf, const TString& numdoc, const TString& invio) const;
|
|
void update_stato(const TString& da_stato, const TString& a_stato);
|
|
|
|
bool on_field_event(TOperable_field& o, TField_event e, long jolly) override;
|
|
void open_java();
|
|
|
|
public:
|
|
void set_has_fp(const bool has_fp) { _has_fp = has_fp; }
|
|
void set_filter_changed() { _filter_changed = true; }
|
|
void load_sheet();
|
|
TTrFa_mask(const TString& msk);
|
|
~TTrFa_mask();
|
|
// Carico i tipi documento all'inizio
|
|
void load_config();
|
|
// Salvo i tipi documento
|
|
void save_config() const;
|
|
// Salvo tutti i records
|
|
bool save_all() const;
|
|
// Controllo tutti i records
|
|
bool check_all();
|
|
// Testo validità record
|
|
static bool check_rec(TPrinter* stampa, TToken_string* rec);
|
|
// Controllo che siano presenti records
|
|
bool check_not_empty();
|
|
// Controllo finale prima di inviare il tutto, se ci sono fatture
|
|
// con più volte lo stesso codice aliquota disabilito il precedente
|
|
void the_final_check_down();
|
|
// Mette il flag di invio = [flag] per la riga numero [nrow]
|
|
void flag_row(int nrow, const TString& flag);
|
|
// Salto se la riga ha un tipo invio non del filtro
|
|
bool check_invio(const TString& invio) const;
|
|
};
|
|
// Funzione inline di stampa
|
|
inline void print_error(TPrinter* stampa, const TString& movimento, const TString& documento, const TString& msgerr);
|
|
TTrFa_mask& msk();
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// TTrFa_app
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
struct clifo_doc
|
|
{
|
|
long _cont_cli_fo;
|
|
long _count_doc;
|
|
std::map<TString, long> _doc_id;
|
|
};
|
|
|
|
class TTrFa_app : public TSkeleton_application
|
|
{
|
|
TAnagrafica _ditta;
|
|
TString16 _cofi;
|
|
TFilename _dbname;
|
|
TLog_report* _log;
|
|
TString _log_tff;
|
|
bool _append;
|
|
TString _myrfso;
|
|
static long _header;
|
|
// Solitamente nei programmi di campo cerco di sfruttare le classi interne ma per mancanza di tempo sono costretto a usare l'std::vector
|
|
std::map<TString, clifo_doc> _m_cli_doc;
|
|
|
|
private:
|
|
int parse_line(const TString& line, TString& var, TString& val) const;
|
|
bool create_table(TScanner& tff, const TString& table);
|
|
static TString get_key(TToken_string* strarr);
|
|
TString get_header(TToken_string* strarr);
|
|
TString get_body(TToken_string* strarr, bool add = true);
|
|
bool tff0100(TSheet_field& sheet); // Header esportazione
|
|
bool tff0200(const TString& key); // Anagrafica ditta
|
|
bool tff0300(TString key, TRectype r_ana); // Rappresentante fiscale ditta
|
|
bool tff0400(TSheet_field& sheet); // Anagrafica clifo
|
|
bool tff0700(TSheet_field& sheet); // Testata documento
|
|
bool tff2200(TToken_string* strarr, int nriga); // Riepilogo aliquote
|
|
bool tff3100(TToken_string* strarr, TRectype r_ana); // Rappresentante fiscale clifo
|
|
bool set_esportato(TSheet_field& sheet);
|
|
bool empty_tables(TString key); // Cancella da tutte le tabelle i record con chiave key
|
|
|
|
protected:
|
|
void log(int severity, const char* msg);
|
|
bool display_log();
|
|
bool syncronize_db();
|
|
bool verify_db(const bool create);
|
|
bool copy_ssa();
|
|
|
|
public:
|
|
bool create() override;
|
|
bool destroy() override;
|
|
void main_loop() override;
|
|
static bool is_new_tipodoc(const TString& tipodoc);
|
|
static bool is_new_natura(const TString& natura);
|
|
static bool check_new_codici_fp(const TSheet_field& sheet);
|
|
bool send(TTrFa_mask* msk);
|
|
|
|
TTrFa_app() : _log(nullptr) {}
|
|
}; |