Patch level : 12.0 no-patch

Files correlati     : ps
Commento            :

Import ordini export bolle Major Flexform
This commit is contained in:
Alessandro Bonazzi 2020-11-25 19:32:22 +01:00
parent 1085a270cd
commit 09aab17a34
21 changed files with 411 additions and 1391 deletions

View File

@ -1,199 +1,126 @@
#include "flexform_xml.h"
#include <stack>
#include <config.h>
#include <date.h>
#include <lffiles.h>
#include <progind.h>
#include <reputils.h>
#include "config.h"
#include "date.h"
#include "progind.h"
#include "velib.h"
#include "sqlset.h"
#define CHECK_CONDXML_OR_RETURNFALSE(cond, msg) { \
TString str; \
if (!(cond)) { \
str << "Errore nella lettura dell'xml: " << (msg); \
warning_box(str); \
return false; } }
#define CHECK_NAMETAG_OR_RETURNFALSE(xml_element, name_tag) { \
TString name; name << (name_tag); \
TString msg; msg << "mi aspettavo di trovare il tag: " << name; \
CHECK_CONDXML_OR_RETURNFALSE((xml_element)->get_name() == name, msg); }
//if ((xml_element)->get_name() != name) { \
// msg.cut(0) << "Errore nella lettura dell'xml:" << name; \
// warning_box(msg); \
// return false; } }
///////////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////////
TFlexform_xml::TFlexform_xml(const char* xml_name, bool to_export) : _file_name(xml_name), _fout(nullptr), _export(to_export)
{
_esa_import.set_root();
if (_export)
_fout = new ofstream(xml_name);
else
_fin = new ifstream(xml_name);
}
#include "../ve/velib04.h"
#define RDOC_RIFFLEX "RIFFLEX"
///////////////////////////////////////////////////////////
// Flexform DDT export
///////////////////////////////////////////////////////////
int TFlexform_xml_ddt::add_doc()
{
const shared_ptr<TXML_element> doc = make_shared<TXML_element>("DOC_UNICO", "");
const shared_ptr<TDDT_testata_xml> test = make_shared<TDDT_testata_xml>();
_docs_unico.insert(_docs_unico.end(), doc);
_docs_unico.back()->set_parent(_esa_import);
_testate.insert(_testate.end(), test);
_testate.back()->set_parent(*_docs_unico.back());
return _docs_unico.size();
}
int TFlexform_xml_ddt::add_row(const shared_ptr<TDDT_riga_xml>& riga, const int which_doc)
void TFlexform_xml_ddt::add_row(TXmlItem & outdoc, const TRiga_documento & rdoc, TLog_report * log)
{
int i = which_doc < 0 ? (int)_testate.size() - 1 : which_doc;
if (!_testate.empty() && i < (int)_testate.size())
riga->set_parent(*_testate[i]);
const TString cod_art = rdoc.get(RDOC_CODARTMAG); // Codice Flexform.
const TArticolo & art = cached_article(cod_art);
const TString cod_art_flex = art.get(ANAMAG_CODPMS);
TString descr = rdoc.get(RDOC_DESCR);
const TString num_ordine = rdoc.get(RDOC_NDOC);
const int nrow = rdoc.get_int(RDOC_NRIGA);
TToken_string refs(rdoc.get(RDOC_ORIGINAL_ROWS), ',');
TToken_string ref_qta(rdoc.get(RDOC_ORIGINAL_QTAROWS), ',');
TString_array ref_rows;
ref_rows.tok2arr(refs);
if (rdoc.sola_descrizione())
{
TXmlItem & row = outdoc.AddChild("MG_MOVMAGR");
TXmlItem & datarow = row.AddChild("datarow");
datarow.AddEnclosedText("ind_tiporiga", rdoc.tipo().is_descrizione() ? "D" : "A");
if (rdoc.get_bool(RDOC_DESCLUNGA))
descr << rdoc.get(RDOC_DESCEST);
datarow.AddEnclosedText("des_articolo_riga", descr);
}
else
i = -1;
return i;
{
FOR_EACH_ARRAY_ROW(ref_rows, r, tok)
{
TXmlItem & row = outdoc.AddChild("MG_MOVMAGR");
TXmlItem & datarow = row.AddChild("datarow");
datarow.AddEnclosedText("ind_tiporiga", rdoc.tipo().is_descrizione() ? "D" : "A");
if (rdoc.get_bool(RDOC_DESCLUNGA))
descr << rdoc.get(RDOC_DESCEST);
datarow.AddEnclosedText("des_articolo_riga", descr);
if (cod_art_flex.full())
{
TString msg = TR("Articolo : ");
msg << cod_art << TR(" codificato come : ") << cod_art_flex;
MSG_ARTICOLO(num_ordine, nrow, msg, false)
}
else
{
TString msg = TR("Codice articolo flexform non trovato per l'articolo :");
msg << cod_art;
MSG_ARTICOLO(num_ordine, nrow, msg, true)
}
datarow.AddEnclosedText("cod_art", cod_art_flex);
datarow.AddEnclosedText("qta_merce", ref_qta.get());
// datarow.AddEnclosedText("qta_merce", rdoc.get(RDOC_QTA));
const TRectype & rdoc_ref = cache().get(LF_RIGHEDOC, *tok); // ORC | 2020 | D | 3 | 8
TRecfield riffld((TRectype &) rdoc_ref, "RG1:" RDOC_RIFFLEX);
const TString riford = (const char *)riffld;
datarow.AddEnclosedText("des_campo_libero6", riford);
}
}
}
bool TFlexform_xml_ddt::print()
void TFlexform_xml_ddt::add_doc(const TDocumento & doc, TLog_report * log)
{
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;
TXmlItem & ddt = AddChild("DOC_UNICO");
TXmlItem & testata = ddt.AddChild("MG_MOVMAGT");
TXmlItem & datarowt = testata.AddChild("datarow");
TFormatted_date datadoc = doc.get_date(DOC_DATADOC); datadoc.set_format("1444/");
TString msg(TR("Esportazione")); msg << doc.get_long(DOC_NDOC);
XML_MSG(msg);
datarowt.AddEnclosedText("dat_doc", datadoc.string());
datarowt.AddEnclosedText("des_num_doc", doc.get(DOC_NDOC));
FOR_EACH_RDOC(doc, i, rdoc)
add_row(testata, *rdoc, log);
}
int TFlexform_xml_ddt::set_testata(const char* data_doc, const char* num_doc, const int which_doc)
void TFlexform_xml_ddt::export_docs(const TString & codnum, long codcli, int year, long from, long to, TLog_report * log)
{
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;
TLista_documenti docs;
TString header("Esportazione ddt");
TCodice_numerazione num_ddt(codnum);
TToken_string tipi = num_ddt.tipi_doc();
TToken_string stati("1|2|3|4|5|6|7|8|9");
const int ndocs = docs.read('D', 'C', codcli, year, tipi, stati, nulldate, nulldate, codnum, from, to);
TProgress_monitor bar(ndocs, header);
for (int n = 0; n < ndocs && bar.add_status(); n++)
{
const TDocumento & doc = docs[n];
add_doc(doc, log);
}
export_doc();
}
TFlexform_xml_ddt::TFlexform_xml_ddt(const char* xml_name) : TFlexform_xml(xml_name)
TFlexform_xml_ddt::TFlexform_xml_ddt(const char* xml_name) : TEsa_xml(xml_name)
{
// <ESA_IMPORT Source=? CreationDate=? InstanceGuid=? FileVersion="1" />
_esa_import.set_attributes(TConfig(CONFIG_DITTA, "Main").get("RAGSOC"), TDate(TODAY), generate_GUID(), "1");
SetTag("ESA_IMPORT");
SetAttr("Source", cache().get(LF_NDITTE, prefix().get_codditta(), "RAGSOC"));
SetAttr("CreationDate", today.string(full, '/'));
SetAttr("InstanceGuid", xvt_GUID());
SetAttr("FileVersion", 1);
}
@ -201,166 +128,144 @@ TFlexform_xml_ddt::TFlexform_xml_ddt(const char* xml_name) : TFlexform_xml(xml_n
// Flexform Ordini export
///////////////////////////////////////////////////////////
void TFlexform_xml_ordini::add_doc()
const TString & TFlexform_xml_ordini::flexart2codart(const TString& cod_art_flexform)
{
/* const shared_ptr<TXML_element> doc = make_shared<TXML_element>("DOC_UNICO", "");
const shared_ptr<TDDT_testata_xml> test = make_shared<TDDT_testata_xml>();
_docs_unico.insert(_docs_unico.end(), doc);
_docs_unico.back()->set_parent(_esa_import);
const TRectype & anamag = cache().get(LF_ANAMAG, cod_art_flexform, 4);
_testate.insert(_testate.end(), test);
_testate.back()->set_parent(*_docs_unico.back());
return _docs_unico.size();*/
return anamag.get(ANAMAG_CODART);
}
bool TFlexform_xml_ordini::print()
void TFlexform_xml_ordini::add_row(long id_ordine, const int nrow,
TDocumento & doc, const TXmlItem * row,
TLog_report * log)
{
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;
}
TString4 tiporiga;
TString des_articolo_riga;
//bool TFlexform_xml_ordini::parse_ordine_xml(unique_ptr<char[]>& ford, const long len)
//{
// TXML_parser parser(ford.get(), len);
// TString name;
// vector<pair<TString, TString>> attributi;
// parser.get_xml_info(name, attributi);
// _info_xml = std::make_unique<TXML_element>(name, TString(""), true);
// TXML_tag tag = parser.get_xml_tag();
// // <ESA_IMPORT Source=? CreationDate=? InstanceGuid=? FileVersion="1" />
// bool ok = true;
// TString source, creation_date, instance_guid, file_version, tipo_operazione;
// ok &= tag.get_attribute(source, "Source")
// && tag.get_attribute(creation_date, "CreationDate")
// && tag.get_attribute(instance_guid, "InstanceGuid")
// && tag.get_attribute(file_version, "FileVersion");
// if (!ok)
// return false;
// _esa_import.set_attributes(source, TDate(creation_date), instance_guid, file_version);
// tag = parser.get_xml_tag();
// tag.get_name(name);
// ok = tag.get_attribute(tipo_operazione, "TipoOperazione");
// _ordine_impegno = std::make_unique<TXML_element>((const char*)name, "");
// _ordine_impegno->add_attribute("TipoOperazione", tipo_operazione);
// _ordine_impegno->set_parent(_esa_import);
// _testata.set_parent(*_ordine_impegno);
// tag = parser.get_xml_tag();
// tag.get_name(name);
// if(name != "OR_ORDINIT")
// {
// warning_box("Errore durante la lettura del tag \"OR_ORDINIT\".");
// return false;
// }
// tag = parser.get_xml_tag();
// if (name != "datarow")
// {
// warning_box("Errore durante la lettura del tag \"datarow\" della testata dell'ordine.");
// return false;
// }
// //parser.get_until_tag_close("datarow");
// return true;
//}
if (!row->GetEnclosedText("ind_tiporiga", tiporiga))
XML_TAG_NOT_FOUND(id_ordine, nrow, "ind_tiporiga");
if (!row->GetEnclosedText("des_articolo_riga", des_articolo_riga))
XML_TAG_NOT_FOUND(id_ordine, nrow, "des_articolo_riga");
bool TFlexform_xml_ordini::convert() const
{
const std::vector<shared_ptr<TXML_element>>& imported = _importer._imported;
TProgress_monitor bar(imported.size(), "Conversione XML ...");
for(auto it = imported.begin(); it != imported.end(); ++it)
TRiga_documento& d_row = doc.new_row(tiporiga == "D" ? "05" : "01");
d_row.put(RDOC_DESCR, des_articolo_riga);
if (tiporiga != "D")
{
if (!bar.add_status())
break;
}
return false;
}
TString cod_art;
real qta_merce;
TDate dat_evas_riga;
TString des_campo_libero6;
TString TFlexform_xml_ordini::flexart2codart(const TString& cod_art_flexform)
{
TSQL_recordset sql("");
TString query; query << "SELECT * FROM ANAMAG WHERE COD_PMS = '" << cod_art_flexform << "'";
sql.set(query);
if(sql.items() == 1)
return sql.get(sql.find_column("CODART")).as_string();
return "";
if (!row->GetEnclosedText("cod_art", cod_art))
XML_TAG_NOT_FOUND(id_ordine, nrow, "cod_art");
const TString cod_art_major = flexart2codart(cod_art);
const bool original_art_exist = cache().get(LF_ANAMAG, cod_art).full();
if (cod_art_major.full() || original_art_exist)
{
TString msg = TR("Articolo flexform : ");
msg << cod_art;
if (cod_art_major.full())
msg << TR(" codificato come : ") << cod_art_major;
MSG_ARTICOLO(id_ordine, nrow, msg, false);
}
else
{
TString msg = TR("Codice articolo flexform : ");
msg << cod_art << TR(" non trovato");
MSG_ARTICOLO(id_ordine, nrow, msg, true);
}
if (!row->GetEnclosedReal("qta_merce", qta_merce))
XML_TAG_NOT_FOUND(id_ordine, nrow, "qta_merce");
if (!row->GetEnclosedDate("dat_evas_riga", dat_evas_riga))
XML_TAG_NOT_FOUND(id_ordine, nrow, "dat_evas_riga");
if (!row->GetEnclosedText("des_campo_libero6", des_campo_libero6))
XML_TAG_NOT_FOUND(id_ordine, nrow, "des_campo_libero6");
d_row.put(RDOC_CODART, cod_art_major.full() ? cod_art_major : cod_art);
const TArticolo & art = cached_article(d_row.get(RDOC_CODART));
d_row.put(RDOC_UMQTA, art.first_um());
d_row.put(RDOC_QTA, qta_merce);
d_row.put(RDOC_DATACONS, dat_evas_riga);
d_row.put("RIFFLEX", des_campo_libero6);
}
}
bool TFlexform_xml_ordini::create_doc()
{
const shared_ptr<TXML_element> esa_import = _importer._imported[1];
CHECK_NAMETAG_OR_RETURNFALSE(esa_import, "ESA_IMPORT");
bool ok = false;
TXML_element* ordine_impegno = esa_import->get_childs()[0];
CHECK_NAMETAG_OR_RETURNFALSE(ordine_impegno, "ORDINE_IMPEGNO");
const auto it = ordine_impegno->find_attribute("TipoOperazione");
CHECK_CONDXML_OR_RETURNFALSE(it != ordine_impegno->get_attributes().end() && it->second == "Insert",
"il 'Tipo Operazione' deve essere 'Insert'.");
TXML_element* or_ordinit = ordine_impegno->get_childs()[0];
CHECK_NAMETAG_OR_RETURNFALSE(or_ordinit, "OR_ORDINIT");
TXML_element* datarow = or_ordinit->get_childs()[0];
CHECK_NAMETAG_OR_RETURNFALSE(datarow, "datarow");
const TDate dat_doc_esterno = (const char*)datarow->get_val_child("dat_doc_esterno");
const TString& des_num_esterno = datarow->get_val_child("des_num_esterno");
const TDate dat_evasione = (const char*)datarow->get_val_child("dat_evasione");
TDocumento doc('D', dat_doc_esterno.year(), _codnum, -1);
doc.put(DOC_TIPODOC, _codnum);
doc.put(DOC_STATO, "2");
doc.put(DOC_DATADOC, dat_doc_esterno);
doc.put(DOC_TIPOCF, "C");
doc.put(DOC_CODCF, _codcli_flex);
doc.put(DOC_DATACONS, dat_evasione);
vector<TXML_element*> childs_ordinit = or_ordinit->get_childs();
CHECK_CONDXML_OR_RETURNFALSE(!childs_ordinit.empty(), "non e' presente alcun ordine.");
auto it_child = childs_ordinit.begin();
if (childs_ordinit.size() > 1) // Ci sono effettivamente dei OR_ORDINIR (almeno 1) oltre al datarow (informazioni di testata ordine).
++it_child;
for (; it_child != childs_ordinit.end(); ++it_child)
if (import_doc())
{
const TXML_element& row = *(*it_child);
const TXML_element& datarow_r = *row.get_childs()[0];
TLog_report * log = _log;
const TXmlItem * first = FindFirstChild("ORDINE_IMPEGNO");
long id_ordine;
const TString& ind_tiporiga = datarow_r.get_val_child("ind_tiporiga");
const TString& cod_art = datarow_r.get_val_child("cod_art");
const TString& des_articolo_riga = datarow_r.get_val_child("des_articolo_riga");
const TString& qta_merce = datarow_r.get_val_child("qta_merce");
const TDate dat_evas_riga = TDate(datarow_r.get_val_child("dat_evas_riga"));
const TString& des_campo_libero6 = datarow_r.get_val_child("des_campo_libero6");
if (first != nullptr)
{
if (first->GetAttr("TipoOperazione") != "Insert")
XML_ERROR(TR("il Tipo Operazione deve essere Insert."));
TString cod_art_major = flexart2codart(cod_art);
TRiga_documento& d_row = doc.new_row(ind_tiporiga == "D" ? "05" : "01");
if (ind_tiporiga != "D")
d_row.put(RDOC_CODART, !cod_art_major.empty() ? cod_art_major : cod_art);
d_row.put(RDOC_DESCR, des_articolo_riga);
d_row.put(RDOC_QTA, qta_merce);
d_row.put("DATA_EVASIONE_RIGA", dat_evas_riga); // RG1 -> DATA_EVASIONE_RIGA
d_row.put("CODFLEX", des_campo_libero6); // RG1 -> CODFLEX
const TXmlItem * ordine = first->FindFirstChild("OR_ORDINIT");
if (ordine != nullptr)
{
const TXmlItem * testata = ordine->FindFirstChild("datarow");
if (testata->GetEnclosedLong("des_num_esterno", id_ordine))
{
TDate dat_doc_esterno;
TDate dat_evasione;
if (!testata->GetEnclosedDate("dat_doc_esterno", dat_doc_esterno))
XML_TAG_NOT_FOUND(id_ordine, 0, "N.ro ordine");
if (!testata->GetEnclosedDate("dat_evasione", dat_evasione))
XML_TAG_NOT_FOUND(id_ordine, 0, "N.ro ordine");
// "sig_serie_esterno"
TDocumento doc('D', dat_doc_esterno.year(), _codnum, -1);
TString msg(TR("Importazione documento ")); msg << id_ordine;
XML_MSG(msg);
doc.put(DOC_TIPODOC, _codnum);
doc.put(DOC_STATO, "2");
doc.put(DOC_DATADOC, dat_doc_esterno);
doc.put(DOC_TIPOCF, "C");
doc.put(DOC_CODCF, _codcli_flex);
doc.put(DOC_DATACONS, dat_evasione);
const int nrow = ordine->GetChildren();
for (int i = 1; i < nrow; i++)
{
const TXmlItem * row = ordine->GetChild(i);
if (row->GetTag() == "OR_ORDINIR")
{
const TXmlItem * data = row->FindFirstChild("datarow");
if (data != nullptr)
add_row(id_ordine, i, doc, data, log);
else
XML_ROW_NOT_FOUND(id_ordine, i);
}
else
XML_ROW_NOT_FOUND(id_ordine, i);
}
ok = doc.write() == NOERR;
}
else
XML_TAG_NOT_FOUND(id_ordine, 0, "N.ro ordine");
}
else
XML_NOT_FOUND("Testata");
}
else
XML_NOT_FOUND("ORDINE_IMPEGNO");
}
bool ok = doc.write() == NOERR;
ok = ok && doc.rewrite() == NOERR;
return ok;
}
bool TFlexform_xml_ordini::parse_and_import_ordine_xml(unique_ptr<char[]>& ford, long len)
{
_importer.parse(ford, len);
// Convertion to my Flexformstructure
//bool ok = convert();
// Creation of ORC in DOC
bool ok = create_doc();
return ok;
}
TFlexform_xml_ordini::TFlexform_xml_ordini(const char* xml_name, const char* codnum, int codcli_flex) : TFlexform_xml(xml_name, false), _codnum(codnum), _codcli_flex(codcli_flex)
{ }
}

