/**
* Дополняет классы {{#crossLink "DataObj"}}{{/crossLink}} и {{#crossLink "DataManager"}}{{/crossLink}} методами чтения,<br />
* записи и синхронизации через стандартный интерфейс <a href="http://its.1c.ru/db/v83doc#bookmark:dev:TI000001362">OData</a>
* /a/unf/odata/standard.odata
*
* © Evgeniy Malyarov http://www.oknosoft.ru 2014-2016
*
* @module metadata
* @submodule rest
* @requires common
*/
/**
* ### Методы общего назначения для работы с rest
*
* @class Rest
* @static
* @menuorder 35
* @tooltip Работа с rest 1С
*/
function Rest(){
/**
* Форматирует период для подстановки в запрос rest
* @method filter_date
* @param fld {String} - имя поля для фильтрации по датам
* @param [dfrom] {Date} - дата начала
* @param [dtill] {Date} - дата окончания
* @return {String}
*/
this.filter_date = function (fld, dfrom, dtill) {
if(!dfrom)
dfrom = new Date("2015-01-01");
var res = fld + " gt datetime'" + $p.moment(dfrom).format($p.moment._masks.iso) + "'";
if(dtill)
res += " and " + fld + " lt datetime'" + $p.moment(dtill).format($p.moment._masks.iso) + "'";
return res;
};
/**
* Преобразует данные, прочитанные из rest-сервиса в json-прототип DataObj
* @method to_data
* @param rdata {Object} - фрагмент ответа rest
* @param mgr {DataManager}
* @return {Object}
*/
this.to_data = function (rdata, mgr) {
var o = {},
cm = mgr.metadata(),
mf = cm.fields,
mts = cm.tabular_sections,
ts, f, tf, row, syn, synts, vmgr;
if(mgr instanceof RefDataManager){
if(rdata.hasOwnProperty("DeletionMark"))
o._deleted = rdata.DeletionMark;
if(rdata.hasOwnProperty("DataVersion"))
;
if(rdata.hasOwnProperty("Ref_Key"))
o.ref = rdata.Ref_Key;
}else{
mf = ({})._mixin(cm.dimensions)._mixin(cm.resources)._mixin(cm.attributes);
}
if(mgr instanceof DocManager){
if(rdata.hasOwnProperty("Number"))
o.number_doc = rdata.Number || rdata.number_doc;
else if(rdata.hasOwnProperty("number_doc"))
o.number_doc = rdata.number_doc;
if(rdata.hasOwnProperty("Date"))
o.date = rdata.Date;
else if(rdata.hasOwnProperty("date"))
o.date = rdata.date;
if(rdata.hasOwnProperty("Posted"))
o.posted = rdata.Posted;
else if(rdata.hasOwnProperty("posted"))
o.posted = rdata.posted;
} else {
if(cm.main_presentation_name){
if(rdata.hasOwnProperty("Description"))
o.name = rdata.Description;
else if(rdata.hasOwnProperty("name"))
o.name = rdata.name;
}
if(cm.code_length){
if(rdata.hasOwnProperty("Code"))
o.id = rdata.Code;
else if(rdata.hasOwnProperty("id"))
o.id = rdata.id;
}
}
for(f in mf){
if(rdata.hasOwnProperty(f)){
o[f] = rdata[f];
}else{
syn = _md.syns_1с(f);
if(syn.indexOf("_Key") == -1 && mf[f].type.is_ref && rdata[syn+"_Key"])
syn+="_Key";
if(!rdata.hasOwnProperty(syn))
continue;
o[f] = rdata[syn];
}
}
for(ts in mts){
synts = (ts == "extra_fields" || rdata.hasOwnProperty(ts)) ? ts : _md.syns_1с(ts);
if(!rdata.hasOwnProperty(synts))
continue;
o[ts] = [];
if(rdata[synts]){
rdata[synts].sort(function (a, b) {
return (a.LineNumber || a.row) > (b.LineNumber || b.row);
});
rdata[synts].forEach(function (r) {
row = {};
for(tf in mts[ts].fields){
syn = (r.hasOwnProperty(tf) || (ts == "extra_fields" && (tf == "property" || tf == "value"))) ? tf : _md.syns_1с(tf);
if(syn.indexOf("_Key") == -1 && mts[ts].fields[tf].type.is_ref && r[syn+"_Key"])
syn+="_Key";
row[tf] = r[syn];
}
o[ts].push(row);
});
}
}
return o;
};
/**
* Выполняет запрос к rest-сервису и возвращает массив прототипов DataObj
* @param attr {Object} - параметры запроса
* @param mgr {DataManager}
* @return {Promise.<T>}
*/
this.ajax_to_data = function (attr, mgr) {
return $p.ajax.get_ex(attr.url, attr)
.then(function (req) {
return JSON.parse(req.response);
})
.then(function (res) {
var data = [];
res.value.forEach(function (rdata) {
data.push(_rest.to_data(rdata, mgr));
});
return data;
});
};
this.build_select = function (attr, mgr) {
var s, f, syn, type, select_str = "";
function build_condition(fld, val){
if(typeof val == "function"){
f += val(mgr, fld);
}else{
syn = _md.syns_1с(fld);
type = _md.get(mgr.class_name, fld);
if(type){
type = type.type;
if(type.is_ref){
if(syn.indexOf("_Key") == -1 && type.types.length && type.types[0].indexOf("enm.")==-1)
syn += "_Key";
}
if(type.types.length){
if(["boolean", "number"].indexOf(typeof val) != -1 )
f += syn + " eq " + val;
else if((type.is_ref && typeof val != "object") || val instanceof DataObj)
f += syn + " eq guid'" + val + "'";
else if(typeof val == "string")
f += syn + " eq '" + val + "'";
else if(typeof val == "object"){
// TODO: учесть in, not, like
if(val.hasOwnProperty("like"))
f += syn + " like '%" + val.like + "%'";
else if(val.hasOwnProperty("not")){
f += " not (" + build_condition(fld, val.not) + ") ";
}
else if(val.hasOwnProperty("in")){
f += (syn + " in (") + (type.is_ref ? val.in.map(function(v){return "guid'" + v + "'"}).join(",") : val.in.join(",")) + ") ";
}
}
}
}
}
}
function build_selection(sel){
for(var fld in sel){
if(!f)
f = "&$filter=";
else
f += " and ";
if(fld == "or" && Array.isArray(sel[fld])){
var first = true;
sel[fld].forEach(function (element) {
if(first){
f += " ( ";
first = false;
}else
f += " or ";
var key = Object.keys(element)[0];
build_condition(key, element[key]);
});
f += " ) ";
}else
build_condition(fld, sel[fld]);
}
}
if(!attr)
attr = {};
// учитываем нужные поля
if(attr.fields){
attr.fields.forEach(function(fld){
if(fld == "ref")
syn = "Ref_Key";
else{
syn = _md.syns_1с(fld);
type = _md.get(mgr.class_name, fld).type;
if(type.is_ref){
if(syn.indexOf("_Key") == -1 && type.types.length && type.types[0].indexOf("enm.")==-1)
syn += "_Key";
}
}
if(!s)
s = "&$select=";
else
s += ",";
s += syn;
});
select_str += s;
}
// учитываем отбор
// /a/unf/hs/rest/Catalog_Контрагенты?allowedOnly=true&$format=json&$top=30&$select=Ref_Key,Description&$filter=IsFolder eq false and Description like '%б%'
if(attr.selection){
if(typeof attr.selection == "function"){
}else if(Array.isArray(attr.selection))
attr.selection.forEach(build_selection);
else
build_selection(attr.selection);
if(f)
select_str += f;
}
// для простых запросов используем стандартный odata 1c
if($p.job_prm.rest &&
mgr.rest_name.indexOf("Module_") == -1 &&
mgr.rest_name.indexOf("DataProcessor_") == -1 &&
mgr.rest_name.indexOf("Report_") == -1 &&
select_str.indexOf(" like ") == -1 &&
select_str.indexOf(" in ") == -1 &&
!mgr.metadata().irest )
$p.ajax.default_attr(attr, $p.job_prm.rest_url());
// для сложных отборов либо при явном irest в метаданных, используем наш irest
else
$p.ajax.default_attr(attr, $p.job_prm.irest_url());
// начинаем строить url: только разрешенные + top
attr.url += mgr.rest_name + "?allowedOnly=true&$format=json&$top=" + (attr.top || 300) + select_str;
//a/unf/odata/standard.odata/Document_ЗаказПокупателя?allowedOnly=true&$format=json&$select=Ref_Key,DataVersion
};
/**
* Загружает список объектов из rest-сервиса, обрезанный отбором
* @method load_array
* @for DataManager
* @param attr {Object} - параметры запроса
* @param [attr.selection] {Object} - условия отбора
* @param [attr.top] {Number} - максимальное число загружаемых записей
* @param mgr {DataManager}
* @return {Promise.<T>} - промис с массивом загруженных прототипов DataObj
* @async
*/
this.load_array = function (attr, mgr) {
_rest.build_select(attr, mgr);
return _rest.ajax_to_data(attr, mgr);
};
/**
* Читает объект из rest-сервиса
* @return {Promise.<DataObj>} - промис с загруженным объектом
*/
this.load_obj = function (tObj) {
var attr = {};
$p.ajax.default_attr(attr, (!tObj._metadata.irest && $p.job_prm.rest) ? $p.job_prm.rest_url() : $p.job_prm.irest_url());
attr.url += tObj._manager.rest_name + "(guid'" + tObj.ref + "')?$format=json";
return $p.ajax.get_ex(attr.url, attr)
.then(function (req) {
return JSON.parse(req.response);
})
.then(function (res) {
tObj._mixin(_rest.to_data(res, tObj._manager))._set_loaded();
return tObj;
})
.catch(function (err) {
if(err.status==404)
return tObj;
else
$p.record_log(err);
});
};
/**
* Сохраняет объект в базе irest-сервиса (наш http-интерфейс)
* @param tObj {DataObj} - сохраняемый объект
* @param attr {Object} - параметры сохранения
* @param attr.[url] {String} - если не указано, будет использован адрес irest из параметров работы программы
* @param attr.[username] {String}
* @param attr.[password] {String}
* @param attr.[post] {Boolean|undefined} - проведение или отмена проведения или просто запись
* @param attr.[operational] {Boolean|undefined} - режим проведения документа [Оперативный, Неоперативный]
* @return {Promise.<T>}
* @async
*/
this.save_irest = function (tObj, attr) {
var post_data = JSON.stringify(tObj),
prm = (attr.post != undefined ? ",post="+attr.post : "")+
(attr.operational != undefined ? ",operational="+attr.operational : "");
$p.ajax.default_attr(attr, $p.job_prm.irest_url());
attr.url += tObj._manager.rest_name + "(guid'"+tObj.ref+"'"+prm+")";
return $p.ajax.post_ex(attr.url, post_data, attr)
.then(function (req) {
return JSON.parse(req.response);
})
.then(function (res) {
return tObj._mixin(res);
});
};
/**
* Сохраняет объект в базе rest-сервиса
* @param tObj {DataObj} - сохраняемый объект
* @param attr {Object} - параметры сохранения
* @param attr.[url] {String} - если не указано, будет использован адрес rest из параметров работы программы
* @param attr.[username] {String}
* @param attr.[password] {String}
* @param attr.[post] {Boolean|undefined} - проведение или отмена проведения или просто запись
* @param attr.[operational] {Boolean} - режим проведения документа [Оперативный, Неоперативный]
* @return {Promise.<T>}
* @async
*/
this.save_rest = function (tObj, attr) {
var atom = tObj.to_atom(),
url;
$p.ajax.default_attr(attr, $p.job_prm.rest_url());
url = attr.url + tObj._manager.rest_name;
// проверяем наличие ссылки в базе приёмника
attr.url = url + "(guid'" + tObj.ref + "')?$format=json&$select=Ref_Key,DeletionMark";
return $p.ajax.get_ex(attr.url, attr)
.catch(function (err) {
if(err.status == 404){
return {response: JSON.stringify({is_new: true})};
}else
return Promise.reject(err);
})
.then(function (req) {
return JSON.parse(req.response);
})
.then(function (data) {
// если объект существует на стороне приемника, выполняем patch, иначе - post
if(data.is_new)
return $p.ajax.post_ex(url, atom, attr);
else
return $p.ajax.patch_ex(url + "(guid'" + tObj.ref + "')", atom, attr);
})
.then(function (req) {
var data = xmlToJSON.parseString(req.response, {
mergeCDATA: false, // extract cdata and merge with text
grokAttr: true, // convert truthy attributes to boolean, etc
grokText: false, // convert truthy text/attr to boolean, etc
normalize: true, // collapse multiple spaces to single space
xmlns: false, // include namespaces as attribute in output
namespaceKey: '_ns', // tag name for namespace objects
textKey: '_text', // tag name for text nodes
valueKey: '_value', // tag name for attribute values
attrKey: '_attr', // tag for attr groups
cdataKey: '_cdata', // tag for cdata nodes (ignored if mergeCDATA is true)
attrsAsObject: false, // if false, key is used as prefix to name, set prefix to '' to merge children and attrs.
stripAttrPrefix: true, // remove namespace prefixes from attributes
stripElemPrefix: true, // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
childrenAsArray: false // force children into arrays
});
if(data.entry && data.entry.content && data.entry.updated){
var p = data.entry.content.properties, r = {}, v;
for(var i in p){
if(i.indexOf("_")==0)
continue;
if(v = p[i].element){
r[i] = [];
if(Array.isArray(v)){
for(var n in v){
r[i][n] = {};
for(var j in v[n])
if(j.indexOf("_")!=0)
r[i][n][j] = v[n][j]._text === "false" ? false : v[n][j]._text;
}
}else{
r[i][0] = {};
for(var j in v)
if(j.indexOf("_")!=0)
r[i][0][j] = v[j]._text === "false" ? false : v[j]._text;
}
}else
r[i] = p[i]._text === "false" ? false : p[i]._text;
}
return _rest.to_data(r, tObj._manager);
}
})
.then(function (res) {
return tObj._mixin(res);
});
};
}
var _rest = $p.rest = new Rest();
/**
* ### Имя объектов этого менеджера для запросов к rest-серверу
* Идентификатор формируется по принципу: ПрефиксИмени_ИмяОбъектаКонфигурации_СуффиксИмени
* - Справочник _Catalog_
* - Документ _Document_
* - Журнал документов _DocumentJournal_
* - Константа _Constant_
* - План обмена _ExchangePlan_
* - План счетов _ChartOfAccounts_
* - План видов расчета _ChartOfCalculationTypes_
* - План видов характеристик _ChartOfCharacteristicTypes_
* - Регистр сведений _InformationRegister_
* - Регистр накопления _AccumulationRegister_
* - Регистр расчета _CalculationRegister_
* - Регистр бухгалтерии _AccountingRegister_
* - Бизнес-процесс _BusinessProcess_
* - Задача _Task_
* - Обработка _DataProcessor_
* - Отчет _Report_
* - Общий модуль _Module_
* - Внешняя обработка _ExternalDataProcessor_
* - Внешний отчет _ExternalReport_
*
* @property rest_name
* @for DataManager
* @type String
* @final
*/
DataManager.prototype.__define("rest_name", {
get : function(){
var fp = this.class_name.split("."),
csyn = {
cat: "Catalog",
doc: "Document",
ireg: "InformationRegister",
areg: "AccumulationRegister",
cch: "ChartOfCharacteristicTypes",
cacc: "ChartOfAccounts",
tsk: "Task",
bp: "BusinessProcess"
};
return csyn[fp[0]] + "_" + _md.syns_1с(fp[1]);
},
enumerable : false
});
DataManager.prototype.rest_tree = function (attr) {
var t = this,
cmd = t.metadata(),
flds = [], ares = [], o, ro, syn, mf;
$p.ajax.default_attr(attr, (!cmd.irest && $p.job_prm.rest) ? $p.job_prm.rest_url() : $p.job_prm.irest_url());
attr.url += this.rest_name + "?allowedOnly=true&$format=json&$top=1000&$select=Ref_Key,DeletionMark,Parent_Key,Description&$filter=IsFolder eq true";
return $p.ajax.get_ex(attr.url, attr)
.then(function (req) {
return JSON.parse(req.response);
})
.then(function (res) {
for(var i = 0; i < res.value.length; i++) {
ro = res.value[i];
o = {
ref: ro["Ref_Key"],
_deleted: ro["DeletionMark"],
parent: ro["Parent_Key"],
presentation: ro["Description"]
};
ares.push(o);
}
return $p.iface.data_to_tree(ares);
});
};
DataManager.prototype.rest_selection = function (attr) {
if(attr.action == "get_tree")
return this.rest_tree(attr);
var t = this,
cmd = t.metadata(),
flds = [],
ares = [], o, ro, syn, mf,
select,
filter_added;
select = (function(){
var s = "$select=Ref_Key,DeletionMark";
if(cmd.form && cmd.form.selection){
cmd.form.selection.fields.forEach(function (fld) {
flds.push(fld);
});
}else if(t instanceof DocManager){
flds.push("posted");
flds.push("date");
flds.push("number_doc");
}else if(t instanceof TaskManager){
flds.push("name as presentation");
flds.push("date");
flds.push("number_doc");
flds.push("completed");
}else if(t instanceof BusinessProcessManager){
flds.push("date");
flds.push("number_doc");
flds.push("started");
flds.push("finished");
}else{
if(cmd["hierarchical"] && cmd["group_hierarchy"])
flds.push("is_folder");
else
flds.push("0 as is_folder");
if(cmd["main_presentation_name"])
flds.push("name as presentation");
else{
if(cmd["code_length"])
flds.push("id as presentation");
else
flds.push("'...' as presentation");
}
if(cmd["has_owners"])
flds.push("owner");
if(cmd["code_length"])
flds.push("id");
}
flds.forEach(function(fld){
var parts;
if(fld.indexOf(" as ") != -1){
parts = fld.split(" as ")[0].split(".");
if(parts.length == 1)
fld = parts[0];
else if(parts[0] != "_t_")
return;
else
fld = parts[1]
}
if(fld == "0")
return;
syn = _md.syns_1с(fld);
if(_md.get(t.class_name, fld).type.is_ref){
if(syn.indexOf("_Key") == -1 && _md.get(t.class_name, fld).type.types.length && _md.get(t.class_name, fld).type.types[0].indexOf("enm.")==-1)
syn += "_Key";
}
s += "," + syn;
});
flds.push("ref");
flds.push("_deleted");
return s;
})();
$p.ajax.default_attr(attr, (!cmd.irest && $p.job_prm.rest) ? $p.job_prm.rest_url() : $p.job_prm.irest_url());
attr.url += (cmd.irest && cmd.irest.selection ? cmd.irest.selection : this.rest_name) + "?allowedOnly=true&$format=json&$top=1000&" + select;
if(_md.get(t.class_name, "date") && (attr.date_from || attr.date_till)){
attr.url += "&$filter=" + _rest.filter_date("Date", attr.date_from, attr.date_till);
filter_added = true;
}
if(cmd["hierarchical"] && attr.parent){
attr.url += filter_added ? " and " : "&$filter=";
attr.url += "Parent_Key eq guid'" + attr.parent + "'";
filter_added = true;
}
if(cmd["has_owners"] && attr.owner){
attr.url += filter_added ? " and " : "&$filter=";
attr.url += "Owner_Key eq guid'" + attr.owner + "'";
filter_added = true;
}
if(attr.filter){
attr.url += filter_added ? " and " : "&$filter=";
attr.url += "$filter eq '" + attr.filter + "'";
filter_added = true;
}
return $p.ajax.get_ex(attr.url, attr)
.then(function (req) {
return JSON.parse(req.response);
})
.then(function (res) {
for(var i = 0; i < res.value.length; i++) {
ro = res.value[i];
o = {};
flds.forEach(function (fld) {
var fldsyn;
if(fld == "ref") {
o[fld] = ro["Ref_Key"];
return;
}else if(fld.indexOf(" as ") != -1){
fldsyn = fld.split(" as ")[1];
fld = fld.split(" as ")[0].split(".");
fld = fld[fld.length-1];
}else
fldsyn = fld;
syn = _md.syns_1с(fld);
mf = _md.get(t.class_name, fld);
if(mf){
if(syn.indexOf("_Key") == -1 && mf.type.is_ref && mf.type.types.length && mf.type.types[0].indexOf("enm.")==-1)
syn += "_Key";
if(mf.type.date_part)
o[fldsyn] = $p.moment(ro[syn]).format($p.moment._masks[mf.type.date_part]);
else if(mf.type.is_ref){
if(!ro[syn] || ro[syn] == $p.utils.blank.guid)
o[fldsyn] = "";
else{
var mgr = _md.value_mgr(o, fld, mf.type, false, ro[syn]);
if(mgr)
o[fldsyn] = mgr.get(ro[syn]).presentation;
else
o[fldsyn] = "";
}
}else
o[fldsyn] = ro[syn];
}
});
ares.push(o);
}
return $p.iface.data_to_grid.call(t, ares, attr);
});
};
InfoRegManager.prototype.rest_slice_last = function(selection){
if(!selection.period)
selection.period = $p.utils.date_add_day(new Date(), 1);
var t = this,
cmd = t.metadata(),
period = "Period=datetime'" + $p.moment(selection.period).format($p.moment._masks.iso) + "'",
condition = "";
for(var fld in cmd.dimensions){
if(selection[fld] === undefined)
continue;
var syn = _md.syns_1с(fld),
mf = cmd.dimensions[fld];
if(syn.indexOf("_Key") == -1 && mf.type.is_ref && mf.type.types.length && mf.type.types[0].indexOf("enm.")==-1){
syn += "_Key";
if(condition)
condition+= " and ";
condition+= syn+" eq guid'"+selection[fld].ref+"'";
}else{
if(condition)
condition+= " and ";
if(mf.type.digits)
condition+= syn+" eq "+$p.utils.fix_number(selection[fld]);
else if(mf.type.date_part)
condition+= syn+" eq datetime'"+ $p.moment(selection[fld]).format($p.moment._masks.iso) +"'";
else
condition+= syn+" eq '"+selection[fld]+"'";
}
}
if(condition)
period+= ",Condition='"+condition+"'";
$p.ajax.default_attr(selection, $p.job_prm.rest_url());
selection.url += this.rest_name + "/SliceLast(%sl)?allowedOnly=true&$format=json&$top=1000".replace("%sl", period);
return _rest.ajax_to_data(selection, t)
.then(function (data) {
return t.load_array(data);
});
};
/**
* Сериализует объект данных в формат xml/atom (например, для rest-сервиса 1С)
* @param [ex_meta] {Object} - метаданные внешней по отношению к текущей базы (например, для записи в *УНФ* объекта *Заказа дилера*).
* Если указано, вывод ограничен полями, доступными во внешней базе + используются синонимы внешней базы
*/
DataObj.prototype.to_atom = function (ex_meta) {
var res = '<entry><category term="StandardODATA.%n" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>\
\n<title type="text"/><updated>%d</updated><author/><summary/><content type="application/xml">\
\n<m:properties xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">\
%p\
\n</m:properties></content></entry>'
.replace('%n', this._manager.rest_name)
.replace('%d', $p.moment().format($p.moment.defaultFormatUtc)),
prop = '\n<d:Ref_Key>' + this.ref + '</d:Ref_Key>' +
'\n<d:DeletionMark>' + this._deleted + '</d:DeletionMark>',
// '\n<d:DataVersion>' + this.data_version + '</d:DataVersion>',
f, mf, fts, ts, mts, pname, v;
function fields_to_atom(obj){
var meta_fields = obj._metadata.fields,
prefix = obj instanceof TabularSectionRow ? '\n\t<d:' : '\n<d:';
for(f in meta_fields){
mf = meta_fields[f];
pname = _md.syns_1с(f);
v = obj[f];
if(v instanceof EnumObj)
v = v.empty() ? "" : v.name;
else if(v instanceof DataObj){
if(pname.indexOf("_Key") == -1)
pname+= '_Key';
v = v.ref;
}else if(mf.type.date_part){
if(v.getFullYear() < 1000)
v = '0001-01-01T00:00:00Z';
else
v = $p.moment(v).format($p.moment.defaultFormatUtc);
}else if(v == undefined)
continue;
prop+= prefix + pname + '>' + v + '</d:' + pname + '>';
}
}
if(this instanceof DocObj){
prop+= '\n<d:Date>' + $p.moment(this.date).format($p.moment.defaultFormatUtc) + '</d:Date>';
prop+= '\n<d:Number>' + this.number_doc + '</d:Number>';
} else {
if(this._metadata.main_presentation_name)
prop+= '\n<d:Description>' + this.name + '</d:Description>';
if(this._metadata.code_length)
prop+= '\n<d:Code>' + this.id + '</d:Code>';
if(this._metadata.hierarchical && this._metadata.group_hierarchy)
prop+= '\n<d:IsFolder>' + this.is_folder + '</d:IsFolder>';
}
fields_to_atom(this);
for(fts in this._metadata.tabular_sections) {
mts = this._metadata.tabular_sections[fts];
//if(mts.hide)
// continue;
pname = 'StandardODATA.' + this._manager.rest_name + '_' + _md.syns_1с(fts) + '_RowType';
ts = this[fts];
if(ts.count()){
prop+= '\n<d:' + _md.syns_1с(fts) + ' m:type="Collection(' + pname + ')">';
ts.each(function (row) {
prop+= '\n\t<d:element m:type="' + pname + '">';
prop+= '\n\t<d:LineNumber>' + row.row + '</d:LineNumber>';
fields_to_atom(row);
prop+= '\n\t</d:element>';
});
prop+= '\n</d:' + _md.syns_1с(fts) + '>';
}else
prop+= '\n<d:' + _md.syns_1с(fts) + ' m:type="Collection(' + pname + ')" />';
}
return res.replace('%p', prop);
//<d:DeletionMark>false</d:DeletionMark>
//<d:Ref_Key>213d87ad-33d5-11de-b58f-00055d80a2b8</d:Ref_Key>
//<d:IsFolder>false</d:IsFolder>
//<d:Description>Новая папка</d:Description>
//<d:Запасы m:type="Collection(StandardODATA.Document_ЗаказПокупателя_Запасы_RowType)">
// <d:element m:type="StandardODATA.Document_ЗаказПокупателя_Запасы_RowType">
// <d:LineNumber>1</d:LineNumber>
// <d:Номенклатура_Key>6ebf3bf7-3565-11de-b591-00055d80a2b9</d:Номенклатура_Key>
// <d:ТипНоменклатурыЗапас>true</d:ТипНоменклатурыЗапас>
// <d:Характеристика_Key>00000000-0000-0000-0000-000000000000</d:Характеристика_Key>
// <d:ПроцентАвтоматическойСкидки>0</d:ПроцентАвтоматическойСкидки>
// <d:СуммаАвтоматическойСкидки>0</d:СуммаАвтоматическойСкидки>
// <d:КлючСвязи>0</d:КлючСвязи>
// </d:element>
//</d:Запасы>
//<d:МатериалыЗаказчика m:type="Collection(StandardODATA.Document_ЗаказПокупателя_МатериалыЗаказчика_RowType)"/>
};