Testing Razor PDF Generator
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 9m29s

This commit is contained in:
Leandro Hernan Rojas 2025-05-15 19:24:12 -03:00
parent 43e650a1f8
commit b6c63b874c
30 changed files with 821 additions and 2314 deletions

View File

@ -1,4 +1,4 @@
using Core.Dtos; using Domain.Dtos;
using Domain.Entities; using Domain.Entities;
using Domain.Generics; using Domain.Generics;

View File

@ -1,4 +1,4 @@
using Core.Dtos; using Domain.Dtos;
using Domain.Constants; using Domain.Constants;
using Domain.Entities; using Domain.Entities;
using Domain.Generics; using Domain.Generics;

View File

@ -1,7 +0,0 @@
namespace Documents
{
public class Class1
{
}
}

View File

@ -4,6 +4,25 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<PreserveCompilationContext>true</PreserveCompilationContext>
<PreserveCompilationReferences>true</PreserveCompilationReferences>
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="Templates\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="RazorLight" Version="2.3.1" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
<ProjectReference Include="..\Transversal\Transversal.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,9 @@
using Documents.Models;
namespace Documents.Interfaces
{
public interface IDocumentTemplateService
{
Task<byte[]> GenerateDocumentAsync(DocumentGenerationRequest request);
}
}

View File

@ -0,0 +1,7 @@
namespace Documents.Interfaces
{
public interface ITemplateRenderer
{
Task<string> RenderAsync<TModel>(string templateKey, TModel model);
}
}

View File

