añadir boton descargar facatura como pdf
This commit is contained in:
parent
28e5bbfbfe
commit
7f11d34e83
|
|
@ -1,4 +1,4 @@
|
|||
import { getInvoiceById, updateInvoice, validateInvoice, addInvoiceLine, deleteInvoiceLine, addPayment, getPayments } from '../services/invoices.js';
|
||||
import { getInvoiceById, updateInvoice, validateInvoice, addInvoiceLine, deleteInvoiceLine, addPayment, getPayments, downloadInvoicePdf } from '../services/invoices.js';
|
||||
import { showConfirmExitModal, FormChangeTracker } from './ConfirmExitModal.js';
|
||||
|
||||
export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
||||
|
|
@ -79,6 +79,7 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
|||
|
||||
const isDraft = invoice.status === 'draft';
|
||||
const canEdit = isDraft || invoice.status === 'validated' || invoice.status === 'unpaid';
|
||||
const canDownloadPdf = invoice.status === 'validated' || invoice.status === 'paid';
|
||||
|
||||
modalContent.innerHTML = `
|
||||
<div class="modal-header">
|
||||
|
|
@ -317,6 +318,7 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
|||
|
||||
<div class="modal-footer">
|
||||
<div class="footer-actions-left">
|
||||
${canDownloadPdf ? '<button type="button" class="btn-download-invoice btn-primary"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 4px;"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>Descargar factura</button>' : ''}
|
||||
${isDraft ? '<button type="button" class="btn-validate btn-success"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 4px;"><polyline points="20 6 9 17 4 12"/></svg>Validar Factura</button>' : ''}
|
||||
</div>
|
||||
<div class="footer-actions-right">
|
||||
|
|
@ -356,6 +358,10 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
|||
const validateBtn = modal.querySelector('.btn-validate');
|
||||
validateBtn?.addEventListener('click', handleValidate);
|
||||
|
||||
// Botón descargar factura PDF
|
||||
const downloadBtn = modal.querySelector('.btn-download-invoice');
|
||||
downloadBtn?.addEventListener('click', handleDownloadPdf);
|
||||
|
||||
// Botón añadir línea
|
||||
const addLineBtn = modal.querySelector('.btn-add-line');
|
||||
addLineBtn?.addEventListener('click', toggleAddLineForm);
|
||||
|
|
@ -510,6 +516,42 @@ export function InvoiceModal(invoiceId, onClose, onUpdate) {
|
|||
}
|
||||
};
|
||||
|
||||
// Manejar descarga del PDF
|
||||
const handleDownloadPdf = async () => {
|
||||
if (!invoice?.number) {
|
||||
alert('No se puede descargar la factura porque no tiene número.');
|
||||
return;
|
||||
}
|
||||
|
||||
const downloadBtn = modal.querySelector('.btn-download-invoice');
|
||||
const originalHtml = downloadBtn?.innerHTML;
|
||||
|
||||
try {
|
||||
if (downloadBtn) {
|
||||
downloadBtn.disabled = true;
|
||||
downloadBtn.textContent = 'Descargando...';
|
||||
}
|
||||
|
||||
const pdfBlob = await downloadInvoicePdf(invoice.number);
|
||||
const blobUrl = URL.createObjectURL(pdfBlob);
|
||||
const link = document.createElement('a');
|
||||
link.href = blobUrl;
|
||||
link.download = `Factura-${invoice.number}.pdf`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
} catch (error) {
|
||||
console.error('Error al descargar factura:', error);
|
||||
alert('Error al descargar la factura: ' + error.message);
|
||||
} finally {
|
||||
if (downloadBtn) {
|
||||
downloadBtn.disabled = false;
|
||||
downloadBtn.innerHTML = originalHtml;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Mostrar/ocultar formulario de añadir línea
|
||||
const toggleAddLineForm = () => {
|
||||
const form = modal.querySelector('.add-line-form');
|
||||
|
|
|
|||
|
|
@ -123,6 +123,24 @@ export async function getPayments(invoiceId) {
|
|||
return await response.json();
|
||||
}
|
||||
|
||||
export async function downloadInvoicePdf(invoiceNumber) {
|
||||
const token = localStorage.getItem('token');
|
||||
const response = await fetch(`${API_BASE_URL}/api/document/invoice/${encodeURIComponent(invoiceNumber)}/pdf`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Accept': 'application/pdf'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
throw new Error(error.detail || 'Error al descargar la factura');
|
||||
}
|
||||
|
||||
return await response.blob();
|
||||
}
|
||||
|
||||
export async function deleteInvoice(id) {
|
||||
// Nota: No hay endpoint DELETE en el OpenAPI spec,
|
||||
// pero podríamos usar el endpoint de cambio de estado a "canceled"
|
||||
|
|
|
|||
Loading…
Reference in New Issue