From 5f538a66b2ea8fb6b0e4a91f97b5e338e93473ec Mon Sep 17 00:00:00 2001 From: Simone Palacino Date: Thu, 5 Mar 2020 10:35:57 +0100 Subject: [PATCH] Patch level : 12.0 no-patch Files correlati : ps6362.exe Commento : - Personalizzazione Major: - Migliorata esportazione xml: caratteri speciali, aggiunta riga info xml - Aggiunto riferimento desccampolibero6 articoli (da finire) - Sistemate query --- src/ps/ps6362100.cpp | 280 +++++++++++++++++++++++++++++++------------ 1 file changed, 204 insertions(+), 76 deletions(-) diff --git a/src/ps/ps6362100.cpp b/src/ps/ps6362100.cpp index a5d673467..a5795cc13 100644 --- a/src/ps/ps6362100.cpp +++ b/src/ps/ps6362100.cpp @@ -1,41 +1,99 @@ #include #include -#include #include #include -#include -#include #include "ps6362.h" #include "ps6362100a.h" #include #include "tabutil.h" #include "sqlset.h" -#include "doc.h" -#include "rdoc.h" #include "progind.h" +#define XML_ESCAPE_CHAR '&' + +/////////////////////////////////////////////////////////// +// Utils +/////////////////////////////////////////////////////////// + +const char* wchar_to_char(const wchar_t* str) +{ + static TString text; + text = ""; + char cod[5]; + for (int i = 0; i < (int)wcslen(str); ++i) + { + if (str[i] != XML_ESCAPE_CHAR) + { + if (str[i] >= 0x00 && str[i] <= 0x7F) + text << (char)str[i]; + else + { + text << "&#x"; + sprintf_s(cod, "%X", (int)str[i]); + text << cod << ";"; + } + } + else + { + if ((int)wcslen(str) > i + 4) + { + char _Buffer[6]; + for (int j = i; j < i + 5; ++j) + _Buffer[j - i] = (char)str[j]; + _Buffer[5] = '\0'; + TString a = _Buffer; // Son certo che sono caratteri normali + if (a == "&") + i += 4; + } + text << "&"; + } + } + return text; +} + +TString escape_chars(const TString& str) +{ + static TString text; + text = ""; + for (int i = 0; i < str.size(); ++i) + { + if (str[i] != XML_ESCAPE_CHAR) + { + if (str[i] >= 0x00 && str[i] <= 0x7F) // ASCII + text << str[i]; + } + else + { + if (str.mid(i, 5) == "&") + i += 4; + text << "&"; + } + } + return text; +} + /////////////////////////////////////////////////////////// // TXML_element /////////////////////////////////////////////////////////// #define XML_ROOT_TAG nullptr -class TFlexform_xml_ordini; -class TOrdini_riga_xml; - class TXML_element { vector> _attributes{}; vector _childs{}; TString _indent; + bool _info_xml; TString _name; TXML_element* _parent; TString _value; - + const wchar_t* _wvalue; + + public: - void add_attribute(const char* _Tag, const char* _Val) { _attributes.insert(_attributes.end(), { _Tag, _Val }); } + void add_attribute(const char* _Tag, const char* _Val) { _attributes.insert(_attributes.end(), { _Tag, _Val }); } void add_attribute(const char* _Tag, const TString& _Val) { _attributes.insert(_attributes.end(), { _Tag, _Val }); } - void add_attribute(const char* _Tag, const TDate& _Val) { _attributes.insert(_attributes.end(), { _Tag, TString(_Val) }); } + void add_attribute(const char* _Tag, const TDate& _Val) { _attributes.insert(_attributes.end(), { _Tag, TString((const TString&)_Val) }); } void add_child(TXML_element& child) { child._parent = this; _childs.insert(_childs.end(), &child); } bool print_on_file(ofstream* fout, int deep = 0, const char* indent = ""); @@ -45,46 +103,68 @@ public: void set_parent(TXML_element& parent) { parent.add_child(*this); } void set_root() { _parent = XML_ROOT_TAG; } + void set_value(const TString& _Val); + bool is_root() const { return _parent == nullptr; } + TXML_element& operator<<(const char* _Val) { _value = _Val; return *this; } - explicit TXML_element(const char* name, const char* value = "") : _indent("\t"), _name(name), _parent(nullptr), _value(value) { } - explicit TXML_element(const TString& name, const TString& value = "") : _name(name), _parent(nullptr), _value(value) { } + explicit TXML_element(const char* name, const char* value = "", bool info_file = false) : _indent("\t"), _info_xml(info_file), _name(name), _parent(nullptr), _value(value), _wvalue(nullptr) { } + explicit TXML_element(const char* name, const wchar_t* value = L"", bool info_file = false) : _indent("\t"), _info_xml(info_file), _name(name), _parent(nullptr), _value(""), _wvalue(value) { } + explicit TXML_element(const TString& name, const TString& value = "", bool info_file = false) : _indent("\t"), _info_xml(info_file), _name(name), _parent(nullptr), _value(value), _wvalue(nullptr) { } + explicit TXML_element(const char* name, bool info_file) : TXML_element(name, "", info_file) { } }; bool TXML_element::print_on_file(ofstream* fout, const int deep, const char* indent) { - const TString _indent = this->_parent == XML_ROOT_TAG ? this->_indent : indent; + const TString ind = indent; + const TString _indent = this->_parent == XML_ROOT_TAG ? this->_indent : ind; if (fout == nullptr || !fout->is_open() || _name.empty()) return false; - + ofstream& out = *fout; bool ok = true; - + // Stampo prima la riga con tag e attributi for (int i = 0; i < deep; ++i) // Indentazione out << _indent; // Apro riga del tag - out << "<" << (const char*)_name; + out << "<" << (_info_xml ? "?" : "") << _name; for (auto& it : _attributes) // Aggiungo eventuali attributi - out << " " << (const char*)it.first << "=\"" << (const char*)it.second << "\""; - out << ">"; - // Fine riga del tag + out << " " << it.first << "=\"" << it.second << "\""; // Stampo figli - if (!_childs.empty()) // O ha figli o ha tag con valore + if (!_info_xml && !_childs.empty()) // O ha figli o ha tag con valore { + out << ">"; + // Fine riga del tag + out << endl; for (auto& child : _childs) ok &= child->print_on_file(fout, deep + 1, _indent); for (int i = 0; i < deep; ++i) out << _indent; + out << "" << std::endl; + } + else if (!_info_xml) // Se non ho figli o ha il valore o e' solo attributi + { + if (!_value.empty() || _wvalue) // Ho il valore + { + out << ">"; + // Fine riga del tag + + if (!_value.empty()) + out << escape_chars(_value); + else if (_wvalue) + out << wchar_to_char(_wvalue); + // Chiudo tag + out << "" << std::endl; + } + else // Ho gli attributi (forse non e' detto, al massimo ho un tag vuoto) + out << " />" << std::endl; // Chiudo tag singolo } else - out << (const char*)_value; - - // Chiudo tag - out << "" << endl; + out << "?>" << endl; return ok; } @@ -101,22 +181,25 @@ void TXML_element::set_indentation(bool use_tab, short n_spaces) } } +void TXML_element::set_value(const TString& _Val) +{ + if (_value.empty()) + _value = _Val; +} + class TEsa_import_xml : public TXML_element { public: - void set_attributes(const TString& source, const TDate& creation_date, const TString& instance_guid, const TString& file_version); - TEsa_import_xml() : TXML_element("ESA_IMPORT") { } + void set_attributes(const TString& source, const TDate& creation_date, const TString& instance_guid, const TString& file_version) + { + add_attribute("Source", source); + add_attribute("CreationDate", creation_date.string(full, '/')); + add_attribute("InstanceGuid", instance_guid); + add_attribute("FileVersion", file_version); + } + TEsa_import_xml() : TXML_element("ESA_IMPORT", "") { } }; -void TEsa_import_xml::set_attributes(const TString& source, const TDate& creation_date, const TString& instance_guid, const TString& file_version) -{ - TString date(creation_date); date.replace('-', '/'); - add_attribute("Source", source); - add_attribute("CreationDate", date); - add_attribute("InstanceGuid", instance_guid); - add_attribute("FileVersion", file_version); -} - @@ -128,16 +211,16 @@ void TEsa_import_xml::set_attributes(const TString& source, const TDate& creatio class TFlexform_xml { protected: - TString _file_name; - ofstream* _fout; - TEsa_import_xml _esa_import; + TString _file_name; + ofstream* _fout; + TEsa_import_xml _esa_import; - static const char* generatre_GUID(); + static const char* generate_GUID(); void set_indentation(const bool use_tab, const short n_spaces) { _esa_import.set_indentation(use_tab, n_spaces); } virtual bool print() pure; public: - bool ok() const { return _fout != nullptr && _fout->is_open(); } + bool ok() const { return _fout != nullptr && _fout->is_open(); } TFlexform_xml(const char* xml_name = ""); virtual ~TFlexform_xml() { delete _fout; } @@ -161,13 +244,15 @@ class TOrdini_riga_xml : public TXML_element public: void set_datarow(const char* ind_tiporiga, const char* cod_art, const char* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6); - TOrdini_riga_xml() : TXML_element("OR_ORDINIR"), _datarow(nullptr), _tiporiga(nullptr), _art(nullptr), _des_articolo(nullptr), _merce(nullptr), _libero(nullptr) { } + TOrdini_riga_xml() : TXML_element("OR_ORDINIR", ""), _datarow(nullptr), _tiporiga(nullptr), _art(nullptr), _des_articolo(nullptr), _merce(nullptr), _libero(nullptr) { } ~TOrdini_riga_xml(); }; // Testata ////////////////////////////////////////////// class TOrdini_testata_xml : public TXML_element { + friend class TOrdini_riga_xml; + TXML_element* _datarow; // Figli di _datarow: campi della testata @@ -179,12 +264,12 @@ public: void add_row(TOrdini_riga_xml& riga) { add_child((TXML_element&)riga); } void set_testata(const char* data_doc, const char* num_doc, const char* str = "CCL"); - TOrdini_testata_xml() : TXML_element("OR_ORDINIT"), _datarow(nullptr), _dat_doc(nullptr), _des_num(nullptr), _sig_serie(nullptr) { } + TOrdini_testata_xml() : TXML_element("OR_ORDINIT", ""), _datarow(nullptr), _dat_doc(nullptr), _des_num(nullptr), _sig_serie(nullptr) { } ~TOrdini_testata_xml(); }; // TFlexform_xml_ordini ///////////////////////////////// -class TFlexform_xml_ordini : public TFlexform_xml +class TFlexform_xml_ordini final : public TFlexform_xml { TXML_element _ordine_impegno; // Unico ordine, figlio di _esa_import TOrdini_testata_xml _testata; // _testata contiene i dati di testata, piu' tutte gli ordini riga come figli, figlio di _ordine_impegno @@ -214,15 +299,17 @@ class TDDT_riga_xml : public TXML_element TXML_element* _libero; public: - void set_datarow(const char* ind_tiporiga, const char* cod_art, const char* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6); - TDDT_riga_xml() : TXML_element("MG_MOVMAGR"), _datarow(nullptr), _tiporiga(nullptr), _art(nullptr), - _des_articolo(nullptr), _merce(nullptr), _libero(nullptr) { } + void set_datarow(const char* ind_tiporiga, const char* cod_art, const char* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6); + void set_datarow(const char* ind_tiporiga, const char* cod_art, const wchar_t* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6); + + TDDT_riga_xml() : TXML_element("MG_MOVMAGR", ""), _datarow(nullptr), _tiporiga(nullptr), _art(nullptr), _des_articolo(nullptr), _merce(nullptr), _libero(nullptr) { } ~TDDT_riga_xml(); }; // Testata ////////////////////////////////////////////// class TDDT_testata_xml : public TXML_element { + friend class TDDT_riga_xml; TXML_element* _datarow; // Figli di _datarow: campi della testata @@ -233,7 +320,7 @@ public: void add_row(TDDT_riga_xml& riga) { add_child((TXML_element&)riga); } void set_testata(const char* data_doc, const char* num_doc); - TDDT_testata_xml() : TXML_element("MG_MOVMAGT"), _datarow(nullptr), _dat_doc(nullptr), _des_num(nullptr) { } + TDDT_testata_xml() : TXML_element("MG_MOVMAGT", ""), _datarow(nullptr), _dat_doc(nullptr), _des_num(nullptr) { } ~TDDT_testata_xml(); }; @@ -271,10 +358,10 @@ public: // Flexform export xml ///////////////////////////////////////////////////////// -const char* TFlexform_xml::generatre_GUID() +const char* TFlexform_xml::generate_GUID() { static TString _guid; - if(_guid.empty()) + if (_guid.empty()) { char cstr[39]; size_t chars; @@ -294,7 +381,8 @@ const char* TFlexform_xml::generatre_GUID() TFlexform_xml::TFlexform_xml(const char* xml_name) : _file_name(xml_name), _fout(nullptr) { - _esa_import.set_attributes(TConfig(CONFIG_DITTA, "Main").get("RAGSOC"), TDate(TODAY), generatre_GUID(), "1"); + // + _esa_import.set_attributes(TConfig(CONFIG_DITTA, "Main").get("RAGSOC"), TDate(TODAY), generate_GUID(), "1"); _esa_import.set_root(); _fout = new ofstream(xml_name); } @@ -306,7 +394,8 @@ TFlexform_xml::TFlexform_xml(const char* xml_name) : _file_name(xml_name), _fout void TOrdini_riga_xml::set_datarow(const char* ind_tiporiga, const char* cod_art, const char* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6) { - _datarow = new TXML_element("datarow"); add_child(*_datarow); + _datarow = new TXML_element("datarow", ""); add_child(*_datarow); + _tiporiga = new TXML_element("ind_tiporiga", ind_tiporiga); _datarow->add_child(*_tiporiga); _art = new TXML_element("cod_art", cod_art); _datarow->add_child(*_art); _des_articolo = new TXML_element("des_articolo_riga", des_articolo_riga); _datarow->add_child(*_des_articolo); @@ -328,10 +417,11 @@ TOrdini_riga_xml::~TOrdini_riga_xml() void TOrdini_testata_xml::set_testata(const char* data_doc, const char* num_doc, const char* str) { - _datarow = new TXML_element("datarow"); add_child(*_datarow); - _dat_doc = new TXML_element("dat_doc_esterno", data_doc); _datarow->add_child(*_dat_doc); - _des_num = new TXML_element("des_num_esterno", num_doc); _datarow->add_child(*_des_num); - _sig_serie = new TXML_element("sig_serie_esterno", str); _datarow->add_child(*_sig_serie); + _datarow = new TXML_element("datarow", ""); add_child(*_datarow); + + _dat_doc = new TXML_element("dat_doc_esterno", data_doc); _datarow->add_child(*_dat_doc); + _des_num = new TXML_element("des_num_esterno", num_doc); _datarow->add_child(*_des_num); + _sig_serie = new TXML_element("sig_serie_esterno", str); _datarow->add_child(*_sig_serie); } TOrdini_testata_xml::~TOrdini_testata_xml() @@ -353,7 +443,7 @@ bool TFlexform_xml_ordini::print() return ok; } -TFlexform_xml_ordini::TFlexform_xml_ordini(const char* xml_name) : TFlexform_xml(xml_name), _ordine_impegno("ORDINE_IMPEGNO") +TFlexform_xml_ordini::TFlexform_xml_ordini(const char* xml_name) : TFlexform_xml(xml_name), _ordine_impegno("ORDINE_IMPEGNO", "") { _ordine_impegno.add_attribute("TipoOperazione", "Insert"); _ordine_impegno.set_parent(_esa_import); @@ -368,10 +458,10 @@ TFlexform_xml_ordini::TFlexform_xml_ordini(const char* xml_name) : TFlexform_xml void TDDT_riga_xml::set_datarow(const char* ind_tiporiga, const char* cod_art, const char* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6) { - const TString _cod_art = cod_art; _cod_art.left(25); - const TString _desc = des_articolo_riga; _desc.left(255); - const TString _libero6 = des_campo_libero6; _libero6.left(30); - _datarow = new TXML_element("datarow"); add_child(*_datarow); + const TString _cod_art = cod_art; _cod_art.left(25); + const TString _desc = des_articolo_riga; _desc.left(255); + const TString _libero6 = des_campo_libero6; _libero6.left(30); + _datarow = new TXML_element("datarow", ""); add_child(*_datarow); _tiporiga = new TXML_element("ind_tiporiga", ind_tiporiga); _datarow->add_child(*_tiporiga); _art = new TXML_element("cod_art", (const char*)_cod_art); _datarow->add_child(*_art); _des_articolo = new TXML_element("des_articolo_riga", (const char*)_desc); _datarow->add_child(*_des_articolo); @@ -379,6 +469,18 @@ void TDDT_riga_xml::set_datarow(const char* ind_tiporiga, const char* cod_art, c _libero = new TXML_element("des_campo_libero6", (const char*)_libero6); _datarow->add_child(*_libero); } +void TDDT_riga_xml::set_datarow(const char* ind_tiporiga, const char* cod_art, const wchar_t* des_articolo_riga, const char* qta_merce, const char* des_campo_libero6) +{ + const TString _cod_art = cod_art; _cod_art.left(25); + const TString _libero6 = des_campo_libero6; _libero6.left(30); + _datarow = new TXML_element("datarow", ""); add_child(*_datarow); + _tiporiga = new TXML_element("ind_tiporiga", ind_tiporiga); _datarow->add_child(*_tiporiga); + _art = new TXML_element("cod_art", (const char*)_cod_art); _datarow->add_child(*_art); + _des_articolo = new TXML_element("des_articolo_riga", des_articolo_riga); _datarow->add_child(*_des_articolo); + _merce = new TXML_element("qta_merce", qta_merce); _datarow->add_child(*_merce); + _libero = new TXML_element("des_campo_libero6", (const char*)_libero6); _datarow->add_child(*_libero); +} + TDDT_riga_xml::~TDDT_riga_xml() { delete _datarow; @@ -393,8 +495,8 @@ TDDT_riga_xml::~TDDT_riga_xml() void TDDT_testata_xml::set_testata(const char* data_doc, const char* num_doc) { - _datarow = new TXML_element("datarow"); add_child(*_datarow); - _dat_doc = new TXML_element("dat_doc", data_doc); _datarow->add_child(*_dat_doc); + _datarow = new TXML_element("datarow", ""); add_child(*_datarow); + _dat_doc = new TXML_element("dat_doc", data_doc); _datarow->add_child(*_dat_doc); _des_num = new TXML_element("des_num_doc", num_doc); _datarow->add_child(*_des_num); } @@ -409,7 +511,7 @@ TDDT_testata_xml::~TDDT_testata_xml() int TFlexform_xml_ddt::add_doc() { - TXML_element* doc = new TXML_element("DOC_UNICO"); + TXML_element* doc = new TXML_element("DOC_UNICO", ""); _docs_unico.insert(_docs_unico.end(), doc); _docs_unico.back()->set_parent(_esa_import); TDDT_testata_xml* test = new TDDT_testata_xml; @@ -535,6 +637,7 @@ class TMajor_export_app : public TSkeleton_application bool create() override; static TFilename check_name_file(const TString& dir, bool sub_fld, int from, int to, bool ddt = true); + static const char* get_riferimento_flexform(const TSQL_recordset& righe_doc); static bool export_ddt(TMask& msk); static bool export_ordini() { return false; } void main_loop() override; @@ -581,6 +684,27 @@ TFilename TMajor_export_app::check_name_file(const TString& dir, const bool sub_ return xml; } +const char* TMajor_export_app::get_riferimento_flexform(const TSQL_recordset& righe_doc) +{ + const TString& rg1 = righe_doc.get(3).as_string(); + const TToken_string t(rg1, '\n'); + TString line; + for(int i = 0; i < t.items(); ++i) + { + t.get(i, line); + if (line.starts_with("RIFERIMENTO_FLEX")) + break; + line.cut(0); + } + if(line.full()) + { + TString rif(line.sub(line.find('=') + 1)); + rif.trim(); + return rif; + } + return ""; +} + bool TMajor_export_app::export_ddt(TMask& msk) { const TString& dir = msk.get(F_FLDDEST); @@ -595,7 +719,7 @@ bool TMajor_export_app::export_ddt(TMask& msk) return false; TFlexform_xml_ddt ddt(xml); TString query_doc; - query_doc << "SELECT * FROM doc WHERE CODNUM = \"" << codnum << "\" AND ANNO == " << year << " AND PROVV == \"D\" AND NDOC >= " << from << " AND NDOC <= " << to; + query_doc << "SELECT DATADOC, NDOC FROM doc WHERE CODNUM = '" << codnum << "' AND ANNO = " << year << " AND PROVV = 'D' AND NDOC >= " << from << " AND NDOC <= " << to; TSQL_recordset doc(query_doc); TProgress_monitor bar(doc.items(), "Esportazione ddt"); @@ -604,22 +728,26 @@ bool TMajor_export_app::export_ddt(TMask& msk) if (!bar.add_status()) break; ddt.add_doc(); - TFormatted_date day(doc.get(doc.find_column(DOC_DATADOC)).as_date()); day.set_format("1444/"); - const TString& n_doc = doc.get(doc.find_column(DOC_NDOC)).as_string(); + TFormatted_date day(doc.get(0).as_date()); day.set_format("1444/"); + const TString& n_doc = doc.get(1).as_string(); ddt.set_testata(day.string(), n_doc); // Righe documento - TString query_righe; query_righe << "SELECT * FROM rdoc WHERE CODNUM = \"" << codnum << "\" AND ANNO == " << year << " AND PROVV == \"D\" AND NDOC=" << n_doc; - TSQL_recordset righe_doc(query_righe); + TString query_righe; + query_righe << "SELECT CODART, DESCR, QTA, RG1, DESCLUNGA, DESCEST\n" + "FROM rdoc\nWHERE CODNUM = '" << codnum << "' AND ANNO = " << year << " AND PROVV = 'D' AND NDOC=" << n_doc; + TSQL_recordset righe_doc(query_righe); for (bool ok_r = righe_doc.move_first(); ok_r; ok_r = righe_doc.move_next()) { - TDDT_riga_xml* riga = ddt.new_row(); - const TString& cod_art = righe_doc.get(righe_doc.find_column(RDOC_CODART)).as_string(); - TString descr = righe_doc.get(righe_doc.find_column(RDOC_DESCR)).as_string(); - if (righe_doc.get(righe_doc.find_column(RDOC_DESCLUNGA)).as_bool()) - descr << righe_doc.get(righe_doc.find_column(RDOC_DESCEST)).as_string(); - const TString& qta = righe_doc.get(righe_doc.find_column(RDOC_QTA)).as_string(); + TDDT_riga_xml* riga = ddt.new_row(); - riga->set_datarow("C", cod_art, descr, qta, ""); + const TString& cod_art = righe_doc.get(0).as_string(); + TString descr = righe_doc.get(1).as_string(); + const TString& qta = righe_doc.get(2).as_string(); + TString desccampolibero6 = get_riferimento_flexform(righe_doc); // get(3) RG1 + if (righe_doc.get(4).as_bool()) + descr << righe_doc.get(5).as_string(); + + riga->set_datarow("C", cod_art, descr, qta, desccampolibero6); ddt.add_row(riga); } }