campo-sirio/fe/fe0100.cpp
guy 55a173256f Patch level :
Files correlati     : fe0.exe fe0100a.msk
Ricompilazione Demo : [ ]
Commento            :
Aggiornata comunicazione dati rilevanti in base all'ultima circolare del 16-9-2011


git-svn-id: svn://10.65.10.50/branches/R_10_00@22428 c028cbd2-c16b-5b4b-a496-9718f37d4682
2011-09-26 14:51:44 +00:00

1778 lines
54 KiB
C++
Executable File
Raw Blame History

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <progind.h>
#include <recarray.h>
#include <textset.h>
#include <relation.h>
#include <reputils.h>
#include <validate.h>
#include <alleg.h>
#include <anafis.h>
#include <anagr.h>
#include <attiv.h>
#include <clifo.h>
#include <comuni.h>
#include <mov.h>
#include <nditte.h>
#include <occas.h>
#include <partite.h>
#include <pconti.h>
#include <rmoviva.h>
#include "fe0100a.h"
#include "../cg/cglib01.h"
// Data limite da cui si cominciano a dichiarare anche gli scontrini
const TDate data_limite_scontrini(1,7,2011);
const long INVALID_NUMREG = 9999999L;
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
static const TString& comune_di(const TString& codcom)
{
if (codcom.blank() || codcom.len() != 4)
return EMPTY_STRING;
TString8 key; key << " |" << codcom;
TString& den = get_tmp_string();
den = cache().get(LF_COMUNI, key, COM_DENCOM);
den.cut(40);
den.upper();
return den;
}
static const TString& provincia_di(const TString& codcom)
{
if (codcom.blank() || codcom.len() != 4)
return EMPTY_STRING;
TString8 key; key << '|' << codcom;
return cache().get(LF_COMUNI, key, COM_PROVCOM);
}
///////////////////////////////////////////////////////////
// TContratto
///////////////////////////////////////////////////////////
class TContratto : public TObject
{
TRectype _rec;
protected:
bool importo_annuale(int anno, real& importo, real& imposta) const;
bool importo_figli(int anno, real& importo, real& imposta) const;
public:
virtual bool ok() const { return !_rec.empty(); }
bool totale_annuale(int anno, real& importo, real& imposta) const;
bool init(const TRectype& rec);
TContratto(char tipocf, long codcf, const char* codcont);
TContratto(const TRectype& rec) : _rec(rec) { init(rec); }
};
bool TContratto::importo_annuale(int anno, real& importo, real& imposta) const
{
if (_rec.empty() || anno < 2010)
return false;
// Determina l'indice i [0..3] degli importi del contratto per l'anno richiesto
char fld[] = "I3";
int i = 3;
for (i = 3; i > 0; i--)
{
fld[1] = '0'+i;
const int y = _rec.get_int(fld);
if (y > 0 && y <= anno)
break;
}
// Determina il nome del campo importo corrispondente all'indice i: 0 -> R0; 1 -> R2; 2 -> R4; 3 -> R6
fld[0] = 'R';
fld[1] = '0'+(i*2);
importo = _rec.get_real(fld);
fld[1]++; // Il campo imposta <20> sempre quello successivo a quello dell'importo
imposta = _rec.get_real(fld);
return importo > ZERO;
}
bool TContratto::importo_figli(int anno, real& importo, real& imposta) const
{
const TString& codtab = _rec.get("CODTAB");
const TString& prefix = codtab.left(7);
const TString& suffix = codtab.mid(7);
TString query;
query << "USE &CON SELECT S1=\"" << suffix << '\"'
<< "\nFROM CODTAB=\"" << prefix << '\"'
<< "\nTO CODTAB=\"" << prefix << '\"';
TISAM_recordset recset(query);
importo = imposta = ZERO;
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
const TContratto child(recset.cursor()->curr());
real imp, iva; child.importo_figli(anno, imp, iva);
importo += imp;
imposta += iva;
}
if (importo <= ZERO)
importo_annuale(anno, importo, imposta);
return !importo.is_zero();
}
bool TContratto::totale_annuale(int anno, real& importo, real& imposta) const
{
importo = imposta = ZERO;
if (!_rec.empty() && anno >= 2010)
{
const TString& padre = _rec.get("S1");
if (padre.full())
{
const TString& codtab = _rec.get("CODTAB");
const TContratto master(codtab[0], atol(codtab.mid(1,6)), padre);
master.totale_annuale(anno, importo, imposta);
}
else
importo_figli(anno, importo, imposta);
}
return importo > ZERO;
}
bool TContratto::init(const TRectype& rec)
{
_rec = rec;
if (!_rec.empty())
{
int primo_anno = _rec.get_int("I0");
if (primo_anno < 2010)
{
const TDate inizio = _rec.get("D0");
primo_anno = inizio.year();
if (primo_anno < 2010)
primo_anno = 2010;
_rec.put("I0", primo_anno);
}
real importo = _rec.get("R0");
if (importo <= ZERO)
{
importo = primo_anno > 2010 ? 3000 : 25000;
_rec.put("R0", importo);
}
}
return ok();
}
TContratto::TContratto(char tipocf, long codcf, const char* codcont) : _rec(LF_TABMOD)
{
TString80 key; key.format("%c%6ld%s", tipocf, codcf, codcont);
init(cache().get("&CON", key));
}
///////////////////////////////////////////////////////////
// TAnagrafica
///////////////////////////////////////////////////////////
class TAnagrafica : public TObject
{
char _tipo; // F o G
TString16 _cofi, _paiv;
TString _ragsoc;
TString4 _com_nasc, _com_res;
TDate _data_nasc;
int _allegato, _stato_estero;
TAnagrafica(const TAnagrafica&) { CHECK(false, "Can't copy TAnagrafica"); }
public:
virtual bool ok() const { return _tipo=='F' || _tipo == 'G'; }
bool fisica() const { return _tipo == 'F'; }
bool giuridica() const { return _tipo == 'G'; }
const TString& codice_fiscale() const { return _cofi; }
const TString& partita_IVA() const { return _paiv; }
const TString& ragione_sociale() const { return _ragsoc; }
const TString& cognome() const { return _ragsoc.left(24); }
const TString& nome() const { return _ragsoc.mid(30,20); }
char sesso() const { return (_cofi[9] >= '4') ? 'F' : 'M'; }
const TDate& data_nascita() const { return _data_nasc; }
int stato_estero() const { return _stato_estero; }
int inserimento_in_allegato() const { return _allegato; }
const TString& comune_nascita() const { return comune_di(_com_nasc); }
const TString& provincia_nascita() const { return provincia_di(_com_nasc); }
const TString& comune_residenza() const { return comune_di(_com_res); }
const TString& provincia_residenza() const { return provincia_di(_com_res); }
bool init(const TRectype& rec);
bool init(int num, const TString& codice) { return init(cache().get(num, codice)); }
bool init(int num, long codice) { return init(cache().get(num, codice)); }
bool init(int num, char tipo, long codice);
bool init(char tipo, long codice, const TString& ocfpi);
TAnagrafica() : _tipo('\0') {}
TAnagrafica(int lognum, const TString& codice) { init(lognum, codice); }
TAnagrafica(int lognum, long codice) { init(lognum, codice); }
TAnagrafica(int lognum, char tipo, long codice) { init(lognum, tipo, codice); }
TAnagrafica(char tipo, long codice, const TString& ocfpi) { init(tipo, codice, ocfpi); }
TAnagrafica(const TRectype& rec) { init(rec); }
};
bool TAnagrafica::init(const TRectype& rec)
{
_tipo = '\0';
_stato_estero = 0;
_allegato = 0;
if (rec.empty())
return false;
switch (rec.num())
{
case LF_OCCAS:
_tipo = 'F';
_cofi = rec.get(OCC_COFI);
_paiv = rec.get(OCC_PAIV);
if (_cofi.blank() || _paiv.blank())
{
const TString& codice = rec.get(OCC_CFPI);
if (_cofi.blank() && cf_check("", codice))
_cofi = codice;
if (_paiv.blank() && pi_check("", codice))
_paiv = codice;
}
_ragsoc = rec.get(OCC_RAGSOC); _ragsoc.upper();
_data_nasc = rec.get(OCC_DNASC);
_com_nasc = rec.get(OCC_COMNASC);
_com_res = rec.get(OCC_COM);
_stato_estero = rec.get_int(OCC_STATO);
_allegato = _paiv.blank() ? 6 : 2;
break;
case LF_ANAG:
_tipo = rec.get_char(ANA_TIPOA);
_ragsoc = rec.get(ANA_RAGSOC); _ragsoc.upper();
_cofi = rec.get(ANA_COFI);
_paiv = rec.get(ANA_PAIV);
// Comune di residenza fiscale o domicilio
_com_res = rec.get(ANA_COMRF);
if (_com_res.empty())
_com_res = rec.get(ANA_COMRES);
// Dati di nascita persone fisiche
if (_tipo == 'F')
{
const TRectype& anafis = cache().get(LF_ANAGFIS, rec.get_long(ANA_CODANAGR));
_data_nasc = anafis.get(ANF_DATANASC);
_com_nasc = anafis.get(ANF_COMNASC);
}
else
_tipo = 'G';
break;
case LF_NDITTE:
{
const bool good = init(LF_ANAG, rec.get_char(NDT_TIPOA), rec.get_long(NDT_CODANAGR));
_ragsoc = rec.get(NDT_RAGSOC); _ragsoc.upper();
return good;
}
break;
case LF_CLIFO:
_tipo = rec.get_char(CLI_TIPOAPER);
if (_tipo == 'F')
init(LF_ANAG, _tipo, rec.get_long(CLI_CODANAGPER));
else
_tipo = 'G';
// Assegno codice fiscale e partita IVA se validi, altrimenti mantengo quelli dell'anagrafica
if (rec.get(CLI_COFI).not_empty())
_cofi = rec.get(CLI_COFI);
if (rec.get(CLI_PAIV).not_empty())
_paiv = rec.get(CLI_PAIV);
// Prevale sempre la ragione sociale del cliente: "Il cliente ha sempre ragione".
_ragsoc = rec.get(CLI_RAGSOC); _ragsoc.upper();
_stato_estero = rec.get_int(CLI_STATOCF);
_allegato = rec.get_int(CLI_ALLEG);
break;
case LF_MOV:
return init(rec.get_char(MOV_TIPO), rec.get_long(MOV_CODCF), rec.get(MOV_OCFPI));
case LF_ALLEG:
return init(rec.get_char(ALL_TIPOCF), rec.get_long(ALL_CODCF), rec.get(ALL_OCFPI));
default:
CHECKD(false, "Record non valido per TAnagrafica ", rec.num());
break;
}
return _tipo == 'F' || _tipo == 'G';
}
bool TAnagrafica::init(int num, char tipo, long codice)
{
TString16 key; key << tipo << '|' << codice;
return init(cache().get(num, key));
}
bool TAnagrafica::init(char tipo, long codice, const TString& ocfpi)
{
bool done = false;
if (ocfpi.full())
done = init(LF_OCCAS, ocfpi);
if (!done)
done = init(LF_CLIFO, tipo, codice);
return done;
}
///////////////////////////////////////////////////////////
// TDati_rilevanti_trc
///////////////////////////////////////////////////////////
#define AN _alfafld
#define CF _alfafld
#define DT _datefld
#define NU _longzerofld
#define PI _alfafld
#define OBBLIG true
class TDati_rilevanti_trc : public TObject
{
int _tipo;
TAS400_recordset* _recset;
protected:
bool add_field(int n, int da, int a, int len, const char* descr, TFieldtypes tipo = AN,
const char* def = NULL, bool required = false);
public:
void create_fields(int tipo, TAS400_recordset& recset);
};
bool TDati_rilevanti_trc::add_field(int n, int da, int a, int len, const char* descr, TFieldtypes tipo,
const char* def, bool required)
{
CHECKD(descr && *descr, "Campo ignoto ", n);
CHECKS(n > 0 && da > 0 && a >= da && a <= 1800 && len == (a-da+1), "Campo inconsistente ", descr);
TString8 name;
name.format("%d.%d", _tipo, n);
bool ok = _recset->create_field(name, da-1, len, tipo, required, def);
CHECKS(ok, "Can't create field ", descr);
return ok;
}
void TDati_rilevanti_trc::create_fields(int tipo, TAS400_recordset& recset)
{
CHECKD(tipo >= 0 && tipo <= 5 || tipo == 9, "Tipo record non valido ", tipo);
_tipo = tipo;
_recset = &recset;
TString4 def; def << _tipo;
add_field(1, 1, 1, 1, "Tipo record", NU, def, OBBLIG);
if (_tipo == 0 || _tipo == 9)
{
add_field( 2, 2, 6, 5, "Codice identificativo fornitura", AN, "ART21", OBBLIG);
add_field( 3, 7, 8, 2, "Codice numerico fornitura", NU, "47", OBBLIG);
add_field( 4, 9, 9, 1, "Tipologia di invio", NU, "0", OBBLIG);
add_field( 5, 10, 26,17, "Protocollo da sostituire", NU);
add_field( 6, 27, 32, 6, "Protocollo documento", NU);
add_field( 7, 33, 48,16, "Codice fiscale", CF, "", OBBLIG);
add_field( 8, 49, 59,11, "Partita IVA", PI);
add_field( 9, 60,119,60, "Denominazione", AN);
add_field(10,120,159,40, "Comune domicilio fiscale", AN);
add_field(11,160,161, 2, "Provincia domicilio fiscale", AN);
add_field(12,162,185,24, "Cognome", AN);
add_field(13,186,205,20, "Nome", AN);
add_field(14,206,206, 1, "Sesso", AN);
add_field(15,207,214, 8, "Data di nascita", DT);
add_field(16,215,254,40, "Comune o stato di nascita", AN);
add_field(17,255,256, 2, "Provincia di nascita", AN);
add_field(18,257,260, 4, "Anno di riferimento", NU);
add_field(19,261,261, 1, "Comunicazione societ<65> incorp.", AN, "0", OBBLIG);
add_field(20,262,265, 4, "Progressivo invio telmatico", NU, "1");
add_field(21,266,269, 4, "Numero totale invii telematici", NU, "1");
add_field(22,270,285,16, "Codice fiscale intermediario", CF);
add_field(23,286,290, 5, "Numero iscrizione C.A.F.", NU);
add_field(24,291,291, 1, "Impegno alla trasmissione", NU, "1");
add_field(25,292,299, 8, "Data dell'impegno", DT);
add_field(26,300,1797,1498, "Filler", AN);
add_field(27,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG);
add_field(28,1799,1800,2,"Caratteri di fine riga", AN, "\r\n");
} else
if (_tipo == 1)
{
add_field(2, 2,17,16, "Codice fiscale", CF, "", OBBLIG);
add_field(3,18,25, 8, "Data dell'operazione", DT);
add_field(4,26,26, 1, "Modalit<EFBFBD> di pagamento", NU, "3", OBBLIG);
add_field(5,27,35, 9, "Importo dovuto", NU);
add_field(6,36,1797,1762, "Filler", AN);
add_field(7,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG);
add_field(8,1799,1800,2,"Caratteri di fine riga", AN, "\r\n");
} else
if (_tipo == 2)
{
add_field( 2, 2,12,11, "Partita IVA", PI, "", OBBLIG);
add_field( 3,13,20, 8, "Data dell'operazione", DT);
add_field( 4,21,35,15, "Numero della fattura", AN);
add_field( 5,36,36, 1, "Modalit<EFBFBD> di pagamento", NU, "1", OBBLIG);
add_field( 6,37,45, 9, "Importo dovuto", NU);
add_field( 7,46,54, 9, "Imposta", NU);
add_field( 8,55,55, 1, "Tipologia dell'operazione", NU, "1", OBBLIG);
add_field( 9,56,1797,1742, "Filler", AN);
add_field(10,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG);
add_field(11,1799,1800,2,"Caratteri di fine riga", AN, "\r\n");
} else
if (_tipo == 3)
{
add_field( 2, 2, 25,24, "Cognome", AN);
add_field( 3, 26, 45,20, "Nome", AN);
add_field( 4, 46, 53, 8, "Data di nascita", DT);
add_field( 5, 54, 93,40, "Comune o stato estero di nascita", AN);
add_field( 6, 94, 95, 2, "Provincia di nascita", AN);
add_field( 7, 96, 98, 3, "Stato estero del domicilio", AN);
add_field( 8, 99,158,60, "Ragione sociale", AN);
add_field( 9,159,198,40, "Citt<EFBFBD> estera della sede legale", AN);
add_field(10,199,201, 3, "Stato estero della sede legale", AN);
add_field(11,202,241,40, "Indirizzo estero della sede legale", AN);
add_field(12,242,249, 8, "Data dell'operazione", DT);
add_field(13,250,264,15, "Numero della fattura", AN);
add_field(14,265,265, 1, "Modalit<EFBFBD> di pagamento", NU, "1", OBBLIG);
add_field(15,266,274, 9, "Importo dovuto", NU);
add_field(16,275,283, 9, "Imposta", NU);
add_field(17,284,284, 1, "Tipologia dell'operazione", NU, "1", OBBLIG);
add_field(18,285,1797,1513, "Filler", AN);
add_field(19,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG);
add_field(20,1799,1800,2,"Caratteri di fine riga", AN, "\r\n");
} else
if (_tipo == 4)
{
add_field( 2, 2,12,11, "Partita IVA", PI);
add_field( 3,13,28,16, "Codice Fiscale", CF);
add_field( 4,29,36, 8, "Data dell'operazione", DT, "", OBBLIG);
add_field( 5,37,51,10, "Numero della Nota di Variazione", AN, "", OBBLIG);
add_field( 6,52,60, 9, "Imponibile Nota di Variazione", NU);
add_field( 7,61,69, 9, "Imposta Nota di Variazione", NU);
add_field( 8,70,77, 8, "Data della Fattura da rettificare", DT, "", OBBLIG);
add_field( 9,78,92,15, "Numero della Fattura da rettificare", AN, "", OBBLIG);
add_field(10,93,93, 9, "Variazione imponib. (Debito/Credito)",AN);
add_field(11,94,94, 9, "Variazione imposta (Debito/Credito)", AN);
add_field(11,95,1797,1703, "Filler", AN);
add_field(12,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG);
add_field(13,1799,1800,2,"Caratteri di fine riga", AN, "\r\n");
} else
if (_tipo == 5)
{
add_field( 2, 2, 25,24, "Cognome", AN);
add_field( 3, 26, 45,20, "Nome", AN);
add_field( 4, 46, 53, 8, "Data di nascita", DT);
add_field( 5, 54, 93,40, "Comune o stato estero di nascita", AN);
add_field( 6, 94, 95, 2, "Provincia di nascita", AN);
add_field( 7, 96, 98, 3, "Stato estero del domicilio", AN);
add_field( 8, 99,158,60, "Ragione sociale", AN);
add_field( 9,159,198,40, "Citt<EFBFBD> estera della sede legale", AN);
add_field(10,199,201, 3, "Stato estero della sede legale", AN);
add_field(11,202,241,40, "Indirizzo estero della sede legale", AN);
add_field(12,242,249, 8, "Data dell'operazione", DT, "", OBBLIG);
add_field(13,250,264,15, "Numero della Nota di Variazione", AN, "", OBBLIG);
add_field(14,265,273, 9, "Imponibile Nota di Variazione", NU);
add_field(15,274,282, 9, "Imposta Nota di Variazione", NU);
add_field(16,283,290, 8, "Data della Fattura da rettificare", DT, "", OBBLIG);
add_field(17,291,305,15, "Numero della Fattura da rettificare", AN, "", OBBLIG);
add_field(18,306,306, 9, "Variazione imponib. (Debito/Credito)",AN);
add_field(19,307,307, 9, "Variazione imposta (Debito/Credito)", AN);
add_field(20,308,1797,1490, "Filler", AN);
add_field(21,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG);
add_field(22,1799,1800,2,"Caratteri di fine riga", AN, "\r\n");
}
_recset = NULL;
}
///////////////////////////////////////////////////////////
// TDati_rilevanti_set
///////////////////////////////////////////////////////////
class TDati_rilevanti_set : public TAS400_recordset
{
int _anno;
protected:
virtual bool set_field(const TAS400_column_info& fi, const TVariant& var);
void init();
bool set_val(int n, const TVariant& v) { return TAS400_recordset::set(n-1, v); }
public:
bool set(unsigned int n, const TVariant& v) { return set_val(n, v); }
bool set(unsigned int n, const TString& v) { return set_val(n, v); }
bool set(unsigned int n, char v) { TString4 str; str << v; return set_val(n, str); }
bool set(unsigned int n, int v) { return set_val(n, long(v)); }
bool set(unsigned int n, const real& v) { return set_val(n, v); }
bool set(unsigned int n, const TDate& v) { return set_val(n, v); }
void add_control_rec(int zero_o_nove, int num_inv = 1, int tot_inv = 1);
bool split(const TFilename& name, const TRecnotype maxalleg = 15000);
TDati_rilevanti_set(int anno);
};
bool TDati_rilevanti_set::set_field(const TAS400_column_info& fi, const TVariant& var)
{
// Salva le date in formato GGMMAAAA invece dello standard ANSI AAAAMMGG
if (fi._type == DT && fi._width == 8)
{
const TDate d = var.as_date();
TString8 str; str.format("%02d%02d%04d", d.day(), d.month(), d.year());
row().overwrite(str, fi._pos);
return true;
} else
// Salva gli importi in formato 000001234 (non possono essere negativi)
if (fi._type == NU && fi._width == 9)
{
TString16 str = var.as_string();
CHECKS(str[0] != '-', "Importo negativo non ammesso:", (const char*)str);
// Tiene la sola parte intera e riempie di zeri
const int dot = str.find('.');
if (dot >= 0) str.cut(dot);
str.right_just(fi._width, '0');
row().overwrite(str, fi._pos);
return true;
}
return TAS400_recordset::set_field(fi, var);
}
void TDati_rilevanti_set::add_control_rec(int zon, int num_inv, int tot_inv)
{
CHECKD(zon == 0 || zon == 9, "Tipo record di testa o coda non valido ", zon);
const TAnagrafica ditta(LF_NDITTE, prefix().get_codditta());
TString4 tipo; tipo << zon;
new_rec(tipo);
set(6, ditta.codice_fiscale());
set(7, ditta.partita_IVA());
if (ditta.giuridica())
{
TString den;
set(8, ditta.ragione_sociale());
set(9, ditta.comune_residenza());
set(10, ditta.provincia_residenza());
}
else
{
set(11, ditta.cognome());
set(12, ditta.nome());
set(13, ditta.sesso());
set(14, ditta.data_nascita());
set(15, ditta.comune_nascita());
set(16, ditta.provincia_nascita());
}
set(17, _anno);
if (tot_inv < 1) tot_inv = 1;
if (num_inv <= 0) num_inv = 1;
if (num_inv > tot_inv) num_inv = tot_inv;
set(19, num_inv);
set(20, tot_inv);
}
bool TDati_rilevanti_set::split(const TFilename& name, const TRecnotype maxalleg)
{
const TRecnotype totrec = items();
bool done = totrec <= maxalleg;
if (!done)
{
const TRecnotype rows_x_file = maxalleg-2;
const int totf = int((totrec-2.0) / rows_x_file + 0.99);
TString msg;
msg.format(FR("Spezzatura del file %s in blocchi da %d righe"), (const char*)name, maxalleg);
TProgind pi(totrec, msg);
move_first();
for (int f = 1; f <= totf; f++)
{
TDati_rilevanti_set outset(_anno);
outset.add_control_rec(0, f, totf);
for (TRecnotype sent = 0; sent < rows_x_file && move_next(); sent++)
{
const TRecnotype r = current_row();
if (!pi.setstatus(r))
{
f = totf; // Procedura interrotta dall'utente
break;
}
const TString& rec = row(r);
if (rec[0] == '0') continue; // Ignora un eventuale record iniziale "spurio"
if (rec[0] == '9') break; // Termina quando incontra il record finale
outset.new_rec(rec);
}
outset.add_control_rec(9, f, totf);
// Costruisce il nome del file di invio parziale, es: datiril_1_3.txt
TFilename outname = name;
const TString8 saved_ext = outname.ext();
outname.ext(""); outname << '_' << f << '_' << totf;
outname.ext(saved_ext);
done = outset.save_as(outname);
if (!done)
{
cantwrite_box(outname);
break;
}
}
}
return done;
}
TDati_rilevanti_set::TDati_rilevanti_set(int anno)
: TAS400_recordset("AS400(1800,1)"), _anno(anno)
{
TDati_rilevanti_trc trc;
for (int i = 0; i <= 5; i++)
trc.create_fields(i, *this);
trc.create_fields(9, *this);
}
///////////////////////////////////////////////////////////
// TDati_rilevanti_msk
///////////////////////////////////////////////////////////
#define MANUAL_ROW 900000L
enum TExclusion_mode { em_incluso, em_importo_limite, em_nullo, em_no_allegato,
em_fiscalita_agevolata, em_estero, em_intra,
em_data_limite, em_art8, em_passaggi_interni,
em_altro };
class TDati_rilevanti_msk : public TAutomask
{
TMaskmode _mode;
bool _sheet_dirty, _send_all;
TAssoc_array _contratti;
TExclusion_mode _why;
TLog_report* _log;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void load_sheet();
bool save_sheet();
bool save_if_dirty();
void set_dirty(bool d = true);
protected:
TRecnotype last_user_progr() const;
TRecnotype nuovo_progr() const;
bool check_rows(bool show_error);
bool send_nc(const TISAM_recordset& alleg, TDati_rilevanti_set& operaz);
bool send_fatt(const TISAM_recordset& alleg, TDati_rilevanti_set& operaz);
bool send_rec(const TISAM_recordset& alleg, TDati_rilevanti_set& operaz);
TExclusion_mode segnala_movimento(const TRectype& mov, TExclusion_mode motivo);
bool is_nota_variazione(const TRectype& mov) const;
real importo_limite(int anno) const;
void elabora_note(const TArray& note, TFast_isamfile& falleg, long& nprog);
public:
TRecnotype genera_alleg();
bool elabora_alleg();
bool send_alleg();
bool azzera_alleg(bool manual, TRecnotype first) const;
TExclusion_mode elabora_movimento(const TRectype& mov, TFast_isamfile& falleg, TRecnotype& progr);
bool salva_allegato(const TRectype& mov, TFast_isamfile& falleg, TRecnotype& progr,
const real& corrispettivo, const real& imposta, int tipope);
TExclusion_mode validate_clifo(const TRectype& mov);
TExclusion_mode validate_mov(const TRectype& mov);
TDati_rilevanti_msk() : TAutomask("fe0100a"), _mode(MODE_QUERY), _log(NULL) { load_profile(); set_dirty(false); }
~TDati_rilevanti_msk() { save_profile(); }
};
TExclusion_mode TDati_rilevanti_msk::segnala_movimento(const TRectype& mov, TExclusion_mode motivo)
{
if (_why == em_incluso)
{
const long numreg = mov.get_long(MOV_NUMREG);
const char* tipocf = mov.get_char(MOV_TIPO) == 'F' ? TR("Fornitore") : TR("Cliente");
const long codcf = mov.get_long(MOV_CODCF);
TString msg; msg.format(FR("%s %6ld - Registrazione %7ld scartata: "), tipocf, codcf, numreg);
switch (motivo)
{
case em_nullo : msg << TR("Soggetto con codice nullo"); break;
case em_importo_limite : msg << TR("importo inferiore al limite della comunicazione"); break;
case em_no_allegato : msg << TR("Soggetto da non inserire in allegato"); break;
case em_fiscalita_agevolata: msg << TR("Soggetto residente in stato a fiscalit<69> agevolata"); break;
case em_estero : msg << TR("Soggetto residente all'estero"); break;
case em_intra : msg << TR("Movimento intra"); break;
case em_data_limite : msg << TR("Data movimento fuori dal limite della comunicazione"); break;
case em_art8 : msg << TR("soggetto all'articolo 8 (del dpr 26-10-1972)"); break;
case em_passaggi_interni : msg << TR("passaggi interni"); break;
default : msg << TR("Altri motivi"); break;
}
_why = motivo;
if (motivo > em_importo_limite)
_log->log(1, msg);
}
return motivo;
}
TExclusion_mode TDati_rilevanti_msk::validate_clifo(const TRectype& mov)
{
const char tipocf = mov.get_char(MOV_TIPO);
const long codcf = mov.get_long(MOV_CODCF);
const TString16 ocfpi = mov.get(MOV_OCFPI);
if (tipocf <= ' ' || (codcf <= 0 && ocfpi.blank()))
return segnala_movimento(mov, em_nullo);
TString4 stato;
if (ocfpi.full())
{
const TRectype& rec_occas = cache().get(LF_OCCAS, ocfpi);
stato = rec_occas.get(OCC_STATO);
}
else
{
TString8 key; key.format("%c|%ld", tipocf, codcf);
const TRectype& rec_clifo = cache().get(LF_CLIFO, key);
stato = rec_clifo.get(CLI_STATOCF);
const int alleg = rec_clifo.get_int(CLI_ALLEG);
if (alleg == 1)
return segnala_movimento(mov, em_no_allegato);
if (tipocf == 'F' && alleg == 5)
return segnala_movimento(mov, em_estero);
if (stato.full())
{
const TRectype& rec_sta = cache().get("%STA", stato);
if (rec_sta.get_bool("B0"))
return segnala_movimento(mov, em_fiscalita_agevolata);
if (tipocf == 'F')
return segnala_movimento(mov, em_estero);
}
}
return em_incluso; //se arriva qui il clifo <20> da considerare
}
TExclusion_mode TDati_rilevanti_msk::validate_mov(const TRectype& mov)
{
// Ignora eventuale vecchio movimento IVA (ANNOIVA < 2010)
const int anno = mov.get_int(MOV_ANNOIVA);
if (anno < 2010)
segnala_movimento(mov, em_data_limite);
// Ignora i movimenti gi<67> comunicati tramite modello INTRA
if (!mov.get_real(MOV_CORRLIRE).is_zero() ||
!mov.get_real(MOV_CORRVALUTA).is_zero())
segnala_movimento(mov, em_intra);
if (anno <= 2011)
{
const TDate datareg = mov.get_date(MOV_DATAREG);
const TString& tipodoc = mov.get(MOV_TIPODOC);
if (tipodoc == "SC" && datareg < data_limite_scontrini)
segnala_movimento(mov, em_data_limite);
}
return validate_clifo(mov);
}
bool TDati_rilevanti_msk::is_nota_variazione(const TRectype& mov) const
{
const real totdoc = mov.get_real(MOV_TOTDOC);
if (totdoc < ZERO)
return true;
const int tipomov = mov.get_int(MOV_TIPOMOV);
if (tipomov == 2)
return true;
const TString& tipodoc = mov.get(MOV_TIPODOC);
if (tipodoc == "NC" || tipodoc == "ND")
return true;
return false;
}
bool TDati_rilevanti_msk::salva_allegato(const TRectype& mov, TFast_isamfile& falleg, TRecnotype& progr,
const real& importo, const real& imposta, int tipope)
{
bool update_existing_row = false;
const int anno = mov.get_int(MOV_ANNOIVA);
const long numreg_mov = mov.get_long(MOV_NUMREG);
long num_fatt = 0; // Numero di registrazione rettificabile
long num_rett = 0; // Numero di registrazione rettificata
falleg.zero();
TRectype& alleg = falleg.curr();
alleg.put(ALL_ANNO, anno);
alleg.put(ALL_PROGR, progr);
const TString80 contratto = mov.get(MOV_CONTRATTO);
if (contratto.full()) // Gestione contratti
{
TString80 key;
key.format("%c%06ld_%s_%d", mov.get_char(MOV_TIPO), mov.get_long(MOV_CODCF),
(const char*)contratto, tipope);
real* first_progr = (real*)_contratti.objptr(key);
if (first_progr == NULL) // Primo movimento del contratto
{
first_progr = new real;
*first_progr = progr;
_contratti.add(key, first_progr);
}
else
{
// Aggiorno il record generato col primo movimento del contratto
const TRecnotype old_progr = first_progr->integer();
CHECKD(old_progr > 0 && old_progr < progr, "Numero progressivo da contratto non valido ", old_progr);
alleg.put(ALL_PROGR, old_progr);
if (falleg.read() != NOERR)
{
TString msg;
msg << TR("Impossibile aggiornare record da contratto: ") << key;
_log->log(2, msg);
return false;
}
update_existing_row = true;
}
}
else
{
// Gestione note di credito
if (importo < ZERO || is_nota_variazione(mov))
{
TLocalisamfile partite(LF_PARTITE);
TRectype& part = partite.curr();
partite.setkey(2);
part.put(PART_NREG, numreg_mov);
part.put(PART_NUMRIG, 1);
if (partite.read() == NOERR) // Ho trovato la partita ora cerco la fattura di riferimento
{
int nriga = part.get_int(PART_NRIGA);
part.zero(PART_NRIGA); // Uso il record come chiave per leggere l'intera partita
TRecord_array partita(part, PART_NRIGA);
for (nriga = partita.pred_row(nriga); nriga >= 1; nriga = partita.pred_row(nriga))
{
const TRectype& riga = partita.row(nriga);
const int tipomov = riga.get_int(PART_TIPOMOV);
const long nreg_part = riga.get_long(PART_NREG);
if (tipomov == 1 && nreg_part > 0) // Fattura
{
num_fatt = nreg_part;
TLocalisamfile recset(LF_ALLEG);
recset.setkey(3);
recset.put(ALL_NUMREG, num_fatt);
if (recset.read(_isgteq) == NOERR && recset.get_long(ALL_NUMREG) == num_fatt)
{
const TDate data_fatt = riga.get(PART_DATAREG);
const int anno_fatt = data_fatt.year();
num_rett = num_fatt; // Memorizzo comunque il numero fattura da rettificare
if (anno_fatt == anno) // Se sono dello stesso anno vario la fattura e non registro la nota di variazione
{
update_existing_row = true;
alleg = recset.curr();
}
else
{
if (anno_fatt < 2010 || anno_fatt > anno)
{
num_rett = 0;
_why = em_data_limite; // Non pertinente
}
else
{
// Variazione di fattura non rilevante
if (_why == em_incluso && abs(importo) < importo_limite(anno))
_why = em_importo_limite;
}
}
break;
}
else
{
// Variazione di fattura non rilevante
if (_why == em_incluso && abs(importo) < importo_limite(anno))
_why = em_importo_limite;
}
}
}
}
const char* tipocf = part.get_char(PART_TIPOCF) == 'F' ? TR("Fornitore") : TR("Cliente");
const long codcf = part.get_long(PART_SOTTOCONTO);
TString msg; msg.format(FR("%s %6ld - Nota di variazione %7ld "), tipocf, codcf, numreg_mov);
if (num_rett > 0)
{
if (update_existing_row)
msg << TR("sommata");
else
msg << TR("associata");
msg << TR(" alla registrazione ") << num_rett;
_log->log(update_existing_row ? 0 : 1, msg);
}
else
{
if (num_fatt <= 0)
{
num_rett = INVALID_NUMREG;
msg << TR("NON associata a nessuna fattura!");
_log->log(1, msg);
}
else
{
num_rett = num_fatt;
}
}
}
}
// I dati della registrazione IVA vanno aggiornati comunque
alleg.put(ALL_DATAREG, mov.get(MOV_DATAREG));
int modpag = mov.get_int(MOV_MODPAG);
if (modpag <= 0)
modpag = contratto.full() ? 2 : 1;
alleg.put(ALL_MODPAG, modpag);
int err = 0;
if (update_existing_row) // Contratti o note di variazione
{
// Mi limito ad incrementare gli importi
alleg.add(ALL_IMPORTO, importo);
alleg.add(ALL_IMPOSTA, imposta);
// Aggiorno il flag di inclusione se necessario
const TExclusion_mode em_old = (TExclusion_mode)alleg.get_int(ALL_IGNORA);
if (em_old == em_incluso || em_old == em_importo_limite)
{
const real imp_new = alleg.get(ALL_IMPORTO);
const TExclusion_mode em_new = imp_new >= importo_limite(anno) ? em_incluso : em_importo_limite;
if (em_new != em_old)
alleg.put(ALL_IGNORA, int(em_new));
}
err = falleg.rewrite();
}
else
{
// Registro tutti i dati del cliente e gli importi
const char tipocf = mov.get_char(MOV_TIPO);
const long codcf = mov.get_long(MOV_CODCF);
alleg.put(ALL_TIPOCF, tipocf);
alleg.put(ALL_CODCF, codcf);
alleg.put(ALL_OCFPI, mov.get(MOV_OCFPI));
alleg.put(ALL_NUMREG, numreg_mov);
alleg.put(ALL_TIPOPE, tipope);
alleg.put(ALL_IMPORTO, importo);
alleg.put(ALL_IMPOSTA, imposta);
if (contratto.full())
{
alleg.put(ALL_CONTRATTO, contratto);
if (_why == em_incluso)
{
TContratto cc(tipocf, codcf, contratto);
real netto, iva;
if (cc.totale_annuale(anno, netto, iva) && netto < importo_limite(anno))
_why = em_importo_limite; // Contratto inutile :-)
}
} else
if (num_rett > 0)
{
alleg.put(ALL_NUMRETT, num_rett);
if (num_rett >= INVALID_NUMREG && _why == em_incluso)
_why = em_altro;
}
alleg.put(ALL_IGNORA, int(_why));
err = falleg.rewrite_write();
if (err == NOERR)
progr++;
}
if (err != NOERR)
{
TString msg;
msg.format(FR("Errore %d di aggiornamento del file %s"), err, (const char*)falleg.name());
_log->log(2, msg);
}
return err == NOERR;
}
real TDati_rilevanti_msk::importo_limite(int anno) const
{ return anno <= 2010 ? 25000 : 3000; }
TExclusion_mode TDati_rilevanti_msk::elabora_movimento(const TRectype& mov, TFast_isamfile& falleg, TRecnotype& progr)
{
validate_mov(mov);
const char tipocf = mov.get_char(MOV_TIPO);
const TString4 tipodoc = mov.get(MOV_TIPODOC);
const TDate datareg = mov.get_date(MOV_DATAREG);
const int anno = datareg.year();
#ifdef DBG
if (mov.get_long(MOV_NUMREG) == 2673)
int cazzone = 1;
#endif
const TString& keytok = mov.get(MOV_NUMREG);
TRecord_array righe_iva(keytok, LF_RMOVIVA);
real tot_imponibile, tot_imposta;
//calcolo di imponibile ed imposta di tutte le righe iva del movimento
for (int r = righe_iva.last_row(); r > 0; r = righe_iva.pred_row(r))
{
const TRectype& rmi = righe_iva.row(r);
const TCodiceIVA ci(rmi.get(RMI_CODIVA));
int natura_operazione = ci.allegato(tipocf);
if (natura_operazione <= 0 || natura_operazione > 5)
continue;
// Tratto a parte gli scontrini: devono sempre essere di tipo 4
if (natura_operazione == 1 && tipodoc == "SC")
natura_operazione = 4;
// Esportazioni
const bool art_8 = ci.get("S2") == "20" && ci.get("S3") == "1";
if (art_8)
segnala_movimento(mov, em_art8);
const TString4 cod_det = rmi.get(RMI_TIPODET);
const int tip_det = cod_det == "3" ? 3 : atoi(cache().get("%DET", cod_det, "I0"));
if (tip_det == 3)
segnala_movimento(mov, em_passaggi_interni);
real rmi_imponibile = rmi.get_real(RMI_IMPONIBILE);
real rmi_imposta = rmi.get_real(RMI_IMPOSTA);
if (natura_operazione == 4 && rmi_imposta.is_zero()) // se l'imposta non <20> specificata sullo scontrino ...
rmi_imposta = ci.scorpora(rmi_imponibile); // ... scorporo il lordo
tot_imponibile += rmi_imponibile;
tot_imposta += rmi_imposta;
}
if (mov.get(MOV_CONTRATTO).blank() && tot_imponibile >= ZERO)
{
// Considera solo registrazioni con importo rilevante
if (tot_imponibile < importo_limite(anno))
segnala_movimento(mov, em_importo_limite);
}
// Cessione o acquisto di beni o servizi (1 o 2)
const int tipope = tipocf == 'C' ? 1 : 2;
salva_allegato(mov, falleg, progr, tot_imponibile, tot_imposta, tipope);
return _why;
}
bool TDati_rilevanti_msk::azzera_alleg(bool manual, TRecnotype first) const
{
const int anno = get_int(F_ANNO);
TFast_isamfile falleg(LF_ALLEG);
// Azzeramento anno/attivit<69> selezionati
TString limit;
limit << ALL_ANNO << '=' << anno << ' '
<< ' ' << ALL_PROGR << '=';
TRecnotype daprog = manual ? MANUAL_ROW : first;
TRecnotype aprog = manual ? 0 : MANUAL_ROW;
TString query;
query << "USE " << LF_ALLEG;
if (manual) // Elimina i record immessi manualmente ed ignorati
query << "\nSELECT " << ALL_IGNORA << "!=\"\"";
if (daprog > 0)query << "\nFROM " << limit << daprog;
if (aprog > 0) query << "\nTO " << limit << aprog;
TISAM_recordset alleg(query);
const TRecnotype items = alleg.items();
TString str_pi;
str_pi << TR("Compattazione dati ") << anno;
TProgind pi(items, str_pi);
const TRectype& rec = alleg.cursor()->curr();
for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
{
if (!pi.addstatus(1))
break;
falleg.curr() = rec;
int err = falleg.remove();
if (err != NOERR)
return cantwrite_box(falleg.name());
}
return items > 0;
}
// Cerca l'ultimo numero di riga immesso manualmente
TRecnotype TDati_rilevanti_msk::last_user_progr() const
{
const int anno = get_int(F_ANNO);
TRecnotype progr = MANUAL_ROW;
TString query;
query << "USE " << LF_ALLEG
<< "\nFROM " << ALL_ANNO << '=' << anno << ' ' << ALL_PROGR << '=' << MANUAL_ROW
<< "\nTO " << ALL_ANNO << '=' << anno;
TISAM_recordset alleg(query);
if (alleg.move_last())
progr = alleg.get(ALL_PROGR).as_int();
return progr;
}
TRecnotype TDati_rilevanti_msk::nuovo_progr() const
{
TRecnotype progr = last_user_progr();
TSheet_field& righe = sfield(F_RIGHE);
const int items = righe.items();
if (items > 0)
{
const int col = righe.cid2index(A_RIGA);
for (int i = items-1; i >= 0; i--)
{
const TRecnotype sheet_progr = atol(righe.cell(i,col));
if (sheet_progr > 0)
{
if (sheet_progr > progr)
progr = sheet_progr;
break;
}
}
}
return progr+1;
}
void TDati_rilevanti_msk::elabora_note(const TArray& note, TFast_isamfile& falleg, long& nprog)
{
FOR_EACH_ARRAY_ITEM(note, i, obj)
{
const TRectype& not_var = *(const TRectype*)obj;
_why = em_incluso;
elabora_movimento(not_var, falleg, nprog);
}
}
TRecnotype TDati_rilevanti_msk::genera_alleg()
{
const int anno = get_int(F_ANNO);
_contratti.destroy(); // Azzera cache contratti
TString str_pi;
str_pi << TR("Movimenti ") << anno;
_log = new TLog_report(str_pi);
TRecnotype nprog = 1;
if (anno >= 2010) // Dummy test for bracing TFast_isamfiles
{
TFast_isamfile falleg(LF_ALLEG);
TFast_isamfile fmov(LF_MOV);
TString query;
query << "USE MOV KEY 3 SELECT BETWEEN(DATAREG," << anno << "0101," << anno << "1231)"
<< "\nFROM TIPO=C\nTO TIPO=F";
TISAM_recordset mov(query);
const TRectype& mov_rec = mov.cursor()->curr();
const TRecnotype items = mov.items();
long last_clifo = 0;
TArray note;
TProgind pi(items, str_pi);
for (bool ok = mov.move_first(); ok; ok = mov.move_next())
{
if (!pi.addstatus(1))
break;
const long curr_clifo = mov_rec.get_long(MOV_CODCF);
if (curr_clifo != last_clifo)
{
elabora_note(note, falleg, nprog);
last_clifo = curr_clifo;
note.destroy();
}
_why = em_incluso;
if (is_nota_variazione(mov_rec))
note.add(mov_rec); // Posticipa l'elaborazione delle note di varizione
else
elabora_movimento(mov_rec, falleg, nprog); // Elabora immediatamente i documenti normali
}
elabora_note(note, falleg, nprog); // Elabora le eventuali note dell'ultimo fornitore
}
_log->preview();
delete _log;
_log = NULL;
return nprog;
}
// Analizza tutti i movimenti dell'anno dell'attivit<69> corrente e genera i record rilevanti
bool TDati_rilevanti_msk::elabora_alleg()
{
if (!check_fields()) // Controlla che l'anno sia valido
return false;
const TRecnotype prog = genera_alleg();
azzera_alleg(false, prog);
return prog > 1;
}
bool TDati_rilevanti_msk::send_nc(const TISAM_recordset& alleg, TDati_rilevanti_set& operaz)
{
const long num_rett = alleg.get(ALL_NUMRETT).as_int();
if (num_rett <= 0 || num_rett >= INVALID_NUMREG)
return false;
TRectype rec_fatt(LF_MOV);
TRectype rec_nota(LF_MOV);
TLocalisamfile mov(LF_MOV);
mov.put(MOV_NUMREG, num_rett);
if (mov.read() == NOERR)
rec_fatt = mov.curr();
else
return false;
const long numreg = alleg.get(ALL_NUMREG).as_int();
mov.put(MOV_NUMREG, numreg);
if (mov.read() == NOERR)
rec_nota = mov.curr();
const TAnagrafica anag(alleg.cursor()->curr());
real imponibile = alleg.get(ALL_IMPORTO).as_real();
real imposta = alleg.get(ALL_IMPOSTA).as_real();
const char tipocf = rec_fatt.get_char(MOV_TIPO);
char segno_imponibile = tipocf == 'C' ? 'D' : 'C'; // Normalmente sono negative e quindi a debito del dichiarante
char segno_imposta = segno_imponibile;
if (imponibile > ZERO)
segno_imponibile = segno_imponibile == 'D' ? 'C' : 'D';
else
imponibile = -imponibile;
if (imposta > ZERO)
segno_imposta = segno_imposta == 'D' ? 'C' : 'D';
else
imposta = -imposta;
if (anag.stato_estero() > 0)
{
operaz.new_rec("5"); // Note di variazione a soggetti non residenti
if (anag.fisica())
{
operaz.set(2, anag.cognome());
operaz.set(3, anag.nome());
operaz.set(4, anag.data_nascita());
operaz.set(5, anag.comune_nascita());
operaz.set(6, anag.provincia_nascita());
operaz.set(7, anag.stato_estero());
}
else
{
operaz.set(8, anag.ragione_sociale());
operaz.set(9, anag.comune_residenza());
operaz.set(10, anag.stato_estero());
operaz.set(11, EMPTY_STRING); // TBI? Indirizzo estero
}
operaz.set(12, alleg.get(ALL_DATAREG));
operaz.set(13, rec_nota.get(MOV_NUMDOC).left(15));
operaz.set(14, imponibile);
operaz.set(15, imposta);
operaz.set(16, rec_fatt.get_date(MOV_DATAREG));
operaz.set(17, rec_fatt.get(MOV_NUMDOC).left(15));
operaz.set(18, segno_imponibile);
operaz.set(19, segno_imposta);
}
else
{
operaz.new_rec("4"); // Note di variazione a soggetti residenti
if (anag.partita_IVA().full())
operaz.set(2, anag.partita_IVA());
else
operaz.set(3, anag.codice_fiscale());
operaz.set(4, alleg.get(ALL_DATAREG));
operaz.set(5, rec_nota.get(MOV_NUMDOC).left(15));
operaz.set(6, imponibile);
operaz.set(7, imposta);
operaz.set(8, rec_fatt.get_date(MOV_DATAREG));
operaz.set(9, rec_fatt.get(MOV_NUMDOC).left(15));
operaz.set(10, segno_imponibile);
operaz.set(11, segno_imposta);
}
return true;
}
bool TDati_rilevanti_msk::send_fatt(const TISAM_recordset& alleg, TDati_rilevanti_set& operaz)
{
if (!_send_all)
{
const int escluso = alleg.get(ALL_IGNORA).as_int();
if (escluso > 0)
return false;
}
const TAnagrafica anag(alleg.cursor()->curr());
const real importo = alleg.get(ALL_IMPORTO).as_real();
const real imposta = alleg.get(ALL_IMPOSTA).as_real();
const TString& paiv = anag.partita_IVA();
TLocalisamfile mov(LF_MOV);
const long numreg = alleg.get(ALL_NUMREG).as_int();
mov.put(MOV_NUMREG, numreg);
if (mov.read() != NOERR)
{
CHECKD(false, "Registrazione fantasma ", numreg);
return false;
}
if (anag.stato_estero() > 0)
{
operaz.new_rec("3"); // Operazioni con soggetti non residenti
if (anag.fisica())
{
operaz.set(2, anag.cognome());
operaz.set(3, anag.nome());
operaz.set(4, anag.data_nascita());
operaz.set(5, anag.comune_nascita());
operaz.set(6, anag.provincia_nascita());
operaz.set(7, anag.stato_estero());
}
else
{
operaz.set(8, anag.ragione_sociale());
operaz.set(9, anag.comune_residenza());
operaz.set(10, anag.stato_estero());
operaz.set(11, EMPTY_STRING); // TBI? Indirizzo estero
}
operaz.set(12, alleg.get(ALL_DATAREG).as_date());
operaz.set(13, mov.get(MOV_NUMDOC));
operaz.set(14, alleg.get(ALL_MODPAG).as_int());
operaz.set(15, importo);
operaz.set(16, imposta);
operaz.set(17, alleg.get(ALL_TIPOPE).as_int());
}
else
{
if (paiv.blank())
{
operaz.new_rec("1"); // Operazioni con soggetti residenti non titolari di partita IVA
operaz.set(2, anag.codice_fiscale());
operaz.set(3, alleg.get(ALL_DATAREG).as_date());
operaz.set(4, alleg.get(ALL_MODPAG).as_int());
operaz.set(5, real(importo+imposta));
}
else
{
operaz.new_rec("2"); // Operazioni con soggetti residenti - titolari di partita IVA
operaz.set(2, paiv);
operaz.set(3, alleg.get(ALL_DATAREG).as_date());
operaz.set(4, mov.get(MOV_NUMDOC));
operaz.set(5, alleg.get(ALL_MODPAG).as_int());
operaz.set(6, alleg.get(ALL_IMPORTO).as_real());
operaz.set(7, alleg.get(ALL_IMPOSTA).as_real());
operaz.set(8, alleg.get(ALL_TIPOPE).as_int());
}
}
return false;
}
bool TDati_rilevanti_msk::send_rec(const TISAM_recordset& alleg, TDati_rilevanti_set& operaz)
{
const long numrett = alleg.get(ALL_NUMRETT).as_int();
return numrett > 0 ? send_nc(alleg, operaz) : send_fatt(alleg, operaz);
}
// Genera file per invio telematico
bool TDati_rilevanti_msk::send_alleg()
{
const int anno = get_int(F_ANNO);
_send_all = get_int(F_SENDALL) != 1; // Devo inviare anche dati NON rilevanti?
TFilename temp = get(F_OUTFOLDER);
if (temp.blank())
temp.tempdir();
temp.add("datiril.txt");
TDati_rilevanti_set recset(anno);
recset.add_control_rec(0);
TString query;
query << "USE " << LF_ALLEG;
if (!_send_all)
query << " SELECT STR(" << ALL_IGNORA << "==0)";
query << "\nFROM " << ALL_ANNO << '=' << anno
<< "\nTO " << ALL_ANNO << '=' << anno;
TISAM_recordset alleg(query);
for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
send_rec(alleg, recset);
recset.add_control_rec(9);
bool done = recset.save_as(temp);
const long maxalleg = get_long(F_MAXREC);
if (recset.items() > maxalleg)
done = recset.split(temp, maxalleg);
return done;
}
void TDati_rilevanti_msk::set_dirty(bool d)
{
_sheet_dirty = d;
enable(DLG_SAVEREC, d);
}
void TDati_rilevanti_msk::load_sheet()
{
const char tipocf = get(F_TIPOCF)[0];
const long codcf = get_long(F_CODCF);
const TString& ocfpi = get(F_OCFPI);
const int show_all = get_int(F_SHOWALL);
TSheet_field& s = sfield(F_RIGHE);
s.hide(); // Nascondo lo sheet per guadagnare un 20% di velocit<69> di caricamento
s.destroy();
TString query;
query << "USE " << LF_ALLEG;
if (codcf > 0 || (show_all > 0 && show_all < 7))
{
query << " SELECT ";
if (codcf > 0)
{
query << "(" << ALL_TIPOCF << "='" << tipocf << "')&&(" << ALL_CODCF << "='" << codcf << "')";
if (ocfpi.full())
query << "&&(" << ALL_OCFPI << "='" << ocfpi << "')";
}
if (show_all > 0 && show_all < 7)
{
if (codcf > 0) query << "&&";
query << "(STR(" << ALL_IGNORA;
switch (show_all)
{
case 1: query << '<'; break; // Importi superiori al limite (20000 o 3000)
case 2: query << '='; break; // Importi inferiori al limite (20000 o 3000)
default: query << '>'; break; // Importi scartati (esteri o leggi speciali)
}
query << "1))";
}
}
const int anno = get_int(F_ANNO);
TString16 limit; limit << ALL_ANNO << '=' << anno;
query << "\nFROM " << limit << "\nTO " << limit;
TISAM_recordset alleg(query);
const TRecnotype items = alleg.items();
if (items > 0)
{
TString pi_str; pi_str << TR("Caricamento ") << anno;
TProgind pi(items, pi_str);
const TRectype& curr = alleg.cursor()->curr();
int rec = 0;
for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
{
if (!pi.addstatus(1)) break;
s.autoload_line(++rec, curr);
}
}
s.force_update();
s.show();
set_dirty(false);
if (s.items() > 0)
{
_mode = MODE_MOD;
disable(-1);
}
else
{
_mode = MODE_QUERY;
enable(-1);
}
}
bool TDati_rilevanti_msk::save_sheet()
{
if (!check_rows(false))
return false;
bool done = true;
const int anno = get_int(F_ANNO);
TSheet_field& s = sfield(F_RIGHE);
const TRecnotype items = s.items();
if (items > 0)
{
TFast_isamfile alleg(LF_ALLEG);
TRectype& rec = alleg.curr();
TProgind pi(items, TR("Registrazione righe"), false);
FOR_EACH_SHEET_ROW(s, r, row)
{
if (!pi.addstatus(1))
break;
alleg.zero();
rec.put(ALL_ANNO, anno);
s.autosave_line(r+1, rec);
const int err = alleg.rewrite_write();
if (err != NOERR)
{
done = cantwrite_box(alleg.name());
break;
}
}
}
if (done)
{
// Cancella le righe manuali marcate come da NON inviare
azzera_alleg(true, MANUAL_ROW);
set_dirty(false);
}
return done;
}
bool TDati_rilevanti_msk::check_rows(bool show_error)
{
const int anno = get_int(F_ANNO);
bool ok = anno >= 2010;
if (!ok)
{
if (show_error)
check_fields(); // Provoco segnalazione automatica
return false;
}
long codcf = 0L;
TString16 ocfpi;
TSheet_field& s = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(s, i, row)
{
row->get(s.cid2index(A_CODCF), codcf);
row->get(s.cid2index(A_OCFPI), ocfpi);
if (codcf <= 0L && ocfpi.blank())
{
ok = show_error && error_box(FR("Soggetto mancante alla riga %d"), i+1);
break;
}
}
return ok;
}
bool TDati_rilevanti_msk::save_if_dirty()
{
bool done = true;
if (_sheet_dirty && yesno_box(TR("Si desiderano registrare le modifiche?")))
{
done = check_rows(true);
if (done)
done = save_sheet();
}
return done;
}
bool TDati_rilevanti_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case DLG_OK: // Salva
if (e == fe_button && jolly == 0) // Selezione su maschera principale
{
if (_mode == MODE_QUERY || save_if_dirty())
load_sheet();
return false;
}
break;
case DLG_CANCEL:
if (e == fe_button && jolly == 0)
{
if (_mode != MODE_QUERY && save_if_dirty())
{
TSheet_field& s = sfield(F_RIGHE);
s.destroy();
s.force_update();
_mode = MODE_QUERY;
enable(-1);
}
return false;
}
break;
case DLG_SAVEREC:
if (e == fe_button)
save_if_dirty();
break;
case DLG_RECALC:
if (e == fe_button && check_fields())
{
if (elabora_alleg())
load_sheet();
}
break;
case DLG_ELABORA:
if (e == fe_button && check_fields())
send_alleg();
break;
case F_OUTFOLDER:
if (e == fe_init && o.empty())
{
TFilename tmp; tmp.tempdir();
o.set(tmp);
}
break;
case F_MAXREC:
if (e == fe_init && o.empty())
o.set(15000L);
break;
case F_RIGHE:
if (e == fe_init)
load_sheet(); else
if (e == se_notify_modify)
set_dirty( true); else
if (e == se_query_add)
{
if (!check_rows(false))
return false;
} else
if (e == se_notify_add)
{
TSheet_field& s = (TSheet_field&)o;
TToken_string& row = s.row(jolly);
row.add(nuovo_progr(), s.cid2index(A_RIGA));
row.add(TDate(TODAY), s.cid2index(A_DATAREG));
row.add(3, s.cid2index(A_MODPAG));
row.add(1, s.cid2index(A_TIPOPE));
} else
if (e == se_query_del)
return false;
break;
case DLG_DELREC:
if (e == fe_button)
{
// La cancellazione fisica non si puo' fare subito
o.mask().set(A_IGNORA, "X");
return false;
}
break;
case DLG_EXPORT:
if (e == fe_button)
return sfield(F_RIGHE).esporta();
break;
case A_CODCF:
case A_OCFPI:
if (e == fe_modify || (e == fe_init && !o.empty()))
{
TMask& m = o.mask();
const TAnagrafica anag(m.get(A_TIPOCF)[0], m.get_long(A_CODCF), m.get(A_OCFPI));
m.set(A_RAGSOC, anag.ragione_sociale());
m.set(A_PAIV, anag.partita_IVA());
m.set(A_COFI, anag.codice_fiscale());
}
break;
case DLG_USER:
if (e == fe_button)
{
const long numreg = o.mask().get_long(A_NUMREG);
if (numreg > 0)
{
TRectype mov(LF_MOV);
mov.put(MOV_NUMREG, numreg);
mov.edit();
}
}
break;
default:
break;
}
return true;
}
///////////////////////////////////////////////////////////
// TDati_rilevanti_app
///////////////////////////////////////////////////////////
class TDati_rilevanti_app : public TSkeleton_application
{
protected:
virtual bool create();
public:
virtual void main_loop();
};
bool TDati_rilevanti_app::create()
{
// Teoricamente <20> possibile visulizzare tutti i movimenti di un anno, per cui allargo il numero riga
TSheet_field::set_line_number_width(6);
// Controllo preventivo dell'avvenuta conversione del tracciato record
const TRectype alleg(LF_ALLEG);
if (alleg.type(ALL_IGNORA) != _intfld)
return error_box(TR("Il database non <20> stato ancora convertito per il modulo FE"));
return TSkeleton_application::create();
}
void TDati_rilevanti_app::main_loop()
{
TDati_rilevanti_msk msk;
msk.run();
}
///////////////////////////////////////////////////////////
// main
///////////////////////////////////////////////////////////
int fe0100(int argc, char* argv[])
{
TDati_rilevanti_app app;
app.run(argc, argv, TR("Gestione dati rilevanti"));
return 0;
}