campo-sirio/src/tf/tf0100b.h
Alessandro Bonazzi e87d605919 Patch level : 12.0 1058
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.
2021-04-22 22:23:28 +02:00

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) {}
};