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
This commit is contained in:
Simone Palacino 2020-03-05 10:35:57 +01:00
parent 93679c4300
commit 5f538a66b2

View File

@ -1,41 +1,99 @@
#include <rpc.h>
#include <rpcdce.h>
#include <comdef.h>
#include <applicat.h>
#include <automask.h>
#include <tsdb.h>
#include <relation.h>
#include "ps6362.h"
#include "ps6362100a.h"
#include <vector>
#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 == "&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 TFlexform_xml_ordini;
class TOrdini_riga_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 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 << "</" << _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 << (const char*)_value;
// Chiudo tag
out << "</" << (const char*)_name << ">" << 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 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);
}
@ -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);
}
}