git-svn-id: svn://10.65.10.50/branches/R_10_00@22886 c028cbd2-c16b-5b4b-a496-9718f37d4682
1787 lines
49 KiB
C++
Executable File
1787 lines
49 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <form.h>
|
||
#include <automask.h>
|
||
#include <progind.h>
|
||
#include <recset.h>
|
||
#include <recarray.h>
|
||
#include <utility.h>
|
||
|
||
#include "777.h"
|
||
#include "777100a.h"
|
||
|
||
#include <anagr.h>
|
||
#include <anafis.h>
|
||
#include <anagiu.h>
|
||
#include <attiv.h>
|
||
#include <comuni.h>
|
||
#include <nditte.h>
|
||
#include "base.h"
|
||
#include "quadroc.h"
|
||
|
||
// Il nuovo quadro ST e' il vecchio quadro L
|
||
#define LF_QUADRO_ST LF_QUAL
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utility
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Codice fiscale di Sirio spa
|
||
#define CF_PRODUTTORE "04879210963"
|
||
|
||
const int ANNO_DIC = 2012;
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TRecord770;
|
||
class TTrasferimento770;
|
||
|
||
enum M770FieldType { AN, CF, CN, PI, DA, DT, NU, PN, PR, CB, VP, VN };
|
||
|
||
class TForm770 : public TForm
|
||
{
|
||
TCursor* _sortedcur;
|
||
|
||
int _index;
|
||
TArray _records;
|
||
TPointer_array _positions;
|
||
|
||
protected:
|
||
bool compatible(const TRectype& r1, const TRectype& r2);
|
||
void add_rec(TRectype& r1, const TRectype& r2);
|
||
|
||
long raggruppa_c();
|
||
int first();
|
||
int next();
|
||
|
||
void transfer_section(TPrint_section& body, int rigo,
|
||
TRecord770& rec, TTrasferimento770& file);
|
||
char log2rec(int num, int& rpm) const;
|
||
|
||
protected:
|
||
|
||
virtual TCursor* cursor() { return _sortedcur ? _sortedcur : TForm::cursor(); }
|
||
virtual bool validate(TForm_item &cf, TToken_string &s);
|
||
|
||
public:
|
||
TRecnotype trasfer(long codditta, TTrasferimento770& file, char tipo, int rpm);
|
||
|
||
TForm770(const char* name);
|
||
virtual ~TForm770();
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TRecord770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
enum { CODE_SIZE = 8, FIELD_SIZE = 16, BLOCK_SIZE = 24, HEADER_SIZE = 89, USEABLE_SIZE = 1800, TOTAL_SIZE = 1900 };
|
||
|
||
struct TField770 : public TObject
|
||
{
|
||
TString _desc;
|
||
int _pos; // Base 1
|
||
int _len;
|
||
M770FieldType _type; // AN,NU,...
|
||
};
|
||
|
||
class TTracciato770 : public TObject
|
||
{
|
||
char _tipo;
|
||
TArray _fields;
|
||
|
||
protected:
|
||
void add_field(const char* name, M770FieldType tipo, int pos, int len, int filedno = 0);
|
||
void add_filler(int pos, int len, M770FieldType tipo = AN)
|
||
{ add_field("Filler", tipo, pos, len); }
|
||
|
||
public:
|
||
const TField770& field(int pos) const;
|
||
void auto_fill(TString& buffer) const;
|
||
|
||
TTracciato770(char tipo);
|
||
virtual ~TTracciato770();
|
||
};
|
||
|
||
class TTracciati770 : public TObject
|
||
{
|
||
TArray _trc;
|
||
TAssoc_array _form;
|
||
bool _centesimi; // Salva importi in centesimi invece che in euro
|
||
|
||
public:
|
||
const TTracciato770& tracciato(char tipo);
|
||
TForm770& form(const char* quadro, char& tipo, int& rpm);
|
||
|
||
void destroy();
|
||
|
||
void set_cent_mode(bool cb) { _centesimi = cb; }
|
||
bool importi_in_centesimi() const { return _centesimi; }
|
||
bool importi_in_euro() const { return !_centesimi; }
|
||
|
||
TTracciati770();
|
||
virtual ~TTracciati770();
|
||
} _trc770;
|
||
|
||
class TCache770 : public TObject
|
||
{
|
||
TArray _files;
|
||
TAssoc_array _tables;
|
||
|
||
public:
|
||
const TRectype& get(int num, const char* key);
|
||
const TRectype& get(int num, long key);
|
||
void destroy();
|
||
|
||
TCache770() { }
|
||
virtual ~TCache770() { }
|
||
} _cache770;
|
||
|
||
class TRecord770 : public TObject
|
||
{
|
||
TString _buffer;
|
||
|
||
protected: // TObject
|
||
virtual TObject* dup() const { return new TRecord770(*this); }
|
||
virtual void print_on(ostream& outs) const;
|
||
virtual void read_from(istream& ins);
|
||
|
||
protected: // TObject
|
||
const TTracciato770& tracciato() const
|
||
{ return _trc770.tracciato(tipo_record()); }
|
||
|
||
const TField770& get_field(int pos) const
|
||
{ return tracciato().field(pos); }
|
||
|
||
void set(const TField770& fld, const char* val);
|
||
int calculate_blocks(const char* val) const;
|
||
|
||
public:
|
||
void set(int pos, const char* val);
|
||
void set(int pos, int val);
|
||
void set(int pos, long val);
|
||
void set(int pos, const real& val);
|
||
void set(int pos, const TDate& val);
|
||
void set(int pos, char val);
|
||
void set(int pos, bool val);
|
||
bool np_put(const char* code, const char* val);
|
||
bool np_put(const char* code, const real& val);
|
||
bool np_put(const char* code, long val);
|
||
|
||
const char* get(int pos, TString& str) const;
|
||
int get_int(int pos) const;
|
||
char get_char(int pos) const;
|
||
|
||
bool np_get(int pos, TString& key, TString& val) const;
|
||
bool np_get_real(int pos, TString& key, real& val) const;
|
||
|
||
const TRecord770& operator=(const TRecord770& rec)
|
||
{ _buffer = rec._buffer; return *this; }
|
||
|
||
char tipo_record() const { return _buffer[0]; }
|
||
void tipo_record(char tipo)
|
||
{ _buffer[0] = tipo; tracciato().auto_fill(_buffer); }
|
||
|
||
void azzera_campi_non_posizionali();
|
||
bool ha_campi_non_posizionali() const { return strchr("DEFGHJ", tipo_record()) != NULL; }
|
||
bool ha_campi_non_posizionali_compilati() const
|
||
{ return _buffer[90] > ' '; }
|
||
|
||
bool valid() const;
|
||
|
||
TRecord770();
|
||
TRecord770(char tipo);
|
||
TRecord770(const TRecord770& rec);
|
||
TRecord770(const TRectype& rec);
|
||
virtual ~TRecord770();
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TTrasferimento770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TTrasferimento770 : public TObject
|
||
{
|
||
TFilename _name;
|
||
ifstream* _in_stream;
|
||
ofstream* _out_stream;
|
||
|
||
long _cod_ditta, _codan_dic;
|
||
TString8 _codatt_dic;
|
||
char _tipoa_dic;
|
||
TString16 _codfis_dic;
|
||
TString _ragsoc_dic;
|
||
bool _save_headers;
|
||
|
||
protected:
|
||
bool riepiloga_ss(const TRecord770& rec, TArray& riep_ss) const;
|
||
bool riepiloga_sx(const TRecord770& rec, TArray& riep_sx) const;
|
||
|
||
public:
|
||
bool open(const char* path = "", char mode = 'r', int volume = 0);
|
||
bool close();
|
||
bool write(const TRecord770& rec);
|
||
bool read(TRecord770& rec);
|
||
bool eof() const { return _in_stream && _in_stream->eof(); }
|
||
|
||
const char* default_name() const;
|
||
|
||
TTrasferimento770& operator<<(const TRecord770& rec)
|
||
{ write(rec); return *this; }
|
||
TTrasferimento770& operator>>(TRecord770& rec)
|
||
{ read(rec); return *this; }
|
||
|
||
const TString& read_codfis_dic(const TRectype& rec);
|
||
const TString& cod_fis_dic() const { return _codfis_dic; }
|
||
|
||
TRecnotype conta_certificazioni() const;
|
||
bool casella_prospetto_st() const;
|
||
bool casella_prospetto_sx() const;
|
||
bool append_record_b();
|
||
long append_quadro(const char* quadro, long codditta, TProgind& pi);
|
||
|
||
bool split(const char* dest_path);
|
||
void remove();
|
||
|
||
void save_headers(bool s) { _save_headers = s; }
|
||
bool save_headers() const { return _save_headers; }
|
||
|
||
TTrasferimento770(const char* name = "", char mode = 'r', int volume = 0);
|
||
virtual ~TTrasferimento770();
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Implementazioni
|
||
///////////////////////////////////////////////////////////
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TForm770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
bool TForm770::validate(TForm_item &cf, TToken_string &s)
|
||
{
|
||
const TString code(s.get(0)); // prende il primo parametro, il codice del messaggio
|
||
if (code == "_PERIODO_RIF")
|
||
{
|
||
const TRectype& curr = relation()->curr();
|
||
const int anno = curr.get_int("QLAP");
|
||
const int mese = curr.get_int("QLMP");
|
||
TString8 str;
|
||
str.format("%02d%04d", mese, anno);
|
||
cf.set(str);
|
||
return true;
|
||
}
|
||
if (code == "_PROVINCIA")
|
||
{
|
||
const TString& prov = cf.get();
|
||
if (prov == "EE") // Il 770 non gradisce la provincia EE associata agli stati esteri
|
||
cf.set("");
|
||
return true;
|
||
}
|
||
|
||
return TForm::validate(cf, s);
|
||
}
|
||
|
||
void TForm770::transfer_section(TPrint_section& body, int rigo,
|
||
TRecord770& rec, TTrasferimento770& file)
|
||
{
|
||
TString8 basecode, code, type;
|
||
TString str;
|
||
|
||
body.update();
|
||
for (word f = 0; f < body.fields(); f++)
|
||
{
|
||
TForm_item& fi = body.field(f);
|
||
str = fi.get(); str.trim();
|
||
if (fi.shown() && str.not_empty())
|
||
{
|
||
basecode = fi.get_special_value("TRASFER");
|
||
if (basecode.not_empty())
|
||
{
|
||
type = fi.get_special_desc("TRASFER");
|
||
if (type.full())
|
||
{
|
||
if (type == "CB") // Casella Barrata
|
||
{
|
||
if (str == "1" || str == "X")
|
||
{
|
||
str = "1";
|
||
str.right_just(16);
|
||
}
|
||
else
|
||
str.cut(0);
|
||
} else
|
||
if (type == "NP" || type == "NU" || type == "VP" || type == "VN") // Numero Positivo, NUmero, Valuta positiva o libera
|
||
{
|
||
if (real::is_null(str))
|
||
str.cut(0);
|
||
else
|
||
{
|
||
// Trattamento a parte degli importi cho possono essere in Euro o Eurocent
|
||
if (xvt_str_compare_ignoring_case(fi.class_name(), "VALUTA") == 0)
|
||
{
|
||
real val = str;
|
||
if (_trc770.importi_in_centesimi())
|
||
{
|
||
val *= CENTO;
|
||
str = val.stringa(16, 0);
|
||
}
|
||
else
|
||
str = val.stringa(16, 2);
|
||
}
|
||
else
|
||
str.right_just(16);
|
||
}
|
||
} else
|
||
if (type == "DT")
|
||
{
|
||
str.strip("-");
|
||
str.right_just(16);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (fi.fields() > 0)
|
||
{
|
||
const TFieldref& fr = ((TForm_string&)fi).field(0);
|
||
const int num = fr.file();
|
||
const char* fn = fr.name();
|
||
const TFieldtypes ft = cursor()->curr(num).type(fn);
|
||
switch (ft)
|
||
{
|
||
case _boolfld:
|
||
str = str.full() ? "1" : "0";
|
||
str.right_just(16);
|
||
break;
|
||
case _datefld:
|
||
if (str.len() == 10 && str[2] == '-' && str[5] == '-')
|
||
{
|
||
str.strip("-");
|
||
str.right_just(16);
|
||
}
|
||
break;
|
||
case _realfld:
|
||
if (real::is_null(str))
|
||
str.cut(0);
|
||
else
|
||
{
|
||
// Trattamento a parte degli importi cho possono essere in Euro o Eurocent
|
||
if (xvt_str_compare_ignoring_case(fi.class_name(), "VALUTA") == 0)
|
||
{
|
||
real val = str;
|
||
if (_trc770.importi_in_centesimi())
|
||
val *= CENTO;
|
||
str = val.string(16, 0);
|
||
}
|
||
else
|
||
str.right_just(16);
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (str.not_empty())
|
||
{
|
||
const int vero_rigo = atoi(basecode.mid(2, 3)) - 1 + rigo;
|
||
code.format("%c%c%03d%c%c%c",
|
||
basecode[0], basecode[1], vero_rigo,
|
||
basecode[5], basecode[6], basecode[7]);
|
||
if (!rec.np_put(code, str))
|
||
{
|
||
file << rec;
|
||
rec.azzera_campi_non_posizionali();
|
||
rec.np_put(code, str);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TForm770::compatible(const TRectype& r1, const TRectype& r2)
|
||
{
|
||
if (r1.empty() || r2.empty())
|
||
return true;
|
||
|
||
if (r1.get_long(QUC_CODDITTA) != r2.get_long(QUC_CODDITTA))
|
||
return false;
|
||
if (r1.get_char(QUC_TIPOA) != r2.get_char(QUC_TIPOA))
|
||
return false;
|
||
if (r1.get_long(QUC_CODANAGR) != r2.get_long(QUC_CODANAGR))
|
||
return false;
|
||
if (r1.get_char(QUC_CAUSALE) != r2.get_char(QUC_CAUSALE))
|
||
return false;
|
||
if (r1.get_int(QUC_TASSAZIONE) != r2.get_int(QUC_TASSAZIONE))
|
||
return false;
|
||
|
||
const real p1 = r1.get_real(QUC_PERC);
|
||
const real p2 = r2.get_real(QUC_PERC);
|
||
bool yes = (p1 == ZERO && p2 != ZERO) || (p1 == p2);
|
||
return yes;
|
||
}
|
||
|
||
void TForm770::add_rec(TRectype& r1, const TRectype& r2)
|
||
{
|
||
if (r1.empty())
|
||
r1 = r2;
|
||
else
|
||
{
|
||
for (int f = r1.items()-1; f >= 0; f--)
|
||
{
|
||
const char* name = r1.fieldname(f);
|
||
if (r1.type(name) == _realfld)
|
||
{
|
||
real val = r1.get_real(name);
|
||
val += r2.get_real(name);
|
||
r1.put(name, val);
|
||
}
|
||
}
|
||
r1.put(QUC_PERC, r2.get(QUC_PERC));
|
||
}
|
||
}
|
||
|
||
long TForm770::raggruppa_c()
|
||
{
|
||
TCursor& cur = *cursor();
|
||
TRectype& rc = cur.curr();
|
||
_records.destroy();
|
||
for (cur = 0; cur.ok(); ++cur)
|
||
{
|
||
bool append = true;
|
||
const int last = _records.items()-1;
|
||
if (last >= 0)
|
||
{
|
||
TRectype& sum = (TRectype&)_records[last];
|
||
if (compatible(sum, rc))
|
||
{
|
||
add_rec(sum, rc);
|
||
append = false;
|
||
}
|
||
}
|
||
if (append)
|
||
{
|
||
_records.add(rc);
|
||
_positions.add_long(cur.pos()+1);
|
||
}
|
||
}
|
||
|
||
return _records.items();
|
||
}
|
||
|
||
int TForm770::first()
|
||
{
|
||
TCursor& cur = *cursor();
|
||
|
||
cur = 0;
|
||
bool ok = cur.ok();
|
||
|
||
if (cur.file().num() == LF_QUAC)
|
||
{
|
||
if (ok)
|
||
{
|
||
raggruppa_c();
|
||
_index = 0;
|
||
cur.curr() = (TRectype&)_records[0];
|
||
}
|
||
}
|
||
|
||
return ok ? NOERR : _iseof;
|
||
}
|
||
|
||
int TForm770::next()
|
||
{
|
||
TCursor& cur = *cursor();
|
||
|
||
bool ok;
|
||
if (cur.file().num() == LF_QUAC)
|
||
{
|
||
_index++;
|
||
ok = _index < _records.items();
|
||
if (ok)
|
||
{
|
||
cur = _positions.get_long(_index) - 1;
|
||
cur.curr() = (TRectype&)_records[_index];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
++cur;
|
||
ok = cur.ok();
|
||
}
|
||
|
||
return ok ? NOERR : _iseof;
|
||
}
|
||
|
||
TRecnotype TForm770::trasfer(long codditta, TTrasferimento770& file, char rectype, int rpm)
|
||
{
|
||
TCursor& cur = *cursor();
|
||
|
||
// Filtra il cursore sulla ditta corrente
|
||
TRectype region(cur.curr());
|
||
region.zero();
|
||
region.put(BSE_CODDITTA, codditta);
|
||
cur.setregion(region, region);
|
||
|
||
if (region.num() == LF_QUADRO_ST)
|
||
{
|
||
TString16 filter;
|
||
filter.format("QLAP=%d", ANNO_DIC);
|
||
cur.setfilter(filter);
|
||
}
|
||
|
||
const TRecnotype items = cur.items();
|
||
if (items > 0) // Se c'e almeno un record ...
|
||
{
|
||
cur.freeze(true); // Per efficienza congela il cursore
|
||
|
||
// Inizializza record col primo modulo
|
||
TRecord770 rec(rectype);
|
||
int modulo = 1;
|
||
int rigo = 1;
|
||
|
||
rec.set(2, file.cod_fis_dic());
|
||
rec.set(3, modulo);
|
||
|
||
switch (rectype)
|
||
{
|
||
case 'E': rec.set(8, CF_PRODUTTORE); break;
|
||
case 'H': rec.set(9, CF_PRODUTTORE); break;
|
||
default : break;
|
||
}
|
||
|
||
TPrint_section& body = section('B', odd_page);
|
||
|
||
int err = first(); // Deve sempre tornare NOERR
|
||
for (; err == NOERR; err = next())
|
||
{
|
||
transfer_section(body, rigo, rec, file);
|
||
rigo++;
|
||
if (rigo > rpm)
|
||
{
|
||
// Scrivi record se non vuoto
|
||
if (rec.ha_campi_non_posizionali_compilati())
|
||
file << rec;
|
||
|
||
// Avanza al prossimo modulo ed azzera la riga
|
||
rigo = 1;
|
||
modulo++;
|
||
|
||
rec.azzera_campi_non_posizionali();
|
||
rec.set(3, modulo);
|
||
}
|
||
}
|
||
|
||
// Ultimo record parzialmente compilato
|
||
if (rec.ha_campi_non_posizionali_compilati())
|
||
file << rec;
|
||
|
||
cur.freeze(false);
|
||
}
|
||
|
||
return items;
|
||
}
|
||
|
||
TForm770::TForm770(const char* name)
|
||
: TForm(name), _sortedcur(NULL)
|
||
{
|
||
const char* key = NULL;
|
||
|
||
switch (TForm::cursor()->file().num())
|
||
{
|
||
case LF_QUALA: key = "CODDITTA|216@->RAGSOC|TIPOA|CODANAGR"; break;
|
||
default : break;
|
||
}
|
||
if (key)
|
||
_sortedcur = new TSorted_cursor(TForm::relation(), key);
|
||
}
|
||
|
||
TForm770::~TForm770()
|
||
{
|
||
if (_sortedcur)
|
||
delete _sortedcur;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TTracciato770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void TTracciato770::add_field(const char* name, M770FieldType type, int pos, int len, int fldno)
|
||
{
|
||
switch (type)
|
||
{
|
||
case AN:
|
||
break;
|
||
case CB:
|
||
CHECKD(len == 1, "Booleano di lunghezza sospetta ", len);
|
||
type = NU;
|
||
break;
|
||
case CF:
|
||
CHECKD(len == 16, "Codice fiscale di lunghezza sospetta ", len);
|
||
type = AN;
|
||
break;
|
||
case CN:
|
||
CHECKD(len == 11, "Codice fiscale numerico di lunghezza sospetta ", len);
|
||
type = NU;
|
||
break;
|
||
case DA:
|
||
CHECKD(len == 6, "Mese+Anno di lunghezza sospetta ", len);
|
||
type = NU;
|
||
break;
|
||
case DT:
|
||
CHECKD(len == 8, "Data di lunghezza sospetta ", len);
|
||
type = NU;
|
||
break;
|
||
case NU:
|
||
break;
|
||
case PN:
|
||
case PR:
|
||
CHECKD(len == 2, "provincia di lunghezza sospetta ", len);
|
||
type = AN;
|
||
break;
|
||
default:
|
||
CHECK(false, "tipo campo sospetto");
|
||
break;
|
||
}
|
||
|
||
TField770* info = new TField770;
|
||
info->_desc = name;
|
||
info->_type = type;
|
||
info->_pos = pos;
|
||
info->_len = len;
|
||
|
||
if (fldno <= 0)
|
||
fldno = _fields.add(info)+1;
|
||
else
|
||
_fields.add(info, fldno-1);
|
||
}
|
||
|
||
const TField770& TTracciato770::field(int pos) const
|
||
{
|
||
TField770* info = (TField770*)_fields.objptr(pos-1);
|
||
#ifdef DBG
|
||
if (info == NULL)
|
||
fatal_box("Non esiste il campo %d sul tipo record %c", pos, _tipo);
|
||
#endif
|
||
return *info;
|
||
}
|
||
|
||
void TTracciato770::auto_fill(TString& buffer) const
|
||
{
|
||
buffer.fill(' ', TOTAL_SIZE);
|
||
char* ptr = buffer.get_buffer();
|
||
for (int f = _fields.last(); f >= 0; f = _fields.pred(f))
|
||
{
|
||
const TField770& info = (const TField770&)_fields[f];
|
||
if (info._type == NU || info._type == CB || info._type == DA || info._type == DT || info._type == CN)
|
||
memset(ptr + info._pos - 1, '0', info._len);
|
||
}
|
||
buffer[0] = _tipo;
|
||
buffer.overwrite("A\r\n", TOTAL_SIZE-3);
|
||
}
|
||
|
||
TTracciato770::TTracciato770(char tipo) : _tipo(tipo)
|
||
{
|
||
if (strchr("ABEFHJZ", tipo) == NULL)
|
||
NFCHECK("Tipo record non valido: %c", tipo);
|
||
|
||
add_field("Tipo record", AN, 1, 1); // 1
|
||
|
||
if (tipo == 'A')
|
||
{
|
||
add_filler(2, 14); // 2
|
||
add_field("Codice fornitura", AN, 16, 5); // 3
|
||
add_field("Tipo fornitore", NU, 21, 2); // 4
|
||
add_field("Codice fiscale del fornitore", CF, 23, 16);
|
||
add_filler(39, 483);
|
||
// Dichiarazione su pi<70> invii
|
||
add_field("Progressivo dell'invio", NU, 522, 4); // 7
|
||
add_field("Numero totale degli invii", NU, 526, 4);
|
||
} else
|
||
if (tipo == 'B')
|
||
{
|
||
add_field("Codice fiscale dichiarante", CF, 2, 16); // 2
|
||
add_field("Progressivo modulo", NU, 18, 8);
|
||
add_filler( 26, 3);
|
||
add_filler( 29,25);
|
||
add_field("Spazio a disposizione", AN, 54, 20);
|
||
add_field("CF del produttore del software", CF, 74, 16); // 7
|
||
|
||
add_field("Flag conferma", CB, 90, 1);
|
||
|
||
// Tipo di dichiarazione
|
||
add_field("Dichiarazione correttiva nei termini", CB, 91, 1); // 9
|
||
add_field("Dichiarazione correttiva parziale", CB, 92, 1);
|
||
add_field("Dichiarazione integrativa", CB, 93, 1);
|
||
add_field("Eventi eccezzziunali veramente", NU, 94, 1); // 12
|
||
|
||
// Dati del contribuente
|
||
add_field("Cognome", AN, 95, 24); // 13
|
||
add_field("Nome", AN,119, 20);
|
||
add_field("Denominazione (Alternativo a 25 e 26)",AN,139, 60);
|
||
add_filler(199,11);
|
||
add_filler(210, 1);
|
||
add_filler(211, 1);
|
||
|
||
add_field("Codice Attivit<69>", NU, 212, 6); // 19
|
||
add_field("Indirizzo E-mail", AN, 218, 100);
|
||
add_field("Telefono o Cellulare", AN, 318, 12);
|
||
add_field("FAX", AN, 330, 12); // 22
|
||
|
||
add_field("Data di nascita", DT, 384, 8, 25); // 25
|
||
add_field("C.a.p. residenza", NU, 435, 5, 29); // 29
|
||
add_field("Data variazione", DT, 479, 8, 32); // 32
|
||
|
||
// Saltiamo a pie' pari i dati delle persone fisiche
|
||
|
||
add_field("Natura giuridica", NU, 487, 2, 33); // 33
|
||
add_field("Data variazione sede legale", DA, 489, 6);
|
||
add_field("Comune della sede legale", AN, 495,40);
|
||
add_field("Sigla della provincia sede legale", PR, 535, 2);
|
||
add_field("CAP del comune della sede legale", NU, 537, 5);
|
||
add_field("Codice comune", AN, 542, 4);
|
||
add_field("Indirizzo della sede legale", AN, 546,35);
|
||
add_field("Data variazione domicilio fiscale", NU, 581, 6); // 40
|
||
add_field("Comune del domicilio fiscale", AN, 587,40);
|
||
add_field("Provincia del domicilio fiscale", PR, 627, 2);
|
||
add_field("CAP del domicilio fiscale", NU, 629, 5);
|
||
add_field("Codice comune", AN, 634, 5);
|
||
add_field("Indirizzo del domicilio fiscale", AN, 638,35);
|
||
add_field("Stato", NU, 673, 1);
|
||
add_field("Situazione", NU, 674, 1);
|
||
add_field("Dicastero di appartenenza", CN, 675, 11);
|
||
|
||
add_field("Redazione della dichiarazione", NU, 797, 1, 75); // 75
|
||
add_field("Numero comunicaz. lavoro dipendente", NU, 798, 8);
|
||
add_field("Numero comunicaz. lavoro autonomo", NU, 806, 8);
|
||
add_field("Casella prospetto SS", CB, 814, 1); // 78
|
||
add_field("Casella prospetto ST", CB, 815, 1);
|
||
add_field("Casella prospetto SV", CB, 816, 1);
|
||
add_field("Casella prospetto SX", CB, 817, 1); // 81
|
||
add_field("Casella prospetto SY", CB, 818, 1);
|
||
add_field("Presenza 770 ordinario 2011", CB, 819, 1);
|
||
add_field("Codice fiscale parte restante", CF, 820,16);
|
||
add_field("Protocollo telematico", NU, 836,17); // 85
|
||
add_field("Progressivo telematico", NU, 853, 6);
|
||
|
||
// dichiarazioni integrative o parziali
|
||
add_field("Casella prospetto SS", CB, 859, 1); // 87
|
||
add_field("Casella prospetto ST", CB, 860, 1);
|
||
add_field("Casella prospetto SV", CB, 861, 1);
|
||
add_field("Casella prospetto SX", CB, 862, 1);
|
||
add_field("Casella prospetto SY", CB, 863, 1);
|
||
add_field("Numero comunicaz. lavoro dipendente", NU, 864, 8);
|
||
add_field("Numero comunicaz. lavoro autonomo", NU, 872, 8); // 93
|
||
|
||
add_field("Firma del dichiarante", CB, 880, 1, 94); // 94
|
||
add_field("Codice fiscale", CF, 881,16);
|
||
add_field("Soggetto", NU, 897, 1);
|
||
add_field("Firma", CB, 898, 1); // 97
|
||
add_field("Codice fiscale", CF, 899,16);
|
||
add_field("Soggetto", NU, 915, 1);
|
||
add_field("Firma", CB, 916, 1); // 100
|
||
add_field("Codice fiscale", CF, 917,16);
|
||
add_field("Soggetto", NU, 933, 1);
|
||
add_field("Firma", CB, 934, 1); // 103
|
||
add_field("Codice fiscale", CF, 935,16);
|
||
add_field("Soggetto", NU, 951, 1);
|
||
add_field("Firma", CB, 952, 1); // 106
|
||
add_field("Codice fiscale", CF, 953,16);
|
||
add_field("Soggetto", NU, 969, 1);
|
||
add_field("Firma", CB, 970, 1); // 107
|
||
|
||
add_field("Situazioni particolari", NU,1180,2, 116); // 116
|
||
|
||
add_field("Codice fiscale del rappresentante", CF,1396,16,126); // 126
|
||
add_field("Codice carica del rappresentante", NU,1412, 2);
|
||
add_field("Data carica del rappresentante", DT,1414, 8);
|
||
|
||
add_field("Cognome", AN,1493,24, 131); // 131
|
||
add_field("Nome", AN,1517,20);
|
||
add_field("Sesso", AN,1537, 1);
|
||
add_field("Data di nascita rappresentante", DT,1538, 8);
|
||
add_field("Comune di nascita", AN,1546,40); // 135
|
||
add_field("Provincia di nascita", PN,1586, 2);
|
||
|
||
add_field("Codice stato estero", NU,1588, 3); // 137
|
||
add_field("Stato federato, provincia, contea", AN,1591,24);
|
||
add_field("Localit<EFBFBD> di residenza", AN,1615,24);
|
||
add_field("Indirizzo estero", AN,1639,35); // 140
|
||
|
||
add_field("Data apertura fallimento", DT,1686, 8, 142); // 142
|
||
add_field("Codice fiscale societa o dichiarante", NU,1694,11);
|
||
|
||
add_field("Invio avviso telematico", CB,1715, 1, 147); // 147
|
||
add_field("Ricezione avviso telematico", CB,1716, 1);
|
||
add_field("Codice fiscale intermediario", CF,1717,16);
|
||
add_field("Numero iscrizione C.A.F.", NU,1733, 5);
|
||
add_field("Impegno a trasmettere la dichiaraz.", NU,1738, 1); // 151
|
||
add_field("Data dell'impegno", DT,1739, 8);
|
||
add_field("Firma dell'intermediario", CB,1747, 1);
|
||
add_field("Codice fiscale responsabile C.A.F.", CF,1748,16);
|
||
add_field("Codice fiscale C.A.F.", CN,1764,11);
|
||
add_field("Codice fiscale professionista", CF,1775,16); // 156
|
||
add_field("Firma", CB,1791, 1);
|
||
} else
|
||
if (tipo == 'E' || tipo == 'F')
|
||
{
|
||
add_field("Codice fiscale del dichiarante", CF, 2, 16); // 2
|
||
add_field("Progressivo modulo", NU, 18, 8);
|
||
add_field("Spazio a disposizione", AN, 26, 3);
|
||
add_field("Tipo operazione", AN, 29, 1);
|
||
add_filler(30, 24);
|
||
add_field("Spazio a disposizione", AN, 54, 20);
|
||
add_field("Identificativo produttore software", AN, 74, 16); // 8
|
||
} else
|
||
if (tipo == 'H')
|
||
{
|
||
add_field("Codice fiscale del dichiarante", CF, 2, 16); // 2
|
||
add_field("Progressivo comunicazione", NU, 18, 8);
|
||
add_field("Spazio a disposizione", AN, 26, 3);
|
||
add_field("Tipo operazione", AN, 29, 1);
|
||
add_field("Codice fiscale del percipiente", AN, 30, 16); // 6
|
||
add_filler(46, 8);
|
||
add_field("Spazio a disposizione", AN, 54, 20);
|
||
add_field("Identificativo produttore software", AN, 74, 16); // 9
|
||
} else
|
||
if (tipo == 'J')
|
||
{
|
||
add_field("Codice fiscale del dichiarante", CF, 2, 16); // 2
|
||
add_field("Progressivo modulo", NU, 18, 8);
|
||
add_field("Spazio a disposizione", AN, 26, 3);
|
||
add_field("Tipo operazione", AN, 29, 1);
|
||
add_filler(30, 24);
|
||
add_field("Spazio a disposizione", AN, 54, 20);
|
||
add_field("Identificativo produttore software", AN, 74, 16); // 8
|
||
} else
|
||
if (tipo == 'Z')
|
||
{
|
||
add_filler(2, 14);
|
||
add_field("Numero record di tipo 'B'", NU, 16, 9); // 3
|
||
add_field("Numero record di tipo 'D'", NU, 25, 9);
|
||
add_field("Numero record di tipo 'E'", NU, 34, 9);
|
||
add_field("Numero record di tipo 'F'", NU, 43, 9); // 6
|
||
add_field("Numero record di tipo 'G'", NU, 52, 9);
|
||
add_field("Numero record di tipo 'H'", NU, 61, 9);
|
||
add_field("Numero record di tipo 'I'", NU, 70, 9);
|
||
add_field("Numero record di tipo 'J'", NU, 79, 9); // 10
|
||
add_filler(88, 1810);
|
||
}
|
||
}
|
||
|
||
TTracciato770::~TTracciato770()
|
||
{
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TTracciati770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const TTracciato770& TTracciati770::tracciato(char tipo)
|
||
{
|
||
const int pos = tipo-AN;
|
||
TTracciato770* trc = (TTracciato770*)_trc.objptr(pos);
|
||
if (trc == NULL)
|
||
{
|
||
trc = new TTracciato770(tipo);
|
||
_trc.add(trc, pos);
|
||
}
|
||
return *trc;
|
||
}
|
||
|
||
TForm770& TTracciati770::form(const char* quadro, char& tiporec, int& rpm)
|
||
{
|
||
CHECK(quadro && *quadro != '\0' && quadro[1] != '\0',
|
||
"Codice quadro non valido");
|
||
|
||
const char* name;
|
||
switch(quadro[1])
|
||
{
|
||
case 'A': name = "77qla"; tiporec = 'H'; rpm = 1; break;
|
||
case 'T': name = "77qst"; tiporec = 'E'; rpm = 12; break;
|
||
default : name = NULL; break;
|
||
}
|
||
|
||
TForm770* frm = (TForm770*)_form.objptr(name);
|
||
if (frm == NULL)
|
||
{
|
||
frm = new TForm770(name);
|
||
_form.add(name, frm);
|
||
}
|
||
|
||
return *frm;
|
||
}
|
||
|
||
void TTracciati770::destroy()
|
||
{
|
||
_trc.destroy();
|
||
_form.destroy();
|
||
}
|
||
|
||
TTracciati770::TTracciati770() : _centesimi(false)
|
||
{
|
||
}
|
||
|
||
TTracciati770::~TTracciati770()
|
||
{
|
||
destroy(); // Non viene mai chiamato!
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TCache770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const TRectype& TCache770::get(int num, const char* key)
|
||
{
|
||
TRecord_cache* rc = (TRecord_cache*)_files.objptr(num);
|
||
if (rc == NULL)
|
||
{
|
||
rc = new TRecord_cache(num);
|
||
_files.add(rc, num);
|
||
}
|
||
return rc->get(key);
|
||
}
|
||
|
||
const TRectype& TCache770::get(int num, long key)
|
||
{
|
||
TString16 str; str << key;
|
||
return get(num, str);
|
||
}
|
||
|
||
void TCache770::destroy()
|
||
{
|
||
_files.destroy();
|
||
_tables.destroy();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TRecord770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void TRecord770::print_on(ostream& outs) const
|
||
{
|
||
outs.write(_buffer, TOTAL_SIZE);
|
||
}
|
||
|
||
void TRecord770::read_from(istream& ins)
|
||
{
|
||
_buffer.fill(' ', TOTAL_SIZE);
|
||
ins.read(_buffer.get_buffer(), TOTAL_SIZE);
|
||
}
|
||
|
||
void TRecord770::set(const TField770& fld, const char* val)
|
||
{
|
||
TString80 str(val);
|
||
if (fld._type == AN)
|
||
str.upper();
|
||
int lenstr = str.len();
|
||
if (lenstr > fld._len)
|
||
{
|
||
#ifdef DBG
|
||
NFCHECK("Campo troppo lungo: '%s' (max. %d)", val, fld._len);
|
||
#endif
|
||
str.cut(lenstr = fld._len);
|
||
}
|
||
if (lenstr != fld._len)
|
||
{
|
||
str.trim();
|
||
if (fld._type == NU)
|
||
str.right_just(fld._len, '0');
|
||
else
|
||
str.left_just(fld._len);
|
||
}
|
||
_buffer.overwrite(str, fld._pos-1);
|
||
}
|
||
|
||
void TRecord770::set(int pos, const char* val)
|
||
{
|
||
const TField770& fld = tracciato().field(pos);
|
||
set(fld, val);
|
||
}
|
||
|
||
void TRecord770::set(int pos, int val)
|
||
{
|
||
const TField770& fld = tracciato().field(pos);
|
||
CHECKD(fld._type == NU, "Invalid numeric field ", pos);
|
||
TString16 str; str.format("%d", val);
|
||
set(fld, str);
|
||
}
|
||
|
||
void TRecord770::set(int pos, long val)
|
||
{
|
||
const TField770& fld = tracciato().field(pos);
|
||
CHECKD(fld._type == NU, "Invalid numeric field ", pos);
|
||
TString16 str; str.format("%ld", val);
|
||
set(fld, str);
|
||
}
|
||
|
||
void TRecord770::set(int pos, const real& val)
|
||
{
|
||
const TField770& fld = tracciato().field(pos);
|
||
CHECKD(fld._type == NU, "Invalid numeric field ", pos);
|
||
const char* str = val.string(fld._len, 0);
|
||
set(fld, str);
|
||
}
|
||
|
||
void TRecord770::set(int pos, const TDate& val)
|
||
{
|
||
const TField770& fld = tracciato().field(pos);
|
||
CHECKD(fld._type == NU && (fld._len == 6 || fld._len == 8),
|
||
"Invalid date field ", pos);
|
||
const char* str;
|
||
if (fld._len == 8)
|
||
str = val.string(full, '\0', full, full, gma_date);
|
||
else
|
||
str = val.string(brief, '\0', full, full, gma_date);
|
||
set(fld, str);
|
||
}
|
||
|
||
void TRecord770::set(int pos, char val)
|
||
{
|
||
const TField770& fld = get_field(pos);
|
||
CHECKD(fld._type == AN && fld._len == 1, "Invalid char field ", pos);
|
||
const char str[2] = { val, '\0' };
|
||
set(fld, str);
|
||
}
|
||
|
||
void TRecord770::set(int pos, bool val)
|
||
{
|
||
const TField770& fld = get_field(pos);
|
||
CHECKD((fld._type == CB || fld._type == NU)&& fld._len == 1, "Invalid boolean field ", pos);
|
||
set(fld, val ? "1" : "0");
|
||
}
|
||
|
||
const char* TRecord770::get(int pos, TString& str) const
|
||
{
|
||
const TField770& fld = get_field(pos);
|
||
str = _buffer.mid(fld._pos-1, fld._len);
|
||
return str.trim();
|
||
}
|
||
|
||
int TRecord770::get_int(int pos) const
|
||
{
|
||
TString16 str; get(pos, str);
|
||
return atoi(str);
|
||
}
|
||
|
||
char TRecord770::get_char(int pos) const
|
||
{
|
||
const TField770& fld = get_field(pos);
|
||
CHECKD(fld._type == AN, "Invalid char field ", pos);
|
||
return _buffer[fld._pos-1];
|
||
}
|
||
|
||
// Calcola i blocchi necessari per contenere la stringa val
|
||
int TRecord770::calculate_blocks(const char* val) const
|
||
{
|
||
// Il primo blocco contiene 16 caratteri, gli altri solo 15 perche' c'e' anche il +
|
||
int blocks = 1;
|
||
if (val && *val)
|
||
{
|
||
const int len = strlen(val);
|
||
if (len > FIELD_SIZE)
|
||
blocks += (len-FIELD_SIZE-1) / (FIELD_SIZE-1) + 1;
|
||
}
|
||
return blocks;
|
||
}
|
||
|
||
// Azzera tutti i campi non posizionali dei record di tipo E
|
||
void TRecord770::azzera_campi_non_posizionali()
|
||
{
|
||
CHECK(ha_campi_non_posizionali(), "Impossibile azzerare un record senza campi non posizionali");
|
||
char* buf = _buffer.get_buffer() + HEADER_SIZE;
|
||
memset(buf, ' ', USEABLE_SIZE);
|
||
}
|
||
|
||
// Aggiunge un campo non posizionale ai record di tipo E,F,G,H,J
|
||
bool TRecord770::np_put(const char* code, const char* val)
|
||
{
|
||
CHECK(ha_campi_non_posizionali(), "Impossibile aggiungere campi non posizionali");
|
||
CHECKS(code && strlen(code) == CODE_SIZE, "Invalid field code ", code);
|
||
CHECKS(val && *val, "Can't add empty field ", code);
|
||
|
||
// Cerca il primo posto libero
|
||
int pos;
|
||
for (pos = HEADER_SIZE; pos < HEADER_SIZE+USEABLE_SIZE; pos += BLOCK_SIZE)
|
||
{
|
||
if (_buffer[pos] == ' ')
|
||
break;
|
||
}
|
||
const int free_blocks = (USEABLE_SIZE - pos) / BLOCK_SIZE;
|
||
const int needed_blocks = calculate_blocks(val);
|
||
const bool ok = free_blocks >= needed_blocks;
|
||
|
||
if (ok) // Se ci sono abbastanza blocchi liberi
|
||
{
|
||
TString80 str(val); str.upper();
|
||
const int lenstr = str.len();
|
||
for (int i = 0; i < lenstr; )
|
||
{
|
||
_buffer.overwrite(code, pos);
|
||
pos += CODE_SIZE;
|
||
int maxlen = FIELD_SIZE;
|
||
if (i > 0)
|
||
{
|
||
_buffer.overwrite("+", pos);
|
||
pos++;
|
||
maxlen--;
|
||
}
|
||
const TString& substr = str.mid(i, maxlen);
|
||
_buffer.overwrite(substr, pos);
|
||
pos += maxlen;
|
||
i += maxlen;
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TRecord770::np_put(const char* code, long val)
|
||
{
|
||
TString16 str; str.format("%16ld", val);
|
||
return np_put(code, str);
|
||
}
|
||
|
||
bool TRecord770::np_put(const char* code, const real& val)
|
||
{
|
||
const TString& str = val.stringa(16, 2);
|
||
return np_put(code, str);
|
||
}
|
||
|
||
bool TRecord770::np_get(int pos, TString& key, TString& val) const
|
||
{
|
||
CHECK(ha_campi_non_posizionali(), "Impossibile leggere campi non posizionali");
|
||
const int n = HEADER_SIZE + pos * BLOCK_SIZE;
|
||
bool ok = false;
|
||
if (n < HEADER_SIZE + USEABLE_SIZE)
|
||
{
|
||
ok = _buffer[n] > ' ';
|
||
if (ok)
|
||
{
|
||
key = _buffer.mid(n, CODE_SIZE);
|
||
val = _buffer.mid(n+CODE_SIZE, FIELD_SIZE);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TRecord770::np_get_real(int pos, TString& key, real& val) const
|
||
{
|
||
TString16 str;
|
||
const bool ok = np_get(pos, key, str);
|
||
if (ok && str.full())
|
||
{
|
||
str.replace(',', '.');
|
||
val = real(str);
|
||
}
|
||
else
|
||
val = ZERO;
|
||
return ok;
|
||
}
|
||
|
||
bool TRecord770::valid() const
|
||
{
|
||
const char tipo = tipo_record();
|
||
const bool ok = (tipo > ' ') && (strchr("ABEHJZ", tipo) != NULL);
|
||
return ok;
|
||
}
|
||
|
||
TRecord770::TRecord770() : _buffer(TOTAL_SIZE, ' ')
|
||
{
|
||
}
|
||
|
||
TRecord770::TRecord770(char tipo) : _buffer(TOTAL_SIZE, ' ')
|
||
{
|
||
tipo_record(tipo);
|
||
}
|
||
|
||
TRecord770::TRecord770(const TRecord770& rec) : _buffer(rec._buffer)
|
||
{ }
|
||
|
||
TRecord770::~TRecord770()
|
||
{ }
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TTrasferimento770
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const char* TTrasferimento770::default_name() const
|
||
{ return "MOD77013"; }
|
||
|
||
bool TTrasferimento770::open(const char* path, char mode, int volume)
|
||
{
|
||
CHECK(mode == 'r' || mode == 'w', "Invalid open mode");
|
||
close();
|
||
|
||
if (path && *path)
|
||
{
|
||
_name = path;
|
||
_name.add(default_name());
|
||
if (volume > 0)
|
||
_name << '_' << volume;
|
||
}
|
||
if (_name.empty())
|
||
{
|
||
_name = default_name();
|
||
if (volume > 0)
|
||
_name << '_' << volume;
|
||
}
|
||
if (mode == 'r')
|
||
_in_stream = new ifstream(_name, ios::in | ios::binary);
|
||
else
|
||
_out_stream = new ofstream(_name, ios::out | ios::binary);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TTrasferimento770::close()
|
||
{
|
||
if (_in_stream)
|
||
{
|
||
delete _in_stream;
|
||
_in_stream = NULL;
|
||
}
|
||
if (_out_stream)
|
||
{
|
||
delete _out_stream;
|
||
_out_stream = NULL;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TTrasferimento770::write(const TRecord770& rec)
|
||
{
|
||
bool ok = _out_stream != NULL;
|
||
if (ok)
|
||
(*_out_stream) << rec;
|
||
return ok;
|
||
}
|
||
|
||
bool TTrasferimento770::read(TRecord770& rec)
|
||
{
|
||
bool ok = _in_stream != NULL && !_in_stream->eof();
|
||
if (ok)
|
||
{
|
||
(*_in_stream) >> rec;
|
||
ok = rec.valid();
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
const TString& TTrasferimento770::read_codfis_dic(const TRectype& rec)
|
||
{
|
||
TToken_string key; // Stringa multiuso
|
||
|
||
key = rec.get(BSE_CODDIC);
|
||
if (key.empty())
|
||
key = rec.get(BSE_CODDITTA);
|
||
|
||
const TRectype& rec_nditte = _cache770.get(LF_NDITTE, key);
|
||
if (rec_nditte.empty())
|
||
{
|
||
error_box(FR("Non esiste la ditta %s"), (const char*)key);
|
||
return EMPTY_STRING;
|
||
}
|
||
_cod_ditta = atol(key);
|
||
_tipoa_dic = rec_nditte.get_char(NDT_TIPOA);
|
||
_codan_dic = rec_nditte.get_long(NDT_CODANAGR);
|
||
|
||
_codatt_dic = rec_nditte.get(NDT_CODATTPREV); // Codice attivita' prevalente
|
||
key.add(_codatt_dic); // key = CODDITTA|CODATTPREV
|
||
const TRectype& attiv = _cache770.get(LF_ATTIV, key);
|
||
if (attiv.exist(ATT_CODATECO)) // Non e' detto che il campo esista sempre
|
||
{
|
||
const TString& codateco = attiv.get(ATT_CODATECO);
|
||
if (codateco.full())
|
||
_codatt_dic = codateco;
|
||
}
|
||
|
||
key.cut(0) << _tipoa_dic;
|
||
key.add(rec_nditte.get(NDT_CODANAGR));
|
||
const TRectype& rec_anagr = _cache770.get(LF_ANAG, key);
|
||
if (rec_anagr.empty())
|
||
{
|
||
error_box(FR("Non esiste la persona %s"), (const char*)key);
|
||
return EMPTY_STRING;
|
||
}
|
||
_codfis_dic = rec_anagr.get(ANA_COFI); // Codice fiscale del dichiarante
|
||
_ragsoc_dic = rec_anagr.get(ANA_RAGSOC); // Denominazione del dichiarante
|
||
|
||
return _codfis_dic;
|
||
}
|
||
|
||
TRecnotype TTrasferimento770::conta_certificazioni() const
|
||
{
|
||
TString query;
|
||
query.format("USE %d\nFROM CODDITTA=%ld\nTO CODDITTA=%ld",
|
||
LF_QUALA, _cod_ditta, _cod_ditta);
|
||
TISAM_recordset recset(query);
|
||
const TRecnotype nc = recset.items();
|
||
return nc;
|
||
}
|
||
|
||
bool TTrasferimento770::casella_prospetto_st() const
|
||
{
|
||
// Il quadro ST e' il "vecchio" quadro L
|
||
TString query;
|
||
query.format("USE %d\nSELECT QLAP=%d\nFROM CODDITTA=%ld\nTO CODDITTA=%ld",
|
||
LF_QUADRO_ST, ANNO_DIC, _cod_ditta, _cod_ditta);
|
||
TISAM_recordset recset(query);
|
||
const TRecnotype nr = recset.items();
|
||
return nr > 0;
|
||
}
|
||
|
||
bool TTrasferimento770::casella_prospetto_sx() const
|
||
{
|
||
// Il quadro SX sono le ritenute versate in eccesso
|
||
TString query;
|
||
query.format("USE %d\nSELECT QLAP=%d\nFROM CODDITTA=%ld\nTO CODDITTA=%ld",
|
||
LF_QUADRO_ST, ANNO_DIC, _cod_ditta, _cod_ditta);
|
||
TISAM_recordset recset(query);
|
||
bool found = false;
|
||
for (bool ok = recset.move_first(); ok && !found; ok = recset.move_next())
|
||
{
|
||
const real verecc = recset.get("QLRITVEREC").as_real();
|
||
found = !verecc.is_zero();
|
||
}
|
||
return found;
|
||
}
|
||
|
||
|
||
bool TTrasferimento770::append_record_b()
|
||
{
|
||
bool ok = false;
|
||
if (save_headers())
|
||
{
|
||
TRecord770 rec('B'); // Compila record di testata B
|
||
rec.set(2, cod_fis_dic());
|
||
rec.set(3, 1); // Modulo (deve essere sempre 1)
|
||
rec.set(7, CF_PRODUTTORE); // CF del produttore Sirio
|
||
|
||
if (_tipoa_dic == 'F')
|
||
{
|
||
rec.set(13, _ragsoc_dic.left(24));
|
||
rec.set(14, _ragsoc_dic.mid(30,20));
|
||
}
|
||
else
|
||
rec.set(15, _ragsoc_dic);
|
||
rec.set(19, _codatt_dic);
|
||
|
||
TToken_string key;
|
||
key << _tipoa_dic << '|' << _codan_dic;
|
||
const TRectype& rec_anagr = _cache770.get(LF_ANAG, key);
|
||
|
||
key = rec_anagr.get(ANA_STATORES);
|
||
key.add(rec_anagr.get(ANA_COMRES), 1);
|
||
const TRectype& rec_comres = _cache770.get(LF_COMUNI, key);
|
||
|
||
if (_tipoa_dic == 'G')
|
||
{
|
||
const TRectype& rec_anagiu = _cache770.get(LF_ANAGGIU, _codan_dic);
|
||
rec.set(33, rec_anagiu.get(ANG_NATGIU));
|
||
|
||
rec.set(35, rec_comres.get(COM_DENCOM));
|
||
rec.set(36, rec_comres.get(COM_PROVCOM));
|
||
TString indirizzo;
|
||
indirizzo << rec_anagr.get(ANA_INDRES) << ' ' << rec_anagr.get(ANA_CIVRES);
|
||
indirizzo.strip_double_spaces(); indirizzo.cut(35);
|
||
rec.set(37, rec_anagr.get(ANA_CAPRES));
|
||
rec.set(38, rec_anagr.get(ANA_COMRES));
|
||
rec.set(39, indirizzo);
|
||
|
||
rec.set(46, rec_anagiu.get(ANG_STATOSOC));
|
||
rec.set(47, rec_anagiu.get(ANG_SITSOC));
|
||
}
|
||
|
||
rec.set(75, 1); // Reazione della dichiarazione (sezione I)
|
||
rec.set(76, 0); // Comunicazioni relative a certificazioni lavoro dipendente
|
||
const int autonomi = conta_certificazioni();
|
||
const bool prosp_st = casella_prospetto_st();
|
||
const bool prosp_sx = casella_prospetto_sx();
|
||
rec.set(77, autonomi);
|
||
rec.set(78, autonomi > 0); // casella prospetto SS
|
||
rec.set(79, prosp_st); // casella prospetto ST
|
||
rec.set(80, false); // casella prospetto SV
|
||
rec.set(81, prosp_sx); // casella prospetto SX
|
||
rec.set(82, false); // casella prospetto SY
|
||
|
||
rec.set(94, 1); // Firma del dichiarante
|
||
|
||
rec.set(100, 0); // situazioni particolari: vale sempre 0
|
||
|
||
const TRectype& rec_nditte = _cache770.get(LF_NDITTE, _cod_ditta);
|
||
|
||
key.cut(0) << "F|" << rec_nditte.get(NDT_RAPPR);
|
||
const TRectype& rec_rap = _cache770.get(LF_ANAG, key);
|
||
const TRectype& rec_rap_fis = _cache770.get(LF_ANAGFIS, key.get(1));
|
||
key.cut(0) << "|" << rec_rap_fis.get(ANF_COMNASC);
|
||
const TRectype& rec_com_nas = _cache770.get(LF_COMUNI, key);
|
||
key.cut(0) << "|" << rec_rap.get(ANA_COMRES);
|
||
const TRectype& rec_com_res = _cache770.get(LF_COMUNI, key);
|
||
rec.set(126, rec_rap.get(ANA_COFI));
|
||
rec.set(127, rec_nditte.get(NDT_CARRAPP));
|
||
rec.set(131, rec_rap.get(ANA_RAGSOC).left(24));
|
||
rec.set(132, rec_rap.get(ANA_RAGSOC).mid(30, 20));
|
||
rec.set(133, rec_rap_fis.get(ANF_SESSO));
|
||
rec.set(134, rec_rap_fis.get_date(ANF_DATANASC));
|
||
rec.set(135, rec_com_nas.get(COM_DENCOM));
|
||
rec.set(136, rec_com_nas.get(COM_PROVCOM));
|
||
|
||
// Ignoro la parte "estera"
|
||
|
||
ok = write(rec);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
long TTrasferimento770::append_quadro(const char* quadro, long codditta, TProgind& pi)
|
||
{
|
||
TString str;
|
||
str << TR("Trasferimento quadro ") << quadro << TR(" ditta ") << codditta;
|
||
pi.set_text(str);
|
||
|
||
char tipo;
|
||
int rpm;
|
||
TForm770& frm = _trc770.form(quadro, tipo, rpm);
|
||
long items = frm.trasfer(codditta, *this, tipo, rpm);
|
||
return items;
|
||
}
|
||
|
||
bool TTrasferimento770::riepiloga_ss(const TRecord770& rec, TArray& riep_ss) const
|
||
{
|
||
TString8 code;
|
||
real val;
|
||
for (int i = 0; rec.np_get_real(i, code, val); i++) if (code.starts_with("AU") && !val.is_zero())
|
||
{
|
||
const TString& key = code.right(3);
|
||
const int num = atoi(key);
|
||
if (num >= 26 && num <= 31)
|
||
{
|
||
const int idx = num-26;
|
||
real* r = (real*)riep_ss.objptr(idx);
|
||
if (r == NULL)
|
||
{
|
||
r = new real;
|
||
riep_ss.add(r, idx);
|
||
}
|
||
*r += val;
|
||
} else
|
||
if (num >= 43 && num <= 48)
|
||
{
|
||
const int idx = num-43;
|
||
real* r = (real*)riep_ss.objptr(idx);
|
||
if (r == NULL)
|
||
{
|
||
r = new real;
|
||
riep_ss.add(r, idx);
|
||
}
|
||
*r -= val;
|
||
}
|
||
}
|
||
return !riep_ss.empty();
|
||
}
|
||
|
||
bool TTrasferimento770::riepiloga_sx(const TRecord770& rec, TArray& riep_sx) const
|
||
{
|
||
TString8 code;
|
||
real val;
|
||
for (int i = 0; rec.np_get_real(i, code, val); i++) if (code.starts_with("ST") && !val.is_zero())
|
||
{
|
||
const int rig = atoi(code.mid(2,3));
|
||
const int col = atoi(code.mid(5,3));
|
||
if (rig >= 2 && rig <= 25 && col >= 4 && col <= 5)
|
||
{
|
||
real* r = (real*)riep_sx.objptr(5); // SX004005
|
||
if (r == NULL)
|
||
{
|
||
r = new real;
|
||
riep_sx.add(r, 5);
|
||
}
|
||
*r += val;
|
||
}
|
||
}
|
||
return !riep_sx.empty();
|
||
}
|
||
|
||
|
||
bool TTrasferimento770::split(const char* path)
|
||
{
|
||
close();
|
||
|
||
const long records = fsize(_name) / TOTAL_SIZE;
|
||
TRecnotype totale[26]; memset(totale, 0, sizeof(totale));
|
||
|
||
TRecord770 rec;
|
||
|
||
unsigned long disk_size = 15*1024*1024; // Max 15 Mb per fornitura
|
||
const bool magnetic = ::xvt_fsys_is_removable_drive(path) !=0;
|
||
if (magnetic)
|
||
{
|
||
if (!yesno_box(FR("Inserire il primo disco del trasferimento nell'unita' %s\n"
|
||
"Tutti i dischi devono essere vuoti ed avere la stesso formato.\n"
|
||
"Si desidera iniziare il trasferimento?"), path))
|
||
return false;
|
||
|
||
disk_size = ::xvt_fsys_get_disk_size(path, 'b');
|
||
}
|
||
const long records_per_disk = long(disk_size / TOTAL_SIZE) - 3; // Tolgo A,B,Z
|
||
const int volumes = int((records-1)/records_per_disk)+1;
|
||
|
||
TProgind pi(records, TR("Generazione file trasferimento"), false, true);
|
||
|
||
// Read from start
|
||
open("", 'r');
|
||
|
||
for (int volume = 1; volume <= volumes; volume++)
|
||
{
|
||
if (magnetic && volume > 1)
|
||
{
|
||
if (!yesno_box(FR("Inserire il disco %d di %d:\nSi desidera proseguire il trasferimento?"),
|
||
volume, volumes))
|
||
break;
|
||
}
|
||
|
||
// Specifica volume solo se necessario
|
||
const int v = (volumes > 1 && !magnetic) ? volume : 0;
|
||
TTrasferimento770 outfile(path, 'w', v);
|
||
|
||
if (_save_headers)
|
||
{
|
||
rec.tipo_record('A'); // Compila record di testata A
|
||
rec.set(3, "77S13"); // Codice fornitura
|
||
rec.set(4, 1); // Tipo fornitore 01 = Soggetto che invia la propria dichiarazione
|
||
rec.set(5, cod_fis_dic()); // Codice fiscale del fornitore
|
||
if (volumes > 1)
|
||
{
|
||
rec.set(7, volume);
|
||
rec.set(8, volumes);
|
||
}
|
||
else
|
||
{
|
||
rec.set(7, 0);
|
||
rec.set(8, 0);
|
||
}
|
||
|
||
outfile << rec; // Scrive record testata
|
||
}
|
||
|
||
long written = 0;
|
||
|
||
TArray riep_ss, riep_sx;
|
||
|
||
if (records > 0)
|
||
{
|
||
while (read(rec))
|
||
{
|
||
pi.addstatus(1);
|
||
|
||
const char tipo_rec = rec.tipo_record();
|
||
if (tipo_rec <= 'A' || tipo_rec == 'F' || tipo_rec == 'J' || tipo_rec >= 'Z')
|
||
continue;
|
||
|
||
if (_save_headers && tipo_rec > 'E' && riep_sx.items() > 0)
|
||
{
|
||
TRecord770 recf('F');
|
||
recf.set(2, cod_fis_dic());
|
||
recf.set(3, 1);
|
||
recf.set(8, CF_PRODUTTORE);
|
||
FOR_EACH_ARRAY_ITEM(riep_sx, i, obj)
|
||
{
|
||
const real* val = (const real*)obj;
|
||
if (val != NULL)
|
||
{
|
||
TString8 code;
|
||
code.format("SX004%03d", i);
|
||
recf.np_put(code, *val);
|
||
}
|
||
}
|
||
outfile << recf;
|
||
totale['F'-'A']++; // Praticamente vale sempre 1
|
||
riep_sx.destroy();
|
||
}
|
||
|
||
outfile << rec;
|
||
written++;
|
||
|
||
if (_save_headers)
|
||
{
|
||
totale[tipo_rec - 'A']++;
|
||
|
||
if (tipo_rec == 'E')
|
||
riepiloga_sx(rec, riep_sx);
|
||
|
||
if (tipo_rec == 'H')
|
||
riepiloga_ss(rec, riep_ss);
|
||
}
|
||
|
||
if (written >= records_per_disk)
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (_save_headers)
|
||
{
|
||
// Compila record di riepilogo SS
|
||
if (riep_ss.items() > 0)
|
||
{
|
||
rec.tipo_record('J');
|
||
rec.set(2, cod_fis_dic());
|
||
rec.set(3, 1);
|
||
rec.set(8, CF_PRODUTTORE);
|
||
FOR_EACH_ARRAY_ITEM(riep_ss, i, obj)
|
||
{
|
||
const real* val = (const real*)obj;
|
||
if (val != NULL)
|
||
{
|
||
TString8 code;
|
||
code.format("SS003%03d", i+1); // i=0 -> SS0003001 -> AUXXX026-AUXXX043
|
||
rec.np_put(code, *val);
|
||
}
|
||
}
|
||
outfile << rec;
|
||
totale['J'-'A']++; // Praticamente vale sempre 1
|
||
}
|
||
|
||
// Compila record di coda
|
||
rec.tipo_record('Z');
|
||
rec.set(3, totale['B'-'A']); // Totale B
|
||
rec.set(4, totale['D'-'A']); // Totale D
|
||
rec.set(5, totale['E'-'A']); // Totale E
|
||
rec.set(6, totale['F'-'A']); // Totale F
|
||
rec.set(7, totale['G'-'A']); // Totale G
|
||
rec.set(8, totale['H'-'A']); // Totale H
|
||
rec.set(9, totale['I'-'A']); // Totale I
|
||
rec.set(10,totale['J'-'A']); // Totale J
|
||
|
||
// Scrive record di coda
|
||
outfile << rec;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Cancella il file
|
||
void TTrasferimento770::remove()
|
||
{
|
||
close();
|
||
::remove(_name);
|
||
}
|
||
|
||
TTrasferimento770::TTrasferimento770(const char* path, char mode, int volume)
|
||
: _in_stream(NULL), _out_stream(NULL), _save_headers(false)
|
||
{
|
||
open(path, mode, volume);
|
||
}
|
||
|
||
TTrasferimento770::~TTrasferimento770()
|
||
{
|
||
close();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// main
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TTransfer770_msk : public TAutomask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& of, TField_event fe, long jolly);
|
||
|
||
public:
|
||
TTransfer770_msk();
|
||
};
|
||
|
||
bool TTransfer770_msk::on_field_event(TOperable_field& of, TField_event fe, long jolly)
|
||
{
|
||
switch (of.dlg())
|
||
{
|
||
case F_PATH:
|
||
if (fe == fe_modify || fe == fe_close)
|
||
{
|
||
TFilename name = of.get();
|
||
if (!name.exist())
|
||
return error_box("Il percorso non e' valido");
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
TTransfer770_msk::TTransfer770_msk() : TAutomask("777100a")
|
||
{
|
||
int anno = ini_get_int(CONFIG_STUDIO, "77", "AnnoDic");
|
||
if (anno <= 0)
|
||
{
|
||
const TDate oggi(TODAY);
|
||
anno = oggi.year()-1;
|
||
}
|
||
set(F_ANNO, anno);
|
||
}
|
||
|
||
class TTransfer770_app : public TSkeleton_application
|
||
{
|
||
protected:
|
||
virtual void main_loop();
|
||
};
|
||
|
||
void TTransfer770_app::main_loop()
|
||
{
|
||
TTransfer770_msk m;
|
||
|
||
while (m.run() == K_ENTER)
|
||
{
|
||
TFilename tmp; tmp.tempdir();
|
||
TTrasferimento770 t(tmp, 'w');
|
||
t.save_headers(m.get_bool(F_HEADERS));
|
||
_trc770.set_cent_mode(m.get_bool(F_CENT));
|
||
|
||
TRelation rel_base(LF_BASE);
|
||
TRectype da_rec(LF_BASE), a_rec(LF_BASE);
|
||
da_rec.put(BSE_CODDITTA, m.get(F_DADITTA));
|
||
a_rec.put(BSE_CODDITTA, m.get(F_ADITTA));
|
||
|
||
TString16 filter;
|
||
/*
|
||
filter << '(' << BSE_ANNODIC << '=' << m.get(F_ANNO) << ")||"
|
||
<< '(' << BSE_ANNODIC << "=0)";
|
||
*/
|
||
TCursor cur_base(&rel_base, filter, 1, &da_rec, &a_rec);
|
||
const TRecnotype items = cur_base.items();
|
||
cur_base.freeze();
|
||
|
||
TProgind pi(items, TR("Generazione file di trasferimento"), false, true);
|
||
for (cur_base = 0; cur_base.ok(); ++cur_base)
|
||
{
|
||
const TRectype& base = cur_base.curr();
|
||
const long codditta = base.get_long(BSE_CODDITTA);
|
||
pi.addstatus(1);
|
||
t.read_codfis_dic(base);
|
||
|
||
t.append_record_b();
|
||
t.append_quadro("ST", codditta, pi);
|
||
t.append_quadro("LA", codditta, pi);
|
||
}
|
||
pi.close_modal();
|
||
|
||
if (m.get(F_SUPPORTO) == "D")
|
||
tmp = m.get(F_DISK);
|
||
else
|
||
tmp = m.get(F_PATH);
|
||
|
||
t.split(tmp);
|
||
t.remove();
|
||
}
|
||
|
||
_trc770.destroy();
|
||
}
|
||
|
||
int m777100(int argc, char* argv[])
|
||
{
|
||
TTransfer770_app app;
|
||
app.run(argc, argv, "Invio");
|
||
return 0;
|
||
}
|