#include #include #include #include #include #include #include "../mg/umart.h" #include "halib.h" class THardy_config : public TConfig { public: virtual const TString& get(const char* var, const char* section = NULL, int index = -1, const char* def = ""); THardy_config(const char* ini_name); }; const TString& THardy_config::get(const char* var, const char* section, int index, const char* def) { const TString& original_val = TConfig::get(var, section, index, def); if (original_val[0] == '"' && original_val.ends_with("\"")) { TString& val = get_tmp_string(); val = original_val; val.rtrim(1); val.ltrim(1); val.trim(); return val; } return original_val; } THardy_config::THardy_config(const char* ini_name) : TConfig(ini_name, "Transaction") { } ///////////////////////////////////////////////////////////// // Applicazione ///////////////////////////////////////////////////////////// class TIni2Txt: public TSkeleton_application { TFilename _output_dir; protected: //metodi di infimo livello TString4 ricava_segno(TConfig& ini); //metodi di medio livello void crea_nome_txt(const TString& prefisso, TFilename& output_path); //metodi di alto livello void genera_cliente_txt(TConfig& ini); void genera_riga_listino_txt(TConfig& ini); void genera_prodotto_txt(TConfig& ini); virtual void main_loop(); public: TIni2Txt(); }; TIni2Txt::TIni2Txt() { if (user().blank()) user() = dongle().administrator(); } //metodo che genera in automatico il nome del file .txt in output (maggggico) void TIni2Txt::crea_nome_txt(const TString& prefisso, TFilename& output_path) { TString_array lista_files; output_path = _output_dir; TString wrkstring; wrkstring << prefisso << "??????.txt"; output_path.add(wrkstring); const int items = list_files(output_path, lista_files); long n = 1; if (items > 0) { lista_files.sort(); TFilename ultimo_txt = lista_files.row(items - 1); ultimo_txt = ultimo_txt.name(); const long last_txt = atol(ultimo_txt.mid(prefisso.len(), 6)); n += last_txt; } //risfruttiamo lo stesso filename che risparmiamo output_path = _output_dir; output_path.add(prefisso); TString8 numero; numero.format("%06ld", n); output_path << numero; output_path.ext("txt"); } TString4 TIni2Txt::ricava_segno(TConfig& ini) { TString4 segno = "+"; const TString& action = ini.get("Action", "Transaction"); if (action == "R") segno = "-"; return segno; } /////////////////////////////////////////////// // metodi di alto livello /////////////////////////////////////////////// void TIni2Txt::genera_cliente_txt(TConfig& ini) { //recordset per i clienti TEsporta_clientiVAR_recordset clienti; clienti.new_rec(""); //controlla il tipo di transazione... const TString4 segno = ricava_segno(ini); //...e poi si lancia a capofitto a riempire il recordset! //campi da clifo (20) //------------------- ini.set_paragraph("20"); const long codcf = ini.get_long(CLI_CODCF); //il codice terminale è il codagente legato al cliente clienti.set("CodiceTerminale", find_codag(codcf)); clienti.set("Segno", segno); clienti.set(CLI_CODCF, codcf); clienti.set(CLI_RAGSOC, ini.get(CLI_RAGSOC)); //l'indirizzo va numerato TString80 indcf = ini.get(CLI_INDCF); indcf << " " << ini.get(CLI_CIVCF); clienti.set(CLI_INDCF, indcf); //panegirico per comune e provincia const TString& statocf = ini.get(CLI_STATOCF); if (statocf.blank()) { const TString& comcf = ini.get(CLI_COMCF); TToken_string key; key.add(statocf); key.add(comcf); const TRectype& rec_comuni = cache().get(LF_COMUNI, key); TString80 dencom = rec_comuni.get(COM_DENCOM); //dencom.cut(20); //il campo sul .txt è lungo 20! clienti.set("Localita", dencom); const TString& provcf = rec_comuni.get(COM_PROVCOM); clienti.set("Provincia", provcf); } clienti.set(CLI_CAPCF, ini.get(CLI_CAPCF)); clienti.set(CLI_PAIV, ini.get(CLI_PAIV)); //attenzione alla lunghezza del codpag TString4 codpag = ini.get(CLI_CODPAG); //codpag.cut(2); //il campo sul .txt è lungo 2! clienti.set(CLI_CODPAG, codpag); TString query; query << "USE CONDV"; query << "\nFROM TIPO=C TIPOCF=C CODCF=#CODCF"; query << "\nTO TIPO=C TIPOCF=C CODCF=#CODCF"; TISAM_recordset contratti(query); contratti.set_var("#CODCF", ini.get_long(CLI_CODCF)); if (contratti.move_last()) { const TString& cod_contr = contratti.get(CONDV_COD).as_string(); clienti.set("CodiceListino", cod_contr); } TString16 ntel = ini.get(CLI_PTEL); ntel << ini.get(CLI_TEL); //ntel.cut(10); clienti.set(CLI_TEL, ntel); clienti.set(CLI_CODCFFATT, ini.get(CLI_CODCFFATT)); //panegirico del fido! //poichè il formato di output prevede comunque 2 decimali -> provvediamo a riempire eventuali buchi real fido = ini.get(CLI_FIDO); fido *= CENTO; fido.round(); clienti.set(CLI_FIDO, fido); //no consegna = sospeso (forse) const TString& sospeso = ini.get_bool(CLI_SOSPESO) ? "S" : ""; clienti.set("NoConsegna", sospeso); clienti.set(CLI_COFI, ini.get(CLI_COFI)); //campi da cfven(17) //------------------ ini.set_paragraph("17"); const TString& str_sconto = ini.get(CFV_SCONTO); clienti.set("ScontoFineFattura", find_sconto(str_sconto)); TString4 assfis = ini.get(CFV_ASSFIS); //assfis.cut(2); //il loro è lungo 2! clienti.set(CFV_ASSFIS, assfis); //prepara il nome corretto del file .txt e lo genera //-------------------------------------------------- const TString prefisso = "clientivar"; TFilename output_path; crea_nome_txt(prefisso, output_path); //..e alla fine della fiera salva il file di testo nell directory selezionata clienti.save_as(output_path, fmt_text); } void TIni2Txt::genera_riga_listino_txt(TConfig& ini) { TEsporta_listiniVAR_recordset riga_listino; const TString4 segno = ricava_segno(ini); //campi da condv (52) //------------------- //ini.set_paragraph("52"); //campi da rcondv (53) //-------------------- //ATTENZIONE!!! Ci sono N righe di tipo 53 per ogni testata, quindi dobbiamo fare il giro for (int r = 1;; r++) { TString8 paragraph; paragraph.format("%d,%d", LF_RCONDV, r); if (!ini.set_paragraph(paragraph)) break; riga_listino.new_rec(""); riga_listino.set("CodiceTerminale", 0L); //nel caso del listino non si sa come comportarsi riga_listino.set("Segno", segno); riga_listino.set(RCONDV_COD, ini.get(RCONDV_COD)); TString80 codart = ini.get(RCONDV_CODRIGA); //codart.cut(5); //il codart è lungo 5 sul txt! riga_listino.set(RCONDV_CODRIGA, codart); //prezzo real prezzo = ini.get(RCONDV_PREZZO); if (prezzo.is_zero()) { TToken_string key_umart; key_umart.add(codart); key_umart.add(1); const TRectype& rec_umart = cache().get(LF_UMART, key_umart); prezzo = rec_umart.get_real(UMART_PREZZO); } prezzo *= 1000; prezzo.round(); riga_listino.set(RCONDV_PREZZO, prezzo.integer()); //sconto const TString& str_sconto = ini.get(RCONDV_SCONTO); riga_listino.set(RCONDV_SCONTO, find_sconto(str_sconto)); } //for(int r=1;;... //prepara il nome corretto del file .txt e lo genera //-------------------------------------------------- const TString prefisso = "listvar"; TFilename output_path; crea_nome_txt(prefisso, output_path); riga_listino.save_as(output_path, fmt_text); } void TIni2Txt::genera_prodotto_txt(TConfig& ini) { TEsporta_prodottiVAR_recordset prodotto; prodotto.new_rec(""); const TString4 segno = ricava_segno(ini); //campi da anamag (47) //------------------- ini.set_paragraph("47"); prodotto.set("Segno", segno); TString80 codart = ini.get(ANAMAG_CODART); //codart.cut(5); //solito problema della lunghezza ridotta prodotto.set(ANAMAG_CODART, codart); TString80 descr = ini.get(ANAMAG_DESCR); //descr.cut(30); prodotto.set(ANAMAG_DESCR, descr); TString4 codiva = ini.get(ANAMAG_CODIVA); //codiva.cut(2); //solito problema della lungh ridotta prodotto.set(ANAMAG_CODIVA, codiva); //sconto const TString& str_sconto = ini.get(ANAMAG_SCONTO); prodotto.set(ANAMAG_SCONTO, find_sconto(str_sconto)); //campi da umart (49) (per ora una sola riga) //------------------------------------------- ini.set_paragraph("49,1"); real prezzo = ini.get(UMART_PREZZO); prezzo *= 1000; prezzo.round(); prodotto.set(UMART_PREZZO, prezzo.integer()); prodotto.set(UMART_UM, ini.get(UMART_UM)); //prepara il nome corretto del file .txt da generare //-------------------------------------------------- const TString prefisso = "prodottivar"; TFilename output_path; crea_nome_txt(prefisso, output_path); prodotto.save_as(output_path, fmt_text); } void TIni2Txt::main_loop() { //stabilisce una volta per tutte ad inizio programma quale cavolo è la directory dove sbattere i .txt generati TConfig hardy(CONFIG_DITTA, "ha"); _output_dir = hardy.get("OuputPath"); //dalla riga di comando raccatta il path completo del file .ini da tradurre TFilename path = argv(2); if (path.exist()) { //crea un config del .ini di tipo Hardy_config con le get astute! THardy_config input_ini_file(path); //elabora il .ini TString_array ini_paragraphs; input_ini_file.list_paragraphs(ini_paragraphs); //clienti if (ini_paragraphs.find("20") >= 0) genera_cliente_txt(input_ini_file); //sospesi //listino if (ini_paragraphs.find("52") >= 0) genera_riga_listino_txt(input_ini_file); //prodotti if (ini_paragraphs.find("47") >= 0) genera_prodotto_txt(input_ini_file); } } int ha1100(int argc, char* argv[]) { TIni2Txt a; a.run(argc, argv, "Generazione .txt da .ini"); return 0; }