#include #include #include #include #include #include #include #include #include #include "../ce/ammce.h" #include "../ce/cespi.h" #include "../ce/salce.h" #include "../cg/cg2103.h" #include "../cg/cglib01.h" #include "lv4.h" #include "lv4100.h" #include "lv4500a.h" #define T_N "N" #define T_X "X" ///////////////////////////////// //// LAUNDRY_RECORDSET //// ///////////////////////////////// //Classe TLaundry_recordset: è un TAS400_recordset "intelligente" class TLaundry_recordset : public TAS400_recordset { public: void add_field(const char* name, const char* tipo, int pos, int len); TLaundry_recordset(const int rec_length); }; //ADD_FIELD: aggiunge i campi al recordset void TLaundry_recordset::add_field(const char* name, const char* tipo, int pos, int len) { const TFixed_string str_tipo(tipo); if (str_tipo.ends_with("N")) { create_field(name, pos-1, len, _intzerofld); return; } create_field(name, pos-1, len, _alfafld); } TLaundry_recordset::TLaundry_recordset(const int rec_lenght) : TAS400_recordset("AS400()") { TString16 query; query << "AS400(" << rec_lenght << ")"; TFilename cazzone; parse_query(query, cazzone); } //////////////////////////////// //// TIMPORTA_FAT_REC //// //////////////////////////////// //Classe TImporta_fat_rec class TImporta_fat_rec : public TLaundry_recordset { protected: virtual TRecnotype new_rec(const char* trc); public: TImporta_fat_rec(const TFilename& filename); }; ///////////////////////////////////////////////////////////// // Recordset specifici per i dati da trasferire INPUT ///////////////////////////////////////////////////////////// TRecnotype TImporta_fat_rec::new_rec(const char* trc) { if (trc && *trc > ' ') { TString rec; rec << trc << "\r\n"; return TText_recordset::new_rec(rec); } return -1; } //questo invece è il metodo magico che vale per il caricamento da file esterno TImporta_fat_rec::TImporta_fat_rec(const TFilename& filename) : TLaundry_recordset(89) { TFilename cazzone; //as400 con lunghezza 89 e chiave lunga 1 (a partire dal ventesimo carattere): è il tipo record parse_query("AS400(89,20,1)", cazzone); //Tipo record C add_field("NDOC", T_N, 1, 6); add_field("DATADOC", T_N, 7, 8); add_field("NPART", T_N, 15, 6); add_field("TIPOMOV", T_X, 21, 1); add_field("SEZIONE", T_X, 22, 1); add_field("CODCF", T_N, 23, 6); add_field("IMPORTO", T_X, 29, 13); add_field("CODVAL", T_X, 42, 4); add_field("CODPAG", T_X, 46, 4); add_field("DATASCAD", T_N, 50, 8); add_field("ABICAB", T_N, 58, 12); add_field("CODCAU", T_N, 70, 4); add_field("REGIVA", T_X, 74, 1); add_field("NREGIVA", T_N, 75, 2); add_field("NPROG", T_N, 77, 11); //Tipo record G add_field("NDOC", T_N, 1, 6); add_field("DATADOC", T_N, 7, 8); add_field("NPART", T_N, 15, 6); add_field("TIPOMOV", T_X, 21, 1); add_field("SEZIONE", T_X, 22, 1); add_field("IMPORTO", T_X, 23, 13); add_field("CODMASTRO", T_N, 36, 6); add_field("CODCONTO", T_N, 42, 6); //Tipo record I add_field("NDOC", T_N, 1, 6); add_field("DATADOC", T_N, 7, 8); add_field("NPART", T_N, 15, 6); add_field("TIPOMOV", T_X, 21, 1); add_field("SEZIONE", T_X, 22, 1); add_field("IMPONIBILE", T_X, 23, 13); add_field("IMPOSTA", T_X, 36, 11); add_field("CODIVA", T_N, 47, 4); add_field("CODMASTRO", T_N, 36, 6); add_field("CODCONTO", T_N, 42, 6); //Tipo record R add_field("NDOC", T_N, 1, 6); add_field("DATADOC", T_N, 7, 8); add_field("NPART", T_N, 15, 6); add_field("TIPOMOV", T_X, 21, 1); add_field("NRATA", T_N, 22, 6); add_field("IMPRATA", T_X, 28, 13); add_field("TIPORATA", T_X, 41, 1); add_field("DATASCAD", T_N, 42, 8); TText_recordset::load_file(filename); } class TDecodifica_codici : public TObject { TAssoc_array _causali; TAssoc_array _condpag; TAssoc_array _codiva; TAssoc_array _regiva; TAssoc_array _valute; protected: void riempi_array(const char* codice); public: TString80 decodifica_causali(const int cau_cog); const TString80 decodifica_condpag(const int condpag_cog); const TString80 decodifica_codiva(const int codiva_cog); const TString80 decodifica_regiva(const int regiva_cog); const TString80 decodifica_valute(const int val_cog); TDecodifica_codici(); }; void TDecodifica_codici::riempi_array(const char* codice) { TString query; query << "USE MULTIREL\n" << "FROM COD=\"" << codice << "\"\n" << "TO COD=\"" << codice << "\""; TISAM_recordset recset(query); //mi piace molto poco; da migliorare for(bool ok = recset.move_first(); ok; ok = recset.move_next()) { if(codice == "CGCAU") _causali.add(recset.get("DATA").as_string(), recset.get("FIRST").as_string()); if(codice == "CGCDP") _condpag.add(recset.get("DATA").as_string(), recset.get("FIRST").as_string()); if(codice == "CGIVA") _codiva.add(recset.get("DATA").as_string(), recset.get("FIRST").as_string()); if(codice == "CGREG") _regiva.add(recset.get("DATA").as_string(), recset.get("FIRST").as_string()); if(codice == "CGVAL") _valute.add(recset.get("DATA").as_string(), recset.get("FIRST").as_string()); } } TString80 TDecodifica_codici::decodifica_causali(const int cau_cog) { if(_causali.empty()) riempi_array("CGCAU"); TString8 key; key << cau_cog; TString& codcau = *(TString*)_causali.objptr(key); return codcau; } const TString80 TDecodifica_codici::decodifica_condpag(const int condpag_cog) { if(_condpag.empty()) riempi_array("CGCDP"); TString8 key; key << condpag_cog; TString& codcdp = *(TString*)_condpag.objptr(key); return codcdp; } const TString80 TDecodifica_codici::decodifica_codiva(const int codiva_cog) { if(_codiva.empty()) riempi_array("CGIVA"); TString8 key; key << codiva_cog; TString& codiva = *(TString*)_codiva.objptr(key); return codiva; } const TString80 TDecodifica_codici::decodifica_regiva(const int regiva_cog) { if(_regiva.empty()) riempi_array("CGREG"); TString8 key; key << regiva_cog; TString& regiva = *(TString*)_regiva.objptr(key); return regiva; } const TString80 TDecodifica_codici::decodifica_valute(const int val_cog) { if(_valute.empty()) riempi_array("CGVAL"); TString8 key; key << val_cog; TString& codval = *(TString*)_valute.objptr(key); return codval; } TDecodifica_codici::TDecodifica_codici() { _causali.destroy(); _condpag.destroy(); _codiva.destroy(); _regiva.destroy(); _valute.destroy(); } //////////////////////////////// //// TIMPORTA_FAT_MSK //// //////////////////////////////// //Classe TImporta_fat_msk class TImporta_fat_msk : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TImporta_fat_msk(); }; TImporta_fat_msk::TImporta_fat_msk() :TAutomask ("lv4500a") { } bool TImporta_fat_msk::on_field_event(TOperable_field& f, TField_event e, long jolly) { switch (f.dlg()) { //giochetto per avere la lista dei files validi nella directory di trasferimento! case F_NAME: if (e == fe_button) { TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@32"); TFilename path = get(F_PATH); path.add("*.txt"); //files delle testate list_files(path, as.rows_array()); TFilename name; FOR_EACH_ARRAY_ROW(as.rows_array(), i, row) { name = *row; *row = name.name(); } if (as.run() == K_ENTER) { f.set(as.row(as.selected())); } } break; default: break; } return true; } //////////////////////////////// //// TIMPORTA_FAT_APP //// //////////////////////////////// //Classe TImporta_fat_app class TImporta_fat_app : public TSkeleton_application { TImporta_fat_msk* _msk; TDecodifica_codici* _codici; protected: bool search_gr_sp_ca(const int gruppo, const char* specie, const int categoria); const TFilename crea_tmpdir() const; const TFilename crea_nomefile(const long ndoc) const; const int segno_testata(const char sezione, const TCausale& cau) const; const int segno_riga(const char sezione, const TCausale& cau) const; const TString16 genera_real(const TVariant importo, const int segno = 1) const; const TString80 riclassifica_pconti(); void genera_testata(TImporta_fat_rec& recset, TConfig* conf, TFilename& tmpdir); //void genera_contropartite(TImporta_fat_rec& recset, TConfig* configfile); void genera_righe_iva(TImporta_fat_rec& recset, TConfig* conf, int nriga, const TCausale& cau); void genera_rate(TImporta_fat_rec& recset, TConfig* conf, int nriga); void elabora_file(const TFilename& tmpdir); void elimina_file(const TFilename& tmpdir); public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); void transfer(const TFilename& file); }; bool TImporta_fat_app::search_gr_sp_ca(const int gruppo, const char* specie, const int categoria) { return true; } //CREA_TMPDIR: crea la directory temporanea e restituisce il suo nome const TFilename TImporta_fat_app::crea_tmpdir() const { TFilename tmpdir; tmpdir.tempdir(); tmpdir.add("fatture"); make_dir(tmpdir); return tmpdir; } //CREA_NOMEFILE: genera il nome del file dal numero documento const TFilename TImporta_fat_app::crea_nomefile(const long ndoc) const { TString strname; strname.format("%06l", ndoc); strname << ".ini"; return strname; } //SEGNO_TESTATA: restituisce + o - uno a seconda che la sezione della riga in esame //e quella della prima riga della causale siano uguali o opposte const int TImporta_fat_app::segno_testata(const char sezione, const TCausale& cau) const { return cau.sezione_clifo() == sezione ? 1 : -1; } //SEGNO_TESTATA: restituisce + o - uno a seconda che la sezione della riga in esame //e quella della prima riga della causale siano opposte o uguali const int TImporta_fat_app::segno_riga(const char sezione, const TCausale& cau) const { return cau.sezione_clifo() == sezione ? -1 : 1; } //GENERA_REAL: crea il numero reale, aggiungendo i decimali e tenendo conto del segno corretto const TString16 TImporta_fat_app::genera_real(const TVariant importo, const int segno) const { real imp = importo.as_real(); imp /= CENTO; imp *= segno; return imp.string(); } //GENERA_TESTATA: genero il paragrafo testata void TImporta_fat_app::genera_testata(TImporta_fat_rec& recset, TConfig* conf, TFilename& tmpdir) { const long ndoc = recset.get("NDOC").as_int(); const TDate datadoc = recset.get("DATADOC").as_date(); const TCausale cau(recset.get("CODCAU").as_string()); const int segno = segno_testata(recset.get("SEZIONE").as_string()[0], cau); TFilename nomefile = tmpdir; nomefile << crea_nomefile(ndoc); conf = new TConfig(nomefile); conf->set_paragraph("Transaction"); //setto il paragrafo [Transaction] del file ini conf->set("Action","INSERT"); conf->set("Mode", "AUTO"); TString paragraph; paragraph.format("%d", LF_MOV); conf->set_paragraph(paragraph); //setto il paragrafo [23] del file ini (testata) conf->set(MOV_ANNOES, datadoc.year()); conf->set(MOV_DATAREG, datadoc); conf->set(MOV_DATACOMP, datadoc); conf->set(MOV_DATADOC, datadoc); conf->set(MOV_NUMDOC, ndoc); conf->set(MOV_CODCAUS, _msk->get_bool(F_DECCAU) ? atol(_codici->decodifica_causali(recset.get("CODCAU").as_int())) : recset.get("CODCAU").as_int()); conf->set(MOV_ANNOIVA, datadoc.year()); conf->set(MOV_REG, _codici->decodifica_regiva(recset.get("REGIVA").as_int())); conf->set(MOV_PROTIVA, recset.get("NREGIVA").as_int()); conf->set(MOV_CODVAL, _msk->get_bool(F_DECVAL) ? _codici->decodifica_valute(recset.get("CODVAL").as_int()) : recset.get("CODVAL").as_string()); conf->set(MOV_TIPO, 'C'); conf->set(MOV_CODCF, recset.get("CODCF").as_int()); conf->set(MOV_TOTDOC, genera_real(recset.get("IMPORTO"), segno)); conf->set(MOV_CODPAG, _msk->get_bool(F_DECCDP) ? atol(_codici->decodifica_condpag(recset.get("CODPAG").as_int())) : recset.get("CODPAG").as_int()); } //GENERA_RIGHE_IVA: genero le righe IVA void TImporta_fat_app::genera_righe_iva(TImporta_fat_rec& recset, TConfig* conf, int nriga, const TCausale& cau) { const TDate datadoc = recset.get("DATADOC").as_date(); const int segno = segno_riga(recset.get("SEZIONE").as_string()[0], cau); TString paragraph; paragraph.format("%d,%d", LF_RMOVIVA, nriga++); conf->set_paragraph(paragraph); conf->set(RMI_ANNOES, datadoc.year()); conf->set(RMI_CODIVA, _msk->get_bool(F_DECCODIVA) ? atol(_codici->decodifica_codiva(recset.get("CODIVA").as_int())) : recset.get("CODIVA").as_int()); conf->set(RMI_IMPONIBILE, genera_real(recset.get("IMPONIBILE"), segno)); conf->set(RMI_IMPOSTA, genera_real(recset.get("IMPOSTA"))); /*Mancano Codice mastro e codice conto*/ } //GENERA_RATE: genero le righe su SCAD void TImporta_fat_app::genera_rate(TImporta_fat_rec& recset, TConfig* conf, int nriga) { TString paragraph; paragraph.format("%d,%d", LF_RMOVIVA, nriga++); conf->set_paragraph(paragraph); const TDate datadoc = recset.get("DATADOC").as_date(); conf->set(SCAD_ANNO, datadoc.year()); conf->set(SCAD_NUMPART, recset.get("NPART").as_int()); conf->set(SCAD_NRIGA, nriga); conf->set(SCAD_NRATA, recset.get("NRATA").as_int()); //??? CODPAG ???// conf->set(SCAD_TIPOPAG, recset.get("TIPOPAG").as_int()); conf->set(SCAD_IMPORTO, genera_real(recset.get("IMPORTO"))); conf->set(SCAD_IMPORTOVAL, genera_real(recset.get("IMPORTO"))); //NON SO IN QUALE DEI DUE VADA conf->set(SCAD_DATASCAD, recset.get("DATASCAD").as_date()); //??? ABI CAB GRUPPO CONTO SOTTOCONTO ???// } //ELABORA_FILE: chiamo la prima nota su tutti gli ini che ho generato void TImporta_fat_app::elabora_file(const TFilename& tmpdir) { TString app; app << "cg2 -0 -i" << tmpdir << "/*.ini"; TExternal_app primanota(app); primanota.run(true); } //ELIMINA_FILE: elimino tutti i file che ho elaborato DA IMPLEMENTARE void TImporta_fat_app::elimina_file(const TFilename& tmpdir) { } void TImporta_fat_app::transfer(const TFilename& file) { TImporta_fat_rec recset(file); TConfig* configfile = NULL; TFilename tmpdir = crea_tmpdir(); int nrigai, nrigar; TProgind pi(recset.items(), "Importazione in corso...", true, true); for(bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; const char tipomov = recset.get("TIPOMOV").as_string()[0]; const TCausale cau(recset.get("CODCAU").as_string()); switch(tipomov) { case 'C': genera_testata(recset, configfile, tmpdir); nrigai = nrigar = 0; break; case 'I': genera_righe_iva(recset, configfile, nrigai, cau); break; case 'R': genera_rate(recset, configfile, nrigar); break; default: break; } } elabora_file(tmpdir); } bool TImporta_fat_app::create() { _msk = new TImporta_fat_msk(); _codici = new TDecodifica_codici(); return TSkeleton_application::create(); } bool TImporta_fat_app::destroy() { delete _msk; return TApplication::destroy(); } void TImporta_fat_app::main_loop() { KEY tasto; tasto = _msk->run(); if (tasto == K_ENTER) { //genero il nome del file da caricare TFilename file = _msk->get(F_PATH); file.add(_msk->get(F_NAME)); if(!file.exist()) { error_box(TR("Il file selezionato non esiste; si prega di controllare")); return; } transfer(file); } } int lv4500 (int argc, char* argv[]) { TImporta_fat_app main_app; main_app.run(argc, argv, TR("Importazione fatture COGECO")); return true; }