campo-sirio/li/li0600.cpp
luca f1560c6744 Patch level :4.0 nopatch
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :corretti errori di compilazione dovuti a compilatore nuovo


git-svn-id: svn://10.65.10.50/trunk@14700 c028cbd2-c16b-5b4b-a496-9718f37d4682
2007-01-02 14:26:03 +00:00

1253 lines
34 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <dongle.h>
#include <execp.h>
#include <progind.h>
#include <recarray.h>
#include <recset.h>
#include <relapp.h>
#include <reprint.h>
#include <tabutil.h>
#include <utility.h>
#include <anagr.h>
#include <anafis.h>
#include <anagiu.h>
#include <clifo.h>
#include <comuni.h>
#include <nditte.h>
#include "../ba/ba0100a.h"
#include "li0.h"
#include "li0600a.h"
#include "li0600b.h"
#include "letint.h"
//--------------------------------------------------------------
// MASCHERA
//--------------------------------------------------------------
class TSend_letint_mask : public TAutomask
{
protected:
bool on_field_event(TOperable_field& o, TField_event e, long jolly);
bool ask_service_pwd();
public:
TSend_letint_mask();
virtual ~TSend_letint_mask() {}
};
TSend_letint_mask::TSend_letint_mask()
:TAutomask("li0600a")
{
}
static TDate _da_data, _a_data;
static bool filtra_per_date(const TRelation* rel)
{
const TDate data = rel->curr().get(LETINT_DATAREG);
return data >= _da_data && data <= _a_data;
}
bool TSend_letint_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_ANNO:
if (e == fe_modify || e == fe_init) //propone il mese corrispondente al primo record NON inviato
{
int mese = 1;
TLocalisamfile letint(LF_LETINT);
const int anno(get_int(F_ANNO));
letint.put(LETINT_ANNO, anno);
int err = letint.read(_isgteq);
if (err == NOERR && letint.get_int(LETINT_ANNO) == anno)
{
for ( ; err == NOERR && letint.get_int(LETINT_ANNO) == anno; err = letint.next())
{
const TDate first_rip = letint.get_date(LETINT_DATAREG);
const int m = first_rip.month();
if (letint.get_bool(LETINT_INVIATO) == false)
{
mese = m;
break;
}
else //caso in cui l'ultimo mese è tutto inviato (ripropone lo stesso mese)
{
if (m > mese)
mese = m;
}
}
}
TString4 str_mese; str_mese.format("%02d", mese);
o.mask().set(F_MESE, str_mese);
//riempie i campi dei progressivi e totali inviati
TISAM_recordset reg_dich("USE REG SELECT (I0==10)&&(CODTAB[1,4]=#ANNO)");
reg_dich.set_var("#ANNO", TVariant(long(anno)));
if (reg_dich.move_first())
{
set(F_PROGINV, reg_dich.get("I3").as_int());
set(F_TOTINV, reg_dich.get("I4").as_int());
set(F_REGISTRO, reg_dich.get("CODTAB[5,7]").as_string());
enable(DLG_OK);
}
else
{
reset(F_PROGINV);
reset(F_TOTINV);
disable(DLG_OK);
error_box(TR("Non esiste il registro delle dichiarazioni d'intento per l'anno selezionato."));
}
}
break;
case F_RIPRISTINA:
if (e == fe_button)
{
if (ask_service_pwd()) //chiede la pwd di servizio x ripristinare
{
TMask mask("li0600b"); //maschera per selezionare il mese ed anno da ripristinare
if (mask.run() == K_ENTER)
{
//ripristinare solo dichiarazioni del mese/anno selezionato
const int anno_rip = mask.get_int(F_ANNO);
const int mese_rip = mask.get_int(F_MESE);
TRectype darec(LF_LETINT), arec(LF_LETINT);
darec.put(LETINT_ANNO, anno_rip);
arec.put(LETINT_ANNO, anno_rip);
TRelation rel_letint(LF_LETINT);
_da_data = TDate(1, mese_rip, anno_rip);
_a_data = TDate(31, 12, anno_rip);
TCursor cur_letint(&rel_letint, "", 1, &darec, &arec);
cur_letint.set_filterfunction(filtra_per_date);
const long items = cur_letint.items();
//ripristinare solo se c'è qualcosa
if (items > 0)
{
if (yesno_box(TR("Si desidera ripristinare %ld dichiarazioni inviate?"), items))
if (yesno_box(TR("Si desidera veramente ripristinare %ld dichiarazioni inviate?"), items))
{
cur_letint.freeze();
TProgind pi(items, "Ripristino dichiarazioni inviate", false);
TRectype& rec_letint = rel_letint.curr();
for (cur_letint = 0; cur_letint.pos() < items; ++cur_letint)
{
pi.addstatus(1);
rec_letint.zero(LETINT_INVIATO); //svuota il campo
rel_letint.rewrite(); //aggiorna fisicamente il file
}
field(F_ANNO).set_focusdirty();
field(F_ANNO).on_hit();
}
else
return true;
else
return true;
} //end if(items>0)
else
message_box(TR("Non ci sono dichiarazioni inviate da ripristinare nel periodo selezionato"));
} //end mask.run()
} //end ask_service_pwd()
} //end if(e==fe_button)
break;
default:
break;
}
return true;
}
bool TSend_letint_mask::ask_service_pwd()
{
bool ok = false;
TMask mask("ba0100a");
mask.disable(F_USER);
mask.set(F_USER, "SERVIZIO");
if (mask.run() == K_ENTER)
{
const TDate oggi(TODAY);
TString16 pwd; pwd << dongle().administrator() << (oggi.month() + oggi.day());
ok = pwd == mask.get(F_PASSWORD);
}
if (!ok)
error_box(TR("Password di servizio errata!\nAccesso negato."));
return ok;
}
//---------------------------------------------------------------
// REPORT
//---------------------------------------------------------------
class TSend_letint_report : public TReport
{
word _last_printed_page;
protected:
virtual bool use_mask() { return false;}
virtual word last_printed_page() const { return _last_printed_page; }
public:
TSend_letint_report(int last_printed_page) : _last_printed_page(last_printed_page) {}
~TSend_letint_report() {}
};
///////////////////////////////////////////////////////////
// RECORD TRecord_DI
///////////////////////////////////////////////////////////
enum { CODE_SIZE = 8, FIELD_SIZE = 16, BLOCK_SIZE = 24, HEADER_SIZE = 89, USEABLE_SIZE = 1800, TOTAL_SIZE = 1900 };
struct TField_DI : public TObject
{
TString _desc;
int _pos; // Base 1
int _len;
char _type; // A/N
TString16 _dflt;
};
////////////////////////////////////////////////////////////
// RIEMPITORE CAMPI TRACCIATO TTracciato_DI
////////////////////////////////////////////////////////////
class TTracciato_DI : public TObject
{
char _tipo;
TArray _fields;
protected:
int add_field(const int numfield, const char* name, const char type, const int pos, const int len, const char* dflt = NULL);
int add_filler(const int numfield, const int pos, const int len, const char tipo = 'A')
{ return add_field(numfield, "Filler", tipo, pos, len); }
public:
const TField_DI& field(int pos) const;
void auto_fill(TString& buffer) const;
TTracciato_DI(char tipo);
virtual ~TTracciato_DI();
};
int TTracciato_DI::add_field(const int numfield, const char* name, const char type, const int pos, const int len, const char* dflt)
{
TField_DI* info = new TField_DI;
info->_desc = name;
info->_type = type;
info->_pos = pos;
info->_len = len;
info->_dflt = dflt;
_fields.add(info, numfield);
return _fields.items();
}
const TField_DI& TTracciato_DI::field(int pos) const
{
TField_DI* info = (TField_DI*)_fields.objptr(pos);
CHECKD(info, "Campo non valido ", pos);
return *info;
}
void TTracciato_DI::auto_fill(TString& buffer) const
{
buffer.fill(' ', TOTAL_SIZE);
for (int f = _fields.last(); f > 0; f = _fields.pred(f))
{
const TField_DI& info = (const TField_DI&)_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);
}
else //riempitore dei campi con valore fisso di default
{
const TString& dflt = info._dflt;
if (!dflt.blank())
{
char* index = buffer.get_buffer();
index += info._pos - 1;
memcpy(index, dflt, dflt.len());
}
}
}
buffer[0] = _tipo;
buffer.overwrite("A\r\n", TOTAL_SIZE-3);
}
TTracciato_DI::TTracciato_DI(char tipo) : _tipo(tipo)
{
if (strchr("ABCZ", tipo) == NULL)
NFCHECK("Tipo record non valido: %c", tipo);
TString4 header; header << _tipo;
add_field(1, "Tipo record", 'A', 1, 1, header);
TConfig config("li0600a.ini", header);
TString_array variables; //array con tutte le righe che trova nel paragrafo header del .ini
config.list_variables(variables, false, header, true); //l'array viene riempito in modo ordinato
TToken_string field_descr(15, ',');
FOR_EACH_ARRAY_ROW(variables, r, numriga)
{
field_descr = config.get(*numriga);
const int num = atoi(*numriga); //ordinale del campo nel record
const int pos = field_descr.get_int(0); //posizione iniziale del campo nel record (base 1)
const int len = field_descr.get_int(1); //lunghezza del campo
const TString4 tc = field_descr.get(2); //tipo campo
const char type = (tc=="AN" || tc=="CF" || tc=="CN") ? 'A' : 'N';
const char* dflt = field_descr.get(3); //valore di default
add_field(num, *numriga, type, pos, len, dflt);
}
}
TTracciato_DI::~TTracciato_DI()
{
}
///////////////////////////////////////////////////////////////
class TTracciati_DI : public TObject
{
TArray _trc;
TAssoc_array _form;
public:
const TTracciato_DI& tracciato(char tipo);
void destroy();
TTracciati_DI();
virtual ~TTracciati_DI();
} _trc_DI;
const TTracciato_DI& TTracciati_DI::tracciato(char tipo)
{
const int pos = tipo-'A';
TTracciato_DI* trc = (TTracciato_DI*)_trc.objptr(pos);
if (trc == NULL)
{
trc = new TTracciato_DI(tipo);
_trc.add(trc, pos);
}
return *trc;
}
void TTracciati_DI::destroy()
{
_trc.destroy();
_form.destroy();
}
TTracciati_DI::TTracciati_DI()
{
}
TTracciati_DI::~TTracciati_DI()
{
destroy(); // Non viene mai chiamato!
}
/////////////////////////////////////////////////////////////
// RECORD
/////////////////////////////////////////////////////////////
class TRecord_DI : public TObject
{
TString _buffer;
protected: // TObject
virtual TObject* dup() const { return new TRecord_DI(*this); }
virtual void print_on(ostream& outs) const;
virtual void read_from(istream& ins);
protected: // TObject
const TTracciato_DI& tracciato() const
{ return _trc_DI.tracciato(tipo_record()); }
const TField_DI& get_field(int pos) const
{ return tracciato().field(pos); }
void set(const TField_DI& 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 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 TRecord_DI& operator=(const TRecord_DI& 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); }
const char* readable_buffer() const { return _buffer; }
char* writeable_buffer() { return _buffer.get_buffer(); }
void azzera_campi_non_posizionali();
bool ha_campi_non_posizionali() const { return strchr("C", tipo_record()) != NULL; }
bool ha_campi_non_posizionali_compilati() const
{ return _buffer[90] > ' '; }
bool valid() const;
TRecord_DI();
TRecord_DI(char tipo);
TRecord_DI(const TRecord_DI& rec);
TRecord_DI(const TRectype& rec);
virtual ~TRecord_DI();
};
void TRecord_DI::print_on(ostream& outs) const
{
outs.write((const char*) _buffer, TOTAL_SIZE);
}
void TRecord_DI::read_from(istream& ins)
{
_buffer.fill(' ', TOTAL_SIZE);
ins.read(_buffer.get_buffer(), TOTAL_SIZE);
}
void TRecord_DI::set(const TField_DI& 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 TRecord_DI::set(int pos, const char* val)
{
const TField_DI& fld = tracciato().field(pos);
set(fld, val);
}
void TRecord_DI::set(int pos, int val)
{
const TField_DI& fld = tracciato().field(pos);
CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
TString16 str; str.format("%d", val);
set(fld, str);
}
void TRecord_DI::set(int pos, long val)
{
const TField_DI& fld = tracciato().field(pos);
CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
TString16 str; str.format("%ld", val);
set(fld, str);
}
void TRecord_DI::set(int pos, const real& val)
{
const TField_DI& fld = tracciato().field(pos);
CHECKD(fld._type == 'N', "Invalid numeric field ", pos);
const char* str = val.string(fld._len, 0);
set(fld, str);
}
void TRecord_DI::set(int pos, const TDate& val)
{
const TField_DI& 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 TRecord_DI::set(int pos, char val)
{
const TField_DI& 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 TRecord_DI::set(int pos, bool val)
{
const TField_DI& 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* TRecord_DI::get(int pos, TString& str) const
{
const TField_DI& fld = get_field(pos);
str = _buffer.mid(fld._pos-1, fld._len);
return str.trim();
}
int TRecord_DI::get_int(int pos) const
{
TString16 str; get(pos, str);
return atoi(str);
}
char TRecord_DI::get_char(int pos) const
{
const TField_DI& 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 TRecord_DI::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 > FIELD_SIZE)
blocks += (len-FIELD_SIZE-1) / (FIELD_SIZE-1) + 1;
return blocks;
}
// Azzera tutti i campi non posizionali dei record di tipo C
void TRecord_DI::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 C
bool TRecord_DI::add(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;
if (i != 0)
{
_buffer.overwrite("+", pos);
pos++;
}
const int maxlen = FIELD_SIZE-1 + (i == 0);
const TString& substr = str.mid(i, maxlen);
_buffer.overwrite(substr, pos);
pos += maxlen;
i += maxlen;
}
}
return ok;
}
bool TRecord_DI::valid() const
{
char tipo = tipo_record();
bool ok = (tipo > ' ') && (strchr("ABCZ", tipo) != NULL);
return ok;
}
TRecord_DI::TRecord_DI() : _buffer(TOTAL_SIZE, ' ')
{
}
TRecord_DI::TRecord_DI(char tipo) : _buffer(TOTAL_SIZE, ' ')
{
tipo_record(tipo);
}
TRecord_DI::TRecord_DI(const TRecord_DI& rec) : _buffer(rec._buffer)
{ }
TRecord_DI::~TRecord_DI()
{ }
///////////////////////////////////////////////////////////////
// CLASSE PER IL TRASFERIMENTO EFFETTIVO SUL FILE
///////////////////////////////////////////////////////////////
class TTrasferimento_DI : public TObject
{
TFilename _name;
FILE* _io_stream;
public:
bool open(const char* path = "", char mode = 'r');
bool close();
bool write(const TRecord_DI& rec);
bool read(TRecord_DI& rec);
bool eof() const { return feof(_io_stream) != 0; }
TTrasferimento_DI& operator<<(const TRecord_DI& rec)
{ write(rec); return *this; }
TTrasferimento_DI& operator>>(TRecord_DI& rec)
{ read(rec); return *this; }
bool split(const char* dest_path);
void remove();
TTrasferimento_DI(const char* name = "", char mode = 'r');
virtual ~TTrasferimento_DI();
};
bool TTrasferimento_DI::open(const char* path, char mode)
{
CHECK(mode == 'r' || mode == 'w', "Invalid open mode");
close();
_name = path;
_io_stream = fopen(_name, mode == 'r' ? "rb" : "wb");
return true;
}
bool TTrasferimento_DI::close()
{
if (_io_stream != NULL)
{
fclose(_io_stream);
_io_stream = NULL;
}
return true;
}
bool TTrasferimento_DI::write(const TRecord_DI& rec)
{
bool ok = _io_stream != NULL;
if (ok)
fwrite(rec.readable_buffer(), 1, TOTAL_SIZE, _io_stream);
return ok;
}
bool TTrasferimento_DI::read(TRecord_DI& rec)
{
bool ok = _io_stream != NULL && !feof(_io_stream);
if (ok)
{
fread(rec.writeable_buffer(), 1, TOTAL_SIZE, _io_stream);
ok = rec.valid();
}
return ok;
}
bool TTrasferimento_DI::split(const char* path)
{
close();
const long records = fsize(_name) / TOTAL_SIZE;
long totale[26]; memset(totale, 0, sizeof(totale));
totale['A' - 'A'] = 1;
totale['B' - 'A'] = 1;
totale['C' - 'A'] = records;
totale['Z' - 'A'] = 1;
TRecord_DI rec;
long records_per_disk = 0;
int volumes = 1;
const bool magnetic = ::xvt_fsys_is_removable_drive(path) !=0;
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 = ::xvt_fsys_get_disk_size(path, 'b');
records_per_disk = long(disk_size / TOTAL_SIZE) - 3; // Tolgo A,B,Z
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;
}
}
TTrasferimento_DI outfile(path, 'w');
long written = 0;
if (records > 0)
{
while (read(rec))
{
pi.addstatus(1);
const char tipo_rec = rec.tipo_record();
if (tipo_rec <= 'B' || tipo_rec == 'Z')
continue;
outfile << rec;
totale[tipo_rec - 'A']++;
written++;
if (magnetic && written >= records_per_disk)
break;
}
}
}
return true;
}
// Cancella il file
void TTrasferimento_DI::remove()
{
close();
::remove(_name);
}
TTrasferimento_DI::TTrasferimento_DI(const char* path, char mode)
//: _in_stream(NULL), _out_stream(NULL)
:_io_stream(NULL)
{
open(path, mode);
}
TTrasferimento_DI::~TTrasferimento_DI()
{
close();
}
//---------------------------------------------------------------
// APPLICAZIONE
//---------------------------------------------------------------
class TSend_letint : public TSkeleton_application
{
TRectype* _rec_anagrafica;
protected:
bool create();
public:
void read_dati_dic();
const TString& get_anagr_field(const TString field_name) { return _rec_anagrafica->get(field_name); }
void fill_a_rec(const TMask& mask, TRecord_DI& rec);
void fill_b_rec(const TMask& mask, const int items, TRecord_DI& rec);
void fill_c_rec(const int modulo, TRecord_DI& rec);
void fill_z_rec(const int items, TRecord_DI& rec);
void fill_non_positional(const int modulo, const int rigo, const TRectype& let_int, TRecord_DI& rec,
TTrasferimento_DI& t, int &written_c_records);
virtual void main_loop();
};
void TSend_letint::read_dati_dic()
{
TString80 key; // Stringa multiuso
key << main_app().get_firm();
const TRectype& rec_nditte = cache().get(LF_NDITTE, key);
const char tipoa = rec_nditte.get_char(NDT_TIPOA); //tipo persona fisica/giuridica
const long codan = rec_nditte.get_long(NDT_CODANAGR);
key.cut(0);
key << tipoa << '|' << rec_nditte.get(NDT_CODANAGR);
const TRectype& rec_anagr = cache().get(LF_ANAG, key);
if (rec_anagr.empty())
{
error_box("Non esiste la persona %s", (const char*)key);
}
if (_rec_anagrafica != NULL)
delete _rec_anagrafica;
_rec_anagrafica = new TRectype(rec_anagr);
}
void TSend_letint::fill_a_rec(const TMask& mask, TRecord_DI& rec)
{
TString80 key;
key << main_app().get_firm();
const TRectype& rec_nditte = cache().get(LF_NDITTE, key); //legge la ditta..
const char dichp = rec_nditte.get_char(NDT_DICHP); //se ha un intermediario..
if (dichp == 'I')
rec.set(4, 10);
else
rec.set(4, 01);
rec.set(5, get_anagr_field(ANA_COFI)); //codice fiscale del dichiarante
rec.set(7, mask.get_int(F_PROGINV)); //progressivo invio nella fornitura
rec.set(8, mask.get_int(F_TOTINV)+1); //totale inviii incrementato dell'attuale
}
void TSend_letint::fill_b_rec(const TMask& mask, const int items, TRecord_DI& rec)
{
const bool persona_fisica = get_anagr_field(ANA_TIPOA) == "F";
rec.set(2, get_anagr_field(ANA_COFI)); //codice fiscale del dichiarante
if (persona_fisica) //se persona fisica..
{
rec.set(25, get_anagr_field(ANA_RAGSOC).left(24)); //cognome dichiarante
rec.set(26, get_anagr_field(ANA_RAGSOC).mid(30,20)); //nome
}
else //..altrimenti..
rec.set(27, get_anagr_field(ANA_RAGSOC)); //ragsoc dichiarante
rec.set(28, get_anagr_field(ANA_PAIV)); //p.iva dichiarante
// periodo inviato
rec.set(36, mask.get_int(F_ANNO));
rec.set(37, mask.get(F_MESE));
TToken_string chiave_comuni;
if (persona_fisica) //se persona fisica..
{
const TRectype& rec_fis = cache().get(LF_ANAGFIS, get_anagr_field(ANA_CODANAGR)); //record della persona fisica
// dati nascita
chiave_comuni.add(rec_fis.get(ANF_STATONASC));
chiave_comuni.add(rec_fis.get(ANF_COMNASC));
const TRectype& rec_nasc = cache().get(LF_COMUNI, chiave_comuni);
rec.set(38, rec_nasc.get(COM_DENCOM));
rec.set(39, rec_nasc.get(COM_PROVCOM));
rec.set(40, rec_fis.get_date(ANF_DATANASC).string(def, '\0'));
rec.set(41, rec_fis.get(ANF_SESSO));
// dati residenza anagrafica
chiave_comuni.cut(0);
chiave_comuni.add(get_anagr_field(ANA_STATORES));
chiave_comuni.add(get_anagr_field(ANA_COMRES));
const TRectype& rec_res = cache().get(LF_COMUNI, chiave_comuni);
rec.set(45, rec_res.get(COM_DENCOM));
rec.set(46, rec_res.get(COM_PROVCOM));
TString address = get_anagr_field(ANA_INDRES);
address << ", " << get_anagr_field(ANA_CIVRES);
rec.set(47, address);
rec.set(48, get_anagr_field(ANA_CAPRES));
}
else //se persona giuridica..
{
// dati residenza
chiave_comuni.add(get_anagr_field(ANA_STATORES));
chiave_comuni.add(get_anagr_field(ANA_COMRES));
const TRectype& rec_res = cache().get(LF_COMUNI, chiave_comuni);
rec.set(69, rec_res.get(COM_DENCOM));
rec.set(70, rec_res.get(COM_PROVCOM));
TString address = get_anagr_field(ANA_INDRES);
address << ", " << get_anagr_field(ANA_CIVRES);
rec.set(71, address);
rec.set(72, get_anagr_field(ANA_CAPRES));
//dati residenza fiscale
chiave_comuni.cut(0);
chiave_comuni.add(" ");
chiave_comuni.add(get_anagr_field(ANA_COMRF));
const TRectype& rec_rfi = cache().get(LF_COMUNI, chiave_comuni);
rec.set(74, rec_rfi.get(COM_DENCOM));
rec.set(75, rec_rfi.get(COM_PROVCOM));
address = get_anagr_field(ANA_INDRF);
address << ", " << get_anagr_field(ANA_CIVRF);
rec.set(76, address);
rec.set(77, get_anagr_field(ANA_CAPRF));
// natura giuridica
const TRectype& rec_giu = cache().get(LF_ANAGGIU, get_anagr_field(ANA_CODANAGR)); //record della persona giuridica
rec.set(83, rec_giu.get_int(ANG_NATGIU));
}
//parte con dati del rappresentante
TString80 key;
key << main_app().get_firm();
const TRectype& rec_nditte = cache().get(LF_NDITTE, key); //legge la ditta..
const char dichp = rec_nditte.get_char(NDT_DICHP); //se ha un intermediario..
if (dichp == 'I')
{
const long firmat = rec_nditte.get_long(NDT_FIRMAT); //..ne prende il codice..
//..e ricava la sua partita iva o codice fiscale
//..e tutti i suoi dati in anagrafica
TToken_string chiave_anagr;
chiave_anagr.add("F");
chiave_anagr.add(firmat);
const TRectype& rec_anagr = cache().get(LF_ANAG, chiave_anagr); //record di anagr
if (!rec_anagr.empty()) //se l'intermediario esiste come persona fisica...
{
rec.set(98, rec_anagr.get(ANA_COFI));
//impegno alla presentazione telematica
rec.set(198, rec_anagr.get(ANA_COFI)); //questo va nella sezione di impegno alla presentazione telematica
TString8 intcaf = rec_nditte.get(NDT_INTCAF).left(5);
rec.set(199, intcaf); //..e questo pure(e' qui x comodita')
rec.set(201, 1);
const int carica_rapp = rec_nditte.get_int(NDT_CARRAPP);
if (carica_rapp != 0) //solo se il rappresentante ha una carica...
{
const long rappr = rec_nditte.get_long(NDT_RAPPR); //..prende codice rappresentante
chiave_anagr.add(rappr, 1);
const TRectype& rec_anag_rappr = cache().get(LF_ANAG, chiave_anagr); //..e ricava tutti i suoi dati
rec.set(99, rec_anag_rappr.get(ANA_COFI));
rec.set(101, carica_rapp);
const TString& ragsoc_rappr = rec_anag_rappr.get(ANA_RAGSOC);
rec.set(104, ragsoc_rappr.left(24));
rec.set(105, ragsoc_rappr.mid(30));
const TRectype& rec_anag_rappr_fis = cache().get(LF_ANAGFIS, rappr); //..anche quelli personali
rec.set(106, rec_anag_rappr_fis.get(ANF_SESSO));
rec.set(107, rec_anag_rappr_fis.get_date(ANF_DATANASC).string(def, '\0'));
chiave_comuni.cut(0);
chiave_comuni.add(" ");
chiave_comuni.add(rec_anag_rappr_fis.get(ANF_COMNASC)); //comune,provincia di nascita
const TRectype& com_nasc_rappr = cache().get(LF_COMUNI, chiave_comuni);
rec.set(108, com_nasc_rappr.get(COM_DENCOM));
rec.set(109, com_nasc_rappr.get(COM_PROVCOM));
chiave_comuni.add(rec_anag_rappr.get(ANA_COMRES), 1); //comune,provincia di residenza
const TRectype& com_res_rappr = cache().get(LF_COMUNI, chiave_comuni);
rec.set(110, com_res_rappr.get(COM_DENCOM));
rec.set(111, com_res_rappr.get(COM_PROVCOM));
rec.set(112, com_res_rappr.get(COM_CAPCOM));
if (!com_res_rappr.get(COM_PROVCOM).empty())
{
TString address_rapp = rec_anag_rappr.get(ANA_INDRES); //indirizzo,civico di residenza
address_rapp << ", " << rec_anag_rappr.get(ANA_CIVRES);
rec.set(113, address_rapp);
}
rec.set(114, rec_anag_rappr.get(ANA_TELRF));
} //endif carica_rappr!=0
} //endif !rec_anagr.empty()
} //endif dichp==I
if (dichp == 'C')
rec.set(200, 1);
//comunicazione dichiarazioni d'intento
rec.set(197, items);
rec.set(202, rec_nditte.get_date(NDT_DECCARINT).string(def, '\0'));
}
void TSend_letint::fill_c_rec(const int modulo, TRecord_DI& rec)
{
rec.set(2, get_anagr_field(ANA_COFI)); //codice fiscale del dichiarante
rec.set(3, modulo); //modulo del corrente record C
rec.azzera_campi_non_posizionali();
}
void TSend_letint::fill_z_rec(const int written_c_records, TRecord_DI& rec)
{
rec.set(4, written_c_records);
}
void TSend_letint::fill_non_positional(const int modulo, const int rigo, const TRectype& let_int, TRecord_DI& c_rec,
TTrasferimento_DI& t, int &written_c_records)
{
//cache del file CLIFO per riempire alcuni val; prende il cliente dal record corrente di LETINT
const long cod = let_int.get_long(LETINT_CODCLI);
TString16 key; key.format("C|%ld", cod);
const TRectype& rec_cli = cache().get(LF_CLIFO, key); //record del cliente
TToken_string chiave_comuni;
chiave_comuni.add(rec_cli.get(CLI_STATOCF));
chiave_comuni.add(rec_cli.get(CLI_COMCF));
const TRectype& rec_com = cache().get(LF_COMUNI, chiave_comuni);
for (int i = 1; i <= 17; i++)
{
//costruzione dei valori da assegnare ai campi non posizionali (auguri..)
TString80 val; //stringa generica di lavoro
switch (i)
{
case 1:
val = let_int.get(LETINT_NUMPROT);
break;
case 2:
val = let_int.get(LETINT_VSPROT);
break;
case 3:
val = rec_cli.get(CLI_COFI);
break;
case 4:
val = rec_cli.get(CLI_PAIV);
break;
case 5:
val = rec_cli.get(CLI_RAGSOC).left(30);
val.trim();
break;
case 6:
val = rec_cli.get(CLI_RAGSOC).mid(30);
break;
case 7:
{
val = rec_cli.get(CLI_INDCF);
const TString& civico = rec_cli.get(CLI_CIVCF);
if (civico.not_empty())
val << ", " << civico;
}
break;
case 8:
val = rec_com.get(COM_DENCOM);
break;
case 9:
val = rec_com.get(COM_PROVCOM);
break;
case 10:
val = rec_cli.get(CLI_STATOCF);
break;
case 11:
if (let_int.get_int(LETINT_TIPOOP) == 1)
val.format("%16d", 1);
break;
case 12:
if (let_int.get_int(LETINT_TIPOOP) == 1)
val = let_int.get_real(LETINT_IMPORTO).stringa(16,2);
break;
case 13:
if (let_int.get_int(LETINT_TIPOOP) == 2)
val.format("%16d", 1);
break;
case 14:
if (let_int.get_int(LETINT_TIPOOP) == 2)
val = let_int.get_real(LETINT_IMPORTO).stringa(16,2);
break;
case 15:
if (let_int.get_int(LETINT_TIPOOP) == 3)
val.format("%16d", 1);
break;
case 16:
if (let_int.get_int(LETINT_TIPOOP) == 3)
{
const TDate dataini = let_int.get_date(LETINT_DAL);
val.format("%8s%02d%02d%04d", "", dataini.day(), dataini.month(), dataini.year());
}
break;
case 17:
if (let_int.get_int(LETINT_TIPOOP) == 3)
{
const TDate datafin = let_int.get_date(LETINT_AL);
val.format("%8s%02d%02d%04d", "", datafin.day(), datafin.month(), datafin.year());
}
break;
default: break;
}
if (!val.blank())
{
TString8 code;
code.format("DI%03d%03d", rigo, i); //codice del campo non posizionale
bool ok = c_rec.add(code, val);
if (!ok)
{
t.write(c_rec); //scrive quello che ci sta..
written_c_records++;
fill_c_rec(modulo, c_rec); //riempie un nuovo C record..
c_rec.add(code, val);
}
}
}
}
bool TSend_letint::create()
{
return TSkeleton_application::create();
}
void TSend_letint::main_loop()
{
_rec_anagrafica = NULL;
TFilename path;
TSend_letint_mask m;
while (m.run() == K_ENTER)
{
TFilename output_filename = m.get(F_PATH);
output_filename.add(m.get(F_FILE));
TTrasferimento_DI t(output_filename, 'w');
TRectype darec(LF_LETINT), arec(LF_LETINT);
const int anno = m.get_int(F_ANNO);
const int mese = m.get_int(F_MESE);
darec.put(LETINT_ANNO, anno);
arec.put(LETINT_ANNO, anno);
TRelation rel_letint(LF_LETINT);
_da_data = TDate(1, mese, anno);
_a_data = _da_data,
_a_data.set_end_month();
TString filtro;
filtro = "(STAMPATO==\"X\")&&(INVIATO!=\"X\")"; //si possono inviare solo dichiarazioni stampate in definitivo
TCursor cur_letint(&rel_letint, filtro, 1, &darec, &arec);
cur_letint.set_filterfunction(filtra_per_date);
const long items = cur_letint.items();
if (items > 0)
{
read_dati_dic(); //legge i dati del dichiarante;
cur_letint.freeze();
TProgind pi(items, "Generazione file di trasferimento", false);
TRectype& rec_letint = rel_letint.curr();
bool go_on = true; //bool per controllare il corretto avanzamento della creazione record
//istanziamento record di tipo A e B (testate) e loro scrittura
TRecord_DI a_rec('A');
fill_a_rec(m, a_rec);
if (!t.write(a_rec))
go_on = false;
TRecord_DI b_rec('B');
fill_b_rec(m, items, b_rec);
if (!t.write(b_rec))
go_on = false;
//record di tipo C (righe)
int written_c_records = 0;
int modulo = 1;
int rigo = 1;
//parte posizionale del primo record di tipo C
TRecord_DI c_rec('C');
fill_c_rec(modulo, c_rec);
for (cur_letint = 0; cur_letint.pos() < items; ++cur_letint)
{
pi.addstatus(1);
//parte non posizionale;va compilata sul record C
fill_non_positional(modulo, rigo, rec_letint, c_rec, t, written_c_records);
rigo++; //avanza di un rigo
if (rigo > 4) //ogni 4 righi di tipo C..
{
t.write(c_rec); //..si scrive sul file..
written_c_records++;
rigo = 1;
modulo++;
fill_c_rec(modulo, c_rec); //..ci vuole una nuova parte posizionale..
}
//registra i record inviati
rec_letint.put(LETINT_INVIATO, 'X'); //riempie il campo
rel_letint.rewrite(); //aggiorna fisicamente il file
}
//caso base in cui il numero di righi non è multiplo di 4
if (c_rec.ha_campi_non_posizionali_compilati())
{
t.write(c_rec); //..si scrive sul file..
written_c_records++;
}
TRecord_DI z_rec('Z');
fill_z_rec(written_c_records, z_rec);
if (!t.write(z_rec))
go_on = false;
//incrementa di 1 il numero totale degli invii sulla tabella registri
if (go_on)
{
TTable tabreg("REG");
TString8 key;
key << anno << m.get(F_REGISTRO);
tabreg.put("CODTAB", key);
if (tabreg.read() == NOERR)
{
tabreg.put("I4", m.get_int(F_TOTINV)+1);
tabreg.rewrite();
}
}
}
}
if (_rec_anagrafica != NULL)
delete _rec_anagrafica;
}
int li0600(int argc, char* argv[])
{
TSend_letint a;
a.run(argc, argv, TR("Invio dichiarazioni d'intento"));
return 0;
}