View File

@ -1,313 +1,95 @@
#ifndef __MAJORXML_H
#define __MAJORXML_H
#include <vector>
#include <fstream>
#include <date.h>
#include <strings.h>
#include <reputils.h>
#include <xml.h>
#include "strings.h"
#include "xml_element.h"
#include "date.h"
#include "../ve/velib.h"
#define XML_ESCAPE_CHAR '&'
#define XML_MSG(str) log->log(0, str);
#define XML_ERROR(str) log->log(2, str);
#define XML_NOT_FOUND(tag) { \
TString msg = TR("Non ho trovato l'attributo : "); msg << (tag); \
log->log(2, msg); \
}
#define XML_TAG_NOT_FOUND(ordine, pos, tag) { \
TString msg = TR("Documento : "); msg << ordine; \
if (pos > 0) msg << TR(" Riga : ") << pos << " "; \
msg << tag << TR(" non trovata"); \
log->log(2, msg); \
}
#define XML_ROW_NOT_FOUND(ordine, pos) { \
TString msg = TR("Documento : "); msg << ordine << TR(" Riga : ") << pos << TR(" non trovata"); \
log->log(2, msg); \
}
#define MSG_ARTICOLO(ordine, pos, msg, error) { \
TString str; \
\
str << TR("Documento : ") << ordine; \
if (pos > 0) str << TR(" Riga : ") << pos; \
str << " - " << (msg); \
log->log(error ? 2 : 0, str); \
}
///////////////////////////////////////////////////////////
// TEsa_import_xml
///////////////////////////////////////////////////////////
/**
* \brief \a TXML_element Contenitore Importazione Flexform.
*/
struct TEsa_import_xml : TXML_element
class TEsa_xml : public TXmlItem
{
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", "") { }
TFilename _file_name;
public:
const TFilename & name() const { return _file_name; }
void export_doc() const { Save(name()); }
bool import_doc() { return Load(name()); }
TEsa_xml::TEsa_xml(const TString & filename) : _file_name(filename) {}
~TEsa_xml() {}
};
///////////////////////////////////////////////////////////
// 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;
ifstream* _fin;
TEsa_import_xml _esa_import;
bool _export;
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 = "", bool to_export = true);
virtual ~TFlexform_xml() { delete _fout; }
};
/**
* \brief Esportatore XML DDT Flexform.
*/
class TFlexform_xml_ddt final : public TFlexform_xml
class TFlexform_xml_ddt : public TEsa_xml
{
vector<shared_ptr<TXML_element>> _docs_unico; // Tanti doc_unico, figli di _esa_import
vector<shared_ptr<TDDT_testata_xml>> _testate; // _testata contiene i dati di testata, piu' tutte gli ordini riga come figli
vector<shared_ptr<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(const shared_ptr<TDDT_riga_xml>& riga, int which_doc = -1);
bool print() override;
shared_ptr<TDDT_riga_xml> new_row() { _rows.insert(_rows.end(), make_shared<TDDT_riga_xml>()); return _rows.back(); }
/** Setto testata al documento n. \a which_doc, 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);
void add_row(TXmlItem & outdoc, const TRiga_documento & rdoc, TLog_report * log);
void add_doc(const TDocumento & doc, TLog_report * log);
void export_docs(const TString & codnum, long codcli, int year, long from, long to, TLog_report * log);
TFlexform_xml_ddt(const char* xml_name = "");
~TFlexform_xml_ddt() = default;
~TFlexform_xml_ddt() {}
};
/**
* \brief Classe dell'ordine xml importato
*/
class TFlexform_xml_ordini final : public TFlexform_xml
class TFlexform_xml_ordini : public TEsa_xml
{
unique_ptr<TXML_element> _info_xml;
unique_ptr<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
TXML_importer _importer;
TString _codnum;
int _codcli_flex;
TLog_report * _log;
public:
void add_doc();
void add_row(const shared_ptr<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); }
bool parse_and_import_ordine_xml(unique_ptr<char[]>& ford, long len);
bool convert() const;
const TString & flexart2codart(const TString & string);
void add_row(long id_ordine, const int nrow,
TDocumento & doc, const TXmlItem * row,
TLog_report * log);
bool create_doc();
static TString flexart2codart(const TString& string);
TFlexform_xml_ordini(const char* xml_name = "", const char* codnum = "", int codcli_flex = 12);
TFlexform_xml_ordini(const TFilename & xml_name, TLog_report * log, const char* codnum, int codcli_flex = 12)
: TEsa_xml(xml_name), _codnum(codnum), _codcli_flex(codcli_flex), _log(log) {}
~TFlexform_xml_ordini() {}
};
/////////////////////////////////////////////////////////
// Utils
/////////////////////////////////////////////////////////
//class TXML_parser
//{
// long _last_pos;
// const long _len;
// const char* _xml;
//public:
// bool get_xml_info(TString& name, vector<pair<TString, TString>>& attributi)
// {
// bool end = false;
// bool ok = true;
// TToken_string line("", ' ');
// if (_xml[_last_pos++] == '<' && _xml[_last_pos++] == '?')
// {
// for (int i = _last_pos; !end && i < _len; ++i)
// {
// bool text = false;
// TString tag;
// if (_xml[i] == '\"')
// text = !text;
// else if (!text && _xml[i] == '?' && i + 1 < _len && _xml[i + 1] == '>')
// {
// end = true;
// continue;
// }
// else if (!text && _xml[i] == '?' && !(i + 1 < _len && _xml[i + 1] == '>'))
// {
// warning_box("tag info XML non chiuso correttamente!");
// ok = false;
// break;
// }
// line << _xml[i];
// }
// name = line.get(0);
// TToken_string tok("", '=');
// for (int i = 1; line.get(-1, tok) && i < line.items(); ++i)
// {
// if (tok.items() != 2)
// {
// warning_box("Errore durante la lettura degli attributi delle info XML.");
// ok = false;
// break;
// }
// attributi.push_back({ tok.get(0), tok.get(1) });
// }
// return ok;
// }
// else
// {
// error_box("XML mal formattato: mi aspettavo la riga di info xml.");
// return false;
// }
// }
//
// void get_single_tag(TString& str) const
// {
// str.cut(0);
// bool end = false;
// bool open = false;
// for (int i = _last_pos; !end && i < _len; ++i)
// {
// if (!open)
// {
// if (_xml[i] != '<')
// continue;
// open = true;
// }
//
// bool text = false;
// TString tag;
// if (_xml[i] == '\"')
// text = !text;
// else if (!text && _xml[i] == '>')
// end = true;
// str << _xml[i];
// }
// }
//
// TXML_tag get_xml_tag() const
// {
// TXML_tag xml_tag;
// TString tag;
// get_single_tag(tag);
// xml_tag.import_tag(tag);
// return xml_tag;
// }
//
// TXML_parser(const char* xml, const long len) : _last_pos(0), _len(len), _xml(xml) { }
//};
#endif // __MAJORXML_H
#endif // __MAJORXML_H

