56f2603f1a
Files correlati : fe0.exe Ricompilazione Demo : [ ] Commento : Corretta associazione note di variazione git-svn-id: svn://10.65.10.50/branches/R_10_00@22485 c028cbd2-c16b-5b4b-a496-9718f37d4682
2655 lines
76 KiB
C++
Executable File
2655 lines
76 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <automask.h>
|
||
#include <colors.h>
|
||
#include <defmask.h>
|
||
#include <modaut.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"
|
||
|
||
const char* const INVALID_NUMDOC = "???????";
|
||
const long MANUAL_ROW = 900000L;
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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);
|
||
}
|
||
|
||
static real importo_limite(int anno)
|
||
{ return anno > 2010 ? 3000: 25000; }
|
||
|
||
static bool is_nota_variazione(const TRectype& mov)
|
||
{
|
||
const int logicnum = mov.num();
|
||
|
||
if (logicnum == LF_MOV)
|
||
{
|
||
const real totdoc = mov.get_real(MOV_TOTDOC);
|
||
if (totdoc < ZERO)
|
||
return true;
|
||
|
||
const int tipomov = mov.get_int(MOV_TIPOMOV);
|
||
if (tipomov == 2) // Nota di credito/debito per saldaconto
|
||
return true;
|
||
|
||
const TString& tipodoc = mov.get(MOV_TIPODOC);
|
||
if (tipodoc == "NC" || tipodoc == "ND") // Nota di credito/debito senza saldaconto
|
||
return true;
|
||
} else
|
||
if (logicnum == LF_ALLEG)
|
||
{
|
||
const TString& numrett = mov.get(ALL_NUMRETT);
|
||
if (numrett.full())
|
||
return true;
|
||
|
||
const real importo = mov.get_real(ALL_IMPORTO);
|
||
const real imposta = mov.get_real(ALL_IMPOSTA);
|
||
if (importo < ZERO || imposta < ZERO)
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
enum TExclusion_mode { em_incluso, em_importo_limite, em_no_allegato,
|
||
em_fiscalita_agevolata, em_estero, em_intra,
|
||
em_art8, em_data_limite, em_passaggi_interni,
|
||
em_inviato, em_altro };
|
||
|
||
static const char* mode2string(TExclusion_mode motivo)
|
||
{
|
||
const char* msg = "";
|
||
switch (motivo)
|
||
{
|
||
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 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;
|
||
case em_inviato : msg = TR("Inviato l'anno precedente"); break;
|
||
default : msg = TR("Altri motivi"); break;
|
||
}
|
||
return msg;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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(); }
|
||
const TString& codice() const { return _rec.get("CODTAB").mid(7); }
|
||
bool totale_annuale(int anno, real& importo, real& imposta) const;
|
||
int modalita_pagamento() const;
|
||
|
||
bool init(char tipocf, long codcf, const TString& codcont);
|
||
bool init(const TRectype& rec);
|
||
TContratto(char tipocf, long codcf, const char* codcont) : _rec(LF_TABMOD) { init(tipocf, codcf, codcont); }
|
||
TContratto(const TRectype& rec) : _rec(LF_TABMOD) { 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;
|
||
}
|
||
|
||
int TContratto::modalita_pagamento() const
|
||
{
|
||
int modpag = _rec.get_int("S6");
|
||
if (modpag != 2 && modpag != 3)
|
||
modpag = 2;
|
||
return modpag;
|
||
}
|
||
|
||
bool TContratto::init(char tipocf, long codcf, const TString& codcont)
|
||
{
|
||
if (tipocf >= 'C' && codcf > 0 && codcont.full())
|
||
{
|
||
TString80 key; key.format("%c%6ld%s", tipocf, codcf, (const char*)codcont);
|
||
init(cache().get("&CON", key));
|
||
}
|
||
else
|
||
_rec.zero();
|
||
return ok();
|
||
}
|
||
|
||
bool TContratto::init(const TRectype& rec)
|
||
{
|
||
switch (rec.num())
|
||
{
|
||
case LF_TABMOD:
|
||
_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);
|
||
}
|
||
}
|
||
break;
|
||
case LF_ALLEG:
|
||
{
|
||
const char tipocf = rec.get_char(ALL_TIPOCF);
|
||
const long codcf = rec.get_long(ALL_CODCF);
|
||
const TString& contr = rec.get(ALL_CONTRATTO);
|
||
init(tipocf, codcf, contr);
|
||
}
|
||
break;
|
||
case LF_MOV:
|
||
{
|
||
const char tipocf = rec.get_char(MOV_TIPO);
|
||
const long codcf = rec.get_long(MOV_CODCF);
|
||
const TString& contr = rec.get(MOV_CONTRATTO);
|
||
init(tipocf, codcf, contr);
|
||
}
|
||
break;
|
||
default:
|
||
CHECKD(false, "Record non valido per contratto FE", rec.num());
|
||
break;
|
||
}
|
||
return ok();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TAnagrafica
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TAnagrafica : public TObject
|
||
{
|
||
char _tipo; // F o G
|
||
TString16 _cofi, _paiv;
|
||
TString80 _ragsoc;
|
||
TString4 _com_nasc, _com_res;
|
||
TString80 _loc_res, _ind_res;
|
||
TDate _data_nasc;
|
||
int _allegato, _stato_estero;
|
||
|
||
TAnagrafica& operator =(const TAnagrafica&) { CHECK(false, "Can't copy TAnagrafica"); }
|
||
TAnagrafica(const TAnagrafica&) { CHECK(false, "Can't copy TAnagrafica"); }
|
||
protected:
|
||
void build_ind_res(const TRectype& rec, const char* ind, const char* civ);
|
||
|
||
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 { CHECK(fisica(), "Non chiedere nome giuridico!"); return _ragsoc.mid(30,20); }
|
||
char sesso() const { CHECK(fisica(), "Solo sesso fisico!"); 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); }
|
||
const TString& localita_residenza() const { return _loc_res; }
|
||
const TString& indirizzo_residenza() const { return _ind_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); }
|
||
};
|
||
|
||
void TAnagrafica::build_ind_res(const TRectype& rec, const char* ind, const char* civ)
|
||
{
|
||
TString80 indirizzo = rec.get(ind);
|
||
if (indirizzo.full())
|
||
{
|
||
const TString& numero = rec.get(civ);
|
||
if (numero.full())
|
||
indirizzo << ", " << numero;
|
||
indirizzo.strip_double_spaces();
|
||
TParagraph_string s(indirizzo, 40);
|
||
_ind_res = s.get(0);
|
||
}
|
||
}
|
||
|
||
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);
|
||
_loc_res = rec.get(OCC_LOCALITA);
|
||
build_ind_res(rec, OCC_INDIR, OCC_CIV);
|
||
_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);
|
||
build_ind_res(rec, ANA_INDRES, ANA_CIVRES);
|
||
|
||
// 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));
|
||
if (rec.get(CLI_COMNASC).not_empty())
|
||
_com_nasc = rec.get(CLI_COMNASC);
|
||
if (rec.get(CLI_DATANASC).not_empty())
|
||
_data_nasc = rec.get(CLI_DATANASC);
|
||
}
|
||
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);
|
||
build_ind_res(rec, CLI_INDCF, CLI_CIVCF);
|
||
|
||
// 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);
|
||
_loc_res = rec.get(CLI_LOCCF);
|
||
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;
|
||
}
|
||
|
||
if (_tipo == 'G')
|
||
_ragsoc.strip_double_spaces();
|
||
|
||
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", AN); // ex NU
|
||
add_field( 6, 27, 32, 6, "Protocollo documento", AN); // ex 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.", AN); // Ex NU
|
||
add_field(24,291,291, 1, "Impegno alla trasmissione", AN ); // Ex NU
|
||
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,15, "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, 1, "Variazione imponib. (Debito/Credito)",AN);
|
||
add_field(11,94,94, 1, "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, 1, "Variazione imponib. (Debito/Credito)",AN);
|
||
add_field(19,307,307, 1, "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);
|
||
virtual const TVariant& get_field(const TAS400_column_info& fi) const;
|
||
|
||
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_header(const TMask& msk, int num_inv = 1, int tot_inv = 1);
|
||
void add_footer();
|
||
bool split(const TFilename& name, const TRecnotype maxalleg = 15000);
|
||
int anno() const { return _anno; }
|
||
|
||
TDati_rilevanti_set(int anno);
|
||
TDati_rilevanti_set(const TFilename& file);
|
||
};
|
||
|
||
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();
|
||
if (d.ok())
|
||
{
|
||
TFixed_string str = d.string(full, '\0', full, full, gma_date);
|
||
row().overwrite(str, fi._pos);
|
||
}
|
||
else
|
||
row().overwrite(" ", 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);
|
||
}
|
||
|
||
const TVariant& TDati_rilevanti_set::get_field(const TAS400_column_info& ci) const
|
||
{
|
||
if (ci._type == DT && ci._width == 8)
|
||
{
|
||
const TRecnotype n = current_row();
|
||
if (n >= 0 && n < items())
|
||
{
|
||
const TString& str = row(n).mid(ci._pos, ci._width);
|
||
const int gg = atoi(str.left(2));
|
||
const int mm = atoi(str.mid(2,2));
|
||
const int aa = atoi(str.mid(4,4));
|
||
if (aa > 1800 && aa < 2100)
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
var.set(TDate(gg, mm, aa));
|
||
return var;
|
||
}
|
||
}
|
||
return NULL_VARIANT;
|
||
}
|
||
return TAS400_recordset::get_field(ci);
|
||
}
|
||
|
||
void TDati_rilevanti_set::add_header(const TMask& msk, int num_inv, int tot_inv)
|
||
{
|
||
const TAnagrafica ditta(LF_NDITTE, prefix().get_codditta());
|
||
|
||
new_rec("0");
|
||
set(7, ditta.codice_fiscale());
|
||
set(8, ditta.partita_IVA());
|
||
|
||
if (ditta.giuridica())
|
||
{
|
||
set( 9, ditta.ragione_sociale());
|
||
set(10, ditta.comune_residenza());
|
||
set(11, ditta.provincia_residenza());
|
||
}
|
||
else
|
||
{
|
||
set(12, ditta.cognome());
|
||
set(13, ditta.nome());
|
||
set(14, ditta.sesso());
|
||
set(15, ditta.data_nascita());
|
||
set(16, ditta.comune_nascita());
|
||
set(17, ditta.provincia_nascita());
|
||
}
|
||
set(18, _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(20, num_inv);
|
||
set(21, tot_inv);
|
||
|
||
const TString& cofi = msk.get(F_INTER_COFI);
|
||
if (cofi.full())
|
||
{
|
||
set(22, cofi);
|
||
set(23, msk.get(F_INTER_CAF));
|
||
set(24, msk.get(F_INTER_COM));
|
||
set(25, msk.get(F_INTER_DATE));
|
||
}
|
||
else
|
||
{
|
||
set(25, TDate()); // Svuota data impegno
|
||
}
|
||
}
|
||
|
||
void TDati_rilevanti_set::add_footer()
|
||
{
|
||
TString f = row(0);
|
||
f.overwrite("9");
|
||
new_rec(f);
|
||
}
|
||
|
||
bool TDati_rilevanti_set::split(const TFilename& name, const TRecnotype maxalleg)
|
||
{
|
||
const TRecnotype totrec = items();
|
||
bool done = totrec <= maxalleg;
|
||
if (!done)
|
||
{
|
||
TString msg;
|
||
msg.format(FR("Spezzatura del file %s in blocchi da %d righe"), (const char*)name, maxalleg);
|
||
TProgind pi(totrec, msg);
|
||
|
||
TDati_rilevanti_set outset(_anno);
|
||
int f = 0;
|
||
for (TRecnotype r = 0; r < totrec; r++)
|
||
{
|
||
if (!pi.setstatus(r))
|
||
break; // Procedura interrotta dall'utente
|
||
outset.new_rec(row(r));
|
||
if (outset.items() >= maxalleg || r == totrec-1)
|
||
{
|
||
// Costruisce il nome del file di invio parziale, es: Spesometro00001_2.txt
|
||
TFilename outname = name;
|
||
const TString8 saved_ext = outname.ext();
|
||
outname.ext(""); outname << '_' << (++f);
|
||
outname.ext(saved_ext);
|
||
done = outset.save_as(outname);
|
||
if (done)
|
||
outset.destroy();
|
||
else
|
||
{
|
||
cantwrite_box(outname);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (f > 1)
|
||
warning_box(FR("Sono stati generati %d file nella cartella %s"), name.path());
|
||
}
|
||
return done;
|
||
}
|
||
|
||
void TDati_rilevanti_set::init()
|
||
{
|
||
TDati_rilevanti_trc trc;
|
||
for (int i = 0; i <= 5; i++)
|
||
trc.create_fields(i, *this);
|
||
trc.create_fields(9, *this);
|
||
|
||
}
|
||
|
||
TDati_rilevanti_set::TDati_rilevanti_set(const TFilename& file)
|
||
: TAS400_recordset("AS400(1800,1)"), _anno(2010)
|
||
{
|
||
init();
|
||
if (load_file(file) && move_first())
|
||
{
|
||
const int anno = get(18).as_int();
|
||
if (anno > 2010)
|
||
_anno = anno;
|
||
}
|
||
}
|
||
|
||
TDati_rilevanti_set::TDati_rilevanti_set(int anno)
|
||
: TAS400_recordset("AS400(1800,1)"), _anno(anno)
|
||
{
|
||
init();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TDati_rilevanti_array
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TDati_rilevanti_array : public TObject
|
||
{
|
||
TArray _data;
|
||
|
||
protected:
|
||
TExclusion_mode segnala_riga(const TRectype& alleg, TExclusion_mode motivo, TLog_report& log) const;
|
||
|
||
public:
|
||
int items() const { return _data.items(); }
|
||
const TRectype& operator[](int i) { return (const TRectype&)_data[i]; }
|
||
TExclusion_mode add(const TRectype& alleg, bool send_all, TLog_report& log);
|
||
void add(const TArray& note, bool send_all, TLog_report& log);
|
||
};
|
||
|
||
TExclusion_mode TDati_rilevanti_array::segnala_riga(const TRectype& alleg, TExclusion_mode motivo, TLog_report& log) const
|
||
{
|
||
const long numreg = alleg.get_long(ALL_PROGR);
|
||
const char* tipocf = alleg.get_char(ALL_TIPOCF) == 'F' ? TR("Fornitore") : TR("Cliente");
|
||
const long codcf = alleg.get_long(MOV_CODCF);
|
||
TString msg; msg.format(FR("%s %6ld - Riga %7ld scartata: "), tipocf, codcf, numreg);
|
||
msg << mode2string(motivo);
|
||
log.log(1, msg);
|
||
return motivo;
|
||
}
|
||
|
||
|
||
TExclusion_mode TDati_rilevanti_array::add(const TRectype& alleg, bool send_all, TLog_report& log)
|
||
{
|
||
TExclusion_mode ignora = TExclusion_mode(alleg.get_int(ALL_IGNORA));
|
||
if (ignora > em_importo_limite)
|
||
return ignora;
|
||
|
||
const real importo = alleg.get_real(ALL_IMPORTO);
|
||
const real imposta = alleg.get_real(ALL_IMPOSTA);
|
||
if (importo.is_zero() && imposta.is_zero())
|
||
return segnala_riga(alleg, em_importo_limite, log);
|
||
|
||
const TString80 contratto = alleg.get(ALL_CONTRATTO);
|
||
const TString8 numrett = alleg.get(ALL_NUMRETT);
|
||
if (contratto.full() || numrett.full())
|
||
{
|
||
TString16 curr_idcf = alleg.get(ALL_OCFPI);
|
||
if (curr_idcf.blank()) curr_idcf = alleg.get(ALL_CODCF);
|
||
TRectype* sum = NULL;
|
||
for (int i = _data.last(); i >= 0; i--)
|
||
{
|
||
TRectype& rec = (TRectype&)_data[i];
|
||
TString16 idcf = rec.get(ALL_OCFPI);
|
||
if (idcf.blank()) idcf = rec.get(ALL_CODCF);
|
||
if (idcf == curr_idcf)
|
||
{
|
||
if ((numrett.full() && numrett == rec.get(ALL_NUMDOC)) ||
|
||
(contratto.full() && contratto == rec.get(ALL_CONTRATTO)))
|
||
{
|
||
sum = &rec;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
if (sum != NULL)
|
||
{
|
||
sum->add(ALL_IMPORTO, importo);
|
||
sum->add(ALL_IMPOSTA, imposta);
|
||
// Le istruzioni dicono di mettere la data dell'ultima rettifica
|
||
// ma la procedura di controllo non accetta anni successivi!
|
||
// Per cui ... comment :-)
|
||
// const TDate sum_data = sum->get(ALL_DATAREG);
|
||
// const TDate all_data = alleg.get(ALL_DATAREG);
|
||
// if (all_data > sum_data)
|
||
// sum->put(ALL_DATAREG, all_data);
|
||
|
||
const int old_mode = sum->get_int(ALL_IGNORA);
|
||
if (old_mode <= 1)
|
||
{
|
||
const int anno = sum->get_int(ALL_ANNO);
|
||
int new_mode = sum->get_real(ALL_IMPORTO) < importo_limite(anno);
|
||
|
||
if (new_mode && contratto.full())
|
||
{
|
||
const TContratto c(alleg);
|
||
real imp, iva;
|
||
if (c.totale_annuale(anno, imp, iva))
|
||
new_mode = imp < importo_limite(anno);
|
||
}
|
||
|
||
if (old_mode != new_mode)
|
||
sum->put(ALL_IGNORA, new_mode);
|
||
}
|
||
return em_incluso; // Aggiunto a record preesistente
|
||
}
|
||
else
|
||
{
|
||
// Ignora le note di variazione non collegate e di importo non rilevante
|
||
if (!send_all && ignora == em_incluso && is_nota_variazione(alleg))
|
||
{
|
||
const int anno = alleg.get_int(ALL_ANNO);
|
||
const real importo = abs(alleg.get_real(ALL_IMPORTO));
|
||
if (importo < importo_limite(anno))
|
||
ignora = segnala_riga(alleg, em_importo_limite, log);
|
||
else
|
||
{
|
||
const TDate datarett = alleg.get(ALL_DATARETT);
|
||
if (datarett.year() != anno)
|
||
return segnala_riga(alleg, em_data_limite, log); // Non posso fare la add con DATARETT errata
|
||
|
||
const TString& nr = alleg.get(ALL_NUMRETT);
|
||
if (nr.blank() || nr == INVALID_NUMDOC)
|
||
return segnala_riga(alleg, em_altro, log); // Non posso fare la add in assenza di NUMRETT
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!send_all && ignora != em_incluso)
|
||
return ignora;
|
||
|
||
// Creo un nuovo record
|
||
_data.add(alleg);
|
||
return em_incluso;
|
||
}
|
||
|
||
void TDati_rilevanti_array::add(const TArray& note, bool send_all, TLog_report& log)
|
||
{
|
||
FOR_EACH_ARRAY_ITEM(note, t, obj)
|
||
{
|
||
const TRectype& nota = *(const TRectype*)obj;
|
||
add(nota, send_all, log);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TCofi_cache
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TCofi_cache : public TCache
|
||
{
|
||
TLocalisamfile _clifo, _occas;
|
||
|
||
protected:
|
||
virtual TObject* key2obj(const char* key);
|
||
|
||
public:
|
||
const TString& cofi2ragsoc(char tipocf, const TString& cofi);
|
||
const TString& paiv2ragsoc(char tipocf, const TString& paiv);
|
||
TCofi_cache() : _clifo(LF_CLIFO), _occas(LF_OCCAS) { }
|
||
};
|
||
|
||
TObject* TCofi_cache::key2obj(const char* key)
|
||
{
|
||
TToken_string chiave(key);
|
||
const int fkey = chiave.get_char(0)=='C' ? 4 : 5;
|
||
const TString4 tipocf = chiave.get();
|
||
const TString16 code= chiave.get();
|
||
|
||
_clifo.setkey(fkey);
|
||
_clifo.zero();
|
||
_clifo.put(CLI_TIPOCF, tipocf);
|
||
if (fkey == 5)
|
||
_clifo.put(CLI_PAIV, code);
|
||
else
|
||
_clifo.put(CLI_COFI, code);
|
||
|
||
int err = _clifo.read();
|
||
if (err != NOERR && fkey == 5 && pi_check("IT", code))
|
||
{
|
||
_clifo.put(CLI_TIPOCF, tipocf);
|
||
_clifo.put(CLI_STATOPAIV, "IT");
|
||
_clifo.put(CLI_PAIV, code);
|
||
err = _clifo.read();
|
||
}
|
||
|
||
if (err == NOERR)
|
||
return new TString80(_clifo.get(CLI_RAGSOC));
|
||
|
||
if (fkey == 5 && !pi_check("IT", code)) // cerco partite IVA estere
|
||
{
|
||
TString query;
|
||
query << "USE CLIFO SELECT PAIV=\"" << code << '"'
|
||
<< "\nFROM TIPOCF=" << tipocf
|
||
<< "\nTO TIPOCF=" << tipocf;
|
||
TISAM_recordset clifo(query);
|
||
if (clifo.move_first())
|
||
return new TString80(clifo.get(CLI_RAGSOC).as_string());
|
||
}
|
||
|
||
_occas.put(OCC_CFPI, code);
|
||
if (_occas.read() == NOERR)
|
||
{
|
||
const TString& cfpi = _occas.get(fkey == 4 ? OCC_COFI : OCC_PAIV);
|
||
if (code == cfpi || cfpi.empty())
|
||
return new TString80(_occas.get(OCC_RAGSOC));
|
||
}
|
||
|
||
TString query;
|
||
query << "USE OCCAS SELECT ";
|
||
if (fkey == 4)
|
||
query << "COFI=\"" << code << '"';
|
||
else
|
||
query << "PAIV=\"" << code << '"';
|
||
TISAM_recordset occas(query);
|
||
if (occas.move_first())
|
||
return new TString80(occas.get(OCC_RAGSOC).as_string());
|
||
|
||
return NULL;
|
||
}
|
||
|
||
const TString& TCofi_cache::cofi2ragsoc(char tipocf, const TString& cofi)
|
||
{
|
||
TString80 key;
|
||
key.format("CF|%c|%s", tipocf, (const char*)cofi);
|
||
const TString* ragsoc = (const TString*)objptr(key);
|
||
return ragsoc != NULL ? *ragsoc : EMPTY_STRING;
|
||
}
|
||
|
||
const TString& TCofi_cache::paiv2ragsoc(char tipocf, const TString& paiv)
|
||
{
|
||
TString80 key;
|
||
key.format("PI|%c|%s", tipocf, (const char*)paiv);
|
||
const TString* ragsoc = (const TString*)objptr(key);
|
||
return ragsoc != NULL ? *ragsoc : EMPTY_STRING;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TDati_rilevanti_rep
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TDati_rilevanti_rep : public TReport
|
||
{
|
||
TCofi_cache _cofi;
|
||
|
||
protected:
|
||
const TString& cofi2ragsoc(char tipocf, const TString& cofi) const
|
||
{ return ((TDati_rilevanti_rep*)this)->_cofi.cofi2ragsoc(tipocf, cofi); }
|
||
|
||
const TString& paiv2ragsoc(char tipocf, const TString& cofi) const
|
||
{ return ((TDati_rilevanti_rep*)this)->_cofi.paiv2ragsoc(tipocf, cofi); }
|
||
|
||
virtual bool get_usr_val(const TString& name, TVariant& var) const;
|
||
|
||
public:
|
||
TDati_rilevanti_rep(const TFilename& file);
|
||
};
|
||
|
||
bool TDati_rilevanti_rep::get_usr_val(const TString& name, TVariant& var) const
|
||
{
|
||
const TDati_rilevanti_set& set = *(TDati_rilevanti_set*)recordset();
|
||
const int tipo = set.rec_type()[0] - '0';
|
||
|
||
if (name == "ANNO")
|
||
{
|
||
var.set(set.anno());
|
||
return true;
|
||
}
|
||
if (name == "TIPO")
|
||
{
|
||
var.set(tipo);
|
||
return true;
|
||
}
|
||
if (name == "COFI")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 1: var = set.get("1.2"); break;
|
||
case 4: var = set.get("4.3"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "PAIV")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 2: var = set.get("2.2"); break;
|
||
case 4: var = set.get("4.2"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "RAGSOC")
|
||
{
|
||
char tipocf = 'C';
|
||
switch (tipo)
|
||
{
|
||
case 2: if (set.get("2.8").as_int() == 2) tipocf = 'F'; break;
|
||
default: break;
|
||
};
|
||
switch (tipo)
|
||
{
|
||
case 1: var = cofi2ragsoc(tipocf, set.get("1.2").as_string()); break;
|
||
case 2: var = paiv2ragsoc(tipocf, set.get("2.2").as_string()); break;
|
||
case 3:
|
||
var = set.get("3.8");
|
||
if (var.is_empty())
|
||
{
|
||
TString80 rs;
|
||
rs << set.get("3.2") << ' ' << set.get("3.3");
|
||
var = rs.trim();
|
||
}
|
||
break;
|
||
case 4:
|
||
{
|
||
const TString16 paiv = set.get("4.2").as_string();
|
||
if (paiv.full())
|
||
{
|
||
var = paiv2ragsoc('C', paiv);
|
||
if (var.is_empty())
|
||
var = paiv2ragsoc('F', paiv);
|
||
}
|
||
else
|
||
{
|
||
const TString16 cofi = set.get("4.3").as_string();
|
||
var = cofi2ragsoc('C', cofi);
|
||
if (var.is_empty())
|
||
var = paiv2ragsoc('F', cofi);
|
||
}
|
||
}
|
||
break;
|
||
case 5:
|
||
var = set.get("5.8");
|
||
if (var.is_empty())
|
||
{
|
||
TString80 rs;
|
||
rs << set.get("5.2") << ' ' << set.get("5.3");
|
||
var = rs.trim();
|
||
}
|
||
break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "DATAREG")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 1: var = set.get("1.3"); break;
|
||
case 2: var = set.get("2.3"); break;
|
||
case 3: var = set.get("3.12"); break;
|
||
case 4: var = set.get("4.4"); break;
|
||
case 5: var = set.get("5.12"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "NUMDOC")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 2: var = set.get("2.4"); break;
|
||
case 3: var = set.get("3.13"); break;
|
||
case 4: var = set.get("4.5"); break;
|
||
case 5: var = set.get("5.13"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "IMPORTO")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 1: var = set.get("1.5"); break;
|
||
case 2: var = set.get("2.6"); break;
|
||
case 3: var = set.get("3.15"); break;
|
||
case 4: var = set.get("4.6"); break;
|
||
case 5: var = set.get("5.14"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "IMPOSTA")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 2: var = set.get("2.7"); break;
|
||
case 3: var = set.get("3.16"); break;
|
||
case 4: var = set.get("4.7"); break;
|
||
case 5: var = set.get("5.15"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "DATARETT")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 4: var = set.get("4.8"); break;
|
||
case 5: var = set.get("5.16"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "NUMRETT")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 4: var = set.get("4.9"); break;
|
||
case 5: var = set.get("5.17"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "SIMPORTO")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 4: var = set.get("4.10"); break;
|
||
case 5: var = set.get("5.18"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "SIMPOSTA")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 4: var = set.get("4.11"); break;
|
||
case 5: var = set.get("5.19"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "MODPAG")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 1: var = set.get("1.4"); break;
|
||
case 2: var = set.get("2.5"); break;
|
||
case 3: var = set.get("3.14"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
if (name == "TIPOPE")
|
||
{
|
||
switch (tipo)
|
||
{
|
||
case 2: var = set.get("2.8"); break;
|
||
case 3: var = set.get("3.17"); break;
|
||
default: var.set_null(); break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
return TReport::get_usr_val(name, var);
|
||
}
|
||
|
||
TDati_rilevanti_rep::TDati_rilevanti_rep(const TFilename& file)
|
||
{
|
||
load("fe0100");
|
||
|
||
TDati_rilevanti_set* set = new TDati_rilevanti_set(file);
|
||
|
||
// Elimina testata e coda
|
||
set->destroy(0);
|
||
set->destroy(set->items()-1);
|
||
|
||
set_recordset(set);
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TDati_rilevanti_msk
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TDati_rilevanti_msk : public TAutomask
|
||
{
|
||
TMaskmode _mode;
|
||
bool _sheet_dirty;
|
||
TExclusion_mode _why;
|
||
TLog_report* _log;
|
||
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
void alleg_sort(TSheet_field& s) const;
|
||
void load_sheet();
|
||
bool save_sheet();
|
||
bool save_if_dirty();
|
||
void set_dirty(bool d = true);
|
||
|
||
bool send_nota_variazione(const TRectype& alleg, TDati_rilevanti_set& operaz);
|
||
bool send_fatt(const TRectype& alleg, TDati_rilevanti_set& operaz);
|
||
void build_outname(TFilename& n) const;
|
||
|
||
protected:
|
||
TRecnotype last_user_progr() const;
|
||
TRecnotype nuovo_progr() const;
|
||
bool check_rows(bool show_error);
|
||
void enable_buttons();
|
||
|
||
bool send_rec(const TRectype& alleg, TDati_rilevanti_set& operaz);
|
||
TExclusion_mode segnala_movimento(const TRectype& mov, TExclusion_mode motivo);
|
||
|
||
bool fattura_associata(long numreg_var, TDate& datafatt, TString& numdoc) const;
|
||
bool controlla_mov(TRectype& mrec) const;
|
||
bool azzera_alleg(TAssoc_array& manuali) const;
|
||
void collega_variazioni() const;
|
||
|
||
public:
|
||
TRecnotype genera_alleg();
|
||
bool elabora_alleg();
|
||
bool send_alleg();
|
||
bool recall_alleg() const;
|
||
|
||
TExclusion_mode elabora_movimento(const TRectype& mov, TBaseisamfile& falleg);
|
||
|
||
bool salva_allegato(const TRectype& mov, TBaseisamfile& 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);
|
||
msg << mode2string(motivo);
|
||
_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_no_allegato);
|
||
|
||
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);
|
||
|
||
return validate_clifo(mov);
|
||
}
|
||
|
||
bool TDati_rilevanti_msk::fattura_associata(long numreg_var, TDate& datafatt, TString& numdoc) const
|
||
{
|
||
long numreg_fatt = 0;
|
||
if (main_app().has_module(SCAUT))
|
||
{
|
||
TLocalisamfile partite(LF_PARTITE);
|
||
partite.setkey(2);
|
||
TRectype& part = partite.curr();
|
||
part.put(PART_NREG, numreg_var);
|
||
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
|
||
{
|
||
datafatt = riga.get(PART_DATAREG);
|
||
numdoc = riga.get(PART_NUMDOC);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return numdoc.full();
|
||
}
|
||
|
||
TExclusion_mode TDati_rilevanti_msk::elabora_movimento(const TRectype& mov, TBaseisamfile& falleg)
|
||
{
|
||
validate_mov(mov);
|
||
|
||
const char tipocf = mov.get_char(MOV_TIPO);
|
||
const long codcf = mov.get_long(MOV_CODCF);
|
||
const TString4 tipodoc = mov.get(MOV_TIPODOC);
|
||
const TDate datareg = mov.get_date(MOV_DATAREG);
|
||
const int anno = get_int(F_ANNO);
|
||
|
||
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;
|
||
|
||
// 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;
|
||
}
|
||
|
||
const int modpag = mov.get_int(MOV_MODPAG);
|
||
if (modpag == 1 && _why == em_incluso)
|
||
{
|
||
// Considera solo registrazioni con importo rilevante
|
||
if (abs(tot_imponibile) < importo_limite(anno))
|
||
_why = em_importo_limite; // Non segnalare migliaia di movimenti inutilmente
|
||
}
|
||
|
||
const long numreg = mov.get_long(MOV_NUMREG);
|
||
|
||
// Registro tutti i dati del cliente e gli importi
|
||
falleg.zero();
|
||
falleg.put(ALL_ANNO, anno);
|
||
falleg.put(ALL_PROGR, numreg);
|
||
falleg.put(ALL_IGNORA, int(_why));
|
||
falleg.put(ALL_TIPOCF, tipocf);
|
||
falleg.put(ALL_CODCF, codcf);
|
||
falleg.put(ALL_OCFPI, mov.get(MOV_OCFPI));
|
||
falleg.put(ALL_DATAREG, mov.get(MOV_DATAREG));
|
||
falleg.put(ALL_NUMDOC, mov.get(MOV_NUMDOC));
|
||
falleg.put(ALL_TIPOPE, tipocf == 'C' ? 1 : 2);
|
||
falleg.put(ALL_IMPORTO, tot_imponibile);
|
||
falleg.put(ALL_IMPOSTA, tot_imposta);
|
||
falleg.put(ALL_MODPAG, modpag);
|
||
if (modpag == 1)
|
||
{
|
||
falleg.put(ALL_DATARETT, mov.get(MOV_DATARETT));
|
||
falleg.put(ALL_NUMRETT, mov.get(MOV_NUMRETT));
|
||
}
|
||
else
|
||
falleg.put(ALL_CONTRATTO, mov.get(MOV_CONTRATTO));
|
||
|
||
const int err = falleg.rewrite_write();
|
||
if (err != NOERR)
|
||
{
|
||
TString msg;
|
||
msg.format(FR("Errore %d di aggiornamento del record %d/%ld sul file %s"),
|
||
err, anno, numreg, (const char*)falleg.name());
|
||
_log->log(2, msg);
|
||
}
|
||
|
||
return _why;
|
||
}
|
||
|
||
// Test di coerenza tra MODPAG, CONTRATTO e NUMRETT
|
||
bool TDati_rilevanti_msk::controlla_mov(TRectype& mrec) const
|
||
{
|
||
const long numreg = mrec.get_long(MOV_NUMREG);
|
||
TString80 contratto = mrec.get(MOV_CONTRATTO);
|
||
|
||
int old_modpag = mrec.get_int(MOV_MODPAG);
|
||
int new_modpag = 1;
|
||
|
||
bool update = false;
|
||
|
||
if (is_nota_variazione(mrec))
|
||
{
|
||
TDate datarett = mrec.get(MOV_DATARETT);
|
||
TString8 numrett = mrec.get(MOV_NUMRETT);
|
||
if (contratto.full())
|
||
{
|
||
mrec.put(MOV_CONTRATTO, contratto.cut(0));
|
||
update = true; // Peccato veniale
|
||
}
|
||
if (numrett.blank())
|
||
{
|
||
if (!fattura_associata(numreg, datarett, numrett))
|
||
numrett = INVALID_NUMDOC;
|
||
mrec.put(MOV_DATARETT, datarett);
|
||
mrec.put(MOV_NUMRETT, numrett);
|
||
update = true;
|
||
}
|
||
const TAnagrafica a(mrec);
|
||
TString msg;
|
||
if (numrett != INVALID_NUMDOC)
|
||
{
|
||
msg.format(FR("Nota n. %ld di %s associata al doc. %s del %s"),
|
||
numreg, (const char*)a.ragione_sociale(), (const char*)numrett, datarett.string());
|
||
_log->log(0, msg);
|
||
}
|
||
else
|
||
{
|
||
msg.format(FR("Nota n. %ld di %s non associata ad una fattura"),
|
||
numreg, (const char*)a.ragione_sociale());
|
||
_log->log(1, msg);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (contratto.full())
|
||
{
|
||
const TContratto c(mrec);
|
||
new_modpag = c.modalita_pagamento();
|
||
}
|
||
if (get(MOV_NUMRETT).full() || get(MOV_DATARETT).full())
|
||
{
|
||
mrec.zero(MOV_DATARETT);
|
||
mrec.zero(MOV_NUMRETT);
|
||
update = true; // Peccato veniale
|
||
}
|
||
}
|
||
if (old_modpag != new_modpag)
|
||
{
|
||
if (old_modpag > 0) // I vecchi movimenti hanno per forza 0: li perdoniamo!
|
||
{
|
||
const TAnagrafica a(mrec);
|
||
TString msg;
|
||
msg.format(FR("Movimento n. %ld di %s con modalit<69> di pagamento incongruente: %d->%d"),
|
||
numreg, (const char*)a.ragione_sociale(), old_modpag, new_modpag);
|
||
_log->log(0, msg);
|
||
}
|
||
mrec.put(MOV_MODPAG, new_modpag);
|
||
update = true;
|
||
}
|
||
|
||
return update;
|
||
}
|
||
|
||
bool TDati_rilevanti_msk::azzera_alleg(TAssoc_array& manuali) const
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
const TDate data = get(F_DATA);
|
||
|
||
TFast_isamfile fast_alleg(LF_ALLEG);
|
||
TFast_isamfile fast_mov(LF_MOV);
|
||
|
||
TString query;
|
||
query << "USE " << LF_ALLEG
|
||
<< "\nJOIN MOV INTO NUMREG==PROGR"
|
||
<< "\nFROM ANNO=" << anno
|
||
<< "\nTO ANNO=" << anno << " PROGR=" << MANUAL_ROW;
|
||
TISAM_recordset alleg(query);
|
||
|
||
TLocalisamfile& falleg = alleg.cursor()->file();
|
||
TRectype& arec = falleg.curr();
|
||
|
||
TLocalisamfile& fmov = alleg.cursor()->file(LF_MOV);
|
||
TRectype& mrec = fmov.curr();
|
||
|
||
TString msg; msg << TR("Azzeramento ") << falleg.description() << ' ' << anno;
|
||
TProgind pi(alleg.items(), msg, false);
|
||
|
||
manuali.destroy();
|
||
for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
|
||
{
|
||
pi.addstatus(1);
|
||
|
||
const long progr = arec.get_long(ALL_PROGR);
|
||
const long numreg = mrec.get_long(MOV_NUMREG);
|
||
const TDate datareg = mrec.get_long(MOV_DATAREG);
|
||
const int annoiva = mrec.get_long(MOV_ANNOIVA);
|
||
|
||
bool kill = numreg != progr || annoiva < anno;
|
||
if (!kill)
|
||
{
|
||
const bool forzata = arec.get_bool(ALL_FORZATURA);
|
||
if (forzata)
|
||
manuali.add(arec.get(ALL_PROGR));
|
||
else
|
||
kill = annoiva == data.year() && datareg > data;
|
||
}
|
||
if (kill)
|
||
falleg.remove(); // Riga generata dalla vecchia versione
|
||
}
|
||
return !manuali.empty();
|
||
}
|
||
|
||
// 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 > progr)
|
||
progr = sheet_progr;
|
||
}
|
||
}
|
||
|
||
return progr+1;
|
||
}
|
||
|
||
static int sort_alleg(const TSortable& s1, const TSortable& s2, void* jolly)
|
||
{
|
||
const TRectype& a1 = (const TRectype&)s1;
|
||
const TRectype& a2 = (const TRectype&)s2;
|
||
|
||
const TString& c1 = a1.get(ALL_CONTRATTO);
|
||
const TString& c2 = a2.get(ALL_CONTRATTO);
|
||
int cmp = c1.compare(c2, -1, true);
|
||
|
||
if (cmp == 0 && c1.blank())
|
||
{
|
||
const int n1 = is_nota_variazione(a1);
|
||
const int n2 = is_nota_variazione(a2);
|
||
cmp = n1 - n2;
|
||
}
|
||
|
||
if (cmp == 0)
|
||
{
|
||
const TDate d1 = a1.get(ALL_DATAREG);
|
||
const TDate d2 = a2.get(ALL_DATAREG);
|
||
cmp = d1 - d2;
|
||
}
|
||
|
||
return cmp;
|
||
}
|
||
|
||
TRecnotype TDati_rilevanti_msk::genera_alleg()
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
const TDate data_estrazione = get(F_DATA);
|
||
|
||
TString str_pi;
|
||
str_pi << TR("Movimenti ") << anno;
|
||
_log = new TLog_report(str_pi);
|
||
|
||
TAssoc_array manuali;
|
||
azzera_alleg(manuali);
|
||
|
||
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," << data_estrazione.date2ansi() << ")"
|
||
<< "\nFROM TIPO=C\nTO TIPO=F";
|
||
TISAM_recordset mov(query);
|
||
TRectype& mov_rec = mov.cursor()->curr();
|
||
const TRecnotype items = mov.items();
|
||
|
||
TProgind pi(items, str_pi);
|
||
for (bool ok = mov.move_first(); ok; ok = mov.move_next())
|
||
{
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
_why = em_incluso;
|
||
|
||
const int annofe = mov_rec.get_int(MOV_ANNOFE);
|
||
if (annofe >= 2010) // Non elaborae i movimenti gia' inviati in definitivo!
|
||
{
|
||
segnala_movimento(mov_rec, em_inviato);
|
||
continue;
|
||
}
|
||
|
||
const TString& key = mov_rec.get(MOV_NUMREG);
|
||
if (manuali.is_key(key))
|
||
{
|
||
manuali.remove(key);
|
||
continue;
|
||
}
|
||
|
||
controlla_mov(mov_rec);
|
||
if (is_nota_variazione(mov_rec))
|
||
{
|
||
const TDate datarett = mov_rec.get(MOV_DATARETT);
|
||
if (!datarett.ok() || datarett.year() == anno)
|
||
elabora_movimento(mov_rec, falleg); // Elabora nota di variazione
|
||
}
|
||
else
|
||
{
|
||
const TDate datareg = mov_rec.get(MOV_DATAREG);
|
||
if (datareg.year() == anno) // Scarta fatture dell'anno dopo
|
||
elabora_movimento(mov_rec, falleg);
|
||
}
|
||
}
|
||
}
|
||
collega_variazioni();
|
||
|
||
_log->preview();
|
||
delete _log;
|
||
_log = NULL;
|
||
|
||
return nprog;
|
||
}
|
||
|
||
void TDati_rilevanti_msk::collega_variazioni() const
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
TString query;
|
||
query << "USE ALLEG KEY 2 SELECT IGNORA<=" << int(em_importo_limite);
|
||
query << "\nJOIN ALLEG KEY 3 ALIAS 220 INTO ANNO=ANNO TIPOCF=TIPOCF CODCF==CODCF NUMRETT=NUMDOC";
|
||
query << "\nFROM ANNO=" << anno << "\nTO ANNO=" << anno;
|
||
TISAM_recordset fatture(query);
|
||
|
||
TProgind pi(fatture.items(), TR("Collegamento note di variazione"), false, true);
|
||
TRelation& rel = *fatture.cursor()->relation();
|
||
|
||
for (bool ok = fatture.move_first(); ok; ok = fatture.move_next())
|
||
{
|
||
pi.addstatus(1);
|
||
if (rel.is_first_match(-220))
|
||
{
|
||
real importo = fatture.get(ALL_IMPORTO).as_real();
|
||
for (bool ok = true; ok; ok = rel.next_match(-220))
|
||
importo += rel.curr(-220).get_real(ALL_IMPORTO);
|
||
|
||
const TExclusion_mode old_mode = TExclusion_mode(fatture.get(ALL_IGNORA).as_int());
|
||
const TExclusion_mode new_mode = importo < importo_limite(anno) ? em_importo_limite : em_incluso;
|
||
if (old_mode != new_mode)
|
||
{
|
||
TLocalisamfile& f = fatture.cursor()->file();
|
||
f.put(ALL_IGNORA, new_mode);
|
||
f.rewrite();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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();
|
||
return prog > 1;
|
||
}
|
||
|
||
bool TDati_rilevanti_msk::send_nota_variazione(const TRectype& alleg, TDati_rilevanti_set& operaz)
|
||
{
|
||
real imponibile = alleg.get_real(ALL_IMPORTO);
|
||
real imposta = alleg.get_real(ALL_IMPOSTA);
|
||
if (imponibile.is_zero() && imposta.is_zero())
|
||
return false;
|
||
|
||
const TAnagrafica anag(alleg);
|
||
if (!anag.ok())
|
||
return false;
|
||
|
||
const char tipocf = alleg.get_char(ALL_TIPOCF);
|
||
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, anag.indirizzo_residenza());
|
||
}
|
||
operaz.set(12, alleg.get(ALL_DATAREG));
|
||
operaz.set(13, alleg.get(ALL_NUMDOC));
|
||
operaz.set(14, imponibile);
|
||
operaz.set(15, imposta);
|
||
operaz.set(16, alleg.get(ALL_DATARETT));
|
||
operaz.set(17, alleg.get(ALL_NUMRETT));
|
||
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, alleg.get(ALL_NUMDOC));
|
||
operaz.set(6, imponibile);
|
||
operaz.set(7, imposta);
|
||
operaz.set(8, alleg.get(ALL_DATARETT));
|
||
operaz.set(9, alleg.get(ALL_NUMRETT));
|
||
operaz.set(10, segno_imponibile);
|
||
operaz.set(11, segno_imposta);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TDati_rilevanti_msk::send_fatt(const TRectype& alleg, TDati_rilevanti_set& operaz)
|
||
{
|
||
const real importo = alleg.get_real(ALL_IMPORTO);
|
||
const real imposta = alleg.get_real(ALL_IMPOSTA);
|
||
if (importo.is_zero() && imposta.is_zero())
|
||
return false;
|
||
|
||
const TAnagrafica anag(alleg);
|
||
if (!anag.ok())
|
||
return false;
|
||
|
||
const TString& paiv = anag.partita_IVA();
|
||
|
||
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());
|
||
if (anag.comune_residenza().empty())
|
||
operaz.set(9, anag.localita_residenza());
|
||
else
|
||
operaz.set(9, anag.comune_residenza());
|
||
operaz.set(10, anag.stato_estero());
|
||
operaz.set(11, anag.indirizzo_residenza());
|
||
}
|
||
operaz.set(12, alleg.get(ALL_DATAREG));
|
||
operaz.set(13, alleg.get(ALL_NUMDOC));
|
||
operaz.set(14, alleg.get(ALL_MODPAG));
|
||
operaz.set(15, importo);
|
||
operaz.set(16, imposta);
|
||
operaz.set(17, alleg.get(ALL_TIPOPE));
|
||
}
|
||
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));
|
||
operaz.set(4, alleg.get(ALL_MODPAG));
|
||
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));
|
||
operaz.set(4, alleg.get(ALL_NUMDOC));
|
||
operaz.set(5, alleg.get(ALL_MODPAG));
|
||
operaz.set(6, alleg.get(ALL_IMPORTO));
|
||
operaz.set(7, alleg.get(ALL_IMPOSTA));
|
||
operaz.set(8, alleg.get(ALL_TIPOPE));
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TDati_rilevanti_msk::send_rec(const TRectype& alleg, TDati_rilevanti_set& operaz)
|
||
{
|
||
bool done = false;
|
||
if (is_nota_variazione(alleg))
|
||
done = send_nota_variazione(alleg, operaz);
|
||
else
|
||
done = send_fatt(alleg, operaz);
|
||
return done;
|
||
}
|
||
|
||
bool TDati_rilevanti_msk::recall_alleg() const
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
if (!yesno_box(FR("Si desidera annullare l'invio definitivo dei movimenti del %d?"), anno))
|
||
return false;
|
||
|
||
TFast_isamfile mov(LF_MOV);
|
||
|
||
TString query;
|
||
query << "USE MOV KEY 2 SELECT ANNOFE=" << anno;
|
||
query << "\nFROM DATAREG=01-01-" << anno;
|
||
TISAM_recordset recset(query);
|
||
TLocalisamfile& file = recset.cursor()->file();
|
||
|
||
TProgind pi(recset.items(), TR("Aggiornamento movimenti di prima nota"));
|
||
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
|
||
{
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
file.zero(MOV_ANNOFE);
|
||
file.rewrite();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void TDati_rilevanti_msk::build_outname(TFilename& n) const
|
||
{
|
||
n = get(F_OUTFOLDER);
|
||
if (n.blank())
|
||
n.tempdir();
|
||
|
||
TString16 f; f.format("Spesometro%05d", prefix().get_codditta());
|
||
n.add(f);
|
||
n.ext("txt");
|
||
}
|
||
|
||
// Genera file per invio telematico
|
||
bool TDati_rilevanti_msk::send_alleg()
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
const bool send_all = get_int(F_SENDALL) != 1;
|
||
|
||
TFilename temp; build_outname(temp);
|
||
|
||
TDati_rilevanti_array data;
|
||
|
||
TString query;
|
||
query << "USE ALLEG KEY 2"
|
||
<< "\nFROM " << ALL_ANNO << '=' << anno
|
||
<< "\nTO " << ALL_ANNO << '=' << anno;
|
||
|
||
TISAM_recordset alleg(query);
|
||
const TRecnotype tot_alleg = alleg.items();
|
||
|
||
if (tot_alleg > 0)
|
||
{
|
||
_log = new TLog_report(temp);
|
||
|
||
const TRectype& rec = alleg.cursor()->curr();
|
||
|
||
TString16 last_clifo;
|
||
TArray note;
|
||
|
||
TProgind pi(tot_alleg, TR("Elaborazione file"));
|
||
for (bool ok = alleg.move_first(); ok; ok = alleg.move_next())
|
||
{
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
|
||
TString16 clifo = rec.get(ALL_OCFPI);
|
||
if (clifo.blank())
|
||
clifo = rec.get(ALL_CODCF);
|
||
|
||
if (clifo != last_clifo)
|
||
{
|
||
data.add(note, send_all, *_log);
|
||
note.destroy();
|
||
last_clifo = clifo;
|
||
}
|
||
|
||
if (is_nota_variazione(rec))
|
||
note.add(rec);
|
||
else
|
||
data.add(rec, send_all, *_log);
|
||
}
|
||
data.add(note, send_all, *_log);
|
||
|
||
if (_log->recordset()->items())
|
||
_log->preview();
|
||
delete _log;
|
||
_log = NULL;
|
||
}
|
||
|
||
TDati_rilevanti_set recset(anno);
|
||
recset.add_header(*this);
|
||
|
||
const int tot = data.items();
|
||
if (tot > 0)
|
||
{
|
||
TProgind pi(tot, TR("Generazione file per Agenzia delle Entrate"));
|
||
for (int a = 0; a < tot; a++)
|
||
{
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
if (send_all || !data[a].get_int(ALL_IGNORA))
|
||
send_rec(data[a], recset);
|
||
}
|
||
}
|
||
|
||
recset.add_footer();
|
||
recset.sort();
|
||
bool done = recset.save_as(temp);
|
||
|
||
const long maxalleg = get_long(F_MAXREC);
|
||
if (recset.items() > maxalleg)
|
||
done = recset.split(temp, maxalleg);
|
||
|
||
if (done && get_bool(F_DEFINITIVO) && yesno_box(TR("Si desidera confermare l'invio definitivo della comunicazione?")))
|
||
{
|
||
TFast_isamfile mov(LF_MOV);
|
||
TProgind pi(data.items(), TR("Aggiornamento movimenti di prima nota"), false);
|
||
for (int i = data.items()-1; i >= 0; i--)
|
||
{
|
||
pi.addstatus(1);
|
||
const TRectype& alleg = data[i];
|
||
const long numreg = alleg.get_long(ALL_PROGR);
|
||
const int ignora = alleg.get_int(ALL_IGNORA);
|
||
if (numreg > 0 && numreg < MANUAL_ROW && !ignora)
|
||
{
|
||
mov.put(MOV_NUMREG, numreg);
|
||
int err = mov.read(_isequal, _lock);
|
||
if (err == NOERR)
|
||
{
|
||
const int modpag = alleg.get_int(ALL_MODPAG);
|
||
mov.put(MOV_MODPAG, modpag);
|
||
if (modpag < 2)
|
||
{
|
||
const TString& nr = alleg.get(ALL_NUMRETT);
|
||
if (nr.full() && nr != INVALID_NUMDOC)
|
||
{
|
||
mov.put(MOV_DATARETT, alleg.get(ALL_DATARETT));
|
||
mov.put(MOV_NUMRETT, nr);
|
||
}
|
||
}
|
||
else
|
||
mov.put(MOV_CONTRATTO, alleg.get(ALL_CONTRATTO));
|
||
mov.put(MOV_ANNOFE, anno);
|
||
err = mov.rewrite();
|
||
}
|
||
if (err != NOERR)
|
||
{
|
||
error_box(FR("Impossibile aggiornare il movimento %ld: errore %d"), numreg, err);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return done;
|
||
}
|
||
|
||
void TDati_rilevanti_msk::set_dirty(bool d)
|
||
{
|
||
_sheet_dirty = d;
|
||
enable(DLG_SAVEREC, d);
|
||
}
|
||
|
||
void TDati_rilevanti_msk::alleg_sort(TSheet_field& s) const
|
||
{
|
||
const int c_codcf = s.cid2index(A_CODCF);
|
||
const int c_numdoc = s.cid2index(A_NUMDOC);
|
||
const int c_numrett = s.cid2index(A_NUMRETT);
|
||
const int c_forzata = s.cid2index(A_FORZATA);
|
||
const int c_ignora = s.cid2index(A_IGNORA);
|
||
const int c_importo = s.cid2index(A_IMPORTO);
|
||
const int tot = s.items();
|
||
|
||
for (int k = 0; k < 2; k++)
|
||
for (int i = tot-1; i >= 0; i--)
|
||
{
|
||
const TString8 numrett = s.cell(i, c_numrett);
|
||
if (numrett.full() && numrett != INVALID_NUMDOC)
|
||
{
|
||
const long codcf_i = atol(s.cell(i, c_codcf));
|
||
int j = -1;
|
||
|
||
// Cerca la fattura andando in su
|
||
for (j = i-1; j >= 0; j--)
|
||
{
|
||
const long codcf_j = atol(s.cell(j, c_codcf));
|
||
if (codcf_j != codcf_i)
|
||
{
|
||
j = -1;
|
||
break;
|
||
}
|
||
if (numrett == s.cell(j, c_numdoc) || numrett == s.cell(j, c_numrett))
|
||
break;
|
||
}
|
||
if (j < 0) // Non l'ho trovata
|
||
{
|
||
// Cerca la fattura andando in gi<67>
|
||
for (j = i+1; j < tot; j++)
|
||
{
|
||
const long codcf_j = atol(s.cell(j, c_codcf));
|
||
if (codcf_j != codcf_i)
|
||
{
|
||
j = tot;
|
||
break;
|
||
}
|
||
if (numrett == s.cell(j, c_numdoc))
|
||
break;
|
||
}
|
||
}
|
||
if (j >= 0 && j < tot) // L'ho trovata
|
||
{
|
||
s.move_row(i, j+1);
|
||
if (*s.cell(j, c_numrett) <= ' ')
|
||
s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, j, c_numdoc);
|
||
s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, j+1, c_numrett);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
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();
|
||
|
||
const int anno = get_int(F_ANNO);
|
||
|
||
TString limit; limit << ALL_ANNO << '=' << anno;
|
||
if (codcf > 0)
|
||
limit << ' ' << ALL_TIPOCF << '=' << tipocf << ' ' << ALL_CODCF << '=' << codcf;
|
||
|
||
TString sel;
|
||
if (ocfpi.full() || (show_all > 0 && show_all < 7))
|
||
{
|
||
if (ocfpi.full())
|
||
sel << "(" << ALL_OCFPI << "='" << ocfpi << "')";
|
||
if (show_all > 0 && show_all < 7)
|
||
{
|
||
if (sel.full()) sel << "&&";
|
||
sel << "(STR(" << ALL_IGNORA;
|
||
switch (show_all)
|
||
{
|
||
case 1: sel << '<'; break; // Importi superiori al limite (20000 o 3000)
|
||
case 2: sel << '='; break; // Importi inferiori al limite (20000 o 3000)
|
||
default: sel << '>'; break; // Importi scartati (esteri o leggi speciali)
|
||
}
|
||
sel << "1))";
|
||
}
|
||
}
|
||
|
||
TString query;
|
||
query << "USE " << LF_ALLEG << " KEY 2";
|
||
if (sel.full())
|
||
query << " SELECT " << sel;
|
||
if (limit.full())
|
||
query << "\nFROM " << limit << "\nTO " << limit;
|
||
|
||
TISAM_recordset alleg(query);
|
||
const TRecnotype items = alleg.items();
|
||
if (items > 0)
|
||
{
|
||
TString pi_str; pi_str << TR("Caricamento ") << items << TR(" movimenti del ") << 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);
|
||
|
||
const int modpag = curr.get_int(ALL_MODPAG);
|
||
if (modpag == 1)
|
||
s.enable_cell(rec-1, A_CONTRATTO, false);
|
||
else
|
||
{
|
||
s.enable_cell(rec-1, A_DATARETT, false);
|
||
s.enable_cell(rec-1, A_NUMRETT, false);
|
||
}
|
||
}
|
||
}
|
||
alleg_sort(s);
|
||
|
||
s.force_update();
|
||
s.show();
|
||
set_dirty(false);
|
||
|
||
if (s.items() > 0)
|
||
{
|
||
_mode = MODE_MOD;
|
||
disable(-1);
|
||
}
|
||
else
|
||
{
|
||
_mode = MODE_QUERY;
|
||
enable(-1);
|
||
}
|
||
enable_buttons();
|
||
}
|
||
|
||
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);
|
||
// Il tipo operazione non <20> pi<70> visibile, per cui lo calcolo ora
|
||
rec.put(ALL_TIPOPE, rec.get_char(ALL_TIPOCF) == 'F' ? 2 : 1);
|
||
const int err = alleg.rewrite_write();
|
||
if (err != NOERR)
|
||
{
|
||
done = cantwrite_box(alleg.name());
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (done)
|
||
{
|
||
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;
|
||
}
|
||
|
||
void TDati_rilevanti_msk::enable_buttons()
|
||
{
|
||
const int anno = get_int(F_ANNO);
|
||
const bool good_year = anno >= 2010;
|
||
const bool def = get_bool(F_DEFINITIVO);
|
||
const bool full_rows = !sfield(F_RIGHE).empty();
|
||
|
||
bool one_sent = false; // Ho spedito almeno un movimento in definitivo
|
||
if (good_year)
|
||
{
|
||
TString query;
|
||
query << "USE MOV KEY 2 SELECT ANNOFE=" << anno;
|
||
query << "\nFROM DATAREG=01-01-" << anno;
|
||
TISAM_recordset recset(query);
|
||
one_sent = recset.move_first();
|
||
}
|
||
|
||
enable(DLG_CANCEL, full_rows);
|
||
enable(DLG_EXPORT, full_rows);
|
||
enable(DLG_RECALC, !full_rows && good_year && !one_sent);
|
||
enable(DLG_ELABORA, good_year && !(one_sent && def));
|
||
enable(DLG_DELREC, one_sent);
|
||
enable(F_DEFINITIVO, !def);
|
||
if (def) reset(F_DEFINITIVO);
|
||
|
||
TFilename temp; build_outname(temp);
|
||
enable(DLG_PREVIEW, temp.exist());
|
||
}
|
||
|
||
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);
|
||
enable_buttons();
|
||
}
|
||
return false;
|
||
}
|
||
break;
|
||
case DLG_SAVEREC:
|
||
if (e == fe_button)
|
||
save_if_dirty();
|
||
break;
|
||
case DLG_EXPORT:
|
||
if (e == fe_button)
|
||
return sfield(F_RIGHE).esporta();
|
||
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();
|
||
enable_buttons(); // Disabilita bottone se definitivo
|
||
}
|
||
break;
|
||
case DLG_DELREC:
|
||
if (e == fe_button && jolly == 0 && o.active())
|
||
{
|
||
recall_alleg();
|
||
enable_buttons(); // Disabilita bottone
|
||
return false;
|
||
}
|
||
break;
|
||
case DLG_PREVIEW:
|
||
if (e == fe_button)
|
||
{
|
||
TFilename temp; build_outname(temp);
|
||
if (temp.exist())
|
||
{
|
||
TDati_rilevanti_rep rep(temp);
|
||
rep.preview();
|
||
}
|
||
}
|
||
break;
|
||
case F_ANNO:
|
||
if (e == fe_init || e == fe_modify)
|
||
{
|
||
int anno = atoi(o.get());
|
||
if (anno < 2010)
|
||
{
|
||
anno = TDate(TODAY).year()-1;
|
||
o.set(anno);
|
||
}
|
||
on_field_event(efield(F_DATA), fe_modify, jolly);
|
||
enable_buttons();
|
||
}
|
||
break;
|
||
case F_DATA:
|
||
if (e == fe_init || e == fe_modify)
|
||
{
|
||
const int anno = max(2010, get_int(F_ANNO));
|
||
TDate d = o.get();
|
||
if (d < TDate(31,12,anno) || d > TDate(31,12,anno+1))
|
||
{
|
||
if (anno == 2010)
|
||
d = TDate(31,12,2011);
|
||
else
|
||
d = TDate(30,4,anno+1);
|
||
set(F_DATA, d);
|
||
}
|
||
}
|
||
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_query_modify)
|
||
{
|
||
TSheet_field& s = (TSheet_field&)o;
|
||
TToken_string& row = s.row(jolly);
|
||
const TRecnotype progr = row.get_long(0);
|
||
s.sheet_mask().enable(DLG_DELREC, progr >= MANUAL_ROW);
|
||
s.sheet_mask().enable(DLG_USER, progr < MANUAL_ROW);
|
||
} else
|
||
if (e == se_notify_modify)
|
||
{
|
||
set_dirty( true);
|
||
TSheet_field& s = (TSheet_field&)o;
|
||
TToken_string& row = s.row(jolly);
|
||
row.add("X", s.cid2index(A_FORZATA));
|
||
} 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(1, s.cid2index(A_MODPAG));
|
||
} else
|
||
if (e == se_query_del)
|
||
{
|
||
TSheet_field& s = (TSheet_field&)o;
|
||
TToken_string& row = s.row(jolly);
|
||
const TRecnotype progr = row.get_long(0);
|
||
return progr >= MANUAL_ROW;
|
||
}
|
||
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 || e == fe_init)
|
||
{
|
||
const long numreg = o.mask().get_long(A_RIGA);
|
||
const bool enab = (numreg > 0 && numreg < MANUAL_ROW);
|
||
if (e == fe_button && enab)
|
||
{
|
||
TRectype mov(LF_MOV);
|
||
mov.put(MOV_NUMREG, numreg);
|
||
mov.edit();
|
||
}
|
||
else
|
||
o.enable(enab);
|
||
}
|
||
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()
|
||
{
|
||
// Controllo preventivo dell'avvenuta conversione del tracciato record
|
||
TRectype alleg(LF_ALLEG);
|
||
if (alleg.type(ALL_NUMDOC) == _nullfld)
|
||
return error_box(TR("Il database non <20> stato ancora convertito per il modulo FE"));
|
||
|
||
// Teoricamente <20> possibile visualizzare tutti i movimenti di un anno, per cui allargo il numero riga
|
||
TSheet_field::set_line_number_width(6);
|
||
|
||
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;
|
||
}
|