Newer
Older
* @module package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice
* Edit a Temporary Invoice and created a posted invoice
define('package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice', [
'qui/controls/buttons/ButtonMultiple',
'qui/controls/buttons/Separator',
'qui/controls/windows/Confirm',
'qui/utils/Form',
'controls/users/address/Select',
'package/quiqqer/invoice/bin/backend/utils/Dialogs',
'package/quiqqer/erp/bin/backend/controls/Comments',
'package/quiqqer/erp/bin/backend/controls/articles/Text',
'package/quiqqer/payments/bin/backend/Payments',
'package/quiqqer/customer/bin/backend/controls/customer/address/Window',
'package/quiqqer/customer/bin/backend/controls/customer/userFiles/Select',
'text!package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice.Data.html',
'text!package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice.Post.html',
'text!package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice.Missing.html',
'css!package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice.css'
], function (QUI, QUIPanel, QUIButton, QUIButtonMultiple, QUISeparator, QUIConfirm, QUIFormUtils,
AddressSelect, Invoices, Dialogs, Comments, TextArticle,
Payments, AddressWindow, CustomerFileSelect, Locker, QUILocale, QUIAjax, Mustache, Users, Editors,
templateData, templatePost, templateMissing) {
Type : 'package/quiqqer/invoice/bin/backend/controls/panels/TemporaryInvoice',
'save',
'post',
'openData',
'openArticles',
'openComments',
'openAddCommentDialog',
'openVerification',
'$openCategory',
'$closeCategory',
'$onDeleteInvoice',
'$onArticleReplaceClick',
'$clickDelete',
'toggleSort',
options: {
invoiceId : false,
customer_id : false,
invoice_address : false,
invoice_address_id: false,
project_name : '',
date : '',
time_for_payment : '',
data : {},
articles : []
},
initialize: function (options) {
this.setAttributes({
this.$AdditionalText = null;
this.$ArticleList = null;
this.$AddProduct = null;
this.$ArticleSort = null;
this.$AddressDelivery = null;
this.$AddSeparator = null;
this.$locked = false;
onCreate : this.$onCreate,
onInject : this.$onInject,
* Return the lock key
*
* @return {string}
$getLockKey: function () {
return 'lock-invoice-temporary-' + this.getAttribute('invoiceId');
},
/**
* Return the lock group
* @return {string}
*/
$getLockGroups: function () {
return 'quiqqer/invoice';
},
/**
* Panel refresh
*/
refresh: function () {
if (this.getAttribute('id')) {
title = this.getAttribute('id');
}
title = title + QUILocale.get(lg, 'brutto.panel.title');
title = title + QUILocale.get(lg, 'netto.panel.title');
this.setAttribute('title', title);
this.parent();
},
/**
* Refresh the invoice data
*/
doRefresh: function () {
const self = this;
let invoiceId = this.getAttribute('invoiceId');
return Invoices.getTemporaryInvoice(invoiceId).then(function (data) {
self.setAttributes(data);
if (data.articles.articles && data.articles.articles.length) {
self.$serializedList = {
articles : data.articles.articles,
priceFactors: data.articles.priceFactors
self.setAttribute('articles', data.articles.articles);
self.setAttribute('priceFactors', data.articles.priceFactors);
if (data.invoice_address) {
self.setAttribute('invoice_address', data.invoice_address);
}
/**
* Saves the current data
*
* @return {Promise}
*/
save: function () {
if (this.$locked) {
return Promise.resolve();
}
this.Loader.show();
this.$unloadCategory(false);
return Invoices.saveInvoice(
this.getAttribute('invoiceId'),
this.getCurrentData()
).then(function () {
this.Loader.hide();
this.showSavedIconAnimation();
}.bind(this)).catch(function (err) {
console.error(err);
console.error(err.getMessage());
this.Loader.show();
this.$unloadCategory(false);
return Invoices.saveInvoice(
this.getAttribute('invoiceId'),
this.getCurrentData()
).then(function (Data) {
return Promise.all([
Invoices.postInvoice(self.getAttribute('invoiceId')),
Invoices.getSetting('temporaryInvoice', 'openPrintDialogAfterPost'),
Data
]);
}).then(function (result) {
openPrintDialogAfterPost = result[1],
Data = result[2];
if (!openPrintDialogAfterPost) {
self.destroy();
return;
}
switch (parseInt(Data.type)) {
case 3:
entityType = 'CreditNote';
break;
case 4:
entityType = 'Canceled';
break;
default:
entityType = 'Invoice';
}
// open print dialog
Dialogs.openPrintDialog(newInvoiceHash, entityType).then(function () {
self.destroy();

Henning Leutz
committed
});
}).catch(function (err) {
console.error(err);
console.error(err.getMessage());
this.Loader.hide();
}.bind(this));
* @returns {{customer_id, invoice_address_id, project_name, articles, date, time_for_payment}}
let deliveryAddress = this.getAttribute('addressDelivery');
if (!deliveryAddress) {
deliveryAddress = this.getAttribute('delivery_address');
}
return {
customer_id : this.getAttribute('customer_id'),
invoice_address_id : this.getAttribute('invoice_address_id'),
project_name : this.getAttribute('project_name'),
articles : this.getAttribute('articles'),
priceFactors : this.getAttribute('priceFactors'),
date : this.getAttribute('date'),
editor_id : this.getAttribute('editor_id'),
ordered_by : this.getAttribute('ordered_by'),
contact_person : this.getAttribute('contact_person'),
contactEmail : this.getAttribute('contactEmail'),
time_for_payment : this.getAttribute('time_for_payment'),
payment_method : this.getAttribute('payment_method'),
additional_invoice_text: this.getAttribute('additional_invoice_text'),
currency : this.getAttribute('currency'),
addressDelivery : deliveryAddress,
processing_status : this.getAttribute('processing_status'),
attached_customer_files: this.getAttribute('attached_customer_files')
/**
* Return the current user data
*/
getUserData: function () {
return {
uid: this.getAttribute('customer_id'),
aid: this.getAttribute('invoice_address_id')
};
* Open the data category
*
* @returns {Promise}
this.renderDataDone = false;
this.Loader.show();
return this.$closeCategory().then(function () {
const Container = self.getContent().getElement('.container');
Container.setStyle('height', null);
Container.set({
html: Mustache.render(templateData, {
textInvoiceData : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textInvoiceData'),
textInvoiceDate : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textInvoiceDate'),
textTermOfPayment : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textTermOfPayment'),
textProjectName : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textProjectName'),
textOrderedBy : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textOrderedBy'),
textEditor : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textEditor'),
textInvoicePayment: QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textInvoicePayment'),
textPaymentMethod : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textPaymentMethod'),
textInvoiceText : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textInvoiceText'),
textStatus : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textStatus'),
textContactPerson : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textContactPerson'),
textCurrency : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textCurrency'),
textCurrencyRate: QUILocale.get(lg, 'erp.panel.temporary.invoice.category.data.textCurrencyRate'),
textInvoiceDeliveryAddress: QUILocale.get(lg, 'deliveryAddress')
QUIFormUtils.setDataToForm(self.getAttribute('data'), Form);
// set invoice date to today
// quiqqer/invoice#46
local.setMinutes(local.getMinutes() - local.getTimezoneOffset());
QUIFormUtils.setDataToForm({
date : dateDate,
time_for_payment : self.getAttribute('time_for_payment'),
project_name : self.getAttribute('project_name'),
editor_id : self.getAttribute('editor_id'),
processing_status: self.getAttribute('processing_status'),
contact_person : self.getAttribute('contact_person'),
currency : self.getAttribute('currency'),
currencyRate : self.getAttribute('currencyRate')
}, Form);
Form.elements.date.set('disabled', true);
Form.elements.date.set('title', QUILocale.get(lg, 'permissions.set.invoice.date'));
require(['Permissions'], function (Permissions) {
Permissions.hasPermission('quiqqer.invoice.changeDate').then(function (has) {
if (has) {
Form.elements.date.set('disabled', false);
Form.elements.date.set('title', '');
return QUI.parse(Container);
}).then(function () {
return new Promise(function (resolve, reject) {
const Form = self.getContent().getElement('form');
require([
'Packages',
'utils/Controls'
], function (Packages, ControlUtils) {
ControlUtils.parse(Form).then(function () {
return Packages.getConfig('quiqqer/currency');
}).then(resolve);
'[data-qui="package/quiqqer/erp/bin/backend/controls/userData/UserData"]'
let editorIdQUIId = Content.getElement('[name="editorId"]').get('data-quiid');
let orderedByIdQUIId = Content.getElement('[name="orderedBy"]').get('data-quiid');
let currencyIdQUIId = Content.getElement('[name="currency"]').get('data-quiid');
let CurrencyRate = Content.getElement('[name="currencyRate"]');

Henning Leutz
committed
let Data = QUI.Controls.getById(quiId);
let EditorId = QUI.Controls.getById(editorIdQUIId);
let OrderedBy = QUI.Controls.getById(orderedByIdQUIId);
let Currency = QUI.Controls.getById(currencyIdQUIId);

Henning Leutz
committed
if (parseInt(config.currency.differentAccountingCurrencies) === 0) {
Content.getElements('table.invoice-currency').setStyle('display', 'none');
}
OrderedBy.setAttribute('showAddressName', false);

Henning Leutz
committed
const Customer = Data.getValue();
let userId = Customer.userId;

Henning Leutz
committed
self.setAttribute('customer_id', parseInt(userId));
self.setAttribute('invoice_address_id', Customer.addressId);
self.setAttribute('contact_person', Customer.contactPerson);
self.setAttribute('contactEmail', Customer.contactEmail);
// reset deliver address
if (self.$AddressDelivery) {
self.$AddressDelivery.setAttribute('userId', userId);
}
Promise.all([
Invoices.getPaymentTime(userId),
Invoices.isNetto(userId)
]).then(function (result) {
let isNetto = result[1];
Content.getElement('[name="time_for_payment"]').value = paymentTime;
self.setAttribute('isbrutto', !isNetto);
self.setAttribute('time_for_payment', paymentTime);
self.refresh();
});
});
// currency
Currency.addEvent('change', function (Instance, value) {
if (self.renderDataDone === false) {
return;
}
self.Loader.show();
self.setAttribute('currency', value);
require(['package/quiqqer/currency/bin/Currency'], function (Currencies) {
Currencies.getCurrency(value).then(function (data) {
if ("rate" in data) {
self.setAttribute('currencyRate', data.rate);
CurrencyRate.value = data.rate;
}
self.Loader.hide();
}).catch(function (err) {
console.error(err);
self.Loader.hide();
});
});
// editor
EditorId.addEvent('onChange', function () {
self.setAttribute('editor_id', EditorId.getValue());
});
if (typeof window.QUIQQER_EMPLOYEE_GROUP !== 'undefined') {
EditorId.setAttribute('search', true);
EditorId.setAttribute('searchSettings', {
filter: {
filter_group: window.QUIQQER_EMPLOYEE_GROUP
}
});
}
if (parseInt(self.getAttribute('editor_id'))) {
EditorId.addItem(self.getAttribute('editor_id'));
} else {
EditorId.addItem(USER.id);
}
// ordered by
OrderedBy.addEvent('onChange', function () {
self.setAttribute('ordered_by', OrderedBy.getValue());
});
if (typeof window.QUIQQER_CUSTOMER_GROUP !== 'undefined') {
OrderedBy.setAttribute('search', true);
OrderedBy.setAttribute('searchSettings', {
filter: {
filter_group: window.QUIQQER_CUSTOMER_GROUP
}
});
}
if (parseInt(self.getAttribute('ordered_by'))) {
OrderedBy.addItem(parseInt(self.getAttribute('ordered_by')));
}
let address = self.getAttribute('invoice_address');
address.userId = self.getAttribute('customer_id');
address.addressId = self.getAttribute('invoice_address_id');
address.contactPerson = self.getAttribute('contact_person') ? self.getAttribute('contact_person') : '';
address.contactEmail = self.getAttribute('contactEmail') ? self.getAttribute('contactEmail') : '';

Patrick Müller
committed
if (self.getAttribute('contactEmail')) {
address.contactEmail = self.getAttribute('contactEmail');
}
return Data.setValue(address);
}).then(function () {
// delivery address
self.$AddressDelivery = QUI.Controls.getById(
self.getContent().getElement(
'[data-qui="package/quiqqer/erp/bin/backend/controls/DeliveryAddress"]'
let deliveryAddress = self.getAttribute('addressDelivery');
if (!deliveryAddress) {
deliveryAddress = self.getAttribute('delivery_address');
if (deliveryAddress) {
deliveryAddress = JSON.decode(deliveryAddress);
if (deliveryAddress) {
self.$AddressDelivery.setAttribute('userId', self.getAttribute('customer_id'));
self.$AddressDelivery.setValue(deliveryAddress);
}
let Container = self.getContent().getElement('.container');
text : QUILocale.get(lg, 'erp.panel.temporary.invoice.button.nextToArticles') +
' <span class="fa fa-angle-right"></span>',
styles: {
display: 'block',
'float': 'right',
margin : '0 0 20px'
},
onClick: function () {
self.openArticles().catch(function (e) {
console.error(e);
}).then(function () {
return Payments.getPayments();
}).then(function (payments) {
// load payments
let Payments = self.getContent().getElement('[name="payment_method"]');
new Element('option', {
html : '',
value: ''
}).inject(Payments);
let i, len, title;
let current = QUILocale.getCurrent();
for (i = 0, len = payments.length; i < len; i++) {
title = payments[i].title;
if (typeOf(title) === 'object' && typeof title[current] !== 'undefined') {
title = title[current];
}
new Element('option', {
html : title,
value: payments[i].id
}).inject(Payments);
}
Payments.value = self.getAttribute('payment_method');
}).then(function () {
// additional-invoice-text -> wysiwyg
return self.$loadAdditionalInvoiceText();
}).then(function () {
self.getCategory('data').setActive();
return self.Loader.hide();
}).then(function () {
return self.$openCategory();
}).then(function () {
self.renderDataDone = true;
});
* Open the product category
*
* @returns {Promise}
return self.$closeCategory().then(function (Container) {
return new Promise(function (resolve) {
require([
'package/quiqqer/erp/bin/backend/controls/articles/ArticleList',
'package/quiqqer/erp/bin/backend/controls/articles/ArticleSummary'
], function (List, Summary) {
self.$ArticleList = new List({
nettoinput: !self.getAttribute('isbrutto'),
currency : self.getAttribute('currency'),
events : {
onArticleReplaceClick: self.$onArticleReplaceClick
},
height: 'calc(100% - 110px)'
}
}).inject(Container);
Container.setStyle('height', '100%');
self.$ArticleListSummary = new Summary({
currency: self.getAttribute('currency'),
List : self.$ArticleList,
styles : {
bottom : -20,
left : 0,
opacity : 0,
position: 'absolute'
}
}).inject(Container.getParent());
moofx(self.$ArticleListSummary.getElm()).animate({
bottom : 0,
opacity: 1
});
self.$ArticleList.setUser(self.getUserData());
if (self.$serializedList) {
self.$ArticleList.unserialize(self.$serializedList);
}
self.$AddProduct.show();
self.$AddSeparator.show();
self.$SortSeparator.show();
self.$ArticleSort.show();
self.getCategory('articles').setActive();
new QUIButton({
text : '<span class="fa fa-angle-left"></span> ' +
QUILocale.get(lg, 'erp.panel.temporary.invoice.button.data'),
styles: {
'float': 'left',
margin : '20px 0 0'
},
onClick: self.openData
}
}).inject(Container);
new QUIButton({
text : QUILocale.get(lg, 'erp.panel.temporary.invoice.category.review.btnGoto') +
' <span class="fa fa-angle-right"></span>',
styles: {
'float': 'right',
margin : '20px 0 0'
},
onClick: self.openVerification
}
}).inject(Container);
self.Loader.hide().then(resolve);
});
});
}).then(function () {
return self.$openCategory();
/**
* open the comments
*
* @return {Promise<Promise>}
*/
this.Loader.show();
this.getCategory('comments').setActive();
return this.$closeCategory().then(function () {
self.refreshComments();
}).then(function () {
return self.$openCategory();
}).then(function () {
self.Loader.hide();
});
/**
*/
const Container = this.getContent().getElement('.container');
Container.set('html', '');
new QUIButton({
textimage: 'fa fa-comments',
text : QUILocale.get(lg, 'invoice.panel.comment.add'),
styles : {
'float' : 'right',
marginBottom: 10
},
events : {
onClick: this.openAddCommentDialog
}
}).inject(Container);
new Comments({
comments: this.getAttribute('comments')
}).inject(Container);
},
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
/**
* Open invoice file management
*
* @returns {Promise}
*/
openInvoiceFiles: function () {
this.Loader.show();
this.getCategory('invoiceFiles').setActive();
return this.$closeCategory().then((Container) => {
Container.setStyle('overflow', 'hidden');
Container.setStyle('padding', 20);
Container.setStyle('height', '100%');
const customerId = this.getAttribute('customer_id');
if (!customerId) {
new Element('p', {
html: QUILocale.get(lg, 'controls.panels.TemporaryInvoice.invoice_files_no_customer')
}).inject(Container);
return;
}
const FileControl = new CustomerFileSelect({
userId : this.getAttribute('customer_id'),
confirmItemDelete: true,
events : {
onChange: (FileSelectControl) => {
FileSelectControl.getFiles().then((customerFiles) => {
this.setAttribute('attached_customer_files', customerFiles);
});
}
}
}).inject(Container);
FileControl.getElm().addClass('quiqqer-invoice-files');
FileControl.importValue(this.getAttribute('attached_customer_files'));
}).then(() => {
return this.$openCategory();
}).catch((err) => {
console.error('ERROR');
console.error(err);
return this.$openCategory();
});
},
const self = this;
return this.$closeCategory().then((Container) => {
FrameContainer = new Element('div', {
'class': 'quiqqer-invoice-backend-temporaryInvoice-previewContainer'
}).inject(Container);
Container.setStyle('overflow', 'hidden');
Container.setStyle('padding', 0);
Container.setStyle('height', '100%');
ParentContainer = Container;
return Invoices.getTemporaryInvoicePreview(
self.getCurrentData()
).then(function (html) {
return new Promise(function (resolve) {
require(['qui/controls/elements/Sandbox'], function (Sandbox) {
new Sandbox({
content: html,
styles : {
height : '100%',
padding: 20,
width : '95%'
},
events : {
onLoad: function (Box) {
Box.getElm().addClass('quiqqer-invoice-backend-temporaryInvoice-preview');
}
}
}).inject(FrameContainer);
}).then(function () {
// check invoice date
let InvoiceDate = new Date(self.getAttribute('date'));
if (InvoiceDate < Now) {
new QUIConfirm({
title : QUILocale.get(lg, 'window.invoice.date.past.title'),
text : QUILocale.get(lg, 'window.invoice.date.past.title'),
information : QUILocale.get(lg, 'window.invoice.date.past.content'),
icon : 'fa fa-clock-o',
texticon : 'fa fa-clock-o',
maxHeight : 400,
maxWidth : 600,
autoclose : false,
cancel_button: {
text : QUILocale.get(lg, 'window.invoice.date.past.cancel.text'),
textimage: 'fa fa-close'
},
ok_button : {
text : QUILocale.get(lg, 'window.invoice.date.past.ok.text'),
textimage: 'fa fa-check'
},
events : {
onSubmit: function (Win) {
Win.Loader.show();
let Today = new Date();
let today = Today.toISOString().split('T')[0];
self.setAttribute('date', today + ' 00:00:00');
self.save().then(function () {
self.openVerification();
Win.close();
});
}
}
}).open();
}
}).then(function () {
return Invoices.getMissingAttributes(self.getAttribute('invoiceId'));
}).then(function (missing) {
'class': 'quiqqer-invoice-backend-temporaryInvoice-missing',
styles : {
opacity: 0,
bottom : -20
}
}).inject(ParentContainer);
if (Object.getLength(missing)) {
Missing.set('html', Mustache.render(templateMissing, {
message: QUILocale.get(lg, 'message.invoice.missing')
}));
'class': 'quiqqer-invoice-backend-temporaryInvoice-missing-miss-message',
styles : {
display: 'none',
opacity: 0
}
}).inject(ParentContainer);
Missing.getElement(
'.quiqqer-invoice-backend-temporaryInvoice-missing-miss-button'
).addEvent('click', function () {
let isShow = parseInt(Info.getStyle('opacity'));
if (isShow) {
moofx(Info).animate({
bottom : 60,
opacity: 0
}, {
callback: function () {
Info.setStyle('display', 'none');
}
});
} else {
Info.setStyle('display', null);

Henning Leutz
committed
moofx(Info).animate({
bottom : 80,
opacity: 1
});
}
});
if (!missing.hasOwnProperty(missed)) {
continue;
}
new Element('div', {
'class': 'messages-message message-error',
html : missing[missed]
}).inject(Info);
Missing.getElement(
'.quiqqer-invoice-backend-temporaryInvoice-missing-miss-button'
).click();
} else {
// post available
Missing.set('html', Mustache.render(templatePost, {
message: QUILocale.get(lg, 'message.invoice.ok')
}));
new QUIButton({
text : QUILocale.get(lg, 'journal.btn.post'),
'class' : 'btn-green',
events : {
onClick: self.post
},
disabled: self.$locked
}).inject(
Missing.getElement('.quiqqer-invoice-backend-temporaryInvoice-missing-button')
);
self.getCategory('verification').setActive();
self.Loader.hide().then(function () {
return new Promise(function (resolve) {
moofx(Missing).animate({
opacity: 1,
bottom : 0
}, {
callback: function () {
self.Loader.hide().then(resolve);
}
});
});
}).then(function () {
return self.$openCategory();
}).catch(function (err) {
console.error('ERROR');
console.error(err);
return self.$openCategory();
});
},
/**
* Opens the product search
*
* @todo only if products are installed
*/
openProductSearch: function () {