@ -0,0 +1,8 @@
namespace Documents.Models
{
public class DocumentGenerationRequest
{
public DocumentType DocumentType { get; set; }
public object Model { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace Documents.Models
{
public enum DocumentType
{
Quote,
Invoice,
Order,
Remito,
Certificate
}
}

View File

@ -0,0 +1,32 @@
using Documents.Interfaces;
using Documents.Models;
using System.Reflection;
using Transversal.Interfaces;
namespace Documents.Services
{
public class DocumentTemplateService : IDocumentTemplateService
{
private readonly ITemplateRenderer _templateRenderer;
private readonly IPdfGeneratorService _pdfGeneratorService;
public DocumentTemplateService(
ITemplateRenderer templateRenderer,
IPdfGeneratorService pdfGeneratorService)
{
_templateRenderer = templateRenderer;
_pdfGeneratorService = pdfGeneratorService;
}
public async Task<byte[]> GenerateDocumentAsync(DocumentGenerationRequest request)
{
// 👉 Renderizar HTML usando RazorLight
string html = await _templateRenderer.RenderAsync("Quotes/Template_v1.cshtml", request.Model);
// 👉 Generar PDF desde el HTML
return await _pdfGeneratorService.GeneratePdfFromHtmlAsync(html);
}
}
}

View File

@ -0,0 +1,23 @@
using RazorLight;
using Documents.Interfaces;
namespace Documents.Services
{
public class RazorLightTemplateRenderer : ITemplateRenderer
{
private readonly RazorLightEngine _engine;
public RazorLightTemplateRenderer()
{
_engine = new RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(RazorLightTemplateRenderer))
.UseMemoryCachingProvider()
.Build();
}
public async Task<string> RenderAsync<TModel>(string templateKey, TModel model)
{
return await _engine.CompileRenderAsync(templateKey, model);
}
}
}

View File

@ -0,0 +1,24 @@
using RazorLight;
using Documents.Interfaces;
namespace Documents.Services
{
public class RazorTemplateEngine : ITemplateRenderer
{
private readonly RazorLightEngine _engine;
public RazorTemplateEngine()
{
var templatesPath = Path.Combine(AppContext.BaseDirectory, "Templates");
_engine = new RazorLightEngineBuilder()
.UseFileSystemProject(templatesPath)
.UseMemoryCachingProvider()
.Build();
}
public async Task<string> RenderAsync<TModel>(string templateKey, TModel model)
{
return await _engine.CompileRenderAsync(templateKey, model);
}
}
}

View File

@ -0,0 +1,137 @@
@model Domain.Dtos.QuoteDto
@{
var culture = System.Globalization.CultureInfo.GetCultureInfo("es-AR");
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Presupuesto N° @Model.Quotenumber</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
color: #333;
}
h1, h2 {
color: #004B8D;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
}
table, th, td {
border: 1px solid #ccc;
}
th {
background-color: #004B8D;
color: white;
padding: 6px;
}
td {
padding: 6px;
}
.section {
margin-bottom: 25px;
}
.header, .footer {
text-align: center;
}
.footer {
font-size: 10px;
margin-top: 50px;
color: #999;
}
</style>
</head>
<body>
<div class="header">
<h1>phronCare - Presupuesto</h1>
<h2>N° @Model.Quotenumber</h2>
<p>Fecha de Emisión: @Model.IssueDate.ToString("dd/MM/yyyy")</p>
</div>
<div class="section">
<h2>Datos del Cliente</h2>
<p><strong>Razón Social:</strong> @Model.CustomerName</p>
<p><strong>Paciente:</strong> @Model.PatientName</p>
<p><strong>Médico:</strong> @Model.ProfessionalName</p>
<p><strong>Institución:</strong> @Model.InstitutionName</p>
</div>
<div class="section">
<h2>Productos Cotizados</h2>
<table>
<thead>
<tr>
<th>Cantidad</th>
<th>Descripción</th>
<th>Precio Unitario (@Model.Currency)</th>
<th>Total (@Model.Currency)</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<tr>
<td>@item.Quantity</td>
<td>@item.Description</td>
<td>@item.UnitPrice.ToString("C", culture)</td>
<td>@item.Total.ToString("C", culture)</td>
</tr>
}
</tbody>
</table>
</div>
<div class="section">
<h2>Totales</h2>
<table>
<tbody>
<tr>
<td><strong>Subtotal</strong></td>
<td>@Model.Items.Sum(i => i.Subtotal).ToString("C", culture)</td>
</tr>
@if (Model.Taxes != null && Model.Taxes.Any())
{
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 != null && Model.Adjustments.Any())
{
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="footer">
<p>Sistema de gestión y administración PhronCare © 2025</p>
</div>
</body>
</html>

View File

@ -1,4 +1,4 @@
namespace Core.Dtos namespace Domain.Dtos
{ {
public class QuoteAdjustmentDto public class QuoteAdjustmentDto
{ {

View File

@ -1,6 +1,4 @@
using Domain.Dtos; namespace Domain.Dtos
namespace Core.Dtos
{ {
public class QuoteDto public class QuoteDto
{ {
@ -68,6 +66,10 @@ namespace Core.Dtos
/// Nombre del vendedor o ejecutivo de ventas. /// Nombre del vendedor o ejecutivo de ventas.
/// </summary> /// </summary>
public string SalespersonName { get; set; } = ""; public string SalespersonName { get; set; } = "";
/// <summary>
/// Nombre del vendedor o ejecutivo de ventas.
/// </summary>
public string Observations { get; set; } = "";
/// <summary> /// <summary>
/// Detalle de los ítems o productos cotizados. /// Detalle de los ítems o productos cotizados.

View File

@ -1,4 +1,4 @@
namespace Core.Dtos namespace Domain.Dtos
{ {
public class QuoteItemDto public class QuoteItemDto
{ {

View File

@ -1,4 +1,4 @@
namespace Core.Dtos namespace Domain.Dtos
{ {
public class QuoteTaxDto public class QuoteTaxDto
{ {

View File

@ -1,11 +1,6 @@
using Core.Dtos; using Domain.Dtos;
using Domain.Entities; using Domain.Entities;
using Domain.Generics; using Domain.Generics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Interfaces namespace Models.Interfaces
{ {

View File

@ -1,10 +1,10 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Core.Dtos;
using Domain.Entities; using Domain.Entities;
using Domain.Generics; using Domain.Generics;
using Models.Interfaces; using Models.Interfaces;
using Models.Helpers; using Models.Helpers;
using Models.Models; using Models.Models;
using Domain.Dtos;
namespace Models.Repositories namespace Models.Repositories
{ {
@ -162,6 +162,7 @@ namespace Models.Repositories
Currency = header.Currency, Currency = header.Currency,
Total = header.Total.GetValueOrDefault(0m), Total = header.Total.GetValueOrDefault(0m),
Status = header.Status.Trim(), Status = header.Status.Trim(),
Observations=header.Observations,
SalespersonName = _context.PhSPeople SalespersonName = _context.PhSPeople
.Where(u => u.Id == header.PeopleId) .Where(u => u.Id == header.PeopleId)
.Select(u => u.Name) .Select(u => u.Name)

View File

@ -1,24 +1,38 @@
using Transversal.Interfaces; using System.Runtime.InteropServices;
using Transversal.Models;
using PuppeteerSharp;
using PuppeteerSharp.Media; using PuppeteerSharp.Media;
using PuppeteerSharp;
using Transversal.Interfaces;
using Transversal.Models;
namespace Transversal.Services namespace Transversal.Services
{ {
public class PuppeteerPdfGeneratorService : IPdfGeneratorService, IAsyncDisposable public class PuppeteerPdfGeneratorService : IPdfGeneratorService, IAsyncDisposable
{ {
private readonly Browser _browser; private readonly Browser _browser;
public PuppeteerPdfGeneratorService() public PuppeteerPdfGeneratorService()
{ {
// NO USAR BrowserFetcher NUNCA en entorno productivo Docker string? executablePath = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/usr/bin/chromium" // Docker/Linux
: null; // Windows local → que use Chrome instalado
_browser = Puppeteer.LaunchAsync(new LaunchOptions _browser = Puppeteer.LaunchAsync(new LaunchOptions
{ {
Headless = true, Headless = true,
ExecutablePath = "/usr/bin/chromium", // ruta de chromium en la imagen docker ExecutablePath = executablePath,
Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" } Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" }
}).GetAwaiter().GetResult(); }).GetAwaiter().GetResult();
} }
//public PuppeteerPdfGeneratorService()
//{
// // NO USAR BrowserFetcher NUNCA en entorno productivo Docker
// _browser = Puppeteer.LaunchAsync(new LaunchOptions
// {
// Headless = true,
// ExecutablePath = "/usr/bin/chromium", // ruta de chromium en la imagen docker
// Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" }
// }).GetAwaiter().GetResult();
//}
public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent, PdfGenerationOptions options = null) public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent, PdfGenerationOptions options = null)
{ {
options ??= new PdfGenerationOptions(); options ??= new PdfGenerationOptions();
@ -46,6 +60,5 @@ namespace Transversal.Services
if (_browser != null) if (_browser != null)
await _browser.CloseAsync(); await _browser.CloseAsync();
} }
} }
} }

View File

@ -0,0 +1,72 @@
using Microsoft.AspNetCore.Mvc;
using Documents.Interfaces;
using Documents.Models;
using Domain.Dtos;
namespace phronCare.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class DocumentTestController : ControllerBase
{
private readonly IDocumentTemplateService _documentTemplateService;
public DocumentTestController(IDocumentTemplateService documentTemplateService)
{
_documentTemplateService = documentTemplateService;
}
[HttpGet("test-quote")]
public async Task<IActionResult> TestQuote()
{
// 👉 Creamos un QuoteDto de prueba
var quote = new QuoteDto
{
Quotenumber = "Q-00000999",
IssueDate = DateTime.Now,
CustomerName = "LEANDRO HERNAN ROJAS",
PatientName = "Paciente Test",
ProfessionalName = "Dr. Demo",
InstitutionName = "Clínica Test",
Currency = "ARS",
Total = 15000m,
Items = new List<QuoteItemDto>
{
new QuoteItemDto
{
Description = "Producto A",
Quantity = 2,
UnitPrice = 5000m,
Subtotal = 10000m,
TaxAmount = 0m,
Total = 10000m
},
new QuoteItemDto
{
Description = "Producto B",
Quantity = 1,
UnitPrice = 5000m,
Subtotal = 5000m,
TaxAmount = 0m,
Total = 5000m
}
},
Taxes = new List<QuoteTaxDto>(),
Adjustments = new List<QuoteAdjustmentDto>(),
Observations = "Esto es una prueba de emisión de presupuesto."
};
// 👉 Llamamos al motor de impresión
var request = new DocumentGenerationRequest
{
DocumentType = DocumentType.Quote,
Model = quote
};
var pdfBytes = await _documentTemplateService.GenerateDocumentAsync(request);
// 👉 Devolvemos el PDF como file
return File(pdfBytes, "application/pdf", $"Presupuesto_{quote.Quotenumber}.pdf");
}
}
}

View File

@ -1,4 +1,4 @@
using Core.Dtos; using Domain.Dtos;
using Domain.Entities; using Domain.Entities;
using Domain.Generics; using Domain.Generics;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;

View File

@ -17,6 +17,9 @@ using Models.Repositories;
using Models.Models; using Models.Models;
using Transversal.Interfaces; using Transversal.Interfaces;
using Transversal.Services; using Transversal.Services;
using Microsoft.AspNetCore.Components.Web;
using Documents.Interfaces;
using Documents.Services;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -177,8 +180,15 @@ app.Run();
static void RepositorysAndServices(WebApplicationBuilder builder) static void RepositorysAndServices(WebApplicationBuilder builder)
{ {
// Registro servicio PDF transversal // Registro servicio PDF transversal
builder.Services.AddScoped<HtmlRenderer>();
// RazorLight + PDF rendering
builder.Services.AddScoped<ITemplateRenderer, RazorTemplateEngine>();
builder.Services.AddScoped<IPdfGeneratorService, PuppeteerPdfGeneratorService>(); builder.Services.AddScoped<IPdfGeneratorService, PuppeteerPdfGeneratorService>();
// DocumentTemplateService (si lo usás para orquestar)
builder.Services.AddScoped<IDocumentTemplateService, DocumentTemplateService>();
builder.Services.AddScoped<ITicketDom, TicketService>(); builder.Services.AddScoped<ITicketDom, TicketService>();
builder.Services.AddScoped<ITicketRepository, TicketRepository>(); builder.Services.AddScoped<ITicketRepository, TicketRepository>();

View File

@ -545,6 +545,16 @@
], ],
"ReturnTypes": [] "ReturnTypes": []
}, },
{
"ContainingType": "phronCare.API.Controllers.DocumentTestController",
"Method": "TestQuote",
"RelativePath": "api/DocumentTest/test-quote",
"HttpMethod": "GET",
"IsController": true,
"Order": 0,
"Parameters": [],
"ReturnTypes": []
},
{ {
"ContainingType": "phronCare.API.Controllers.Sales.DocumentTypeController", "ContainingType": "phronCare.API.Controllers.Sales.DocumentTypeController",
"Method": "GetAll", "Method": "GetAll",
@ -1673,7 +1683,7 @@
], ],
"ReturnTypes": [ "ReturnTypes": [
{ {
"Type": "Domain.Generics.PagedResult\u00601[[Core.Dtos.QuoteDto, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]", "Type": "Domain.Generics.PagedResult\u00601[[Domain.Dtos.QuoteDto, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]",
"MediaTypes": [ "MediaTypes": [
"text/plain", "text/plain",
"application/json", "application/json",

View File

@ -79,6 +79,92 @@
} }
} }
}, },
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Documents\\Documents.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Documents\\Documents.csproj",
"projectName": "Documents",
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Documents\\Documents.csproj",
"packagesPath": "C:\\Users\\maski\\.nuget\\packages\\",
"outputPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Documents\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\maski\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net8.0"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"projectReferences": {
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj"
},
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Transversal\\Transversal.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Transversal\\Transversal.csproj"
}
}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"dependencies": {
"Microsoft.Extensions.Caching.Memory": {
"target": "Package",
"version": "[8.0.1, )"
},
"RazorLight": {
"target": "Package",
"version": "[2.3.1, )"
},
"System.Text.Json": {
"target": "Package",
"version": "[8.0.5, )"
}
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201/PortableRuntimeIdentifierGraph.json"
}
}
},
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj": { "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj": {
"version": "1.0.0", "version": "1.0.0",
"restore": { "restore": {
@ -256,6 +342,9 @@
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Core\\Core.csproj": { "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Core\\Core.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Core\\Core.csproj" "projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Core\\Core.csproj"
}, },
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Documents\\Documents.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Documents\\Documents.csproj"
},
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj": { "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj" "projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Domain\\Domain.csproj"
}, },
@ -264,6 +353,9 @@
}, },
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Services\\Services.csproj": { "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Services\\Services.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Services\\Services.csproj" "projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Services\\Services.csproj"
},
"C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Transversal\\Transversal.csproj": {
"projectPath": "C:\\Users\\maski\\source\\repos\\SaludLAB\\phronCare\\Transversal\\Transversal.csproj"
} }
} }
} }
@ -334,10 +426,18 @@
"target": "Package", "target": "Package",
"version": "[1.21.0, )" "version": "[1.21.0, )"
}, },
"Newtonsoft.Json": {
"target": "Package",
"version": "[13.0.3, )"
},
"Serilog.AspNetCore": { "Serilog.AspNetCore": {
"target": "Package", "target": "Package",
"version": "[8.0.3, )" "version": "[8.0.3, )"
}, },
"SharpZipLib": {
"target": "Package",
"version": "[1.4.2, )"
},
"Swashbuckle.AspNetCore": { "Swashbuckle.AspNetCore": {
"target": "Package", "target": "Package",
"version": "[6.6.2, )" "version": "[6.6.2, )"
@ -346,6 +446,10 @@
"target": "Package", "target": "Package",
"version": "[8.9.0, )" "version": "[8.9.0, )"
}, },
"System.Net.Http": {
"target": "Package",
"version": "[4.3.4, )"
},
"System.Text.Json": { "System.Text.Json": {
"target": "Package", "target": "Package",
"version": "[8.0.5, )" "version": "[8.0.5, )"

View File

@ -22,7 +22,6 @@
<Import Project="$(NuGetPackageRoot)entityframework\6.5.1\buildTransitive\net6.0\EntityFramework.props" Condition="Exists('$(NuGetPackageRoot)entityframework\6.5.1\buildTransitive\net6.0\EntityFramework.props')" /> <Import Project="$(NuGetPackageRoot)entityframework\6.5.1\buildTransitive\net6.0\EntityFramework.props" Condition="Exists('$(NuGetPackageRoot)entityframework\6.5.1\buildTransitive\net6.0\EntityFramework.props')" />
</ImportGroup> </ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> <PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<PkgNewtonsoft_Json Condition=" '$(PkgNewtonsoft_Json)' == '' ">C:\Users\maski\.nuget\packages\newtonsoft.json\10.0.3</PkgNewtonsoft_Json>
<PkgMicrosoft_Extensions_ApiDescription_Server Condition=" '$(PkgMicrosoft_Extensions_ApiDescription_Server)' == '' ">C:\Users\maski\.nuget\packages\microsoft.extensions.apidescription.server\6.0.5</PkgMicrosoft_Extensions_ApiDescription_Server> <PkgMicrosoft_Extensions_ApiDescription_Server Condition=" '$(PkgMicrosoft_Extensions_ApiDescription_Server)' == '' ">C:\Users\maski\.nuget\packages\microsoft.extensions.apidescription.server\6.0.5</PkgMicrosoft_Extensions_ApiDescription_Server>
<PkgMicrosoft_CodeAnalysis_Analyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_Analyzers)' == '' ">C:\Users\maski\.nuget\packages\microsoft.codeanalysis.analyzers\3.3.3</PkgMicrosoft_CodeAnalysis_Analyzers> <PkgMicrosoft_CodeAnalysis_Analyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_Analyzers)' == '' ">C:\Users\maski\.nuget\packages\microsoft.codeanalysis.analyzers\3.3.3</PkgMicrosoft_CodeAnalysis_Analyzers>
<PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets Condition=" '$(PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets)' == '' ">C:\Users\maski\.nuget\packages\microsoft.visualstudio.azure.containers.tools.targets\1.21.0</PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets> <PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets Condition=" '$(PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets)' == '' ">C:\Users\maski\.nuget\packages\microsoft.visualstudio.azure.containers.tools.targets\1.21.0</PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets>

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>26c44b09-62da-4394-8f6c-1536957fe62e</UserSecretsId> <UserSecretsId>26c44b09-62da-4394-8f6c-1536957fe62e</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -32,17 +33,22 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.9.0" /> <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.9.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.9.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.9.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.Json" Version="8.0.5" /> <PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" /> <ProjectReference Include="..\Core\Core.csproj" />
<ProjectReference Include="..\Documents\Documents.csproj" />
<ProjectReference Include="..\Domain\Domain.csproj" /> <ProjectReference Include="..\Domain\Domain.csproj" />
<ProjectReference Include="..\Models\Models.csproj" /> <ProjectReference Include="..\Models\Models.csproj" />
<ProjectReference Include="..\Services\Services.csproj" /> <ProjectReference Include="..\Services\Services.csproj" />
<ProjectReference Include="..\Transversal\Transversal.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="appsettings.json"> <None Include="appsettings.json">

View File

@ -1,6 +1,6 @@
@page "/quotes" @page "/quotes"
@using Core.Dtos @using Domain.Dtos
@using Domain.Generics @using Domain.Generics
@using phronCare.UIBlazor.Services.Sales.Quotes @using phronCare.UIBlazor.Services.Sales.Quotes
@inject NavigationManager Navigation @inject NavigationManager Navigation

View File

@ -1,4 +1,4 @@
using Core.Dtos; using Domain.Dtos;
using Domain.Entities; using Domain.Entities;
using Domain.Generics; using Domain.Generics;
using System.Net.Http.Json; using System.Net.Http.Json;

View File

@ -41,7 +41,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services", "Services\Servic
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.5 Documents", "1.5 Documents", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.5 Documents", "1.5 Documents", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Documents", "Documents\Documents.csproj", "{85E827F9-36AF-4E3D-83E5-5B5644AB044B}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Documents", "Documents\Documents.csproj", "{0EFF27D3-C585-49F3-BBB5-A5E99C52207B}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -81,10 +81,10 @@ Global
{34FC5538-4779-41F5-8355-7866B1395A4F}.Debug|Any CPU.Build.0 = Debug|Any CPU {34FC5538-4779-41F5-8355-7866B1395A4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34FC5538-4779-41F5-8355-7866B1395A4F}.Release|Any CPU.ActiveCfg = Release|Any CPU {34FC5538-4779-41F5-8355-7866B1395A4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34FC5538-4779-41F5-8355-7866B1395A4F}.Release|Any CPU.Build.0 = Release|Any CPU {34FC5538-4779-41F5-8355-7866B1395A4F}.Release|Any CPU.Build.0 = Release|Any CPU
{85E827F9-36AF-4E3D-83E5-5B5644AB044B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0EFF27D3-C585-49F3-BBB5-A5E99C52207B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85E827F9-36AF-4E3D-83E5-5B5644AB044B}.Debug|Any CPU.Build.0 = Debug|Any CPU {0EFF27D3-C585-49F3-BBB5-A5E99C52207B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85E827F9-36AF-4E3D-83E5-5B5644AB044B}.Release|Any CPU.ActiveCfg = Release|Any CPU {0EFF27D3-C585-49F3-BBB5-A5E99C52207B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85E827F9-36AF-4E3D-83E5-5B5644AB044B}.Release|Any CPU.Build.0 = Release|Any CPU {0EFF27D3-C585-49F3-BBB5-A5E99C52207B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -103,7 +103,7 @@ Global
{13328F60-28A6-446D-9935-23866F3F3D9D} = {74280C0B-F2CC-4A3E-86D6-05530F9766D5} {13328F60-28A6-446D-9935-23866F3F3D9D} = {74280C0B-F2CC-4A3E-86D6-05530F9766D5}
{34FC5538-4779-41F5-8355-7866B1395A4F} = {13328F60-28A6-446D-9935-23866F3F3D9D} {34FC5538-4779-41F5-8355-7866B1395A4F} = {13328F60-28A6-446D-9935-23866F3F3D9D}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {74280C0B-F2CC-4A3E-86D6-05530F9766D5} {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {74280C0B-F2CC-4A3E-86D6-05530F9766D5}
{85E827F9-36AF-4E3D-83E5-5B5644AB044B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {0EFF27D3-C585-49F3-BBB5-A5E99C52207B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {92DE3FEB-7D7E-4C78-BE8C-34931CA1DAED} SolutionGuid = {92DE3FEB-7D7E-4C78-BE8C-34931CA1DAED}