View File

@ -13,8 +13,7 @@
#include "pg0069.h"
#include "pg0069100a.h"
#include "../cg/cg2103.h"
#include "../cg/cglib02.h"
#include "../cg/cglib.h"
#include "../cg/cgsaldac.h"
#include "../ve/velib.h"
#include "../ve/velib04.h"

View File

@ -8,8 +8,7 @@
#include <reputils.h>
#include <textset.h>
#include "../cg/cg2103.h"
#include "../cg/cglib02.h"
#include "../cg/cglib.h"
#include "../cg/cgsaldac.h"
#include "../ve/velib.h"

View File

@ -13,8 +13,7 @@
#include "pg0214.h"
#include "pg0214200a.h"
#include "../cg/cg2103.h"
#include "../cg/cglib02.h"
#include "../cg/cglib.h"
#include "../cg/cgpagame.h"
#include "../cg/cgsaldac.h"
#include "../ve/velib.h"

View File

@ -8,9 +8,7 @@
#include <sheet.h>
#include "../cg/cglib01.h"
#include "../cg/cg2103.h"
#include "../cg/cglib.h"
#include "pi0001.h"
#include "pi0001100.h"

View File

@ -9,8 +9,7 @@
#include <tabutil.h>
#include <sheet.h>
#include "../cg/cglib01.h"
#include "../cg/cg2103.h"
#include "../cg/cglib.h"
#include "../cg/cgsaldac.h"
#include "../cg/cgpagame.h"

