From f9a77b4736c5ee37232429a372ca94a388a18581 Mon Sep 17 00:00:00 2001 From: Simone Palacino Date: Thu, 5 Mar 2020 10:44:33 +0100 Subject: [PATCH] Patch level : 12.0 no-patch Files correlati : ps6362.exe Commento : - Personalizzazione Major: - Migliorata leggibilita' codice - Spostate classi in file separati --- build/ps6362.vcxproj | 4 + build/ps6362.vcxproj.filters | 12 + src/ps/flexform_xml.cpp | 224 ++++++++++++++ src/ps/flexform_xml.h | 208 +++++++++++++ src/ps/ps6362100.cpp | 563 +---------------------------------- src/ps/xml_element.cpp | 147 +++++++++ src/ps/xml_element.h | 48 +++ 7 files changed, 649 insertions(+), 557 deletions(-) create mode 100644 src/ps/flexform_xml.cpp create mode 100644 src/ps/flexform_xml.h create mode 100644 src/ps/xml_element.cpp create mode 100644 src/ps/xml_element.h diff --git a/build/ps6362.vcxproj b/build/ps6362.vcxproj index bd955d4c3..e785d7503 100644 --- a/build/ps6362.vcxproj +++ b/build/ps6362.vcxproj @@ -160,12 +160,16 @@ + + + + diff --git a/build/ps6362.vcxproj.filters b/build/ps6362.vcxproj.filters index 1fbd269f4..dcbed6cee 100644 --- a/build/ps6362.vcxproj.filters +++ b/build/ps6362.vcxproj.filters @@ -24,6 +24,12 @@ Sources + + Sources + + + Sources + @@ -32,6 +38,12 @@ Headers + + Headers + + + Headers + diff --git a/src/ps/flexform_xml.cpp b/src/ps/flexform_xml.cpp new file mode 100644 index 000000000..9865a39ff --- /dev/null +++ b/src/ps/flexform_xml.cpp @@ -0,0 +1,224 @@ +#include +#include + +#include "flexform_xml.h" +#include "config.h" +#include "date.h" + + +/////////////////////////////////////////////////////////// +// ELEMENTI DDT +/////////////////////////////////////////////////////////// + +// Testata DDT + +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); + _des_num = new TXML_element("des_num_doc", num_doc); _datarow->add_child(*_des_num); +} + +TDDT_testata_xml::~TDDT_testata_xml() +{ + delete _datarow; + delete _dat_doc; + delete _des_num; +} + +// Riga DDT + +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); + _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); + _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); +} + +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; + delete _tiporiga; + delete _art; + delete _des_articolo; + delete _merce; + delete _libero; +} + + +/////////////////////////////////////////////////////////// +// ELEMENTI ORDINI +/////////////////////////////////////////////////////////// + +// Testata Ordini + +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); +} + +TOrdini_testata_xml::~TOrdini_testata_xml() +{ + delete _datarow; + delete _dat_doc; + delete _des_num; + delete _sig_serie; +} + + +// Riga Ordini + +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); + + _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); + _merce = new TXML_element("qta_merce", qta_merce); _datarow->add_child(*_merce); + _libero = new TXML_element("des_campo_libero6", des_campo_libero6); _datarow->add_child(*_libero); +} + +TOrdini_riga_xml::~TOrdini_riga_xml() +{ + delete _datarow; + delete _tiporiga; + delete _art; + delete _des_articolo; + delete _merce; + delete _libero; +} + + + +/////////////////////////////////////////////////////////// +// Flexform xml export +/////////////////////////////////////////////////////////// + +const char* TFlexform_xml::generate_GUID() +{ + static TString _guid; + if (_guid.empty()) + { + char cstr[39]; + size_t chars; + GUID uuid; + if (UuidCreate(&uuid) == RPC_S_OK) + { + LPOLESTR lpsz; + StringFromCLSID(uuid, &lpsz); + wcstombs_s(&chars, cstr, lpsz, wcslen(lpsz)); + _guid = cstr; + } + else + _guid = ""; + } + return _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), generate_GUID(), "1"); + _esa_import.set_root(); + _fout = new ofstream(xml_name); +} + + +/////////////////////////////////////////////////////////// +// Flexform DDT export +/////////////////////////////////////////////////////////// + +int TFlexform_xml_ddt::add_doc() +{ + 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; + _testate.insert(_testate.end(), test); + _testate.back()->set_parent(*_docs_unico.back()); + return _docs_unico.size(); +} + +int TFlexform_xml_ddt::add_row(TDDT_riga_xml* riga, int which_doc) +{ + int i = which_doc < 0 ? (int)_testate.size() - 1 : which_doc; + if (!_testate.empty() && i < (int)_testate.size()) + riga->set_parent(*_testate[i]); + else + i = -1; + return i; +} + +bool TFlexform_xml_ddt::print() +{ + ofstream& out = *_fout; + out << R"()" << endl; + const bool ok = _esa_import.print_on_file(_fout); + _fout->close(); + return ok; +} + +int TFlexform_xml_ddt::set_testata(const char* data_doc, const char* num_doc, const int which_doc) +{ + int i = which_doc < 0 ? (int)_testate.size() - 1 : which_doc; + if (!_testate.empty() && i < (int)_testate.size()) + _testate[i]->set_testata(data_doc, num_doc); + else + i = -1; + return i; +} + +TFlexform_xml_ddt::~TFlexform_xml_ddt() +{ + for (auto doc : _docs_unico) + delete doc; + for (auto testata : _testate) + delete testata; + for (auto row : _rows) + delete row; +} + + +/////////////////////////////////////////////////////////// +// Flexform Ordini export +/////////////////////////////////////////////////////////// + +bool TFlexform_xml_ordini::print() +{ + ofstream& out = *_fout; + out << R"()" << endl; + const bool ok = _esa_import.print_on_file(_fout); + _fout->close(); + return ok; +} + +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); + _testata.set_parent(_ordine_impegno); + _fout = new ofstream(_file_name); +} diff --git a/src/ps/flexform_xml.h b/src/ps/flexform_xml.h new file mode 100644 index 000000000..9f76fb000 --- /dev/null +++ b/src/ps/flexform_xml.h @@ -0,0 +1,208 @@ +#ifndef __MAJORXML_H__ +#define __MAJORXML_H__ + +#include +#include + +#include "strings.h" +#include "stdtypes.h" +#include "xml_element.h" +#include "date.h" + +#define XML_ESCAPE_CHAR '&' + +/////////////////////////////////////////////////////////// +// TEsa_import_xml +/////////////////////////////////////////////////////////// + +/** + * \brief \a TXML_element Contenitore Importazione Flexform. + */ +struct TEsa_import_xml : TXML_element +{ + 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", "") { } +}; + + + + +/////////////////////////////////////////////////////////// +// ELEMENTI DDT +/////////////////////////////////////////////////////////// + +/** + * \brief \a TXML_element Testata DDT. + */ +class TDDT_testata_xml : public TXML_element +{ + friend class TDDT_riga_xml; + TXML_element* _datarow; + + // Figli di _datarow: campi della testata + + TXML_element* _dat_doc; + TXML_element* _des_num; +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(); +}; + +/** + * \brief \a TXML_element Riga DDT. + */ +class TDDT_riga_xml : public TXML_element +{ + TXML_element* _datarow; // Unico figlio di OR_ORDINIR contenenti i campi campi dell'ordine + + // Figli di _datarow: campi dell'ordine + + TXML_element* _tiporiga; + TXML_element* _art; + TXML_element* _des_articolo; + TXML_element* _merce; + 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); + 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(); +}; + + + +/////////////////////////////////////////////////////////// +// ELEMENTI ORDINI +/////////////////////////////////////////////////////////// + +/** + * \brief \a TXML_element Testata Ordine. + */ +class TOrdini_testata_xml : public TXML_element +{ + friend class TOrdini_riga_xml; + + TXML_element* _datarow; + + // Figli di _datarow: campi della testata + + TXML_element* _dat_doc; + TXML_element* _des_num; + TXML_element* _sig_serie; +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(); +}; + +/** + * \brief \a TXML_element Riga Ordine. + */ +class TOrdini_riga_xml : public TXML_element +{ + TXML_element* _datarow; // Unico figlio di OR_ORDINIR contenenti i campi campi dell'ordine + + // Figli di _datarow: campi dell'ordine + + TXML_element* _tiporiga; + TXML_element* _art; + TXML_element* _des_articolo; + TXML_element* _merce; + 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); + TOrdini_riga_xml() : TXML_element("OR_ORDINIR", ""), _datarow(nullptr), _tiporiga(nullptr), _art(nullptr), _des_articolo(nullptr), _merce(nullptr), _libero(nullptr) { } + ~TOrdini_riga_xml(); +}; + + + + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +// Flexform export xml +/////////////////////////////////////////////////////////// + +/** + * \brief Main FLEXFORM XML Class. + */ +class TFlexform_xml +{ +protected: + TString _file_name; + ofstream* _fout; + TEsa_import_xml _esa_import; + + 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(); } + + TFlexform_xml(const char* xml_name = ""); + virtual ~TFlexform_xml() { delete _fout; } +}; + + +/** + * \brief Esportatore XML DDT Flexform. + */ +class TFlexform_xml_ddt final : public TFlexform_xml +{ + vector _docs_unico; // Tanti doc_unico, figli di _esa_import + vector _testate; // _testata contiene i dati di testata, piu' tutte gli ordini riga come figli + + vector _rows; +public: + int add_doc(); + /** Aggiungo la riga al documento n. \a which_riga, altrimenti se non specificato mette sull'ultimo doc presente. + * \returns indice documento in cui e' stata inserita la riga. + * \returns -1 se non e' mai stato inserito alcun documento o l'indice (\a which_doc) non e' corretto. + */ + int add_row(TDDT_riga_xml* riga, int which_doc = -1); + bool print() override; + TDDT_riga_xml* new_row() { _rows.push_back(new TDDT_riga_xml); return _rows.back(); } + + /** Setto testata al documento n. \a which_riga, altrimenti se non specificato setta l'ultimo doc presente. + * \returns indice documento settato. + * \returns -1 se non e' mai stato inserito alcun documento o l'indice (\a which_doc) non e' corretto. + */ + int set_testata(const char* data_doc, const char* num_doc, int which_doc = -1); + + TFlexform_xml_ddt(const char* xml_name = "") : TFlexform_xml(xml_name) { } + ~TFlexform_xml_ddt(); +}; + + +/** + * \brief Esportatore XML Ordini Flexform. + */ +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 + +public: + void add_row(TOrdini_riga_xml* riga) { riga->set_parent(_testata); } + bool print() override; + void set_testata(const char* data_doc, const char* num_doc, const char* str) { _testata.set_testata(data_doc, num_doc, str); } + + TFlexform_xml_ordini(const char* xml_name = ""); +}; + +#endif // __MAJORXML_H__ \ No newline at end of file diff --git a/src/ps/ps6362100.cpp b/src/ps/ps6362100.cpp index a5795cc13..ca49ed6bc 100644 --- a/src/ps/ps6362100.cpp +++ b/src/ps/ps6362100.cpp @@ -1,564 +1,13 @@ -#include -#include -#include -#include #include "ps6362.h" #include "ps6362100a.h" -#include -#include "tabutil.h" -#include "sqlset.h" -#include "progind.h" -#define XML_ESCAPE_CHAR '&' +#include "applicat.h" +#include "automask.h" +#include "tabutil.h" // TTable +#include "sqlset.h" // TSQL_recordset +#include "progind.h" // TProgress_monitor -/////////////////////////////////////////////////////////// -// 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 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 TString& _Val) { _attributes.insert(_attributes.end(), { _Tag, _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 = ""); - - /** Imposta tab (use_tab = true) o spazi (false). Se spazi indicare n_spazi (1 - 8): se non specificato o troppo grande sara' di 4; */ - void set_indentation(bool use_tab, short n_spaces = -1); - 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 = "", 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 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 << "<" << (_info_xml ? "?" : "") << _name; - for (auto& it : _attributes) // Aggiungo eventuali attributi - out << " " << it.first << "=\"" << it.second << "\""; - - // Stampo figli - 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 << "?>" << endl; - return ok; -} - -void TXML_element::set_indentation(bool use_tab, short n_spaces) -{ - if (use_tab) - _indent = "\t"; - else - { - const short to = n_spaces > 0 && n_spaces <= 8 ? n_spaces : (short)4; - _indent.cut(0); - for (short i = 0; i < to; ++i) - _indent << " "; - } -} - -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) - { - 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", "") { } -}; - - - - -///////////////////////////////////////////////////////// -///////////////////////////////////////////////////////// -// Flexform export xml -///////////////////////////////////////////////////////// - -class TFlexform_xml -{ -protected: - TString _file_name; - ofstream* _fout; - TEsa_import_xml _esa_import; - - 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(); } - - TFlexform_xml(const char* xml_name = ""); - virtual ~TFlexform_xml() { delete _fout; } -}; - -///////////////////////////////////////////////////////// -// ORDINI -///////////////////////////////////////////////////////// -// Riga ///////////////////////////////////////////////// -class TOrdini_riga_xml : public TXML_element -{ - TXML_element* _datarow; // Unico figlio di OR_ORDINIR contenenti i campi campi dell'ordine - - // Figli di _datarow: campi dell'ordine - - TXML_element* _tiporiga; - TXML_element* _art; - TXML_element* _des_articolo; - TXML_element* _merce; - 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); - 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 - - TXML_element* _dat_doc; - TXML_element* _des_num; - TXML_element* _sig_serie; -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(); -}; - -// TFlexform_xml_ordini ///////////////////////////////// -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 - -public: - void add_row(TOrdini_riga_xml* riga) { riga->set_parent(_testata); } - bool print() override; - void set_testata(const char* data_doc, const char* num_doc, const char* str) { _testata.set_testata(data_doc, num_doc, str); } - - TFlexform_xml_ordini(const char* xml_name = ""); -}; - -///////////////////////////////////////////////////////// -// DDT -///////////////////////////////////////////////////////// -// Riga ///////////////////////////////////////////////// -class TDDT_riga_xml : public TXML_element -{ - TXML_element* _datarow; // Unico figlio di OR_ORDINIR contenenti i campi campi dell'ordine - - // Figli di _datarow: campi dell'ordine - - TXML_element* _tiporiga; - TXML_element* _art; - TXML_element* _des_articolo; - TXML_element* _merce; - 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); - 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 - - TXML_element* _dat_doc; - TXML_element* _des_num; -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(); -}; - -// TFlexform_xml_ddt /////////////////////////////////////// -class TFlexform_xml_ddt final : public TFlexform_xml -{ - vector _docs_unico; // Tanti doc_unico, figli di _esa_import - vector _testate; // _testata contiene i dati di testata, piu' tutte gli ordini riga come figli - - vector _rows; -public: - int add_doc(); - /** Aggiungo la riga al documento n. \a which_riga, altrimenti se non specificato mette sull'ultimo doc presente. - * \returns indice documento in cui e' stata inserita la riga. - * \returns -1 se non e' mai stato inserito alcun documento o l'indice (\a which_doc) non e' corretto. - */ - int add_row(TDDT_riga_xml* riga, int which_doc = -1); - bool print() override; - TDDT_riga_xml* new_row() { _rows.push_back(new TDDT_riga_xml); return _rows.back(); } - - /** Setto testata al documento n. \a which_riga, altrimenti se non specificato setta l'ultimo doc presente. - * \returns indice documento settato. - * \returns -1 se non e' mai stato inserito alcun documento o l'indice (\a which_doc) non e' corretto. - */ - int set_testata(const char* data_doc, const char* num_doc, int which_doc = -1); - - TFlexform_xml_ddt(const char* xml_name = "") : TFlexform_xml(xml_name) { } - ~TFlexform_xml_ddt(); -}; - - - -// Definizioni -///////////////////////////////////////////////////////// -// Flexform export xml -///////////////////////////////////////////////////////// - -const char* TFlexform_xml::generate_GUID() -{ - static TString _guid; - if (_guid.empty()) - { - char cstr[39]; - size_t chars; - GUID uuid; - if (UuidCreate(&uuid) == RPC_S_OK) - { - LPOLESTR lpsz; - StringFromCLSID(uuid, &lpsz); - wcstombs_s(&chars, cstr, lpsz, wcslen(lpsz)); - _guid = cstr; - } - else - _guid = ""; - } - return _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), generate_GUID(), "1"); - _esa_import.set_root(); - _fout = new ofstream(xml_name); -} - -///////////////////////////////////////////////////////// -// ORDINI -///////////////////////////////////////////////////////// -// Righe //////////////////////////////////////////////// - -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); - - _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); - _merce = new TXML_element("qta_merce", qta_merce); _datarow->add_child(*_merce); - _libero = new TXML_element("des_campo_libero6", des_campo_libero6); _datarow->add_child(*_libero); -} - -TOrdini_riga_xml::~TOrdini_riga_xml() -{ - delete _datarow; - delete _tiporiga; - delete _art; - delete _des_articolo; - delete _merce; - delete _libero; -} - -// Testata ////////////////////////////////////////////// - -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); -} - -TOrdini_testata_xml::~TOrdini_testata_xml() -{ - delete _datarow; - delete _dat_doc; - delete _des_num; - delete _sig_serie; -} - -// TFlexform_xml_ordini ///////////////////////////////// - -bool TFlexform_xml_ordini::print() -{ - ofstream& out = *_fout; - out << R"()" << endl; - const bool ok = _esa_import.print_on_file(_fout); - _fout->close(); - return ok; -} - -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); - _testata.set_parent(_ordine_impegno); - _fout = new ofstream(_file_name); -} - -///////////////////////////////////////////////////////// -// DDT -///////////////////////////////////////////////////////// -// Riga ///////////////////////////////////////////////// - -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); - _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); - _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); -} - -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; - delete _tiporiga; - delete _art; - delete _des_articolo; - delete _merce; - delete _libero; -} - -// Testata ////////////////////////////////////////////// - -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); - _des_num = new TXML_element("des_num_doc", num_doc); _datarow->add_child(*_des_num); -} - -TDDT_testata_xml::~TDDT_testata_xml() -{ - delete _datarow; - delete _dat_doc; - delete _des_num; -} - -// TFlexform_xml_ddt /////////////////////////////////////// - -int TFlexform_xml_ddt::add_doc() -{ - 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; - _testate.insert(_testate.end(), test); - _testate.back()->set_parent(*_docs_unico.back()); - return _docs_unico.size(); -} - -int TFlexform_xml_ddt::add_row(TDDT_riga_xml* riga, int which_doc) -{ - int i = which_doc < 0 ? (int)_testate.size() - 1 : which_doc; - if (!_testate.empty() && i < (int)_testate.size()) - riga->set_parent(*_testate[i]); - else - i = -1; - return i; -} - -bool TFlexform_xml_ddt::print() -{ - ofstream& out = *_fout; - out << R"()" << endl; - const bool ok = _esa_import.print_on_file(_fout); - _fout->close(); - return ok; -} - -int TFlexform_xml_ddt::set_testata(const char* data_doc, const char* num_doc, const int which_doc) -{ - int i = which_doc < 0 ? (int)_testate.size() - 1 : which_doc; - if (!_testate.empty() && i < (int)_testate.size()) - _testate[i]->set_testata(data_doc, num_doc); - else - i = -1; - return i; -} - -TFlexform_xml_ddt::~TFlexform_xml_ddt() -{ - for (auto doc : _docs_unico) - delete doc; - for (auto testata : _testate) - delete testata; - for (auto row : _rows) - delete row; -} -/////////////////////////////////////////////////////////// +#include "flexform_xml.h" /////////////////////////////////////////////////////////// diff --git a/src/ps/xml_element.cpp b/src/ps/xml_element.cpp new file mode 100644 index 000000000..788dcfe1d --- /dev/null +++ b/src/ps/xml_element.cpp @@ -0,0 +1,147 @@ +#include "xml_element.h" + +#define XML_ESCAPE_CHAR '&' + +// Utils + +const char* wchar_to_char(const wchar_t* str); +TString escape_chars (const TString& str); + +/////////////////////////////////////////////////////////// +// TXML_element +/////////////////////////////////////////////////////////// + +bool TXML_element::print_on_file(ofstream* fout, const int deep, const char* 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 << "<" << (_info_xml ? "?" : "") << _name; + for (auto& it : _attributes) // Aggiungo eventuali attributi + out << " " << it.first << "=\"" << it.second << "\""; + + // Stampo figli + 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 << "" << 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 << "" << endl; + } + else // Ho gli attributi (forse non e' detto, al massimo ho un tag vuoto) + out << " />" << endl; // Chiudo tag singolo + } + else + out << "?>" << endl; + return ok; +} + +void TXML_element::set_indentation(bool use_tab, short n_spaces) +{ + if (use_tab) + _indent = "\t"; + else + { + const short to = n_spaces > 0 && n_spaces <= 8 ? n_spaces : (short)4; + _indent.cut(0); + for (short i = 0; i < to; ++i) + _indent << " "; + } +} + +void TXML_element::set_value(const TString& _Val) +{ + if (_value.empty()) + _value = _Val; +} + + + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +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; +} \ No newline at end of file diff --git a/src/ps/xml_element.h b/src/ps/xml_element.h new file mode 100644 index 000000000..2f003f00e --- /dev/null +++ b/src/ps/xml_element.h @@ -0,0 +1,48 @@ +#ifndef __XMLELEMENT_H__ +#define __XMLELEMENT_H__ + +#include +#include "strings.h" + +#define XML_ROOT_TAG nullptr + +/** + * \brief Elemento base 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 TString& _Val) { _attributes.insert(_attributes.end(), { _Tag, _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 = ""); + + /** Imposta tab (use_tab = true) o spazi (false). Se spazi indicare n_spazi (1 - 8): se non specificato o troppo grande sara' di 4; */ + void set_indentation(bool use_tab, short n_spaces = -1); + 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 = "", 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) { } +}; + +#endif // __XMLELEMENT_H__ \ No newline at end of file