From 24c6e43f2d670f26eb265ec5e8d5899a0c6d5107 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 5 Mar 2025 20:27:44 -0300 Subject: [PATCH 01/91] =?UTF-8?q?a=C3=B1adido=20cors=20para=20ipv6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Program.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Aspnet/Program.cs b/Aspnet/Program.cs index aa81588..eb7495a 100644 --- a/Aspnet/Program.cs +++ b/Aspnet/Program.cs @@ -35,6 +35,15 @@ builder.Services.AddCors(options => .AllowAnyMethod() .AllowCredentials(); }); + + options.AddPolicy("AllowSvelteAppv6", + builder => + { + builder.WithOrigins("http://[::1]:5173") + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); }); var app = builder.Build(); -- 2.52.0 From 878583664ed516d3825ee9bed8bf20f9a7b51ff2 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 5 Mar 2025 20:28:03 -0300 Subject: [PATCH 02/91] =?UTF-8?q?a=C3=B1adido=20que=20logee=20la=20ip=20y?= =?UTF-8?q?=20los=20logins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/LoginController.cs | 2 +- Modelo/Facade/AuditoriaFacade.cs | 26 ++++++++++++++++++++++++++ Modelo/RepositorioUsuarios.cs | 12 +++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Aspnet/Controllers/LoginController.cs b/Aspnet/Controllers/LoginController.cs index b4efd38..c9cd1ac 100644 --- a/Aspnet/Controllers/LoginController.cs +++ b/Aspnet/Controllers/LoginController.cs @@ -19,7 +19,7 @@ public class LoginController: ControllerBase if (!usuario) return Unauthorized(new {message = "El usuario no existe o la contraseña es incorrecta"}); string tokenString = GenerarToken(loginDto); - RepositorioUsuarios.Singleton.GuardarToken(loginDto, tokenString); + RepositorioUsuarios.Singleton.GuardarToken(loginDto, tokenString, Request.HttpContext.Connection.RemoteIpAddress); var cookieOptions = new CookieOptions { diff --git a/Modelo/Facade/AuditoriaFacade.cs b/Modelo/Facade/AuditoriaFacade.cs index 50187b9..0fcf6a4 100644 --- a/Modelo/Facade/AuditoriaFacade.cs +++ b/Modelo/Facade/AuditoriaFacade.cs @@ -1,3 +1,4 @@ +using System.Net; using Entidades; using Microsoft.EntityFrameworkCore; @@ -28,6 +29,31 @@ public class AuditoriaFacade { _persistenciaDeLog.GuardarLog(log, log.LogDetalles); } + internal void GenerarLogLogin(long dni, string v, IPAddress? remoteIpAddress) { + var fechaActual = DateTime.Now; + + var log = new Log{ + Fecha = fechaActual, + Dniusuario = dni, + Accion = v + }; + + log.LogDetalles = new List([ + new LogDetalle{ + Id = 1, + Dniusuario = dni, + Fecha = fechaActual, + NombreTabla = "Logs", + Columna = "Login", + ValorAnterior = "", + ValorNuevo = $"Se inicio sesión con la direccion ip: {remoteIpAddress.ToString()}", + } + ]); + + _persistenciaDeLog.GuardarLog(log, log.LogDetalles); + + } + private List ProcesarCambios(IEnumerable cambios, DateTime fechaActual, long dniUsuario) { diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index 3dc2d8f..b309a94 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -4,6 +4,8 @@ using Entidades.Dto; using Entidades; using Microsoft.EntityFrameworkCore; using Entidades.Admin; +using System.Net; +using Modelo.Facade; namespace Modelo; @@ -95,14 +97,22 @@ public class RepositorioUsuarios: RepositorioBase { return usu.Token == token; } - public void GuardarToken(LoginDto login, string tokenString) { + public void GuardarToken(LoginDto login, string tokenString, System.Net.IPAddress? remoteIpAddress) { var con = Context; var usu = con.Clientes.FirstOrDefault(x => x.Email == login.Email); if (usu == null) return; usu.Token = tokenString; + GenerarLog(con, usu.Dni, "Login", remoteIpAddress); Guardar(con); } + private void GenerarLog(AlquilaFacilContext con, long dni, string v, IPAddress? remoteIpAddress) + { + var Auditoria = new AuditoriaFacade(con); + Auditoria.GenerarLogLogin(dni, v, remoteIpAddress); + + } + public bool CheckGrupo(string email, string grupo) { var con = Context; var usu = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Email == email); -- 2.52.0 From b3ffa657f53df05dc9d100b32c4d539085e6bc54 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 14 Mar 2025 02:33:59 -0300 Subject: [PATCH 03/91] =?UTF-8?q?a=C3=B1adido=20endpoint=20para=20crear=20?= =?UTF-8?q?permisos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/AccionesController.cs | 48 +++++++++++++++++++----- Entidades/Dto/CrearAccionesDto.cs | 5 +++ Modelo/RepositorioPermisos.cs | 33 +++++++++++----- 3 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 Entidades/Dto/CrearAccionesDto.cs diff --git a/Aspnet/Controllers/AccionesController.cs b/Aspnet/Controllers/AccionesController.cs index 9be95b8..ea3dff9 100644 --- a/Aspnet/Controllers/AccionesController.cs +++ b/Aspnet/Controllers/AccionesController.cs @@ -1,20 +1,20 @@ -using System.ComponentModel.DataAnnotations; using Entidades.Dto; using Microsoft.AspNetCore.Mvc; using Modelo; -using System.Text.Json; +using Entidades; - namespace AlquilaFacil.Controllers; [ApiController] -public class AccionesController: ControllerBase { - +public class AccionesController : ControllerBase +{ + [HttpGet("api/acciones")] - public IActionResult ListarAccionesPorUsuario([FromHeader(Name ="Email")] string Email, [FromHeader(Name = "Auth")] string Auth) { + public IActionResult ListarAccionesPorUsuario([FromHeader(Name = "Email")] string Email, [FromHeader(Name = "Auth")] string Auth) + { if (Email == "" || Email == null) return BadRequest(); - - if (Auth == "") return Unauthorized(new { esValido = false}); + + if (Auth == "") return Unauthorized(new { esValido = false }); bool esValido = RepositorioUsuarios.Singleton.CheckToken(Email, Auth); if (!esValido) return Unauthorized(); @@ -37,4 +37,34 @@ public class AccionesController: ControllerBase { var permisos = RepositorioGrupos.Singleton.ListarPermisosDeGrupo(req.Grupo); return Ok(permisos); } -} \ No newline at end of file + + [HttpPost("api/acciones/crear")] + public IActionResult CrearAcciones([FromHeader(Name = "Auth")] string Auth, + [FromBody] CrearAccionesDto req) + { + if (string.IsNullOrEmpty(Auth)) return BadRequest(); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return Unauthorized(); + + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1); //wip lo voy a usar para crear el permiso que va + if (ret == false) return Unauthorized(); + + if (string.IsNullOrWhiteSpace(req.Descripcion)) + { + return BadRequest(new { message = "La descripción no puede estar vacía" }); + } + + if (req.Descripcion.Length > 25) + { + return BadRequest(new { message = "La descripción no puede ser mayor a 25 caracteres" }); + } + + var per = new Permiso + { + Descripcion = req.Descripcion, + } + var ret2 = RepositorioPermisos.Singleton.CrearPermiso(per); + return ret2 ? Ok(new { message = "se creo correctamente" }) : BadRequest(new { message = "No se pudo crear el permiso" }); + } +} diff --git a/Entidades/Dto/CrearAccionesDto.cs b/Entidades/Dto/CrearAccionesDto.cs new file mode 100644 index 0000000..5e8a23f --- /dev/null +++ b/Entidades/Dto/CrearAccionesDto.cs @@ -0,0 +1,5 @@ +namespace Entidades.Dto; +public class CrearAccionesDto +{ + public string Descripcion { get; set; } = ""; +} diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index a5d4445..f2d457a 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -3,21 +3,26 @@ using Entidades; using Microsoft.EntityFrameworkCore; namespace Modelo; -public class RepositorioPermisos: RepositorioBase { - public object? ListarPermisos(string email) { +public class RepositorioPermisos : RepositorioBase +{ + public object? ListarPermisos(string email) + { var con = Context; Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email); if (cli == null) return null; var list = con.Clientes .Where(c => c.Dni == cli.Dni) - .SelectMany(c => c.Idgrupos) - .Include(x=> x.Idpermisos); - + .SelectMany(c => c.Idgrupos) + .Include(x => x.Idpermisos); + return list; } - public bool CheckPermisos(string token, int idpermiso){ + public bool CheckPermisos(string token, int idpermiso) + { + // Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos + // var con = Context; bool tienePermiso = false; @@ -41,12 +46,22 @@ public class RepositorioPermisos: RepositorioBase { //int.TryParse(match.Groups[1].Value, out int idpermiso); ///////////////////////////////////////////////////////////////// - Parallel.ForEach(permisos, (x, i) =>{ - if (x.Id == idpermiso) { + Parallel.ForEach(permisos, (x, i) => + { + if (x.Id == idpermiso) + { tienePermiso = true; } }); return tienePermiso; } -} \ No newline at end of file + + public bool CrearPermiso(Permiso per) + { + var con = Context; + per.Id = con.Permisos.Any() ? con.Permisos.Max(x => x.Id) + 1 : 1; + con.Permisos.Add(per); + return Guardar(con); + } +} -- 2.52.0 From 25f77f6f487b4bb1413f3dcf6008abd61bde630c Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 14 Mar 2025 02:43:41 -0300 Subject: [PATCH 04/91] primera edicion de un archivo para cambiar grupos a permisos --- Aspnet/Controllers/AdminController.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Aspnet/Controllers/AdminController.cs b/Aspnet/Controllers/AdminController.cs index d41d0e0..f6f05c9 100644 --- a/Aspnet/Controllers/AdminController.cs +++ b/Aspnet/Controllers/AdminController.cs @@ -47,7 +47,7 @@ public class AdminController: ControllerBase [HttpGet("api/contratos/controlPagos/propiedad")] public IActionResult obtenerPropiedad([FromHeader(Name = "Auth")] string Auth, int id = 0) { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14); if (validacion1 == false) return Unauthorized(); if (id <= 0) return BadRequest(new { message = "No hay propiedades con id igual o menor a 0"}); @@ -89,7 +89,7 @@ public class AdminController: ControllerBase [HttpGet("/api/admin/contrato/verDocumento")] public IActionResult verDocumento([FromHeader(Name = "Auth")] string Auth, int idcontrato = 0){ if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14); if (validacion1 == false) return Unauthorized(); if (idcontrato <= 0) return BadRequest(new {message = "La id no puede ser igual o menor a 0"}); @@ -123,7 +123,7 @@ public class AdminController: ControllerBase [HttpGet("api/admin/contrato/canons")] public IActionResult ObtenerCanones([FromHeader(Name="Auth")]string Auth, int id = 0){ if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14); if (validacion1 == false) return Unauthorized(); var cont = RepositorioContratos.Singleton.ObtenerContratoPorId(id); @@ -161,7 +161,7 @@ public class AdminController: ControllerBase [HttpPost("api/admin/contrato/marcarPago")] public IActionResult realizarPago([FromHeader(Name="Auth")]string Auth, MarcarPagoDto dto) { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14); if (validacion1 == false) return Unauthorized(); if (dto.Idcontrato<=0) return BadRequest(new { message = "No puede existir un contrato con id 0 o menor"}); @@ -188,7 +188,7 @@ public class AdminController: ControllerBase [HttpPost("api/admin/notificarInquilino")] public IActionResult NotificarInquilino([FromHeader(Name ="Auth")]string Auth, NotificarAdmin data){ if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14); if (validacion1 == false) return Unauthorized(); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); -- 2.52.0 From 790cc31f9351c7368e15b734d7a563cf66622543 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 31 Mar 2025 19:38:42 -0300 Subject: [PATCH 05/91] refactor porque era ilejible --- .../DtoBuilder/ContratoPropiedadDtoBuilder.cs | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs index ab8a5e5..6665c4d 100644 --- a/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs +++ b/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs @@ -1,74 +1,94 @@ using Entidades.Dto; namespace AlquilaFacil.Builder; -public class ContratoPropiedadDtoBuilder : Builder{ - public ContratoPropiedadDtoBuilder SetId(long id ){ +public class ContratoPropiedadDtoBuilder : Builder +{ + public ContratoPropiedadDtoBuilder SetId(long id) + { data.id = id; return this; } - public ContratoPropiedadDtoBuilder SetUbicacion(string ub){ + public ContratoPropiedadDtoBuilder SetUbicacion(string ub) + { data.Ubicacion = ub; return this; } - public ContratoPropiedadDtoBuilder SetTipo(string tipo){ + public ContratoPropiedadDtoBuilder SetTipo(string tipo) + { data.TipoPropiedad = tipo; return this; } - public ContratoPropiedadDtoBuilder SetFechaInicio(DateTime fec) { + public ContratoPropiedadDtoBuilder SetFechaInicio(DateTime fec) + { data.Fechainicio = fec; return this; } - public ContratoPropiedadDtoBuilder SetInquilino(string inquilino){ + public ContratoPropiedadDtoBuilder SetInquilino(string inquilino) + { data.Inquilino = inquilino; return this; } - public ContratoPropiedadDtoBuilder SetPropietario(string propietario){ + public ContratoPropiedadDtoBuilder SetPropietario(string propietario) + { data.Propietario = propietario; return this; } - public ContratoPropiedadDtoBuilder SetEstado(ulong habilitado, ulong cancelado) { - bool Habilitado = habilitado == 0?false:true; - bool Cancelado = cancelado == 0?false:true; + public ContratoPropiedadDtoBuilder SetEstado(ulong habilitado, ulong cancelado) + { + bool Habilitado = habilitado == 0 ? false : true; + bool Cancelado = cancelado == 0 ? false : true; - if (Habilitado == true && Cancelado == false){ + if (Habilitado == true && Cancelado == false) + { data.Estado = "Alquiler Iniciado"; - } else if (Cancelado == true && Habilitado == false) { + } + else if (Cancelado == true && Habilitado == false) + { data.Estado = "Nunca Empezo Esta Cancelado"; - } else if (Habilitado == false && Cancelado ==false){ + } + else if (Habilitado == false && Cancelado == false) + { data.Estado = "Esta en Proceso"; - } else if (Habilitado == true && Cancelado == true){ + } + else if (Habilitado == true && Cancelado == true) + { data.Estado = "Terminado"; } return this; } - public ContratoPropiedadDtoBuilder SetHabitaciones(int habitaciones){ + public ContratoPropiedadDtoBuilder SetHabitaciones(int habitaciones) + { data.Habitaciones = habitaciones; return this; } - public ContratoPropiedadDtoBuilder SetPiso(int piso){ + public ContratoPropiedadDtoBuilder SetPiso(int piso) + { data.Piso = piso; return this; } - public ContratoPropiedadDtoBuilder SetLetra(string letra){ + public ContratoPropiedadDtoBuilder SetLetra(string letra) + { data.Letra = letra; return this; } - public ContratoPropiedadDtoBuilder SetMesesAumento(int mesesAumento){ + public ContratoPropiedadDtoBuilder SetMesesAumento(int mesesAumento) + { data.MesesAumento = mesesAumento; return this; } - public ContratoPropiedadDtoBuilder SetMesesDuracion(int mesesDurationContrato) { + public ContratoPropiedadDtoBuilder SetMesesDuracion(int mesesDurationContrato) + { data.MesesDuracion = mesesDurationContrato; return this; } -- 2.52.0 From 0036f48d192a4e1364cc2f5696244d2f5795e72f Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 31 Mar 2025 23:27:25 -0300 Subject: [PATCH 06/91] =?UTF-8?q?primeros=20pasos=20en=20a=C3=B1adir=20las?= =?UTF-8?q?=20cosas=20que=20pide=20el=20profe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Builder/PermisoBuilder.cs | 9 ++++++++ Aspnet/Controllers/AccionesController.cs | 8 ++++--- Aspnet/Controllers/GruposController.cs | 14 ++++++++++++ Aspnet/Controllers/PermisoController.cs | 23 ++++++++++++++++++++ Entidades/Dto/GrupoYPermisoDto.cs | 14 ++++++++++++ Front/src/paginas/AdminGrupos.svelte | 6 +++++ Front/src/paginas/AdministrarPermisos.svelte | 1 + Modelo/RepositorioPermisos.cs | 2 +- 8 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 Aspnet/Builder/PermisoBuilder.cs create mode 100644 Aspnet/Controllers/GruposController.cs create mode 100644 Aspnet/Controllers/PermisoController.cs create mode 100644 Entidades/Dto/GrupoYPermisoDto.cs create mode 100644 Front/src/paginas/AdminGrupos.svelte create mode 100644 Front/src/paginas/AdministrarPermisos.svelte diff --git a/Aspnet/Builder/PermisoBuilder.cs b/Aspnet/Builder/PermisoBuilder.cs new file mode 100644 index 0000000..ca30788 --- /dev/null +++ b/Aspnet/Builder/PermisoBuilder.cs @@ -0,0 +1,9 @@ +using Entidades; +public class PermisoBuilder : Builder +{ + public PermisoBuilder SetDescripcion(string desc) + { + data.Descripcion = desc; + return this; + } +} diff --git a/Aspnet/Controllers/AccionesController.cs b/Aspnet/Controllers/AccionesController.cs index ea3dff9..568ccae 100644 --- a/Aspnet/Controllers/AccionesController.cs +++ b/Aspnet/Controllers/AccionesController.cs @@ -24,9 +24,11 @@ public class AccionesController : ControllerBase return Ok(Permisos); } + [HttpPost("api/acciones/grupo")] - public IActionResult ListarAccionesPorGrupo([FromHeader(Name = "Auth")] string Auth, - [FromBody] AccionesPorGrupoDto req) { + public IActionResult ListarAccionesPorGrupo([FromHeader(Name = "Auth")] string Auth, + [FromBody] AccionesPorGrupoDto req) + { if (string.IsNullOrEmpty(Auth)) return BadRequest(); bool esValido = RepositorioUsuarios.Singleton.CheckToken(req.Email, Auth); if (esValido == false) return BadRequest(esValido); @@ -63,7 +65,7 @@ public class AccionesController : ControllerBase var per = new Permiso { Descripcion = req.Descripcion, - } + }; var ret2 = RepositorioPermisos.Singleton.CrearPermiso(per); return ret2 ? Ok(new { message = "se creo correctamente" }) : BadRequest(new { message = "No se pudo crear el permiso" }); } diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs new file mode 100644 index 0000000..3208dea --- /dev/null +++ b/Aspnet/Controllers/GruposController.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; +using Modelo; +namespace AlquilaFacil.Controllers; + +[ApiController] +public class GruposController : ControllerBase +{ + [HttpPost("api/admin/grupos")] + public IActionResult ObtenerGrupos([FromHeader(Name = "Auth")] string Auth) + {//WIP + + + } +} diff --git a/Aspnet/Controllers/PermisoController.cs b/Aspnet/Controllers/PermisoController.cs new file mode 100644 index 0000000..e502aa1 --- /dev/null +++ b/Aspnet/Controllers/PermisoController.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Mvc; +using Modelo; +namespace AlquilaFacil.Controllers; + +[ApiController] +public class PermisoController : ControllerBase +{ + [HttpPost("api/admin/grupos")] + public IActionResult CrearPermiso([FromHeader(Name = "Auth")] string Auth, PermisoDto perm) + { + //WIP + var ret1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 17); + + if (String.IsNullOrWhiteSpace(perm.Descripcion)) return BadRequest(new { message = "No puede tener una descripcion vacia" }); + if (perm.Descripcion.Length > 25) return BadRequest(new { message = "la descripcion no puede tener más de 25 caractéres" }); + + var permiso = new PermisoBuilder().SetDescripcion(perm.Descripcion).Build(); + + var ret = RepositorioPermisos.Singleton.CrearPermiso(permiso); + + return ret ? Ok() : BadRequest(); + } +} diff --git a/Entidades/Dto/GrupoYPermisoDto.cs b/Entidades/Dto/GrupoYPermisoDto.cs new file mode 100644 index 0000000..4017198 --- /dev/null +++ b/Entidades/Dto/GrupoYPermisoDto.cs @@ -0,0 +1,14 @@ +public class GrupoDto +{ + public int idgrupo { get; set; } + public string Nombre { get; set; } = ""; + public HashSet GruposIncluidos { get; set; } = []; + public List Permisos { get; set; } = []; + +} + +public class PermisoDto +{ + public int Id { get; set; } + public string Descripcion { get; set; } = ""; +} diff --git a/Front/src/paginas/AdminGrupos.svelte b/Front/src/paginas/AdminGrupos.svelte new file mode 100644 index 0000000..8a651db --- /dev/null +++ b/Front/src/paginas/AdminGrupos.svelte @@ -0,0 +1,6 @@ + + + +
diff --git a/Front/src/paginas/AdministrarPermisos.svelte b/Front/src/paginas/AdministrarPermisos.svelte new file mode 100644 index 0000000..7c94f5c --- /dev/null +++ b/Front/src/paginas/AdministrarPermisos.svelte @@ -0,0 +1 @@ +//WIP diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index f2d457a..bb0ffa8 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -36,7 +36,7 @@ public class RepositorioPermisos : RepositorioBase .SelectMany(x => x.Idgrupos) .SelectMany(x => x.Idpermisos) .Distinct(); - + ///////////////////////////////////////////////////////////////// //Esto esta comentado porque antes pasaba el string del path de la url, es una mala idea a muchos niveles // abajo un comentario viejo mio -- 2.52.0 From 2ad084cf1975ddbe2f41ab0a4e7b538c45705f14 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 7 Apr 2025 14:27:01 -0300 Subject: [PATCH 07/91] =?UTF-8?q?a=C3=B1adido=20boton=20para=20cerrar=20se?= =?UTF-8?q?sion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Front/public/logout.svg | 21 ++ .../Componentes/NavBarAutocompletable.svelte | 260 ++++++++++-------- 2 files changed, 171 insertions(+), 110 deletions(-) create mode 100644 Front/public/logout.svg diff --git a/Front/public/logout.svg b/Front/public/logout.svg new file mode 100644 index 0000000..3af916e --- /dev/null +++ b/Front/public/logout.svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/Front/src/Componentes/NavBarAutocompletable.svelte b/Front/src/Componentes/NavBarAutocompletable.svelte index 2ef9085..5640120 100644 --- a/Front/src/Componentes/NavBarAutocompletable.svelte +++ b/Front/src/Componentes/NavBarAutocompletable.svelte @@ -1,126 +1,166 @@ - - AlquilaFacil - -
-
- - Volver al Menú - -
- - -
- (isOpen = !isOpen)} /> - - - + + +
+ + + + (isOpen = !isOpen)} /> + + +
-- 2.52.0 From eadeeb2b086c306de11353614d60267846aee0c3 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 7 Apr 2025 14:44:51 -0300 Subject: [PATCH 08/91] potencial codigo duplicado --- Aspnet/Controllers/AccionesController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aspnet/Controllers/AccionesController.cs b/Aspnet/Controllers/AccionesController.cs index 568ccae..6372798 100644 --- a/Aspnet/Controllers/AccionesController.cs +++ b/Aspnet/Controllers/AccionesController.cs @@ -40,7 +40,7 @@ public class AccionesController : ControllerBase return Ok(permisos); } - [HttpPost("api/acciones/crear")] + [HttpPost("api/acciones/crear")] //creo que es codido duplicado public IActionResult CrearAcciones([FromHeader(Name = "Auth")] string Auth, [FromBody] CrearAccionesDto req) { -- 2.52.0 From 483a2b540913c2adf3f7a9fdb3728b177ca2e298 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 7 Apr 2025 14:55:37 -0300 Subject: [PATCH 09/91] fix: ahora no hace autoscroll hacia arriba --- .../src/Componentes/PaginacionStepper.svelte | 90 ++++++++++++------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/Front/src/Componentes/PaginacionStepper.svelte b/Front/src/Componentes/PaginacionStepper.svelte index f2ee2f4..826b173 100644 --- a/Front/src/Componentes/PaginacionStepper.svelte +++ b/Front/src/Componentes/PaginacionStepper.svelte @@ -1,18 +1,18 @@ {#if cantpag > 1} - -{/if} \ No newline at end of file + +{/if} -- 2.52.0 From bb995d15873f0984249f68331f7edcaf0a06661a Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 7 Apr 2025 15:30:10 -0300 Subject: [PATCH 10/91] fix: el checkbox no guardaba estado --- Front/src/paginas/Informes.svelte | 228 ++++++++++++++++++------------ 1 file changed, 141 insertions(+), 87 deletions(-) diff --git a/Front/src/paginas/Informes.svelte b/Front/src/paginas/Informes.svelte index 69dca2f..19e2e89 100644 --- a/Front/src/paginas/Informes.svelte +++ b/Front/src/paginas/Informes.svelte @@ -4,39 +4,52 @@ import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte"; import FChart from "../Componentes/Estadisticas/fChart.svelte"; import ModalEstatico from "../Componentes/ModalEstatico.svelte"; - import {urlG} from "../stores/urlStore"; + import { urlG } from "../stores/urlStore"; import type { ChartData } from "../types"; - let token = sessionStorage.getItem("token")||""; + let token = sessionStorage.getItem("token") || ""; let y = $state(2025); - let cdata:ChartData|any = $state(); - let aldata:{id:number, ubicacion:string, divisa:string}[]= $state([]); + let cdata: ChartData | any = $state(); + let aldata: { id: number; ubicacion: string; divisa: string }[] = $state( + [], + ); - let chartMesesDuracion:ChartData|any = $state(); - let tablaMesesDuracion:{meses:number, repes:number, semaforizacion:string}[] = $state([]); - - let modaldata:string = $state(""); - - onMount(async() => { + let chartMesesDuracion: ChartData | any = $state(); + let tablaMesesDuracion: { + meses: number; + repes: number; + semaforizacion: string; + }[] = $state([]); + + let showModoDaltonico: boolean = $state(false); + let modaldata: string = $state(""); + + onMount(async () => { await dataAlquileresporAño(); }); async function dataAlquileresporAño(year = 2025) { - try{ - const rep = fetch($urlG+"/api/stats/alquileresIniciados?year="+year, { - method : "GET", - headers: { - "Auth": token, - } - }); - const pre = fetch($urlG+"/api/tabla/alquileresIniciados?year="+year, { - method : "GET", - headers: { - "Auth": token, - } - }); - let [r,p] = await Promise.all([rep, pre]); + try { + const rep = fetch( + $urlG + "/api/stats/alquileresIniciados?year=" + year, + { + method: "GET", + headers: { + Auth: token, + }, + }, + ); + const pre = fetch( + $urlG + "/api/tabla/alquileresIniciados?year=" + year, + { + method: "GET", + headers: { + Auth: token, + }, + }, + ); + let [r, p] = await Promise.all([rep, pre]); let data = await r.json(); let data2 = await p.json(); @@ -44,76 +57,93 @@ cdata = data; aldata = data2; return; - }catch{ - modaldata="Fallo al intentar alcanzar el servidor"; + } catch { + modaldata = "Fallo al intentar alcanzar el servidor"; } } - let visibleMesesDuracion:boolean = $state(false); + let visibleMesesDuracion: boolean = $state(false); async function dataMesesDuracion() { - try{ - const p1 = fetch($urlG+"/api/stats/duracionContrato", { - method : "GET", + try { + const p1 = fetch($urlG + "/api/stats/duracionContrato", { + method: "GET", headers: { - "Auth": token, - } + Auth: token, + }, }); - const p2 = fetch($urlG+"/api/tabla/duracionContrato", { - method : "GET", + const p2 = fetch($urlG + "/api/tabla/duracionContrato", { + method: "GET", headers: { - "Auth": token, - } + Auth: token, + }, }); - let [r1, r2] = await Promise.all([p1,p2]); - let [d1,d2] = await Promise.all([r1.json(), r2.json()]) + let [r1, r2] = await Promise.all([p1, p2]); + let [d1, d2] = await Promise.all([r1.json(), r2.json()]); chartMesesDuracion = d1; tablaMesesDuracion = d2; - }catch { - modaldata="Fallo al intentar alcanzar el servidor"; + } catch { + modaldata = "Fallo al intentar alcanzar el servidor"; } } - - function toggleModoDaltonico() { - if (tablaMesesDuracion== null) return; - tablaMesesDuracion.forEach(item => { - if (item.semaforizacion === '🟢') { - item.semaforizacion = '🔵'; - } else if (item.semaforizacion === '🔵') { - item.semaforizacion = '🟢'; + function toggleModoDaltonico() { + if (tablaMesesDuracion == null) return; + + tablaMesesDuracion.forEach((item) => { + if (item.semaforizacion === "🟢") { + item.semaforizacion = "🔵"; + } else if (item.semaforizacion === "🔵") { + item.semaforizacion = "🟢"; } }); } {#if modaldata} - !!(modaldata = "")} /> + !!(modaldata = "")} /> {/if} - +
-
- +
+

-

-
+
- - + +
@@ -125,18 +155,18 @@ {#each aldata as al} - - - - - + + + + + {/each}
{al.id}{al.ubicacion}{al.divisa}
{al.id}{al.ubicacion}{al.divisa}
{#if cdata} - + {/if}
@@ -144,30 +174,51 @@

-

-
+
-

Objetivo: Mide la longitud de los contratos en meses y cuantos hay por cada longitud. por lo menos 2.

- Activar Modo Daltónico +

+ Objetivo: Mide la longitud de los contratos en meses + y cuantos hay por cada longitud. por lo + menos 2. +

+ { + showModoDaltonico = !showModoDaltonico; + toggleModoDaltonico(); + }} + checked={showModoDaltonico} + /> + Activar Modo Daltónico @@ -189,7 +240,10 @@
{#if chartMesesDuracion} - + {/if}
-- 2.52.0 From 6fb6ade153e515600917b632f29b6e060092f527 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 14 Apr 2025 17:28:28 -0300 Subject: [PATCH 11/91] add concurrently --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index 6833aa4..f8bb850 100644 --- a/makefile +++ b/makefile @@ -1,2 +1,2 @@ run: - dotnet watch run --project Aspnet/AlquilaFacil.csproj + bunx concurrently "dotnet watch run --project Aspnet/AlquilaFacil.csproj" "make -C ./Front" -- 2.52.0 From c1a27baedd11c44ac22bf1f59e43362b3f8a408f Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 17 Apr 2025 13:24:07 -0300 Subject: [PATCH 12/91] =?UTF-8?q?avansando=20m=C3=A1s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DtoBuilder/GrupoyPermisoDtoBuilder.cs | 44 +++ Aspnet/Controllers/GruposController.cs | 26 +- Aspnet/Controllers/PermisoController.cs | 1 + Aspnet/bin/Debug/net8.0/settings.json | 5 +- Aspnet/settings.json | 5 +- Entidades/Alquilafacilcontext.cs | 14 +- Entidades/Dto/GrupoYPermisoDto.cs | 1 + Front/src/App.svelte | 276 +++++++++--------- .../Componentes/NavBarAutocompletable.svelte | 2 +- Front/src/Componentes/NavBarLogin.svelte | 77 ++--- Front/src/paginas/AdminGrupos.svelte | 101 ++++++- Front/src/paginas/VerLogs.svelte | 108 ++++--- Front/src/types.d.ts | 33 ++- Modelo/RepositorioGrupos.cs | 31 +- Modelo/RepositorioPermisos.cs | 15 +- 15 files changed, 477 insertions(+), 262 deletions(-) create mode 100644 Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs diff --git a/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs new file mode 100644 index 0000000..a7e3df4 --- /dev/null +++ b/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs @@ -0,0 +1,44 @@ +using Entidades.Dto; + +namespace AlquilaFacil.Builder; +public class GrupoDtoBuilder : Builder +{ + public GrupoDtoBuilder ConNombre(string nombre) + { + data.Nombre = nombre; + return this; + } + + public GrupoDtoBuilder ConIdGrupo(int id) + { + data.idgrupo = id; + return this; + } + + public GrupoDtoBuilder ConGruposIncluidos(HashSet grupos) + { + data.GruposIncluidos = grupos; + return this; + } + + public GrupoDtoBuilder ConPermisos(List permisos) + { + data.Permisos = permisos; + return this; + } +} + +public class PermisoDtoBuilder : Builder +{ + public PermisoDtoBuilder ConId(int id) + { + data.Id = id; + return this; + } + + public PermisoDtoBuilder ConDescripcion(string descripcion) + { + data.Descripcion = descripcion; + return this; + } +} diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs index 3208dea..5d12051 100644 --- a/Aspnet/Controllers/GruposController.cs +++ b/Aspnet/Controllers/GruposController.cs @@ -1,14 +1,36 @@ using Microsoft.AspNetCore.Mvc; using Modelo; +using AlquilaFacil.Builder; +using Entidades; + namespace AlquilaFacil.Controllers; [ApiController] public class GruposController : ControllerBase { - [HttpPost("api/admin/grupos")] + [HttpGet("api/admin/grupos")] public IActionResult ObtenerGrupos([FromHeader(Name = "Auth")] string Auth) - {//WIP + { + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18); + if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" }); + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); + var grupos = RepositorioGrupos.Singleton.ListarTodosLosGrupos() + .Select(g => new GrupoDtoBuilder() + .ConNombre(g.Nombre) + .ConIdGrupo(g.Id) + .ConGruposIncluidos(new HashSet(g.IdGrupoHijos + .Select(id => id.ToString() ?? ""))) + .ConPermisos(g.Idpermisos.Select(p => new PermisoDtoBuilder() + .ConId(p.Id) + .ConDescripcion(p.Descripcion) + .Build()) + .ToList()) + .Build()) + .ToList(); + + return Ok(grupos); } } diff --git a/Aspnet/Controllers/PermisoController.cs b/Aspnet/Controllers/PermisoController.cs index e502aa1..17cc326 100644 --- a/Aspnet/Controllers/PermisoController.cs +++ b/Aspnet/Controllers/PermisoController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Modelo; +using Entidades.Dto; namespace AlquilaFacil.Controllers; [ApiController] diff --git a/Aspnet/bin/Debug/net8.0/settings.json b/Aspnet/bin/Debug/net8.0/settings.json index ca7cba9..f44d236 100644 --- a/Aspnet/bin/Debug/net8.0/settings.json +++ b/Aspnet/bin/Debug/net8.0/settings.json @@ -1,4 +1,5 @@ { - "usr":"nwFNMLJcn5m0owbzeXMs", - "scrt":"Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70" + "usr": "nwFNMLJcn5m0owbzeXMs", + "scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70", + "connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" } diff --git a/Aspnet/settings.json b/Aspnet/settings.json index ca7cba9..f44d236 100644 --- a/Aspnet/settings.json +++ b/Aspnet/settings.json @@ -1,4 +1,5 @@ { - "usr":"nwFNMLJcn5m0owbzeXMs", - "scrt":"Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70" + "usr": "nwFNMLJcn5m0owbzeXMs", + "scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70", + "connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" } diff --git a/Entidades/Alquilafacilcontext.cs b/Entidades/Alquilafacilcontext.cs index 0d9ce17..ad46245 100644 --- a/Entidades/Alquilafacilcontext.cs +++ b/Entidades/Alquilafacilcontext.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Text.Json; using Microsoft.EntityFrameworkCore; namespace Entidades; @@ -53,9 +54,16 @@ public partial class AlquilaFacilContext : DbContext public virtual DbSet Ventas { get; set; } + private class context + { + public string connectiondb { get; set; } = ""; + } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) -#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. - => optionsBuilder.UseMySQL("Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none"); + { + context connection = JsonSerializer.Deserialize(File.ReadAllText("settings.json")) ?? new(); + optionsBuilder.UseMySQL(connection.connectiondb); + } protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/Entidades/Dto/GrupoYPermisoDto.cs b/Entidades/Dto/GrupoYPermisoDto.cs index 4017198..2764cca 100644 --- a/Entidades/Dto/GrupoYPermisoDto.cs +++ b/Entidades/Dto/GrupoYPermisoDto.cs @@ -1,3 +1,4 @@ +namespace Entidades.Dto; public class GrupoDto { public int idgrupo { get; set; } diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 59f47f0..9c4747f 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -1,170 +1,174 @@ - - - + + + + + - - - - - - - - + + + - - - - + + + + - - - - + + + + - - - - - - - - - + + + + - - - + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - + + + + - - - - + + + + - - - - - - - - - - - - - + + + + - - - - - - - - - + + + + - - - - + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/Front/src/Componentes/NavBarAutocompletable.svelte b/Front/src/Componentes/NavBarAutocompletable.svelte index 5640120..8af1fb2 100644 --- a/Front/src/Componentes/NavBarAutocompletable.svelte +++ b/Front/src/Componentes/NavBarAutocompletable.svelte @@ -87,7 +87,7 @@ } - + AlquilaFacil
diff --git a/Front/src/Componentes/NavBarLogin.svelte b/Front/src/Componentes/NavBarLogin.svelte index 343e94c..665f4b9 100644 --- a/Front/src/Componentes/NavBarLogin.svelte +++ b/Front/src/Componentes/NavBarLogin.svelte @@ -1,38 +1,47 @@ - - - - AlquilaFacil - -
- -
- (isOpen = !isOpen)} /> - - - + + AlquilaFacil +
+ +
+ (isOpen = !isOpen)} /> + + +
diff --git a/Front/src/paginas/AdminGrupos.svelte b/Front/src/paginas/AdminGrupos.svelte index 8a651db..88b15a5 100644 --- a/Front/src/paginas/AdminGrupos.svelte +++ b/Front/src/paginas/AdminGrupos.svelte @@ -1,6 +1,103 @@ - -
+
+ {#if grupos.length == 0} +
+
+ Loading... +
+
+ {:else} + {#each grupos as grupo} +
+
+

+ +

+
+
+
+
+
Grupos Incluidos
+
    + {#if grupo.gruposIncluidos.length == 0} +
  • + No hay grupos incluidos +
  • + {:else} + {#each grupo.gruposIncluidos as grupoIncluido} +
  • + {grupoIncluido} +
  • + {/each} + {/if} +
+
+
+
Permisos
+
    + {#if grupo.permisos.length == 0} +
  • + No hay grupos incluidos +
  • + {:else} + {#each grupo.permisos as permiso} +
  • + {permiso.descripcion} +
  • + {/each} + {/if} +
+
+
+
+
+ +
+
+
+
+
+ {/each} + {/if} +
diff --git a/Front/src/paginas/VerLogs.svelte b/Front/src/paginas/VerLogs.svelte index 532e78f..2e8bfd3 100644 --- a/Front/src/paginas/VerLogs.svelte +++ b/Front/src/paginas/VerLogs.svelte @@ -9,25 +9,25 @@ import PaginacionStepper from "../Componentes/PaginacionStepper.svelte"; let Logs: LogDto[] = $state([]); - let pagina:number = $state(1); - let token:string = sessionStorage.getItem("token")||""; - let modaldata:string = $state(""); - let showmodal:boolean =$state(false); - let ll:LogDto|any = $state({}); - let cantpag:number = $state(0); + let pagina: number = $state(1); + let token: string = sessionStorage.getItem("token") || ""; + let modaldata: string = $state(""); + let showmodal: boolean = $state(false); + let ll: LogDto | any = $state({}); + let cantpag: number = $state(0); - onMount(()=>{ + onMount(() => { obtenerLogs(); obtenerPaginas(); }); async function obtenerPaginas() { - try{ - const r = await fetch($urlG+"/api/Logs/cantPag", { + try { + const r = await fetch($urlG + "/api/Logs/cantPag", { method: "GET", headers: { - "Auth": token, - } + Auth: token, + }, }); let data = await r.json(); if (r.ok) { @@ -41,12 +41,12 @@ } async function obtenerLogs() { - try{ - const r = await fetch($urlG+"/api/Logs?pag="+pagina, { + try { + const r = await fetch($urlG + "/api/Logs?pag=" + pagina, { method: "GET", headers: { - "Auth": token, - } + Auth: token, + }, }); let data = await r.json(); if (r.ok) { @@ -63,49 +63,65 @@ ll = l; showmodal = true; } - function queryPag(a:number) { + function queryPag(a: number) { pagina = a; obtenerLogs(); } - + {#if modaldata} - !!(modaldata = "")}/> + !!(modaldata = "")} /> {/if} {#if showmodal} - !!(showmodal=!showmodal)} log={ll}/> + !!(showmodal = !showmodal)} log={ll} /> {/if}
- -
- - - - - - - - - - {#each Logs as l} - - - - - - - {/each} - -
FechaId UsuarioAccion
{l.fecha}{l.dniusuario}{l.accion} - -
-
- + +
+ + + + + + + + + + + {#each Logs as l} + + + + + + + {/each} + +
FechaId UsuarioAccion
{l.fecha}{l.dniusuario}{l.accion} + +
+
+ +
diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index bc113a5..eb2e59d 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -24,7 +24,7 @@ export type PropiedadVentaDto = { export type AdminParametrosBusqueda = { cantidadhabitaciones: number=0, - tipopropiedad: number=0, + tipopropiedad: number=0, servicios: string="", pag: number=1 } @@ -77,7 +77,7 @@ export type MensajeDto = { mensaje: string, fecha: Date, propiedad: string, - + } export type GaranteDto = { @@ -187,9 +187,9 @@ export type LogDto = { export type LogDetalleDto = { fecha:Date, dniusuario:number, - nombreTabla:string, - columna:string, - valorAnterior:string, + nombreTabla:string, + columna:string, + valorAnterior:string, valorNuevo:string } @@ -208,14 +208,25 @@ export type setVenta = { } export type PatchPropiedad = { - id:number, + id:number, ubicacion:string, - canthabitaciones:number, - piso:number, - letra:string, - email:string, + canthabitaciones:number, + piso:number, + letra:string, + email:string, tipo:number, servicios: string[], monto:number, iddivisa:number -} \ No newline at end of file +} + +export type GrupoDto = { + idgrupo:number, + nombre:string, + gruposIncluidos:string[], + permisos:PermisoDto[] +} +export type PermisoDto = { + id:number, + descripcion:string +} diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 2f5a476..795762f 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -3,29 +3,40 @@ using Entidades.Admin; using Microsoft.EntityFrameworkCore; namespace Modelo; -public class RepositorioGrupos: RepositorioBase { +public class RepositorioGrupos : RepositorioBase +{ - public IQueryable ListarPermisosDeGrupo(string grupo) { + public IQueryable ListarTodosLosGrupos() + { var con = Context; - return con.Grupos.Where(x=>x.Nombre == grupo).SelectMany(x => x.Idpermisos); + var grupos = con.Grupos.Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos).Include(x => x.Idpermisos); + return grupos; + } + public IQueryable ListarPermisosDeGrupo(string grupo) + { + var con = Context; //WIP Revisar esto + return con.Grupos.Where(x => x.Nombre == grupo).SelectMany(x => x.Idpermisos); } - public IQueryable ObtenerGruposPorDni(long Dni) { + public IQueryable ObtenerGruposPorDni(long Dni) + { var con = Context; - var grupos = con.Clientes.Where(x=>x.Dni == Dni).SelectMany(x=>x.Idgrupos) - .Select(x=> new GrupoAdmin{ + var grupos = con.Clientes.Where(x => x.Dni == Dni).SelectMany(x => x.Idgrupos) + .Select(x => new GrupoAdmin + { Id = x.Id, Descripcion = x.Nombre, }); return grupos; } - public bool CheckGrupos(string token, string grupo){ + public bool CheckGrupos(string token, string grupo) + { var con = Context; - Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Token == token); + Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Token == token); if (cli == null) return false; - Grupo? gru = con.Grupos.FirstOrDefault(x=>x.Nombre == grupo); + Grupo? gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo); if (gru == null) return false; if (cli.Idgrupos.Contains(gru)) return true; @@ -33,4 +44,4 @@ public class RepositorioGrupos: RepositorioBase { return false; } -} \ No newline at end of file +} diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index bb0ffa8..1ac508a 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore; namespace Modelo; public class RepositorioPermisos : RepositorioBase { - public object? ListarPermisos(string email) + public IQueryable? ListarPermisos(string email) { var con = Context; Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email); @@ -21,31 +21,20 @@ public class RepositorioPermisos : RepositorioBase public bool CheckPermisos(string token, int idpermiso) { - // Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos + //WIP Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos // var con = Context; bool tienePermiso = false; - //checkeo que el token corresponda a un usuario Cliente? cli = con.Clientes.FirstOrDefault(x => x.Token == token); if (cli == null || cli.Dni == 0) return false; - // obtengo una lista de los permisos var permisos = con.Clientes .Where(x => x.Dni == cli.Dni) .SelectMany(x => x.Idgrupos) .SelectMany(x => x.Idpermisos) .Distinct(); - ///////////////////////////////////////////////////////////////// - //Esto esta comentado porque antes pasaba el string del path de la url, es una mala idea a muchos niveles - // abajo un comentario viejo mio - ///////////////////////////////////////////////////////////////// - //me inspiré y hice un regex pero si eliminaba los primeros 8(?) caracteres del string era lo mismo - //Match match = Regex.Match(path, @"^/accion/(\d+)$"); - //int.TryParse(match.Groups[1].Value, out int idpermiso); - ///////////////////////////////////////////////////////////////// - Parallel.ForEach(permisos, (x, i) => { if (x.Id == idpermiso) -- 2.52.0 From 701f699c5506b64973749086ef9dfcd7eb8c80fe Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 17 Apr 2025 13:45:35 -0300 Subject: [PATCH 13/91] primer inicio del modal --- Front/src/Componentes/ModalEditarGrupo.svelte | 45 +++++++++++++++++++ Front/src/types.d.ts | 1 + 2 files changed, 46 insertions(+) create mode 100644 Front/src/Componentes/ModalEditarGrupo.svelte diff --git a/Front/src/Componentes/ModalEditarGrupo.svelte b/Front/src/Componentes/ModalEditarGrupo.svelte new file mode 100644 index 0000000..97e3dca --- /dev/null +++ b/Front/src/Componentes/ModalEditarGrupo.svelte @@ -0,0 +1,45 @@ + + + diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index eb2e59d..26a28de 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -226,6 +226,7 @@ export type GrupoDto = { gruposIncluidos:string[], permisos:PermisoDto[] } + export type PermisoDto = { id:number, descripcion:string -- 2.52.0 From b98fde72cac90050bcd707d64c6e888d52d4ca46 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 18 Apr 2025 23:54:27 -0300 Subject: [PATCH 14/91] hecha funcionalida de modificar grupos --- Aspnet/Controllers/GruposController.cs | 16 +++- Aspnet/Controllers/PermisoController.cs | 14 ++++ Front/src/Componentes/ModalEditarGrupo.svelte | 73 +++++++++++++++-- Front/src/paginas/AdminGrupos.svelte | 80 ++++++++++++++++++- Modelo/RepositorioGrupos.cs | 28 +++++++ Modelo/RepositorioPermisos.cs | 5 ++ 6 files changed, 206 insertions(+), 10 deletions(-) diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs index 5d12051..d8569ff 100644 --- a/Aspnet/Controllers/GruposController.cs +++ b/Aspnet/Controllers/GruposController.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Modelo; using AlquilaFacil.Builder; using Entidades; - +using Entidades.Dto; namespace AlquilaFacil.Controllers; [ApiController] @@ -21,7 +21,7 @@ public class GruposController : ControllerBase .ConNombre(g.Nombre) .ConIdGrupo(g.Id) .ConGruposIncluidos(new HashSet(g.IdGrupoHijos - .Select(id => id.ToString() ?? ""))) + .Select(id => id.Nombre ?? ""))) .ConPermisos(g.Idpermisos.Select(p => new PermisoDtoBuilder() .ConId(p.Id) .ConDescripcion(p.Descripcion) @@ -33,4 +33,16 @@ public class GruposController : ControllerBase return Ok(grupos); } + [HttpPatch("/api/grupo")] + public IActionResult PatchGrupo([FromHeader(Name = "Auth")] string Auth, GrupoDto grupo) + { + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18); + if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" }); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); + Console.WriteLine(grupo.GruposIncluidos.Count); + bool ret2 = RepositorioGrupos.Singleton.PatchGrupo(grupo, cli); + return ret2 ? Ok(new { message = "Se Modifico el grupo" }) : BadRequest(new { message = "Fallo al editar el grupo" }); + } } diff --git a/Aspnet/Controllers/PermisoController.cs b/Aspnet/Controllers/PermisoController.cs index 17cc326..f83b1fa 100644 --- a/Aspnet/Controllers/PermisoController.cs +++ b/Aspnet/Controllers/PermisoController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Modelo; using Entidades.Dto; +using AlquilaFacil.Builder; namespace AlquilaFacil.Controllers; [ApiController] @@ -21,4 +22,17 @@ public class PermisoController : ControllerBase return ret ? Ok() : BadRequest(); } + [HttpGet("/api/permisos/todos")] + public IActionResult ObtenerTodosLosPermisos([FromHeader(Name = "Auth")] string Auth) + { + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18); + if (ret == false) return BadRequest(new { message = "No tiene permiso para ver Todos los permisos" }); + + var permisos = RepositorioPermisos.Singleton.ListarPermisos(); + var perms = permisos.Select(permiso => new PermisoDtoBuilder() + .ConId(permiso.Id) + .ConDescripcion(permiso.Descripcion) + .Build()); + return Ok(perms); + } } diff --git a/Front/src/Componentes/ModalEditarGrupo.svelte b/Front/src/Componentes/ModalEditarGrupo.svelte index 97e3dca..1b2277e 100644 --- a/Front/src/Componentes/ModalEditarGrupo.svelte +++ b/Front/src/Componentes/ModalEditarGrupo.svelte @@ -1,21 +1,33 @@ @@ -23,6 +35,7 @@ class="modal show d-block" tabindex="-1" role="dialog" + style="background: rgba(0, 0, 0, 0.5)" aria-labelledby="exampleModalLabel" aria-hidden="true" > @@ -39,7 +52,57 @@ onclick={onClose} >
- + +
diff --git a/Front/src/paginas/AdminGrupos.svelte b/Front/src/paginas/AdminGrupos.svelte index 88b15a5..23fd4ce 100644 --- a/Front/src/paginas/AdminGrupos.svelte +++ b/Front/src/paginas/AdminGrupos.svelte @@ -1,8 +1,11 @@ +{#if modaldat != ""} + +{/if} + +{#if showModal} + (showModal = false)} + onSubmit={submitedit} + /> +{/if} -
+
+ {#if grupos.length == 0}
@@ -92,7 +162,11 @@

- +
diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 795762f..f1b1c97 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -1,10 +1,38 @@ using Entidades; using Entidades.Admin; +using Entidades.Dto; using Microsoft.EntityFrameworkCore; namespace Modelo; public class RepositorioGrupos : RepositorioBase { + public bool PatchGrupo(GrupoDto grupo, Cliente cli) + { + var con = Context; + var g = con.Grupos + .Include(x => x.IdGrupoHijos) + .Include(x => x.Idpermisos).FirstOrDefault(x => x.Id == grupo.idgrupo); + + if (g == null) + { + return false; + } + var listg = grupo.GruposIncluidos.ToList(); + if (grupo.GruposIncluidos != null) + { + g.IdGrupoHijos = con.Grupos.Where(x => listg.Contains(x.Nombre)).ToList(); + + } + + if (grupo.Permisos != null) + { + g.Idpermisos = con.Permisos.Where(x => grupo.Permisos.Select(p => p.Id).Contains(x.Id)).ToList(); + } + + GenerarLog(con, cli.Dni, "Patch Grupo"); + return Guardar(con); + + } public IQueryable ListarTodosLosGrupos() { diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index 1ac508a..68a7e69 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -19,6 +19,11 @@ public class RepositorioPermisos : RepositorioBase return list; } + public List ListarPermisos() + { + return Context.Permisos.ToList(); + } + public bool CheckPermisos(string token, int idpermiso) { //WIP Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos -- 2.52.0 From ffb860688d27af4d4898275df2a17da6d5fc5f79 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 01:09:53 -0300 Subject: [PATCH 15/91] analizado que necesito hacer de aca en adelante - [ ] una pagina de grupo default - [ ] los permisos resuelvan los de subgrupos --- Modelo/RepositorioGrupos.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index f1b1c97..6c8d42f 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -42,7 +42,7 @@ public class RepositorioGrupos : RepositorioBase } public IQueryable ListarPermisosDeGrupo(string grupo) { - var con = Context; //WIP Revisar esto + var con = Context; //WIP Revisar esto. revisado necesito hacer una pagina de grupo default y que los permisos resuelvan los de subgrupos return con.Grupos.Where(x => x.Nombre == grupo).SelectMany(x => x.Idpermisos); } -- 2.52.0 From 543bc9e5a60f768af0259d2341e1bb3c0456f4ff Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 16:01:15 -0300 Subject: [PATCH 16/91] =?UTF-8?q?A=C3=B1adido=20soporte=20para=20crear=20g?= =?UTF-8?q?rupos=20nuevos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/GruposController.cs | 20 ++- Front/public/plus.svg | 20 +++ Front/src/Componentes/BotonEsquina.svelte | 41 ++++++ Front/src/Componentes/ModalAñadirGrupo.svelte | 133 ++++++++++++++++++ Front/src/paginas/AdminGrupos.svelte | 35 +++++ Modelo/RepositorioGrupos.cs | 15 ++ 6 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 Front/public/plus.svg create mode 100644 Front/src/Componentes/BotonEsquina.svelte create mode 100644 Front/src/Componentes/ModalAñadirGrupo.svelte diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs index d8569ff..3521b96 100644 --- a/Aspnet/Controllers/GruposController.cs +++ b/Aspnet/Controllers/GruposController.cs @@ -41,8 +41,26 @@ public class GruposController : ControllerBase Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); - Console.WriteLine(grupo.GruposIncluidos.Count); + bool ret2 = RepositorioGrupos.Singleton.PatchGrupo(grupo, cli); return ret2 ? Ok(new { message = "Se Modifico el grupo" }) : BadRequest(new { message = "Fallo al editar el grupo" }); } + + [HttpPost("/api/grupo")] + public IActionResult PostGrupo([FromHeader(Name = "Auth")] string Auth, GrupoDto grupo) + { + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18); + if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" }); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); + + if (grupo.Nombre.Length > 25) + { + return BadRequest(new { message = "El nombre del grupo no puede superar los 25 caracteres" }); + } + + bool ret2 = RepositorioGrupos.Singleton.AddGrupo(grupo, cli); + return ret2 ? Ok(new { message = "Se Añadio el grupo" }) : BadRequest(new { message = "Fallo al añadirse el grupo" }); + } } diff --git a/Front/public/plus.svg b/Front/public/plus.svg new file mode 100644 index 0000000..c0ae662 --- /dev/null +++ b/Front/public/plus.svg @@ -0,0 +1,20 @@ + + + + + diff --git a/Front/src/Componentes/BotonEsquina.svelte b/Front/src/Componentes/BotonEsquina.svelte new file mode 100644 index 0000000..550a2f8 --- /dev/null +++ b/Front/src/Componentes/BotonEsquina.svelte @@ -0,0 +1,41 @@ + + + + + diff --git a/Front/src/Componentes/ModalAñadirGrupo.svelte b/Front/src/Componentes/ModalAñadirGrupo.svelte new file mode 100644 index 0000000..91c7680 --- /dev/null +++ b/Front/src/Componentes/ModalAñadirGrupo.svelte @@ -0,0 +1,133 @@ + + + diff --git a/Front/src/paginas/AdminGrupos.svelte b/Front/src/paginas/AdminGrupos.svelte index 23fd4ce..dedbfbb 100644 --- a/Front/src/paginas/AdminGrupos.svelte +++ b/Front/src/paginas/AdminGrupos.svelte @@ -6,11 +6,15 @@ import ModalEstatico from "../Componentes/ModalEstatico.svelte"; import ModalEditarGrupo from "../Componentes/ModalEditarGrupo.svelte"; import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte"; + import BotonEsquina from "../Componentes/BotonEsquina.svelte"; + import ModalAadirGrupo from "../Componentes/ModalAñadirGrupo.svelte"; const token: string = sessionStorage.getItem("token") || ""; let grupos: GrupoDto[] = $state([]); let modaldat: string = $state(""); + let showmodaladd = $state(false); + onMount(() => { ObtenerGrupos(); obtenerPermisos(); @@ -84,6 +88,27 @@ modaldat = "Fallo Al intentar hacer la request"; } } + + async function submitGrupo(a: GrupoDto) { + let b = a; + try { + let req = await fetch($urlG + "/api/grupo", { + method: "POST", + headers: { + Auth: token, + "Content-Type": "application/json", + }, + body: JSON.stringify(b), + }); + const resp = await req.json(); + modaldat = resp.message; + if (req.ok) { + ObtenerGrupos(); + } + } catch { + modaldat = "Fallo al hacer la request"; + } + } {#if modaldat != ""} @@ -102,6 +127,7 @@
+ {#if grupos.length == 0}
@@ -109,6 +135,15 @@
{:else} + (showmodaladd = true)} /> + {#if showmodaladd} + (showmodaladd = false)} + {grupos} + {permisos} + onSubmit={submitGrupo} + /> + {/if} {#each grupos as grupo}
diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 6c8d42f..2e3ba7b 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -6,6 +6,21 @@ using Microsoft.EntityFrameworkCore; namespace Modelo; public class RepositorioGrupos : RepositorioBase { + public bool AddGrupo(GrupoDto grupo, Cliente cli) + { + var con = Context; + + var g = new Grupo + { + Id = con.Grupos.Max(x => x.Id) + 1, + Nombre = grupo.Nombre, + IdGrupoHijos = con.Grupos.Where(x => grupo.GruposIncluidos.Contains(x.Nombre)).ToList(), + Idpermisos = con.Permisos.Where(x => grupo.Permisos.Select(x => x.Id).Contains(x.Id)).ToList(), + }; + con.Grupos.Add(g); + GenerarLog(con, cli.Dni, $"Alta Grupo: {g.Nombre}"); + return Guardar(con); + } public bool PatchGrupo(GrupoDto grupo, Cliente cli) { var con = Context; -- 2.52.0 From de9ff8f0b348f14c452d78776d8f4fbcc5295d77 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 16:02:05 -0300 Subject: [PATCH 17/91] skeleton para pagina grupo creado por usuario --- Front/src/App.svelte | 4 + Front/src/Componentes/RutaProtegida.svelte | 100 +++++++++++---------- Front/src/paginas/grupos/OtroG.svelte | 13 +++ 3 files changed, 69 insertions(+), 48 deletions(-) create mode 100644 Front/src/paginas/grupos/OtroG.svelte diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 9c4747f..9accdc5 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -31,6 +31,7 @@ import BuscarVentas from "./paginas/BuscarVentas.svelte"; import MisPropiedadesEnVenta from "./paginas/MisPropiedadesEnVenta.svelte"; import AdminGrupos from "./paginas/AdminGrupos.svelte"; + import OtroG from "./paginas/grupos/OtroG.svelte"; @@ -151,6 +152,9 @@ + + + diff --git a/Front/src/Componentes/RutaProtegida.svelte b/Front/src/Componentes/RutaProtegida.svelte index 661ea2c..254fa54 100644 --- a/Front/src/Componentes/RutaProtegida.svelte +++ b/Front/src/Componentes/RutaProtegida.svelte @@ -1,55 +1,59 @@ - + {#if !$isVerified} -
-
- Loading... -
-
+
+
+ Loading... +
+
+{:else if $isAuthenticated} + {#if typeof componente === "object" && componente !== null} + {@render componente.OtroG(componente.params)} + {:else} + {@render componente()} + {/if} {:else} - {#if $isAuthenticated} - {@render componente()} - {:else} - {window.location.replace('/')} - {/if} -{/if} + {window.location.replace("/")} +{/if} diff --git a/Front/src/paginas/grupos/OtroG.svelte b/Front/src/paginas/grupos/OtroG.svelte new file mode 100644 index 0000000..52d909f --- /dev/null +++ b/Front/src/paginas/grupos/OtroG.svelte @@ -0,0 +1,13 @@ + + + +
+
+

Menu grupo: {id}

+
+ +
-- 2.52.0 From b75f672b0aef6c49ad4a91809ea2c15538a93e46 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 16:23:15 -0300 Subject: [PATCH 18/91] arreglado bug que no salia el nombre del grupo --- Front/src/Componentes/RutaProtegida.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Front/src/Componentes/RutaProtegida.svelte b/Front/src/Componentes/RutaProtegida.svelte index 254fa54..f889538 100644 --- a/Front/src/Componentes/RutaProtegida.svelte +++ b/Front/src/Componentes/RutaProtegida.svelte @@ -50,7 +50,7 @@
{:else if $isAuthenticated} {#if typeof componente === "object" && componente !== null} - {@render componente.OtroG(componente.params)} + {:else} {@render componente()} {/if} -- 2.52.0 From 4e5e0a4f6ff7eca910219d78f9b0fe8995c53dd3 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 16:32:50 -0300 Subject: [PATCH 19/91] ahora las opciones de grupos corresponden a las que existen en vez de ser hardcode --- Aspnet/Controllers/GruposController.cs | 5 +- Front/src/paginas/AdminUsuarios.svelte | 75 ++++++++++++++++++-------- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs index 3521b96..0d54433 100644 --- a/Aspnet/Controllers/GruposController.cs +++ b/Aspnet/Controllers/GruposController.cs @@ -11,8 +11,9 @@ public class GruposController : ControllerBase [HttpGet("api/admin/grupos")] public IActionResult ObtenerGrupos([FromHeader(Name = "Auth")] string Auth) { - var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18); - if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" }); + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18) || RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + if (ret == false) return BadRequest(new { message = "No tiene permiso para ver todos los grupos" }); + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); diff --git a/Front/src/paginas/AdminUsuarios.svelte b/Front/src/paginas/AdminUsuarios.svelte index da3c5d2..4ced956 100644 --- a/Front/src/paginas/AdminUsuarios.svelte +++ b/Front/src/paginas/AdminUsuarios.svelte @@ -18,17 +18,39 @@ let grupo:string = $state(""); let SelCliente: Cliente = $state(null); + let gruposopt: GrupoDto[] = $state([]); + onMount(() => { cargaUsuarios(); + ObtenerGrupos(); }); - async function cargaUsuarios(){ - try{ - const response = await fetch($urlG+"/api/admin/clientes", { + + async function ObtenerGrupos() { + try { + const ret = await fetch($urlG + "/api/admin/grupos", { method: "GET", headers: { - "Auth": String(token), - } - }) + Auth: token || "", + }, + }); + if (!ret.ok) { + modaldata = "Fallo Al intentar hacer la request"; + return; + } + gruposopt = await ret.json(); + } catch { + modaldata = "Fallo Al intentar hacer la request"; + } + } + + async function cargaUsuarios() { + try { + const response = await fetch($urlG + "/api/admin/clientes", { + method: "GET", + headers: { + Auth: String(token), + }, + }); if (response.ok) { let data: Cliente[] = await response.json(); Clientes = data; @@ -38,7 +60,6 @@ } catch { modaldata = "fallo al intentar obtener la lista de clientes"; } - } async function cargaGrupos(cli: Cliente){ try { @@ -284,21 +305,31 @@ {#if showAddmenu} -
- -
añadirGrupo(e,SelCliente, grupo)}> -
- - -
- -
-
+
+ +
añadirGrupo(e, SelCliente, grupo)} + > +
+ + +
+ +
+
{/if}
-- 2.52.0 From 524a315dc15e6bb59f47c0d646d967f55e667b64 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 16:33:11 -0300 Subject: [PATCH 20/91] refactor de admin usuarios --- Front/src/paginas/AdminUsuarios.svelte | 248 +++++++++++++++---------- 1 file changed, 149 insertions(+), 99 deletions(-) diff --git a/Front/src/paginas/AdminUsuarios.svelte b/Front/src/paginas/AdminUsuarios.svelte index 4ced956..66e3433 100644 --- a/Front/src/paginas/AdminUsuarios.svelte +++ b/Front/src/paginas/AdminUsuarios.svelte @@ -1,8 +1,8 @@ - + {#if modaldata} - !!(modaldata = "")}/> + !!(modaldata = "")} /> {/if} {#if showModificarCliente} -!!(showModificarCliente = false)} - onConfirm={patchCliente}/> + !!(showModificarCliente = false)} + onConfirm={patchCliente} + /> {/if}
- - + +
- +
@@ -248,33 +276,45 @@ {#each Clientes as cli} - cargaGrupos(cli)} in:fade> - - - - - + cargaGrupos(cli)} in:fade> + + + + + {/each}
Dni
{cli.dni}{cli.nombre}{cli.email} - {#if cli.habilitado} - - {:else} - - {/if} - -
{cli.dni}{cli.nombre}{cli.email} + {#if cli.habilitado} + + {:else} + + {/if} + +
- - + +
@@ -283,23 +323,34 @@ - {#if Grupos.length>0} - - {#each Grupos as g} - - - - - - {/each} + {#if Grupos.length > 0} + {#each Grupos as g} + + + + + + {/each} {:else if SelCliente != null} - - - + + + {:else} - - - + + + {/if}
Id
{g.id}{g.descripcion}
{g.id}{g.descripcion}
Este Cliente no tiene Grupos
Este Cliente no tiene Grupos
Seleccione un cliente para ver sus grupos
Seleccione un cliente para ver sus grupos
@@ -334,4 +385,3 @@
- \ No newline at end of file -- 2.52.0 From e118a3acd28dd146ba71424277983a4b22ac4729 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 21 Apr 2025 19:37:03 -0300 Subject: [PATCH 21/91] falta poner los fetch --- Front/src/App.svelte | 6 + .../src/Componentes/ModalEditarPermiso.svelte | 85 ++++++++++ Front/src/paginas/GestionPemisos.svelte | 148 ++++++++++++++++++ 3 files changed, 239 insertions(+) create mode 100644 Front/src/Componentes/ModalEditarPermiso.svelte create mode 100644 Front/src/paginas/GestionPemisos.svelte diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 9accdc5..8d0a851 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -32,6 +32,7 @@ import MisPropiedadesEnVenta from "./paginas/MisPropiedadesEnVenta.svelte"; import AdminGrupos from "./paginas/AdminGrupos.svelte"; import OtroG from "./paginas/grupos/OtroG.svelte"; + import GestionPemisos from "./paginas/GestionPemisos.svelte"; @@ -129,6 +130,11 @@ + + + + + diff --git a/Front/src/Componentes/ModalEditarPermiso.svelte b/Front/src/Componentes/ModalEditarPermiso.svelte new file mode 100644 index 0000000..95b9116 --- /dev/null +++ b/Front/src/Componentes/ModalEditarPermiso.svelte @@ -0,0 +1,85 @@ + + + diff --git a/Front/src/paginas/GestionPemisos.svelte b/Front/src/paginas/GestionPemisos.svelte new file mode 100644 index 0000000..a1a4779 --- /dev/null +++ b/Front/src/paginas/GestionPemisos.svelte @@ -0,0 +1,148 @@ + + +{#if modaldat != ""} + +{/if} + + +
+ + + {#if permisos.length == 0} +
+
+ Loading... +
+
+ {:else} +
+ (showmodaladd = true)} /> +
+ {#if showmodaladd} + (showmodaladd = false)} + permiso={{ descripcion: "", id: 0 }} + onSubmit={NuevoPermiso} + modalTitle="Nuevo Permiso" + /> + {/if} + {#if showmodaledit} +
+ { + showmodaledit = false; + selpermiso.descripcion = a; + }} + bind:permiso={selpermiso} + onSubmit={PatchPermiso} + modalTitle="Modificar Permiso" + /> +
+ {/if} +
+
+
+ + + + + + + + + + {#each permisos as permiso} + + + + + + {/each} + +
IDDescripciónAccioness
{permiso.id}{permiso.descripcion} +
+ +
+
+
+
+
+ {/if} +
-- 2.52.0 From eeb2ff1c65d64da4c541476a161ed2fb06218e70 Mon Sep 17 00:00:00 2001 From: fede Date: Tue, 22 Apr 2025 21:00:58 -0300 Subject: [PATCH 22/91] ahora esta la gestion de permisos --- Aspnet/Builder/PermisoBuilder.cs | 6 +++ Aspnet/Controllers/AccionesController.cs | 57 ++++++++++++------------ Aspnet/Controllers/PermisoController.cs | 29 ++++++++++-- Front/src/paginas/GestionPemisos.svelte | 46 +++++++++++++++++-- Modelo/RepositorioPermisos.cs | 15 ++++++- 5 files changed, 117 insertions(+), 36 deletions(-) diff --git a/Aspnet/Builder/PermisoBuilder.cs b/Aspnet/Builder/PermisoBuilder.cs index ca30788..c6753d3 100644 --- a/Aspnet/Builder/PermisoBuilder.cs +++ b/Aspnet/Builder/PermisoBuilder.cs @@ -6,4 +6,10 @@ public class PermisoBuilder : Builder data.Descripcion = desc; return this; } + + public PermisoBuilder SetID(int id) + { + data.Id = id; + return this; + } } diff --git a/Aspnet/Controllers/AccionesController.cs b/Aspnet/Controllers/AccionesController.cs index 6372798..8c4b9a9 100644 --- a/Aspnet/Controllers/AccionesController.cs +++ b/Aspnet/Controllers/AccionesController.cs @@ -39,34 +39,35 @@ public class AccionesController : ControllerBase var permisos = RepositorioGrupos.Singleton.ListarPermisosDeGrupo(req.Grupo); return Ok(permisos); } - - [HttpPost("api/acciones/crear")] //creo que es codido duplicado - public IActionResult CrearAcciones([FromHeader(Name = "Auth")] string Auth, - [FromBody] CrearAccionesDto req) - { - if (string.IsNullOrEmpty(Auth)) return BadRequest(); - - Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); - if (cli == null) return Unauthorized(); - - var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1); //wip lo voy a usar para crear el permiso que va - if (ret == false) return Unauthorized(); - - if (string.IsNullOrWhiteSpace(req.Descripcion)) + /* + [HttpPost("api/acciones/crear")] //creo que es codido duplicado + public IActionResult CrearAcciones([FromHeader(Name = "Auth")] string Auth, + [FromBody] CrearAccionesDto req) { - return BadRequest(new { message = "La descripción no puede estar vacía" }); + if (string.IsNullOrEmpty(Auth)) return BadRequest(); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return Unauthorized(); + + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1); //wip lo voy a usar para crear el permiso que va + if (ret == false) return Unauthorized(); + + if (string.IsNullOrWhiteSpace(req.Descripcion)) + { + return BadRequest(new { message = "La descripción no puede estar vacía" }); + } + + if (req.Descripcion.Length > 25) + { + return BadRequest(new { message = "La descripción no puede ser mayor a 25 caracteres" }); + } + + var per = new Permiso + { + Descripcion = req.Descripcion, + }; + var ret2 = RepositorioPermisos.Singleton.CrearPermiso(per); + return ret2 ? Ok(new { message = "se creo correctamente" }) : BadRequest(new { message = "No se pudo crear el permiso" }); } - - if (req.Descripcion.Length > 25) - { - return BadRequest(new { message = "La descripción no puede ser mayor a 25 caracteres" }); - } - - var per = new Permiso - { - Descripcion = req.Descripcion, - }; - var ret2 = RepositorioPermisos.Singleton.CrearPermiso(per); - return ret2 ? Ok(new { message = "se creo correctamente" }) : BadRequest(new { message = "No se pudo crear el permiso" }); - } + */ } diff --git a/Aspnet/Controllers/PermisoController.cs b/Aspnet/Controllers/PermisoController.cs index f83b1fa..42c61eb 100644 --- a/Aspnet/Controllers/PermisoController.cs +++ b/Aspnet/Controllers/PermisoController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Modelo; +using Entidades; using Entidades.Dto; using AlquilaFacil.Builder; namespace AlquilaFacil.Controllers; @@ -7,18 +8,40 @@ namespace AlquilaFacil.Controllers; [ApiController] public class PermisoController : ControllerBase { - [HttpPost("api/admin/grupos")] + [HttpPost("api/permisos")] public IActionResult CrearPermiso([FromHeader(Name = "Auth")] string Auth, PermisoDto perm) { - //WIP var ret1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 17); + if (ret1 == false) return BadRequest(new { message = "No tienes permiso para esto" }); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); if (String.IsNullOrWhiteSpace(perm.Descripcion)) return BadRequest(new { message = "No puede tener una descripcion vacia" }); if (perm.Descripcion.Length > 25) return BadRequest(new { message = "la descripcion no puede tener más de 25 caractéres" }); var permiso = new PermisoBuilder().SetDescripcion(perm.Descripcion).Build(); - var ret = RepositorioPermisos.Singleton.CrearPermiso(permiso); + var ret = RepositorioPermisos.Singleton.CrearPermiso(permiso, cli); + + return ret ? Ok() : BadRequest(); + } + [HttpPatch("api/permisos")] + public IActionResult PatchPermiso([FromHeader(Name = "Auth")] string Auth, PermisoDto perm) + { + var ret1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 17); + if (ret1 == false) return BadRequest(new { message = "No tienes permiso para esto" }); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); + + if (perm.Id <= 0) return BadRequest(new { message = "No puede haber una id 0 o menor" }); + if (String.IsNullOrWhiteSpace(perm.Descripcion)) return BadRequest(new { message = "No puede tener una descripcion vacia" }); + if (perm.Descripcion.Length > 25) return BadRequest(new { message = "la descripcion no puede tener más de 25 caractéres" }); + + var permiso = new PermisoBuilder().SetDescripcion(perm.Descripcion).SetID(perm.Id).Build(); + + var ret = RepositorioPermisos.Singleton.PatchPermiso(permiso, cli); return ret ? Ok() : BadRequest(); } diff --git a/Front/src/paginas/GestionPemisos.svelte b/Front/src/paginas/GestionPemisos.svelte index a1a4779..88283e8 100644 --- a/Front/src/paginas/GestionPemisos.svelte +++ b/Front/src/paginas/GestionPemisos.svelte @@ -8,6 +8,8 @@ import BotonEsquina from "../Componentes/BotonEsquina.svelte"; import ModalEditarPermiso from "../Componentes/ModalEditarPermiso.svelte"; import Login from "./login.svelte"; + import { Modal } from "@sveltestrap/sveltestrap"; + import ModalLogs from "../Componentes/ModalLogs.svelte"; const token: string = sessionStorage.getItem("token") || ""; @@ -60,12 +62,48 @@ } } - function NuevoPermiso(a: PermisoDto): void { - throw new Error("Function not implemented.WIP"); + async function NuevoPermiso(a: PermisoDto) { + let b = a; + try { + const req = await fetch($urlG + "/api/permisos", { + method: "POST", + headers: { + Auth: token, + "Content-Type": "application/json", + }, + body: JSON.stringify(b), + }); + if (req.ok) { + obtenerPermisos(); + return; + } + modaldat = "Hubieron problemas creando el permiso"; + return; + } catch { + modaldat = "Fallo al hacer la request"; + } } - function PatchPermiso(): void { - throw new Error("Function not implemented.WIP"); + async function PatchPermiso(a: PermisoDto) { + let b = a; + try { + const req = await fetch($urlG + "/api/permisos", { + method: "PATCH", + headers: { + Auth: token, + "Content-Type": "application/json", + }, + body: JSON.stringify(b), + }); + if (req.ok) { + obtenerPermisos(); + return; + } + modaldat = "Hubieron problemas editando el permiso"; + return; + } catch { + modaldat = "Fallo al hacer la request"; + } } diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index 68a7e69..1b91a0c 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -51,11 +51,24 @@ public class RepositorioPermisos : RepositorioBase return tienePermiso; } - public bool CrearPermiso(Permiso per) + public bool CrearPermiso(Permiso per, Cliente cli) { var con = Context; per.Id = con.Permisos.Any() ? con.Permisos.Max(x => x.Id) + 1 : 1; con.Permisos.Add(per); + GenerarLog(con, cli.Dni, $"Creado Permiso {per.Descripcion}"); return Guardar(con); } + public bool PatchPermiso(Permiso per, Cliente cli) + { + var con = Context; + var perm = con.Permisos.FirstOrDefault(x => x.Id == per.Id); + if (perm == null) return false; + + perm.Descripcion = per.Descripcion; + + GenerarLog(con, cli.Dni, $"Editado Permiso {per.Id}"); + return Guardar(con); + + } } -- 2.52.0 From df751ead5731251ef953d4a66ad4a27db559277f Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 11:23:42 -0300 Subject: [PATCH 23/91] =?UTF-8?q?a=C3=B1adido=20un=20bit=20de=20habilitado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entidades/Alquilafacilcontext.cs | 4 ++++ Entidades/Grupo.cs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/Entidades/Alquilafacilcontext.cs b/Entidades/Alquilafacilcontext.cs index ad46245..ac23178 100644 --- a/Entidades/Alquilafacilcontext.cs +++ b/Entidades/Alquilafacilcontext.cs @@ -424,6 +424,10 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Id) .HasColumnType("int(11)") .HasColumnName("id"); + entity.Property(e => e.Habilitado) + .IsRequired() + .HasDefaultValueSql("'1'") + .HasColumnName("habilitado"); entity.Property(e => e.Nombre) .HasMaxLength(12) .HasColumnName("nombre"); diff --git a/Entidades/Grupo.cs b/Entidades/Grupo.cs index 4aac993..2938803 100644 --- a/Entidades/Grupo.cs +++ b/Entidades/Grupo.cs @@ -10,6 +10,8 @@ public partial class Grupo:IComponenteSeguridad public string Nombre { get; set; } = null!; + public bool? Habilitado { get; set; } + [JsonIgnore] public virtual ICollection IdGrupoHijos { get; set; } = new List(); -- 2.52.0 From fdcb74bb1103f5a3ea96b63f3a1e144d8f0cd859 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 11:35:36 -0300 Subject: [PATCH 24/91] feat: crea todas las entidades para mergearlas con meld --- Entidades/makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Entidades/makefile b/Entidades/makefile index b9d75c1..da00705 100644 --- a/Entidades/makefile +++ b/Entidades/makefile @@ -1,6 +1,10 @@ run: - dotnet ef dbcontext scaffold "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" MySql.EntityFrameworkCore -o . + dotnet ef dbcontext scaffold "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" MySql.EntityFrameworkCore -o . ./convert_to_pascalcase.sh clean: rm *.cs + +table: + dotnet ef dbcontext scaffold "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" MySql.EntityFrameworkCore -o ./tmp + ./convert_to_pascalcase.sh -- 2.52.0 From 1d3784d848cc3ea537412c0024de383ad7a8f296 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 13:06:19 -0300 Subject: [PATCH 25/91] creado toggle habilitar grupo y correjido un par de bugs de modalestatico --- .../DtoBuilder/GrupoyPermisoDtoBuilder.cs | 6 ++++ Aspnet/Controllers/GruposController.cs | 17 +++++++++ Entidades/Dto/GrupoYPermisoDto.cs | 1 + Front/src/paginas/AdminGrupos.svelte | 36 ++++++++++++++++++- Front/src/paginas/GestionPemisos.svelte | 2 +- Front/src/types.d.ts | 1 + Modelo/RepositorioGrupos.cs | 13 +++++++ 7 files changed, 74 insertions(+), 2 deletions(-) diff --git a/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs index a7e3df4..ad02d72 100644 --- a/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs +++ b/Aspnet/Builder/DtoBuilder/GrupoyPermisoDtoBuilder.cs @@ -9,6 +9,12 @@ public class GrupoDtoBuilder : Builder return this; } + public GrupoDtoBuilder ConHabilitado(bool habilitado) + { + data.Habilitado = habilitado; + return this; + } + public GrupoDtoBuilder ConIdGrupo(int id) { data.idgrupo = id; diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs index 0d54433..2a14a1c 100644 --- a/Aspnet/Controllers/GruposController.cs +++ b/Aspnet/Controllers/GruposController.cs @@ -21,6 +21,7 @@ public class GruposController : ControllerBase .Select(g => new GrupoDtoBuilder() .ConNombre(g.Nombre) .ConIdGrupo(g.Id) + .ConHabilitado(g.Habilitado ?? false) .ConGruposIncluidos(new HashSet(g.IdGrupoHijos .Select(id => id.Nombre ?? ""))) .ConPermisos(g.Idpermisos.Select(p => new PermisoDtoBuilder() @@ -64,4 +65,20 @@ public class GruposController : ControllerBase bool ret2 = RepositorioGrupos.Singleton.AddGrupo(grupo, cli); return ret2 ? Ok(new { message = "Se Añadio el grupo" }) : BadRequest(new { message = "Fallo al añadirse el grupo" }); } + + [HttpDelete("/api/grupo")] + public IActionResult DeleteGrupo([FromHeader(Name = "Auth")] string Auth, [FromQuery] int id) + { + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18); + if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" }); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" }); + + if (id <= 0) return BadRequest(new { message = "El ID del grupo debe ser mayor que cero" }); + var (ret2, estado) = RepositorioGrupos.Singleton.ToggleGrupo(id, cli); + return ret2 + ? Ok(new { message = (estado ? "Grupo habilitado exitosamente" : "Grupo deshabilitado exitosamente") }) + : BadRequest(new { message = "No se pudo cambiar el estado del grupo" }); + } } diff --git a/Entidades/Dto/GrupoYPermisoDto.cs b/Entidades/Dto/GrupoYPermisoDto.cs index 2764cca..6d4155b 100644 --- a/Entidades/Dto/GrupoYPermisoDto.cs +++ b/Entidades/Dto/GrupoYPermisoDto.cs @@ -3,6 +3,7 @@ public class GrupoDto { public int idgrupo { get; set; } public string Nombre { get; set; } = ""; + public bool Habilitado { get; set; } = false; public HashSet GruposIncluidos { get; set; } = []; public List Permisos { get; set; } = []; diff --git a/Front/src/paginas/AdminGrupos.svelte b/Front/src/paginas/AdminGrupos.svelte index dedbfbb..dc58059 100644 --- a/Front/src/paginas/AdminGrupos.svelte +++ b/Front/src/paginas/AdminGrupos.svelte @@ -109,10 +109,28 @@ modaldat = "Fallo al hacer la request"; } } + + async function togglegrupo(grupo: GrupoDto) { + try { + const req = await fetch($urlG + "/api/grupo?id=" + grupo.idgrupo, { + method: "DELETE", + headers: { + Auth: token, + }, + }); + if (req.ok) { + grupo.habilitado = !grupo.habilitado; + } + modaldat = (await req.json()).message; + ObtenerGrupos(); + } catch { + modaldat = "Fallo al hacer la request"; + } + } {#if modaldat != ""} - + !!(modaldat = "")} /> {/if} {#if showModal} @@ -157,6 +175,14 @@ aria-controls={grupo.idgrupo} > {grupo.nombre} + + {grupo.habilitado + ? "Habilitado" + : "Desabilitado"} +
@@ -202,6 +228,14 @@ onclick={() => setModalEditar(grupo)} >Editar +
diff --git a/Front/src/paginas/GestionPemisos.svelte b/Front/src/paginas/GestionPemisos.svelte index 88283e8..5d636d7 100644 --- a/Front/src/paginas/GestionPemisos.svelte +++ b/Front/src/paginas/GestionPemisos.svelte @@ -108,7 +108,7 @@ {#if modaldat != ""} - + !!(modaldat = "")} /> {/if} diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index 26a28de..1e4c9d1 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -223,6 +223,7 @@ export type PatchPropiedad = { export type GrupoDto = { idgrupo:number, nombre:string, + habilitado:boolean gruposIncluidos:string[], permisos:PermisoDto[] } diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 2e3ba7b..5d1ceb5 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -49,6 +49,19 @@ public class RepositorioGrupos : RepositorioBase } + public (bool, bool) ToggleGrupo(int id, Cliente cli) + { + var con = Context; + var grupo = con.Grupos.FirstOrDefault(x => x.Id == id); + if (grupo == null) return (false, false); + if (grupo.Habilitado == null) grupo.Habilitado = false; + + grupo.Habilitado = !grupo.Habilitado; + + GenerarLog(con, cli.Dni, $"Se dio de {(grupo.Habilitado == true ? "alta" : "baja")} el grupo: {id}"); + return (Guardar(con), grupo.Habilitado ?? false); + } + public IQueryable ListarTodosLosGrupos() { var con = Context; -- 2.52.0 From c5a0eb70b86156c3cfe9c4298943db5b974fc0fa Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 13:36:41 -0300 Subject: [PATCH 26/91] duplica la funcion con gestion permisos --- Front/src/paginas/AdministrarPermisos.svelte | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Front/src/paginas/AdministrarPermisos.svelte diff --git a/Front/src/paginas/AdministrarPermisos.svelte b/Front/src/paginas/AdministrarPermisos.svelte deleted file mode 100644 index 7c94f5c..0000000 --- a/Front/src/paginas/AdministrarPermisos.svelte +++ /dev/null @@ -1 +0,0 @@ -//WIP -- 2.52.0 From 36b8f034215eedfeef7c4fec435d0f7ee7c80f50 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 13:46:40 -0300 Subject: [PATCH 27/91] eliminado un wip --- Aspnet/Controllers/AdminController.cs | 4 +++- Front/src/paginas/AdminUsuarios.svelte | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Aspnet/Controllers/AdminController.cs b/Aspnet/Controllers/AdminController.cs index f6f05c9..add56b4 100644 --- a/Aspnet/Controllers/AdminController.cs +++ b/Aspnet/Controllers/AdminController.cs @@ -362,7 +362,9 @@ public class AdminController: ControllerBase } // lo da de baja si no tiene el grupo propietario y no tiene alquileres pendientes var ret = RepositorioUsuarios.Singleton.BajaCliente(Dni); - return Ok(ret); + return ret ? + Ok(new { message = "Cliente ha sido modificado" }) : + BadRequest(new { message = "No se pudo modificar al cliente" }); } [HttpDelete("api/admin/propiedad")] diff --git a/Front/src/paginas/AdminUsuarios.svelte b/Front/src/paginas/AdminUsuarios.svelte index 66e3433..7846262 100644 --- a/Front/src/paginas/AdminUsuarios.svelte +++ b/Front/src/paginas/AdminUsuarios.svelte @@ -87,7 +87,6 @@ } async function bajaCliente(event: Event, cli: Cliente) { - //WIP añadir una flag para que muestre que no se pudo dar se alta/baja event.stopPropagation(); try { const response = await fetch( @@ -99,13 +98,14 @@ }, }, ); + let data = await response.json(); + modaldata = data.message; if (response.ok) { - let data = await response.json(); - modaldata = data.message; cli.habilitado = !cli.habilitado; + cargaUsuarios(); } } catch { - modaldata = ""; + modaldata = "Fallo al hacer la request"; } } async function añadirGrupo(e: Event, cli: Cliente, grupo: string) { -- 2.52.0 From 25e399a5b37908f8dfd040bef0fc218baf408d9e Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 13:47:13 -0300 Subject: [PATCH 28/91] fix: mejorado espacio vertical que ocupa la tabla --- Front/src/paginas/AdminUsuarios.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Front/src/paginas/AdminUsuarios.svelte b/Front/src/paginas/AdminUsuarios.svelte index 7846262..2a3c529 100644 --- a/Front/src/paginas/AdminUsuarios.svelte +++ b/Front/src/paginas/AdminUsuarios.svelte @@ -262,7 +262,7 @@
-
+
-- 2.52.0 From 190f9a8e10ce04a4d767a7c6e0c12cc8e69fb633 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 14:52:16 -0300 Subject: [PATCH 29/91] bruh estaba la relacion al revez --- Entidades/Grupo.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Entidades/Grupo.cs b/Entidades/Grupo.cs index 2938803..113d8a8 100644 --- a/Entidades/Grupo.cs +++ b/Entidades/Grupo.cs @@ -1,10 +1,10 @@ -using System; +using System; using System.Collections.Generic; using System.Text.Json.Serialization; namespace Entidades; -public partial class Grupo:IComponenteSeguridad +public partial class Grupo : IComponenteSeguridad { public int Id { get; set; } @@ -14,7 +14,7 @@ public partial class Grupo:IComponenteSeguridad [JsonIgnore] public virtual ICollection IdGrupoHijos { get; set; } = new List(); - + [JsonIgnore] public virtual ICollection IdGrupoPadres { get; set; } = new List(); @@ -27,11 +27,13 @@ public partial class Grupo:IComponenteSeguridad { if (visitados.Contains(Id)) return; visitados.Add(Id); - foreach (var permiso in Idpermisos) { + foreach (var permiso in Idpermisos) + { permisos.Add(permiso); } - foreach (var subgrupo in IdGrupoPadres) { + foreach (var subgrupo in IdGrupoHijos) + { subgrupo.ObtenerPermisos(permisos, visitados); } -- 2.52.0 From b2f45baec789b35ac24dec6153d41e15986cffa2 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 16:23:10 -0300 Subject: [PATCH 30/91] ahora lista usando profundidad --- Modelo/RepositorioGrupos.cs | 14 +++++++++++++- Modelo/RepositorioPermisos.cs | 19 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 5d1ceb5..2f8018f 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -68,10 +68,22 @@ public class RepositorioGrupos : RepositorioBase var grupos = con.Grupos.Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos).Include(x => x.Idpermisos); return grupos; } + public IQueryable ListarPermisosDeGrupo(string grupo) { var con = Context; //WIP Revisar esto. revisado necesito hacer una pagina de grupo default y que los permisos resuelvan los de subgrupos - return con.Grupos.Where(x => x.Nombre == grupo).SelectMany(x => x.Idpermisos); + var listg = con.Grupos + .Include(x => x.Idpermisos) + .Include(x => x.IdGrupoHijos) + .ThenInclude(x => x.Idpermisos).ToList(); + var g = listg.FirstOrDefault(x => x.Nombre == grupo); + if (g == null) return Enumerable.Empty().AsQueryable(); + + var permisos = new HashSet(); + var visitados = new HashSet(); + g.ObtenerPermisos(permisos, visitados); + + return permisos.AsQueryable(); } public IQueryable ObtenerGruposPorDni(long Dni) diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index 1b91a0c..8d44cec 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -7,14 +7,27 @@ public class RepositorioPermisos : RepositorioBase { public IQueryable? ListarPermisos(string email) { + //WIP Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos var con = Context; Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email); if (cli == null) return null; + // Obtener todos los grupos del cliente var list = con.Clientes - .Where(c => c.Dni == cli.Dni) - .SelectMany(c => c.Idgrupos) - .Include(x => x.Idpermisos); + .Where(c => c.Dni == cli.Dni) + .SelectMany(c => c.Idgrupos) + .Include(x => x.Idpermisos) + .Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos); + + + // Cargamos todos los subgrupos de forma recursiva + foreach (var grupo in list) + { + var visitados = new HashSet(); + var todosLosPermisos = new HashSet(); + grupo.ObtenerPermisos(todosLosPermisos, visitados); + grupo.Idpermisos = todosLosPermisos.ToList(); + } return list; } -- 2.52.0 From 8e385a471007db0990518b3b14babe04b7a22ef7 Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 18:02:48 -0300 Subject: [PATCH 31/91] eliminado wip --- Modelo/RepositorioGrupos.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 2f8018f..6ca9c63 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -71,7 +71,7 @@ public class RepositorioGrupos : RepositorioBase public IQueryable ListarPermisosDeGrupo(string grupo) { - var con = Context; //WIP Revisar esto. revisado necesito hacer una pagina de grupo default y que los permisos resuelvan los de subgrupos + var con = Context; var listg = con.Grupos .Include(x => x.Idpermisos) .Include(x => x.IdGrupoHijos) -- 2.52.0 From 99591b8cc26f8d7501079b4d88a5820204d890af Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Apr 2025 19:46:18 -0300 Subject: [PATCH 32/91] bueno ya esta implemntado todo lo de permisos de forma recursiva --- Aspnet/Controllers/LogsController.cs | 38 +++++++++++++++---------- Front/src/paginas/GestionPemisos.svelte | 3 -- Modelo/RepositorioPermisos.cs | 20 ++++++++----- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Aspnet/Controllers/LogsController.cs b/Aspnet/Controllers/LogsController.cs index c232bd1..1f074bd 100644 --- a/Aspnet/Controllers/LogsController.cs +++ b/Aspnet/Controllers/LogsController.cs @@ -5,21 +5,25 @@ using Modelo; namespace AlquilaFacil.Controllers; [ApiController] -public class LogsController: ControllerBase { +public class LogsController : ControllerBase +{ [HttpGet("/api/Logs")] - public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, int pag=1) { + public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, int pag = 1) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 7); if (validacion1 == false) return Unauthorized(); - if (pag<=0) return BadRequest(new { message = "no puede haber una pagina 0 o menor"}); + if (pag <= 0) return BadRequest(new { message = "no puede haber una pagina 0 o menor" }); - pag-=1; + pag -= 1; var l = RepositorioLogs.Singleton.ObtenerLogsPaginado(pag); List ll = new(); - foreach (var i in l) { - ll.Add(new LogDto{ + foreach (var i in l) + { + ll.Add(new LogDto + { Fecha = i.Fecha, Accion = i.Accion, Dniusuario = i.Dniusuario, @@ -29,16 +33,19 @@ public class LogsController: ControllerBase { } [HttpGet("/api/Logs/detalle")] - public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, [FromQuery]DateTime fecha, [FromQuery]long idusuario) { + public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, [FromQuery] DateTime fecha, [FromQuery] long idusuario) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 7); if (validacion1 == false) return Unauthorized(); - if (idusuario<=0) return BadRequest(new { message = "no puede haber un id 0 o menor"}); + if (idusuario <= 0) return BadRequest(new { message = "no puede haber un id 0 o menor" }); var l = RepositorioLogs.Singleton.ObtenerDetallesLogs(fecha, idusuario); List ll = new(); - foreach (var i in l) { - ll.Add(new LogDetalleDto{ + foreach (var i in l) + { + ll.Add(new LogDetalleDto + { Fecha = i.Fecha, Dniusuario = i.Dniusuario, NombreTabla = i.NombreTabla, @@ -51,12 +58,13 @@ public class LogsController: ControllerBase { } [HttpGet("/api/Logs/cantPag")] - public IActionResult cantidadPaginas([FromHeader(Name = "Auth")] string Auth){ + public IActionResult cantidadPaginas([FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 7); if (validacion1 == false) return Unauthorized(); int c = RepositorioLogs.Singleton.ObtenerCantidadPaginas(); return Ok(c); } -} \ No newline at end of file +} diff --git a/Front/src/paginas/GestionPemisos.svelte b/Front/src/paginas/GestionPemisos.svelte index 5d636d7..ffa58ee 100644 --- a/Front/src/paginas/GestionPemisos.svelte +++ b/Front/src/paginas/GestionPemisos.svelte @@ -7,9 +7,6 @@ import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte"; import BotonEsquina from "../Componentes/BotonEsquina.svelte"; import ModalEditarPermiso from "../Componentes/ModalEditarPermiso.svelte"; - import Login from "./login.svelte"; - import { Modal } from "@sveltestrap/sveltestrap"; - import ModalLogs from "../Componentes/ModalLogs.svelte"; const token: string = sessionStorage.getItem("token") || ""; diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index 8d44cec..f8ab3cd 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -7,7 +7,6 @@ public class RepositorioPermisos : RepositorioBase { public IQueryable? ListarPermisos(string email) { - //WIP Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos var con = Context; Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email); if (cli == null) return null; @@ -47,19 +46,26 @@ public class RepositorioPermisos : RepositorioBase Cliente? cli = con.Clientes.FirstOrDefault(x => x.Token == token); if (cli == null || cli.Dni == 0) return false; - var permisos = con.Clientes + var grupos = con.Clientes .Where(x => x.Dni == cli.Dni) .SelectMany(x => x.Idgrupos) - .SelectMany(x => x.Idpermisos) - .Distinct(); + .Include(x => x.Idpermisos) + .Include(x => x.IdGrupoHijos) + .ThenInclude(x => x.Idpermisos) + .ToList(); - Parallel.ForEach(permisos, (x, i) => + foreach (var grupo in grupos) { - if (x.Id == idpermiso) + var visitados = new HashSet(); + var todosLosPermisos = new HashSet(); + grupo.ObtenerPermisos(todosLosPermisos, visitados); + + if (todosLosPermisos.Any(p => p.Id == idpermiso)) { tienePermiso = true; + break; } - }); + } return tienePermiso; } -- 2.52.0 From 0961618e4021ca387b936e18ab0ad60cb855100f Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 17:15:12 -0300 Subject: [PATCH 33/91] lol ahora si usa composite bien --- Entidades/Grupo.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Entidades/Grupo.cs b/Entidades/Grupo.cs index 113d8a8..ac7b270 100644 --- a/Entidades/Grupo.cs +++ b/Entidades/Grupo.cs @@ -27,15 +27,14 @@ public partial class Grupo : IComponenteSeguridad { if (visitados.Contains(Id)) return; visitados.Add(Id); - foreach (var permiso in Idpermisos) - { - permisos.Add(permiso); - } - foreach (var subgrupo in IdGrupoHijos) - { - subgrupo.ObtenerPermisos(permisos, visitados); - } + var componentes = new List(); + componentes.AddRange(Idpermisos); + componentes.AddRange(IdGrupoHijos); + foreach (var componente in componentes) + { + componente.ObtenerPermisos(permisos, visitados); + } } } -- 2.52.0 From 69262213539de4d792dc72c84096cee3c00d836d Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 17:27:02 -0300 Subject: [PATCH 34/91] eliminado checkgrupos en notificaciones controller --- .../Controllers/NotificacionesController.cs | 126 ++++++++++-------- 1 file changed, 67 insertions(+), 59 deletions(-) diff --git a/Aspnet/Controllers/NotificacionesController.cs b/Aspnet/Controllers/NotificacionesController.cs index 76dc46b..6080115 100644 --- a/Aspnet/Controllers/NotificacionesController.cs +++ b/Aspnet/Controllers/NotificacionesController.cs @@ -7,79 +7,85 @@ using Modelo; namespace AlquilaFacil.Controllers; [ApiController] -public class NotificacionesController: ControllerBase { +public class NotificacionesController : ControllerBase +{ [HttpGet("api/notificaciones")] - public IActionResult GetNotificaciones([FromHeader(Name ="Auth")]string Auth, bool leido = false) { + public IActionResult GetNotificaciones([FromHeader(Name = "Auth")] string Auth, bool leido = false) + { if (string.IsNullOrEmpty(Auth)) return Unauthorized(); - + var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); - if (cli == null) return BadRequest(new {message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)"}); - + if (cli == null) return BadRequest(new { message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)" }); + IQueryable notificaciones = RepositorioNotificaciones.Singleton.ObtenerNotificacionesDeUsuario(cli.Dni) - .Where(x=>x.Leido == leido); - - + .Where(x => x.Leido == leido); + + List noti = new(); - foreach (Notificacione i in notificaciones) { - if(i.DniclienteNavigation == null || i.DniremitenteNavigation==null) return BadRequest(new { message = "Esta mal cargado el precontrato"}); + foreach (Notificacione i in notificaciones) + { + if (i.DniclienteNavigation == null || i.DniremitenteNavigation == null) return BadRequest(new { message = "Esta mal cargado el precontrato" }); var dto = new NotificacionDtoBuilder() - .SetRemitente(i.DniremitenteNavigation.Email??"") - .SetAccion(i.Accion??"") - .SetMensaje(i.Mensaje??"") + .SetRemitente(i.DniremitenteNavigation.Email ?? "") + .SetAccion(i.Accion ?? "") + .SetMensaje(i.Mensaje ?? "") .SetFecha(i.Fecha) - .SetPropiedad(i.Idpropiedad.ToString()??"") - .SetReceptor(i.DniclienteNavigation.Email??"") + .SetPropiedad(i.Idpropiedad.ToString() ?? "") + .SetReceptor(i.DniclienteNavigation.Email ?? "") .Build(); noti.Add(dto); } - + return Ok(noti); } [HttpGet("api/notificaciones/haySinLeer")] - public IActionResult GetHayNotis([FromHeader(Name ="Auth")]string Auth) { + public IActionResult GetHayNotis([FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); - if (cli == null) return BadRequest(new {message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)"}); + if (cli == null) return BadRequest(new { message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)" }); bool ret = RepositorioNotificaciones.Singleton.HayNotis(cli.Dni); - return Ok(new {message = ret}); + return Ok(new { message = ret }); } [HttpPut("api/notificaciones")] - public IActionResult MarcarComoLeido([FromHeader(Name = "Auth")]string Auth, NotificacionMarcarLeidoDto nota) { + public IActionResult MarcarComoLeido([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto nota) + { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); - if (nota.Fecha == null || String.IsNullOrWhiteSpace(nota.Email)) return BadRequest(new {message = "Faltan datos"}); + if (nota.Fecha == null || String.IsNullOrWhiteSpace(nota.Email)) return BadRequest(new { message = "Faltan datos" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); - if (cli == null) return BadRequest(new {message = "El token de autorizacion no pertenese a ningun Usuario"}); + if (cli == null) return BadRequest(new { message = "El token de autorizacion no pertenese a ningun Usuario" }); + + if (cli.Email != nota.Email) return BadRequest(new { message = "El token de autorizacion no corresponde a tu usuario" }); - if (cli.Email != nota.Email) return BadRequest(new {message = "El token de autorizacion no corresponde a tu usuario"}); - bool ret = RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, nota.Fecha); return ret ? - Ok(new{message = "Se Marco como leido"}):BadRequest(new{message = "Fallo al marcarse como leido"}); + Ok(new { message = "Se Marco como leido" }) : BadRequest(new { message = "Fallo al marcarse como leido" }); } [HttpPost("api/notificaciones/consultaAlquiler")] - public IActionResult ConsultaAlquiler([FromHeader(Name ="Auth")]string Auth, [FromBody] AltaNotificacionDto data) { + public IActionResult ConsultaAlquiler([FromHeader(Name = "Auth")] string Auth, [FromBody] AltaNotificacionDto data) + { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); bool validacion1 = RepositorioUsuarios.Singleton.CheckToken(data.Remitente, Auth); - if (validacion1 == false) return BadRequest(new {message = "el token no corresponde a su usuario"}); + if (validacion1 == false) return BadRequest(new { message = "el token no corresponde a su usuario" }); - if (data.Accion == "") return BadRequest(new{message = "El campo Accion esta vacio"}); - if (data.Mensaje == "") return BadRequest(new {message = "El campo Mensaje esta vacio"}); + if (data.Accion == "") return BadRequest(new { message = "El campo Accion esta vacio" }); + if (data.Mensaje == "") return BadRequest(new { message = "El campo Mensaje esta vacio" }); Cliente? inq = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (inq == null) return BadRequest(new { message = "no hay un usuario para el cual el token de autorizacion corresponda (vuelvase a logear)" }); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(data.Propiedad); - if (prop == null || prop.Idestado != 1) return BadRequest(new{message="No hay una propiedad dada de alta para ese id"}); - if (prop.DnipropietarioNavigation == null) return BadRequest(new{message="la propiedad no tiene propietario dado de alto ????"}); + if (prop == null || prop.Idestado != 1) return BadRequest(new { message = "No hay una propiedad dada de alta para ese id" }); + if (prop.DnipropietarioNavigation == null) return BadRequest(new { message = "la propiedad no tiene propietario dado de alto ????" }); var noti = new NotificacioneBuilder() .SetAccion(data.Accion) @@ -90,23 +96,24 @@ public class NotificacionesController: ControllerBase { .SetIdpropiedad(prop.Id) .SetFecha(DateTime.Now) .Build(); - + var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); - return ret? - Ok(new {message = "Se envio la notificacion"}):BadRequest(new {message = "Fallo al intentar guardar la notificacion"}); + return ret ? + Ok(new { message = "Se envio la notificacion" }) : BadRequest(new { message = "Fallo al intentar guardar la notificacion" }); } [HttpPost("api/notificarInquilino")] - public IActionResult NotificarInq([FromHeader(Name ="Auth")]string Auth, [FromBody] AvisoInquilinoDto data) { + public IActionResult NotificarInq([FromHeader(Name = "Auth")] string Auth, [FromBody] AvisoInquilinoDto data) + { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false)return Unauthorized(); - - if (data.Mensaje == "") return BadRequest(new {message = "El campo Mensaje esta vacio"}); - if (data.Idpropiedad <= 0) return BadRequest(new {message = "La id de propiedad no puede ser 0 o menor"}); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12); + if (validacion1 == false) return Unauthorized(); + + if (data.Mensaje == "") return BadRequest(new { message = "El campo Mensaje esta vacio" }); + if (data.Idpropiedad <= 0) return BadRequest(new { message = "La id de propiedad no puede ser 0 o menor" }); Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(data.Idpropiedad); - if (cont == null || cont.DniinquilinoNavigation == null || cont.DnipropietarioNavigation == null || cont.IdpropiedadNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id"}); + if (cont == null || cont.DniinquilinoNavigation == null || cont.DnipropietarioNavigation == null || cont.IdpropiedadNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id" }); var n = new NotificacioneBuilder() .SetAccion("Notificacion Inquilino") @@ -118,41 +125,42 @@ public class NotificacionesController: ControllerBase { .SetFecha(DateTime.Now) .Build(); var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(n); - return ret? - Ok(new { message = "se envio el aviso" }):BadRequest(new { message = "Fallo al intentar enviar el aviso" }); + return ret ? + Ok(new { message = "se envio el aviso" }) : BadRequest(new { message = "Fallo al intentar enviar el aviso" }); } [HttpPost("api/notificar/ConsultaCompra")] - public IActionResult EnviarConsultaCompra([FromHeader(Name ="Auth")]string Auth, AltaNotificacionDto dto) { + public IActionResult EnviarConsultaCompra([FromHeader(Name = "Auth")] string Auth, AltaNotificacionDto dto) + { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ - validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { - return Unauthorized(); - } + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 16); + if (validacion1 == false) + { + + return Unauthorized(); + } - if (dto.Accion == "") return BadRequest(new{message = "El campo Accion esta vacio"}); - if (dto.Mensaje == "") return BadRequest(new {message = "El campo Mensaje esta vacio"}); + if (dto.Accion == "") return BadRequest(new { message = "El campo Accion esta vacio" }); + if (dto.Mensaje == "") return BadRequest(new { message = "El campo Mensaje esta vacio" }); - Cliente?cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.Propiedad); - if (prop == null) return BadRequest(new { message = "No hay una propiedad con id 0 o menor"}); + if (prop == null) return BadRequest(new { message = "No hay una propiedad con id 0 o menor" }); var n = new NotificacioneBuilder() .SetAccion("Consulta Compra") .SetMensaje(dto.Mensaje) .SetLeido(false) - .SetDnicliente(prop.Dnipropietario??0) + .SetDnicliente(prop.Dnipropietario ?? 0) .SetDniremitente(cli.Dni) .SetIdpropiedad(prop.Id) .SetFecha(DateTime.Now) .Build(); - var ret2= RepositorioNotificaciones.Singleton.AltaNotificacion(n, cli.Dni); - return ret2? - Ok(new { message = "se envio el aviso" }):BadRequest(new { message = "Fallo al intentar enviar el aviso" }); + var ret2 = RepositorioNotificaciones.Singleton.AltaNotificacion(n, cli.Dni); + return ret2 ? + Ok(new { message = "se envio el aviso" }) : BadRequest(new { message = "Fallo al intentar enviar el aviso" }); } -} \ No newline at end of file +} -- 2.52.0 From 2dd72bf0700ab1dfaa9becf83b183ba4629d624d Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 17:41:26 -0300 Subject: [PATCH 35/91] Update App.svelte --- Front/src/App.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 8d0a851..378ac80 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -75,7 +75,7 @@ - + -- 2.52.0 From 2304e7b54ba350ecbd3b4f5e08e946a90f682152 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 17:41:43 -0300 Subject: [PATCH 36/91] cambiado que use permisos --- Aspnet/Controllers/EstadisticaController.cs | 59 ++++++++++++--------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/Aspnet/Controllers/EstadisticaController.cs b/Aspnet/Controllers/EstadisticaController.cs index b00e5d9..e35caa3 100644 --- a/Aspnet/Controllers/EstadisticaController.cs +++ b/Aspnet/Controllers/EstadisticaController.cs @@ -5,44 +5,49 @@ using Modelo; namespace AlquilaFacil.Controllers; [ApiController] -public class EstadisticaController: ControllerBase { +public class EstadisticaController : ControllerBase +{ [HttpGet("api/stats/alquileresIniciados")] - public IActionResult alquileresIniciadosEsteAño([FromHeader(Name ="Auth")]string Auth, int year) { + public IActionResult alquileresIniciadosEsteAño([FromHeader(Name = "Auth")] string Auth, int year) + { if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6); if (validacion1 == false) return Unauthorized(); - + var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); - if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año"}); + if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año" }); var a = RepositorioEstadisticas.Singleton.ObtenerDataIniciadosPorAño(year); return Ok(a); } [HttpGet("api/contrato/stats")] - public IActionResult ObtenerMesesPagos([FromHeader(Name ="Auth")]string Auth, long idcontrato=0){ + public IActionResult ObtenerMesesPagos([FromHeader(Name = "Auth")] string Auth, long idcontrato = 0) + { if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) return Unauthorized(); - - if (idcontrato<=0) return BadRequest(new {message = "No puede tener un id contrato menor o igual a 0"}); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12); + if (validacion1 == false) return Unauthorized(); + + if (idcontrato <= 0) return BadRequest(new { message = "No puede tener un id contrato menor o igual a 0" }); var ret = RepositorioEstadisticas.Singleton.ObtenerDatosPagosContrato(idcontrato); return Ok(ret); } [HttpGet("api/tabla/alquileresIniciados")] - public IActionResult tablaalquileresIniciadosEsteAño([FromHeader(Name ="Auth")]string Auth, int year) { + public IActionResult tablaalquileresIniciadosEsteAño([FromHeader(Name = "Auth")] string Auth, int year) + { if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6); if (validacion1 == false) return Unauthorized(); - - var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); - if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año"}); - var a = RepositorioEstadisticas.Singleton.TablaObtenerContratosIniciadosPorAño(year); - if (a == null) return BadRequest(new { message = "Fallo al obtener el contrato"}); - List informe =new(); - foreach (var i in a) { + var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); + if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año" }); + var a = RepositorioEstadisticas.Singleton.TablaObtenerContratosIniciadosPorAño(year); + if (a == null) return BadRequest(new { message = "Fallo al obtener el contrato" }); + + List informe = new(); + foreach (var i in a) + { var d = new InformesAlquilerBuilder() .SetId(i.Id).SetUbicacion(i.IdpropiedadNavigation.Ubicacion) .SetDivisa(i.IddivisaNavigation.Signo) @@ -52,22 +57,24 @@ public class EstadisticaController: ControllerBase { return Ok(informe); } [HttpGet("api/stats/duracionContrato")] - public IActionResult DuracionContrato([FromHeader(Name ="Auth")]string Auth) { + public IActionResult DuracionContrato([FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6); if (validacion1 == false) return Unauthorized(); - + var a = RepositorioEstadisticas.Singleton.ObtenerDataDuracionContratos(); return Ok(a); } [HttpGet("api/tabla/duracionContrato")] - public IActionResult TablaDuracionContrato([FromHeader(Name ="Auth")]string Auth) { + public IActionResult TablaDuracionContrato([FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6); if (validacion1 == false) return Unauthorized(); - + var a = RepositorioEstadisticas.Singleton.TablaObtenerDataDuracionContratos(); return Ok(a); } -} \ No newline at end of file +} -- 2.52.0 From 5df52d8426908a6548bd3dd3505060186d5a9ee1 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 18:32:49 -0300 Subject: [PATCH 37/91] ahi le cambie los checkgrupo por checkpermiso --- Aspnet/Controllers/PropiedadesController.cs | 217 +++++++++++--------- 1 file changed, 123 insertions(+), 94 deletions(-) diff --git a/Aspnet/Controllers/PropiedadesController.cs b/Aspnet/Controllers/PropiedadesController.cs index 5b03bbc..f91f4aa 100644 --- a/Aspnet/Controllers/PropiedadesController.cs +++ b/Aspnet/Controllers/PropiedadesController.cs @@ -6,9 +6,11 @@ using Modelo; namespace AlquilaFacil.Controllers; [ApiController] -public class PropiedadesController: ControllerBase { +public class PropiedadesController : ControllerBase +{ [HttpGet("api/propiedades")] - public IActionResult ListarPropiedades([FromHeader(Name = "Auth")] string Auth, int pag = 0) { + public IActionResult ListarPropiedades([FromHeader(Name = "Auth")] string Auth, int pag = 0) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); if (validacion1 == false) validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); @@ -16,9 +18,12 @@ public class PropiedadesController: ControllerBase { IQueryable ret; - if (pag == 0){ + if (pag == 0) + { ret = RepositorioPropiedades.Singleton.ListarPropiedades(); - } else{ + } + else + { ret = RepositorioPropiedades.Singleton.ListarPropiedadesPorPagina(pag); } @@ -26,31 +31,35 @@ public class PropiedadesController: ControllerBase { } [HttpGet("/api/propiedades/Venta")] - public IActionResult ObtenerPropiedadesParaVenta([FromHeader(Name = "Auth")] string Auth, int pag = 0) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + public IActionResult ObtenerPropiedadesParaVenta([FromHeader(Name = "Auth")] string Auth, int pag = 0) + { + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 16); + if (validacion1 == false) + { return Unauthorized(); } - if (pag<=0) return BadRequest(new { message = "no existe una pagina 0"}); + if (pag <= 0) return BadRequest(new { message = "no existe una pagina 0" }); - pag-=1; + pag -= 1; var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesEnVenta(pag); - if (props == null) return BadRequest(new { message = "no tengo claro que fallo creo que no existen propiedades en venta"}); + if (props == null) return BadRequest(new { message = "no tengo claro que fallo creo que no existen propiedades en venta" }); List l = new(); - foreach (var i in props) { - var p = new PropiedadesVentaDto{ + foreach (var i in props) + { + var p = new PropiedadesVentaDto + { Id = i.Id, Ubicacion = i.Ubicacion, Canthabitaciones = i.Canthabitaciones, Divisa = i.IddivisaNavigation.Signo, - Letra = i.Letra??"", + Letra = i.Letra ?? "", Monto = i.Monto, - Piso = i.Piso??0, - Servicios =string.Join(", ", i.IdServicios.Select(s => s.Descripcion)), + Piso = i.Piso ?? 0, + Servicios = string.Join(", ", i.IdServicios.Select(s => s.Descripcion)), Tipo = i.IdtipropiedadNavigation.Descripcion, }; l.Add(p); @@ -58,31 +67,35 @@ public class PropiedadesController: ControllerBase { int cantpag = RepositorioPropiedades.Singleton.ObtenerPaginasDePropiedadesEnVenta(); - return Ok(new { propiedades = l, cantpaginas = cantpag}); + return Ok(new { propiedades = l, cantpaginas = cantpag }); } [HttpGet("api/propiedades/Venta/Propietario")] - public IActionResult ObtenerPropiedadesVentaDePropietario( [FromHeader(Name = "Auth")] string Auth){ - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + public IActionResult ObtenerPropiedadesVentaDePropietario([FromHeader(Name = "Auth")] string Auth) + { + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15); + if (validacion1 == false) + { return Unauthorized(); } - + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); - var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesAVentaPorDni(cli.Dni); + var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesAVentaPorDni(cli.Dni); List ll = new(); - foreach (var i in props) { - var a = new PropiedadesDto { + foreach (var i in props) + { + var a = new PropiedadesDto + { id = i.Id, Ubicacion = i.Ubicacion, canthabitaciones = i.Canthabitaciones, Iddivisa = i.Iddivisa, - letra = i.Letra??"", + letra = i.Letra ?? "", Monto = (int)i.Monto, //mmmm - piso = i.Piso??0, + piso = i.Piso ?? 0, Servicios = string.Join(", ", i.IdServicios.Select(x => x.Descripcion)), Tipo = i.IdtipropiedadNavigation.Descripcion, }; @@ -92,71 +105,79 @@ public class PropiedadesController: ControllerBase { } [HttpGet("api/propiedad")] - public IActionResult ObtenerPropiedadPorId(int Id, [FromHeader(Name = "Auth")] string Auth) { + public IActionResult ObtenerPropiedadPorId(int Id, [FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); if (validacion1 == false) return Unauthorized(); - if (Id < 0) return BadRequest(new {message ="la id de propiedad no puede ser negativa"}); + if (Id < 0) return BadRequest(new { message = "la id de propiedad no puede ser negativa" }); var ret = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(Id); - if (ret == null) return BadRequest(new {message ="No existe la propiedad"}); + if (ret == null) return BadRequest(new { message = "No existe la propiedad" }); return Ok(ret); } [HttpGet("api/propiedad/cantPagina")] - public IActionResult ObtenerCantidadDePaginas([FromHeader(Name = "Auth")] string Auth, int estado = 0) { + public IActionResult ObtenerCantidadDePaginas([FromHeader(Name = "Auth")] string Auth, int estado = 0) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); if (validacion1 == false) return Unauthorized(); - if (estado < 0) return BadRequest(new {message = "No puede tener un numero menor a 0"}); + if (estado < 0) return BadRequest(new { message = "No puede tener un numero menor a 0" }); int cant; - if(estado == 0){ + if (estado == 0) + { cant = RepositorioPropiedades.Singleton.CuantasPaginas(); - }else{ + } + else + { cant = RepositorioPropiedades.Singleton.CuantasPaginas(estado); } - - return Ok(new {message = cant}); - + + return Ok(new { message = cant }); + } [HttpGet("api/propiedades/Propietario")] - public IActionResult ObtenerPropiedadesPorPropietario ( + public IActionResult ObtenerPropiedadesPorPropietario( [FromHeader(Name = "Email")] string email, - [FromHeader(Name = "Auth")] string Auth) { + [FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) return Unauthorized(); email = email.Trim(); - if (String.IsNullOrEmpty(email)) return BadRequest(new {message ="falta campo email"}); + if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "falta campo email" }); IQueryable ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesPorEmail(email); return Ok(ret); } [HttpGet("api/propiedades/Propietario/Bajas")] - public IActionResult ObtenerPropiedadesPorPropietarioBajas ( + public IActionResult ObtenerPropiedadesPorPropietarioBajas( [FromHeader(Name = "Email")] string email, - [FromHeader(Name = "Auth")] string Auth) { + [FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 8); if (validacion1 == false) return Unauthorized(); email = email.Trim(); - if (String.IsNullOrEmpty(email)) return BadRequest(new {message ="falta campo email"}); + if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "falta campo email" }); IQueryable ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesDeBajaPorEmail(email); return Ok(ret); } [HttpPost("api/propiedad")] - public IActionResult AltaPropiedad([FromBody] AltaPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) { + public IActionResult AltaPropiedad([FromBody] AltaPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1); if (validacion1 == false) return Unauthorized(); @@ -165,9 +186,10 @@ public class PropiedadesController: ControllerBase { if (validacion2 != "") return BadRequest(new { message = validacion2 }); Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email); - if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario"}); + if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario" }); - Propiedade Prop = new Propiedade{ + Propiedade Prop = new Propiedade + { Canthabitaciones = propiedad.Canthabitaciones, Dnipropietario = cli.Dni, Idtipropiedad = propiedad.Idtipropiedad, @@ -179,27 +201,29 @@ public class PropiedadesController: ControllerBase { }; var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop); - return (ret)? - Ok(new { message = "Fue Cargado Correctamente"}) : - BadRequest(new { message = "Fallo al momento de añadir la propiedad a la base de datos"}); + return (ret) ? + Ok(new { message = "Fue Cargado Correctamente" }) : + BadRequest(new { message = "Fallo al momento de añadir la propiedad a la base de datos" }); } [HttpPatch("api/propiedad")] - public IActionResult PatchPropiedad([FromBody] PatchPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) { - + public IActionResult PatchPropiedad([FromBody] PatchPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) + { + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) return Unauthorized(); - + string validacion2 = ValidarPropiedad(propiedad); if (validacion2 != "") return BadRequest(new { message = validacion2 }); - + Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email); - if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario"}); + if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario" }); List servs = RepositorioServicios.Singleton.ObtenerServiciosPorDescripcion(propiedad.Servicios); - - Propiedade Prop = new Propiedade{ + + Propiedade Prop = new Propiedade + { Id = propiedad.id, Canthabitaciones = propiedad.Canthabitaciones, Dnipropietario = cli.Dni, @@ -213,61 +237,64 @@ public class PropiedadesController: ControllerBase { }; bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop, cli.Dni); - return (ret)? - Ok(new {message = "Fue modificado Correctamente"}): - BadRequest(new {message = "Fallo al modificar la base de datos"}); - } + return (ret) ? + Ok(new { message = "Fue modificado Correctamente" }) : + BadRequest(new { message = "Fallo al modificar la base de datos" }); + } [HttpDelete("api/propiedad")] - public IActionResult BajaPropiedad(int id, [FromHeader(Name = "Auth")] string Auth, [FromHeader(Name = "Email")] string email){ + public IActionResult BajaPropiedad(int id, [FromHeader(Name = "Auth")] string Auth, [FromHeader(Name = "Email")] string email) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) return Unauthorized(); - if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "Fallo al identificarse el usuario"}); - if (id <= 0) return BadRequest(new { message = "No es una id valida"}); + if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "Fallo al identificarse el usuario" }); + if (id <= 0) return BadRequest(new { message = "No es una id valida" }); Cliente? propie = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(email); var ret = RepositorioPropiedades.Singleton.BajaPropiedad(id, propie); - return ret ? - Ok(new { message = $"Se Cambio el estado de la propiedad con id {id}"}): - BadRequest(new {message="Fallo al cambiar el estado de la propiedad"}); - } + return ret ? + Ok(new { message = $"Se Cambio el estado de la propiedad con id {id}" }) : + BadRequest(new { message = "Fallo al cambiar el estado de la propiedad" }); + } [HttpPut("api/propiedades/addServicio")] - public IActionResult AñadirServicio([FromBody] ServicioAPropiedadDto Servicios, [FromHeader(Name = "Auth")] string Auth) { + public IActionResult AñadirServicio([FromBody] ServicioAPropiedadDto Servicios, [FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) return Unauthorized(); - if (Servicios.propiedadid <= 0) return BadRequest(new {message ="No puede tener una id negativa o cero"}); - if (Servicios.idServicios.Count() < 1) return BadRequest(new {message ="Falta añadir servicios"}); - if (Servicios.idServicios.Any(x => x<= 0)) return BadRequest(new {message ="No tienen haber ids negativas o cero de servicio"}); + if (Servicios.propiedadid <= 0) return BadRequest(new { message = "No puede tener una id negativa o cero" }); + if (Servicios.idServicios.Count() < 1) return BadRequest(new { message = "Falta añadir servicios" }); + if (Servicios.idServicios.Any(x => x <= 0)) return BadRequest(new { message = "No tienen haber ids negativas o cero de servicio" }); var serv = RepositorioServicios.Singleton.ObtenerServiciosPorPropiedad(Servicios.propiedadid); - + bool validacion2 = Servicios.idServicios.Any(x => serv.Contains(x)); - if (validacion2 == true) return BadRequest(new {message ="Hay elementos repetidos"}); + if (validacion2 == true) return BadRequest(new { message = "Hay elementos repetidos" }); bool ret = RepositorioPropiedades. Singleton.AñadirServicioAPropiedad(Servicios.propiedadid, Servicios.idServicios); return ret ? - Ok(new {message ="Los Servicios Se Cargaron correctamente a la propiedad"}) : BadRequest(new {message ="No se pudo Cargar los Servicios a la propiedad"}); + Ok(new { message = "Los Servicios Se Cargaron correctamente a la propiedad" }) : BadRequest(new { message = "No se pudo Cargar los Servicios a la propiedad" }); } [HttpPut("api/propiedades/RmServicio")] - public IActionResult EliminarServicio([FromBody] ServicioAPropiedadDto servicio, [FromHeader(Name = "Auth")] string Auth) { + public IActionResult EliminarServicio([FromBody] ServicioAPropiedadDto servicio, [FromHeader(Name = "Auth")] string Auth) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) return Unauthorized(); - if (servicio.propiedadid <= 0) return BadRequest(new {message ="No puede tener una id negativa o cero"}); - if (servicio.idServicios.Count() < 1) return BadRequest(new {message ="Falta añadir servicios"}); - if (servicio.idServicios.Any(x => x<= 0)) return BadRequest(new {message ="No tienen haber ids negativas o cero de servicio"}); + if (servicio.propiedadid <= 0) return BadRequest(new { message = "No puede tener una id negativa o cero" }); + if (servicio.idServicios.Count() < 1) return BadRequest(new { message = "Falta añadir servicios" }); + if (servicio.idServicios.Any(x => x <= 0)) return BadRequest(new { message = "No tienen haber ids negativas o cero de servicio" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); @@ -276,49 +303,51 @@ public class PropiedadesController: ControllerBase { var repetidos = serv.Intersect(servicio.idServicios); bool ret = RepositorioPropiedades.Singleton.BajaServiciosAPropiedad(servicio.propiedadid, servicio.idServicios, cli.Dni); - + return ret ? - Ok(new {message ="Se Eliminaron los servicios seleccionados de la propiedad"}) : BadRequest(new {message ="Fallo al eliminarse los servicios de la propiedad"}); + Ok(new { message = "Se Eliminaron los servicios seleccionados de la propiedad" }) : BadRequest(new { message = "Fallo al eliminarse los servicios de la propiedad" }); } - private string ValidarPropiedad(AltaPropiedadDto prop) { + private string ValidarPropiedad(AltaPropiedadDto prop) + { if (prop == null) return "Esta mal formado el body de la request"; string ret = ""; if (String.IsNullOrEmpty(prop.Email)) ret += "Falta Definir un email de propietario\n"; - + if (prop.Canthabitaciones < 0) ret += "No se puede tener una cantidad de habitaciones negativa\n"; - + if (prop.Idtipropiedad <= 0) ret += "No tiene un tipo de propiedad asociada\n"; - + if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n"; - - if (prop.Monto<=1) ret += "El monto tiene que ser como minimo mayor a 0"; - - if (prop.Iddivisa<0 || prop.Iddivisa>1) ret += "se tiene que elejir entre AR$ y US$"; + + if (prop.Monto <= 1) ret += "El monto tiene que ser como minimo mayor a 0"; + + if (prop.Iddivisa < 0 || prop.Iddivisa > 1) ret += "se tiene que elejir entre AR$ y US$"; return ret; } - private string ValidarPropiedad(PatchPropiedadDto prop) { + private string ValidarPropiedad(PatchPropiedadDto prop) + { if (prop == null) return "Esta mal formado el body de la request"; string ret = ""; - if (prop.id <1) ret += "No Cargo el dato de id"; + if (prop.id < 1) ret += "No Cargo el dato de id"; if (String.IsNullOrEmpty(prop.Email)) ret += "Falta Definir un email de propietario\n"; - - if (prop.id <1 ) ret += "No puede haber una id menor a 1\n"; - + + if (prop.id < 1) ret += "No puede haber una id menor a 1\n"; + if (prop.Canthabitaciones < 0) ret += "No se puede tener una cantidad de habitaciones negativa\n"; if (prop.tipo <= 0) ret += "No tiene un tipo de propiedad asociada\n"; if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n"; - if (prop.Monto<=1) ret += "El monto tiene que ser como minimo mayor a 0"; - - if (prop.Iddivisa<0 || prop.Iddivisa>1) ret += "se tiene que elejir entre AR$ y US$"; + if (prop.Monto <= 1) ret += "El monto tiene que ser como minimo mayor a 0"; + + if (prop.Iddivisa < 0 || prop.Iddivisa > 1) ret += "se tiene que elejir entre AR$ y US$"; return ret; -- 2.52.0 From b6d78747c869a5d127cb65755f3e45cf18c0b2ff Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 20:24:22 -0300 Subject: [PATCH 38/91] Replace RepositorioGrupos with RepositorioPermisos --- Aspnet/Controllers/DefectoController.cs | 69 ++++++++++++++----------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/Aspnet/Controllers/DefectoController.cs b/Aspnet/Controllers/DefectoController.cs index 6096e7c..189384a 100644 --- a/Aspnet/Controllers/DefectoController.cs +++ b/Aspnet/Controllers/DefectoController.cs @@ -7,17 +7,21 @@ using Modelo; namespace AlquilaFacil.Controllers; [ApiController] -public class DefectoController: ControllerBase { +public class DefectoController : ControllerBase +{ [HttpGet("api/defectos")] - public IActionResult ObtenerDefectosEnContrato([FromHeader(Name = "Auth")] string Auth, long Idcontrato = 0) { - if (Idcontrato <= 0) return BadRequest( new { message = "La id de contrato no puede ser menor o igual a 0"}); + public IActionResult ObtenerDefectosEnContrato([FromHeader(Name = "Auth")] string Auth, long Idcontrato = 0) + { + if (Idcontrato <= 0) return BadRequest(new { message = "La id de contrato no puede ser menor o igual a 0" }); if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ - validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12); + if (validacion1 == false) + { + validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11); + if (validacion1 == false) + { return Unauthorized(); } } @@ -26,19 +30,20 @@ public class DefectoController: ControllerBase { if (cli == null) return Unauthorized(); Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(Idcontrato); - if (cont == null) return BadRequest(new { message = "No hay contrato por esa id"}); + if (cont == null) return BadRequest(new { message = "No hay contrato por esa id" }); - if (cont.Dniinquilino != cli.Dni && cont.Dnipropietario != cli.Dni) return BadRequest(new { message = "no deberias tener acceso a esto"}); + if (cont.Dniinquilino != cli.Dni && cont.Dnipropietario != cli.Dni) return BadRequest(new { message = "no deberias tener acceso a esto" }); var l = RepositorioDefectos.Singleton.ObtenerDefectosPorIdContrato(Idcontrato); List ll = new(); - foreach (var i in l){ + foreach (var i in l) + { var n = new DefectoDtoBuilder() - .SetId(i.Id) + .SetId(i.Id) .SetDesc(i.Descripcion) .SetCosto(i.Costo) .SetEstado(i.IdestadoNavigation.Descipcion) - .SetIdContrato(i.Idcontrato??0) + .SetIdContrato(i.Idcontrato ?? 0) .SetPagaInquilino(i.Pagainquilino) .SetDivisa(i.IddivisaNavigation.Signo) .Build(); @@ -48,54 +53,58 @@ public class DefectoController: ControllerBase { } [HttpPost("api/defecto")] - public IActionResult AltaDefecto([FromHeader(Name = "Auth")] string Auth, AltaDefectoDto data) { + public IActionResult AltaDefecto([FromHeader(Name = "Auth")] string Auth, AltaDefectoDto data) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11); if (validacion1 == false) return Unauthorized(); - Cliente? cli =RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); string r = ValidarDto(data); if (r != "") return BadRequest(new { message = r }); - Defecto defecto = new Defecto{ + Defecto defecto = new Defecto + { Costo = data.Costo, Descripcion = data.Descripcion, Idcontrato = data.Idcontrato, Iddivisa = data.Iddivisa, - Pagainquilino = data.Pagainquilino==0?0Lu:1Lu, + Pagainquilino = data.Pagainquilino == 0 ? 0Lu : 1Lu, Idestado = 1, }; var b = RepositorioDefectos.Singleton.AltaDefecto(defecto, cli.Dni); - return b ?Ok(new { message = "Se cargo el Defecto en el sistema"}):BadRequest(new { message ="No se pudo cargar el defecto en el sistema"}); + return b ? Ok(new { message = "Se cargo el Defecto en el sistema" }) : BadRequest(new { message = "No se pudo cargar el defecto en el sistema" }); } - private string ValidarDto(AltaDefectoDto d){ - string ret =""; + private string ValidarDto(AltaDefectoDto d) + { + string ret = ""; if (d == null) return "Dto nulo"; - if (d.Iddivisa <0 || d.Iddivisa>1) ret +="No son divisas validas\n"; - if (d.Descripcion == "") ret+="La descripcion no puede estar vacia\n"; - if (d.Idcontrato<=0)ret += "No puede haber un id de contrato igual o menor a 0\n"; + if (d.Iddivisa < 0 || d.Iddivisa > 1) ret += "No son divisas validas\n"; + if (d.Descripcion == "") ret += "La descripcion no puede estar vacia\n"; + if (d.Idcontrato <= 0) ret += "No puede haber un id de contrato igual o menor a 0\n"; return ret; } - [HttpPut("api/defecto/marcarpago")] - public IActionResult MarcarPago([FromHeader(Name = "Auth")] string Auth, long iddefecto = 0) { + [HttpPut("api/defecto/marcarpago")] + public IActionResult MarcarPago([FromHeader(Name = "Auth")] string Auth, long iddefecto = 0) + { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12); if (validacion1 == false) return Unauthorized(); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); - if (cli==null) return Unauthorized(); + if (cli == null) return Unauthorized(); - if (iddefecto<=0) return BadRequest(new { message = "No hay canones con id 0 o menor"}); + if (iddefecto <= 0) return BadRequest(new { message = "No hay canones con id 0 o menor" }); bool ret = RepositorioDefectos.Singleton.MarcarPago(iddefecto, cli.Dni); - + return ret ? - Ok(new { message = "Se marco como pagado" }):BadRequest(new { message = "Fallo el acceso a la base de datos o no se encontro el defecto" }); + Ok(new { message = "Se marco como pagado" }) : BadRequest(new { message = "Fallo el acceso a la base de datos o no se encontro el defecto" }); } } -- 2.52.0 From 6194e5b4b99dadcb3f731cc18bde23e6c3e3ca88 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 20:41:39 -0300 Subject: [PATCH 39/91] Refactor code formatting --- Aspnet/Controllers/VentaController.cs | 352 +++++++++++++++----------- 1 file changed, 205 insertions(+), 147 deletions(-) diff --git a/Aspnet/Controllers/VentaController.cs b/Aspnet/Controllers/VentaController.cs index 76706ca..fff7cf8 100644 --- a/Aspnet/Controllers/VentaController.cs +++ b/Aspnet/Controllers/VentaController.cs @@ -12,27 +12,31 @@ using Modelo; namespace AlquilaFacil.Controllers; [ApiController] -public class VentaController:ControllerBase { +public class VentaController : ControllerBase +{ [HttpPost("api/venta/AceptarConsultaVenta")] - public IActionResult AceptarConsultaVenta([FromHeader(Name="Auth")]string Auth, NotificacionMarcarLeidoDto dto) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + public IActionResult AceptarConsultaVenta([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto dto) + { + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15); + if (validacion1 == false) + { return Unauthorized(); } - if (dto.Email == "") return BadRequest(new { message = "Falta dato Email"}); + if (dto.Email == "") return BadRequest(new { message = "Falta dato Email" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) Unauthorized(); - if (cli.Email != dto.Email) return BadRequest(new {message = "El token de autorizacion no corresponde a tu usuario"}); + if (cli.Email != dto.Email) return BadRequest(new { message = "El token de autorizacion no corresponde a tu usuario" }); RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha); - Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha); - if (n == null) return BadRequest(new { message = "No se encuentra la notificacion"}); + Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha); + if (n == null) return BadRequest(new { message = "No se encuentra la notificacion" }); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(n.Idpropiedad); - if (prop == null) return BadRequest(new { message = "No se encuentra una propiedad por ese id"}); - Venta? v = new Venta{ + if (prop == null) return BadRequest(new { message = "No se encuentra una propiedad por ese id" }); + Venta? v = new Venta + { Fechainicio = DateTime.Now, IdVendedor = prop.Dnipropietario, IdComprador = n.Dniremitente, @@ -44,7 +48,8 @@ public class VentaController:ControllerBase { }; bool ret = RepositorioVentas.Singleton.IniciarVenta(v, cli.Dni); - if (ret){ + if (ret) + { var noti = new NotificacioneBuilder() .SetAccion("Notificacion") .SetMensaje("Debe Realizar el pago para que se registre el traspaso de la propiedad") @@ -56,25 +61,27 @@ public class VentaController:ControllerBase { .Build(); ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); } - return ret? - Ok(new { message = "Se inicio la venta"}):BadRequest(new { message ="fallo al iniciar la venta"}); + return ret ? + Ok(new { message = "Se inicio la venta" }) : BadRequest(new { message = "fallo al iniciar la venta" }); } [HttpPost("api/venta/CancelarConsultaVenta")] - public IActionResult CancelarConsultaVenta([FromHeader(Name="Auth")]string Auth, NotificacionMarcarLeidoDto dto) { + public IActionResult CancelarConsultaVenta([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto dto) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } - if (dto.Email == "") return BadRequest(new { message = "Falta dato Email"}); + if (dto.Email == "") return BadRequest(new { message = "Falta dato Email" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) Unauthorized(); - if (cli.Email != dto.Email) return BadRequest(new {message = "El token de autorizacion no corresponde a tu usuario"}); + if (cli.Email != dto.Email) return BadRequest(new { message = "El token de autorizacion no corresponde a tu usuario" }); RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha); - Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha); + Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha); var noti = new NotificacioneBuilder() .SetAccion("Notificacion") .SetMensaje("El propietario no quiere vender") @@ -84,90 +91,98 @@ public class VentaController:ControllerBase { .SetIdpropiedad(n.Idpropiedad) .SetFecha(DateTime.Now) .Build(); - + var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); return ret ? - Ok(new{message = "Se Envio una notificacion"}):BadRequest(new{message = "Fallo al Descartar Consulta"}); + Ok(new { message = "Se Envio una notificacion" }) : BadRequest(new { message = "Fallo al Descartar Consulta" }); } [HttpGet("/api/propiedad/EstaALaVenta")] - public IActionResult EstaALaVenta([FromHeader(Name="Auth")]string Auth, int idprop=0) { + public IActionResult EstaALaVenta([FromHeader(Name = "Auth")] string Auth, int idprop = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } - if (idprop<=0) return BadRequest(new { message = "No hay propiedades con id 0 o menor"}); + if (idprop <= 0) return BadRequest(new { message = "No hay propiedades con id 0 o menor" }); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(idprop); - if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id"}); - return Ok(new { EstaAVenta = prop.Idestado ==4?true:false}); + if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id" }); + return Ok(new { EstaAVenta = prop.Idestado == 4 ? true : false }); } [HttpPut("/api/propiedad/setPropiedadAVenta")] - public IActionResult setPropiedadAVenta([FromHeader(Name="Auth")]string Auth, SetVentaDto dto) { + public IActionResult setPropiedadAVenta([FromHeader(Name = "Auth")] string Auth, SetVentaDto dto) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } - if (dto.iddivisa != 0 && dto.iddivisa!=1) return BadRequest(new { message = "no hay una divisa por esa id"}); - if (dto.idpropiedad<=0) return BadRequest(new { message = "No hay propiedades con id 0 o menor"}); - if (dto.monto<1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1"}); + if (dto.iddivisa != 0 && dto.iddivisa != 1) return BadRequest(new { message = "no hay una divisa por esa id" }); + if (dto.idpropiedad <= 0) return BadRequest(new { message = "No hay propiedades con id 0 o menor" }); + if (dto.monto < 1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad); - if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id"}); + if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id" }); if (cli.Dni != prop.Dnipropietario) return Unauthorized(); var ret = RepositorioVentas.Singleton.SetVenta(prop.Id, dto.monto, dto.iddivisa, cli.Dni); - return ret? - Ok(new { message = "Se puso la propiedad de venta"}) : BadRequest(new { message = "No se pudo poner a la Venta"}); + return ret ? + Ok(new { message = "Se puso la propiedad de venta" }) : BadRequest(new { message = "No se pudo poner a la Venta" }); } [HttpPut("/api/propiedad/unsetPropiedadAVenta")] - public IActionResult unsetPropiedadAVenta([FromHeader(Name="Auth")]string Auth, SetVentaDto dto) { + public IActionResult unsetPropiedadAVenta([FromHeader(Name = "Auth")] string Auth, SetVentaDto dto) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } - - if (dto.iddivisa != 0 && dto.iddivisa!=1) return BadRequest(new { message = "no hay una divisa por esa id"}); - if (dto.idpropiedad<=0) return BadRequest(new { message = "No hay propiedades con id 0 o menor"}); - if (dto.monto<1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1"}); + + if (dto.iddivisa != 0 && dto.iddivisa != 1) return BadRequest(new { message = "no hay una divisa por esa id" }); + if (dto.idpropiedad <= 0) return BadRequest(new { message = "No hay propiedades con id 0 o menor" }); + if (dto.monto < 1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad); - if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id"}); + if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id" }); if (cli.Dni != prop.Dnipropietario) return Unauthorized(); bool ret = RepositorioVentas.Singleton.UnSetVenta(prop.Id, dto.monto, dto.iddivisa, cli.Dni); - return ret? - Ok(new { message = "Se Bajo la propiedad de venta"}) : BadRequest(new { message = "No se pudo Bajar de venta"}); + return ret ? + Ok(new { message = "Se Bajo la propiedad de venta" }) : BadRequest(new { message = "No se pudo Bajar de venta" }); } [HttpPost("/api/ventas/ejercerOpcionVenta")] - public IActionResult EjercerOpcionVenta([FromHeader(Name="Auth")]string Auth, [FromQuery]long idcontrato=0) { + public IActionResult EjercerOpcionVenta([FromHeader(Name = "Auth")] string Auth, [FromQuery] long idcontrato = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } - if (idcontrato <= 0) return BadRequest(new { message = "No pueden hacer cotratos con id 0 o menor"}); + if (idcontrato <= 0) return BadRequest(new { message = "No pueden hacer cotratos con id 0 o menor" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato); - if (cont == null || cont.IdventaNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id"}); - if (cont.Tieneopcionventa == 0) return BadRequest(new { message = "No tiene opcion de venta"}); - if (puedeEjercer(cont) == false) return BadRequest(new { message = "No cumple con los requisitos para ejercer la opcion de compra"}); + if (cont == null || cont.IdventaNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id" }); + if (cont.Tieneopcionventa == 0) return BadRequest(new { message = "No tiene opcion de venta" }); + if (puedeEjercer(cont) == false) return BadRequest(new { message = "No cumple con los requisitos para ejercer la opcion de compra" }); Venta venta = cont.IdventaNavigation; venta.IdVendedor = cont.Dnipropietario; @@ -177,31 +192,34 @@ public class VentaController:ControllerBase { bool ret = RepositorioVentas.Singleton.PatchVenta(venta, cli.Dni); - return ret? - Ok(new { message = "Se ejercio la opcion de venta"}): - BadRequest(new { message = "No se pude ejercer la opcion de venta"}); + return ret ? + Ok(new { message = "Se ejercio la opcion de venta" }) : + BadRequest(new { message = "No se pude ejercer la opcion de venta" }); } [HttpPost("/api/ventas/subirReciboPago")] - public async Task SubirRecibo([FromHeader(Name="Auth")]string Auth, IFormFile file, long idventa ) { + public async Task SubirRecibo([FromHeader(Name = "Auth")] string Auth, IFormFile file, long idventa) + { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } - if (idventa <=0) return BadRequest(new { message = "Las id 0 o menor no son validas" }); + if (idventa <= 0) return BadRequest(new { message = "Las id 0 o menor no son validas" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); - if (venta == null) return BadRequest(new { message = "no hay una venta por esa id"}); + if (venta == null) return BadRequest(new { message = "no hay una venta por esa id" }); - if (cli.Dni !=venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized(); + if (cli.Dni != venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized(); if (file == null) return BadRequest(new { message = "Debe subir un archivo." }); if (file.ContentType != "application/pdf") return BadRequest(new { message = "El archivo debe ser un documento PDF." }); @@ -209,39 +227,45 @@ public class VentaController:ControllerBase { string nuevoNombreArchivo = $"id:{venta.Id}-comprador:{venta.IdComprador}-vendedor:{venta.IdVendedor}-idprop:{venta.Idpropiedad}.pdf"; bool ret = await subirContrato(file, nuevoNombreArchivo); - if(ret == false) return BadRequest(new {message = "No se pudo subir el archivo"}); + if (ret == false) return BadRequest(new { message = "No se pudo subir el archivo" }); ret = RepositorioVentas.Singleton.SetUrlRecibo(venta.Id, nuevoNombreArchivo, cli.Dni); - if (ret == false) return BadRequest(new { message = "no se pudo guardar el nombre del archivo subido"}); + if (ret == false) return BadRequest(new { message = "no se pudo guardar el nombre del archivo subido" }); - return Ok(new { message = "Se Subio el Recibo"}); + return Ok(new { message = "Se Subio el Recibo" }); } private readonly IMinioClient mc; - public VentaController(IMinioClient minioClient) { + public VentaController(IMinioClient minioClient) + { mc = minioClient; - if (mc == null){ - MinioConfigcus? mcon = JsonSerializer.Deserialize(System.IO.File.ReadAllText("./settings.json"))?? null; + if (mc == null) + { + MinioConfigcus? mcon = JsonSerializer.Deserialize(System.IO.File.ReadAllText("./settings.json")) ?? null; if (mcon == null) throw new Exception(); mc = new MinioClient().WithCredentials(mcon.usr, mcon.scrt) .WithEndpoint("0.0.0.0:9000") .WithSSL(false) .Build(); - } + } } - private async Task subirContrato(IFormFile f, string flname) { - try { + private async Task subirContrato(IFormFile f, string flname) + { + try + { var buck = new BucketExistsArgs().WithBucket("alquilafacil"); bool encontrado = await mc.BucketExistsAsync(buck).ConfigureAwait(false); - if(!encontrado){ + if (!encontrado) + { var mb = new MakeBucketArgs().WithBucket("alquilafacil"); await mc.MakeBucketAsync(mb).ConfigureAwait(false); } - using (var stream = new MemoryStream()){ + using (var stream = new MemoryStream()) + { await f.CopyToAsync(stream); - stream.Position=0; + stream.Position = 0; PutObjectArgs putbj = new PutObjectArgs() .WithBucket("alquilafacil") .WithObject(flname) @@ -251,118 +275,140 @@ public class VentaController:ControllerBase { await mc.PutObjectAsync(putbj); } return true; - } catch (Exception e ) { + } + catch (Exception e) + { Console.Error.WriteLine(e.Message); return false; } } [HttpGet("/api/ventas/verRecibo")] - public IActionResult verRecibo([FromHeader(Name="Auth")]string Auth, long idventa=0){ + public IActionResult verRecibo([FromHeader(Name = "Auth")] string Auth, long idventa = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } - if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"}); + if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); - if (venta == null) return BadRequest(new { message = "no hay una venta con esa id"}); + if (venta == null) return BadRequest(new { message = "no hay una venta con esa id" }); if (cli.Dni != venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized(); - try{ - var memstream = new MemoryStream(); + try + { + var memstream = new MemoryStream(); var goa = new GetObjectArgs() .WithBucket("alquilafacil") .WithObject(venta.UrlRecibo) - .WithCallbackStream(stream => { - memstream.Position=0; + .WithCallbackStream(stream => + { + memstream.Position = 0; stream.CopyTo(memstream); - }); - + }); + mc.GetObjectAsync(goa).Wait(); memstream.Position = 0; - + if (memstream.Length == 0) return BadRequest(new { message = "El archivo está vacío" }); - + return File(memstream, "application/pdf", venta.UrlRecibo); - - } catch (Exception e){ + + } + catch (Exception e) + { Console.Error.WriteLine(e); - return BadRequest(new { message = "Fallo al intentar obtener el archivo del almacenamiento o este no existe"}); + return BadRequest(new { message = "Fallo al intentar obtener el archivo del almacenamiento o este no existe" }); } } - + [HttpPost("/api/ventas/propietarioverifica")] - public IActionResult PropietarioVerifica([FromHeader(Name="Auth")]string Auth, long idventa=0) { + public IActionResult PropietarioVerifica([FromHeader(Name = "Auth")] string Auth, long idventa = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } - if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"}); + if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); - if (ventas == null) return BadRequest(new { message ="No hay una venta con ese id"}); + if (ventas == null) return BadRequest(new { message = "No hay una venta con ese id" }); if (ventas.IdVendedor != cli.Dni) return Unauthorized(); bool ret = RepositorioVentas.Singleton.EfectuarVenta(idventa); - return ret ? Ok(new { message = "Se traspaso la propiedad"}): BadRequest(new { message = ""}); + return ret ? Ok(new { message = "Se traspaso la propiedad" }) : BadRequest(new { message = "" }); } - + [HttpGet("/api/venta")] - public IActionResult ObtenerVenta([FromHeader(Name="Auth")]string Auth, long idventa=0) { + public IActionResult ObtenerVenta([FromHeader(Name = "Auth")] string Auth, long idventa = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } - if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"}); + if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); - if (ventas == null) return BadRequest(new { message ="No hay una venta con ese id"}); - if (ventas.IdVendedor !=cli.Dni && ventas.IdComprador != cli.Dni) return Unauthorized(); + if (ventas == null) return BadRequest(new { message = "No hay una venta con ese id" }); + if (ventas.IdVendedor != cli.Dni && ventas.IdComprador != cli.Dni) return Unauthorized(); var v = new VentasDtoBuilder() - .SetId(ventas.Id) - .SetMonto(ventas.Monto) - .SetDivisa(ventas.IddivisaNavigation.Signo) - .SetUbicacion(ventas.IdpropiedadNavigation.Ubicacion) - .SetNombreVendedor($"{ventas.IdVendedorNavigation.Nombre} {ventas.IdVendedorNavigation.Apellido}") - .SetIdVendedor(ventas.IdVendedor??0) - .SetNombreComprador($"{ventas.IdCompradorNavigation.Nombre} {ventas.IdCompradorNavigation.Apellido}") - .SetIdComprador(ventas.IdComprador??0) - .SetEstado(ventas.IdestadoNavigation.Descripcion??"") + .SetId(ventas.Id) + .SetMonto(ventas.Monto) + .SetDivisa(ventas.IddivisaNavigation.Signo) + .SetUbicacion(ventas.IdpropiedadNavigation.Ubicacion) + .SetNombreVendedor($"{ventas.IdVendedorNavigation.Nombre} {ventas.IdVendedorNavigation.Apellido}") + .SetIdVendedor(ventas.IdVendedor ?? 0) + .SetNombreComprador($"{ventas.IdCompradorNavigation.Nombre} {ventas.IdCompradorNavigation.Apellido}") + .SetIdComprador(ventas.IdComprador ?? 0) + .SetEstado(ventas.IdestadoNavigation.Descripcion ?? "") .Build(); - return Ok(new { data = v, iscomprador = (ventas.IdComprador==cli.Dni)?true:false, - necesitaRecibo = ventas.UrlRecibo==null?true:false}); + return Ok(new + { + data = v, + iscomprador = (ventas.IdComprador == cli.Dni) ? true : false, + necesitaRecibo = ventas.UrlRecibo == null ? true : false + }); } [HttpGet("/api/ventas")] - public IActionResult ObtenerVentas([FromHeader(Name="Auth")]string Auth) { + public IActionResult ObtenerVentas([FromHeader(Name = "Auth")] string Auth) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } @@ -371,20 +417,21 @@ public class VentaController:ControllerBase { if (cli == null) return Unauthorized(); var ventas = RepositorioVentas.Singleton.ObtenerVentasPorDni(cli.Dni); - if (ventas == null) return BadRequest(new { message ="no estas involucrado en ninguna venta o compra"}); + if (ventas == null) return BadRequest(new { message = "no estas involucrado en ninguna venta o compra" }); List lista = new(); - foreach (var i in ventas) { + foreach (var i in ventas) + { var v = new VentasDtoBuilder() - .SetId(i.Id) - .SetMonto(i.Monto) - .SetDivisa(i.IddivisaNavigation.Signo) - .SetUbicacion(i.IdpropiedadNavigation.Ubicacion) - .SetNombreVendedor($"{i.IdVendedorNavigation.Nombre} {i.IdVendedorNavigation.Apellido}") - .SetIdVendedor(i.IdVendedor??0) - .SetNombreComprador($"{i.IdCompradorNavigation.Nombre} {i.IdCompradorNavigation.Apellido}") - .SetIdComprador(i.IdComprador??0) - .SetEstado(i.IdestadoNavigation.Descripcion??"") + .SetId(i.Id) + .SetMonto(i.Monto) + .SetDivisa(i.IddivisaNavigation.Signo) + .SetUbicacion(i.IdpropiedadNavigation.Ubicacion) + .SetNombreVendedor($"{i.IdVendedorNavigation.Nombre} {i.IdVendedorNavigation.Apellido}") + .SetIdVendedor(i.IdVendedor ?? 0) + .SetNombreComprador($"{i.IdCompradorNavigation.Nombre} {i.IdCompradorNavigation.Apellido}") + .SetIdComprador(i.IdComprador ?? 0) + .SetEstado(i.IdestadoNavigation.Descripcion ?? "") .Build(); lista.Add(v); } @@ -392,43 +439,51 @@ public class VentaController:ControllerBase { } [HttpGet("/api/opcionventa")] - public IActionResult ObtenerDto([FromHeader(Name="Auth")]string Auth, long idcontrato=0) { + public IActionResult ObtenerDto([FromHeader(Name = "Auth")] string Auth, long idcontrato = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } - if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0"}); + if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato); - if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id"}); + if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id" }); var dto = new OpcionVentaDtoBuilder() - .SetId(cont.Idventa??0) + .SetId(cont.Idventa ?? 0) .SetMonto(cont.IdventaNavigation.Monto) .SetDivisa(cont.IdventaNavigation.IddivisaNavigation.Signo) .SetEnOrden(puedeEjercer(cont)) - .SetFueEjercido(cont.IdventaNavigation.Idestado??0) + .SetFueEjercido(cont.IdventaNavigation.Idestado ?? 0) .Build(); - + return Ok(dto); } - private bool puedeEjercer(Contrato c) { + private bool puedeEjercer(Contrato c) + { bool ret = c.Idcanons.All(x => x.Pagado == 1); - if (ret) { + if (ret) + { var canonConFechaMasTardia = c.Idcanons.OrderByDescending(x => x.Fecha).FirstOrDefault(); - if (canonConFechaMasTardia != null && canonConFechaMasTardia.Fecha.Year >= DateTime.Now.Year - && canonConFechaMasTardia.Fecha.Month >= DateTime.Now.Month) { + if (canonConFechaMasTardia != null && canonConFechaMasTardia.Fecha.Year >= DateTime.Now.Year + && canonConFechaMasTardia.Fecha.Month >= DateTime.Now.Month) + { ret = true; - }else{ + } + else + { ret = false; } } @@ -437,24 +492,27 @@ public class VentaController:ControllerBase { } [HttpGet("/api/contrato/tieneopcionventa")] - public IActionResult TieneOpcionVenta([FromHeader(Name="Auth")]string Auth, long idcontrato=0) { + public IActionResult TieneOpcionVenta([FromHeader(Name = "Auth")] string Auth, long idcontrato = 0) + { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false){ + if (validacion1 == false) + { validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) { + if (validacion1 == false) + { return Unauthorized(); } } - if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0"}); - + if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0" }); + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return Unauthorized(); Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(idcontrato); - if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id"}); - if (cont.Dniinquilino !=cli.Dni && cont.Dnipropietario != cli.Dni) return Unauthorized(); + if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id" }); + if (cont.Dniinquilino != cli.Dni && cont.Dnipropietario != cli.Dni) return Unauthorized(); - return Ok( new { message = cont.Tieneopcionventa}); + return Ok(new { message = cont.Tieneopcionventa }); } -} \ No newline at end of file +} -- 2.52.0 From 11f4d38f8bbad9d2118e69ae76e69bd956be308b Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 28 Apr 2025 21:08:18 -0300 Subject: [PATCH 40/91] Remplazados algunos checkgrupos faltan 8 --- Aspnet/Controllers/VentaController.cs | 37 ++++++++++----------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/Aspnet/Controllers/VentaController.cs b/Aspnet/Controllers/VentaController.cs index fff7cf8..a7e91f9 100644 --- a/Aspnet/Controllers/VentaController.cs +++ b/Aspnet/Controllers/VentaController.cs @@ -68,7 +68,7 @@ public class VentaController : ControllerBase [HttpPost("api/venta/CancelarConsultaVenta")] public IActionResult CancelarConsultaVenta([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto dto) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15); if (validacion1 == false) { return Unauthorized(); @@ -97,7 +97,7 @@ public class VentaController : ControllerBase Ok(new { message = "Se Envio una notificacion" }) : BadRequest(new { message = "Fallo al Descartar Consulta" }); } - [HttpGet("/api/propiedad/EstaALaVenta")] + [HttpGet("/api/propiedad/EstaALaVenta")] //Creo que esto es codigo muerto public IActionResult EstaALaVenta([FromHeader(Name = "Auth")] string Auth, int idprop = 0) { var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); @@ -115,8 +115,9 @@ public class VentaController : ControllerBase [HttpPut("/api/propiedad/setPropiedadAVenta")] public IActionResult setPropiedadAVenta([FromHeader(Name = "Auth")] string Auth, SetVentaDto dto) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); - if (validacion1 == false) + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); + var validacion2 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 8); + if (validacion1 == false || validacion2 == false) { return Unauthorized(); } @@ -141,7 +142,7 @@ public class VentaController : ControllerBase [HttpPut("/api/propiedad/unsetPropiedadAVenta")] public IActionResult unsetPropiedadAVenta([FromHeader(Name = "Auth")] string Auth, SetVentaDto dto) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15); if (validacion1 == false) { return Unauthorized(); @@ -169,7 +170,7 @@ public class VentaController : ControllerBase [HttpPost("/api/ventas/ejercerOpcionVenta")] public IActionResult EjercerOpcionVenta([FromHeader(Name = "Auth")] string Auth, [FromQuery] long idcontrato = 0) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11); if (validacion1 == false) { return Unauthorized(); @@ -201,14 +202,10 @@ public class VentaController : ControllerBase public async Task SubirRecibo([FromHeader(Name = "Auth")] string Auth, IFormFile file, long idventa) { if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13); if (validacion1 == false) { - validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) - { - return Unauthorized(); - } + return Unauthorized(); } if (idventa <= 0) return BadRequest(new { message = "Las id 0 o menor no son validas" }); @@ -286,14 +283,10 @@ public class VentaController : ControllerBase [HttpGet("/api/ventas/verRecibo")] public IActionResult verRecibo([FromHeader(Name = "Auth")] string Auth, long idventa = 0) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13); if (validacion1 == false) { - validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) - { - return Unauthorized(); - } + return Unauthorized(); } if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" }); @@ -336,14 +329,10 @@ public class VentaController : ControllerBase [HttpPost("/api/ventas/propietarioverifica")] public IActionResult PropietarioVerifica([FromHeader(Name = "Auth")] string Auth, long idventa = 0) { - var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13); if (validacion1 == false) { - validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); - if (validacion1 == false) - { - return Unauthorized(); - } + return Unauthorized(); } if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" }); -- 2.52.0 From 402c98eb6b14e358f98c93cb0ebe2ae3ec202623 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 5 May 2025 12:45:01 -0300 Subject: [PATCH 41/91] ya estaba implementado --- Modelo/RepositorioPermisos.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index f8ab3cd..0b68310 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -38,8 +38,6 @@ public class RepositorioPermisos : RepositorioBase public bool CheckPermisos(string token, int idpermiso) { - //WIP Aca tengo que modificar esto para que haga una busqueda de profundidad para los permisos - // var con = Context; bool tienePermiso = false; -- 2.52.0 From 4f4458150382fd4eb302b27bce6bbf98ab80740a Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 5 May 2025 13:25:01 -0300 Subject: [PATCH 42/91] Add user profile button to navigation bar --- Front/public/user.svg | 1 + Front/src/Componentes/NavBarAutocompletable.svelte | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 Front/public/user.svg diff --git a/Front/public/user.svg b/Front/public/user.svg new file mode 100644 index 0000000..1beb5d7 --- /dev/null +++ b/Front/public/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/src/Componentes/NavBarAutocompletable.svelte b/Front/src/Componentes/NavBarAutocompletable.svelte index 8af1fb2..89cbf50 100644 --- a/Front/src/Componentes/NavBarAutocompletable.svelte +++ b/Front/src/Componentes/NavBarAutocompletable.svelte @@ -120,6 +120,13 @@ {/if} +
+ + {/if} + + + + + {#if showmodal} + + {/if} + diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index 1e4c9d1..e6a4ff7 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -232,3 +232,12 @@ export type PermisoDto = { id:number, descripcion:string } + +export type ClientePanel = { + dni:number, + nombre:string, + apellido:string, + domicilio:string, + celular:string, + email:string +} diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index b309a94..12432cf 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -9,14 +9,29 @@ using Modelo.Facade; namespace Modelo; -public class RepositorioUsuarios: RepositorioBase { - public bool AltaInquilino(Cliente cli, long dni) { +public class RepositorioUsuarios : RepositorioBase +{ + + public bool CambiarContraseña(string pass, Cliente cli) + { var con = Context; - + var clii = con.Clientes.FirstOrDefault(x => x.Dni == cli.Dni); + if (clii == null) return false; + clii.Contraseña = Encoding.UTF8.GetBytes(HacerHash(pass)); + + this.GenerarLog(con, cli.Dni, "Modificada contraseña"); + return Guardar(con); + } + + public bool AltaInquilino(Cliente cli, long dni) + { + var con = Context; + Grupo? grupo; //check por si la cuenta ya existe (puede ser propietario) - Cliente? cli2 = con.Clientes.FirstOrDefault(x=>x.Email == cli.Email); - if (cli2 != null) { + Cliente? cli2 = con.Clientes.FirstOrDefault(x => x.Email == cli.Email); + if (cli2 != null) + { grupo = con.Grupos.Find(2); if (grupo == null || grupo.Id == 0) return false; cli2.Idgrupos.Add(grupo); @@ -25,7 +40,7 @@ public class RepositorioUsuarios: RepositorioBase { grupo = con.Grupos.Find(2); if (grupo == null || grupo.Id == 0) return false; - + con.Clientes.Add(cli); if (cli.Dni == 0) return false; @@ -35,13 +50,15 @@ public class RepositorioUsuarios: RepositorioBase { return Guardar(con); } - public bool AltaPropietario(Cliente cli, long dni) { + public bool AltaPropietario(Cliente cli, long dni) + { var con = Context; - + Grupo? grupo; //check por si la cuenta ya existe (puede ser propietario) Cliente? cli2 = con.Clientes.Find(cli.Dni); - if (cli2 != null) { + if (cli2 != null) + { grupo = con.Grupos.Find(1); if (grupo == null || grupo.Id == 0) return false; cli2.Idgrupos.Add(grupo); @@ -50,7 +67,7 @@ public class RepositorioUsuarios: RepositorioBase { grupo = con.Grupos.Find(1); if (grupo == null || grupo.Id == 0) return false; - + con.Clientes.Add(cli); if (cli.Dni == 0) return false; @@ -60,7 +77,8 @@ public class RepositorioUsuarios: RepositorioBase { return Guardar(con); } - public bool ActualizarPropietario(Cliente cli) { + public bool ActualizarPropietario(Cliente cli) + { var con = Context; Cliente? cliOld = con.Clientes.Find(cli.Dni); if (cliOld == null) return false; @@ -71,9 +89,10 @@ public class RepositorioUsuarios: RepositorioBase { } - public bool CheckUsuario(LoginDto logindto) { - if (logindto.Contraseña ==null)return false; - + public bool CheckUsuario(LoginDto logindto) + { + if (logindto.Contraseña == null) return false; + string Contraseña = HacerHash(logindto.Contraseña); Cliente? usu = Context.Clientes.FirstOrDefault(a => a.Email == logindto.Email); @@ -83,21 +102,24 @@ public class RepositorioUsuarios: RepositorioBase { if (hashdb == Contraseña) return true; return false; - + } - private string HacerHash(string pass) { + private string HacerHash(string pass) + { var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass)); - return BitConverter.ToString(buf).Replace("-",""); + return BitConverter.ToString(buf).Replace("-", ""); } - public bool CheckToken(string email, string token) { - var usu = Context.Clientes.FirstOrDefault(x => x.Email == email); + public bool CheckToken(string email, string token) + { + var usu = Context.Clientes.FirstOrDefault(x => x.Email == email); if (usu == null) return false; return usu.Token == token; } - public void GuardarToken(LoginDto login, string tokenString, System.Net.IPAddress? remoteIpAddress) { + public void GuardarToken(LoginDto login, string tokenString, System.Net.IPAddress? remoteIpAddress) + { var con = Context; var usu = con.Clientes.FirstOrDefault(x => x.Email == login.Email); if (usu == null) return; @@ -113,40 +135,49 @@ public class RepositorioUsuarios: RepositorioBase { } - public bool CheckGrupo(string email, string grupo) { + public bool CheckGrupo(string email, string grupo) + { var con = Context; - var usu = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Email == email); + var usu = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email); bool ret = false; - if (usu != null && usu.Idgrupos != null) { - Parallel.ForEach(usu.Idgrupos, (idGrupo, state) => { - if (idGrupo.Nombre == grupo) { + if (usu != null && usu.Idgrupos != null) + { + Parallel.ForEach(usu.Idgrupos, (idGrupo, state) => + { + if (idGrupo.Nombre == grupo) + { ret = true; - state.Break(); + state.Break(); } }); } - + return ret; } - public IEnumerable GetClientes(){ + public IEnumerable GetClientes() + { var con = Context; - var list = con.Clientes.ToList().Select(x => new Entidades.Admin.UsuarioAdmin { + var list = con.Clientes.ToList().Select(x => new Entidades.Admin.UsuarioAdmin + { Dni = x.Dni, Email = x.Email, - Nombre = x.Nombre+" "+x.Apellido, - Habilitado = x.Habilitado}); + Nombre = x.Nombre + " " + x.Apellido, + Habilitado = x.Habilitado + }); return list; } - public bool AñadirClienteAGrupo(string email, string grupo, long dni) { + public bool AñadirClienteAGrupo(string email, string grupo, long dni) + { var con = Context; - + var cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email); var gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo); - - if (cli == null || gru == null) { + + if (cli == null || gru == null) + { return false; } @@ -155,13 +186,15 @@ public class RepositorioUsuarios: RepositorioBase { return Guardar(con); } - public bool EliminarClienteAGrupo(string email, string grupo, long dniresponsable) { + public bool EliminarClienteAGrupo(string email, string grupo, long dniresponsable) + { var con = Context; - + var cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email); var gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo); - - if (cli == null || gru == null) { + + if (cli == null || gru == null) + { return false; } cli.Idgrupos.Remove(gru); @@ -169,40 +202,47 @@ public class RepositorioUsuarios: RepositorioBase { return Guardar(con); } - public bool BajaCliente(long dni) { + public bool BajaCliente(long dni) + { var con = Context; - Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Dni == dni); + Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Dni == dni); if (cli == null) return false; - - if (cli.Habilitado == 0) { + + if (cli.Habilitado == 0) + { cli.Habilitado = 1; - } else { + } + else + { cli.Habilitado = 0; } GenerarLog(con, cli.Dni, $"Baja cliente id: {cli.Dni}"); return Guardar(con); } - public Cliente? ObtenerClientePorDni(long dni) { + public Cliente? ObtenerClientePorDni(long dni) + { var con = Context; - Cliente? cli = con.Clientes.FirstOrDefault(x=>x.Dni == dni); + Cliente? cli = con.Clientes.FirstOrDefault(x => x.Dni == dni); return cli; } - public Cliente? ObtenerClientePorToken(string token) { + public Cliente? ObtenerClientePorToken(string token) + { var con = Context; - Cliente? cli = con.Clientes.Include(x=>x.NotificacioneDniclienteNavigations).FirstOrDefault(x=>x.Token == token); + Cliente? cli = con.Clientes.Include(x => x.NotificacioneDniclienteNavigations).FirstOrDefault(x => x.Token == token); - if (cli == null|| cli.Dni == 0) return null; + if (cli == null || cli.Dni == 0) return null; return cli; } - public bool PatchUsuario(UpdateUsuarioAdmin dto, long dni, long responsabledni) { + public bool PatchUsuario(UpdateUsuarioAdmin dto, long dni, long responsabledni) + { var con = Context; - var usu = con.Clientes.FirstOrDefault(x=>x.Dni ==dni); + var usu = con.Clientes.FirstOrDefault(x => x.Dni == dni); if (usu == null) return false; - + usu.Nombre = dto.Nombre; usu.Apellido = dto.Apellido; usu.Celular = dto.Celular; -- 2.52.0 From ca44b3cf84f10ceeba54c7d0663e58998c983026 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 5 May 2025 18:48:05 -0300 Subject: [PATCH 44/91] ahora solo ve los grupos activos tanto en la resolucion de permisos como en el front --- Entidades/Grupo.cs | 2 ++ Modelo/RepositorioGrupos.cs | 1 + Modelo/RepositorioPermisos.cs | 2 ++ 3 files changed, 5 insertions(+) diff --git a/Entidades/Grupo.cs b/Entidades/Grupo.cs index ac7b270..c81225a 100644 --- a/Entidades/Grupo.cs +++ b/Entidades/Grupo.cs @@ -28,6 +28,8 @@ public partial class Grupo : IComponenteSeguridad if (visitados.Contains(Id)) return; visitados.Add(Id); + if (this.Habilitado == false) return; + var componentes = new List(); componentes.AddRange(Idpermisos); componentes.AddRange(IdGrupoHijos); diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index 6ca9c63..2203d77 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -73,6 +73,7 @@ public class RepositorioGrupos : RepositorioBase { var con = Context; var listg = con.Grupos + .Where(x => x.Habilitado == true) .Include(x => x.Idpermisos) .Include(x => x.IdGrupoHijos) .ThenInclude(x => x.Idpermisos).ToList(); diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index 0b68310..6bbee72 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -15,6 +15,7 @@ public class RepositorioPermisos : RepositorioBase var list = con.Clientes .Where(c => c.Dni == cli.Dni) .SelectMany(c => c.Idgrupos) + .Where(x => x.Habilitado == true) .Include(x => x.Idpermisos) .Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos); @@ -47,6 +48,7 @@ public class RepositorioPermisos : RepositorioBase var grupos = con.Clientes .Where(x => x.Dni == cli.Dni) .SelectMany(x => x.Idgrupos) + .Where(x => x.Habilitado == true) .Include(x => x.Idpermisos) .Include(x => x.IdGrupoHijos) .ThenInclude(x => x.Idpermisos) -- 2.52.0 From fddafd5234eae7c47c9a662f0fd2292daa1fd3de Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 5 May 2025 21:36:36 -0300 Subject: [PATCH 45/91] Add recovery email field to Cliente entity --- Entidades/Cliente.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Entidades/Cliente.cs b/Entidades/Cliente.cs index 4fe77e0..fc67897 100644 --- a/Entidades/Cliente.cs +++ b/Entidades/Cliente.cs @@ -23,6 +23,8 @@ public partial class Cliente public ulong Habilitado { get; set; } + public string? EmailRecuperacion { get; set; } + public virtual ICollection ContratoDniinquilinoNavigations { get; set; } = new List(); public virtual ICollection ContratoDnipropietarioNavigations { get; set; } = new List(); -- 2.52.0 From f7d52041ba6a0f73f086465d143de07b351892a2 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 5 May 2025 22:45:45 -0300 Subject: [PATCH 46/91] Format code with proper spacing and brackets --- Modelo/RepositorioPropiedades.cs | 458 +++++++++++++++++-------------- 1 file changed, 255 insertions(+), 203 deletions(-) diff --git a/Modelo/RepositorioPropiedades.cs b/Modelo/RepositorioPropiedades.cs index 36c0c99..4156658 100644 --- a/Modelo/RepositorioPropiedades.cs +++ b/Modelo/RepositorioPropiedades.cs @@ -8,43 +8,48 @@ using Microsoft.Identity.Client; using Modelo; using MySql.Data.MySqlClient; -public class RepositorioPropiedades: RepositorioBase { +public class RepositorioPropiedades : RepositorioBase +{ - public IQueryable ListarPropiedades(){ + public IQueryable ListarPropiedades() + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id - GROUP BY p.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id + GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); + + var ret = Context.Database.SqlQuery(sqlq); return ret; } - public Propiedade? ObtenerPropiedadPorId(int Id) { + public Propiedade? ObtenerPropiedadPorId(int Id) + { var con = Context; - Propiedade? prop = con.Propiedades.Include(x=>x.DnipropietarioNavigation).FirstOrDefault(x=>x.Id == Id); - - if (prop == null || prop.Id == 0) { + Propiedade? prop = con.Propiedades.Include(x => x.DnipropietarioNavigation).FirstOrDefault(x => x.Id == Id); + + if (prop == null || prop.Id == 0) + { return null; } return prop; } - public bool AñadirPropiedad(Propiedade? prop) { + public bool AñadirPropiedad(Propiedade? prop) + { if (prop == null) return false; var con = Context; if (string.IsNullOrEmpty(prop.Letra)) prop.Letra = "_"; - + var filasInsertadasParam = new MySqlParameter("@p_filas_insertadas", SqlDbType.Int) { Direction = ParameterDirection.Output @@ -62,18 +67,19 @@ public class RepositorioPropiedades: RepositorioBase { new MySqlParameter("@p_letra", prop.Letra), new MySqlParameter("@p_dni_propietario", prop.Dnipropietario), new MySqlParameter("@p_id_tipo_propiedad", prop.Idtipropiedad), - new MySqlParameter("@p_monto",prop.Monto), + new MySqlParameter("@p_monto", prop.Monto), new MySqlParameter("@iddivisa", prop.Iddivisa), filasInsertadasParam ); - return (int)filasInsertadasParam.Value == 1? true: false; + return (int)filasInsertadasParam.Value == 1 ? true : false; } - public bool PatchPropiedad(Propiedade prop, long dni) { + public bool PatchPropiedad(Propiedade prop, long dni) + { var con = Context; - Propiedade? propi = con.Propiedades.Include(x=>x.IdServicios).FirstOrDefault(x=>x.Id == prop.Id); - + Propiedade? propi = con.Propiedades.Include(x => x.IdServicios).FirstOrDefault(x => x.Id == prop.Id); + if (propi == null) return false; propi.Canthabitaciones = prop.Canthabitaciones; @@ -83,10 +89,11 @@ public class RepositorioPropiedades: RepositorioBase { propi.Letra = prop.Letra; propi.Monto = prop.Monto; propi.Iddivisa = prop.Iddivisa; - + propi.IdServicios.Clear(); - foreach(Servicio ser in prop.IdServicios) { - var servi = con.Servicios.FirstOrDefault(x=>x.Id == ser.Id); + foreach (Servicio ser in prop.IdServicios) + { + var servi = con.Servicios.FirstOrDefault(x => x.Id == ser.Id); if (servi == null) return false; propi.IdServicios.Add(servi); } @@ -94,46 +101,50 @@ public class RepositorioPropiedades: RepositorioBase { return Guardar(con); } - public IQueryable ObtenerPropiedadesPorEmail(string email) { + public IQueryable ObtenerPropiedadesPorEmail(string email) + { FormattableString sqlq = $""" SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto, p.iddivisa as Iddivisa FROM Propiedades p - JOIN Clientes c ON c.dni = p.dnipropietario - JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad + JOIN Clientes c ON c.dni = p.dnipropietario + JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad LEFT JOIN Servicio_Propiedad ps ON ps.idPropiedad = p.id LEFT JOIN Servicios s ON s.Id = ps.idServicio WHERE c.email = {email} AND p.idestado = 1 GROUP BY p.id """; var ret = Context.Database.SqlQuery(sqlq); - + return ret; } - public IQueryable ObtenerPropiedadesDeBajaPorEmail(string email) { + public IQueryable ObtenerPropiedadesDeBajaPorEmail(string email) + { FormattableString sqlq = $""" SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto, p.iddivisa as Iddivisa FROM Propiedades p - JOIN Clientes c ON c.dni = p.dnipropietario - JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad + JOIN Clientes c ON c.dni = p.dnipropietario + JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad LEFT JOIN Servicio_Propiedad ps ON ps.idPropiedad = p.id LEFT JOIN Servicios s ON s.Id = ps.idServicio WHERE c.email = {email} AND p.idestado = 3 GROUP BY p.id """; var ret = Context.Database.SqlQuery(sqlq); - + return ret; } - public bool AñadirServicioAPropiedad(int idprop, List idserv){ + public bool AñadirServicioAPropiedad(int idprop, List idserv) + { var con = Context; Propiedade? prop = con.Propiedades.Find(idprop); if (prop == null) return false; - foreach (int id in idserv) { + foreach (int id in idserv) + { Servicio? servicio = con.Servicios.Find(id); if (servicio == null) return false; @@ -143,17 +154,21 @@ public class RepositorioPropiedades: RepositorioBase { return Guardar(con); } - public bool BajaPropiedad(int id, Cliente? cli) { + public bool BajaPropiedad(int id, Cliente? cli) + { if (cli == null) return false; var con = Context; - Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id); + Propiedade? prop = con.Propiedades.FirstOrDefault(x => x.Id == id); if (prop == null) return false; if (prop.Dnipropietario != cli.Dni) return false; - if(prop.Idestado == 1){ + if (prop.Idestado == 1) + { prop.Idestado = 3; - }else{ + } + else + { prop.Idestado = 1; } GenerarLog(con, cli.Dni, $"Baja propiedad: {prop.Id}"); @@ -161,36 +176,41 @@ public class RepositorioPropiedades: RepositorioBase { } - public bool BajaPropiedad(int id, long dni) { + public bool BajaPropiedad(int id, long dni) + { var con = Context; - Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id); - - if (prop == null||prop.Dnipropietario == 0) return false; + Propiedade? prop = con.Propiedades.FirstOrDefault(x => x.Id == id); + + if (prop == null || prop.Dnipropietario == 0) return false; prop.Idestado = prop.Idestado == 3 ? 1 : 3; GenerarLog(con, dni, $"Baja propiedad: {prop.Id}"); return Guardar(con); } - public bool BajaServiciosAPropiedad(int idprop, List idserv, long dni) { + public bool BajaServiciosAPropiedad(int idprop, List idserv, long dni) + { var con = Context; - Propiedade? prop = con.Propiedades.Include(x=>x.IdServicios).FirstOrDefault(x => x.Id == idprop); + Propiedade? prop = con.Propiedades.Include(x => x.IdServicios).FirstOrDefault(x => x.Id == idprop); if (prop == null) return false; - foreach (int id in idserv) { + foreach (int id in idserv) + { Servicio? servicio = con.Servicios.Find(id); if (servicio == null) return false; - if (prop.IdServicios.Contains(servicio)){ + if (prop.IdServicios.Contains(servicio)) + { prop.IdServicios.Remove(servicio); } } GenerarLog(con, dni, $"Baja servicios a propiedad: {prop.Id}"); - return Guardar(con); + return Guardar(con); } - public IQueryable ObtenerPropiedesPorHabitaciones_Tipo_Servicios(int habitaciones, int tipo, string servicios) { + public IQueryable ObtenerPropiedesPorHabitaciones_Tipo_Servicios(int habitaciones, int tipo, string servicios) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, @@ -198,9 +218,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {habitaciones} AND p.idtipropiedad = {tipo} AND EXISTS ( SELECT 1 @@ -211,30 +231,32 @@ public class RepositorioPropiedades: RepositorioBase { ) GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); + + var ret = Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorHabitaciones_Tipo(int cantidadHabitaciones, int tipoPropiedad) { + public IQueryable ObtenerPropiedesPorHabitaciones_Tipo(int cantidadHabitaciones, int tipoPropiedad) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {cantidadHabitaciones} AND p.idtipropiedad = {tipoPropiedad} - GROUP BY p.id + GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); + + var ret = Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorServicios(string servicios) { + public IQueryable ObtenerPropiedesPorServicios(string servicios) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" @@ -243,9 +265,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE EXISTS ( SELECT 1 FROM Servicio_Propiedad sp2 @@ -253,50 +275,53 @@ public class RepositorioPropiedades: RepositorioBase { WHERE sp2.idPropiedad = p.id AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) ) - GROUP BY p.id + GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); - return ret; - } - public IQueryable ObtenerPropiedesPorHabitaciones(int cantidadHabitaciones) { - FormattableString sqlq = $""" - SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, - p.iddivisa as Iddivisa - FROM Propiedades p - JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id - WHERE p.canthabitaciones = {cantidadHabitaciones} - GROUP BY p.id - """; - - var ret = Context.Database.SqlQuery(sqlq); + var ret = Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorTipo(int tipoPropiedad) { + public IQueryable ObtenerPropiedesPorHabitaciones(int cantidadHabitaciones) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id - WHERE p.idtipropiedad = {tipoPropiedad} - GROUP BY p.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id + WHERE p.canthabitaciones = {cantidadHabitaciones} + GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); - return ret; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; } - public IQueryable ObtenerPropiedesPorHabitaciones_Servicios(int cantidadHabitaciones, string servicios) { + public IQueryable ObtenerPropiedesPorTipo(int tipoPropiedad) + { + FormattableString sqlq = $""" + SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Iddivisa + FROM Propiedades p + JOIN EstadoPropiedad ep ON p.idestado = 1 + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id + WHERE p.idtipropiedad = {tipoPropiedad} + GROUP BY p.id + """; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; + } + + public IQueryable ObtenerPropiedesPorHabitaciones_Servicios(int cantidadHabitaciones, string servicios) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, @@ -304,9 +329,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {cantidadHabitaciones} AND EXISTS ( SELECT 1 @@ -317,12 +342,13 @@ public class RepositorioPropiedades: RepositorioBase { ) GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); - return ret; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; } - public IQueryable ObtenerPropiedesPorTipo_Servicios(int tipoPropiedad, string servicios) { + public IQueryable ObtenerPropiedesPorTipo_Servicios(int tipoPropiedad, string servicios) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, @@ -330,9 +356,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.idtipropiedad = {tipoPropiedad} AND EXISTS ( SELECT 1 @@ -343,119 +369,130 @@ public class RepositorioPropiedades: RepositorioBase { ) GROUP BY p.id """; - - var ret = Context.Database.SqlQuery(sqlq); - return ret; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; } - public bool BajaPropiedades(string email) { + public bool BajaPropiedades(string email) + { var con = Context; - try { - IQueryable listprop = con.Propiedades.Where(x=>x.DnipropietarioNavigation.Email == email); - foreach (var item in listprop) { + try + { + IQueryable listprop = con.Propiedades.Where(x => x.DnipropietarioNavigation.Email == email); + foreach (var item in listprop) + { item.Idestado = 3; } - } catch { + } + catch + { return false; } return Guardar(con); } - public IQueryable ListarPropiedadesPorPagina(int pag) { + public IQueryable ListarPropiedadesPorPagina(int pag) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id - GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id + GROUP BY p.id + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Context.Database.SqlQuery(sqlq); + + var ret = Context.Database.SqlQuery(sqlq); return ret; } ///////////////ADMIN - public IQueryable ListarPropiedadesPorPaginaAdmin(int pag) { + public IQueryable ListarPropiedadesPorPaginaAdmin(int pag) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id - GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id + GROUP BY p.id + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorHabitacionesPaginado(int cantidadHabitaciones, int pag) { + public IQueryable ObtenerPropiedesPorHabitacionesPaginado(int cantidadHabitaciones, int pag) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {cantidadHabitaciones} - GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + GROUP BY p.id + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorTipoPaginado(int tipoPropiedad, int pag) { + public IQueryable ObtenerPropiedesPorTipoPaginado(int tipoPropiedad, int pag) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.idtipropiedad = {tipoPropiedad} - GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + GROUP BY p.id + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorHabitaciones_TipoPaginado(int cantidadHabitaciones, int tipoPropiedad, int pag) { + public IQueryable ObtenerPropiedesPorHabitaciones_TipoPaginado(int cantidadHabitaciones, int tipoPropiedad, int pag) + { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {cantidadHabitaciones} AND p.idtipropiedad = {tipoPropiedad} - GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + GROUP BY p.id + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorServiciosPaginado(string servicios, int pag) { + public IQueryable ObtenerPropiedesPorServiciosPaginado(string servicios, int pag) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" @@ -464,9 +501,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE EXISTS ( SELECT 1 FROM Servicio_Propiedad sp2 @@ -474,15 +511,16 @@ public class RepositorioPropiedades: RepositorioBase { WHERE sp2.idPropiedad = p.id AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) ) - GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + GROUP BY p.id + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorHabitaciones_Servicios_Paginado(int cantidadHabitaciones, string servicios, int pag) { + public IQueryable ObtenerPropiedesPorHabitaciones_Servicios_Paginado(int cantidadHabitaciones, string servicios, int pag) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, @@ -490,9 +528,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {cantidadHabitaciones} AND EXISTS ( SELECT 1 @@ -502,14 +540,15 @@ public class RepositorioPropiedades: RepositorioBase { AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) ) GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); - return ret; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; } - public IQueryable ObtenerPropiedesPorTipo_Servicios_Paginado(int tipoPropiedad, string servicios, int pag) { + public IQueryable ObtenerPropiedesPorTipo_Servicios_Paginado(int tipoPropiedad, string servicios, int pag) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, @@ -517,9 +556,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.idtipropiedad = {tipoPropiedad} AND EXISTS ( SELECT 1 @@ -529,14 +568,15 @@ public class RepositorioPropiedades: RepositorioBase { AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) ) GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public IQueryable ObtenerPropiedesPorHabitaciones_Tipo_Servicios_Paginado(int habitaciones, int tipo, string servicios, int pag) { + public IQueryable ObtenerPropiedesPorHabitaciones_Tipo_Servicios_Paginado(int habitaciones, int tipo, string servicios, int pag) + { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, @@ -544,9 +584,9 @@ public class RepositorioPropiedades: RepositorioBase { p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id - JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id - JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad - JOIN Servicios s on sp.idServicio =s.id + JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id + JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad + JOIN Servicios s on sp.idServicio =s.id WHERE p.canthabitaciones = {habitaciones} AND p.idtipropiedad = {tipo} AND EXISTS ( SELECT 1 @@ -556,30 +596,35 @@ public class RepositorioPropiedades: RepositorioBase { AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) ) GROUP BY p.id - LIMIT 10 OFFSET {pag*10} + LIMIT 10 OFFSET {pag * 10} """; - - var ret = Singleton.Context.Database.SqlQuery(sqlq); + + var ret = Singleton.Context.Database.SqlQuery(sqlq); return ret; } - public int CuantasPaginas(int estado = 0) { + public int CuantasPaginas(int estado = 0) + { var con = Context; double inter; int ret; - if (estado == 0){ - inter = con.Propiedades.Count()/10.0; - } else { - inter = con.Propiedades.Where(x=>x.Idestado == estado).Count(); + if (estado == 0) + { + inter = con.Propiedades.Count() / 10.0; + } + else + { + inter = con.Propiedades.Where(x => x.Idestado == estado).Count(); } if (inter == 0.00) return 0; ret = (int)Math.Ceiling(inter); - + return ret; } - public int CuantasPaginasBusqueda(int habitaciones, string servicios, int tipoPropiedad, int estado) { + public int CuantasPaginasBusqueda(int habitaciones, string servicios, int tipoPropiedad, int estado) + { int registrosPorPagina = 10; var query = Context.Propiedades @@ -588,19 +633,23 @@ public class RepositorioPropiedades: RepositorioBase { .Include(p => p.IdServicios) .AsQueryable(); - if (habitaciones > 0) { + if (habitaciones > 0) + { query = query.Where(p => p.Canthabitaciones == habitaciones); } - if (estado > 0){ - query = query.Where(x=>x.Idestado == estado); + if (estado > 0) + { + query = query.Where(x => x.Idestado == estado); } - if (tipoPropiedad > 0) { + if (tipoPropiedad > 0) + { query = query.Where(p => p.Idtipropiedad == tipoPropiedad); } - if (!string.IsNullOrWhiteSpace(servicios)) { + if (!string.IsNullOrWhiteSpace(servicios)) + { var listaServicios = servicios.Split(',').Select(s => s.Trim()).ToList(); query = query.Where(p => p.IdServicios.Any(sp => @@ -612,26 +661,29 @@ public class RepositorioPropiedades: RepositorioBase { return (int)Math.Ceiling((double)totalRegistros / registrosPorPagina); } - public IQueryable? ObtenerPropiedadesEnVenta(int pag){ + public IQueryable? ObtenerPropiedadesEnVenta(int pag) + { var con = Context; - var props = con.Propiedades.Include(x=>x.IdServicios).Include(x=>x.IddivisaNavigation) - .Include(c=>c.IdtipropiedadNavigation) - .Where(x=>x.Idestado ==4 && !x.Venta.Any(x=>x.Idestado ==2)) - .Skip(pag*10).Take(10); + var props = con.Propiedades.Include(x => x.IdServicios).Include(x => x.IddivisaNavigation) + .Include(c => c.IdtipropiedadNavigation) + .Where(x => x.Idestado == 4 && !x.Venta.Any(x => x.Idestado == 2)) + .Skip(pag * 10).Take(10); return props; } - public int ObtenerPaginasDePropiedadesEnVenta(){ + public int ObtenerPaginasDePropiedadesEnVenta() + { var con = Context; - var props = con.Propiedades.Where(x=>x.Idestado ==4 && !x.Venta.Any(x=>x.Idestado ==2)).Count(); + var props = con.Propiedades.Where(x => x.Idestado == 4 && !x.Venta.Any(x => x.Idestado == 2)).Count(); return (int)Math.Ceiling((double)props / 10); } - public IQueryable ObtenerPropiedadesAVentaPorDni(long dni) { + public IQueryable ObtenerPropiedadesAVentaPorDni(long dni) + { var con = Context; - var l = con.Propiedades.Include(x=>x.IdServicios).Include(x=>x.IdtipropiedadNavigation) - .Where(x=>x.Dnipropietario == dni && x.Idestado ==4); + var l = con.Propiedades.Include(x => x.IdServicios).Include(x => x.IdtipropiedadNavigation) + .Where(x => x.Dnipropietario == dni && x.Idestado == 4); return l; } -} \ No newline at end of file +} -- 2.52.0 From c825d737fc980893290214b7395cf23c79a283df Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 5 May 2025 22:59:34 -0300 Subject: [PATCH 47/91] Fix database connection handling in AlquilaFacilContext Improved error handling when loading database connection, replaced custom context class with Dictionary, and added null checks for safer configuration. --- ...facilcontext.cs => AlquilaFacilContext.cs} | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) rename Entidades/{Alquilafacilcontext.cs => AlquilaFacilContext.cs} (97%) diff --git a/Entidades/Alquilafacilcontext.cs b/Entidades/AlquilaFacilContext.cs similarity index 97% rename from Entidades/Alquilafacilcontext.cs rename to Entidades/AlquilaFacilContext.cs index ac23178..64cf8b5 100644 --- a/Entidades/Alquilafacilcontext.cs +++ b/Entidades/AlquilaFacilContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text.Json; + using Microsoft.EntityFrameworkCore; namespace Entidades; @@ -54,17 +55,30 @@ public partial class AlquilaFacilContext : DbContext public virtual DbSet Ventas { get; set; } - private class context - { - public string connectiondb { get; set; } = ""; - } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - context connection = JsonSerializer.Deserialize(File.ReadAllText("settings.json")) ?? new(); - optionsBuilder.UseMySQL(connection.connectiondb); + if (!optionsBuilder.IsConfigured) + { + try + { + var jsonContent = File.ReadAllText("settings.json"); + var options = JsonSerializer.Deserialize>(jsonContent); + if (options != null && options.ContainsKey("connectiondb")) + { + optionsBuilder.UseMySQL(options["connectiondb"]); + } + else + { + throw new Exception("No se encontró la clave 'connectiondb' en el archivo settings.json"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error al configurar la conexión a la base de datos: {ex.Message}"); + throw; + } + } } - protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(entity => @@ -119,6 +133,9 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Email) .HasMaxLength(50) .HasColumnName("email"); + entity.Property(e => e.EmailRecuperacion) + .HasMaxLength(50) + .HasColumnName("emailRecuperacion"); entity.Property(e => e.Habilitado) .HasDefaultValueSql("b'1'") .HasColumnType("bit(1)") -- 2.52.0 From 61eacc553351bf102393180f18e826bb62a42dce Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 7 May 2025 15:29:11 -0300 Subject: [PATCH 48/91] Update bun.lockb --- Front/bun.lockb | Bin 42252 -> 38770 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Front/bun.lockb b/Front/bun.lockb index 3bc8666287f9873f687f448e90eb38d8b7b86ce4..59bbdc78487857ccd35816b727b44ffb1da8f71e 100755 GIT binary patch delta 6112 zcmeA<#q?<%(*!-ucjhl8SATdOzR|`m$MoReUE<#gqTkD!^z(2`s(n%&ef!Zg1~5pR z7%pEQn*e4rFfgPQ<>!?!FfddyFfi~jFf=4*Bo>uq6*CktFfed3Ff`aQLc}8&7#JiN z7#fPpQgcdD85p)OF)(m5Ff^=SVqoB5U}&&mVqlPFU}%`Z#K0iHz|hbG6%S`(VBlq7 zXhbRs)MzAO{uECzHnMz3_=VH4R4|JZ76*b zN^ghKMfo{7r3DNOOd<>nvJ4Cj&x9EmWEdD4P6|W#8-yVtHc6O)L5_i;Ay1frK?M|& z!rlxF3JeSl22crJVFm_e28M>$LJSN_3=9otgcum)85kPYLg{`XhyevqeuxmnB1<6# z2I>2+~Uddt4WY0YL6^9+; z#L1eR_KY_tXL8yzNwQ2{#c9VB!ZP_4CrG0vmp$X2$(daCjBh5d9pk>qncVh_A1ANmwr5IboBWE~j`J)V1A`X>Lj&{VLJo5#arVhsJa&v_lUMTC zGaYB2oW*O$s6TlnuRUY>;6-7@{Y?6|rWm5@BG71hX!~#q>lO7=poKjiL+;v6FKpY*<7Y7&5^^ z?qUoKiD1?WF_0w45LR&phIFu4jyMBDDwuUqoPi-8%rcOGvHB%oI^Mv=yd_}{SR%>5 z5DwD8#4a^iOWuytS&D(dh=HMjY4S!{bEa0Q$*bh;nC?hTUL|YC#3McVm8>0;mGtCS z@^+lX(hLk13=9n{lQ&A4bFPN-3Z>0CA4@YZgn*OEMqYEKc$vvs(soRfWhQ4y+p%7j zVPG(ttjlH1$tughUSC6PNttRg!j0Hu95SN!oFi$wS=FGI=APInxUH$yri%OjqP5 zuadH33Ral>O3IG2MS+1K4D4`4cH_xQ6eT1XA+-@Ge}ifz1}0F^01}&gS5bcQ7e$H5 zDoO(NAZbMq!N9CexJQ*=EkGbMA*L?EQpzJ)_XZ?n&IBZOHPTz_rGd<(ROZ4M}C*`u8`u*=R-I> z+X_N9`%IpzDKXjBz?+eEa-e4Ty&1VDCu)aJ&d}kVd{o<;k$1A7PWWUAUEay1I^K-@lMm{IPd=f`J6ToNn^ACb zp>Fu(3O(M*S9QG^g(oZOg-_Pd=bhZD=glZO`J!I<W5G6FyNj1 zRNs5^0|Qfm$)TR!jGmJhdWKKl;mA9g)ytdFd$Of__~Z;H-pO;_y%~Kc2YQ81mT=~s zyw%H_(SI_dclhKJ&b*UTy}cO&C!cfJ6YGon=yEDrAzo^4OiaDcU`<0Lnm+a z4xfC(m3OkJk2hoZSw3V|J9BPRuNuznR} zVBiPqR|xzw*&xJ(sZ?t6y%4X-3V|(P;|_#yh*`@*x^N)lU~O}2S+Ft#zZkGGxLYwE)_k+>$Wap+RJFLZ+tFzyA;bN~Vzv3=9vTN?ejAM`f!`K9gx63QE0o3=9mQ z;-G7zPH0SOx}$I0goWcm@UrkPAT7xFrL)`OaX?0B!~| z*fM~dGz|6(3=9qo3=ED83=B>T3=GZ;pf=>)ENwARW5ApN-1lH806B<(f#FTc(CS{H%p5f%mp1`r0R6@m1#L49aY zXAso!V-SS4cKD&*<7EK%wL#ru22gefRgRpHsz(XbNe62bX8?CkL0wp|m;{v1IXO4i zcydQh1|!epk2&u3q6`cSehdr@zR)oChB_MLSRV!k22iwtO6E`o28KWea90;>9;k67 z%mD70!W|gGz`zj9z`zj10Pb7E9S2eibs#wOK`{}{z`zg%3PO+%Kq&&`dr7E;plAXq z0!0zX(s+=gwLlRE5`}678xPV6R>8o)pa4n_3=9lzrJLRIBpCHT;}g{hYpjaOQ`49j z$IUxuE?gD+Jduep&PdPDSkHg~Ht+%K zQ3`-%4D~D+Y$qSi*H*d62yS#Xz{V#S()JyBJE8Cn*aVOP3^q)YV`?Or!kH%P6c{n3 zFilPruweBOE{ z#yDd=13d!BQU%BDsTRJw@I9dG0srWP|t_~$>O>~2__q+$?Iw*CT}Q| zVlro&e5O!>$&YQaUy%gkw#oksB_YycawZJ0fs}{;&aTri;hh0C&q&XZfdQf(s*=fo zVe*^eSJK=Z;6&LlQ9r6zZL6)N2;&cS$asd>Ul4OIo%UC@@16U@=Folgbb@%_Bvt3#66+!`QMCwP}%sP`fr~V^k3?`qgkTmlX zhKyjDtFN^%`hCF-ArBkmn$##0Sy%Q|10gd>c(P2TgbZv{%$_|kt*GN<3PQn2;mHA& z5@xVrH2y~y4R!vU{)12e8))k&nyr4f!;=>w1I{60lMU+4Kq)?>-i7I?)Z}&b3X}iU zNik(fPrgter(!O{z@WjvK-~hvm$7HEb}hle!VGs|0UMyTi(}ezUsY>XMr*R%gTrDyJkS%U0Kp&>aVv8W`gm?4#cfkA?Sp`o}eHK!z%fx(%H zfq|QWp~0Mqfq{pCq2V+m1A{aJLxVaK1A_nqLxVI_{23zy11|$ZLuzqRVgUmKLuzrZ zZfaf`Lvl`W1;|cbCI$w+dIp9DW+ny(E(V5%&x{ZQ5|i_b@)#HxwlOj=h%zuV++}58 zkYr$JaAjj)5NBX$IK~R0Kd?dMgBT$Wj$nXTSe6NLCIdrSacWs=UP*C5esM{1aWR86 zCq&+m6JlRpVqSiIW(vq;W&9iX%hl$LB)=pvC$qRDwuy0W1}alRelR zCJV4B)K6WsSUhnLbLWc+1}`I?h}#v1mz~^|($8FEw#oR&1%|aX6AwnQA5fUPc42n- z=}^0mbMvlV_dWb;<2pk#%e{(swy*yDeUZV{_b0kLZ%#h;LqB-(925`Kk>%+O4TcZu9T1S|q;vhgO2Dvgh@KpU%2lJl=5e@#OEUl9LVCBqmQ_^I+_r ze3Q+d@xo+Dc6&zl$v4^U85<`{a@aHaO^)QSXY83glf$0r9Mj}m9Cn-v%nS@3psY7} zBAfo?3v3*W8IvP9?U`0EPoBkT$Ml$a@-0p~M$yTVT=tCKlOwt88LKDHwrBdrI{6m29cK(11A`aX;6x5{re$oCqj>BXStrlr zv1jsTpFE4*j(09Q1A`?4Ljw~71B2k?gzSfBCg0+*V>~ojlGmQ`*W^fEdsYul z1_r0eb9t;eyEqvbY(U9&@d z!CAlHEH_@5>?B?W1~0I>JG=}G9$=OVAB>d)XKjJA{=iu-{4jMraMl$#OGbc!!3}I) z5}dUH&Uy!DnFum4xPaAFz*&3XEKr7r$hrtY)iF+=94TVYx=DnAA$oGGh&3y(C<8+z zn3X096FVr%zz_@;6A@!zhy}9>#TXbe!K_R!Dwvfb z!N3p?W*vsJlq6v~>Lo$4b46`fBw-FPmttTD2WjB!lVV^9V_;}tnVcwN&gme{z+eK7 zvqVmFruov7rDW}xE=o_1lC|UHmSJEp0;^QyGiS1unS4vujx$q+fguZ=aulV^nO?|D zj*_!ul9Zi%OUjPZSC)an0W6m&WzO0w%fMhXS(eM1W4|l|gBb%u!{iBU2B2ib`BfI? z22i>dkl^HyV_+}<>jVo(g9R+W0*X@RoTud=u4IDb1Ab0*IR*w>kh4Lh5E9Nyttinm zvS8>@*Xm&m*UOyjAS=TOO6Z_u%szP{oA%@j?3^6(5Zf3hKa?lXd0g>p}XI85kHqv?@rHfq?-;GczzSXh8YMG#>-l^PnaJgA-I9M1$13LiyNe zaRvs47^plFT@MyQ5}-35Vm~&QVK_vHfq?Z{k zqj5CZgMt`a@~0r#+mWB_L9W?+S4Dww@>(_T$sTIFlUdch8CfR>s)tYhp~gFTtGYKM z`(#Fq@X0IGc_*i8cr$WN-l!2iIYNVXvZ$svBlqM)&G5+_n!J;bYI-yBP8QS(pS(kp zcXFwgHzWV#gIeK}GqiXot7>~Q3QjK64xcQc%{%$3wl|~jWJR6u$tSdVC%5W&Gm1{W zs1rW9LWg&u?ldQNV1 z4xb!h$2<9{vp1vnWJ8zm$sG2)lc&0PGx|<`=n_78hdu9PS66RF|H%_w!zX7r@J>GK z;LR8~S<*3lvV#^A{(9m6M|aO9o*)zvwak>MZzKSlEdPD%IX z41@MANj?{IMRT3WdlM6jUK?F4R%>w$cC=xuRy&$EUqUFMZl2lsc{fVM)UN1=G=?)w zn5VllE?^4Z}@9CtFr>Fm@YF zUs@`->dVQ8*=f6`Zp_%V*mds|PV?QjviC6~xh@jqEGTA~T6C^!RZ7syg{~J}@A+nI zxO(XHwI$8+cTaq)Tz;yd`L>+8>FcMno=UEqJx$^CjF&IYZ45f{@~7wXALY|d{(Sqz z-gfd?XNk#s?YtSICv)0|PwsHxtyfa(wHfrl6!3yACvR5s=cpwBe@maABDMf=IU8bmMUe< zK5|Hrq5A3bsdF#3J2wAXWUBu2_P1Xri!0aJR^Ji-uOJ!Qa!q{Sz9$A+@(NeBJmQ$) zz2ah1%eQRB@X5Na67|7*V@{ea+a>Gda$)|GG^=gBd!|dDJ@9dd)SLf;5fAE%($4+W zpJG*-b>(lRUM!!ngxqsY*{#brFZxhl;B|hremRos;-M}BQ7jKu)MhUz%Vk$$68|l# z-Qy}L68W67VfNlRKR@2rdAafH^}pvzT%5Edmy}s>pPe1^zhu>>w{bU_kD6s{Y~CI; zdBc>+cU>hWZ?*MiOq|SU7tWY8InpkiF?n*LeK=#v$rspIIANnUE|U+sXHQXn3<<12e?&CzTs`c6sS0v&nFDzn8^=(IK+-ALHhh4YhdF5$CM`X`FL&q z;WjWvLpI7=BA7?v?GFf3s|VB=kZ~ZRL5)I??-Lmq7!nx3<4U06L2#Q76sVxe4b)}_ zsRK0uKut8R$p@3f>vW&2LH)|$;O<>J`%1EW?*0l zVqjnhWMDw?5f{`qAR3ol0U$FO7#KjKmLQjhF)%PhLw%aUz`&5q03OR@0Qm^yE>Kv5 z+yxr<0!42CC@>2^i4K&C8a97Rkzf=Djkm%Es+bt#jPwl6^$ZzOCv&GsPPR*vl7@}# z!bZ9vYK-*^7=kAErfI7rFfuSGGB7m2hF%%c_8oaUq3{k^9Y`6&X~xNV84^s-7$;{G z7%_cjoIIyMLK-%L>#;O%-3@s*b|%I+Q$1rnL(t&c`2xwwW$Av>uwmhoufE;?)U)sk z6JwmQo`Ie*1B3eH`{|O5=92>pB^jM3XBSE`K`fDhjUd~_G3~kXp5s0fW1OL$fu0!y z$Q26;B_>y8NXfuPgJ+9we8YzYjX=T% z^uR%3sAn*_FI`gFh=Bn%QVARQV`7Xm(F4iL70H0ZKwQj}0XFOj8$|>K|Kyl_=`0IS zn8F4@VPlFQSv|0`V8f@d(MYgY4L}YCm06$xR@iu@03$mGB&uNpv9G5+OtfmkLp$1YHKON*v$dXm<=l@`)5fqZk-%k zB00G!ONz;mbMm|_2{YJuyY|(^MHjO-#ek#F2;>9Uxb?kz`{%AU+H1+eXrO0g2#T{9 zuE}q*BxGO%-Os0$d|GJ#Z8t(e1J`7QYzb4?$heu$nQaRvZK*;ifQ_9SIL(UR&c@G# zkl8*tH(OE~HrC$3vL+*5(5eCj~60jLbxZ}z0WnnbYGcp0CBWB^r z6LKZYl%VqfY$caca?X8bLMVXE6l_*yi8Xl9DvXec7oL1CS3(*#wb0%Fcg}WY!B+?c z3nmNZNirUuteqz*^H3NvF=4L0*23ub1vi8$Mv=)0c@k!@sf>_&`xmx~8XmyKkoS^)bpN>7$8lw`yxXt9*ApmqnSusF>)c|oCs9*!c|5HX=cY$*A{=5SzB zB20|ca*!q;w&G3?Tx`MSfhwTWD)0hr^7?#fNO>(bSt#EOROEQ&yD({ROrDUhz;sb@ z@|pZNp?ON+p~!{?@MtOn!-0m$0i^{}*A>7+S`950re_!{`2Kx>N|!8|e5jPYWhQ@^%2}VCS)#8CGF2B+BkPrha7Nmj<%g@eC&CD&xFDlW^ zO)W{(ElMrU&nZhSPA$=eR5Q8-iABY!Md0evK%u5aAD_Ck|$dSxarm}a`!Yf327*~XpAf1yx)+q`? z;#gl-AHvWzntZWRSr%b{zAnfZT~PfFGk$Voxq>D}Fo2wd9yGc}dghZIdlV;spAe^u zB`o!I^|6TRn&=sVbcsUiY<*pQC`;E=&k*ElVMqk%>*_-ox(0e?lO21MB$49|RrYKD Xg~@GI(wjpkaxqS}p1g0equUGs7Z;K@ -- 2.52.0 From 1a5006e832f21cafbfabf33ad690ae8d2f457913 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 7 May 2025 15:30:05 -0300 Subject: [PATCH 49/91] =?UTF-8?q?A=C3=B1ade=20la=20capacidad=20de=20que=20?= =?UTF-8?q?setes=20un=20mail=20de=20recuperacion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Builder/DtoBuilder/UsuarioDtoBuilder.cs | 5 + Aspnet/Controllers/UsuarioController.cs | 17 ++- Entidades/Dto/UsuarioDto.cs | 1 + Front/src/paginas/UsuarioPanel.svelte | 125 ++++++++++++++++++ Front/src/types.d.ts | 3 +- Modelo/RepositorioUsuarios.cs | 10 ++ 6 files changed, 159 insertions(+), 2 deletions(-) diff --git a/Aspnet/Builder/DtoBuilder/UsuarioDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/UsuarioDtoBuilder.cs index 620cb78..88bc7cb 100644 --- a/Aspnet/Builder/DtoBuilder/UsuarioDtoBuilder.cs +++ b/Aspnet/Builder/DtoBuilder/UsuarioDtoBuilder.cs @@ -33,4 +33,9 @@ public class UsuarioDtoBuilder : Builder data.Email = email; return this; } + public UsuarioDtoBuilder SetEmailRecuperacion(string? email) + { + data.EmailRecuperacion = email ?? ""; + return this; + } } diff --git a/Aspnet/Controllers/UsuarioController.cs b/Aspnet/Controllers/UsuarioController.cs index 5379e6b..11c6637 100644 --- a/Aspnet/Controllers/UsuarioController.cs +++ b/Aspnet/Controllers/UsuarioController.cs @@ -18,6 +18,7 @@ public class UsuarioController : ControllerBase .SetNombre(cli.Nombre).SetApellido(cli.Apellido) .SetEmail(cli.Email).SetCelular(cli.Celular) .SetDni(cli.Dni).SetDomicilio(cli.Domicilio) + .SetEmailRecuperacion(cli.EmailRecuperacion) .Build(); return Ok(usu); } @@ -37,6 +38,20 @@ public class UsuarioController : ControllerBase bool ret = RepositorioUsuarios.Singleton.CambiarContraseña(body.contraseña, cli); return ret ? Ok(new { message = "Contraseña cambiada con éxito" }) : BadRequest(new { message = "No se pudo cambiar la contraseña" }); - } + + public record setemail(string EmailRecuperacion); + [HttpPut("/api/usuario/emailrecuperacion")] + public IActionResult CambiarPass([FromHeader(Name = "Auth")] string Auth, [FromBody] setemail setemail) + { + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un usuario por ese token" }); + + string emailrecuperacion = setemail.EmailRecuperacion; + if (!emailrecuperacion.Contains("@")) return BadRequest(new { message = "Tiene que ser un email" }); + + bool ret = RepositorioUsuarios.Singleton.SetEmailRecuperacion(emailrecuperacion, cli); + return ret ? Ok(new { message = "Email de recuperación actualizado con éxito" }) : BadRequest(new { message = "No se pudo actualizar el email de recuperación" }); + } + } diff --git a/Entidades/Dto/UsuarioDto.cs b/Entidades/Dto/UsuarioDto.cs index ca6fd49..844934e 100644 --- a/Entidades/Dto/UsuarioDto.cs +++ b/Entidades/Dto/UsuarioDto.cs @@ -8,4 +8,5 @@ public class UsuarioDto public string Domicilio { get; set; } = null!; public string Celular { get; set; } = null!; public string Email { get; set; } = null!; + public string? EmailRecuperacion { get; set; } = null!; } diff --git a/Front/src/paginas/UsuarioPanel.svelte b/Front/src/paginas/UsuarioPanel.svelte index 2b7391f..537488b 100644 --- a/Front/src/paginas/UsuarioPanel.svelte +++ b/Front/src/paginas/UsuarioPanel.svelte @@ -4,10 +4,12 @@ import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte"; import type { ClientePanel } from "../types"; import { urlG } from "../stores/urlStore"; + import ModalEstatico from "../Componentes/ModalEstatico.svelte"; let token: string = sessionStorage.getItem("token") || ""; let user: ClientePanel | null = $state(null); let showmodal: boolean = $state(false); + let showrecuperacionset: boolean = $state(false); let modaldata: string = $state(""); onMount(async () => { @@ -54,8 +56,40 @@ modaldata = "no se pudo hacer la request"; } } + + async function submitemail(e: Event) { + e.preventDefault(); + + const t = e.target as HTMLFormElement; + const emailinput = t.querySelector( + "#emailRecuperacion", + ) as HTMLInputElement; + const email: string = emailinput.value; + + try { + let req = await fetch($urlG + "/api/usuario/emailrecuperacion", { + method: "PUT", + headers: { Auth: token, "Content-Type": "Application/json" }, + body: JSON.stringify({ EmailRecuperacion: email }), + }); + showmodal = false; + + modaldata = (await req.json()).message; + if (req.ok) { + fetchusuario(); + } + showrecuperacionset = false; + } catch { + modaldata = "no se pudo hacer la request"; + showrecuperacionset = false; + } + } +{#if modaldata} + !!(modaldata = "")} payload={modaldata} /> +{/if} +
@@ -168,4 +202,95 @@
{/if} + + +
+
+
+
Correo de Recuperación
+
+
+ {#if !user} +
+
+ Cargando... +
+
+ {:else} +
+
+ Email de Recuperación +
+

+ {user.emailRecuperacion || "No configurado"} +

+
+
+ +
+ {#if showrecuperacionset} + + {/if} + {/if} +
+
+
diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index e6a4ff7..f5bf440 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -239,5 +239,6 @@ export type ClientePanel = { apellido:string, domicilio:string, celular:string, - email:string + email:string, + emailRecuperacion:string|null } diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index 12432cf..a937988 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -12,6 +12,16 @@ namespace Modelo; public class RepositorioUsuarios : RepositorioBase { + public bool SetEmailRecuperacion(string emailrecuperacion, Cliente cli) + { + var con = Context; + Cliente clii = con.Clientes.FirstOrDefault(x => x.Dni == cli.Dni); + if (clii == null) return false; + clii.EmailRecuperacion = emailrecuperacion; + base.GenerarLog(con, cli.Dni, "Set email Recuperacion"); + return Guardar(con); + } + public bool CambiarContraseña(string pass, Cliente cli) { var con = Context; -- 2.52.0 From 6f6d8a4e8c1cf668d23d7c3ba3b56452ca637592 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 7 May 2025 15:30:31 -0300 Subject: [PATCH 50/91] refactor del Fchart --- .../Componentes/Estadisticas/fChart.svelte | 95 +++++++++---------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/Front/src/Componentes/Estadisticas/fChart.svelte b/Front/src/Componentes/Estadisticas/fChart.svelte index a57ec3c..d33965d 100644 --- a/Front/src/Componentes/Estadisticas/fChart.svelte +++ b/Front/src/Componentes/Estadisticas/fChart.svelte @@ -1,59 +1,56 @@
- +
- -- 2.52.0 From 02add8907ef734c0c57f3ffbc59ab53ce1b053ca Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 8 May 2025 01:00:34 -0300 Subject: [PATCH 51/91] Esta todo a medio hacerse pero quiero versionar esto ya para no perder nada --- Aspnet/Controllers/UsuarioController.cs | 10 + Aspnet/Emailer/Builder/EmailBuilder.cs | 28 +++ Aspnet/Emailer/Builder/EmailHtmlGenerator.cs | 58 +++++ Aspnet/Emailer/Decorator/IEmailerSender.cs | 9 + .../Decorator/OtpEmailSenderDecorator.cs | 25 +++ Aspnet/settings.json | 6 +- Entidades/EstadoPropiedad.cs | 13 ++ Entidades/LogDetalle.cs | 23 ++ Entidades/TipoPropiedad.cs | 13 ++ Front/src/Componentes/LoginPanel.svelte | 209 +++++++++++++----- Modelo/RepositorioUsuarios.cs | 12 + 11 files changed, 348 insertions(+), 58 deletions(-) create mode 100644 Aspnet/Emailer/Builder/EmailBuilder.cs create mode 100644 Aspnet/Emailer/Builder/EmailHtmlGenerator.cs create mode 100644 Aspnet/Emailer/Decorator/IEmailerSender.cs create mode 100644 Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs create mode 100644 Entidades/EstadoPropiedad.cs create mode 100644 Entidades/LogDetalle.cs create mode 100644 Entidades/TipoPropiedad.cs diff --git a/Aspnet/Controllers/UsuarioController.cs b/Aspnet/Controllers/UsuarioController.cs index 11c6637..38ba1bf 100644 --- a/Aspnet/Controllers/UsuarioController.cs +++ b/Aspnet/Controllers/UsuarioController.cs @@ -54,4 +54,14 @@ public class UsuarioController : ControllerBase return ret ? Ok(new { message = "Email de recuperación actualizado con éxito" }) : BadRequest(new { message = "No se pudo actualizar el email de recuperación" }); } + public record recuperarusuario(string Email, string EmailRecuperacion); + [HttpPost("/api/recuperarUsuario")] + public IActionResult RecuperarUsuario([FromBody] recuperarusuario mails) + { + bool check = RepositorioUsuarios.Singleton.CheckEmailRecuperacion(mails.Email, mails.EmailRecuperacion); + if (check == false) return BadRequest(new { message = "El email no corresponde al email de recuperacion" }); + + //WIP hacer emailer + + } } diff --git a/Aspnet/Emailer/Builder/EmailBuilder.cs b/Aspnet/Emailer/Builder/EmailBuilder.cs new file mode 100644 index 0000000..34777c6 --- /dev/null +++ b/Aspnet/Emailer/Builder/EmailBuilder.cs @@ -0,0 +1,28 @@ +using System.Net.Mail; +namespace AlquilaFacil.Emailer.Builder; + +public class EmailBuilder +{ + private MailMessage _message = new(); + + public EmailBuilder To(string to) + { + _message.To.Add(to); + return this; + } + + public EmailBuilder Subject(string subject) + { + _message.Subject = subject; + return this; + } + + public EmailBuilder Body(string email, string pin) + { + _message.IsBodyHtml = true; + _message.Body = new HtmlGenerator().GenerarMail2fa(email, pin); + return this; + } + + public MailMessage Build() => _message; +} diff --git a/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs b/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs new file mode 100644 index 0000000..bb27711 --- /dev/null +++ b/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs @@ -0,0 +1,58 @@ +namespace AlquilaFacil.Emailer.Builder; + +public class HtmlGenerator +{ + public string GenerarMail2fa(string emailUsuario, string pin) + { + var msg = $""" + + + +
+
+ + + + + +
+
+ Aqui esta su codigo OTP: +
+

+ {pin} +

+
+ Este codigo es del usuario con email:{emailUsuario} +
+
+ Si no sabes para que es el email, ignoralo. +
+
+
+ + + + """; + + return msg; + } +} diff --git a/Aspnet/Emailer/Decorator/IEmailerSender.cs b/Aspnet/Emailer/Decorator/IEmailerSender.cs new file mode 100644 index 0000000..a5007a4 --- /dev/null +++ b/Aspnet/Emailer/Decorator/IEmailerSender.cs @@ -0,0 +1,9 @@ +using System.Net.Mail; + +namespace AlquilaFacil.Emailer.Sender; + +public interface IEmailSender +{ + public void Send(MailMessage message, SmtpClient smtp); + +} diff --git a/Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs b/Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs new file mode 100644 index 0000000..e6615f5 --- /dev/null +++ b/Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs @@ -0,0 +1,25 @@ +namespace AlquilaFacil.Emailer.Sender; +using System.Net.Mail; +public class OtpEmailSender : IEmailSender +{ + private readonly int _codigoLength; + + public OtpEmailSenderDecorator(int codigoLength = 6) + { + _codigoLength = codigoLength; + } + + public void Send(MailMessage message, SmtpClient? smtp = null) + { + if (smtp == null) + { + smtp = new(); + //WIP + smtp.DeliveryMethod = SmtpDeliveryMethod.Network; + + } + + + // 4.2 Construir HTML de verificación + + } diff --git a/Aspnet/settings.json b/Aspnet/settings.json index f44d236..b3fc1c9 100644 --- a/Aspnet/settings.json +++ b/Aspnet/settings.json @@ -1,5 +1,9 @@ { "usr": "nwFNMLJcn5m0owbzeXMs", "scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70", - "connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" + "connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none", + "smtpHost": "smtp.gmail.com", + "smtpPort": "587", + "emailAddr": "emailerpasillo@gmail.com", + "emailPass": "hgwa mznx xuff exws" } diff --git a/Entidades/EstadoPropiedad.cs b/Entidades/EstadoPropiedad.cs new file mode 100644 index 0000000..ed87dfa --- /dev/null +++ b/Entidades/EstadoPropiedad.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace Entidades; + +public partial class EstadoPropiedad +{ + public int Id { get; set; } + + public string Descripcion { get; set; } = null!; + + public virtual ICollection Propiedades { get; set; } = new List(); +} diff --git a/Entidades/LogDetalle.cs b/Entidades/LogDetalle.cs new file mode 100644 index 0000000..9b3b469 --- /dev/null +++ b/Entidades/LogDetalle.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace Entidades; + +public partial class LogDetalle +{ + public DateTime Fecha { get; set; } + + public long Dniusuario { get; set; } + + public string NombreTabla { get; set; } = null!; + + public string Columna { get; set; } = null!; + + public string? ValorAnterior { get; set; } + + public string? ValorNuevo { get; set; } + + public int Id { get; set; } + + public virtual Log Log { get; set; } = null!; +} diff --git a/Entidades/TipoPropiedad.cs b/Entidades/TipoPropiedad.cs new file mode 100644 index 0000000..c842eec --- /dev/null +++ b/Entidades/TipoPropiedad.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace Entidades; + +public partial class TipoPropiedad +{ + public int Id { get; set; } + + public string Descripcion { get; set; } = null!; + + public virtual ICollection Propiedades { get; set; } = new List(); +} diff --git a/Front/src/Componentes/LoginPanel.svelte b/Front/src/Componentes/LoginPanel.svelte index 9de9755..b9a8769 100644 --- a/Front/src/Componentes/LoginPanel.svelte +++ b/Front/src/Componentes/LoginPanel.svelte @@ -1,66 +1,161 @@ - - - Iniciar Sesión - - -
- - - - - - - - - -
-{#if errorMessage} -
diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index f5bf440..28cdf7f 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -242,3 +242,9 @@ export type ClientePanel = { email:string, emailRecuperacion:string|null } + +export type IngresosDto = { + mes:number, + ingresoAr:number, + ingresoUs:number +} -- 2.52.0 From e5d17c3a38bebdc10c68ef5c4a04a979dbbfffc2 Mon Sep 17 00:00:00 2001 From: fede Date: Sat, 31 May 2025 01:06:22 -0300 Subject: [PATCH 69/91] =?UTF-8?q?a=C3=B1adido=20tercera=20estadistica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/EstadisticaController.cs | 15 ++++ Entidades/Informes/InformePagos.cs | 9 +++ Front/src/paginas/Informes.svelte | 84 ++++++++++++++++----- Front/src/types.d.ts | 5 +- Modelo/RepositorioEstadisticas.cs | 42 ++++++++++- 5 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 Entidades/Informes/InformePagos.cs diff --git a/Aspnet/Controllers/EstadisticaController.cs b/Aspnet/Controllers/EstadisticaController.cs index e35caa3..1f53f9c 100644 --- a/Aspnet/Controllers/EstadisticaController.cs +++ b/Aspnet/Controllers/EstadisticaController.cs @@ -7,6 +7,21 @@ namespace AlquilaFacil.Controllers; [ApiController] public class EstadisticaController : ControllerBase { + [HttpGet("/api/stats/Pagos")] + public IActionResult EstadisticasPagos([FromHeader(Name ="Auth")] string Auth, int year){ + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6); + if (validacion1 == false) return Unauthorized(); + + ChartData stats; + List tabla; + + (stats, tabla) = RepositorioEstadisticas.Singleton.InformePagos(year); + + return Ok(new { chart = stats, tabla = tabla}); + } + + [HttpGet("api/stats/alquileresIniciados")] public IActionResult alquileresIniciadosEsteAño([FromHeader(Name = "Auth")] string Auth, int year) { diff --git a/Entidades/Informes/InformePagos.cs b/Entidades/Informes/InformePagos.cs new file mode 100644 index 0000000..fd47743 --- /dev/null +++ b/Entidades/Informes/InformePagos.cs @@ -0,0 +1,9 @@ +namespace Entidades.Informes; + +public class InformePagos +{ + public int Mes { get; set; } + public int Realizados { get; set; } + public int Atrasados {get;set;} + public int Sin_realizar {get;set;} +} diff --git a/Front/src/paginas/Informes.svelte b/Front/src/paginas/Informes.svelte index 15ca489..8d289dc 100644 --- a/Front/src/paginas/Informes.svelte +++ b/Front/src/paginas/Informes.svelte @@ -98,11 +98,17 @@ }); } +const nombresMeses = [ + "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", + "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" +]; + let ingresos: IngresosDto[] = $state([]); let chartingresos: ChartData | null = $state(null); - async function getIngresos() { + let yearr:number = $state(0); + async function getIngresos(year:number) { try{ - const req = await fetch($urlG+"", { + const req = await fetch($urlG+"/api/stats/Pagos?year="+year, { method:"GET", headers: { "Auth": token || "", @@ -110,7 +116,10 @@ }); const data = await req.json(); if (req.ok){ - ingresos = data.tabla; + ingresos = data.tabla.map(item => ({ + ...item, + mes: nombresMeses[Number(item.mes) - 1] + })); chartingresos = data.chart; } else { modaldata = data.message; @@ -141,7 +150,7 @@ aria-expanded="true" aria-controls="c1" > - Alquileres en el ultimo año + Alquileres Por Mes
Buscar
+

+ Todos los Alquileres de un año mostrados por mes +

@@ -279,39 +291,77 @@ data-bs-target="#c3" aria-expanded="false" aria-controls="c3" - > - Ingresos + onclick={async ()=> { + if (yearr ==0){ + yearr = new Date().getFullYear(); + getIngresos(yearr); + + } else if (yearr != 0){ + yearr = 0; + }}} + > + Estado Pagos por Mes
-
-
+
+
+ +
+ + +
+

+ Todos los canones ya sean pagados, Pagados Atrasados o Sin Realizar +

+ {#if ingresos.length == 0} +
+
+ Cargando... +
+
+ {:else}
- - + + + - {#each ingresos as i } - + {#each ingresos as i } + - - + + + {/each}
MesIngreso AR$Ingreso US$Pagos RealizadosPagos AtrasadosPagos Sin Realizar
{i.mes}{i.ingresoAr}{i.ingresoUs}{i.realizados}{i.atrasados}{i.sin_realizar}
+ {/if}
-
+
{#if chartingresos != null} {/if}
diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index 28cdf7f..771b839 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -245,6 +245,7 @@ export type ClientePanel = { export type IngresosDto = { mes:number, - ingresoAr:number, - ingresoUs:number + realizados:number, + atrasados:number, + sin_realizar:number } diff --git a/Modelo/RepositorioEstadisticas.cs b/Modelo/RepositorioEstadisticas.cs index c9ed217..f6cd96d 100644 --- a/Modelo/RepositorioEstadisticas.cs +++ b/Modelo/RepositorioEstadisticas.cs @@ -4,6 +4,46 @@ using Microsoft.EntityFrameworkCore; namespace Modelo; public class RepositorioEstadisticas: RepositorioBase { + + + public (ChartData, List) InformePagos(int year) + { + var con = Context; + + ChartData data = new(); + data.Labels = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]; + + var can = con.Canons.Where(x => x.Fecha.Year == year) + .Include(x=>x.IdreciboNavigation) + .GroupBy(x => x.Fecha.Month) + .Select(x=> new InformePagos{Mes = x.Key, + Realizados = x.Count(x=> x.Pagado == 1 && x.IdreciboNavigation.Fecha <= x.Fecha), + Atrasados = x.Count(x=> x.Pagado == 1 && x.IdreciboNavigation.Fecha > x.Fecha), + Sin_realizar = x.Count(x=> x.Pagado == 0)}); + + List lst = can.ToList(); + + data.Datasets.Add(new Dataset + { + Label = "Realizados", + Data = lst.Select(x => x.Realizados.ToString()).ToList() + }); + + data.Datasets.Add(new Dataset + { + Label = "Atrasados", + Data = lst.Select(x => x.Atrasados.ToString()).ToList() + }); + + data.Datasets.Add(new Dataset + { + Label = "Sin_realizar", + Data = lst.Select(x => x.Sin_realizar.ToString()).ToList() + }); + + return (data, lst); + } + public ChartData? ObtenerDataIniciadosPorAño(int year){ var con = Context; var contratosPorMes = con.Contratos @@ -98,4 +138,4 @@ public class RepositorioEstadisticas: RepositorioBase { } -} \ No newline at end of file +} -- 2.52.0 From f6dc641508fd5415c2acc8b304eebc439efd018d Mon Sep 17 00:00:00 2001 From: fede Date: Sat, 21 Jun 2025 01:32:43 -0300 Subject: [PATCH 70/91] le doy permiso a ver grupos al p 19 --- Aspnet/Controllers/GruposController.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Aspnet/Controllers/GruposController.cs b/Aspnet/Controllers/GruposController.cs index 2d75c70..3a7120d 100644 --- a/Aspnet/Controllers/GruposController.cs +++ b/Aspnet/Controllers/GruposController.cs @@ -11,7 +11,9 @@ public class GruposController : ControllerBase [HttpGet("api/admin/grupos")] public IActionResult ObtenerGrupos([FromHeader(Name = "Auth")] string Auth) { - var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18) || RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18) || + RepositorioPermisos.Singleton.CheckPermisos(Auth, 9) || + RepositorioPermisos.Singleton.CheckPermisos(Auth, 19); if (ret == false) return BadRequest(new { message = "No tiene permiso para ver todos los grupos" }); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); -- 2.52.0 From 98dbc8c8654d9460bdc446e8363c257736d8216b Mon Sep 17 00:00:00 2001 From: fede Date: Sat, 21 Jun 2025 01:33:23 -0300 Subject: [PATCH 71/91] =?UTF-8?q?a=C3=B1adido=20nuevo=20crear=20grupo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/UsuarioController.cs | 48 +++++++ Front/src/App.svelte | 7 + Front/src/paginas/CrearUsuario.svelte | 173 ++++++++++++++++++++++++ Front/src/types.d.ts | 12 ++ Modelo/RepositorioUsuarios.cs | 18 +++ 5 files changed, 258 insertions(+) create mode 100644 Front/src/paginas/CrearUsuario.svelte diff --git a/Aspnet/Controllers/UsuarioController.cs b/Aspnet/Controllers/UsuarioController.cs index 754ff7d..3c3e102 100644 --- a/Aspnet/Controllers/UsuarioController.cs +++ b/Aspnet/Controllers/UsuarioController.cs @@ -126,4 +126,52 @@ public class UsuarioController : ControllerBase return Ok(new { token = cli.Token }); } + + public record Crearusuario(long Dni, string Nombre, string Apellido, string Domicilio, string Celular, + string Email, string Contraseña, string? EmailRecuperacion, List grupos); + [HttpPost("api/crearusuario")] + public IActionResult CrearUsuario([FromHeader(Name ="Auth")] string Auth, [FromBody] Crearusuario cu) + { + var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 19); + if (!ret) return BadRequest(new { message = "No tienes permisos para Crear un usuario" }); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un usuario por ese token" }); + + string rett = ""; + + if (cu.Dni <= 0) + rett += "No puede haber un documento con numero menor o igual a 0"; + if (cu.Apellido.Length > 20) + rett += "Apellido excede los 20 caracteres. "; + if (cu.Nombre.Length > 20) + rett += "Nombre excede los 20 caracteres. "; + if (cu.Celular.Length > 40) + rett += "Celular excede los 40 caracteres. "; + if (cu.Domicilio.Length > 40) + rett += "Domicilio excede los 40 caracteres. "; + if (cu.Email.Length > 50) + rett += "Email excede los 50 caracteres. "; + if (cu.EmailRecuperacion?.Length > 50) + rett += "Email de recuperación excede los 50 caracteres. "; + + if (rett != "") return BadRequest(new { message = rett }); + + Cliente clii = new Cliente + { + Habilitado = 1, + Dni = cu.Dni, + Nombre = cu.Nombre, + Apellido = cu.Apellido, + Celular = cu.Celular, + Email = cu.Email, + EmailRecuperacion = ((cu.EmailRecuperacion ?? "").Length == 0) ? cu.Email : cu.EmailRecuperacion, + Domicilio = cu.Domicilio + }; + + var rettt = RepositorioUsuarios.Singleton.AltaUsuario(cli.Dni, clii, cu.Contraseña, cu.grupos); + + return rettt + ? Ok(new { message = "Usuario creado exitosamente." }) + : BadRequest(new { message = "Hubo un error al crear el usuario." }); } } diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 8f29e38..842e967 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -34,6 +34,7 @@ import OtroG from "./paginas/grupos/OtroG.svelte"; import GestionPemisos from "./paginas/GestionPemisos.svelte"; import UsuarioPanel from "./paginas/UsuarioPanel.svelte"; + import CrearUsuario from "./paginas/CrearUsuario.svelte"; @@ -141,6 +142,12 @@ + + + + + + diff --git a/Front/src/paginas/CrearUsuario.svelte b/Front/src/paginas/CrearUsuario.svelte new file mode 100644 index 0000000..04f7d47 --- /dev/null +++ b/Front/src/paginas/CrearUsuario.svelte @@ -0,0 +1,173 @@ + + +{#if modaldata} + !!(modaldata="")}/> +{/if} + + + +
+ +
handleSubmit(e)} class="row g-3 mt-2" id="formcrearusu"> + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ {#each grupos as grupo} + + {/each} +
+
+ + +
+ +
+
+
diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index 771b839..ab747a1 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -249,3 +249,15 @@ export type IngresosDto = { atrasados:number, sin_realizar:number } + +export type CrearUsuario = { + Dni: number; + Nombre: string; + Apellido: string; + Domicilio: string; + Celular: string; + Email: string; + Contraseña: string; + EmailRecuperacion?: string | null; + grupos: number[]; +} diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index bf76fc5..ecd9262 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -11,6 +11,24 @@ namespace Modelo; public class RepositorioUsuarios : RepositorioBase { + + public bool AltaUsuario(long Dni, Cliente clii, string Contraseña, List grupos) + { + var con = Context; + + foreach (int i in grupos) + { + var g = con.Grupos.FirstOrDefault(x => x.Id == i); + clii.Idgrupos.Add(g); + } + + clii.Contraseña = Encoding.UTF8.GetBytes(HacerHash(Contraseña)); + + con.Clientes.Add(clii); + base.GenerarLog(con, Dni, "Creacion de usuario"); + return Guardar(con); + } + public (bool, long) Check2fa(string Email, string Pin) { var con = Context; -- 2.52.0 From 84a99a15909c38c280f190df920ba6f011cf7157 Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 17 Jul 2025 00:15:24 -0300 Subject: [PATCH 72/91] Bueno elimine la necesidad de usar un storeprocedure --- Aspnet/Controllers/PropiedadesController.cs | 5 +++- Modelo/RepositorioPropiedades.cs | 30 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Aspnet/Controllers/PropiedadesController.cs b/Aspnet/Controllers/PropiedadesController.cs index f91f4aa..00fd9a5 100644 --- a/Aspnet/Controllers/PropiedadesController.cs +++ b/Aspnet/Controllers/PropiedadesController.cs @@ -200,7 +200,10 @@ public class PropiedadesController : ControllerBase Iddivisa = propiedad.Iddivisa, }; - var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop); + Cliente? responsable = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return Unauthorized(); + + var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop, responsable.Dni); return (ret) ? Ok(new { message = "Fue Cargado Correctamente" }) : BadRequest(new { message = "Fallo al momento de añadir la propiedad a la base de datos" }); diff --git a/Modelo/RepositorioPropiedades.cs b/Modelo/RepositorioPropiedades.cs index 4156658..03ee51e 100644 --- a/Modelo/RepositorioPropiedades.cs +++ b/Modelo/RepositorioPropiedades.cs @@ -42,7 +42,7 @@ public class RepositorioPropiedades : RepositorioBase return prop; } - public bool AñadirPropiedad(Propiedade? prop) + public bool AñadirPropiedad(Propiedade? prop, long dni = 0) { if (prop == null) return false; @@ -50,6 +50,33 @@ public class RepositorioPropiedades : RepositorioBase if (string.IsNullOrEmpty(prop.Letra)) prop.Letra = "_"; + prop.Id = (con.Propiedades.Count()!=0) ? con.Propiedades.Count() + 1 : 1; + prop.Idestado = 1; + + var a = con.Divisas.ToList(); + + + + + Console.WriteLine($"Id: {prop.Id}"); + Console.WriteLine($"Ubicacion: {prop.Ubicacion}"); + Console.WriteLine($"Cant. Habitaciones: {prop.Canthabitaciones}"); + Console.WriteLine($"PROPiso: {prop.Piso}"); + Console.WriteLine($"Letra: {prop.Letra}"); + Console.WriteLine($"DNI PROPropietario: {prop.Dnipropietario}"); + Console.WriteLine($"Id Tipropo Propiedad: {prop.Idtipropiedad}"); + Console.WriteLine($"Id Estado: {prop.Idestado}"); + Console.WriteLine($"Monto: {prop.Monto}"); + Console.WriteLine($"Id Divisa: {prop.Iddivisa}"); + + + + con.Propiedades.Add(prop); + if (dni!=0) GenerarLog(con, dni, $"Se guardo la propiedad"); + return Guardar(con); + + + /* var filasInsertadasParam = new MySqlParameter("@p_filas_insertadas", SqlDbType.Int) { Direction = ParameterDirection.Output @@ -73,6 +100,7 @@ public class RepositorioPropiedades : RepositorioBase ); return (int)filasInsertadasParam.Value == 1 ? true : false; + */ } public bool PatchPropiedad(Propiedade prop, long dni) -- 2.52.0 From e7b2115d6f4d9d9b0dd98cfc2d35d76a14ce0ced Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 17 Jul 2025 00:16:13 -0300 Subject: [PATCH 73/91] eliminado codigo test --- Modelo/RepositorioPropiedades.cs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Modelo/RepositorioPropiedades.cs b/Modelo/RepositorioPropiedades.cs index 03ee51e..82b6e52 100644 --- a/Modelo/RepositorioPropiedades.cs +++ b/Modelo/RepositorioPropiedades.cs @@ -53,24 +53,6 @@ public class RepositorioPropiedades : RepositorioBase prop.Id = (con.Propiedades.Count()!=0) ? con.Propiedades.Count() + 1 : 1; prop.Idestado = 1; - var a = con.Divisas.ToList(); - - - - - Console.WriteLine($"Id: {prop.Id}"); - Console.WriteLine($"Ubicacion: {prop.Ubicacion}"); - Console.WriteLine($"Cant. Habitaciones: {prop.Canthabitaciones}"); - Console.WriteLine($"PROPiso: {prop.Piso}"); - Console.WriteLine($"Letra: {prop.Letra}"); - Console.WriteLine($"DNI PROPropietario: {prop.Dnipropietario}"); - Console.WriteLine($"Id Tipropo Propiedad: {prop.Idtipropiedad}"); - Console.WriteLine($"Id Estado: {prop.Idestado}"); - Console.WriteLine($"Monto: {prop.Monto}"); - Console.WriteLine($"Id Divisa: {prop.Iddivisa}"); - - - con.Propiedades.Add(prop); if (dni!=0) GenerarLog(con, dni, $"Se guardo la propiedad"); return Guardar(con); -- 2.52.0 From eceefba3916cdd2367a9467ef43bb11b3d3471c8 Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 17 Jul 2025 00:16:28 -0300 Subject: [PATCH 74/91] correjidos componentesw para usar el enter como submit --- Front/src/Componentes/ModalEditarGrupo.svelte | 4 +++- Front/src/Componentes/ModalEditarPermiso.svelte | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Front/src/Componentes/ModalEditarGrupo.svelte b/Front/src/Componentes/ModalEditarGrupo.svelte index 1b2277e..1298e14 100644 --- a/Front/src/Componentes/ModalEditarGrupo.svelte +++ b/Front/src/Componentes/ModalEditarGrupo.svelte @@ -52,6 +52,7 @@ onclick={onClose} >
+
handleSubmit(e)}> +
diff --git a/Front/src/Componentes/ModalEditarPermiso.svelte b/Front/src/Componentes/ModalEditarPermiso.svelte index 95b9116..68a1f32 100644 --- a/Front/src/Componentes/ModalEditarPermiso.svelte +++ b/Front/src/Componentes/ModalEditarPermiso.svelte @@ -18,7 +18,8 @@ let remaining: number = $state(25); const ogdesc: string = permiso.descripcion; - function saveChanges() { + function saveChanges(e:Event) { + e.preventDefault(); onSubmit(permiso); onClose(ogdesc); } @@ -51,6 +52,7 @@ onclick={() => onClose(ogdesc)} >
+
saveChanges(e)}>
-- 2.52.0 From af3933480d3562af3e9e8804f423513f0dba031b Mon Sep 17 00:00:00 2001 From: fede Date: Sun, 20 Jul 2025 00:33:22 -0300 Subject: [PATCH 75/91] fix: se logeaban usuario desactivados --- Modelo/RepositorioUsuarios.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index ecd9262..c01a0d8 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -155,10 +155,11 @@ public class RepositorioUsuarios : RepositorioBase { if (logindto.Contraseña == null) return false; + Cliente? usu = Context.Clientes.FirstOrDefault(a => a.Email == logindto.Email && a.Habilitado == 1ul); + if (usu == null) return false; + string Contraseña = HacerHash(logindto.Contraseña); - Cliente? usu = Context.Clientes.FirstOrDefault(a => a.Email == logindto.Email); - if (usu == null) return false; string hashdb = Encoding.UTF8.GetString(usu.Contraseña); -- 2.52.0 From a7355ea540ac8a89918da3654850911aced20e1d Mon Sep 17 00:00:00 2001 From: fede Date: Sun, 20 Jul 2025 00:34:17 -0300 Subject: [PATCH 76/91] fix: contador de meses --- Aspnet/Controllers/ContratoController.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Aspnet/Controllers/ContratoController.cs b/Aspnet/Controllers/ContratoController.cs index aacb1ae..647b6d7 100644 --- a/Aspnet/Controllers/ContratoController.cs +++ b/Aspnet/Controllers/ContratoController.cs @@ -180,12 +180,14 @@ public class ContratoController : ControllerBase foreach (var i in list) { + int totalMeses = (i.Fecha.Year - cont.Fechainicio.Year) * 12 + (i.Fecha.Month - cont.Fechainicio.Month); + int mesNum = totalMeses + 1; var c = new CanonDtoBuilder() .SetId(i.Id) .SetPago(i.Idrecibo == null ? false : true) .SetDivisa(divisa == "" ? "Ugh esta mal cargado la divisa en el contrato" : divisa) .SetMes(i.Fecha) - .SetMesNum(int.Parse((i.Fecha.Month - cont.Fechainicio.Month).ToString()) + 1) + .SetMesNum(mesNum) .SetMonto(i.Monto) .Build(); d.Add(c); -- 2.52.0 From 2435ae803e735e6c8f90882d6e38e488fde55887 Mon Sep 17 00:00:00 2001 From: fede Date: Sun, 20 Jul 2025 00:34:42 -0300 Subject: [PATCH 77/91] fix: correjidos mensajes de error --- Aspnet/Controllers/ContratoController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Aspnet/Controllers/ContratoController.cs b/Aspnet/Controllers/ContratoController.cs index 647b6d7..5cb9957 100644 --- a/Aspnet/Controllers/ContratoController.cs +++ b/Aspnet/Controllers/ContratoController.cs @@ -389,13 +389,16 @@ public class ContratoController : ControllerBase ret = RepositorioContratos.Singleton.CargaPrecontratoOpcionVenta(precontrato, notificacion, v, cli.Dni); } + if (ret == false) return BadRequest(new { message = "No se pudo cargar el precontrato" }); + if (ret) { ret = RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, DateTime.Parse(dto.fechaprimernotificacion)); } + return (ret) ? Ok(new { message = "Se Cargo el precontrato y envio una notificacion al inquilino" }) : - BadRequest(new { message = "No se pudo cargar el precontrato" }); + BadRequest(new { message = "No se pudo enviar la notificacion" }); } [HttpPut("api/contratos/addGarantes")] -- 2.52.0 From 4ab98a0a2e6ed231fa54f04ed3920b46f68d0142 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 23 Jul 2025 01:09:25 -0300 Subject: [PATCH 78/91] eliminado el SystemBytes --- Front/src/Componentes/ModalLogs.svelte | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Front/src/Componentes/ModalLogs.svelte b/Front/src/Componentes/ModalLogs.svelte index 28638a3..e3d6137 100644 --- a/Front/src/Componentes/ModalLogs.svelte +++ b/Front/src/Componentes/ModalLogs.svelte @@ -51,8 +51,22 @@ {d.fecha} {d.nombreTabla} {d.columna} - {d.valorAnterior} - {d.valorNuevo} + + + {#if d.columna == "Contraseña"} + * + {:else} + {d.valorAnterior} + {/if} + + + + {#if d.columna == "Contraseña"} + * + {:else} + {d.valorNuevo} + {/if} + {/each} @@ -60,4 +74,4 @@ - \ No newline at end of file + -- 2.52.0 From 4e5c209584a6b8a8b68b3accc5a1989031bda727 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 23 Jul 2025 02:13:14 -0300 Subject: [PATCH 79/91] =?UTF-8?q?a=C3=B1adido=20logging=20de=20cerrar=20se?= =?UTF-8?q?sion=20+=20invalidacion=20de=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/LoginController.cs | 22 ++++++++++++++++++- .../Componentes/NavBarAutocompletable.svelte | 18 +++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Aspnet/Controllers/LoginController.cs b/Aspnet/Controllers/LoginController.cs index c9cd1ac..b25e99a 100644 --- a/Aspnet/Controllers/LoginController.cs +++ b/Aspnet/Controllers/LoginController.cs @@ -52,7 +52,27 @@ public class LoginController: ControllerBase } } - + + [HttpDelete("/api/logout")] + public IActionResult CerrarSesion([FromHeader(Name = "Auth")]string Auth){ + var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null ) return BadRequest(new { message = "No hay un cliente con ese token" }); + + var log = new LoginDto { + Email = cli.Email, + Contraseña = "", + }; + + string tokenString = GenerarToken(log); + + try{ + RepositorioUsuarios.Singleton.GuardarToken(log, tokenString, Request.HttpContext.Connection.RemoteIpAddress, "Cerrar Sesión"); + } catch { + return BadRequest( new { message = "Fallo al cambiar el token" } ); + } + return Ok(new { message = "Se Cerro la sesion" }); + } + private string GenerarToken(LoginDto loginDto){ var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes("ffb2cdc15d472e41a5b626e294c45020"); diff --git a/Front/src/Componentes/NavBarAutocompletable.svelte b/Front/src/Componentes/NavBarAutocompletable.svelte index 89cbf50..1892cc8 100644 --- a/Front/src/Componentes/NavBarAutocompletable.svelte +++ b/Front/src/Componentes/NavBarAutocompletable.svelte @@ -80,10 +80,20 @@ localStorage.setItem("theme", theme); }; - function cerrarSesion() { - localStorage.removeItem("email"); - sessionStorage.removeItem("token"); - navigate("/"); + async function cerrarSesion() { + try{ + const req = await fetch($urlG+"/api/logout", { + method: "DELETE", + headers: { + "Auth": token || "", + } + }); + + }finally{ + localStorage.removeItem("email"); + sessionStorage.removeItem("token"); + navigate("/"); + } } -- 2.52.0 From 5444b1dda364d09360aed34d3e3702d8be464ddb Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 23 Jul 2025 02:13:54 -0300 Subject: [PATCH 80/91] correjido mensaje del log --- Modelo/Facade/AuditoriaFacade.cs | 2 +- Modelo/RepositorioUsuarios.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modelo/Facade/AuditoriaFacade.cs b/Modelo/Facade/AuditoriaFacade.cs index 0fcf6a4..8ed2325 100644 --- a/Modelo/Facade/AuditoriaFacade.cs +++ b/Modelo/Facade/AuditoriaFacade.cs @@ -46,7 +46,7 @@ public class AuditoriaFacade { NombreTabla = "Logs", Columna = "Login", ValorAnterior = "", - ValorNuevo = $"Se inicio sesión con la direccion ip: {remoteIpAddress.ToString()}", + ValorNuevo = $"Se Accedio con la direccion ip: {remoteIpAddress.ToString()}", } ]); diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index c01a0d8..a0502e4 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -181,13 +181,13 @@ public class RepositorioUsuarios : RepositorioBase return usu.Token == token; } - public void GuardarToken(LoginDto login, string tokenString, System.Net.IPAddress? remoteIpAddress) + public void GuardarToken(LoginDto login, string tokenString, System.Net.IPAddress? remoteIpAddress, string? logout = null) { var con = Context; var usu = con.Clientes.FirstOrDefault(x => x.Email == login.Email); if (usu == null) return; usu.Token = tokenString; - GenerarLog(con, usu.Dni, "Login", remoteIpAddress); + GenerarLog(con, usu.Dni, logout!=null? logout : "Login", remoteIpAddress); Guardar(con); } -- 2.52.0 From fef97e1d055456ccec38c80d81ede5210c7d8885 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 23 Jul 2025 02:15:20 -0300 Subject: [PATCH 81/91] =?UTF-8?q?Sacada=20tilde=20del=20s=C3=AD=20porque?= =?UTF-8?q?=20daba=20problemas=20con=20libreoffice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Front/src/paginas/ContratosPropietario.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Front/src/paginas/ContratosPropietario.svelte b/Front/src/paginas/ContratosPropietario.svelte index d363aef..9adb4ab 100644 --- a/Front/src/paginas/ContratosPropietario.svelte +++ b/Front/src/paginas/ContratosPropietario.svelte @@ -363,7 +363,7 @@ if (canons.length > 0) { contenido += "ID,Mes Num,Mes,Monto,Divisa,Pago\n"; canons.forEach(c => { - let fila = [c.id, c.mesNum, String(c.mes).split("T")[0], c.monto, c.divisa, c.pago ? "Sí" : "No"].join(","); + let fila = [c.id, c.mesNum, String(c.mes).split("T")[0], c.monto, c.divisa, c.pago ? "Si" : "No"].join(","); contenido += fila + "\n"; }); } -- 2.52.0 From caa654a07886977b537b08653ab67944c44d2fe6 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 23 Jul 2025 19:37:24 -0300 Subject: [PATCH 82/91] comentado writeline --- Aspnet/Controllers/ContratoController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aspnet/Controllers/ContratoController.cs b/Aspnet/Controllers/ContratoController.cs index 5cb9957..8936063 100644 --- a/Aspnet/Controllers/ContratoController.cs +++ b/Aspnet/Controllers/ContratoController.cs @@ -446,7 +446,7 @@ public class ContratoController : ControllerBase var ret = RepositorioContratos.Singleton.CargaGarantes(gar, dto.EmailInquilino, dto.Idpropiedad, cli.Dni); if (ret) { - Console.WriteLine(dto.fecha); + //Console.WriteLine(dto.fecha); RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.fecha); var noti = new NotificacioneBuilder() -- 2.52.0 From ff63497b6110287f6cb07e0cab4b57dc009930dd Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 24 Jul 2025 20:40:19 -0300 Subject: [PATCH 83/91] solucionado tema de que no salian datos en meses antiguos --- Modelo/RepositorioEstadisticas.cs | 75 ++++++++++++++++++------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/Modelo/RepositorioEstadisticas.cs b/Modelo/RepositorioEstadisticas.cs index f6cd96d..0832c51 100644 --- a/Modelo/RepositorioEstadisticas.cs +++ b/Modelo/RepositorioEstadisticas.cs @@ -5,44 +5,59 @@ using Microsoft.EntityFrameworkCore; namespace Modelo; public class RepositorioEstadisticas: RepositorioBase { +public (ChartData, List) InformePagos(int year) { + var con = Context; - public (ChartData, List) InformePagos(int year) - { - var con = Context; + ChartData data = new(); + List meses = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]; + data.Labels = meses; - ChartData data = new(); - data.Labels = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]; + var canonData = con.Canons.Where(x => x.Fecha.Year == year) + .Include(x => x.IdreciboNavigation) + .Select(x => new { + Mes = x.Fecha.Month, + Pagado = x.Pagado, + CanonFecha = x.Fecha, + ReciboFecha = x.IdreciboNavigation != null ? x.IdreciboNavigation.Fecha : (DateTime?)null + }) + .ToList(); - var can = con.Canons.Where(x => x.Fecha.Year == year) - .Include(x=>x.IdreciboNavigation) - .GroupBy(x => x.Fecha.Month) - .Select(x=> new InformePagos{Mes = x.Key, - Realizados = x.Count(x=> x.Pagado == 1 && x.IdreciboNavigation.Fecha <= x.Fecha), - Atrasados = x.Count(x=> x.Pagado == 1 && x.IdreciboNavigation.Fecha > x.Fecha), - Sin_realizar = x.Count(x=> x.Pagado == 0)}); + var groupedData = canonData + .GroupBy(x => x.Mes) + .Select(g => new InformePagos { + Mes = g.Key, + Realizados = g.Count(x => x.Pagado == 1 && x.ReciboFecha.HasValue && x.ReciboFecha <= x.CanonFecha), + Atrasados = g.Count(x => x.Pagado == 1 && x.ReciboFecha.HasValue && x.ReciboFecha > x.CanonFecha), + Sin_realizar = g.Count(x => x.Pagado == 0) + }) + .ToList(); - List lst = can.ToList(); + List lst = Enumerable.Range(1, 12) + .Select(mes => groupedData.FirstOrDefault(x => x.Mes == mes) ?? new InformePagos { + Mes = mes, + Realizados = 0, + Atrasados = 0, + Sin_realizar = 0 + }) + .ToList(); - data.Datasets.Add(new Dataset - { - Label = "Realizados", - Data = lst.Select(x => x.Realizados.ToString()).ToList() - }); + data.Datasets.Add(new Dataset { + Label = "Realizados", + Data = lst.Select(x => x.Realizados.ToString()).ToList() + }); - data.Datasets.Add(new Dataset - { - Label = "Atrasados", - Data = lst.Select(x => x.Atrasados.ToString()).ToList() - }); + data.Datasets.Add(new Dataset { + Label = "Atrasados", + Data = lst.Select(x => x.Atrasados.ToString()).ToList() + }); - data.Datasets.Add(new Dataset - { - Label = "Sin_realizar", - Data = lst.Select(x => x.Sin_realizar.ToString()).ToList() - }); + data.Datasets.Add(new Dataset { + Label = "Sin_realizar", + Data = lst.Select(x => x.Sin_realizar.ToString()).ToList() + }); - return (data, lst); - } + return (data, lst); +} public ChartData? ObtenerDataIniciadosPorAño(int year){ var con = Context; -- 2.52.0 From b7b7b80072d59d42495372a3fec2839f74e8ce0c Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Jul 2025 03:12:40 -0300 Subject: [PATCH 84/91] =?UTF-8?q?a=C3=B1adida=20informacion=20a=20la=20pan?= =?UTF-8?q?talla=20de=20a=C3=B1adirgarantes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aspnet/Controllers/ContratoController.cs | 32 ++++++++++ Entidades/Dto/PreContratoDataDto.cs | 7 +++ Front/src/Componentes/ModalAddGarantes.svelte | 61 ++++++++++++++----- Front/src/paginas/Notificaciones.svelte | 29 ++++++++- Front/src/types.d.ts | 34 +++++++---- Modelo/RepositorioContratos.cs | 10 +++ 6 files changed, 143 insertions(+), 30 deletions(-) create mode 100644 Entidades/Dto/PreContratoDataDto.cs diff --git a/Aspnet/Controllers/ContratoController.cs b/Aspnet/Controllers/ContratoController.cs index 8936063..0740652 100644 --- a/Aspnet/Controllers/ContratoController.cs +++ b/Aspnet/Controllers/ContratoController.cs @@ -401,6 +401,38 @@ public class ContratoController : ControllerBase BadRequest(new { message = "No se pudo enviar la notificacion" }); } + [HttpGet("api/precontrato/preCargaGarantes/data")] + public IActionResult ObtenerDatosParaMostrarleAlInquilinoPreCargaGarantes([FromHeader(Name="Auth")]string Auth, int propiedadId){ + if (propiedadId<=0) return BadRequest(new { message = "Numero de propiedad inexistente"}); + + var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay cliente por ese token" }); + + Contrato? contrato = RepositorioContratos.Singleton.ObtenerPreContratoPorIdDePropiedadyCliente(cli, propiedadId); + + if (contrato == null) return BadRequest(new {message = "no se pudo encontrar los datos del precontrato"}); + + PreContratoDataDto d = new PreContratoDataDto + { + TieneOpcionDeVenta = contrato.Tieneopcionventa == 1, + + MontoOpcionDeVenta = contrato.Tieneopcionventa == 1 && contrato.IdventaNavigation != null + ? contrato.IdventaNavigation.Monto + : null, + + MonedaOpcionDeVenta = contrato.Tieneopcionventa == 1 + && contrato.IdventaNavigation != null + && contrato.IdventaNavigation.IddivisaNavigation != null + ? contrato.IdventaNavigation.IddivisaNavigation.Signo + : null, + + DuracionEnMeses = contrato.MesesDurationContrato, + + FrecuenciaAumentoEnMeses = contrato.MesesHastaAumento + }; + return Ok(d); + } + [HttpPut("api/contratos/addGarantes")] public IActionResult AddGarantes([FromHeader(Name = "Auth")] string Auth, AltaGarantesDto dto) { diff --git a/Entidades/Dto/PreContratoDataDto.cs b/Entidades/Dto/PreContratoDataDto.cs new file mode 100644 index 0000000..cc02485 --- /dev/null +++ b/Entidades/Dto/PreContratoDataDto.cs @@ -0,0 +1,7 @@ +public class PreContratoDataDto{ + public bool TieneOpcionDeVenta { get; set; } + public decimal? MontoOpcionDeVenta { get; set; } + public string? MonedaOpcionDeVenta { get; set; } + public int DuracionEnMeses { get; set; } + public int? FrecuenciaAumentoEnMeses { get; set; } +} diff --git a/Front/src/Componentes/ModalAddGarantes.svelte b/Front/src/Componentes/ModalAddGarantes.svelte index ca0e721..1351662 100644 --- a/Front/src/Componentes/ModalAddGarantes.svelte +++ b/Front/src/Componentes/ModalAddGarantes.svelte @@ -1,16 +1,17 @@ + \ No newline at end of file + diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index ab747a1..0b2f059 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -244,20 +244,28 @@ export type ClientePanel = { } export type IngresosDto = { - mes:number, - realizados:number, - atrasados:number, - sin_realizar:number + mes:number, + realizados:number, + atrasados:number, + sin_realizar:number } export type CrearUsuario = { - Dni: number; - Nombre: string; - Apellido: string; - Domicilio: string; - Celular: string; - Email: string; - Contraseña: string; - EmailRecuperacion?: string | null; - grupos: number[]; + Dni: number; + Nombre: string; + Apellido: string; + Domicilio: string; + Celular: string; + Email: string; + Contraseña: string; + EmailRecuperacion?: string | null; + grupos: number[]; } + +export type PreContratoData = { + tieneOpcionDeVenta: boolean; + montoOpcionDeVenta?: number; + monedaOpcionDeVenta?: string; + duracionEnMeses: number; + frecuenciaAumentoEnMeses?: number | null; +}; diff --git a/Modelo/RepositorioContratos.cs b/Modelo/RepositorioContratos.cs index 5119af3..8d073f4 100644 --- a/Modelo/RepositorioContratos.cs +++ b/Modelo/RepositorioContratos.cs @@ -168,6 +168,16 @@ public class RepositorioContratos: RepositorioBase { return Guardar(con); } + public Contrato? ObtenerPreContratoPorIdDePropiedadyCliente(Cliente cli, int propiedadid){ + var con = Context; + + var cont = con.Contratos.Where(x=>x.Habilitado == 0ul && x.Cancelado == 0ul) + .Include(x=>x.IdventaNavigation) + .ThenInclude(x=>x.IddivisaNavigation) + .FirstOrDefault(x => x.Dniinquilino == cli.Dni && x.Idpropiedad == propiedadid); + return cont; + } + public IQueryable ObtenerContratosDePropietario(long dni) { var con = Context; var l = con.Contratos -- 2.52.0 From 98414a5ec787d240f1abb5898d1d85a716f006da Mon Sep 17 00:00:00 2001 From: fede Date: Fri, 25 Jul 2025 23:20:09 -0300 Subject: [PATCH 85/91] correjido posible desreferenciacion nula --- Modelo/Facade/AuditoriaFacade.cs | 2 +- Modelo/RepositorioLogs.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modelo/Facade/AuditoriaFacade.cs b/Modelo/Facade/AuditoriaFacade.cs index 8ed2325..fe6984e 100644 --- a/Modelo/Facade/AuditoriaFacade.cs +++ b/Modelo/Facade/AuditoriaFacade.cs @@ -46,7 +46,7 @@ public class AuditoriaFacade { NombreTabla = "Logs", Columna = "Login", ValorAnterior = "", - ValorNuevo = $"Se Accedio con la direccion ip: {remoteIpAddress.ToString()}", + ValorNuevo = $"Se Accedio con la direccion ip: {remoteIpAddress?.ToString() ?? "Desconocida"}", } ]); diff --git a/Modelo/RepositorioLogs.cs b/Modelo/RepositorioLogs.cs index d03d46b..802dd28 100644 --- a/Modelo/RepositorioLogs.cs +++ b/Modelo/RepositorioLogs.cs @@ -21,9 +21,9 @@ public class RepositorioLogs: RepositorioBase { return d.LogDetalles.OrderBy(x=>x.Id); } - public IQueryable? ObtenerLogsPaginado(int pag) { + public IQueryable ObtenerLogsPaginado(int pag) { var con = Context; var l = con.Logs.OrderByDescending(x=>x.Fecha).Skip(10*pag).Take(10); return l; } -} \ No newline at end of file +} -- 2.52.0 From 5d944b0ee459b77720bc0b6f813d526ada9b1465 Mon Sep 17 00:00:00 2001 From: fede Date: Sat, 26 Jul 2025 02:42:30 -0300 Subject: [PATCH 86/91] =?UTF-8?q?a=C3=B1adido=20front=20para=20que=20el=20?= =?UTF-8?q?admin=20suba=20el=20contrato?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CargaContratoAdminController.cs | 45 ++ Entidades/Dto/PropietarioDto.cs | 6 + Front/src/App.svelte | 5 + Front/src/paginas/CargarContratoAdmin.svelte | 568 ++++++++++++++++++ Modelo/RepositorioDivisas.cs | 10 + Modelo/RepositorioPropiedades.cs | 6 + Modelo/RepositorioPropietario.cs | 14 +- 7 files changed, 652 insertions(+), 2 deletions(-) create mode 100644 Aspnet/Controllers/CargaContratoAdminController.cs create mode 100644 Entidades/Dto/PropietarioDto.cs create mode 100644 Front/src/paginas/CargarContratoAdmin.svelte create mode 100644 Modelo/RepositorioDivisas.cs diff --git a/Aspnet/Controllers/CargaContratoAdminController.cs b/Aspnet/Controllers/CargaContratoAdminController.cs new file mode 100644 index 0000000..c01729f --- /dev/null +++ b/Aspnet/Controllers/CargaContratoAdminController.cs @@ -0,0 +1,45 @@ +using Microsoft.AspNetCore.Mvc; +using Modelo; + + +[ApiController] +public class CargarContratoAdminController: ControllerBase{ + + [HttpGet("api/admin/contrato/data")] + public IActionResult GetData([FromHeader(Name ="Auth")]string Auth) { + var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay usuario por ese token"}); + + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 20); + if (validacion1 == false) return Unauthorized(); + + var divisas = RepositorioDivisas.Singleton.ObtenerDivisas(); + + var propiedades = RepositorioPropiedades.Singleton.ListarPropiedades().ToList() + .Select(x=> new {id = x.id, + ubicacion = x.Ubicacion}); + + var inquilinos = RepositorioInquilinos.Singleton.GetInquilinos().ToList() + .Select(x=>new {dni=x.Dni, nombre = x.Nombre}); + + var propietarios = RepositorioPropietario.Singleton.GetPropietarios().ToList() + .Select(x=>new {dni=x.Dni, nombre = x.Nombre}); + + return Ok(new {divisas, + propiedades, + inquilinos, + propietarios}); + } + + [HttpGet("api/admin/contrato/propieades")] + public IActionResult GetPropiedadesPorPropietario([FromHeader(Name ="Auth")]string Auth, long dnipropietario){ + var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay usuario por ese token"}); + + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 20); + if (validacion1 == false) return Unauthorized(); + + var propiedades = RepositorioPropiedades.Singleton.ObtenerPropiedadEnAlquilerPorDni(dnipropietario); + return Ok(propiedades); + } +} diff --git a/Entidades/Dto/PropietarioDto.cs b/Entidades/Dto/PropietarioDto.cs new file mode 100644 index 0000000..a80224c --- /dev/null +++ b/Entidades/Dto/PropietarioDto.cs @@ -0,0 +1,6 @@ +namespace Entidades.Dto; +public class PropietarioDto{ + public string Nombre {get; set;} = ""; + public long Dni {get; set;} + public string Apellido {get; set;} = ""; +} diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 842e967..bcf328b 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -35,6 +35,7 @@ import GestionPemisos from "./paginas/GestionPemisos.svelte"; import UsuarioPanel from "./paginas/UsuarioPanel.svelte"; import CrearUsuario from "./paginas/CrearUsuario.svelte"; + import CargarContratoAdmin from "./paginas/CargarContratoAdmin.svelte"; @@ -147,6 +148,10 @@ + + + + diff --git a/Front/src/paginas/CargarContratoAdmin.svelte b/Front/src/paginas/CargarContratoAdmin.svelte new file mode 100644 index 0000000..923d94d --- /dev/null +++ b/Front/src/paginas/CargarContratoAdmin.svelte @@ -0,0 +1,568 @@ + + + +{#if modaldata} + !!(modaldata = "")}/> +{/if} + +
+

Alta de Contrato

+ + +
+ +
+
+ + +
+
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + {#if contrato.cantgarantemin > 0} +
+
+
Garantes
+
+ + + + + + + + + + + + + {#each contrato.garantes as garante, i} + + + + + + + + + {/each} + +
DNINombreApellidoDomicilioCelularDomicilio Laboral
+ actualizarGarante(i, 'dni', e.target.value)} + /> + + actualizarGarante(i, 'nombre', e.target.value)} + /> + + actualizarGarante(i, 'apellido', e.target.value)} + /> + + actualizarGarante(i, 'domicilio', e.target.value)} + /> + + actualizarGarante(i, 'celular', e.target.value)} + /> + + actualizarGarante(i, 'domicilioLaboral', e.target.value)} + /> +
+
+
+
+ {/if} + +
+ +
+ + {#if contrato.archivoContrato} + Archivo seleccionado: {contrato.archivoContrato.name} + {/if} +
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + {#if contrato.tieneopcionventa} +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+ {/if} + +
+
+ +
+
+ +
diff --git a/Modelo/RepositorioDivisas.cs b/Modelo/RepositorioDivisas.cs new file mode 100644 index 0000000..0142d3d --- /dev/null +++ b/Modelo/RepositorioDivisas.cs @@ -0,0 +1,10 @@ +using Entidades; + +namespace Modelo; +public class RepositorioDivisas: RepositorioBase { + public List ObtenerDivisas(){ + var con = Context; + var divisas = con.Divisas.ToList(); + return divisas; + } +} diff --git a/Modelo/RepositorioPropiedades.cs b/Modelo/RepositorioPropiedades.cs index 82b6e52..21ae862 100644 --- a/Modelo/RepositorioPropiedades.cs +++ b/Modelo/RepositorioPropiedades.cs @@ -11,6 +11,12 @@ using MySql.Data.MySqlClient; public class RepositorioPropiedades : RepositorioBase { + public List ObtenerPropiedadEnAlquilerPorDni(long dni){ + var con = Context; + var propiedades = con.Propiedades.Where(x=>x.Dnipropietario == dni && x.Idestado == 1).ToList(); + return propiedades; + } + public IQueryable ListarPropiedades() { FormattableString sqlq = $""" diff --git a/Modelo/RepositorioPropietario.cs b/Modelo/RepositorioPropietario.cs index cc5bbb2..a48322a 100644 --- a/Modelo/RepositorioPropietario.cs +++ b/Modelo/RepositorioPropietario.cs @@ -1,10 +1,20 @@ -using System; using Entidades; +using Entidades.Dto; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; using Modelo; public class RepositorioPropietario: RepositorioBase { + + public IQueryable GetPropietarios() { + FormattableString sqlq = + $""" + SELECT I.Dni, I.Nombre, I.Apellido FROM Clientes I + JOIN cliente_Grupos cg on cg.idcliente = I.Dni + WHERE cg.idgrupo = 1; + """; + return Context.Database.SqlQuery(sqlq); + } + public Cliente? ObtenerPropietarioPorDni(long Dni){ if (Dni < 1) return null; -- 2.52.0 From a5f78673d47d54a099b0e5c24d0e6e0515230191 Mon Sep 17 00:00:00 2001 From: fede Date: Sun, 27 Jul 2025 04:00:39 -0300 Subject: [PATCH 87/91] =?UTF-8?q?primera=20parte=20de=20a=C3=B1adir=20lo?= =?UTF-8?q?=20de=20contratos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CargaContratoAdminController.cs | 238 +++++++++++++++++- Front/src/paginas/CargarContratoAdmin.svelte | 20 -- Modelo/RepositorioContratos.cs | 23 ++ 3 files changed, 260 insertions(+), 21 deletions(-) diff --git a/Aspnet/Controllers/CargaContratoAdminController.cs b/Aspnet/Controllers/CargaContratoAdminController.cs index c01729f..ee718ca 100644 --- a/Aspnet/Controllers/CargaContratoAdminController.cs +++ b/Aspnet/Controllers/CargaContratoAdminController.cs @@ -1,6 +1,13 @@ using Microsoft.AspNetCore.Mvc; +using AlquilaFacil.Config; using Modelo; - +using Entidades.Dto; +using Entidades; +using Minio; +using Minio.DataModel; +using Minio.DataModel.Args; +using Minio.Exceptions; +using System.Text.Json; [ApiController] public class CargarContratoAdminController: ControllerBase{ @@ -42,4 +49,233 @@ public class CargarContratoAdminController: ControllerBase{ var propiedades = RepositorioPropiedades.Singleton.ObtenerPropiedadEnAlquilerPorDni(dnipropietario); return Ok(propiedades); } + + [HttpPost("api/admin/contrato/carga")] + public async Task CargaContrato([FromHeader(Name="Auth")]string Auth) { + var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay usuario por ese token"}); + + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 20); + if (validacion1 == false) return Unauthorized(); + + if (!Request.HasFormContentType) + { + return BadRequest(new { message = "La solicitud debe contener datos de formulario (FormData)." }); + } + + var formData = await Request.ReadFormAsync(); + if (formData == null) + { + return BadRequest(new { message = "No se pudieron leer los datos del formulario." }); + } + + var archivoContrato = Request.Form.Files.FirstOrDefault(x=>x.FileName =="archivoContrato"); + if (archivoContrato == null) return BadRequest(new { message = "Falto Subir el archivo" }); + + if (archivoContrato.ContentType != "application/pdf") + { + return BadRequest(new { message = "El archivo debe ser un PDF." }); + } + + Contrato? cont; ActionResult? req; + + (cont, req) = ParseContratoFromForm(formData); + if (req != null && cont == null) return req; + + var ret = RepositorioContratos.Singleton.AdminCargaContrato(cont, cli.Dni); + + //WIP + //Falta Carga del archivo a minio + //Falta añadir la url al contrato + //Falta generar canones + //Falta mandar notificaciones + + + } + + private (Contrato? contratoDto, IActionResult? errorResult) ParseContratoFromForm(IFormCollection formData) { + if (formData == null) { + return (null, BadRequest(new { message = "No se pudieron leer los datos del formulario." })); + } + + bool TryParseInt(string? value, out int result) => int.TryParse(value, out result); + bool TryParseLong(string? value, out long result) => long.TryParse(value, out result); + bool TryParseDecimal(string? value, out decimal result) => decimal.TryParse(value, out result); + bool TryParseBool(string? value, out bool result) => bool.TryParse(value, out result); + + int cantGarantMin = 0; + if (formData.TryGetValue("cantgarantemin", out var cantGarantMinValues) && + !string.IsNullOrEmpty(cantGarantMinValues.FirstOrDefault()) && + !TryParseInt(cantGarantMinValues.FirstOrDefault(), out cantGarantMin)) { + return (null, BadRequest(new { message = "Campo 'cantgarantemin' inválido." })); + } + if (cantGarantMin<1) return (null, BadRequest(new { message = "Minimo 1 garante" })); + + if (!formData.TryGetValue("dniinquilino", out var dniInqValues) || + string.IsNullOrEmpty(dniInqValues.FirstOrDefault()) || + !TryParseLong(dniInqValues.FirstOrDefault(), out long dniInquilino)) { + return (null, BadRequest(new { message = "Campo 'dniinquilino' inválido o faltante." })); + } + if (dniInquilino<=0) return (null, BadRequest(new { message = "No pueden haber dni 0 o menor" })); + + if (!formData.TryGetValue("dnipropietario", out var dniPropValues) || + string.IsNullOrEmpty(dniPropValues.FirstOrDefault()) || + !TryParseLong(dniPropValues.FirstOrDefault(), out long dniPropietario)) { + return (null, BadRequest(new { message = "Campo 'dnipropietario' inválido o faltante." })); + } + if (dniPropietario<=0) return (null, BadRequest(new { message = "No pueden haber dni 0 o menor" })); + + if (!formData.TryGetValue("iddivisa", out var idDivisaValues) || + string.IsNullOrEmpty(idDivisaValues.FirstOrDefault()) || + !TryParseInt(idDivisaValues.FirstOrDefault(), out int idDivisa)) { + return (null, BadRequest(new { message = "Campo 'iddivisa' inválido o faltante." })); + } + + if (!formData.TryGetValue("idpropiedad", out var idPropValues) || + string.IsNullOrEmpty(idPropValues.FirstOrDefault()) || + !TryParseInt(idPropValues.FirstOrDefault(), out int idPropiedad)) { + return (null, BadRequest(new { message = "Campo 'idpropiedad' inválido o faltante." })); + } + + if (!formData.TryGetValue("mesesDurationContrato", out var mesesDurValues) || + string.IsNullOrEmpty(mesesDurValues.FirstOrDefault()) || + !TryParseInt(mesesDurValues.FirstOrDefault(), out int mesesDuration)) { + return (null, BadRequest(new { message = "Campo 'mesesDurationContrato' inválido o faltante." })); + } + + if (mesesDuration <= 0){ + return (null, BadRequest(new { message = "No se cargaron los meses de duracion del contrato" })); + } + + int mesesHastaAumento = 0; + if (formData.TryGetValue("mesesHastaAumento", out var mesesHastaValues) && + !string.IsNullOrEmpty(mesesHastaValues.FirstOrDefault())) { + if (!TryParseInt(mesesHastaValues.FirstOrDefault(), out mesesHastaAumento)) + { + return (null, BadRequest(new { message = "Campo 'mesesHastaAumento' inválido." })); + } + } + + if (mesesHastaAumento <= 0){ + return (null, BadRequest(new { message = "No se cargaron los meses hasta el aumento" })); + } + + if (!formData.TryGetValue("monto", out var montoValues) || + string.IsNullOrEmpty(montoValues.FirstOrDefault()) || + !TryParseDecimal(montoValues.FirstOrDefault(), out decimal monto)) { + return (null, BadRequest(new { message = "Campo 'monto' inválido o faltante." })); + } + + if (monto <= 0.0m){ + return (null, BadRequest(new { message = "No se cargo el monto de alquiler" })); + } + + bool tieneOpcionVenta = false; + if (formData.TryGetValue("tieneopcionventa", out var tieneOpcionValues) && + !string.IsNullOrEmpty(tieneOpcionValues.FirstOrDefault())) { + if (!TryParseBool(tieneOpcionValues.FirstOrDefault(), out tieneOpcionVenta)) { + return (null, BadRequest(new { message = "Campo 'tieneopcionventa' inválido." })); + } + } + + int divisaOpcionVenta = 0; + decimal montoOpcionVenta = 0m; + + if (tieneOpcionVenta) { + if (formData.TryGetValue("divisaOpcionVenta", out var divisaOpcValues) && + !string.IsNullOrEmpty(divisaOpcValues.FirstOrDefault())) { + if (!TryParseInt(divisaOpcValues.FirstOrDefault(), out int divisaOpcParsed)) { + return (null, BadRequest(new { message = "Campo 'divisaOpcionVenta' inválido." })); + } + divisaOpcionVenta = divisaOpcParsed; + } + + if (formData.TryGetValue("montoOpcionVenta", out var montoOpcValues) && + !string.IsNullOrEmpty(montoOpcValues.FirstOrDefault())) { + if (!TryParseDecimal(montoOpcValues.FirstOrDefault(), out decimal montoOpcParsed)) { + return (null, BadRequest(new { message = "Campo 'montoOpcionVenta' inválido." })); + } + montoOpcionVenta = montoOpcParsed; + } + } + + if (montoOpcionVenta <= 0.0m){ + return (null, BadRequest(new { message = "No se cargo el monto de la opcion de venta" })); + } + + var cont = new Contrato{ + Cancelado=0, + Habilitado=1, + Cantgarantemin=cantGarantMin, + Dniinquilino=dniInquilino, + Dnipropietario=dniPropietario, + Fechainicio=DateTime.Now, + Iddivisa=idDivisa, + Idpropiedad=idPropiedad, + Monto=monto, + MesesDurationContrato = mesesDuration, + MesesHastaAumento=mesesHastaAumento, + + Idgarantes = ParseGarantes(formData), + + Tieneopcionventa=tieneOpcionVenta?1ul:0ul, + + + }; + + if(cont.Tieneopcionventa==1ul){ + cont.IdventaNavigation = new Venta{ + Idestado = 1, + Monto= montoOpcionVenta, + Iddivisa = divisaOpcionVenta + }; + } + + return (cont, null); + } + + private Garante[] ParseGarantes(IFormCollection formData) { + var garantes = new List(); + + var garanteKeys = formData.Keys.Where(k => k.StartsWith("garantes[")).ToList(); + var garanteCount = garanteKeys.Count / 6; + + for (int i = 0; i < garanteCount; i++) { + var dni = formData.TryGetValue($"garantes[{i}].dni", out var dniValue) ? dniValue.ToString() ?? "" : ""; + var nombre = formData.TryGetValue($"garantes[{i}].nombre", out var nombreValue) ? nombreValue.ToString() ?? "" : ""; + var apellido = formData.TryGetValue($"garantes[{i}].apellido", out var apellidoValue) ? apellidoValue.ToString() ?? "" : ""; + var domicilio = formData.TryGetValue($"garantes[{i}].domicilio", out var domicilioValue) ? domicilioValue.ToString() ?? "" : ""; + var celular = formData.TryGetValue($"garantes[{i}].celular", out var celularValue) ? celularValue.ToString() ?? "" : ""; + var domicilioLaboral = formData.TryGetValue($"garantes[{i}].domicilioLaboral", out var domLaboralValue) ? domLaboralValue.ToString() ?? "" : ""; + + var garante = new Garante{ + Dni = dni, + Nombre = nombre, + Apellido = apellido, + Domicilio = domicilio, + Celular = celular, + Domiciliolaboral = domicilioLaboral + }; + garantes.Add(garante); + } + + return garantes.ToArray(); + } + + + private readonly IMinioClient mc; + public CargarContratoAdminController(IMinioClient minioClient) + { + mc = minioClient; + if (mc == null) + { + MinioConfigcus? mcon = JsonSerializer.Deserialize(System.IO.File.ReadAllText("./settings.json")) ?? null; + if (mcon == null) throw new Exception(); + + mc = new MinioClient().WithCredentials(mcon.usr, mcon.scrt) + .WithEndpoint("0.0.0.0:9000") + .WithSSL(false) + .Build(); + } + } } diff --git a/Front/src/paginas/CargarContratoAdmin.svelte b/Front/src/paginas/CargarContratoAdmin.svelte index 923d94d..653df58 100644 --- a/Front/src/paginas/CargarContratoAdmin.svelte +++ b/Front/src/paginas/CargarContratoAdmin.svelte @@ -11,8 +11,6 @@ dnipropietario: 0n, iddivisa: 0, idpropiedad: 0, - idventa: 0n, - indiceactualizacion: 0, mesesDurationContrato: 0, mesesHastaAumento: 0, monto: 0, @@ -137,8 +135,6 @@ formData.append('dnipropietario', contrato.dnipropietario.toString()); formData.append('iddivisa', contrato.iddivisa.toString()); formData.append('idpropiedad', contrato.idpropiedad.toString()); - formData.append('idventa', contrato.idventa.toString()); - formData.append('indiceactualizacion', contrato.indiceactualizacion.toString()); formData.append('mesesDurationContrato', contrato.mesesDurationContrato.toString()); formData.append('mesesHastaAumento', contrato.mesesHastaAumento.toString()); formData.append('monto', contrato.monto.toString()); @@ -180,8 +176,6 @@ dnipropietario: 0n, iddivisa: 0, idpropiedad: 0, - idventa: 0n, - indiceactualizacion: 0, mesesDurationContrato: 0, mesesHastaAumento: 0, monto: 0, @@ -323,20 +317,6 @@ -
- -
- -
-
-
diff --git a/Modelo/RepositorioContratos.cs b/Modelo/RepositorioContratos.cs index 8d073f4..e723275 100644 --- a/Modelo/RepositorioContratos.cs +++ b/Modelo/RepositorioContratos.cs @@ -4,6 +4,29 @@ using Microsoft.EntityFrameworkCore; namespace Modelo; public class RepositorioContratos: RepositorioBase { + + + public bool AdminCargaContrato(Contrato? cont, long dni){ + if (cont == null) return false; + + var con = Context; + + cont.Id = (con.Contratos.Any() ? con.Contratos.Max(x => x.Id) : 0) + 1; + + if (cont.IdventaNavigation != null){ + cont.IdventaNavigation.Id = (con.Ventas.Any()?con.Ventas.Count():0)+1; + con.Ventas.Add(cont.IdventaNavigation); + } + + var prop = con.Propiedades.FirstOrDefault(x=>x.Id == cont.Idpropiedad); + if (prop == null)return false; + + prop.Idestado = 2; + con.Contratos.Add(cont); + GenerarLog(con, dni, "Carga del contrato por parte de admin"); + return Guardar(con); + } + public IQueryable? ObtenerContratosPorEmailInquilino(string email) { var con = Context; try{ -- 2.52.0 From c180c8ef80938026b135dabb1f7eaea1e2253069 Mon Sep 17 00:00:00 2001 From: fede Date: Sun, 27 Jul 2025 13:53:57 -0300 Subject: [PATCH 88/91] fix: esto arregla todos los warnings de svelte --- Front/src/Componentes/LoginPanel.svelte | 4 +-- Front/src/Componentes/ModalAddGarantes.svelte | 30 +++++++++---------- Front/src/paginas/CrearUsuario.svelte | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Front/src/Componentes/LoginPanel.svelte b/Front/src/Componentes/LoginPanel.svelte index 417e7b2..0425889 100644 --- a/Front/src/Componentes/LoginPanel.svelte +++ b/Front/src/Componentes/LoginPanel.svelte @@ -171,8 +171,8 @@
{/if}
- (showrecuperarmodal = true)} - >Recuperar Cuenta {showrecuperarmodal = true; window.scrollTo(0,0);}} + >Recuperar Cuenta diff --git a/Front/src/Componentes/ModalAddGarantes.svelte b/Front/src/Componentes/ModalAddGarantes.svelte index 1351662..8890543 100644 --- a/Front/src/Componentes/ModalAddGarantes.svelte +++ b/Front/src/Componentes/ModalAddGarantes.svelte @@ -84,13 +84,13 @@
- +

Duración del Contrato:

{datosprecontrato.duracionEnMeses} Meses

- +

Frecuencia de Aumento:

Cada {datosprecontrato.frecuenciaAumentoEnMeses} meses

@@ -114,28 +114,28 @@
Añadir Garante
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +