TERMINADO LA PARTE DE IMPRESIÓN

This commit is contained in:
2025-08-21 14:48:41 +02:00
parent d906dee081
commit 43a042e173
5 changed files with 425 additions and 36 deletions

View File

@@ -84,6 +84,7 @@
</div>
</div>
@* TRABAJAO PROFESIONAL *@
<div class="col-12 mx-auto mb-5">
<div class="mb-4 col-8 mx-auto justify-content-center d-flex">
@@ -132,6 +133,8 @@
<div style="height: 49px; margin-top:50px;">
<b>Documentación Opcional:</b>
</div>
@if (objetoURBAN.TrabajoProfesional.DocumentacionOpcional.Count != 0)
{
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
@@ -150,7 +153,12 @@
}
</tbody>
</table>
</div>
</div>
}
else
{
<label>Sin documentación</label>
}
</div>
@* TABLA DE DATOS NECESARIOS *@
<div class="col-11 mx-auto">
@@ -281,7 +289,7 @@
</div>
<div class="col-9 mb-5 ">
<div style="height: 24px;">
<div style="height: 49px;">
<b>Trabajo profesional</b>
</div>
<table class="table tablaCACOA tablaCACOA2 mb-0">
@@ -321,7 +329,7 @@
<label style="color: #078b98 !important"><b>Coste de producción</b></label>
</div>
<div class="col-8 mx-auto">
<div style="height: 24px;">
<div style="height: 49px;">
<b>Costes Asociados a los Servicios de Arquitectura</b>
</div>
<table class="table tablaCACOA tablaCACOA2 mb-0">
@@ -358,13 +366,11 @@
</div>
</div>
</div>
@code {
[Parameter]
public URBAN objetoURBAN { get; set; } = new URBAN();
@@ -378,5 +384,4 @@
{
this.StateHasChanged();
}
}

View File

@@ -125,7 +125,7 @@
<tbody>
<tr>
<td>Plazo de presentación de la documentación</td>
<td class="text-end">@objetoLicitaciones.PlazoPresentacionDocumentos</td>
<td class="text-end">@objetoLicitaciones.PlazoPresentacionDocumentos meses</td>
</tr>
<tr>

View File

