105 Commits

Author SHA1 Message Date
fede 6bc32da996 Merge pull request 'dev' (#90) from dev into main
Reviewed-on: #90
2025-08-05 16:46:14 -03:00
fede 0b6bf0ba40 fix: repetida timestamp para el ingreso de contrato 2025-08-05 16:42:25 -03:00
fede 83dffcad72 modificados los lugares donde se muestra opcion venta 2025-08-01 02:14:54 -03:00
fede a84367cd60 correjido un typo 2025-07-29 02:04:30 -03:00
fede afe39d1c80 cambie un conteiner fluid por container 2025-07-29 02:03:36 -03:00
fede f08743ac55 Merge pull request 'v2 ing soft' (#89) from dev into main
Reviewed-on: #89
2025-07-28 20:20:56 -03:00
fede a30e42d06f cambiado canons a canones 2025-07-28 20:00:10 -03:00
fede 76582013c4 arreglado autotab en el pin input 2025-07-27 19:48:30 -03:00
fede 7bb6c6abc2 carga de contratos por admin funcional 2025-07-27 18:14:36 -03:00
fede c180c8ef80 fix: esto arregla todos los warnings de svelte 2025-07-27 13:53:57 -03:00
fede a5f78673d4 primera parte de añadir lo de contratos 2025-07-27 04:00:39 -03:00
fede 5d944b0ee4 añadido front para que el admin suba el contrato 2025-07-26 02:42:30 -03:00
fede 98414a5ec7 correjido posible desreferenciacion nula 2025-07-25 23:29:48 -03:00
fede b7b7b80072 añadida informacion a la pantalla de añadirgarantes 2025-07-25 03:13:04 -03:00
fede ff63497b61 solucionado tema de que no salian datos en meses antiguos 2025-07-24 20:40:19 -03:00
fede caa654a078 comentado writeline 2025-07-23 19:37:24 -03:00
fede fef97e1d05 Sacada tilde del sí porque daba problemas con libreoffice 2025-07-23 02:15:20 -03:00
fede 5444b1dda3 correjido mensaje del log 2025-07-23 02:14:28 -03:00
fede 4e5c209584 añadido logging de cerrar sesion + invalidacion de token 2025-07-23 02:13:14 -03:00
fede 4ab98a0a2e eliminado el SystemBytes 2025-07-23 01:09:25 -03:00
fede 2435ae803e fix: correjidos mensajes de error 2025-07-20 00:34:42 -03:00
fede a7355ea540 fix: contador de meses 2025-07-20 00:34:17 -03:00
fede af3933480d fix: se logeaban usuario desactivados 2025-07-20 00:33:22 -03:00
fede eceefba391 correjidos componentesw para usar el enter como submit 2025-07-17 00:16:28 -03:00
fede e7b2115d6f eliminado codigo test 2025-07-17 00:16:13 -03:00
fede 84a99a1590 Bueno elimine la necesidad de usar un storeprocedure 2025-07-17 00:15:24 -03:00
fede 98dbc8c865 añadido nuevo crear grupo 2025-06-21 01:33:23 -03:00
fede f6dc641508 le doy permiso a ver grupos al p 19 2025-06-21 01:32:43 -03:00
fede e5d17c3a38 añadido tercera estadistica 2025-05-31 01:06:59 -03:00
fede 616c9503bc añadido skeleton del codigo para pagos/ingresos 2025-05-30 00:08:46 -03:00
fede da7f0cf167 corregido limite de chars 2025-05-29 21:34:42 -03:00
fede e0a636ac85 arreglado lo de que se parseaban grupos extra 2025-05-29 21:34:19 -03:00
fede 374540a424 qa 2025-05-24 01:11:17 -03:00
fede e6937c65ca falta testear nomas 2025-05-22 19:38:35 -03:00
fede 033acc1016 eliminados bastantes checkgrupo 2025-05-22 17:35:24 -03:00
fede 3a477e8dc5 refactor 2025-05-22 16:58:26 -03:00
fede 76f5c3a9e9 eliminadas llamadas a checkgrupos 2025-05-22 15:49:00 -03:00
fede 779ab9b982 eliiminado codigo muerto 2025-05-22 15:41:46 -03:00
fede 6f3d985960 1. Update first controller:
- Add new method `CaminarContraAdmin` for changing contrasection
- Include HTTP PATCH handler
- Use camelCase for class names
2. Update second controller:
- Update method name from `caminarContraseña` to `caminarContraAdmin`
- Fix message "contraseña" to be more precise ("contraseña correcta")
3. Update modal component:
- Change `handleSubmit` event from `submit` (JS) to `POST` (Svelte)
- Ensure form validation in JavaScript
4. Update page admin/users to use CardLink for links
2025-05-22 15:23:49 -03:00
fede b4a1d5c0c5 avanzando 2025-05-22 00:59:14 -03:00
fede c51382b565 fix: no se actualizaba la lista de permisos 2025-05-21 00:37:25 -03:00
fede faa3f386a9 Update UsuarioController.cs 2025-05-21 00:26:54 -03:00
fede deb4b90c18 refactor ahora es recuperar cuenta 2025-05-21 00:01:02 -03:00
fede f0da8143eb Update LoginPanel.svelte 2025-05-20 23:19:34 -03:00
fede c3aa0db42d añadido coso 2025-05-20 22:06:09 -03:00
fede e3fa663ffa me traigo todos los cambios del recuperar cuenta y set email respaldo 2025-05-20 00:36:12 -03:00
fede 02add8907e Esta todo a medio hacerse pero quiero versionar esto ya para no perder
nada
2025-05-08 01:00:34 -03:00
fede 6f6d8a4e8c refactor del Fchart 2025-05-07 15:30:31 -03:00
fede 1a5006e832 Añade la capacidad de que setes un mail de recuperacion 2025-05-07 15:30:05 -03:00
fede 61eacc5533 Update bun.lockb 2025-05-07 15:29:11 -03:00
fede c825d737fc Fix database connection handling in AlquilaFacilContext
Improved error handling when loading database connection,
replaced custom context class with Dictionary<string,string>,
and added null checks for safer configuration.
2025-05-05 22:59:34 -03:00
fede f7d52041ba Format code with proper spacing and brackets 2025-05-05 22:45:45 -03:00
fede fddafd5234 Add recovery email field to Cliente entity 2025-05-05 21:36:36 -03:00
fede ca44b3cf84 ahora solo ve los grupos activos tanto en la resolucion de permisos como
en el front
2025-05-05 18:48:05 -03:00
fede 139b855c2c feat: login usuario 2025-05-05 17:48:05 -03:00
fede 4f44581503 Add user profile button to navigation bar 2025-05-05 13:25:01 -03:00
fede 402c98eb6b ya estaba implementado 2025-05-05 12:45:01 -03:00
fede 11f4d38f8b Remplazados algunos checkgrupos faltan 8 2025-04-28 21:08:18 -03:00
fede 6194e5b4b9 Refactor code formatting 2025-04-28 20:41:39 -03:00
fede b6d78747c8 Replace RepositorioGrupos with RepositorioPermisos 2025-04-28 20:24:22 -03:00
fede 5df52d8426 ahi le cambie los checkgrupo por checkpermiso 2025-04-28 18:32:49 -03:00
fede 2304e7b54b cambiado que use permisos 2025-04-28 17:41:43 -03:00
fede 2dd72bf070 Update App.svelte 2025-04-28 17:41:26 -03:00
fede 6926221353 eliminado checkgrupos en notificaciones controller 2025-04-28 17:27:02 -03:00
fede 0961618e40 lol ahora si usa composite bien 2025-04-28 17:15:12 -03:00
fede 99591b8cc2 bueno ya esta implemntado todo lo de permisos de forma recursiva 2025-04-25 19:46:18 -03:00
fede 8e385a4710 eliminado wip 2025-04-25 18:02:48 -03:00
fede b2f45baec7 ahora lista usando profundidad 2025-04-25 16:23:10 -03:00
fede 190f9a8e10 bruh estaba la relacion al revez 2025-04-25 14:52:16 -03:00
fede 25e399a5b3 fix: mejorado espacio vertical que ocupa la tabla 2025-04-25 13:47:13 -03:00
fede 36b8f03421 eliminado un wip 2025-04-25 13:46:40 -03:00
fede c5a0eb70b8 duplica la funcion con gestion permisos 2025-04-25 13:36:41 -03:00
fede 1d3784d848 creado toggle habilitar grupo y correjido un par de bugs de
modalestatico
2025-04-25 13:06:19 -03:00
fede fdcb74bb11 feat: crea todas las entidades para mergearlas con meld 2025-04-25 11:35:36 -03:00
fede df751ead57 añadido un bit de habilitado 2025-04-25 11:23:42 -03:00
fede eeb2ff1c65 ahora esta la gestion de permisos 2025-04-22 21:00:58 -03:00
fede e118a3acd2 falta poner los fetch 2025-04-21 19:37:03 -03:00
fede 524a315dc1 refactor de admin usuarios 2025-04-21 16:33:11 -03:00
fede 4e5e0a4f6f ahora las opciones de grupos corresponden a las que existen en vez de
ser hardcode
2025-04-21 16:32:50 -03:00
fede b75f672b0a arreglado bug que no salia el nombre del grupo 2025-04-21 16:23:15 -03:00
fede de9ff8f0b3 skeleton para pagina grupo creado por usuario 2025-04-21 16:02:05 -03:00
fede 543bc9e5a6 Añadido soporte para crear grupos nuevos 2025-04-21 16:01:15 -03:00
fede ffb860688d analizado que necesito hacer de aca en adelante
- [ ] una pagina de grupo default
- [ ] los permisos resuelvan los de subgrupos
2025-04-21 01:09:53 -03:00
fede b98fde72ca hecha funcionalida de modificar grupos 2025-04-18 23:54:27 -03:00
fede 701f699c55 primer inicio del modal 2025-04-17 13:45:35 -03:00
fede c1a27baedd avansando más 2025-04-17 13:24:07 -03:00
fede 6fb6ade153 add concurrently 2025-04-14 17:28:28 -03:00
fede bb995d1587 fix: el checkbox no guardaba estado 2025-04-07 15:30:10 -03:00
fede 483a2b5409 fix: ahora no hace autoscroll hacia arriba 2025-04-07 14:55:37 -03:00
fede eadeeb2b08 potencial codigo duplicado 2025-04-07 14:44:51 -03:00
fede 2ad084cf19 añadido boton para cerrar sesion 2025-04-07 14:27:01 -03:00
fede 0036f48d19 primeros pasos en añadir las cosas que pide el profe 2025-03-31 23:27:25 -03:00
fede 790cc31f93 refactor porque era ilejible 2025-03-31 19:38:42 -03:00
fede 25f77f6f48 primera edicion de un archivo para cambiar grupos a permisos 2025-03-14 02:43:41 -03:00
fede b3ffa657f5 añadido endpoint para crear permisos 2025-03-14 02:33:59 -03:00
fede 878583664e añadido que logee la ip y los logins 2025-03-05 20:28:03 -03:00
fede 24c6e43f2d añadido cors para ipv6 2025-03-05 20:27:44 -03:00
fede b898c6911c Merge pull request 'main' (#70) from main into dev
Reviewed-on: #70
2025-03-05 19:16:26 -03:00
fede befe0f2848 Merge pull request 'deploy-local-de-la-v1-del-sistema' (#68) from deploy-local-de-la-v1-del-sistema into main
Reviewed-on: #68
2025-03-05 19:15:45 -03:00
fede 8f494b383a arreglado colapsed 2025-03-05 19:13:23 -03:00
fede 09f41c00cd faltaba query al servidor para tener los garantes 2025-03-05 19:13:13 -03:00
fede dda1032685 cambios para tener composite 2025-03-05 19:12:02 -03:00
fede 21724a372f añado bootstrap como dependencia para que carge sin conexion 2025-03-05 19:08:11 -03:00
fede 6c58c6da78 cambios en el acceso no me preocupo porque queda tocar esto 2025-03-05 19:07:20 -03:00
fede 22d68d4ce9 mal uso de la palabra acá
Signed-off-by: fede <federico.nicolas.polidoro@gmail.com>
2025-02-17 17:11:18 -03:00
91 changed files with 7006 additions and 2124 deletions
@@ -1,74 +1,94 @@
using Entidades.Dto; using Entidades.Dto;
namespace AlquilaFacil.Builder; namespace AlquilaFacil.Builder;
public class ContratoPropiedadDtoBuilder : Builder<ContratoPropiedadDto>{ public class ContratoPropiedadDtoBuilder : Builder<ContratoPropiedadDto>
public ContratoPropiedadDtoBuilder SetId(long id ){ {
public ContratoPropiedadDtoBuilder SetId(long id)
{
data.id = id; data.id = id;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetUbicacion(string ub){ public ContratoPropiedadDtoBuilder SetUbicacion(string ub)
{
data.Ubicacion = ub; data.Ubicacion = ub;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetTipo(string tipo){ public ContratoPropiedadDtoBuilder SetTipo(string tipo)
{
data.TipoPropiedad = tipo; data.TipoPropiedad = tipo;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetFechaInicio(DateTime fec) { public ContratoPropiedadDtoBuilder SetFechaInicio(DateTime fec)
{
data.Fechainicio = fec; data.Fechainicio = fec;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetInquilino(string inquilino){ public ContratoPropiedadDtoBuilder SetInquilino(string inquilino)
{
data.Inquilino = inquilino; data.Inquilino = inquilino;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetPropietario(string propietario){ public ContratoPropiedadDtoBuilder SetPropietario(string propietario)
{
data.Propietario = propietario; data.Propietario = propietario;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetEstado(ulong habilitado, ulong cancelado) { public ContratoPropiedadDtoBuilder SetEstado(ulong habilitado, ulong cancelado)
bool Habilitado = habilitado == 0?false:true; {
bool Cancelado = cancelado == 0?false:true; bool Habilitado = habilitado == 0 ? false : true;
bool Cancelado = cancelado == 0 ? false : true;
if (Habilitado == true && Cancelado == false){ if (Habilitado == true && Cancelado == false)
{
data.Estado = "Alquiler Iniciado"; data.Estado = "Alquiler Iniciado";
} else if (Cancelado == true && Habilitado == false) { }
else if (Cancelado == true && Habilitado == false)
{
data.Estado = "Nunca Empezo Esta Cancelado"; data.Estado = "Nunca Empezo Esta Cancelado";
} else if (Habilitado == false && Cancelado ==false){ }
else if (Habilitado == false && Cancelado == false)
{
data.Estado = "Esta en Proceso"; data.Estado = "Esta en Proceso";
} else if (Habilitado == true && Cancelado == true){ }
else if (Habilitado == true && Cancelado == true)
{
data.Estado = "Terminado"; data.Estado = "Terminado";
} }
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetHabitaciones(int habitaciones){ public ContratoPropiedadDtoBuilder SetHabitaciones(int habitaciones)
{
data.Habitaciones = habitaciones; data.Habitaciones = habitaciones;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetPiso(int piso){ public ContratoPropiedadDtoBuilder SetPiso(int piso)
{
data.Piso = piso; data.Piso = piso;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetLetra(string letra){ public ContratoPropiedadDtoBuilder SetLetra(string letra)
{
data.Letra = letra; data.Letra = letra;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetMesesAumento(int mesesAumento){ public ContratoPropiedadDtoBuilder SetMesesAumento(int mesesAumento)
{
data.MesesAumento = mesesAumento; data.MesesAumento = mesesAumento;
return this; return this;
} }
public ContratoPropiedadDtoBuilder SetMesesDuracion(int mesesDurationContrato) { public ContratoPropiedadDtoBuilder SetMesesDuracion(int mesesDurationContrato)
{
data.MesesDuracion = mesesDurationContrato; data.MesesDuracion = mesesDurationContrato;
return this; return this;
} }
@@ -0,0 +1,50 @@
using Entidades.Dto;
namespace AlquilaFacil.Builder;
public class GrupoDtoBuilder : Builder<GrupoDto>
{
public GrupoDtoBuilder ConNombre(string nombre)
{
data.Nombre = nombre;
return this;
}
public GrupoDtoBuilder ConHabilitado(bool habilitado)
{
data.Habilitado = habilitado;
return this;
}
public GrupoDtoBuilder ConIdGrupo(int id)
{
data.idgrupo = id;
return this;
}
public GrupoDtoBuilder ConGruposIncluidos(HashSet<string> grupos)
{
data.GruposIncluidos = grupos;
return this;
}
public GrupoDtoBuilder ConPermisos(List<PermisoDto> permisos)
{
data.Permisos = permisos;
return this;
}
}
public class PermisoDtoBuilder : Builder<PermisoDto>
{
public PermisoDtoBuilder ConId(int id)
{
data.Id = id;
return this;
}
public PermisoDtoBuilder ConDescripcion(string descripcion)
{
data.Descripcion = descripcion;
return this;
}
}
@@ -0,0 +1,41 @@
using Entidades.Dto;
namespace AlquilaFacil.Builder;
public class UsuarioDtoBuilder : Builder<UsuarioDto>
{
public UsuarioDtoBuilder SetDni(long dni)
{
data.Dni = dni;
return this;
}
public UsuarioDtoBuilder SetNombre(string nombre)
{
data.Nombre = nombre;
return this;
}
public UsuarioDtoBuilder SetApellido(string apellido)
{
data.Apellido = apellido;
return this;
}
public UsuarioDtoBuilder SetDomicilio(string domicilio)
{
data.Domicilio = domicilio;
return this;
}
public UsuarioDtoBuilder SetCelular(string celular)
{
data.Celular = celular;
return this;
}
public UsuarioDtoBuilder SetEmail(string email)
{
data.Email = email;
return this;
}
public UsuarioDtoBuilder SetEmailRecuperacion(string? email)
{
data.EmailRecuperacion = email ?? "";
return this;
}
}
+15
View File
@@ -0,0 +1,15 @@
using Entidades;
public class PermisoBuilder : Builder<Permiso>
{
public PermisoBuilder SetDescripcion(string desc)
{
data.Descripcion = desc;
return this;
}
public PermisoBuilder SetID(int id)
{
data.Id = id;
return this;
}
}
+40 -7
View File
@@ -1,20 +1,20 @@
using System.ComponentModel.DataAnnotations;
using Entidades.Dto; using Entidades.Dto;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Modelo; using Modelo;
using System.Text.Json; using Entidades;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class AccionesController: ControllerBase { public class AccionesController : ControllerBase
{
[HttpGet("api/acciones")] [HttpGet("api/acciones")]
public IActionResult ListarAccionesPorUsuario([FromHeader(Name ="Email")] string Email, [FromHeader(Name = "Auth")] string Auth) { public IActionResult ListarAccionesPorUsuario([FromHeader(Name = "Email")] string Email, [FromHeader(Name = "Auth")] string Auth)
{
if (Email == "" || Email == null) return BadRequest(); if (Email == "" || Email == null) return BadRequest();
if (Auth == "") return Unauthorized(new { esValido = false}); if (Auth == "") return Unauthorized(new { esValido = false });
bool esValido = RepositorioUsuarios.Singleton.CheckToken(Email, Auth); bool esValido = RepositorioUsuarios.Singleton.CheckToken(Email, Auth);
if (!esValido) return Unauthorized(); if (!esValido) return Unauthorized();
@@ -24,9 +24,11 @@ public class AccionesController: ControllerBase {
return Ok(Permisos); return Ok(Permisos);
} }
[HttpPost("api/acciones/grupo")] [HttpPost("api/acciones/grupo")]
public IActionResult ListarAccionesPorGrupo([FromHeader(Name = "Auth")] string Auth, public IActionResult ListarAccionesPorGrupo([FromHeader(Name = "Auth")] string Auth,
[FromBody] AccionesPorGrupoDto req) { [FromBody] AccionesPorGrupoDto req)
{
if (string.IsNullOrEmpty(Auth)) return BadRequest(); if (string.IsNullOrEmpty(Auth)) return BadRequest();
bool esValido = RepositorioUsuarios.Singleton.CheckToken(req.Email, Auth); bool esValido = RepositorioUsuarios.Singleton.CheckToken(req.Email, Auth);
if (esValido == false) return BadRequest(esValido); if (esValido == false) return BadRequest(esValido);
@@ -37,4 +39,35 @@ public class AccionesController: ControllerBase {
var permisos = RepositorioGrupos.Singleton.ListarPermisosDeGrupo(req.Grupo); var permisos = RepositorioGrupos.Singleton.ListarPermisosDeGrupo(req.Grupo);
return Ok(permisos); return Ok(permisos);
} }
/*
[HttpPost("api/acciones/crear")] //creo que es codido duplicado
public IActionResult CrearAcciones([FromHeader(Name = "Auth")] string Auth,
[FromBody] CrearAccionesDto req)
{
if (string.IsNullOrEmpty(Auth)) return BadRequest();
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized();
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1); //wip lo voy a usar para crear el permiso que va
if (ret == false) return Unauthorized();
if (string.IsNullOrWhiteSpace(req.Descripcion))
{
return BadRequest(new { message = "La descripción no puede estar vacía" });
}
if (req.Descripcion.Length > 25)
{
return BadRequest(new { message = "La descripción no puede ser mayor a 25 caracteres" });
}
var per = new Permiso
{
Descripcion = req.Descripcion,
};
var ret2 = RepositorioPermisos.Singleton.CrearPermiso(per);
return ret2 ? Ok(new { message = "se creo correctamente" }) : BadRequest(new { message = "No se pudo crear el permiso" });
}
*/
} }
+11 -7
View File
@@ -47,7 +47,7 @@ public class AdminController: ControllerBase
[HttpGet("api/contratos/controlPagos/propiedad")] [HttpGet("api/contratos/controlPagos/propiedad")]
public IActionResult obtenerPropiedad([FromHeader(Name = "Auth")] string Auth, int id = 0) { public IActionResult obtenerPropiedad([FromHeader(Name = "Auth")] string Auth, int id = 0) {
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (id <= 0) return BadRequest(new { message = "No hay propiedades con id igual o menor a 0"}); if (id <= 0) return BadRequest(new { message = "No hay propiedades con id igual o menor a 0"});
@@ -89,7 +89,7 @@ public class AdminController: ControllerBase
[HttpGet("/api/admin/contrato/verDocumento")] [HttpGet("/api/admin/contrato/verDocumento")]
public IActionResult verDocumento([FromHeader(Name = "Auth")] string Auth, int idcontrato = 0){ public IActionResult verDocumento([FromHeader(Name = "Auth")] string Auth, int idcontrato = 0){
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (idcontrato <= 0) return BadRequest(new {message = "La id no puede ser igual o menor a 0"}); if (idcontrato <= 0) return BadRequest(new {message = "La id no puede ser igual o menor a 0"});
@@ -123,7 +123,7 @@ public class AdminController: ControllerBase
[HttpGet("api/admin/contrato/canons")] [HttpGet("api/admin/contrato/canons")]
public IActionResult ObtenerCanones([FromHeader(Name="Auth")]string Auth, int id = 0){ public IActionResult ObtenerCanones([FromHeader(Name="Auth")]string Auth, int id = 0){
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
var cont = RepositorioContratos.Singleton.ObtenerContratoPorId(id); var cont = RepositorioContratos.Singleton.ObtenerContratoPorId(id);
@@ -161,7 +161,7 @@ public class AdminController: ControllerBase
[HttpPost("api/admin/contrato/marcarPago")] [HttpPost("api/admin/contrato/marcarPago")]
public IActionResult realizarPago([FromHeader(Name="Auth")]string Auth, MarcarPagoDto dto) { public IActionResult realizarPago([FromHeader(Name="Auth")]string Auth, MarcarPagoDto dto) {
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (dto.Idcontrato<=0) return BadRequest(new { message = "No puede existir un contrato con id 0 o menor"}); if (dto.Idcontrato<=0) return BadRequest(new { message = "No puede existir un contrato con id 0 o menor"});
@@ -188,7 +188,7 @@ public class AdminController: ControllerBase
[HttpPost("api/admin/notificarInquilino")] [HttpPost("api/admin/notificarInquilino")]
public IActionResult NotificarInquilino([FromHeader(Name ="Auth")]string Auth, NotificarAdmin data){ public IActionResult NotificarInquilino([FromHeader(Name ="Auth")]string Auth, NotificarAdmin data){
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Admin"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
@@ -269,6 +269,7 @@ public class AdminController: ControllerBase
BadRequest(new { message = "Fallo al guardar los datos"}); BadRequest(new { message = "Fallo al guardar los datos"});
} }
public record GrupoI_D(int Id, string Descripcion);
[HttpGet("api/admin/clientes/grupo")] [HttpGet("api/admin/clientes/grupo")]
public IActionResult GetGruposByCliente([FromHeader(Name ="Auth")]string Auth, [FromQuery]long Dni){ public IActionResult GetGruposByCliente([FromHeader(Name ="Auth")]string Auth, [FromQuery]long Dni){
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
@@ -277,9 +278,10 @@ public class AdminController: ControllerBase
if (Dni <= 0) return BadRequest(new {message = "No puede tener un dni con numero negativo o cero"}); if (Dni <= 0) return BadRequest(new {message = "No puede tener un dni con numero negativo o cero"});
IEnumerable<GrupoAdmin> list = RepositorioGrupos.Singleton.ObtenerGruposPorDni(Dni); IEnumerable<GrupoI_D> list = RepositorioGrupos.Singleton.ObtenerGruposPorDni(Dni).Select(x=> new GrupoI_D(x.Id,x.Nombre));
return Ok(list); return Ok(list);
} }
[HttpPatch("api/admin/cliente/addGrupo")] [HttpPatch("api/admin/cliente/addGrupo")]
public IActionResult AddGrupoACliente([FromHeader(Name = "Auth")]string Auth, [FromBody]EmailGrupo data){ public IActionResult AddGrupoACliente([FromHeader(Name = "Auth")]string Auth, [FromBody]EmailGrupo data){
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
@@ -362,7 +364,9 @@ public class AdminController: ControllerBase
} }
// lo da de baja si no tiene el grupo propietario y no tiene alquileres pendientes // lo da de baja si no tiene el grupo propietario y no tiene alquileres pendientes
var ret = RepositorioUsuarios.Singleton.BajaCliente(Dni); var ret = RepositorioUsuarios.Singleton.BajaCliente(Dni);
return Ok(ret); return ret ?
Ok(new { message = "Cliente ha sido modificado" }) :
BadRequest(new { message = "No se pudo modificar al cliente" });
} }
[HttpDelete("api/admin/propiedad")] [HttpDelete("api/admin/propiedad")]
@@ -0,0 +1,353 @@
using Microsoft.AspNetCore.Mvc;
using AlquilaFacil.Config;
using Modelo;
using Entidades.Dto;
using Entidades;
using Minio;
using Minio.DataModel;
using Minio.DataModel.Args;
using Minio.Exceptions;
using System.Text.Json;
[ApiController]
public class CargarContratoAdminController: ControllerBase{
[HttpGet("api/admin/contrato/data")]
public IActionResult GetData([FromHeader(Name ="Auth")]string Auth) {
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay usuario por ese token"});
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 20);
if (validacion1 == false) return Unauthorized();
var divisas = RepositorioDivisas.Singleton.ObtenerDivisas();
var propiedades = RepositorioPropiedades.Singleton.ListarPropiedades().ToList()
.Select(x=> new {id = x.id,
ubicacion = x.Ubicacion});
var inquilinos = RepositorioInquilinos.Singleton.GetInquilinos().ToList()
.Select(x=>new {dni=x.Dni, nombre = x.Nombre});
var propietarios = RepositorioPropietario.Singleton.GetPropietarios().ToList()
.Select(x=>new {dni=x.Dni, nombre = x.Nombre});
return Ok(new {divisas,
propiedades,
inquilinos,
propietarios});
}
[HttpGet("api/admin/contrato/propieades")]
public IActionResult GetPropiedadesPorPropietario([FromHeader(Name ="Auth")]string Auth, long dnipropietario){
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay usuario por ese token"});
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 20);
if (validacion1 == false) return Unauthorized();
var propiedades = RepositorioPropiedades.Singleton.ObtenerPropiedadEnAlquilerPorDni(dnipropietario);
return Ok(propiedades);
}
[HttpPost("api/admin/contrato/carga")]
public async Task<IActionResult> CargaContrato([FromHeader(Name="Auth")]string Auth) {
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay usuario por ese token"});
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 20);
if (validacion1 == false) return Unauthorized();
if (!Request.HasFormContentType) {
return BadRequest(new { message = "La solicitud debe contener datos de formulario (FormData)." });
}
var formData = await Request.ReadFormAsync();
if (formData == null) {
return BadRequest(new { message = "No se pudieron leer los datos del formulario." });
}
var archivoContrato = Request.Form.Files.FirstOrDefault(x=>x.Name =="archivoContrato");
if (archivoContrato == null) return BadRequest(new { message = "Falto Subir el archivo" });
if (archivoContrato.ContentType != "application/pdf") {
return BadRequest(new { message = "El archivo debe ser un PDF." });
}
Contrato? cont; IActionResult? req;
(cont, req) = ParseContratoFromForm(formData);
if (req != null && cont == null) return req;
var ret = RepositorioContratos.Singleton.AdminCargaContrato(cont, cli.Dni);
if(ret == false) return BadRequest( new {message = "No se pudo cargar el contrato" });
var inq = RepositorioUsuarios.Singleton.ObtenerClientePorDni(cont.Dniinquilino??0);
cont = RepositorioContratos.Singleton.ObtenerContrato(inq.Email, cont.Idpropiedad ?? 0);
if (cont == null) return BadRequest(new { message = "No se pudo recuperar el contrato" });
string nuevoNombreArchivo = $"id:{cont.Id}-inq:{cont.Dniinquilino}-propi:{cont.Dnipropietario}-idprop:{cont.Idpropiedad}.pdf";
ret = await subirContrato(archivoContrato, nuevoNombreArchivo);
if (ret == false) return BadRequest(new { message = "No se pudo subir el archivo" });
ret = RepositorioContratos.Singleton.AddUrl(cont.Id, nuevoNombreArchivo);
if (ret == false) return BadRequest(new { message = "No se pudo guardar la url del contrato" });
ret = RepositorioContratos.Singleton.GenerarCanones(cont.Id, cli.Dni);
if (ret == false) return BadRequest( new { message = "Fallo al generar canones" });
var noti = new NotificacioneBuilder()
.SetDniremitente(int.Parse(cli.Dni.ToString()))
.SetIdpropiedad(cont.Idpropiedad ?? 0)
.SetDnicliente(cont.Dniinquilino ?? 0)
.SetAccion("Notificacion")
.SetMensaje($"Contrato Cargado desde Administracion")
.SetFecha(DateTime.Now)
.SetLeido(false)
.Build();
var noti2 = new NotificacioneBuilder()
.SetDniremitente(int.Parse(cli.Dni.ToString()))
.SetIdpropiedad(cont.Idpropiedad ?? 0)
.SetDnicliente(cont.Dnipropietario ?? 0)
.SetAccion("Notificacion")
.SetMensaje($"Contrato Cargado desde Administracion")
.SetFecha(DateTime.Now)
.SetLeido(false)
.Build();
ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti);
if (ret == false) return BadRequest( new { message = "No se pudo entregar la notificacion al inquilino" });
ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti2);
if (ret == false) return BadRequest( new { message = "No se pudo entregar la notificacion al propietario" });
return Ok(new { message = "Se cargo el contrato" });
}
private (Contrato? contratoDto, IActionResult? errorResult) ParseContratoFromForm(IFormCollection formData) {
if (formData == null) {
return (null, BadRequest(new { message = "No se pudieron leer los datos del formulario." }));
}
bool TryParseInt(string? value, out int result) => int.TryParse(value, out result);
bool TryParseLong(string? value, out long result) => long.TryParse(value, out result);
bool TryParseDecimal(string? value, out decimal result) => decimal.TryParse(value, out result);
bool TryParseBool(string? value, out bool result) => bool.TryParse(value, out result);
int cantGarantMin = 0;
if (formData.TryGetValue("cantgarantemin", out var cantGarantMinValues) &&
!string.IsNullOrEmpty(cantGarantMinValues.FirstOrDefault()) &&
!TryParseInt(cantGarantMinValues.FirstOrDefault(), out cantGarantMin)) {
return (null, BadRequest(new { message = "Campo 'cantgarantemin' inválido." }));
}
if (cantGarantMin<1) return (null, BadRequest(new { message = "Minimo 1 garante" }));
if (!formData.TryGetValue("dniinquilino", out var dniInqValues) ||
string.IsNullOrEmpty(dniInqValues.FirstOrDefault()) ||
!TryParseLong(dniInqValues.FirstOrDefault(), out long dniInquilino)) {
return (null, BadRequest(new { message = "Campo 'dniinquilino' inválido o faltante." }));
}
if (dniInquilino<=0) return (null, BadRequest(new { message = "No pueden haber dni 0 o menor" }));
if (!formData.TryGetValue("dnipropietario", out var dniPropValues) ||
string.IsNullOrEmpty(dniPropValues.FirstOrDefault()) ||
!TryParseLong(dniPropValues.FirstOrDefault(), out long dniPropietario)) {
return (null, BadRequest(new { message = "Campo 'dnipropietario' inválido o faltante." }));
}
if (dniPropietario<=0) return (null, BadRequest(new { message = "No pueden haber dni 0 o menor" }));
if (!formData.TryGetValue("iddivisa", out var idDivisaValues) ||
string.IsNullOrEmpty(idDivisaValues.FirstOrDefault()) ||
!TryParseInt(idDivisaValues.FirstOrDefault(), out int idDivisa)) {
return (null, BadRequest(new { message = "Campo 'iddivisa' inválido o faltante." }));
}
if (!formData.TryGetValue("idpropiedad", out var idPropValues) ||
string.IsNullOrEmpty(idPropValues.FirstOrDefault()) ||
!TryParseInt(idPropValues.FirstOrDefault(), out int idPropiedad)) {
return (null, BadRequest(new { message = "Campo 'idpropiedad' inválido o faltante." }));
}
if (!formData.TryGetValue("mesesDurationContrato", out var mesesDurValues) ||
string.IsNullOrEmpty(mesesDurValues.FirstOrDefault()) ||
!TryParseInt(mesesDurValues.FirstOrDefault(), out int mesesDuration)) {
return (null, BadRequest(new { message = "Campo 'mesesDurationContrato' inválido o faltante." }));
}
if (mesesDuration <= 0){
return (null, BadRequest(new { message = "No se cargaron los meses de duracion del contrato" }));
}
int mesesHastaAumento = 0;
if (formData.TryGetValue("mesesHastaAumento", out var mesesHastaValues) &&
!string.IsNullOrEmpty(mesesHastaValues.FirstOrDefault())) {
if (!TryParseInt(mesesHastaValues.FirstOrDefault(), out mesesHastaAumento))
{
return (null, BadRequest(new { message = "Campo 'mesesHastaAumento' inválido." }));
}
}
if (mesesHastaAumento <= 0){
return (null, BadRequest(new { message = "No se cargaron los meses hasta el aumento" }));
}
if (mesesDuration<mesesHastaAumento) return (null, BadRequest( new { message = "El contrato no puede durar menos que el tiempo hasta el aumento" } ));
if (!formData.TryGetValue("monto", out var montoValues) ||
string.IsNullOrEmpty(montoValues.FirstOrDefault()) ||
!TryParseDecimal(montoValues.FirstOrDefault(), out decimal monto)) {
return (null, BadRequest(new { message = "Campo 'monto' inválido o faltante." }));
}
if (monto <= 0.0m){
return (null, BadRequest(new { message = "No se cargo el monto de alquiler" }));
}
bool tieneOpcionVenta = false;
if (formData.TryGetValue("tieneopcionventa", out var tieneOpcionValues) &&
!string.IsNullOrEmpty(tieneOpcionValues.FirstOrDefault())) {
if (!TryParseBool(tieneOpcionValues.FirstOrDefault(), out tieneOpcionVenta)) {
return (null, BadRequest(new { message = "Campo 'tieneopcionventa' inválido." }));
}
}
int divisaOpcionVenta = 0;
decimal montoOpcionVenta = 0m;
if (tieneOpcionVenta) {
if (formData.TryGetValue("divisaOpcionVenta", out var divisaOpcValues) &&
!string.IsNullOrEmpty(divisaOpcValues.FirstOrDefault())) {
if (!TryParseInt(divisaOpcValues.FirstOrDefault(), out int divisaOpcParsed)) {
return (null, BadRequest(new { message = "Campo 'divisaOpcionVenta' inválido." }));
}
divisaOpcionVenta = divisaOpcParsed;
}
if (formData.TryGetValue("montoOpcionVenta", out var montoOpcValues) &&
!string.IsNullOrEmpty(montoOpcValues.FirstOrDefault())) {
if (!TryParseDecimal(montoOpcValues.FirstOrDefault(), out decimal montoOpcParsed)) {
return (null, BadRequest(new { message = "Campo 'montoOpcionVenta' inválido." }));
}
montoOpcionVenta = montoOpcParsed;
}
}
if (montoOpcionVenta <= 0.0m && tieneOpcionVenta){
return (null, BadRequest(new { message = "No se cargo el monto de la opcion de venta" }));
}
var cont = new Contrato{
Cancelado=0,
Habilitado=0,
Cantgarantemin=cantGarantMin,
Dniinquilino=dniInquilino,
Dnipropietario=dniPropietario,
Fechainicio=DateTime.Now,
Iddivisa=idDivisa,
Idpropiedad=idPropiedad,
Monto=monto,
MesesDurationContrato = mesesDuration,
MesesHastaAumento=mesesHastaAumento,
Idgarantes = ParseGarantes(formData),
Tieneopcionventa=tieneOpcionVenta?1ul:0ul,
};
if(cont.Tieneopcionventa==1ul){
cont.IdventaNavigation = new Venta{
Idestado = 1,
Monto= montoOpcionVenta,
Iddivisa = divisaOpcionVenta
};
}
return (cont, null);
}
private Garante[] ParseGarantes(IFormCollection formData) {
var garantes = new List<Garante>();
var garanteKeys = formData.Keys.Where(k => k.StartsWith("garantes[")).ToList();
var garanteCount = garanteKeys.Count / 6;
for (int i = 0; i < garanteCount; i++) {
int dni = 0;
if (formData.TryGetValue($"garantes[{i}].dni", out var dniValue) &&
!string.IsNullOrEmpty(dniValue.FirstOrDefault()))
{
int.TryParse(dniValue.FirstOrDefault(), out dni);
}
var nombre = formData.TryGetValue($"garantes[{i}].nombre", out var nombreValue) ? nombreValue.ToString() ?? "" : "";
var apellido = formData.TryGetValue($"garantes[{i}].apellido", out var apellidoValue) ? apellidoValue.ToString() ?? "" : "";
var domicilio = formData.TryGetValue($"garantes[{i}].domicilio", out var domicilioValue) ? domicilioValue.ToString() ?? "" : "";
var celular = formData.TryGetValue($"garantes[{i}].celular", out var celularValue) ? celularValue.ToString() ?? "" : "";
var domicilioLaboral = formData.TryGetValue($"garantes[{i}].domicilioLaboral", out var domLaboralValue) ? domLaboralValue.ToString() ?? "" : "";
var garante = new Garante{
Dni = dni,
Nombre = nombre,
Apellido = apellido,
Domicilio = domicilio,
Celular = celular,
Domiciliolaboral = domicilioLaboral
};
garantes.Add(garante);
}
return garantes.ToArray();
}
private readonly IMinioClient mc;
public CargarContratoAdminController(IMinioClient minioClient)
{
mc = minioClient;
if (mc == null)
{
MinioConfigcus? mcon = JsonSerializer.Deserialize<MinioConfigcus>(System.IO.File.ReadAllText("./settings.json")) ?? null;
if (mcon == null) throw new Exception();
mc = new MinioClient().WithCredentials(mcon.usr, mcon.scrt)
.WithEndpoint("0.0.0.0:9000")
.WithSSL(false)
.Build();
}
}
private async Task<bool> 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;
}
}
}
File diff suppressed because it is too large Load Diff
+36 -27
View File
@@ -7,17 +7,21 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class DefectoController: ControllerBase { public class DefectoController : ControllerBase
{
[HttpGet("api/defectos")] [HttpGet("api/defectos")]
public IActionResult ObtenerDefectosEnContrato([FromHeader(Name = "Auth")] string Auth, long Idcontrato = 0) { public IActionResult ObtenerDefectosEnContrato([FromHeader(Name = "Auth")] string Auth, long Idcontrato = 0)
if (Idcontrato <= 0) return BadRequest( new { message = "La id de contrato no puede ser menor o igual a 0"}); {
if (Idcontrato <= 0) return BadRequest(new { message = "La id de contrato no puede ser menor o igual a 0" });
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12);
if (validacion1 == false){ if (validacion1 == false)
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); {
if (validacion1 == false) { validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
} }
@@ -26,19 +30,20 @@ public class DefectoController: ControllerBase {
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(Idcontrato); Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(Idcontrato);
if (cont == null) return BadRequest(new { message = "No hay contrato por esa id"}); if (cont == null) return BadRequest(new { message = "No hay contrato por esa id" });
if (cont.Dniinquilino != cli.Dni && cont.Dnipropietario != cli.Dni) return BadRequest(new { message = "no deberias tener acceso a esto"}); if (cont.Dniinquilino != cli.Dni && cont.Dnipropietario != cli.Dni) return BadRequest(new { message = "no deberias tener acceso a esto" });
var l = RepositorioDefectos.Singleton.ObtenerDefectosPorIdContrato(Idcontrato); var l = RepositorioDefectos.Singleton.ObtenerDefectosPorIdContrato(Idcontrato);
List<DefectoDto> ll = new(); List<DefectoDto> ll = new();
foreach (var i in l){ foreach (var i in l)
{
var n = new DefectoDtoBuilder() var n = new DefectoDtoBuilder()
.SetId(i.Id) .SetId(i.Id)
.SetDesc(i.Descripcion) .SetDesc(i.Descripcion)
.SetCosto(i.Costo) .SetCosto(i.Costo)
.SetEstado(i.IdestadoNavigation.Descipcion) .SetEstado(i.IdestadoNavigation.Descipcion)
.SetIdContrato(i.Idcontrato??0) .SetIdContrato(i.Idcontrato ?? 0)
.SetPagaInquilino(i.Pagainquilino) .SetPagaInquilino(i.Pagainquilino)
.SetDivisa(i.IddivisaNavigation.Signo) .SetDivisa(i.IddivisaNavigation.Signo)
.Build(); .Build();
@@ -48,54 +53,58 @@ public class DefectoController: ControllerBase {
} }
[HttpPost("api/defecto")] [HttpPost("api/defecto")]
public IActionResult AltaDefecto([FromHeader(Name = "Auth")] string Auth, AltaDefectoDto data) { public IActionResult AltaDefecto([FromHeader(Name = "Auth")] string Auth, AltaDefectoDto data)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
Cliente? cli =RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
string r = ValidarDto(data); string r = ValidarDto(data);
if (r != "") return BadRequest(new { message = r }); if (r != "") return BadRequest(new { message = r });
Defecto defecto = new Defecto{ Defecto defecto = new Defecto
{
Costo = data.Costo, Costo = data.Costo,
Descripcion = data.Descripcion, Descripcion = data.Descripcion,
Idcontrato = data.Idcontrato, Idcontrato = data.Idcontrato,
Iddivisa = data.Iddivisa, Iddivisa = data.Iddivisa,
Pagainquilino = data.Pagainquilino==0?0Lu:1Lu, Pagainquilino = data.Pagainquilino == 0 ? 0Lu : 1Lu,
Idestado = 1, Idestado = 1,
}; };
var b = RepositorioDefectos.Singleton.AltaDefecto(defecto, cli.Dni); var b = RepositorioDefectos.Singleton.AltaDefecto(defecto, cli.Dni);
return b ?Ok(new { message = "Se cargo el Defecto en el sistema"}):BadRequest(new { message ="No se pudo cargar el defecto en el sistema"}); return b ? Ok(new { message = "Se cargo el Defecto en el sistema" }) : BadRequest(new { message = "No se pudo cargar el defecto en el sistema" });
} }
private string ValidarDto(AltaDefectoDto d){ private string ValidarDto(AltaDefectoDto d)
string ret =""; {
string ret = "";
if (d == null) return "Dto nulo"; if (d == null) return "Dto nulo";
if (d.Iddivisa <0 || d.Iddivisa>1) ret +="No son divisas validas\n"; if (d.Iddivisa < 0 || d.Iddivisa > 1) ret += "No son divisas validas\n";
if (d.Descripcion == "") ret+="La descripcion no puede estar vacia\n"; if (d.Descripcion == "") ret += "La descripcion no puede estar vacia\n";
if (d.Idcontrato<=0)ret += "No puede haber un id de contrato igual o menor a 0\n"; if (d.Idcontrato <= 0) ret += "No puede haber un id de contrato igual o menor a 0\n";
return ret; return ret;
} }
[HttpPut("api/defecto/marcarpago")] [HttpPut("api/defecto/marcarpago")]
public IActionResult MarcarPago([FromHeader(Name = "Auth")] string Auth, long iddefecto = 0) { public IActionResult MarcarPago([FromHeader(Name = "Auth")] string Auth, long iddefecto = 0)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli==null) return Unauthorized(); if (cli == null) return Unauthorized();
if (iddefecto<=0) return BadRequest(new { message = "No hay canones con id 0 o menor"}); if (iddefecto <= 0) return BadRequest(new { message = "No hay canones con id 0 o menor" });
bool ret = RepositorioDefectos.Singleton.MarcarPago(iddefecto, cli.Dni); bool ret = RepositorioDefectos.Singleton.MarcarPago(iddefecto, cli.Dni);
return ret ? return ret ?
Ok(new { message = "Se marco como pagado" }):BadRequest(new { message = "Fallo el acceso a la base de datos o no se encontro el defecto" }); Ok(new { message = "Se marco como pagado" }) : BadRequest(new { message = "Fallo el acceso a la base de datos o no se encontro el defecto" });
} }
} }
+40 -18
View File
@@ -5,44 +5,64 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class EstadisticaController: ControllerBase { public class EstadisticaController : ControllerBase
[HttpGet("api/stats/alquileresIniciados")] {
public IActionResult alquileresIniciadosEsteAño([FromHeader(Name ="Auth")]string Auth, int year) { [HttpGet("/api/stats/Pagos")]
public IActionResult EstadisticasPagos([FromHeader(Name ="Auth")] string Auth, int year){
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6);
if (validacion1 == false) return Unauthorized();
ChartData stats;
List<InformePagos> tabla;
(stats, tabla) = RepositorioEstadisticas.Singleton.InformePagos(year);
return Ok(new { chart = stats, tabla = tabla});
}
[HttpGet("api/stats/alquileresIniciados")]
public IActionResult alquileresIniciadosEsteAño([FromHeader(Name = "Auth")] string Auth, int year)
{
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year);
if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año"}); if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año" });
var a = RepositorioEstadisticas.Singleton.ObtenerDataIniciadosPorAño(year); var a = RepositorioEstadisticas.Singleton.ObtenerDataIniciadosPorAño(year);
return Ok(a); return Ok(a);
} }
[HttpGet("api/contrato/stats")] [HttpGet("api/contrato/stats")]
public IActionResult ObtenerMesesPagos([FromHeader(Name ="Auth")]string Auth, long idcontrato=0){ public IActionResult ObtenerMesesPagos([FromHeader(Name = "Auth")] string Auth, long idcontrato = 0)
{
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (idcontrato<=0) return BadRequest(new {message = "No puede tener un id contrato menor o igual a 0"}); if (idcontrato <= 0) return BadRequest(new { message = "No puede tener un id contrato menor o igual a 0" });
var ret = RepositorioEstadisticas.Singleton.ObtenerDatosPagosContrato(idcontrato); var ret = RepositorioEstadisticas.Singleton.ObtenerDatosPagosContrato(idcontrato);
return Ok(ret); return Ok(ret);
} }
[HttpGet("api/tabla/alquileresIniciados")] [HttpGet("api/tabla/alquileresIniciados")]
public IActionResult tablaalquileresIniciadosEsteAño([FromHeader(Name ="Auth")]string Auth, int year) { public IActionResult tablaalquileresIniciadosEsteAño([FromHeader(Name = "Auth")] string Auth, int year)
{
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year);
if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año"}); if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año" });
var a = RepositorioEstadisticas.Singleton.TablaObtenerContratosIniciadosPorAño(year); var a = RepositorioEstadisticas.Singleton.TablaObtenerContratosIniciadosPorAño(year);
if (a == null) return BadRequest(new { message = "Fallo al obtener el contrato"}); if (a == null) return BadRequest(new { message = "Fallo al obtener el contrato" });
List<InformesAlquiler> informe =new(); List<InformesAlquiler> informe = new();
foreach (var i in a) { foreach (var i in a)
{
var d = new InformesAlquilerBuilder() var d = new InformesAlquilerBuilder()
.SetId(i.Id).SetUbicacion(i.IdpropiedadNavigation.Ubicacion) .SetId(i.Id).SetUbicacion(i.IdpropiedadNavigation.Ubicacion)
.SetDivisa(i.IddivisaNavigation.Signo) .SetDivisa(i.IddivisaNavigation.Signo)
@@ -52,9 +72,10 @@ public class EstadisticaController: ControllerBase {
return Ok(informe); return Ok(informe);
} }
[HttpGet("api/stats/duracionContrato")] [HttpGet("api/stats/duracionContrato")]
public IActionResult DuracionContrato([FromHeader(Name ="Auth")]string Auth) { public IActionResult DuracionContrato([FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
var a = RepositorioEstadisticas.Singleton.ObtenerDataDuracionContratos(); var a = RepositorioEstadisticas.Singleton.ObtenerDataDuracionContratos();
@@ -62,9 +83,10 @@ public class EstadisticaController: ControllerBase {
} }
[HttpGet("api/tabla/duracionContrato")] [HttpGet("api/tabla/duracionContrato")]
public IActionResult TablaDuracionContrato([FromHeader(Name ="Auth")]string Auth) { public IActionResult TablaDuracionContrato([FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); if (String.IsNullOrWhiteSpace(Auth)) return BadRequest("");
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 6);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
var a = RepositorioEstadisticas.Singleton.TablaObtenerDataDuracionContratos(); var a = RepositorioEstadisticas.Singleton.TablaObtenerDataDuracionContratos();
+86
View File
@@ -0,0 +1,86 @@
using Microsoft.AspNetCore.Mvc;
using Modelo;
using AlquilaFacil.Builder;
using Entidades;
using Entidades.Dto;
namespace AlquilaFacil.Controllers;
[ApiController]
public class GruposController : ControllerBase
{
[HttpGet("api/admin/grupos")]
public IActionResult ObtenerGrupos([FromHeader(Name = "Auth")] string Auth)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18) ||
RepositorioPermisos.Singleton.CheckPermisos(Auth, 9) ||
RepositorioPermisos.Singleton.CheckPermisos(Auth, 19);
if (ret == false) return BadRequest(new { message = "No tiene permiso para ver todos los grupos" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
var grupos = RepositorioGrupos.Singleton.ListarTodosLosGrupos()
.Select(g => new GrupoDtoBuilder()
.ConNombre(g.Nombre)
.ConIdGrupo(g.Id)
.ConHabilitado(g.Habilitado ?? false)
.ConGruposIncluidos(new HashSet<string>(g.IdGrupoHijos
.Select(id => id.Nombre ?? "")))
.ConPermisos(g.Idpermisos.Select(p => new PermisoDtoBuilder()
.ConId(p.Id)
.ConDescripcion(p.Descripcion)
.Build())
.ToList())
.Build())
.ToList();
return Ok(grupos);
}
[HttpPatch("/api/grupo")]
public IActionResult PatchGrupo([FromHeader(Name = "Auth")] string Auth, GrupoDto grupo)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18);
if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
bool ret2 = RepositorioGrupos.Singleton.PatchGrupo(grupo, cli);
return ret2 ? Ok(new { message = "Se Modifico el grupo" }) : BadRequest(new { message = "Fallo al editar el grupo" });
}
[HttpPost("/api/grupo")]
public IActionResult PostGrupo([FromHeader(Name = "Auth")] string Auth, GrupoDto grupo)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18);
if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
if (grupo.Nombre.Length > 12)
{
return BadRequest(new { message = "El nombre del grupo no puede superar los 12 caracteres" });
}
bool ret2 = RepositorioGrupos.Singleton.AddGrupo(grupo, cli);
return ret2 ? Ok(new { message = "Se Añadio el grupo" }) : BadRequest(new { message = "Fallo al añadirse el grupo" });
}
[HttpDelete("/api/grupo")]
public IActionResult DeleteGrupo([FromHeader(Name = "Auth")] string Auth, [FromQuery] int id)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18);
if (ret == false) return BadRequest(new { message = "No tiene permiso para Gestionar grupos" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
if (id <= 0) return BadRequest(new { message = "El ID del grupo debe ser mayor que cero" });
var (ret2, estado) = RepositorioGrupos.Singleton.ToggleGrupo(id, cli);
return ret2
? Ok(new { message = (estado ? "Grupo habilitado exitosamente" : "Grupo deshabilitado exitosamente") })
: BadRequest(new { message = "No se pudo cambiar el estado del grupo" });
}
}
+17 -11
View File
@@ -9,11 +9,12 @@ using System.Security.Cryptography;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class InquilinoController: ControllerBase public class InquilinoController : ControllerBase
{ {
[HttpGet("api/inquilino")] [HttpGet("api/inquilino")]
public IActionResult Get([FromHeader(Name = "Auth")] string Auth) { public IActionResult Get([FromHeader(Name = "Auth")] string Auth)
{
if (!string.IsNullOrEmpty(Auth)) return BadRequest(); if (!string.IsNullOrEmpty(Auth)) return BadRequest();
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9); var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9);
@@ -25,18 +26,20 @@ public class InquilinoController: ControllerBase
} }
[HttpPost("api/inquilino")] [HttpPost("api/inquilino")]
public IActionResult Post([FromBody] CrearClienteDto cid, [FromHeader(Name = "Auth")] string Auth) { public IActionResult Post([FromBody] CrearClienteDto cid, [FromHeader(Name = "Auth")] string Auth)
if (string.IsNullOrEmpty(Auth)) return BadRequest(new {message = "El String Auth Esta Vacio"}); {
if (string.IsNullOrEmpty(Auth)) return BadRequest(new { message = "El String Auth Esta Vacio" });
var ret3 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 4); var ret3 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 4);
if (ret3 == false) return BadRequest(new {message = "Falló el permiso"}); if (ret3 == false) return BadRequest(new { message = "Falló el permiso" });
Cliente? rep = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? rep = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (rep == null) return Unauthorized(); if (rep == null) return Unauthorized();
var ret = verificarCrearUsuario(cid); var ret = verificarCrearUsuario(cid);
if (ret != "") return BadRequest(new {message = ret}); if (ret != "") return BadRequest(new { message = ret });
var cli = new Cliente { var cli = new Cliente
{
Dni = cid.dni, Dni = cid.dni,
Nombre = cid.nombre, Nombre = cid.nombre,
Domicilio = cid.domicilio, Domicilio = cid.domicilio,
@@ -45,13 +48,15 @@ public class InquilinoController: ControllerBase
Email = cid.email, Email = cid.email,
Contraseña = Encoding.UTF8.GetBytes(HacerHash(cid.contraseña)), Contraseña = Encoding.UTF8.GetBytes(HacerHash(cid.contraseña)),
Habilitado = 1, Habilitado = 1,
EmailRecuperacion = cid.email,
}; };
bool ret2 = RepositorioUsuarios.Singleton.AltaInquilino(cli, rep.Dni); bool ret2 = RepositorioUsuarios.Singleton.AltaInquilino(cli, rep.Dni);
return (ret2) ? Ok(new {message = "Se dio de alta la cuenta"}) : BadRequest(new {message = "Fallo Dar de Alta El inquilino"}); return (ret2) ? Ok(new { message = "Se dio de alta la cuenta" }) : BadRequest(new { message = "Fallo Dar de Alta El inquilino" });
} }
private string verificarCrearUsuario(CrearClienteDto cid) { private string verificarCrearUsuario(CrearClienteDto cid)
{
string msg = ""; string msg = "";
if (cid.email == string.Empty) msg += "Falta ingresar el email\n"; if (cid.email == string.Empty) msg += "Falta ingresar el email\n";
@@ -65,8 +70,9 @@ public class InquilinoController: ControllerBase
return msg; return msg;
} }
private string HacerHash(string pass){ private string HacerHash(string pass)
{
var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass)); var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass));
return BitConverter.ToString(buf).Replace("-",""); return BitConverter.ToString(buf).Replace("-", "");
} }
} }
+21 -1
View File
@@ -19,7 +19,7 @@ public class LoginController: ControllerBase
if (!usuario) return Unauthorized(new {message = "El usuario no existe o la contraseña es incorrecta"}); if (!usuario) return Unauthorized(new {message = "El usuario no existe o la contraseña es incorrecta"});
string tokenString = GenerarToken(loginDto); string tokenString = GenerarToken(loginDto);
RepositorioUsuarios.Singleton.GuardarToken(loginDto, tokenString); RepositorioUsuarios.Singleton.GuardarToken(loginDto, tokenString, Request.HttpContext.Connection.RemoteIpAddress);
var cookieOptions = new CookieOptions var cookieOptions = new CookieOptions
{ {
@@ -53,6 +53,26 @@ public class LoginController: ControllerBase
} }
[HttpDelete("/api/logout")]
public IActionResult CerrarSesion([FromHeader(Name = "Auth")]string Auth){
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null ) return BadRequest(new { message = "No hay un cliente con ese token" });
var log = new LoginDto {
Email = cli.Email,
Contraseña = "",
};
string tokenString = GenerarToken(log);
try{
RepositorioUsuarios.Singleton.GuardarToken(log, tokenString, Request.HttpContext.Connection.RemoteIpAddress, "Cerrar Sesión");
} catch {
return BadRequest( new { message = "Fallo al cambiar el token" } );
}
return Ok(new { message = "Se Cerro la sesion" });
}
private string GenerarToken(LoginDto loginDto){ private string GenerarToken(LoginDto loginDto){
var tokenHandler = new JwtSecurityTokenHandler(); var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("ffb2cdc15d472e41a5b626e294c45020"); var key = Encoding.ASCII.GetBytes("ffb2cdc15d472e41a5b626e294c45020");
+22 -14
View File
@@ -5,21 +5,25 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class LogsController: ControllerBase { public class LogsController : ControllerBase
{
[HttpGet("/api/Logs")] [HttpGet("/api/Logs")]
public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, int pag=1) { public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, int pag = 1)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 7);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (pag<=0) return BadRequest(new { message = "no puede haber una pagina 0 o menor"}); if (pag <= 0) return BadRequest(new { message = "no puede haber una pagina 0 o menor" });
pag-=1; pag -= 1;
var l = RepositorioLogs.Singleton.ObtenerLogsPaginado(pag); var l = RepositorioLogs.Singleton.ObtenerLogsPaginado(pag);
List<LogDto> ll = new(); List<LogDto> ll = new();
foreach (var i in l) { foreach (var i in l)
ll.Add(new LogDto{ {
ll.Add(new LogDto
{
Fecha = i.Fecha, Fecha = i.Fecha,
Accion = i.Accion, Accion = i.Accion,
Dniusuario = i.Dniusuario, Dniusuario = i.Dniusuario,
@@ -29,16 +33,19 @@ public class LogsController: ControllerBase {
} }
[HttpGet("/api/Logs/detalle")] [HttpGet("/api/Logs/detalle")]
public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, [FromQuery]DateTime fecha, [FromQuery]long idusuario) { public IActionResult ObtenerLogs([FromHeader(Name = "Auth")] string Auth, [FromQuery] DateTime fecha, [FromQuery] long idusuario)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 7);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (idusuario<=0) return BadRequest(new { message = "no puede haber un id 0 o menor"}); if (idusuario <= 0) return BadRequest(new { message = "no puede haber un id 0 o menor" });
var l = RepositorioLogs.Singleton.ObtenerDetallesLogs(fecha, idusuario); var l = RepositorioLogs.Singleton.ObtenerDetallesLogs(fecha, idusuario);
List<LogDetalleDto> ll = new(); List<LogDetalleDto> ll = new();
foreach (var i in l) { foreach (var i in l)
ll.Add(new LogDetalleDto{ {
ll.Add(new LogDetalleDto
{
Fecha = i.Fecha, Fecha = i.Fecha,
Dniusuario = i.Dniusuario, Dniusuario = i.Dniusuario,
NombreTabla = i.NombreTabla, NombreTabla = i.NombreTabla,
@@ -51,9 +58,10 @@ public class LogsController: ControllerBase {
} }
[HttpGet("/api/Logs/cantPag")] [HttpGet("/api/Logs/cantPag")]
public IActionResult cantidadPaginas([FromHeader(Name = "Auth")] string Auth){ public IActionResult cantidadPaginas([FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 7);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
int c = RepositorioLogs.Singleton.ObtenerCantidadPaginas(); int c = RepositorioLogs.Singleton.ObtenerCantidadPaginas();
+58 -50
View File
@@ -7,28 +7,31 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class NotificacionesController: ControllerBase { public class NotificacionesController : ControllerBase
{
[HttpGet("api/notificaciones")] [HttpGet("api/notificaciones")]
public IActionResult GetNotificaciones([FromHeader(Name ="Auth")]string Auth, bool leido = false) { public IActionResult GetNotificaciones([FromHeader(Name = "Auth")] string Auth, bool leido = false)
{
if (string.IsNullOrEmpty(Auth)) return Unauthorized(); if (string.IsNullOrEmpty(Auth)) return Unauthorized();
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new {message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)"}); if (cli == null) return BadRequest(new { message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)" });
IQueryable<Notificacione> notificaciones = RepositorioNotificaciones.Singleton.ObtenerNotificacionesDeUsuario(cli.Dni) IQueryable<Notificacione> notificaciones = RepositorioNotificaciones.Singleton.ObtenerNotificacionesDeUsuario(cli.Dni)
.Where(x=>x.Leido == leido); .Where(x => x.Leido == leido);
List<NotificacionDto> noti = new(); List<NotificacionDto> noti = new();
foreach (Notificacione i in notificaciones) { foreach (Notificacione i in notificaciones)
if(i.DniclienteNavigation == null || i.DniremitenteNavigation==null) return BadRequest(new { message = "Esta mal cargado el precontrato"}); {
if (i.DniclienteNavigation == null || i.DniremitenteNavigation == null) return BadRequest(new { message = "Esta mal cargado el precontrato" });
var dto = new NotificacionDtoBuilder() var dto = new NotificacionDtoBuilder()
.SetRemitente(i.DniremitenteNavigation.Email??"") .SetRemitente(i.DniremitenteNavigation.Email ?? "")
.SetAccion(i.Accion??"") .SetAccion(i.Accion ?? "")
.SetMensaje(i.Mensaje??"") .SetMensaje(i.Mensaje ?? "")
.SetFecha(i.Fecha) .SetFecha(i.Fecha)
.SetPropiedad(i.Idpropiedad.ToString()??"") .SetPropiedad(i.Idpropiedad.ToString() ?? "")
.SetReceptor(i.DniclienteNavigation.Email??"") .SetReceptor(i.DniclienteNavigation.Email ?? "")
.Build(); .Build();
noti.Add(dto); noti.Add(dto);
@@ -38,48 +41,51 @@ public class NotificacionesController: ControllerBase {
} }
[HttpGet("api/notificaciones/haySinLeer")] [HttpGet("api/notificaciones/haySinLeer")]
public IActionResult GetHayNotis([FromHeader(Name ="Auth")]string Auth) { public IActionResult GetHayNotis([FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new {message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)"}); if (cli == null) return BadRequest(new { message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)" });
bool ret = RepositorioNotificaciones.Singleton.HayNotis(cli.Dni); bool ret = RepositorioNotificaciones.Singleton.HayNotis(cli.Dni);
return Ok(new {message = ret}); return Ok(new { message = ret });
} }
[HttpPut("api/notificaciones")] [HttpPut("api/notificaciones")]
public IActionResult MarcarComoLeido([FromHeader(Name = "Auth")]string Auth, NotificacionMarcarLeidoDto nota) { public IActionResult MarcarComoLeido([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto nota)
{
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
if (nota.Fecha == null || String.IsNullOrWhiteSpace(nota.Email)) return BadRequest(new {message = "Faltan datos"}); if (nota.Fecha == null || String.IsNullOrWhiteSpace(nota.Email)) return BadRequest(new { message = "Faltan datos" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new {message = "El token de autorizacion no pertenese a ningun Usuario"}); if (cli == null) return BadRequest(new { message = "El token de autorizacion no pertenese a ningun Usuario" });
if (cli.Email != nota.Email) return BadRequest(new {message = "El token de autorizacion no corresponde a tu usuario"}); if (cli.Email != nota.Email) return BadRequest(new { message = "El token de autorizacion no corresponde a tu usuario" });
bool ret = RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, nota.Fecha); bool ret = RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, nota.Fecha);
return ret ? return ret ?
Ok(new{message = "Se Marco como leido"}):BadRequest(new{message = "Fallo al marcarse como leido"}); Ok(new { message = "Se Marco como leido" }) : BadRequest(new { message = "Fallo al marcarse como leido" });
} }
[HttpPost("api/notificaciones/consultaAlquiler")] [HttpPost("api/notificaciones/consultaAlquiler")]
public IActionResult ConsultaAlquiler([FromHeader(Name ="Auth")]string Auth, [FromBody] AltaNotificacionDto data) { public IActionResult ConsultaAlquiler([FromHeader(Name = "Auth")] string Auth, [FromBody] AltaNotificacionDto data)
{
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
bool validacion1 = RepositorioUsuarios.Singleton.CheckToken(data.Remitente, Auth); bool validacion1 = RepositorioUsuarios.Singleton.CheckToken(data.Remitente, Auth);
if (validacion1 == false) return BadRequest(new {message = "el token no corresponde a su usuario"}); if (validacion1 == false) return BadRequest(new { message = "el token no corresponde a su usuario" });
if (data.Accion == "") return BadRequest(new{message = "El campo Accion esta vacio"}); if (data.Accion == "") return BadRequest(new { message = "El campo Accion esta vacio" });
if (data.Mensaje == "") return BadRequest(new {message = "El campo Mensaje esta vacio"}); if (data.Mensaje == "") return BadRequest(new { message = "El campo Mensaje esta vacio" });
Cliente? inq = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); 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)" }); 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); 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 == null || prop.Idestado != 1) return BadRequest(new { message = "No hay una propiedad dada de alta para ese id" });
if (prop.DnipropietarioNavigation == null) return BadRequest(new{message="la propiedad no tiene propietario dado de alto ????"}); if (prop.DnipropietarioNavigation == null) return BadRequest(new { message = "la propiedad no tiene propietario dado de alto ????" });
var noti = new NotificacioneBuilder() var noti = new NotificacioneBuilder()
.SetAccion(data.Accion) .SetAccion(data.Accion)
@@ -92,21 +98,22 @@ public class NotificacionesController: ControllerBase {
.Build(); .Build();
var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti);
return ret? return ret ?
Ok(new {message = "Se envio la notificacion"}):BadRequest(new {message = "Fallo al intentar guardar la notificacion"}); Ok(new { message = "Se envio la notificacion" }) : BadRequest(new { message = "Fallo al intentar guardar la notificacion" });
} }
[HttpPost("api/notificarInquilino")] [HttpPost("api/notificarInquilino")]
public IActionResult NotificarInq([FromHeader(Name ="Auth")]string Auth, [FromBody] AvisoInquilinoDto data) { public IActionResult NotificarInq([FromHeader(Name = "Auth")] string Auth, [FromBody] AvisoInquilinoDto data)
{
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12);
if (validacion1 == false)return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (data.Mensaje == "") return BadRequest(new {message = "El campo Mensaje esta vacio"}); if (data.Mensaje == "") return BadRequest(new { message = "El campo Mensaje esta vacio" });
if (data.Idpropiedad <= 0) return BadRequest(new {message = "La id de propiedad no puede ser 0 o menor"}); if (data.Idpropiedad <= 0) return BadRequest(new { message = "La id de propiedad no puede ser 0 o menor" });
Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(data.Idpropiedad); Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(data.Idpropiedad);
if (cont == null || cont.DniinquilinoNavigation == null || cont.DnipropietarioNavigation == null || cont.IdpropiedadNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id"}); if (cont == null || cont.DniinquilinoNavigation == null || cont.DnipropietarioNavigation == null || cont.IdpropiedadNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id" });
var n = new NotificacioneBuilder() var n = new NotificacioneBuilder()
.SetAccion("Notificacion Inquilino") .SetAccion("Notificacion Inquilino")
@@ -118,41 +125,42 @@ public class NotificacionesController: ControllerBase {
.SetFecha(DateTime.Now) .SetFecha(DateTime.Now)
.Build(); .Build();
var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(n); var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(n);
return ret? return ret ?
Ok(new { message = "se envio el aviso" }):BadRequest(new { message = "Fallo al intentar enviar el aviso" }); Ok(new { message = "se envio el aviso" }) : BadRequest(new { message = "Fallo al intentar enviar el aviso" });
} }
[HttpPost("api/notificar/ConsultaCompra")] [HttpPost("api/notificar/ConsultaCompra")]
public IActionResult EnviarConsultaCompra([FromHeader(Name ="Auth")]string Auth, AltaNotificacionDto dto) { public IActionResult EnviarConsultaCompra([FromHeader(Name = "Auth")] string Auth, AltaNotificacionDto dto)
{
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 16);
if (validacion1 == false){ if (validacion1 == false)
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); {
if (validacion1 == false) {
return Unauthorized(); return Unauthorized();
}
} }
if (dto.Accion == "") return BadRequest(new{message = "El campo Accion esta vacio"}); if (dto.Accion == "") return BadRequest(new { message = "El campo Accion esta vacio" });
if (dto.Mensaje == "") return BadRequest(new {message = "El campo Mensaje esta vacio"}); if (dto.Mensaje == "") return BadRequest(new { message = "El campo Mensaje esta vacio" });
Cliente?cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.Propiedad); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.Propiedad);
if (prop == null) return BadRequest(new { message = "No hay una propiedad con id 0 o menor"}); if (prop == null) return BadRequest(new { message = "No hay una propiedad con id 0 o menor" });
var n = new NotificacioneBuilder() var n = new NotificacioneBuilder()
.SetAccion("Consulta Compra") .SetAccion("Consulta Compra")
.SetMensaje(dto.Mensaje) .SetMensaje(dto.Mensaje)
.SetLeido(false) .SetLeido(false)
.SetDnicliente(prop.Dnipropietario??0) .SetDnicliente(prop.Dnipropietario ?? 0)
.SetDniremitente(cli.Dni) .SetDniremitente(cli.Dni)
.SetIdpropiedad(prop.Id) .SetIdpropiedad(prop.Id)
.SetFecha(DateTime.Now) .SetFecha(DateTime.Now)
.Build(); .Build();
var ret2= RepositorioNotificaciones.Singleton.AltaNotificacion(n, cli.Dni); var ret2 = RepositorioNotificaciones.Singleton.AltaNotificacion(n, cli.Dni);
return ret2? return ret2 ?
Ok(new { message = "se envio el aviso" }):BadRequest(new { message = "Fallo al intentar enviar el aviso" }); Ok(new { message = "se envio el aviso" }) : BadRequest(new { message = "Fallo al intentar enviar el aviso" });
} }
} }
+61
View File
@@ -0,0 +1,61 @@
using Microsoft.AspNetCore.Mvc;
using Modelo;
using Entidades;
using Entidades.Dto;
using AlquilaFacil.Builder;
namespace AlquilaFacil.Controllers;
[ApiController]
public class PermisoController : ControllerBase
{
[HttpPost("api/permisos")]
public IActionResult CrearPermiso([FromHeader(Name = "Auth")] string Auth, PermisoDto perm)
{
var ret1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 17);
if (ret1 == false) return BadRequest(new { message = "No tienes permiso para esto" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
if (String.IsNullOrWhiteSpace(perm.Descripcion)) return BadRequest(new { message = "No puede tener una descripcion vacia" });
if (perm.Descripcion.Length > 25) return BadRequest(new { message = "la descripcion no puede tener más de 25 caractéres" });
var permiso = new PermisoBuilder().SetDescripcion(perm.Descripcion).Build();
var ret = RepositorioPermisos.Singleton.CrearPermiso(permiso, cli);
return ret ? Ok() : BadRequest();
}
[HttpPatch("api/permisos")]
public IActionResult PatchPermiso([FromHeader(Name = "Auth")] string Auth, PermisoDto perm)
{
var ret1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 17);
if (ret1 == false) return BadRequest(new { message = "No tienes permiso para esto" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un cliente por el token que enviaste" });
if (perm.Id <= 0) return BadRequest(new { message = "No puede haber una id 0 o menor" });
if (String.IsNullOrWhiteSpace(perm.Descripcion)) return BadRequest(new { message = "No puede tener una descripcion vacia" });
if (perm.Descripcion.Length > 25) return BadRequest(new { message = "la descripcion no puede tener más de 25 caractéres" });
var permiso = new PermisoBuilder().SetDescripcion(perm.Descripcion).SetID(perm.Id).Build();
var ret = RepositorioPermisos.Singleton.PatchPermiso(permiso, cli);
return ret ? Ok() : BadRequest();
}
[HttpGet("/api/permisos/todos")]
public IActionResult ObtenerTodosLosPermisos([FromHeader(Name = "Auth")] string Auth)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 18);
if (ret == false) return BadRequest(new { message = "No tiene permiso para ver Todos los permisos" });
var permisos = RepositorioPermisos.Singleton.ListarPermisos();
var perms = permisos.Select(permiso => new PermisoDtoBuilder()
.ConId(permiso.Id)
.ConDescripcion(permiso.Descripcion)
.Build());
return Ok(perms);
}
}
+108 -76
View File
@@ -6,9 +6,11 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class PropiedadesController: ControllerBase { public class PropiedadesController : ControllerBase
{
[HttpGet("api/propiedades")] [HttpGet("api/propiedades")]
public IActionResult ListarPropiedades([FromHeader(Name = "Auth")] string Auth, int pag = 0) { public IActionResult ListarPropiedades([FromHeader(Name = "Auth")] string Auth, int pag = 0)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10);
if (validacion1 == false) validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); if (validacion1 == false) validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
@@ -16,9 +18,12 @@ public class PropiedadesController: ControllerBase {
IQueryable<PropiedadesDto> ret; IQueryable<PropiedadesDto> ret;
if (pag == 0){ if (pag == 0)
{
ret = RepositorioPropiedades.Singleton.ListarPropiedades(); ret = RepositorioPropiedades.Singleton.ListarPropiedades();
} else{ }
else
{
ret = RepositorioPropiedades.Singleton.ListarPropiedadesPorPagina(pag); ret = RepositorioPropiedades.Singleton.ListarPropiedadesPorPagina(pag);
} }
@@ -26,31 +31,35 @@ public class PropiedadesController: ControllerBase {
} }
[HttpGet("/api/propiedades/Venta")] [HttpGet("/api/propiedades/Venta")]
public IActionResult ObtenerPropiedadesParaVenta([FromHeader(Name = "Auth")] string Auth, int pag = 0) { public IActionResult ObtenerPropiedadesParaVenta([FromHeader(Name = "Auth")] string Auth, int pag = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 16);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
if (pag<=0) return BadRequest(new { message = "no existe una pagina 0"}); if (pag <= 0) return BadRequest(new { message = "no existe una pagina 0" });
pag-=1; pag -= 1;
var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesEnVenta(pag); var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesEnVenta(pag);
if (props == null) return BadRequest(new { message = "no tengo claro que fallo creo que no existen propiedades en venta"}); if (props == null) return BadRequest(new { message = "no tengo claro que fallo creo que no existen propiedades en venta" });
List<PropiedadesVentaDto> l = new(); List<PropiedadesVentaDto> l = new();
foreach (var i in props) { foreach (var i in props)
var p = new PropiedadesVentaDto{ {
var p = new PropiedadesVentaDto
{
Id = i.Id, Id = i.Id,
Ubicacion = i.Ubicacion, Ubicacion = i.Ubicacion,
Canthabitaciones = i.Canthabitaciones, Canthabitaciones = i.Canthabitaciones,
Divisa = i.IddivisaNavigation.Signo, Divisa = i.IddivisaNavigation.Signo,
Letra = i.Letra??"", Letra = i.Letra ?? "",
Monto = i.Monto, Monto = i.Monto,
Piso = i.Piso??0, Piso = i.Piso ?? 0,
Servicios =string.Join(", ", i.IdServicios.Select(s => s.Descripcion)), Servicios = string.Join(", ", i.IdServicios.Select(s => s.Descripcion)),
Tipo = i.IdtipropiedadNavigation.Descripcion, Tipo = i.IdtipropiedadNavigation.Descripcion,
}; };
l.Add(p); l.Add(p);
@@ -58,31 +67,35 @@ public class PropiedadesController: ControllerBase {
int cantpag = RepositorioPropiedades.Singleton.ObtenerPaginasDePropiedadesEnVenta(); int cantpag = RepositorioPropiedades.Singleton.ObtenerPaginasDePropiedadesEnVenta();
return Ok(new { propiedades = l, cantpaginas = cantpag}); return Ok(new { propiedades = l, cantpaginas = cantpag });
} }
[HttpGet("api/propiedades/Venta/Propietario")] [HttpGet("api/propiedades/Venta/Propietario")]
public IActionResult ObtenerPropiedadesVentaDePropietario( [FromHeader(Name = "Auth")] string Auth){ public IActionResult ObtenerPropiedadesVentaDePropietario([FromHeader(Name = "Auth")] string Auth)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesAVentaPorDni(cli.Dni); var props = RepositorioPropiedades.Singleton.ObtenerPropiedadesAVentaPorDni(cli.Dni);
List<PropiedadesDto> ll = new(); List<PropiedadesDto> ll = new();
foreach (var i in props) { foreach (var i in props)
var a = new PropiedadesDto { {
var a = new PropiedadesDto
{
id = i.Id, id = i.Id,
Ubicacion = i.Ubicacion, Ubicacion = i.Ubicacion,
canthabitaciones = i.Canthabitaciones, canthabitaciones = i.Canthabitaciones,
Iddivisa = i.Iddivisa, Iddivisa = i.Iddivisa,
letra = i.Letra??"", letra = i.Letra ?? "",
Monto = (int)i.Monto, //mmmm Monto = (int)i.Monto, //mmmm
piso = i.Piso??0, piso = i.Piso ?? 0,
Servicios = string.Join(", ", i.IdServicios.Select(x => x.Descripcion)), Servicios = string.Join(", ", i.IdServicios.Select(x => x.Descripcion)),
Tipo = i.IdtipropiedadNavigation.Descripcion, Tipo = i.IdtipropiedadNavigation.Descripcion,
}; };
@@ -92,71 +105,79 @@ public class PropiedadesController: ControllerBase {
} }
[HttpGet("api/propiedad")] [HttpGet("api/propiedad")]
public IActionResult ObtenerPropiedadPorId(int Id, [FromHeader(Name = "Auth")] string Auth) { public IActionResult ObtenerPropiedadPorId(int Id, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (Id < 0) return BadRequest(new {message ="la id de propiedad no puede ser negativa"}); if (Id < 0) return BadRequest(new { message = "la id de propiedad no puede ser negativa" });
var ret = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(Id); var ret = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(Id);
if (ret == null) return BadRequest(new {message ="No existe la propiedad"}); if (ret == null) return BadRequest(new { message = "No existe la propiedad" });
return Ok(ret); return Ok(ret);
} }
[HttpGet("api/propiedad/cantPagina")] [HttpGet("api/propiedad/cantPagina")]
public IActionResult ObtenerCantidadDePaginas([FromHeader(Name = "Auth")] string Auth, int estado = 0) { public IActionResult ObtenerCantidadDePaginas([FromHeader(Name = "Auth")] string Auth, int estado = 0)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 10);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (estado < 0) return BadRequest(new {message = "No puede tener un numero menor a 0"}); if (estado < 0) return BadRequest(new { message = "No puede tener un numero menor a 0" });
int cant; int cant;
if(estado == 0){ if (estado == 0)
{
cant = RepositorioPropiedades.Singleton.CuantasPaginas(); cant = RepositorioPropiedades.Singleton.CuantasPaginas();
}else{ }
else
{
cant = RepositorioPropiedades.Singleton.CuantasPaginas(estado); cant = RepositorioPropiedades.Singleton.CuantasPaginas(estado);
} }
return Ok(new {message = cant}); return Ok(new { message = cant });
} }
[HttpGet("api/propiedades/Propietario")] [HttpGet("api/propiedades/Propietario")]
public IActionResult ObtenerPropiedadesPorPropietario ( public IActionResult ObtenerPropiedadesPorPropietario(
[FromHeader(Name = "Email")] string email, [FromHeader(Name = "Email")] string email,
[FromHeader(Name = "Auth")] string Auth) { [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
email = email.Trim(); email = email.Trim();
if (String.IsNullOrEmpty(email)) return BadRequest(new {message ="falta campo email"}); if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "falta campo email" });
IQueryable<PropiedadesDto> ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesPorEmail(email); IQueryable<PropiedadesDto> ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesPorEmail(email);
return Ok(ret); return Ok(ret);
} }
[HttpGet("api/propiedades/Propietario/Bajas")] [HttpGet("api/propiedades/Propietario/Bajas")]
public IActionResult ObtenerPropiedadesPorPropietarioBajas ( public IActionResult ObtenerPropiedadesPorPropietarioBajas(
[FromHeader(Name = "Email")] string email, [FromHeader(Name = "Email")] string email,
[FromHeader(Name = "Auth")] string Auth) { [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 8); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 8);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
email = email.Trim(); email = email.Trim();
if (String.IsNullOrEmpty(email)) return BadRequest(new {message ="falta campo email"}); if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "falta campo email" });
IQueryable<PropiedadesDto> ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesDeBajaPorEmail(email); IQueryable<PropiedadesDto> ret = RepositorioPropiedades.Singleton.ObtenerPropiedadesDeBajaPorEmail(email);
return Ok(ret); return Ok(ret);
} }
[HttpPost("api/propiedad")] [HttpPost("api/propiedad")]
public IActionResult AltaPropiedad([FromBody] AltaPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) { public IActionResult AltaPropiedad([FromBody] AltaPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 1);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
@@ -165,9 +186,10 @@ public class PropiedadesController: ControllerBase {
if (validacion2 != "") return BadRequest(new { message = validacion2 }); if (validacion2 != "") return BadRequest(new { message = validacion2 });
Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email); Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email);
if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario"}); if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario" });
Propiedade Prop = new Propiedade{ Propiedade Prop = new Propiedade
{
Canthabitaciones = propiedad.Canthabitaciones, Canthabitaciones = propiedad.Canthabitaciones,
Dnipropietario = cli.Dni, Dnipropietario = cli.Dni,
Idtipropiedad = propiedad.Idtipropiedad, Idtipropiedad = propiedad.Idtipropiedad,
@@ -178,14 +200,18 @@ public class PropiedadesController: ControllerBase {
Iddivisa = propiedad.Iddivisa, Iddivisa = propiedad.Iddivisa,
}; };
var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop); Cliente? responsable = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
return (ret)? if (cli == null) return Unauthorized();
Ok(new { message = "Fue Cargado Correctamente"}) :
BadRequest(new { message = "Fallo al momento de añadir la propiedad a la base de datos"}); var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop, responsable.Dni);
return (ret) ?
Ok(new { message = "Fue Cargado Correctamente" }) :
BadRequest(new { message = "Fallo al momento de añadir la propiedad a la base de datos" });
} }
[HttpPatch("api/propiedad")] [HttpPatch("api/propiedad")]
public IActionResult PatchPropiedad([FromBody] PatchPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth) { public IActionResult PatchPropiedad([FromBody] PatchPropiedadDto propiedad, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
@@ -195,11 +221,12 @@ public class PropiedadesController: ControllerBase {
if (validacion2 != "") return BadRequest(new { message = validacion2 }); if (validacion2 != "") return BadRequest(new { message = validacion2 });
Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email); Cliente? cli = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(propiedad.Email);
if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario"}); if (cli == null) return BadRequest(new { message = "El email no corresponde a un propietario" });
List<Servicio> servs = RepositorioServicios.Singleton.ObtenerServiciosPorDescripcion(propiedad.Servicios); List<Servicio> servs = RepositorioServicios.Singleton.ObtenerServiciosPorDescripcion(propiedad.Servicios);
Propiedade Prop = new Propiedade{ Propiedade Prop = new Propiedade
{
Id = propiedad.id, Id = propiedad.id,
Canthabitaciones = propiedad.Canthabitaciones, Canthabitaciones = propiedad.Canthabitaciones,
Dnipropietario = cli.Dni, Dnipropietario = cli.Dni,
@@ -213,61 +240,64 @@ public class PropiedadesController: ControllerBase {
}; };
bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop, cli.Dni); bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop, cli.Dni);
return (ret)? return (ret) ?
Ok(new {message = "Fue modificado Correctamente"}): Ok(new { message = "Fue modificado Correctamente" }) :
BadRequest(new {message = "Fallo al modificar la base de datos"}); BadRequest(new { message = "Fallo al modificar la base de datos" });
} }
[HttpDelete("api/propiedad")] [HttpDelete("api/propiedad")]
public IActionResult BajaPropiedad(int id, [FromHeader(Name = "Auth")] string Auth, [FromHeader(Name = "Email")] string email){ public IActionResult BajaPropiedad(int id, [FromHeader(Name = "Auth")] string Auth, [FromHeader(Name = "Email")] string email)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "Fallo al identificarse el usuario"}); if (String.IsNullOrEmpty(email)) return BadRequest(new { message = "Fallo al identificarse el usuario" });
if (id <= 0) return BadRequest(new { message = "No es una id valida"}); if (id <= 0) return BadRequest(new { message = "No es una id valida" });
Cliente? propie = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(email); Cliente? propie = RepositorioPropietario.Singleton.ObtenerPropietarioPorEmail(email);
var ret = RepositorioPropiedades.Singleton.BajaPropiedad(id, propie); var ret = RepositorioPropiedades.Singleton.BajaPropiedad(id, propie);
return ret ? return ret ?
Ok(new { message = $"Se Cambio el estado de la propiedad con id {id}"}): Ok(new { message = $"Se Cambio el estado de la propiedad con id {id}" }) :
BadRequest(new {message="Fallo al cambiar el estado de la propiedad"}); BadRequest(new { message = "Fallo al cambiar el estado de la propiedad" });
} }
[HttpPut("api/propiedades/addServicio")] [HttpPut("api/propiedades/addServicio")]
public IActionResult AñadirServicio([FromBody] ServicioAPropiedadDto Servicios, [FromHeader(Name = "Auth")] string Auth) { public IActionResult AñadirServicio([FromBody] ServicioAPropiedadDto Servicios, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (Servicios.propiedadid <= 0) return BadRequest(new {message ="No puede tener una id negativa o cero"}); if (Servicios.propiedadid <= 0) return BadRequest(new { message = "No puede tener una id negativa o cero" });
if (Servicios.idServicios.Count() < 1) return BadRequest(new {message ="Falta añadir servicios"}); if (Servicios.idServicios.Count() < 1) return BadRequest(new { message = "Falta añadir servicios" });
if (Servicios.idServicios.Any(x => x<= 0)) return BadRequest(new {message ="No tienen haber ids negativas o cero de servicio"}); if (Servicios.idServicios.Any(x => x <= 0)) return BadRequest(new { message = "No tienen haber ids negativas o cero de servicio" });
var serv = RepositorioServicios.Singleton.ObtenerServiciosPorPropiedad(Servicios.propiedadid); var serv = RepositorioServicios.Singleton.ObtenerServiciosPorPropiedad(Servicios.propiedadid);
bool validacion2 = Servicios.idServicios.Any(x => serv.Contains(x)); bool validacion2 = Servicios.idServicios.Any(x => serv.Contains(x));
if (validacion2 == true) return BadRequest(new {message ="Hay elementos repetidos"}); if (validacion2 == true) return BadRequest(new { message = "Hay elementos repetidos" });
bool ret = RepositorioPropiedades. bool ret = RepositorioPropiedades.
Singleton.AñadirServicioAPropiedad(Servicios.propiedadid, Servicios.idServicios); Singleton.AñadirServicioAPropiedad(Servicios.propiedadid, Servicios.idServicios);
return ret ? return ret ?
Ok(new {message ="Los Servicios Se Cargaron correctamente a la propiedad"}) : BadRequest(new {message ="No se pudo Cargar los Servicios a la propiedad"}); Ok(new { message = "Los Servicios Se Cargaron correctamente a la propiedad" }) : BadRequest(new { message = "No se pudo Cargar los Servicios a la propiedad" });
} }
[HttpPut("api/propiedades/RmServicio")] [HttpPut("api/propiedades/RmServicio")]
public IActionResult EliminarServicio([FromBody] ServicioAPropiedadDto servicio, [FromHeader(Name = "Auth")] string Auth) { public IActionResult EliminarServicio([FromBody] ServicioAPropiedadDto servicio, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
if (servicio.propiedadid <= 0) return BadRequest(new {message ="No puede tener una id negativa o cero"}); if (servicio.propiedadid <= 0) return BadRequest(new { message = "No puede tener una id negativa o cero" });
if (servicio.idServicios.Count() < 1) return BadRequest(new {message ="Falta añadir servicios"}); if (servicio.idServicios.Count() < 1) return BadRequest(new { message = "Falta añadir servicios" });
if (servicio.idServicios.Any(x => x<= 0)) return BadRequest(new {message ="No tienen haber ids negativas o cero de servicio"}); if (servicio.idServicios.Any(x => x <= 0)) return BadRequest(new { message = "No tienen haber ids negativas o cero de servicio" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
@@ -278,11 +308,12 @@ public class PropiedadesController: ControllerBase {
bool ret = RepositorioPropiedades.Singleton.BajaServiciosAPropiedad(servicio.propiedadid, servicio.idServicios, cli.Dni); bool ret = RepositorioPropiedades.Singleton.BajaServiciosAPropiedad(servicio.propiedadid, servicio.idServicios, cli.Dni);
return ret ? return ret ?
Ok(new {message ="Se Eliminaron los servicios seleccionados de la propiedad"}) : BadRequest(new {message ="Fallo al eliminarse los servicios de la propiedad"}); Ok(new { message = "Se Eliminaron los servicios seleccionados de la propiedad" }) : BadRequest(new { message = "Fallo al eliminarse los servicios de la propiedad" });
} }
private string ValidarPropiedad(AltaPropiedadDto prop) { private string ValidarPropiedad(AltaPropiedadDto prop)
{
if (prop == null) return "Esta mal formado el body de la request"; if (prop == null) return "Esta mal formado el body de la request";
string ret = ""; string ret = "";
@@ -294,21 +325,22 @@ public class PropiedadesController: ControllerBase {
if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n"; if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n";
if (prop.Monto<=1) ret += "El monto tiene que ser como minimo mayor a 0"; if (prop.Monto <= 1) ret += "El monto tiene que ser como minimo mayor a 0";
if (prop.Iddivisa<0 || prop.Iddivisa>1) ret += "se tiene que elejir entre AR$ y US$"; if (prop.Iddivisa < 0 || prop.Iddivisa > 1) ret += "se tiene que elejir entre AR$ y US$";
return ret; return ret;
} }
private string ValidarPropiedad(PatchPropiedadDto prop) { private string ValidarPropiedad(PatchPropiedadDto prop)
{
if (prop == null) return "Esta mal formado el body de la request"; if (prop == null) return "Esta mal formado el body de la request";
string ret = ""; string ret = "";
if (prop.id <1) ret += "No Cargo el dato de id"; if (prop.id < 1) ret += "No Cargo el dato de id";
if (String.IsNullOrEmpty(prop.Email)) ret += "Falta Definir un email de propietario\n"; if (String.IsNullOrEmpty(prop.Email)) ret += "Falta Definir un email de propietario\n";
if (prop.id <1 ) ret += "No puede haber una id menor a 1\n"; if (prop.id < 1) ret += "No puede haber una id menor a 1\n";
if (prop.Canthabitaciones < 0) ret += "No se puede tener una cantidad de habitaciones negativa\n"; if (prop.Canthabitaciones < 0) ret += "No se puede tener una cantidad de habitaciones negativa\n";
@@ -316,9 +348,9 @@ public class PropiedadesController: ControllerBase {
if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n"; if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n";
if (prop.Monto<=1) ret += "El monto tiene que ser como minimo mayor a 0"; if (prop.Monto <= 1) ret += "El monto tiene que ser como minimo mayor a 0";
if (prop.Iddivisa<0 || prop.Iddivisa>1) ret += "se tiene que elejir entre AR$ y US$"; if (prop.Iddivisa < 0 || prop.Iddivisa > 1) ret += "se tiene que elejir entre AR$ y US$";
return ret; return ret;
+21 -12
View File
@@ -9,10 +9,12 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class PropietarioController: ControllerBase { public class PropietarioController : ControllerBase
{
[HttpGet("api/propietario")] [HttpGet("api/propietario")]
public IActionResult ObtenerPropietarioPorDni(long Dni, [FromHeader(Name ="Auth")] string Auth) { public IActionResult ObtenerPropietarioPorDni(long Dni, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 14);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
@@ -22,8 +24,9 @@ public class PropietarioController: ControllerBase {
} }
[HttpPost("api/propietario")] [HttpPost("api/propietario")]
public IActionResult AltaPropietario([FromBody]CrearClienteDto Propietario, public IActionResult AltaPropietario([FromBody] CrearClienteDto Propietario,
[FromHeader(Name = "Auth")] string Auth) { [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 5); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 5);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
@@ -34,7 +37,8 @@ public class PropietarioController: ControllerBase {
string validacion2 = verificarCrearUsuario(Propietario); string validacion2 = verificarCrearUsuario(Propietario);
if (validacion2 != "") return BadRequest(validacion2); if (validacion2 != "") return BadRequest(validacion2);
var cli = new Cliente { var cli = new Cliente
{
Dni = Propietario.dni, Dni = Propietario.dni,
Nombre = Propietario.nombre, Nombre = Propietario.nombre,
Domicilio = Propietario.domicilio, Domicilio = Propietario.domicilio,
@@ -43,15 +47,17 @@ public class PropietarioController: ControllerBase {
Email = Propietario.email, Email = Propietario.email,
Contraseña = Encoding.UTF8.GetBytes(HacerHash(Propietario.contraseña)), Contraseña = Encoding.UTF8.GetBytes(HacerHash(Propietario.contraseña)),
Habilitado = 1, Habilitado = 1,
EmailRecuperacion = Propietario.email,
}; };
bool ret = RepositorioUsuarios.Singleton.AltaPropietario(cli, rep.Dni); bool ret = RepositorioUsuarios.Singleton.AltaPropietario(cli, rep.Dni);
return ret ? return ret ?
Ok(new {message = "Se añadio el propietario exitosamente"}) : BadRequest(); Ok(new { message = "Se añadio el propietario exitosamente" }) : BadRequest();
} }
[HttpPatch("api/propietarios")] [HttpPatch("api/propietarios")]
public IActionResult PatchPropietario([FromBody]CrearClienteDto Propietario, [FromHeader(Name = "Auth")] string Auth){ public IActionResult PatchPropietario([FromBody] CrearClienteDto Propietario, [FromHeader(Name = "Auth")] string Auth)
{
if (String.IsNullOrEmpty(Auth)) return Unauthorized(); if (String.IsNullOrEmpty(Auth)) return Unauthorized();
var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 5); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 5);
if (validacion1 == false) return Unauthorized(); if (validacion1 == false) return Unauthorized();
@@ -59,7 +65,8 @@ public class PropietarioController: ControllerBase {
string validacion2 = verificarCrearUsuario(Propietario); string validacion2 = verificarCrearUsuario(Propietario);
if (validacion2 != "") return BadRequest(validacion2); if (validacion2 != "") return BadRequest(validacion2);
var cli = new Cliente { var cli = new Cliente
{
Dni = Propietario.dni, Dni = Propietario.dni,
Nombre = Propietario.nombre, Nombre = Propietario.nombre,
Domicilio = Propietario.domicilio, Domicilio = Propietario.domicilio,
@@ -70,10 +77,11 @@ public class PropietarioController: ControllerBase {
}; };
var ret = RepositorioUsuarios.Singleton.ActualizarPropietario(cli); var ret = RepositorioUsuarios.Singleton.ActualizarPropietario(cli);
return ret ? return ret ?
Ok(new {message = "Se Modifico el propietario exitosamente"}) : BadRequest(); Ok(new { message = "Se Modifico el propietario exitosamente" }) : BadRequest();
} }
private string verificarCrearUsuario(CrearClienteDto cid) { private string verificarCrearUsuario(CrearClienteDto cid)
{
string msg = ""; string msg = "";
if (cid.email == string.Empty) msg += "Falta ingresar el email\n"; if (cid.email == string.Empty) msg += "Falta ingresar el email\n";
@@ -87,8 +95,9 @@ public class PropietarioController: ControllerBase {
return msg; return msg;
} }
private string HacerHash(string pass){ private string HacerHash(string pass)
{
var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass)); var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass));
return BitConverter.ToString(buf).Replace("-",""); return BitConverter.ToString(buf).Replace("-", "");
} }
} }
+177
View File
@@ -0,0 +1,177 @@
using AlquilaFacil.Builder;
using Microsoft.AspNetCore.Mvc;
using Modelo;
using Entidades;
using AlquilaFacil.Emailer.Sender;
namespace AlquilaFacil.Controllers;
[ApiController]
public class UsuarioController : ControllerBase
{
[HttpGet("/api/usuario")]
public IActionResult ObtenerInfoUsuario([FromHeader(Name = "Auth")] string Auth)
{
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un usuari por ese token" });
var usu = new UsuarioDtoBuilder()
.SetNombre(cli.Nombre).SetApellido(cli.Apellido)
.SetEmail(cli.Email).SetCelular(cli.Celular)
.SetDni(cli.Dni).SetDomicilio(cli.Domicilio)
.SetEmailRecuperacion(cli.EmailRecuperacion)
.Build();
return Ok(usu);
}
public class bodyCambiarContraseña
{
public string contraseña { get; set; } = "";
}
[HttpPatch("/api/usuario")]
public IActionResult CambiarPass([FromHeader(Name = "Auth")] string Auth, [FromBody] bodyCambiarContraseña body)
{
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un usuario por ese token" });
if (body.contraseña.Length < 8) return BadRequest(new { message = "Tiene que tener por lo menos 8 caracteres" });
bool ret = RepositorioUsuarios.Singleton.CambiarContraseña(body.contraseña, cli);
return ret ? Ok(new { message = "Contraseña cambiada con éxito" }) : BadRequest(new { message = "No se pudo cambiar la contraseña" });
}
public class bodyCambiarContraAdmin : bodyCambiarContraseña
{
public long Dni { get; set; }
}
[HttpPatch("/api/admin/contraseña")]
public IActionResult CambiarPassAdmin([FromHeader(Name = "Auth")] string Auth, [FromBody] bodyCambiarContraAdmin body)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 9);
if (!ret) return BadRequest(new { message = "No tienes permisos para cambiar contraseñas de usuario" });
if (body.contraseña.Length < 8 || string.IsNullOrWhiteSpace(body.contraseña)) return BadRequest(new { message = "La contraseña debe tener al menos 8 caracteres y no puede estar vacía" });
if (body.Dni <= 0) return BadRequest(new { message = "El DNI no puede estar vacío" });
Cliente? usu = RepositorioUsuarios.Singleton.ObtenerClientePorDni(body.Dni);
if (usu == null) return BadRequest(new { message = "No existe un usuario con ese DNI" });
ret = RepositorioUsuarios.Singleton.CambiarContraseña(body.contraseña, usu);
return ret ? Ok(new { message = "Contraseña cambiada con éxito" }) : BadRequest(new { message = "No se pudo cambiar la contraseña" });
}
public record SetEmail(string EmailRecuperacion);
[HttpPut("/api/usuario/emailrecuperacion")]
public IActionResult CambiarPass([FromHeader(Name = "Auth")] string Auth, [FromBody] SetEmail setemail)
{
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un usuario por ese token" });
string emailrecuperacion = setemail.EmailRecuperacion;
if (!emailrecuperacion.Contains("@")) return BadRequest(new { message = "Tiene que ser un email" });
bool ret = RepositorioUsuarios.Singleton.SetEmailRecuperacion(emailrecuperacion, cli);
if (ret == false) return BadRequest(new { message = "No se pudo actualizar el email de recuperación" });
Task.Run(() =>
{
AvisoEmailSender s = new();
s.Send(cli.Email, setemail.EmailRecuperacion);
});
return Ok(new { message = "Email de recuperación actualizado con éxito" });
}
public record RecuperarUsuarioDto(string Email, string EmailRecuperacion);
[HttpPost("/api/recuperarUsuario")]
public IActionResult RecuperarUsuario([FromBody] RecuperarUsuarioDto mails)
{
bool check = RepositorioUsuarios.Singleton.CheckEmailRecuperacion(mails.Email, mails.EmailRecuperacion);
if (check == false) return BadRequest(new { message = "El email no corresponde al email de recuperacion" });
string pin = "";
var ran = new Random();
for (int i = 0; i < 6; i++) pin += ran.Next(0, 10);
bool ret = RepositorioUsuarios.Singleton.SetF2aPin(pin, mails.Email);
if (ret == false) return BadRequest(new { message = "no se pudo generar/guardar el codigo 2fa" });
Task.Run(() =>
{
OtpEmailSender s = new();
s.Send(mails.EmailRecuperacion, mails.Email, pin);
});
return Ok(new { message = $"Se envio un email de recuperacion a {mails.EmailRecuperacion}" });
}
public record ingreso2fa(string Pin, string Email);
[HttpPost("/api/ingresar2fa")]
public IActionResult IngresarUsuario([FromBody] ingreso2fa data)
{
if (!data.Email.Contains("@")) return BadRequest(new { message = "Tiene que ser un email" });
if (data.Pin.Length != 6) return BadRequest(new { message = "el pin tiene que tener 6 digitos" });
(bool check, long Dni) = RepositorioUsuarios.Singleton.Check2fa(data.Email, data.Pin);
if (check == false) return BadRequest(new { message = "El pin es incorrecto" });
var cli = RepositorioUsuarios.Singleton.ObtenerClientePorDni(Dni);
//esto literalmente no se puede triggerear pero lo pongo para evitar una warning
if (cli == null) return BadRequest(new { message = "El usuario no existe" });
return Ok(new { token = cli.Token });
}
public record Crearusuario(long Dni, string Nombre, string Apellido, string Domicilio, string Celular,
string Email, string Contraseña, string? EmailRecuperacion, List<int> grupos);
[HttpPost("api/crearusuario")]
public IActionResult CrearUsuario([FromHeader(Name ="Auth")] string Auth, [FromBody] Crearusuario cu)
{
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, 19);
if (!ret) return BadRequest(new { message = "No tienes permisos para Crear un usuario" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return BadRequest(new { message = "No hay un usuario por ese token" });
string rett = "";
if (cu.Dni <= 0)
rett += "No puede haber un documento con numero menor o igual a 0";
if (cu.Apellido.Length > 20)
rett += "Apellido excede los 20 caracteres. ";
if (cu.Nombre.Length > 20)
rett += "Nombre excede los 20 caracteres. ";
if (cu.Celular.Length > 40)
rett += "Celular excede los 40 caracteres. ";
if (cu.Domicilio.Length > 40)
rett += "Domicilio excede los 40 caracteres. ";
if (cu.Email.Length > 50)
rett += "Email excede los 50 caracteres. ";
if (cu.EmailRecuperacion?.Length > 50)
rett += "Email de recuperación excede los 50 caracteres. ";
if (rett != "") return BadRequest(new { message = rett });
Cliente clii = new Cliente
{
Habilitado = 1,
Dni = cu.Dni,
Nombre = cu.Nombre,
Apellido = cu.Apellido,
Celular = cu.Celular,
Email = cu.Email,
EmailRecuperacion = ((cu.EmailRecuperacion ?? "").Length == 0) ? cu.Email : cu.EmailRecuperacion,
Domicilio = cu.Domicilio
};
var rettt = RepositorioUsuarios.Singleton.AltaUsuario(cli.Dni, clii, cu.Contraseña, cu.grupos);
return rettt
? Ok(new { message = "Usuario creado exitosamente." })
: BadRequest(new { message = "Hubo un error al crear el usuario." }); }
}
+176 -161
View File
@@ -1,5 +1,3 @@
using System.Configuration;
using System.Formats.Asn1;
using System.Text.Json; using System.Text.Json;
using AlquilaFacil.Builder; using AlquilaFacil.Builder;
using AlquilaFacil.Config; using AlquilaFacil.Config;
@@ -12,27 +10,31 @@ using Modelo;
namespace AlquilaFacil.Controllers; namespace AlquilaFacil.Controllers;
[ApiController] [ApiController]
public class VentaController:ControllerBase { public class VentaController : ControllerBase
{
[HttpPost("api/venta/AceptarConsultaVenta")] [HttpPost("api/venta/AceptarConsultaVenta")]
public IActionResult AceptarConsultaVenta([FromHeader(Name="Auth")]string Auth, NotificacionMarcarLeidoDto dto) { public IActionResult AceptarConsultaVenta([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto dto)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
if (dto.Email == "") return BadRequest(new { message = "Falta dato Email"}); if (dto.Email == "") return BadRequest(new { message = "Falta dato Email" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) Unauthorized(); if (cli == null) Unauthorized();
if (cli.Email != dto.Email) return BadRequest(new {message = "El token de autorizacion no corresponde a tu usuario"}); if (cli.Email != dto.Email) return BadRequest(new { message = "El token de autorizacion no corresponde a tu usuario" });
RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha); RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha);
Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha); Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha);
if (n == null) return BadRequest(new { message = "No se encuentra la notificacion"}); if (n == null) return BadRequest(new { message = "No se encuentra la notificacion" });
Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(n.Idpropiedad); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(n.Idpropiedad);
if (prop == null) return BadRequest(new { message = "No se encuentra una propiedad por ese id"}); if (prop == null) return BadRequest(new { message = "No se encuentra una propiedad por ese id" });
Venta? v = new Venta{ Venta? v = new Venta
{
Fechainicio = DateTime.Now, Fechainicio = DateTime.Now,
IdVendedor = prop.Dnipropietario, IdVendedor = prop.Dnipropietario,
IdComprador = n.Dniremitente, IdComprador = n.Dniremitente,
@@ -44,7 +46,8 @@ public class VentaController:ControllerBase {
}; };
bool ret = RepositorioVentas.Singleton.IniciarVenta(v, cli.Dni); bool ret = RepositorioVentas.Singleton.IniciarVenta(v, cli.Dni);
if (ret){ if (ret)
{
var noti = new NotificacioneBuilder() var noti = new NotificacioneBuilder()
.SetAccion("Notificacion") .SetAccion("Notificacion")
.SetMensaje("Debe Realizar el pago para que se registre el traspaso de la propiedad") .SetMensaje("Debe Realizar el pago para que se registre el traspaso de la propiedad")
@@ -56,25 +59,27 @@ public class VentaController:ControllerBase {
.Build(); .Build();
ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti);
} }
return ret? return ret ?
Ok(new { message = "Se inicio la venta"}):BadRequest(new { message ="fallo al iniciar la venta"}); Ok(new { message = "Se inicio la venta" }) : BadRequest(new { message = "fallo al iniciar la venta" });
} }
[HttpPost("api/venta/CancelarConsultaVenta")] [HttpPost("api/venta/CancelarConsultaVenta")]
public IActionResult CancelarConsultaVenta([FromHeader(Name="Auth")]string Auth, NotificacionMarcarLeidoDto dto) { public IActionResult CancelarConsultaVenta([FromHeader(Name = "Auth")] string Auth, NotificacionMarcarLeidoDto dto)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
if (dto.Email == "") return BadRequest(new { message = "Falta dato Email"}); if (dto.Email == "") return BadRequest(new { message = "Falta dato Email" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) Unauthorized(); if (cli == null) Unauthorized();
if (cli.Email != dto.Email) return BadRequest(new {message = "El token de autorizacion no corresponde a tu usuario"}); if (cli.Email != dto.Email) return BadRequest(new { message = "El token de autorizacion no corresponde a tu usuario" });
RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha); RepositorioNotificaciones.Singleton.MarcarComoLeido(cli.Dni, dto.Fecha);
Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha); Notificacione? n = RepositorioNotificaciones.Singleton.ObtenerNotificacionPorKeys(cli.Dni, dto.Fecha);
var noti = new NotificacioneBuilder() var noti = new NotificacioneBuilder()
.SetAccion("Notificacion") .SetAccion("Notificacion")
.SetMensaje("El propietario no quiere vender") .SetMensaje("El propietario no quiere vender")
@@ -87,87 +92,81 @@ public class VentaController:ControllerBase {
var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti); var ret = RepositorioNotificaciones.Singleton.AltaNotificacion(noti);
return ret ? return ret ?
Ok(new{message = "Se Envio una notificacion"}):BadRequest(new{message = "Fallo al Descartar Consulta"}); Ok(new { message = "Se Envio una notificacion" }) : BadRequest(new { message = "Fallo al Descartar Consulta" });
}
[HttpGet("/api/propiedad/EstaALaVenta")]
public IActionResult EstaALaVenta([FromHeader(Name="Auth")]string Auth, int idprop=0) {
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario");
if (validacion1 == false) {
return Unauthorized();
}
if (idprop<=0) return BadRequest(new { message = "No hay propiedades con id 0 o menor"});
Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(idprop);
if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id"});
return Ok(new { EstaAVenta = prop.Idestado ==4?true:false});
} }
[HttpPut("/api/propiedad/setPropiedadAVenta")] [HttpPut("/api/propiedad/setPropiedadAVenta")]
public IActionResult setPropiedadAVenta([FromHeader(Name="Auth")]string Auth, SetVentaDto dto) { public IActionResult setPropiedadAVenta([FromHeader(Name = "Auth")] string Auth, SetVentaDto dto)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 2);
var validacion2 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 8);
if (validacion1 == false || validacion2 == false)
{
return Unauthorized(); return Unauthorized();
} }
if (dto.iddivisa != 0 && dto.iddivisa!=1) return BadRequest(new { message = "no hay una divisa por esa id"}); if (dto.iddivisa != 0 && dto.iddivisa != 1) return BadRequest(new { message = "no hay una divisa por esa id" });
if (dto.idpropiedad<=0) return BadRequest(new { message = "No hay propiedades con id 0 o menor"}); if (dto.idpropiedad <= 0) return BadRequest(new { message = "No hay propiedades con id 0 o menor" });
if (dto.monto<1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1"}); if (dto.monto < 1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad);
if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id"}); if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id" });
if (cli.Dni != prop.Dnipropietario) return Unauthorized(); if (cli.Dni != prop.Dnipropietario) return Unauthorized();
var ret = RepositorioVentas.Singleton.SetVenta(prop.Id, dto.monto, dto.iddivisa, cli.Dni); var ret = RepositorioVentas.Singleton.SetVenta(prop.Id, dto.monto, dto.iddivisa, cli.Dni);
return ret? return ret ?
Ok(new { message = "Se puso la propiedad de venta"}) : BadRequest(new { message = "No se pudo poner a la Venta"}); Ok(new { message = "Se puso la propiedad de venta" }) : BadRequest(new { message = "No se pudo poner a la Venta" });
} }
[HttpPut("/api/propiedad/unsetPropiedadAVenta")] [HttpPut("/api/propiedad/unsetPropiedadAVenta")]
public IActionResult unsetPropiedadAVenta([FromHeader(Name="Auth")]string Auth, SetVentaDto dto) { public IActionResult unsetPropiedadAVenta([FromHeader(Name = "Auth")] string Auth, SetVentaDto dto)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 15);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
if (dto.iddivisa != 0 && dto.iddivisa!=1) return BadRequest(new { message = "no hay una divisa por esa id"}); if (dto.iddivisa != 0 && dto.iddivisa != 1) return BadRequest(new { message = "no hay una divisa por esa id" });
if (dto.idpropiedad<=0) return BadRequest(new { message = "No hay propiedades con id 0 o menor"}); if (dto.idpropiedad <= 0) return BadRequest(new { message = "No hay propiedades con id 0 o menor" });
if (dto.monto<1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1"}); if (dto.monto < 1) return BadRequest(new { message = "No se pueden hacer ventas por montos menores a 1" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad); Propiedade? prop = RepositorioPropiedades.Singleton.ObtenerPropiedadPorId(dto.idpropiedad);
if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id"}); if (prop == null) return BadRequest(new { message = "No hay propiedades por ese id" });
if (cli.Dni != prop.Dnipropietario) return Unauthorized(); if (cli.Dni != prop.Dnipropietario) return Unauthorized();
bool ret = RepositorioVentas.Singleton.UnSetVenta(prop.Id, dto.monto, dto.iddivisa, cli.Dni); bool ret = RepositorioVentas.Singleton.UnSetVenta(prop.Id, dto.monto, dto.iddivisa, cli.Dni);
return ret? return ret ?
Ok(new { message = "Se Bajo la propiedad de venta"}) : BadRequest(new { message = "No se pudo Bajar de venta"}); Ok(new { message = "Se Bajo la propiedad de venta" }) : BadRequest(new { message = "No se pudo Bajar de venta" });
} }
[HttpPost("/api/ventas/ejercerOpcionVenta")] [HttpPost("/api/ventas/ejercerOpcionVenta")]
public IActionResult EjercerOpcionVenta([FromHeader(Name="Auth")]string Auth, [FromQuery]long idcontrato=0) { public IActionResult EjercerOpcionVenta([FromHeader(Name = "Auth")] string Auth, [FromQuery] long idcontrato = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); {
if (validacion1 == false) { var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
if (idcontrato <= 0) return BadRequest(new { message = "No pueden hacer cotratos con id 0 o menor"}); if (idcontrato <= 0) return BadRequest(new { message = "No pueden hacer cotratos con id 0 o menor" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato); Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato);
if (cont == null || cont.IdventaNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id"}); if (cont == null || cont.IdventaNavigation == null) return BadRequest(new { message = "no hay un contrato por esa id" });
if (cont.Tieneopcionventa == 0) return BadRequest(new { message = "No tiene opcion de venta"}); if (cont.Tieneopcionventa == 0) return BadRequest(new { message = "No tiene opcion de venta" });
if (puedeEjercer(cont) == false) return BadRequest(new { message = "No cumple con los requisitos para ejercer la opcion de compra"}); if (puedeEjercer(cont) == false) return BadRequest(new { message = "No cumple con los requisitos para ejercer la opcion de compra" });
Venta venta = cont.IdventaNavigation; Venta venta = cont.IdventaNavigation;
venta.IdVendedor = cont.Dnipropietario; venta.IdVendedor = cont.Dnipropietario;
@@ -177,31 +176,30 @@ public class VentaController:ControllerBase {
bool ret = RepositorioVentas.Singleton.PatchVenta(venta, cli.Dni); bool ret = RepositorioVentas.Singleton.PatchVenta(venta, cli.Dni);
return ret? return ret ?
Ok(new { message = "Se ejercio la opcion de venta"}): Ok(new { message = "Se ejercio la opcion de venta" }) :
BadRequest(new { message = "No se pude ejercer la opcion de venta"}); BadRequest(new { message = "No se pude ejercer la opcion de venta" });
} }
[HttpPost("/api/ventas/subirReciboPago")] [HttpPost("/api/ventas/subirReciboPago")]
public async Task<IActionResult> SubirRecibo([FromHeader(Name="Auth")]string Auth, IFormFile file, long idventa ) { public async Task<IActionResult> SubirRecibo([FromHeader(Name = "Auth")] string Auth, IFormFile file, long idventa)
{
if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized(); if (String.IsNullOrWhiteSpace(Auth)) return Unauthorized();
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13);
if (validacion1 == false){ if (validacion1 == false)
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); {
if (validacion1 == false) { return Unauthorized();
return Unauthorized();
}
} }
if (idventa <=0) return BadRequest(new { message = "Las id 0 o menor no son validas" }); if (idventa <= 0) return BadRequest(new { message = "Las id 0 o menor no son validas" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
if (venta == null) return BadRequest(new { message = "no hay una venta por esa id"}); if (venta == null) return BadRequest(new { message = "no hay una venta por esa id" });
if (cli.Dni !=venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized(); if (cli.Dni != venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized();
if (file == null) return BadRequest(new { message = "Debe subir un archivo." }); if (file == null) return BadRequest(new { message = "Debe subir un archivo." });
if (file.ContentType != "application/pdf") return BadRequest(new { message = "El archivo debe ser un documento PDF." }); if (file.ContentType != "application/pdf") return BadRequest(new { message = "El archivo debe ser un documento PDF." });
@@ -209,19 +207,21 @@ public class VentaController:ControllerBase {
string nuevoNombreArchivo = $"id:{venta.Id}-comprador:{venta.IdComprador}-vendedor:{venta.IdVendedor}-idprop:{venta.Idpropiedad}.pdf"; string nuevoNombreArchivo = $"id:{venta.Id}-comprador:{venta.IdComprador}-vendedor:{venta.IdVendedor}-idprop:{venta.Idpropiedad}.pdf";
bool ret = await subirContrato(file, nuevoNombreArchivo); bool ret = await subirContrato(file, nuevoNombreArchivo);
if(ret == false) return BadRequest(new {message = "No se pudo subir el archivo"}); if (ret == false) return BadRequest(new { message = "No se pudo subir el archivo" });
ret = RepositorioVentas.Singleton.SetUrlRecibo(venta.Id, nuevoNombreArchivo, cli.Dni); ret = RepositorioVentas.Singleton.SetUrlRecibo(venta.Id, nuevoNombreArchivo, cli.Dni);
if (ret == false) return BadRequest(new { message = "no se pudo guardar el nombre del archivo subido"}); if (ret == false) return BadRequest(new { message = "no se pudo guardar el nombre del archivo subido" });
return Ok(new { message = "Se Subio el Recibo"}); return Ok(new { message = "Se Subio el Recibo" });
} }
private readonly IMinioClient mc; private readonly IMinioClient mc;
public VentaController(IMinioClient minioClient) { public VentaController(IMinioClient minioClient)
{
mc = minioClient; mc = minioClient;
if (mc == null){ if (mc == null)
MinioConfigcus? mcon = JsonSerializer.Deserialize<MinioConfigcus>(System.IO.File.ReadAllText("./settings.json"))?? null; {
MinioConfigcus? mcon = JsonSerializer.Deserialize<MinioConfigcus>(System.IO.File.ReadAllText("./settings.json")) ?? null;
if (mcon == null) throw new Exception(); if (mcon == null) throw new Exception();
mc = new MinioClient().WithCredentials(mcon.usr, mcon.scrt) mc = new MinioClient().WithCredentials(mcon.usr, mcon.scrt)
@@ -230,18 +230,22 @@ public class VentaController:ControllerBase {
.Build(); .Build();
} }
} }
private async Task<bool> subirContrato(IFormFile f, string flname) { private async Task<bool> subirContrato(IFormFile f, string flname)
try { {
try
{
var buck = new BucketExistsArgs().WithBucket("alquilafacil"); var buck = new BucketExistsArgs().WithBucket("alquilafacil");
bool encontrado = await mc.BucketExistsAsync(buck).ConfigureAwait(false); bool encontrado = await mc.BucketExistsAsync(buck).ConfigureAwait(false);
if(!encontrado){ if (!encontrado)
{
var mb = new MakeBucketArgs().WithBucket("alquilafacil"); var mb = new MakeBucketArgs().WithBucket("alquilafacil");
await mc.MakeBucketAsync(mb).ConfigureAwait(false); await mc.MakeBucketAsync(mb).ConfigureAwait(false);
} }
using (var stream = new MemoryStream()){ using (var stream = new MemoryStream())
{
await f.CopyToAsync(stream); await f.CopyToAsync(stream);
stream.Position=0; stream.Position = 0;
PutObjectArgs putbj = new PutObjectArgs() PutObjectArgs putbj = new PutObjectArgs()
.WithBucket("alquilafacil") .WithBucket("alquilafacil")
.WithObject(flname) .WithObject(flname)
@@ -251,38 +255,41 @@ public class VentaController:ControllerBase {
await mc.PutObjectAsync(putbj); await mc.PutObjectAsync(putbj);
} }
return true; return true;
} catch (Exception e ) { }
catch (Exception e)
{
Console.Error.WriteLine(e.Message); Console.Error.WriteLine(e.Message);
return false; return false;
} }
} }
[HttpGet("/api/ventas/verRecibo")] [HttpGet("/api/ventas/verRecibo")]
public IActionResult verRecibo([FromHeader(Name="Auth")]string Auth, long idventa=0){ public IActionResult verRecibo([FromHeader(Name = "Auth")] string Auth, long idventa = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false){ var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13);
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); if (validacion1 == false)
if (validacion1 == false) { {
return Unauthorized(); return Unauthorized();
}
} }
if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"}); if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); Venta? venta = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
if (venta == null) return BadRequest(new { message = "no hay una venta con esa id"}); if (venta == null) return BadRequest(new { message = "no hay una venta con esa id" });
if (cli.Dni != venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized(); if (cli.Dni != venta.IdComprador && cli.Dni != venta.IdVendedor) return Unauthorized();
try{ try
var memstream = new MemoryStream(); {
var memstream = new MemoryStream();
var goa = new GetObjectArgs() var goa = new GetObjectArgs()
.WithBucket("alquilafacil") .WithBucket("alquilafacil")
.WithObject(venta.UrlRecibo) .WithObject(venta.UrlRecibo)
.WithCallbackStream(stream => { .WithCallbackStream(stream =>
memstream.Position=0; {
memstream.Position = 0;
stream.CopyTo(memstream); stream.CopyTo(memstream);
}); });
@@ -293,53 +300,50 @@ public class VentaController:ControllerBase {
return File(memstream, "application/pdf", venta.UrlRecibo); return File(memstream, "application/pdf", venta.UrlRecibo);
} catch (Exception e){ }
catch (Exception e)
{
Console.Error.WriteLine(e); Console.Error.WriteLine(e);
return BadRequest(new { message = "Fallo al intentar obtener el archivo del almacenamiento o este no existe"}); return BadRequest(new { message = "Fallo al intentar obtener el archivo del almacenamiento o este no existe" });
} }
} }
[HttpPost("/api/ventas/propietarioverifica")] [HttpPost("/api/ventas/propietarioverifica")]
public IActionResult PropietarioVerifica([FromHeader(Name="Auth")]string Auth, long idventa=0) { public IActionResult PropietarioVerifica([FromHeader(Name = "Auth")] string Auth, long idventa = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false){ var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13);
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); if (validacion1 == false)
if (validacion1 == false) { {
return Unauthorized(); return Unauthorized();
}
} }
if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"}); if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
if (ventas == null) return BadRequest(new { message ="No hay una venta con ese id"}); if (ventas == null) return BadRequest(new { message = "No hay una venta con ese id" });
if (ventas.IdVendedor != cli.Dni) return Unauthorized(); if (ventas.IdVendedor != cli.Dni) return Unauthorized();
bool ret = RepositorioVentas.Singleton.EfectuarVenta(idventa); bool ret = RepositorioVentas.Singleton.EfectuarVenta(idventa);
return ret ? Ok(new { message = "Se traspaso la propiedad"}): BadRequest(new { message = ""}); return ret ? Ok(new { message = "Se traspaso la propiedad" }) : BadRequest(new { message = "" });
} }
[HttpGet("/api/venta")] [HttpGet("/api/venta")]
public IActionResult ObtenerVenta([FromHeader(Name="Auth")]string Auth, long idventa=0) { public IActionResult ObtenerVenta([FromHeader(Name = "Auth")] string Auth, long idventa = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false){ var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13);
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
if (validacion1 == false) { if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0" });
return Unauthorized();
}
}
if (idventa <= 0) return BadRequest(new { message = "No existen ventas validas para la id 0"});
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa); var ventas = RepositorioVentas.Singleton.ObtenerVentaPorId(idventa);
if (ventas == null) return BadRequest(new { message ="No hay una venta con ese id"}); if (ventas == null) return BadRequest(new { message = "No hay una venta con ese id" });
if (ventas.IdVendedor !=cli.Dni && ventas.IdComprador != cli.Dni) return Unauthorized(); if (ventas.IdVendedor != cli.Dni && ventas.IdComprador != cli.Dni) return Unauthorized();
var v = new VentasDtoBuilder() var v = new VentasDtoBuilder()
.SetId(ventas.Id) .SetId(ventas.Id)
@@ -347,44 +351,44 @@ public class VentaController:ControllerBase {
.SetDivisa(ventas.IddivisaNavigation.Signo) .SetDivisa(ventas.IddivisaNavigation.Signo)
.SetUbicacion(ventas.IdpropiedadNavigation.Ubicacion) .SetUbicacion(ventas.IdpropiedadNavigation.Ubicacion)
.SetNombreVendedor($"{ventas.IdVendedorNavigation.Nombre} {ventas.IdVendedorNavigation.Apellido}") .SetNombreVendedor($"{ventas.IdVendedorNavigation.Nombre} {ventas.IdVendedorNavigation.Apellido}")
.SetIdVendedor(ventas.IdVendedor??0) .SetIdVendedor(ventas.IdVendedor ?? 0)
.SetNombreComprador($"{ventas.IdCompradorNavigation.Nombre} {ventas.IdCompradorNavigation.Apellido}") .SetNombreComprador($"{ventas.IdCompradorNavigation.Nombre} {ventas.IdCompradorNavigation.Apellido}")
.SetIdComprador(ventas.IdComprador??0) .SetIdComprador(ventas.IdComprador ?? 0)
.SetEstado(ventas.IdestadoNavigation.Descripcion??"") .SetEstado(ventas.IdestadoNavigation.Descripcion ?? "")
.Build(); .Build();
return Ok(new { data = v, iscomprador = (ventas.IdComprador==cli.Dni)?true:false, return Ok(new
necesitaRecibo = ventas.UrlRecibo==null?true:false}); {
data = v,
iscomprador = (ventas.IdComprador == cli.Dni) ? true : false,
necesitaRecibo = ventas.UrlRecibo == null ? true : false
});
} }
[HttpGet("/api/ventas")] [HttpGet("/api/ventas")]
public IActionResult ObtenerVentas([FromHeader(Name="Auth")]string Auth) { public IActionResult ObtenerVentas([FromHeader(Name = "Auth")] string Auth)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false){ var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 13);
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino");
if (validacion1 == false) {
return Unauthorized();
}
}
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
var ventas = RepositorioVentas.Singleton.ObtenerVentasPorDni(cli.Dni); var ventas = RepositorioVentas.Singleton.ObtenerVentasPorDni(cli.Dni);
if (ventas == null) return BadRequest(new { message ="no estas involucrado en ninguna venta o compra"}); if (ventas == null) return BadRequest(new { message = "no estas involucrado en ninguna venta o compra" });
List<VentasDto> lista = new(); List<VentasDto> lista = new();
foreach (var i in ventas) { foreach (var i in ventas)
{
var v = new VentasDtoBuilder() var v = new VentasDtoBuilder()
.SetId(i.Id) .SetId(i.Id)
.SetMonto(i.Monto) .SetMonto(i.Monto)
.SetDivisa(i.IddivisaNavigation.Signo) .SetDivisa(i.IddivisaNavigation.Signo)
.SetUbicacion(i.IdpropiedadNavigation.Ubicacion) .SetUbicacion(i.IdpropiedadNavigation.Ubicacion)
.SetNombreVendedor($"{i.IdVendedorNavigation.Nombre} {i.IdVendedorNavigation.Apellido}") .SetNombreVendedor($"{i.IdVendedorNavigation.Nombre} {i.IdVendedorNavigation.Apellido}")
.SetIdVendedor(i.IdVendedor??0) .SetIdVendedor(i.IdVendedor ?? 0)
.SetNombreComprador($"{i.IdCompradorNavigation.Nombre} {i.IdCompradorNavigation.Apellido}") .SetNombreComprador($"{i.IdCompradorNavigation.Nombre} {i.IdCompradorNavigation.Apellido}")
.SetIdComprador(i.IdComprador??0) .SetIdComprador(i.IdComprador ?? 0)
.SetEstado(i.IdestadoNavigation.Descripcion??"") .SetEstado(i.IdestadoNavigation.Descripcion ?? "")
.Build(); .Build();
lista.Add(v); lista.Add(v);
} }
@@ -392,43 +396,51 @@ public class VentaController:ControllerBase {
} }
[HttpGet("/api/opcionventa")] [HttpGet("/api/opcionventa")]
public IActionResult ObtenerDto([FromHeader(Name="Auth")]string Auth, long idcontrato=0) { public IActionResult ObtenerDto([FromHeader(Name = "Auth")] string Auth, long idcontrato = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false){ var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11);
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); if (validacion1 == false)
if (validacion1 == false) { {
validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
} }
if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0"}); if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato); Contrato? cont = RepositorioVentas.Singleton.ObtenerVentaPorContrato(idcontrato);
if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id"}); if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id" });
var dto = new OpcionVentaDtoBuilder() var dto = new OpcionVentaDtoBuilder()
.SetId(cont.Idventa??0) .SetId(cont.Idventa ?? 0)
.SetMonto(cont.IdventaNavigation.Monto) .SetMonto(cont.IdventaNavigation.Monto)
.SetDivisa(cont.IdventaNavigation.IddivisaNavigation.Signo) .SetDivisa(cont.IdventaNavigation.IddivisaNavigation.Signo)
.SetEnOrden(puedeEjercer(cont)) .SetEnOrden(puedeEjercer(cont))
.SetFueEjercido(cont.IdventaNavigation.Idestado??0) .SetFueEjercido(cont.IdventaNavigation.Idestado ?? 0)
.Build(); .Build();
return Ok(dto); return Ok(dto);
} }
private bool puedeEjercer(Contrato c) { private bool puedeEjercer(Contrato c)
{
bool ret = c.Idcanons.All(x => x.Pagado == 1); bool ret = c.Idcanons.All(x => x.Pagado == 1);
if (ret) { if (ret)
{
var canonConFechaMasTardia = c.Idcanons.OrderByDescending(x => x.Fecha).FirstOrDefault(); var canonConFechaMasTardia = c.Idcanons.OrderByDescending(x => x.Fecha).FirstOrDefault();
if (canonConFechaMasTardia != null && canonConFechaMasTardia.Fecha.Year >= DateTime.Now.Year if (canonConFechaMasTardia != null && canonConFechaMasTardia.Fecha.Year >= DateTime.Now.Year
&& canonConFechaMasTardia.Fecha.Month >= DateTime.Now.Month) { && canonConFechaMasTardia.Fecha.Month >= DateTime.Now.Month)
{
ret = true; ret = true;
}else{ }
else
{
ret = false; ret = false;
} }
} }
@@ -437,24 +449,27 @@ public class VentaController:ControllerBase {
} }
[HttpGet("/api/contrato/tieneopcionventa")] [HttpGet("/api/contrato/tieneopcionventa")]
public IActionResult TieneOpcionVenta([FromHeader(Name="Auth")]string Auth, long idcontrato=0) { public IActionResult TieneOpcionVenta([FromHeader(Name = "Auth")] string Auth, long idcontrato = 0)
var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Propietario"); {
if (validacion1 == false){ var validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 11);
validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Inquilino"); if (validacion1 == false)
if (validacion1 == false) { {
validacion1 = RepositorioPermisos.Singleton.CheckPermisos(Auth, 12);
if (validacion1 == false)
{
return Unauthorized(); return Unauthorized();
} }
} }
if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0"}); if (idcontrato == 0) return BadRequest(new { message = "No existen contatos validos para la id 0" });
Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); Cliente? cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth);
if (cli == null) return Unauthorized(); if (cli == null) return Unauthorized();
Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(idcontrato); Contrato? cont = RepositorioContratos.Singleton.ObtenerContratoPorId(idcontrato);
if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id"}); if (cont == null) return BadRequest(new { message = "No hay un contrato por esa id" });
if (cont.Dniinquilino !=cli.Dni && cont.Dnipropietario != cli.Dni) return Unauthorized(); if (cont.Dniinquilino != cli.Dni && cont.Dnipropietario != cli.Dni) return Unauthorized();
return Ok( new { message = cont.Tieneopcionventa}); return Ok(new { message = cont.Tieneopcionventa });
} }
} }
+38
View File
@@ -0,0 +1,38 @@
using System.Net.Mail;
namespace AlquilaFacil.Emailer.Builder;
public class EmailBuilder
{
private MailMessage _message = new();
public EmailBuilder To(string to)
{
_message.To.Add(to);
return this;
}
public EmailBuilder Subject(string subject)
{
_message.Subject = subject;
return this;
}
public EmailBuilder Body(string email, string pin, string modo = "2fa")
{
_message.IsBodyHtml = true;
switch (modo)
{
case "2fa":
_message.Body = new HtmlGenerator().GenerarMail2fa(email, pin);
break;
case "aviso":
_message.Body = new HtmlGenerator().AvisoSetEmail(email, pin);
break;
default:
break;
}
return this;
}
public MailMessage Build() => _message;
}
@@ -0,0 +1,112 @@
namespace AlquilaFacil.Emailer.Builder;
public class HtmlGenerator
{
public string GenerarMail2fa(string emailUsuario, string pin)
{
var msg = $"""
<!doctype html>
<html>
<body>
<div
style='background-color:#000000;color:#FFFFFF;font-family:"Iowan Old Style", "Palatino Linotype", "URW Palladio L", P052, serif;font-size:16px;font-weight:400;letter-spacing:0.15008px;line-height:1.5;margin:0;padding:32px 0;min-height:100%;width:100%'
>
<table
align="center"
width="100%"
style="margin:0 auto;max-width:600px;background-color:#000000"
role="presentation"
cellspacing="0"
cellpadding="0"
border="0"
>
<tbody>
<tr style="width:100%">
<td>
<div
style="color:#ffffff;font-size:16px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
>
Aqui esta su codigo OTP:
</div>
<h1
style='font-weight:bold;text-align:center;margin:0;font-family:"Nimbus Mono PS", "Courier New", "Cutive Mono", monospace;font-size:32px;padding:16px 24px 16px 24px'
>
{pin}
</h1>
<div
style="color:#868686;font-size:16px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
>
Este codigo es del usuario con email:{emailUsuario}
</div>
<div
style="color:#868686;font-size:14px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
>
Si no sabes para que es el email, ignoralo.
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
""";
return msg;
}
public string AvisoSetEmail(string emailUsuario, string emailreq)
{
var msg = $"""
<!doctype html>
<html>
<body>
<div
style='background-color:#000000;color:#FFFFFF;font-family:"Iowan Old Style", "Palatino Linotype", "URW Palladio L", P052, serif;font-size:16px;font-weight:400;letter-spacing:0.15008px;line-height:1.5;margin:0;padding:32px 0;min-height:100%;width:100%'
>
<table
align="center"
width="100%"
style="margin:0 auto;max-width:600px;background-color:#000000"
role="presentation"
cellspacing="0"
cellpadding="0"
border="0"
>
<tbody>
<tr style="width:100%">
<td>
<div
style="color:#ffffff;font-size:16px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
>
Aviso:
</div>
<h1
style='font-weight:bold;text-align:center;margin:0;font-family:"Nimbus Mono PS", "Courier New", "Cutive Mono", monospace;font-size:32px;padding:16px 24px 16px 24px'
>
Se seteo este email : {emailreq}, como email de respaldo
</h1>
<div
style="color:#868686;font-size:16px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
>
</div>
<div
style="color:#868686;font-size:14px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
>
Si no sabes para que es el email, ignoralo.
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
""";
return msg;
}
}
@@ -0,0 +1,11 @@
namespace AlquilaFacil.Emailer.Sender;
using AlquilaFacil.Emailer.Builder;
public class AvisoEmailSender : EmailSender
{
public void Send(string emailusu, string emailreq)
{
var mail = new EmailBuilder().Body(emailusu, emailreq, "aviso").To(emailreq).Subject("AvisoEmail").Build();
base.Send(mail);
}
}
+50
View File
@@ -0,0 +1,50 @@
using System.Net.Mail;
using System.Net;
using System.Text.Json;
namespace AlquilaFacil.Emailer.Sender;
public class EmailSender
{
protected static SmtpClient? smtp = null;
protected void configSmtp(MailMessage mail)
{
var jsonContent = File.ReadAllText("settings.json");
var options = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent);
if (options == null) return;
bool check = options.ContainsKey("smtpHost");
check = options.ContainsKey("smtpPort");
check = options.ContainsKey("emailAddr");
check = options.ContainsKey("emailPass");
if (check == false) return;
mail.Sender = new MailAddress(options["emailAddr"]);
mail.From = new MailAddress(options["emailAddr"]);
if (null != smtp) return;
smtp = new();
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.EnableSsl = true;
smtp.Host = options["smtpHost"];
smtp.Port = int.Parse(options["smtpPort"].ToString());
smtp.Credentials = new NetworkCredential(options["emailAddr"], options["emailPass"]);
}
public virtual void Send(MailMessage message)
{
configSmtp(message);
if (smtp == null) return;
try
{
smtp.Send(message);
message.Dispose();
}
catch (Exception)
{
throw;
}
}
}
@@ -0,0 +1,13 @@
namespace AlquilaFacil.Emailer.Sender;
using AlquilaFacil.Emailer.Builder;
public class OtpEmailSender : EmailSender
{
public void Send(string To, string email, string pin)
{
var mail = new EmailBuilder().To(To).Body(email, pin).Subject("Mail de Recuperacion").Build();
base.Send(mail);
}
}
+9
View File
@@ -35,6 +35,15 @@ builder.Services.AddCors(options =>
.AllowAnyMethod() .AllowAnyMethod()
.AllowCredentials(); .AllowCredentials();
}); });
options.AddPolicy("AllowSvelteAppv6",
builder =>
{
builder.WithOrigins("http://[::1]:5173")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
}); });
var app = builder.Build(); var app = builder.Build();
+7 -2
View File
@@ -1,4 +1,9 @@
{ {
"usr":"nwFNMLJcn5m0owbzeXMs", "usr": "nwFNMLJcn5m0owbzeXMs",
"scrt":"Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70" "scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70",
"connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none",
"smtpHost": "smtp.gmail.com",
"smtpPort": "587",
"emailAddr": "emailerpasillo@gmail.com",
"emailPass": "hgwa mznx xuff exws"
} }
+7 -2
View File
@@ -1,4 +1,9 @@
{ {
"usr":"nwFNMLJcn5m0owbzeXMs", "usr": "nwFNMLJcn5m0owbzeXMs",
"scrt":"Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70" "scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70",
"connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none",
"smtpHost": "smtp.gmail.com",
"smtpPort": "587",
"emailAddr": "emailerpasillo@gmail.com",
"emailPass": "hgwa mznx xuff exws"
} }
+72 -4
View File
@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Entidades; namespace Entidades;
@@ -54,9 +56,29 @@ public partial class AlquilaFacilContext : DbContext
public virtual DbSet<Venta> Ventas { get; set; } public virtual DbSet<Venta> Ventas { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. {
=> optionsBuilder.UseMySQL("Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none"); if (!optionsBuilder.IsConfigured)
{
try
{
var jsonContent = File.ReadAllText("settings.json");
var options = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent);
if (options != null && options.ContainsKey("connectiondb"))
{
optionsBuilder.UseMySQL(options["connectiondb"]);
}
else
{
throw new Exception("No se encontró la clave 'connectiondb' en el archivo settings.json");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error al configurar la conexión a la base de datos: {ex.Message}");
throw;
}
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
modelBuilder.Entity<Canon>(entity => modelBuilder.Entity<Canon>(entity =>
@@ -111,6 +133,12 @@ public partial class AlquilaFacilContext : DbContext
entity.Property(e => e.Email) entity.Property(e => e.Email)
.HasMaxLength(50) .HasMaxLength(50)
.HasColumnName("email"); .HasColumnName("email");
entity.Property(e => e.EmailRecuperacion)
.HasMaxLength(50)
.HasColumnName("emailRecuperacion");
entity.Property(e => e.F2a)
.HasMaxLength(6)
.HasColumnName("f2a");
entity.Property(e => e.Habilitado) entity.Property(e => e.Habilitado)
.HasDefaultValueSql("b'1'") .HasDefaultValueSql("b'1'")
.HasColumnType("bit(1)") .HasColumnType("bit(1)")
@@ -416,9 +444,49 @@ public partial class AlquilaFacilContext : DbContext
entity.Property(e => e.Id) entity.Property(e => e.Id)
.HasColumnType("int(11)") .HasColumnType("int(11)")
.HasColumnName("id"); .HasColumnName("id");
entity.Property(e => e.Habilitado)
.IsRequired()
.HasDefaultValueSql("'1'")
.HasColumnName("habilitado");
entity.Property(e => e.Nombre) entity.Property(e => e.Nombre)
.HasMaxLength(12) .HasMaxLength(12)
.HasColumnName("nombre"); .HasColumnName("nombre");
entity.HasMany(d => d.IdGrupoHijos).WithMany(p => p.IdGrupoPadres)
.UsingEntity<Dictionary<string, object>>(
"GrupoSubgrupo",
r => r.HasOne<Grupo>().WithMany()
.HasForeignKey("IdGrupoHijo")
.HasConstraintName("Grupo_Subgrupo_ibfk_2"),
l => l.HasOne<Grupo>().WithMany()
.HasForeignKey("IdGrupoPadre")
.HasConstraintName("Grupo_Subgrupo_ibfk_1"),
j =>
{
j.HasKey("IdGrupoPadre", "IdGrupoHijo").HasName("PRIMARY");
j.ToTable("Grupo_Subgrupo");
j.HasIndex(new[] { "IdGrupoHijo" }, "IdGrupoHijo");
j.IndexerProperty<int>("IdGrupoPadre").HasColumnType("int(11)");
j.IndexerProperty<int>("IdGrupoHijo").HasColumnType("int(11)");
});
entity.HasMany(d => d.IdGrupoPadres).WithMany(p => p.IdGrupoHijos)
.UsingEntity<Dictionary<string, object>>(
"GrupoSubgrupo",
r => r.HasOne<Grupo>().WithMany()
.HasForeignKey("IdGrupoPadre")
.HasConstraintName("Grupo_Subgrupo_ibfk_1"),
l => l.HasOne<Grupo>().WithMany()
.HasForeignKey("IdGrupoHijo")
.HasConstraintName("Grupo_Subgrupo_ibfk_2"),
j =>
{
j.HasKey("IdGrupoPadre", "IdGrupoHijo").HasName("PRIMARY");
j.ToTable("Grupo_Subgrupo");
j.HasIndex(new[] { "IdGrupoHijo" }, "IdGrupoHijo");
j.IndexerProperty<int>("IdGrupoPadre").HasColumnType("int(11)");
j.IndexerProperty<int>("IdGrupoHijo").HasColumnType("int(11)");
});
}); });
modelBuilder.Entity<Log>(entity => modelBuilder.Entity<Log>(entity =>
+6 -1
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Entidades; namespace Entidades;
@@ -23,6 +23,11 @@ public partial class Cliente
public ulong Habilitado { get; set; } public ulong Habilitado { get; set; }
public string? EmailRecuperacion { get; set; }
public string? F2a { get; set; }
public virtual ICollection<Contrato> ContratoDniinquilinoNavigations { get; set; } = new List<Contrato>(); public virtual ICollection<Contrato> ContratoDniinquilinoNavigations { get; set; } = new List<Contrato>();
public virtual ICollection<Contrato> ContratoDnipropietarioNavigations { get; set; } = new List<Contrato>(); public virtual ICollection<Contrato> ContratoDnipropietarioNavigations { get; set; } = new List<Contrato>();
+5
View File
@@ -0,0 +1,5 @@
namespace Entidades.Dto;
public class CrearAccionesDto
{
public string Descripcion { get; set; } = "";
}
+16
View File
@@ -0,0 +1,16 @@
namespace Entidades.Dto;
public class GrupoDto
{
public int idgrupo { get; set; }
public string Nombre { get; set; } = "";
public bool Habilitado { get; set; } = false;
public HashSet<string> GruposIncluidos { get; set; } = [];
public List<PermisoDto> Permisos { get; set; } = [];
}
public class PermisoDto
{
public int Id { get; set; }
public string Descripcion { get; set; } = "";
}
+7
View File
@@ -0,0 +1,7 @@
public class PreContratoDataDto{
public bool TieneOpcionDeVenta { get; set; }
public decimal? MontoOpcionDeVenta { get; set; }
public string? MonedaOpcionDeVenta { get; set; }
public int DuracionEnMeses { get; set; }
public int? FrecuenciaAumentoEnMeses { get; set; }
}
+6
View File
@@ -0,0 +1,6 @@
namespace Entidades.Dto;
public class PropietarioDto{
public string Nombre {get; set;} = "";
public long Dni {get; set;}
public string Apellido {get; set;} = "";
}
+12
View File
@@ -0,0 +1,12 @@
namespace Entidades.Dto;
public class UsuarioDto
{
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 Email { get; set; } = null!;
public string? EmailRecuperacion { get; set; } = null!;
}
+1 -1
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Entidades; namespace Entidades;
+27 -2
View File
@@ -1,17 +1,42 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Entidades; namespace Entidades;
public partial class Grupo public partial class Grupo : IComponenteSeguridad
{ {
public int Id { get; set; } public int Id { get; set; }
public string Nombre { get; set; } = null!; public string Nombre { get; set; } = null!;
public bool? Habilitado { get; set; }
[JsonIgnore]
public virtual ICollection<Grupo> IdGrupoHijos { get; set; } = new List<Grupo>();
[JsonIgnore]
public virtual ICollection<Grupo> IdGrupoPadres { get; set; } = new List<Grupo>();
[JsonIgnore] [JsonIgnore]
public virtual ICollection<Cliente> Idclientes { get; set; } = new List<Cliente>(); public virtual ICollection<Cliente> Idclientes { get; set; } = new List<Cliente>();
public virtual ICollection<Permiso> Idpermisos { get; set; } = new List<Permiso>(); public virtual ICollection<Permiso> Idpermisos { get; set; } = new List<Permiso>();
public void ObtenerPermisos(HashSet<Permiso> permisos, HashSet<int> visitados)
{
if (visitados.Contains(Id)) return;
visitados.Add(Id);
if (this.Habilitado == false) return;
var componentes = new List<IComponenteSeguridad>();
componentes.AddRange(Idpermisos);
componentes.AddRange(IdGrupoHijos);
foreach (var componente in componentes)
{
componente.ObtenerPermisos(permisos, visitados);
}
}
} }
+9
View File
@@ -0,0 +1,9 @@
namespace Entidades.Informes;
public class InformePagos
{
public int Mes { get; set; }
public int Realizados { get; set; }
public int Atrasados {get;set;}
public int Sin_realizar {get;set;}
}
+1 -1
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Entidades; namespace Entidades;
+6 -1
View File
@@ -4,7 +4,7 @@ using System.Text.Json.Serialization;
namespace Entidades; namespace Entidades;
public partial class Permiso public partial class Permiso:IComponenteSeguridad
{ {
public int Id { get; set; } public int Id { get; set; }
@@ -12,4 +12,9 @@ public partial class Permiso
[JsonIgnore] [JsonIgnore]
public virtual ICollection<Grupo> Idgrupos { get; set; } = new List<Grupo>(); public virtual ICollection<Grupo> Idgrupos { get; set; } = new List<Grupo>();
public void ObtenerPermisos(HashSet<Permiso> permisos, HashSet<int> visitados)
{
permisos.Add(this);
}
} }
@@ -0,0 +1,5 @@
namespace Entidades;
public interface IComponenteSeguridad {
public void ObtenerPermisos(HashSet<Permiso> permisos, HashSet<int> visitados);
}
+1 -1
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Entidades; namespace Entidades;
+4
View File
@@ -4,3 +4,7 @@ run:
clean: clean:
rm *.cs rm *.cs
table:
dotnet ef dbcontext scaffold "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none" MySql.EntityFrameworkCore -o ./tmp
./convert_to_pascalcase.sh
BIN
View File
Binary file not shown.
+20
View File
@@ -9,6 +9,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@sveltestrap/sveltestrap": "^6.2.8", "@sveltestrap/sveltestrap": "^6.2.8",
"bootstrap": "^5.3.3",
"chartjs": "^0.3.24", "chartjs": "^0.3.24",
"svelte-routing": "^2.13.0" "svelte-routing": "^2.13.0"
}, },
@@ -206,6 +207,25 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/bootstrap": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT",
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/chartjs": { "node_modules/chartjs": {
"version": "0.3.24", "version": "0.3.24",
"license": "MIT" "license": "MIT"
+1
View File
@@ -22,6 +22,7 @@
}, },
"dependencies": { "dependencies": {
"@sveltestrap/sveltestrap": "^6.2.8", "@sveltestrap/sveltestrap": "^6.2.8",
"bootstrap": "^5.3.3",
"chartjs": "^0.3.24", "chartjs": "^0.3.24",
"svelte-routing": "^2.13.0" "svelte-routing": "^2.13.0"
} }
+21
View File
@@ -0,0 +1,21 @@
<!--
category: Design
tags: [pencil, change, update]
version: "1.0"
unicode: "ea98"
-->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1" />
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z" />
<path d="M16 5l3 3" />
</svg>

After

Width:  |  Height:  |  Size: 481 B

+19
View File
@@ -0,0 +1,19 @@
<!--
tags: [password, login, authentication, secure]
version: "1.0"
unicode: "eac7"
-->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0z" />
<path d="M15 9h.01" />
</svg>

After

Width:  |  Height:  |  Size: 679 B

+21
View File
@@ -0,0 +1,21 @@
<!--
category: System
tags: [exit, shut, unplug, close]
version: "1.4"
unicode: "eba8"
-->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2" />
<path d="M9 12h12l-3 -3" />
<path d="M18 15l3 -3" />
</svg>

After

Width:  |  Height:  |  Size: 451 B

+20
View File
@@ -0,0 +1,20 @@
<!--
category: Math
tags: [add, create, new, "+"]
version: "1.0"
unicode: "eb0b"
-->
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 5l0 14" />
<path d="M5 12l14 0" />
</svg>

After

Width:  |  Height:  |  Size: 345 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-user"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" /><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" /></svg>

After

Width:  |  Height:  |  Size: 411 B

+162 -130
View File
@@ -1,169 +1,201 @@
<script lang="ts"> <script lang="ts">
import Login from "./paginas/login.svelte"; import "bootstrap/dist/css/bootstrap.min.css";
import { Router, Route, link } from 'svelte-routing'; import Login from "./paginas/login.svelte";
import MenuPage from './paginas/menu.svelte'; import { Router, Route, link } from "svelte-routing";
import ProteRoute from './Componentes/RutaProtegida.svelte'; import MenuPage from "./paginas/menu.svelte";
import InfoPage from './paginas/info.svelte'; import ProteRoute from "./Componentes/RutaProtegida.svelte";
import InqPage from "./paginas/inquilino.svelte"; import InfoPage from "./paginas/info.svelte";
import PropPage from "./paginas/propietario.svelte"; import InqPage from "./paginas/inquilino.svelte";
import MisPropiedades from "./paginas/MisPropiedades.svelte"; import PropPage from "./paginas/propietario.svelte";
import MisPropiedadesDeBaja from "./paginas/MisPropiedadesDeBaja.svelte"; import MisPropiedades from "./paginas/MisPropiedades.svelte";
import FrontAdmin from "./paginas/grupos/AdminG.svelte"; import MisPropiedadesDeBaja from "./paginas/MisPropiedadesDeBaja.svelte";
import FrontInformes from "./paginas/grupos/InformesG.svelte"; import FrontAdmin from "./paginas/grupos/AdminG.svelte";
import FrontInquilino from "./paginas/grupos/InquilinoG.svelte"; import FrontInformes from "./paginas/grupos/InformesG.svelte";
import FrontPropietario from "./paginas/grupos/PropietarioG.svelte"; import FrontInquilino from "./paginas/grupos/InquilinoG.svelte";
import PublicarPropiedad from "./paginas/PublicarPropiedad.svelte"; import FrontPropietario from "./paginas/grupos/PropietarioG.svelte";
import BusquedaPropiedades from "./paginas/BusquedaPropiedades.svelte"; import PublicarPropiedad from "./paginas/PublicarPropiedad.svelte";
import AdminUsuarios from "./paginas/AdminUsuarios.svelte"; import BusquedaPropiedades from "./paginas/BusquedaPropiedades.svelte";
import AdminPropiedades from "./paginas/AdminPropiedades.svelte"; import AdminUsuarios from "./paginas/AdminUsuarios.svelte";
import Notificaciones from "./paginas/Notificaciones.svelte"; import AdminPropiedades from "./paginas/AdminPropiedades.svelte";
import ControlAlquileresInquilino from "./paginas/ControlAlquileresInquilino.svelte"; import Notificaciones from "./paginas/Notificaciones.svelte";
import ControlAlquileresPropietario from "./paginas/ControlAlquileresPropietario.svelte"; import ControlAlquileresInquilino from "./paginas/ControlAlquileresInquilino.svelte";
import ContratosPropietario from "./paginas/ContratosPropietario.svelte"; import ControlAlquileresPropietario from "./paginas/ControlAlquileresPropietario.svelte";
import ContratoInquilino from "./paginas/ContratoInquilino.svelte"; import ContratosPropietario from "./paginas/ContratosPropietario.svelte";
import Informes from "./paginas/Informes.svelte"; import ContratoInquilino from "./paginas/ContratoInquilino.svelte";
import CompraYVentas from "./paginas/CompraYVenta.svelte"; import Informes from "./paginas/Informes.svelte";
import Ventas from "./paginas/Ventas.svelte"; import CompraYVentas from "./paginas/CompraYVenta.svelte";
import Ventas from "./paginas/Ventas.svelte";
import VerLogs from "./paginas/VerLogs.svelte"; import VerLogs from "./paginas/VerLogs.svelte";
import ControlPagos from "./paginas/ControlPagos.svelte"; import ControlPagos from "./paginas/ControlPagos.svelte";
import ContratoAdmin from "./paginas/ContratoAdmin.svelte"; import ContratoAdmin from "./paginas/ContratoAdmin.svelte";
import BuscarVentas from "./paginas/BuscarVentas.svelte"; import BuscarVentas from "./paginas/BuscarVentas.svelte";
import MisPropiedadesEnVenta from "./paginas/MisPropiedadesEnVenta.svelte"; import MisPropiedadesEnVenta from "./paginas/MisPropiedadesEnVenta.svelte";
import AdminGrupos from "./paginas/AdminGrupos.svelte";
import OtroG from "./paginas/grupos/OtroG.svelte";
import GestionPemisos from "./paginas/GestionPemisos.svelte";
import UsuarioPanel from "./paginas/UsuarioPanel.svelte";
import CrearUsuario from "./paginas/CrearUsuario.svelte";
import CargarContratoAdmin from "./paginas/CargarContratoAdmin.svelte";
</script> </script>
<Router> <Router>
<!-- Plantilla path <!-- Plantilla path
<Route path=""> <Route path="">
<ProteRoute componente={}/> <ProteRoute componente={}/>
</Route> </Route>
--> -->
<Route path="/" component={Login} /> <Route path="/" component={Login} />
<Route path="/Info" component={InfoPage} /> <Route path="/Info" component={InfoPage} />
<Route path="/Menu">
<ProteRoute componente={MenuPage} />
</Route>
<Route path="/Menu"> <!--Publicar Prop
<ProteRoute componente={MenuPage} />
</Route>
<!--Publicar Prop
iedad--> iedad-->
<Route path="/accion/1"> <Route path="/accion/1">
<ProteRoute componente={PublicarPropiedad}/> <ProteRoute componente={PublicarPropiedad} />
</Route> </Route>
<!--Mis Propiedades--> <!--Mis Propiedades-->
<Route path="/accion/2"> <Route path="/accion/2">
<ProteRoute componente={MisPropiedades}/> <ProteRoute componente={MisPropiedades} />
</Route> </Route>
<!--Buscar Propiedades--> <!--Buscar Propiedades-->
<Route path="/accion/3"> <Route path="/accion/3">
<ProteRoute componente={BusquedaPropiedades}/> <ProteRoute componente={BusquedaPropiedades} />
</Route> </Route>
<!--Crear Cuenta Inquilino--> <!--Crear Cuenta Inquilino-->
<Route path="/accion/4"> <Route path="/accion/4">
<ProteRoute componente={InqPage}/> <ProteRoute componente={InqPage} />
</Route> </Route>
<!--Crear Cuenta Propietario-->
<Route path="/accion/5">
<ProteRoute componente={PropPage}/>
</Route>
<!--Crear Cuenta Propietario--> <!--Crear Cuenta Propietario-->
<Route path="/accion/6"> <Route path="/accion/5">
<ProteRoute componente={Informes}/> <ProteRoute componente={PropPage} />
</Route> </Route>
<!--Ver Logs--> <!--Informes-->
<Route path="/accion/7"> <Route path="/accion/6">
<ProteRoute componente={VerLogs}/> <ProteRoute componente={Informes} />
</Route> </Route>
<!--Administrar Propiedades Dadas de Baja--> <!--Ver Logs-->
<Route path="/accion/8"> <Route path="/accion/7">
<ProteRoute componente={MisPropiedadesDeBaja}/> <ProteRoute componente={VerLogs} />
</Route> </Route>
<!-- Pantalla Control Usuarios --> <!--Administrar Propiedades Dadas de Baja-->
<Route path="/accion/9"> <Route path="/accion/8">
<ProteRoute componente={AdminUsuarios}/> <ProteRoute componente={MisPropiedadesDeBaja} />
</Route> </Route>
<!-- Pantalla Control Propiedades --> <!-- Pantalla Control Usuarios -->
<Route path="/accion/10"> <Route path="/accion/9">
<ProteRoute componente={AdminPropiedades}/> <ProteRoute componente={AdminUsuarios} />
</Route> </Route>
<!-- Pantalla Control Alquileres Inquilino --> <!-- Pantalla Control Propiedades -->
<Route path="/accion/11"> <Route path="/accion/10">
<ProteRoute componente={ControlAlquileresInquilino}/> <ProteRoute componente={AdminPropiedades} />
</Route> </Route>
<!-- Pantalla Control Alquileres Propietario --> <!-- Pantalla Control Alquileres Inquilino -->
<Route path="/accion/12"> <Route path="/accion/11">
<ProteRoute componente={ControlAlquileresPropietario}/> <ProteRoute componente={ControlAlquileresInquilino} />
</Route> </Route>
<!-- Compra y Ventas --> <!-- Pantalla Control Alquileres Propietario -->
<Route path="/accion/13"> <Route path="/accion/12">
<ProteRoute componente={CompraYVentas}/> <ProteRoute componente={ControlAlquileresPropietario} />
</Route> </Route>
<!-- Control Pago Contratos Incumplidos --> <!-- Compra y Ventas -->
<Route path="/accion/14"> <Route path="/accion/13">
<ProteRoute componente={ControlPagos}/> <ProteRoute componente={CompraYVentas} />
</Route> </Route>
<!-- VerPropiedadesEnVenta --> <!-- Control Pago Contratos Incumplidos -->
<Route path="/accion/15"> <Route path="/accion/14">
<ProteRoute componente={MisPropiedadesEnVenta}/> <ProteRoute componente={ControlPagos} />
</Route> </Route>
<!-- Buscar Ventas --> <!-- VerPropiedadesEnVenta -->
<Route path="/accion/16"> <Route path="/accion/15">
<ProteRoute componente={BuscarVentas}/> <ProteRoute componente={MisPropiedadesEnVenta} />
</Route> </Route>
<!-- Pagina Ventas --> <!-- Buscar Ventas -->
<Route path="/Ventas"> <Route path="/accion/16">
<ProteRoute componente={Ventas}/> <ProteRoute componente={BuscarVentas} />
</Route> </Route>
<!--Paginas info Grupo--> <!-- Creacion Permisos -->
<Route path="/grupo/Inquilino"> <Route path="/accion/17">
<ProteRoute componente={FrontInquilino}/> <ProteRoute componente={GestionPemisos} />
</Route> </Route>
<Route path="/grupo/Propietario">
<ProteRoute componente={FrontPropietario}/>
</Route>
<Route path="/grupo/Admin">
<ProteRoute componente={FrontAdmin}/>
</Route>
<Route path="/grupo/Informes">
<ProteRoute componente={FrontInformes}/>
</Route>
<!--Notificaciones--> <!-- Gestion Grupos -->
<Route path="/notificaciones"> <Route path="/accion/18">
<ProteRoute componente={Notificaciones}/> <ProteRoute componente={AdminGrupos} />
</Route> </Route>
<!--Contratos Propietarios--> <!-- Crear Usuario -->
<Route path="/propietario/contratos"> <Route path="/accion/19">
<ProteRoute componente={ContratosPropietario}/> <ProteRoute componente={CrearUsuario} />
</Route> </Route>
<!--Contratos Inquilino--> <!-- Cargar Contrato Admin -->
<Route path="/inquilino/contratos"> <Route path="/accion/20">
<ProteRoute componente={ContratoInquilino}/> <ProteRoute componente={CargarContratoAdmin}/>
</Route> </Route>
<!--Contratos Admin--> <!-- Pagina Ventas -->
<Route path="/admin/contratos"> <Route path="/Ventas">
<ProteRoute componente={ContratoAdmin}/> <ProteRoute componente={Ventas} />
</Route> </Route>
<!--Paginas info Grupo-->
<Route path="/grupo/Inquilino">
<ProteRoute componente={FrontInquilino} />
</Route>
<Route path="/grupo/Propietario">
<ProteRoute componente={FrontPropietario} />
</Route>
<Route path="/grupo/Admin">
<ProteRoute componente={FrontAdmin} />
</Route>
<Route path="/grupo/Informes">
<ProteRoute componente={FrontInformes} />
</Route>
<Route path="/grupo/:id" let:params>
<ProteRoute componente={{ OtroG, params }} />
</Route>
<!--Notificaciones-->
<Route path="/notificaciones">
<ProteRoute componente={Notificaciones} />
</Route>
<Route path="/usuario">
<ProteRoute componente={UsuarioPanel} />
</Route>
<!--Contratos Propietarios-->
<Route path="/propietario/contratos">
<ProteRoute componente={ContratosPropietario} />
</Route>
<!--Contratos Inquilino-->
<Route path="/inquilino/contratos">
<ProteRoute componente={ContratoInquilino} />
</Route>
<!--Contratos Admin-->
<Route path="/admin/contratos">
<ProteRoute componente={ContratoAdmin} />
</Route>
</Router> </Router>
+41
View File
@@ -0,0 +1,41 @@
<script>
import { onMount } from "svelte";
let isHovered = $state(false);
let { handleclick } = $props();
function handleMouseEnter() {
isHovered = true;
}
function handleMouseLeave() {
isHovered = false;
}
</script>
<button
class="position-fixed bottom-0 end-0 m-3 p-3 bg-secondary rounded-circle transition-element border"
class:rotated={isHovered}
class:active={isHovered}
style="width: 5rem; height: 5rem;"
onmouseenter={handleMouseEnter}
onmouseleave={handleMouseLeave}
onclick={handleclick}
>
<img
src="/plus.svg"
alt="añadir"
style="width: 2.5rem; height: 2.5rem; filter: invert(1);"
/>
</button>
<style>
.transition-element {
transition: transform 0.3s ease-in-out;
}
.rotated {
transform: rotate(90deg);
}
</style>
@@ -1,59 +1,56 @@
<script> <script>
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from "svelte";
import Chart from 'chart.js/auto'; import { Chart } from "chart.js/auto";
let {chartData, typec='bar'} = $props(); let { chartData, typec = "bar" } = $props();
let chartContainer; let chartContainer;
let instance; let instance;
onDestroy(() => {
onDestroy(() => { if (instance) {
if (instance) { instance.destroy();
instance.destroy(); }
}
});
const createChart = () => {
if (instance) {
instance.destroy();
}
const ctx = chartContainer.getContext('2d');
instance = new Chart(ctx, {
type: typec,
data: {
labels: chartData.labels,
datasets: chartData.datasets.map(dataset => ({
label: dataset.label,
data: dataset.data.map(x => String(x)),
borderWidth: dataset.borderWidth
}))
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
},
scales: {
x: {
beginAtZero: true,
},
y: {
beginAtZero: true,
},
},
},
}); });
};
onMount(createChart);
$effect(createChart);
const createChart = () => {
if (instance) {
instance.destroy();
}
const ctx = chartContainer.getContext("2d");
instance = new Chart(ctx, {
type: typec,
data: {
labels: chartData.labels,
datasets: chartData.datasets.map((dataset) => ({
label: dataset.label,
data: dataset.data.map((x) => String(x)),
borderWidth: dataset.borderWidth,
})),
},
options: {
responsive: true,
plugins: {
legend: {
position: "top",
},
},
scales: {
x: {
beginAtZero: true,
},
y: {
beginAtZero: true,
},
},
},
});
};
onMount(createChart);
$effect(createChart);
</script> </script>
<div class="card card-body"> <div class="card card-body">
<canvas bind:this={chartContainer}></canvas> <canvas bind:this={chartContainer}></canvas>
</div> </div>
+270 -53
View File
@@ -1,66 +1,283 @@
<script> <script>
import { CardHeader, CardTitle, Button, Card, Input, Form, CardBody, FormGroup } from '@sveltestrap/sveltestrap'; import {
import { navigate } from 'svelte-routing'; CardHeader,
import { urlG } from "../stores/urlStore"; CardTitle,
Button,
Card,
Input,
Form,
CardBody,
FormGroup,
Modal,
} from "@sveltestrap/sveltestrap";
import { navigate } from "svelte-routing";
import { urlG } from "../stores/urlStore";
import ModalEstatico from "./ModalEstatico.svelte";
import { parse } from "svelte/compiler";
let email = $state("") let email = $state("");
let contraseña = $state("") let contraseña = $state("");
let errorMessage = $state("") let errorMessage = $state("");
// @ts-ignore // @ts-ignore
async function submitForm(event) { async function submitForm(event) {
event.preventDefault(); event.preventDefault();
const data = {email, contraseña}; const data = { email, contraseña };
try{ try {
const response = await fetch(String($urlG)+"/api/login",{ const response = await fetch(String($urlG) + "/api/login", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify(data), body: JSON.stringify(data),
credentials: "include" credentials: "include",
}); });
if (!response.ok){ if (!response.ok) {
const errorData = await response.json() const errorData = await response.json();
errorMessage = errorData.message; errorMessage = errorData.message;
return; return;
} }
const ret = await response.json(); const ret = await response.json();
localStorage.setItem('email', ret.email); localStorage.setItem("email", ret.email);
sessionStorage.setItem('token', ret.token); sessionStorage.setItem("token", ret.token);
//setTimeout(() => console.log("50ms") ,50); //setTimeout(() => console.log("50ms") ,50);
navigate(ret.redirect); navigate(ret.redirect);
} catch (e) { } catch (e) {}
} }
} let showrecuperarmodal = $state(false);
let modaldata = $state("");
let emailr = $state("");
let emailrecovery = $state("");
async function SubmitRecuperarContraseñaEmail(e) {
e.preventDefault();
if (emailrecovery == "") emailrecovery = emailr;
try {
const req = await fetch($urlG + "/api/recuperarUsuario", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
Email: emailr,
EmailRecuperacion: emailrecovery,
}),
});
const data = await req.json();
showrecuperarmodal = false;
if (req.ok) {
showf2amodal = true;
return;
}
//hago esto para que no puedan haber errores en caso de que intente recuperar 1 cuenta, aborte y intente recuperar una segunda
emailr = "";
emailrecovery = "";
//
modaldata = data.message;
} catch {
modaldata = "Fallo al hacer la request";
}
}
let showf2amodal = $state(false);
async function submitf2a(e) {
e.preventDefault();
const inputs = document.querySelectorAll(".otp-input");
let otppin = "";
inputs.forEach((x) => {
otppin += x.value.trim();
});
if (otppin.length != 6) {
modaldata = "la longitud del pin es incorrecta";
return;
}
if (emailr == "") {
modaldata = "Fallo vuelva a intentar";
return;
}
try {
const req = await fetch($urlG + "/api/ingresar2fa", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ Pin: otppin, Email: emailr }),
});
const data = await req.json();
if (req.ok) {
sessionStorage.setItem("token", data.token);
localStorage.setItem("email", emailr);
showf2amodal = false;
navigate("/usuario");
}
} catch {
modaldata = "Fallo al hacer la request";
}
}
function handleInput(index) {
const otpInputs = document.querySelectorAll(".otp-input");
console.log(otpInputs);
if (index === 5) return;
otpInputs[index+1].focus();
}
</script> </script>
<Card class="position-sticky top-50 start-50 translate-middle-x border border-success" style="width: 20rem; height: auto;" theme="auto" outline> {#if modaldata}
<CardHeader> <ModalEstatico close={() => !!(modaldata = "")} payload={modaldata} />
<CardTitle>Iniciar Sesión</CardTitle> {/if}
</CardHeader>
<CardBody> <Card
<Form on:submit={submitForm}> class="position-sticky top-50 start-50 translate-middle-x border border-success"
<FormGroup floating label="Email"> style="width: 20rem; height: auto;"
<Input type="email" placeholder="ejemplo@mail.com" bind:value={email} required/> theme="auto"
</FormGroup> outline
<FormGroup floating label="Contraseña"> >
<Input type="password" placeholder="*********" bind:value={contraseña} required/> <CardHeader>
</FormGroup> <CardTitle>Iniciar Sesión</CardTitle>
<FormGroup> </CardHeader>
<Button color="primary" type="submit">Ingresar</Button> <CardBody>
</FormGroup> <Form onsubmit={(e) => submitForm(e)}>
</Form> <FormGroup floating label="Email">
{#if errorMessage} <Input
<div class='alert alert-warning alert-dismissible fade show' role='alert'> type="email"
<strong>{errorMessage}</strong> placeholder="ejemplo@mail.com"
<button type="button" class="btn-close close" aria-label="Close" data-bs-dismiss="alert"></button> bind:value={email}
required
/>
</FormGroup>
<FormGroup floating label="Contraseña">
<Input
type="password"
placeholder="*********"
bind:value={contraseña}
required
/>
</FormGroup>
<FormGroup>
<Button color="primary" type="submit">Ingresar</Button>
</FormGroup>
</Form>
{#if errorMessage}
<div
class="alert alert-warning alert-dismissible fade show"
role="alert"
>
<strong>{errorMessage}</strong>
<button
type="button"
class="btn-close close"
aria-label="Close"
data-bs-dismiss="alert"
></button>
</div>
{/if}
<hr />
<button class="btn btn-link" onclick={() => {showrecuperarmodal = true; window.scrollTo(0,0);}}
>Recuperar Cuenta</button
>
</CardBody>
</Card>
{#if showf2amodal}
<div
class="modal"
tabindex="-1"
style="display: block; background-color: rgba(0, 0, 0, 0.3);"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Recuperar Cuenta</h5>
</div>
<form onsubmit={submitf2a}>
<div class="modal-body">
<div class="mb-3">
<label for="f2a" class="form-label">
Ingrese el codigo que tendria que haber llegado a su email
</label>
<div class="d-flex gap-2 justify-content-center">
{#each Array(6) as _, i}
<input
type="text"
class="form-control text-center otp-input"
maxlength="1"
inputmode="numeric"
pattern="[0-9]*"
style="width: 3rem;"
oninput={()=> handleInput(i)}
/>
{/each}
</div>
</div>
</div>
<div class="modal-footer d-flex">
<button type="submit" class="btn btn-primary">
Enviar
</button>
</div>
</form>
</div>
</div>
</div>
{/if}
{#if showrecuperarmodal}
<div
class="modal"
tabindex="-1"
style="display: block; background-color: rgba(0, 0, 0, 0.3);"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Recuperar Cuenta</h5>
<button
type="button"
class="btn-close"
aria-label="Close"
onclick={() => (showrecuperarmodal = false)}
></button>
</div>
<div class="modal-body">
<form onsubmit={SubmitRecuperarContraseñaEmail}>
<div class="mb-3">
<label for="Email" class="form-label">Email*</label>
<input
type="email"
class="form-control"
id="Email"
placeholder="Ingresa tu email"
required
bind:value={emailr}
/>
</div>
<div class="mb-3">
<label for="recoveryEmail" class="form-label"
>Email Recuperacion</label
>
<input
type="email"
class="form-control"
id="recoveryEmail"
placeholder="Ingresa tu email de recuperacion"
bind:value={emailrecovery}
/>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary"
>Enviar</button
>
</div>
</form>
</div>
</div>
</div>
</div> </div>
{/if} {/if}
</CardBody>
</Card>
+58 -25
View File
@@ -1,10 +1,11 @@
<script lang="ts"> <script lang="ts">
import type { GaranteDto } from "../types"; import type { GaranteDto, PreContratoData } from "../types";
let { onClose, onSubmit, maxGarantes }: { let { onClose, onSubmit, maxGarantes, datosprecontrato }: {
onClose: () => void, onClose: () => void,
onSubmit: (garantes: GaranteDto[]) => void, onSubmit: (garantes: GaranteDto[]) => void,
maxGarantes: number maxGarantes: number,
datosprecontrato: PreContratoData,
} = $props(); } = $props();
let cantGarantes: number = $state(0); let cantGarantes: number = $state(0);
@@ -21,6 +22,7 @@
Domiciliolaboral: "" Domiciliolaboral: ""
}); });
function handleSubmit(e: Event) { function handleSubmit(e: Event) {
e.preventDefault(); e.preventDefault();
onSubmit(garantes); onSubmit(garantes);
@@ -48,6 +50,7 @@
} }
</script> </script>
<div class="modal fade show" tabindex="-1" role="dialog" style="display: block; background-color: rgba(0, 0, 0, 0.5);"> <div class="modal fade show" tabindex="-1" role="dialog" style="display: block; background-color: rgba(0, 0, 0, 0.5);">
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
@@ -55,6 +58,43 @@
<h5 class="modal-title">Nuevo Alquiler - Garantes</h5> <h5 class="modal-title">Nuevo Alquiler - Garantes</h5>
<button class="btn-close" onclick={onClose} aria-label="Close"></button> <button class="btn-close" onclick={onClose} aria-label="Close"></button>
</div> </div>
<div class="card">
<div class="card-body">
<h5>Detalles del Precontrato</h5>
<hr />
<!-- Opción de Venta -->
<div class="mb-3">
<p class="form-label"><strong>Opción de Venta:</strong></p>
<div>
{#if datosprecontrato.tieneOpcionDeVenta}
<span class="badge bg-success" id="tieneOpcionDeVenta"></span>
{:else}
<span class="badge bg-secondary" id="noTieneOpcionDeVenta">No</span>
{/if}
</div>
</div>
{#if datosprecontrato.tieneOpcionDeVenta}
<!-- Monto y Moneda de Opción de Venta (visible solo si hay opción) -->
<div class="mb-3" id="opcionVentaDetalles">
<p class="form-label"><strong>Monto de Opción de Venta:</strong></p>
<p class="form-control-plaintext" id="montoOpcionDeVenta">{datosprecontrato.montoOpcionDeVenta} {datosprecontrato.monedaOpcionDeVenta}</p>
</div>
{/if}
<!-- Duración del Contrato -->
<div class="mb-3">
<p class="form-label"><strong>Duración del Contrato:</strong></p>
<p class="form-control-plaintext" id="duracionEnMeses">{datosprecontrato.duracionEnMeses} Meses</p>
</div>
<!-- Frecuencia de Aumento -->
<div class="mb-3">
<p class="form-label"><strong>Frecuencia de Aumento:</strong></p>
<p class="form-control-plaintext" id="frecuenciaAumentoEnMeses">Cada {datosprecontrato.frecuenciaAumentoEnMeses} meses</p>
</div>
</div>
</div>
<form onsubmit={handleSubmit}> <form onsubmit={handleSubmit}>
<div class="modal-body"> <div class="modal-body">
<div class="mb-3"> <div class="mb-3">
@@ -74,39 +114,32 @@
<div class="form-group mt-3"> <div class="form-group mt-3">
<h6>Añadir Garante</h6> <h6>Añadir Garante</h6>
<div class="mb-2"> <div class="mb-2">
<label>DNI</label> <label for="dni">DNI</label>
<input type="number" class="form-control" bind:value={newGarante.Dni} required /> <input type="number" class="form-control" bind:value={newGarante.Dni} name="dni" id="dni" required />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label>Nombre</label> <label for="nombre">Nombre</label>
<input type="text" class="form-control" bind:value={newGarante.Nombre} required /> <input type="text" class="form-control" bind:value={newGarante.Nombre} name="nombre" id="nombre" required />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label>Apellido</label> <label for="apellido">Apellido</label>
<input type="text" class="form-control" bind:value={newGarante.Apellido} required /> <input type="text" class="form-control" bind:value={newGarante.Apellido} name="apellido" id="apellido" required />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label>Domicilio</label> <label for="domicilio">Domicilio</label>
<input type="text" class="form-control" bind:value={newGarante.Domicilio} required /> <input type="text" class="form-control" bind:value={newGarante.Domicilio} name="domicilio" id="domicilio" required />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label>Celular</label> <label for="celular">Celular</label>
<input type="text" class="form-control" bind:value={newGarante.Celular} required /> <input type="text" class="form-control" bind:value={newGarante.Celular} name="celular" id="celular" required />
</div> </div>
<div class="mb-2"> <div class="mb-2">
<label>Domicilio Laboral</label> <label for="domicilioLaboral">Domicilio Laboral</label>
<input type="text" class="form-control" bind:value={newGarante.Domiciliolaboral} required /> <input type="text" class="form-control" bind:value={newGarante.Domiciliolaboral} name="domicilioLaboral" id="domicilioLaboral" required />
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<button <button class="btn btn-success" type="button" onclick={addGarante}>
class="btn btn-secondary" Añadir
type="button"
onclick={() => (showAddForm = false)}
>
Cancelar
</button>
<button class="btn btn-primary" type="button" onclick={addGarante}>
Confirmar
</button> </button>
</div> </div>
</div> </div>
@@ -115,7 +148,7 @@
<!-- Tabla de garantes --> <!-- Tabla de garantes -->
{#if cantGarantes > 0} {#if cantGarantes > 0}
<div class="form-group mt-3"> <div class="form-group mt-3">
<label>Lista de Garantes</label> <p>Lista de Garantes</p>
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<thead> <thead>
<tr> <tr>
@@ -0,0 +1,137 @@
<script lang="ts">
import type { GrupoDto, PermisoDto } from "../types";
let {
onClose,
grupos,
permisos,
onSubmit,
}: {
onClose: () => void;
grupos: GrupoDto[];
permisos: PermisoDto[];
onSubmit: (a: GrupoDto) => void;
} = $props();
let data: GrupoDto = $state({
gruposIncluidos: [],
idgrupo: 0,
nombre: "",
permisos: [],
});
const handleSubmit = (e: Event) => {
e.preventDefault();
data.gruposIncluidos = grupos
.filter(
(grupo) =>
(
document.getElementById(
`grupo-${grupo.idgrupo}`,
) as HTMLInputElement
)?.checked,
)
.map((grupo) => grupo.nombre);
data.permisos = permisos.filter(
(permiso) =>
(
document.getElementById(
`permiso-${permiso.id}`,
) as HTMLInputElement
)?.checked,
);
onSubmit(data);
onClose();
};
let nombreGrupo = "";
</script>
<div
class="modal show d-block"
tabindex="-1"
role="dialog"
style="background: rgba(0, 0, 0, 0.5)"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Añadir Grupo</h5>
<button
type="button"
class="btn-close"
aria-label="Close"
onclick={onClose}
></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="nombre-grupo" class="form-label"
>Nombre del Grupo:</label
>
<input
type="text"
class="form-control"
id="nombre-grupo"
maxlength="12"
bind:value={data.nombre}
placeholder="Ingrese el nombre del grupo"
/>
<p class="fs-6 fw-light mt-1">
Cantidad de caracteres: {data.nombre.length} / 12
</p>
</div>
<div class="mb-3">
<h6>Incluir en Grupos:</h6>
{#each grupos as grupo}
<div class="form-check">
<input
type="checkbox"
class="form-check-input"
id={`grupo-${grupo.idgrupo}`}
checked={data.gruposIncluidos?.includes(
grupo.nombre,
)}
/>
<label
class="form-check-label"
for={`grupo-${grupo.idgrupo}`}
>
{grupo.nombre}
</label>
</div>
{/each}
</div>
<div>
<h6>Asignar Permisos:</h6>
{#each permisos as permiso}
<div class="form-check">
<input
type="checkbox"
class="form-check-input"
id={`permiso-${permiso.id}`}
checked={data.permisos?.some(
(p) => p.id === permiso.id,
)}
/>
<label
class="form-check-label"
for={`permiso-${permiso.id}`}
>
{permiso.descripcion}
</label>
</div>
{/each}
</div>
</div>
<div class="modal-footer d-flex justify-content-center">
<button class="btn btn-primary w-100" onclick={handleSubmit}
>Guardar Grupo</button
>
</div>
</div>
</div>
</div>
@@ -0,0 +1,110 @@
<script lang="ts">
import type { GrupoDto, PermisoDto } from "../types";
let {
onClose,
data = $bindable(),
grupos,
permisos,
onSubmit,
}: {
onClose: () => void;
data: GrupoDto;
grupos: GrupoDto[];
permisos: PermisoDto[];
onSubmit: (a: GrupoDto) => void;
} = $props();
const handleSubmit = (e: Event) => {
e.preventDefault();
data.gruposIncluidos = grupos
.filter(
(grupo) =>
document.getElementById(`grupo-${grupo.idgrupo}`)?.checked,
)
.map((grupo) => grupo.nombre);
data.permisos = permisos.filter(
(permiso) =>
document.getElementById(`permiso-${permiso.id}`)?.checked,
);
onSubmit(data);
onClose();
};
</script>
<div
class="modal show d-block"
tabindex="-1"
role="dialog"
style="background: rgba(0, 0, 0, 0.5)"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">
Selecciona una opción
</h5>
<button
type="button"
class="btn-close"
aria-label="Close"
onclick={onClose}
></button>
</div>
<form onsubmit={(e) => handleSubmit(e)}>
<div class="modal-body">
<div class="mb-3">
<h6>Grupos:</h6>
{#each grupos as grupo}
<div class="form-check">
<input
type="checkbox"
class="form-check-input"
id={`grupo-${grupo.idgrupo}`}
checked={data.gruposIncluidos?.includes(
grupo.nombre,
)}
/>
<label
class="form-check-label"
for={`grupo-${grupo.idgrupo}`}
>
{grupo.nombre}
</label>
</div>
{/each}
</div>
<div>
<h6>Permisos:</h6>
{#each permisos as permiso}
<div class="form-check">
<input
type="checkbox"
class="form-check-input"
id={`permiso-${permiso.id}`}
checked={data.permisos?.some(
(p) => p.id === permiso.id,
)}
/>
<label
class="form-check-label"
for={`permiso-${permiso.id}`}
>
{permiso.descripcion}
</label>
</div>
{/each}
</div>
</div>
<div class="modal-footer d-flex justify-content-center">
<button class="btn btn-primary w-100" type="submit"
>Guardar</button
>
</div>
</form>
</div>
</div>
</div>
@@ -0,0 +1,88 @@
<script lang="ts">
import { onMount } from "svelte";
import type { PermisoDto } from "../types";
let {
permiso = $bindable(),
onClose,
onSubmit,
modalTitle = "Modificar Permiso",
}: {
permiso: PermisoDto;
onClose: (a: string) => void;
onSubmit: (arg0: PermisoDto) => void;
modalTitle: string;
} = $props();
const maxChars = $state(25);
let remaining: number = $state(25);
const ogdesc: string = permiso.descripcion;
function saveChanges(e:Event) {
e.preventDefault();
onSubmit(permiso);
onClose(ogdesc);
}
function updateRemaining(event: Event) {
const inputValue = (event.target as HTMLInputElement).value;
permiso.descripcion = inputValue;
remaining = maxChars - inputValue.length;
}
$effect(() => {
remaining = maxChars - permiso.descripcion.length;
});
</script>
<div
class="modal show fade d-block"
tabindex="-1"
aria-labelledby="textModalLabel"
style="background-color: rgba(0, 0, 0, 0.3);"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="textModalLabel">{modalTitle}</h5>
<button
type="button"
class="btn-close"
aria-label="Close"
onclick={() => onClose(ogdesc)}
></button>
</div>
<form onsubmit={(e)=>saveChanges(e)}>
<div class="modal-body">
<div class="mb-3">
<label for="textInput" class="form-label">Descripcion</label
>
<input
type="text"
class="form-control"
id="textInput"
value={permiso.descripcion}
maxlength={maxChars}
oninput={updateRemaining}
/>
<small class="form-text text-muted">
{remaining} caracteres restantes de {maxChars}
</small>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
onclick={() => onClose(ogdesc)}>Cerrar</button
>
<button
type="submit"
class="btn btn-primary"
>Guardar</button
>
</div>
</form>
</div>
</div>
</div>
+16 -2
View File
@@ -51,8 +51,22 @@
<td style="word-wrap: break-word;">{d.fecha}</td> <td style="word-wrap: break-word;">{d.fecha}</td>
<td style="word-wrap: break-word;">{d.nombreTabla}</td> <td style="word-wrap: break-word;">{d.nombreTabla}</td>
<td style="word-wrap: break-word;">{d.columna}</td> <td style="word-wrap: break-word;">{d.columna}</td>
<td style="word-wrap: break-word;">{d.valorAnterior}</td>
<td style="word-wrap: break-word;">{d.valorNuevo}</td> <td style="word-wrap: break-word;">
{#if d.columna == "Contraseña"}
*
{:else}
{d.valorAnterior}
{/if}
</td>
<td style="word-wrap: break-word;">
{#if d.columna == "Contraseña"}
*
{:else}
{d.valorNuevo}
{/if}
</td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
@@ -0,0 +1,57 @@
<script lang="ts">
let {
close,
submit,
}: { close: () => void; submit: (e: Event, pass: string) => void } =
$props();
let password: string = $state("");
function handleSubmit(e: Event) {
e.preventDefault();
submit(e, password);
}
</script>
<div
class="modal fade show d-block"
tabindex="-1"
style="background-color: rgba(0,0,0,0.5);"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Restablecer Contraseña</h5>
<button
type="button"
class="btn-close"
aria-label="Close"
onclick={close}
></button>
</div>
<div class="modal-body">
<form onsubmit={handleSubmit}>
<div class="mb-3">
<label for="password" class="form-label"
>Contraseña</label
>
<input
type="password"
id="password"
class="form-control"
minlength="8"
required
bind:value={password}
/>
<div class="form-text">
La contraseña debe tener al menos 8 caracteres.
</div>
</div>
<button type="submit" class="btn btn-primary"
>Guardar</button
>
</form>
</div>
</div>
</div>
</div>
@@ -59,7 +59,7 @@
disabled={!contratoDescargado} disabled={!contratoDescargado}
/> />
<label class="form-check-label" for="leiContratoCheckbox"> <label class="form-check-label" for="leiContratoCheckbox">
Firme el contrato con el agente de la inmobiliaria Leí el contrato con el agente de la inmobiliaria
</label> </label>
</div> </div>
</div> </div>
+167 -110
View File
@@ -1,126 +1,183 @@
<script lang="ts"> <script lang="ts">
import { Navbar, NavbarBrand, NavbarToggler, Nav, Collapse } from "@sveltestrap/sveltestrap"; import {
import { onMount } from "svelte"; Navbar,
import { writable } from 'svelte/store'; NavbarBrand,
import { link, links } from "svelte-routing"; NavbarToggler,
import './css/popup.css'; Nav,
import type { Grupo } from "../types"; Collapse,
Button,
} 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 { urlG } from "../stores/urlStore";
import { navigate } from "svelte-routing"; import { navigate } from "svelte-routing";
let isOpen: boolean = $state(false); let isOpen: boolean = $state(false);
let hayNotis:boolean = $state(false); let hayNotis: boolean = $state(false);
const permisos = writable<Grupo[]>([]); const permisos = writable<Grupo[]>([]);
const email = localStorage.getItem('email'); const email = localStorage.getItem("email");
const token = sessionStorage.getItem('token'); const token = sessionStorage.getItem("token");
async function obtenerPermisos(){ async function obtenerPermisos() {
try { try {
const response = await fetch(String($urlG)+"/api/acciones",{ const response = await fetch(String($urlG) + "/api/acciones", {
method: 'GET', method: "GET",
headers: { headers: {
'Auth' : String(token), Auth: String(token),
'Email' : String(email), Email: String(email),
'Content-Type' : "application/json" "Content-Type": "application/json",
}, },
}); });
if (response.ok){ if (response.ok) {
const json = await response.json(); const json = await response.json();
permisos.set(json); permisos.set(json);
} }
} catch (e) { } catch (e) {
console.error(e); console.error(e);
}
}
onMount( () => {
obtenerPermisos();
obtenerNotis();
})
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){ onMount(() => {
navigate(path); obtenerPermisos();
} obtenerNotis();
});
let theme = $state(localStorage.getItem("theme") ?? "light"); async function obtenerNotis() {
const toggleTheme = () => { try {
theme = theme === "light" ? "dark" : "light"; const responce = await fetch(
document.body.setAttribute("data-bs-theme", theme); $urlG + "/api/notificaciones/haySinLeer",
localStorage.setItem("theme", theme); {
}; 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);
};
async function cerrarSesion() {
try{
const req = await fetch($urlG+"/api/logout", {
method: "DELETE",
headers: {
"Auth": token || "",
}
});
}finally{
localStorage.removeItem("email");
sessionStorage.removeItem("token");
navigate("/");
}
}
</script> </script>
<Navbar container="xxl" expand="md" color="dark-subtle"> <Navbar class="border-bottom" container="xxl" expand="md" color="dark-subtle">
<NavbarBrand href="/"> <NavbarBrand href="/">AlquilaFacil</NavbarBrand>
AlquilaFacil <div class="d-flex gap-2">
</NavbarBrand> <div class="badge" style="background-color: turquoise;" use:links>
<div> <a href="/Menu">
<div class="badge" style="background-color: turquoise;" use:links> <img src="/home.svg" alt="Volver al Menú" />
<a href="/Menu"> </a>
<img src="/home.svg" alt="Volver al Menú"/>
</a>
</div>
<button class="badge btn" onclick={toggleTheme} style="background-color: cadetblue;">
{#if theme === "light" }
<img src="/toggle-left.svg" alt=""/>
{:else}
<img src="/toggle-right.svg" alt=""/>
{/if}
</button>
<button class="badge btn btn-info position-relative" onclick={()=>navigate("/notificaciones")}>
<img src="/bell.svg" alt="">
{#if hayNotis}
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
!
<span class="visually-hidden">unread messages</span>
</span>
{/if}
</button>
</div>
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
<Collapse isOpen={isOpen} navbar expand="md">
<Nav class="ms-auto" navbar >
{#each $permisos as item }
<div class="dropdown">
<div class="btn-group" style="margin-left: 3px; margin-top: 3px">
<button class="btn btn-secondary" onclick={() => redirijir("/grupo/"+item.nombre)} >{item.nombre}</button>
<button class="btn btn-secondary dropdown-toggle dropdown-toggle-split" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" use:links>
{#each item.idpermisos as perm}
<a class="dropdown-item link-underline-opacity-0 link-underline" href="/accion/{perm.id}" >{perm.descripcion}</a>
<li><hr class="dropdown-divider"></li>
{/each}
</ul>
</div> </div>
</div> <button
{/each} class="badge btn"
</Nav> onclick={toggleTheme}
</Collapse> style="background-color: cadetblue;"
>
{#if theme === "light"}
<img src="/toggle-left.svg" alt="" />
{:else}
<img src="/toggle-right.svg" alt="" />
{/if}
</button>
<button
class="badge btn btn-info position-relative"
onclick={() => navigate("/notificaciones")}
>
<img src="/bell.svg" alt="" />
{#if hayNotis}
<span
class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger"
>
!
<span class="visually-hidden">unread messages</span>
</span>
{/if}
</button>
<button
class="btn badge"
onclick={() => navigate("/usuario")}
style="background-color: wheat;"
>
<img src="/user.svg" alt="usuario" />
</button>
<div class="vr"></div>
<button class="badge btn btn-danger" onclick={cerrarSesion}>
<img src="/logout.svg" alt="CerrarSesion" />
</button>
</div>
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
<Collapse {isOpen} navbar expand="md">
<Nav class="ms-auto" navbar>
{#each $permisos as item}
<div class="dropdown">
<div
class="btn-group"
style="margin-left: 3px; margin-top: 3px"
>
<button
class="btn btn-secondary"
onclick={() => redirijir("/grupo/" + item.nombre)}
>{item.nombre}</button
>
<button
class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" use:links>
{#each item.idpermisos as perm}
<a
class="dropdown-item link-underline-opacity-0 link-underline"
href="/accion/{perm.id}"
>{perm.descripcion}</a
>
<li><hr class="dropdown-divider" /></li>
{/each}
</ul>
</div>
</div>
{/each}
</Nav>
</Collapse>
</Navbar> </Navbar>
+41 -32
View File
@@ -1,38 +1,47 @@
<script lang="ts"> <script lang="ts">
import { Navbar, NavbarBrand, NavbarToggler, NavItem, Nav, NavLink, Collapse } from "@sveltestrap/sveltestrap"; import {
Navbar,
NavbarBrand,
NavbarToggler,
NavItem,
Nav,
NavLink,
Collapse,
} from "@sveltestrap/sveltestrap";
let isOpen:boolean =$state(false); let isOpen: boolean = $state(false);
let theme = $state(localStorage.getItem("theme") ?? "light"); let theme = $state(localStorage.getItem("theme") ?? "light");
const toggleTheme = () => { const toggleTheme = () => {
theme = theme === "light" ? "dark" : "light"; theme = theme === "light" ? "dark" : "light";
document.body.setAttribute("data-bs-theme", theme); document.body.setAttribute("data-bs-theme", theme);
localStorage.setItem("theme", theme); localStorage.setItem("theme", theme);
}; };
</script> </script>
<Navbar class="border-bottom" container="xxl" expand="md" color="dark-subtle">
<Navbar container="xxl" expand="md" color="dark-subtle"> <NavbarBrand href="/">AlquilaFacil</NavbarBrand>
<NavbarBrand href="/"> <div>
AlquilaFacil <button
</NavbarBrand> class="badge btn"
<div> onclick={toggleTheme}
<button class="badge btn" onclick={toggleTheme} style="background-color: cadetblue;"> style="background-color: cadetblue;"
{#if theme === "light" } >
<img src="/toggle-left.svg" alt=""/> {#if theme === "light"}
{:else} <img src="/toggle-left.svg" alt="" />
<img src="/toggle-right.svg" alt=""/> {:else}
{/if} <img src="/toggle-right.svg" alt="" />
</button> {/if}
</div> </button>
<NavbarToggler on:click={() => (isOpen = !isOpen)} /> </div>
<Collapse isOpen={isOpen} navbar expand="md"> <NavbarToggler on:click={() => (isOpen = !isOpen)} />
<Nav class="ms-auto" navbar> <Collapse {isOpen} navbar expand="md">
<NavItem> <Nav class="ms-auto" navbar>
<NavLink href="/">Login</NavLink> <NavItem>
</NavItem> <NavLink href="/">Login</NavLink>
<NavItem> </NavItem>
<NavLink href="/Info">Preguntas Frecuentes</NavLink> <NavItem>
</NavItem> <NavLink href="/Info">Preguntas Frecuentes</NavLink>
</Nav> </NavItem>
</Collapse> </Nav>
</Collapse>
</Navbar> </Navbar>
+57 -29
View File
@@ -1,18 +1,18 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
let {
currentPag,
cantpag,
queryPag,
centrado = false,
}: {
currentPag: number;
cantpag: number;
queryPag: (a: number) => void;
centrado: boolean;
} = $props();
let {currentPag, function getVisiblePages() {
cantpag,
queryPag,
centrado = false
}:{
currentPag: number,
cantpag: number,
queryPag: (a:number) => void,
centrado:boolean
} = $props();
function getVisiblePages() {
if (!centrado || cantpag <= 5) { if (!centrado || cantpag <= 5) {
return Array.from({ length: cantpag }, (_, i) => i + 1); return Array.from({ length: cantpag }, (_, i) => i + 1);
} }
@@ -20,28 +20,56 @@
if (currentPag <= 3) { if (currentPag <= 3) {
return [1, 2, 3, 4, 5]; return [1, 2, 3, 4, 5];
} else if (currentPag >= cantpag - 2) { } else if (currentPag >= cantpag - 2) {
return [cantpag - 4, cantpag - 3, cantpag - 2, cantpag - 1, cantpag]; return [
cantpag - 4,
cantpag - 3,
cantpag - 2,
cantpag - 1,
cantpag,
];
} else { } else {
return [currentPag - 2, currentPag - 1, currentPag, currentPag + 1, currentPag + 2]; return [
currentPag - 2,
currentPag - 1,
currentPag,
currentPag + 1,
currentPag + 2,
];
} }
} }
let visiblePages = $derived.by(getVisiblePages); let visiblePages = $derived.by(getVisiblePages);
</script> </script>
{#if cantpag > 1} {#if cantpag > 1}
<nav aria-label="Paginador"> <nav aria-label="Paginador">
<ul class="pagination"> <ul class="pagination">
<li class="page-item {currentPag === 1 ? 'disabled' : ''}"> <li class="page-item {currentPag === 1 ? 'disabled' : ''}">
<a class="page-link" href="#" onclick={() => currentPag > 1 && queryPag(currentPag - 1)}>Anterior</a> <button
</li> class="page-link"
{#each visiblePages as num } onclick={() => currentPag > 1 && queryPag(currentPag - 1)}
<li class="page-item"><a class="page-link" class:active={currentPag === num} href="#" onclick={()=>queryPag(num)}>{String(num)}</a></li> >
{/each} Anterior
<li class="page-item {currentPag === cantpag ? 'disabled' : ''}"> </button>
<a class="page-link" href="#" onclick={() => currentPag < cantpag && queryPag(currentPag + 1)}>Siguiente</a> </li>
</li> {#each visiblePages as num}
</ul> <li class="page-item">
</nav> <button
class="page-link"
class:active={currentPag === num}
onclick={() => queryPag(num)}
>
{String(num)}
</button>
</li>
{/each}
<li class="page-item {currentPag === cantpag ? 'disabled' : ''}">
<button
class="page-link"
onclick={() =>
currentPag < cantpag && queryPag(currentPag + 1)}
>Siguiente</button
>
</li>
</ul>
</nav>
{/if} {/if}
+46 -42
View File
@@ -1,55 +1,59 @@
<script> <script>
import { onMount } from 'svelte'; import { onMount } from "svelte";
import { writable } from 'svelte/store'; import { writable } from "svelte/store";
import { urlG } from "../stores/urlStore"; import { urlG } from "../stores/urlStore";
let { componente } = $props(); let { componente } = $props();
const isAuthenticated = writable(false); const isAuthenticated = writable(false);
const isVerified = writable(false); const isVerified = writable(false);
const redirect = window.location.pathname; const redirect = window.location.pathname;
const email = localStorage.getItem('email'); const email = localStorage.getItem("email");
const token = sessionStorage.getItem('token'); const token = sessionStorage.getItem("token");
const handleAccess = async () => { const handleAccess = async () => {
try { try {
const response = await fetch($urlG+"/api/login/validar", { const response = await fetch($urlG + "/api/login/validar", {
method: 'POST', method: "POST",
headers: { headers: {
'Auth': String(token), Auth: String(token),
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
body: JSON.stringify({ email, redirect }), body: JSON.stringify({ email, redirect }),
credentials: "include" credentials: "include",
}); });
if (response.ok) { if (response.ok) {
isAuthenticated.set(true); // Actualiza el store isAuthenticated.set(true); // Actualiza el store
} }
} catch (error) { } catch (error) {
console.error('Error durante la autenticación:', error); console.error("Error durante la autenticación:", error);
} finally { } finally {
isVerified.set(true); // Marca la verificación como completada isVerified.set(true); // Marca la verificación como completada
} }
}; };
onMount(() => { onMount(() => {
handleAccess(); handleAccess();
}); });
</script> </script>
{#if !$isVerified} {#if !$isVerified}
<div class="d-flex justify-content-center position-absolute top-50 start-50"> <div
<div class="spinner-border" role="status"> class="d-flex justify-content-center position-absolute top-50 start-50"
<span class="visually-hidden">Loading...</span> >
</div> <div class="spinner-border" role="status">
</div> <span class="visually-hidden">Loading...</span>
</div>
</div>
{:else if $isAuthenticated}
{#if typeof componente === "object" && componente !== null}
<componente.OtroG id={componente.params.id} />
{:else}
{@render componente()}
{/if}
{:else} {:else}
{#if $isAuthenticated} {window.location.replace("/")}
{@render componente()}
{:else}
{window.location.replace('/')}
{/if}
{/if} {/if}
+247
View File
@@ -0,0 +1,247 @@
<script lang="ts">
import { onMount } from "svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import type { GrupoDto, PermisoDto } from "../types";
import { urlG } from "../stores/urlStore";
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import ModalEditarGrupo from "../Componentes/ModalEditarGrupo.svelte";
import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte";
import BotonEsquina from "../Componentes/BotonEsquina.svelte";
import ModalAadirGrupo from "../Componentes/ModalAñadirGrupo.svelte";
const token: string = sessionStorage.getItem("token") || "";
let grupos: GrupoDto[] = $state([]);
let modaldat: string = $state("");
let showmodaladd = $state(false);
onMount(() => {
ObtenerGrupos();
obtenerPermisos();
});
async function ObtenerGrupos() {
try {
const ret = await fetch($urlG + "/api/admin/grupos", {
method: "GET",
headers: {
Auth: token,
},
});
if (!ret.ok) {
modaldat = "Fallo Al intentar hacer la request";
return;
}
grupos = await ret.json();
} catch {
modaldat = "Fallo Al intentar hacer la request";
}
}
let selgru: GrupoDto = $state({
gruposIncluidos: [],
idgrupo: 0,
habilitado: false,
nombre: "",
permisos: [],
});
let showModal: boolean = $state(false);
function setModalEditar(data: GrupoDto) {
selgru = data;
showModal = true;
}
async function submitedit(a: GrupoDto) {
let b = a;
try {
let req = await fetch($urlG + "/api/grupo", {
method: "PATCH",
headers: {
Auth: token,
"Content-Type": "application/json",
},
body: JSON.stringify(b),
});
const resp = await req.json();
modaldat = resp.message;
if (req.ok) {
ObtenerGrupos();
}
} catch {
modaldat = "Fallo al hacer la request";
}
}
let permisos: PermisoDto[] = $state([]);
async function obtenerPermisos() {
try {
let a = await fetch($urlG + "/api/permisos/todos", {
method: "GET",
headers: {
Auth: token,
},
});
if (!a.ok) {
modaldat = "Fallo al obtener los permisos";
return;
}
permisos = await a.json();
} catch {
modaldat = "Fallo Al intentar hacer la request";
}
}
async function submitGrupo(a: GrupoDto) {
let b = a;
try {
let req = await fetch($urlG + "/api/grupo", {
method: "POST",
headers: {
Auth: token,
"Content-Type": "application/json",
},
body: JSON.stringify(b),
});
const resp = await req.json();
modaldat = resp.message;
if (req.ok) {
ObtenerGrupos();
}
} catch {
modaldat = "Fallo al hacer la request";
}
}
async function togglegrupo(grupo: GrupoDto) {
try {
const req = await fetch($urlG + "/api/grupo?id=" + grupo.idgrupo, {
method: "DELETE",
headers: {
Auth: token,
},
});
if (req.ok) {
grupo.habilitado = !grupo.habilitado;
}
modaldat = (await req.json()).message;
ObtenerGrupos();
} catch {
modaldat = "Fallo al hacer la request";
}
}
</script>
{#if modaldat != ""}
<ModalEstatico payload={modaldat} close={() => !!(modaldat = "")} />
{/if}
{#if showModal}
<ModalEditarGrupo
bind:data={selgru}
{permisos}
{grupos}
onClose={() => (showModal = false)}
onSubmit={submitedit}
/>
{/if}
<NavBarAutocompletable />
<div class="container mt-2">
<BarraHorizontalConTexto text="Gestionar Grupos" />
{#if grupos.length == 0}
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
{:else}
{#if showmodaladd}
<ModalAadirGrupo
onClose={() => (showmodaladd = false)}
{grupos}
{permisos}
onSubmit={submitGrupo}
/>
{/if}
{#each grupos as grupo}
<div class="accordion mt-2">
<div class="accordion-item">
<h2 class="accordion-header">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target={`#${grupo.idgrupo}`}
aria-expanded="false"
aria-controls={grupo.idgrupo}
>
{grupo.nombre}
<span
class="ms-1 badge text-bg-secondary position-relative"
style="top: -5px;"
>
{grupo.habilitado
? "Habilitado"
: "Desabilitado"}
</span>
</button>
</h2>
<div id={grupo.idgrupo} class="accordion-collapse collapse">
<div class="accordion-body">
<div class="row">
<div class="col-6">
<h5>Grupos Incluidos</h5>
<ul class="list-group">
{#if grupo.gruposIncluidos.length == 0}
<li class="list-group-item">
No hay grupos incluidos
</li>
{:else}
{#each grupo.gruposIncluidos as grupoIncluido}
<li class="list-group-item">
{grupoIncluido}
</li>
{/each}
{/if}
</ul>
</div>
<div class="col-6">
<h5>Permisos</h5>
<ul class="list-group">
{#if grupo.permisos.length == 0}
<li class="list-group-item">
No hay grupos incluidos
</li>
{:else}
{#each grupo.permisos as permiso}
<li class="list-group-item">
{permiso.descripcion}
</li>
{/each}
{/if}
</ul>
</div>
</div>
<hr />
<div class="d-flex justify-content-between">
<button
class="btn btn-primary"
onclick={() => setModalEditar(grupo)}
>Editar</button
>
<button
class="btn"
class:btn-danger={grupo.habilitado}
class:btn-success={!grupo.habilitado}
onclick={() => togglegrupo(grupo)}
>
{#if grupo.habilitado}Baja{:else}Alta{/if}
</button>
</div>
</div>
</div>
</div>
</div>
{/each}
<BotonEsquina handleclick={() => (showmodaladd = true)} />
{/if}
</div>
+253 -126
View File
@@ -1,34 +1,57 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte"; import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import type { Cliente, Grupo, UpdateCliente } from "../types"; import type { Cliente, Grupo, GrupoDto, UpdateCliente } from "../types";
import {urlG} from "../stores/urlStore"; import { urlG } from "../stores/urlStore";
import ModalEstatico from "../Componentes/ModalEstatico.svelte"; import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte"; import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte";
import { fade, fly } from "svelte/transition"; import { fade, fly } from "svelte/transition";
import ModalModificarPropietarios from "../Componentes/ModalModificarPropietarios.svelte"; import ModalModificarPropietarios from "../Componentes/ModalModificarPropietarios.svelte";
import { CardLink } from "@sveltestrap/sveltestrap"; import { CardLink, Modal } from "@sveltestrap/sveltestrap";
import ModalRestablecerContra from "../Componentes/ModalRestablecerContra.svelte";
let Clientes: Cliente[] = $state([]); let Clientes: Cliente[] = $state([]);
let Grupos:any[] = $state([]); let Grupos: any[] = $state([]);
let modaldata = $state(); let modaldata = $state();
let token = sessionStorage.getItem("token"); let token = sessionStorage.getItem("token");
let showAddmenu: boolean = $state(false); let showAddmenu: boolean = $state(false);
let grupo:string = $state(""); let grupo: string = $state("");
let SelCliente: Cliente = $state(null); let SelCliente: Cliente = $state(null);
let gruposopt: GrupoDto[] = $state([]);
onMount(() => { onMount(() => {
cargaUsuarios(); cargaUsuarios();
ObtenerGrupos();
}); });
async function cargaUsuarios(){
try{ async function ObtenerGrupos() {
const response = await fetch($urlG+"/api/admin/clientes", { try {
const ret = await fetch($urlG + "/api/admin/grupos", {
method: "GET", method: "GET",
headers: { headers: {
"Auth": String(token), Auth: token || "",
} },
}) });
if (!ret.ok) {
modaldata = "Fallo Al intentar hacer la request";
return;
}
gruposopt = await ret.json();
} catch {
modaldata = "Fallo Al intentar hacer la request";
}
}
async function cargaUsuarios() {
try {
const response = await fetch($urlG + "/api/admin/clientes", {
method: "GET",
headers: {
Auth: String(token),
},
});
if (response.ok) { if (response.ok) {
let data: Cliente[] = await response.json(); let data: Cliente[] = await response.json();
Clientes = data; Clientes = data;
@@ -38,17 +61,19 @@
} catch { } catch {
modaldata = "fallo al intentar obtener la lista de clientes"; modaldata = "fallo al intentar obtener la lista de clientes";
} }
} }
async function cargaGrupos(cli: Cliente){ async function cargaGrupos(cli: Cliente) {
try { try {
const response = await fetch($urlG+"/api/admin/clientes/grupo?Dni="+cli.dni, { const response = await fetch(
method: "GET", $urlG + "/api/admin/clientes/grupo?Dni=" + cli.dni,
headers: { {
"Auth": String(token), method: "GET",
headers: {
Auth: String(token),
},
}, },
}); );
if (response.ok){ if (response.ok) {
let data = await response.json(); let data = await response.json();
Grupos = data; Grupos = data;
showAddmenu = true; showAddmenu = true;
@@ -62,45 +87,49 @@
} }
} }
async function bajaCliente(event:Event, cli:Cliente) { async function bajaCliente(event: Event, cli: Cliente) {
//WIP añadir una flag para que muestre que no se pudo dar se alta/baja
event.stopPropagation(); event.stopPropagation();
try { try {
const response = await fetch($urlG+"/api/admin/cliente?Dni="+cli.dni, { const response = await fetch(
method: "DELETE", $urlG + "/api/admin/cliente?Dni=" + cli.dni,
headers: { {
"Auth": String(token), method: "DELETE",
} headers: {
}); Auth: String(token),
if(response.ok){ },
let data = await response.json(); },
modaldata = data.message; );
let data = await response.json();
modaldata = data.message;
if (response.ok) {
cli.habilitado = !cli.habilitado; cli.habilitado = !cli.habilitado;
cargaUsuarios();
} }
} catch { } catch {
modaldata = ""; modaldata = "Fallo al hacer la request";
} }
} }
async function añadirGrupo(e:Event, cli: Cliente, grupo:string){ async function añadirGrupo(e: Event, cli: Cliente, grupo: string) {
e.preventDefault(); e.preventDefault();
if (cli.dni == 0 || cli.email == "" || grupo == ""){ if (cli.dni == 0 || cli.email == "" || grupo == "") {
modaldata = "No se selecciono un cliente o Grupo"; modaldata = "No se selecciono un cliente o Grupo";
return; return;
} }
const email = cli.email; const email = cli.email;
try { try {
const response = await fetch($urlG+"/api/admin/cliente/addGrupo", { const response = await fetch(
method: "PATCH", $urlG + "/api/admin/cliente/addGrupo",
headers: { {
"Auth": String(token), method: "PATCH",
'Content-Type' : 'application/json', headers: {
Auth: String(token),
"Content-Type": "application/json",
},
body: JSON.stringify({ email, grupo }),
}, },
body: JSON.stringify({email, grupo}) );
});
if (response.ok){ if (response.ok) {
let data = await response.json(); let data = await response.json();
modaldata = data.message; modaldata = data.message;
cargaGrupos(cli); cargaGrupos(cli);
@@ -112,27 +141,32 @@
modaldata = "Falla la conexion al servidor"; modaldata = "Falla la conexion al servidor";
} }
} }
async function BajaGrupo(e:Event, cli: Cliente, grupo:string){ async function BajaGrupo(e: Event, cli: Cliente, grupo: string) {
e.preventDefault(); e.preventDefault();
if (cli.dni == 0 || cli.email == "" || grupo == ""){ if (cli.dni == 0 || cli.email == "" || grupo == "") {
modaldata = "No se selecciono un cliente o Grupo"; modaldata = "No se selecciono un cliente o Grupo";
return; return;
} }
const email = cli.email; const email = cli.email;
if (grupo === "Propietario"){ if (grupo === "Propietario") {
if (confirm("Sos propietario si te desactivas de ese rol tus propiedades se van a dar de baja, Estas seguro?") == false) return; if (
confirm(
"Sos propietario si te desactivas de ese rol tus propiedades se van a dar de baja, Estas seguro?",
) == false
)
return;
} }
try { try {
const response = await fetch($urlG+"/api/admin/cliente/rmGrupo", { const response = await fetch($urlG + "/api/admin/cliente/rmGrupo", {
method: "PATCH", method: "PATCH",
headers: { headers: {
"Auth": String(token), Auth: String(token),
'Content-Type' : 'application/json', "Content-Type": "application/json",
}, },
body: JSON.stringify({email, grupo}) body: JSON.stringify({ email, grupo }),
}); });
if (response.ok){ if (response.ok) {
let data = await response.json(); let data = await response.json();
modaldata = data.message; modaldata = data.message;
cargaGrupos(cli); cargaGrupos(cli);
@@ -145,20 +179,26 @@
} }
} }
let showModificarCliente:boolean = $state(false); let showModificarCliente: boolean = $state(false);
let datoscli:UpdateCliente = $state({dni:0, apellido:"", celular:"", domicilio:"", nombre:""}); let datoscli: UpdateCliente = $state({
dni: 0,
apellido: "",
celular: "",
domicilio: "",
nombre: "",
});
async function abrirModalModificarCliente(e: Event, cli: Cliente) { async function abrirModalModificarCliente(e: Event, cli: Cliente) {
e.stopPropagation(); e.stopPropagation();
try { try {
const r = await fetch($urlG+"/api/admin/cliente?dni="+cli.dni, { const r = await fetch($urlG + "/api/admin/cliente?dni=" + cli.dni, {
method: "GET", method: "GET",
headers: { headers: {
"Auth": token||"", Auth: token || "",
} },
}); });
let data = await r.json(); let data = await r.json();
if (r.ok){ if (r.ok) {
datoscli = data; datoscli = data;
datoscli.dni = cli.dni; datoscli.dni = cli.dni;
showModificarCliente = true; showModificarCliente = true;
@@ -170,53 +210,100 @@
} }
} }
async function patchCliente(a:UpdateCliente) { async function patchCliente(a: UpdateCliente) {
if (a.apellido =="" || a.celular=="" || a.domicilio=="" || a.nombre==""){ if (
a.apellido == "" ||
a.celular == "" ||
a.domicilio == "" ||
a.nombre == ""
) {
modaldata = "Hay campos vacios"; modaldata = "Hay campos vacios";
return; return;
} }
let dto ={ let dto = {
apellido: a.apellido, apellido: a.apellido,
celular: a.celular, celular: a.celular,
domicilio: a.domicilio, domicilio: a.domicilio,
nombre: a.nombre, nombre: a.nombre,
} };
try{ try {
const r = await fetch($urlG+"/api/admin/cliente?dni="+a.dni, { const r = await fetch($urlG + "/api/admin/cliente?dni=" + a.dni, {
method: "PATCH", method: "PATCH",
headers: { headers: {
"Auth": token||"", Auth: token || "",
"Content-Type": "application/json" "Content-Type": "application/json",
}, },
body: JSON.stringify(dto), body: JSON.stringify(dto),
}); });
let data = await r.json(); let data = await r.json();
modaldata = data.message; modaldata = data.message;
if (r.ok) cargaUsuarios(); if (r.ok) cargaUsuarios();
}catch{ } catch {
modaldata = "Falla la conexion al servidor"; modaldata = "Falla la conexion al servidor";
} }
} }
let restablecercontracli: Cliente | null = $state(null);
let showmodalrestablecercontra: boolean = $state(false);
async function handleRestablecerContraseña(e: Event, pass: string) {
e.preventDefault();
try {
const req = await fetch($urlG + "/api/admin/contraseña", {
method: "PATCH",
headers: {
Auth: token || "",
"Content-Type": "application/json",
},
body: JSON.stringify({
Dni: restablecercontracli?.dni,
contraseña: pass,
}),
});
const js = await req.json();
showmodalrestablecercontra = false;
restablecercontracli = null;
modaldata = js.message;
} catch {
modaldata = "Falla la conexion al servidor";
}
}
function triggermodalcontra(cli: Cliente) {
restablecercontracli = cli;
showmodalrestablecercontra = true;
}
</script> </script>
<NavBarAutocompletable/> <NavBarAutocompletable />
{#if modaldata} {#if modaldata}
<ModalEstatico payload={modaldata} close={()=> !!(modaldata = "")}/> <ModalEstatico payload={modaldata} close={() => !!(modaldata = "")} />
{/if} {/if}
{#if showModificarCliente} {#if showModificarCliente}
<ModalModificarPropietarios datos={datoscli} onCancel={()=>!!(showModificarCliente = false)} <ModalModificarPropietarios
onConfirm={patchCliente}/> datos={datoscli}
onCancel={() => !!(showModificarCliente = false)}
onConfirm={patchCliente}
/>
{/if}
{#if showmodalrestablecercontra}
<ModalRestablecerContra
close={() => (showmodalrestablecercontra = false)}
submit={handleRestablecerContraseña}
/>
{/if} {/if}
<div class="content-fluid align-items-start"> <div class="content-fluid align-items-start">
<div class="row"> <div class="row">
<div class="col ms-2"> <div class="col ms-2">
<BarraHorizontalConTexto text="Clientes"/> <BarraHorizontalConTexto text="Clientes" />
<div style="height:70vh; overflow-y: auto; max-width: 100%"> <div style="height:85vh; overflow-y: auto; max-width: 100%">
<table class="table table-responsive table-striped table-hover table-bordered"> <table
class="table table-responsive table-striped table-hover table-bordered"
>
<thead> <thead>
<tr> <tr>
<th>Dni</th> <th>Dni</th>
@@ -227,33 +314,53 @@
</thead> </thead>
<tbody> <tbody>
{#each Clientes as cli} {#each Clientes as cli}
<tr onclick={() => cargaGrupos(cli)} in:fade> <tr onclick={() => cargaGrupos(cli)} in:fade>
<td>{cli.dni}</td> <td>{cli.dni}</td>
<td>{cli.nombre}</td> <td>{cli.nombre}</td>
<td>{cli.email}</td> <td>{cli.email}</td>
<td> <td>
{#if cli.habilitado} {#if cli.habilitado}
<button class="btn btn-warning" onclick={(e) => bajaCliente(e, cli)}> <button
Baja class="btn btn-warning"
</button> onclick={(e) => bajaCliente(e, cli)}
{:else} >
<button class="btn btn-success" onclick={(e) => bajaCliente(e, cli)}> Baja
Alta </button>
</button> {:else}
{/if} <button
<button class="btn btn-secondary" onclick={(e)=>abrirModalModificarCliente(e, cli)}> class="btn btn-success"
Modificar onclick={(e) => bajaCliente(e, cli)}
</button> >
</td> Alta
</tr> </button>
{/if}
<button
class="btn btn-secondary"
onclick={(e) =>
abrirModalModificarCliente(e, cli)}
>
<img src="/edit.svg" alt="Editar" />
</button>
<button
class="btn btn-info"
onclick={() => triggermodalcontra(cli)}
><img
src="/key.svg"
alt="RestablecerContraseña"
/>
</button>
</td>
</tr>
{/each} {/each}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div class="col me-2 ps-0"> <div class="col me-2 ps-0">
<BarraHorizontalConTexto text="Grupos del Cliente Seleccionado"/> <BarraHorizontalConTexto text="Grupos del Cliente Seleccionado" />
<table class="table table-striped table-responsive table-sm table-bordered"> <table
class="table table-striped table-responsive table-sm table-bordered"
>
<thead> <thead>
<tr> <tr>
<th>Id</th> <th>Id</th>
@@ -262,45 +369,65 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#if Grupos.length>0} {#if Grupos.length > 0}
{#each Grupos as g}
{#each Grupos as g} <tr in:fade>
<tr in:fade> <td>{g.id}</td>
<td>{g.id}</td> <td>{g.descripcion}</td>
<td>{g.descripcion}</td> <td
<td><button class="btn btn-outline-danger" onclick={(e)=>BajaGrupo(e, SelCliente, g.descripcion)}>Baja</button></td> ><button
</tr> class="btn btn-outline-danger"
{/each} onclick={(e) =>
BajaGrupo(
e,
SelCliente,
g.descripcion,
)}>Baja</button
></td
>
</tr>
{/each}
{:else if SelCliente != null} {:else if SelCliente != null}
<tr> <tr>
<td colspan="3">Este Cliente no tiene Grupos</td> <td colspan="3">Este Cliente no tiene Grupos</td>
</tr> </tr>
{:else} {:else}
<tr> <tr>
<td colspan="3">Seleccione un cliente para ver sus grupos</td> <td colspan="3"
</tr> >Seleccione un cliente para ver sus grupos</td
>
</tr>
{/if} {/if}
</tbody> </tbody>
</table> </table>
{#if showAddmenu} {#if showAddmenu}
<div in:fade> <div in:fade>
<BarraHorizontalConTexto text="Añadir Grupos al Usuario"/> <BarraHorizontalConTexto text="Añadir Grupos al Usuario" />
<form class="card card-body" onsubmit={(e) => añadirGrupo(e,SelCliente, grupo)}> <form
<div class="mb-3"> class="card card-body"
<label for="userRole" class="form-label">Seleccionar Grupo</label> onsubmit={(e) => añadirGrupo(e, SelCliente, grupo)}
<select id="userRole" class="form-select" bind:value={grupo}> >
<option value="Propietario">Propietario</option> <div class="mb-3">
<option value="Inquilino">Inquilino</option> <label for="userRole" class="form-label"
<option value="Admin">Admin</option> >Seleccionar Grupo</label
<option value="Informes">Informes</option> >
</select> <select
</div> id="userRole"
<button class="btn btn-primary" type="submit">Añadir</button> class="form-select"
</form> bind:value={grupo}
</div> >
{#each gruposopt as g}
<option value={g.nombre}>{g.nombre}</option>
{/each}
</select>
</div>
<button class="btn btn-primary" type="submit"
>Añadir</button
>
</form>
</div>
{/if} {/if}
</div> </div>
</div> </div>
</div> </div>
@@ -0,0 +1,551 @@
<script>
import { onMount } from 'svelte';
import NavBarAutocompletable from '../Componentes/NavBarAutocompletable.svelte';
import { urlG } from '../stores/urlStore';
import ModalEstatico from '../Componentes/ModalEstatico.svelte';
let contrato = $state({
id: 0,
cantgarantemin: 0,
dniinquilino: 0n,
dnipropietario: 0n,
iddivisa: 0,
idpropiedad: 0,
mesesDurationContrato: 0,
mesesHastaAumento: 0,
monto: 0,
tieneopcionventa: false,
archivoContrato: null,
divisaOpcionVenta: 0,
montoOpcionVenta: 0,
garantes: []
});
let modaldata = $state("");
let token = sessionStorage.getItem("token");
let busquedaDivisa = $state('');
let busquedaDivisaOpVenta = $state('');
let busquedaPropiedad = $state('');
let busquedaInquilino = $state('');
let busquedaPropietario = $state('');
let divisas = $state([]);
let propiedades = $state([]);
let inquilinos = $state([]);
let propietarios = $state([]);
$effect(() => {
const currentLength = contrato.garantes.length;
if (contrato.cantgarantemin > currentLength) {
// Agregar garantes faltantes
for (let i = currentLength; i < contrato.cantgarantemin; i++) {
contrato.garantes = [...contrato.garantes, {
dni: '',
nombre: '',
apellido: '',
domicilio: '',
celular: '',
domicilioLaboral: ''
}];
}
} else if (contrato.cantgarantemin < currentLength) {
// Remover garantes excedentes
contrato.garantes = contrato.garantes.slice(0, contrato.cantgarantemin);
}
});
onMount(async () => {
obtenerDatos();
});
async function obtenerDatos(){
try{
const req = await fetch($urlG + "/api/admin/contrato/data", {
method: "GET",
headers: {
"Auth": token || "",
}
});
const data = await req.json();
if (req.ok){
({ divisas, propiedades, inquilinos, propietarios } = data);
return;
}
modaldata = data.message;
}catch{
modaldata = "Fallo la request";
}
}
function handleFileChange(event) {
const file = event.target.files[0];
if (file) {
contrato.archivoContrato = file;
}
}
let divisasFiltradas = $derived(
divisas.filter(d =>
!busquedaDivisa ||
d.signo?.toLowerCase().includes(busquedaDivisa.toLowerCase()) ||
d.id.toString().includes(busquedaDivisa)
)
);
let divisasFiltradasOpVenta = $derived(
divisas.filter(d =>
!busquedaDivisaOpVenta ||
d.signo?.toLowerCase().includes(busquedaDivisaOpVenta.toLowerCase()) ||
d.id.toString().includes(busquedaDivisaOpVenta)
)
);
let propiedadesFiltradas = $derived(
propiedades.filter(p =>
!busquedaPropiedad ||
p.ubicacion?.toLowerCase().includes(busquedaPropiedad.toLowerCase()) ||
p.id.toString().includes(busquedaPropiedad)
)
);
let inquilinosFiltrados = $derived(
inquilinos.filter(i =>
!busquedaInquilino ||
i.nombre?.toLowerCase().includes(busquedaInquilino.toLowerCase()) ||
i.dni.toString().includes(busquedaInquilino)
)
);
let propietariosFiltrados = $derived(
propietarios.filter(p =>
!busquedaPropietario ||
p.nombre?.toLowerCase().includes(busquedaPropietario.toLowerCase()) ||
p.dni.toString().includes(busquedaPropietario)
)
);
async function handleSubmit(e) {
e.preventDefault();
const formData = new FormData();
formData.append('cantgarantemin', contrato.cantgarantemin.toString());
formData.append('dniinquilino', contrato.dniinquilino.toString());
formData.append('dnipropietario', contrato.dnipropietario.toString());
formData.append('iddivisa', contrato.iddivisa.toString());
formData.append('idpropiedad', contrato.idpropiedad.toString());
formData.append('mesesDurationContrato', contrato.mesesDurationContrato.toString());
formData.append('mesesHastaAumento', contrato.mesesHastaAumento.toString());
formData.append('monto', contrato.monto.toString());
formData.append('tieneopcionventa', contrato.tieneopcionventa.toString());
contrato.garantes.forEach((garante, index) => {
formData.append(`garantes[${index}].dni`, garante.dni);
formData.append(`garantes[${index}].nombre`, garante.nombre);
formData.append(`garantes[${index}].apellido`, garante.apellido);
formData.append(`garantes[${index}].domicilio`, garante.domicilio);
formData.append(`garantes[${index}].celular`, garante.celular);
formData.append(`garantes[${index}].domicilioLaboral`, garante.domicilioLaboral);
});
if (contrato.tieneopcionventa) {
formData.append('divisaOpcionVenta', contrato.divisaOpcionVenta.toString());
formData.append('montoOpcionVenta', contrato.montoOpcionVenta.toString());
}
// Agregar el archivo si existe
if (contrato.archivoContrato) {
formData.append('archivoContrato', contrato.archivoContrato);
}
try {
const response = await fetch($urlG + '/api/admin/contrato/carga', {
method: 'POST',
headers: {
"Auth": token || "",
},
body: formData
});
const data = await response.json();
if (response.ok) {
contrato = {
id: 0,
cantgarantemin: 0,
dniinquilino: 0n,
dnipropietario: 0n,
iddivisa: 0,
idpropiedad: 0,
mesesDurationContrato: 0,
mesesHastaAumento: 0,
monto: 0,
tieneopcionventa: false,
archivoContrato: null,
divisaOpcionVenta: 0,
montoOpcionVenta: 0,
garantes: []
};
}
modaldata = data.message;
} catch (error) {
modaldata = "Fallo al hacer la request";
}
}
async function actualizarPropiedades(dnipropietario){
try{
const req = await fetch($urlG + "/api/admin/contrato/propieades?dnipropietario="+ dnipropietario, {
method: "GET",
headers:{
"Auth": token || "",
}
});
const data = await req.json();
if (req.ok){
propiedades = data;
return;
}
modaldata = data.message;
}catch{
modaldata = "Fallo al hacer la request";
}
}
function actualizarGarante(index, campo, valor) {
contrato.garantes[index] = { ...contrato.garantes[index], [campo]: valor };
}
</script>
<NavBarAutocompletable/>
{#if modaldata}
<ModalEstatico payload={modaldata} close={()=>!!(modaldata = "")}/>
{/if}
<div class="container mt-4">
<h2>Alta de Contrato</h2>
<form onsubmit={handleSubmit}>
<div class="row mb-3">
<label for="dniinquilino" class="col-sm-3 col-form-label">Inquilino</label>
<div class="col-sm-9">
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Buscar inquilino (DNI o nombre)..."
bind:value={busquedaInquilino}
/>
<select
class="form-select"
id="dniinquilino"
bind:value={contrato.dniinquilino}
required
>
<option value="">Seleccionar Inquilino...</option>
{#each inquilinosFiltrados as inq}
<option value={inq.dni}>{inq.nombre} | {inq.dni}</option>
{/each}
</select>
</div>
</div>
</div>
<div class="row mb-3">
<label for="dnipropietario" class="col-sm-3 col-form-label">Propietario</label>
<div class="col-sm-9">
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Buscar propietario (DNI o nombre)..."
bind:value={busquedaPropietario}
/>
<select
class="form-select"
id="dnipropietario"
bind:value={contrato.dnipropietario}
required
onchange={()=>actualizarPropiedades(contrato.dnipropietario)}
>
<option value="">Seleccionar Propietario...</option>
{#each propietariosFiltrados as prop}
<option value={prop.dni}>{prop.nombre} | {prop.dni}</option>
{/each}
</select>
</div>
</div>
</div>
<div class="row mb-3">
<label for="monto" class="col-sm-3 col-form-label">Monto del Contrato</label>
<div class="col-sm-9">
<input
type="number"
step="0.01"
min="1"
class="form-control"
id="monto"
bind:value={contrato.monto}
required
/>
</div>
</div>
<div class="row mb-3">
<label for="mesesDurationContrato" class="col-sm-3 col-form-label">Duración (meses)</label>
<div class="col-sm-9">
<input
type="number"
min="1"
class="form-control"
id="mesesDurationContrato"
bind:value={contrato.mesesDurationContrato}
required
/>
</div>
</div>
<div class="row mb-3">
<label for="mesesHastaAumento" class="col-sm-3 col-form-label">Meses hasta Aumento</label>
<div class="col-sm-9">
<input
type="number"
min="1"
class="form-control"
id="mesesHastaAumento"
bind:value={contrato.mesesHastaAumento}
/>
</div>
</div>
<div class="row mb-3">
<label for="cantgarantemin" class="col-sm-3 col-form-label">Cantidad Garantes Mínimos</label>
<div class="col-sm-9">
<input
type="number"
min="0"
max="100"
class="form-control"
id="cantgarantemin"
bind:value={contrato.cantgarantemin}
/>
</div>
</div>
{#if contrato.cantgarantemin > 0}
<div class="row mb-3">
<div class="col-12">
<h5>Garantes</h5>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>DNI</th>
<th>Nombre</th>
<th>Apellido</th>
<th>Domicilio</th>
<th>Celular</th>
<th>Domicilio Laboral</th>
</tr>
</thead>
<tbody>
{#each contrato.garantes as garante, i}
<tr>
<td>
<input
type="text"
class="form-control"
placeholder="DNI"
min="0"
max="99999999"
bind:value={garante.dni}
oninput={(e) => actualizarGarante(i, 'dni', e.target.value)}
/>
</td>
<td>
<input
type="text"
class="form-control"
minlength="1"
placeholder="Nombre"
bind:value={garante.nombre}
oninput={(e) => actualizarGarante(i, 'nombre', e.target.value)}
/>
</td>
<td>
<input
type="text"
class="form-control"
placeholder="Apellido"
bind:value={garante.apellido}
oninput={(e) => actualizarGarante(i, 'apellido', e.target.value)}
/>
</td>
<td>
<input
type="text"
class="form-control"
placeholder="Domicilio"
bind:value={garante.domicilio}
oninput={(e) => actualizarGarante(i, 'domicilio', e.target.value)}
/>
</td>
<td>
<input
type="text"
class="form-control"
placeholder="Celular"
bind:value={garante.celular}
oninput={(e) => actualizarGarante(i, 'celular', e.target.value)}
/>
</td>
<td>
<input
type="text"
class="form-control"
placeholder="Domicilio Laboral"
bind:value={garante.domicilioLaboral}
oninput={(e) => actualizarGarante(i, 'domicilioLaboral', e.target.value)}
/>
</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>
{/if}
<div class="row mb-3">
<label for="archivoContrato" class="col-sm-3 col-form-label">Archivo del Contrato</label>
<div class="col-sm-9">
<input
type="file"
class="form-control"
id="archivoContrato"
accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"
onchange={handleFileChange}
/>
{#if contrato.archivoContrato}
<small class="text-muted">Archivo seleccionado: {contrato.archivoContrato.name}</small>
{/if}
</div>
</div>
<div class="row mb-3">
<label for="iddivisa" class="col-sm-3 col-form-label">Divisa</label>
<div class="col-sm-9">
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Buscar divisa..."
bind:value={busquedaDivisa}
/>
<select
class="form-select"
id="iddivisa"
bind:value={contrato.iddivisa}
required
>
<option value="">Seleccionar Divisa...</option>
{#each divisasFiltradas as divisa}
<option value={divisa.id}>{divisa.signo}</option>
{/each}
</select>
</div>
</div>
</div>
<div class="row mb-3">
<label for="idpropiedad" class="col-sm-3 col-form-label">Propiedad</label>
<div class="col-sm-9">
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Buscar propiedad (ID o dirección)..."
bind:value={busquedaPropiedad}
/>
<select
class="form-select"
id="idpropiedad"
bind:value={contrato.idpropiedad}
required
>
<option value="">Seleccionar Propiedad...</option>
{#each propiedadesFiltradas as propiedad}
<option value={propiedad.id}>{propiedad.id} - {propiedad.ubicacion}</option>
{/each}
</select>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-9 offset-sm-3">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
bind:checked={contrato.tieneopcionventa}
id="tieneopcionventa"
/>
<label class="form-check-label" for="tieneopcionventa">
Tiene Opción de Venta
</label>
</div>
</div>
</div>
{#if contrato.tieneopcionventa}
<div class="row mb-3">
<label for="divisaOpcionVenta" class="col-sm-3 col-form-label">Divisa Opción Venta</label>
<div class="col-sm-9">
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Buscar divisa..."
bind:value={busquedaDivisaOpVenta}
/>
<select
class="form-select"
id="divisaOpcionVenta"
bind:value={contrato.divisaOpcionVenta}
required
>
<option value="">Seleccionar Divisa...</option>
{#each divisasFiltradasOpVenta as divisa}
<option value={divisa.id}>{divisa.signo}</option>
{/each}
</select>
</div>
</div>
</div>
<div class="row mb-3">
<label for="montoOpcionVenta" class="col-sm-3 col-form-label">Monto Opción Venta</label>
<div class="col-sm-9">
<input
type="number"
step="0.01"
class="form-control"
id="montoOpcionVenta"
bind:value={contrato.montoOpcionVenta}
required
/>
</div>
</div>
{/if}
<div class="row mb-3">
<div class="col-sm-9 offset-sm-3">
<button type="submit" class="btn btn-primary">Guardar Contrato</button>
</div>
</div>
</form>
</div>
+22 -2
View File
@@ -33,9 +33,29 @@
onMount(()=>{ onMount(()=>{
getparams(); getparams();
obtenerDatosACargar(); obtenerDatosACargar();
getgarantes();
}); });
async function getgarantes() {
try{
const ret = await fetch($urlG+"/api/contratos/garantes"+"?idcontrato="+contratoid,{
method: "GET",
headers: {
"Auth": token
},
});
if (!ret.ok){
let data = await ret.json();
modaldata = data.message;
return;
}
let data = await ret.json();
garantes = data;
return;
}catch{
modaldata = "No se pudo obtener la lista de garantes actualizada";
}
}
async function refreshCanon() { async function refreshCanon() {
try { try {
const ret = await fetch($urlG+"/api/admin/contrato/canons?id="+contratoid, { const ret = await fetch($urlG+"/api/admin/contrato/canons?id="+contratoid, {
@@ -273,7 +293,7 @@
aria-expanded="true" aria-expanded="true"
aria-controls="collapseTwo" aria-controls="collapseTwo"
> >
Canons Canones
</button> </button>
</h2> </h2>
<div <div
+343 -234
View File
@@ -2,41 +2,55 @@
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte"; import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import { onMount } from "svelte"; import { onMount } from "svelte";
import ModalEstatico from "../Componentes/ModalEstatico.svelte"; import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import {urlG} from "../stores/urlStore"; import { urlG } from "../stores/urlStore";
import type { AltaDefectoDto, CanonDto, ContratoDto, ContratoPropiedadDto, DefectoDto, GaranteDto2, OpcionVentaDto } from "../types"; import type {
AltaDefectoDto,
CanonDto,
ContratoDto,
ContratoPropiedadDto,
DefectoDto,
GaranteDto2,
OpcionVentaDto,
} from "../types";
import ModalPedirDoc from "../Componentes/ModalPedirDoc.svelte"; import ModalPedirDoc from "../Componentes/ModalPedirDoc.svelte";
import FormAltaDefecto from "../Componentes/FormAltaDefecto.svelte"; import FormAltaDefecto from "../Componentes/FormAltaDefecto.svelte";
import { navigate } from "svelte-routing"; import { navigate } from "svelte-routing";
let token:string = sessionStorage.getItem("token")||""; let token: string = sessionStorage.getItem("token") || "";
let selMod:any =$state(); let selMod: any = $state();
let showmodal:boolean = $state(false); let showmodal: boolean = $state(false);
let canons:CanonDto[] = $state([]); let canons: CanonDto[] = $state([]);
let garantes: GaranteDto2[] = $state([]); let garantes: GaranteDto2[] = $state([]);
let prop:ContratoPropiedadDto = $state({ let prop: ContratoPropiedadDto = $state({
estado:"", estado: "",
fechainicio:"", fechainicio: "",
id:0, id: 0,
inquilino:"", inquilino: "",
propietario:"", propietario: "",
tipoPropiedad:"", tipoPropiedad: "",
ubicacion:"", ubicacion: "",
habitaciones:0, habitaciones: 0,
piso:0, piso: 0,
letra:"", letra: "",
mesesAumento:0, mesesAumento: 0,
mesesDuracion:0, mesesDuracion: 0,
}); });
let defectos:DefectoDto[] = $state([]); let defectos: DefectoDto[] = $state([]);
let TieneOpcionVenta:boolean =$state(false); let TieneOpcionVenta: boolean = $state(false);
let dtoVenta:OpcionVentaDto =$state({divisa:"", id:0, monto:0, enOrden:false, fueEjercido:false}); let dtoVenta: OpcionVentaDto = $state({
divisa: "",
id: 0,
monto: 0,
enOrden: false,
fueEjercido: false,
});
let modaldata:string = $state(""); let modaldata: string = $state("");
let contratoid:string = $state(""); let contratoid: string = $state("");
onMount(()=>{ onMount(() => {
getparams(); getparams();
obtenerDatosACargar(); obtenerDatosACargar();
opcionVenta(); opcionVenta();
@@ -44,16 +58,21 @@
async function opcionVenta() { async function opcionVenta() {
try { try {
const r = await fetch($urlG+"/api/contrato/tieneopcionventa?idcontrato="+contratoid, { const r = await fetch(
method: "GET", $urlG +
headers: { "/api/contrato/tieneopcionventa?idcontrato=" +
"Auth": String(token), contratoid,
} {
}); method: "GET",
if (r.ok){ headers: {
Auth: String(token),
},
},
);
if (r.ok) {
let data = await r.json(); let data = await r.json();
TieneOpcionVenta = data.message; TieneOpcionVenta = data.message;
if (TieneOpcionVenta){ if (TieneOpcionVenta) {
ObtenerOpcionVentaDto(); ObtenerOpcionVentaDto();
} }
return; return;
@@ -61,58 +80,79 @@
let data = await r.json(); let data = await r.json();
modaldata = data.message; modaldata = data.message;
return; return;
}catch { } catch {
modaldata = "Fallo hacer la request"; modaldata = "Fallo hacer la request";
} }
} }
async function ObtenerOpcionVentaDto() { async function ObtenerOpcionVentaDto() {
try{ try {
const r = await fetch($urlG+"/api/opcionventa?idcontrato="+contratoid, { const r = await fetch(
method: "GET", $urlG + "/api/opcionventa?idcontrato=" + contratoid,
headers: { {
"Auth": String(token), method: "GET",
} headers: {
}); Auth: String(token),
},
},
);
if (r.ok) { if (r.ok) {
let data = await r.json(); let data = await r.json();
dtoVenta = data; dtoVenta = data;
return return;
} }
let data = await r.json(); let data = await r.json();
modaldata = data.message; modaldata = data.message;
}catch{ } catch {
modaldata = "Fallo hacer la request"; modaldata = "Fallo hacer la request";
} }
} }
async function obtenerDatosACargar() { async function obtenerDatosACargar() {
try { try {
const respPropiedad = fetch($urlG+"/api/contrato/inquilino?id="+contratoid, { const respPropiedad = fetch(
method: "GET", $urlG + "/api/contrato/inquilino?id=" + contratoid,
headers: { {
"Auth": String(token), method: "GET",
} headers: {
}); Auth: String(token),
const respgarantes = fetch($urlG+"/api/contratos/garantes?idcontrato="+contratoid, { },
method: "GET", },
headers: { );
"Auth": String(token), const respgarantes = fetch(
} $urlG + "/api/contratos/garantes?idcontrato=" + contratoid,
}); {
const respCanons = fetch($urlG+"/api/contratos/canon?id="+contratoid, { method: "GET",
method: "GET", headers: {
headers: { Auth: String(token),
"Auth": String(token), "Content-Type": "application/json",
} },
}); },
const respoDefect = fetch($urlG+"/api/defectos?Idcontrato="+contratoid, { );
method: "GET", const respCanons = fetch(
headers: { $urlG + "/api/contratos/canon?id=" + contratoid,
"Auth": token, {
} method: "GET",
}); headers: {
const [p, g, c, d] = await Promise.all([respPropiedad, respgarantes, respCanons, respoDefect]); Auth: String(token),
},
},
);
const respoDefect = fetch(
$urlG + "/api/defectos?Idcontrato=" + contratoid,
{
method: "GET",
headers: {
Auth: token,
},
},
);
const [p, g, c, d] = await Promise.all([
respPropiedad,
respgarantes,
respCanons,
respoDefect,
]);
const datosPropiedad = await p.json(); const datosPropiedad = await p.json();
const datosGarantes = await g.json(); const datosGarantes = await g.json();
@@ -123,27 +163,29 @@
garantes = datosGarantes; garantes = datosGarantes;
canons = datosCanons; canons = datosCanons;
defectos = datosDefect; defectos = datosDefect;
} catch { } catch {
modaldata = "Fallo hacer las request"; modaldata = "Fallo hacer las request";
} }
} }
function getparams(){ function getparams() {
const qs = window.location.search; const qs = window.location.search;
const par = new URLSearchParams(qs); const par = new URLSearchParams(qs);
contratoid = par.get("id")||""; contratoid = par.get("id") || "";
} }
async function refreshCanon() { async function refreshCanon() {
try { try {
const ret = await fetch($urlG+"/api/contratos/canon?id="+contratoid, { const ret = await fetch(
method: "GET", $urlG + "/api/contratos/canon?id=" + contratoid,
headers: { {
"Auth": String(token), method: "GET",
} headers: {
}); Auth: String(token),
if (!ret.ok){ },
},
);
if (!ret.ok) {
let data = await ret.json(); let data = await ret.json();
modaldata = data.message; modaldata = data.message;
return; return;
@@ -162,42 +204,45 @@
return; return;
} }
try { try {
const resp = await fetch ($urlG+"/api/contrato/DocumentoFinal?idcontrato="+prop.id, { const resp = await fetch(
method: "GET", $urlG + "/api/contrato/DocumentoFinal?idcontrato=" + prop.id,
headers: { {
"Auth": String(token), method: "GET",
} headers: {
}); Auth: String(token),
},
},
);
if (!resp.ok) { if (!resp.ok) {
let blob = await resp.json(); let blob = await resp.json();
modaldata=blob.message; modaldata = blob.message;
return; return;
} }
let blob = await resp.blob(); let blob = await resp.blob();
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
window.open(blobUrl, '_blank'); window.open(blobUrl, "_blank");
setTimeout(() => URL.revokeObjectURL(blobUrl), 100000); setTimeout(() => URL.revokeObjectURL(blobUrl), 100000);
} catch { } catch {
modaldata= "fallo intentar hacer la request"; modaldata = "fallo intentar hacer la request";
} }
} }
async function realizarpago(mes: Date) { async function realizarpago(mes: Date) {
try { try {
const ret = await fetch($urlG+"/api/contratos/realizarPago", { const ret = await fetch($urlG + "/api/contratos/realizarPago", {
method: "POST", method: "POST",
headers: { headers: {
"Auth": String(token), Auth: String(token),
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({idcontrato:contratoid, fecha:mes}), body: JSON.stringify({ idcontrato: contratoid, fecha: mes }),
}); });
let data = await ret.json(); let data = await ret.json();
modaldata = data.message; modaldata = data.message;
if (ret.ok){ if (ret.ok) {
refreshCanon() refreshCanon();
return; return;
} }
} catch { } catch {
@@ -205,31 +250,36 @@
} }
} }
function generarTiket(mod: any) {
function generarTiket(mod:any) {
selMod = mod; selMod = mod;
showmodal =true; showmodal = true;
} }
async function pedirdocumento(op:boolean) { async function pedirdocumento(op: boolean) {
try { try {
const ret = await fetch($urlG+"/api/contrato/GenerarRecibo?html="+op, { const ret = await fetch(
method: "POST", $urlG + "/api/contrato/GenerarRecibo?html=" + op,
headers: { {
"Auth": String(token), method: "POST",
"Content-Type": "application/json", headers: {
}, Auth: String(token),
"Content-Type": "application/json",
},
body: JSON.stringify({fecha: selMod.mes, idcontrato: contratoid}) body: JSON.stringify({
}); fecha: selMod.mes,
idcontrato: contratoid,
}),
},
);
if (!ret.ok) { if (!ret.ok) {
let blob = await ret.json(); let blob = await ret.json();
modaldata=blob.message; modaldata = blob.message;
return; return;
} }
let blob = await ret.blob(); let blob = await ret.blob();
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
window.open(blobUrl, '_blank'); window.open(blobUrl, "_blank");
setTimeout(() => URL.revokeObjectURL(blobUrl), 100000); setTimeout(() => URL.revokeObjectURL(blobUrl), 100000);
} catch { } catch {
modaldata = "Fallo al intentar hacer la request"; modaldata = "Fallo al intentar hacer la request";
@@ -237,12 +287,12 @@
} }
async function cargarDefecto(data: AltaDefectoDto) { async function cargarDefecto(data: AltaDefectoDto) {
if(data.idcontrato ==0) data.idcontrato = prop.id; if (data.idcontrato == 0) data.idcontrato = prop.id;
try { try {
const r = await fetch($urlG+"/api/defecto", { const r = await fetch($urlG + "/api/defecto", {
method: "POST", method: "POST",
headers: { headers: {
"Auth": String(token), Auth: String(token),
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify(data), body: JSON.stringify(data),
@@ -252,38 +302,45 @@
if (r.ok) { if (r.ok) {
refreshDefectos(); refreshDefectos();
} }
}catch{ } catch {
modaldata = "Fallo al intentar hacer la request"; modaldata = "Fallo al intentar hacer la request";
} }
} }
async function refreshDefectos() { async function refreshDefectos() {
try { try {
const r = await fetch($urlG+"/api/defectos?Idcontrato="+contratoid, { const r = await fetch(
method: "GET", $urlG + "/api/defectos?Idcontrato=" + contratoid,
headers: { {
"Auth": token, method: "GET",
} headers: {
}); Auth: token,
let rr =await r.json(); },
},
);
let rr = await r.json();
defectos = rr; defectos = rr;
} catch { } catch {
modaldata ="No se pudo pedir la lista de Defectos"; modaldata = "No se pudo pedir la lista de Defectos";
} }
} }
async function ejercerOpcionVenta() { async function ejercerOpcionVenta() {
try { try {
const r = await fetch($urlG+"/api/ventas/ejercerOpcionVenta?idcontrato="+contratoid, { const r = await fetch(
method: "POST", $urlG +
headers: { "/api/ventas/ejercerOpcionVenta?idcontrato=" +
"Auth": token, contratoid,
} {
}); method: "POST",
headers: {
Auth: token,
},
},
);
let data = await r.json(); let data = await r.json();
modaldata =data.message; modaldata = data.message;
if(r.ok){ if (r.ok) {
opcionVenta(); opcionVenta();
return; return;
} }
@@ -293,14 +350,17 @@
} }
</script> </script>
<NavBarAutocompletable/> <NavBarAutocompletable />
{#if modaldata} {#if modaldata}
<ModalEstatico payload={modaldata} close={()=>!!(modaldata = "")}/> <ModalEstatico payload={modaldata} close={() => !!(modaldata = "")} />
{/if} {/if}
{#if showmodal} {#if showmodal}
<ModalPedirDoc onClose={()=>showmodal=false} onSubmit={pedirdocumento} /> <ModalPedirDoc
onClose={() => (showmodal = false)}
onSubmit={pedirdocumento}
/>
{/if} {/if}
<div class="container-fluid mt-4 d-flex"> <div class="container-fluid mt-4 d-flex">
@@ -315,7 +375,10 @@
<p><b>Habitaciones:</b> {prop.habitaciones}</p> <p><b>Habitaciones:</b> {prop.habitaciones}</p>
<p><b>Piso:</b> {prop.piso}</p> <p><b>Piso:</b> {prop.piso}</p>
<p><b>Letra:</b> {prop.letra}</p> <p><b>Letra:</b> {prop.letra}</p>
<p><b>Fecha Inicio:</b> {String(prop.fechainicio).split("T")[0]}</p> <p>
<b>Fecha Inicio:</b>
{String(prop.fechainicio).split("T")[0]}
</p>
<p><b>Estado:</b> {prop.estado}</p> <p><b>Estado:</b> {prop.estado}</p>
<button class="btn btn-secondary" onclick={verContrato}> <button class="btn btn-secondary" onclick={verContrato}>
Ver Contrato Ver Contrato
@@ -362,14 +425,14 @@
</thead> </thead>
<tbody> <tbody>
{#each garantes as g} {#each garantes as g}
<tr> <tr>
<td>{g.dni}</td> <td>{g.dni}</td>
<td>{g.nombre}</td> <td>{g.nombre}</td>
<td>{g.apellido}</td> <td>{g.apellido}</td>
<td>{g.domicilio}</td> <td>{g.domicilio}</td>
<td>{g.domiciliolaboral}</td> <td>{g.domiciliolaboral}</td>
<td>{g.celular}</td> <td>{g.celular}</td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
</table> </table>
@@ -386,7 +449,7 @@
aria-expanded="false" aria-expanded="false"
aria-controls="collapseTwo" aria-controls="collapseTwo"
> >
Canons Canones
</button> </button>
</h2> </h2>
<div <div
@@ -398,27 +461,53 @@
<div class="accordion-body"> <div class="accordion-body">
<div class="row"> <div class="row">
{#each canons as canon} {#each canons as canon}
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<div class="card"> <div class="card">
<div class="card-header text-center"> <div class="card-header text-center">
{canon.mesNum}/{prop.mesesDuracion} {canon.mesNum}/{prop.mesesDuracion}
</div> </div>
<div class="card-body"> <div class="card-body">
<p><strong>Mes:</strong> {String(canon.mes).split("T")[0]}</p> <p>
<p><strong>Monto:</strong> {canon.monto}</p> <strong>Mes:</strong>
<p><strong>Divisa:</strong> {canon.divisa}</p> {String(canon.mes).split(
<p><strong>Pago:</strong> {canon.pago ? "Sí" : "No"}</p> "T",
</div> )[0]}
<div class="card-footer d-flex justify-content-between"> </p>
<button class="btn btn-primary btn-xs" disabled={canon.pago} onclick={()=>realizarpago(canon.mes)}> <p>
Pagar <strong>Monto:</strong>
</button> {canon.monto}
<button class="btn btn-info btn-xs" disabled={!canon.pago} onclick={()=> generarTiket(canon)}> </p>
Generar Tiket <p>
</button> <strong>Divisa:</strong>
{canon.divisa}
</p>
<p>
<strong>Pago:</strong>
{canon.pago ? "Sí" : "No"}
</p>
</div>
<div
class="card-footer d-flex justify-content-between"
>
<button
class="btn btn-primary btn-xs"
disabled={canon.pago}
onclick={() =>
realizarpago(canon.mes)}
>
Pagar
</button>
<button
class="btn btn-info btn-xs"
disabled={!canon.pago}
onclick={() =>
generarTiket(canon)}
>
Generar Tiket
</button>
</div>
</div> </div>
</div> </div>
</div>
{/each} {/each}
</div> </div>
</div> </div>
@@ -442,102 +531,122 @@
class="accordion-collapse collapse" class="accordion-collapse collapse"
aria-labelledby="ht" aria-labelledby="ht"
data-bs-parent="#accordionExample" data-bs-parent="#accordionExample"
> >
<div class="accordion-body"> <div class="accordion-body">
{#if prop.estado != "Terminado"} {#if prop.estado != "Terminado"}
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
Notificar Defecto en Propiedad Notificar Defecto en Propiedad
</div>
<div class="card-body">
<FormAltaDefecto
onConfirm={cargarDefecto}
idcontrato={prop.id}
/>
</div>
<div class="card-footer"></div>
</div> </div>
<div class="card-body"> <br />
<FormAltaDefecto onConfirm={cargarDefecto} idcontrato={prop.id} />
</div>
<div class="card-footer">
</div>
</div>
<br>
{/if} {/if}
<table class="table table-hover table-striped"> <table class="table table-hover table-striped">
<thead> <thead>
<tr> <tr>
<th>Descripción</th> <th>Descripción</th>
<th>Costo</th> <th>Costo</th>
<th>Estado</th> <th>Estado</th>
<th>Paga Inquilino</th> <th>Paga Inquilino</th>
<th>Divisa</th> <th>Divisa</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#if defectos.length == 0} {#if defectos.length == 0}
<tr> <tr>
<td colspan="6">No hay defectos que mostrar</td> <td colspan="6"
</tr> >No hay defectos que mostrar</td
{:else} >
{#each defectos as defecto} </tr>
<tr> {:else}
<td>{defecto.descripcion}</td> {#each defectos as defecto}
<td>{defecto.costo}</td> <tr>
<td>{defecto.estado}</td> <td>{defecto.descripcion}</td>
<td>{defecto.pagainquilino}</td> <td>{defecto.costo}</td>
<td>{defecto.divisa}</td> <td>{defecto.estado}</td>
</tr> <td>{defecto.pagainquilino}</td>
{/each} <td>{defecto.divisa}</td>
{/if} </tr>
{/each}
{/if}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
{#if TieneOpcionVenta} {#if TieneOpcionVenta}
<div class="accordion-item">
<div class="accordion-item"> <h2 class="accordion-header" id="hq">
<h2 class="accordion-header" id="hq"> <button
<button class="accordion-button collapsed"
class="accordion-button collapsed" type="button"
type="button" data-bs-toggle="collapse"
data-bs-toggle="collapse" data-bs-target="#cq"
data-bs-target="#cq" aria-expanded="false"
aria-expanded="false" aria-controls="cq"
aria-controls="cq" >
Opcion Compra
</button>
</h2>
<div
id="cq"
class="accordion-collapse collapse"
aria-labelledby="hq"
data-bs-parent="#accordionExample"
> >
Opcion Venta <div class="accordion-body">
</button> <div class="card">
</h2> <div class="card-header">
<div Datos Opcion Compra
id="cq" </div>
class="accordion-collapse collapse" <div class="card-body">
aria-labelledby="hq" <b>Monto</b>: {dtoVenta.divisa}
data-bs-parent="#accordionExample" {dtoVenta.monto}.
>
<div class="accordion-body">
<div class="card">
<div class="card-header">
Datos Opcion Venta
</div>
<div class="card-body">
<b>Monto</b>: {dtoVenta.divisa} {dtoVenta.monto}.
<p class="mt-2 text-muted"> <p class="mt-2 text-muted">
Para poder ejercer la opcion de venta necesitas estar en el mismo mes que el ultimo pago y haber pagado todos los canones Para poder ejercer la opcion de venta
</p> necesitas estar en el mismo mes que el
<div class="d-flex justify-content-between"> ultimo pago y haber pagado todos los
<button class="btn btn-primary" disabled={dtoVenta.enOrden==false || dtoVenta.fueEjercido == true} onclick={()=>ejercerOpcionVenta()}> canones
Ejercer </p>
</button> <div class="d-flex justify-content-between">
{#if dtoVenta.fueEjercido} <button
<button class="btn btn-secondary" onclick={()=>navigate("/Ventas?idventa="+dtoVenta.id)}> class="btn btn-primary"
Ir a la pagina de la Venta disabled={dtoVenta.enOrden ==
false ||
dtoVenta.fueEjercido == true}
onclick={() => ejercerOpcionVenta()}
>
Ejercer
</button> </button>
{/if} {#if dtoVenta.fueEjercido}
<button
class="btn btn-secondary"
onclick={() =>
navigate(
"/Ventas?idventa=" +
dtoVenta.id,
)}
>
Ir a la pagina de la Venta
</button>
{/if}
</div>
</div>
<div class="card-footer text-center">
IdOpcionVenta: {dtoVenta.id}
</div> </div>
</div> </div>
<div class="card-footer text-center">IdOpcionVenta: {dtoVenta.id}</div>
</div> </div>
</div> </div>
</div> </div>
</div>
{/if} {/if}
</div> </div>
</div> </div>
@@ -363,7 +363,7 @@
if (canons.length > 0) { if (canons.length > 0) {
contenido += "ID,Mes Num,Mes,Monto,Divisa,Pago\n"; contenido += "ID,Mes Num,Mes,Monto,Divisa,Pago\n";
canons.forEach(c => { canons.forEach(c => {
let fila = [c.id, c.mesNum, String(c.mes).split("T")[0], c.monto, c.divisa, c.pago ? "Sí" : "No"].join(","); let fila = [c.id, c.mesNum, String(c.mes).split("T")[0], c.monto, c.divisa, c.pago ? "Si" : "No"].join(",");
contenido += fila + "\n"; contenido += fila + "\n";
}); });
} }
@@ -505,7 +505,7 @@
aria-expanded="false" aria-expanded="false"
aria-controls="collapseTwo" aria-controls="collapseTwo"
> >
Canons Canones
</button> </button>
</h2> </h2>
<div <div
@@ -642,7 +642,7 @@
aria-expanded="false" aria-expanded="false"
aria-controls="cq" aria-controls="cq"
> >
Opcion Venta Opcion Compra
</button> </button>
</h2> </h2>
<div <div
@@ -654,13 +654,13 @@
<div class="accordion-body"> <div class="accordion-body">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
Datos Opcion Venta Datos Opcion Compra
</div> </div>
<div class="card-body"> <div class="card-body">
<b>Monto</b>: {dtoVenta.divisa} {dtoVenta.monto}. <b>Monto</b>: {dtoVenta.divisa} {dtoVenta.monto}.
<p class="mt-2 text-muted"> <p class="mt-2 text-muted">
Para que el inquilino pueda ejercer la opcion de venta necesitas estar en el mismo mes que el ultimo pago y haber pagado todos los canones Para que el inquilino pueda ejercer la opcion de Compra necesitas estar en el mismo mes que el ultimo pago y haber pagado todos los canones
</p> </p>
<div class="d-flex"> <div class="d-flex">
<button class="btn btn-primary" disabled={!dtoVenta.fueEjercido} onclick={()=>navigate("/Ventas?idventa="+dtoVenta.id)}> <button class="btn btn-primary" disabled={!dtoVenta.fueEjercido} onclick={()=>navigate("/Ventas?idventa="+dtoVenta.id)}>
+173
View File
@@ -0,0 +1,173 @@
<script lang="ts">
import { onMount } from "svelte";
import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte";
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import { urlG } from "../stores/urlStore";
import type { CrearUsuario, Grupo, GrupoDto } from "../types";
let formData: CrearUsuario = $state({
Dni: 0,
Nombre: '',
Apellido: '',
Domicilio: '',
Celular: '',
Email: '',
Contraseña: '',
EmailRecuperacion: null,
grupos: []
});
let token = sessionStorage.getItem("token");
let grupos: GrupoDto[] = $state([]);
let modaldata: string = $state("");
onMount(async ()=>{
obtenerGrupos();
});
async function obtenerGrupos(){
try {
const req = await fetch($urlG+ "/api/admin/grupos", {
method: "GET",
headers: {
"Auth": token,
}
});
let data = await req.json();
if (req.ok){
grupos= data;
} else{
modaldata = data.message;
}
} catch{
modaldata = "Fallo al hacer la request";
}
}
const resetForm = () => {
formData = {
Dni: 0,
Nombre: '',
Apellido: '',
Domicilio: '',
Celular: '',
Email: '',
Contraseña: '',
EmailRecuperacion: null,
grupos: []
};
};
async function handleSubmit(e:Event){
e.preventDefault();
try{
const req = await fetch($urlG +"/api/crearusuario", {
method: "POST",
headers: {
"Auth": token,
"Content-Type": "Application/json"
},
body: JSON.stringify(formData)
});
let data = await req.json();
modaldata = data.message;
if (req.ok){
resetForm();
}
}catch {
modaldata = "Fallo al hacer la request";
}
}
const toggleGrupo = (id: number) => {
const index = formData.grupos.indexOf(id);
if (index === -1) {
formData.grupos = [...formData.grupos, id];
} else {
formData.grupos = formData.grupos.filter(g => g !== id);
}
};
</script>
{#if modaldata}
<ModalEstatico payload={modaldata} close={()=>!!(modaldata="")}/>
{/if}
<NavBarAutocompletable/>
<div class="container mt-4">
<BarraHorizontalConTexto text="Crear Usuario" />
<form onsubmit={(e)=>handleSubmit(e)} class="row g-3 mt-2" id="formcrearusu">
<!-- DNI -->
<div class="col-md-6">
<label for="dni" class="form-label">DNI</label>
<input type="number" min="0" max="99999999" id="dni" bind:value={formData.Dni} class="form-control" required />
</div>
<!-- Nombre -->
<div class="col-md-6">
<label for="nombre" class="form-label">Nombre</label>
<input type="text" id="nombre" bind:value={formData.Nombre} class="form-control" maxlength="20" required/>
</div>
<!-- Apellido -->
<div class="col-md-6">
<label for="apellido" class="form-label">Apellido</label>
<input type="text" id="apellido" bind:value={formData.Apellido} class="form-control" maxlength="20" required/>
</div>
<!-- Domicilio -->
<div class="col-md-6">
<label for="domicilio" class="form-label">Domicilio</label>
<input type="text" id="domicilio" bind:value={formData.Domicilio} class="form-control" maxlength="40" required/>
</div>
<!-- Celular -->
<div class="col-md-6">
<label for="celular" class="form-label">Celular</label>
<input type="tel" id="celular" bind:value={formData.Celular} class="form-control" maxlength="40" required/>
</div>
<!-- Email -->
<div class="col-md-6">
<label for="email" class="form-label">Email</label>
<input type="email" id="email" bind:value={formData.Email} class="form-control" maxlength="50" required/>
</div>
<!-- Email Recuperación -->
<div class="col-md-6">
<label for="recuperacion" class="form-label">Email de Recuperación</label>
<input type="email" id="recuperacion" bind:value={formData.EmailRecuperacion} class="form-control" maxlength="50" />
</div>
<!-- Contraseña -->
<div class="col-md-6">
<label for="contrasena" class="form-label">Contraseña</label>
<input type="password" id="contrasena" bind:value={formData.Contraseña} class="form-control" required minlength="8"/>
</div>
<!-- Grupos -->
<div class="col-md-6">
<p class="form-label">Selecciona Grupos</p>
<div class="d-flex flex-wrap gap-2">
{#each grupos as grupo}
<button
type="button"
class="btn {formData.grupos.includes(grupo.idgrupo) ? 'btn-primary' : 'btn-outline-secondary'}"
onclick={() => toggleGrupo(grupo.idgrupo)}
>
{grupo.nombre}
</button>
{/each}
</div>
</div>
<!-- Botón -->
<div class="col-12 mt-3">
<button type="submit" class="btn btn-success">Crear Usuario</button>
</div>
</form>
</div>
+183
View File
@@ -0,0 +1,183 @@
<script lang="ts">
import { onMount } from "svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import type { GrupoDto, PermisoDto } from "../types";
import { urlG } from "../stores/urlStore";
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte";
import BotonEsquina from "../Componentes/BotonEsquina.svelte";
import ModalEditarPermiso from "../Componentes/ModalEditarPermiso.svelte";
const token: string = sessionStorage.getItem("token") || "";
let permisos: PermisoDto[] = $state([]);
let selpermiso: PermisoDto = $state({ descripcion: "", id: 0 });
let modaldat: string = $state("");
let showmodaladd = $state(false);
let showmodaledit = $state(false);
onMount(() => {
obtenerPermisos();
});
async function submitedit(a: GrupoDto) {
let b = a;
try {
let req = await fetch($urlG + "/api/grupo", {
method: "PATCH",
headers: {
Auth: token,
"Content-Type": "application/json",
},
body: JSON.stringify(b),
});
const resp = await req.json();
modaldat = resp.message;
if (req.ok) {
obtenerPermisos;
}
} catch {
modaldat = "Fallo al hacer la request";
}
}
async function obtenerPermisos() {
try {
let a = await fetch($urlG + "/api/permisos/todos", {
method: "GET",
headers: {
Auth: token,
},
});
if (!a.ok) {
modaldat = "Fallo al obtener los permisos";
return;
}
permisos = await a.json();
} catch {
modaldat = "Fallo Al intentar hacer la request";
}
}
async function NuevoPermiso(a: PermisoDto) {
let b = a;
try {
const req = await fetch($urlG + "/api/permisos", {
method: "POST",
headers: {
Auth: token,
"Content-Type": "application/json",
},
body: JSON.stringify(b),
});
if (req.ok) {
obtenerPermisos();
return;
}
modaldat = "Hubieron problemas creando el permiso";
return;
} catch {
modaldat = "Fallo al hacer la request";
}
}
async function PatchPermiso(a: PermisoDto) {
let b = a;
try {
const req = await fetch($urlG + "/api/permisos", {
method: "PATCH",
headers: {
Auth: token,
"Content-Type": "application/json",
},
body: JSON.stringify(b),
});
if (req.ok) {
obtenerPermisos();
return;
}
modaldat = "Hubieron problemas editando el permiso";
return;
} catch {
modaldat = "Fallo al hacer la request";
}
}
</script>
{#if modaldat != ""}
<ModalEstatico payload={modaldat} close={() => !!(modaldat = "")} />
{/if}
<NavBarAutocompletable />
<div class="container-fluid mt-2">
<BarraHorizontalConTexto text="Gestionar Permisos" />
{#if permisos.length == 0}
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
{:else}
<div class="position-relative z-1">
<BotonEsquina handleclick={() => (showmodaladd = true)} />
</div>
{#if showmodaladd}
<ModalEditarPermiso
onClose={() => (showmodaladd = false)}
permiso={{ descripcion: "", id: 0 }}
onSubmit={NuevoPermiso}
modalTitle="Nuevo Permiso"
/>
{/if}
{#if showmodaledit}
<div class="position-relative z-2">
<ModalEditarPermiso
onClose={(a: string) => {
showmodaledit = false;
selpermiso.descripcion = a;
}}
bind:permiso={selpermiso}
onSubmit={PatchPermiso}
modalTitle="Modificar Permiso"
/>
</div>
{/if}
<div class="card mb-3">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Descripción</th>
<th scope="col">Acciones</th>
</tr>
</thead>
<tbody>
{#each permisos as permiso}
<tr>
<td>{permiso.id}</td>
<td>{permiso.descripcion}</td>
<td>
<div
class="d-flex justify-content-between"
>
<button
class="btn btn-warning btn-sm"
onclick={() => {
showmodaledit = true;
selpermiso = permiso;
}}>Editar</button
>
</div>
</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>
{/if}
</div>
+258 -82
View File
@@ -4,39 +4,52 @@
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte"; import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import FChart from "../Componentes/Estadisticas/fChart.svelte"; import FChart from "../Componentes/Estadisticas/fChart.svelte";
import ModalEstatico from "../Componentes/ModalEstatico.svelte"; import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import {urlG} from "../stores/urlStore"; import { urlG } from "../stores/urlStore";
import type { ChartData } from "../types"; import type { ChartData, IngresosDto } from "../types";
let token = sessionStorage.getItem("token")||""; let token = sessionStorage.getItem("token") || "";
let y = $state(2025); let y = $state(2025);
let cdata:ChartData|any = $state(); let cdata: ChartData | any = $state();
let aldata:{id:number, ubicacion:string, divisa:string}[]= $state([]); let aldata: { id: number; ubicacion: string; divisa: string }[] = $state(
[],
);
let chartMesesDuracion:ChartData|any = $state(); let chartMesesDuracion: ChartData | any = $state();
let tablaMesesDuracion:{meses:number, repes:number, semaforizacion:string}[] = $state([]); let tablaMesesDuracion: {
meses: number;
repes: number;
semaforizacion: string;
}[] = $state([]);
let modaldata:string = $state(""); let showModoDaltonico: boolean = $state(false);
let modaldata: string = $state("");
onMount(async() => { onMount(async () => {
await dataAlquileresporAño(); await dataAlquileresporAño();
}); });
async function dataAlquileresporAño(year = 2025) { async function dataAlquileresporAño(year = 2025) {
try{ try {
const rep = fetch($urlG+"/api/stats/alquileresIniciados?year="+year, { const rep = fetch(
method : "GET", $urlG + "/api/stats/alquileresIniciados?year=" + year,
headers: { {
"Auth": token, method: "GET",
} headers: {
}); Auth: token,
const pre = fetch($urlG+"/api/tabla/alquileresIniciados?year="+year, { },
method : "GET", },
headers: { );
"Auth": token, const pre = fetch(
} $urlG + "/api/tabla/alquileresIniciados?year=" + year,
}); {
let [r,p] = await Promise.all([rep, pre]); method: "GET",
headers: {
Auth: token,
},
},
);
let [r, p] = await Promise.all([rep, pre]);
let data = await r.json(); let data = await r.json();
let data2 = await p.json(); let data2 = await p.json();
@@ -44,77 +57,128 @@
cdata = data; cdata = data;
aldata = data2; aldata = data2;
return; return;
}catch{ } catch {
modaldata="Fallo al intentar alcanzar el servidor"; modaldata = "Fallo al intentar alcanzar el servidor";
} }
} }
let visibleMesesDuracion:boolean = $state(false); let visibleMesesDuracion: boolean = $state(false);
async function dataMesesDuracion() { async function dataMesesDuracion() {
try{ try {
const p1 = fetch($urlG+"/api/stats/duracionContrato", { const p1 = fetch($urlG + "/api/stats/duracionContrato", {
method : "GET", method: "GET",
headers: { headers: {
"Auth": token, Auth: token,
} },
}); });
const p2 = fetch($urlG+"/api/tabla/duracionContrato", { const p2 = fetch($urlG + "/api/tabla/duracionContrato", {
method : "GET", method: "GET",
headers: { headers: {
"Auth": token, Auth: token,
} },
}); });
let [r1, r2] = await Promise.all([p1,p2]); let [r1, r2] = await Promise.all([p1, p2]);
let [d1,d2] = await Promise.all([r1.json(), r2.json()]) let [d1, d2] = await Promise.all([r1.json(), r2.json()]);
chartMesesDuracion = d1; chartMesesDuracion = d1;
tablaMesesDuracion = d2; tablaMesesDuracion = d2;
}catch { } catch {
modaldata="Fallo al intentar alcanzar el servidor"; modaldata = "Fallo al intentar alcanzar el servidor";
} }
} }
function toggleModoDaltonico() { function toggleModoDaltonico() {
if (tablaMesesDuracion== null) return; if (tablaMesesDuracion == null) return;
tablaMesesDuracion.forEach(item => { tablaMesesDuracion.forEach((item) => {
if (item.semaforizacion === '🟢') { if (item.semaforizacion === "🟢") {
item.semaforizacion = '🔵'; item.semaforizacion = "🔵";
} else if (item.semaforizacion === '🔵') { } else if (item.semaforizacion === "🔵") {
item.semaforizacion = '🟢'; item.semaforizacion = "🟢";
} }
}); });
} }
const nombresMeses = [
"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
];
let ingresos: IngresosDto[] = $state([]);
let chartingresos: ChartData | null = $state(null);
let yearr:number = $state(0);
async function getIngresos(year:number) {
try{
const req = await fetch($urlG+"/api/stats/Pagos?year="+year, {
method:"GET",
headers: {
"Auth": token || "",
},
});
const data = await req.json();
if (req.ok){
ingresos = data.tabla.map(item => ({
...item,
mes: nombresMeses[Number(item.mes) - 1]
}));
chartingresos = data.chart;
} else {
modaldata = data.message;
}
}catch{
modaldata="Fallo la req para obtener ingresos";
}
}
</script> </script>
{#if modaldata} {#if modaldata}
<ModalEstatico payload={modaldata} close={()=>!!(modaldata = "")} /> <ModalEstatico payload={modaldata} close={() => !!(modaldata = "")} />
{/if} {/if}
<NavBarAutocompletable/> <NavBarAutocompletable />
<div class="container-fluid"> <div class="container-fluid">
<div class="row mt-4" > <div class="row mt-4">
<BarraHorizontalConTexto text="Estadisticas"/> <BarraHorizontalConTexto text="Estadisticas" />
<div class="accordion" id="accordionExample"> <div class="accordion" id="accordionExample">
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header" id="hea1"> <h2 class="accordion-header" id="hea1">
<button class="accordion-button" <button
type="button" class="accordion-button"
data-bs-toggle="collapse" type="button"
data-bs-target="#c1" data-bs-toggle="collapse"
aria-expanded="true" data-bs-target="#c1"
aria-controls="c1"> aria-expanded="true"
aria-controls="c1"
Alquileres en el ultimo año >
Alquileres Por Mes
</button> </button>
</h2> </h2>
<div class="accordion-collapse collapse show" id="c1" data-bs-parent="#accordionExample"> <div
class="accordion-collapse collapse show"
id="c1"
data-bs-parent="#accordionExample"
>
<div class="accordion-body row"> <div class="accordion-body row">
<div class="col"> <div class="col">
<div class="d-flex input-group"> <div class="d-flex input-group">
<input class="form-control" type="number" bind:value={y}> <input
<button class="btn btn-primary" onclick={()=>dataAlquileresporAño(y)}><img src="/zoom.svg" alt="lupa" aria-label="Lupa">Buscar</button> class="form-control"
type="number"
bind:value={y}
/>
<button
class="btn btn-primary"
onclick={() => dataAlquileresporAño(y)}
><img
src="/zoom.svg"
alt="lupa"
aria-label="Lupa"
/>Buscar</button
>
</div> </div>
<p class="text-muted">
Todos los Alquileres de un año mostrados por mes
</p>
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
@@ -125,18 +189,18 @@
</thead> </thead>
<tbody> <tbody>
{#each aldata as al} {#each aldata as al}
<tr> <tr>
<td>{al.id}</td> <td>{al.id}</td>
<td>{al.ubicacion}</td> <td>{al.ubicacion}</td>
<td>{al.divisa}</td> <td>{al.divisa}</td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="col"> <div class="col">
{#if cdata} {#if cdata}
<FChart chartData={cdata}/> <FChart chartData={cdata} />
{/if} {/if}
</div> </div>
</div> </div>
@@ -144,27 +208,51 @@
</div> </div>
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header" id="hea2"> <h2 class="accordion-header" id="hea2">
<button class="accordion-button" <button
data-bs-toggle="collapse" class="accordion-button collapsed"
data-bs-target="#c2" type="button"
onclick={()=>{ data-bs-toggle="collapse"
if(visibleMesesDuracion === true){ data-bs-target="#c2"
visibleMesesDuracion=false; aria-expanded="false"
return; aria-controls="c2"
} else if (visibleMesesDuracion== false){ onclick={() => {
dataMesesDuracion(); if (visibleMesesDuracion === true) {
visibleMesesDuracion = false;
} return;
}} } else if (visibleMesesDuracion === false) {
visibleMesesDuracion = true;
showModoDaltonico = false;
dataMesesDuracion();
}
}}
> >
Meses De Duracion Meses De Duracion
</button> </button>
</h2> </h2>
<div class="accordion-collapse collapse" id="c2" data-bs-parent="#accordionExample"> <div
class="accordion-collapse collapse"
id="c2"
data-bs-parent="#accordionExample"
>
<div class="accordion-body row"> <div class="accordion-body row">
<div class="col"> <div class="col">
<p class="text-muted">Objetivo: <i>Mide la longitud de los contratos en meses y cuantos hay por cada longitud. por lo menos 2.</i></p> <p class="text-muted">
<input class="form-check-input" type="checkbox" onclick={toggleModoDaltonico}> Activar Modo Daltónico Objetivo: <i
>Mide la longitud de los contratos en meses
y cuantos hay por cada longitud. por lo
menos 2.</i
>
</p>
<input
class="form-check-input"
type="checkbox"
onclick={() => {
showModoDaltonico = !showModoDaltonico;
toggleModoDaltonico();
}}
checked={showModoDaltonico}
/>
Activar Modo Daltónico
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
@@ -186,7 +274,95 @@
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
{#if chartMesesDuracion} {#if chartMesesDuracion}
<FChart chartData={chartMesesDuracion} typec="pie"/> <FChart
chartData={chartMesesDuracion}
typec="pie"
/>
{/if}
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#c3"
aria-expanded="false"
aria-controls="c3"
onclick={async ()=> {
if (yearr ==0){
yearr = new Date().getFullYear();
getIngresos(yearr);
} else if (yearr != 0){
yearr = 0;
}}}
>
Estado Pagos por Mes
</button>
</h2>
<div class="accordion-collapse collapse" id="c3"
data-bs-parent="#accordionExample"
>
<div class="accordion-body row">
<div class="col">
<div class="d-flex input-group">
<input
class="form-control"
type="number"
bind:value={yearr}
/>
<button
class="btn btn-primary"
onclick={() => getIngresos(yearr)}
><img
src="/zoom.svg"
alt="lupa"
aria-label="Lupa"
/>Buscar</button
>
</div>
<p class="text-muted">
Todos los canones ya sean pagados, Pagados Atrasados o Sin Realizar
</p>
{#if ingresos.length == 0}
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Cargando...</span>
</div>
</div>
{:else}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Mes</th>
<th>Pagos Realizados</th>
<th>Pagos Atrasados</th>
<th>Pagos Sin Realizar</th>
</tr>
</thead>
<tbody>
{#each ingresos as i }
<tr>
<td>{i.mes}</td>
<td>{i.realizados}</td>
<td>{i.atrasados}</td>
<td>{i.sin_realizar}</td>
</tr>
{/each}
</tbody>
</table>
{/if}
</div>
<div class="col">
{#if chartingresos != null}
<FChart
chartData={chartingresos}
typec="line"
/>
{/if} {/if}
</div> </div>
</div> </div>
+25 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte"; import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import type { GaranteDto, MensajeDto } from "../types"; import type { GaranteDto, MensajeDto, PreContratoData } from "../types";
import ModalEstatico from "../Componentes/ModalEstatico.svelte"; import ModalEstatico from "../Componentes/ModalEstatico.svelte";
import { urlG } from "../stores/urlStore"; import { urlG } from "../stores/urlStore";
import ModalConfirm from "../Componentes/ModalConfirm.svelte"; import ModalConfirm from "../Componentes/ModalConfirm.svelte";
@@ -113,6 +113,7 @@
if (mensaje.accion === "Carge Garantes") { if (mensaje.accion === "Carge Garantes") {
Selmens = { ...mensaje }; Selmens = { ...mensaje };
setCantGarantes = Number(Selmens.mensaje.split(" ").reverse()[1]); setCantGarantes = Number(Selmens.mensaje.split(" ").reverse()[1]);
ObtenerDatosPreContrato();
return; return;
} }
@@ -467,6 +468,28 @@
} }
showConsultaCompra = false; Selmens.accion = ""; showConsultaCompra = false; Selmens.accion = "";
} }
let datosprecontrato: PreContratoData = $state({});
async function ObtenerDatosPreContrato(){
try {
const req = await fetch($urlG + "/api/precontrato/preCargaGarantes/data?propiedadId="+Selmens.propiedad, {
method: 'GET',
headers: {
"Auth": token || "",
}
});
const data = await req.json();
if (req.ok){
datosprecontrato = data;
return;
}
modaldata = data.message;
} catch {
modaldata = "Fallo al obtener los datos del precontrato";
}
}
</script> </script>
<NavBarAutocompletable/> <NavBarAutocompletable/>
@@ -478,7 +501,7 @@
{#if Selmens.accion == "Nuevo Alquiler" } {#if Selmens.accion == "Nuevo Alquiler" }
<ModalPrecontrato onClose={() => (Selmens.accion = "")} onSubmit={handleEnviarmensaje2} /> <ModalPrecontrato onClose={() => (Selmens.accion = "")} onSubmit={handleEnviarmensaje2} />
{:else if Selmens.accion == "Carge Garantes"} {:else if Selmens.accion == "Carge Garantes"}
<ModalAddGarantes maxGarantes={setCantGarantes} onClose={() => (Selmens.accion = "")} onSubmit={handleEnviarmensaje3}/> <ModalAddGarantes maxGarantes={setCantGarantes} onClose={() => (Selmens.accion = "")} onSubmit={handleEnviarmensaje3} {datosprecontrato}/>
{:else if Selmens.accion == "Check y Contrato"} {:else if Selmens.accion == "Check y Contrato"}
<ModalCheckYContrato {garantes} men={Selmens} onCancel={handleCancelPrecontrato} onClose={() => (Selmens.accion = "")} onConfirm={handleEnviarmensaje4}/> <ModalCheckYContrato {garantes} men={Selmens} onCancel={handleCancelPrecontrato} onClose={() => (Selmens.accion = "")} onConfirm={handleEnviarmensaje4}/>
{:else if Selmens.accion == "Aceptar Contrato"} {:else if Selmens.accion == "Aceptar Contrato"}
+296
View File
@@ -0,0 +1,296 @@
<script lang="ts">
import { onMount } from "svelte";
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
import BarraHorizontalConTexto from "../Componentes/BarraHorizontalConTexto.svelte";
import type { ClientePanel } from "../types";
import { urlG } from "../stores/urlStore";
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
let token: string = sessionStorage.getItem("token") || "";
let user: ClientePanel | null = $state(null);
let showmodal: boolean = $state(false);
let showrecuperacionset: boolean = $state(false);
let modaldata: string = $state("");
onMount(async () => {
fetchusuario();
});
async function fetchusuario() {
try {
let req = await fetch($urlG + "/api/usuario", {
method: "GET",
headers: {
Auth: token,
},
});
if (!req.ok) {
modaldata = (await req.json()).message;
return;
}
user = await req.json();
} catch {
modaldata = "no se pudo hacer la request";
}
}
async function submitpass(e: Event) {
e.preventDefault();
const target = e.target as HTMLFormElement;
const passwordInput = target.querySelector(
"#contraseña",
) as HTMLInputElement;
const password = passwordInput.value;
try {
let req = await fetch($urlG + "/api/usuario", {
method: "PATCH",
headers: { Auth: token, "Content-Type": "application/json" },
body: JSON.stringify({ contraseña: password }),
});
showmodal = false;
modaldata = (await req.json()).message;
return;
} catch {
modaldata = "no se pudo hacer la request";
}
}
async function submitemail(e: Event) {
e.preventDefault();
const t = e.target as HTMLFormElement;
const emailinput = t.querySelector(
"#emailRecuperacion",
) as HTMLInputElement;
const email: string = emailinput.value;
try {
let req = await fetch($urlG + "/api/usuario/emailrecuperacion", {
method: "PUT",
headers: { Auth: token, "Content-Type": "Application/json" },
body: JSON.stringify({ EmailRecuperacion: email }),
});
showmodal = false;
modaldata = (await req.json()).message;
if (req.ok) {
fetchusuario();
}
showrecuperacionset = false;
} catch {
modaldata = "no se pudo hacer la request";
showrecuperacionset = false;
}
}
</script>
{#if modaldata}
<ModalEstatico close={() => !!(modaldata = "")} payload={modaldata} />
{/if}
<NavBarAutocompletable />
<div class="mt-2">
<BarraHorizontalConTexto text="Panel de Usuario" />
</div>
<div
class="container d-flex justify-content-center align-items-center flex-column mt-2 mx-auto"
>
<!-- Información del Usuario -->
<div class="w-75 mb-4">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">Información Personal</h5>
</div>
<div class="card-body">
{#if !user}
<div class="d-flex justify-content-center my-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Cargando...</span>
</div>
</div>
{:else}
<div class="mb-3">
<h6 class="text-muted fw-bold">DNI</h6>
<p class="lead">{user.dni}</p>
</div>
<div class="mb-3">
<h6 class="text-muted fw-bold">Nombre</h6>
<p class="lead">{user.nombre}</p>
</div>
<div class="mb-3">
<h6 class="text-muted fw-bold">Apellido</h6>
<p class="lead">{user.apellido}</p>
</div>
<div class="mb-3">
<h6 class="text-muted fw-bold">Domicilio</h6>
<p class="lead">{user.domicilio}</p>
</div>
<div class="mb-3">
<h6 class="text-muted fw-bold">Celular</h6>
<p class="lead">{user.celular}</p>
</div>
<div class="mb-3">
<h6 class="text-muted fw-bold">Correo Electrónico</h6>
<p class="lead">{user.email}</p>
</div>
<div class="mb-3">
<button
class="btn btn-primary"
onclick={() => (showmodal = true)}
>Cambiar Contraseña</button
>
</div>
{/if}
</div>
</div>
</div>
<!-- Esto es un modal para el cambio de contraseña -->
{#if showmodal}
<div
class="modal show d-block"
tabindex="-1"
style="background-color: rgba(0,0,0,0.3);"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Ingrese información</h5>
<button
type="button"
class="btn-close"
onclick={() => (showmodal = false)}
aria-label="Close"
></button>
</div>
<form onsubmit={submitpass}>
<div class="modal-body">
<div class="mb-3">
<div class="mb-3 text-muted">
<small
>La contraseña debe tener al menos 8
caracteres</small
>
</div>
<label for="contraseña" class="form-label"
>Contraseña</label
>
<input
type="text"
class="form-control"
id="contraseña"
placeholder="********"
/>
</div>
</div>
<div
class="modal-footer d-flex justify-content-between"
>
<button
type="button"
class="btn btn-secondary"
onclick={() => (showmodal = false)}
>Cerrar</button
>
<button type="submit" class="btn btn-primary"
>Guardar cambios</button
>
</div>
</form>
</div>
</div>
</div>
{/if}
<!-- Información de Correo de Recuperación -->
<div class="w-75 mb-4">
<div class="card">
<div class="card-header bg-secondary text-white">
<h5 class="mb-0">Correo de Recuperación</h5>
</div>
<div class="card-body">
{#if !user}
<div class="d-flex justify-content-center my-5">
<div class="spinner-border text-info" role="status">
<span class="visually-hidden">Cargando...</span>
</div>
</div>
{:else}
<div class="mb-3">
<h6 class="text-muted fw-bold">
Email de Recuperación
</h6>
<p class="lead">
{user.emailRecuperacion || "No configurado"}
</p>
</div>
<div class="mb-3">
<button
class="btn btn-secondary text-white"
onclick={() => (showrecuperacionset = true)}
>Actualizar Email de Recuperación</button
>
</div>
{#if showrecuperacionset}
<div
class="modal show d-block"
tabindex="-1"
style="background-color: rgba(0,0,0,0.3);"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
Actualizar Email de Recuperación
</h5>
<button
type="button"
class="btn-close"
onclick={() =>
(showrecuperacionset = false)}
aria-label="Close"
></button>
</div>
<form onsubmit={(e) => submitemail(e)}>
<div class="modal-body">
<div class="mb-3">
<label
for="emailRecuperacion"
class="form-label"
>Email de Recuperación</label
>
<input
type="email"
class="form-control"
id="emailRecuperacion"
placeholder="correo@ejemplo.com"
/>
</div>
</div>
<div
class="modal-footer d-flex justify-content-between"
>
<button
type="button"
class="btn btn-secondary"
onclick={() =>
(showrecuperacionset = false)}
>Cancelar</button
>
<button
type="submit"
class="btn btn-primary"
>Guardar</button
>
</div>
</form>
</div>
</div>
</div>
{/if}
{/if}
</div>
</div>
</div>
</div>
+62 -46
View File
@@ -9,25 +9,25 @@
import PaginacionStepper from "../Componentes/PaginacionStepper.svelte"; import PaginacionStepper from "../Componentes/PaginacionStepper.svelte";
let Logs: LogDto[] = $state([]); let Logs: LogDto[] = $state([]);
let pagina:number = $state(1); let pagina: number = $state(1);
let token:string = sessionStorage.getItem("token")||""; let token: string = sessionStorage.getItem("token") || "";
let modaldata:string = $state(""); let modaldata: string = $state("");
let showmodal:boolean =$state(false); let showmodal: boolean = $state(false);
let ll:LogDto|any = $state({}); let ll: LogDto | any = $state({});
let cantpag:number = $state(0); let cantpag: number = $state(0);
onMount(()=>{ onMount(() => {
obtenerLogs(); obtenerLogs();
obtenerPaginas(); obtenerPaginas();
}); });
async function obtenerPaginas() { async function obtenerPaginas() {
try{ try {
const r = await fetch($urlG+"/api/Logs/cantPag", { const r = await fetch($urlG + "/api/Logs/cantPag", {
method: "GET", method: "GET",
headers: { headers: {
"Auth": token, Auth: token,
} },
}); });
let data = await r.json(); let data = await r.json();
if (r.ok) { if (r.ok) {
@@ -41,12 +41,12 @@
} }
async function obtenerLogs() { async function obtenerLogs() {
try{ try {
const r = await fetch($urlG+"/api/Logs?pag="+pagina, { const r = await fetch($urlG + "/api/Logs?pag=" + pagina, {
method: "GET", method: "GET",
headers: { headers: {
"Auth": token, Auth: token,
} },
}); });
let data = await r.json(); let data = await r.json();
if (r.ok) { if (r.ok) {
@@ -63,49 +63,65 @@
ll = l; ll = l;
showmodal = true; showmodal = true;
} }
function queryPag(a:number) { function queryPag(a: number) {
pagina = a; pagina = a;
obtenerLogs(); obtenerLogs();
} }
</script> </script>
<NavBarAutocompletable/> <NavBarAutocompletable />
{#if modaldata} {#if modaldata}
<ModalEstatico payload={modaldata} close={()=>!!(modaldata = "")}/> <ModalEstatico payload={modaldata} close={() => !!(modaldata = "")} />
{/if} {/if}
{#if showmodal} {#if showmodal}
<ModalLogs onClose={()=>!!(showmodal=!showmodal)} log={ll}/> <ModalLogs onClose={() => !!(showmodal = !showmodal)} log={ll} />
{/if} {/if}
<div class="container-fluid mt-2"> <div class="container-fluid mt-2">
<BarraHorizontalConTexto text={"Logs"}/> <BarraHorizontalConTexto text={"Logs"} />
<table class="table table-responsive table-hover table-striped"> <div
<thead> class="table-container"
<tr> style="height: 80vh; overflow-y: auto; margin-bottom: 2.5rem;"
<th>Fecha</th> >
<th>Id Usuario</th> <table class="table table-responsive table-hover table-striped">
<th>Accion</th> <thead>
<th></th> <tr>
</tr> <th>Fecha</th>
</thead> <th>Id Usuario</th>
<tbody> <th>Accion</th>
{#each Logs as l} <th></th>
<tr> </tr>
<td>{l.fecha}</td> </thead>
<td>{l.dniusuario}</td> <tbody>
<td>{l.accion}</td> {#each Logs as l}
<td> <tr>
<button class="btn btn-primary" onclick={()=>prepararModal(l)}> <td>{l.fecha}</td>
Ver <td>{l.dniusuario}</td>
</button> <td>{l.accion}</td>
</td> <td>
</tr> <button
{/each} class="btn btn-primary"
</tbody> onclick={() => prepararModal(l)}
</table> >
<div class="d-flex justify-content-center"> Ver
<PaginacionStepper currentPag={pagina} {cantpag} {queryPag} centrado={true}/> </button>
</td>
</tr>
{/each}
</tbody>
</table>
<div
class="fixed-bottom w-100 d-flex justify-content-center border-top py-2"
style="background-color: rgba(0,0,0,0.5);"
>
<PaginacionStepper
currentPag={pagina}
{cantpag}
{queryPag}
centrado={true}
/>
</div>
</div> </div>
</div> </div>
+15
View File
@@ -0,0 +1,15 @@
<script lang="ts">
import ListaAcciones from "../../Componentes/ListaAcciones.svelte";
import NavBarAutocompletable from "../../Componentes/NavBarAutocompletable.svelte";
let { id }: { id: string } = $props();
</script>
<NavBarAutocompletable />
<div class="container mt-5">
<div class="text-center mb-4">
<h1>Menu grupo: {id}</h1>
</div>
{#key id}
<ListaAcciones />
{/key}
</div>
+50
View File
@@ -219,3 +219,53 @@ export type PatchPropiedad = {
monto:number, monto:number,
iddivisa:number iddivisa:number
} }
export type GrupoDto = {
idgrupo:number,
nombre:string,
habilitado:boolean
gruposIncluidos:string[],
permisos:PermisoDto[]
}
export type PermisoDto = {
id:number,
descripcion:string
}
export type ClientePanel = {
dni:number,
nombre:string,
apellido:string,
domicilio:string,
celular:string,
email:string,
emailRecuperacion:string|null
}
export type IngresosDto = {
mes:number,
realizados:number,
atrasados:number,
sin_realizar:number
}
export type CrearUsuario = {
Dni: number;
Nombre: string;
Apellido: string;
Domicilio: string;
Celular: string;
Email: string;
Contraseña: string;
EmailRecuperacion?: string | null;
grupos: number[];
}
export type PreContratoData = {
tieneOpcionDeVenta: boolean;
montoOpcionDeVenta?: number;
monedaOpcionDeVenta?: string;
duracionEnMeses: number;
frecuenciaAumentoEnMeses?: number | null;
};
+26
View File
@@ -1,3 +1,4 @@
using System.Net;
using Entidades; using Entidades;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -28,6 +29,31 @@ public class AuditoriaFacade {
_persistenciaDeLog.GuardarLog(log, log.LogDetalles); _persistenciaDeLog.GuardarLog(log, log.LogDetalles);
} }
internal void GenerarLogLogin(long dni, string v, IPAddress? remoteIpAddress) {
var fechaActual = DateTime.Now;
var log = new Log{
Fecha = fechaActual,
Dniusuario = dni,
Accion = v
};
log.LogDetalles = new List<LogDetalle>([
new LogDetalle{
Id = 1,
Dniusuario = dni,
Fecha = fechaActual,
NombreTabla = "Logs",
Columna = "Login",
ValorAnterior = "",
ValorNuevo = $"Se Accedio con la direccion ip: {remoteIpAddress?.ToString() ?? "Desconocida"}",
}
]);
_persistenciaDeLog.GuardarLog(log, log.LogDetalles);
}
private List<LogDetalle> ProcesarCambios(IEnumerable<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry> cambios, private List<LogDetalle> ProcesarCambios(IEnumerable<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry> cambios,
DateTime fechaActual, long dniUsuario) { DateTime fechaActual, long dniUsuario) {
+89 -2
View File
@@ -4,6 +4,81 @@ using Microsoft.EntityFrameworkCore;
namespace Modelo; namespace Modelo;
public class RepositorioContratos: RepositorioBase<RepositorioContratos> { public class RepositorioContratos: RepositorioBase<RepositorioContratos> {
public bool GenerarCanones(long id = 0, long dni=0){
if (id == 0) return false;
var con = Context;
var cont = con.Contratos.Include(x=>x.IdpropiedadNavigation).FirstOrDefault(x=>x.Id == id && x.Cancelado == 0 && x.Habilitado == 0);
if (cont == null) return false;
cont.Habilitado = 1;
cont.Fechainicio = DateTime.Now;
var fecha = cont.Fechainicio;
cont.IdpropiedadNavigation.Monto = cont.Monto;
if (cont.MesesDurationContrato < cont.MesesHastaAumento)
{
for (int i = 0; i < cont.MesesDurationContrato; 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);
}
}
else
{
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);
}
}
// GenerarLog(con, dni, "Creacion de Canones");
return Guardar(con);
}
public bool AdminCargaContrato(Contrato? cont, long dni){
if (cont == null) return false;
var con = Context;
cont.Id = (con.Contratos.Any() ? con.Contratos.Max(x => x.Id) : 0) + 1;
foreach(Garante g in cont.Idgarantes){
g.Id = (con.Garantes.Any()?con.Garantes.Max(x=>x.Id): 0) + 1;
}
if (cont.IdventaNavigation != null){
cont.IdventaNavigation.Id = (con.Ventas.Any()?con.Ventas.Count():0)+1;
con.Ventas.Add(cont.IdventaNavigation);
}
var prop = con.Propiedades.FirstOrDefault(x=>x.Id == cont.Idpropiedad);
if (prop == null)return false;
prop.Idestado = 2;
con.Contratos.Add(cont);
GenerarLog(con, dni, "Carga del contrato por parte de admin");
return Guardar(con);
}
public IQueryable<Contrato>? ObtenerContratosPorEmailInquilino(string email) { public IQueryable<Contrato>? ObtenerContratosPorEmailInquilino(string email) {
var con = Context; var con = Context;
try{ try{
@@ -102,13 +177,15 @@ public class RepositorioContratos: RepositorioBase<RepositorioContratos> {
return contr; return contr;
} }
public bool AddUrl(long id, string nuevoNombreArchivo, long dni) { public bool AddUrl(long id, string nuevoNombreArchivo, long dni =0) {
var con = Context; var con = Context;
Contrato? contrato = con.Contratos Contrato? contrato = con.Contratos
.FirstOrDefault(x=>x.Id == id); .FirstOrDefault(x=>x.Id == id);
if (contrato == null) return false; if (contrato == null) return false;
contrato.UrlContrato = nuevoNombreArchivo; contrato.UrlContrato = nuevoNombreArchivo;
GenerarLog(con, dni, $"Añadido contrato"); if (dni != 0 ){
GenerarLog(con, dni, $"Añadido contrato");
}
return Guardar(con); return Guardar(con);
} }
@@ -168,6 +245,16 @@ public class RepositorioContratos: RepositorioBase<RepositorioContratos> {
return Guardar(con); return Guardar(con);
} }
public Contrato? ObtenerPreContratoPorIdDePropiedadyCliente(Cliente cli, int propiedadid){
var con = Context;
var cont = con.Contratos.Where(x=>x.Habilitado == 0ul && x.Cancelado == 0ul)
.Include(x=>x.IdventaNavigation)
.ThenInclude(x=>x.IddivisaNavigation)
.FirstOrDefault(x => x.Dniinquilino == cli.Dni && x.Idpropiedad == propiedadid);
return cont;
}
public IQueryable<Contrato> ObtenerContratosDePropietario(long dni) { public IQueryable<Contrato> ObtenerContratosDePropietario(long dni) {
var con = Context; var con = Context;
var l = con.Contratos var l = con.Contratos
+10
View File
@@ -0,0 +1,10 @@
using Entidades;
namespace Modelo;
public class RepositorioDivisas: RepositorioBase<RepositorioDivisas> {
public List<Divisa> ObtenerDivisas(){
var con = Context;
var divisas = con.Divisas.ToList();
return divisas;
}
}
+55
View File
@@ -4,6 +4,61 @@ using Microsoft.EntityFrameworkCore;
namespace Modelo; namespace Modelo;
public class RepositorioEstadisticas: RepositorioBase<RepositorioEstadisticas> { public class RepositorioEstadisticas: RepositorioBase<RepositorioEstadisticas> {
public (ChartData, List<InformePagos>) InformePagos(int year) {
var con = Context;
ChartData data = new();
List<string> meses = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"];
data.Labels = meses;
var canonData = con.Canons.Where(x => x.Fecha.Year == year)
.Include(x => x.IdreciboNavigation)
.Select(x => new {
Mes = x.Fecha.Month,
Pagado = x.Pagado,
CanonFecha = x.Fecha,
ReciboFecha = x.IdreciboNavigation != null ? x.IdreciboNavigation.Fecha : (DateTime?)null
})
.ToList();
var groupedData = canonData
.GroupBy(x => x.Mes)
.Select(g => new InformePagos {
Mes = g.Key,
Realizados = g.Count(x => x.Pagado == 1 && x.ReciboFecha.HasValue && x.ReciboFecha <= x.CanonFecha),
Atrasados = g.Count(x => x.Pagado == 1 && x.ReciboFecha.HasValue && x.ReciboFecha > x.CanonFecha),
Sin_realizar = g.Count(x => x.Pagado == 0)
})
.ToList();
List<InformePagos> lst = Enumerable.Range(1, 12)
.Select(mes => groupedData.FirstOrDefault(x => x.Mes == mes) ?? new InformePagos {
Mes = mes,
Realizados = 0,
Atrasados = 0,
Sin_realizar = 0
})
.ToList();
data.Datasets.Add(new Dataset {
Label = "Realizados",
Data = lst.Select(x => x.Realizados.ToString()).ToList()
});
data.Datasets.Add(new Dataset {
Label = "Atrasados",
Data = lst.Select(x => x.Atrasados.ToString()).ToList()
});
data.Datasets.Add(new Dataset {
Label = "Sin_realizar",
Data = lst.Select(x => x.Sin_realizar.ToString()).ToList()
});
return (data, lst);
}
public ChartData? ObtenerDataIniciadosPorAño(int year){ public ChartData? ObtenerDataIniciadosPorAño(int year){
var con = Context; var con = Context;
var contratosPorMes = con.Contratos var contratosPorMes = con.Contratos
+88 -13
View File
@@ -1,31 +1,106 @@
using Entidades; using Entidades;
using Entidades.Admin; using Entidades.Admin;
using Entidades.Dto;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Modelo; namespace Modelo;
public class RepositorioGrupos: RepositorioBase<RepositorioGrupos> { public class RepositorioGrupos : RepositorioBase<RepositorioGrupos>
{
public IQueryable<Permiso> ListarPermisosDeGrupo(string grupo) { public bool AddGrupo(GrupoDto grupo, Cliente cli)
{
var con = Context; var con = Context;
return con.Grupos.Where(x=>x.Nombre == grupo).SelectMany(x => x.Idpermisos);
var g = new Grupo
{
Id = con.Grupos.Max(x => x.Id) + 1,
Nombre = grupo.Nombre,
IdGrupoHijos = con.Grupos.Where(x => grupo.GruposIncluidos.Contains(x.Nombre)).ToList(),
Idpermisos = con.Permisos.Where(x => grupo.Permisos.Select(x => x.Id).Contains(x.Id)).ToList(),
};
con.Grupos.Add(g);
GenerarLog(con, cli.Dni, $"Alta Grupo: {g.Nombre}");
return Guardar(con);
}
public bool PatchGrupo(GrupoDto grupo, Cliente cli)
{
var con = Context;
var g = con.Grupos
.Include(x => x.IdGrupoHijos)
.Include(x => x.Idpermisos).FirstOrDefault(x => x.Id == grupo.idgrupo);
if (g == null)
{
return false;
}
var listg = grupo.GruposIncluidos.ToList();
if (grupo.GruposIncluidos != null)
{
g.IdGrupoHijos = con.Grupos.Where(x => listg.Contains(x.Nombre)).ToList();
}
if (grupo.Permisos != null)
{
g.Idpermisos = con.Permisos.Where(x => grupo.Permisos.Select(p => p.Id).Contains(x.Id)).ToList();
}
GenerarLog(con, cli.Dni, "Patch Grupo");
return Guardar(con);
} }
public IQueryable<GrupoAdmin> ObtenerGruposPorDni(long Dni) { public (bool, bool) ToggleGrupo(int id, Cliente cli)
{
var con = Context; var con = Context;
var grupos = con.Clientes.Where(x=>x.Dni == Dni).SelectMany(x=>x.Idgrupos) var grupo = con.Grupos.FirstOrDefault(x => x.Id == id);
.Select(x=> new GrupoAdmin{ if (grupo == null) return (false, false);
Id = x.Id, if (grupo.Habilitado == null) grupo.Habilitado = false;
Descripcion = x.Nombre,
}); grupo.Habilitado = !grupo.Habilitado;
GenerarLog(con, cli.Dni, $"Se dio de {(grupo.Habilitado == true ? "alta" : "baja")} el grupo: {id}");
return (Guardar(con), grupo.Habilitado ?? false);
}
public IQueryable<Grupo> ListarTodosLosGrupos()
{
var con = Context;
var grupos = con.Grupos.Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos).Include(x => x.Idpermisos);
return grupos; return grupos;
} }
public bool CheckGrupos(string token, string grupo){ public IQueryable<Permiso> ListarPermisosDeGrupo(string grupo)
{
var con = Context; var con = Context;
Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Token == token); var listg = con.Grupos
.Where(x => x.Habilitado == true)
.Include(x => x.Idpermisos)
.Include(x => x.IdGrupoHijos)
.ThenInclude(x => x.Idpermisos).ToList();
var g = listg.FirstOrDefault(x => x.Nombre == grupo);
if (g == null) return Enumerable.Empty<Permiso>().AsQueryable();
var permisos = new HashSet<Permiso>();
var visitados = new HashSet<int>();
g.ObtenerPermisos(permisos, visitados);
return permisos.AsQueryable();
}
public List<Grupo> ObtenerGruposPorDni(long Dni)
{
var con = Context;
var grupos = con.Clientes.Where(x => x.Dni == Dni).SelectMany(x => x.Idgrupos).ToList();
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; if (cli == null) return false;
Grupo? gru = con.Grupos.FirstOrDefault(x=>x.Nombre == grupo); Grupo? gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo);
if (gru == null) return false; if (gru == null) return false;
if (cli.Idgrupos.Contains(gru)) return true; if (cli.Idgrupos.Contains(gru)) return true;
+1 -1
View File
@@ -21,7 +21,7 @@ public class RepositorioLogs: RepositorioBase<RepositorioLogs> {
return d.LogDetalles.OrderBy(x=>x.Id); return d.LogDetalles.OrderBy(x=>x.Id);
} }
public IQueryable<Log>? ObtenerLogsPaginado(int pag) { public IQueryable<Log> ObtenerLogsPaginado(int pag) {
var con = Context; var con = Context;
var l = con.Logs.OrderByDescending(x=>x.Fecha).Skip(10*pag).Take(10); var l = con.Logs.OrderByDescending(x=>x.Fecha).Skip(10*pag).Take(10);
return l; return l;
+63 -22
View File
@@ -3,50 +3,91 @@ using Entidades;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Modelo; namespace Modelo;
public class RepositorioPermisos: RepositorioBase<RepositorioPermisos> { public class RepositorioPermisos : RepositorioBase<RepositorioPermisos>
public object? ListarPermisos(string email) { {
public IQueryable<Grupo>? ListarPermisos(string email)
{
var con = Context; var con = Context;
Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email); Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(c => c.Email == email);
if (cli == null) return null; if (cli == null) return null;
// Obtener todos los grupos del cliente
var list = con.Clientes var list = con.Clientes
.Where(c => c.Dni == cli.Dni) .Where(c => c.Dni == cli.Dni)
.SelectMany(c => c.Idgrupos) .SelectMany(c => c.Idgrupos)
.Include(x=> x.Idpermisos); .Where(x => x.Habilitado == true)
.Include(x => x.Idpermisos)
.Include(x => x.IdGrupoHijos).ThenInclude(x => x.Idpermisos);
// Cargamos todos los subgrupos de forma recursiva
foreach (var grupo in list)
{
var visitados = new HashSet<int>();
var todosLosPermisos = new HashSet<Permiso>();
grupo.ObtenerPermisos(todosLosPermisos, visitados);
grupo.Idpermisos = todosLosPermisos.ToList();
}
return list; return list;
} }
public bool CheckPermisos(string token, int idpermiso){ public List<Permiso> ListarPermisos()
{
return Context.Permisos.ToList();
}
public bool CheckPermisos(string token, int idpermiso)
{
var con = Context; var con = Context;
bool tienePermiso = false; bool tienePermiso = false;
//checkeo que el token corresponda a un usuario
Cliente? cli = con.Clientes.FirstOrDefault(x => x.Token == token); Cliente? cli = con.Clientes.FirstOrDefault(x => x.Token == token);
if (cli == null || cli.Dni == 0) return false; if (cli == null || cli.Dni == 0) return false;
// obtengo una lista de los permisos var grupos = con.Clientes
var permisos = con.Clientes
.Where(x => x.Dni == cli.Dni) .Where(x => x.Dni == cli.Dni)
.SelectMany(x => x.Idgrupos) .SelectMany(x => x.Idgrupos)
.SelectMany(x => x.Idpermisos) .Where(x => x.Habilitado == true)
.Distinct(); .Include(x => x.Idpermisos)
.Include(x => x.IdGrupoHijos)
.ThenInclude(x => x.Idpermisos)
.ToList();
///////////////////////////////////////////////////////////////// foreach (var grupo in grupos)
//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 var visitados = new HashSet<int>();
///////////////////////////////////////////////////////////////// var todosLosPermisos = new HashSet<Permiso>();
//me inspiré y hice un regex pero si eliminaba los primeros 8(?) caracteres del string era lo mismo grupo.ObtenerPermisos(todosLosPermisos, visitados);
//Match match = Regex.Match(path, @"^/accion/(\d+)$");
//int.TryParse(match.Groups[1].Value, out int idpermiso);
/////////////////////////////////////////////////////////////////
Parallel.ForEach(permisos, (x, i) =>{ if (todosLosPermisos.Any(p => p.Id == idpermiso))
if (x.Id == idpermiso) { {
tienePermiso = true; tienePermiso = true;
break;
} }
}); }
return tienePermiso; return tienePermiso;
} }
public bool CrearPermiso(Permiso per, Cliente cli)
{
var con = Context;
per.Id = con.Permisos.Any() ? con.Permisos.Max(x => x.Id) + 1 : 1;
con.Permisos.Add(per);
GenerarLog(con, cli.Dni, $"Creado Permiso {per.Descripcion}");
return Guardar(con);
}
public bool PatchPermiso(Permiso per, Cliente cli)
{
var con = Context;
var perm = con.Permisos.FirstOrDefault(x => x.Id == per.Id);
if (perm == null) return false;
perm.Descripcion = per.Descripcion;
GenerarLog(con, cli.Dni, $"Editado Permiso {per.Id}");
return Guardar(con);
}
} }
+146 -78
View File
@@ -8,9 +8,17 @@ using Microsoft.Identity.Client;
using Modelo; using Modelo;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> { public class RepositorioPropiedades : RepositorioBase<RepositorioPropiedades>
{
public IQueryable<PropiedadesDto> ListarPropiedades(){ public List<Propiedade> ObtenerPropiedadEnAlquilerPorDni(long dni){
var con = Context;
var propiedades = con.Propiedades.Where(x=>x.Dnipropietario == dni && x.Idestado == 1).ToList();
return propiedades;
}
public IQueryable<PropiedadesDto> ListarPropiedades()
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto,
@@ -27,24 +35,36 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public Propiedade? ObtenerPropiedadPorId(int Id) { public Propiedade? ObtenerPropiedadPorId(int Id)
{
var con = Context; var con = Context;
Propiedade? prop = con.Propiedades.Include(x=>x.DnipropietarioNavigation).FirstOrDefault(x=>x.Id == Id); Propiedade? prop = con.Propiedades.Include(x => x.DnipropietarioNavigation).FirstOrDefault(x => x.Id == Id);
if (prop == null || prop.Id == 0) { if (prop == null || prop.Id == 0)
{
return null; return null;
} }
return prop; return prop;
} }
public bool AñadirPropiedad(Propiedade? prop) { public bool AñadirPropiedad(Propiedade? prop, long dni = 0)
{
if (prop == null) return false; 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 = "_";
prop.Id = (con.Propiedades.Count()!=0) ? con.Propiedades.Count() + 1 : 1;
prop.Idestado = 1;
con.Propiedades.Add(prop);
if (dni!=0) GenerarLog(con, dni, $"Se guardo la propiedad");
return Guardar(con);
/*
var filasInsertadasParam = new MySqlParameter("@p_filas_insertadas", SqlDbType.Int) var filasInsertadasParam = new MySqlParameter("@p_filas_insertadas", SqlDbType.Int)
{ {
Direction = ParameterDirection.Output Direction = ParameterDirection.Output
@@ -62,17 +82,19 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
new MySqlParameter("@p_letra", prop.Letra), new MySqlParameter("@p_letra", prop.Letra),
new MySqlParameter("@p_dni_propietario", prop.Dnipropietario), new MySqlParameter("@p_dni_propietario", prop.Dnipropietario),
new MySqlParameter("@p_id_tipo_propiedad", prop.Idtipropiedad), new MySqlParameter("@p_id_tipo_propiedad", prop.Idtipropiedad),
new MySqlParameter("@p_monto",prop.Monto), new MySqlParameter("@p_monto", prop.Monto),
new MySqlParameter("@iddivisa", prop.Iddivisa), new MySqlParameter("@iddivisa", prop.Iddivisa),
filasInsertadasParam filasInsertadasParam
); );
return (int)filasInsertadasParam.Value == 1? true: false; return (int)filasInsertadasParam.Value == 1 ? true : false;
*/
} }
public bool PatchPropiedad(Propiedade prop, long dni) { public bool PatchPropiedad(Propiedade prop, long dni)
{
var con = Context; var con = Context;
Propiedade? propi = con.Propiedades.Include(x=>x.IdServicios).FirstOrDefault(x=>x.Id == prop.Id); Propiedade? propi = con.Propiedades.Include(x => x.IdServicios).FirstOrDefault(x => x.Id == prop.Id);
if (propi == null) return false; if (propi == null) return false;
@@ -85,8 +107,9 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
propi.Iddivisa = prop.Iddivisa; propi.Iddivisa = prop.Iddivisa;
propi.IdServicios.Clear(); propi.IdServicios.Clear();
foreach(Servicio ser in prop.IdServicios) { foreach (Servicio ser in prop.IdServicios)
var servi = con.Servicios.FirstOrDefault(x=>x.Id == ser.Id); {
var servi = con.Servicios.FirstOrDefault(x => x.Id == ser.Id);
if (servi == null) return false; if (servi == null) return false;
propi.IdServicios.Add(servi); propi.IdServicios.Add(servi);
} }
@@ -94,7 +117,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return Guardar(con); return Guardar(con);
} }
public IQueryable<PropiedadesDto> ObtenerPropiedadesPorEmail(string email) { public IQueryable<PropiedadesDto> ObtenerPropiedadesPorEmail(string email)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto, SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto,
p.iddivisa as Iddivisa p.iddivisa as Iddivisa
@@ -111,7 +135,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedadesDeBajaPorEmail(string email) { public IQueryable<PropiedadesDto> ObtenerPropiedadesDeBajaPorEmail(string email)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto, SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto,
p.iddivisa as Iddivisa p.iddivisa as Iddivisa
@@ -128,12 +153,14 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public bool AñadirServicioAPropiedad(int idprop, List<int> idserv){ public bool AñadirServicioAPropiedad(int idprop, List<int> idserv)
{
var con = Context; var con = Context;
Propiedade? prop = con.Propiedades.Find(idprop); Propiedade? prop = con.Propiedades.Find(idprop);
if (prop == null) return false; if (prop == null) return false;
foreach (int id in idserv) { foreach (int id in idserv)
{
Servicio? servicio = con.Servicios.Find(id); Servicio? servicio = con.Servicios.Find(id);
if (servicio == null) return false; if (servicio == null) return false;
@@ -143,17 +170,21 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return Guardar(con); return Guardar(con);
} }
public bool BajaPropiedad(int id, Cliente? cli) { public bool BajaPropiedad(int id, Cliente? cli)
{
if (cli == null) return false; if (cli == null) return false;
var con = Context; var con = Context;
Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id); Propiedade? prop = con.Propiedades.FirstOrDefault(x => x.Id == id);
if (prop == null) return false; if (prop == null) return false;
if (prop.Dnipropietario != cli.Dni) return false; if (prop.Dnipropietario != cli.Dni) return false;
if(prop.Idestado == 1){ if (prop.Idestado == 1)
{
prop.Idestado = 3; prop.Idestado = 3;
}else{ }
else
{
prop.Idestado = 1; prop.Idestado = 1;
} }
GenerarLog(con, cli.Dni, $"Baja propiedad: {prop.Id}"); GenerarLog(con, cli.Dni, $"Baja propiedad: {prop.Id}");
@@ -161,28 +192,32 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
} }
public bool BajaPropiedad(int id, long dni) { public bool BajaPropiedad(int id, long dni)
{
var con = Context; var con = Context;
Propiedade? prop = con.Propiedades.FirstOrDefault(x=>x.Id == id); Propiedade? prop = con.Propiedades.FirstOrDefault(x => x.Id == id);
if (prop == null||prop.Dnipropietario == 0) return false; if (prop == null || prop.Dnipropietario == 0) return false;
prop.Idestado = prop.Idestado == 3 ? 1 : 3; prop.Idestado = prop.Idestado == 3 ? 1 : 3;
GenerarLog(con, dni, $"Baja propiedad: {prop.Id}"); GenerarLog(con, dni, $"Baja propiedad: {prop.Id}");
return Guardar(con); return Guardar(con);
} }
public bool BajaServiciosAPropiedad(int idprop, List<int> idserv, long dni) { public bool BajaServiciosAPropiedad(int idprop, List<int> idserv, long dni)
{
var con = Context; var con = Context;
Propiedade? prop = con.Propiedades.Include(x=>x.IdServicios).FirstOrDefault(x => x.Id == idprop); Propiedade? prop = con.Propiedades.Include(x => x.IdServicios).FirstOrDefault(x => x.Id == idprop);
if (prop == null) return false; if (prop == null) return false;
foreach (int id in idserv) { foreach (int id in idserv)
{
Servicio? servicio = con.Servicios.Find(id); Servicio? servicio = con.Servicios.Find(id);
if (servicio == null) return false; if (servicio == null) return false;
if (prop.IdServicios.Contains(servicio)){ if (prop.IdServicios.Contains(servicio))
{
prop.IdServicios.Remove(servicio); prop.IdServicios.Remove(servicio);
} }
} }
@@ -190,7 +225,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return Guardar(con); return Guardar(con);
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones_Tipo_Servicios(int habitaciones, int tipo, string servicios) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones_Tipo_Servicios(int habitaciones, int tipo, string servicios)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo,
@@ -216,7 +252,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones_Tipo(int cantidadHabitaciones, int tipoPropiedad) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones_Tipo(int cantidadHabitaciones, int tipoPropiedad)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto,
@@ -234,7 +271,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorServicios(string servicios) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorServicios(string servicios)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
@@ -260,7 +298,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones(int cantidadHabitaciones) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones(int cantidadHabitaciones)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto,
@@ -278,7 +317,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorTipo(int tipoPropiedad) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorTipo(int tipoPropiedad)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto,
@@ -296,7 +336,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones_Servicios(int cantidadHabitaciones, string servicios) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorHabitaciones_Servicios(int cantidadHabitaciones, string servicios)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo,
@@ -322,7 +363,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public IQueryable<PropiedadesDto> ObtenerPropiedesPorTipo_Servicios(int tipoPropiedad, string servicios) { public IQueryable<PropiedadesDto> ObtenerPropiedesPorTipo_Servicios(int tipoPropiedad, string servicios)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo,
@@ -348,20 +390,26 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public bool BajaPropiedades(string email) { public bool BajaPropiedades(string email)
{
var con = Context; var con = Context;
try { try
IQueryable<Propiedade> listprop = con.Propiedades.Where(x=>x.DnipropietarioNavigation.Email == email); {
foreach (var item in listprop) { IQueryable<Propiedade> listprop = con.Propiedades.Where(x => x.DnipropietarioNavigation.Email == email);
foreach (var item in listprop)
{
item.Idestado = 3; item.Idestado = 3;
} }
} catch { }
catch
{
return false; return false;
} }
return Guardar(con); return Guardar(con);
} }
public IQueryable<PropiedadesDto> ListarPropiedadesPorPagina(int pag) { public IQueryable<PropiedadesDto> ListarPropiedadesPorPagina(int pag)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto,
@@ -372,14 +420,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad
JOIN Servicios s on sp.idServicio =s.id JOIN Servicios s on sp.idServicio =s.id
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Context.Database.SqlQuery<PropiedadesDto>(sqlq); var ret = Context.Database.SqlQuery<PropiedadesDto>(sqlq);
return ret; return ret;
} }
///////////////ADMIN ///////////////ADMIN
public IQueryable<PropiedadesAdmin> ListarPropiedadesPorPaginaAdmin(int pag) { public IQueryable<PropiedadesAdmin> ListarPropiedadesPorPaginaAdmin(int pag)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado,
@@ -390,7 +439,7 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad JOIN Servicio_Propiedad sp on p.id =sp.idPropiedad
JOIN Servicios s on sp.idServicio =s.id JOIN Servicios s on sp.idServicio =s.id
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
@@ -398,7 +447,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitacionesPaginado(int cantidadHabitaciones, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitacionesPaginado(int cantidadHabitaciones, int pag)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado,
@@ -410,14 +460,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
JOIN Servicios s on sp.idServicio =s.id JOIN Servicios s on sp.idServicio =s.id
WHERE p.canthabitaciones = {cantidadHabitaciones} WHERE p.canthabitaciones = {cantidadHabitaciones}
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorTipoPaginado(int tipoPropiedad, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorTipoPaginado(int tipoPropiedad, int pag)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado,
@@ -429,14 +480,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
JOIN Servicios s on sp.idServicio =s.id JOIN Servicios s on sp.idServicio =s.id
WHERE p.idtipropiedad = {tipoPropiedad} WHERE p.idtipropiedad = {tipoPropiedad}
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitaciones_TipoPaginado(int cantidadHabitaciones, int tipoPropiedad, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitaciones_TipoPaginado(int cantidadHabitaciones, int tipoPropiedad, int pag)
{
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, 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, GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado,
@@ -448,14 +500,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
JOIN Servicios s on sp.idServicio =s.id JOIN Servicios s on sp.idServicio =s.id
WHERE p.canthabitaciones = {cantidadHabitaciones} AND p.idtipropiedad = {tipoPropiedad} WHERE p.canthabitaciones = {cantidadHabitaciones} AND p.idtipropiedad = {tipoPropiedad}
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorServiciosPaginado(string servicios, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorServiciosPaginado(string servicios, int pag)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
@@ -475,14 +528,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) AND FIND_IN_SET(s2.descripcion, {serviciosEscapados})
) )
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitaciones_Servicios_Paginado(int cantidadHabitaciones, string servicios, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitaciones_Servicios_Paginado(int cantidadHabitaciones, string servicios, int pag)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo,
@@ -502,14 +556,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) AND FIND_IN_SET(s2.descripcion, {serviciosEscapados})
) )
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorTipo_Servicios_Paginado(int tipoPropiedad, string servicios, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorTipo_Servicios_Paginado(int tipoPropiedad, string servicios, int pag)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo,
@@ -529,14 +584,15 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) AND FIND_IN_SET(s2.descripcion, {serviciosEscapados})
) )
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitaciones_Tipo_Servicios_Paginado(int habitaciones, int tipo, string servicios, int pag) { public IQueryable<PropiedadesAdmin> ObtenerPropiedesPorHabitaciones_Tipo_Servicios_Paginado(int habitaciones, int tipo, string servicios, int pag)
{
string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim()));
FormattableString sqlq = $""" FormattableString sqlq = $"""
SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo,
@@ -556,22 +612,26 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
AND FIND_IN_SET(s2.descripcion, {serviciosEscapados}) AND FIND_IN_SET(s2.descripcion, {serviciosEscapados})
) )
GROUP BY p.id GROUP BY p.id
LIMIT 10 OFFSET {pag*10} LIMIT 10 OFFSET {pag * 10}
"""; """;
var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq); var ret = Singleton.Context.Database.SqlQuery<PropiedadesAdmin>(sqlq);
return ret; return ret;
} }
public int CuantasPaginas(int estado = 0) { public int CuantasPaginas(int estado = 0)
{
var con = Context; var con = Context;
double inter; double inter;
int ret; int ret;
if (estado == 0){ if (estado == 0)
inter = con.Propiedades.Count()/10.0; {
} else { inter = con.Propiedades.Count() / 10.0;
inter = con.Propiedades.Where(x=>x.Idestado == estado).Count(); }
else
{
inter = con.Propiedades.Where(x => x.Idestado == estado).Count();
} }
if (inter == 0.00) return 0; if (inter == 0.00) return 0;
ret = (int)Math.Ceiling(inter); ret = (int)Math.Ceiling(inter);
@@ -579,7 +639,8 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return ret; return ret;
} }
public int CuantasPaginasBusqueda(int habitaciones, string servicios, int tipoPropiedad, int estado) { public int CuantasPaginasBusqueda(int habitaciones, string servicios, int tipoPropiedad, int estado)
{
int registrosPorPagina = 10; int registrosPorPagina = 10;
var query = Context.Propiedades var query = Context.Propiedades
@@ -588,19 +649,23 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
.Include(p => p.IdServicios) .Include(p => p.IdServicios)
.AsQueryable(); .AsQueryable();
if (habitaciones > 0) { if (habitaciones > 0)
{
query = query.Where(p => p.Canthabitaciones == habitaciones); query = query.Where(p => p.Canthabitaciones == habitaciones);
} }
if (estado > 0){ if (estado > 0)
query = query.Where(x=>x.Idestado == estado); {
query = query.Where(x => x.Idestado == estado);
} }
if (tipoPropiedad > 0) { if (tipoPropiedad > 0)
{
query = query.Where(p => p.Idtipropiedad == tipoPropiedad); query = query.Where(p => p.Idtipropiedad == tipoPropiedad);
} }
if (!string.IsNullOrWhiteSpace(servicios)) { if (!string.IsNullOrWhiteSpace(servicios))
{
var listaServicios = servicios.Split(',').Select(s => s.Trim()).ToList(); var listaServicios = servicios.Split(',').Select(s => s.Trim()).ToList();
query = query.Where(p => query = query.Where(p =>
p.IdServicios.Any(sp => p.IdServicios.Any(sp =>
@@ -612,26 +677,29 @@ public class RepositorioPropiedades: RepositorioBase<RepositorioPropiedades> {
return (int)Math.Ceiling((double)totalRegistros / registrosPorPagina); return (int)Math.Ceiling((double)totalRegistros / registrosPorPagina);
} }
public IQueryable<Propiedade>? ObtenerPropiedadesEnVenta(int pag){ public IQueryable<Propiedade>? ObtenerPropiedadesEnVenta(int pag)
{
var con = Context; var con = Context;
var props = con.Propiedades.Include(x=>x.IdServicios).Include(x=>x.IddivisaNavigation) var props = con.Propiedades.Include(x => x.IdServicios).Include(x => x.IddivisaNavigation)
.Include(c=>c.IdtipropiedadNavigation) .Include(c => c.IdtipropiedadNavigation)
.Where(x=>x.Idestado ==4 && !x.Venta.Any(x=>x.Idestado ==2)) .Where(x => x.Idestado == 4 && !x.Venta.Any(x => x.Idestado == 2))
.Skip(pag*10).Take(10); .Skip(pag * 10).Take(10);
return props; return props;
} }
public int ObtenerPaginasDePropiedadesEnVenta(){ public int ObtenerPaginasDePropiedadesEnVenta()
{
var con = Context; var con = Context;
var props = con.Propiedades.Where(x=>x.Idestado ==4 && !x.Venta.Any(x=>x.Idestado ==2)).Count(); var props = con.Propiedades.Where(x => x.Idestado == 4 && !x.Venta.Any(x => x.Idestado == 2)).Count();
return (int)Math.Ceiling((double)props / 10); return (int)Math.Ceiling((double)props / 10);
} }
public IQueryable<Propiedade> ObtenerPropiedadesAVentaPorDni(long dni) { public IQueryable<Propiedade> ObtenerPropiedadesAVentaPorDni(long dni)
{
var con = Context; var con = Context;
var l = con.Propiedades.Include(x=>x.IdServicios).Include(x=>x.IdtipropiedadNavigation) var l = con.Propiedades.Include(x => x.IdServicios).Include(x => x.IdtipropiedadNavigation)
.Where(x=>x.Dnipropietario == dni && x.Idestado ==4); .Where(x => x.Dnipropietario == dni && x.Idestado == 4);
return l; return l;
} }
} }
+12 -2
View File
@@ -1,10 +1,20 @@
using System;
using Entidades; using Entidades;
using Entidades.Dto;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using Modelo; using Modelo;
public class RepositorioPropietario: RepositorioBase<RepositorioPropietario> { public class RepositorioPropietario: RepositorioBase<RepositorioPropietario> {
public IQueryable<PropietarioDto> GetPropietarios() {
FormattableString sqlq =
$"""
SELECT I.Dni, I.Nombre, I.Apellido FROM Clientes I
JOIN cliente_Grupos cg on cg.idcliente = I.Dni
WHERE cg.idgrupo = 1;
""";
return Context.Database.SqlQuery<PropietarioDto>(sqlq);
}
public Cliente? ObtenerPropietarioPorDni(long Dni){ public Cliente? ObtenerPropietarioPorDni(long Dni){
if (Dni < 1) return null; if (Dni < 1) return null;
+153 -40
View File
@@ -4,17 +4,96 @@ using Entidades.Dto;
using Entidades; using Entidades;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Entidades.Admin; using Entidades.Admin;
using System.Net;
using Modelo.Facade;
namespace Modelo; namespace Modelo;
public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> { public class RepositorioUsuarios : RepositorioBase<RepositorioUsuarios>
public bool AltaInquilino(Cliente cli, long dni) { {
public bool AltaUsuario(long Dni, Cliente clii, string Contraseña, List<int> grupos)
{
var con = Context;
foreach (int i in grupos)
{
var g = con.Grupos.FirstOrDefault(x => x.Id == i);
clii.Idgrupos.Add(g);
}
clii.Contraseña = Encoding.UTF8.GetBytes(HacerHash(Contraseña));
con.Clientes.Add(clii);
base.GenerarLog(con, Dni, "Creacion de usuario");
return Guardar(con);
}
public (bool, long) Check2fa(string Email, string Pin)
{
var con = Context;
var cli = con.Clientes.FirstOrDefault(x => x.Email == Email);
if (cli == null || cli.F2a == null) return (false, 0);
if (cli.F2a != Pin) return (false, 0);
return (true, cli.Dni);
}
public bool SetF2aPin(string pin, string Email)
{
if (pin.Length != 6) return false;
var con = Context;
var cli = con.Clientes.FirstOrDefault(x => x.Email == Email);
if (cli == null) return false;
cli.F2a = pin;
//no Necesita logs esto
return Guardar(con);
}
public bool CheckEmailRecuperacion(string Email, string EmailRecuperacion)
{
var con = Context;
Cliente cli = con.Clientes.FirstOrDefault(x => x.Email == Email);
if (cli == null) return false;
if (cli.EmailRecuperacion == EmailRecuperacion)
{
base.GenerarLog(con, cli.Dni, "Intento de recuperar Usuario");
return true;
}
return false;
}
public bool SetEmailRecuperacion(string emailrecuperacion, Cliente cli)
{
var con = Context;
Cliente clii = con.Clientes.FirstOrDefault(x => x.Dni == cli.Dni);
if (clii == null) return false;
clii.EmailRecuperacion = emailrecuperacion;
base.GenerarLog(con, cli.Dni, "Set email Recuperacion");
return Guardar(con);
}
public bool CambiarContraseña(string pass, Cliente cli)
{
var con = Context;
var clii = con.Clientes.FirstOrDefault(x => x.Dni == cli.Dni);
if (clii == null) return false;
clii.Contraseña = Encoding.UTF8.GetBytes(HacerHash(pass));
this.GenerarLog(con, cli.Dni, "Modificada contraseña");
return Guardar(con);
}
public bool AltaInquilino(Cliente cli, long dni)
{
var con = Context; var con = Context;
Grupo? grupo; Grupo? grupo;
//check por si la cuenta ya existe (puede ser propietario) //check por si la cuenta ya existe (puede ser propietario)
Cliente? cli2 = con.Clientes.FirstOrDefault(x=>x.Email == cli.Email); Cliente? cli2 = con.Clientes.FirstOrDefault(x => x.Email == cli.Email);
if (cli2 != null) { if (cli2 != null)
{
grupo = con.Grupos.Find(2); grupo = con.Grupos.Find(2);
if (grupo == null || grupo.Id == 0) return false; if (grupo == null || grupo.Id == 0) return false;
cli2.Idgrupos.Add(grupo); cli2.Idgrupos.Add(grupo);
@@ -33,13 +112,15 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
return Guardar(con); return Guardar(con);
} }
public bool AltaPropietario(Cliente cli, long dni) { public bool AltaPropietario(Cliente cli, long dni)
{
var con = Context; var con = Context;
Grupo? grupo; Grupo? grupo;
//check por si la cuenta ya existe (puede ser propietario) //check por si la cuenta ya existe (puede ser propietario)
Cliente? cli2 = con.Clientes.Find(cli.Dni); Cliente? cli2 = con.Clientes.Find(cli.Dni);
if (cli2 != null) { if (cli2 != null)
{
grupo = con.Grupos.Find(1); grupo = con.Grupos.Find(1);
if (grupo == null || grupo.Id == 0) return false; if (grupo == null || grupo.Id == 0) return false;
cli2.Idgrupos.Add(grupo); cli2.Idgrupos.Add(grupo);
@@ -58,7 +139,8 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
return Guardar(con); return Guardar(con);
} }
public bool ActualizarPropietario(Cliente cli) { public bool ActualizarPropietario(Cliente cli)
{
var con = Context; var con = Context;
Cliente? cliOld = con.Clientes.Find(cli.Dni); Cliente? cliOld = con.Clientes.Find(cli.Dni);
if (cliOld == null) return false; if (cliOld == null) return false;
@@ -69,13 +151,15 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
} }
public bool CheckUsuario(LoginDto logindto) { public bool CheckUsuario(LoginDto logindto)
if (logindto.Contraseña ==null)return false; {
if (logindto.Contraseña == null) return false;
Cliente? usu = Context.Clientes.FirstOrDefault(a => a.Email == logindto.Email && a.Habilitado == 1ul);
if (usu == null) return false;
string Contraseña = HacerHash(logindto.Contraseña); string Contraseña = HacerHash(logindto.Contraseña);
Cliente? usu = Context.Clientes.FirstOrDefault(a => a.Email == logindto.Email);
if (usu == null) return false;
string hashdb = Encoding.UTF8.GetString(usu.Contraseña); string hashdb = Encoding.UTF8.GetString(usu.Contraseña);
@@ -83,34 +167,49 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
return false; return false;
} }
private string HacerHash(string pass) { private string HacerHash(string pass)
{
var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass)); var buf = SHA256.HashData(Encoding.UTF8.GetBytes(pass));
return BitConverter.ToString(buf).Replace("-",""); return BitConverter.ToString(buf).Replace("-", "");
} }
public bool CheckToken(string email, string token) { public bool CheckToken(string email, string token)
var usu = Context.Clientes.FirstOrDefault(x => x.Email == email); {
var usu = Context.Clientes.FirstOrDefault(x => x.Email == email);
if (usu == null) return false; if (usu == null) return false;
return usu.Token == token; return usu.Token == token;
} }
public void GuardarToken(LoginDto login, string tokenString) { public void GuardarToken(LoginDto login, string tokenString, System.Net.IPAddress? remoteIpAddress, string? logout = null)
{
var con = Context; var con = Context;
var usu = con.Clientes.FirstOrDefault(x => x.Email == login.Email); var usu = con.Clientes.FirstOrDefault(x => x.Email == login.Email);
if (usu == null) return; if (usu == null) return;
usu.Token = tokenString; usu.Token = tokenString;
GenerarLog(con, usu.Dni, logout!=null? logout : "Login", remoteIpAddress);
Guardar(con); Guardar(con);
} }
public bool CheckGrupo(string email, string grupo) { private void GenerarLog(AlquilaFacilContext con, long dni, string v, IPAddress? remoteIpAddress)
{
var Auditoria = new AuditoriaFacade(con);
Auditoria.GenerarLogLogin(dni, v, remoteIpAddress);
}
public bool CheckGrupo(string email, string grupo)
{
var con = Context; var con = Context;
var usu = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Email == email); var usu = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email);
bool ret = false; bool ret = false;
if (usu != null && usu.Idgrupos != null) { if (usu != null && usu.Idgrupos != null)
Parallel.ForEach(usu.Idgrupos, (idGrupo, state) => { {
if (idGrupo.Nombre == grupo) { Parallel.ForEach(usu.Idgrupos, (idGrupo, state) =>
{
if (idGrupo.Nombre == grupo)
{
ret = true; ret = true;
state.Break(); state.Break();
} }
@@ -120,23 +219,28 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
return ret; return ret;
} }
public IEnumerable<Entidades.Admin.UsuarioAdmin> GetClientes(){ public IEnumerable<Entidades.Admin.UsuarioAdmin> GetClientes()
{
var con = Context; var con = Context;
var list = con.Clientes.ToList().Select(x => new Entidades.Admin.UsuarioAdmin { var list = con.Clientes.ToList().Select(x => new Entidades.Admin.UsuarioAdmin
{
Dni = x.Dni, Dni = x.Dni,
Email = x.Email, Email = x.Email,
Nombre = x.Nombre+" "+x.Apellido, Nombre = x.Nombre + " " + x.Apellido,
Habilitado = x.Habilitado}); Habilitado = x.Habilitado
});
return list; return list;
} }
public bool AñadirClienteAGrupo(string email, string grupo, long dni) { public bool AñadirClienteAGrupo(string email, string grupo, long dni)
{
var con = Context; var con = Context;
var cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email); var cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email);
var gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo); var gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo);
if (cli == null || gru == null) { if (cli == null || gru == null)
{
return false; return false;
} }
@@ -145,13 +249,15 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
return Guardar(con); return Guardar(con);
} }
public bool EliminarClienteAGrupo(string email, string grupo, long dniresponsable) { public bool EliminarClienteAGrupo(string email, string grupo, long dniresponsable)
{
var con = Context; var con = Context;
var cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email); var cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Email == email);
var gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo); var gru = con.Grupos.FirstOrDefault(x => x.Nombre == grupo);
if (cli == null || gru == null) { if (cli == null || gru == null)
{
return false; return false;
} }
cli.Idgrupos.Remove(gru); cli.Idgrupos.Remove(gru);
@@ -159,38 +265,45 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios> {
return Guardar(con); return Guardar(con);
} }
public bool BajaCliente(long dni) { public bool BajaCliente(long dni)
{
var con = Context; var con = Context;
Cliente? cli = con.Clientes.Include(x=>x.Idgrupos).FirstOrDefault(x=>x.Dni == dni); Cliente? cli = con.Clientes.Include(x => x.Idgrupos).FirstOrDefault(x => x.Dni == dni);
if (cli == null) return false; if (cli == null) return false;
if (cli.Habilitado == 0) { if (cli.Habilitado == 0)
{
cli.Habilitado = 1; cli.Habilitado = 1;
} else { }
else
{
cli.Habilitado = 0; cli.Habilitado = 0;
} }
GenerarLog(con, cli.Dni, $"Baja cliente id: {cli.Dni}"); GenerarLog(con, cli.Dni, $"Baja cliente id: {cli.Dni}");
return Guardar(con); return Guardar(con);
} }
public Cliente? ObtenerClientePorDni(long dni) { public Cliente? ObtenerClientePorDni(long dni)
{
var con = Context; var con = Context;
Cliente? cli = con.Clientes.FirstOrDefault(x=>x.Dni == dni); Cliente? cli = con.Clientes.FirstOrDefault(x => x.Dni == dni);
return cli; return cli;
} }
public Cliente? ObtenerClientePorToken(string token) { public Cliente? ObtenerClientePorToken(string token)
{
var con = Context; var con = Context;
Cliente? cli = con.Clientes.Include(x=>x.NotificacioneDniclienteNavigations).FirstOrDefault(x=>x.Token == token); Cliente? cli = con.Clientes.Include(x => x.NotificacioneDniclienteNavigations).FirstOrDefault(x => x.Token == token);
if (cli == null|| cli.Dni == 0) return null; if (cli == null || cli.Dni == 0) return null;
return cli; return cli;
} }
public bool PatchUsuario(UpdateUsuarioAdmin dto, long dni, long responsabledni) { public bool PatchUsuario(UpdateUsuarioAdmin dto, long dni, long responsabledni)
{
var con = Context; var con = Context;
var usu = con.Clientes.FirstOrDefault(x=>x.Dni ==dni); var usu = con.Clientes.FirstOrDefault(x => x.Dni == dni);
if (usu == null) return false; if (usu == null) return false;
usu.Nombre = dto.Nombre; usu.Nombre = dto.Nombre;
+1 -1
View File
@@ -1,2 +1,2 @@
run: run:
dotnet watch run --project Aspnet/AlquilaFacil.csproj bunx concurrently "dotnet watch run --project Aspnet/AlquilaFacil.csproj" "make -C ./Front"