Update GetByIdDTO
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 6m14s
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 6m14s
This commit is contained in:
parent
510862ed60
commit
5ec19044f2
@ -19,6 +19,7 @@ namespace Models.Interfaces
|
||||
#endregion
|
||||
#region Guardado completo de presupuesto (encabezado + detalles + roles + ajustes + impuestos)
|
||||
Task<string> CreateFullQuoteAsync(EQuoteHeader quote, int formSeriesId);
|
||||
Task<QuoteDto?> GetDtoByIdAsync(int id);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,7 @@ namespace Core.Services
|
||||
//private readonly IPhSQuoteRepository _quoteRepository = quoteRepository;
|
||||
#endregion
|
||||
|
||||
#region Presupuestos
|
||||
public async Task<PagedResult<QuoteDto>> SearchAsync(int? customerId, string? customerText, string? quoteNumber, int? professionalId, string? professionalText, int? institutionId, string? institutionText, int? patientId, string? patientText, DateTime? issueDateFrom, DateTime? issueDateTo, string? status, int page, int pageSize)
|
||||
{
|
||||
return await _quoteRepository.SearchAsync(
|
||||
@ -31,7 +32,11 @@ namespace Core.Services
|
||||
page,
|
||||
pageSize);
|
||||
}
|
||||
#region Presupuestos
|
||||
|
||||
public async Task<QuoteDto?> GetDtoByIdAsync(int id)
|
||||
{
|
||||
return await _quoteRepository.GetDtoByIdAsync(id);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Guardado completo de presupuesto (encabezado + detalles + roles + ajustes + impuestos)
|
||||
|
||||
@ -23,9 +23,6 @@ namespace Documents.Services
|
||||
{
|
||||
// 👉 Renderizar HTML usando RazorLight
|
||||
string html = await _templateRenderer.RenderAsync("Quotes/Template_v1.cshtml", request.Model);
|
||||
|
||||
// 🔍 Dump HTML a archivo temporal para inspección
|
||||
File.WriteAllText("/tmp/html_debug_output.html", html, Encoding.UTF8);
|
||||
// 👉 Generar PDF desde el HTML
|
||||
return await _pdfGeneratorService.GeneratePdfFromHtmlAsync(html);
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
@model Domain.Dtos.QuoteDto
|
||||
@using Domain.Dtos
|
||||
@using System.Globalization
|
||||
@model Domain.Dtos.QuoteDto
|
||||
|
||||
@{
|
||||
var culture = System.Globalization.CultureInfo.GetCultureInfo("es-AR");
|
||||
var culture = CultureInfo.GetCultureInfo("es-AR");
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
@ -10,171 +13,163 @@
|
||||
<title>Presupuesto @Model.Quotenumber</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Liberation Sans", "DejaVu Sans", sans-serif;
|
||||
font-size: 13px;
|
||||
color: #222;
|
||||
margin: 40px;
|
||||
line-height: 1.5;
|
||||
font-family: 'Liberation Sans', Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
margin: 30px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.company-info {
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
h1, h2, h3 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
color: #444;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.header, .footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 10px;
|
||||
margin-top: 40px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
margin-bottom: 0;
|
||||
color: #004B8D;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
margin-top: 30px;
|
||||
color: #004B8D;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding-bottom: 4px;
|
||||
.section {
|
||||
margin-top: 10px;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #ccc;
|
||||
padding: 6px;
|
||||
vertical-align: top;
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f0f0f0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.totals-table td {
|
||||
border: none;
|
||||
.totales {
|
||||
margin-top: 10px;
|
||||
float: right;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.observaciones {
|
||||
white-space: pre-wrap;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
background: #f9f9f9;
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
margin-top: 20px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="company-info">
|
||||
<strong>BIODEC S.A.</strong><br />
|
||||
CUIT: 33-70849672-9 | Ing. Brutos: 901-070604-2<br />
|
||||
Inicio Actividades: 02/10/2003 | IVA: Responsable Inscripto<br />
|
||||
Segurola 1885 – C.P. C1407AOK – CABA – Buenos Aires – Argentina<br />
|
||||
Tel: (011) 4864-6005 | Fax: 4864-5710<br />
|
||||
<a href="mailto:ventas@biodec.net">ventas@biodec.net</a> |
|
||||
Web: www.biodec.net<br />
|
||||
Urgencias: 15-2155-9380 / 15-5909-4987 / 15-5909-4892
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1>phronCare - Presupuesto</h1>
|
||||
<p><strong>Número:</strong> @Model.Quotenumber</p>
|
||||
<p><strong>Fecha de Emisión:</strong> @Model.IssueDate.ToString("dd/MM/yyyy")</p>
|
||||
<h2>Presupuesto Nº @Model.Quotenumber</h2>
|
||||
<p>Fecha de emisión: @Model.IssueDate.ToString("dd/MM/yyyy")</p>
|
||||
</div>
|
||||
|
||||
<h2>Datos del Cliente</h2>
|
||||
<table>
|
||||
<tr><th>Razón Social</th><td>@Model.CustomerName</td></tr>
|
||||
<tr><th>Paciente</th><td>@Model.PatientName</td></tr>
|
||||
<tr><th>Médico</th><td>@Model.ProfessionalName</td></tr>
|
||||
<tr><th>Institución</th><td>@Model.InstitutionName</td></tr>
|
||||
<tr><th>Fecha estimada cirugía</th><td>@(Model.EstimatedDate?.ToString("dd/MM/yyyy") ?? "-")</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Productos Cotizados</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Cantidad</th>
|
||||
<th>Descripción</th>
|
||||
<th class="right">Precio Unitario (@Model.Currency)</th>
|
||||
<th class="right">Total (@Model.Currency)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Items)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Quantity</td>
|
||||
<td>@item.Description</td>
|
||||
<td class="right">@item.UnitPrice.ToString("C", culture)</td>
|
||||
<td class="right">@item.Total.ToString("C", culture)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Totales</h2>
|
||||
<table class="totals-table">
|
||||
<tr>
|
||||
<td class="right"><strong>Subtotal:</strong></td>
|
||||
<td class="right">@Model.Items.Sum(i => i.Subtotal).ToString("C", culture)</td>
|
||||
</tr>
|
||||
@if (Model.Taxes?.Any() == true)
|
||||
<div class="section">
|
||||
<h3>Datos del Cliente</h3>
|
||||
<p><strong>Nombre:</strong> @Model.Customer.Name</p>
|
||||
<p><strong>Domicilio:</strong> @Model.Customer.Address</p>
|
||||
<p><strong>Condición IVA:</strong> @Model.Customer.IvaCondition</p>
|
||||
@if (Model.Customer.Documents != null && Model.Customer.Documents.Any())
|
||||
{
|
||||
foreach (var tax in Model.Taxes)
|
||||
{
|
||||
<tr>
|
||||
<td class="right"><strong>@tax.TaxName (@tax.TaxRate%)</strong></td>
|
||||
<td class="right">@tax.TaxAmount.ToString("C", culture)</td>
|
||||
</tr>
|
||||
}
|
||||
<p><strong>Documentos:</strong></p>
|
||||
<ul>
|
||||
@foreach (var doc in Model.Customer.Documents)
|
||||
{
|
||||
<li>@doc.DocumentType: @doc.Number</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
@if (Model.Adjustments?.Any() == true)
|
||||
else
|
||||
{
|
||||
foreach (var adj in Model.Adjustments)
|
||||
{
|
||||
<tr>
|
||||
<td class="right"><strong>Ajuste: @adj.Reason</strong></td>
|
||||
<td class="right">@adj.Amount.ToString("C", culture)</td>
|
||||
</tr>
|
||||
}
|
||||
<p>— Sin documentos —</p>
|
||||
}
|
||||
<tr class="highlight">
|
||||
<td class="right"><strong>Total Final:</strong></td>
|
||||
<td class="right">@Model.Total.ToString("C", culture)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2>Observaciones</h2>
|
||||
<div class="observaciones">
|
||||
@Model.Observations
|
||||
<div class="section">
|
||||
<h3>Datos del Paciente y Atención</h3>
|
||||
<p><strong>Paciente:</strong> @Model.PatientName</p>
|
||||
<p><strong>Médico:</strong> @Model.ProfessionalName</p>
|
||||
<p><strong>Institución:</strong> @Model.InstitutionName</p>
|
||||
<p><strong>Fecha estimada:</strong> @(Model.EstimatedDate?.ToString("dd/MM/yyyy") ?? "—")</p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Productos Cotizados</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Descripción</th>
|
||||
<th>Cantidad</th>
|
||||
<th>Precio Unitario</th>
|
||||
<th>Subtotal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Items)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Description</td>
|
||||
<td>@item.Quantity</td>
|
||||
<td>@item.UnitPrice.ToString("C", culture)</td>
|
||||
<td>@item.Total.ToString("C", culture)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Totales</h3>
|
||||
<table class="totales">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>Subtotal</strong></td>
|
||||
<td>@Model.Items.Sum(i => i.Subtotal).ToString("C", culture)</td>
|
||||
</tr>
|
||||
@if (Model.Taxes?.Any() == true)
|
||||
{
|
||||
@foreach (var tax in Model.Taxes)
|
||||
{
|
||||
<tr>
|
||||
<td><strong>@tax.TaxName (@tax.TaxRate%)</strong></td>
|
||||
<td>@tax.TaxAmount.ToString("C", culture)</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
@if (Model.Adjustments?.Any() == true)
|
||||
{
|
||||
@foreach (var adj in Model.Adjustments)
|
||||
{
|
||||
<tr>
|
||||
<td><strong>Ajuste: @adj.Reason</strong></td>
|
||||
<td>@adj.Amount.ToString("C", culture)</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
<tr>
|
||||
<td><strong>Total Final</strong></td>
|
||||
<td>@Model.Total.ToString("C", culture)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Observaciones</h3>
|
||||
<p>@(string.IsNullOrWhiteSpace(Model.Observations) ? "— Sin observaciones —" : Model.Observations)</p>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Sistema de gestión y administración PhronCare © 2025</p>
|
||||
<p>Sistema de Gestión y Administración - PhronCare © 2025</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -3,10 +3,8 @@
|
||||
public class QuoteCustomerDto
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public string Cuit { get; set; } = "";
|
||||
public string IngresosBrutos { get; set; } = "";
|
||||
public string Address { get; set; } = "";
|
||||
public string IvaCondition { get; set; } = "";
|
||||
public List<QuoteCustomerDocumentDto> Documents { get; set; } = new();
|
||||
}
|
||||
|
||||
}
|
||||
8
Domain/Dtos/QuoteCustomerDocumentDto.cs
Normal file
8
Domain/Dtos/QuoteCustomerDocumentDto.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Domain.Dtos
|
||||
{
|
||||
public class QuoteCustomerDocumentDto
|
||||
{
|
||||
public string DocumentType { get; set; } = "";
|
||||
public string Number { get; set; } = "";
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ namespace Models.Interfaces
|
||||
#endregion
|
||||
#region Guardado completo de presupuesto (encabezado + detalles + roles + ajustes + impuestos)
|
||||
Task<string> CreateFullQuoteAsync(EQuoteHeader quote, int formSeriesId);
|
||||
Task<QuoteDto?> GetDtoByIdAsync(int id);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,6 +213,129 @@ namespace Models.Repositories
|
||||
PageSize = pagedEntities.PageSize
|
||||
};
|
||||
}
|
||||
public async Task<QuoteDto?> GetDtoByIdAsync(int id)
|
||||
{
|
||||
var header = await _context.PhSQuoteHeaders
|
||||
.Include(q => q.PhSQuoteDetails)
|
||||
.Include(q => q.PhSQuoteRoles)
|
||||
.Include(q => q.PhSQuoteAdjustments)
|
||||
.Include(q => q.PhSQuoteTaxes)
|
||||
.FirstOrDefaultAsync(q => q.Id == id);
|
||||
|
||||
if (header == null)
|
||||
return null;
|
||||
|
||||
// Cargar Customer completo con documentos y tipos
|
||||
var customer = await _context.PhSCustomers
|
||||
.Include(c => c.PhSCustomerDocuments)
|
||||
.ThenInclude(d => d.Documenttypes) // ✅ CORRECTO
|
||||
.Include(c => c.PhSCustomerAddresses)
|
||||
.Include(c => c.TaxCondition)
|
||||
.FirstOrDefaultAsync(c => c.Id == header.CustomerId);
|
||||
|
||||
var totalTaxAmount = header.PhSQuoteTaxes.Sum(t => t.Taxamount);
|
||||
var netBase = header.Netamount.GetValueOrDefault() != 0m
|
||||
? header.Netamount.Value
|
||||
: 1m;
|
||||
|
||||
var dto = new QuoteDto
|
||||
{
|
||||
Id = header.Id,
|
||||
Quotenumber = header.Quotenumber,
|
||||
IssueDate = header.Issuedate,
|
||||
EstimatedDate = header.Estimateddate,
|
||||
Currency = header.Currency,
|
||||
Total = header.Total.GetValueOrDefault(0m),
|
||||
Status = header.Status.Trim(),
|
||||
Observations = header.Observations ?? "",
|
||||
|
||||
CustomerName = customer?.Name ?? "",
|
||||
BusinessUnitName = _context.PhSBusinessUnits
|
||||
.Where(b => b.Id == header.BusinessunitId)
|
||||
.Select(b => b.Code)
|
||||
.FirstOrDefault() ?? "",
|
||||
|
||||
ProfessionalName = header.PhSQuoteRoles
|
||||
.Where(r => r.Entitytype == PhSEntityTypes.Professional)
|
||||
.Select(r => _context.PhSProfessionals
|
||||
.Where(p => p.Id == r.EntityId)
|
||||
.Select(p => p.Fullname)
|
||||
.FirstOrDefault())
|
||||
.FirstOrDefault() ?? "",
|
||||
|
||||
InstitutionName = header.PhSQuoteRoles
|
||||
.Where(r => r.Entitytype == PhSEntityTypes.Institution)
|
||||
.Select(r => _context.PhSInstitutions
|
||||
.Where(i => i.Id == r.EntityId)
|
||||
.Select(i => i.Name)
|
||||
.FirstOrDefault())
|
||||
.FirstOrDefault() ?? "",
|
||||
|
||||
PatientName = header.PhSQuoteRoles
|
||||
.Where(r => r.Entitytype == PhSEntityTypes.Patient)
|
||||
.Select(r => _context.PhSPatients
|
||||
.Where(pt => pt.Id == r.EntityId)
|
||||
.Select(pt => (pt.Firstname + " " + pt.Lastname).Trim())
|
||||
.FirstOrDefault())
|
||||
.FirstOrDefault() ?? "",
|
||||
|
||||
SalespersonName = _context.PhSPeople
|
||||
.Where(u => u.Id == header.PeopleId)
|
||||
.Select(u => u.Name)
|
||||
.FirstOrDefault() ?? "",
|
||||
|
||||
Items = header.PhSQuoteDetails.Select(d =>
|
||||
{
|
||||
var itemBase = d.Quantity * d.Unitprice;
|
||||
var itemTax = totalTaxAmount * itemBase / netBase;
|
||||
|
||||
return new QuoteItemDto
|
||||
{
|
||||
Description = d.ProductDescription,
|
||||
Quantity = d.Quantity,
|
||||
UnitPrice = d.Unitprice,
|
||||
Subtotal = itemBase,
|
||||
TaxAmount = itemTax,
|
||||
Total = itemBase + itemTax
|
||||
};
|
||||
}).ToList(),
|
||||
|
||||
Taxes = header.PhSQuoteTaxes.Select(t => new QuoteTaxDto
|
||||
{
|
||||
TaxName = t.Taxname,
|
||||
TaxCode = t.Taxcode,
|
||||
TaxableAmount = t.TaxableAmount,
|
||||
TaxRate = t.Taxrate,
|
||||
TaxAmount = t.Taxamount,
|
||||
IsIncludedInPrice = t.IsIncludedInPrice
|
||||
}).ToList(),
|
||||
|
||||
Adjustments = header.PhSQuoteAdjustments.Select(a => new QuoteAdjustmentDto
|
||||
{
|
||||
Reason = _context.PhSAdjustmentReasons
|
||||
.Where(r => r.Code == a.ReasonCode)
|
||||
.Select(r => r.Description)
|
||||
.FirstOrDefault() ?? "",
|
||||
Amount = a.Amount.GetValueOrDefault(0m)
|
||||
}).ToList(),
|
||||
|
||||
Customer = new QuoteCustomerDto
|
||||
{
|
||||
Name = customer?.Name ?? "",
|
||||
Address = customer?.PhSCustomerAddresses
|
||||
.Select(a => a.Streetaddress1)
|
||||
.FirstOrDefault() ?? "",
|
||||
IvaCondition = customer?.TaxCondition?.Description ?? "",
|
||||
Documents = customer?.PhSCustomerDocuments
|
||||
.Select(d => new QuoteCustomerDocumentDto
|
||||
{
|
||||
DocumentType = d.Documenttypes.Name, // ✅ correcto
|
||||
Number = d.DocumentNumber
|
||||
}).ToList() ?? new()
|
||||
}
|
||||
};
|
||||
return dto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region Guardado completo de presupuesto (encabezado + detalles + roles + ajustes + impuestos)
|
||||
|
||||
22
phronCare.API/Controllers/Documents/DocumentsController.cs
Normal file
22
phronCare.API/Controllers/Documents/DocumentsController.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Documents.Interfaces;
|
||||
using Documents.Models;
|
||||
using Domain.Dtos;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Models.Interfaces;
|
||||
|
||||
namespace phronCare.API.Controllers.Documents
|
||||
{
|
||||
public class DocumentController : ControllerBase
|
||||
{
|
||||
private readonly IDocumentTemplateService _documentTemplateService;
|
||||
private readonly IQuoteDom _quoteService;
|
||||
|
||||
public DocumentController(IDocumentTemplateService documentTemplateService, IQuoteDom quoteService)
|
||||
{
|
||||
_documentTemplateService = documentTemplateService;
|
||||
_quoteService = quoteService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,11 @@
|
||||
using Domain.Dtos;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Documents.Models;
|
||||
using Domain.Dtos;
|
||||
using Domain.Entities;
|
||||
using Domain.Generics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Models.Interfaces;
|
||||
using System.Reflection;
|
||||
using Documents.Interfaces;
|
||||
|
||||
namespace phronCare.API.Controllers.Sales
|
||||
{
|
||||
@ -11,10 +13,14 @@ namespace phronCare.API.Controllers.Sales
|
||||
[ApiController]
|
||||
public class QuoteController : ControllerBase
|
||||
{
|
||||
private readonly IDocumentTemplateService _documentTemplateService;
|
||||
private readonly IQuoteDom _quoteService;
|
||||
public QuoteController(IQuoteDom quoteService)
|
||||
public QuoteController(IDocumentTemplateService documentTemplateService, IQuoteDom quoteService)
|
||||
{
|
||||
_quoteService = quoteService ?? throw new ArgumentNullException(nameof(quoteService));
|
||||
_documentTemplateService = documentTemplateService ??
|
||||
throw new ArgumentNullException(nameof(documentTemplateService)); ;
|
||||
_quoteService = quoteService ??
|
||||
throw new ArgumentNullException(nameof(quoteService));
|
||||
}
|
||||
|
||||
#region Obtener Presupuestos
|
||||
@ -65,143 +71,24 @@ namespace phronCare.API.Controllers.Sales
|
||||
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("quote/{id}/pdf")]
|
||||
public async Task<IActionResult> GetQuotePdf(int id)
|
||||
{
|
||||
var quote = await _quoteService.GetDtoByIdAsync(id);
|
||||
|
||||
if (quote == null)
|
||||
return NotFound($"Presupuesto con ID {id} no encontrado.");
|
||||
|
||||
var pdfBytes = await _documentTemplateService.GenerateDocumentAsync(new DocumentGenerationRequest
|
||||
{
|
||||
Model = quote
|
||||
});
|
||||
|
||||
return File(pdfBytes, "application/pdf", $"Presupuesto_{quote.Quotenumber}.pdf");
|
||||
}
|
||||
#endregion
|
||||
|
||||
//[HttpGet("all")]
|
||||
//public async Task<IActionResult> GetAll([FromQuery] int page = 1, [FromQuery] int pageSize = 50)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var result = await _quoteService.GetAllQuotesAsync(page, pageSize);
|
||||
// return Ok(result);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
// return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
// }
|
||||
//}
|
||||
|
||||
//[HttpGet("search")]
|
||||
//public async Task<IActionResult> Search(
|
||||
// [FromQuery] int? customerId,
|
||||
// [FromQuery] string? customerText,
|
||||
// [FromQuery] string? quoteNumber,
|
||||
// [FromQuery] int? professionalId,
|
||||
// [FromQuery] string? professionalText,
|
||||
// [FromQuery] int? institutionId,
|
||||
// [FromQuery] string? institutionText,
|
||||
// [FromQuery] int? patientId,
|
||||
// [FromQuery] string? patientText,
|
||||
// [FromQuery] DateTime? issueDateFrom,
|
||||
// [FromQuery] DateTime? issueDateTo,
|
||||
// [FromQuery] string? status,
|
||||
// [FromQuery] int page = 1,
|
||||
// [FromQuery] int pageSize = 50)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var result = await _quoteService.SearchAsync(
|
||||
// customerId,
|
||||
// customerText,
|
||||
// quoteNumber,
|
||||
// professionalId,
|
||||
// professionalText,
|
||||
// institutionId,
|
||||
// institutionText,
|
||||
// patientId,
|
||||
// patientText,
|
||||
// issueDateFrom,
|
||||
// issueDateTo,
|
||||
// status,
|
||||
// page,
|
||||
// pageSize);
|
||||
|
||||
// return Ok(result);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
// return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
// }
|
||||
//}
|
||||
|
||||
//[HttpGet("{id:int}")]
|
||||
//public async Task<ActionResult<EQuoteHeader>> GetById(int id)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var quote = await _quoteService.GetQuoteByIdAsync(id);
|
||||
// if (quote == null)
|
||||
// return NotFound();
|
||||
|
||||
// return Ok(quote);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
// return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
// }
|
||||
//}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Crear / Actualizar / Eliminar
|
||||
|
||||
//[HttpPut("update")]
|
||||
//public async Task<IActionResult> Update([FromBody] EQuoteHeader quote)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// if (quote == null || quote.Id <= 0)
|
||||
// return BadRequest("El presupuesto es inválido o no tiene un ID válido.");
|
||||
|
||||
// await _quoteService.UpdateQuoteAsync(quote);
|
||||
// return Ok("Presupuesto actualizado correctamente.");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
// return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
// }
|
||||
//}
|
||||
|
||||
//[HttpDelete("delete/{id:int}")]
|
||||
//public async Task<IActionResult> Delete(int id)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// await _quoteService.DeleteQuoteAsync(id);
|
||||
// return Ok("Presupuesto eliminado correctamente.");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
|
||||
// return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//#region Exportación
|
||||
|
||||
//[HttpPost("exportfiltered")]
|
||||
//public async Task<IActionResult> ExportFiltered([FromBody] QuoteSearchParams searchParams)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var file = await _quoteService.ExportFilteredQuotesToExcelAsync(searchParams);
|
||||
// return File(file,
|
||||
// "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
// "Presupuestos.xlsx");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return BadRequest(ex.Message);
|
||||
// }
|
||||
//}
|
||||
|
||||
//#endregion
|
||||
|
||||
#region Endpoint de emision de presupuesto (encabezado + detalles + roles + ajustes + impuestos)
|
||||
[HttpPost("createfull")]
|
||||
public async Task<IActionResult> CreateFullQuote([FromBody] CreateFullQuoteRequest request)
|
||||
@ -243,5 +130,7 @@ namespace phronCare.API.Controllers.Sales
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1602,6 +1602,22 @@
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "GetQuotePdf",
|
||||
"RelativePath": "api/Quote/quote/{id}/pdf",
|
||||
"HttpMethod": "GET",
|
||||
"IsController": true,
|
||||
"Order": 0,
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "id",
|
||||
"Type": "System.Int32",
|
||||
"IsRequired": true
|
||||
}
|
||||
],
|
||||
"ReturnTypes": []
|
||||
},
|
||||
{
|
||||
"ContainingType": "phronCare.API.Controllers.Sales.QuoteController",
|
||||
"Method": "Search",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user