#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fe0100a.h" #include "../cg/cglib01.h" const char* const INVALID_NUMDOC = "???????"; const long MANUAL_ROW = 900000L; /////////////////////////////////////////////////////////// // Utility /////////////////////////////////////////////////////////// static const TString& comune_di(const TString& codcom) { if (codcom.blank() || codcom.len() != 4) return EMPTY_STRING; TString8 key; key << " |" << codcom; TString& den = get_tmp_string(); den = cache().get(LF_COMUNI, key, COM_DENCOM); den.cut(40); den.upper(); return den; } static const TString& provincia_di(const TString& codcom) { if (codcom.blank() || codcom.len() != 4) return EMPTY_STRING; TString8 key; key << '|' << codcom; return cache().get(LF_COMUNI, key, COM_PROVCOM); } static real importo_limite(int anno) { return anno > 2010 ? 3000: 25000; } static bool is_nota_variazione(const TRectype& mov) { const int logicnum = mov.num(); if (logicnum == LF_MOV) { const real totdoc = mov.get_real(MOV_TOTDOC); if (totdoc < ZERO) return true; const int tipomov = mov.get_int(MOV_TIPOMOV); if (tipomov == 2) // Nota di credito/debito per saldaconto return true; const TString& tipodoc = mov.get(MOV_TIPODOC); if (tipodoc == "NC" || tipodoc == "ND") // Nota di credito/debito senza saldaconto return true; } else if (logicnum == LF_ALLEG) { const TString& numrett = mov.get(ALL_NUMRETT); if (numrett.full()) return true; const real importo = mov.get_real(ALL_IMPORTO); const real imposta = mov.get_real(ALL_IMPOSTA); if (importo < ZERO || imposta < ZERO) return true; } return false; } enum TExclusion_mode { em_incluso, em_importo_limite, em_no_allegato, em_fiscalita_agevolata, em_estero, em_intra, em_art8, em_data_limite, em_passaggi_interni, em_inviato, em_altro }; static const char* mode2string(TExclusion_mode motivo) { const char* msg = ""; switch (motivo) { case em_importo_limite : msg = TR("importo inferiore al limite della comunicazione"); break; case em_no_allegato : msg = TR("Soggetto da non inserire in allegato"); break; case em_fiscalita_agevolata: msg = TR("Soggetto residente in stato a fiscalità agevolata"); break; case em_estero : msg = TR("Soggetto residente all'estero"); break; case em_intra : msg = TR("Movimento intra"); break; case em_data_limite : msg = TR("Data fuori dal limite della comunicazione"); break; case em_art8 : msg = TR("Soggetto all'articolo 8 (del dpr 26-10-1972)"); break; case em_passaggi_interni : msg = TR("Passaggi interni"); break; case em_inviato : msg = TR("Inviato l'anno precedente"); break; default : msg = TR("Altri motivi"); break; } return msg; } /////////////////////////////////////////////////////////// // TContratto /////////////////////////////////////////////////////////// class TContratto : public TObject { TRectype _rec; protected: bool importo_annuale(int anno, real& importo, real& imposta) const; bool importo_figli(int anno, real& importo, real& imposta) const; public: virtual bool ok() const { return !_rec.empty(); } const TString& codice() const { return _rec.get("CODTAB").mid(7); } bool totale_annuale(int anno, real& importo, real& imposta) const; int modalita_pagamento() const; bool init(char tipocf, long codcf, const TString& codcont); bool init(const TRectype& rec); TContratto(char tipocf, long codcf, const char* codcont) : _rec(LF_TABMOD) { init(tipocf, codcf, codcont); } TContratto(const TRectype& rec) : _rec(LF_TABMOD) { init(rec); } }; bool TContratto::importo_annuale(int anno, real& importo, real& imposta) const { if (_rec.empty() || anno < 2010) return false; // Determina l'indice i [0..3] degli importi del contratto per l'anno richiesto char fld[] = "I3"; int i = 3; for (i = 3; i > 0; i--) { fld[1] = '0'+i; const int y = _rec.get_int(fld); if (y > 0 && y <= anno) break; } // Determina il nome del campo importo corrispondente all'indice i: 0 -> R0; 1 -> R2; 2 -> R4; 3 -> R6 fld[0] = 'R'; fld[1] = '0'+(i*2); importo = _rec.get_real(fld); fld[1]++; // Il campo imposta è sempre quello successivo a quello dell'importo imposta = _rec.get_real(fld); return importo > ZERO; } bool TContratto::importo_figli(int anno, real& importo, real& imposta) const { const TString& codtab = _rec.get("CODTAB"); const TString& prefix = codtab.left(7); const TString& suffix = codtab.mid(7); TString query; query << "USE &CON SELECT S1=\"" << suffix << '\"' << "\nFROM CODTAB=\"" << prefix << '\"' << "\nTO CODTAB=\"" << prefix << '\"'; TISAM_recordset recset(query); importo = imposta = ZERO; for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { const TContratto child(recset.cursor()->curr()); real imp, iva; child.importo_figli(anno, imp, iva); importo += imp; imposta += iva; } if (importo <= ZERO) importo_annuale(anno, importo, imposta); return !importo.is_zero(); } bool TContratto::totale_annuale(int anno, real& importo, real& imposta) const { importo = imposta = ZERO; if (!_rec.empty() && anno >= 2010) { const TString& padre = _rec.get("S1"); if (padre.full()) { const TString& codtab = _rec.get("CODTAB"); const TContratto master(codtab[0], atol(codtab.mid(1,6)), padre); master.totale_annuale(anno, importo, imposta); } else importo_figli(anno, importo, imposta); } return importo > ZERO; } int TContratto::modalita_pagamento() const { int modpag = _rec.get_int("S6"); if (modpag != 2 && modpag != 3) modpag = 2; return modpag; } bool TContratto::init(char tipocf, long codcf, const TString& codcont) { if (tipocf >= 'C' && codcf > 0 && codcont.full()) { TString80 key; key.format("%c%6ld%s", tipocf, codcf, (const char*)codcont); init(cache().get("&CON", key)); } else _rec.zero(); return ok(); } bool TContratto::init(const TRectype& rec) { switch (rec.num()) { case LF_TABMOD: _rec = rec; if (!_rec.empty()) { int primo_anno = _rec.get_int("I0"); if (primo_anno < 2010) { const TDate inizio = _rec.get("D0"); primo_anno = inizio.year(); if (primo_anno < 2010) primo_anno = 2010; _rec.put("I0", primo_anno); } real importo = _rec.get("R0"); if (importo <= ZERO) { importo = primo_anno > 2010 ? 3000 : 25000; _rec.put("R0", importo); } } break; case LF_ALLEG: { const char tipocf = rec.get_char(ALL_TIPOCF); const long codcf = rec.get_long(ALL_CODCF); const TString& contr = rec.get(ALL_CONTRATTO); init(tipocf, codcf, contr); } break; case LF_MOV: { const char tipocf = rec.get_char(MOV_TIPO); const long codcf = rec.get_long(MOV_CODCF); const TString& contr = rec.get(MOV_CONTRATTO); init(tipocf, codcf, contr); } break; default: CHECKD(false, "Record non valido per contratto FE", rec.num()); break; } return ok(); } /////////////////////////////////////////////////////////// // TAnagrafica /////////////////////////////////////////////////////////// class TAnagrafica : public TObject { char _tipo; // F o G TString16 _cofi, _paiv; TString80 _ragsoc; TString4 _com_nasc, _com_res; TString80 _loc_res, _ind_res; TDate _data_nasc; int _allegato, _stato_estero; TAnagrafica& operator =(const TAnagrafica&) { CHECK(false, "Can't copy TAnagrafica"); } TAnagrafica(const TAnagrafica&) { CHECK(false, "Can't copy TAnagrafica"); } protected: void build_ind_res(const TRectype& rec, const char* ind, const char* civ); public: virtual bool ok() const { return _tipo=='F' || _tipo == 'G'; } bool fisica() const { return _tipo == 'F'; } bool giuridica() const { return _tipo == 'G'; } const TString& codice_fiscale() const { return _cofi; } const TString& partita_IVA() const { return _paiv; } const TString& ragione_sociale() const { return _ragsoc; } const TString& cognome() const { return _ragsoc.left(24); } const TString& nome() const { CHECK(fisica(), "Non chiedere nome giuridico!"); return _ragsoc.mid(30,20); } char sesso() const { CHECK(fisica(), "Solo sesso fisico!"); return (_cofi[9] >= '4') ? 'F' : 'M'; } const TDate& data_nascita() const { return _data_nasc; } int stato_estero() const { return _stato_estero; } int inserimento_in_allegato() const { return _allegato; } const TString& comune_nascita() const { return comune_di(_com_nasc); } const TString& provincia_nascita() const { return provincia_di(_com_nasc); } const TString& comune_residenza() const { return comune_di(_com_res); } const TString& provincia_residenza() const { return provincia_di(_com_res); } const TString& localita_residenza() const { return _loc_res; } const TString& indirizzo_residenza() const { return _ind_res; } bool init(const TRectype& rec); bool init(int num, const TString& codice) { return init(cache().get(num, codice)); } bool init(int num, long codice) { return init(cache().get(num, codice)); } bool init(int num, char tipo, long codice); bool init(char tipo, long codice, const TString& ocfpi); TAnagrafica() : _tipo('\0') {} TAnagrafica(int lognum, const TString& codice) { init(lognum, codice); } TAnagrafica(int lognum, long codice) { init(lognum, codice); } TAnagrafica(int lognum, char tipo, long codice) { init(lognum, tipo, codice); } TAnagrafica(char tipo, long codice, const TString& ocfpi) { init(tipo, codice, ocfpi); } TAnagrafica(const TRectype& rec) { init(rec); } }; void TAnagrafica::build_ind_res(const TRectype& rec, const char* ind, const char* civ) { TString80 indirizzo = rec.get(ind); if (indirizzo.full()) { const TString& numero = rec.get(civ); if (numero.full()) indirizzo << ", " << numero; indirizzo.strip_double_spaces(); TParagraph_string s(indirizzo, 40); _ind_res = s.get(0); } } bool TAnagrafica::init(const TRectype& rec) { _tipo = '\0'; _stato_estero = 0; _allegato = 0; if (rec.empty()) return false; switch (rec.num()) { case LF_OCCAS: _tipo = 'F'; _cofi = rec.get(OCC_COFI); _paiv = rec.get(OCC_PAIV); if (_cofi.blank() || _paiv.blank()) { const TString& codice = rec.get(OCC_CFPI); if (_cofi.blank() && cf_check("", codice)) _cofi = codice; if (_paiv.blank() && pi_check("", codice)) _paiv = codice; } _ragsoc = rec.get(OCC_RAGSOC); _ragsoc.upper(); _data_nasc = rec.get(OCC_DNASC); _com_nasc = rec.get(OCC_COMNASC); _com_res = rec.get(OCC_COM); _loc_res = rec.get(OCC_LOCALITA); build_ind_res(rec, OCC_INDIR, OCC_CIV); _stato_estero = rec.get_int(OCC_STATO); _allegato = _paiv.blank() ? 6 : 2; break; case LF_ANAG: _tipo = rec.get_char(ANA_TIPOA); _ragsoc = rec.get(ANA_RAGSOC); _ragsoc.upper(); _cofi = rec.get(ANA_COFI); _paiv = rec.get(ANA_PAIV); // Comune di residenza fiscale o domicilio _com_res = rec.get(ANA_COMRF); if (_com_res.empty()) _com_res = rec.get(ANA_COMRES); build_ind_res(rec, ANA_INDRES, ANA_CIVRES); // Dati di nascita persone fisiche if (_tipo == 'F') { const TRectype& anafis = cache().get(LF_ANAGFIS, rec.get_long(ANA_CODANAGR)); _data_nasc = anafis.get(ANF_DATANASC); _com_nasc = anafis.get(ANF_COMNASC); } else _tipo = 'G'; break; case LF_NDITTE: { const bool good = init(LF_ANAG, rec.get_char(NDT_TIPOA), rec.get_long(NDT_CODANAGR)); _ragsoc = rec.get(NDT_RAGSOC); _ragsoc.upper(); return good; } break; case LF_CLIFO: _tipo = rec.get_char(CLI_TIPOAPER); if (_tipo == 'F') { init(LF_ANAG, _tipo, rec.get_long(CLI_CODANAGPER)); if (rec.get(CLI_COMNASC).not_empty()) _com_nasc = rec.get(CLI_COMNASC); if (rec.get(CLI_DATANASC).not_empty()) _data_nasc = rec.get(CLI_DATANASC); } else _tipo = 'G'; // Assegno codice fiscale e partita IVA se validi, altrimenti mantengo quelli dell'anagrafica if (rec.get(CLI_COFI).not_empty()) _cofi = rec.get(CLI_COFI); if (rec.get(CLI_PAIV).not_empty()) _paiv = rec.get(CLI_PAIV); build_ind_res(rec, CLI_INDCF, CLI_CIVCF); // Prevale sempre la ragione sociale del cliente: "Il cliente ha sempre ragione". _ragsoc = rec.get(CLI_RAGSOC); _ragsoc.upper(); _stato_estero = rec.get_int(CLI_STATOCF); _allegato = rec.get_int(CLI_ALLEG); _loc_res = rec.get(CLI_LOCCF); break; case LF_MOV: return init(rec.get_char(MOV_TIPO), rec.get_long(MOV_CODCF), rec.get(MOV_OCFPI)); case LF_ALLEG: return init(rec.get_char(ALL_TIPOCF), rec.get_long(ALL_CODCF), rec.get(ALL_OCFPI)); default: CHECKD(false, "Record non valido per TAnagrafica ", rec.num()); break; } if (_tipo == 'G') _ragsoc.strip_double_spaces(); return _tipo == 'F' || _tipo == 'G'; } bool TAnagrafica::init(int num, char tipo, long codice) { TString16 key; key << tipo << '|' << codice; return init(cache().get(num, key)); } bool TAnagrafica::init(char tipo, long codice, const TString& ocfpi) { bool done = false; if (ocfpi.full()) done = init(LF_OCCAS, ocfpi); if (!done) done = init(LF_CLIFO, tipo, codice); return done; } /////////////////////////////////////////////////////////// // TDati_rilevanti_trc /////////////////////////////////////////////////////////// #define AN _alfafld #define CF _alfafld #define DT _datefld #define NU _longzerofld #define PI _alfafld #define OBBLIG true class TDati_rilevanti_trc : public TObject { int _tipo; TAS400_recordset* _recset; protected: bool add_field(int n, int da, int a, int len, const char* descr, TFieldtypes tipo = AN, const char* def = NULL, bool required = false); public: void create_fields(int tipo, TAS400_recordset& recset); }; bool TDati_rilevanti_trc::add_field(int n, int da, int a, int len, const char* descr, TFieldtypes tipo, const char* def, bool required) { CHECKD(descr && *descr, "Campo ignoto ", n); CHECKS(n > 0 && da > 0 && a >= da && a <= 1800 && len == (a-da+1), "Campo inconsistente ", descr); TString8 name; name.format("%d.%d", _tipo, n); bool ok = _recset->create_field(name, da-1, len, tipo, required, def); CHECKS(ok, "Can't create field ", descr); return ok; } void TDati_rilevanti_trc::create_fields(int tipo, TAS400_recordset& recset) { CHECKD(tipo >= 0 && tipo <= 5 || tipo == 9, "Tipo record non valido ", tipo); _tipo = tipo; _recset = &recset; TString4 def; def << _tipo; add_field(1, 1, 1, 1, "Tipo record", NU, def, OBBLIG); if (_tipo == 0 || _tipo == 9) { add_field( 2, 2, 6, 5, "Codice identificativo fornitura", AN, "ART21", OBBLIG); add_field( 3, 7, 8, 2, "Codice numerico fornitura", NU, "47", OBBLIG); add_field( 4, 9, 9, 1, "Tipologia di invio", NU, "0", OBBLIG); add_field( 5, 10, 26,17, "Protocollo da sostituire", AN); // ex NU add_field( 6, 27, 32, 6, "Protocollo documento", AN); // ex NU add_field( 7, 33, 48,16, "Codice fiscale", CF, "", OBBLIG); add_field( 8, 49, 59,11, "Partita IVA", PI); add_field( 9, 60,119,60, "Denominazione", AN); add_field(10,120,159,40, "Comune domicilio fiscale", AN); add_field(11,160,161, 2, "Provincia domicilio fiscale", AN); add_field(12,162,185,24, "Cognome", AN); add_field(13,186,205,20, "Nome", AN); add_field(14,206,206, 1, "Sesso", AN); add_field(15,207,214, 8, "Data di nascita", DT); add_field(16,215,254,40, "Comune o stato di nascita", AN); add_field(17,255,256, 2, "Provincia di nascita", AN); add_field(18,257,260, 4, "Anno di riferimento", NU); add_field(19,261,261, 1, "Comunicazione società incorp.", AN, "0", OBBLIG); add_field(20,262,265, 4, "Progressivo invio telmatico", NU, "1"); add_field(21,266,269, 4, "Numero totale invii telematici", NU, "1"); add_field(22,270,285,16, "Codice fiscale intermediario", CF); add_field(23,286,290, 5, "Numero iscrizione C.A.F.", AN); // Ex NU add_field(24,291,291, 1, "Impegno alla trasmissione", AN ); // Ex NU add_field(25,292,299, 8, "Data dell'impegno", DT); add_field(26,300,1797,1498, "Filler", AN); add_field(27,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG); add_field(28,1799,1800,2,"Caratteri di fine riga", AN, "\r\n"); } else if (_tipo == 1) { add_field(2, 2,17,16, "Codice fiscale", CF, "", OBBLIG); add_field(3,18,25, 8, "Data dell'operazione", DT); add_field(4,26,26, 1, "Modalità di pagamento", NU, "3", OBBLIG); add_field(5,27,35, 9, "Importo dovuto", NU); add_field(6,36,1797,1762, "Filler", AN); add_field(7,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG); add_field(8,1799,1800,2,"Caratteri di fine riga", AN, "\r\n"); } else if (_tipo == 2) { add_field( 2, 2,12,11, "Partita IVA", PI, "", OBBLIG); add_field( 3,13,20, 8, "Data dell'operazione", DT); add_field( 4,21,35,15, "Numero della fattura", AN); add_field( 5,36,36, 1, "Modalità di pagamento", NU, "1", OBBLIG); add_field( 6,37,45, 9, "Importo dovuto", NU); add_field( 7,46,54, 9, "Imposta", NU); add_field( 8,55,55, 1, "Tipologia dell'operazione", NU, "1", OBBLIG); add_field( 9,56,1797,1742, "Filler", AN); add_field(10,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG); add_field(11,1799,1800,2,"Caratteri di fine riga", AN, "\r\n"); } else if (_tipo == 3) { add_field( 2, 2, 25,24, "Cognome", AN); add_field( 3, 26, 45,20, "Nome", AN); add_field( 4, 46, 53, 8, "Data di nascita", DT); add_field( 5, 54, 93,40, "Comune o stato estero di nascita", AN); add_field( 6, 94, 95, 2, "Provincia di nascita", AN); add_field( 7, 96, 98, 3, "Stato estero del domicilio", AN); add_field( 8, 99,158,60, "Ragione sociale", AN); add_field( 9,159,198,40, "Città estera della sede legale", AN); add_field(10,199,201, 3, "Stato estero della sede legale", AN); add_field(11,202,241,40, "Indirizzo estero della sede legale", AN); add_field(12,242,249, 8, "Data dell'operazione", DT); add_field(13,250,264,15, "Numero della fattura", AN); add_field(14,265,265, 1, "Modalità di pagamento", NU, "1", OBBLIG); add_field(15,266,274, 9, "Importo dovuto", NU); add_field(16,275,283, 9, "Imposta", NU); add_field(17,284,284, 1, "Tipologia dell'operazione", NU, "1", OBBLIG); add_field(18,285,1797,1513, "Filler", AN); add_field(19,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG); add_field(20,1799,1800,2,"Caratteri di fine riga", AN, "\r\n"); } else if (_tipo == 4) { add_field( 2, 2,12,11, "Partita IVA", PI); add_field( 3,13,28,16, "Codice Fiscale", CF); add_field( 4,29,36, 8, "Data dell'operazione", DT, "", OBBLIG); add_field( 5,37,51,15, "Numero della Nota di Variazione", AN, "", OBBLIG); add_field( 6,52,60, 9, "Imponibile Nota di Variazione", NU); add_field( 7,61,69, 9, "Imposta Nota di Variazione", NU); add_field( 8,70,77, 8, "Data della Fattura da rettificare", DT, "", OBBLIG); add_field( 9,78,92,15, "Numero della Fattura da rettificare", AN, "", OBBLIG); add_field(10,93,93, 1, "Variazione imponib. (Debito/Credito)",AN); add_field(11,94,94, 1, "Variazione imposta (Debito/Credito)", AN); add_field(11,95,1797,1703, "Filler", AN); add_field(12,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG); add_field(13,1799,1800,2,"Caratteri di fine riga", AN, "\r\n"); } else if (_tipo == 5) { add_field( 2, 2, 25,24, "Cognome", AN); add_field( 3, 26, 45,20, "Nome", AN); add_field( 4, 46, 53, 8, "Data di nascita", DT); add_field( 5, 54, 93,40, "Comune o stato estero di nascita", AN); add_field( 6, 94, 95, 2, "Provincia di nascita", AN); add_field( 7, 96, 98, 3, "Stato estero del domicilio", AN); add_field( 8, 99,158,60, "Ragione sociale", AN); add_field( 9,159,198,40, "Città estera della sede legale", AN); add_field(10,199,201, 3, "Stato estero della sede legale", AN); add_field(11,202,241,40, "Indirizzo estero della sede legale", AN); add_field(12,242,249, 8, "Data dell'operazione", DT, "", OBBLIG); add_field(13,250,264,15, "Numero della Nota di Variazione", AN, "", OBBLIG); add_field(14,265,273, 9, "Imponibile Nota di Variazione", NU); add_field(15,274,282, 9, "Imposta Nota di Variazione", NU); add_field(16,283,290, 8, "Data della Fattura da rettificare", DT, "", OBBLIG); add_field(17,291,305,15, "Numero della Fattura da rettificare", AN, "", OBBLIG); add_field(18,306,306, 1, "Variazione imponib. (Debito/Credito)",AN); add_field(19,307,307, 1, "Variazione imposta (Debito/Credito)", AN); add_field(20,308,1797,1490, "Filler", AN); add_field(21,1798,1798,1,"Carattere di controllo", AN, "A", OBBLIG); add_field(22,1799,1800,2,"Caratteri di fine riga", AN, "\r\n"); } _recset = NULL; } /////////////////////////////////////////////////////////// // TDati_rilevanti_set /////////////////////////////////////////////////////////// class TDati_rilevanti_set : public TAS400_recordset { int _anno; protected: virtual bool set_field(const TAS400_column_info& fi, const TVariant& var); virtual const TVariant& get_field(const TAS400_column_info& fi) const; void init(); bool set_val(int n, const TVariant& v) { return TAS400_recordset::set(n-1, v); } public: bool set(unsigned int n, const TVariant& v) { return set_val(n, v); } bool set(unsigned int n, const TString& v) { return set_val(n, v); } bool set(unsigned int n, char v) { TString4 str; str << v; return set_val(n, str); } bool set(unsigned int n, int v) { return set_val(n, long(v)); } bool set(unsigned int n, const real& v) { return set_val(n, v); } bool set(unsigned int n, const TDate& v) { return set_val(n, v); } void add_header(const TMask& msk, int num_inv = 1, int tot_inv = 1); void add_footer(); bool split(const TFilename& name, const TRecnotype maxalleg = 15000); int anno() const { return _anno; } TDati_rilevanti_set(int anno); TDati_rilevanti_set(const TFilename& file); }; bool TDati_rilevanti_set::set_field(const TAS400_column_info& fi, const TVariant& var) { // Salva le date in formato GGMMAAAA invece dello standard ANSI AAAAMMGG if (fi._type == DT && fi._width == 8) { const TDate d = var.as_date(); if (d.ok()) { TFixed_string str = d.string(full, '\0', full, full, gma_date); row().overwrite(str, fi._pos); } else row().overwrite(" ", fi._pos); return true; } else // Salva gli importi in formato 000001234 (non possono essere negativi) if (fi._type == NU && fi._width == 9) { TString16 str = var.as_string(); CHECKS(str[0] != '-', "Importo negativo non ammesso:", (const char*)str); // Tiene la sola parte intera e riempie di zeri const int dot = str.find('.'); if (dot >= 0) str.cut(dot); str.right_just(fi._width, '0'); row().overwrite(str, fi._pos); return true; } return TAS400_recordset::set_field(fi, var); } const TVariant& TDati_rilevanti_set::get_field(const TAS400_column_info& ci) const { if (ci._type == DT && ci._width == 8) { const TRecnotype n = current_row(); if (n >= 0 && n < items()) { const TString& str = row(n).mid(ci._pos, ci._width); const int gg = atoi(str.left(2)); const int mm = atoi(str.mid(2,2)); const int aa = atoi(str.mid(4,4)); if (aa > 1800 && aa < 2100) { TVariant& var = get_tmp_var(); var.set(TDate(gg, mm, aa)); return var; } } return NULL_VARIANT; } return TAS400_recordset::get_field(ci); } void TDati_rilevanti_set::add_header(const TMask& msk, int num_inv, int tot_inv) { const TAnagrafica ditta(LF_NDITTE, prefix().get_codditta()); new_rec("0"); set(7, ditta.codice_fiscale()); set(8, ditta.partita_IVA()); if (ditta.giuridica()) { set( 9, ditta.ragione_sociale()); set(10, ditta.comune_residenza()); set(11, ditta.provincia_residenza()); } else { set(12, ditta.cognome()); set(13, ditta.nome()); set(14, ditta.sesso()); set(15, ditta.data_nascita()); set(16, ditta.comune_nascita()); set(17, ditta.provincia_nascita()); } set(18, _anno); if (tot_inv < 1) tot_inv = 1; if (num_inv <= 0) num_inv = 1; if (num_inv > tot_inv) num_inv = tot_inv; set(20, num_inv); set(21, tot_inv); const TString& cofi = msk.get(F_INTER_COFI); if (cofi.full()) { set(22, cofi); set(23, msk.get(F_INTER_CAF)); set(24, msk.get(F_INTER_COM)); set(25, msk.get(F_INTER_DATE)); } else { set(25, TDate()); // Svuota data impegno } } void TDati_rilevanti_set::add_footer() { TString f = row(0); f.overwrite("9"); new_rec(f); } bool TDati_rilevanti_set::split(const TFilename& name, const TRecnotype maxalleg) { const TRecnotype totrec = items(); bool done = totrec <= maxalleg; if (!done) { TString msg; msg.format(FR("Spezzatura del file %s in blocchi da %d righe"), (const char*)name, maxalleg); TProgind pi(totrec, msg); TDati_rilevanti_set outset(_anno); int f = 0; for (TRecnotype r = 0; r < totrec; r++) { if (!pi.setstatus(r)) break; // Procedura interrotta dall'utente outset.new_rec(row(r)); if (outset.items() >= maxalleg || r == totrec-1) { // Costruisce il nome del file di invio parziale, es: Spesometro00001_2.txt TFilename outname = name; const TString8 saved_ext = outname.ext(); outname.ext(""); outname << '_' << (++f); outname.ext(saved_ext); done = outset.save_as(outname); if (done) outset.destroy(); else { cantwrite_box(outname); break; } } } if (f > 1) warning_box(FR("Sono stati generati %d file nella cartella %s"), name.path()); } return done; } void TDati_rilevanti_set::init() { TDati_rilevanti_trc trc; for (int i = 0; i <= 5; i++) trc.create_fields(i, *this); trc.create_fields(9, *this); } TDati_rilevanti_set::TDati_rilevanti_set(const TFilename& file) : TAS400_recordset("AS400(1800,1)"), _anno(2010) { init(); if (load_file(file) && move_first()) { const int anno = get(18).as_int(); if (anno > 2010) _anno = anno; } } TDati_rilevanti_set::TDati_rilevanti_set(int anno) : TAS400_recordset("AS400(1800,1)"), _anno(anno) { init(); } /////////////////////////////////////////////////////////// // TDati_rilevanti_array /////////////////////////////////////////////////////////// class TDati_rilevanti_array : public TObject { TArray _data; protected: TExclusion_mode segnala_riga(const TRectype& alleg, TExclusion_mode motivo, TLog_report& log) const; public: int items() const { return _data.items(); } const TRectype& operator[](int i) { return (const TRectype&)_data[i]; } TExclusion_mode add(const TRectype& alleg, bool send_all, TLog_report& log); void add(const TArray& note, bool send_all, TLog_report& log); }; TExclusion_mode TDati_rilevanti_array::segnala_riga(const TRectype& alleg, TExclusion_mode motivo, TLog_report& log) const { const long numreg = alleg.get_long(ALL_PROGR); const char* tipocf = alleg.get_char(ALL_TIPOCF) == 'F' ? TR("Fornitore") : TR("Cliente"); const long codcf = alleg.get_long(MOV_CODCF); TString msg; msg.format(FR("%s %6ld - Riga %7ld scartata: "), tipocf, codcf, numreg); msg << mode2string(motivo); log.log(1, msg); return motivo; } TExclusion_mode TDati_rilevanti_array::add(const TRectype& alleg, bool send_all, TLog_report& log) { TExclusion_mode ignora = TExclusion_mode(alleg.get_int(ALL_IGNORA)); if (ignora > em_importo_limite) return ignora; const real importo = alleg.get_real(ALL_IMPORTO); const real imposta = alleg.get_real(ALL_IMPOSTA); if (importo.is_zero() && imposta.is_zero()) return segnala_riga(alleg, em_importo_limite, log); const TString80 contratto = alleg.get(ALL_CONTRATTO); const TString8 numrett = alleg.get(ALL_NUMRETT); if (contratto.full() || numrett.full()) { TString16 curr_idcf = alleg.get(ALL_OCFPI); if (curr_idcf.blank()) curr_idcf = alleg.get(ALL_CODCF); TRectype* sum = NULL; for (int i = _data.last(); i >= 0; i--) { TRectype& rec = (TRectype&)_data[i]; TString16 idcf = rec.get(ALL_OCFPI); if (idcf.blank()) idcf = rec.get(ALL_CODCF); if (idcf == curr_idcf) { if ((numrett.full() && numrett == rec.get(ALL_NUMDOC)) || (contratto.full() && contratto == rec.get(ALL_CONTRATTO))) { sum = &rec; break; } } else break; } if (sum != NULL) { sum->add(ALL_IMPORTO, importo); sum->add(ALL_IMPOSTA, imposta); // Le istruzioni dicono di mettere la data dell'ultima rettifica // ma la procedura di controllo non accetta anni successivi! // Per cui ... comment :-) // const TDate sum_data = sum->get(ALL_DATAREG); // const TDate all_data = alleg.get(ALL_DATAREG); // if (all_data > sum_data) // sum->put(ALL_DATAREG, all_data); const int old_mode = sum->get_int(ALL_IGNORA); if (old_mode <= 1) { const int anno = sum->get_int(ALL_ANNO); int new_mode = sum->get_real(ALL_IMPORTO) < importo_limite(anno); if (new_mode && contratto.full()) { const TContratto c(alleg); real imp, iva; if (c.totale_annuale(anno, imp, iva)) new_mode = imp < importo_limite(anno); } if (old_mode != new_mode) sum->put(ALL_IGNORA, new_mode); } return em_incluso; // Aggiunto a record preesistente } else { // Ignora le note di variazione non collegate e di importo non rilevante if (!send_all && ignora == em_incluso && is_nota_variazione(alleg)) { const int anno = alleg.get_int(ALL_ANNO); const real importo = abs(alleg.get_real(ALL_IMPORTO)); if (importo < importo_limite(anno)) ignora = segnala_riga(alleg, em_importo_limite, log); else { const TDate datarett = alleg.get(ALL_DATARETT); if (datarett.year() != anno) return segnala_riga(alleg, em_data_limite, log); // Non posso fare la add con DATARETT errata const TString& nr = alleg.get(ALL_NUMRETT); if (nr.blank() || nr == INVALID_NUMDOC) return segnala_riga(alleg, em_altro, log); // Non posso fare la add in assenza di NUMRETT } } } } if (!send_all && ignora != em_incluso) return ignora; // Creo un nuovo record _data.add(alleg); return em_incluso; } void TDati_rilevanti_array::add(const TArray& note, bool send_all, TLog_report& log) { FOR_EACH_ARRAY_ITEM(note, t, obj) { const TRectype& nota = *(const TRectype*)obj; add(nota, send_all, log); } } /////////////////////////////////////////////////////////// // TCofi_cache /////////////////////////////////////////////////////////// class TCofi_cache : public TCache { TLocalisamfile _clifo, _occas; protected: virtual TObject* key2obj(const char* key); public: const TString& cofi2ragsoc(char tipocf, const TString& cofi); const TString& paiv2ragsoc(char tipocf, const TString& paiv); TCofi_cache() : _clifo(LF_CLIFO), _occas(LF_OCCAS) { } }; TObject* TCofi_cache::key2obj(const char* key) { TToken_string chiave(key); const int fkey = chiave.get_char(0)=='C' ? 4 : 5; const TString4 tipocf = chiave.get(); const TString16 code= chiave.get(); _clifo.setkey(fkey); _clifo.zero(); _clifo.put(CLI_TIPOCF, tipocf); if (fkey == 5) _clifo.put(CLI_PAIV, code); else _clifo.put(CLI_COFI, code); int err = _clifo.read(); if (err != NOERR && fkey == 5 && pi_check("IT", code)) { _clifo.put(CLI_TIPOCF, tipocf); _clifo.put(CLI_STATOPAIV, "IT"); _clifo.put(CLI_PAIV, code); err = _clifo.read(); } if (err == NOERR) return new TString80(_clifo.get(CLI_RAGSOC)); if (fkey == 5 && !pi_check("IT", code)) // cerco partite IVA estere { TString query; query << "USE CLIFO SELECT PAIV=\"" << code << '"' << "\nFROM TIPOCF=" << tipocf << "\nTO TIPOCF=" << tipocf; TISAM_recordset clifo(query); if (clifo.move_first()) return new TString80(clifo.get(CLI_RAGSOC).as_string()); } _occas.put(OCC_CFPI, code); if (_occas.read() == NOERR) { const TString& cfpi = _occas.get(fkey == 4 ? OCC_COFI : OCC_PAIV); if (code == cfpi || cfpi.empty()) return new TString80(_occas.get(OCC_RAGSOC)); } TString query; query << "USE OCCAS SELECT "; if (fkey == 4) query << "COFI=\"" << code << '"'; else query << "PAIV=\"" << code << '"'; TISAM_recordset occas(query); if (occas.move_first()) return new TString80(occas.get(OCC_RAGSOC).as_string()); return NULL; } const TString& TCofi_cache::cofi2ragsoc(char tipocf, const TString& cofi) { TString80 key; key.format("CF|%c|%s", tipocf, (const char*)cofi); const TString* ragsoc = (const TString*)objptr(key); return ragsoc != NULL ? *ragsoc : EMPTY_STRING; } const TString& TCofi_cache::paiv2ragsoc(char tipocf, const TString& paiv) { TString80 key; key.format("PI|%c|%s", tipocf, (const char*)paiv); const TString* ragsoc = (const TString*)objptr(key); return ragsoc != NULL ? *ragsoc : EMPTY_STRING; } /////////////////////////////////////////////////////////// // TDati_rilevanti_rep /////////////////////////////////////////////////////////// class TDati_rilevanti_rep : public TReport { TCofi_cache _cofi; protected: const TString& cofi2ragsoc(char tipocf, const TString& cofi) const { return ((TDati_rilevanti_rep*)this)->_cofi.cofi2ragsoc(tipocf, cofi); } const TString& paiv2ragsoc(char tipocf, const TString& cofi) const { return ((TDati_rilevanti_rep*)this)->_cofi.paiv2ragsoc(tipocf, cofi); } virtual bool get_usr_val(const TString& name, TVariant& var) const; public: TDati_rilevanti_rep(const TFilename& file); }; bool TDati_rilevanti_rep::get_usr_val(const TString& name, TVariant& var) const { const TDati_rilevanti_set& set = *(TDati_rilevanti_set*)recordset(); const int tipo = set.rec_type()[0] - '0'; if (name == "ANNO") { var.set(set.anno()); return true; } if (name == "TIPO") { var.set(tipo); return true; } if (name == "COFI") { switch (tipo) { case 1: var = set.get("1.2"); break; case 4: var = set.get("4.3"); break; default: var.set_null(); break; } return true; } if (name == "PAIV") { switch (tipo) { case 2: var = set.get("2.2"); break; case 4: var = set.get("4.2"); break; default: var.set_null(); break; } return true; } if (name == "RAGSOC") { char tipocf = 'C'; switch (tipo) { case 2: if (set.get("2.8").as_int() == 2) tipocf = 'F'; break; default: break; }; switch (tipo) { case 1: var = cofi2ragsoc(tipocf, set.get("1.2").as_string()); break; case 2: var = paiv2ragsoc(tipocf, set.get("2.2").as_string()); break; case 3: var = set.get("3.8"); if (var.is_empty()) { TString80 rs; rs << set.get("3.2") << ' ' << set.get("3.3"); var = rs.trim(); } break; case 4: { const TString16 paiv = set.get("4.2").as_string(); if (paiv.full()) { var = paiv2ragsoc('C', paiv); if (var.is_empty()) var = paiv2ragsoc('F', paiv); } else { const TString16 cofi = set.get("4.3").as_string(); var = cofi2ragsoc('C', cofi); if (var.is_empty()) var = paiv2ragsoc('F', cofi); } } break; case 5: var = set.get("5.8"); if (var.is_empty()) { TString80 rs; rs << set.get("5.2") << ' ' << set.get("5.3"); var = rs.trim(); } break; default: var.set_null(); break; } return true; } if (name == "DATAREG") { switch (tipo) { case 1: var = set.get("1.3"); break; case 2: var = set.get("2.3"); break; case 3: var = set.get("3.12"); break; case 4: var = set.get("4.4"); break; case 5: var = set.get("5.12"); break; default: var.set_null(); break; } return true; } if (name == "NUMDOC") { switch (tipo) { case 2: var = set.get("2.4"); break; case 3: var = set.get("3.13"); break; case 4: var = set.get("4.5"); break; case 5: var = set.get("5.13"); break; default: var.set_null(); break; } return true; } if (name == "IMPORTO") { switch (tipo) { case 1: var = set.get("1.5"); break; case 2: var = set.get("2.6"); break; case 3: var = set.get("3.15"); break; case 4: var = set.get("4.6"); break; case 5: var = set.get("5.14"); break; default: var.set_null(); break; } return true; } if (name == "IMPOSTA") { switch (tipo) { case 2: var = set.get("2.7"); break; case 3: var = set.get("3.16"); break; case 4: var = set.get("4.7"); break; case 5: var = set.get("5.15"); break; default: var.set_null(); break; } return true; } if (name == "DATARETT") { switch (tipo) { case 4: var = set.get("4.8"); break; case 5: var = set.get("5.16"); break; default: var.set_null(); break; } return true; } if (name == "NUMRETT") { switch (tipo) { case 4: var = set.get("4.9"); break; case 5: var = set.get("5.17"); break; default: var.set_null(); break; } return true; } if (name == "SIMPORTO") { switch (tipo) { case 4: var = set.get("4.10"); break; case 5: var = set.get("5.18"); break; default: var.set_null(); break; } return true; } if (name == "SIMPOSTA") { switch (tipo) { case 4: var = set.get("4.11"); break; case 5: var = set.get("5.19"); break; default: var.set_null(); break; } return true; } if (name == "MODPAG") { switch (tipo) { case 1: var = set.get("1.4"); break; case 2: var = set.get("2.5"); break; case 3: var = set.get("3.14"); break; default: var.set_null(); break; } return true; } if (name == "TIPOPE") { switch (tipo) { case 2: var = set.get("2.8"); break; case 3: var = set.get("3.17"); break; default: var.set_null(); break; } return true; } return TReport::get_usr_val(name, var); } TDati_rilevanti_rep::TDati_rilevanti_rep(const TFilename& file) { load("fe0100"); TDati_rilevanti_set* set = new TDati_rilevanti_set(file); // Elimina testata e coda set->destroy(0); set->destroy(set->items()-1); set_recordset(set); } /////////////////////////////////////////////////////////// // TDati_rilevanti_msk /////////////////////////////////////////////////////////// class TDati_rilevanti_msk : public TAutomask { TMaskmode _mode; bool _sheet_dirty; TExclusion_mode _why; TLog_report* _log; protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void alleg_sort(TSheet_field& s) const; void load_sheet(); bool save_sheet(); bool save_if_dirty(); void set_dirty(bool d = true); bool send_nota_variazione(const TRectype& alleg, TDati_rilevanti_set& operaz); bool send_fatt(const TRectype& alleg, TDati_rilevanti_set& operaz); void build_outname(TFilename& n) const; protected: TRecnotype last_user_progr() const; TRecnotype nuovo_progr() const; bool check_rows(bool show_error); void enable_buttons(); bool send_rec(const TRectype& alleg, TDati_rilevanti_set& operaz); TExclusion_mode segnala_movimento(const TRectype& mov, TExclusion_mode motivo); bool fattura_associata(long numreg_var, TDate& datafatt, TString& numdoc) const; bool controlla_mov(TRectype& mrec) const; bool azzera_alleg(TAssoc_array& manuali) const; void collega_variazioni() const; public: TRecnotype genera_alleg(); bool elabora_alleg(); bool send_alleg(); bool recall_alleg() const; TExclusion_mode elabora_movimento(const TRectype& mov, TBaseisamfile& falleg); bool salva_allegato(const TRectype& mov, TBaseisamfile& falleg, TRecnotype& progr, const real& corrispettivo, const real& imposta, int tipope); TExclusion_mode validate_clifo(const TRectype& mov); TExclusion_mode validate_mov(const TRectype& mov); TDati_rilevanti_msk() : TAutomask("fe0100a"), _mode(MODE_QUERY), _log(NULL) { load_profile(); set_dirty(false); } ~TDati_rilevanti_msk() { save_profile(); } }; TExclusion_mode TDati_rilevanti_msk::segnala_movimento(const TRectype& mov, TExclusion_mode motivo) { if (_why == em_incluso) { const long numreg = mov.get_long(MOV_NUMREG); const char* tipocf = mov.get_char(MOV_TIPO) == 'F' ? TR("Fornitore") : TR("Cliente"); const long codcf = mov.get_long(MOV_CODCF); TString msg; msg.format(FR("%s %6ld - Registrazione %7ld scartata: "), tipocf, codcf, numreg); msg << mode2string(motivo); _why = motivo; if (motivo > em_importo_limite) _log->log(1, msg); } return motivo; } TExclusion_mode TDati_rilevanti_msk::validate_clifo(const TRectype& mov) { const char tipocf = mov.get_char(MOV_TIPO); const long codcf = mov.get_long(MOV_CODCF); const TString16 ocfpi = mov.get(MOV_OCFPI); if (tipocf <= ' ' || (codcf <= 0 && ocfpi.blank())) return segnala_movimento(mov, em_no_allegato); TString4 stato; if (ocfpi.full()) { const TRectype& rec_occas = cache().get(LF_OCCAS, ocfpi); stato = rec_occas.get(OCC_STATO); } else { TString8 key; key.format("%c|%ld", tipocf, codcf); const TRectype& rec_clifo = cache().get(LF_CLIFO, key); stato = rec_clifo.get(CLI_STATOCF); const int alleg = rec_clifo.get_int(CLI_ALLEG); if (alleg == 1) return segnala_movimento(mov, em_no_allegato); if (tipocf == 'F' && alleg == 5) return segnala_movimento(mov, em_estero); if (stato.full()) { const TRectype& rec_sta = cache().get("%STA", stato); if (rec_sta.get_bool("B0")) return segnala_movimento(mov, em_fiscalita_agevolata); if (tipocf == 'F') return segnala_movimento(mov, em_estero); } } return em_incluso; //se arriva qui il clifo è da considerare } TExclusion_mode TDati_rilevanti_msk::validate_mov(const TRectype& mov) { // Ignora eventuale vecchio movimento IVA (ANNOIVA < 2010) const int anno = mov.get_int(MOV_ANNOIVA); if (anno < 2010) segnala_movimento(mov, em_data_limite); // Ignora i movimenti già comunicati tramite modello INTRA if (!mov.get_real(MOV_CORRLIRE).is_zero() || !mov.get_real(MOV_CORRVALUTA).is_zero()) segnala_movimento(mov, em_intra); return validate_clifo(mov); } bool TDati_rilevanti_msk::fattura_associata(long numreg_var, TDate& datafatt, TString& numdoc) const { long numreg_fatt = 0; if (main_app().has_module(SCAUT)) { TLocalisamfile partite(LF_PARTITE); partite.setkey(2); TRectype& part = partite.curr(); part.put(PART_NREG, numreg_var); part.put(PART_NUMRIG, 1); if (partite.read() == NOERR) // Ho trovato la partita ora cerco la fattura di riferimento { int nriga = part.get_int(PART_NRIGA); part.zero(PART_NRIGA); // Uso il record come chiave per leggere l'intera partita TRecord_array partita(part, PART_NRIGA); for (nriga = partita.pred_row(nriga); nriga >= 1; nriga = partita.pred_row(nriga)) { const TRectype& riga = partita.row(nriga); const int tipomov = riga.get_int(PART_TIPOMOV); const long nreg_part = riga.get_long(PART_NREG); if (tipomov == 1 && nreg_part > 0) // Fattura { datafatt = riga.get(PART_DATAREG); numdoc = riga.get(PART_NUMDOC); break; } } } } return numdoc.full(); } TExclusion_mode TDati_rilevanti_msk::elabora_movimento(const TRectype& mov, TBaseisamfile& falleg) { validate_mov(mov); const char tipocf = mov.get_char(MOV_TIPO); const long codcf = mov.get_long(MOV_CODCF); const TString4 tipodoc = mov.get(MOV_TIPODOC); const TDate datareg = mov.get_date(MOV_DATAREG); const int anno = get_int(F_ANNO); const TString& keytok = mov.get(MOV_NUMREG); TRecord_array righe_iva(keytok, LF_RMOVIVA); real tot_imponibile, tot_imposta; //calcolo di imponibile ed imposta di tutte le righe iva del movimento for (int r = righe_iva.last_row(); r > 0; r = righe_iva.pred_row(r)) { const TRectype& rmi = righe_iva.row(r); const TCodiceIVA ci(rmi.get(RMI_CODIVA)); int natura_operazione = ci.allegato(tipocf); if (natura_operazione <= 0 || natura_operazione > 5) continue; // Esportazioni const bool art_8 = ci.get("S2") == "20" && ci.get("S3") == "1"; if (art_8) segnala_movimento(mov, em_art8); const TString4 cod_det = rmi.get(RMI_TIPODET); const int tip_det = cod_det == "3" ? 3 : atoi(cache().get("%DET", cod_det, "I0")); if (tip_det == 3) segnala_movimento(mov, em_passaggi_interni); real rmi_imponibile = rmi.get_real(RMI_IMPONIBILE); real rmi_imposta = rmi.get_real(RMI_IMPOSTA); if (natura_operazione == 4 && rmi_imposta.is_zero()) // se l'imposta non è specificata sullo scontrino ... rmi_imposta = ci.scorpora(rmi_imponibile); // ... scorporo il lordo tot_imponibile += rmi_imponibile; tot_imposta += rmi_imposta; } const int modpag = mov.get_int(MOV_MODPAG); if (modpag == 1 && _why == em_incluso) { // Considera solo registrazioni con importo rilevante if (abs(tot_imponibile) < importo_limite(anno)) _why = em_importo_limite; // Non segnalare migliaia di movimenti inutilmente } const long numreg = mov.get_long(MOV_NUMREG); // Registro tutti i dati del cliente e gli importi falleg.zero(); falleg.put(ALL_ANNO, anno); falleg.put(ALL_PROGR, numreg); falleg.put(ALL_IGNORA, int(_why)); falleg.put(ALL_TIPOCF, tipocf); falleg.put(ALL_CODCF, codcf); falleg.put(ALL_OCFPI, mov.get(MOV_OCFPI)); falleg.put(ALL_DATAREG, mov.get(MOV_DATAREG)); falleg.put(ALL_NUMDOC, mov.get(MOV_NUMDOC)); falleg.put(ALL_TIPOPE, tipocf == 'C' ? 1 : 2); falleg.put(ALL_IMPORTO, tot_imponibile); falleg.put(ALL_IMPOSTA, tot_imposta); falleg.put(ALL_MODPAG, modpag); if (modpag == 1) { falleg.put(ALL_DATARETT, mov.get(MOV_DATARETT)); falleg.put(ALL_NUMRETT, mov.get(MOV_NUMRETT)); } else falleg.put(ALL_CONTRATTO, mov.get(MOV_CONTRATTO)); const int err = falleg.rewrite_write(); if (err != NOERR) { TString msg; msg.format(FR("Errore %d di aggiornamento del record %d/%ld sul file %s"), err, anno, numreg, (const char*)falleg.name()); _log->log(2, msg); } return _why; } // Test di coerenza tra MODPAG, CONTRATTO e NUMRETT bool TDati_rilevanti_msk::controlla_mov(TRectype& mrec) const { const long numreg = mrec.get_long(MOV_NUMREG); TString80 contratto = mrec.get(MOV_CONTRATTO); int old_modpag = mrec.get_int(MOV_MODPAG); int new_modpag = 1; bool update = false; if (is_nota_variazione(mrec)) { TDate datarett = mrec.get(MOV_DATARETT); TString8 numrett = mrec.get(MOV_NUMRETT); if (contratto.full()) { mrec.put(MOV_CONTRATTO, contratto.cut(0)); update = true; // Peccato veniale } if (numrett.blank()) { if (!fattura_associata(numreg, datarett, numrett)) numrett = INVALID_NUMDOC; mrec.put(MOV_DATARETT, datarett); mrec.put(MOV_NUMRETT, numrett); update = true; } const TAnagrafica a(mrec); TString msg; if (numrett != INVALID_NUMDOC) { msg.format(FR("Nota n. %ld di %s associata al doc. %s del %s"), numreg, (const char*)a.ragione_sociale(), (const char*)numrett, datarett.string()); _log->log(0, msg); } else { msg.format(FR("Nota n. %ld di %s non associata ad una fattura"), numreg, (const char*)a.ragione_sociale()); _log->log(1, msg); } } else { if (contratto.full()) { const TContratto c(mrec); new_modpag = c.modalita_pagamento(); } if (get(MOV_NUMRETT).full() || get(MOV_DATARETT).full()) { mrec.zero(MOV_DATARETT); mrec.zero(MOV_NUMRETT); update = true; // Peccato veniale } } if (old_modpag != new_modpag) { if (old_modpag > 0) // I vecchi movimenti hanno per forza 0: li perdoniamo! { const TAnagrafica a(mrec); TString msg; msg.format(FR("Movimento n. %ld di %s con modalità di pagamento incongruente: %d->%d"), numreg, (const char*)a.ragione_sociale(), old_modpag, new_modpag); _log->log(0, msg); } mrec.put(MOV_MODPAG, new_modpag); update = true; } return update; } bool TDati_rilevanti_msk::azzera_alleg(TAssoc_array& manuali) const { const int anno = get_int(F_ANNO); const TDate data = get(F_DATA); TFast_isamfile fast_alleg(LF_ALLEG); TFast_isamfile fast_mov(LF_MOV); TString query; query << "USE " << LF_ALLEG << "\nJOIN MOV INTO NUMREG==PROGR" << "\nFROM ANNO=" << anno << "\nTO ANNO=" << anno << " PROGR=" << MANUAL_ROW; TISAM_recordset alleg(query); TLocalisamfile& falleg = alleg.cursor()->file(); TRectype& arec = falleg.curr(); TLocalisamfile& fmov = alleg.cursor()->file(LF_MOV); TRectype& mrec = fmov.curr(); TString msg; msg << TR("Azzeramento ") << falleg.description() << ' ' << anno; TProgind pi(alleg.items(), msg, false); manuali.destroy(); for (bool ok = alleg.move_first(); ok; ok = alleg.move_next()) { pi.addstatus(1); const long progr = arec.get_long(ALL_PROGR); const long numreg = mrec.get_long(MOV_NUMREG); const TDate datareg = mrec.get_long(MOV_DATAREG); const int annoiva = mrec.get_long(MOV_ANNOIVA); bool kill = numreg != progr || annoiva < anno; if (!kill) { const bool forzata = arec.get_bool(ALL_FORZATURA); if (forzata) manuali.add(arec.get(ALL_PROGR)); else kill = annoiva == data.year() && datareg > data; } if (kill) falleg.remove(); // Riga generata dalla vecchia versione } return !manuali.empty(); } // Cerca l'ultimo numero di riga immesso manualmente TRecnotype TDati_rilevanti_msk::last_user_progr() const { const int anno = get_int(F_ANNO); TRecnotype progr = MANUAL_ROW; TString query; query << "USE " << LF_ALLEG << "\nFROM " << ALL_ANNO << '=' << anno << ' ' << ALL_PROGR << '=' << MANUAL_ROW << "\nTO " << ALL_ANNO << '=' << anno; TISAM_recordset alleg(query); if (alleg.move_last()) progr = alleg.get(ALL_PROGR).as_int(); return progr; } TRecnotype TDati_rilevanti_msk::nuovo_progr() const { TRecnotype progr = last_user_progr(); TSheet_field& righe = sfield(F_RIGHE); const int items = righe.items(); if (items > 0) { const int col = righe.cid2index(A_RIGA); for (int i = items-1; i >= 0; i--) { const TRecnotype sheet_progr = atol(righe.cell(i,col)); if (sheet_progr > progr) progr = sheet_progr; } } return progr+1; } static int sort_alleg(const TSortable& s1, const TSortable& s2, void* jolly) { const TRectype& a1 = (const TRectype&)s1; const TRectype& a2 = (const TRectype&)s2; const TString& c1 = a1.get(ALL_CONTRATTO); const TString& c2 = a2.get(ALL_CONTRATTO); int cmp = c1.compare(c2, -1, true); if (cmp == 0 && c1.blank()) { const int n1 = is_nota_variazione(a1); const int n2 = is_nota_variazione(a2); cmp = n1 - n2; } if (cmp == 0) { const TDate d1 = a1.get(ALL_DATAREG); const TDate d2 = a2.get(ALL_DATAREG); cmp = d1 - d2; } return cmp; } TRecnotype TDati_rilevanti_msk::genera_alleg() { const int anno = get_int(F_ANNO); const TDate data_estrazione = get(F_DATA); TString str_pi; str_pi << TR("Movimenti ") << anno; _log = new TLog_report(str_pi); TAssoc_array manuali; azzera_alleg(manuali); TRecnotype nprog = 1; if (anno >= 2010) // Dummy test for bracing TFast_isamfiles { TFast_isamfile falleg(LF_ALLEG); TFast_isamfile fmov(LF_MOV); TString query; query << "USE MOV KEY 3 SELECT BETWEEN(DATAREG," << anno << "0101," << data_estrazione.date2ansi() << ")" << "\nFROM TIPO=C\nTO TIPO=F"; TISAM_recordset mov(query); TRectype& mov_rec = mov.cursor()->curr(); const TRecnotype items = mov.items(); TProgind pi(items, str_pi); for (bool ok = mov.move_first(); ok; ok = mov.move_next()) { if (!pi.addstatus(1)) break; _why = em_incluso; const int annofe = mov_rec.get_int(MOV_ANNOFE); if (annofe >= 2010) // Non elaborae i movimenti gia' inviati in definitivo! { segnala_movimento(mov_rec, em_inviato); continue; } const TString& key = mov_rec.get(MOV_NUMREG); if (manuali.is_key(key)) { manuali.remove(key); continue; } controlla_mov(mov_rec); if (is_nota_variazione(mov_rec)) { const TDate datarett = mov_rec.get(MOV_DATARETT); if (!datarett.ok() || datarett.year() == anno) elabora_movimento(mov_rec, falleg); // Elabora nota di variazione } else { const TDate datareg = mov_rec.get(MOV_DATAREG); if (datareg.year() == anno) // Scarta fatture dell'anno dopo elabora_movimento(mov_rec, falleg); } } } collega_variazioni(); _log->preview(); delete _log; _log = NULL; return nprog; } void TDati_rilevanti_msk::collega_variazioni() const { const int anno = get_int(F_ANNO); TString query; query << "USE ALLEG KEY 2 SELECT IGNORA<=" << int(em_importo_limite); query << "\nJOIN ALLEG KEY 3 ALIAS 220 INTO ANNO=ANNO TIPOCF=TIPOCF CODCF==CODCF NUMRETT=NUMDOC"; query << "\nFROM ANNO=" << anno << "\nTO ANNO=" << anno; TISAM_recordset fatture(query); TProgind pi(fatture.items(), TR("Collegamento note di variazione"), false, true); TRelation& rel = *fatture.cursor()->relation(); for (bool ok = fatture.move_first(); ok; ok = fatture.move_next()) { pi.addstatus(1); if (rel.is_first_match(-220)) { real importo = fatture.get(ALL_IMPORTO).as_real(); for (bool ok = true; ok; ok = rel.next_match(-220)) importo += rel.curr(-220).get_real(ALL_IMPORTO); const TExclusion_mode old_mode = TExclusion_mode(fatture.get(ALL_IGNORA).as_int()); const TExclusion_mode new_mode = importo < importo_limite(anno) ? em_importo_limite : em_incluso; if (old_mode != new_mode) { TLocalisamfile& f = fatture.cursor()->file(); f.put(ALL_IGNORA, new_mode); f.rewrite(); } } } } // Analizza tutti i movimenti dell'anno dell'attività corrente e genera i record rilevanti bool TDati_rilevanti_msk::elabora_alleg() { if (!check_fields()) // Controlla che l'anno sia valido return false; const TRecnotype prog = genera_alleg(); return prog > 1; } bool TDati_rilevanti_msk::send_nota_variazione(const TRectype& alleg, TDati_rilevanti_set& operaz) { real imponibile = alleg.get_real(ALL_IMPORTO); real imposta = alleg.get_real(ALL_IMPOSTA); if (imponibile.is_zero() && imposta.is_zero()) return false; const TAnagrafica anag(alleg); if (!anag.ok()) return false; const char tipocf = alleg.get_char(ALL_TIPOCF); char segno_imponibile = tipocf == 'C' ? 'D' : 'C'; // Normalmente sono negative e quindi a debito del dichiarante char segno_imposta = segno_imponibile; if (imponibile >= ZERO) segno_imponibile = segno_imponibile == 'D' ? 'C' : 'D'; else imponibile = -imponibile; if (imposta >= ZERO) segno_imposta = segno_imposta == 'D' ? 'C' : 'D'; else imposta = -imposta; if (anag.stato_estero() > 0) { operaz.new_rec("5"); // Note di variazione a soggetti non residenti if (anag.fisica()) { operaz.set(2, anag.cognome()); operaz.set(3, anag.nome()); operaz.set(4, anag.data_nascita()); operaz.set(5, anag.comune_nascita()); operaz.set(6, anag.provincia_nascita()); operaz.set(7, anag.stato_estero()); } else { operaz.set(8, anag.ragione_sociale()); operaz.set(9, anag.comune_residenza()); operaz.set(10, anag.stato_estero()); operaz.set(11, anag.indirizzo_residenza()); } operaz.set(12, alleg.get(ALL_DATAREG)); operaz.set(13, alleg.get(ALL_NUMDOC)); operaz.set(14, imponibile); operaz.set(15, imposta); operaz.set(16, alleg.get(ALL_DATARETT)); operaz.set(17, alleg.get(ALL_NUMRETT)); operaz.set(18, segno_imponibile); operaz.set(19, segno_imposta); } else { operaz.new_rec("4"); // Note di variazione a soggetti residenti if (anag.partita_IVA().full()) operaz.set(2, anag.partita_IVA()); else operaz.set(3, anag.codice_fiscale()); operaz.set(4, alleg.get(ALL_DATAREG)); operaz.set(5, alleg.get(ALL_NUMDOC)); operaz.set(6, imponibile); operaz.set(7, imposta); operaz.set(8, alleg.get(ALL_DATARETT)); operaz.set(9, alleg.get(ALL_NUMRETT)); operaz.set(10, segno_imponibile); operaz.set(11, segno_imposta); } return true; } bool TDati_rilevanti_msk::send_fatt(const TRectype& alleg, TDati_rilevanti_set& operaz) { const real importo = alleg.get_real(ALL_IMPORTO); const real imposta = alleg.get_real(ALL_IMPOSTA); if (importo.is_zero() && imposta.is_zero()) return false; const TAnagrafica anag(alleg); if (!anag.ok()) return false; const TString& paiv = anag.partita_IVA(); if (anag.stato_estero() > 0) { operaz.new_rec("3"); // Operazioni con soggetti non residenti if (anag.fisica()) { operaz.set(2, anag.cognome()); operaz.set(3, anag.nome()); operaz.set(4, anag.data_nascita()); operaz.set(5, anag.comune_nascita()); operaz.set(6, anag.provincia_nascita()); operaz.set(7, anag.stato_estero()); } else { operaz.set(8, anag.ragione_sociale()); if (anag.comune_residenza().empty()) operaz.set(9, anag.localita_residenza()); else operaz.set(9, anag.comune_residenza()); operaz.set(10, anag.stato_estero()); operaz.set(11, anag.indirizzo_residenza()); } operaz.set(12, alleg.get(ALL_DATAREG)); operaz.set(13, alleg.get(ALL_NUMDOC)); operaz.set(14, alleg.get(ALL_MODPAG)); operaz.set(15, importo); operaz.set(16, imposta); operaz.set(17, alleg.get(ALL_TIPOPE)); } else { if (paiv.blank()) { operaz.new_rec("1"); // Operazioni con soggetti residenti non titolari di partita IVA operaz.set(2, anag.codice_fiscale()); operaz.set(3, alleg.get(ALL_DATAREG)); operaz.set(4, alleg.get(ALL_MODPAG)); operaz.set(5, real(importo+imposta)); } else { operaz.new_rec("2"); // Operazioni con soggetti residenti - titolari di partita IVA operaz.set(2, paiv); operaz.set(3, alleg.get(ALL_DATAREG)); operaz.set(4, alleg.get(ALL_NUMDOC)); operaz.set(5, alleg.get(ALL_MODPAG)); operaz.set(6, alleg.get(ALL_IMPORTO)); operaz.set(7, alleg.get(ALL_IMPOSTA)); operaz.set(8, alleg.get(ALL_TIPOPE)); } } return true; } bool TDati_rilevanti_msk::send_rec(const TRectype& alleg, TDati_rilevanti_set& operaz) { bool done = false; if (is_nota_variazione(alleg)) done = send_nota_variazione(alleg, operaz); else done = send_fatt(alleg, operaz); return done; } bool TDati_rilevanti_msk::recall_alleg() const { const int anno = get_int(F_ANNO); if (!yesno_box(FR("Si desidera annullare l'invio definitivo dei movimenti del %d?"), anno)) return false; TFast_isamfile mov(LF_MOV); TString query; query << "USE MOV KEY 2 SELECT ANNOFE=" << anno; query << "\nFROM DATAREG=01-01-" << anno; TISAM_recordset recset(query); TLocalisamfile& file = recset.cursor()->file(); TProgind pi(recset.items(), TR("Aggiornamento movimenti di prima nota")); for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; file.zero(MOV_ANNOFE); file.rewrite(); } return true; } void TDati_rilevanti_msk::build_outname(TFilename& n) const { n = get(F_OUTFOLDER); if (n.blank()) n.tempdir(); TString16 f; f.format("Spesometro%05d", prefix().get_codditta()); n.add(f); n.ext("txt"); } // Genera file per invio telematico bool TDati_rilevanti_msk::send_alleg() { const int anno = get_int(F_ANNO); const bool send_all = get_int(F_SENDALL) != 1; TFilename temp; build_outname(temp); TDati_rilevanti_array data; TString query; query << "USE ALLEG KEY 2" << "\nFROM " << ALL_ANNO << '=' << anno << "\nTO " << ALL_ANNO << '=' << anno; TISAM_recordset alleg(query); const TRecnotype tot_alleg = alleg.items(); if (tot_alleg > 0) { _log = new TLog_report(temp); const TRectype& rec = alleg.cursor()->curr(); TString16 last_clifo; TArray note; TProgind pi(tot_alleg, TR("Elaborazione file")); for (bool ok = alleg.move_first(); ok; ok = alleg.move_next()) { if (!pi.addstatus(1)) break; TString16 clifo = rec.get(ALL_OCFPI); if (clifo.blank()) clifo = rec.get(ALL_CODCF); if (clifo != last_clifo) { data.add(note, send_all, *_log); note.destroy(); last_clifo = clifo; } if (is_nota_variazione(rec)) note.add(rec); else data.add(rec, send_all, *_log); } data.add(note, send_all, *_log); if (_log->recordset()->items()) _log->preview(); delete _log; _log = NULL; } TDati_rilevanti_set recset(anno); recset.add_header(*this); const int tot = data.items(); if (tot > 0) { TProgind pi(tot, TR("Generazione file per Agenzia delle Entrate")); for (int a = 0; a < tot; a++) { if (!pi.addstatus(1)) break; if (send_all || !data[a].get_int(ALL_IGNORA)) send_rec(data[a], recset); } } recset.add_footer(); recset.sort(); bool done = recset.save_as(temp); const long maxalleg = get_long(F_MAXREC); if (recset.items() > maxalleg) done = recset.split(temp, maxalleg); if (done && get_bool(F_DEFINITIVO) && yesno_box(TR("Si desidera confermare l'invio definitivo della comunicazione?"))) { TFast_isamfile mov(LF_MOV); TProgind pi(data.items(), TR("Aggiornamento movimenti di prima nota"), false); for (int i = data.items()-1; i >= 0; i--) { pi.addstatus(1); const TRectype& alleg = data[i]; const long numreg = alleg.get_long(ALL_PROGR); const int ignora = alleg.get_int(ALL_IGNORA); if (numreg > 0 && numreg < MANUAL_ROW && !ignora) { mov.put(MOV_NUMREG, numreg); int err = mov.read(_isequal, _lock); if (err == NOERR) { const int modpag = alleg.get_int(ALL_MODPAG); mov.put(MOV_MODPAG, modpag); if (modpag < 2) { const TString& nr = alleg.get(ALL_NUMRETT); if (nr.full() && nr != INVALID_NUMDOC) { mov.put(MOV_DATARETT, alleg.get(ALL_DATARETT)); mov.put(MOV_NUMRETT, nr); } } else mov.put(MOV_CONTRATTO, alleg.get(ALL_CONTRATTO)); mov.put(MOV_ANNOFE, anno); err = mov.rewrite(); } if (err != NOERR) { error_box(FR("Impossibile aggiornare il movimento %ld: errore %d"), numreg, err); break; } } } } return done; } void TDati_rilevanti_msk::set_dirty(bool d) { _sheet_dirty = d; enable(DLG_SAVEREC, d); } void TDati_rilevanti_msk::alleg_sort(TSheet_field& s) const { const int c_codcf = s.cid2index(A_CODCF); const int c_numdoc = s.cid2index(A_NUMDOC); const int c_numrett = s.cid2index(A_NUMRETT); const int c_forzata = s.cid2index(A_FORZATA); const int c_ignora = s.cid2index(A_IGNORA); const int c_importo = s.cid2index(A_IMPORTO); const int tot = s.items(); for (int k = 0; k < 2; k++) for (int i = tot-1; i >= 0; i--) { const TString8 numrett = s.cell(i, c_numrett); if (numrett.full() && numrett != INVALID_NUMDOC) { const long codcf_i = atol(s.cell(i, c_codcf)); int j = -1; // Cerca la fattura andando in su for (j = i-1; j >= 0; j--) { const long codcf_j = atol(s.cell(j, c_codcf)); if (codcf_j != codcf_i) { j = -1; break; } if (numrett == s.cell(j, c_numdoc) || numrett == s.cell(j, c_numrett)) break; } if (j < 0) // Non l'ho trovata { // Cerca la fattura andando in giù for (j = i+1; j < tot; j++) { const long codcf_j = atol(s.cell(j, c_codcf)); if (codcf_j != codcf_i) { j = tot; break; } if (numrett == s.cell(j, c_numdoc)) break; } } if (j >= 0 && j < tot) // L'ho trovata { s.move_row(i, j+1); if (*s.cell(j, c_numrett) <= ' ') s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, j, c_numdoc); s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, j+1, c_numrett); } } } } void TDati_rilevanti_msk::load_sheet() { const char tipocf = get(F_TIPOCF)[0]; const long codcf = get_long(F_CODCF); const TString& ocfpi = get(F_OCFPI); const int show_all = get_int(F_SHOWALL); TSheet_field& s = sfield(F_RIGHE); s.hide(); // Nascondo lo sheet per guadagnare un 20% di velocità di caricamento s.destroy(); const int anno = get_int(F_ANNO); TString limit; limit << ALL_ANNO << '=' << anno; if (codcf > 0) limit << ' ' << ALL_TIPOCF << '=' << tipocf << ' ' << ALL_CODCF << '=' << codcf; TString sel; if (ocfpi.full() || (show_all > 0 && show_all < 7)) { if (ocfpi.full()) sel << "(" << ALL_OCFPI << "='" << ocfpi << "')"; if (show_all > 0 && show_all < 7) { if (sel.full()) sel << "&&"; sel << "(STR(" << ALL_IGNORA; switch (show_all) { case 1: sel << '<'; break; // Importi superiori al limite (20000 o 3000) case 2: sel << '='; break; // Importi inferiori al limite (20000 o 3000) default: sel << '>'; break; // Importi scartati (esteri o leggi speciali) } sel << "1))"; } } TString query; query << "USE " << LF_ALLEG << " KEY 2"; if (sel.full()) query << " SELECT " << sel; if (limit.full()) query << "\nFROM " << limit << "\nTO " << limit; TISAM_recordset alleg(query); const TRecnotype items = alleg.items(); if (items > 0) { TString pi_str; pi_str << TR("Caricamento ") << items << TR(" movimenti del ") << anno; TProgind pi(items, pi_str); const TRectype& curr = alleg.cursor()->curr(); int rec = 0; for (bool ok = alleg.move_first(); ok; ok = alleg.move_next()) { if (!pi.addstatus(1)) break; s.autoload_line(++rec, curr); const int modpag = curr.get_int(ALL_MODPAG); if (modpag == 1) s.enable_cell(rec-1, A_CONTRATTO, false); else { s.enable_cell(rec-1, A_DATARETT, false); s.enable_cell(rec-1, A_NUMRETT, false); } } } alleg_sort(s); s.force_update(); s.show(); set_dirty(false); if (s.items() > 0) { _mode = MODE_MOD; disable(-1); } else { _mode = MODE_QUERY; enable(-1); } enable_buttons(); } bool TDati_rilevanti_msk::save_sheet() { if (!check_rows(false)) return false; bool done = true; const int anno = get_int(F_ANNO); TSheet_field& s = sfield(F_RIGHE); const TRecnotype items = s.items(); if (items > 0) { TFast_isamfile alleg(LF_ALLEG); TRectype& rec = alleg.curr(); TProgind pi(items, TR("Registrazione righe"), false); FOR_EACH_SHEET_ROW(s, r, row) { if (!pi.addstatus(1)) break; alleg.zero(); rec.put(ALL_ANNO, anno); s.autosave_line(r+1, rec); // Il tipo operazione non è più visibile, per cui lo calcolo ora rec.put(ALL_TIPOPE, rec.get_char(ALL_TIPOCF) == 'F' ? 2 : 1); const int err = alleg.rewrite_write(); if (err != NOERR) { done = cantwrite_box(alleg.name()); break; } } } if (done) { set_dirty(false); } return done; } bool TDati_rilevanti_msk::check_rows(bool show_error) { const int anno = get_int(F_ANNO); bool ok = anno >= 2010; if (!ok) { if (show_error) check_fields(); // Provoco segnalazione automatica return false; } long codcf = 0L; TString16 ocfpi; TSheet_field& s = sfield(F_RIGHE); FOR_EACH_SHEET_ROW(s, i, row) { row->get(s.cid2index(A_CODCF), codcf); row->get(s.cid2index(A_OCFPI), ocfpi); if (codcf <= 0L && ocfpi.blank()) { ok = show_error && error_box(FR("Soggetto mancante alla riga %d"), i+1); break; } } return ok; } bool TDati_rilevanti_msk::save_if_dirty() { bool done = true; if (_sheet_dirty && yesno_box(TR("Si desiderano registrare le modifiche?"))) { done = check_rows(true); if (done) done = save_sheet(); } return done; } void TDati_rilevanti_msk::enable_buttons() { const int anno = get_int(F_ANNO); const bool good_year = anno >= 2010; const bool def = get_bool(F_DEFINITIVO); const bool full_rows = !sfield(F_RIGHE).empty(); bool one_sent = false; // Ho spedito almeno un movimento in definitivo if (good_year) { TString query; query << "USE MOV KEY 2 SELECT ANNOFE=" << anno; query << "\nFROM DATAREG=01-01-" << anno; TISAM_recordset recset(query); one_sent = recset.move_first(); } enable(DLG_CANCEL, full_rows); enable(DLG_EXPORT, full_rows); enable(DLG_RECALC, !full_rows && good_year && !one_sent); enable(DLG_ELABORA, good_year && !(one_sent && def)); enable(DLG_DELREC, one_sent); enable(F_DEFINITIVO, !def); if (def) reset(F_DEFINITIVO); TFilename temp; build_outname(temp); enable(DLG_PREVIEW, temp.exist()); } bool TDati_rilevanti_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_OK: // Salva if (e == fe_button && jolly == 0) // Selezione su maschera principale { if (_mode == MODE_QUERY || save_if_dirty()) load_sheet(); return false; } break; case DLG_CANCEL: if (e == fe_button && jolly == 0) { if (_mode != MODE_QUERY && save_if_dirty()) { TSheet_field& s = sfield(F_RIGHE); s.destroy(); s.force_update(); _mode = MODE_QUERY; enable(-1); enable_buttons(); } return false; } break; case DLG_SAVEREC: if (e == fe_button) save_if_dirty(); break; case DLG_EXPORT: if (e == fe_button) return sfield(F_RIGHE).esporta(); break; case DLG_RECALC: if (e == fe_button && check_fields()) { if (elabora_alleg()) load_sheet(); } break; case DLG_ELABORA: if (e == fe_button && check_fields()) { send_alleg(); enable_buttons(); // Disabilita bottone se definitivo } break; case DLG_DELREC: if (e == fe_button && jolly == 0 && o.active()) { recall_alleg(); enable_buttons(); // Disabilita bottone return false; } break; case DLG_PREVIEW: if (e == fe_button) { TFilename temp; build_outname(temp); if (temp.exist()) { TDati_rilevanti_rep rep(temp); rep.preview(); } } break; case F_ANNO: if (e == fe_init || e == fe_modify) { int anno = atoi(o.get()); if (anno < 2010) { anno = TDate(TODAY).year()-1; o.set(anno); } on_field_event(efield(F_DATA), fe_modify, jolly); enable_buttons(); } break; case F_DATA: if (e == fe_init || e == fe_modify) { const int anno = max(2010, get_int(F_ANNO)); TDate d = o.get(); if (d < TDate(31,12,anno) || d > TDate(31,12,anno+1)) { if (anno == 2010) d = TDate(31,12,2011); else d = TDate(30,4,anno+1); set(F_DATA, d); } } break; case F_OUTFOLDER: if (e == fe_init && o.empty()) { TFilename tmp; tmp.tempdir(); o.set(tmp); } break; case F_MAXREC: if (e == fe_init && o.empty()) o.set(15000L); break; case F_RIGHE: if (e == fe_init) load_sheet(); else if (e == se_query_modify) { TSheet_field& s = (TSheet_field&)o; TToken_string& row = s.row(jolly); const TRecnotype progr = row.get_long(0); s.sheet_mask().enable(DLG_DELREC, progr >= MANUAL_ROW); s.sheet_mask().enable(DLG_USER, progr < MANUAL_ROW); } else if (e == se_notify_modify) { set_dirty( true); TSheet_field& s = (TSheet_field&)o; TToken_string& row = s.row(jolly); row.add("X", s.cid2index(A_FORZATA)); } else if (e == se_query_add) { if (!check_rows(false)) return false; } else if (e == se_notify_add) { TSheet_field& s = (TSheet_field&)o; TToken_string& row = s.row(jolly); row.add(nuovo_progr(), s.cid2index(A_RIGA)); row.add(1, s.cid2index(A_MODPAG)); } else if (e == se_query_del) { TSheet_field& s = (TSheet_field&)o; TToken_string& row = s.row(jolly); const TRecnotype progr = row.get_long(0); return progr >= MANUAL_ROW; } break; case A_CODCF: case A_OCFPI: if (e == fe_modify || (e == fe_init && !o.empty())) { TMask& m = o.mask(); const TAnagrafica anag(m.get(A_TIPOCF)[0], m.get_long(A_CODCF), m.get(A_OCFPI)); m.set(A_RAGSOC, anag.ragione_sociale()); m.set(A_PAIV, anag.partita_IVA()); m.set(A_COFI, anag.codice_fiscale()); } break; case DLG_USER: if (e == fe_button || e == fe_init) { const long numreg = o.mask().get_long(A_RIGA); const bool enab = (numreg > 0 && numreg < MANUAL_ROW); if (e == fe_button && enab) { TRectype mov(LF_MOV); mov.put(MOV_NUMREG, numreg); mov.edit(); } else o.enable(enab); } break; default: break; } return true; } /////////////////////////////////////////////////////////// // TDati_rilevanti_app /////////////////////////////////////////////////////////// class TDati_rilevanti_app : public TSkeleton_application { protected: virtual bool create(); public: virtual void main_loop(); }; bool TDati_rilevanti_app::create() { // Controllo preventivo dell'avvenuta conversione del tracciato record TRectype alleg(LF_ALLEG); if (alleg.type(ALL_NUMDOC) == _nullfld) return error_box(TR("Il database non è stato ancora convertito per il modulo FE")); // Teoricamente è possibile visualizzare tutti i movimenti di un anno, per cui allargo il numero riga TSheet_field::set_line_number_width(6); return TSkeleton_application::create(); } void TDati_rilevanti_app::main_loop() { TDati_rilevanti_msk msk; msk.run(); } /////////////////////////////////////////////////////////// // main /////////////////////////////////////////////////////////// int fe0100(int argc, char* argv[]) { TDati_rilevanti_app app; app.run(argc, argv, TR("Gestione dati rilevanti")); return 0; }