Программный интерфейс

Показывать:
  1. /**
  2. * Процедуры импорта и экспорта данных
  3. *
  4. * © Evgeniy Malyarov http://www.oknosoft.ru 2014-2016
  5. *
  6. * @module metadata
  7. * @submodule import_export
  8. * @requires common
  9. */
  10.  
  11.  
  12. /**
  13. * ### Экспортирует данные в файл или в строковую переменную или на сервер
  14. * - Выгружаться может как единичный объект, так и коллекция объектов
  15. * - В параметрах метода либо интерактивно могут задаваться правила экспорта, такие как:
  16. * - Формат формируемого файла (json, xlsx, sql)
  17. * - Дополнять ли формируемый файл информацией о метаданных (типы и связи полей)
  18. * - Включать ли в формируемый файл данные связанных объектов<br />(например, выгружать вместе с заказом объекты номенклатуры и характеристик)
  19. *
  20. * @method export
  21. * @for DataManager
  22. * @param attr {Object} - параметры экспорта
  23. * @param [attr.pwnd] {dhtmlXWindows} - указатель на родительскую форму
  24. *
  25. * @example
  26. *
  27. * // обработчик нажатия кнопок командной панели формы списка
  28. * function toolbar_click(btn_id){
  29. * if(btn_id=="btn_import"){
  30. * // открываем диалог импорта объектов текущего менеджера
  31. * _mgr.import();
  32. * }else if(btn_id=="btn_export"){
  33. * // открываем диалог экспорта объектов текущего менеджера и передаём ссылку текущей строки
  34. * // если ссылка не пустая, будет предложено экспортировать единственный объект
  35. * // при необходимости, в диалоге можно указать экспорт всех объектов текущего менеджера
  36. * _mgr.export(wnd.elmnts.grid.getSelectedRowId());
  37. * }
  38. * }
  39. */
  40. DataManager.prototype.export = function(attr){
  41.  
  42. if(attr && "string" === typeof attr)
  43. attr = {items: attr.split(",")};
  44. else if(!attr)
  45. attr = {items: []};
  46.  
  47.  
  48. var _mgr = this, wnd,
  49. options = {
  50. name: 'export',
  51. wnd: {
  52. top: 130,
  53. left: 200,
  54. width: 480,
  55. height: 350
  56. }
  57. };
  58.  
  59. // читаем объект из локального SQL или из 1С
  60. frm_create();
  61.  
  62.  
  63. /**
  64. * ПриСозданииНаСервере()
  65. */
  66. function frm_create(){
  67.  
  68. $p.wsql.restore_options("data_manager", options);
  69. options.wnd.caption = "Экспорт " + _mgr.family_name + " '" + (_mgr.metadata().synonym || _mgr.metadata().name) + "'";
  70.  
  71. wnd = $p.iface.dat_blank(null, options.wnd);
  72.  
  73. wnd.bottom_toolbar({
  74. buttons: [
  75. {name: 'btn_cancel', text: '<i class="fa fa-times fa-lg"></i> Отмена', title: 'Отмена', width:'80px', float: 'right'},
  76. {name: 'btn_ok', b: '<i class="fa fa-floppy-o"></i> Ок', title: 'Выполнить экспорт', width:'50px', float: 'right'}],
  77. onclick: function (name) {
  78. if(name == 'btn_ok')
  79. do_export();
  80. else
  81. wnd.close();
  82. return false;
  83. }
  84. });
  85.  
  86.  
  87. wnd.button('close').show();
  88. wnd.button('park').hide();
  89. wnd.attachEvent("onClose", frm_close);
  90.  
  91. var str = [
  92. { type:"fieldset" , name:"form_range", label:"Выгрузить", list:[
  93. { type:"settings" , labelWidth:320, labelAlign:"left", position:"label-right" },
  94. { type:"radio" , name:"range", label:"Выделенные строки", value:"selected" },
  95. { type:"radio" , name:"range", label:"Весь справочник", value:"all" }
  96. ]},
  97. { type:"fieldset" , name:"form_fieldset_2", label:"Дополнительно выгрузить", list:[
  98. { type:"settings" , labelWidth:160, position:"label-right" },
  99. { type:"checkbox" , name:"meta", label:"Описание метаданных", labelAlign:"left", position:"label-right", checked: options.meta },
  100. { type:"newcolumn" },
  101. { type:"checkbox" , name:"relation", label:"Связанные объекты", position:"label-right", checked: options.relation, tooltip: "Связанные объекты по ссылкам (пока не реализовано)" }
  102. ] },
  103. { type:"fieldset" , name:"fieldset_format", label:"Формат файла", list:[
  104. { type:"settings" , labelWidth:60, labelAlign:"left", position:"label-right" },
  105. { type:"radio" , name:"format", label:"json", value:"json", tooltip: "Выгрузить в формате JSON" },
  106. { type:"newcolumn" },
  107. { type:"radio" , name:"format", label:"xlsx", value:"xlsx", tooltip: "Выгрузить в офисном формате XLSX" },
  108. { type:"newcolumn" },
  109. { type:"radio" , name:"format", label:"atom", value:"atom", tooltip: "Выгрузить в формате XML Atom" }
  110.  
  111. ] }
  112.  
  113.  
  114. ];
  115. wnd.elmnts.frm = wnd.attachForm(str);
  116.  
  117. wnd.elmnts.frm.setItemValue("range", options.range || "all");
  118.  
  119. if(attr.items && attr.items.length == 1){
  120. if(attr.obj)
  121. wnd.elmnts.frm.setItemLabel("range", "selected", "Тек. объект: " + attr.items[0].presentation);
  122. else
  123. _mgr.get(attr.items[0], true).then(function (Obj) {
  124. wnd.elmnts.frm.setItemLabel("range", "selected", "Тек. объект: " + Obj.presentation);
  125. });
  126. wnd.elmnts.frm.setItemValue("range", "selected");
  127.  
  128. }else if(attr.items && attr.items.length)
  129. wnd.elmnts.frm.setItemLabel("range", "selected", "Выделенные строки (" + attr.items.length + " элем.)");
  130.  
  131. if(_mgr instanceof DocManager)
  132. wnd.elmnts.frm.setItemLabel("range", "all", "Все документы из кеша (0 элем.)");
  133.  
  134.  
  135. wnd.elmnts.frm.setItemValue("format", options.format || "json");
  136.  
  137. wnd.elmnts.frm.attachEvent("onChange", set_availability);
  138.  
  139. set_availability();
  140.  
  141. if(attr.pwnd && attr.pwnd.isModal && attr.pwnd.isModal()){
  142. attr.set_pwnd_modal = true;
  143. attr.pwnd.setModal(false);
  144. }
  145. wnd.setModal(true);
  146.  
  147. }
  148.  
  149. function set_availability(){
  150.  
  151. wnd.elmnts.frm.setItemValue("relation", false);
  152. wnd.elmnts.frm.disableItem("relation");
  153.  
  154. if(wnd.elmnts.frm.getItemValue("range") == "all"){
  155. wnd.elmnts.frm.disableItem("format", "atom");
  156. if(wnd.elmnts.frm.getItemValue("format") == "atom")
  157. wnd.elmnts.frm.setItemValue("format", "json");
  158. }else
  159. wnd.elmnts.frm.enableItem("format", "atom");
  160.  
  161. if(wnd.elmnts.frm.getItemValue("format") == "json"){
  162. wnd.elmnts.frm.enableItem("meta");
  163.  
  164. }else if(wnd.elmnts.frm.getItemValue("format") == "sql"){
  165. wnd.elmnts.frm.setItemValue("meta", false);
  166. wnd.elmnts.frm.disableItem("meta");
  167.  
  168. }else{
  169. wnd.elmnts.frm.setItemValue("meta", false);
  170. wnd.elmnts.frm.disableItem("meta");
  171.  
  172. }
  173. }
  174.  
  175. function refresh_options(){
  176. options.format = wnd.elmnts.frm.getItemValue("format");
  177. options.range = wnd.elmnts.frm.getItemValue("range");
  178. options.meta = wnd.elmnts.frm.getItemValue("meta");
  179. options.relation = wnd.elmnts.frm.getItemValue("relation");
  180. return options;
  181. }
  182.  
  183. function do_export(){
  184.  
  185. refresh_options();
  186.  
  187. function export_xlsx(){
  188. if(attr.obj)
  189. $p.wsql.alasql("SELECT * INTO XLSX('"+_mgr.table_name+".xlsx',{headers:true}) FROM ?", [attr.items[0]._obj]);
  190. else
  191. $p.wsql.alasql("SELECT * INTO XLSX('"+_mgr.table_name+".xlsx',{headers:true}) FROM " + _mgr.table_name);
  192. }
  193.  
  194. var res = {meta: {}, items: {}},
  195. items = res.items[_mgr.class_name] = [];
  196.  
  197. //$p.wsql.aladb.tables.refs.data.push({ref: "dd274d11-833b-11e1-92c2-8b79e9a2b61c"})
  198. //$p.wsql.alasql('select * from cat_cashboxes where ref in (select ref from refs)')
  199.  
  200. if(options.meta)
  201. res.meta[_mgr.class_name] = _mgr.metadata();
  202.  
  203. if(options.format == "json"){
  204.  
  205. if(attr.obj)
  206. items.push(attr.items[0]._obj);
  207. else
  208. _mgr.each(function (o) {
  209. if(options.range == "all" || attr.items.indexOf(o.ref) != -1)
  210. items.push(o._obj);
  211. });
  212.  
  213. if(attr.items.length && !items.length)
  214. _mgr.get(attr.items[0], true).then(function (Obj) {
  215. items.push(Obj._obj);
  216. alasql.utils.saveFile(_mgr.table_name+".json", JSON.stringify(res, null, 4));
  217. });
  218.  
  219. else
  220. alasql.utils.saveFile(_mgr.table_name+".json", JSON.stringify(res, null, 4));
  221.  
  222. }else if(options.format == "xlsx"){
  223. if(!window.xlsx)
  224. $p.load_script("//cdn.jsdelivr.net/js-xlsx/latest/xlsx.core.min.js", "script", export_xlsx);
  225. else
  226. export_xlsx();
  227.  
  228. }else if(options.format == "atom" && attr.items.length){
  229.  
  230. var po = attr.obj ? Promise.resolve(attr.items[0]) : _mgr.get(attr.items[0], true);
  231. po.then(function (o) {
  232. alasql.utils.saveFile(_mgr.table_name+".xml", o.to_atom());
  233. });
  234.  
  235. }else{
  236. //$p.wsql.alasql("SELECT * INTO SQL('"+_mgr.table_name+".sql') FROM " + _mgr.table_name);
  237. $p.msg.show_not_implemented();
  238. }
  239. }
  240.  
  241. function frm_close(win){
  242.  
  243. $p.iface.popup.hide();
  244. wnd.wnd_options(options.wnd);
  245. $p.wsql.save_options("data_manager", refresh_options());
  246.  
  247. wnd.setModal(false);
  248. if(attr.set_pwnd_modal && attr.pwnd.setModal)
  249. attr.pwnd.setModal(true);
  250.  
  251. return true;
  252. }
  253.  
  254.  
  255. };
  256.  
  257. /**
  258. * Осуществляет загрузку данных из json-файла
  259. * @param [file] {String|Blob|undefined}
  260. * @param [obj] {DataObj} - если указано, загрузка осуществляется только в этот объект. остальные данные файла - игнорируются
  261. */
  262. DataManager.prototype.import = function(file, obj){
  263.  
  264. var input_file, imported;
  265.  
  266. function import_file(event){
  267.  
  268. function do_with_collection(cl_name, items){
  269. var _mgr = _md.mgr_by_class_name(cl_name);
  270. if(items.length){
  271. if(!obj){
  272. imported = true;
  273. _mgr.load_array(items, true);
  274. } else if(obj._manager == _mgr){
  275. for(var i in items){
  276. if($p.utils.fix_guid(items[i]) == obj.ref){
  277. imported = true;
  278. _mgr.load_array([items[i]], true);
  279. }
  280. }
  281. }
  282. }
  283. }
  284.  
  285. wnd.close();
  286. if(input_file.files.length){
  287.  
  288. var reader = new FileReader();
  289. reader.onload = function(e) {
  290. try{
  291. var res = JSON.parse(reader.result);
  292.  
  293. if(res.items){
  294. for(var cl_name in res.items)
  295. do_with_collection(cl_name, res.items[cl_name]);
  296.  
  297. }else{
  298. ["cat", "doc", "ireg", "areg", "cch", "cacc"].forEach(function (cl) {
  299. if(res[cl]) {
  300. for (var cl_name in res[cl])
  301. do_with_collection(cl + "." + cl_name, res.cat[cl_name]);
  302. }
  303. });
  304. }
  305. if(!imported)
  306. $p.msg.show_msg($p.msg.sync_no_data);
  307.  
  308. }catch(err){
  309. $p.msg.show_msg(err.message);
  310. }
  311. };
  312. reader.readAsText(input_file.files[0]);
  313. }
  314. }
  315.  
  316. if(!file && typeof window != undefined){
  317.  
  318. var options = {
  319. name: 'import',
  320. wnd: {
  321. width: 300,
  322. height: 100,
  323. caption: $p.msg.select_file_import
  324. }
  325. },
  326. wnd = $p.iface.dat_blank(null, options.wnd);
  327.  
  328. input_file = document.createElement("input");
  329. input_file.setAttribute("id", "json_file");
  330. input_file.setAttribute("type", "file");
  331. input_file.setAttribute("accept", ".json");
  332. input_file.setAttribute("value", "*.json");
  333. input_file.onchange = import_file;
  334.  
  335. wnd.button('close').show();
  336. wnd.button('park').hide();
  337. wnd.attachObject(input_file);
  338. wnd.centerOnScreen();
  339. wnd.setModal(true);
  340.  
  341. setTimeout(function () {
  342. input_file.click();
  343. }, 100);
  344. }
  345. };
  346.