diff --git a/bin/backend/controls/OutputDialog.html b/bin/backend/controls/OutputDialog.html index 76a10dbd7ebc022490b4bc8a26bc4cc4eeee2849..1961952ce5e633530c4b439199f4a1cecaa72918 100644 --- a/bin/backend/controls/OutputDialog.html +++ b/bin/backend/controls/OutputDialog.html @@ -34,6 +34,18 @@ </label> </td> </tr> + <tr style="display: none"> + <td> + <label class="field-container"> + <span class="field-container-item" title="{{labelPDFView}}"> + {{labelPDFView}} + </span> + <span class="field-container-field"> + <span class="quiqqer-erp-outputDialog-pdfView"></span> + </span> + </label> + </td> + </tr> <tr style="display: none"> <td> <label class="field-container"> diff --git a/bin/backend/controls/OutputDialog.js b/bin/backend/controls/OutputDialog.js index 92885ed543b8a60bf062c93242f9d8b5b17dd571..d270f3c7ced8887ccaef03a0d74c639ccf00d008 100644 --- a/bin/backend/controls/OutputDialog.js +++ b/bin/backend/controls/OutputDialog.js @@ -4,719 +4,871 @@ * * @event onOuput [FormData, this] - Fires if the user submits the popup with a chosen output format */ -define('package/quiqqer/erp/bin/backend/controls/OutputDialog', [ +define( + 'package/quiqqer/erp/bin/backend/controls/OutputDialog', + [ + + 'qui/QUI', + 'qui/controls/windows/Confirm', + 'qui/controls/buttons/Select', + 'qui/controls/elements/Sandbox', + 'qui/controls/buttons/Switch', + + 'package/quiqqer/erp/bin/backend/controls/Comments', + 'package/quiqqer/erp/bin/backend/utils/ERPEntities', + + 'qui/utils/Form', + + 'Ajax', + 'Locale', + 'Mustache', + + 'text!package/quiqqer/erp/bin/backend/controls/OutputDialog.html', + 'css!package/quiqqer/erp/bin/backend/controls/OutputDialog.css' + + ], + function( + QUI, + QUIConfirm, + QUISelect, + QUISandbox, + QUISwitch, + ERPComments, + ERPEntities, + QUIFormUtils, + QUIAjax, + QUILocale, + Mustache, + template + ) { + 'use strict'; + + const lg = 'quiqqer/erp'; + let PDF_SUPPORT = null; + let CURRENT_VIEW = null; + + return new Class({ + + Extends: QUIConfirm, + type: 'package/quiqqer/erp/bin/backend/controls/OutputDialog', + + Binds: [ + '$onOpen', + '$onOutputChange', + '$onPrintFinish', + '$getPreview', + '$onChangeToEmail', + '$onChangeToPDF', + '$onChangeToPrint', + '$resizeCommentsBox', + '$onChangeMailRecipient' + ], + + options: { + entityId: false, // Clean entity ID WITHOUT prefix and suffix + entityType: false, // Entity type (e.g. "Invoice") + entityPlugin: false, + + comments: false, // Comments as array [must be readble by package/quiqqer/erp/bin/backend/controls/Comments] + + showMarkAsSentOption: false, // show checkbox for "Mark as sent" + mailEditor: true, // shows editable subject and body for mail output + + maxHeight: 800, + maxWidth: 1500 + }, + + initialize: function(options) { + this.parent(options); + + this.setAttributes({ + icon: 'fa fa-print', + title: QUILocale.get(lg, 'controls.OutputDialog.title'), + autoclose: false, + cancel_button: { + textimage: 'fa fa-close', + text: QUILocale.get('quiqqer/system', 'close') + } + }); - 'qui/QUI', - 'qui/controls/windows/Confirm', - 'qui/controls/buttons/Select', - 'qui/controls/elements/Sandbox', + this.$Output = null; + this.$PDFView = null; + this.$Preview = null; + this.$customerMail = null; + this.$Template = null; - 'package/quiqqer/erp/bin/backend/controls/Comments', - 'package/quiqqer/erp/bin/backend/utils/ERPEntities', + this.$CommentsBox = null; + this.$Form = null; + this.$MessagesBox = null; - 'qui/utils/Form', + this.$mailSent = false; - 'Ajax', - 'Locale', - 'Mustache', + this.$Mail = { + subject: false, + content: false, + attachedMediaFileIds: [] + }; - 'text!package/quiqqer/erp/bin/backend/controls/OutputDialog.html', - 'css!package/quiqqer/erp/bin/backend/controls/OutputDialog.css' + this.addEvents({ + onOpen: this.$onOpen, + onSubmit: this.$onSubmit, + onOpenBegin: function() { + const winSize = QUI.getWindowSize(); + let height = 800; + let width = 1400; -], function(QUI, QUIConfirm, QUISelect, QUISandbox, ERPComments, ERPEntities, QUIFormUtils, QUIAjax, QUILocale, Mustache, template) { - 'use strict'; + if (winSize.y * 0.9 < height) { + height = winSize.y * 0.9; + } - const lg = 'quiqqer/erp'; + if (winSize.x * 0.9 < width) { + width = winSize.x * 0.9; + } - return new Class({ + this.setAttribute('maxHeight', height); + this.setAttribute('maxWidth', width); + }.bind(this) + }); + }, - Extends: QUIConfirm, - type: 'package/quiqqer/erp/bin/backend/controls/OutputDialog', + /** + * event: on open + */ + $onOpen: function() { + const self = this, + Content = this.getContent(); - Binds: [ - '$onOpen', - '$onOutputChange', - '$onPrintFinish', - '$getPreview', - '$onChangeToEmail', - '$onChangeToPDF', - '$onChangeToPrint', - '$resizeCommentsBox', - '$onChangeMailRecipient' - ], + this.Loader.show(); + this.getContent().set('html', ''); - options: { - entityId: false, // Clean entity ID WITHOUT prefix and suffix - entityType: false, // Entity type (e.g. "Invoice") - entityPlugin: false, + const onError = function(error) { + self.close().then(function() { + self.destroy(); + }); - comments: false, // Comments as array [must be readble by package/quiqqer/erp/bin/backend/controls/Comments] + QUI.getMessageHandler().then(function(MH) { + if (typeof error === 'object' && typeof error.getMessage !== 'undefined') { + MH.addError(error.getMessage()); + return; + } - showMarkAsSentOption: false, // show checkbox for "Mark as sent" - mailEditor: true, // shows editable subject and body for mail output + MH.addError(error); + }); + }; - maxHeight: 800, - maxWidth: 1500 - }, + Content.set({ + html: Mustache.render(template, { + entityId: this.getAttribute('entityId'), + labelEntityId: QUILocale.get(lg, 'controls.OutputDialog.labelEntityId'), + labelTemplate: QUILocale.get(lg, 'controls.OutputDialog.labelTemplate'), + labelOutputType: QUILocale.get(lg, 'controls.OutputDialog.labelOutputType'), + labelPDFView: QUILocale.get(lg, 'controls.OutputDialog.labelPDFView'), + labelEmail: QUILocale.get('quiqqer/core', 'recipient'), + showMarkAsSentOption: !!this.getAttribute('showMarkAsSentOption'), + mailEditor: !!this.getAttribute('mailEditor'), + labelOpenMailEditor: QUILocale.get(lg, 'controls.OutputDialog.labelOpenMailEditor'), + labelMarkAsSent: QUILocale.get(lg, 'controls.OutputDialog.labelMarkAsSent'), + descMarkAsSent: QUILocale.get(lg, 'controls.OutputDialog.descMarkAsSent') + }) + }); - initialize: function(options) { - this.parent(options); + Content.addClass('quiqqer-erp-outputDialog'); + + self.$MessagesBox = Content.getElement('.quiqqer-erp-outputDialog-messages'); + + // "To mail editor" button + if (this.getAttribute('mailEditor')) { + Content.getElement('.quiqqer-erp-outputDialog-openMailEditor').addEvent('click', function() { + require( + ['package/quiqqer/erp/bin/backend/controls/OutputMailEditor'], + function(OutputMailEditor) { + new OutputMailEditor({ + entityId: self.getAttribute('entityId'), + entityType: self.getAttribute('entityType'), + entityPlugin: self.getAttribute('entityPlugin'), + + mailSubject: self.$Mail.subject, + mailContent: self.$Mail.content, + attachedMediaFileIds: self.$Mail.attachedMediaFileIds, + + events: { + onMailSubmit: function(MailData) { + self.$Mail = MailData; + } + } + }).open(); + } + ); + }); + } - this.setAttributes({ - icon: 'fa fa-print', - title: QUILocale.get(lg, 'controls.OutputDialog.title'), - autoclose: false, - cancel_button: { - textimage: 'fa fa-close', - text: QUILocale.get('quiqqer/system', 'close') + if (this.checkPdfSupport()) { + this.$PDFView = new QUISwitch({ + name: 'pdfView', + status: 0, + events: { + onChange: () => { + this.$renderPreview(); + } + } + }).inject(this.getElm().getElement('.quiqqer-erp-outputDialog-pdfView')); } - }); - - this.$Output = null; - this.$Preview = null; - this.$customerMail = null; - this.$Template = null; - - this.$CommentsBox = null; - this.$Form = null; - this.$MessagesBox = null; - - this.$mailSent = false; - - this.$Mail = { - subject: false, - content: false, - attachedMediaFileIds: [] - }; - - this.addEvents({ - onOpen: this.$onOpen, - onSubmit: this.$onSubmit, - onOpenBegin: function() { - const winSize = QUI.getWindowSize(); - let height = 800; - let width = 1400; - - if (winSize.y * 0.9 < height) { - height = winSize.y * 0.9; - } - if (winSize.x * 0.9 < width) { - width = winSize.x * 0.9; + this.$Output = new QUISelect({ + localeStorage: 'quiqqer-erp-output-dialog', + name: 'output', + styles: { + border: 'none', + width: '100%' + }, + events: { + onChange: self.$onOutputChange } - - this.setAttribute('maxHeight', height); - this.setAttribute('maxWidth', width); - }.bind(this) - }); - }, - - /** - * event: on open - */ - $onOpen: function() { - const self = this, - Content = this.getContent(); - - this.Loader.show(); - this.getContent().set('html', ''); - - const onError = function(error) { - self.close().then(function() { - self.destroy(); }); - QUI.getMessageHandler().then(function(MH) { - if (typeof error === 'object' && typeof error.getMessage !== 'undefined') { - MH.addError(error.getMessage()); - return; - } - - MH.addError(error); - }); - }; - - Content.set({ - html: Mustache.render(template, { - entityId: this.getAttribute('entityId'), - labelEntityId: QUILocale.get(lg, 'controls.OutputDialog.labelEntityId'), - labelTemplate: QUILocale.get(lg, 'controls.OutputDialog.labelTemplate'), - labelOutputType: QUILocale.get(lg, 'controls.OutputDialog.labelOutputType'), - labelEmail: QUILocale.get('quiqqer/core', 'recipient'), - showMarkAsSentOption: !!this.getAttribute('showMarkAsSentOption'), - mailEditor: !!this.getAttribute('mailEditor'), - labelOpenMailEditor: QUILocale.get(lg, 'controls.OutputDialog.labelOpenMailEditor'), - labelMarkAsSent: QUILocale.get(lg, 'controls.OutputDialog.labelMarkAsSent'), - descMarkAsSent: QUILocale.get(lg, 'controls.OutputDialog.descMarkAsSent') - }) - }); - - Content.addClass('quiqqer-erp-outputDialog'); - - self.$MessagesBox = Content.getElement('.quiqqer-erp-outputDialog-messages'); - - // "To mail editor" button - if (this.getAttribute('mailEditor')) { - Content.getElement('.quiqqer-erp-outputDialog-openMailEditor').addEvent('click', function() { - require(['package/quiqqer/erp/bin/backend/controls/OutputMailEditor'], function(OutputMailEditor) { - new OutputMailEditor({ - entityId: self.getAttribute('entityId'), - entityType: self.getAttribute('entityType'), - entityPlugin: self.getAttribute('entityPlugin'), - - mailSubject: self.$Mail.subject, - mailContent: self.$Mail.content, - attachedMediaFileIds: self.$Mail.attachedMediaFileIds, - - events: { - onMailSubmit: function(MailData) { - self.$Mail = MailData; - } - } - }).open(); - }); - }); - } + this.$Output.appendChild( + QUILocale.get(lg, 'controls.OutputDialog.data.output.print'), + 'print', + 'fa fa-print' + ); - this.$Output = new QUISelect({ - localeStorage: 'quiqqer-erp-output-dialog', - name: 'output', - styles: { - border: 'none', - width: '100%' - }, - events: { - onChange: self.$onOutputChange - } - }); + this.$Output.appendChild( + QUILocale.get(lg, 'controls.OutputDialog.data.output.pdf'), + 'pdf', + 'fa fa-file-pdf-o' + ); - this.$Output.appendChild( - QUILocale.get(lg, 'controls.OutputDialog.data.output.print'), - 'print', - 'fa fa-print' - ); + this.$Output.appendChild( + QUILocale.get(lg, 'controls.OutputDialog.data.output.email'), + 'email', + 'fa fa-envelope-o' + ); - this.$Output.appendChild( - QUILocale.get(lg, 'controls.OutputDialog.data.output.pdf'), - 'pdf', - 'fa fa-file-pdf-o' - ); + this.$Output.inject(Content.getElement('.field-output')); - this.$Output.appendChild( - QUILocale.get(lg, 'controls.OutputDialog.data.output.email'), - 'email', - 'fa fa-envelope-o' - ); + Promise.all([ + this.$getTemplates(), + this.$getEntityData() + ]).then(function(result) { + const templates = result[0]; + const EntityData = result[1]; - this.$Output.inject(Content.getElement('.field-output')); + const Form = Content.getElement('form'); + let Selected = false; - Promise.all([ - this.$getTemplates(), - this.$getEntityData() - ]).then(function(result) { - const templates = result[0]; - const EntityData = result[1]; + Content.getElement('.quiqqer-erp-outputDialog-options-entityId').set( + 'html', + EntityData.prefixedNumber + ); - const Form = Content.getElement('form'); - let Selected = false; + if (!templates.length) { + new Element('option', { + value: '#', + html: QUILocale.get(lg, 'controls.OutputDialog.no_templates_found') + }).inject(Form.elements.template); - Content.getElement('.quiqqer-erp-outputDialog-options-entityId').set('html', EntityData.prefixedNumber); + Form.elements.template.disabled = true; - if (!templates.length) { - new Element('option', { - value: '#', - html: QUILocale.get(lg, 'controls.OutputDialog.no_templates_found') - }).inject(Form.elements.template); + const PreviewContent = self.getContent().getElement('.quiqqer-erp-outputDialog-preview'); - Form.elements.template.disabled = true; + new Element('div', { + 'class': 'quiqqer-erp-outputDialog-nopreview', + html: QUILocale.get(lg, 'controls.OutputDialog.no_preview') + }).inject(PreviewContent); - const PreviewContent = self.getContent().getElement('.quiqqer-erp-outputDialog-preview'); + self.$Output.disable(); + self.getButton('submit').disable(); - new Element('div', { - 'class': 'quiqqer-erp-outputDialog-nopreview', - html: QUILocale.get(lg, 'controls.OutputDialog.no_preview') - }).inject(PreviewContent); + self.Loader.hide(); + return; + } - self.$Output.disable(); - self.getButton('submit').disable(); + for (let i = 0, len = templates.length; i < len; i++) { + let Template = templates[i]; - self.Loader.hide(); - return; - } + if (Template.isSystemDefault && EntityData.hideSystemDefaultTemplate) { + continue; + } - for (let i = 0, len = templates.length; i < len; i++) { - let Template = templates[i]; + new Element('option', { + value: Template.id, + html: Template.title, + 'data-provider': Template.provider + }).inject(Form.elements.template); - if (Template.isSystemDefault && EntityData.hideSystemDefaultTemplate) { - continue; + if (!Selected && Template.isDefault) { + Selected = Template; + } } - new Element('option', { - value: Template.id, - html: Template.title, - 'data-provider': Template.provider - }).inject(Form.elements.template); + Form.elements.template.addEvent('change', function(event) { + self.$Template = { + id: event.target.value, + provider: event.target.getElement('option[value="' + event.target.value + '"]').get( + 'data-provider') + }; - if (!Selected && Template.isDefault) { - Selected = Template; - } - } + self.$renderPreview(); + }); - Form.elements.template.addEvent('change', function(event) { + // Set initial template and render preview + Form.elements.template.value = Selected.id; self.$Template = { - id: event.target.value, - provider: event.target.getElement('option[value="' + event.target.value + '"]').get( - 'data-provider') + id: Selected.id, + provider: Selected.provider }; self.$renderPreview(); - }); - - // Set initial template and render preview - Form.elements.template.value = Selected.id; - self.$Template = { - id: Selected.id, - provider: Selected.provider - }; - self.$renderPreview(); + // Customer data + self.$customerMail = EntityData.email; + CURRENT_VIEW = null; + self.$onOutputChange(); - // Customer data - self.$customerMail = EntityData.email; - self.$onOutputChange(); + self.Loader.hide(); - self.Loader.hide(); + // Load comments + self.$CommentsBox = Content.getElement('.quiqqer-erp-outputDialog-comments'); + self.$Form = Form; - // Load comments - self.$CommentsBox = Content.getElement('.quiqqer-erp-outputDialog-comments'); - self.$Form = Form; + if (!self.getAttribute('comments') || !self.getAttribute('comments').length) { + if (self.$CommentsBox) { + self.$CommentsBox.destroy(); + } - if (!self.getAttribute('comments') || !self.getAttribute('comments').length) { - if (self.$CommentsBox) { - self.$CommentsBox.destroy(); + self.$CommentsBox = null; + return; } - self.$CommentsBox = null; - return; - } + new ERPComments({ + comments: self.getAttribute('comments') + }).inject(self.$CommentsBox); - new ERPComments({ - comments: self.getAttribute('comments') - }).inject(self.$CommentsBox); - - self.$resizeCommentsBox(); - }).catch(function(e) { - onError(e); - }); - }, + self.$resizeCommentsBox(); + }).catch(function(e) { + onError(e); + }); + }, - /** - * Render preview with selected template - */ - $renderPreview: function() { - const self = this; - const PreviewContent = this.getContent().getElement('.quiqqer-erp-outputDialog-preview'); + /** + * Render preview with selected template + */ + $renderPreview: function() { + const self = this; + const PreviewContent = this.getContent().getElement('.quiqqer-erp-outputDialog-preview'); - this.Loader.show(); + this.Loader.show(); - const showPreviewError = function() { - PreviewContent.set('html', ''); - - new Element('div', { - 'class': 'quiqqer-erp-outputDialog-nopreview', - html: QUILocale.get(lg, 'controls.OutputDialog.preview_error'), - styles: { - padding: 20 - } - }).inject(PreviewContent); - }; + const showPreviewError = function() { + PreviewContent.set('html', ''); - this.$getPreview().then(function(previewHtml) { - self.Loader.hide(); + new Element('div', { + 'class': 'quiqqer-erp-outputDialog-nopreview', + html: QUILocale.get(lg, 'controls.OutputDialog.preview_error'), + styles: { + padding: 20 + } + }).inject(PreviewContent); + }; - if (!previewHtml) { - showPreviewError(); + if (this.$PDFView && this.$PDFView.getStatus()) { + this.showAsPDF(); return; } - PreviewContent.set('html', ''); + this.$getPreview().then(function(previewHtml) { + self.Loader.hide(); - new QUISandbox({ - content: previewHtml, - styles: { - height: '100%', - padding: 20, - width: '100%' - }, - events: { - onLoad: function(Box) { - Box.getElm().addClass('quiqqer-erp-outputDialog-preview'); - } + if (!previewHtml) { + showPreviewError(); + return; } - }).inject(PreviewContent); - }).catch(function() { - self.Loader.hide(); - showPreviewError(); - }); - }, - - /** - * event: on submit - */ - $onSubmit: function() { - const self = this; - let Run = Promise.resolve(); - - this.Loader.show(); - - const action = this.$Output.getValue(); - - switch (action) { - case 'print': - Run = this.print(); - break; - - case 'pdf': - Run = this.saveAsPdf(); - break; - - case 'email': - Run = this.$sendMail(); - break; - } - Run.then(function() { - const Form = self.getContent().getElement('form'); + PreviewContent.set('html', ''); + + new QUISandbox({ + content: previewHtml, + styles: { + height: '100%', + padding: 20, + width: '100%' + }, + events: { + onLoad: function(Box) { + Box.getElm().addClass('quiqqer-erp-outputDialog-preview'); + } + } + }).inject(PreviewContent); + }).catch(function() { + self.Loader.hide(); + showPreviewError(); + }); + }, + + /** + * event: on submit + */ + $onSubmit: function() { + const self = this; + let Run = Promise.resolve(); - self.fireEvent('output', [ - QUIFormUtils.getFormData(Form), - self - ]); + this.Loader.show(); - const Submit = self.getButton('submit'); + const action = this.$Output.getValue(); switch (action) { case 'print': - self.$addMessage(QUILocale.get(lg, 'controls.OutputDialog.msg.output_print')); + Run = this.print(); break; case 'pdf': - self.$addMessage(QUILocale.get(lg, 'controls.OutputDialog.msg.output_pdf')); + Run = this.saveAsPdf(); break; case 'email': - self.$mailSent = true; - Submit.disable(); - - self.$addMessage(QUILocale.get(lg, 'controls.OutputDialog.msg.mail_sent', { - recipient: Form.elements.recipient.value - })); + Run = this.$sendMail(); break; } - self.$resizeCommentsBox(); - self.Loader.hide(); - }, function() { - self.Loader.hide(); - }); - }, - - /** - * Add message to log - * - * @param {String} msg - */ - $addMessage: function(msg) { - const Now = new Date(); - - new Element('div', { - 'class': 'quiqqer-erp-outputDialog-messages-entry box message-success', - html: '<b>' + Now.format('%H:%M:%S') + '</b> ' + msg - }).inject(this.$MessagesBox, 'top'); - }, - - /** - * Print the document - * - * @return {Promise} - */ - print: function() { - const self = this, - entityId = this.getAttribute('entityId'); - - return new Promise(function(resolve) { - const id = 'print-document-' + entityId, - Content = self.getContent(), - Form = Content.getElement('form'); - - self.Loader.show(); - - new Element('iframe', { - src: URL_OPT_DIR + 'quiqqer/erp/bin/output/backend/print.php?' + Object.toQueryString({ - id: entityId, - t: self.getAttribute('entityType'), - ep: self.getAttribute('entityPlugin'), - oid: self.getId(), - tpl: self.$Template.id, - tplpr: self.$Template.provider - }), - id: id, - styles: { - position: 'absolute', - top: -200, - left: -200, - width: 50, - height: 50 + Run.then(function() { + const Form = self.getContent().getElement('form'); + + self.fireEvent('output', [ + QUIFormUtils.getFormData(Form), + self + ]); + + const Submit = self.getButton('submit'); + + switch (action) { + case 'print': + self.$addMessage(QUILocale.get(lg, 'controls.OutputDialog.msg.output_print')); + break; + + case 'pdf': + self.$addMessage(QUILocale.get(lg, 'controls.OutputDialog.msg.output_pdf')); + break; + + case 'email': + self.$mailSent = true; + Submit.disable(); + + self.$addMessage(QUILocale.get(lg, 'controls.OutputDialog.msg.mail_sent', { + recipient: Form.elements.recipient.value + })); + break; } - }).inject(document.body); - self.addEvent('onPrintFinish', function(self, pId) { - if (pId === entityId) { + self.$resizeCommentsBox(); + self.Loader.hide(); + }, function() { + self.Loader.hide(); + }); + }, + + /** + * Add message to log + * + * @param {String} msg + */ + $addMessage: function(msg) { + const Now = new Date(); + + new Element('div', { + 'class': 'quiqqer-erp-outputDialog-messages-entry box message-success', + html: '<b>' + Now.format('%H:%M:%S') + '</b> ' + msg + }).inject(this.$MessagesBox, 'top'); + }, + + /** + * Print the document + * + * @return {Promise} + */ + print: function() { + const self = this, + entityId = this.getAttribute('entityId'); + + return new Promise(function(resolve) { + const id = 'print-document-' + entityId, + Content = self.getContent(), + Form = Content.getElement('form'); + + self.Loader.show(); + + new Element('iframe', { + src: URL_OPT_DIR + 'quiqqer/erp/bin/output/backend/print.php?' + Object.toQueryString({ + id: entityId, + t: self.getAttribute('entityType'), + ep: self.getAttribute('entityPlugin'), + oid: self.getId(), + tpl: self.$Template.id, + tplpr: self.$Template.provider + }), + id: id, + styles: { + position: 'absolute', + top: -200, + left: -200, + width: 50, + height: 50 + } + }).inject(document.body); + + self.addEvent('onPrintFinish', function(self, pId) { + if (pId === entityId) { + resolve(); + } + }); + }); + }, + + /** + * event: on print finish + * + * @param {String|Number} id + */ + $onPrintFinish: function(id) { + this.fireEvent('printFinish', [ + this, + id + ]); + + (function() { + document.getElements('#print-document-' + id).destroy(); + this.Loader.hide(); + }).delay(1000, this); + }, + + /** + * Export the document as PDF + * + * @return {Promise} + */ + saveAsPdf: function() { + const self = this, + entityId = this.getAttribute('entityId'); + + return new Promise(function(resolve) { + const id = 'download-document-' + entityId, + Content = self.getContent(), + Form = Content.getElement('form'); + + new Element('iframe', { + src: URL_OPT_DIR + 'quiqqer/erp/bin/output/backend/download.php?' + Object.toQueryString({ + id: entityId, + t: self.getAttribute('entityType'), + ep: self.getAttribute('entityPlugin'), + oid: self.getId(), + tpl: self.$Template.id, + tplpr: self.$Template.provider + }), + id: id, + styles: { + position: 'absolute', + top: -200, + left: -200, + width: 50, + height: 50 + } + }).inject(document.body); + + (function() { resolve(); - } + }).delay(2000, this); + + (function() { + document.getElements('#' + id).destroy(); + }).delay(20000, this); }); - }); - }, - - /** - * event: on print finish - * - * @param {String|Number} id - */ - $onPrintFinish: function(id) { - this.fireEvent('printFinish', [ - this, - id - ]); - - (function() { - document.getElements('#print-document-' + id).destroy(); - this.Loader.hide(); - }).delay(1000, this); - }, - - /** - * Export the document as PDF - * - * @return {Promise} - */ - saveAsPdf: function() { - const self = this, - entityId = this.getAttribute('entityId'); - - return new Promise(function(resolve) { - const id = 'download-document-' + entityId, - Content = self.getContent(), - Form = Content.getElement('form'); - - new Element('iframe', { - src: URL_OPT_DIR + 'quiqqer/erp/bin/output/backend/download.php?' + Object.toQueryString({ - id: entityId, - t: self.getAttribute('entityType'), - ep: self.getAttribute('entityPlugin'), - oid: self.getId(), - tpl: self.$Template.id, - tplpr: self.$Template.provider - }), - id: id, - styles: { - position: 'absolute', - top: -200, - left: -200, - width: 50, - height: 50 + }, + + showAsPDF: function() { + this.Loader.show(); + + const PreviewContent = this.getContent().getElement('.quiqqer-erp-outputDialog-preview'); + const entityId = this.getAttribute('entityId'); + + PreviewContent.set('html', ''); + + return new Promise((resolve) => { + const id = 'download-document-' + entityId; + + new Element('iframe', { + src: URL_OPT_DIR + 'quiqqer/erp/bin/output/backend/download.php?' + Object.toQueryString({ + id: entityId, + t: this.getAttribute('entityType'), + ep: this.getAttribute('entityPlugin'), + oid: this.getId(), + tpl: this.$Template.id, + tplpr: this.$Template.provider, + show: 1 + }), + id: id, + styles: { + height: 'calc(100% - 5px)', + width: '100%', + border: 'none', + padding: 0 + } + }).inject(PreviewContent); + + (function() { + resolve(); + }).delay(2000, this); + + this.Loader.hide(); + }); + }, + + /** + * event : on output change + */ + $onOutputChange: function() { + if (CURRENT_VIEW === this.$Output.getValue()) { + return; + } + + const Recipient = this.getElm().getElement('[name="recipient"]'); + const PDFView = this.getElm().getElement('.quiqqer-erp-outputDialog-pdfView'); + + Recipient.getParent('tr').setStyle('display', 'none'); + PDFView.getParent('tr').setStyle('display', 'none'); + + if (this.$PDFView && this.$PDFView.getStatus() === 1) { + if (this.$Output.getValue() === 'pdf') { + this.$PDFView.setSilentOff(); + } else { + this.$PDFView.off(); } - }).inject(document.body); + } else { + (() => { + this.$PDFView.setSilentOff(); + }).delay(100); + } - (function() { - resolve(); - }).delay(2000, this); + switch (this.$Output.getValue()) { + case 'print': + this.$onChangeToPrint(); + break; - (function() { - document.getElements('#' + id).destroy(); - }).delay(20000, this); - }); - }, - - /** - * event : on output change - * - * @return {Promise} - */ - $onOutputChange: function() { - const Recipient = this.getElm().getElement('[name="recipient"]'); - - Recipient.getParent('tr').setStyle('display', 'none'); - - switch (this.$Output.getValue()) { - case 'print': - this.$onChangeToPrint(); - break; - - case 'pdf': - this.$onChangeToPDF(); - break; - - case 'email': - this.$onChangeToEmail(); - break; - } + case 'pdf': + this.$onChangeToPDF(); + break; - this.$resizeCommentsBox(); - this.getButton('submit').enable(); - }, + case 'email': + this.$onChangeToEmail(); + break; + } - /** - * event: on output change -> to print - */ - $onChangeToPrint: function() { - const Submit = this.getButton('submit'); + this.$resizeCommentsBox(); + this.getButton('submit').enable(); + CURRENT_VIEW = this.$Output.getValue(); + }, - Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.print.btn')); - Submit.setAttribute('textimage', 'fa fa-print'); - }, + /** + * event: on output change -> to print + */ + $onChangeToPrint: function() { + const Submit = this.getButton('submit'); - /** - * event: on output change -> to pdf - */ - $onChangeToPDF: function() { - const Submit = this.getButton('submit'); + Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.print.btn')); + Submit.setAttribute('textimage', 'fa fa-print'); + }, - Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.pdf.btn')); - Submit.setAttribute('textimage', 'fa fa-file-pdf-o'); - }, + /** + * event: on output change -> to pdf + */ + $onChangeToPDF: function() { + const Submit = this.getButton('submit'); - /** - * event: on output change -> to Email - */ - $onChangeToEmail: function() { - const Submit = this.getButton('submit'); - const Recipient = this.getElm().getElement('[name="recipient"]'); + Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.pdf.btn')); + Submit.setAttribute('textimage', 'fa fa-file-pdf-o'); - Recipient.getParent('tr').setStyle('display', null); + const PDFView = this.getElm().getElement('.quiqqer-erp-outputDialog-pdfView'); + PDFView.getParent('tr').setStyle('display', null); + }, - Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.email.btn')); - Submit.setAttribute('textimage', 'fa fa-envelope-o'); + /** + * event: on output change -> to Email + */ + $onChangeToEmail: function() { + const Submit = this.getButton('submit'); + const Recipient = this.getElm().getElement('[name="recipient"]'); - if (this.$customerMail && Recipient.value === '') { - Recipient.value = this.$customerMail; - } + Recipient.getParent('tr').setStyle('display', null); + + Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.email.btn')); + Submit.setAttribute('textimage', 'fa fa-envelope-o'); - Recipient.removeEvent('keyup', this.$onChangeMailRecipient); - Recipient.addEvent('keyup', this.$onChangeMailRecipient); + if (this.$customerMail && Recipient.value === '') { + Recipient.value = this.$customerMail; + } - Recipient.focus(); + Recipient.removeEvent('keyup', this.$onChangeMailRecipient); + Recipient.addEvent('keyup', this.$onChangeMailRecipient); - if (this.$mailSent) { - Submit.disable(); - } - }, - - /** - * If e-mail recipient changes - */ - $onChangeMailRecipient: function() { - this.getButton('submit').enable(); - this.$mailSent = false; - }, - - /** - * Get data of the entity that is outputted - * - * @return {Promise} - */ - $getEntityData: function() { - const self = this; - - return new Promise(function(resolve, reject) { - QUIAjax.get('package_quiqqer_erp_ajax_output_getEntityData', resolve, { - 'package': 'quiqqer/erp', - entityId: self.getAttribute('entityId'), - entityType: self.getAttribute('entityType'), - entityPlugin: self.getAttribute('entityPlugin'), - onError: reject + Recipient.focus(); + + if (this.$mailSent) { + Submit.disable(); + } + }, + + /** + * If e-mail recipient changes + */ + $onChangeMailRecipient: function() { + this.getButton('submit').enable(); + this.$mailSent = false; + }, + + /** + * Get data of the entity that is outputted + * + * @return {Promise} + */ + $getEntityData: function() { + const self = this; + + return new Promise(function(resolve, reject) { + QUIAjax.get('package_quiqqer_erp_ajax_output_getEntityData', resolve, { + 'package': 'quiqqer/erp', + entityId: self.getAttribute('entityId'), + entityType: self.getAttribute('entityType'), + entityPlugin: self.getAttribute('entityPlugin'), + onError: reject + }); }); - }); - }, - - /** - * Fetch available templates based on entity type - * - * @return {Promise} - */ - $getTemplates: function() { - const self = this; - - return new Promise(function(resolve, reject) { - QUIAjax.get('package_quiqqer_erp_ajax_output_getTemplates', resolve, { - 'package': 'quiqqer/erp', - entityType: self.getAttribute('entityType'), - entityPlugin: self.getAttribute('entityPlugin'), - onError: reject + }, + + /** + * Fetch available templates based on entity type + * + * @return {Promise} + */ + $getTemplates: function() { + const self = this; + + return new Promise(function(resolve, reject) { + QUIAjax.get('package_quiqqer_erp_ajax_output_getTemplates', resolve, { + 'package': 'quiqqer/erp', + entityType: self.getAttribute('entityType'), + entityPlugin: self.getAttribute('entityPlugin'), + onError: reject + }); }); - }); - }, - - /** - * Fetch available templates based on entity type - * - * @return {Promise} - */ - $getPreview: function() { - const self = this; - - return new Promise(function(resolve, reject) { - QUIAjax.get('package_quiqqer_erp_ajax_output_getPreview', resolve, { - 'package': 'quiqqer/erp', - entity: JSON.encode({ - id: self.getAttribute('entityId'), - type: self.getAttribute('entityType'), - plugin: self.getAttribute('entityPlugin') - }), - template: JSON.encode(self.$Template), - onError: reject + }, + + /** + * Fetch available templates based on entity type + * + * @return {Promise} + */ + $getPreview: function() { + const self = this; + + return new Promise(function(resolve, reject) { + QUIAjax.get('package_quiqqer_erp_ajax_output_getPreview', resolve, { + 'package': 'quiqqer/erp', + entity: JSON.encode({ + id: self.getAttribute('entityId'), + type: self.getAttribute('entityType'), + plugin: self.getAttribute('entityPlugin') + }), + template: JSON.encode(self.$Template), + onError: reject + }); }); - }); - }, - - /** - * Get data of the entity that is outputted - * - * @return {Promise} - */ - $sendMail: function() { - const self = this, - Form = this.getContent().getElement('form'); - - return new Promise(function(resolve, reject) { - QUIAjax.post('package_quiqqer_erp_ajax_output_sendMail', resolve, { - 'package': 'quiqqer/erp', - entityId: self.getAttribute('entityId'), - entityType: self.getAttribute('entityType'), - entityPlugin: self.getAttribute('entityPlugin'), - template: self.$Template.id, - templateProvider: self.$Template.provider, - mailSubject: self.$Mail.subject, - mailContent: self.$Mail.content, - mailAttachmentMediaFileIds: JSON.encode(self.$Mail.attachedMediaFileIds), - mailRecipient: Form.elements.recipient.value, - onError: reject + }, + + /** + * Get data of the entity that is outputted + * + * @return {Promise} + */ + $sendMail: function() { + const self = this, + Form = this.getContent().getElement('form'); + + return new Promise(function(resolve, reject) { + QUIAjax.post('package_quiqqer_erp_ajax_output_sendMail', resolve, { + 'package': 'quiqqer/erp', + entityId: self.getAttribute('entityId'), + entityType: self.getAttribute('entityType'), + entityPlugin: self.getAttribute('entityPlugin'), + template: self.$Template.id, + templateProvider: self.$Template.provider, + mailSubject: self.$Mail.subject, + mailContent: self.$Mail.content, + mailAttachmentMediaFileIds: JSON.encode(self.$Mail.attachedMediaFileIds), + mailRecipient: Form.elements.recipient.value, + onError: reject + }); }); - }); - }, - - /** - * Resize the erp entity comments container - */ - $resizeCommentsBox: function() { - if (!this.$Form || !this.$CommentsBox || !this.$MessagesBox) { - return; - } + }, + + /** + * Resize the erp entity comments container + */ + $resizeCommentsBox: function() { + if (!this.$Form || !this.$CommentsBox || !this.$MessagesBox) { + return; + } + + const maxHeight = 685 - (710 - this.getContent().getSize().y); + const height = this.$Form.getSize().y + this.$MessagesBox.getSize().y; + + this.$CommentsBox.setStyle('height', (maxHeight - height)); + }, + + checkPdfSupport: function() { + return new Promise((resolve) => { + if (PDF_SUPPORT !== null) { + resolve(PDF_SUPPORT); + return; + } + + const PDFFrame = new Element('iframe', { + src: URL_OPT_DIR + 'quiqqer/erp/bin/output/backend/test.pdf', + styles: { + position: 'absolute', + top: -200, + left: -200, + width: 50, + height: 50 + } + }).inject(document.body); + + PDFFrame.onload = function() { + try { + const pdfDoc = PDFFrame.contentDocument || PDFFrame.contentWindow.document; + + if (pdfDoc && pdfDoc.body && pdfDoc.body.innerHTML.includes('PDF') === false) { + PDF_SUPPORT = true; + } else { + // PDF kann nicht angezeigt werden, Fallback anzeigen + // pdfFrame.style.display = 'none'; + // document.getElementById('pdfFallback').style.display = 'block'; + PDF_SUPPORT = false; + } + } catch (error) { + // Möglicher Cross-Origin-Fehler oder PDF nicht unterstützt + // pdfFrame.style.display = 'none'; + // document.getElementById('pdfFallback').style.display = 'block'; + PDF_SUPPORT = false; + } + }; - const maxHeight = 685 - (710 - this.getContent().getSize().y); - const height = this.$Form.getSize().y + this.$MessagesBox.getSize().y; + PDFFrame.onerror = function() { + // Fehler beim Laden des PDFs im iframe + // pdfFrame.style.display = 'none'; + // document.getElementById('pdfFallback').style.display = 'block'; + PDF_SUPPORT = false; + }; - this.$CommentsBox.setStyle('height', (maxHeight - height)); - } - }); -}); + }); + } + }); + } +); diff --git a/bin/output/backend/download.php b/bin/output/backend/download.php index 136ac18190930cefc345fa057e27f9e19dfc76dc..a96300069576cb29179ec6ecd8db40b5261101c4 100644 --- a/bin/output/backend/download.php +++ b/bin/output/backend/download.php @@ -25,6 +25,7 @@ $template = Orthos::clear($Request->query->get('tpl')); $templateProvider = Orthos::clear($Request->query->get('tplpr')); $quiId = Orthos::clear($Request->query->get('oid')); +$show = Orthos::clear($Request->query->get('show')); $errorOutput = function ($message) use ($quiId) { echo ' @@ -57,7 +58,21 @@ $template ?: null ); - $HtmlPdfDocument->download(); + if (isset($show) && $show) { + $pdfFile = $HtmlPdfDocument->createPDF(); + $filename = $HtmlPdfDocument->getAttribute('filename'); + + if (empty($filename)) { + $filename = $entityId . '_' . date("d_m_Y__H_m") . '.pdf'; + } + + header("Content-Type: application/pdf"); + header("Content-Disposition: inline; filename=\"$filename\""); // inline zeigt es im Browser an + + echo file_get_contents($pdfFile); + } else { + $HtmlPdfDocument->download(); + } } catch (\Exception $Exception) { QUI\System\Log::writeException($Exception); diff --git a/bin/output/backend/test.pdf b/bin/output/backend/test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..34df66dabb13891070d6b9289fd1ea43e1e351f0 Binary files /dev/null and b/bin/output/backend/test.pdf differ diff --git a/locale.xml b/locale.xml index d69912e6b3afdffb2fbb9eb3cd06abaa3253f992..399fcc9a76400c1cdeaecbbb043bccf169d190b9 100644 --- a/locale.xml +++ b/locale.xml @@ -1182,6 +1182,10 @@ <de><![CDATA[Beleg PDF heruntergeladen]]></de> <en><![CDATA[Document PDF downloaded]]></en> </locale> + <locale name="controls.OutputDialog.labelPDFView"> + <de><![CDATA[PDF Vorschau]]></de> + <en><![CDATA[PDF Preview]]></en> + </locale> <locale name="controls.OutputMailEditor.title"> <de><![CDATA[E-Mail für Beleg bearbeiten]]></de>