Compare commits
No commits in common. "4dc6e5ac92dee8120179e10f85bfea0fa4a772b2" and "b1d48d4eecf941709aded70acf926dd2e22cd28e" have entirely different histories.
4dc6e5ac92
...
b1d48d4eec
@ -4,9 +4,9 @@
|
|||||||
{
|
{
|
||||||
Quote,
|
Quote,
|
||||||
Expedition,
|
Expedition,
|
||||||
DeliveryNote,
|
|
||||||
Invoice,
|
Invoice,
|
||||||
Order,
|
Order,
|
||||||
|
Remito,
|
||||||
Certificate
|
Certificate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
using Documents.Interfaces;
|
using Documents.Interfaces;
|
||||||
using Documents.Models;
|
using Documents.Models;
|
||||||
using Domain.Dtos; // QuoteDto
|
using Domain.Dtos; // QuoteDto
|
||||||
using Domain.Dtos.Sales; // DeliveryNoteDto
|
|
||||||
using Domain.Dtos.Stock; // ExpeditionDto
|
using Domain.Dtos.Stock; // ExpeditionDto
|
||||||
using Transversal.Interfaces;
|
using Transversal.Interfaces;
|
||||||
|
|
||||||
@ -58,7 +57,6 @@ public class DocumentTemplateService : IDocumentTemplateService
|
|||||||
private static string ResolveTemplate(DocumentType type) => type switch
|
private static string ResolveTemplate(DocumentType type) => type switch
|
||||||
{
|
{
|
||||||
DocumentType.Quote => "Quotes/Template_v1.cshtml",
|
DocumentType.Quote => "Quotes/Template_v1.cshtml",
|
||||||
DocumentType.DeliveryNote => "DeliveryNotes/Template_v1.cshtml",
|
|
||||||
DocumentType.Expedition => "Expeditions/Template_v1.cshtml",
|
DocumentType.Expedition => "Expeditions/Template_v1.cshtml",
|
||||||
_ => "Shared/Template_Generic.cshtml"
|
_ => "Shared/Template_Generic.cshtml"
|
||||||
};
|
};
|
||||||
@ -74,9 +72,6 @@ public class DocumentTemplateService : IDocumentTemplateService
|
|||||||
case ExpeditionDto e:
|
case ExpeditionDto e:
|
||||||
e.LogoBase64 = base64;
|
e.LogoBase64 = base64;
|
||||||
break;
|
break;
|
||||||
case DeliveryNoteDto d:
|
|
||||||
d.LogoBase64 = base64;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// Si no tiene LogoBase64, no hacemos nada.
|
// Si no tiene LogoBase64, no hacemos nada.
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,182 +0,0 @@
|
|||||||
@using System
|
|
||||||
@using System.Globalization
|
|
||||||
@using System.Text.Json
|
|
||||||
@using Domain.Dtos.Sales
|
|
||||||
@model DeliveryNoteDto
|
|
||||||
|
|
||||||
@{
|
|
||||||
Layout = null;
|
|
||||||
|
|
||||||
var ci = CultureInfo.GetCultureInfo("es-AR");
|
|
||||||
CultureInfo.CurrentCulture = ci;
|
|
||||||
CultureInfo.CurrentUICulture = ci;
|
|
||||||
|
|
||||||
SurgerySnapshot snap;
|
|
||||||
if (string.IsNullOrWhiteSpace(Model.ExtraInfoJson))
|
|
||||||
{
|
|
||||||
snap = new SurgerySnapshot();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
snap = JsonSerializer.Deserialize<SurgerySnapshot>(Model.ExtraInfoJson) ?? new SurgerySnapshot();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
snap = new SurgerySnapshot();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var reprintText = Model.PrintCount > 0 ? (" — Reimpresión " + Model.PrintCount) : string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
@functions {
|
|
||||||
public class SurgerySnapshot
|
|
||||||
{
|
|
||||||
public string? Professional { get; set; }
|
|
||||||
public string? Institution { get; set; }
|
|
||||||
public string? Patient { get; set; }
|
|
||||||
public DateTime? SurgeryDate { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string FQty(decimal q) => q.ToString("G29", CultureInfo.InvariantCulture);
|
|
||||||
public static string FDate(DateTime? d) => d.HasValue ? d.Value.ToString("dd/MM/yyyy") : string.Empty;
|
|
||||||
public static string FText(string? value) => string.IsNullOrWhiteSpace(value) ? "-" : value.Trim();
|
|
||||||
public static string FOrigin(byte originType) => originType switch
|
|
||||||
{
|
|
||||||
1 => "Presupuesto",
|
|
||||||
2 => "Manual",
|
|
||||||
_ => originType.ToString()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="es">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>Remito @Model.DeliveryNoteNumber</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style>
|
|
||||||
@@page { size: A4; margin: 10mm 9mm 10mm 9mm; }
|
|
||||||
html, body { font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: #000; }
|
|
||||||
.sheet { width: 100%; }
|
|
||||||
.header { display: grid; grid-template-columns: 1.6fr 1fr; gap: 10px; align-items: start; }
|
|
||||||
.company { line-height: 1.2; }
|
|
||||||
.company .tagline { margin-top: 4px; font-size: 11px; }
|
|
||||||
.doc-title { text-align: right; }
|
|
||||||
.doc-title h1 { font-size: 22px; margin: 0 0 4px 0; letter-spacing: .4px; }
|
|
||||||
.doc-title .num { font-weight: bold; font-size: 14px; }
|
|
||||||
.doc-title .date { margin-top: 3px; }
|
|
||||||
.hr { border-bottom: 1px solid #000; margin: 8px 0; }
|
|
||||||
.info-block table, .snapshot table, .items table { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
|
||||||
.info-block td, .snapshot td { padding: 3px 4px; vertical-align: top; }
|
|
||||||
.info-block .lbl, .snapshot .lbl { width: 18%; font-weight: 600; }
|
|
||||||
.info-block .val, .snapshot .val { width: 32%; word-break: break-word; }
|
|
||||||
.section-title { font-size: 13px; font-weight: 700; margin: 10px 0 6px; }
|
|
||||||
.items { margin-top: 8px; }
|
|
||||||
.items thead th { border: 1px solid #000; background: #eaeaea; color: #000; padding: 4px 4px; text-align: center; font-weight: 700; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
||||||
.items tbody td { border: 1px solid #000; padding: 4px 4px; vertical-align: top; }
|
|
||||||
.items thead { display: table-header-group; }
|
|
||||||
.col-line { width: 7%; text-align: center; }
|
|
||||||
.col-desc { width: 43%; text-align: left; }
|
|
||||||
.col-qty { width: 10%; text-align: center; }
|
|
||||||
.col-origin { width: 14%; text-align: center; }
|
|
||||||
.col-originid { width: 10%; text-align: center; }
|
|
||||||
.col-notes { width: 16%; text-align: left; word-break: break-word; }
|
|
||||||
.observ { margin-top: 10px; min-height: 52px; border: 1px dashed #888; padding: 8px; white-space: pre-wrap; }
|
|
||||||
.footer { margin-top: 12px; padding-top: 6px; border-top: 1px solid #000; font-size: 11px; text-align: center; }
|
|
||||||
.muted { color: #111; }
|
|
||||||
.avoid-break { page-break-inside: avoid; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="sheet">
|
|
||||||
<div class="header">
|
|
||||||
<div class="company">
|
|
||||||
@if (!string.IsNullOrWhiteSpace(Model.LogoBase64))
|
|
||||||
{
|
|
||||||
<img src="data:image/png;base64,@Model.LogoBase64" alt="Logo" style="height:48px; margin-bottom:2px;" />
|
|
||||||
}
|
|
||||||
<div class="tagline muted">Documento generado por PhronCare</div>
|
|
||||||
</div>
|
|
||||||
<div class="doc-title">
|
|
||||||
<h1>Remito</h1>
|
|
||||||
<div class="num">@Model.DeliveryNoteNumber@reprintText</div>
|
|
||||||
<div class="date">Fecha: @Model.IssueDate.ToString("dd/MM/yyyy")</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="hr"></div>
|
|
||||||
|
|
||||||
<div class="info-block avoid-break">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td class="lbl">Cliente</td>
|
|
||||||
<td class="val">@FText(Model.CustomerName)</td>
|
|
||||||
<td class="lbl">Estado</td>
|
|
||||||
<td class="val">@FText(Model.Status)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="lbl">Presupuesto</td>
|
|
||||||
<td class="val">@FText(Model.QuoteNumber)</td>
|
|
||||||
<td class="lbl">ID interno</td>
|
|
||||||
<td class="val">@Model.Id</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section-title">Contexto clínico</div>
|
|
||||||
<div class="snapshot avoid-break">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td class="lbl">Profesional</td>
|
|
||||||
<td class="val">@FText(snap.Professional)</td>
|
|
||||||
<td class="lbl">Institución</td>
|
|
||||||
<td class="val">@FText(snap.Institution)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="lbl">Paciente</td>
|
|
||||||
<td class="val">@FText(snap.Patient)</td>
|
|
||||||
<td class="lbl">Fecha cirugía</td>
|
|
||||||
<td class="val">@FDate(snap.SurgeryDate)</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section-title">Detalle de ítems</div>
|
|
||||||
<div class="items">
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="col-line">#</th>
|
|
||||||
<th class="col-desc">Descripción</th>
|
|
||||||
<th class="col-qty">Cantidad</th>
|
|
||||||
<th class="col-origin">Origen</th>
|
|
||||||
<th class="col-originid">Ref.</th>
|
|
||||||
<th class="col-notes">Notas</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var item in Model.Items.OrderBy(i => i.LineNumber))
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td class="col-line">@item.LineNumber</td>
|
|
||||||
<td class="col-desc">@FText(item.Description)</td>
|
|
||||||
<td class="col-qty">@FQty(item.Quantity)</td>
|
|
||||||
<td class="col-origin">@FOrigin(item.OriginType)</td>
|
|
||||||
<td class="col-originid">@(item.OriginId?.ToString() ?? "-")</td>
|
|
||||||
<td class="col-notes">@FText(item.Notes)</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section-title">Observaciones</div>
|
|
||||||
<div class="observ">@FText(Model.Observations)</div>
|
|
||||||
|
|
||||||
<div class="footer">Impreso el @DateTime.Now.ToString("dd/MM/yyyy HH:mm")</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Domain.Dtos.Sales
|
namespace Domain.Dtos.Sales
|
||||||
@ -11,14 +11,11 @@ namespace Domain.Dtos.Sales
|
|||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string DeliveryNoteNumber { get; set; } = string.Empty;
|
public string DeliveryNoteNumber { get; set; } = string.Empty;
|
||||||
public string CustomerName { get; set; } = string.Empty;
|
|
||||||
public int? QuoteId { get; set; }
|
public int? QuoteId { get; set; }
|
||||||
public string? QuoteNumber { get; set; }
|
|
||||||
public int? SalesInvoiceId { get; set; }
|
public int? SalesInvoiceId { get; set; }
|
||||||
public DateTime IssueDate { get; set; }
|
public DateTime IssueDate { get; set; }
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
public string Status { get; set; } = string.Empty;
|
public string Status { get; set; } = string.Empty;
|
||||||
public string? LogoBase64 { get; set; }
|
|
||||||
public string? Observations { get; set; }
|
public string? Observations { get; set; }
|
||||||
public string? ExtraInfoJson { get; set; }
|
public string? ExtraInfoJson { get; set; }
|
||||||
public int PrintCount { get; set; }
|
public int PrintCount { get; set; }
|
||||||
|
|||||||
@ -86,8 +86,6 @@ namespace Models.Repositories
|
|||||||
public async Task<DeliveryNoteDto?> GetDtoByIdAsync(int id)
|
public async Task<DeliveryNoteDto?> GetDtoByIdAsync(int id)
|
||||||
{
|
{
|
||||||
var entity = await _context.PhSDeliveryNotes
|
var entity = await _context.PhSDeliveryNotes
|
||||||
.Include(x => x.Customer)
|
|
||||||
.Include(x => x.Quote)
|
|
||||||
.Include(x => x.PhSDeliveryNoteDetails)
|
.Include(x => x.PhSDeliveryNoteDetails)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(x => x.Id == id);
|
.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
@ -98,8 +96,6 @@ namespace Models.Repositories
|
|||||||
public async Task<DeliveryNoteDto?> GetDtoByDeliveryNoteNumberAsync(string deliveryNoteNumber)
|
public async Task<DeliveryNoteDto?> GetDtoByDeliveryNoteNumberAsync(string deliveryNoteNumber)
|
||||||
{
|
{
|
||||||
var entity = await _context.PhSDeliveryNotes
|
var entity = await _context.PhSDeliveryNotes
|
||||||
.Include(x => x.Customer)
|
|
||||||
.Include(x => x.Quote)
|
|
||||||
.Include(x => x.PhSDeliveryNoteDetails)
|
.Include(x => x.PhSDeliveryNoteDetails)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(x => x.Deliverynotenumber == deliveryNoteNumber);
|
.FirstOrDefaultAsync(x => x.Deliverynotenumber == deliveryNoteNumber);
|
||||||
@ -110,8 +106,6 @@ namespace Models.Repositories
|
|||||||
public async Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId)
|
public async Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId)
|
||||||
{
|
{
|
||||||
var entities = await _context.PhSDeliveryNotes
|
var entities = await _context.PhSDeliveryNotes
|
||||||
.Include(x => x.Customer)
|
|
||||||
.Include(x => x.Quote)
|
|
||||||
.Include(x => x.PhSDeliveryNoteDetails)
|
.Include(x => x.PhSDeliveryNoteDetails)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => x.QuoteId == quoteId)
|
.Where(x => x.QuoteId == quoteId)
|
||||||
@ -145,9 +139,7 @@ namespace Models.Repositories
|
|||||||
{
|
{
|
||||||
Id = source.Id,
|
Id = source.Id,
|
||||||
DeliveryNoteNumber = source.Deliverynotenumber,
|
DeliveryNoteNumber = source.Deliverynotenumber,
|
||||||
CustomerName = source.Customer?.Name ?? string.Empty,
|
|
||||||
QuoteId = source.QuoteId,
|
QuoteId = source.QuoteId,
|
||||||
QuoteNumber = source.Quote?.Quotenumber,
|
|
||||||
SalesInvoiceId = source.SalesinvoiceId,
|
SalesInvoiceId = source.SalesinvoiceId,
|
||||||
IssueDate = source.Issuedate,
|
IssueDate = source.Issuedate,
|
||||||
CustomerId = source.CustomerId,
|
CustomerId = source.CustomerId,
|
||||||
@ -155,7 +147,6 @@ namespace Models.Repositories
|
|||||||
Observations = source.Observations,
|
Observations = source.Observations,
|
||||||
ExtraInfoJson = source.ExtrainfoJson,
|
ExtraInfoJson = source.ExtrainfoJson,
|
||||||
PrintCount = source.Printcount,
|
PrintCount = source.Printcount,
|
||||||
LogoBase64 = null,
|
|
||||||
CreatedAt = source.Createdat,
|
CreatedAt = source.Createdat,
|
||||||
ModifiedAt = source.Modifiedat,
|
ModifiedAt = source.Modifiedat,
|
||||||
Items = source.PhSDeliveryNoteDetails
|
Items = source.PhSDeliveryNoteDetails
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
using Core.Interfaces;
|
using Core.Interfaces;
|
||||||
using Documents.Interfaces;
|
|
||||||
using Documents.Models;
|
|
||||||
using Domain.Dtos.Sales;
|
using Domain.Dtos.Sales;
|
||||||
using Domain.Generics;
|
using Domain.Generics;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -12,14 +10,10 @@ namespace phronCare.API.Controllers.Sales
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
public class DeliveryNoteController : ControllerBase
|
public class DeliveryNoteController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IDocumentTemplateService _documentTemplateService;
|
|
||||||
private readonly IDeliveryNoteDom _deliveryNoteService;
|
private readonly IDeliveryNoteDom _deliveryNoteService;
|
||||||
|
|
||||||
public DeliveryNoteController(
|
public DeliveryNoteController(IDeliveryNoteDom deliveryNoteService)
|
||||||
IDocumentTemplateService documentTemplateService,
|
|
||||||
IDeliveryNoteDom deliveryNoteService)
|
|
||||||
{
|
{
|
||||||
_documentTemplateService = documentTemplateService ?? throw new ArgumentNullException(nameof(documentTemplateService));
|
|
||||||
_deliveryNoteService = deliveryNoteService ?? throw new ArgumentNullException(nameof(deliveryNoteService));
|
_deliveryNoteService = deliveryNoteService ?? throw new ArgumentNullException(nameof(deliveryNoteService));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,24 +89,6 @@ namespace phronCare.API.Controllers.Sales
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("{id:int}/pdf")]
|
|
||||||
public async Task<IActionResult> GetDeliveryNotePdf(int id)
|
|
||||||
{
|
|
||||||
var deliveryNote = await _deliveryNoteService.GetDtoByIdAsync(id);
|
|
||||||
|
|
||||||
if (deliveryNote == null)
|
|
||||||
return NotFound($"Remito con ID {id} no encontrado.");
|
|
||||||
|
|
||||||
var pdfBytes = await _documentTemplateService.GenerateDocumentAsync(new DocumentGenerationRequest
|
|
||||||
{
|
|
||||||
Model = deliveryNote,
|
|
||||||
DocumentType = DocumentType.DeliveryNote
|
|
||||||
});
|
|
||||||
|
|
||||||
return File(pdfBytes, "application/pdf", $"Remito_{deliveryNote.DeliveryNoteNumber}.pdf");
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("by-quote/{quoteId:int}")]
|
[HttpGet("by-quote/{quoteId:int}")]
|
||||||
public async Task<ActionResult<IEnumerable<DeliveryNoteDto>>> GetByQuoteId(int quoteId)
|
public async Task<ActionResult<IEnumerable<DeliveryNoteDto>>> GetByQuoteId(int quoteId)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -369,7 +369,6 @@
|
|||||||
|
|
||||||
var response = await DeliveryNoteService.CreateAndIssueAsync(request);
|
var response = await DeliveryNoteService.CreateAndIssueAsync(request);
|
||||||
toastService.ShowSuccess($"Remito {response.DeliveryNoteNumber} emitido correctamente.");
|
toastService.ShowSuccess($"Remito {response.DeliveryNoteNumber} emitido correctamente.");
|
||||||
await DeliveryNoteService.ExportPdfAsync(response.Id, response.DeliveryNoteNumber);
|
|
||||||
Navigation.NavigateTo("/deliverynotes");
|
Navigation.NavigateTo("/deliverynotes");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@ -93,7 +93,6 @@
|
|||||||
<td>@deliveryNote.PrintCount</td>
|
<td>@deliveryNote.PrintCount</td>
|
||||||
<td class="text-center align-middle">
|
<td class="text-center align-middle">
|
||||||
<button class="btn btn-link btn-lg p-0 text-primary ms-2" title="Ver detalle" @onclick="() => OpenDetailAsync(deliveryNote)"><i class="fas fa-eye"></i></button>
|
<button class="btn btn-link btn-lg p-0 text-primary ms-2" title="Ver detalle" @onclick="() => OpenDetailAsync(deliveryNote)"><i class="fas fa-eye"></i></button>
|
||||||
<button class="btn btn-link btn-lg p-0 text-danger ms-2" title="Imprimir PDF" @onclick="() => PrintPdfAsync(deliveryNote)"><i class="fas fa-print"></i></button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@ -257,18 +256,6 @@
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PrintPdfAsync(DeliveryNoteSummaryDto deliveryNote)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await deliveryNoteService.ExportPdfAsync(deliveryNote.Id, deliveryNote.DeliveryNoteNumber);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
toastService.ShowError(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExportarExcel()
|
private void ExportarExcel()
|
||||||
{
|
{
|
||||||
toastService.ShowInfo("La exportación a Excel se implementará en una próxima story.");
|
toastService.ShowInfo("La exportación a Excel se implementará en una próxima story.");
|
||||||
|
|||||||
@ -1,19 +1,16 @@
|
|||||||
using Domain.Dtos.Sales;
|
using Domain.Dtos.Sales;
|
||||||
using Domain.Generics;
|
using Domain.Generics;
|
||||||
using Microsoft.JSInterop;
|
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
|
|
||||||
namespace phronCare.UIBlazor.Services.Sales.DeliveryNotes
|
namespace phronCare.UIBlazor.Services.Sales.DeliveryNotes
|
||||||
{
|
{
|
||||||
public class DeliveryNoteService : IDeliveryNoteService
|
public class DeliveryNoteService : IDeliveryNoteService
|
||||||
{
|
{
|
||||||
private readonly IJSRuntime _js;
|
|
||||||
private readonly HttpClient _http;
|
private readonly HttpClient _http;
|
||||||
|
|
||||||
public DeliveryNoteService(HttpClient http, IJSRuntime js)
|
public DeliveryNoteService(HttpClient http)
|
||||||
{
|
{
|
||||||
_http = http;
|
_http = http;
|
||||||
_js = js;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,29 +94,5 @@ namespace phronCare.UIBlazor.Services.Sales.DeliveryNotes
|
|||||||
var result = await response.Content.ReadFromJsonAsync<DeliveryNoteCreateResponse>();
|
var result = await response.Content.ReadFromJsonAsync<DeliveryNoteCreateResponse>();
|
||||||
return result ?? throw new Exception("Respuesta vacía del servidor.");
|
return result ?? throw new Exception("Respuesta vacía del servidor.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ExportPdfAsync(int deliveryNoteId, string deliveryNoteNumber)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await _http.GetAsync($"/api/deliverynote/{deliveryNoteId}/pdf");
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
var error = await response.Content.ReadAsStringAsync();
|
|
||||||
throw new Exception($"Error al generar PDF: {error}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var bytes = await response.Content.ReadAsByteArrayAsync();
|
|
||||||
var base64 = Convert.ToBase64String(bytes);
|
|
||||||
var fileName = $"{deliveryNoteNumber}.pdf";
|
|
||||||
|
|
||||||
await _js.InvokeVoidAsync("saveAsFile", fileName, base64);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new Exception($"ExportPdfAsync: {ex.Message}", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,5 @@ namespace phronCare.UIBlazor.Services.Sales.DeliveryNotes
|
|||||||
Task<DeliveryNoteDto?> GetByDeliveryNoteNumberAsync(string deliveryNoteNumber);
|
Task<DeliveryNoteDto?> GetByDeliveryNoteNumberAsync(string deliveryNoteNumber);
|
||||||
Task<IEnumerable<DeliveryNoteDto>> GetByQuoteIdAsync(int quoteId);
|
Task<IEnumerable<DeliveryNoteDto>> GetByQuoteIdAsync(int quoteId);
|
||||||
Task<DeliveryNoteCreateResponse> CreateAndIssueAsync(DeliveryNoteCreateRequest request);
|
Task<DeliveryNoteCreateResponse> CreateAndIssueAsync(DeliveryNoteCreateRequest request);
|
||||||
Task ExportPdfAsync(int deliveryNoteId, string deliveryNoteNumber);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user