diff --git a/Aspnet/Builder/Builder.cs b/Aspnet/Builder/Builder.cs new file mode 100644 index 0000000..2a9b274 --- /dev/null +++ b/Aspnet/Builder/Builder.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; +using Minio.Helper; + +public abstract class Builder where T:new() { + protected T data = new T(); + public T Build() { + return data; + } +} \ No newline at end of file diff --git a/Aspnet/Builder/DtoBuilder/GaranteDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/GaranteDtoBuilder.cs new file mode 100644 index 0000000..6583038 --- /dev/null +++ b/Aspnet/Builder/DtoBuilder/GaranteDtoBuilder.cs @@ -0,0 +1,36 @@ +using Entidades.Dto; + +namespace AlquilaFacil.Builder; +public class GaranteDtoBuilder : Builder { + + public GaranteDtoBuilder SetDni (long Dni) { + data.Dni = Dni; + return this; + } + + public GaranteDtoBuilder SetNombre (string Nombre) { + data.Nombre = Nombre; + return this; + } + + public GaranteDtoBuilder SetApellido (string Apellido) { + data.Apellido = Apellido; + return this; + } + + public GaranteDtoBuilder SetDomicilio (string Domicilio) { + data.Domicilio = Domicilio; + return this; + } + + public GaranteDtoBuilder SetCelular (string Celular) { + data.Celular = Celular; + return this; + } + + public GaranteDtoBuilder SetDomicilioLaboral (string Domiciliolaboral) { + data.Domiciliolaboral = Domiciliolaboral; + return this; + } + +} \ No newline at end of file diff --git a/Aspnet/Builder/DtoBuilder/NotificacionDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/NotificacionDtoBuilder.cs new file mode 100644 index 0000000..7f9cfdb --- /dev/null +++ b/Aspnet/Builder/DtoBuilder/NotificacionDtoBuilder.cs @@ -0,0 +1,34 @@ +namespace AlquilaFacil.Builder; +using Entidades.Dto; +public class NotificacionDtoBuilder: Builder { + + public NotificacionDtoBuilder SetRemitente(string remitente) { + data.Remitente = remitente; + return this; + } + + public NotificacionDtoBuilder SetAccion(string accion) { + data.Accion = accion; + return this; + } + + public NotificacionDtoBuilder SetMensaje(string mensaje) { + data.Mensaje = mensaje; + return this; + } + + public NotificacionDtoBuilder SetFecha(DateTime? fecha) { + data.Fecha = fecha; + return this; + } + + public NotificacionDtoBuilder SetPropiedad(string propiedad) { + data.Propiedad = propiedad; + return this; + } + + public NotificacionDtoBuilder SetReceptor(string receptor) { + data.Receptor = receptor; + return this; + } +} \ No newline at end of file diff --git a/Aspnet/Builder/GaranteBuilder.cs b/Aspnet/Builder/GaranteBuilder.cs new file mode 100644 index 0000000..4c996f4 --- /dev/null +++ b/Aspnet/Builder/GaranteBuilder.cs @@ -0,0 +1,35 @@ +using Entidades; + +namespace AlquilaFacil.Builder; + +public class GaranteBuilder : Builder { + public GaranteBuilder SetNombre(string Nombre) { + data.Nombre = Nombre; + return this; + } + + public GaranteBuilder SetApellido(string Apellido) { + data.Apellido = Apellido; + return this; + } + + public GaranteBuilder SetDni(long Dni) { + data.Dni = Dni; + return this; + } + + public GaranteBuilder SetDomicilio(string Domicilio) { + data.Domicilio = Domicilio; + return this; + } + + public GaranteBuilder SetCelular(string Celular) { + data.Celular = Celular; + return this; + } + + public GaranteBuilder SetDomicilioLaboral(string Domiciliolaboral) { + data.Domiciliolaboral = Domiciliolaboral; + return this; + } +} \ No newline at end of file diff --git a/Aspnet/Builder/NotificacionBuilder.cs b/Aspnet/Builder/NotificacionBuilder.cs new file mode 100644 index 0000000..baf3e6b --- /dev/null +++ b/Aspnet/Builder/NotificacionBuilder.cs @@ -0,0 +1,40 @@ +using System; +using Entidades; + +public class NotificacioneBuilder : Builder +{ + public NotificacioneBuilder SetDnicliente(long dnicliente) { + data.Dnicliente = dnicliente; + return this; + } + + public NotificacioneBuilder SetDniremitente(long dniremitente) { + data.Dniremitente = dniremitente; + return this; + } + + public NotificacioneBuilder SetFecha(DateTime fecha) { + data.Fecha = fecha; + return this; + } + + public NotificacioneBuilder SetMensaje(string mensaje) { + data.Mensaje = mensaje; + return this; + } + + public NotificacioneBuilder SetAccion(string accion) { + data.Accion = accion; + return this; + } + + public NotificacioneBuilder SetIdpropiedad(int idpropiedad) { + data.Idpropiedad = idpropiedad; + return this; + } + + public NotificacioneBuilder SetLeido(bool leido) { + data.Leido = leido; + return this; + } +} diff --git a/Aspnet/Builder/PrecontratoBuilder.cs b/Aspnet/Builder/PrecontratoBuilder.cs new file mode 100644 index 0000000..a51b1c0 --- /dev/null +++ b/Aspnet/Builder/PrecontratoBuilder.cs @@ -0,0 +1,45 @@ +namespace AlquilaFacil.Builder; + +using System; +using Entidades; +public class PrecontratoBuilder : Builder { + public PrecontratoBuilder SetHabilitado(){ + data.Habilitado = 0; + return this; + } + + public PrecontratoBuilder SetInquilino(long dniInq) { + data.Dniinquilino = dniInq; + return this; + } + + public PrecontratoBuilder SetPropietario(long dniProp) { + data.Dnipropietario = dniProp; + return this; + } + + public PrecontratoBuilder SetPropiedad(int idprop) { + data.Idpropiedad = idprop; + return this; + } + + public PrecontratoBuilder SetCantidadGarantes(int cantgarante) { + data.Cantgarantemin = cantgarante; + return this; + } + + public PrecontratoBuilder SetIndiceActializacionInicial() { + data.Indiceactualizacion = 0.000M; + return this; + } + + public PrecontratoBuilder SetMesesHastaAumento(int meses) { + data.MesesHastaAumento = meses; + return this; + } + + public PrecontratoBuilder SetFecha(DateTime fechaprimernotificacion){ + data.Fechainicio = fechaprimernotificacion; + return this; + } +} \ No newline at end of file diff --git a/Aspnet/Config/MinioConfig.cs b/Aspnet/Config/MinioConfig.cs new file mode 100644 index 0000000..df4fec8 --- /dev/null +++ b/Aspnet/Config/MinioConfig.cs @@ -0,0 +1,5 @@ +namespace AlquilaFacil.Config; +public class MinioConfigcus { + public string usr { get; set; } =""; + public string scrt { get; set; } = ""; +} \ No newline at end of file diff --git a/Aspnet/Controllers/AdminController.cs b/Aspnet/Controllers/AdminController.cs new file mode 100644 index 0000000..759c19d --- /dev/null +++ b/Aspnet/Controllers/AdminController.cs @@ -0,0 +1,152 @@ +using Microsoft.AspNetCore.Mvc; +using Modelo; +using Entidades.Admin; +using Entidades.Dto; +using Entidades; +using System.Linq.Expressions; +using AlquilaFacil.StrategyBusquedaAdmin; +using System.Diagnostics; +namespace AlquilaFacil.Controllers; + +[ApiController] +public class AdminController: ControllerBase +{ + [HttpGet("api/admin/clientes")] + public IActionResult GetClientes([FromHeader(Name ="Auth")]string Auth){ + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + if (validacion1 == false) return Unauthorized(); + + IEnumerablelist = RepositorioUsuarios.Singleton.GetClientes(); + return Ok(list); + } + + [HttpGet("api/admin/clientes/grupo")] + public IActionResult GetGruposByCliente([FromHeader(Name ="Auth")]string Auth, [FromQuery]long Dni){ + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + if (validacion1 == false) return Unauthorized(); + + if (Dni <= 0) return BadRequest(new {message = "No puede tener un dni con numero negativo o cero"}); + + IEnumerable list = RepositorioGrupos.Singleton.ObtenerGruposPorDni(Dni); + return Ok(list); + } + [HttpPatch("api/admin/cliente/addGrupo")] + public IActionResult AddGrupoACliente([FromHeader(Name = "Auth")]string Auth, [FromBody]EmailGrupo data){ + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + if (validacion1 == false) return Unauthorized(); + + if (data.email == "" || data.grupo == "") return BadRequest(new { message = "Faltan datos en la request" }); + + var ret = RepositorioUsuarios.Singleton.CheckGrupo(data.email, data.grupo); + if (ret) return BadRequest(new { message = $"El usuario ya pertenece al grupo {data.grupo}"}); + + var ret2 = RepositorioUsuarios.Singleton.AñadirClienteAGrupo(data.email, data.grupo); + + return ret2 ? Ok(new {message = "Se Añadio al Grupo"}): BadRequest(new { message = "Fallo al añadirse al Grupo" }); + } + + [HttpPatch("api/admin/cliente/rmGrupo")] + public IActionResult RmGrupoACliente([FromHeader(Name = "Auth")]string Auth, [FromBody]EmailGrupo data){ + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + if (validacion1 == false) return Unauthorized(); + + if (data.email == "" || data.grupo == "") return BadRequest(new { message = "Faltan datos en la request" }); + + //una ward para que no me bloquee a mi mismo de tener acceso a admin + if (data.email == "celu@fedesrv.ddns.net" && data.grupo == "Admin") return BadRequest(new { message = "Si hago esto me estaria bloqueando la cuenta a mi mismo" }); + + var ret = RepositorioUsuarios.Singleton.CheckGrupo(data.email, data.grupo); + if (!ret) return BadRequest(new { message = $"El usuario no pertenece al grupo {data.grupo}"}); + + if (data.grupo == "Propietario") { + IQueryable ret3 = RepositorioPropiedades.Singleton.ObtenerPropiedadesPorEmail(data.email); + if (ret3.Count() > 0){ + bool ret4 = RepositorioPropiedades.Singleton.BajaPropiedades(data.email); + if (ret4 == false) return BadRequest(new { message = "No se pudo dar de baja las propiedades"}); + } + } + if (data.grupo == "Inquilino") { + var ret5 = RepositorioContratos.Singleton.ObtenerContratosPorEmailInquilino(data.email); + if ( ret5 == null || ret5.Where(x=>x.Habilitado == 0).Count() > 0) return BadRequest(new { message = "Aun tenes alquileres pendientes o fallo al intentar obtener la lista de alquileres, no se puede dar de baja"}); + } + + var ret2 = RepositorioUsuarios.Singleton.EliminarClienteAGrupo(data.email, data.grupo); + return ret2 ? Ok(new {message = $"Se elimino del Grupo: {data.grupo}"}): BadRequest(new { message = "Fallo al añadirse al Grupo" }); + } + + [HttpDelete("api/admin/cliente")] + public IActionResult BajaCliente([FromHeader(Name ="Auth")]string Auth, long Dni){ + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); + if (validacion1 == false) return Unauthorized(); + + if ( Dni <=0) return BadRequest(new {message = "No puede tener un Dni menor o igual a 0"}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorDni(Dni); + + if (cli == null) return BadRequest(new {message = "No existe un cliente con ese numero de dni"}); + + bool esPropietario = RepositorioUsuarios.Singleton.CheckGrupo(cli.Email, "Propietario"); + bool esInquilino = RepositorioUsuarios.Singleton.CheckGrupo(cli.Email, "Inquilino"); + + if (esPropietario) { + IQueryable ret3 = RepositorioPropiedades.Singleton.ObtenerPropiedadesPorEmail(cli.Email); + if (ret3.Count() > 0){ + bool ret4 = RepositorioPropiedades.Singleton.BajaPropiedades(cli.Email); + if (ret4 == false) return BadRequest(new { message = "No se pudo dar de baja las propiedades"}); + } + } + + if (esInquilino) { + var ret5 = RepositorioContratos.Singleton.ObtenerContratosPorEmailInquilino(cli.Email); + if ( ret5 == null || ret5.Where(x=>x.Habilitado == 0).Count() > 0) return BadRequest(new { message = "Aun tenes alquileres pendientes o fallo al intentar obtener la lista de alquileres, no se puede dar de baja"}); + } + // lo da de baja si no tiene el grupo propietario y no tiene alquileres pendientes + var ret = RepositorioUsuarios.Singleton.BajaCliente(Dni); + return Ok(ret); + } + + [HttpDelete("api/admin/propiedad")] + public IActionResult BajaPropiedad([FromHeader(Name = "Auth")] string Auth, int id = 0) { + 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 = "Falto indicar id Propiedad"}); + + var ret = RepositorioPropiedades.Singleton.BajaPropiedad(id); + return ret ? + Ok(new {message = "Se cambio el estado de la propiedad"}): BadRequest(new { message = "No se pudo dar de baja"}); + } + + [HttpGet("api/admin/busqueda/paginada")] + public IActionResult FiltroPropiedadesPaginado([FromHeader(Name = "Auth")]string Auth, int cantidadHabitaciones = 0, int tipoPropiedad = 0, [FromQuery]string servicios = "", int pag = 1) { + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); + if (validacion1 == false) return Unauthorized(); + + IQueryable? props = null; + pag -= 1; + + var clave = $"{(cantidadHabitaciones != 0 ? "1" : "0")}{(tipoPropiedad != 0 ? "1" : "0")}{(!string.IsNullOrEmpty(servicios) ? "1" : "0")}"; + var gen = AdminBusquedaContext.Singleton; + var estrategia = gen.ObtenerEstrategia(clave); + props = estrategia.Filtrar(servicios, cantidadHabitaciones, tipoPropiedad, pag); + + return Ok(props); + } + + [HttpGet("api/admin/busqueda/cantPag")] + public IActionResult CantidadPaginas([FromHeader(Name = "Auth")]string Auth, int cantidadHabitaciones = 0, int tipoPropiedad = 0, [FromQuery]string servicios = "") { + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); + if (validacion1 == false) return Unauthorized(); + + int ret = RepositorioPropiedades.Singleton.CuantasPaginasBusqueda(cantidadHabitaciones, servicios, tipoPropiedad, 0); + return Ok(new { message = ret}); + } +} \ No newline at end of file diff --git a/Aspnet/Controllers/BusquedaControler.cs b/Aspnet/Controllers/BusquedaControler.cs new file mode 100644 index 0000000..1098add --- /dev/null +++ b/Aspnet/Controllers/BusquedaControler.cs @@ -0,0 +1,38 @@ +using Entidades.Dto; +using Modelo; +using Microsoft.AspNetCore.Mvc; +using Entidades.Admin; +using AlquilaFacil.StrategyBusqueda; + +namespace AlquilaFacil.Controllers; + +[ApiController] +public class BusquedaController: ControllerBase { + [HttpGet("api/busqueda")] + public IActionResult FiltroPropiedades([FromHeader(Name = "Auth")]string Auth, int cantidadHabitaciones = 0, int tipoPropiedad = 0, [FromQuery]string servicios = "") { + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 3); + if (validacion1 == false) return Unauthorized(); + + IQueryable? props = null; + + var clave = $"{(cantidadHabitaciones != 0 ? "1" : "0")}{(tipoPropiedad != 0 ? "1" : "0")}{(!string.IsNullOrEmpty(servicios) ? "1" : "0")}"; + + var gen = BusquedaContext.Singleton; + var estrategia = gen.ObtenerEstrategia(clave); + props = estrategia.Filtrar(servicios, cantidadHabitaciones, tipoPropiedad); + + return Ok(props); + } + + [HttpGet("api/busqueda/cantPag")] + public IActionResult GetCantPag([FromHeader(Name = "Auth")]string Auth, int cantidadHabitaciones = 0, int tipoPropiedad = 0, [FromQuery]string servicios = "") { + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 3); + if (validacion1 == false) return Unauthorized(); + + int ret = RepositorioPropiedades.Singleton.CuantasPaginasBusqueda(cantidadHabitaciones, servicios, tipoPropiedad, 1); + return Ok(new { message = ret}); + + } +} diff --git a/Aspnet/Controllers/ContratoController.cs b/Aspnet/Controllers/ContratoController.cs new file mode 100644 index 0000000..7b21e4c --- /dev/null +++ b/Aspnet/Controllers/ContratoController.cs @@ -0,0 +1,465 @@ +using System.Net; +using System.Text.Json; +using AlquilaFacil.Builder; +using AlquilaFacil.Config; +using Entidades; +using Entidades.Dto; +using Microsoft.AspNetCore.Mvc; +using Minio; +using Minio.DataModel; +using Minio.DataModel.Args; +using Minio.Exceptions; +using Modelo; + +namespace AlquilaFacil.Controllers; + +[ApiController] +public class ContratoController: ControllerBase { + + [HttpGet("api/contratos")] //WIP + public IActionResult ObtenerContratosPorUsuario([FromHeader(Name="Auth")]string Auth) { + return Ok(); + } + + [HttpPost("api/contratos/precontrato")] + public IActionResult IniciarPrecontrato([FromHeader(Name = "Auth")]string Auth, [FromBody] PrecontratoDto dto) { + if (String.IsNullOrEmpty(Auth)) return Unauthorized(); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + if (validacion1 == false) return Unauthorized(); + + string validacion2 = ValidarDtoPrecontrato(dto); + if (validacion2 != "") return BadRequest(new {message = validacion2}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new {message = "Tu token no corresponde a ningun cliente (volvete a logear)"}); + if (cli.Email != dto.EmailPropietario) return BadRequest(new {message = "No Corresponde el email de propietario con el del token"}); + + Cliente? propi = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(dto.EmailPropietario); + if (propi == null || propi.Dni == 0) return BadRequest(new {message = "No hay propietario por ese email"}); + + Cliente? inq = RepositorioInquilinos.Singleton.ObtenerInquilinoPorEmail(dto.EmailInquilino); + if (inq == null || inq.Dni == 0) return BadRequest(new {message = "No hay inquilinos por ese email"}); + + Propiedade? p = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.IdPropiedad); + if (p == null || p.Id == 0) return BadRequest(new {message = "La id de propiedad no corresponde a una propiedad"}); + + var precontrato = new PrecontratoBuilder() + .SetHabilitado() + .SetPropietario(propi.Dni) + .SetInquilino(inq.Dni) + .SetCantidadGarantes(dto.CantidadGarantes) + .SetIndiceActializacionInicial() + .SetMesesHastaAumento(dto.MesesHastaAumento) + .SetPropiedad(p.Id) + .SetFecha(DateTime.Parse(dto.fechaprimernotificacion)) + .Build(); + + + var notificacion = new NotificacioneBuilder() + .SetAccion("Carge Garantes") + .SetDniremitente(propi.Dni) + .SetDnicliente(inq.Dni) + .SetLeido(false) + .SetFecha(DateTime.Now) + .SetIdpropiedad(p.Id) + .SetMensaje($"El propietario {propi.Nombre} {propi.Apellido} te requiere que carges informacion de {dto.CantidadGarantes} Garantes") + .Build(); + + var ret = RepositorioContratos.Singleton.CargaPrecontrato(precontrato, notificacion); + 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"}); + } + + [HttpPut("api/contratos/addGarantes")] + public IActionResult AddGarantes([FromHeader(Name = "Auth")]string Auth, AltaGarantesDto dto) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); + if (validacion1 == false) return Unauthorized(); + + var validacion2 = ValidarDtoAltaGarantes(dto); + if (validacion2 != "") return BadRequest(new {message = validacion2}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new {message = "Tu token no corresponde a ningun cliente (volvete a logear)"}); + if (cli.Email != dto.EmailInquilino) return BadRequest(new {message = "No Corresponde el email de inquilino con el del token"}); + + var validacion4 = RepositorioContratos.Singleton.CantidadGarantesEncontrato(dto.EmailInquilino, dto.Idpropiedad); + if (validacion4 <= 0 || dto.garantes.Count()!=validacion4) return BadRequest(new{message="Cantidad de garantes incorrecta"}); + + Cliente? propi = RepositorioPropietario.Singleton.ObtenerPropietarioPorIdPropiedad(dto.Idpropiedad); + if(propi == null) return BadRequest(new{message = "No se encuentra el propietario de la propiedad"}); + + foreach (var i in dto.garantes) { + string validacion3 = ValidarDtoGarante(i); + if (validacion3 != "") return BadRequest( new { message = validacion3 }); + } + + List gar = new(); + + foreach (var i in dto.garantes) { + Garante g = new GaranteBuilder() + .SetNombre(i.Nombre) + .SetApellido(i.Apellido) + .SetCelular(i.Celular) + .SetDomicilio(i.Domicilio) + .SetDni(i.Dni) + .SetDomicilioLaboral(i.Domiciliolaboral) + .Build(); + gar.Add(g); + } + + var contr = RepositorioContratos.Singleton.ObtenerContrato(dto.EmailInquilino, dto.Idpropiedad); + if (contr == null) return BadRequest(new { message = "No existe el contrato o ya fue activado"}); + + var ret = RepositorioContratos.Singleton.CargaGarantes(gar, dto.EmailInquilino, dto.Idpropiedad); + if (ret) { + Console.WriteLine(dto.fecha); + RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.fecha); + + var noti = new NotificacioneBuilder() + .SetIdpropiedad(dto.Idpropiedad) + .SetAccion("Check y Contrato") + .SetMensaje($"El inquilino cargó los datos de garantes comprobá y carga el contrato: {contr.Id}") + .SetLeido(false) + .SetDniremitente(cli.Dni) + .SetDnicliente(propi.Dni) + .SetFecha(DateTime.Now) + .Build(); + ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); + } + return ret ? + Ok(new {message = "Se Añadieron los Garantes"}):BadRequest(new { message = "Fallo la carga"}); + } + + [HttpPut("api/contratos/cancelar")] + public IActionResult CancelarPrecontrato([FromHeader(Name = "Auth")]string Auth, CancelarPrecontratoDto dto) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + if (validacion1 == false) return Unauthorized(); + + var validacion2 = ValidarCancelarDto(dto); + if (validacion2 != "") return BadRequest(new {message = validacion2}); + + Cliente? pro = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(dto.EmailPropietario); + if (pro == null) return BadRequest(new {message = "No Existe Usuario con ese email"}); + if (pro.Token != Auth) return BadRequest(new {message = "El token de auth no corresponde al token el usuario propietario"}); + + Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad); + if (prop == null) return BadRequest(new {message = "No existe la propiedad por esa id"}); + if (prop.Dnipropietario != pro.Dni) return BadRequest(new {message = "Este propietario no es el dueño de la propiedad"}); + + var inq = RepositorioInquilinos.Singleton.ObtenerInquilinoPorEmail(dto.EmailInquilino); + if (inq == null) return BadRequest(new {message = "No hay un inquilino por ese email"}); + + var ret = RepositorioContratos.Singleton.CancelarPrecontrato(dto.EmailInquilino, dto.idpropiedad); + if (ret) { + prop.Idestado = 1; + ret = RepositorioPropiedades.Singleton.PatchPropiedad(prop); + if (ret){ + RepositorioNotificaciones.Singleton.MarcarComoLeido(pro.Dni, dto.fecha); + var noti = new NotificacioneBuilder() + .SetAccion("ContratoCancelado") + .SetIdpropiedad(dto.idpropiedad) + .SetDniremitente(pro.Dni) + .SetDnicliente(inq.Dni) + .SetMensaje($"Se cancelo el intento de alquilar la propiedad: {dto.idpropiedad}") + .SetIdpropiedad(dto.idpropiedad) + .SetLeido(false) + .Build(); + ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); + if (ret){ + return Ok(new {message = "Se cancelo el precontrato"}); + }else{ + return Ok(new {message = "Se cancelo el precontrato, pero no se pudo notificar al inquilino"}); + } + }else{ + return BadRequest(new {message = "No se pudo setear la propiedad como Disponible en busqueda"}); + } + }else{ + return BadRequest(new {message = "Se fallo al intentar cancelar el precontrato"}); + } + } + + [HttpGet("api/contratos/precontrato/listaGarantes")] + public IActionResult ObtenerListaGarantes([FromHeader(Name = "Auth")]string Auth, long idcontrato = 0, [FromQuery] string EmailPropietario = "" ) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); + if (validacion1 == false) return Unauthorized(); + + if (idcontrato == 0 || EmailPropietario == "") return BadRequest(new { message = "Estan mal cargados los datos"}); + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new {message = "No hay un propietario por ese token"}); + if (cli.Email != EmailPropietario) return BadRequest(new {message = "El Email del usuario no coinside con el del token"}); + + Contrato? contr = RepositorioContratos.Singleton.ObtenerPreContratoPorId(idcontrato); + if (contr == null) return BadRequest(new {message = "No hay un precontrato por esa id"}); + + LinkedList list = new(); + foreach (var i in contr.Idgarantes) { + list.AddFirst(new GaranteDtoBuilder() + .SetCelular(i.Celular) + .SetDni(i.Dni) + .SetDomicilio(i.Domicilio) + .SetDomicilioLaboral(i.Domiciliolaboral) + .SetNombre(i.Nombre) + .SetApellido(i.Apellido) + .Build()); + } + return Ok(list); + } + + private readonly IMinioClient mc; + public ContratoController(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("192.168.1.11:9000") + .WithSSL(false) + .Build(); + } + } + + [HttpPost("api/contratos/subirContrato")] + public async Task subirContrato([FromHeader(Name = "Auth")]string Auth, [FromForm]long idcontrato, [FromForm]DateTime ubicarnotificacion, IFormFile contrato) { + 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"}); + Contrato? contr = RepositorioContratos.Singleton.ObtenerPreContratoPorId(idcontrato); + if (contr == null) return BadRequest(new { message = "No hay precontrato por esa id"}); + if (contr.Dniinquilino == 0 || contr.Dnipropietario == 0 || contr.Idpropiedad == 0 || + contr.Dniinquilino == null || contr.Dnipropietario == null || contr.Idpropiedad == null) { + return BadRequest(new { message = "Estan mal cargados los datos del precontrato comunicate con un administrador"}); + } + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null || contr.DnipropietarioNavigation == null) return BadRequest(new { message ="No se pudo checkear que el token corresponda al propietario"}); + if (cli.Dni != contr.DnipropietarioNavigation.Dni) return BadRequest(new { message = "el token de usuario no coinside con el usuario propietario"}); + + if (contrato == null) return BadRequest(new { message = "Debe subir un archivo." }); + if (contrato.ContentType != "application/pdf") return BadRequest(new { message = "El archivo debe ser un documento PDF." }); + if (!Path.GetExtension(contrato.FileName).Equals(".pdf", StringComparison.OrdinalIgnoreCase)) return BadRequest(new { message = "El archivo debe tener la extensión .pdf." }); + + string nuevoNombreArchivo = $"id:{contr.Id}-inq:{contr.Dniinquilino}-propi:{contr.Dnipropietario}-idprop:{contr.Idpropiedad}.pdf"; + + bool ret = await subirContrato(contrato, nuevoNombreArchivo); + if(ret == false) return BadRequest(new {message = "No se pudo subir el archivo"}); + + ret = RepositorioContratos.Singleton.AddUrl(contr.Id, nuevoNombreArchivo); + if (ret == false) return BadRequest(new { message = "No se pudo guardar la url del contrato" }); + + var noti = new NotificacioneBuilder() + .SetDniremitente(contr.Dnipropietario??0) + .SetIdpropiedad(contr.Idpropiedad??0) + .SetDnicliente(contr.Dniinquilino??0) + .SetAccion("Aceptar Contrato") + .SetMensaje($"El propietario: {contr.Dnipropietario}, hizo un documento de contrato: {contr.Id}") + .SetFecha(DateTime.Now) + .SetLeido(false) + .Build(); + + RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, ubicarnotificacion); + ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); + + return (ret)? + Ok(new { message = "se notifico al futuro inquilino"}): BadRequest(new { message = "No se pudo enviar la notificacion"}); + + } + + [HttpGet("api/contrato/getdocumento")] + public IActionResult ObtenerContrato([FromHeader(Name = "Auth")]string Auth, [FromQuery]long idcontrato) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); + if (validacion1 == false) return Unauthorized(); + + if (idcontrato <= 0) return BadRequest(new {message = "La id no puede ser igual o menor a 0"}); + + Contrato? contr = RepositorioContratos.Singleton.ObtenerPreContratoPorId(idcontrato); + if (contr == null || contr.Dniinquilino == 0) return BadRequest(new { message = "No hay un precontrato por esa id"}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por ese token"}); + if (cli.Dni != contr.Dniinquilino) return BadRequest(new { message = "El token no corresponde con el del inquilino"}); + + string nuevoNombreArchivo = $"id:{contr.Id}-inq:{contr.Dniinquilino}-propi:{contr.Dnipropietario}-idprop:{contr.Idpropiedad}.pdf"; + try{ + var memstream = new MemoryStream(); + + var goa = new GetObjectArgs() + .WithBucket("alquilafacil") + .WithObject(nuevoNombreArchivo) + .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", nuevoNombreArchivo); + + } catch (Exception e){ + Console.Error.WriteLine(e); + return BadRequest(new { message = "Fallo al intentar obtener el archivo del almacenamiento o este no existe"}); + } + + } + + [HttpPost("api/contratos/aceptarContrato")] + public IActionResult AceptarContrato([FromHeader(Name = "Auth")]string Auth, [FromBody] AceptarContratoDto dto){ + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); + if (validacion1 == false) return Unauthorized(); + + if (dto.Idcontrato <= 0) return BadRequest(new {message = "La id no puede ser igual o menor a 0"}); + + Contrato? contr = RepositorioContratos.Singleton.ObtenerPreContratoPorId(dto.Idcontrato); + if (contr == null || contr.Dniinquilino == 0) return BadRequest(new { message = "No hay un precontrato por esa id"}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por ese token"}); + if (cli.Dni != contr.Dniinquilino) return BadRequest(new { message = "El token no corresponde con el del inquilino"}); + + bool ret = RepositorioContratos.Singleton.AceptarContrato(dto.Idcontrato); + if (ret == false) return BadRequest(new { message ="fallo al aceptar el contrato"}); + + RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha); + + var noti = new NotificacioneBuilder() + .SetDniremitente(cli.Dni) + .SetIdpropiedad(contr.Idpropiedad??0) + .SetDnicliente(contr.Dnipropietario??0) + .SetAccion("Aceptado Contrato") + .SetMensaje($"Se inicio el alquiler") + .SetFecha(DateTime.Now) + .SetLeido(false) + .Build(); + + ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); + return ret ? + Ok(new { message = "Se acepto el contrato y se crearon los Canons a ser pagados"}) : + BadRequest(new { message = "No se pudo aceptar el contrato"}); + + } + + [HttpPut("api/contratos/rechazarPreContrato")] + public IActionResult CancelarContrato([FromHeader(Name = "Auth")]string Auth, [FromBody] RechazarPreContrato dto ) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); + if (validacion1 == false) return Unauthorized(); + + if (dto.Idcontrato <= 0) return BadRequest(new {message = "La id no puede ser igual o menor a 0"}); + + Contrato? contr = RepositorioContratos.Singleton.ObtenerPreContratoPorId(dto.Idcontrato); + if (contr == null || contr.Dniinquilino == 0) return BadRequest(new { message = "No hay un precontrato por esa id"}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + if (cli == null) return BadRequest(new { message = "No hay un cliente por ese token"}); + if (cli.Dni != contr.Dniinquilino) return BadRequest(new { message = "El token no corresponde con el del inquilino"}); + + var ret = RepositorioContratos.Singleton.CancelarPrecontrato(dto.Idcontrato); + if (ret == false) return BadRequest(new {message = "Fallo al intentar cancelar el precontrato"}); + + RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha); + var noti = new NotificacioneBuilder() + .SetDniremitente(cli.Dni) + .SetIdpropiedad(contr.Idpropiedad??0) + .SetDnicliente(contr.Dnipropietario??0) + .SetAccion("Rechazo Contrato") + .SetMensaje($"Se cancelo el proceso para alquilar de: {cli.Nombre}") + .SetFecha(DateTime.Now) + .SetLeido(false) + .Build(); + ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); + + return ret? + Ok(new { message = "Se cancelo el proceso para iniciar el alquiler"}): + BadRequest(new { message = "No se pudo cancelar"}); + } + + 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){ + var mb = new MakeBucketArgs().WithBucket("alquilafacil"); + await mc.MakeBucketAsync(mb).ConfigureAwait(false); + } + using (var stream = new MemoryStream()){ + await f.CopyToAsync(stream); + stream.Position=0; + PutObjectArgs putbj = new PutObjectArgs() + .WithBucket("alquilafacil") + .WithObject(flname) + .WithStreamData(stream) + .WithContentType("application/pdf") + .WithObjectSize(stream.Length); + await mc.PutObjectAsync(putbj); + } + return true; + } catch (Exception e ) { + Console.Error.WriteLine(e.Message); + return false; + } + } + + private string ValidarCancelarDto(CancelarPrecontratoDto dto) { + if (dto == null) return "dto nulo"; + string ret = ""; + + if (dto.EmailInquilino =="") ret += "No puede tener un EmailInquilino Vacio\n"; + if (dto.EmailPropietario =="") ret += "No puede tener un EmailPropietario Vacio\n"; + if (dto.idpropiedad <= 0 ) ret += "No puede tener id propiedad igual o menor a 0\n"; + if (dto.fecha == DateTime.MinValue) ret += "Falta fecha\n"; + return ret; + } + + private string ValidarDtoGarante(GaranteDto g) { + string ret = ""; + if (g == null) return "dto nulo"; + + if (g.Celular == "") ret += "No puede tener un numero de telefono vacio\n"; + if (g.Nombre == "") ret += "No puede tener un nombre vacio\n"; + if (g.Apellido == "") ret += "No puede tener un apellido vacio\n"; + if (g.Domiciliolaboral == "") ret += "Tiene que especificar su domicilio laboral\n"; + if (g.Domicilio == "") ret += "Tiene que especificar su domilio\n"; + + return ret; + } + + private string ValidarDtoAltaGarantes(AltaGarantesDto dto){ + string ret = ""; + if (dto == null) return "dto nulo"; + + if (dto.garantes.Count()<=0) ret += "No se puede tener 0 o menos garantes\n"; + if (dto.Idpropiedad<=0) ret += "la id de propiedad no puede ser igual o menor a 0\n"; + if (dto.EmailInquilino == "") ret += "El email de inquilino no puede estar vacio\n"; + + return ret; + } + private string ValidarDtoPrecontrato( PrecontratoDto dto) { + string ret = ""; + if (dto == null) return "dto nulo"; + + if (dto.CantidadGarantes<0) ret += "la cantidad de garantes necesarios no pueden ser menor a 0\n"; + if (dto.CantidadGarantes>10) ret += "Hay un maximo de 10 garantes\n"; + if (dto.EmailInquilino == "") ret += "el email del inquilino no puede ser nulo\n"; + if (dto.EmailPropietario == "") ret += "el email del propietario no puede estar vacio\n"; + if (dto.IdPropiedad <= 0) ret += "la id de propiedad no puede ser igual o menor a 0\n"; + if (dto.MesesHastaAumento <= 0) ret += "No puede tener 0 o menos meses hasta el aumento\n"; + + return ret; + } + +} \ No newline at end of file diff --git a/Aspnet/Controllers/NotificacionesController.cs b/Aspnet/Controllers/NotificacionesController.cs new file mode 100644 index 0000000..fa8a141 --- /dev/null +++ b/Aspnet/Controllers/NotificacionesController.cs @@ -0,0 +1,95 @@ +using AlquilaFacil.Builder; +using Entidades; +using Entidades.Dto; +using Microsoft.AspNetCore.Mvc; +using Modelo; + +namespace AlquilaFacil.Controllers; + +[ApiController] +public class NotificacionesController: ControllerBase { + [HttpGet("api/notificaciones")] + 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?)"}); + + + IQueryable notificaciones = RepositorioNotificaciones.Singleton.ObtenerNotificacionesDeUsuario(cli.Dni) + .Where(x=>x.Leido == leido); + List noti = new(); + Parallel.ForEach(notificaciones, i => { + var dto = new NotificacionDtoBuilder() + .SetRemitente(i.DniremitenteNavigation.Email) + .SetAccion(i.Accion) + .SetMensaje(i.Mensaje) + .SetFecha(i.Fecha) + .SetPropiedad(i.IdpropiedadNavigation.Id.ToString()) + .SetReceptor(i.DniclienteNavigation.Email) + .Build(); + + noti.Add(dto); + }); + return Ok(noti); + } + + [HttpGet("api/notificaciones/haySinLeer")] + 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?)"}); + + bool ret = RepositorioNotificaciones.Singleton.HayNotis(cli.Dni); + return Ok(new {message = ret}); + } + + [HttpPut("api/notificaciones")] + 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"}); + + Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); + + 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"}); + + 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"}); + } + + [HttpPost("api/notificaciones/consultaAlquiler")] + 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 (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 ????"}); + + var noti = new NotificacioneBuilder() + .SetAccion(data.Accion) + .SetMensaje(data.Mensaje) + .SetLeido(false) + .SetDnicliente(prop.DnipropietarioNavigation.Dni) + .SetDniremitente(inq.Dni) + .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"}); + } +} \ No newline at end of file diff --git a/Aspnet/Controllers/PropiedadesController.cs b/Aspnet/Controllers/PropiedadesController.cs index 08f78c9..0da73b7 100644 --- a/Aspnet/Controllers/PropiedadesController.cs +++ b/Aspnet/Controllers/PropiedadesController.cs @@ -8,19 +8,27 @@ namespace AlquilaFacil.Controllers; [ApiController] public class PropiedadesController: ControllerBase { [HttpGet("api/propiedades")] - public IActionResult ListarPropiedades([FromHeader(Name = "Auth")] string Auth) { + public IActionResult ListarPropiedades([FromHeader(Name = "Auth")] string Auth, int pag = 0) { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12); + var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); + if (validacion1 == false) validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) return Unauthorized(); - var ret = RepositorioPropiedades.Singleton.ListarPropiedades(); + IQueryable ret; + + if (pag == 0){ + ret = RepositorioPropiedades.Singleton.ListarPropiedades(); + } else{ + ret = RepositorioPropiedades.Singleton.ListarPropiedadesPorPagina(pag); + } + return Ok(ret); } [HttpGet("api/propiedad")] public IActionResult ObtenerPropiedadPorId(int Id, [FromHeader(Name = "Auth")] string Auth) { if (String.IsNullOrEmpty(Auth)) return Unauthorized(); - var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12); + 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"}); @@ -30,6 +38,25 @@ public class PropiedadesController: ControllerBase { return Ok(ret); } + [HttpGet("api/propiedad/cantPagina")] + 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"}); + int cant; + + if(estado == 0){ + cant = RepositorioPropiedades.Singleton.CuantasPaginas(); + }else{ + cant = RepositorioPropiedades.Singleton.CuantasPaginas(estado); + } + + return Ok(new {message = cant}); + + } + [HttpGet("api/propiedades/Propietario")] public IActionResult ObtenerPropiedadesPorPropietario ( [FromHeader(Name = "Email")] string email, @@ -81,6 +108,7 @@ public class PropiedadesController: ControllerBase { Ubicacion = propiedad.Ubicacion, Letra = propiedad.Letra ?? null, Piso = propiedad.Piso ?? null, + Monto = propiedad.Monto, }; var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop); @@ -113,6 +141,7 @@ public class PropiedadesController: ControllerBase { Letra = propiedad.Letra ?? null, Piso = propiedad.Piso ?? null, IdServicios = servs, + Monto = propiedad.Monto }; bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop); @@ -191,10 +220,11 @@ public class PropiedadesController: ControllerBase { 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"; + 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"; return ret; } @@ -205,14 +235,15 @@ public class PropiedadesController: ControllerBase { 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"; + 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"; + 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"; return ret; } diff --git a/Aspnet/Program.cs b/Aspnet/Program.cs index e83391e..4ad5df2 100644 --- a/Aspnet/Program.cs +++ b/Aspnet/Program.cs @@ -1,10 +1,29 @@ +using System.Text.Json; +using Minio; +using AlquilaFacil.Config; +using Microsoft.AspNetCore.Http.Features; + var builder = WebApplication.CreateBuilder(args); + +MinioConfigcus? mcon = JsonSerializer.Deserialize(File.ReadAllText("./settings.json"))?? null; +if (mcon == null) return; + // Add services to the container. builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddMinio(options => options + .WithCredentials(mcon.usr, mcon.scrt) + .WithEndpoint("192.168.1.11:9000") + .WithSSL(false) + .Build()); + +builder.Services.Configure(options => +{ + options.MultipartBodyLengthLimit = 50 * 1024 * 1024; // 50 MB +}); builder.Services.AddCors(options => { diff --git a/Aspnet/Strategy/Busqueda/BusquedaContext.cs b/Aspnet/Strategy/Busqueda/BusquedaContext.cs new file mode 100644 index 0000000..497272b --- /dev/null +++ b/Aspnet/Strategy/Busqueda/BusquedaContext.cs @@ -0,0 +1,29 @@ +namespace AlquilaFacil.StrategyBusqueda; + +public class BusquedaContext +{ + private static readonly BusquedaContext singleton = new(); + public static BusquedaContext Singleton {get { return singleton; } } + + private readonly Dictionary _estrategias; + + public BusquedaContext() + { + _estrategias = new Dictionary + { + { "000", new BusquedaSinParametros() }, + { "100", new BusquedaPorHabitaciones() }, + { "010", new BusquedaPorTipo() }, + { "001", new BusquedaPorServicios() }, + { "110", new BusquedaPorHabitacionesTipo() }, + { "101", new BusquedaPorHabitacionesServicios() }, + { "011", new BusquedaTipoServicios() }, + { "111", new BusquedaFull() } + }; + } + + public IBusquedaStrategy ObtenerEstrategia(string clave) + { + return _estrategias.ContainsKey(clave) ? _estrategias[clave] : new BusquedaSinParametros(); + } +} \ No newline at end of file diff --git a/Aspnet/Strategy/Busqueda/Filtros.cs b/Aspnet/Strategy/Busqueda/Filtros.cs new file mode 100644 index 0000000..e50c434 --- /dev/null +++ b/Aspnet/Strategy/Busqueda/Filtros.cs @@ -0,0 +1,52 @@ +using Entidades.Dto; +using Modelo; + +namespace AlquilaFacil.StrategyBusqueda; + +public class BusquedaSinParametros : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ListarPropiedades(); + } +} + +public class BusquedaPorHabitaciones : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones(cantidadHabitaciones); + } +} + +public class BusquedaPorTipo : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorTipo(tipoPropiedad); + } +} + +public class BusquedaPorServicios : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorServicios(servicios); + } +} + +public class BusquedaPorHabitacionesTipo : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones_Tipo(cantidadHabitaciones, tipoPropiedad); + } +} + +public class BusquedaPorHabitacionesServicios : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones_Servicios(cantidadHabitaciones, servicios); + } +} + +public class BusquedaTipoServicios : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorTipo_Servicios(tipoPropiedad, servicios); + } +} + +public class BusquedaFull : IBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones_Tipo_Servicios(cantidadHabitaciones, tipoPropiedad, servicios); + } +} \ No newline at end of file diff --git a/Aspnet/Strategy/Busqueda/IBusquedaStrategy.cs b/Aspnet/Strategy/Busqueda/IBusquedaStrategy.cs new file mode 100644 index 0000000..4a3f411 --- /dev/null +++ b/Aspnet/Strategy/Busqueda/IBusquedaStrategy.cs @@ -0,0 +1,6 @@ +namespace AlquilaFacil.StrategyBusqueda; +using Entidades.Dto; +public interface IBusquedaStrategy { + IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad); +} + diff --git a/Aspnet/Strategy/BusquedaAdmin/AdminBusquedaContext.cs b/Aspnet/Strategy/BusquedaAdmin/AdminBusquedaContext.cs new file mode 100644 index 0000000..801557b --- /dev/null +++ b/Aspnet/Strategy/BusquedaAdmin/AdminBusquedaContext.cs @@ -0,0 +1,29 @@ +namespace AlquilaFacil.StrategyBusquedaAdmin; + +public class AdminBusquedaContext +{ + private static readonly AdminBusquedaContext singleton = new(); + public static AdminBusquedaContext Singleton {get { return singleton; } } + + private readonly Dictionary _estrategias; + + public AdminBusquedaContext() + { + _estrategias = new Dictionary + { + { "000", new BusquedaSinParametros() }, + { "100", new BusquedaPorHabitaciones() }, + { "010", new BusquedaPorTipo() }, + { "001", new BusquedaPorServicios() }, + { "110", new BusquedaPorHabitacionesTipo() }, + { "101", new BusquedaPorHabitacionesServicios() }, + { "011", new BusquedaTipoServicios() }, + { "111", new BusquedaFull() } + }; + } + + public IAdminBusquedaStrategy ObtenerEstrategia(string clave) + { + return _estrategias.ContainsKey(clave) ? _estrategias[clave] : new BusquedaSinParametros(); + } +} \ No newline at end of file diff --git a/Aspnet/Strategy/BusquedaAdmin/Filtros.cs b/Aspnet/Strategy/BusquedaAdmin/Filtros.cs new file mode 100644 index 0000000..8506bd9 --- /dev/null +++ b/Aspnet/Strategy/BusquedaAdmin/Filtros.cs @@ -0,0 +1,52 @@ +using Entidades.Admin; +using Modelo; + +namespace AlquilaFacil.StrategyBusquedaAdmin; + +public class BusquedaSinParametros : IAdminBusquedaStrategy { + public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ListarPropiedadesPorPaginaAdmin(pag); + } +} + +public class BusquedaPorHabitaciones : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitacionesPaginado(cantidadHabitaciones, pag); + } +} + +public class BusquedaPorTipo : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorTipoPaginado(tipoPropiedad, pag); + } +} + +public class BusquedaPorServicios : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorServiciosPaginado(servicios, pag); + } +} + +public class BusquedaPorHabitacionesTipo : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones_TipoPaginado(cantidadHabitaciones, tipoPropiedad, pag); + } +} + +public class BusquedaPorHabitacionesServicios : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones_Servicios_Paginado(cantidadHabitaciones, servicios, pag); + } +} + +public class BusquedaTipoServicios : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorTipo_Servicios_Paginado(tipoPropiedad, servicios, pag); + } +} + +public class BusquedaFull : IAdminBusquedaStrategy { +public IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag) { + return RepositorioPropiedades.Singleton.ObtenerPropiedesPorHabitaciones_Tipo_Servicios_Paginado(cantidadHabitaciones, tipoPropiedad, servicios, pag); + } +} \ No newline at end of file diff --git a/Aspnet/Strategy/BusquedaAdmin/IAdminBusquedaStrategy.cs b/Aspnet/Strategy/BusquedaAdmin/IAdminBusquedaStrategy.cs new file mode 100644 index 0000000..9151de7 --- /dev/null +++ b/Aspnet/Strategy/BusquedaAdmin/IAdminBusquedaStrategy.cs @@ -0,0 +1,6 @@ +namespace AlquilaFacil.StrategyBusquedaAdmin; +using Entidades.Admin; +public interface IAdminBusquedaStrategy { + IQueryable Filtrar(string servicios, int cantidadHabitaciones, int tipoPropiedad, int pag); +} + diff --git a/Aspnet/bin/Debug/net8.0/settings.json b/Aspnet/bin/Debug/net8.0/settings.json new file mode 100644 index 0000000..a595e0c --- /dev/null +++ b/Aspnet/bin/Debug/net8.0/settings.json @@ -0,0 +1,4 @@ +{ + "usr":"aVO9C3PqeK1hiPCyqZCj", + "scrt":"szj58kceWG3GcRZ8P1QCQiv5tSjMI7iD5zfjneTT" +} \ No newline at end of file diff --git a/Aspnet/settings.json b/Aspnet/settings.json new file mode 100644 index 0000000..a595e0c --- /dev/null +++ b/Aspnet/settings.json @@ -0,0 +1,4 @@ +{ + "usr":"aVO9C3PqeK1hiPCyqZCj", + "scrt":"szj58kceWG3GcRZ8P1QCQiv5tSjMI7iD5zfjneTT" +} \ No newline at end of file diff --git a/Entidades/Admin/EmailGrupo.cs b/Entidades/Admin/EmailGrupo.cs new file mode 100644 index 0000000..3db517c --- /dev/null +++ b/Entidades/Admin/EmailGrupo.cs @@ -0,0 +1,2 @@ +namespace Entidades.Admin; +public record EmailGrupo(string email, string grupo); \ No newline at end of file diff --git a/Entidades/Admin/GrupoAdmin.cs b/Entidades/Admin/GrupoAdmin.cs new file mode 100644 index 0000000..a25dd9c --- /dev/null +++ b/Entidades/Admin/GrupoAdmin.cs @@ -0,0 +1,7 @@ +namespace Entidades.Admin; + +public class GrupoAdmin { + public int Id {get; set;} = 0; + public String Descripcion {get; set;} = ""; + public List Permisos {get; set;} = new(); +} \ No newline at end of file diff --git a/Entidades/Admin/PermisosAdmin.cs b/Entidades/Admin/PermisosAdmin.cs new file mode 100644 index 0000000..aba95e0 --- /dev/null +++ b/Entidades/Admin/PermisosAdmin.cs @@ -0,0 +1,6 @@ +namespace Entidades.Admin; + +public class PermisoAdmin { + public int Id {get; set;} + public String Descripcion {get; set;} = ""; +} \ No newline at end of file diff --git a/Entidades/Admin/PropiedadesAdmin.cs b/Entidades/Admin/PropiedadesAdmin.cs new file mode 100644 index 0000000..25274e5 --- /dev/null +++ b/Entidades/Admin/PropiedadesAdmin.cs @@ -0,0 +1,12 @@ +namespace Entidades.Admin; +public class PropiedadesAdmin { + public int id { get; set; } + public string Ubicacion { get; set; } = ""; + public int canthabitaciones { get; set; } + public int piso { get; set; } + public string letra { get; set; } = ""; + public string Tipo { get; set; } = ""; + public string? Servicios {get;set;} = ""; + public int Monto { get; set; } + public string Estado { get; set; } = ""; +} diff --git a/Entidades/Admin/UsuarioAdmin.cs b/Entidades/Admin/UsuarioAdmin.cs new file mode 100644 index 0000000..6833961 --- /dev/null +++ b/Entidades/Admin/UsuarioAdmin.cs @@ -0,0 +1,8 @@ +namespace Entidades.Admin; + +public record UsuarioAdmin { + public long Dni { get; set; } = 0; + public string Nombre { get; set; } = ""; + public string Email { get; set; } = ""; + public ulong Habilitado { get; set; } +} \ No newline at end of file diff --git a/Entidades/Alquilafacilcontext.cs b/Entidades/Alquilafacilcontext.cs index 9aa070d..8199acb 100644 --- a/Entidades/Alquilafacilcontext.cs +++ b/Entidades/Alquilafacilcontext.cs @@ -33,6 +33,8 @@ public partial class AlquilaFacilContext : DbContext public virtual DbSet Grupos { get; set; } + public virtual DbSet Notificaciones { get; set; } + public virtual DbSet Permisos { get; set; } public virtual DbSet Propiedades { get; set; } @@ -154,6 +156,9 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Id) .HasColumnType("bigint(20)") .HasColumnName("id"); + entity.Property(e => e.Cancelado) + .HasColumnType("bit(1)") + .HasColumnName("cancelado"); entity.Property(e => e.Cantgarantemin) .HasColumnType("int(11)") .HasColumnName("cantgarantemin"); @@ -178,12 +183,16 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Indiceactualizacion) .HasPrecision(8) .HasColumnName("indiceactualizacion"); + entity.Property(e => e.MesesHastaAumento).HasColumnType("int(11)"); entity.Property(e => e.Monto) .HasPrecision(12) .HasColumnName("monto"); entity.Property(e => e.Tieneopcionventa) .HasColumnType("bit(1)") .HasColumnName("tieneopcionventa"); + entity.Property(e => e.UrlContrato) + .HasMaxLength(100) + .HasColumnName("urlContrato"); entity.HasOne(d => d.DniinquilinoNavigation).WithMany(p => p.ContratoDniinquilinoNavigations) .HasForeignKey(d => d.Dniinquilino) @@ -312,17 +321,20 @@ public partial class AlquilaFacilContext : DbContext modelBuilder.Entity(entity => { - entity.HasKey(e => e.Dni).HasName("PRIMARY"); + entity.HasKey(e => e.Id).HasName("PRIMARY"); - entity.Property(e => e.Dni) - .HasColumnType("bigint(20)") - .HasColumnName("dni"); + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); entity.Property(e => e.Apellido) .HasMaxLength(20) .HasColumnName("apellido"); entity.Property(e => e.Celular) .HasMaxLength(40) .HasColumnName("celular"); + entity.Property(e => e.Dni) + .HasColumnType("bigint(20)") + .HasColumnName("dni"); entity.Property(e => e.Domicilio) .HasMaxLength(40) .HasColumnName("domicilio"); @@ -333,7 +345,7 @@ public partial class AlquilaFacilContext : DbContext .HasMaxLength(20) .HasColumnName("nombre"); - entity.HasMany(d => d.Idcontratos).WithMany(p => p.Dnigarantes) + entity.HasMany(d => d.Idcontratos).WithMany(p => p.Idgarantes) .UsingEntity>( "ContratoGarante", r => r.HasOne().WithMany() @@ -341,17 +353,17 @@ public partial class AlquilaFacilContext : DbContext .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_CONGAR_CON"), l => l.HasOne().WithMany() - .HasForeignKey("Dnigarante") + .HasForeignKey("Idgarante") .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_CONGAR_GAR"), j => { - j.HasKey("Dnigarante", "Idcontrato").HasName("PRIMARY"); + j.HasKey("Idgarante", "Idcontrato").HasName("PRIMARY"); j.ToTable("contrato_garantes"); j.HasIndex(new[] { "Idcontrato" }, "FK_CONGAR_CON"); - j.IndexerProperty("Dnigarante") - .HasColumnType("bigint(20)") - .HasColumnName("dnigarante"); + j.IndexerProperty("Idgarante") + .HasColumnType("int(11)") + .HasColumnName("idgarante"); j.IndexerProperty("Idcontrato") .HasColumnType("bigint(20)") .HasColumnName("idcontrato"); @@ -370,6 +382,50 @@ public partial class AlquilaFacilContext : DbContext .HasColumnName("nombre"); }); + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.Dnicliente, e.Fecha }).HasName("PRIMARY"); + + entity.HasIndex(e => e.Idpropiedad, "FK_NOTPROP"); + + entity.HasIndex(e => e.Dniremitente, "FK_NOTREM"); + + entity.Property(e => e.Dnicliente) + .HasColumnType("bigint(20)") + .HasColumnName("dnicliente"); + entity.Property(e => e.Fecha) + .HasColumnType("datetime") + .HasColumnName("fecha"); + entity.Property(e => e.Accion) + .HasMaxLength(30) + .HasColumnName("accion"); + entity.Property(e => e.Dniremitente) + .HasColumnType("bigint(20)") + .HasColumnName("dniremitente"); + entity.Property(e => e.Idpropiedad) + .HasColumnType("int(11)") + .HasColumnName("idpropiedad"); + entity.Property(e => e.Leido).HasColumnName("leido"); + entity.Property(e => e.Mensaje) + .HasMaxLength(255) + .HasColumnName("mensaje"); + + entity.HasOne(d => d.DniclienteNavigation).WithMany(p => p.NotificacioneDniclienteNavigations) + .HasForeignKey(d => d.Dnicliente) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_NOTCLI"); + + entity.HasOne(d => d.DniremitenteNavigation).WithMany(p => p.NotificacioneDniremitenteNavigations) + .HasForeignKey(d => d.Dniremitente) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_NOTREM"); + + entity.HasOne(d => d.IdpropiedadNavigation).WithMany(p => p.Notificaciones) + .HasForeignKey(d => d.Idpropiedad) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_NOTPROP"); + }); + modelBuilder.Entity(entity => { entity.HasKey(e => e.Id).HasName("PRIMARY"); @@ -378,7 +434,7 @@ public partial class AlquilaFacilContext : DbContext .HasColumnType("int(11)") .HasColumnName("id"); entity.Property(e => e.Descripcion) - .HasMaxLength(15) + .HasMaxLength(25) .HasColumnName("descripcion"); entity.HasMany(d => d.Idgrupos).WithMany(p => p.Idpermisos) @@ -435,6 +491,9 @@ public partial class AlquilaFacilContext : DbContext .HasMaxLength(1) .IsFixedLength() .HasColumnName("letra"); + entity.Property(e => e.Monto) + .HasPrecision(10) + .HasColumnName("monto"); entity.Property(e => e.Piso) .HasColumnType("int(11)") .HasColumnName("piso"); diff --git a/Entidades/Cliente.cs b/Entidades/Cliente.cs index ef52593..9f69cbb 100644 --- a/Entidades/Cliente.cs +++ b/Entidades/Cliente.cs @@ -27,6 +27,10 @@ public partial class Cliente public virtual ICollection ContratoDnipropietarioNavigations { get; set; } = new List(); + public virtual ICollection NotificacioneDniclienteNavigations { get; set; } = new List(); + + public virtual ICollection NotificacioneDniremitenteNavigations { get; set; } = new List(); + public virtual ICollection Propiedades { get; set; } = new List(); public virtual ICollection VentaIdCompradorNavigations { get; set; } = new List(); diff --git a/Entidades/Contrato.cs b/Entidades/Contrato.cs index 2f0fdbc..fb566fd 100644 --- a/Entidades/Contrato.cs +++ b/Entidades/Contrato.cs @@ -27,6 +27,12 @@ public partial class Contrato public ulong Habilitado { get; set; } + public int MesesHastaAumento { get; set; } + + public string? UrlContrato { get; set; } + + public ulong Cancelado { get; set; } + public virtual ICollection Defectos { get; set; } = new List(); public virtual Cliente? DniinquilinoNavigation { get; set; } @@ -37,7 +43,7 @@ public partial class Contrato public virtual Venta? IdventaNavigation { get; set; } - public virtual ICollection Dnigarantes { get; set; } = new List(); - public virtual ICollection Idcanons { get; set; } = new List(); + + public virtual ICollection Idgarantes { get; set; } = new List(); } diff --git a/Entidades/Dto/AceptarContratoDto.cs b/Entidades/Dto/AceptarContratoDto.cs new file mode 100644 index 0000000..35ba502 --- /dev/null +++ b/Entidades/Dto/AceptarContratoDto.cs @@ -0,0 +1,5 @@ +namespace Entidades.Dto; +public class AceptarContratoDto { + public long Idcontrato { get; set; } + public DateTime Fecha { get; set; } +} \ No newline at end of file diff --git a/Entidades/Dto/AltaGarantesDto.cs b/Entidades/Dto/AltaGarantesDto.cs new file mode 100644 index 0000000..c1971b9 --- /dev/null +++ b/Entidades/Dto/AltaGarantesDto.cs @@ -0,0 +1,9 @@ +namespace Entidades.Dto; + +public class AltaGarantesDto { + public string EmailInquilino { get; set; } = ""; + public int Idpropiedad {get; set;} + public DateTime fecha { get; set;} + public List garantes{ get; set; } = new(); + +} \ No newline at end of file diff --git a/Entidades/Dto/AltaNotificacionDto.cs b/Entidades/Dto/AltaNotificacionDto.cs new file mode 100644 index 0000000..14b9a96 --- /dev/null +++ b/Entidades/Dto/AltaNotificacionDto.cs @@ -0,0 +1,7 @@ +namespace Entidades.Dto; +public class AltaNotificacionDto { + public string Remitente { get; set; } =""; + public string Accion { get; set; } =""; + public string Mensaje { get; set; } =""; + public int Propiedad { get; set;} +} \ No newline at end of file diff --git a/Entidades/Dto/AltaPropiedadDto.cs b/Entidades/Dto/AltaPropiedadDto.cs index 86865ce..a549463 100644 --- a/Entidades/Dto/AltaPropiedadDto.cs +++ b/Entidades/Dto/AltaPropiedadDto.cs @@ -6,4 +6,5 @@ public class AltaPropiedadDto { public string? Letra { get; set; } = null; public string Email { get; set; } = string.Empty; public int Idtipropiedad { get; set; } + public int Monto { get; set; } } \ No newline at end of file diff --git a/Entidades/Dto/BusquedaDto.cs b/Entidades/Dto/BusquedaDto.cs new file mode 100644 index 0000000..bae05d0 --- /dev/null +++ b/Entidades/Dto/BusquedaDto.cs @@ -0,0 +1,3 @@ +namespace Entidades.Dto; + +public record BusquedaDto(int Id, string Ubicacion, string? Servicios = ""); diff --git a/Entidades/Dto/CancelarPrecontratoDto.cs b/Entidades/Dto/CancelarPrecontratoDto.cs new file mode 100644 index 0000000..3372b09 --- /dev/null +++ b/Entidades/Dto/CancelarPrecontratoDto.cs @@ -0,0 +1,8 @@ +namespace Entidades.Dto; +public class CancelarPrecontratoDto { + public string EmailPropietario { get; set; } =""; + public string EmailInquilino { get; set; } =""; + public DateTime fecha { get; set; } + + public int idpropiedad { get; set; } = 0; +} \ No newline at end of file diff --git a/Entidades/Dto/GaranteDto.cs b/Entidades/Dto/GaranteDto.cs new file mode 100644 index 0000000..736473e --- /dev/null +++ b/Entidades/Dto/GaranteDto.cs @@ -0,0 +1,16 @@ +namespace Entidades.Dto; + +public class GaranteDto { + public long Dni { get; set; } + + public string Nombre { get; set; } = null!; + + public string Apellido { get; set; } = null!; + + public string Domicilio { get; set; } = null!; + + public string Celular { get; set; } = null!; + + public string Domiciliolaboral { get; set; } = null!; + +} \ No newline at end of file diff --git a/Entidades/Dto/NotificacionDto.cs b/Entidades/Dto/NotificacionDto.cs new file mode 100644 index 0000000..9daa73e --- /dev/null +++ b/Entidades/Dto/NotificacionDto.cs @@ -0,0 +1,9 @@ +namespace Entidades.Dto; +public class NotificacionDto { + public string Remitente { get; set; } =""; + public string Accion { get; set; } =""; + public string Receptor { get; set; } =""; + public string Mensaje { get; set; } =""; + public DateTime? Fecha{get; set;} =null; + public string Propiedad { get; set;} =""; +} \ No newline at end of file diff --git a/Entidades/Dto/NotificacionMarcarLeidoDto.cs b/Entidades/Dto/NotificacionMarcarLeidoDto.cs new file mode 100644 index 0000000..60965bb --- /dev/null +++ b/Entidades/Dto/NotificacionMarcarLeidoDto.cs @@ -0,0 +1 @@ +public record NotificacionMarcarLeidoDto(DateTime? Fecha, string Email); \ No newline at end of file diff --git a/Entidades/Dto/PatchPropiedadDto.cs b/Entidades/Dto/PatchPropiedadDto.cs index e146ce7..f7a01d5 100644 --- a/Entidades/Dto/PatchPropiedadDto.cs +++ b/Entidades/Dto/PatchPropiedadDto.cs @@ -1,3 +1,3 @@ namespace Entidades.Dto; -public record PatchPropiedadDto(int id, string Ubicacion, int Canthabitaciones, int? Piso, string? Letra, string Email, int tipo, List Servicios); +public record PatchPropiedadDto(int id, string Ubicacion, int Canthabitaciones, int? Piso, string? Letra, string Email, int tipo, List Servicios, int Monto); diff --git a/Entidades/Dto/PrecontratoDto.cs b/Entidades/Dto/PrecontratoDto.cs new file mode 100644 index 0000000..206889e --- /dev/null +++ b/Entidades/Dto/PrecontratoDto.cs @@ -0,0 +1,10 @@ +namespace Entidades.Dto; +public class PrecontratoDto { + public string EmailInquilino { get; set; } = ""; + public string EmailPropietario { get; set; } = ""; + public int IdPropiedad { get; set; } + public int CantidadGarantes { get; set; } + public int MesesHastaAumento { get; set; } + public bool TieneOpcionVenta { get; set; } + public string fechaprimernotificacion { get; set; } +} \ No newline at end of file diff --git a/Entidades/Dto/PropiedadesDto.cs b/Entidades/Dto/PropiedadesDto.cs index b4aa423..274206f 100644 --- a/Entidades/Dto/PropiedadesDto.cs +++ b/Entidades/Dto/PropiedadesDto.cs @@ -7,4 +7,5 @@ public class PropiedadesDto { public string letra { get; set; } = ""; public string Tipo { get; set; } = ""; public string? Servicios {get;set;} = ""; + public int Monto { get; set; } } diff --git a/Entidades/Dto/RechazarContratoDto.cs b/Entidades/Dto/RechazarContratoDto.cs new file mode 100644 index 0000000..6e735fb --- /dev/null +++ b/Entidades/Dto/RechazarContratoDto.cs @@ -0,0 +1,5 @@ +namespace Entidades.Dto; +public class RechazarPreContrato { + public long Idcontrato { get; set; } + public DateTime Fecha { get; set; } +} \ No newline at end of file diff --git a/Entidades/Dto/SubirContratoDto.cs b/Entidades/Dto/SubirContratoDto.cs new file mode 100644 index 0000000..adb224b --- /dev/null +++ b/Entidades/Dto/SubirContratoDto.cs @@ -0,0 +1,6 @@ +using System.Configuration; + +namespace Entidades.Dto; +public class SubirContratoDto{ + public int IdContrato { get; set; } +} diff --git a/Entidades/Garante.cs b/Entidades/Garante.cs index d95318b..39359d1 100644 --- a/Entidades/Garante.cs +++ b/Entidades/Garante.cs @@ -5,6 +5,8 @@ namespace Entidades; public partial class Garante { + public int Id { get; set; } + public long Dni { get; set; } public string Nombre { get; set; } = null!; diff --git a/Entidades/Notificacione.cs b/Entidades/Notificacione.cs new file mode 100644 index 0000000..d44a5f4 --- /dev/null +++ b/Entidades/Notificacione.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace Entidades; + +public partial class Notificacione +{ + public long Dnicliente { get; set; } + + public long Dniremitente { get; set; } + + public DateTime Fecha { get; set; } + + public string Mensaje { get; set; } = null!; + + public string Accion { get; set; } = null!; + + public int Idpropiedad { get; set; } + + public bool Leido { get; set; } + + public virtual Cliente DniclienteNavigation { get; set; } = null!; + + public virtual Cliente DniremitenteNavigation { get; set; } = null!; + + public virtual Propiedade IdpropiedadNavigation { get; set; } = null!; +} diff --git a/Entidades/Propiedade.cs b/Entidades/Propiedade.cs index 8d47663..4a4812c 100644 --- a/Entidades/Propiedade.cs +++ b/Entidades/Propiedade.cs @@ -21,6 +21,8 @@ public partial class Propiedade public int? Idestado { get; set; } + public decimal Monto { get; set; } + public virtual ICollection Contratos { get; set; } = new List(); public virtual Cliente? DnipropietarioNavigation { get; set; } @@ -29,6 +31,8 @@ public partial class Propiedade public virtual TipoPropiedad IdtipropiedadNavigation { get; set; } = null!; + public virtual ICollection Notificaciones { get; set; } = new List(); + public virtual ICollection Venta { get; set; } = new List(); public virtual ICollection IdServicios { get; set; } = new List(); diff --git a/Front/bun.lockb b/Front/bun.lockb index 14f40ba..502d03b 100755 Binary files a/Front/bun.lockb and b/Front/bun.lockb differ diff --git a/Front/index.html b/Front/index.html index 135b7b8..a051eac 100644 --- a/Front/index.html +++ b/Front/index.html @@ -5,7 +5,11 @@ - + AlquilaFacil diff --git a/Front/package.json b/Front/package.json index 6a4b9fc..347fd5b 100644 --- a/Front/package.json +++ b/Front/package.json @@ -21,6 +21,7 @@ "dependencies": { "@sveltejs/kit": "^2.7.3", "@sveltestrap/sveltestrap": "^6.2.7", + "chartjs": "^0.3.24", "svelte-routing": "^2.13.0" } } diff --git a/Front/public/bell.svg b/Front/public/bell.svg new file mode 100644 index 0000000..8a1f51e --- /dev/null +++ b/Front/public/bell.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/public/toggle-left.svg b/Front/public/toggle-left.svg new file mode 100644 index 0000000..9f7d915 --- /dev/null +++ b/Front/public/toggle-left.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/Front/public/toggle-right.svg b/Front/public/toggle-right.svg new file mode 100644 index 0000000..28a184b --- /dev/null +++ b/Front/public/toggle-right.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/Front/public/zoom.svg b/Front/public/zoom.svg new file mode 100644 index 0000000..6371d03 --- /dev/null +++ b/Front/public/zoom.svg @@ -0,0 +1,19 @@ + + + + + diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 6528cb0..44c19fa 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -13,6 +13,10 @@ import FrontInquilino from "./paginas/grupos/InquilinoG.svelte"; import FrontPropietario from "./paginas/grupos/PropietarioG.svelte"; import PublicarPropiedad from "./paginas/PublicarPropiedad.svelte"; + import BusquedaPropiedades from "./paginas/BusquedaPropiedades.svelte"; + import AdminUsuarios from "./paginas/AdminUsuarios.svelte"; + import AdminPropiedades from "./paginas/AdminPropiedades.svelte"; + import Notificaciones from "./paginas/Notificaciones.svelte"; @@ -30,7 +34,8 @@ - + @@ -40,22 +45,38 @@ + + + + + - - + + + + + + + + + + + + + @@ -70,6 +91,10 @@ + + + + diff --git a/Front/src/Componentes/AdminPanelBusqueda.svelte b/Front/src/Componentes/AdminPanelBusqueda.svelte new file mode 100644 index 0000000..ef212a4 --- /dev/null +++ b/Front/src/Componentes/AdminPanelBusqueda.svelte @@ -0,0 +1,86 @@ + + +
+ +
Busqueda Filtrada +
+
+ +
+ + +
+ +
+
Servicios
+ {#each servicios as servicio} +
+ + +
+ {/each} +
+ +
+ + +
+ + +
+ \ No newline at end of file diff --git a/Front/src/Componentes/AdminPropiedad.svelte b/Front/src/Componentes/AdminPropiedad.svelte new file mode 100644 index 0000000..a4f478b --- /dev/null +++ b/Front/src/Componentes/AdminPropiedad.svelte @@ -0,0 +1,59 @@ + + +
+
+
{prop.tipo}
+
+
+
+ +
+
{prop.ubicacion}
+

+ Habitaciones: {prop.canthabitaciones}
+ Piso: {prop.piso || "N/A"}
+ Letra: {prop.letra || "N/A"}
+ Servicios: {prop.servicios || "Sin servicios especificados"}
+ Monto: ${prop.monto}
+ Estado: {prop.estado}
+

+ {#if prop.estado == "Disponible"} + + {:else} + + {/if} +
+ +
+ \ No newline at end of file diff --git a/Front/src/Componentes/BarraHorizontalConTexto.svelte b/Front/src/Componentes/BarraHorizontalConTexto.svelte index 6a48406..82a7aba 100644 --- a/Front/src/Componentes/BarraHorizontalConTexto.svelte +++ b/Front/src/Componentes/BarraHorizontalConTexto.svelte @@ -1,11 +1,11 @@

-
{prop.text}
+
{text}

\ No newline at end of file diff --git a/Front/src/Componentes/BotonVolverArriba.svelte b/Front/src/Componentes/BotonVolverArriba.svelte new file mode 100644 index 0000000..3c576ad --- /dev/null +++ b/Front/src/Componentes/BotonVolverArriba.svelte @@ -0,0 +1,14 @@ + + + diff --git a/Front/src/Componentes/ListaAcciones.svelte b/Front/src/Componentes/ListaAcciones.svelte index 51bdbfa..c5674d3 100644 --- a/Front/src/Componentes/ListaAcciones.svelte +++ b/Front/src/Componentes/ListaAcciones.svelte @@ -1,6 +1,8 @@ -
+
{#each $permisos as item} - + {item.descripcion} {/each} diff --git a/Front/src/Componentes/login.svelte b/Front/src/Componentes/LoginPanel.svelte similarity index 87% rename from Front/src/Componentes/login.svelte rename to Front/src/Componentes/LoginPanel.svelte index 34a432c..9de9755 100644 --- a/Front/src/Componentes/login.svelte +++ b/Front/src/Componentes/LoginPanel.svelte @@ -1,6 +1,7 @@ - + Iniciar Sesión diff --git a/Front/src/Componentes/ModalAddGarantes.svelte b/Front/src/Componentes/ModalAddGarantes.svelte new file mode 100644 index 0000000..ca0e721 --- /dev/null +++ b/Front/src/Componentes/ModalAddGarantes.svelte @@ -0,0 +1,165 @@ + + + diff --git a/Front/src/Componentes/ModalCheckYContrato.svelte b/Front/src/Componentes/ModalCheckYContrato.svelte new file mode 100644 index 0000000..b46a5b3 --- /dev/null +++ b/Front/src/Componentes/ModalCheckYContrato.svelte @@ -0,0 +1,107 @@ + + + diff --git a/Front/src/Componentes/ModalConfirm.svelte b/Front/src/Componentes/ModalConfirm.svelte new file mode 100644 index 0000000..dea14b3 --- /dev/null +++ b/Front/src/Componentes/ModalConfirm.svelte @@ -0,0 +1,36 @@ + + + {#if show} + + {/if} + \ No newline at end of file diff --git a/Front/src/Componentes/ModalPrecontrato.svelte b/Front/src/Componentes/ModalPrecontrato.svelte new file mode 100644 index 0000000..d3d5dd4 --- /dev/null +++ b/Front/src/Componentes/ModalPrecontrato.svelte @@ -0,0 +1,50 @@ + + + \ No newline at end of file diff --git a/Front/src/Componentes/ModalVeryAceptarContrato.svelte b/Front/src/Componentes/ModalVeryAceptarContrato.svelte new file mode 100644 index 0000000..92cbbd4 --- /dev/null +++ b/Front/src/Componentes/ModalVeryAceptarContrato.svelte @@ -0,0 +1,95 @@ + + + + + \ No newline at end of file diff --git a/Front/src/Componentes/NavBarAutocompletable.svelte b/Front/src/Componentes/NavBarAutocompletable.svelte index 225919a..2ef9085 100644 --- a/Front/src/Componentes/NavBarAutocompletable.svelte +++ b/Front/src/Componentes/NavBarAutocompletable.svelte @@ -2,9 +2,15 @@ import { Navbar, NavbarBrand, NavbarToggler, Nav, Collapse } from "@sveltestrap/sveltestrap"; import { onMount } from "svelte"; import { writable } from 'svelte/store'; + import { link, links } from "svelte-routing"; import './css/popup.css'; import type { Grupo } from "../types"; + + import { urlG } from "../stores/urlStore"; + import { navigate } from "svelte-routing"; + let isOpen: boolean = $state(false); + let hayNotis:boolean = $state(false); const permisos = writable([]); const email = localStorage.getItem('email'); @@ -12,7 +18,7 @@ async function obtenerPermisos(){ try { - const response = await fetch("http://localhost:5007/api/acciones",{ + const response = await fetch(String($urlG)+"/api/acciones",{ method: 'GET', headers: { 'Auth' : String(token), @@ -33,26 +39,72 @@ onMount( () => { obtenerPermisos(); + obtenerNotis(); }) - function redirijir(path: string){ - location.replace(path); + async function obtenerNotis() { + try { + const responce = await fetch($urlG+"/api/notificaciones/haySinLeer", { + method: "GET", + headers: { + "Auth": String(token) + } + }); + if(responce.ok) { + let data = await responce.json(); + hayNotis = data.message; + return; + } + } catch (e) { + console.error(e); + + } } + function redirijir(path: string){ + navigate(path); + } + + let theme = $state(localStorage.getItem("theme") ?? "light"); + const toggleTheme = () => { + theme = theme === "light" ? "dark" : "light"; + document.body.setAttribute("data-bs-theme", theme); + localStorage.setItem("theme", theme); + }; + AlquilaFacil -
- - Volver al Menú - +
+
+ + Volver al Menú + +
+ +
(isOpen = !isOpen)} /> -
diff --git a/Front/src/stores/urlStore.js b/Front/src/stores/urlStore.js deleted file mode 100644 index 4ef3ca2..0000000 --- a/Front/src/stores/urlStore.js +++ /dev/null @@ -1,3 +0,0 @@ -import { readable } from 'svelte/store'; - -export const urlG = readable('http://localhost:5007'); diff --git a/Front/src/stores/urlStore.ts b/Front/src/stores/urlStore.ts new file mode 100644 index 0000000..d02927a --- /dev/null +++ b/Front/src/stores/urlStore.ts @@ -0,0 +1,3 @@ +import { readable, type Readable } from 'svelte/store'; + +export const urlG: Readable = readable('http://localhost:5007'); diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index a9f26ca..cb2723e 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -5,13 +5,40 @@ export type PropiedadDto = { piso: string | null, letra: string | null, canthabitaciones: number, - servicios: string + servicios: string, + monto: number +} + +export type AdminParametrosBusqueda = { + cantidadhabitaciones: number=0, + tipopropiedad: number=0, + servicios: string="", + pag: number=1 +} + +export type PropiedadAdmin = { + id: number, + ubicacion: string, + tipo: string, + piso: string | null, + letra: string | null, + canthabitaciones: number, + servicios: string, + monto: number, + estado: string } export type Permiso = { id: number; descripcion: string; }; +export type Cliente = { + dni: number, + nombre: string, + email: string, + habilitado: boolean +} + export type Grupo = { id: number; nombre: string; @@ -25,4 +52,24 @@ export type Propiedad = { letra: string, email: string, idtipropiedad: number, + monto: number +}; + +export type MensajeDto = { + remitente: string, + accion: string, + receptor: string, + mensaje: string, + fecha: Date, + propiedad: string, + +} + +export type GaranteDto = { + Dni: number; + Nombre: string; + Apellido: string; + Domicilio: string; + Celular: string; + Domiciliolaboral: string; }; diff --git a/Front/tsconfig.json b/Front/tsconfig.json index df56300..7c608fc 100644 --- a/Front/tsconfig.json +++ b/Front/tsconfig.json @@ -17,5 +17,4 @@ "moduleDetection": "force" }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], - "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/Modelo/RepositorioContratos.cs b/Modelo/RepositorioContratos.cs new file mode 100644 index 0000000..2df62f5 --- /dev/null +++ b/Modelo/RepositorioContratos.cs @@ -0,0 +1,147 @@ +using Entidades; +using Microsoft.EntityFrameworkCore; + +namespace Modelo; +public class RepositorioContratos: RepositorioBase { + public IQueryable? ObtenerContratosPorEmailInquilino(string email) { + var con = Context; + try{ + var listcont = con.Contratos.Where(x=>x.DniinquilinoNavigation.Email == email); + return listcont; + } catch { + return null; + } + } + + public bool CargaPrecontrato(Contrato? c = null, Notificacione? n = null) { + if (c == null || c.Habilitado == 1) return false; + if (n == null) return false; + var con = Context; + + var prop = con.Propiedades.FirstOrDefault(x=>x.Id==c.Idpropiedad); + if (prop == null) return false; + prop.Idestado = 2; + + c.Id = (con.Contratos.Any() ? con.Contratos.Max(x => x.Id) : 0) + 1; + c.Monto = prop.Monto; + + con.Contratos.Add(c); + con.Notificaciones.Add(n); + + return Guardar(con); + } + public bool CargaGarantes(List gar, string emailInquilino, int idpropiedad) { + var con = Context; + Contrato? contr = con.Contratos.Include(x=>x.DniinquilinoNavigation).Include(x=>x.Idgarantes) + .FirstOrDefault(x=>x.Idpropiedad == idpropiedad && + x.DniinquilinoNavigation.Email == emailInquilino && + x.Habilitado == 0 && + x.Cancelado == 0); + + if (contr == null) return false; + int inicial = (con.Garantes.Any()? con.Garantes.Max(x=>x.Id): 0) + 1; + foreach (var i in gar) { + i.Id = inicial; + inicial++; + con.Garantes.Add(i); + contr.Idgarantes.Add(i); + } + + return Guardar(con); + } + + public int CantidadGarantesEncontrato(string emailInquilino, int idpropiedad) { + var con = Context; + Contrato? contr = con.Contratos.Include(x=>x.DniinquilinoNavigation) + .FirstOrDefault(x=>x.Idpropiedad == idpropiedad && + x.DniinquilinoNavigation.Email == emailInquilino && + x.Habilitado == 0 && + x.Cancelado == 0); + if (contr == null) return 0; + return contr.Cantgarantemin; + } + + public Contrato? ObtenerContrato(string emailInquilino, int idpropiedad) { + var con = Context; + Contrato? contr = con.Contratos.Include(x=>x.DniinquilinoNavigation) + .FirstOrDefault(x=>x.Idpropiedad == idpropiedad && + x.DniinquilinoNavigation.Email == emailInquilino && + x.Habilitado == 0 && + x.Cancelado == 0); + if (contr == null) return null; + return contr; + + } + + public bool CancelarPrecontrato(string emailInquilino, int idpropiedad) { + var con = Context; + Contrato? contr = con.Contratos.Include(x=>x.DniinquilinoNavigation) + .FirstOrDefault(x=>x.Idpropiedad == idpropiedad && + x.DniinquilinoNavigation.Email == emailInquilino && + x.Habilitado == 0 && + x.Cancelado == 0); + + if (contr == null || contr.IdpropiedadNavigation == null) return false; + contr.Cancelado = 1; + contr.IdpropiedadNavigation.Idestado = 1; + return Guardar(con); + } + + public Contrato? ObtenerPreContratoPorId(long idcontrato) { + var con = Context; + Contrato? contr = con.Contratos + .Include(x=>x.DnipropietarioNavigation) + .Include(x=>x.Idgarantes) + .Where(x=>x.Cancelado == 0 && x.Habilitado == 0) + .FirstOrDefault(x=>x.Id == idcontrato); + if (contr == null) return null; + return contr; + } + + public bool AddUrl(long id, string nuevoNombreArchivo) { + var con = Context; + Contrato? contrato = con.Contratos + .FirstOrDefault(x=>x.Id == id); + if (contrato == null) return false; + contrato.UrlContrato = nuevoNombreArchivo; + return Guardar(con); + } + + public bool AceptarContrato(long idcontrato) { + var con = Context; + Contrato? cont = con.Contratos + .Include(x=>x.Idcanons) + .Include(x=>x.IdpropiedadNavigation) + .FirstOrDefault(x=>x.Id ==idcontrato && + x.Habilitado ==0 && + x.Cancelado == 0); + + if (cont == null || cont.IdpropiedadNavigation==null) return false; + + cont.Habilitado = 1; + var fecha = cont.Fechainicio; + + for (int i = 0; i < cont.MesesHastaAumento; i++) { + Canon can = new Canon{ + Fecha = fecha.AddMonths(i), + Monto = cont.IdpropiedadNavigation.Monto, + Pagado = 0, + }; + can.Id = (con.Canons.Any()? con.Canons.Count() :0)+1+i; + + + con.Canons.Add(can); + cont.Idcanons.Add(can); + } + return Guardar(con); + } + + public bool CancelarPrecontrato(long idcontrato) { + var con = Context; + Contrato? cont = con.Contratos.Include(x=>x.IdpropiedadNavigation).FirstOrDefault(x=>x.Id ==idcontrato && x.Habilitado ==0); + if (cont == null|| cont.IdpropiedadNavigation==null) return false; + cont.Cancelado = 1; + cont.IdpropiedadNavigation.Idestado = 1; + return Guardar(con); + } +} diff --git a/Modelo/RepositorioGrupos.cs b/Modelo/RepositorioGrupos.cs index c8bef71..81cc13d 100644 --- a/Modelo/RepositorioGrupos.cs +++ b/Modelo/RepositorioGrupos.cs @@ -1,6 +1,5 @@ -#if DEBUG - using Entidades; +using Entidades.Admin; using Microsoft.EntityFrameworkCore; namespace Modelo; @@ -23,6 +22,28 @@ public class RepositorioGrupos: RepositorioBase { var con = Context; return con.Grupos.Where(x=>x.Nombre == grupo).SelectMany(x => x.Idpermisos); } -} -#endif \ No newline at end of file + 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{ + Id = x.Id, + Descripcion = x.Nombre, + }); + return grupos; + } + + public bool CheckGrupos(string token, string grupo){ + var con = Context; + 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); + if (gru == null) return false; + + if (cli.Idgrupos.Contains(gru)) return true; + + return false; + + } +} \ No newline at end of file diff --git a/Modelo/RepositorioInquilinos.cs b/Modelo/RepositorioInquilinos.cs index 48de959..1f55265 100644 --- a/Modelo/RepositorioInquilinos.cs +++ b/Modelo/RepositorioInquilinos.cs @@ -1,3 +1,4 @@ +using Entidades; using Entidades.Dto; using Microsoft.EntityFrameworkCore; @@ -15,5 +16,15 @@ public class RepositorioInquilinos: RepositorioBase { return Context.Database.SqlQuery(sqlq); } + public Cliente? ObtenerInquilinoPorEmail(string Email){ + var con = Context; + Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Email == Email); + if (cli == null || cli.Dni == 0) return null; + + Grupo? gru = cli.Idgrupos.FirstOrDefault(x=>x.Id == 2); + if (gru == null) return null; + + return cli; + } } \ No newline at end of file diff --git a/Modelo/RepositorioNotificaciones.cs b/Modelo/RepositorioNotificaciones.cs new file mode 100644 index 0000000..47a3307 --- /dev/null +++ b/Modelo/RepositorioNotificaciones.cs @@ -0,0 +1,45 @@ +using System.Security.Cryptography; +using System.Text; +using Entidades.Dto; +using Entidades; +using Microsoft.EntityFrameworkCore; +using System.Collections.Concurrent; +using Org.BouncyCastle.Math.EC.Rfc7748; + +namespace Modelo; + +public class RepositorioNotificaciones : RepositorioBase { + public bool MarcarComoLeido(long dni, DateTime? fecha) { + if (fecha == null) return false; + + var con = Context; + Notificacione? noti = con.Notificaciones.FirstOrDefault(x=> x.Dnicliente == dni && x.Fecha == fecha); + if (noti == null) return false; + + noti.Leido = true; + return Guardar(con); + } + + public bool AltaNotificacion(Notificacione n) { + var con = Context; + + con.Notificaciones.Add(n); + return Guardar(con); + } + + public IQueryable ObtenerNotificacionesDeUsuario(long dni) { + var con = Context; + + var notis = con.Notificaciones + .Include(x=>x.IdpropiedadNavigation) + .Include(x=>x.DniremitenteNavigation) + .Where(x => x.Dnicliente == dni); + return notis; + } + + public bool HayNotis(long dni) { + var con = Context; + bool hay = con.Notificaciones.Where(x=>x.Leido == false).Any(); + return hay; + } +} \ No newline at end of file diff --git a/Modelo/RepositorioPermisos.cs b/Modelo/RepositorioPermisos.cs index e53fb40..e92a993 100644 --- a/Modelo/RepositorioPermisos.cs +++ b/Modelo/RepositorioPermisos.cs @@ -34,6 +34,7 @@ public class RepositorioPermisos: RepositorioBase { ///////////////////////////////////////////////////////////////// //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+)$"); diff --git a/Modelo/RepositorioPropiedades.cs b/Modelo/RepositorioPropiedades.cs index 3c1632e..e05d6d6 100644 --- a/Modelo/RepositorioPropiedades.cs +++ b/Modelo/RepositorioPropiedades.cs @@ -1,9 +1,10 @@ using System; using System.Data; using Entidades; +using Entidades.Admin; using Entidades.Dto; -using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; +using Microsoft.Identity.Client; using Modelo; using MySql.Data.MySqlClient; @@ -11,9 +12,14 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ListarPropiedades(){ FormattableString sqlq = $""" - SELECT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS TipoPropiedad FROM Propiedades p + 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 + 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 """; var ret = Context.Database.SqlQuery(sqlq); @@ -21,14 +27,9 @@ public class RepositorioPropiedades: RepositorioBase { } public Propiedade? ObtenerPropiedadPorId(int Id) { + var con = Context; + Propiedade? prop = con.Propiedades.Include(x=>x.DnipropietarioNavigation).FirstOrDefault(x=>x.Id == Id); - FormattableString sqlq = $""" - SELECT * FROM Propiedades p - WHERE p.id = {Id} - LIMIT 1 - """; - - Propiedade? prop = Context.Database.SqlQuery(sqlq).First(); if (prop == null || prop.Id == 0) { return null; } @@ -36,35 +37,36 @@ public class RepositorioPropiedades: RepositorioBase { return prop; } -public bool AñadirPropiedad(Propiedade? prop) { - if (prop == null) return false; + public bool AñadirPropiedad(Propiedade? prop) { + if (prop == null) return false; - var con = Context; + var con = Context; - if (string.IsNullOrEmpty(prop.Letra)) prop.Letra = "_"; + if (string.IsNullOrEmpty(prop.Letra)) prop.Letra = "_"; - var filasInsertadasParam = new MySqlParameter("@p_filas_insertadas", SqlDbType.Int) - { - Direction = ParameterDirection.Output - }; + var filasInsertadasParam = new MySqlParameter("@p_filas_insertadas", SqlDbType.Int) + { + Direction = ParameterDirection.Output + }; - // Ejecutar el procedimiento almacenado - var row = con.Database.ExecuteSqlRaw( - $""" - CALL InsertarPropiedad(@p_ubicacion, @p_cant_habitaciones, @p_piso, @p_letra, - @p_dni_propietario, @p_id_tipo_propiedad, @p_filas_insertadas) - """, - new MySqlParameter("@p_ubicacion", prop.Ubicacion), - new MySqlParameter("@p_cant_habitaciones", prop.Canthabitaciones), - new MySqlParameter("@p_piso", prop.Piso), - new MySqlParameter("@p_letra", prop.Letra), - new MySqlParameter("@p_dni_propietario", prop.Dnipropietario), - new MySqlParameter("@p_id_tipo_propiedad", prop.Idtipropiedad), - filasInsertadasParam - ); + // Ejecutar el procedimiento almacenado + var row = con.Database.ExecuteSqlRaw( + $""" + CALL InsertarPropiedad(@p_ubicacion, @p_cant_habitaciones, @p_piso, @p_letra, + @p_dni_propietario, @p_id_tipo_propiedad, @p_monto, @p_filas_insertadas) + """, + new MySqlParameter("@p_ubicacion", prop.Ubicacion), + new MySqlParameter("@p_cant_habitaciones", prop.Canthabitaciones), + new MySqlParameter("@p_piso", prop.Piso), + 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), + filasInsertadasParam + ); - return (int)filasInsertadasParam.Value == 1? true: false; -} + return (int)filasInsertadasParam.Value == 1? true: false; + } public bool PatchPropiedad(Propiedade prop) { var con = Context; @@ -77,6 +79,7 @@ public bool AñadirPropiedad(Propiedade? prop) { propi.Ubicacion = prop.Ubicacion; propi.Piso = prop.Piso; propi.Letra = prop.Letra; + propi.Monto = prop.Monto; propi.IdServicios.Clear(); foreach(Servicio ser in prop.IdServicios) { @@ -90,7 +93,7 @@ public bool AñadirPropiedad(Propiedade? prop) { 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 + 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 FROM Propiedades p JOIN Clientes c ON c.dni = p.dnipropietario JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad @@ -106,7 +109,7 @@ public bool AñadirPropiedad(Propiedade? prop) { 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 + 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 FROM Propiedades p JOIN Clientes c ON c.dni = p.dnipropietario JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad @@ -153,8 +156,18 @@ public bool AñadirPropiedad(Propiedade? prop) { } - public bool BajaServiciosAPropiedad(int idprop, List idserv) - { + public bool BajaPropiedad(int id) { + var con = Context; + Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id); + + if (prop == null||prop.Dnipropietario == 0) return false; + + prop.Idestado = prop.Idestado == 3 ? 1 : 3; + + return Guardar(con); + } + + public bool BajaServiciosAPropiedad(int idprop, List idserv) { var con = Context; Propiedade? prop = con.Propiedades.Include(x=>x.IdServicios).FirstOrDefault(x => x.Id == idprop); if (prop == null) return false; @@ -170,5 +183,411 @@ public bool AñadirPropiedad(Propiedade? prop) { } return Guardar(con); + } + + 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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + 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 = {habitaciones} AND p.idtipropiedad = {tipo} + AND EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + """; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; + } + + 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 + 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} AND p.idtipropiedad = {tipoPropiedad} + GROUP BY p.id + """; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; + } + + public IQueryable ObtenerPropiedesPorServicios(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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + 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 EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + 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 + 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); + return ret; + } + + 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 + 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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + 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} + AND EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + """; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; + } + + 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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + 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} + AND EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + """; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; + } + + public bool BajaPropiedades(string email) { + var con = Context; + try { + IQueryable listprop = con.Propiedades.Where(x=>x.DnipropietarioNavigation.Email == email); + foreach (var item in listprop) { + item.Idestado = 3; + } + } catch { + return false; } -} + return Guardar(con); + } + + 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 + 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} + """; + + var ret = Context.Database.SqlQuery(sqlq); + return ret; + } + ///////////////ADMIN + 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 + 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} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + + 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 + 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 + WHERE p.canthabitaciones = {cantidadHabitaciones} + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + 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 + 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 + WHERE p.idtipropiedad = {tipoPropiedad} + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + 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 + 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 + WHERE p.canthabitaciones = {cantidadHabitaciones} AND p.idtipropiedad = {tipoPropiedad} + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + public IQueryable ObtenerPropiedesPorServiciosPaginado(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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + 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 + WHERE EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + 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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + 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 + WHERE p.canthabitaciones = {cantidadHabitaciones} + AND EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + 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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + 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 + WHERE p.idtipropiedad = {tipoPropiedad} + AND EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + 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, + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + 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 + WHERE p.canthabitaciones = {habitaciones} AND p.idtipropiedad = {tipo} + AND EXISTS ( + SELECT 1 + FROM Servicio_Propiedad sp2 + JOIN Servicios s2 ON sp2.idServicio = s2.id + WHERE sp2.idPropiedad = p.id + AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) + ) + GROUP BY p.id + LIMIT 10 OFFSET {pag*10} + """; + + var ret = Singleton.Context.Database.SqlQuery(sqlq); + return ret; + } + + 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 (inter == 0.00) return 0; + ret = (int)Math.Ceiling(inter); + + return ret; + } + + public int CuantasPaginasBusqueda(int habitaciones, string servicios, int tipoPropiedad, int estado) { + int registrosPorPagina = 10; + + var query = Context.Propiedades + .Include(p => p.IdestadoNavigation) + .Include(p => p.IdtipropiedadNavigation) + .Include(p => p.IdServicios) + .AsQueryable(); + + if (habitaciones > 0) { + query = query.Where(p => p.Canthabitaciones == habitaciones); + } + + if (estado > 0){ + query = query.Where(x=>x.Idestado == estado); + } + + if (tipoPropiedad > 0) { + query = query.Where(p => p.Idtipropiedad == tipoPropiedad); + } + + if (!string.IsNullOrWhiteSpace(servicios)) { + var listaServicios = servicios.Split(',').Select(s => s.Trim()).ToList(); + query = query.Where(p => + p.IdServicios.Any(sp => + listaServicios.Contains(sp.Descripcion))); + } + + int totalRegistros = query.Distinct().Count(); + + return (int)Math.Ceiling((double)totalRegistros / registrosPorPagina); + } +} \ No newline at end of file diff --git a/Modelo/RepositorioPropietario.cs b/Modelo/RepositorioPropietario.cs index e8636dd..cc5bbb2 100644 --- a/Modelo/RepositorioPropietario.cs +++ b/Modelo/RepositorioPropietario.cs @@ -25,9 +25,19 @@ public class RepositorioPropietario: RepositorioBase { public Cliente? ObtenerPropietarioPorEmail(string email){ var con = Context; - Cliente? cli = con.Clientes.FirstOrDefault(x=>x.Email == email); + Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Email == email); if (cli == null|| cli.Dni == 0) return null; - if (cli.Dni == 0 || cli == null) return null; + var grupo = cli.Idgrupos.FirstOrDefault(x=>x.Id == 1); + if (grupo == null) return null; return cli; } + + public Cliente? ObtenerPropietarioPorIdPropiedad(int idpropiedad) { + var con = Context; + Propiedade? pro = con.Propiedades.Include(x=>x.DnipropietarioNavigation) + .FirstOrDefault(x=>x.Id == idpropiedad); + if (pro == null || pro.DnipropietarioNavigation == null) return null; + + return pro.DnipropietarioNavigation; + } } diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index 24f6941..f0dd6af 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -12,7 +12,7 @@ public class RepositorioUsuarios: RepositorioBase { Grupo? grupo; //check por si la cuenta ya existe (puede ser propietario) - Cliente? cli2 = con.Clientes.Find(cli.Dni); + 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; @@ -88,10 +88,6 @@ public class RepositorioUsuarios: RepositorioBase { var usu = Context.Clientes.FirstOrDefault(x => x.Email == email); if (usu == null) return false; - #if DEBUG - //Console.WriteLine(token + "\n" +usu.Token); - #endif - return usu.Token == token; } @@ -119,4 +115,70 @@ public class RepositorioUsuarios: RepositorioBase { return ret; } + + public IEnumerable GetClientes(){ + var con = Context; + 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}); + return list; + } + + public bool AñadirClienteAGrupo(string email, string grupo) { + 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) { + return false; + } + + cli.Idgrupos.Add(gru); + return Guardar(con); + } + + public bool EliminarClienteAGrupo(string email, string grupo) { + 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) { + return false; + } + cli.Idgrupos.Remove(gru); + return Guardar(con); + } + + public bool BajaCliente(long dni) { + var con = Context; + + Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Dni == dni); + if (cli == null) return false; + + if (cli.Habilitado == 0) { + cli.Habilitado = 1; + } else { + cli.Habilitado = 0; + } + + return Guardar(con); + } + + public Cliente? ObtenerClientePorDni(long dni) { + var con = Context; + Cliente? cli = con.Clientes.FirstOrDefault(x=>x.Dni == dni); + return cli; + } + + public Cliente? ObtenerClientePorToken(string token) { + var con = Context; + Cliente? cli = con.Clientes.Include(x=>x.NotificacioneDniclienteNavigations).FirstOrDefault(x=>x.Token == token); + + if (cli == null|| cli.Dni == 0) return null; + return cli; + } }