@@ -0,0 +1,317 @@
@using System.Globalization
<div id="LiciURBANImprimir" class="d-flex flex-column align-items-center">
@* TRABAJAO PROFESIONAL *@
<div class="col-12 mx-auto mb-5">
<div class="mb-4 col-8 mx-auto justify-content-center d-flex">
<label style="color: #078b98 !important"><b>Trabajo Profesional</b></label>
</div>
<div class="col-12 d-flex justify-content-center" style="gap:20px;">
<div class="formatoCampos pt-2">
<label class="tituloLbl">Tipo de Documento:</label>
<label>@CultureInfo.CurrentCulture.TextInfo.ToTitleCase(@objetoLicitacionUrban.Enumerados.TiposDeDocumentos.First(x => x.idEnumeracion == objetoLicitacionUrban.TrabajoProfesional.idTipoDocumentacion).Descripcion.ToLower())</label>
</div>
<div class="formatoCampos pt-2">
<label class="tituloLbl">Documento:</label>
@if (objetoLicitacionUrban.TrabajoProfesional.idTipoDocumentacion != 0)
{
<label>@objetoLicitacionUrban.Enumerados.ProyectosPorTipo(objetoLicitacionUrban.TrabajoProfesional.idTipoDocumentacion).First(x => x.idtipoproyectos == objetoLicitacionUrban.TrabajoProfesional.idTipoProyecto).Descripcion</label>
}
</div>
</div>
@* TABLAS DE DATOS MINIMOS Y OPCIONALES *@
<div class="col-11 mx-auto">
@* TABLA DE DATOS MINIMOS *@
<div style="height: 49px; margin-top:50px;">
<b>Documentación Mínima:</b>
</div>
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Descripción</th>
</tr>
</thead>
<tbody>
@foreach (var item in objetoLicitacionUrban.TrabajoProfesional.DocumentacionMinima)
{
<tr>
<td class="colorB w4">@item.Descripcion</td>
</tr>
}
</tbody>
</table>
</div>
@* TABLA DE DATOS OPCIONALES *@
<div style="height: 49px; margin-top:50px;">
<b>Documentación Opcional:</b>
</div>
@if (objetoLicitacionUrban.TrabajoProfesional.DocumentacionOpcional.Count != 0)
{
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Descripción</th>
<th class="colorB fw-bold">Añadida</th>
</tr>
</thead>
<tbody>
@foreach (var item in objetoLicitacionUrban.TrabajoProfesional.DocumentacionOpcional)
{
<tr>
<td class="colorB w4">@item.Descripcion</td>
<td class="colorB w4 text-end">@item.Checkeada</td>
</tr>
}
</tbody>
</table>
</div>
}
else
{
<label>Sin documentación</label>
}
</div>
@* TABLA DE DATOS NECESARIOS *@
<div class="col-12 d-flex justify-content-center" style="gap:20px;">
<div class="col-6">
<div class="col-11 mx-auto">
<div style="height: 49px; margin-top:50px;">
<b>Datos Necesarios:</b>
</div>
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Descripción</th>
<th class="colorB fw-bold">Valor</th>
</tr>
</thead>
<tbody>
@foreach (var item in objetoLicitacionUrban.TrabajoProfesional.DatosNecesarios)
{
<tr>
<td class="colorB w4">@item.Descripcion</td>
<td class="colorB w4 text-end">@item.ValorNecesario</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<div class="col-6">
<div class="col-11 mx-auto">
<div style="height: 49px; margin-top:50px;">
<b>Fases:</b>
</div>
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Fases</th>
<th class="colorB fw-bold"></th>
</tr>
</thead>
<tbody>
@foreach (var item in objetoLicitacionUrban.TrabajoProfesional.FasesTrabajoProfesional)
{
<tr>
<td class="colorB w4">@item.Denominacion</td>
<td class="colorB w4">@item.Porcentaje %</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="2" class="text-end fw-bold colorC TotalesTabla">
<div class="d-flex justify-content-end">
<div style="align-self: center;">
@if (objetoLicitacionUrban.TrabajoProfesional.FasesTrabajoProfesional.Sum(x => x.Porcentaje) != 100)
{
<div>
Trabajo en misión parcial: <span> @objetoLicitacionUrban.TrabajoProfesional.FasesTrabajoProfesional.Sum(x => x.Porcentaje) %</span>
</div>
}
else
{
<div>
Total: <span> @objetoLicitacionUrban.TrabajoProfesional.FasesTrabajoProfesional.Sum(x => x.Porcentaje) %</span>
</div>
}
</div>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
@* INNOVACION INSTRUMENTOS *@
<div class="col-11 mx-auto mb-5">
<div>
<div class="mt-3 mb-3"><b>Innovacion de los instrumentos</b></div>
<p class="col-6">
<label>@objetoLicitacionUrban.TrabajoProfesional.valorInstrumentos %</label>
</p>
@foreach (var enu in objetoLicitacionUrban.Enumerados.ListaInstrumentos)
{
<div class="form-check" style="gap:10px;">
@if (enu.Seleccionado)
{
<span>poner circlo relleno</span>
}
else
{
<span>poner circlo vacio</span>
}
<label class="form-check-label" for="@enu.idEnumeracion">@enu.Descripcion</label>
</div>
}
</div>
</div>
</div>
@* Costes de producción *@
<div class="col-12 mx-auto mb-5">
<div class="mb-4 col-8 mx-auto justify-content-center d-flex">
<label style="color: #078b98 !important"><b>Costes de producción</b></label>
</div>
@* Solvencia tecnica *@
<div class="col-11 mx-auto">
<div style="height: 49px; margin-top:50px;">
<b>Solvencia técnica:</b>
</div>
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Trabajadores</th>
<th class="colorB fw-bold">Nº Trabajadores</th>
<th class="colorB fw-bold">Categoría Profesional</th>
</tr>
</thead>
<tbody>
@foreach (var otroTrabajo in objetoLicitacionUrban.ListaSolvenciaTecnica)
{
<tr>
<td>@otroTrabajo.Descripcion</td>
<td class="text-end">@otroTrabajo.Cantidad</td>
<td >@otroTrabajo.TipoConvenio</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="2" class="text-end fw-bold colorC TotalesTabla">
<div class="align-items-center">
<div style="align-self: center;">
Total trabajadores:
<span> @objetoLicitacionUrban.ListaSolvenciaTecnica.Sum(x => x.Cantidad)</span>
</div>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
@* costes asociados *@
<div class="col-11 mx-auto">
<div style="height: 49px; margin-top:50px;">
<b>Costes Asociados a los Servicios de Arquitectura:</b>
</div>
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Concepto</th>
<th class="colorB fw-bold text-end"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="colorFilasIntro w4">Plazo de presentación de la documentación:</td>
<td class="text-end columna40Ancho">
<div class="text-end" style="gap:3px;">
<label>@objetoLicitacionUrban.PlazoPresentacionDocumentos</label> meses
</div>
</td>
</tr>
<tr>
<td class="colorB w4">Coste hora de producción</td>
<td class="text-end columna40Ancho"><span> @objetoLicitacionUrban.CosteHP.MilesYDecimales() €/hora</span></td>
</tr>
<tr>
<td style="width:50%;">Horas Trabajo Profesional </td>
<td class="tdAlineadoDerecha">
<span>
@objetoLicitacionUrban.TrabajoProfesional.horasTrabProfesional.MilesYDecimales() h
</span>
</td>
</tr>
<tr>
<td class="colorB w4">Coste de producción del Trabajo Profesional</td>
<td class="text-end columna40Ancho"><span> @objetoLicitacionUrban.CostesProduccionTrabProf.MilesYDecimales() €</span></td>
</tr>
<tr>
<td class="colorB fw-bold w4">
G.G. + B.I. <br />
<span class="fw-normal" style="font-size:10px;">(40/19 Junta Consultiva de Contratación Pública del Estado)</span>
</td>
<td class="text-end columna40Ancho" style="align-content:center;">
<div class="d-flex" style="justify-content: end; gap:3px;">
@objetoLicitacionUrban.Beneficio %
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" class="TotalesTabla text-end fw-bold">
Precio del trabajo profesional: <span>@objetoLicitacionUrban.PrecioDelTrabajo.MilesYDecimales() €</span>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
@code {
[Parameter]
public bdHerramientaCACOA.LicitacionesURBAN objetoLicitacionUrban { get; set; } = new bdHerramientaCACOA.LicitacionesURBAN();
public tsHerramientasCACOA bd;
protected override async Task OnInitializedAsync()
{
bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false);
}
public void RefreshState()
{
this.StateHasChanged();
}
}

View File

@@ -105,7 +105,6 @@
<CascadingValue Value="this" IsFixed="false">
@* <InstrumentosLicitacionesUrban objetoLicitacionUrban="objetoLicitacionUrban"></InstrumentosLicitacionesUrban> *@
<InstrumentosLicitacionesUrban @ref="componenteInstrumentos" objetoLicitacionUrban="objetoLicitacionUrban" />
</CascadingValue>
</div>

View File

@@ -1,5 +1,4 @@

@page "/LicitacionesUrban"
@page "/LicitacionesUrban"
@rendermode InteractiveServer
@using HerramientaCASA.Components.Pages.LicitacionUrban
@using HerramientaCASA.Model
@@ -8,6 +7,9 @@
@using bdHerramientaCACOA.HerramientaURBAN
@using bdHerramientaCACOA.db
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@using PuppeteerSharp
@inject IJSRuntime JS
@inject ProtectedLocalStorage ProtectedLocalStore
@inject NavigationManager Navigation
@@ -48,7 +50,7 @@
<button @onclick="@(() => abrirPopupGuardar())" class="btnBlue d-flex align-items-center"> <i class="fas fa-save pe-2"></i>@TituloBoton</button>
<b class="Fuente2 ps-2 pe-2 nomSim">Nombre de la simulación: </b>
<InputText @bind-Value="objetoLicitacionUrban.NombreSimulacion" class="form-control inputForm formatoMoneda inputTabla " style="text-align:left;font-weight:bold;"></InputText>
<button class="btnBlue d-flex align-items-center ms-1" style="background-color: #65b7c3 !important;"> <i class="fas fa-print pe-2"></i>Imprimir</button>
<button @onclick="imprimir" class="btnBlue d-flex align-items-center ms-1" style="background-color: #65b7c3 !important;"> <i class="fas fa-print pe-2"></i>Imprimir</button>
<button class="btnBlue d-flex align-items-center ms-1" style="background-color: #65b7c3 !important;"> <i class="fas fa-book pe-2"></i>Manual</button>
</div>
<div class="row">
@@ -74,11 +76,11 @@
{
<div class="row">
<div class="col-md-12 mt-3 mb-3">
<CascadingValue Value="this">
<DocumentosLicitacion objetoLicitacionUrban="objetoLicitacionUrban"></DocumentosLicitacion>
</CascadingValue>
<CascadingValue Value="this">
<DocumentosLicitacion objetoLicitacionUrban="objetoLicitacionUrban"></DocumentosLicitacion>
</CascadingValue>
</div>
</div>
</div>
}
<div class="row">
<div class="col-md-3">
@@ -125,7 +127,7 @@
<td class="text-end columna40Ancho"><span> @objetoLicitacionUrban.CosteHP.MilesYDecimales() €/hora</span></td>
</tr>
<tr>
<td style="width:50%;">Horas Trabajo Profesional </td>
<td style="width:50%;">Horas Trabajo Profesional </td>
<td class="tdAlineadoDerecha">
@if (objetoLicitacionUrban.EsPorUsos)
{
@@ -160,7 +162,7 @@
</tbody>
<tfoot>
<tr>
<td colspan="2" class="TotalesTabla text-end fw-bold" >
<td colspan="2" class="TotalesTabla text-end fw-bold">
Precio del trabajo profesional: <span>@objetoLicitacionUrban.PrecioDelTrabajo.MilesYDecimales() €</span>
</td>
</tr>
@@ -216,6 +218,9 @@
</div>
</div>
<div style="display:none">
<HerramientaCASA.Components.Pages.Imprimir.LicitacionesURBANImprimir objetoLicitacionUrban="objetoLicitacionUrban"></HerramientaCASA.Components.Pages.Imprimir.LicitacionesURBANImprimir>
</div>
@code {
[Parameter]
@@ -224,6 +229,7 @@
public string TituloBoton = "Guardar";
private Modal popupGuardar = default!;
public bool actualizado = true;
private string pdfUrl;
public tsHerramientasCACOA bd;
private bdHerramientaCACOA.LicitacionesURBAN objetoLicitacionUrban;
@@ -249,7 +255,7 @@
idSimulador = clValue;
}
if (string.IsNullOrEmpty(idSimulador))
{
@@ -317,10 +323,10 @@
if (bd.simulaciones.Any(x => x.Descripcion == objetoLicitacionUrban.NombreSimulacion && x.idTipoSimulacion == idtipoSimulacion))
{
mensajes.Add(new ToastMessage
{
Type = ToastType.Danger,
Message = $"Ya existe una simulación con el mismo nombre.",
});
{
Type = ToastType.Danger,
Message = $"Ya existe una simulación con el mismo nombre.",
});
cerrarPopupGuardar();
}
else
@@ -335,15 +341,15 @@
if (listadoSimulacionesExistentes.Any(x => x.Descripcion == objetoLicitacionUrban.NombreSimulacion))
{
mensajes.Add(new ToastMessage
{
Type = ToastType.Danger,
Message = $"Ya existe una simulación con el mismo nombre.",
});
{
Type = ToastType.Danger,
Message = $"Ya existe una simulación con el mismo nombre.",
});
cerrarPopupGuardar();
}
else
{
actualizarSimulacion(jsonObjeto);
actualizarSimulacion(jsonObjeto);
}
}
@@ -353,10 +359,10 @@
int idSimulacionCreada = UtilidadesCASA.crearObjeto(bd, HerramientaCASA.UtilidadesCASA.TiposSimulaciones.URBANDSIMP, jsonObjeto, objetoLicitacionUrban.NombreSimulacion, "licitacionesUrban.json", idUser);
string link = "/LicitacionesURBAN?idSimulador=" + tsUtilidades.crypt.FEncS(idSimulacionCreada.ToString(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", 875421649);
mensajes.Add(new ToastMessage
{
Type = ToastType.Primary,
Message = $"Licitación creada correctamente.",
});
{
Type = ToastType.Primary,
Message = $"Licitación creada correctamente.",
});
Navigation.NavigateTo(link, true);
}
@@ -365,10 +371,10 @@
UtilidadesCASA.actualziarObjeto(bd, jsonObjeto, objetoLicitacionUrban.NombreSimulacion, idSimulador);
cerrarPopupGuardar();
mensajes.Add(new ToastMessage
{
Type = ToastType.Primary,
Message = $"Licitación actualizada correctamente.",
});
{
Type = ToastType.Primary,
Message = $"Licitación actualizada correctamente.",
});
}
private void clonarUrban()
@@ -397,7 +403,7 @@
this.StateHasChanged();
}
private async void PlazoPresentacionDocumentosCambiado(double e)
{
objetoLicitacionUrban.PlazoPresentacionDocumentos = e;
@@ -459,5 +465,67 @@
// objetoLicitacionUrban.CalcularHorasSuperficie();
await InvokeAsync(StateHasChanged);
}
private async Task imprimir()
{
var cssPath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "Content", "Site.css");
var cssContent = await File.ReadAllTextAsync(cssPath);
var contenidoHtml = await JS.InvokeAsync<string>("obtenerContenidoHtml");
var fullHtml = $@"
<html>
<head>
<style>{cssContent}</style>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css' rel='stylesheet' integrity='sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN' crossorigin='anonymous'>
</head>
<body>
{contenidoHtml}
</body>
</html>";
var fileName = $"factura_{DateTime.Now:yyyyMMddHHmmss}.pdf";
var filePath = Path.Combine("wwwroot", fileName);
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = new[] { "--ignore-certificate-errors" }
});
using var page = await browser.NewPageAsync();
await page.SetViewportAsync(new ViewPortOptions { Width = 1200, Height = 800 });
await page.SetContentAsync(fullHtml);
await page.PdfAsync(filePath, new PdfOptions
{
PrintBackground = true,
Format = PuppeteerSharp.Media.PaperFormat.A4,
MarginOptions = new PuppeteerSharp.Media.MarginOptions
{
Top = "20mm",
Bottom = "20mm"
}
});
pdfUrl = "/" + fileName;
Navigation.NavigateTo(pdfUrl, true);
}
}
<script>
function obtenerContenidoHtml() {
const DespachoImprimir = document.getElementById('LiciURBANImprimir');
let html = DespachoImprimir.outerHTML + "<br>";
return html;
};
</script>