campo-sirio/m770/777100.cpp
angelo a7867e4a1c Patch level :
Files correlati     :
Ricompilazione Demo : [ ]
Commento            : Corrette alcune diciture sul programma di Invio:
non piu' 770 ma Gestione percipienti


git-svn-id: svn://10.65.10.50/trunk@7029 c028cbd2-c16b-5b4b-a496-9718f37d4682
1998-09-03 13:28:56 +00:00

1453 lines
39 KiB
C++
Executable File
Raw Blame History

#include <fstream.h>
#include <applicat.h>
#include <form.h>
#include <automask.h>
#include <os_dep.h>
#include <progind.h>
#include <recarray.h>
#include <utility.h>
#include "777.h"
#include "777100a.h"
#include <anagr.h>
#include <anafis.h>
#include <anagiu.h>
#include <comuni.h>
#include <nditte.h>
#include "base.h"
#include "quadroc.h"
///////////////////////////////////////////////////////////
// Dichiarazioni
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// TForm770
///////////////////////////////////////////////////////////
class TRecord770;
class TTrasferimento770;
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(); }
public:
long trasfer(long codditta, TTrasferimento770& file, char tipo, int rpm);
TForm770(const char* name);
virtual ~TForm770();
};
///////////////////////////////////////////////////////////
// TRecord770
///////////////////////////////////////////////////////////
enum { FIELD_SIZE = 16, BLOCK_SIZE = 24,
USEABLE_SIZE = 3997, TOTAL_SIZE = 4000 };
struct TField770 : public TObject
{
TString _desc;
int _pos; // Base 1
int _len;
char _type; // A/N
};
class TTracciato770 : public TObject
{
char _tipo;
TArray _fields;
protected:
int add_field(const char* name, char type, int pos, int len);
int add_filler(char type, int pos, int len)
{ return add_field("Filler", type, 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;
public:
const TTracciato770& tracciato(char tipo);
TForm770& form(const char* quadro, char& tipo, int& rpm);
void destroy();
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;
bool fill(const TRectype& rec);
bool fill_e(const TRectype& rec);
bool fill_comune(const TRectype& rec_anagr, int whichcom, bool swapcap, int offset);
bool fill_residenza(const TRectype& rec_anagr, int offset, int whichcom, bool swapcap);
bool fill_telefono(const TRectype& rec_anagr, int offset);
bool fill_persona(const TRectype& rec_anagr, int offset, int gap);
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 add(const char* code, const char* val);
const char* get(int pos, TString& str) const;
int get_int(int pos) const;
char get_char(int pos) const;
const TRecord770& operator=(const TRecord770& rec)
{ _buffer = rec._buffer; return *this; }
const TRecord770& operator=(const TRectype& rec)
{ fill(rec); 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();
void set_magnetic_support(bool mag)
{ _buffer[3997] = mag ? 'A' : ' '; }
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;
public:
bool open(const char* path = "", char mode = 'r');
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 { return "MOD77098"; }
TTrasferimento770& operator<<(const TRecord770& rec)
{ write(rec); return *this; }
TTrasferimento770& operator>>(TRecord770& rec)
{ read(rec); return *this; }
long append_quadro(const char* quadro, long codditta, TProgind& pi);
bool split(const char* dest_path);
void remove();
TTrasferimento770(const char* name = "", char mode = 'r');
virtual ~TTrasferimento770();
};
///////////////////////////////////////////////////////////
// Implementazioni
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// TForm770
///////////////////////////////////////////////////////////
void TForm770::transfer_section(TPrint_section& body, int rigo,
TRecord770& rec, TTrasferimento770& file)
{
TString16 basecode, code;
TString80 str;
TCursor& cur = *cursor();
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())
{
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 = cur.curr(num).type(fn);
switch (ft)
{
case _boolfld:
if (!str.blank())
str = "1";
str.right_just(16);
break;
case _datefld:
if (str.len() == 10 && str[2] == '-' && str[5] == '-')
{
str[2] = str[3]; str[3] = str[4];
str[4] = str[8]; str[5] = str[9];
str.cut(6); str.right_just(16);
}
break;
case _realfld:
if (str.len() > 3)
str.rtrim(3);
case _intfld:
case _longfld:
str.right_just(16);
break;
default:
break;
}
}
const int vero_rigo = atoi(basecode.mid(2, 2)) + rigo;
code.format("%c%c%02d%c%c00", basecode[0], basecode[1],
vero_rigo, basecode[4], basecode[5]);
if (!rec.add(code, str))
{
file << rec;
rec.azzera_campi_non_posizionali();
rec.add(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;
}
long TForm770::trasfer(long codditta, TTrasferimento770& file,
char rectype, int rpm)
{
TCursor& cur = *cursor();
// Filtra il cursore sulla ditta corrente
TRectype filter(cur.curr());
filter.zero();
filter.put(BSE_CODDITTA, codditta);
cur.setregion(filter, filter);
const long items = cur.items();
if (items > 0) // Se c'e almeno un record ...
{
cur.freeze(TRUE); // Per efficienza congela il cursore
int rpm = 10; // Righe per modulo
// Inizializza record col primo modulo
TRecord770 rec(rectype);
int modulo = 1;
int rigo = 0;
rec.set(6, modulo);
int err = first(); // Deve sempre tornare NOERR
TPrint_section& head = section('H', first_page);
transfer_section(head, rigo, rec, file);
for (; err == NOERR; err = next())
{
TPrint_section& body = section('B', odd_page);
transfer_section(body, rigo, rec, file);
rigo++;
if (rigo >= rpm)
{
// Scrivi record se non vuoto
if (rec.get_char(7) > ' ')
file << rec;
// Avanza al prossimo modulo ed azzera la riga
rigo = 0;
modulo++;
rec.azzera_campi_non_posizionali();
rec.set(6, modulo);
transfer_section(head, rigo, rec, file);
}
}
// Ultimo record parzialmente compilato
if (rec.get_char(7) > ' ')
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_QUAC: key = "CODDITTA|TIPOA|216@->RAGSOC|CODANAGR|CODCAUS|PERC";
case LF_QUAD: 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
///////////////////////////////////////////////////////////
int TTracciato770::add_field(const char* name, char type, int pos, int len)
{
TField770* info = new TField770;
info->_desc = name;
info->_type = type;
info->_pos = pos;
info->_len = len;
_fields.add(info);
return _fields.items();
}
const TField770& TTracciato770::field(int pos) const
{
TField770* info = (TField770*)_fields.objptr(pos-1);
CHECKD(info, "Campo non valido ", pos);
return *info;
}
void TTracciato770::auto_fill(TString& buffer) const
{
buffer.fill(' ', TOTAL_SIZE);
for (int f = _fields.last(); f >= 0; f--)
{
const TField770& info = (const TField770&)_fields[f];
if (info._desc == "Filler")
{
const char fill = info._type == 'N' ? '0' : ' ';
char* index = buffer.get_buffer();
index += info._pos - 1;
memset(index, fill, info._len);
}
}
buffer[0] = _tipo;
buffer.overwrite("\r\n", TOTAL_SIZE-2);
}
TTracciato770::TTracciato770(char tipo) : _tipo(tipo)
{
if (strchr("AEFGHZ", tipo) == NULL)
NFCHECK("Tipo record non valido: %c", tipo);
add_field("Tipo record", 'A', 1, 1); // 1
add_filler('N', 2, 2); // 2
if (tipo == 'A' || tipo == 'Z')
{
add_filler('N', 4, 2); // 3
add_field("Numero totale volumi inviati", 'N', 6, 3);
add_field("Progressivo del volume inviato", 'N', 9, 3);
add_field("Data di emissione", 'N', 12, 6);
add_field("Codice fornitura", 'N', 18, 5);
if (tipo == 'A')
{
add_field("Tipo fornitore", 'N', 23, 1); // 8
add_field("Codice fiscale del fornitore", 'A', 24, 16);
add_field("Cognome del fornitore", 'A', 40, 60);
add_field("Data di nascita del fornitore", 'N', 100, 8);
add_field("Comune o stato", 'A', 108, 40);
add_field("Provincia di nascita", 'A', 148, 2);
add_field("Indirizzo", 'A', 150, 35);
add_field("C.A.P.", 'N', 185, 5);
add_field("Comune di residenza", 'A', 190, 40);
add_field("Provincia di residenza", 'A', 230, 2);
add_field("Indirizzo di residenza", 'A', 232, 35);
add_field("C.A.P. di residenza", 'N', 267, 5);
}
else
{
add_field("Numero complessivo di record", 'N', 23, 9); // 8
add_filler('N', 32, 9);
add_field("Numero record di tipo 'E'", 'N', 41, 9);
add_field("Numero record di tipo 'F'", 'N', 50, 9);
add_field("Numero record di tipo 'G'", 'N', 59, 9);
add_field("Numero record di tipo 'H'", 'N', 68, 9);
add_filler('A', 77, 3921);
add_field("Supporto magnetico", 'A',3998, 1);
}
}
if (tipo >= 'E' && tipo <= 'H')
{
add_field("Codice fiscale del soggetto dichiarante", 'A', 4, 16); // 3
add_field("Protocollo", 'A', 20, 25);
add_field("Spazio riservato all'applicazione", 'A', 45, 35);
if (tipo == 'E')
{
add_field("Data di presentazione", 'N', 80, 6); // 6
add_field("Numero progressivo del pacco", 'N', 86, 7);
add_field("Numero sequenza all'interno del pacco", 'N', 93, 3);
add_field("Cognome", 'A', 96, 60);
add_field("Nome", 'A',120, 20);
add_filler('A',140, 16);
add_field("Dichiarazione integrativa", 'N',156, 1); // 12
add_field("Data di nascita del dichiarante", 'N',157, 6);
add_field("Sesso", 'A',163, 1);
add_field("Comune o Stato estero di nascita", 'A',164, 40);
add_field("Sigla provincia di nascita del dic", 'A',204, 2);
add_field("Mese di variazione residenza o domicilio",'N',206, 2);
add_field("Anno variazione residenza o domicilio", 'N',208, 2);
add_field("Comune di residenza o domicilio dich", 'A',210, 40);
add_field("Sigla provincia di resid o domicilio", 'A',250, 2); // 20
add_field("Indirizzo residenza o domicilio", 'A',252, 35);
add_field("CAP residenza o domicilio", 'N',287, 5);
add_field("Codice attivit<69> F", 'A',292, 5);
add_field("Telefono F", 'A',297, 13);
add_field("Mese variazione sede legale", 'N',310, 2);
add_field("Anno variazione sede legale", 'N',312, 2);
add_field("Comune della sede legale", 'A',314, 40);
add_field("Sigla provincia sede legale", 'A',354, 2);
add_field("Indirizzo sede legale", 'A',356, 35);
add_field("CAP sede legale", 'N',391, 5); // 30
add_field("Mese variazione domicilio fiscale", 'N',396, 2);
add_field("Anno variazione domicilio fiscale", 'N',398, 2);
add_field("Comune domicilio fiscale", 'N',400, 40);
add_field("Sigla provincia domicilio fiscale", 'N',440, 2);
add_field("Indirizzo domicilio fiscale", 'A',442, 35);
add_field("CAP domicilio fiscale", 'N',477, 5);
add_field("Codice attivit<69> G", 'A',482, 5);
add_field("Stato", 'N',487, 1);
add_field("Natura giuridica", 'N',488, 2);
add_field("Situazione", 'N',490, 1); // 40
add_field("Telefono G", 'A',491, 13);
add_field("Codice fiscale", 'A',504, 16);
add_field("Codice carica", 'N',520, 1);
add_field("Cognome rappresentante", 'A',521, 24);
add_field("Nome del rappresentante", 'A',545, 20);
add_field("Sesso del rappresentante", 'A',565, 1);
add_field("Data nascita rappresentante", 'N',566, 6);
add_field("Comune nascita rappresentante", 'A',572, 40);
add_field("Sigla provincia nascita rap", 'A',612, 2);
add_field("Comune residenza anagrafica rap", 'A',614, 40); // 50
add_field("Sigla residenza anagrafica nascita rap", 'A',654, 2);
add_field("CAP residenza anagrafica rap", 'N',656, 5);
add_field("Indirizzo residenza anagrafica rap", 'A',661, 35);
add_field("Telefono rap", 'A',696, 13);
add_field("Casella quadro SA", 'N',709, 1);
add_field("Casella quadro SB", 'N',710, 1);
add_field("Casella quadro SC", 'N',711, 1);
add_field("Casella quadro SD", 'N',712, 1);
add_field("Casella quadro SE", 'N',713, 1);
add_field("Casella quadro SF", 'N',714, 1); // 60
add_field("Casella quadro SG", 'N',715, 1);
add_field("Casella quadro SH", 'N',716, 1);
add_field("Casella quadro SK", 'N',717, 1);
add_field("Casella quadro SL", 'N',718, 1);
add_field("Casella quadro SM", 'N',719, 1);
add_field("Casella quadro SN", 'N',720, 1);
add_field("Casella quadro SP", 'N',721, 1);
add_field("Casella quadro SQ", 'N',722, 1);
add_field("Casella quadro SR", 'N',723, 1);
add_field("Casella quadro SS", 'N',724, 1); // 70
add_field("Casella quadro ST", 'N',725, 1);
add_field("Casella quadro SU", 'N',726, 1);
add_field("Casella quadro SV", 'N',727, 1);
add_field("Casella quadro SW", 'N',728, 1);
add_field("Casella quadro SZ", 'N',729, 1);
add_field("Firma presidente o compon organo contr", 'N',730, 1);
add_field("Firma del dichiarante", 'N',731, 1);
add_field("Codice fiscale del CAAF", 'N',732, 11);
add_field("Numero iscrizione all'albo", 'N',743, 5);
add_field("Codice fiscale Direttore Tecnico CAAF", 'A',748, 16); // 80
add_field("Casella controlli", 'N',764, 1);
add_field("Dichiarazione non compilata", 'N',765, 1);
add_field("Dichiarazione non firmata", 'N',766, 1);
add_field("Dichiarazione incompleta", 'N',767, 1);
add_field("Altri casi 1", 'N',768, 1);
add_field("Altri casi 2", 'N',769, 1);
add_field("Dichiarazione smarrita", 'N',770, 1);
}
else
{
add_field("Numero modulo", 'N', 80, 6); // 6
add_field("Campi non posizionali", 'A', 86, 24); // 7
add_field("Supporto magnetico", 'A', 3998, 1); // 8
}
}
}
TTracciato770::~TTracciato770()
{
}
///////////////////////////////////////////////////////////
// TTracciati770
///////////////////////////////////////////////////////////
const TTracciato770& TTracciati770::tracciato(char tipo)
{
const int pos = tipo-'A';
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& tipo, int& rpm)
{
CHECK(quadro && *quadro == 'S' && quadro[1] != '\0',
"Codice quadro non valido");
const char* name;
switch(quadro[1])
{
case 'C': name = "77qc"; tipo = 'F'; rpm = 11; break;
case 'F': name = "77qd"; tipo = 'G'; rpm = 9; break;
case 'G': name = "77qdb"; tipo = 'G'; rpm = 9; break;
case 'H': name = "77qd1"; tipo = 'G'; rpm = 9; break;
case 'K': name = "77qsk"; tipo = 'G'; rpm = 31; break;
case 'L': name = "77ql"; tipo = 'G'; rpm = 22; break;
case 'P': name = "77qe"; tipo = 'G'; rpm = 14; break;
case 'Q': name = "77qe1"; tipo = 'G'; rpm = 15; 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()
{
}
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); 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 == 'N')
str.right_just(fld._len);
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 == 'N', "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 == 'N', "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 == 'N', "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 == 'N' && (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 == 'A' && 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 == 'N' && fld._len == 1,
"Invalid boolean field ", pos);
const char str[2] = { val ? '1' : '0', '\0' };
set(fld, str);
}
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 == 'A', "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;
const int len = strlen(val);
if (len > 16)
blocks += (len-17) / 15 + 1;
return blocks;
}
// Azzera tutti i campi non posizionali dei record di tipo F, G e H
void TRecord770::azzera_campi_non_posizionali()
{
CHECK(strchr("FGH", tipo_record()) != NULL,
"Impossibile azzerare un record senza campi non posizionali");
char* buf = _buffer.get_buffer() + 85;
memset(buf, ' ', TOTAL_SIZE-88);
}
// Aggiunge un campo non posizionale ai record di tipo F, G e H
bool TRecord770::add(const char* code, const char* val)
{
CHECK(strchr("FGH", tipo_record()) != NULL,
"Impossibile aggiungere campi non posizionali");
CHECKS(code && strlen(code) == 8, "Invalid field code ", code);
CHECKS(val && *val, "Can't add empty field ", code);
// Cerca il primo posto libero
for (int pos = 85; pos < 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 += 8;
if (i != 0)
{
_buffer.overwrite("+", pos);
pos++;
}
const int maxlen = 15 + (i == 0);
const TString& substr = str.mid(i, maxlen);
_buffer.overwrite(substr, pos);
pos += maxlen;
i += maxlen;
}
}
return ok;
}
bool TRecord770::fill_persona(const TRectype& rec_anagr, int offset, int gap)
{
TString16 key = rec_anagr.get(ANA_CODANAGR);
const TRectype& rec_anafis = _cache770.get(LF_ANAGFIS, key);
set(0+offset, rec_anagr.get(ANA_RAGSOC).left(24));
set(1+offset, rec_anagr.get(ANA_RAGSOC).mid(30, 20));
if (gap)
{
offset += gap;
set(2+offset, rec_anafis.get_date(ANF_DATANASC));
set(3+offset, rec_anafis.get(ANF_SESSO));
}
else
{
set(2+offset, rec_anafis.get(ANF_SESSO));
set(3+offset, rec_anafis.get_date(ANF_DATANASC));
}
key = rec_anafis.get(ANF_COMNASC);
if (key.not_empty())
{
key.insert(" |");
const TRectype& rec_comnasc = _cache770.get(LF_COMUNI, key);
set(4+offset, rec_comnasc.get(COM_DENCOM).left(40));
set(5+offset, rec_comnasc.get(COM_PROVCOM).left(2));
}
return TRUE;
}
bool TRecord770::fill_telefono(const TRectype& rec_anagr,int offset)
{
TString80 key = rec_anagr.get(ANA_PTELRF);
if (key.not_empty()) key << '-';
key << rec_anagr.get(ANA_TELRF);
key.cut(13);
set(offset, key);
return key.not_empty();
}
bool TRecord770::fill_comune(const TRectype& rec_anagr,
int whichcom, bool swapcap, int offset)
{
bool use_comres;
if (whichcom < 0)
use_comres = rec_anagr.get(ANA_COMRF).empty();
else
use_comres = whichcom ? TRUE : FALSE;
TString80 key = rec_anagr.get(use_comres ? ANA_COMRES : ANA_COMRF);
if (key.not_empty())
{
key.insert(" |");
const TRectype& rec_comres = _cache770.get(LF_COMUNI, key);
set(0+offset, rec_comres.get(COM_DENCOM).left(40));
set(1+offset, rec_comres.get(COM_PROVCOM).left(2));
key = rec_anagr.get(use_comres ? ANA_INDRES : ANA_INDRF);
if (key.not_empty()) key << ',';
key << rec_anagr.get(use_comres ? ANA_CIVRES : ANA_CIVRF);
key.cut(35);
if (swapcap)
{
set(3+offset, key);
set(2+offset, rec_anagr.get(use_comres ? ANA_CAPRES : ANA_CAPRF));
}
else
{
set(2+offset, key);
set(3+offset, rec_anagr.get(use_comres ? ANA_CAPRES : ANA_CAPRF));
}
}
return key.not_empty();
}
bool TRecord770::fill_residenza(const TRectype& rec_anagr, int offset,
int whichcom, bool swapcap)
{
bool use_comres;
if (whichcom < 0)
use_comres = rec_anagr.get(ANA_COMRF).empty();
else
use_comres = whichcom ? TRUE : FALSE;
const TDate data_var_df = rec_anagr.get(use_comres ? ANA_DVARSLORES : ANA_DVARDF);
set(0+offset, data_var_df.month());
set(1+offset, data_var_df.year() % 100);
return fill_comune(rec_anagr, whichcom, swapcap, 2+offset);
}
bool TRecord770::fill_e(const TRectype& rec)
{
TString80 key; // Stringa multiuso
tipo_record('E');
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())
return error_box("Non esiste la ditta %s", (const char*)key);
const char tipoa = rec_nditte.get_char(NDT_TIPOA);
const long codan = rec_nditte.get_long(NDT_CODANAGR);
key.cut(0);
key << tipoa << '|' << rec_nditte.get(NDT_CODANAGR);
const TRectype& rec_anagr = _cache770.get(LF_ANAG, key);
if (rec_anagr.empty())
return error_box("Non esiste la persona %s", (const char*)key);
set(3, rec_anagr.get(ANA_COFI)); // Codice fiscale del dichiarante
if (tipoa == 'F')
{
fill_persona(rec_anagr, 9, 2); // 9 - 16
fill_residenza(rec_anagr, 17, -1, FALSE); // 17 - 22
set(23, rec_nditte.get(NDT_CODATTPREV));
fill_telefono(rec_anagr, 24);
}
else
{
set(9, rec_anagr.get(ANA_RAGSOC));
fill_residenza(rec_anagr, 25, 1, FALSE);
fill_residenza(rec_anagr, 31, 0, FALSE);
set(37, rec_nditte.get(NDT_CODATTPREV));
const TRectype& rec_anagiu = _cache770.get(LF_ANAGGIU, codan);
set(38, rec_anagiu.get(ANG_STATOSOC));
set(39, rec_anagiu.get(ANG_NATGIU));
set(40, rec_anagiu.get(ANG_SITSOC));
fill_telefono(rec_anagr, 41);
}
// Rappresentante
key = rec_nditte.get(NDT_RAPPR);
if (key.not_empty())
{
key.insert("F|");
const TRectype& rec_anagr = _cache770.get(LF_ANAG, key);
if (!rec_anagr.empty())
{
set(42, rec_anagr.get(ANA_COFI)); // Codice fiscale del dichiarante
fill_persona(rec_anagr, 44, 0); // 44- 49
fill_comune(rec_anagr, -1, TRUE, 50);
fill_telefono(rec_anagr, 54);
}
}
TDecoder basebis(LF_BASEBIS, BSE_QCOMP);
key = rec.get(BSE_TIPOQUA);
key << '|' << rec.get(BSE_CODDITTA);
key = basebis.decode(key);
key.left_just(21);
for (int q = 0; q < 21; q++)
{
const bool yes = key[q] > ' ';
set(55+q, yes);
}
return TRUE;
}
// Assegna un rectype (serve solo per il quadro base)
bool TRecord770::fill(const TRectype& rec)
{
bool ok = FALSE;
switch(rec.num())
{
case LF_BASE: ok = fill_e(rec); break;
default: NFCHECK("Unsupported record assignment"); break;
}
return ok;
}
bool TRecord770::valid() const
{
char tipo = tipo_record();
bool ok = (tipo > ' ') && (strchr("AEFGHZ", 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(const TRectype& rec)
{ fill(rec); }
TRecord770::~TRecord770()
{ }
///////////////////////////////////////////////////////////
// TTrasferimento770
///////////////////////////////////////////////////////////
bool TTrasferimento770::open(const char* path, char mode)
{
CHECK(mode == 'r' || mode == 'w', "Invalid open mode");
close();
if (path && *path)
{
_name = path;
_name.add(default_name());
}
if (_name.empty())
_name = default_name();
if (mode == 'r')
_in_stream = new ifstream(_name, ios::in | ios::nocreate | 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;
}
long TTrasferimento770::append_quadro(const char* quadro, long codditta,
TProgind& pi)
{
TString80 str;
str << "Trasferimento quadro " << quadro << " 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::split(const char* path)
{
close();
long totale[4]; memset(totale, 0, sizeof(totale));
long records = fsize(_name) / TOTAL_SIZE;
TRecord770 rec;
if (records > 0)
{
open("", 'r');
TProgind pi(records, "Conteggio records da trasferire", FALSE, TRUE);
while (read(rec))
{
pi.addstatus(1);
const int pos = rec.tipo_record() - 'E';
if (pos >= 0 && pos < 4)
totale[pos]++;
}
records = totale[0]+totale[1]+totale[2]+totale[3];
}
else
return FALSE;
long records_per_disk = 0;
int volumes = 1;
const bool magnetic = ::os_is_removable_drive(path);
if (magnetic)
{
if (!yesno_box("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;
unsigned long disk_size = ::os_get_disk_size(path);
records_per_disk = long(disk_size / TOTAL_SIZE - 2);
volumes = int((records-1)/records_per_disk)+1;
}
TProgind pi(records, "Trasferimento records", FALSE, TRUE);
// Read from start
open("", 'r');
for (int volume = 1; volume <= volumes; volume++)
{
if (magnetic && volume > 1)
{
if (!yesno_box("Inserire il disco %d di %d:\n"
"Si desidera proseguire il trasferimento?",
volume, volumes))
{
break;
}
}
TTrasferimento770 outfile(path, 'w');
// Compila record di testata
rec.tipo_record('A');
if (magnetic)
{
rec.set(4, volumes);
rec.set(5, volume);
}
const TDate data_emissione(TODAY);
rec.set(6, data_emissione);
rec.set(7, "77098");
rec.set_magnetic_support(magnetic);
outfile << rec; // Scrive record testata
// Azzera totali
memset(totale, 0, sizeof(totale));
long written = 0;
while (read(rec))
{
const char tipo_rec = rec.tipo_record();
if (tipo_rec == 'A' || tipo_rec == 'Z')
continue;
const int pos = tipo_rec - 'E';
if (pos >= 0 && pos < 4)
{
rec.set_magnetic_support(magnetic);
outfile << rec;
totale[pos]++;
written++;
pi.addstatus(1);
}
else
error_box("Tipo record non riconosciuto: %c", tipo_rec);
if (magnetic && written > records_per_disk)
break;
}
// Compila record di coda
rec.tipo_record('Z');
if (magnetic)
{
rec.set(4, volumes);
rec.set(5, volume);
rec.set_magnetic_support(magnetic);
}
rec.set(6, data_emissione);
rec.set(7, "77098");
rec.set(8, written);
for (int r = 0; r < 4; r++)
rec.set(10+r, totale[r]);
// Scrive record di coda
outfile << rec;
}
return TRUE;
}
// Cancella il file
void TTrasferimento770::remove()
{
close();
::remove(_name);
}
TTrasferimento770::TTrasferimento770(const char* path, char mode)
: _in_stream(NULL), _out_stream(NULL)
{
open(path, mode);
}
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() : TAutomask("777100a") { }
virtual ~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;
}
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');
TRecord770 rec;
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));
TCursor cur_base(&rel_base, "", 1, &da_rec, &a_rec);
TProgind pi(cur_base.items(), "Generazione file di trasferimento", FALSE, TRUE);
cur_base.freeze();
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);
rec = base;
t << rec; // Append quadro base
t.append_quadro("SC", codditta, pi);
t.append_quadro("SF", codditta, pi);
t.append_quadro("SG", codditta, pi);
t.append_quadro("SH", codditta, pi);
t.append_quadro("SK", codditta, pi);
t.append_quadro("SL", codditta, pi);
t.append_quadro("SP", codditta, pi);
t.append_quadro("SQ", 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;
}