import ngModule from '../module'; import Section from 'salix/components/section'; import UserError from 'core/lib/user-error'; import './style.scss'; class Controller extends Section { $onInit() { const date = Date.vnNew(); Object.assign(this, { maxShipped: new Date(date.getFullYear(), date.getMonth(), 0), clientsToInvoice: 'all', companyFk: this.vnConfig.companyFk, parallelism: 1 }); const params = {companyFk: this.companyFk}; this.$http.get('InvoiceOuts/getInvoiceDate', {params}) .then(res => { this.minInvoicingDate = res.data.issued ? new Date(res.data.issued) : null; this.invoiceDate = this.minInvoicingDate; }); const filter = {fields: ['parallelism']}; this.$http.get('InvoiceOutConfigs/findOne', {filter}) .then(res => { if (res.data.parallelism) this.parallelism = res.data.parallelism; }) .catch(res => { if (res.status == 404) return; throw res; }); } makeInvoice() { this.invoicing = true; this.status = 'packageInvoicing'; this.errors = []; this.addresses = null; try { if (this.clientsToInvoice == 'one' && !this.clientId) throw new UserError('Choose a valid client'); if (!this.invoiceDate || !this.maxShipped) throw new UserError('Invoice date and the max date should be filled'); if (this.invoiceDate < this.maxShipped) throw new UserError('Invoice date can\'t be less than max date'); if (this.minInvoicingDate && this.invoiceDate.getTime() < this.minInvoicingDate.getTime()) throw new UserError('Exists an invoice with a future date'); if (!this.companyFk) throw new UserError('Choose a valid company'); if (!this.printerFk) throw new UserError('Choose a valid printer'); if (this.clientsToInvoice == 'all') this.clientId = undefined; const params = { invoiceDate: this.invoiceDate, maxShipped: this.maxShipped, clientId: this.clientId, companyFk: this.companyFk }; this.$http.post(`InvoiceOuts/clientsToInvoice`, params) .then(res => { this.addresses = res.data; if (!this.addresses.length) throw new UserError(`There aren't tickets to invoice`); this.nRequests = 0; this.nPdfs = 0; this.totalPdfs = 0; this.addressIndex = 0; this.invoiceClient(); }) .catch(err => this.handleError(err)); } catch (err) { this.handleError(err); } } handleError(err) { this.invoicing = false; this.status = null; throw err; } invoiceClient() { if (this.nRequests == this.parallelism || this.isInvoicing) return; if (this.addressIndex >= this.addresses.length || this.status == 'stopping') { if (this.nRequests) return; this.invoicing = false; this.status = 'done'; return; } this.status = 'invoicing'; const address = this.addresses[this.addressIndex]; this.currentAddress = address; this.isInvoicing = true; const params = { clientId: address.clientId, addressId: address.id, invoiceDate: this.invoiceDate, maxShipped: this.maxShipped, companyFk: this.companyFk }; this.$http.post(`InvoiceOuts/invoiceClient`, params) .then(res => { this.isInvoicing = false; if (res.data) this.makePdfAndNotify(res.data, address); this.invoiceNext(); }) .catch(res => { this.isInvoicing = false; if (res.status >= 400 && res.status < 500) { this.invoiceError(address, res); this.invoiceNext(); } else { this.invoicing = false; this.status = 'done'; throw new UserError(`Critical invoicing error, proccess stopped`); } }); } invoiceNext() { this.addressIndex++; this.invoiceClient(); } makePdfAndNotify(invoiceId, address) { this.nRequests++; this.totalPdfs++; const params = {printerFk: this.printerFk}; this.$http.post(`InvoiceOuts/${invoiceId}/makePdfAndNotify`, params) .catch(res => { this.invoiceError(address, res, true); }) .finally(() => { this.nPdfs++; this.nRequests--; this.invoiceClient(); }); } invoiceError(address, res, isWarning) { const message = res.data?.error?.message || res.message; this.errors.unshift({address, message, isWarning}); } get nAddresses() { if (!this.addresses) return 0; return this.addresses.length; } get addressNumber() { return Math.min(this.addressIndex + 1, this.nAddresses); } get percentage() { const len = this.nAddresses; return Math.min(this.addressIndex, len) / len; } } ngModule.vnComponent('vnInvoiceOutGlobalInvoicing', { template: require('./index.html'), controller: Controller });