Patch level : 12.0 no-patch

Files correlati     : ps6362.exe
Commento            :
- Personalizzazione Major:
- Migliorata leggibilita' codice
- Spostate classi in file separati
This commit is contained in:
Simone Palacino 2020-03-05 10:44:33 +01:00
parent 5f538a66b2
commit f9a77b4736
7 changed files with 649 additions and 557 deletions

View File

@ -160,12 +160,16 @@
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\ps\flexform_xml.h" />
<ClInclude Include="..\src\ps\ps6362.h" />
<ClInclude Include="..\src\ps\ps6362100a.h" />
<ClInclude Include="..\src\ps\xml_element.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\ps\flexform_xml.cpp" />
<ClCompile Include="..\src\ps\ps6362.cpp" />
<ClCompile Include="..\src\ps\ps6362100.cpp" />
<ClCompile Include="..\src\ps\xml_element.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\src\ps\ps6362100a.uml">

View File

@ -24,6 +24,12 @@
<ClCompile Include="..\src\ps\ps6362.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\ps\xml_element.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\ps\flexform_xml.cpp">
<Filter>Sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\ps\ps6362.h">
@ -32,6 +38,12 @@
<ClInclude Include="..\src\ps\ps6362100a.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="..\src\ps\flexform_xml.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="..\src\ps\xml_element.h">
<Filter>Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\src\ps\ps6362100a.uml">

224
src/ps/flexform_xml.cpp Normal file
View File

@ -0,0 +1,224 @@
#include <rpc.h>
#include <rpcdce.h>
#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 Source=? CreationDate=? InstanceGuid=? FileVersion="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);
}
///////////////////////////////////////////////////////////
// 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"(<?xml version="1.0" encoding="UTF-8"?>)" << 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"(<?xml version="1.0" encoding="UTF-8"?>)" << 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);
}

208
src/ps/flexform_xml.h Normal file
View File

@ -0,0 +1,208 @@
#ifndef __MAJORXML_H__
#define __MAJORXML_H__
#include <vector>
#include <fstream>
#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<TXML_element*> _docs_unico; // Tanti doc_unico, figli di _esa_import
vector<TDDT_testata_xml*> _testate; // _testata contiene i dati di testata, piu' tutte gli ordini riga come figli
vector<TDDT_riga_xml*> _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__

View File

@ -1,564 +1,13 @@
#include <rpc.h>
#include <rpcdce.h>
#include <applicat.h>
#include <automask.h>
#include "ps6362.h"
#include "ps6362100a.h"
#include <vector>
#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 == "&amp;")
i += 4;
}
text << "&amp;";
}
}
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) == "&amp;")
i += 4;
text << "&amp;";
}
}
return text;
}
///////////////////////////////////////////////////////////
// TXML_element
///////////////////////////////////////////////////////////
#define XML_ROOT_TAG nullptr
class TXML_element
{
vector<pair<TString, TString>> _attributes{};
vector<TXML_element*> _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 << "</" << _name << ">" << 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 << "</" << _name << ">" << 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<TXML_element*> _docs_unico; // Tanti doc_unico, figli di _esa_import
vector<TDDT_testata_xml*> _testate; // _testata contiene i dati di testata, piu' tutte gli ordini riga come figli
vector<TDDT_riga_xml*> _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 Source=? CreationDate=? InstanceGuid=? FileVersion="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);
}
/////////////////////////////////////////////////////////
// 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"(<?xml version="1.0" encoding="UTF-8"?>)" << 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"(<?xml version="1.0" encoding="UTF-8"?>)" << 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"
///////////////////////////////////////////////////////////

147
src/ps/xml_element.cpp Normal file
View File

@ -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 << "</" << _name << ">" << 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 << "</" << _name << ">" << 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 == "&amp;")
i += 4;
}
text << "&amp;";
}
}
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) == "&amp;")
i += 4;
text << "&amp;";
}
}
return text;
}

48
src/ps/xml_element.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __XMLELEMENT_H__
#define __XMLELEMENT_H__
#include <vector>
#include "strings.h"
#define XML_ROOT_TAG nullptr
/**
* \brief Elemento base xml.
*/
class TXML_element
{
vector<pair<TString, TString>> _attributes{};
vector<TXML_element*> _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__