Skip to content
Code-Schnipsel Gruppen Projekte
OutputDialog.js 23,7 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * @module package/quiqqer/erp/bin/backend/controls/OutputDialog
     * @author www.pcsg.de (Patrick Müller)
    
     *
     * @event onOuput [FormData, this] - Fires if the user submits the popup with a chosen output format
    
     */
    define('package/quiqqer/erp/bin/backend/controls/OutputDialog', [
    
        'qui/QUI',
        'qui/controls/windows/Confirm',
        'qui/controls/buttons/Select',
    
        'qui/controls/elements/Sandbox',
    
        'package/quiqqer/erp/bin/backend/controls/Comments',
    
    
        '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, ERPComments, QUIFormUtils, QUIAjax, QUILocale, Mustache, template) {
    
        const lg = 'quiqqer/erp';
    
    
        return new Class({
    
            Extends: QUIConfirm,
            type   : 'package/quiqqer/erp/bin/backend/controls/OutputDialog',
    
            Binds: [
                '$onOpen',
                '$onOutputChange',
    
                '$onPrintFinish',
    
                '$getPreview',
                '$onChangeToEmail',
                '$onChangeToPDF',
    
                '$onChangeToPrint',
                '$resizeCommentsBox',
                '$onChangeMailRecipient'
    
                entityId  : false,  // Clean entity ID WITHOUT prefix and suffix
    
                entityType: false,  // Entity type (e.g. "Invoice")
    
                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')
                    }
                });
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                this.$Output = null;
                this.$Preview = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
                this.$Template = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
                this.$Form = null;
    
                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.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/quiqqer', 'recipient'),
    
                        showMarkAsSentOption: !!this.getAttribute('showMarkAsSentOption'),
                        mailEditor          : !!this.getAttribute('mailEditor'),
    
                        labelOpenMailEditor : QUILocale.get(lg, 'controls.OutputDialog.labelOpenMailEditor'),
    
                        labelMarkAsSent     : QUILocale.get(lg, 'controls.OutputDialog.labelMarkAsSent'),
    
    Patrick Müller's avatar
    Patrick Müller committed
                        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'),
    
    
                                mailSubject         : self.$Mail.subject,
                                mailContent         : self.$Mail.content,
                                attachedMediaFileIds: self.$Mail.attachedMediaFileIds,
    
    
                                events: {
                                    onMailSubmit: function (MailData) {
                                        self.$Mail = MailData;
                                    }
                                }
                            }).open();
                        });
                    });
                }
    
    
                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.print'),
                    'print',
                    'fa fa-print'
                );
    
                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.email'),
                    'email',
                    'fa fa-envelope-o'
                );
    
                this.$Output.inject(Content.getElement('.field-output'));
    
                Promise.all([
                    this.$getTemplates(),
                    this.$getEntityData()
                ]).then(function (result) {
    
                    const templates = result[0];
                    const EntityData = result[1];
    
                    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);
    
                        Form.elements.template.disabled = true;
    
    
                        const PreviewContent = self.getContent().getElement('.quiqqer-erp-outputDialog-preview');
    
    
                        new Element('div', {
                            'class': 'quiqqer-erp-outputDialog-nopreview',
                            html   : QUILocale.get(lg, 'controls.OutputDialog.no_preview')
                        }).inject(PreviewContent);
    
                        self.$Output.disable();
                        self.getButton('submit').disable();
    
                        self.Loader.hide();
                        return;
                    }
    
    
                    for (let i = 0, len = templates.length; i < len; i++) {
                        let Template = templates[i];
    
    
                        if (Template.isSystemDefault && EntityData.hideSystemDefaultTemplate) {
                            continue;
                        }
    
    
                        new Element('option', {
    
                            value          : Template.id,
                            html           : Template.title,
                            'data-provider': Template.provider
    
                        }).inject(Form.elements.template);
    
    
                        if (!Selected && Template.isDefault) {
                            Selected = Template;
    
                    Form.elements.template.addEvent('change', function (event) {
                        self.$Template = {
                            id      : event.target.value,
    
    Patrick Müller's avatar
    Patrick Müller committed
                            provider: event.target.getElement('option[value="' + event.target.value + '"]')
    
    Henning Leutz's avatar
    Henning Leutz committed
                                           .get('data-provider')
    
                        self.$renderPreview();
    
                    // Set initial template and render preview
                    Form.elements.template.value = Selected.id;
    
    Henning Leutz's avatar
    Henning Leutz committed
                    self.$Template = {
    
                        id      : Selected.id,
                        provider: Selected.provider
                    };
    
                    self.$renderPreview();
    
                    // Customer data
    
                    self.$customerMail = EntityData.email;
    
                    self.$onOutputChange();
    
                    self.Loader.hide();
    
    
                    // Load comments
                    self.$CommentsBox = Content.getElement('.quiqqer-erp-outputDialog-comments');
    
    Henning Leutz's avatar
    Henning Leutz committed
                    self.$Form = Form;
    
                    if (!self.getAttribute('comments') || !self.getAttribute('comments').length) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                        if (self.$CommentsBox) {
                            self.$CommentsBox.destroy();
                        }
    
    Henning Leutz's avatar
    Henning Leutz committed
                        self.$CommentsBox = null;
    
    
                    new ERPComments({
                        comments: self.getAttribute('comments')
                    }).inject(self.$CommentsBox);
    
                    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');
    
                this.Loader.show();
    
                const showPreviewError = function () {
    
    Patrick Müller's avatar
    Patrick Müller committed
                    PreviewContent.set('html', '');
    
                    new Element('div', {
                        'class': 'quiqqer-erp-outputDialog-nopreview',
    
                        html   : QUILocale.get(lg, 'controls.OutputDialog.preview_error'),
                        styles : {
                            padding: 20
                        }
    
    Patrick Müller's avatar
    Patrick Müller committed
                    }).inject(PreviewContent);
                };
    
    
                this.$getPreview().then(function (previewHtml) {
    
    Patrick Müller's avatar
    Patrick Müller committed
                    if (!previewHtml) {
                        showPreviewError();
                        return;
                    }
    
    
                    PreviewContent.set('html', '');
    
                    new QUISandbox({
                        content: previewHtml,
                        styles : {
    
                        },
                        events : {
                            onLoad: function (Box) {
    
                                Box.getElm().addClass('quiqqer-erp-outputDialog-preview');
    
                    }).inject(PreviewContent);
    
    Patrick Müller's avatar
    Patrick Müller committed
                }).catch(function () {
    
    Patrick Müller's avatar
    Patrick Müller committed
                    showPreviewError();
    
                });
            },
    
            /**
             * event: on submit
             */
            $onSubmit: function () {
    
                const self = this;
                let Run = Promise.resolve();
    
                const action = this.$Output.getValue();
    
                    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');
    
    
                    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;
                    }
    
                    self.$resizeCommentsBox();
    
                    self.Loader.hide();
                });
            },
    
    
            /**
             * Add message to log
             *
             * @param {String} msg
             */
            $addMessage: function (msg) {
                var 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');
            },
    
    
             *
             * @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'),
                            oid  : self.getId(),
    
    Patrick Müller's avatar
    Patrick Müller committed
                            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) {
    
                            resolve();
                        }
                    });
                });
            },
    
            /**
             * event: on print finish
             *
             * @param {String|Number} id
             */
            $onPrintFinish: function (id) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                this.fireEvent('printFinish', [
                    this,
                    id
                ]);
    
                    document.getElements('#print-document-' + id).destroy();
    
                }).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'),
                            oid  : self.getId(),
    
    Patrick Müller's avatar
    Patrick Müller committed
                            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 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;
                }
    
                this.getButton('submit').enable();
    
            },
    
            /**
             * event: on output change -> to print
             */
            $onChangeToPrint: function () {
    
                const Submit = this.getButton('submit');
    
                Submit.setAttribute('text', QUILocale.get(lg, 'controls.OutputDialog.data.output.print.btn'));
    
                Submit.setAttribute('textimage', 'fa fa-print');
            },
    
            /**
             * event: on output change -> to pdf
             */
            $onChangeToPDF: function () {
    
                const Submit = this.getButton('submit');
    
                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 Email
             */
            $onChangeToEmail: function () {
    
                const Submit = this.getButton('submit');
                const Recipient = this.getElm().getElement('[name="recipient"]');
    
    
                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');
    
    
                if (this.$customerMail && Recipient.value === '') {
                    Recipient.value = this.$customerMail;
    
                Recipient.removeEvent('keyup', this.$onChangeMailRecipient);
                Recipient.addEvent('keyup', this.$onChangeMailRecipient);
    
                Recipient.focus();
    
    
                if (this.$mailSent) {
                    Submit.disable();
                }
            },
    
            /**
             * If e-mail recipient changes
             */
    
            $onChangeMailRecipient: function () {
                this.getButton('submit').enable();
    
            },
    
            /**
             * 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'),
                        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'),
                        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')
    
                        }),
                        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'),
                        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;
                }
    
    
                const maxHeight = 685 - (710 - this.getContent().getSize().y);
                const height = this.$Form.getSize().y + this.$MessagesBox.getSize().y;
    
    
                this.$CommentsBox.setStyle('height', (maxHeight - height));