import ngModule from '../module'; import Section from 'salix/components/section'; import './style.scss'; class Controller extends Section { constructor($element, $, vnReport, vnEmail, vnFile) { super($element, $); this.vnReport = vnReport; this.vnEmail = vnEmail; this.vnFile = vnFile; } get ticketId() { return this._ticketId; } set ticketId(value) { this._ticketId = value; this.id = value; } get id() { return this._id; } set id(value) { this._id = value; if (!value) return; this.loadData().then(() => { if (this.$params.sendSMS) { this.showSMSDialog({ message: this.$params.message }); } }); const filter = { fields: ['id', 'originFk', 'creationDate', 'newInstance'], where: { originFk: value, newInstance: {like: '%"isDeleted":true%'} }, order: 'creationDate DESC', limit: 1 }; this.$http.get(`TicketLogs`, {filter}) .then(res => { if (res && res.data && res.data.length) { const now = Date.vnNew(); const maxDate = new Date(res.data[0].creationDate); maxDate.setHours(maxDate.getHours() + 1); if (now <= maxDate) return this.canRestoreTicket = true; } this.canRestoreTicket = false; }) .catch(() => { this.canRestoreTicket = false; }); } get isInvoiced() { return this.ticket.refFk !== null; } get isTicketModule() { return this.$state.getCurrentPath()[1].state.name === 'ticket'; } get hasInvoicing() { return this.aclService.hasAny(['invoicing']); } loadData() { const filter = { include: [{ relation: 'address', }, { relation: 'client', scope: { fields: [ 'salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked', 'credit', 'email', 'phone', 'mobile', 'hasElectronicInvoice', ], include: { relation: 'salesPersonUser', scope: { fields: ['id', 'name'] } } } }, { relation: 'invoiceOut' }] }; return this.$http.get(`Tickets/${this.ticketId}`, {filter}) .then(res => this.ticket = res.data) .then(() => { this.isTicketEditable(); }); } reload() { return this.loadData().then(() => { if (this.parentReload) this.parentReload(); }); } transferClient() { const ticket = this.ticket; const clientFk = ticket.client.id; this.$http.patch(`Tickets/${ticket.id}/transferClient`, {clientFk}) .then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); this.reload(); }); } isTicketEditable() { if (!this.ticket) return; this.$http.get(`Tickets/${this.id}/isEditable`).then(res => { this.isEditable = res.data; }); } addTurn(day) { const params = { ticketFk: this.id, weekDay: day, agencyModeFk: this.ticket.agencyModeFk }; return this.$http.patch(`TicketWeeklies`, params) .then(() => { this.$.addTurn.hide(); this.vnApp.showSuccess(this.$t('Current ticket deleted and added to shift')); this.reload(); }); } showPdfDeliveryNote(type) { this.vnReport.show(`tickets/${this.id}/delivery-note-pdf`, { recipientId: this.ticket.client.id, type: type }); } sendPdfDeliveryNote($data) { let query = `tickets/${this.id}/delivery-note-email`; if (this.hasDocuwareFile) query = `docuwares/delivery-note-email`; return this.vnEmail.send(query, { id: this.id, recipientId: this.ticket.client.id, recipient: $data.email }); } showCsvDeliveryNote() { this.vnReport.show(`tickets/${this.id}/delivery-note-csv`, { recipientId: this.ticket.client.id }); } sendCsvDeliveryNote($data) { return this.vnEmail.send(`tickets/${this.id}/delivery-note-csv-email`, { recipientId: this.ticket.client.id, recipient: $data.email }); } deleteTicket() { return this.$http.post(`Tickets/${this.id}/setDeleted`) .then(() => this.reload()) .then(() => { const isInsideTicket = this.$state.current.name.startsWith('ticket'); if (isInsideTicket) this.$state.go('ticket.index'); this.vnApp.showSuccess(this.$t('Ticket deleted. You can undo this action within the first hour')); }); } restoreTicket() { return this.$http.post(`Tickets/${this.id}/restore`) .then(() => this.reload()) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } showChangeShipped() { this.newShipped = this.ticket.shipped; this.$.changeShippedDialog.show(); } changeShipped() { const data = {shipped: this.newShipped}; return this.$http.post(`Tickets/${this.id}/updateEditableTicket`, data) .then(() => this.reload()) .then(() => this.vnApp.showSuccess(this.$t('Shipped hour updated'))); } sendImportSms() { const params = { ticketId: this.id, shipped: this.ticket.shipped }; this.showSMSDialog({ message: this.$t('Minimum is needed', params) }); } sendPaymentSms() { this.showSMSDialog({ message: this.$t('Make a payment') }); } sendChangesSms() { return this.$http.get(`TicketLogs/${this.id}/getChanges`) .then(res => { const params = { ticketId: this.id, created: this.ticket.updated, changes: res.data }; this.showSMSDialog({message: this.$t('Send changes', params)}); }); } showSMSDialog(params) { const address = this.ticket.address; const client = this.ticket.client; const phone = this.$params.phone || address.mobile || address.phone || client.mobile || client.phone; this.newSMS = Object.assign({ ticketId: this.id, destinationFk: this.ticket.clientFk, destination: phone }, params); this.$.sms.open(); } makeInvoice(force) { if (this.ticket.address.incotermsFk && !this.ticket.weight && !force) return this.$.withoutWeightConfirmation.show(); return this.$http.post(`Tickets/invoiceTicketsAndPdf`, {ticketsIds: [this.id]}) .then(() => this.reload()) .then(() => this.vnApp.showSuccess(this.$t('Ticket invoiced'))); } createPdfInvoice() { const invoiceId = this.ticket.invoiceOut.id; return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) .then(() => this.reload()) .then(() => { const snackbarMessage = this.$t( `The invoice PDF document has been regenerated`); this.vnApp.showSuccess(snackbarMessage); }); } recalculateComponents() { return this.$http.post(`Tickets/${this.id}/recalculateComponents`) .then(() => this.reload()) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } refund(withWarehouse) { const params = { ticketsIds: [this.id], withWarehouse: withWarehouse, negative: true // Asumimos que queremos cantidades negativas para reembolsos }; const query = 'Tickets/cloneAll'; return this.$http.post(query, params) .then(res => { const [refundTicket] = res.data; this.vnApp.showSuccess(this.$t('The following refund ticket has been created', { ticketId: refundTicket.id })); this.$state.go('ticket.card.sale', {id: refundTicket.id}); }) .catch(error => { this.vnApp.showError(this.$t('Error creating refund ticket', { error: error.data?.error?.message || 'Unknown error' })); }); } onSmsSend(sms) { return this.$http.post(`Tickets/${this.id}/sendSms`, sms) .then(() => this.vnApp.showSuccess(this.$t('SMS sent'))); } hasDocuware() { this.$http.post(`Docuwares/${this.id}/checkFile`, {fileCabinet: 'deliveryNote', signed: true}) .then(res => { this.hasDocuwareFile = res.data; }); } uploadDocuware(force) { if (!force) return this.$.pdfToTablet.show(); return this.$http.post(`Docuwares/upload`, {fileCabinet: 'deliveryNote', ticketIds: [this.id]}) .then(() => { this.vnApp.showSuccess(this.$t('PDF sent!')); }); } docuwareDownload() { this.vnFile.download(`api/Tickets/${this.ticket.id}/docuwareDownload`); } setTicketWeight(weight) { return this.$http.patch(`Tickets/${this.ticket.id}`, {weight}) .then(() => { this.$.setTicketWeight.hide(); this.vnApp.showSuccess(this.$t('Data saved!')); this.reload(); }); } } Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail', 'vnFile']; ngModule.vnComponent('vnTicketDescriptorMenu', { template: require('./index.html'), controller: Controller, bindings: { ticketId: '<', parentReload: '&' } });