#include #include #include #include #include #include #include #include #include #include #include "../mg/codcorr.h" #include "../cg/cglib01.h" #include "../ve/velib.h" #include "ha2.h" #include "ha2200a.h" const char* const APPNAME = TR("Esselunga: generazione file Fatture"); /////////////////////////////////////////////////////////// // TAutomask /////////////////////////////////////////////////////////// class THardy_esselunga_fat_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: THardy_esselunga_fat_mask(); virtual ~THardy_esselunga_fat_mask() {}; }; THardy_esselunga_fat_mask::THardy_esselunga_fat_mask() : TAutomask ("ha2200a") { } bool THardy_esselunga_fat_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_DATAINI: if (e == fe_close || e == fe_modify) { //se la data iniziale è piena -> l'anno deve essere lo stesso nelle 2 date; //se invece è vuota -> la data iniziale viene presa come la data iniziale dell'esercizio della data finale... //..ma questo qui non serve e viene rinviato alla query principale del recordset const TDate datafin = get_date(F_DATAFIN); TEsercizi_contabili esc; const int datafin_esc = esc.date2esc(datafin); TDate dataini = o.get(); if (dataini.ok()) { const int dataini_esc = esc.date2esc(dataini); if (datafin_esc != dataini_esc) return error_box("Le date devono appartenere allo stesso esercizio!"); } } break; default: break; } return true; } /////////////////////////////////////////////////////////// // TCodArtEsselunga_cache /////////////////////////////////////////////////////////// class TCodArtEsselunga_cache : public TCache { protected: virtual TObject* key2obj(const char* key); public: const TString& decode(const TString& codart); TCodArtEsselunga_cache() {} }; TObject* TCodArtEsselunga_cache::key2obj(const char* key) { TToken_string code(key); TString80 codart; code.get(0, codart); const TString& codcf = ini_get_string(CONFIG_DITTA, "ha", "Esselunga_CodEsselunga"); TISAM_recordset codcorr("USE CODCORR\nSELECT CODCF=#CODCF\nFROM CODART=#COD\nTO CODART=#COD"); codcorr.set_var("#COD", TVariant(codart)); codcorr.set_var("#CODCF", TVariant(codcf)); if (codcorr.items()>0) { codcorr.move_first(); return new TString80(codcorr.get(CODCORR_CODARTALT).as_string()); } else return new TString80(codart); } const TString& TCodArtEsselunga_cache::decode(const TString& codart) { return *(const TString*)objptr(codart); } ///////////////////////////////////////////////////////////// // Recordset per file fatture ///////////////////////////////////////////////////////////// enum TFE_type { AN, NU }; class TFatture_recordset : public TAS400_recordset { void add_field(const char* name, TFE_type type, int len, int pos, bool required = false, const char* def = NULL); public: TFatture_recordset(const TString4 dipendenza); }; void TFatture_recordset::add_field(const char* name, TFE_type type, int len, int pos, bool required, const char* def) { CHECKS(len > 0, "Lunghezza nulla sul campo ", name); CHECKS(pos > 0, "Posizione nulla sul campo ", name); TFieldtypes ft = _alfafld; switch (type) { case NU: ft = _longfld; break; default: ft = _alfafld; break; } bool ok = false; if (def && *def) ok = create_field(name, pos, len, ft, required, TVariant(def)); else ok = create_field(name, pos, len, ft, required); CHECKS(ok, "Impossibile creare il campo ", (const char*)name); } TFatture_recordset::TFatture_recordset(const TString4 dipendenza) : TAS400_recordset("AS400(400)") { TConfig config(CONFIG_DITTA, "ha"); const TString80 piva_hardy = config.get("Esselunga_PIvaHardy"); const TString80 piva_esselunga = config.get("Esselunga_PIvaEsselunga"); const TString8 tipo_emissione = config.get("Esselunga_TipoEmissione"); // Record BGM: nome documento e numero fattura add_field("BGM.TIPOREC", "AN", 3, 1, true, "BGM"); add_field("BGM.ID-EDI-MITT-1", "AN", 35, 4, true, piva_hardy); add_field("BGM.ID-EDI-MITT-2", "AN", 4, 39, true, tipo_emissione); add_field("BGM.ID-EDI-MITT-3", "AN", 14, 43); add_field("BGM.ID-EDI-DEST-1", "AN", 35, 57, true, piva_esselunga); add_field("BGM.ID-EDI-DEST-2", "AN", 4, 92, true, tipo_emissione); add_field("BGM.ID-EDI-DEST-3", "AN", 14, 96); add_field("BGM.TIPODOC", "AN", 6, 110, true); add_field("BGM.NUMDOC", "AN", 35, 116, true); add_field("BGM.DATADOC", "NU", 8, 151, true); add_field("BGM.ORADOC", "NU", 4, 159); add_field("BGM.FILLER", "AN", 6, 163); const TString80 cod_hardy = config.get("Esselunga_CodHardy"); // Record NAS: identificazione mittente add_field("BGM.TIPOREC", "AN", 3, 1, true, "NAS"); add_field("BGM.CODFORN", "AN", 17, 4, true, cod_hardy); add_field("BGM.QCODFORN", "AN", 3, 21, true, "92"); add_field("BGM.RAGSOCF", "AN", 70, 24, true, ); } /////////////////////////////////////// // TSkeleton_application /////////////////////////////////////// class THardy_esselunga_fat : public TSkeleton_application { protected: long genera_recordset(const TMask& mask, TISAM_recordset& recset); void elabora(const TMask& mask); void check_date(const TDate& datafine, TDate& dataini); long check_cliente(const long codcf, const TString4 dipendenza); TFilename scrivi_testata(const TMask& mask); public: virtual void main_loop(); virtual bool create(); }; //metodo per ricavare la data iniziale di elaborazione qualora l'utonto non la metta e l'esercizio da usare void THardy_esselunga_fat::check_date(const TDate& datafine, TDate& dataini) { TEsercizi_contabili esc; TDate datafine_tmp = datafine; const int esercizio = esc.date2esc(datafine); esc.code2range(esercizio, dataini, datafine_tmp); } //metodo che filtra tutti i documenti in base ai parametri della maschera long THardy_esselunga_fat::genera_recordset(const TMask& mask, TISAM_recordset& recset) { TString query; query << "USE DOC \n"; TString filt_expr; // aggiungo alla query le condizioni sulle numerazioni selezionare da maschera TSheet_field& sheet = mask.sfield(F_SHEETDOC); const long items = sheet.items(); if (items > 0) { TString16 codnum; filt_expr << " SELECT"; FOR_EACH_SHEET_ROW(sheet, r, row) { codnum = row->get(0); if (codnum.not_empty()) { filt_expr << " (CODNUM=\""; filt_expr << codnum << "\") ||"; } } filt_expr.rtrim(2); query << filt_expr; } query << "\nFROM DATADOC=#DATAINI PROVV='D' ANNO=#ANNO"; query << "\nTO DATADOC=#DATAFIN PROVV='D' ANNO=#ANNO"; recset.set(query); //settaggio delle variabili const TDate datafin = mask.get_date(F_DATAFIN); TDate dataini = mask.get_date(F_DATAINI); //se la data iniziale è vuota deve coincidere con l'inizio dell'esercizio della data finale (obbligatoria!) int esc = datafin.year(); if (!dataini.ok()) check_date(datafin, dataini); recset.set_var("#ANNO", long(esc)); recset.set_var("#DATAINI", dataini); recset.set_var("#DATAFIN", datafin); return recset.items(); } TFilename THardy_esselunga_fat::scrivi_testata(const TMask& mask) { const TString4 dipendenza = mask.get(F_DIPENDENZA); TConfig config(CONFIG_DITTA, "ha"); TFilename file_privat = config.get("Esselunga_Path"); if (dipendenza[0] == 'D') file_privat.add("CDMI"); else file_privat.add("CDFI"); file_privat.ext("txt"); ofstream file_output(file_privat); TString record(260); // tipo record/filler/tot_record/progr_record record = "PVT*?*001001"; // nome del file record << file_privat.name(); // identificativo mittente record.overwrite(config.get("Esselunga_PIvaHardy"), 85); record.overwrite(config.get("Esselunga_TipoEmissione"), 120); // identificativo destinatario record.overwrite(config.get("Esselunga_PIvaEsselunga"), 138); record.overwrite(config.get("Esselunga_TipoEmissione"), 173); // formato (Ascii) record.overwrite("A", 191); // identificativo univoco del documento record.overwrite("0000000000000001", 243); file_output << record << endl; file_output.close(); return file_privat; } void THardy_esselunga_fat::elabora(const TMask& mask) { TLog_report log; const TString4 dipendenza = mask.get(F_DIPENDENZA); TFilename file_privat = scrivi_testata(mask); TISAM_recordset recset(""); const long items = genera_recordset(mask, recset); if (items == 0) log.log(1, "Non esistono documenti che soddisfano i parametri selezionati."); // lettura dei documenti da recordset TProgind pi(recset.items(), TR("Elaborazione documenti in corso..."), true, true); TPrivat_recordset privat(dipendenza); TCodArtEsselunga_cache cache_ca; for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; const long codcf = recset.get(DOC_CODCF).as_int(); // verificare se il cliente appartiene alla dipendenza selezionata e se ha tutti i parametri per poter essere inviato const long codcf_esselunga = check_cliente(codcf, dipendenza); if ( codcf_esselunga > 0) { TDocumento* doc = new TDocumento(recset.cursor()->curr()); // passo tutte le righe del documento all'AS400recordset TString16 numdoc; const TString& num = doc->numerazione(); numdoc.format("%012d",doc->numero()); numdoc << cache().get("%NUM", num, "S7"); numdoc.strip("/"); numdoc = numdoc.right(12); FOR_EACH_PHYSICAL_RDOC(*doc, r, rigadoc) { const TString80& codart_esselunga = cache_ca.decode(rigadoc->get(RDOC_CODART)); privat.new_rec(""); privat.set("CDC", TVariant(codcf_esselunga)); privat.set("CODART", codart_esselunga); privat.set("NUMBOLLA", numdoc); privat.set("DATABOLLA", recset.get(DOC_DATADOC)); real qta = rigadoc->get_real(RDOC_QTA); TString16 qtastr = qta.string(8,2,'0'); qtastr.strip("."); privat.set("QTACONS", qtastr); privat.set("QTARESA", "0000000"); } //FOR_EACH... } // if check_cliente... } //for (bool ok = recset.move_first()... TFilename tempfile; tempfile.temp(); privat.save_as(tempfile, fmt_text); fcopy(tempfile, file_privat, true); // memorizzo su campo virtuale che il doc. e' stato inviato const bool definitivo = mask.get_bool(F_DEFINITIVO); if (definitivo) { } log.print_or_preview(); } long THardy_esselunga_fat::check_cliente(const long codcf, const TString4 dipendenza) { long codcf_hardy = -1; TString key; key.format("%ld", codcf); const TRectype rec_cliente = cache().get("&CEL", key); const bool invio = rec_cliente.get_bool("B0"); if (invio) { const char dip_cliente = rec_cliente.get("S1")[0]; if (dip_cliente == dipendenza[0]) codcf_hardy = rec_cliente.get_long("I0"); } return codcf_hardy; } void THardy_esselunga_fat::main_loop() { THardy_esselunga_fat_mask mask; while (mask.run() == K_ENTER) elabora(mask); } bool THardy_esselunga_fat::create() { open_files(LF_DOC, LF_RIGHEDOC, 0); return TSkeleton_application::create(); } int ha2200 (int argc, char* argv[]) { THardy_esselunga_fat elabapp; elabapp.run(argc, argv, APPNAME); return 0; }