#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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; }