View File

@ -12,7 +12,7 @@
#include <tabutil.h>
#include <clifo.h>
#include <..\cg\cglib01.h>
#include <..\cg\cglib.h>
#include <..\lv\lvcondv.h>
#include <..\lv\lvrcondv.h>
#include <..\mg\clifogiac.h>

View File

@ -29,10 +29,6 @@ class TProgind;
#include <reputils.h>
#endif
#ifndef __CLIFOR_H
#include "../ve/clifor.h"
#endif
#include "../ve/velib.h"
class TCache_th;

View File

@ -7,7 +7,7 @@
#include <reprint.h>
#include <textset.h>
#include "../cg/cglib01.h"
#include "../cg/cglib.h"
#include "../ve/velib07.h"
///////////////////////////////////////////////////////////

View File

@ -358,7 +358,6 @@ void TDichiarazione_CONAI::scrivi_csv(const TRectype& prima_riga, TDichiarazione
break;
}
}
if (n_riga_generata > 0)
scrivi_csv_doc_con_riga_generata(doc, n_riga_generata, csv, conai_specie);
else

View File

@ -10,7 +10,7 @@
#include <utility.h>
#include "../or/orlib.h"
#include "../cg/cglib01.h"
#include "../cg/cglib.h"
#include "../mg/anamag.h"
#include "../ve/velib07.h"

