#include "cg3.h" #include "cg2103.h" #include "cg3900a.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TAllegato_info /////////////////////////////////////////////////////////// struct TAllegato_importi : public TObject { real _imp, _iva; // Imponibile ed imposta real _impNI, _impES, _ivaNE; // Non imponibili, esenti, Non esposti real _ind; // Valore indecifrabile valido solo per i fornitori fino al 2008 real _impNA; // Pattumiera per tutti valori NON in allegato bool is_not_null(bool strict) const; }; bool TAllegato_importi::is_not_null(bool strict) const { if (!strict && !_impNA.is_zero()) return true; return !(_imp.is_zero() && _iva.is_zero() && _ind.is_zero() && _impNI.is_zero() && _impES.is_zero() && _ivaNE.is_zero()); } class TAllegato_info : public TObject { char _tipo; long _codice; TString80 _occas; // Eventuale codice cliente occasionale TAllegato_importi _curr, _prec; public: bool occasionale() const { return _tipo == 'C' && _occas.full(); } char tipo() const { return _tipo; } long codice() const { return _codice; } const TString & occas_code() const { return _occas;} TVariant get(const TString& field) const; void key(TString& str) const; TAllegato_importi& importi(bool prec) { return prec ? _prec : _curr; } const TAllegato_importi& importi(bool prec) const { return prec ? _prec : _curr; } bool is_not_null(bool strict) const { return _curr.is_not_null(strict) || _prec.is_not_null(strict); } void set_codice(long codice, const char* occas) { _codice = codice; _occas = occas; } TAllegato_info(const TRecordset& mov); }; // Legge un campo dal record virtuale del cliente / fornitore TVariant TAllegato_info::get(const TString& field) const { TVariant var; if (field.starts_with("C_") || field.starts_with("P_")) { const bool anno_prec = field[0] == 'P'; const TAllegato_importi& allimp = importi(anno_prec); if (allimp.is_not_null(false)) { const TString& impfield = field.mid(2); real euro; if (impfield == "IMP") euro = allimp._imp; else if (impfield == "IVA") euro = allimp._iva; else if (impfield == "NI") euro = allimp._impNI; else if (impfield == "ES") euro = allimp._impES; else if (impfield == "NE") euro = allimp._ivaNE; else if (impfield == "IND") euro = allimp._ind; else if (impfield == "NA") euro = allimp._impNA; euro.round(0); var = euro; } } else if (field == CLI_TIPOCF) { const char t[2] = { _tipo, '\0' }; var = t; } else if (field == CLI_CODCF) { var = _codice; } else if (field == COM_DENCOM || field == COM_PROVCOM) { TToken_string key; key << get(CLI_STATOCF); const bool italy = key.blank() || key == "IT"; key << '|' << get(CLI_COMCF); var = cache().get(LF_COMUNI, key, field); if (var.is_empty() && italy) // Ritento col CAP per gli Italiani { key = " |"; key << cap2comune(get(CLI_CAPCF).as_string(), get(CLI_LOCCF).as_string()); var = cache().get(LF_COMUNI, key, field); } if (var.is_empty() && field == COM_PROVCOM) { if (!italy || key.get_char(1) == 'Z') var = "EE"; } } else { if (occasionale()) { const TRectype& occas = cache().get(LF_OCCAS, _occas); // Tratto a parte COFI e PAIV degli occasionali if (field == CLI_COFI || field == CLI_PAIV) { // Questi campi sono nel tracciato solo dalla versione 3.1 in poi if (occas.type(field) != _nullfld) var = occas.get(field); /* Troppo astuto per "Sirio il Dragone" // Se non compilato cerco di desumerlo da codice occasionale if (var.is_empty()) { if (field == CLI_COFI) { if (cf_check("", _occas)) var = _occas; } else { if (pi_check("", _occas)) var = _occas; } } */ } else // Tutti gli altri campi a parte COFI e PAIV { // Converto opportunamente il nome del campo da CLIFO ad OCCAS const char* const cli[] = { CLI_RAGSOC, CLI_STATOCF, CLI_COMCF, CLI_STATOPAIV, CLI_INDCF, CLI_CAPCF, CLI_LOCCF, NULL, }; const char* const occ[] = { OCC_RAGSOC, OCC_STATO, OCC_COM, OCC_STATO, OCC_INDIR, OCC_CAP, OCC_LOCALITA, NULL, }; for (int f = 0; cli[f]; f++) { if (field == cli[f]) { var = occas.get(occ[f]); break; } } } } else // Clienti/Fornitori "normali" (non occasionali) { TString16 key; key.format("%c|%ld", _tipo, _codice); const TRectype& clifo = cache().get(LF_CLIFO, key); var = clifo.get(field); } } return var; } void TAllegato_info::key(TString& tmp) const { tmp = get(CLI_PAIV).as_string(); if (tmp.blank()) { tmp = get(CLI_COFI).as_string(); if (tmp.blank()) tmp.cut(0) << _codice; } tmp.insert(_tipo == 'F' ? "F|" : "C|"); } TAllegato_info::TAllegato_info(const TRecordset& mov) : _tipo(mov.get(MOV_TIPO).as_string()[0]), _codice(mov.get(MOV_CODCF).as_int()), _occas(mov.get(MOV_OCFPI).as_string()) { CHECK(_tipo == 'C' || _tipo == 'F', "Tipo C/F errato"); CHECKD(_codice > 0, "Codice C/F errato ", _codice); } /////////////////////////////////////////////////////////// // TAllegati_set /////////////////////////////////////////////////////////// class TAllegati_set : public TAS400_recordset { protected: const TString& comune(const TRectype& clifo, const char* field) const; public: void add(const TAllegato_info& info); TAllegati_set(); }; void TAllegati_set::add(const TAllegato_info& info) { new_rec(); for (unsigned int i = 0; i < columns(); i++) { const TString& field = column_info(i)._name; set(field, info.get(field)); } } TAllegati_set::TAllegati_set() : TAS400_recordset("AS400(512)") { const char* const campi[] = { CLI_TIPOCF, CLI_CODCF, CLI_RAGSOC, CLI_COFI, CLI_PAIV, CLI_INDCF, CLI_CIVCF, CLI_CAPCF, CLI_LOCCF, CLI_COMCF, NULL }; TRectype clifo(LF_CLIFO); for (int i = 0; campi[i]; i++) { const char* f = campi[i]; create_field(f, -1, clifo.length(f), clifo.type(f)); } create_field(COM_DENCOM, -1, 50, _alfafld); create_field(COM_PROVCOM, -1, 2, _alfafld); for (int j = 0; j < 2; j++) { create_field(j ? "P_IMP" : "C_IMP", -1, 16, _longfld); create_field(j ? "P_IVA" : "C_IVA", -1, 16, _longfld); create_field(j ? "P_IND" : "C_IND", -1, 16, _longfld); create_field(j ? "P_NI" : "C_NI", -1, 16, _longfld); create_field(j ? "P_ES" : "C_ES", -1, 16, _longfld); create_field(j ? "P_NE" : "C_NE", -1, 16, _longfld); create_field(j ? "P_NA" : "C_NA", -1, 16, _longfld); } } /////////////////////////////////////////////////////////// // TPadoaSchioppa_set /////////////////////////////////////////////////////////// enum TPs_type { AN, CF, DT, NU, PI, PR }; enum TPs_campi_non_posizionali { npCode = 8, npValue = 16, npSize = 24, npCount = 70 }; class TPadoaSchioppa_set : public TAS400_recordset { void add_field(const int trc, int da, int a, int lung, const char* name, TPs_type ft, bool required = false, const char* def = NULL); void add_trc(int trc); protected: int primo_campo_libero(); // Posizione primo campo libero per record 1 e 2 void init_trc(); // Constructor helper public: long new_rec(int tiporec); // 0, 1, 2, 3, 9, -1 (1 o 2 a seconda del tipo corrente) const TString& curr_row() const { return row(-1); } // Campi posizionali (record 0, 3 e 9) bool set(const char* name, const TVariant& value); bool set(const char* name, const TString& value); bool set(const char* name, const TDate& value); // Campi non posizionali (record 1 e 2) bool set(int fldcode, const TString& val); bool set(int fldcode, long val); bool set(int fldcode, const TVariant& val); TPadoaSchioppa_set(); TPadoaSchioppa_set(const TFilename& name); }; long TPadoaSchioppa_set::new_rec(int tiporec) { if (tiporec < 0) { tiporec = atoi(rec_type()); CHECKD(tiporec == 1 || tiporec == 2, "Tipo record non duplicabile ", tiporec); } CHECKD(tiporec >= 0 && tiporec <= 3 || tiporec == 9, "Tipo record errato ", tiporec); char tr[2] = { '0'+tiporec, '\0' }; return TAS400_recordset::new_rec(tr); } void TPadoaSchioppa_set::add_field(int trc, int da, int a, int lung, const char* name, TPs_type tc, bool required, const char* def) { CHECKS(da > 0 && a >= da, "Posizioni incoerenti sul campo ", name); CHECKS(lung == a-da+1, "Lunghezza incoerente sul campo ", name); TString80 field; field.format("%d.%s", trc, (const char*)name); TFieldtypes ft = _alfafld; switch (tc) { case DT: CHECKS(lung == 8, "Lunghezza incoerente data ", name); ft = _longzerofld; break; case NU: ft = _longfld; break; case CF: CHECKS(lung == 16, "Lunghezza incoerente codice fiscale ", name); ft = _alfafld; break; case PI: CHECKS(lung == 11, "Lunghezza incoerente partita IVA ", name); ft = _longzerofld; break; case PR: CHECKS(lung == 2, "Lunghezza incoerente provincia ", name); ft = _alfafld; break; default: ft = _alfafld; break; } bool ok = false; if (def && *def) ok = create_field(field, da-1, lung, ft, required, TVariant(def)); else ok = create_field(field, da-1, lung, ft, required); CHECKS(ok, "Impossibile creare il campo ", (const char*)field); } void TPadoaSchioppa_set::add_trc(int trc) { TString4 str; str << trc; add_field(trc, 1, 1, 1, "TipoRecord", NU, true, str); switch (trc) { case 0: // Testata case 9: // Coda add_field(trc, 2, 4, 3, "IdentificativoFornitura" , AN, true, "ECF"); add_field(trc, 5, 6, 2, "IdentificativoAnno" , AN, true, "00"); add_field(trc, 7, 8, 2, "CodiceFornitura" , NU, true, "38"); add_field(trc, 9, 24, 16, "CodiceFiscale" , CF, true); add_field(trc, 25, 35, 11, "PartitaIVA" , PI, true); add_field(trc, 36, 61, 26, "Cognome" , AN); // Persone fisiche add_field(trc, 62, 86, 25, "Nome" , AN); add_field(trc, 87, 87, 1, "Sesso" , AN); add_field(trc, 88, 95, 8, "DataNascita" , DT); add_field(trc, 96, 135, 40, "ComuneNascita" , AN); add_field(trc, 136, 137, 2, "ProvinciaNascita" , PR); add_field(trc, 138, 207, 70, "Denominazione" , AN); // Persone NON fisiche add_field(trc, 208, 247, 40, "ComuneSedeLegale" , AN); add_field(trc, 248, 249, 2, "ProvinciaSedeLegale" , AN); add_field(trc, 250, 265, 16, "CodiceSoggettoObbligato" , CF); add_field(trc, 266, 269, 4, "AnnoRiferimento" , NU, true); add_field(trc, 270, 273, 4, "ProgressivoTelematico" , NU); add_field(trc, 274, 277, 4, "NumeroTotaleInvii" , NU); add_field(trc, 278, 293, 16, "CodiceIntermediario" , CF); add_field(trc, 294, 298, 5, "NumeroIscrizioneAlboCAF" , NU); add_field(trc, 299, 299, 1, "ImpegnoAllaTrasmissione" , NU); add_field(trc, 300, 307, 8, "DataImpegno" , DT); break; case 1: // Clienti case 2: // Fornitori // NESSUN CAMPO POSIZIONALE! break; case 3: add_field(trc, 2, 9, 8, "Clienti" , NU); // 2 add_field(trc, 10, 17, 8, "Fornitori" , NU); add_field(trc, 18, 37, 20, "CL004001" , NU); // 4 add_field(trc, 38, 57, 20, "CL004002" , NU); add_field(trc, 58, 77, 20, "CL005001" , NU); add_field(trc, 78, 97, 20, "CL006001" , NU); add_field(trc, 98, 117, 20, "CL007001" , NU); add_field(trc, 118, 137, 20, "CL008001" , NU); // 9 add_field(trc, 138, 157, 20, "CL008002" , NU); add_field(trc, 158, 177, 20, "CL009001" , NU); add_field(trc, 178, 197, 20, "CL010001" , NU); add_field(trc, 198, 217, 20, "CL011001" , NU); // 13 add_field(trc, 218, 237, 20, "FR004001" , NU); // 14 add_field(trc, 238, 257, 20, "FR004002" , NU); add_field(trc, 258, 277, 20, "FR005001" , NU); add_field(trc, 278, 297, 20, "FR006001" , NU); add_field(trc, 298, 317, 20, "FR007001" , NU); add_field(trc, 318, 337, 20, "FR008001" , NU); add_field(trc, 338, 357, 20, "FR009001" , NU); // 20 add_field(trc, 358, 377, 20, "FR009002" , NU); add_field(trc, 378, 397, 20, "FR010001" , NU); add_field(trc, 398, 417, 20, "FR011001" , NU); add_field(trc, 418, 437, 20, "FR012001" , NU); add_field(trc, 438, 457, 20, "FR013001" , NU); // 25 break; default: CHECKD(false, "Tipo record non valido ", trc); break; } add_field(trc,1798,1798, 1, "CarattereControllo" , AN, true, "A"); add_field(trc,1799,1800, 2, "FineRiga" , AN, true, "\r\n"); // 0D 0A } int TPadoaSchioppa_set::primo_campo_libero() { const TToken_string& curr = row(-1); // Record corrente int i = 0, pos = 1; for (i = 0; i < npCount; i++, pos += npSize) // Scandice i 70 campi non posizionali { // if (curr.mid(pos, fld_size).blank()) if (curr[pos] == ' ' && curr[pos+npSize-1] == ' ') // Campo vuoto! break; } if (i >= npCount) // Non c'e' piu' posto! { new_rec(-1); // Creo un nuovo record del tipo corrente (1 o 2) pos = 1; // Vado a colpo "sicuro" } return pos; } bool TPadoaSchioppa_set::set(const char* name, const TVariant& value) { bool ok = false; const int tiporec = atoi(rec_type()); if (tiporec == 1 || tiporec == 2) // Gestione campi non posizionali { CHECKS(name!=NULL && strlen(name) == npCode, "Lunghezza nome campo non posizionale errata ", name); CHECKS((tiporec==1 && *name=='C') || (tiporec==2 && *name=='F'), "Campo non posizionale incompatibile col tipo record (1/2=C/F) ", name); const long codice = atol(name+2); CHECKS(codice >= 1001 && codice <= 13001, "Campo non posizionale errato ", name); if (value.is_empty()) { ok = codice > 4000; CHECKS(ok, "Campo obbligatorio non specificato ", name); return ok; } const int pos = primo_campo_libero(); TString80 str = name; if (codice < 4000) // Campi alfanumerici (1001,2001,3001) allineati a sinistra { str << value.as_string(); str.rpad(npSize); } else { // Importi interi allineati a destra real r = value.as_real(); r.round(0); // Inutile in quanto gia' arrotondato all'origine: ma non si sa mai str << r.string(npValue, 0); } CHECKS(str.len() == npSize, "Lunghezza campo non posizionale codice(8)+valore(16) <> 24 ", (const char*)str); row(-1).overwrite(str, pos, npSize); ok = true; } else { // Gestisco le date solo nei record 0,3,9 if (value.is_date() && !value.is_empty()) { const TDate date = value.as_date(); TString8 str; str.format("%02d%02d%04d", date.day(), date.month(), date.year()); ok = TAS400_recordset::set(name, TVariant(str)); } else { if (value.is_string()) { TString80 str = value.as_string(); str.upper(); ok = TAS400_recordset::set(name, TVariant(str)); } else ok = TAS400_recordset::set(name, value); } CHECKS(ok, "Campo non valido ", name); } return ok; } bool TPadoaSchioppa_set::set(const char* name, const TString& value) { return set(name, value.full() ? TVariant(value) : NULL_VARIANT); } bool TPadoaSchioppa_set::set(const char* name, const TDate& value) { return set(name, value.ok() ? TVariant(value) : NULL_VARIANT); } // Usata per 1001, 2001 e 3001 bool TPadoaSchioppa_set::set(int fldcode, const TString& val) { CHECKD(fldcode >= 1001 && fldcode <= 3001, "Codice campo non valido ", fldcode); CHECKD(val.full(), "Campo non posizionale vuoto ", fldcode); const int tiporec = atoi(rec_type()); TString8 field; field.format("%2s%06d", tiporec == 1 ? "CL" : "FR", fldcode); return set(field, val); } // Usata solo per 1001 bool TPadoaSchioppa_set::set(int fldcode, long val) { CHECKD(fldcode == 1001, "Codice campo non valido ", fldcode); CHECKD(val > 0, "Campo non posizionale vuoto ", fldcode); TString16 value; value.format("%16ld", val); return set(fldcode, value); } // Usata dal 4001 in poi bool TPadoaSchioppa_set::set(int fldcode, const TVariant& val) { CHECKD(fldcode >= 4001 && fldcode <= 13001, "Codice campo non valido ", fldcode); if (val.is_zero()) return true; const int tiporec = atoi(rec_type()); TString8 field; field.format("%2s%06d", tiporec == 1 ? "CL" : "FR", fldcode); return set(field, val); } void TPadoaSchioppa_set::init_trc() { add_trc(0); add_trc(1); add_trc(2); add_trc(3); add_trc(9); } TPadoaSchioppa_set::TPadoaSchioppa_set() : TAS400_recordset("AS400(1800,1)") { init_trc(); } TPadoaSchioppa_set::TPadoaSchioppa_set(const TFilename& name) : TAS400_recordset("AS400(1800,1)") { init_trc(); load_file(name); } /////////////////////////////////////////////////////////// // TCodiva_cache /////////////////////////////////////////////////////////// class TCodiva_cache : public TCache { protected: virtual TObject* key2obj(const char* key); public: const TCodiceIVA& codiva(const char* codice); }; TObject* TCodiva_cache::key2obj(const char* key) { return new TCodiceIVA(key); } const TCodiceIVA& TCodiva_cache::codiva(const char* codice) { return *(TCodiceIVA*)objptr(codice); } /////////////////////////////////////////////////////////// // TCusali_cache /////////////////////////////////////////////////////////// class TCausali_cache : public TCache { protected: virtual TObject* key2obj(const char* key); public: const TCausale& causale(const char* codice, int annoiva); }; TObject* TCausali_cache::key2obj(const char* key) { // Metodo bastardo per evitare TToken_string temporanee "a randa" // sfrutto chiave a lunghezza fissa const int anno = atoi(key); const char* codice = key+5; TCausale* pcaus = new TCausale(codice, anno); return pcaus; } const TCausale& TCausali_cache::causale(const char* codice, int annoiva) { // Metodo bastardo per evitare TToken_string temporanee "a randa" // creo chiave a lunghezza fissa anno+codice = 9999|AAA TString8 key; key.format("%04d|%s", annoiva, codice); return *(const TCausale*)objptr(key); } /////////////////////////////////////////////////////////// // TAlleg_report /////////////////////////////////////////////////////////// class TAlleg_report : public TReport { TAssoc_array _vars; protected: virtual bool use_mask() { return false; } virtual bool set_usr_val(const TString& name, const TVariant& var); virtual bool get_usr_val(const TString& name, TVariant& var) const; public: TAlleg_report(TRecordset* rs, const TMask& am, bool hide_not_alleg = false); }; bool TAlleg_report::set_usr_val(const TString& name, const TVariant& var) { if (!TReport::set_usr_val(name, var)) _vars.add(name, new TVariant(var)); return true; } bool TAlleg_report::get_usr_val(const TString& name, TVariant& var) const { if (name[0] == '#') { TVariant* v = (TVariant*)_vars.objptr(name); if (v != NULL) { var = *v; return true; } } return TReport::get_usr_val(name, var); } TAlleg_report::TAlleg_report(TRecordset* rs, const TMask& am, bool hide_not_alleg) { load("cg3900a"); mask2report(am); TString4 filtro; if (!hide_not_alleg) filtro = am.get(F_FILTRO); set_usr_val("#FILTRO", TVariant(filtro)); if (hide_not_alleg) { const char* const fields[] = { "H0.107", "B1.107", "B1.207", "F1.107", "F1.207", NULL }; for (int i = 0; fields[i]; i++) { TReport_field* rf = field(fields[i]); if (rf != NULL) rf->deactivate(); } } set_recordset(rs); } /////////////////////////////////////////////////////////// // TAlleg_log /////////////////////////////////////////////////////////// class TAlleg_log : public TLog_report { bool _red_alert; public: virtual bool log(int severity, const char* msg); bool red_alert() const { return _red_alert; } TAlleg_log() : TLog_report(TR("Errori riscontrati")), _red_alert(false) {} }; bool TAlleg_log::log(int severity, const char* msg) { if (severity > 0) _red_alert = true; return TLog_report::log(severity, msg); } /////////////////////////////////////////////////////////// // TAlleg_mask /////////////////////////////////////////////////////////// class TAlleg_mask : public TAutomask { TCodiva_cache _codiva; TCausali_cache _causali; protected: // TAutomask virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual void on_firm_change(); protected: // Elaborazione const TRectype& contribuente() const; bool documento_corrispettivi(const TString& tipodoc) const; int imp_iva(char tipocf, bool non_esposti, const TRecordset& riga, real& imp, real& iva); real indetraibile_al(const TRecordset& riga, bool prorata100) const; bool scan_iva_rows(const TRecordset& mov, TAssoc_array& clifi, bool invio, bool ministeriale); TRecordset* new_recordset(char tipocf = ' ', bool strict = false); void log_error(const char* ragsoc, const char* msg1, const char* msg2, TAlleg_log& errlog, int severity = 2); void log_error(const TRecordset& clifo, const char* msg1, const char* msg2, TAlleg_log& errlog, int severity = 2); void copia_importo(const TRecordset& clifo, const char* fldname, TPadoaSchioppa_set& pss, int fldcode) const; protected: // Generazione bool build_output_name(TFilename& fname) const; void add_0_9(int trc, TPadoaSchioppa_set& pss, TAlleg_log& log); void add_1_2(int trc, TRecordset& clifo, TPadoaSchioppa_set& pss, TAlleg_log& log); void add_3(TPadoaSchioppa_set& pss); bool show_errors(TAlleg_log& log) const; void generazione(); protected: // Fusione bool test_file(const TFilename& name, TString& error) const; void import_clifo(const TFilename& name, TAssoc_array& clips, TAssoc_array& forps, TAlleg_log& log); TRecnotype export_clifo(int tiporec, TAssoc_array& clifo, TAllegati_set& all, TPadoaSchioppa_set& pss); void fusione(); public: TAlleg_mask(); ~TAlleg_mask(); }; bool TAlleg_mask::documento_corrispettivi(const TString& tipodoc) const { const TRectype& tpd = cache().get("%TPD", tipodoc); bool corrisp = tpd.get_bool("B0"); if (corrisp) { const int natura_doc = tpd.get_int("I0"); corrisp = natura_doc == 1 || natura_doc == 9; } return corrisp; } int TAlleg_mask::imp_iva(char tipocf, bool non_esposti, const TRecordset& riga, real& imp, real& iva) { // Estraggo imponibile ed imposta dalla riga IVA ed // inizialmente fingo che non ci sia una parte indetraibile imp = riga.get(RMI_IMPONIBILE).as_real(); iva = riga.get(RMI_IMPOSTA).as_real(); int allegato = 0; if (non_esposti) { allegato = 4; } else { const TString& codice = riga.get(RMI_CODIVA).as_string(); const TCodiceIVA& codiva = _codiva.codiva(codice); allegato = codiva.allegato(tipocf); if (allegato == 5 && get_int(F_ANNO) >= 2008) // FR005001 non esiste piu' nel 2008 allegato = 1; } if (allegato != 1 && !iva.is_zero()) // Succede col Reverse Charge { imp += iva; iva = ZERO; } return allegato; } bool TAlleg_mask::scan_iva_rows(const TRecordset& mov, TAssoc_array& clifi, bool invio, bool ministeriale) { // Informazioni base sul cliente in testata: vengono ignorati gli importi const TAllegato_info clifo(mov); const int tipalleg = clifo.get(CLI_ALLEG).as_int(); if (invio) { // Ignoro da subito chi non va in allegato if (tipalleg != 0 && tipalleg != 4) return false; // Gli occasionali meritano solo di essere ignorati if (clifo.occasionale()) return false; const TVariant stato = clifo.get(CLI_STATOPAIV); if (!stato.is_empty() && stato.as_string() != "IT") // Scarto gli esteri return false; } else { // Per efficienza andrebbe nella funzione chiamante const int filtro = get_int(F_FILTRO); if (filtro >= 0 && tipalleg != filtro) return false; } TString80 clifo_key; clifo.key(clifo_key); TAllegato_info* ai = (TAllegato_info*)clifi.objptr(clifo_key); if (ai == NULL) { ai = new TAllegato_info(mov); clifi.add(clifo_key, ai); } else { // Se questa partita IVA esiste gia' deve prevalere la ragione sociale con tipalleg=0 if (tipalleg == 0) { const long codcf = clifo.codice(); // Codice corrente const long old_codcf = ai->codice(); // Codice su fornitura if (codcf != old_codcf) ai->set_codice(codcf, clifo.occas_code()); } } const TDate datareg = mov.get(MOV_DATAREG).as_date(); const TDate datadoc = mov.get(MOV_DATADOC).as_date(); const int anno = get_int(F_ANNO); const int annoiva = datareg.year(); const TString& codcaus = mov.get(MOV_CODCAUS).as_string(); const TCausale& caus = _causali.causale(codcaus, annoiva); const bool vendite = clifo.tipo() == 'C'; const bool movintra = caus.intra(); const int reg_spec = caus.regime_speciale(); const bool reverse_charge = (reg_spec == 13) || (reg_spec == 50) || (reg_spec == 51); const bool non_esposti = vendite && (movintra || reverse_charge); const bool prorata100 = caus.reg().prorata100(annoiva); TISAM_recordset righe_iva("USE RMOVIVA\nFROM NUMREG=#NR\nTO NUMREG=#NR"); righe_iva.set_var("#NR", mov.get(MOV_NUMREG)); real imponibile, imposta, indecifrabile; for (bool ok = righe_iva.move_first(); ok; ok = righe_iva.move_next()) { bool anno_prec = false; if (ministeriale) anno_prec = righe_iva.get(RMI_NAVP).as_bool(); else anno_prec = datadoc.year() == anno-1; // Serve per quadrature TAllegato_importi& allimp = ai->importi(anno_prec); const int allegato = imp_iva(clifo.tipo(), non_esposti, righe_iva, imponibile, imposta); switch (allegato) { case 1: allimp._imp += imponibile; allimp._iva += imposta; break; case 2: allimp._impNI += imponibile; break; case 3: allimp._impES += imponibile; break; case 4: allimp._ivaNE += imponibile; break; // Importi con IVA non esposta case 5: allimp._ind += imponibile; break; // Importi INDecifrabili default: allimp._impNA += imponibile; break; // same as case 0 } } return true; } // algo: R=data Registrazione; D=data Documento TRecordset* TAlleg_mask::new_recordset(char tipocf, bool invio) { const bool ministeriale = get(F_ALGO) == "D"; // Compito: tradurre in ISAM la seguente query: // SELECT * FROM MOV // WHERE TIPO=#TYPE AND ANNOIVA=#ANNO // ORDER BY TIPO,CODCF; TString query = "USE MOV KEY 3"; // La chiave 3 e' TIPO+CODCF+DATAREG+NUMREG query << "\nSELECT "; if (ministeriale) query << "(ANNOIVA>=#ANNO)"; // Seleziona dall'anno desiderato in poi else query << "(ANNOIVA==#ANNO)"; // Seleziona solo l'anno desiderato query << "\nFROM TIPO=#TYPE CODCF=1"; // Salta tutti movimenti senza CODCF query << "\nTO TIPO=#TYPE"; // Inutile dire CODCF=999999 TISAM_recordset mov(query); if (tipocf <= ' ') tipocf = get(F_TIPO)[0]; const char tipo[2] = { tipocf, '\0' }; const int anno = get_int(F_ANNO); mov.set_var("#ANNO", TVariant(long(anno))); mov.set_var("#TYPE", TVariant(tipo)); const TRecnotype movs = mov.items(); TString msg; msg << TR("Elaborazione") << ' ' << movs << ' ' << TR("Movimenti") << ' ' << (tipocf == 'C' ? TR("Clienti") : TR("Fornitori")); TProgind pi(movs, msg, true, true); TAssoc_array clifi; for (bool ok = mov.move_first(); ok; ok = mov.move_next()) { if (!pi.addstatus(1)) break; const int annoiva = mov.get(MOV_ANNOIVA).as_int(); const TString& codcaus = mov.get(MOV_CODCAUS).as_string(); const TCausale& caus = _causali.causale(codcaus, annoiva); if (caus.esclusione_allegati()) // Controllo il flag di esclusione dagli allegati continue; // Scarta trasferimento movimenti intra prima del 2008 if (invio && anno < 2008 && caus.intra()) continue; // Controllo inutilmente anche il tipo documento const TString& tipodoc = caus.tipodoc(); if (documento_corrispettivi(tipodoc)) continue; // Controllo se registro e' compatibile const TRegistro& reg = caus.reg(); if (reg.corrispettivi()) continue; const TipoIVA tipoiva = reg.iva(); bool keep = tipoiva == iva_vendite || tipoiva == iva_acquisti; // Voglio solo registri IVA if (keep) keep = (tipocf == 'C') ^ (tipoiva == iva_acquisti); // compatibile if (keep && ministeriale) { const int annodoc = mov.get(MOV_DATADOC).as_date().year(); const bool is_nota = (tipodoc=="NC") || (tipodoc=="ND"); keep = (annodoc == anno) ; // || (is_nota && (annodoc == anno-1)); } if (!keep) continue; scan_iva_rows(mov, clifi, invio, ministeriale); } TAllegati_set* hullygully = new TAllegati_set; FOR_EACH_ASSOC_OBJECT(clifi, h, k, o) { const TAllegato_info& ai = *(TAllegato_info*)o; if (ai.is_not_null(invio)) hullygully->add(ai); } hullygully->sort(); return hullygully; } const TRectype& TAlleg_mask::contribuente() const { const char tipoa = prefix().firm().get(NDT_TIPOA)[0]; const long codanagr = prefix().firm().get_long(NDT_CODANAGR); TToken_string key; key.add(tipoa, 0); key.add(codanagr, 1); const TRectype& anag = cache().get(LF_ANAG, key); return anag; } void TAlleg_mask::add_0_9(int trc, TPadoaSchioppa_set& pss, TAlleg_log& log) { pss.new_rec(trc); const TRectype& anag = contribuente(); const char tipoa = anag.get_char(ANA_TIPOA); const long codanagr = anag.get_long(ANA_CODANAGR); const TString ragsoc = anag.get(ANA_RAGSOC); // Non fidarsi ad usare TString& TString16 pariva = anag.get(ANA_PAIV); pariva.right_just(11, '0'); if (!pi_check("", pariva)) log_error(ragsoc, TR("*** Ditta con partita IVA errata"), pariva, log, 2); else { if (pariva[0] == '8' || pariva[0] == '9') log_error(ragsoc, TR("* Verificare esenzione dall'invio degli elenchi"), pariva, log, 2); } const TString16 codfis = anag.get(ANA_COFI); if (!cf_check("", codfis)) log_error(ragsoc, TR("** Ditta con codice fiscale errato"), codfis, log, 2); pss.set("CodiceFiscale", codfis.full() ? codfis : pariva); pss.set("PartitaIVA", pariva.full() ? pariva : codfis); if (tipoa == 'F') { pss.set("Cognome", ragsoc.left(30)); pss.set("Nome", ragsoc.mid(30)); const TRectype& anafis = cache().get(LF_ANAGFIS, codanagr); pss.set("Sesso", anafis.get(ANF_SESSO)); pss.set("DataNascita", anafis.get_date(ANF_DATANASC)); const TString4 stato = anafis.get(ANF_STATONASC); const TString4 comun = anafis.get(ANF_COMNASC); TString8 key; key << stato << '|' << comun; const TRectype& comnas = cache().get(LF_COMUNI, key); pss.set("ComuneNascita", comnas.get(COM_DENCOM)); if (stato.full() || comun[0] >= 'Z') // Nato all'estero pss.set("ProvinciaNascita", TVariant("EE")); else pss.set("ProvinciaNascita", comnas.get(COM_PROVCOM)); } else { const TString4 stato = anag.get(ANA_STATORES); const TString4 comun = anag.get(ANA_COMRES); TString8 key; key << stato << '|' << comun; const TRectype& comres = cache().get(LF_COMUNI, key); pss.set("Denominazione", ragsoc); pss.set("ComuneSedeLegale", comres.get(COM_DENCOM)); pss.set("ProvinciaSedeLegale", comres.get(COM_PROVCOM)); } const long anno = get_int(F_ANNO); pss.set("AnnoRiferimento", TVariant(anno)); // 2006, 2007, 2008, ... // Compilare solo se diverso da dichiarante pss.set("CodiceSoggettoObbligato", get(F_SOGG)); // Dati dell'intermediario che si cucca 50 Euro senza fare una mazza! const TString& inter = get(F_INTR); if (inter.full() && codfis != inter) { pss.set("CodiceIntermediario" , inter); pss.set("NumeroIscrizioneAlboCAF", get(F_CAF)); pss.set("ImpegnoAllaTrasmissione", get(F_COMP)); pss.set("DataImpegno", get_date(F_DATA)); } } void TAlleg_mask::add_3(TPadoaSchioppa_set& pss) { long num_cli = 0; long num_for = 0; TAssoc_array totali; TString8 code; for (bool ok = pss.move_first(); ok; ok = pss.move_next()) { const int tipo = atoi(pss.rec_type()); if (tipo == 1 || tipo == 2) { const TString& curr = pss.curr_row(); int pos = 1; // Scansione dei 70 campi non posizionali for (int i = 0; i < npCount; i++, pos += npSize) { code = curr.mid(pos, npCode); // Codice campo if (code.blank()) // Campo nullo = Fine record, "certamente" ultimo di questo tipo break; const int subcode = atoi(code.mid(2)); // CL004001 -> 4001 if (subcode == 1001) // Numero progressivo ... { if (tipo == 1) // ... cliente num_cli++; else num_for++; // ... fornitore } else if (subcode >= 4001 && subcode <= 13001) // Cosidera solo gli importi { real* tot = (real*)totali.objptr(code); if (tot == NULL) { tot = new real; totali.add(code, tot); } const real val(curr.mid(pos+npCode, npValue)); // Importo sicuramente NON nullo *tot += val; } } } } pss.new_rec(3); pss.set("Clienti", TVariant(num_cli)); pss.set("Fornitori", TVariant(num_for)); FOR_EACH_ASSOC_OBJECT(totali, hash, key, v) { const real& val = *(real*)v; pss.set(key, val); } } void TAlleg_mask::copia_importo(const TRecordset& clifo, const char* fldname, TPadoaSchioppa_set& pss, int fldcode) const { const TVariant& val = clifo.get(fldname); if (!val.is_zero()) { CHECKS(!val.is_string(), "Campo importo di tipo errato", fldname); pss.set(fldcode, val); } } void TAlleg_mask::log_error(const char* ragsoc, const char* msg1, const char* msg2, TAlleg_log& errlog, int severity) { TString str; str << ragsoc << " - " << msg1; if (msg2 && *msg2) str << " : " << msg2; errlog.log(severity, str); } void TAlleg_mask::log_error(const TRecordset& clifo, const char* msg1, const char* msg2, TAlleg_log& errlog, int severity) { TString str; str << clifo.get("#RECORD.NUMBER") << ". " << clifo.get(CLI_TIPOCF) << clifo.get(CLI_CODCF) << ' ' << clifo.get(CLI_RAGSOC); str.strip_double_spaces(); log_error(str, msg1, msg2, errlog, severity); } void TAlleg_mask::add_1_2(int trc, TRecordset& clifo, TPadoaSchioppa_set& pss, TAlleg_log& log) { const int anno = get_int(F_ANNO); const bool coffee = get_bool(F_COFI); // Codice fiscale voluto o obbligatorio long np = 0; // Prossimo numero progressivo clifo for (bool ok = clifo.move_first(); ok; ok = clifo.move_next()) { if (np == 0) // Se sto per scrivere il primo elemento ... pss.new_rec(trc); // ... creo un nuovo record per accoglierlo pss.set(1001, ++np); // Incremento il numero progressivo // Gestione automagica del codice fiscale e della partita IVA TString16 paiv = clifo.get(CLI_PAIV).as_string(); paiv.trim(); if (paiv.full() && real::is_natural(paiv)) paiv.right_just(11, '0'); TString16 cofi = clifo.get(CLI_COFI).as_string(); cofi.trim(); /* Troppo astuto per "Sirio il Dragone" // Se il codice fiscale e' vuoto prendo la partita IVA numerica if (cofi.blank() && pi_check("", paiv)) cofi = paiv; // Se la partita IVA e' vuota ed il codice fiscale e' numerico ... if (paiv.blank() && pi_check("", cofi)) paiv = cofi; // ... allora copia nella partita IVA il codice fiscale */ // Voglio o devo salvare il codice fiscale del tizio if (coffee) { if (cofi.blank()) { log_error(clifo, TR("* Codice fiscale mancante"), cofi, log, 2); } else { if (!real::is_natural(cofi) && !cf_check("", cofi)) log_error(clifo, TR("** Codice fiscale errato"), cofi, log, 1); pss.set(2001, cofi); // Codice fiscale (obbligatorio dal 2008) } } if (real::is_null(paiv)) { if (anno < 2008 || cofi.blank()) log_error(clifo, TR("** Partita IVA mancante"), NULL, log, 2); } else { if (!pi_check("", paiv)) log_error(clifo, TR("** Partita IVA errata"), paiv, log, 1); else { if (paiv[0] == '8' || paiv[0] == '9') log_error(clifo, TR("* Verificare esclusione della Partita IVA"), paiv, log, 1); } pss.set(3001, paiv); // Partita IVA (obbligatoria dal 2006) } if (trc == 1) // Clienti { // Importi anno corrente copia_importo(clifo, "C_IMP", pss, 4001); copia_importo(clifo, "C_IVA", pss, 4002); copia_importo(clifo, "C_NI" , pss, 5001); copia_importo(clifo, "C_ES" , pss, 6001); copia_importo(clifo, "C_NE" , pss, 7001); // Importi anno precedente copia_importo(clifo, "P_IMP", pss, 8001); copia_importo(clifo, "P_IVA", pss, 8002); copia_importo(clifo, "P_NI" , pss, 9001); copia_importo(clifo, "P_ES" , pss,10001); copia_importo(clifo, "P_NE" , pss,11001); } else // Fornitori { // Importi anno corrente copia_importo(clifo, "C_IMP", pss, 4001); copia_importo(clifo, "C_IVA", pss, 4002); copia_importo(clifo, "C_IND", pss, 5001); // Indecifrabile copia_importo(clifo, "C_NI" , pss, 6001); copia_importo(clifo, "C_ES" , pss, 7001); copia_importo(clifo, "C_NE" , pss, 8001); // Importi anno precedente copia_importo(clifo, "P_IMP", pss, 9001); copia_importo(clifo, "P_IVA", pss, 9002); copia_importo(clifo, "P_IND", pss,10001); copia_importo(clifo, "P_NI" , pss,11001); copia_importo(clifo, "P_ES" , pss,12001); copia_importo(clifo, "P_NE" , pss,13001); } } } bool TAlleg_mask::show_errors(TAlleg_log& log) const { if (yesno_box(TR("Sono stati rilevati errori sulla fornitura:\nSi desidera visualizzarli?"))) { TReport_book errbuc; errbuc.add(log); errbuc.preview(); } return yesno_box(TR("Si desidera generare ugualmente la fornitura?")); } // Pulisce e normalizza un nome di file static bool normalize_name(TFilename& name) { name.trim(); if (name.not_empty()) { name.lower(); name.replace('\\', '/'); } return name.not_empty(); } // Estrae un nome di file pulito da una riga di spreadsheet static bool row2name(const TToken_string& row, TFilename& name) { row.get(0, name); return normalize_name(name); } bool TAlleg_mask::build_output_name(TFilename& fname) const { fname = get(F_DIR); fname.add(get(F_NAME)); return normalize_name(fname); } void TAlleg_mask::generazione() { TPadoaSchioppa_set pss; TAlleg_log log; add_0_9(0, pss, log); // Testa TRecordset* cli = new_recordset('C', true); if (cli != NULL && cli->items()) { log.log(0, TR("CLIENTI")); add_1_2(1, *cli, pss, log); // Clienti } TRecordset* acq = new_recordset('F', true); if (acq != NULL && acq->items() > 0) { log.log(0, TR("FORNITORI")); add_1_2(2, *acq, pss, log); // Fornitori } add_3(pss); // Totali Clienti e Fornitori add_0_9(9, pss, log); // Piede (= Testa) bool go_on = true; if (log.red_alert()) go_on = show_errors(log); if (go_on) { TFilename fname; if (build_output_name(fname)) pss.save_as(fname); TReport_book book; TAlleg_report clirep(cli, *this, true); book.add(clirep); TAlleg_report acqrep(acq, *this, true); book.add(acqrep); book.preview(); } else { delete cli; delete acq; } } void TAlleg_mask::import_clifo(const TFilename& name, TAssoc_array& clips, TAssoc_array& forps, TAlleg_log& log) { TString error; if (test_file(name, error)) { TPadoaSchioppa_set inps(name); TProgind pi(inps.items(), name, true, true); TAssoc_array* cur_clifo = NULL; for (bool ok = inps.move_first(); ok; ok = inps.move_next()) { if (!pi.addstatus(1)) break; const int trc = inps.rec_type()[0]-'0'; if (trc == 1 || trc == 2) { TAssoc_array& clifo = trc == 1 ? clips : forps; int i = 0, pos = 1; const TString& rec = inps.curr_row(); for (i = 0; i < npCount; i++, pos += npSize) // Scandisce i 70 campi non posizionali { const TString& fld = rec.mid(pos, npSize); const TString8 code = fld.mid(2,6); const int ncode = atoi(code); if (ncode > 1000) { switch (ncode) { case 1001: // Inizia una nuova anagrafica cur_clifo = NULL; break; case 3001: // Ho trovato la Partita IVA della nuova anagrafica if (cur_clifo == NULL) { // Cerco l'anagrafica corrispondente alla Partita IVA const TString16 piva = fld.mid(8); cur_clifo = (TAssoc_array*)clifo.objptr(piva); if (cur_clifo == NULL) // Se non la trovo ... { cur_clifo = new TAssoc_array; // ... allora la creo nuova clifo.add(piva, cur_clifo); } } else log.log(2, "Dati inconsistenti"); break; default : if (cur_clifo != NULL) { if (ncode > 4000) // Importi { const real imp = fld.mid(8); const TVariant value(imp); // Impossibile fondere con riga precedente :-? TVariant* tot = (TVariant*)cur_clifo->objptr(code); if (tot != NULL) tot->add(value); // Incremento importo precedente else cur_clifo->add(code, value); // Creo nuovo importo } else // Non importi: praticamente solo Codice Fiscale { const TVariant value(fld.mid(8)); cur_clifo->add(code, value); } } else log.log(2, "Dati inconsistenti"); break; } } else break; } } } } else { error.replace('\n', ' '); log.log(1, error); } } TRecnotype TAlleg_mask::export_clifo(int tiporec, TAssoc_array& clifo, TAllegati_set& all, TPadoaSchioppa_set& pss) { TRecnotype count = 0; if (!clifo.empty()) { pss.new_rec(tiporec); FOR_EACH_ASSOC_OBJECT(clifo, cash, ckey, cobj) { const TVariant piva = ckey; pss.set(1001, ++count); pss.set(3001, piva.as_string()); all.new_rec(); all.set(CLI_TIPOCF, tiporec == 1 ? "C" : "F"); all.set(CLI_CODCF, count); all.set(CLI_PAIV, piva); TString80 str = tiporec == 1 ? TR("Cliente") : TR("Fornitore"); str << ' ' << count; all.set(CLI_RAGSOC, (const char*)str); TAssoc_array& data = *(TAssoc_array*)cobj; FOR_EACH_ASSOC_OBJECT(data, dash, dkey, dobj) { const int code = atoi(dkey); const TVariant& var = *(TVariant*)dobj; if (code > 4000) { pss.set(code, var); if (tiporec == 1) // Clienti { switch (code) { case 4001: all.set("C_IMP", var); break; case 4002: all.set("C_IVA", var); break; case 5001: all.set("C_NI", var); break; case 6001: all.set("C_ES", var); break; case 7001: all.set("C_NE", var); break; default : break; } } else // Fornitori { switch (code) { case 4001: all.set("C_IMP", var); break; case 4002: all.set("C_IVA", var); break; case 5001: all.set("C_IND", var); break; case 6001: all.set("C_NI", var); break; case 7001: all.set("C_ES", var); break; case 8001: all.set("C_NE", var); break; default : break; } } } else { if (code != 1001 && code != 3001) // Gia' scritti da prima pss.set(code, var.as_string()); } } } } return count; } void TAlleg_mask::fusione() { TPadoaSchioppa_set pss; TAlleg_log log; add_0_9(0, pss, log); // Testa TAssoc_array clips, forps; TSheet_field& sheet = sfield(F_FUSION); TFilename name; FOR_EACH_SHEET_ROW(sheet, r, row) if (row2name(*row, name)) { TString error; if (test_file(name, error)) import_clifo(name, clips, forps, log); else log.log(1, error); } TAllegati_set* all = new TAllegati_set; export_clifo(1, clips, *all, pss); // Clienti export_clifo(2, forps, *all, pss); // Fornitori add_3(pss); // Totali Clienti e Fornitori add_0_9(9, pss, log); // Piede (= Testa) bool go_on = all->items() > 0; if (log.red_alert()) go_on = show_errors(log); if (go_on) { TFilename fname; if (build_output_name(fname)) pss.save_as(fname); TReport_book book; TAlleg_report rep(all, *this, true); book.add(rep); book.preview(); } else delete all; } bool TAlleg_mask::test_file(const TFilename& name, TString& error) const { TToken_string errors(80, ';'); error.cut(0); if (!name.exist()) errors = TR("non e' accessibile o inesistente"); else { const TFixed_string ecf_ext("ecf"); if (ecf_ext.compare(name.ext(), true) != 0) errors.add(TR("non ha un'estensione valida (ECF)")); TFilename outname; build_output_name(outname); if (name == outname) errors.add(TR("ha lo stesso nome del file totale")); const long sz = fsize(name); if (sz % 1800) errors.add(TR("non ha una dimensione valida (multipla di 1800)")); ifstream ecf_file(name); TString4 head; head.spaces(); ecf_file.read(head.get_buffer(), head.size()); if (!head.starts_with("0ECF")) errors.add(TR("non ha un record di testata valido (0ECF)")); } if (errors.full()) { error << '\'' << name << "' " << TR("non e' una fornitura valida") << ":\n" << errors; } return errors.empty(); } bool TAlleg_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_ANNO: if (e == fe_init || e == fe_modify) { int anno = atoi(o.get()); if (anno < 2006) { const TDate oggi(TODAY); anno = oggi.year()-1; set(F_ANNO, anno); } if (anno >= 2008) { set(F_COFI, "X"); disable(F_COFI); } else enable(F_COFI); } break; case F_DIR: if (e == fe_init || e == fe_modify) { if (o.empty()) { TFilename fdir; fdir.tempdir(); o.set(fdir); } } break; case F_NAME: if (e == fe_init || e == fe_modify) { if (e == fe_init || o.empty()) { const TRectype& anag = contribuente(); TFilename ecf = anag.get(ANA_PAIV); ecf.right_just(11, '0'); ecf << "_ECF00.ecf"; set(F_NAME, ecf); o.set(ecf); } } break; case F_CONT: if (e == fe_init) { const TRectype& anag = contribuente(); o.set(anag.get(ANA_COFI)); o.disable(); set(F_PIVA, anag.get(ANA_PAIV)); } break; case F_INTR: if (e == fe_init && o.empty()) { TString16 key = prefix().firm().get(NDT_FIRMAT); if (key.full()) { key.insert("F|"); o.set(cache().get(LF_ANAG, key, ANA_COFI)); } } break; case F_CAF: if (o.empty()) { if (e == fe_init) o.set(prefix().firm().get(NDT_INTCAF)); } break; case DLG_SELECT: if (e == fe_button) { TRecordset* rs = new_recordset(); TRecordset_sheet sheet(*rs, TR("Elenco di controllo"), 0x8); while (sheet.run() == K_ENTER) { const long sel = sheet.selected(); TToken_string& row = sheet.row(sel); TRectype clifo(LF_CLIFO); clifo.put(CLI_TIPOCF, row.get(0)); clifo.put(CLI_CODCF, row.get(1)); clifo.edit(); } delete rs; return false; } break; case DLG_EDIT: if (e == fe_button) { TRecordset* rs = new_recordset(); TFilename fname = get(F_DIR); fname.add("clifo.xls"); if (rs->save_as(fname)) xvt_sys_goto_url(fname, "open"); delete rs; return false; } break; case DLG_PRINT: if (e == fe_button) { TRecordset* rs = new_recordset(); TAlleg_report rep(rs, *this); TReport_book book; book.add(rep); book.print_or_preview(); return false; } break; case DLG_ELABORA: if (e == fe_button) { if (check_fields()) { if (curr_page() == 0) generazione(); else fusione(); } return false; } break; case F_FUSION: if (e == se_notify_modify) { TFilename name; if (row2name(((TSheet_field&)o).row(jolly), name)) { TString error; if (!test_file(name, error)) return error_box(error); } } else if (e == fe_close) { TSheet_field& s = (TSheet_field&)o; TString error; TFilename name1, name2; FOR_EACH_SHEET_ROW(s, i, row1) if (row2name(*row1, name1)) { if (!test_file(name1, error)) return error_box(error); FOR_EACH_SHEET_ROW(s, j, row2) if (j > i && row2name(*row2, name2)) { if (name1 == name2) { error.format("La riga %d e' duplicata nella riga %d", i+1, j+1); return error_box(error); } } } } break; default: break; } return true; } void TAlleg_mask::on_firm_change() { set(F_NAME, "", 3); } TAlleg_mask::TAlleg_mask() : TAutomask("cg3900a") { } TAlleg_mask::~TAlleg_mask() { save_profile(); } /////////////////////////////////////////////////////////// // TClifo_alleg_app /////////////////////////////////////////////////////////// class TClifo_alleg_app : public TSkeleton_application { public: virtual void main_loop(); }; void TClifo_alleg_app::main_loop() { // Roba anagrafica open_files(LF_ANAG, LF_ANAGFIS, LF_COMUNI, LF_NDITTE, LF_OCCAS, LF_TAB, LF_TABCOM, 0); // Roba contabile open_files(LF_CAUSALI, LF_CLIFO, LF_MOV, LF_RMOVIVA, 0); TAlleg_mask m; m.run(); } int cg3900(int argc, char* argv[]) { TClifo_alleg_app app; app.run(argc, argv, TR("Elenco clienti/fornitori")); return 0; }