main.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. window.pdfjsLib.GlobalWorkerOptions.workerSrc = '/print_engine/static/lib/js/pdf.worker.js';
  2. // Tools
  3. openerp.pdfJs = window.pdfjsLib || {};
  4. openerp.printJs = window.printJS || {};
  5. openerp.html2canvas = window.html2canvas || {};
  6. /**
  7. *
  8. * @param {*} instance
  9. * @param {*} local
  10. */
  11. openerp.print_engine = function (instance, local) {
  12. // Clase que maneja el socket de conexión entre odoo y el programa de impresión cliente encargada de la impresión directa
  13. var SocketManager = instance.web.Class.extend({
  14. init: function () {
  15. this.socket = null;
  16. this.start();
  17. },
  18. start: function () {
  19. this.open_socket();
  20. },
  21. open_socket: function () {
  22. var self = this;
  23. var setup = self.setup_socket = function (config) {
  24. self.config = config;
  25. self.config.is_mobile = self.is_mobile_browser()
  26. if (!self.config.is_mobile) {
  27. self.socket = io(location.protocol + '//' + config.host + ':' + config.port, {
  28. path: config.path
  29. });
  30. self.socket.on('connect', self.handle_connect);
  31. self.socket.on('error', self.handle_error);
  32. self.socket.on('connect_error', self.handle_connect_error);
  33. self.socket.on('request_printer_name', self.handle_printer_selection);
  34. self.socket.on('show_print_status', self.handle_print_status);
  35. self.socket.on('download_data', self.handle_download_data);
  36. }
  37. }
  38. this.get_socket_config().then(setup);
  39. },
  40. update_config: function () {
  41. instance.web.blockUI();
  42. var self = this;
  43. this.get_socket_config().then(function (config) {
  44. instance.web.unblockUI();
  45. self.config = _.extend(self.config, config);
  46. self.socket.destroy();
  47. self.setup_socket(config);
  48. });
  49. },
  50. handle_connect: function () {
  51. $('#printer-status').removeClass();
  52. $('#printer-status').addClass('printer-status-online');
  53. },
  54. handle_error: function (e) {
  55. instance.webclient.crashmanager.show_message(e);
  56. },
  57. handle_connect_error: function (e) {
  58. $('#printer-status').removeClass();
  59. $('#printer-status').addClass('printer-status-offline');
  60. },
  61. handle_printer_selection: function (data) {
  62. instance.web.unblockUI();
  63. var self = this;
  64. if (data.printers && data.printers.length === 0) {
  65. instance.web.notification.do_notify('Impresión', 'No hay impresoras instaladas');
  66. return;
  67. }
  68. var widget = new PrinterSelectionDialog(data);
  69. widget.get_selection().then(function (request) {
  70. self.emit('request_print', request);
  71. });
  72. },
  73. handle_print_status: function (data) {
  74. instance.web.unblockUI();
  75. if (_.isEqual(data.status, 'failed')) {
  76. instance.web.notification.do_warn('Impresión', 'Ha fallado la cola de impresión');
  77. return;
  78. }
  79. if (_.isEqual(data.status, 'canceled')) {
  80. instance.web.notification.do_notify('Impresión', 'Se ha cancelado la impresión');
  81. return;
  82. }
  83. if (_.isEqual(data.status, 'unknown')) {
  84. instance.web.notification.do_warn('Impresión', 'Imposible imprimir un formato de datos desconocido');
  85. return;
  86. }
  87. if (_.isEqual(data.status, 'printing')) {
  88. instance.web.notification.do_notify('Impresión', 'La impresora ' + data.printer + ' está imprimiendo');
  89. return;
  90. }
  91. if (_.isEqual(data.status, 'printed')) {
  92. instance.web.notification.do_notify('Impresión', 'La impresora ' + data.printer + ' finalizó la impresión');
  93. return;
  94. }
  95. if (_.isEqual(data.status, 'error')) {
  96. instance.web.notification.do_warn('Impresión', 'Ocurrió un error al imprimir: ' + data.printer);
  97. }
  98. },
  99. handle_download_data: function (data) {
  100. instance.web.blockUI();
  101. instance.pdfJs.getDocument({
  102. data: atob(data)
  103. }).then(function (pdf) {
  104. if (local.socket_manager.config.action_download_pdf) {
  105. pdf.getData().then(function (data) {
  106. instance.web.unblockUI();
  107. var url = instance.pdfJs.createObjectURL(data, 'application/pdf');
  108. var a = document.createElement('a');
  109. a.href = url;
  110. a.download = 'download.pdf';
  111. a.target = '_parent';
  112. a.click();
  113. });
  114. return;
  115. }
  116. preview_pdf(null, pdf);
  117. });
  118. },
  119. get_socket_config: function () {
  120. var url = '/print_engine/socket_config';
  121. return this.get_from_server(url);
  122. },
  123. get_from_server: function (url) {
  124. instance.web.blockUI();
  125. return $.Deferred(function (d) {
  126. instance.web.jsonRpc(url, 'call').done(function () {
  127. instance.web.unblockUI();
  128. d.resolve.apply(d, arguments);
  129. }).fail(function (e) {
  130. instance.web.unblockUI();
  131. d.reject.apply(d, arguments);
  132. });
  133. });
  134. },
  135. is_mobile_browser: function () {
  136. var userAgent = navigator.userAgent;
  137. return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4));
  138. },
  139. request_print: function (data, print_directly) {
  140. if (!data) {
  141. instance.web.notification.do_warn('Impresión', 'No hay datos para imprimir');
  142. return;
  143. }
  144. if (!this.socket || !this.socket.connected) {
  145. instance.web.notification.do_warn('Impresión', 'La impresora no está preparada');
  146. return;
  147. }
  148. instance.web.blockUI();
  149. var mime_type = 'data:application/pdf;base64,';
  150. if (data instanceof Uint8Array) {
  151. data = mime_type + btoa(String.fromCharCode.apply(null, data));
  152. }
  153. if (!data.startsWith(mime_type)) {
  154. data = mime_type + data;
  155. }
  156. try {
  157. atob(data.replace(mime_type, ''));
  158. this.socket.emit('request_print', {
  159. print_directly: print_directly || this.config.print_directly,
  160. data: data
  161. });
  162. } catch (e) {
  163. instance.web.unblockUI();
  164. instance.webclient.crashmanager.show_message(e);
  165. }
  166. }
  167. });
  168. // Diálogo que sirve para descargar del repositorio el programa cliente
  169. var DownloadPrinterTools = instance.web.Widget.extend({
  170. template: 'DownloadPrinterTools',
  171. events: {
  172. 'click .download_button': 'handle_download'
  173. },
  174. init: function (parent) {
  175. this._super(parent);
  176. },
  177. start: function () {
  178. this.renderElement();
  179. this.$el.appendTo($('body'));
  180. this.$el.on('hidden.bs.modal', this, this.on_hide);
  181. if (this.is_linux_platform()) {
  182. this.$('.download_logo_windows').css('display', 'none');
  183. this.$('.windows_download_button').css('display', 'none');
  184. }
  185. if (this.is_win_platform()) {
  186. this.$('.download_logo_linux').css('display', 'none');
  187. this.$('.linux_download_button').css('display', 'none');
  188. }
  189. this.$el.modal('show');
  190. },
  191. on_hide: function (e) {
  192. var self = e.data;
  193. self.$el.remove();
  194. self.destroy();
  195. },
  196. is_win_platform: function () {
  197. return /^Win(?:32|64)$/.test(navigator.platform);
  198. },
  199. is_linux_platform: function () {
  200. return /^Linux\sx86(?:|_64)$/.test(navigator.platform);
  201. },
  202. handle_download: function (e) {
  203. var download_url = 'https://repo.eiru.com.py/attachments/';
  204. if (this.is_linux_platform()) {
  205. download_url += '94bcc4d4-8fe7-45f9-8715-97c11fdcdd6f';
  206. }
  207. if (this.is_win_platform()) {
  208. download_url += '8b9b5283-c5f8-4a62-a798-2691b72936bd';
  209. }
  210. var a = document.createElement('a');
  211. a.href = download_url;
  212. a.target = '_parent';
  213. a.click();
  214. this.$el.modal('hide');
  215. }
  216. });
  217. // Icono de notificación en la barra superior del sistema
  218. var PrinterTopNotificator = instance.web.Widget.extend({
  219. template: 'PrinterTopNotificator',
  220. events: {
  221. 'click .printer_status_notificator': 'handle_click'
  222. },
  223. init: function (parent) {
  224. this._super(parent);
  225. },
  226. handle_click: function (e) {
  227. e.preventDefault();
  228. if (local.socket_manager.socket.disconnected) {
  229. var widget = new DownloadPrinterTools(this);
  230. widget.start();
  231. }
  232. }
  233. });
  234. // Diálogo de impresión cuando la impresión directa no está disponible
  235. var PrinterUnavailableDialog = instance.web.Widget.extend({
  236. template: 'PrinterUnavailableDialog',
  237. events: {
  238. 'click li': 'on_download'
  239. },
  240. init: function (parent) {
  241. this._super(parent);
  242. this.start();
  243. },
  244. start: function () {
  245. this.defer = $.Deferred();
  246. this.render_widget();
  247. },
  248. render_widget: function () {
  249. this.renderElement();
  250. $('body').append(this.$el);
  251. this.$el.on('hidden.bs.modal', this, this.on_hide);
  252. this.$el.modal('show');
  253. },
  254. on_download: function () {
  255. this.download_pdf = true;
  256. this.$el.modal('hide');
  257. },
  258. on_hide: function (e) {
  259. var self = e.data;
  260. self.defer.resolve(!!self.download_pdf);
  261. self.destroy();
  262. self.$el.remove();
  263. },
  264. can_download: function () {
  265. return this.defer;
  266. }
  267. });
  268. // Diálogo de selección de la impresora que se encargará de la impresión
  269. var PrinterSelectionDialog = instance.web.Widget.extend({
  270. template: 'PrinterSelectionDialog',
  271. events: {
  272. 'click li': 'on_select'
  273. },
  274. init: function (data) {
  275. var config = local.socket_manager.config;
  276. this.download_pdf = config.action_download_pdf || config.action_preview_pdf || false;
  277. this.printers = data.printers || [];
  278. this.id = data.id;
  279. this.start();
  280. },
  281. start: function () {
  282. this.defer = $.Deferred();
  283. this.render_widget();
  284. },
  285. render_widget: function () {
  286. this.renderElement();
  287. $('body').append(this.$el);
  288. this.$el.on('hidden.bs.modal', this, this.on_hide);
  289. this.$el.modal('show');
  290. },
  291. get_selection: function () {
  292. return this.defer;
  293. },
  294. on_select: function (e) {
  295. var $el = $(e.target).closest('li');
  296. var name = $el.data('name');
  297. this.selected_printer = name;
  298. this.$el.modal('hide');
  299. },
  300. on_hide: function (e) {
  301. var self = e.data;
  302. self.defer.resolve({
  303. id: self.id,
  304. printer: self.selected_printer,
  305. print_directly: true
  306. });
  307. self.$el.remove();
  308. }
  309. });
  310. // Pequeño visor pdf
  311. var PdfViewerDialog = instance.web.Widget.extend({
  312. template: 'PdfViewerDialog',
  313. events: {
  314. 'click a.btn': 'on_action'
  315. },
  316. init: function (parent, source, name) {
  317. this._super(parent);
  318. this.source = source;
  319. this.name = name;
  320. this.set('current_page', -1);
  321. this.on('change:current_page', this, this.render_page);
  322. if (_.isObject(this.source)) {
  323. this.pdf = source;
  324. this.render_widget();
  325. return;
  326. }
  327. var matchReportUrl = this.source.match(/(?:\/(?:web\/)?report(?:\/pdf)?)/);
  328. if (matchReportUrl) {
  329. var self = this;
  330. instance.web.blockUI();
  331. instance.pdfJs.getDocument(self.source).then(function (pdf) {
  332. self.pdf = pdf;
  333. self.render_widget();
  334. });
  335. return;
  336. }
  337. var matchMimeType = this.source.match(/data:[a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+.*,/);
  338. if (matchMimeType) {
  339. if (self.source.startsWith('data:application/pdf;base64,')) {
  340. self.source = {
  341. data: self.source
  342. };
  343. }
  344. }
  345. try {
  346. atob(this.source.data || this.source);
  347. } catch (e) {
  348. instance.webclient.crashmanager.show_message('Unknown data format');
  349. }
  350. var self = this;
  351. instance.web.blockUI();
  352. instance.pdfJs.getDocument(self.source.data || self.source).then(function (pdf) {
  353. self.pdf = pdf;
  354. self.render_widget();
  355. });
  356. },
  357. render_widget: function () {
  358. this.renderElement();
  359. $('body').append(this.$el);
  360. this.$el.on('shown.bs.modal', this, this.render_pdf);
  361. this.$el.on('hidden.bs.modal', this, this.on_hide);
  362. this.$el.modal('show');
  363. },
  364. render_pdf: function (e) {
  365. var self = e.data;
  366. if (!self.pdf) {
  367. instance.web.unblockUI();
  368. instance.web.notification.do_warn('No hay archivo PDF');
  369. return;
  370. }
  371. self.set('current_page', 1);
  372. },
  373. render_page: function () {
  374. var self = this;
  375. var current_page = self.get('current_page');
  376. self.pdf.getPage(current_page).then(function (page) {
  377. var scale = 1;
  378. var viewport = page.getViewport(scale);
  379. var $canvas = self.$el.find('canvas');
  380. var context = $canvas.get(0).getContext('2d');
  381. $canvas.attr('height', viewport.height);
  382. $canvas.attr('width', viewport.width);
  383. page.render({
  384. canvasContext: context,
  385. viewport: viewport
  386. }).then(function () {
  387. self.$('.page_counter').text('Página ' + current_page + ' de ' + self.pdf.numPages);
  388. instance.web.unblockUI();
  389. });
  390. }, function (error) {
  391. instance.web.unblockUI();
  392. instance.webclient.crashmanager.show_message(error);
  393. });
  394. },
  395. on_hide: function (e) {
  396. var self = e.data;
  397. if (self.pdf) {
  398. self.pdf.destroy();
  399. }
  400. self.destroy();
  401. self.$el.remove();
  402. },
  403. on_action: function (e) {
  404. e.preventDefault();
  405. var action = $(e.target).closest('a').data('action');
  406. this['on_' + action]();
  407. },
  408. on_next: function () {
  409. var current_page = this.get('current_page');
  410. if (current_page >= this.pdf.numPages) {
  411. return;
  412. }
  413. this.set('current_page', current_page + 1);
  414. },
  415. on_previous: function () {
  416. var current_page = this.get('current_page');
  417. if (current_page <= 1) {
  418. return;
  419. }
  420. this.set('current_page', current_page - 1);
  421. },
  422. on_print: function () {
  423. var self = this;
  424. if (!self.pdf) {
  425. return;
  426. }
  427. instance.web.blockUI();
  428. self.pdf.getData().then(function (data) {
  429. instance.web.unblockUI();
  430. if (local.socket_manager.socket.connected) {
  431. local.socket_manager.request_print(data, true);
  432. return;
  433. }
  434. instance.printJs({
  435. printable: instance.pdfJs.createObjectURL(data, 'application/pdf')
  436. });
  437. });
  438. },
  439. on_download: function () {
  440. var self = this;
  441. if (!self.pdf) {
  442. return;
  443. }
  444. self.pdf.getMetadata().then(function (metadata) {
  445. self.pdf.getData().then(function (data) {
  446. var url = instance.pdfJs.createObjectURL(data, 'application/pdf');
  447. var a = document.createElement('a');
  448. a.href = url;
  449. a.download = (self.name || metadata.contentDispositionFilename) + '.pdf';
  450. a.target = '_parent';
  451. a.click();
  452. });
  453. });
  454. }
  455. });
  456. // Dispara el visor pdf
  457. var preview_pdf = function (owner, data, name) {
  458. new PdfViewerDialog(owner, data, name);
  459. };
  460. // Dispara la descarga del pdf
  461. var download_pdf = function (source) {
  462. var matchMimeType = source.match(/data:[a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+.*,/);
  463. if (!matchMimeType) {
  464. return;
  465. }
  466. if (!source.startsWith(matchMimeType[0])) {
  467. return;
  468. }
  469. var a = document.createElement('a');
  470. a.href = source;
  471. a.download = 'documento.pdf';
  472. a.target = '_parent';
  473. a.click();
  474. };
  475. // Dispara la impresión directa o descarga pdf
  476. local.print = function (data) {
  477. var config = this.socket_manager.config;
  478. if (config.is_mobile) {
  479. download_pdf(data);
  480. return;
  481. }
  482. if (this.socket_manager.socket.disconnected) {
  483. if (config.action_download_pdf) {
  484. download_pdf(data);
  485. return;
  486. }
  487. var widget = new PrinterUnavailableDialog();
  488. widget.can_download().then(function (can_download) {
  489. if (!can_download) {
  490. return;
  491. }
  492. if (config.action_preview_pdf) {
  493. preview_pdf(null, data, null);
  494. return;
  495. }
  496. download_pdf(data);
  497. });
  498. return;
  499. }
  500. this.socket_manager.request_print(data);
  501. };
  502. // Test
  503. local.TicketTestPage = instance.web.Widget.extend({
  504. template: 'TicketTestPage',
  505. events: {
  506. 'click .ticket-test-btn': 'print_test'
  507. },
  508. start: function () {
  509. },
  510. print_test: function (e) {
  511. e.preventDefault();
  512. var html = openerp.web.qweb.render('EiruPosTicket');
  513. var pdf = new jsPDF({
  514. unit: 'mm',
  515. format: [290, 70]
  516. });
  517. pdf.fromHTML(html, 0, 0);
  518. var data = pdf.output('datauristring');
  519. local.print(data);
  520. }
  521. });
  522. instance.web.client_actions.add('printer.test_ticket', 'instance.print_engine.TicketTestPage');
  523. if (instance.web) {
  524. if (instance.web.UserMenu) {
  525. instance.web.UserMenu.include({
  526. do_update: function () {
  527. var printer = new PrinterTopNotificator(this);
  528. printer.appendTo($('.oe_systray'));
  529. local.socket_manager = new SocketManager();
  530. return this._super.apply(this, arguments);
  531. }
  532. });
  533. }
  534. if (instance.web.FormView) {
  535. instance.web.FormView.include({
  536. record_saved: function (r) {
  537. if (this.model === 'res.users') {
  538. local.socket_manager.update_config();
  539. }
  540. return this._super.apply(this, arguments);
  541. }
  542. });
  543. }
  544. if (instance.web.ActionManager) {
  545. instance.web.ActionManager.include({
  546. trigger_preview_pdf: function (action) {
  547. var self = this;
  548. var regex = /^(?:qweb-(pdf|html)|controller)$/;
  549. if (_.has(action, 'report_type') && regex.test(action.report_type)) {
  550. var format = action.report_type.match(regex)[1];
  551. var url = (format || action.report_file) && ('/report/' + format + '/' + action.report_name);
  552. if (_.isEmpty(action.data) && _.has(action.context, 'active_ids')) {
  553. url += '/' + action.context.active_ids.join(',');
  554. } else {
  555. url += '?options=' + encodeURIComponent(JSON.stringify(action.data)) + '&context=' + encodeURIComponent(JSON.stringify(action.context));
  556. }
  557. preview_pdf(self, url, action.name);
  558. return;
  559. }
  560. var params = {
  561. action: JSON.stringify(action),
  562. token: (new Date()).getTime()
  563. };
  564. preview_pdf(self, this.session.url('/web/report', params), action.name);
  565. },
  566. trigger_download_pdf: function (action) {
  567. var regex = /^(?:qweb-(pdf|html)|controller)$/;
  568. var url = null;
  569. instance.web.blockUI();
  570. if (_.has(action, 'report_type') && regex.test(action.report_type)) {
  571. var format = action.report_type.match(regex)[1];
  572. url = (format || action.report_file) && ('/report/' + format + '/' + action.report_name);
  573. if (_.isEmpty(action.data) && _.has(action.context, 'active_ids')) {
  574. url += '/' + action.context.active_ids.join(',');
  575. } else {
  576. url += '?options=' + encodeURIComponent(JSON.stringify(action.data)) + '&context=' + encodeURIComponent(JSON.stringify(action.context));
  577. }
  578. }
  579. if (!url) {
  580. var params = {
  581. action: JSON.stringify(action),
  582. token: (new Date()).getTime()
  583. };
  584. url = this.session.url('/web/report', params);
  585. }
  586. instance.pdfJs.getDocument(url).then(function (pdf) {
  587. pdf.getData().then(function (data) {
  588. instance.web.unblockUI();
  589. var url = instance.pdfJs.createObjectURL(data, 'application/pdf');
  590. var a = document.createElement('a');
  591. a.href = url;
  592. a.download = (action.name || action.report_name) + '.pdf';
  593. a.target = '_parent';
  594. a.click();
  595. pdf.destroy();
  596. });
  597. });
  598. },
  599. trigger_print_pdf: function (action) {
  600. var url = '/print_engine/get_pdf';
  601. var ctx = _.clone(action.context);
  602. ctx.report_name = action.report_name;
  603. instance.web.jsonRpc(url, 'call', {
  604. context: ctx
  605. }).done(function (result) {
  606. local.socket_manager.request_print(result.data);
  607. }).fail(function (e) {
  608. instance.webclient.crashmanager.show_message(e);
  609. });
  610. },
  611. ir_actions_report_xml: function (action, options) {
  612. var self = this;
  613. var config = local.socket_manager.config;
  614. var eval_contexts = ([instance.session.user_context] || []).concat([action.context]);
  615. action.context = instance.web.pyeval.eval('contexts', eval_contexts);
  616. if (config.is_mobile) {
  617. this.trigger_preview_pdf(action);
  618. return;
  619. }
  620. if (instance.print_engine.socket_manager.socket.disconnected) {
  621. if (config.action_download_pdf) {
  622. self.trigger_download_pdf(action);
  623. return;
  624. }
  625. var widget = new PrinterUnavailableDialog(this);
  626. widget.can_download().then(function (can_download) {
  627. if (!can_download) {
  628. return;
  629. }
  630. if (config.action_preview_pdf) {
  631. self.trigger_preview_pdf(action);
  632. return;
  633. }
  634. self.trigger_download_pdf(action);
  635. });
  636. return;
  637. }
  638. self.trigger_print_pdf(action);
  639. }
  640. });
  641. }
  642. }
  643. }