View File

@ -5,7 +5,7 @@
#include <textset.h>
#include <utility.h>
#include "../cg/cglib01.h"
#include "../cg/cglib.h"
#include "ps0430400a.h"
#include "../ve/velib.h"

View File

@ -4,8 +4,7 @@
#include <reputils.h>
#include "../cg/cg2101.h"
#include "../cg/cglib02.h"
#include "../cg/cglib.h"
#include "../mg/mglib.h"
#include "ps0430500a.h"

View File

@ -13,8 +13,7 @@
#include <config.h>
#include "../cg/cg2101.h"
#include "../cg/cglib02.h"
#include "../cg/cglib.h"
#include "../mg/mglib.h"
#include "ps0430600a.h"

View File

@ -5,7 +5,7 @@
#include <reputils.h>
#include <textset.h>
#include "../cg/cg2101.h"
#include "../cg/cglib.h"
#include "ps0431.h"
#include "ps0431100a.h"

View File

@ -6,7 +6,6 @@
#include <recset.h>
#include <cfven.h>
#include "../ve/clifor.h"
#include "../ve/condv.h"
#include "../ve/rcondv.h"
#include "../ve/velib.h"

View File

@ -1,291 +1,143 @@
#include <Shlobj_core.h> // KnownFolder di Windows
//#include <strings.h>
#include <applicat.h> // TSkeleton_application
#include <automask.h> // TAutomask
#include <config.h>
#include <isam.h>
#include <lffiles.h>
#include <progind.h> // TProgress_monitor
#include <recarray.h>
#include <tabutil.h> // TTable
#include <sqlset.h> // TSQL_recordset
#include <utility.h> // list_files
#include <clifo.h>
#include "../mg/anamag.h"
#include "../ve/velib.h"
#include "ps6362.h"
#include "ps6362100a.h"
#include "applicat.h" // TSkeleton_application
#include "automask.h" // TAutomask
#include "config.h"
#include "lffiles.h"
#include "clifo.h"
#include "isam.h"
#include "tabutil.h" // TTable
#include "sqlset.h" // TSQL_recordset
#include "utility.h" // list_files
#include "progind.h" // TProgress_monitor
#include "flexform_xml.h"
///////////////////////////////////////////////////////////
// Main Mask
///////////////////////////////////////////////////////////
class TMajor_export_mask final : public TAutomask
class TMajor_export_mask:public TAutomask
{
protected:
bool on_field_event(TOperable_field& o, TField_event e, long jolly) override;
void load_all();
public:
void save_all() const;
TMajor_export_mask();
~TMajor_export_mask() { save_all(); }
void load_all();
TMajor_export_mask() : TAutomask("ps6362100a") {}
// ~TMajor_export_mask() {}
};
bool TMajor_export_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch(o.dlg())
{
case F_TIPODOC:
if(e == fe_modify || e == fe_init)
{
const TString& c = get(F_TIPODOC);
const bool en = c == "D";
field(F_FLDDEST).enable(en);
field(F_SUBFLD).enable(en);
field(F_FLDSOURCE).enable(!en);
field(F_ANNO_ELAB).enable(en);
field(F_NUMDDT).enable(en);
field(F_NUMORD).enable(!en);
field(F_NUMDDT_DA).enable(en);
field(F_NUMDDT_A).enable(en);
}
break;
default: break;
default:
break;
}
return true;
}
TMajor_export_mask::TMajor_export_mask() : TAutomask("ps6362100a")
{
load_all();
}
void TMajor_export_mask::save_all() const
{
ini_set_string(CONFIG_DITTA, "ps6362", "flddest", get(F_FLDDEST));
ini_set_bool (CONFIG_DITTA, "ps6362", "fldroot_b", get_bool(F_SUBFLD));
ini_set_string(CONFIG_DITTA, "ps6362", "fldsource", get(F_FLDSOURCE));
ini_set_string(CONFIG_DITTA, "ps6362", "fldyear", get(F_ANNO_ELAB));
ini_set_string(CONFIG_DITTA, "ps6362", "tipodoc", get(F_TIPODOC));
ini_set_string(CONFIG_DITTA, "ps6362", "numddt", get(F_NUMDDT));
ini_set_string(CONFIG_DITTA, "ps6362", "codcf", get(F_CODCF));
ini_set_string(CONFIG_DITTA, "ps6362", "num_da", get(F_NUMDDT_DA));
ini_set_string(CONFIG_DITTA, "ps6362", "num_a", get(F_NUMDDT_A));
}
void TMajor_export_mask::load_all()
{
TFilename dir = ini_get_string(CONFIG_DITTA, "ps6362", "flddest", "");
if (dir.empty())
{
PWSTR szPath[MAX_PATH];
char dest[MAX_PATH];
if ((HRESULT)SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, szPath) >= 0)
{
size_t size;
wcstombs_s(&size, dest, MAX_PATH, szPath[0], MAX_PATH);
dir = dest;
}
else
dir.tempdir();
}
load();
TString y; y << TDate(TODAY).year();
TFilename dir = get(F_FLDDEST);
TString cod_flexform(ini_get_string(CONFIG_DITTA, "ps6362", "codcf", ""));
if (cod_flexform.empty())
if (dir.blank())
{
TLocalisamfile clifo(LF_CLIFO);
clifo.setkey(2);
clifo.put(CLI_TIPOCF, "C");
clifo.put(CLI_RAGSOC, "FLEXFORM");
if (clifo.read(_isgteq) == NOERR && clifo.get(CLI_RAGSOC).starts_with("FLEXFORM"))
cod_flexform = clifo.get(CLI_CODCF);
else
cod_flexform = "12";
dir = get_system_dir(desktop_dir);
set(F_FLDDEST, dir);
set(F_SUBFLD, true);
}
TString dir2 = ini_get_string(CONFIG_DITTA, "ps6362", "fldsource", "");
if(dir2.empty())
set(F_ANNO_ELAB, today.year());
dir = get(F_FLDSOURCE);
if (dir.blank())
{
dir2 << dir;
dir2 << "\\upload";
}
set(F_FLDDEST, dir);
set(F_FLDSOURCE, dir2);
set(F_SUBFLD, ini_get_bool (CONFIG_DITTA, "ps6362", "fldroot_b", true));
set(F_ANNO_ELAB, ini_get_string(CONFIG_DITTA, "ps6362", "fldyear", y));
set(F_NUMDDT, ini_get_string(CONFIG_DITTA, "ps6362", "numddt", ""));
set(F_NUMORD, ini_get_string(CONFIG_DITTA, "ps6362", "numord", ""));
set(F_TIPODOC, ini_get_string(CONFIG_DITTA, "ps6362", "tipodoc", "D"));
set(F_CODCF, cod_flexform);
set(F_NUMDDT_DA, ini_get_string(CONFIG_DITTA, "ps6362", "num_da", ""));
set(F_NUMDDT_A, ini_get_string(CONFIG_DITTA, "ps6362", "num_a", ""));
if(get(F_NUMDDT).empty() || get(F_NUMORD).empty())
{
TTable num("%NUM");
TString ord, ddt;
for (num.first(); num.good(); num.next())
{
if (ddt.empty() && num.get("CODTAB").starts_with("B0"))
ddt = num.get("CODTAB");
else if (ord.empty() && num.get("CODTAB").starts_with("ORC"))
ord = num.get("CODTAB");
if (ord.full() && ddt.full())
break;
}
if (get(F_NUMDDT).empty())
set(F_NUMDDT, ddt);
if (get(F_NUMORD).empty())
set(F_NUMORD, ord);
dir = get_system_dir(desktop_dir);
dir.add("upload");
set(F_FLDSOURCE, dir);
}
if(get(F_NUMDDT).blank())
set(F_NUMDDT, "B01");
if (get(F_NUMORD).blank())
set(F_NUMORD, "ORC");
}
///////////////////////////////////////////////////////////
// Main Program
///////////////////////////////////////////////////////////
class TMajor_flexform_boll_app : public TSkeleton_application
class TMajor_flexform_boll_app:public TSkeleton_application
{
TString _fld_dest;
bool create() override;
static TFilename check_name_file(const TString& dir, bool sub_fld, int from, int to, bool ddt = true);
static TString get_riferimento_flexform(const TSQL_recordset& righe_doc);
static bool export_ddt(TMask& msk);
static bool import_ordini(TMask& msk);
void main_loop() override;
bool create();
bool check_name_file(const TString & dir, TFilename & xml, bool sub_fld, int from, int to, bool ddt = true);
bool export_ddt(TMask& msk);
bool import_ordini(TMask& msk);
void main_loop();
public:
TMajor_flexform_boll_app() = default;
TMajor_flexform_boll_app() {}
};
bool TMajor_flexform_boll_app::create()
{
open_files(LF_DOC, LF_RIGHEDOC);
open_files(LF_DOC, LF_RIGHEDOC, LF_CLIFO, 0);
return TSkeleton_application::create();
}
TFilename TMajor_flexform_boll_app::check_name_file(const TString& dir, const bool sub_fld, const int from, const int to, bool ddt)
bool TMajor_flexform_boll_app::check_name_file(const TString & dir, TFilename & xml, const bool sub_fld, const int from, const int to, bool ddt)
{
TString cartella = dir; cartella << "/";
TString da, a;
TString name;
if (sub_fld)
cartella << "CAMPO_" << TDate(TODAY).date2ansi() << "/";
TString da, a;
da.format("%07d", from);
a.format("%07d", to);
name << (ddt ? "ddt" : "ord") << TDate(TODAY).year() << da << a;
TString name; name << (ddt ? "ddt" : "ord") << TDate(TODAY).year() << da << a;
TFilename xml(cartella);
if (!xvt_fsys_dir_exists(xml))
xvt_fsys_mkdir(xml);
xml = cartella;
if (!xml.exist())
make_dir(xml);
xml << name << ".xml";
if (xml.exist())
{
const int key = yesnocancel_box("Esiste gia' un file per questa esportazione. Creare duplicato?\nCliccare 'No' se si vuole sostituire il file.");
if (key == K_YES)
{
int i = 1;
do
{
xml = cartella;
xml << name << "_" << i++ << ".xml";
} while (xml.exist() && i < 128);
if (i == 128)
fatal_box("Attenzione si sta cercando di generare troppi file per questa esportazione.");
}
else if (key != K_NO)
xml = "";
}
return xml;
TString msg(TR("Il file ")); msg << xml << TR(" esiste.Devo rigenerarlo ? ");
return !xml.exist() || yesnocancel_box(msg) == K_YES;
}
TString TMajor_flexform_boll_app::get_riferimento_flexform(const TSQL_recordset& righe_doc)
{
const TString& rg1 = righe_doc.get(3).as_string();
const TToken_string t(rg1, char(0xB6)); // Simbolo paragrafo ¶
TString line;
for(int i = 0; i < t.items(); ++i)
{
t.get(i, line);
if (line.starts_with("CODFLEX"))
break;
line.cut(0);
}
if(line.full())
{
TString rif(line.sub(line.find('=') + 1));
rif.trim();
return rif;
}
return "";
}
bool TMajor_flexform_boll_app::export_ddt(TMask& msk)
{
const TString& dir = msk.get(F_FLDDEST);
const bool sub_fld = msk.get_bool(F_SUBFLD);
const int year = msk.get_int(F_ANNO_ELAB);
const int codcli = msk.get_int(F_CODCF);
const int from = msk.get_int(F_NUMDDT_DA);
const int to = msk.get_int(F_NUMDDT_A);
const TString& codnum = msk.get(F_NUMDDT);
const TString & dir = msk.get(F_FLDDEST);
const bool sub_fld = msk.get_bool(F_SUBFLD);
const int year = msk.get_int(F_ANNO_ELAB);
const long codcli = msk.get_long(F_CODCF);
const long from = msk.get_long(F_NUMDDT_DA);
const long to = msk.get_int(F_NUMDDT_A);
const TString & codnum = msk.get(F_NUMDDT);
TLog_report log;
TFilename path_xml;
bool ok = check_name_file(dir, path_xml, sub_fld, from, to);
TFilename path_xml = check_name_file(dir, sub_fld, from, to);
if (path_xml.empty())
return false;
TFlexform_xml_ddt xml_ddts(path_xml);
TString query_doc;
query_doc << "SELECT DATADOC, NDOC FROM doc WHERE CODNUM = '" << codnum << "' AND ANNO = " << year <<
" AND PROVV = 'D' AND TIPOCF = 'C' AND CODCF = " << codcli << " AND NDOC >= " << from << " AND NDOC <= " << to;
TSQL_recordset doc(query_doc);
TProgress_monitor bar(doc.items(), "Esportazione ddt");
for(bool ok_d = doc.move_first(); ok_d; ok_d = doc.move_next())
if (ok)
{
if (!bar.add_status())
break;
xml_ddts.add_doc();
TFormatted_date day(doc.get(0).as_date()); day.set_format("1444/");
const TString& n_doc = doc.get(1).as_string();
xml_ddts.set_testata(day.string(), n_doc);
// Righe documento
TString query_righe;
query_righe << "SELECT rdoc.CODART, rdoc.DESCR, rdoc.QTA, rdoc.RG1, rdoc.DESCLUNGA, rdoc.DESCEST, COD_PMS\n"
"FROM rdoc\n"
"LEFT JOIN anamag ON rdoc.CODART = anamag.CODART\n"
"WHERE 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())
{
shared_ptr<TDDT_riga_xml> riga = xml_ddts.new_row();
TString cod_art = righe_doc.get(6).as_string(); // Codice Flexform.
if(cod_art.empty())
cod_art = righe_doc.get(0).as_string(); // Codice interno.
TFlexform_xml_ddt xml_ddts(path_xml);
TString descr = righe_doc.get(1).as_string();
const TString& qta = righe_doc.get(2).as_string();
const TString& desccampolibero6 = get_riferimento_flexform(righe_doc); // get(3) RG1
if (righe_doc.get(4).as_bool())
descr << righe_doc.get(5).as_string();
if(!desccampolibero6.empty())
riga->set_datarow("A", cod_art, descr, qta, desccampolibero6);
else
riga->set_datarow("C", "", descr, "0", "");
xml_ddts.add_row(riga);
}
xml_ddts.export_docs(codnum, codcli, year, from,to, &log);
#ifdef DBG
log.print_or_preview();
#endif
}
bool ok = true;
if (ok &= xml_ddts.ok())
ok &= xml_ddts.print();
return ok;
}
@ -293,53 +145,57 @@ bool TMajor_flexform_boll_app::import_ordini(TMask& msk)
{
bool ok = false;
const TString& dir_in = msk.get(F_FLDSOURCE);
TFilename path(dir_in);
TString_array flist;
TBit_array lookup_t;
TString header("Importazione ordini");
TLog_report log(header);
path.add("*.xml");
list_files(path, flist);
bool* lookup_t = new bool[flist.items()];
for (int i = 0; i < flist.items(); ++i)
lookup_t[i] = false;
TProgress_monitor prog(flist.items(), "Importazione ordini");
FOR_EACH_ARRAY_ROW(flist, nr, ford_name)
{
if (!prog.add_status())
break;
TProgress_monitor prog(flist.items(), header);
TFilename ford_filename(ford_name->operator const char*());
FILE* fin;
if (!fopen_s(&fin, ford_filename, "rb") && fin) // Read-Binary mode
FOR_EACH_ARRAY_ROW(flist, nr, str)
{
lookup_t[nr] = true;
std::fseek(fin, 0, SEEK_END);
const long len = std::ftell(fin);
std::unique_ptr<char[]> ford = std::make_unique<char[]>(len + 1);
std::fseek(fin, 0, 0);
fread_s(ford.get(), len + 1, 1, len, fin);
ford[len] = '\0';
fclose(fin);
if (prog.add_status())
{
TFilename ford_filename(*str);
TFlexform_xml_ordini order((const char*)ford_filename, msk.get(F_NUMORD), msk.get_int(F_CODCF));
ok = order.parse_and_import_ordine_xml(ford, len);
}
else
{
TString msg; msg << "Impossibile aprire il file " << ford_filename << "\nProcedura terminata.";
warning_box(msg);
return false;
if (ford_filename.exist())
{
TFlexform_xml_ordini order(ford_filename, &log, msk.get(F_NUMORD), msk.get_int(F_CODCF));
ok = order.create_doc();
}
else
{
TString msg;
msg << TR("Il file ") << ford_filename << TR("non esiste\nProcedura terminata.");
log.log(2, msg);
}
}
}
}
#ifdef DBG
// log.print_or_preview();
#endif
return ok;
}
void TMajor_flexform_boll_app::main_loop()
{
TMajor_export_mask msk;
msk.load_all();
while (msk.run() == K_ENTER)
{
bool ok = true;
TString msg;
msk.save();
if (msk.get(F_TIPODOC) == "D")
{
msg << "Esportazione ";

View File

@ -10,13 +10,13 @@ END
#include <helpbar.h>
ENDPAGE
PAGE "Configurazione Esportazione Major-Flexform" 0 2 0 0
PAGE "Import/Export Major-Flexform" 0 2 0 0
RADIOBUTTON F_TIPODOC 64
BEGIN
PROMPT 6 1 "@bSelezionare la funzione"
ITEM "O|Importazione Ordini"
ITEM "D|Esportazione Bolle"
ITEM "O|Importazione Ordini" MESSAGE DISABLE,1@|ENABLE,2@
ITEM "D|Esportazione Bolle" MESSAGE ENABLE,1@|DISABLE,2@
FLAG ""
END
@ -29,21 +29,21 @@ STRING F_FLDDEST 250 50
BEGIN
PROMPT 2 6 "Cartella di destinazione"
DSELECT
FLAGS ""
GROUP 1
CHECKTYPE REQUIRED
END
BOOLEAN F_SUBFLD
BEGIN
PROMPT 2 7 "Crea sottocartella con data odierna"
FLAGS ""
GROUP 1
END
STRING F_FLDSOURCE 250 50
BEGIN
PROMPT 2 8 "Cartella caricamento "
DSELECT
FLAGS ""
GROUP 2
CHECKTYPE REQUIRED
END
@ -60,30 +60,33 @@ END
STRING F_NUMDDT 4
BEGIN
PROMPT 7 12 "DDT "
FLAG "UZ"
FLAG "U"
USE %NUM
INPUT CODTAB F_NUMDDT
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@50" S0
OUTPUT F_NUMDDT CODTAB
CHECKTYPE NORMAL
GROUP 1
END
STRING F_NUMORD 4
BEGIN
PROMPT 7 13 "ORDINI"
FLAG "UZD"
FLAG "Z"
USE %NUM
INPUT CODTAB F_NUMORD
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@50" S0
OUTPUT F_NUMORD CODTAB
CHECKTYPE NORMAL
GROUP 2
END
STRING F_ANNO_ELAB 4
BEGIN
PROMPT 32 11 "Anno elaborazione"
FLAGS "D"
END
NUMBER F_CODCF 6
@ -102,8 +105,8 @@ NUMBER F_NUMDDT_DA 7
BEGIN
PROMPT 32 13 "da num. doc. "
USE LF_DOC
JOIN %TIP ALIAS 104 INTO CODTAB=TIPODOC
JOIN LF_CLIFO INTO TIPOCF=TIPOCF CODCF=CODCF
JOIN %TIP ALIAS 104 INTO CODTAB=TIPODOC
JOIN LF_CLIFO INTO TIPOCF=TIPOCF CODCF=CODCF
INPUT PROVV "D"
INPUT ANNO F_ANNO_ELAB SELECT
INPUT CODNUM F_NUMDDT SELECT
@ -113,6 +116,7 @@ BEGIN
DISPLAY "Ragione sociale@50" LF_CLIFO->RAGSOC
OUTPUT F_NUMDDT_DA NDOC
ADD RUN ve0 -0
GROUP 1
END
NUMBER F_NUMDDT_A 7
@ -128,6 +132,7 @@ BEGIN
NUM_EXPR (#THIS_FIELD==0)||(#THIS_FIELD>=#F_NUMDDT_DA)
WARNING "Specificare un numero documento superiore a quello di partenza"
ADD RUN ve0 -0
GROUP 1
END
ENDPAGE

View File

@ -1,400 +0,0 @@
#include <rpc.h>
#include <rpcdce.h>
#include <stack>
#include "xml_element.h"
#include "strings.h"
#include "progind.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 TString& TXML_element::get_val_child(const char* name_child) const
{
static TString appo = "";
const auto it = find_child(_childs, name_child);
if (it != _childs.end())
return (*it)->get_val();
return appo;
}
const wchar_t* TXML_element::get_wval_child(const char* name_child) const
{
static wchar_t* appo = L"";
const auto it = find_child(_childs, name_child);
if (it != _childs.end())
return (*it)->get_wval();
return appo;
}
vector<pair<TString, TString>>::const_iterator TXML_element::find_attribute(const char* str)
{
vector<pair<TString, TString>>::const_iterator a = _attributes.end();
for (auto it = _attributes.begin(); it != _attributes.end(); ++it)
if (it->first == str)
a = it;
return a;
}
vector<TXML_element*>::const_iterator TXML_element::find_child(const vector<TXML_element*>& childs, const char* str)
{
vector<TXML_element*>::const_iterator a = childs.end();
for (auto it = childs.begin(); it != childs.end(); ++it) if ((*it)->get_name() == str) a = it;
return a;
}
///////////////////////////////////////////////////////////
// TXML_importer
///////////////////////////////////////////////////////////
bool TXML_importer::parse(std::unique_ptr<char[]>& ford, long len)
{
char* xml = ford.get();
std::stack<TXML_tag> s_tags;
std::stack<TXML_element*> s_elems;
bool tag_open = false;
bool text_open = false;
TString token;
TString value_pending;
TProgress_monitor bar(len, "Parsing XML Flexform Ordini");
for (int i = 0; i < len; ++i)
{
if (!bar.add_status())
break;
if (!text_open && !tag_open && xml[i] == '<')
{
tag_open = true;
if (!token.empty())
{
if (s_tags.empty())
{
TString msg; msg << "Trovato testo fuori dai tag ma senza alcun tag? " << token;
warning_box(msg);
return false;
}
// Se al giro dopo becco lo stesso tag ma di chiusura vuol dire che questo e' un valore e lo aggiungo
value_pending.cut(0) << token;
}
token.cut(0) << xml[i];
}
else if (xml[i] == '"')
{
text_open = !text_open;
token << xml[i];
}
else if (!text_open && tag_open && xml[i] == '>')
{
tag_open = false;
token << xml[i];
TXML_tag tag;
tag.import_tag(token);
if (tag._opener)
{
_imported.push_back(make_shared<TXML_element>((const char*)tag._name, "", tag._info));
if (s_tags.empty())
_imported.back()->set_root();
else
_imported.back()->set_parent(*s_elems.top());
// Aggiungo gli attributi, se ce ne sono
for (auto& attribute : tag._attributes)
_imported.back()->add_attribute(attribute.first, attribute.second);
// Aggiungo allo stack solo se non si tratta di tag singoli (<xxxxx />) o del tag info xml (<?xml xxxxx?>)
// Poiche' questi non determinano nessuna apertura
if (!tag._closed && !tag._info)
{
s_tags.push(tag);
s_elems.push(_imported.back().get());
}
}
else
{
TXML_tag t = s_tags.top();
if (t._name != tag._name)
{
TString msg; msg << "Chiuso tag sbagliato. Mi aspettavo: " << tag._name << " trovato: " << t._name;
warning_box(msg);
return false;
}
if (!value_pending.trim().empty())
{
TXML_element* last = s_elems.top();
last->set_value(value_pending);
value_pending.cut(0);
}
s_tags.pop();
s_elems.pop();
}
token.cut(0);
}
else if (!tag_open && !s_tags.empty() || tag_open) // Se sto fetchando roba dentro il tag o i valori dei tag
token << xml[i];
}
if (!s_tags.empty())
return false;
return true;
}
////////////////////////////////////////////////////////////////////////////////
// TXML_tag
////////////////////////////////////////////////////////////////////////////////
vector<pair<TString, TString>>::const_iterator TXML_tag::find_attribute(
const vector<pair<TString, TString>>& attributes, const char* str)
{
vector<pair<TString, TString>>::const_iterator a = attributes.end();
for (auto it = attributes.begin(); it != attributes.end(); ++it)
if (it->first == str)
a = it;
return a;
}
bool TXML_tag::get_attribute(TString& out, const char* str)
{
const auto p = find_attribute(_attributes, str);
if (p == _attributes.end())
{
TString msg;
msg << "Impossibile trovare l'attributo " << str << " nel tag " << _name;
warning_box(msg);
out = "";
return false;
}
out = p->second;
return true;
}
bool TXML_tag::import_tag(const TString& tag)
{
bool ok = true;
if (tag[0] == '<' && tag[tag.len() - 1] == '>')
{
_opener = tag[1] != '/';
_info = tag[1] == '?';
_closed = tag[tag.len() - 2] == '/';
TString tok(tag.sub(1 + (_info || !_opener ? 1 : 0), tag.len() - 1 - (_info || _closed ? 1 : 0)));
if (tok.empty())
{
warning_box("Error reading tag.");
ok = false;
}
int i = tok.find(' ');
_name = tok.sub(0, i);
bool end = i == -1;
for (++i; !end;)
{
TString tok_;
bool end_2 = false;
bool text = false;
for (; !end_2 && i < tok.len(); ++i)
{
if (tok[i] == '\"')
text = !text;
else if (!text && tok[i] == ' ')
{
end_2 = true;
continue;
}
tok_ << tok[i];
}
if (i == tok.len())
end = true;
TToken_string att(tok_, '=');
if (att.items() == 2)
{
TString key, val;
key = att.get(0);
key.trim();
val = att.get(1);
val = *att.get(1) == '\"' ? val.sub(1, val.len() - 1) : att.get(1);
val.trim();
_attributes.insert(_attributes.end(), {key, val});
}
else
{
TString msg;
msg << "Error parsing attributes of tag " << _name;
warning_box(msg);
ok = false;
}
}
return ok;
}
return false;
}
///////////////////////////////////////////////////////////
const char* 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;
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
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;
}

View File

@ -1,114 +0,0 @@
#ifndef __XMLELEMENT_H
#define __XMLELEMENT_H
#include <vector>
#include "strings.h"
#define XML_ROOT_TAG nullptr
const char* generate_GUID();
/**
* \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; }
const TString& get_name() const { return _name; }
const TXML_element& get_parent() const { return *_parent; }
const vector<TXML_element*>& get_childs() const { return _childs; }
const vector<pair<TString, TString>>& get_attributes() const { return _attributes; }
const TString& get_val() const { return _value; }
const wchar_t* get_wval() const { return _wvalue; }
const TString& get_val_child(const char* name_child) const;
const wchar_t* get_wval_child(const char* name_child) const;
/*static vector<pair<TString, TString>>::const_iterator find_attribute(const vector<pair<TString, TString>>& attributes, const char* str)
{
vector<pair<TString, TString>>::const_iterator a = attributes.end();
for (auto it = attributes.begin(); it != attributes.end(); ++it)
if (it->first == str)
a = it;
return a;
}*/
vector<pair<TString, TString>>::const_iterator find_attribute(const char* str);
TXML_element& operator<<(const char* _Val) { _value = _Val; return *this; }
vector<TXML_element*>::const_iterator find_child(const char* str) const { return find_child(_childs, str); }
static vector<TXML_element*>::const_iterator find_child(const vector<TXML_element*>& childs, const char* str);
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) { }
};
class TXML_importer
{
public:
std::vector<shared_ptr<TXML_element>> _imported;
bool parse(std::unique_ptr<char[]>& ford, long len);
};
/**
* \brief Classe di supporto con info singolo tag.
*/
class TXML_tag
{
public:
TString _name;
bool _opener;
bool _closed; // Tag singoli (<xxxxx />).
vector<pair<TString, TString>> _attributes; // Vector perche' ho bisogno di mantenere l'ordine.
TString _val; // Tutto cio' che c'e' all'interno del tag.
bool _info = false;
void add_attribute(const char* key, const char* val) { _attributes.insert(_attributes.end(), { key, val }); }
void set_name(const char* name) { _name = name; }
void set_opener(bool tag_di_apertura) { _opener = tag_di_apertura; }
void set_single_tag(bool closed) { _closed = closed; }
void get_name(TString& name) const { name = _name; }
static vector<pair<TString, TString>>::const_iterator find_attribute(const vector<pair<TString, TString>>& attributes,
const char* str);
bool get_attribute(_Out_ TString& out, const char* str);
bool import_tag(const TString& tag);
TXML_tag() : _opener(false), _closed(false) { }
TXML_tag(const char* name, bool tag_di_apertura = false, bool single = false) : _name(name), _opener(tag_di_apertura), _closed(single) { }
TXML_tag(const char* name, vector<pair<TString, TString>>& attributes, bool tag_di_apertura = false, bool single = false)
: _name(name), _opener(tag_di_apertura), _closed(single), _attributes(attributes) { }
};
#endif // __XMLELEMENT_H