From a85d39cba8162096fbf6dbc61b60ef2e42a56645 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 13 Jan 2025 18:14:19 -0300 Subject: [PATCH 01/24] stash pop --- Front/src/App.svelte | 6 +++++- .../paginas/ControlAlquileresInquilino.svelte | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Front/src/paginas/ControlAlquileresInquilino.svelte diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 44c19fa..749f697 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -17,6 +17,7 @@ import AdminUsuarios from "./paginas/AdminUsuarios.svelte"; import AdminPropiedades from "./paginas/AdminPropiedades.svelte"; import Notificaciones from "./paginas/Notificaciones.svelte"; + import ControlAlquileresInquilino from "./paginas/ControlAlquileresInquilino.svelte"; @@ -74,8 +75,11 @@ - + + + + diff --git a/Front/src/paginas/ControlAlquileresInquilino.svelte b/Front/src/paginas/ControlAlquileresInquilino.svelte new file mode 100644 index 0000000..511886b --- /dev/null +++ b/Front/src/paginas/ControlAlquileresInquilino.svelte @@ -0,0 +1,16 @@ + + + + +
+ + +
+ +
+
\ No newline at end of file -- 2.52.0 From 280bcd294a840d6fa27d8ce2b6b5e93531576fb1 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 13 Jan 2025 20:02:31 -0300 Subject: [PATCH 02/24] =?UTF-8?q?migracion:=20a=C3=B1adida=20divisa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entidades/Alquilafacilcontext.cs | 54 ++++++++++++++++++++++++++++++++ Entidades/Contrato.cs | 4 +++ Entidades/Defecto.cs | 4 +++ Entidades/Divisa.cs | 19 +++++++++++ Entidades/Propiedade.cs | 4 +++ Entidades/Venta.cs | 4 +++ 6 files changed, 89 insertions(+) create mode 100644 Entidades/Divisa.cs diff --git a/Entidades/Alquilafacilcontext.cs b/Entidades/Alquilafacilcontext.cs index 8199acb..0272db0 100644 --- a/Entidades/Alquilafacilcontext.cs +++ b/Entidades/Alquilafacilcontext.cs @@ -23,6 +23,8 @@ public partial class AlquilaFacilContext : DbContext public virtual DbSet Defectos { get; set; } + public virtual DbSet Divisas { get; set; } + public virtual DbSet EstadoPropiedads { get; set; } public virtual DbSet Estadodefectos { get; set; } @@ -153,6 +155,8 @@ public partial class AlquilaFacilContext : DbContext entity.HasIndex(e => e.Idventa, "FK_CON_VEN"); + entity.HasIndex(e => e.Iddivisa, "FK_contdiv"); + entity.Property(e => e.Id) .HasColumnType("bigint(20)") .HasColumnName("id"); @@ -174,6 +178,9 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Habilitado) .HasColumnType("bit(1)") .HasColumnName("habilitado"); + entity.Property(e => e.Iddivisa) + .HasColumnType("int(11)") + .HasColumnName("iddivisa"); entity.Property(e => e.Idpropiedad) .HasColumnType("int(11)") .HasColumnName("idpropiedad"); @@ -204,6 +211,11 @@ public partial class AlquilaFacilContext : DbContext .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_CON_PROPI"); + entity.HasOne(d => d.IddivisaNavigation).WithMany(p => p.Contratos) + .HasForeignKey(d => d.Iddivisa) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_contdiv"); + entity.HasOne(d => d.IdpropiedadNavigation).WithMany(p => p.Contratos) .HasForeignKey(d => d.Idpropiedad) .OnDelete(DeleteBehavior.Restrict) @@ -249,6 +261,8 @@ public partial class AlquilaFacilContext : DbContext entity.HasIndex(e => e.Idestado, "FK_DEF_EST"); + entity.HasIndex(e => e.Iddivisa, "FK_defdiv"); + entity.Property(e => e.Id) .HasColumnType("bigint(20)") .HasColumnName("id"); @@ -261,6 +275,9 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Idcontrato) .HasColumnType("bigint(20)") .HasColumnName("idcontrato"); + entity.Property(e => e.Iddivisa) + .HasColumnType("int(11)") + .HasColumnName("iddivisa"); entity.Property(e => e.Idestado) .HasColumnType("int(11)") .HasColumnName("idestado"); @@ -273,12 +290,29 @@ public partial class AlquilaFacilContext : DbContext .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_DEF_CON"); + entity.HasOne(d => d.IddivisaNavigation).WithMany(p => p.Defectos) + .HasForeignKey(d => d.Iddivisa) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_defdiv"); + entity.HasOne(d => d.IdestadoNavigation).WithMany(p => p.Defectos) .HasForeignKey(d => d.Idestado) .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_DEF_EST"); }); + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.Property(e => e.Id) + .HasColumnType("int(11)") + .HasColumnName("id"); + entity.Property(e => e.Signo) + .HasMaxLength(3) + .HasColumnName("signo"); + }); + modelBuilder.Entity(entity => { entity.HasKey(e => e.Id).HasName("PRIMARY"); @@ -472,6 +506,8 @@ public partial class AlquilaFacilContext : DbContext entity.HasIndex(e => e.Idtipropiedad, "FK_PROP_TIPO"); + entity.HasIndex(e => e.Iddivisa, "FK_propdiv"); + entity.Property(e => e.Id) .HasColumnType("int(11)") .HasColumnName("id"); @@ -481,6 +517,9 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.Dnipropietario) .HasColumnType("bigint(20)") .HasColumnName("dnipropietario"); + entity.Property(e => e.Iddivisa) + .HasColumnType("int(11)") + .HasColumnName("iddivisa"); entity.Property(e => e.Idestado) .HasColumnType("int(11)") .HasColumnName("idestado"); @@ -506,6 +545,11 @@ public partial class AlquilaFacilContext : DbContext .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_PROP_PROPI"); + entity.HasOne(d => d.IddivisaNavigation).WithMany(p => p.Propiedades) + .HasForeignKey(d => d.Iddivisa) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_propdiv"); + entity.HasOne(d => d.IdestadoNavigation).WithMany(p => p.Propiedades) .HasForeignKey(d => d.Idestado) .OnDelete(DeleteBehavior.Restrict) @@ -596,6 +640,8 @@ public partial class AlquilaFacilContext : DbContext entity.HasIndex(e => e.Idpropiedad, "FK_VEN_PROP"); + entity.HasIndex(e => e.Iddivisa, "FK_ventdiv"); + entity.Property(e => e.Id) .HasColumnType("bigint(20)") .HasColumnName("id"); @@ -611,6 +657,9 @@ public partial class AlquilaFacilContext : DbContext entity.Property(e => e.IdVendedor) .HasColumnType("bigint(20)") .HasColumnName("idVendedor"); + entity.Property(e => e.Iddivisa) + .HasColumnType("int(11)") + .HasColumnName("iddivisa"); entity.Property(e => e.Idestado) .HasColumnType("int(11)") .HasColumnName("idestado"); @@ -631,6 +680,11 @@ public partial class AlquilaFacilContext : DbContext .OnDelete(DeleteBehavior.Restrict) .HasConstraintName("FK_VEN_PROL"); + entity.HasOne(d => d.IddivisaNavigation).WithMany(p => p.Venta) + .HasForeignKey(d => d.Iddivisa) + .OnDelete(DeleteBehavior.Restrict) + .HasConstraintName("FK_ventdiv"); + entity.HasOne(d => d.IdestadoNavigation).WithMany(p => p.Venta) .HasForeignKey(d => d.Idestado) .OnDelete(DeleteBehavior.Restrict) diff --git a/Entidades/Contrato.cs b/Entidades/Contrato.cs index fb566fd..ecbe717 100644 --- a/Entidades/Contrato.cs +++ b/Entidades/Contrato.cs @@ -33,12 +33,16 @@ public partial class Contrato public ulong Cancelado { get; set; } + public int Iddivisa { get; set; } + public virtual ICollection Defectos { get; set; } = new List(); public virtual Cliente? DniinquilinoNavigation { get; set; } public virtual Cliente? DnipropietarioNavigation { get; set; } + public virtual Divisa IddivisaNavigation { get; set; } = null!; + public virtual Propiedade? IdpropiedadNavigation { get; set; } public virtual Venta? IdventaNavigation { get; set; } diff --git a/Entidades/Defecto.cs b/Entidades/Defecto.cs index 1147a55..6cc2269 100644 --- a/Entidades/Defecto.cs +++ b/Entidades/Defecto.cs @@ -17,7 +17,11 @@ public partial class Defecto public ulong Pagainquilino { get; set; } + public int Iddivisa { get; set; } + public virtual Contrato? IdcontratoNavigation { get; set; } + public virtual Divisa IddivisaNavigation { get; set; } = null!; + public virtual Estadodefecto? IdestadoNavigation { get; set; } } diff --git a/Entidades/Divisa.cs b/Entidades/Divisa.cs new file mode 100644 index 0000000..f9a5cb1 --- /dev/null +++ b/Entidades/Divisa.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Entidades; + +public partial class Divisa +{ + public int Id { get; set; } + + public string Signo { get; set; } = null!; + + public virtual ICollection Contratos { get; set; } = new List(); + + public virtual ICollection Defectos { get; set; } = new List(); + + public virtual ICollection Propiedades { get; set; } = new List(); + + public virtual ICollection Venta { get; set; } = new List(); +} diff --git a/Entidades/Propiedade.cs b/Entidades/Propiedade.cs index 4a4812c..268fa3d 100644 --- a/Entidades/Propiedade.cs +++ b/Entidades/Propiedade.cs @@ -23,10 +23,14 @@ public partial class Propiedade public decimal Monto { get; set; } + public int Iddivisa { get; set; } + public virtual ICollection Contratos { get; set; } = new List(); public virtual Cliente? DnipropietarioNavigation { get; set; } + public virtual Divisa IddivisaNavigation { get; set; } = null!; + public virtual EstadoPropiedad? IdestadoNavigation { get; set; } public virtual TipoPropiedad IdtipropiedadNavigation { get; set; } = null!; diff --git a/Entidades/Venta.cs b/Entidades/Venta.cs index 4620380..200b45c 100644 --- a/Entidades/Venta.cs +++ b/Entidades/Venta.cs @@ -21,12 +21,16 @@ public partial class Venta public DateTime? Fechafinal { get; set; } + public int Iddivisa { get; set; } + public virtual ICollection Contratos { get; set; } = new List(); public virtual Cliente? IdCompradorNavigation { get; set; } public virtual Cliente? IdVendedorNavigation { get; set; } + public virtual Divisa IddivisaNavigation { get; set; } = null!; + public virtual Estadoventa? IdestadoNavigation { get; set; } public virtual Propiedade? IdpropiedadNavigation { get; set; } -- 2.52.0 From 7565e21df890c3cae2f76a39ba64cc6b42239440 Mon Sep 17 00:00:00 2001 From: fede Date: Mon, 13 Jan 2025 20:31:09 -0300 Subject: [PATCH 03/24] dmgc: llegue al frontend --- Aspnet/Controllers/PropiedadesController.cs | 10 +++- Entidades/Admin/PropiedadesAdmin.cs | 1 + Entidades/Dto/AltaPropiedadDto.cs | 1 + Entidades/Dto/PatchPropiedadDto.cs | 2 +- Entidades/Dto/PropiedadesDto.cs | 1 + Front/src/types.d.ts | 9 ++- Modelo/RepositorioPropiedades.cs | 61 ++++++++++++++------- 7 files changed, 60 insertions(+), 25 deletions(-) diff --git a/Aspnet/Controllers/PropiedadesController.cs b/Aspnet/Controllers/PropiedadesController.cs index 0da73b7..26f34b6 100644 --- a/Aspnet/Controllers/PropiedadesController.cs +++ b/Aspnet/Controllers/PropiedadesController.cs @@ -109,6 +109,7 @@ public class PropiedadesController: ControllerBase { Letra = propiedad.Letra ?? null, Piso = propiedad.Piso ?? null, Monto = propiedad.Monto, + Iddivisa = propiedad.Iddivisa, }; var ret = RepositorioPropiedades.Singleton.AñadirPropiedad(Prop); @@ -141,7 +142,8 @@ public class PropiedadesController: ControllerBase { Letra = propiedad.Letra ?? null, Piso = propiedad.Piso ?? null, IdServicios = servs, - Monto = propiedad.Monto + Monto = propiedad.Monto, + Iddivisa = propiedad.Iddivisa, }; bool ret = RepositorioPropiedades.Singleton.PatchPropiedad(Prop); @@ -225,6 +227,9 @@ public class PropiedadesController: ControllerBase { if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n"; if (prop.Monto<=1) ret += "El monto tiene que ser como minimo mayor a 0"; + + if (prop.Iddivisa<0 || prop.Iddivisa>1) ret += "se tiene que elejir entre AR$ y US$"; + return ret; } @@ -244,6 +249,9 @@ public class PropiedadesController: ControllerBase { if (String.IsNullOrEmpty(prop.Ubicacion)) ret += "Tiene que definir la ubicacion de la propiedad\n"; if (prop.Monto<=1) ret += "El monto tiene que ser como minimo mayor a 0"; + + if (prop.Iddivisa<0 || prop.Iddivisa>1) ret += "se tiene que elejir entre AR$ y US$"; + return ret; } diff --git a/Entidades/Admin/PropiedadesAdmin.cs b/Entidades/Admin/PropiedadesAdmin.cs index 25274e5..38149b7 100644 --- a/Entidades/Admin/PropiedadesAdmin.cs +++ b/Entidades/Admin/PropiedadesAdmin.cs @@ -9,4 +9,5 @@ public class PropiedadesAdmin { public string? Servicios {get;set;} = ""; public int Monto { get; set; } public string Estado { get; set; } = ""; + public int Iddivisa { get; set; } } diff --git a/Entidades/Dto/AltaPropiedadDto.cs b/Entidades/Dto/AltaPropiedadDto.cs index a549463..8517bd2 100644 --- a/Entidades/Dto/AltaPropiedadDto.cs +++ b/Entidades/Dto/AltaPropiedadDto.cs @@ -7,4 +7,5 @@ public class AltaPropiedadDto { public string Email { get; set; } = string.Empty; public int Idtipropiedad { get; set; } public int Monto { get; set; } + public int Iddivisa { get; set; } } \ No newline at end of file diff --git a/Entidades/Dto/PatchPropiedadDto.cs b/Entidades/Dto/PatchPropiedadDto.cs index f7a01d5..3c2ec20 100644 --- a/Entidades/Dto/PatchPropiedadDto.cs +++ b/Entidades/Dto/PatchPropiedadDto.cs @@ -1,3 +1,3 @@ namespace Entidades.Dto; -public record PatchPropiedadDto(int id, string Ubicacion, int Canthabitaciones, int? Piso, string? Letra, string Email, int tipo, List Servicios, int Monto); +public record PatchPropiedadDto(int id, string Ubicacion, int Canthabitaciones, int? Piso, string? Letra, string Email, int tipo, List Servicios, int Monto, int Iddivisa); diff --git a/Entidades/Dto/PropiedadesDto.cs b/Entidades/Dto/PropiedadesDto.cs index 274206f..d5e2c13 100644 --- a/Entidades/Dto/PropiedadesDto.cs +++ b/Entidades/Dto/PropiedadesDto.cs @@ -8,4 +8,5 @@ public class PropiedadesDto { public string Tipo { get; set; } = ""; public string? Servicios {get;set;} = ""; public int Monto { get; set; } + public int Iddivisa { get; set; } } diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index cb2723e..bd249fc 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -6,7 +6,8 @@ export type PropiedadDto = { letra: string | null, canthabitaciones: number, servicios: string, - monto: number + monto: number, + iddivisa: number } export type AdminParametrosBusqueda = { @@ -25,7 +26,8 @@ export type PropiedadAdmin = { canthabitaciones: number, servicios: string, monto: number, - estado: string + estado: string, + iddvisa: number } export type Permiso = { id: number; @@ -52,7 +54,8 @@ export type Propiedad = { letra: string, email: string, idtipropiedad: number, - monto: number + monto: number, + iddivisa: number }; export type MensajeDto = { diff --git a/Modelo/RepositorioPropiedades.cs b/Modelo/RepositorioPropiedades.cs index e05d6d6..6d9dcc4 100644 --- a/Modelo/RepositorioPropiedades.cs +++ b/Modelo/RepositorioPropiedades.cs @@ -13,7 +13,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ListarPropiedades(){ FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -53,7 +54,7 @@ public class RepositorioPropiedades: RepositorioBase { var row = con.Database.ExecuteSqlRaw( $""" CALL InsertarPropiedad(@p_ubicacion, @p_cant_habitaciones, @p_piso, @p_letra, - @p_dni_propietario, @p_id_tipo_propiedad, @p_monto, @p_filas_insertadas) + @p_dni_propietario, @p_id_tipo_propiedad, @p_monto, @iddivisa, @p_filas_insertadas) """, new MySqlParameter("@p_ubicacion", prop.Ubicacion), new MySqlParameter("@p_cant_habitaciones", prop.Canthabitaciones), @@ -62,6 +63,7 @@ public class RepositorioPropiedades: RepositorioBase { new MySqlParameter("@p_dni_propietario", prop.Dnipropietario), new MySqlParameter("@p_id_tipo_propiedad", prop.Idtipropiedad), new MySqlParameter("@p_monto",prop.Monto), + new MySqlParameter("@iddivisa", prop.Iddivisa), filasInsertadasParam ); @@ -80,6 +82,7 @@ public class RepositorioPropiedades: RepositorioBase { propi.Piso = prop.Piso; propi.Letra = prop.Letra; propi.Monto = prop.Monto; + prop.Iddivisa = prop.Iddivisa; propi.IdServicios.Clear(); foreach(Servicio ser in prop.IdServicios) { @@ -93,7 +96,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedadesPorEmail(string email) { FormattableString sqlq = $""" - SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto + 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 Idivisa FROM Propiedades p JOIN Clientes c ON c.dni = p.dnipropietario JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad @@ -109,7 +113,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedadesDeBajaPorEmail(string email) { FormattableString sqlq = $""" - SELECT p.id, p.ubicacion as Ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion as Tipo, GROUP_CONCAT(IFNULL(s.descripcion, '') SEPARATOR ', ') AS Servicios, p.monto as Monto + 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 Idivisa FROM Propiedades p JOIN Clientes c ON c.dni = p.dnipropietario JOIN TipoPropiedad tp ON tp.id = p.idtipropiedad @@ -189,7 +194,8 @@ public class RepositorioPropiedades: RepositorioBase { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -213,7 +219,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedesPorHabitaciones_Tipo(int cantidadHabitaciones, int tipoPropiedad) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -232,7 +239,8 @@ public class RepositorioPropiedades: RepositorioBase { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -255,7 +263,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedesPorHabitaciones(int cantidadHabitaciones) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -272,7 +281,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedesPorTipo(int tipoPropiedad) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -290,7 +300,8 @@ public class RepositorioPropiedades: RepositorioBase { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -315,7 +326,8 @@ public class RepositorioPropiedades: RepositorioBase { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -352,7 +364,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ListarPropiedadesPorPagina(int pag) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, + p.iddivisa as Idivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = 1 JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -369,7 +382,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ListarPropiedadesPorPaginaAdmin(int pag) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -387,7 +401,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedesPorHabitacionesPaginado(int cantidadHabitaciones, int pag) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -405,7 +420,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedesPorTipoPaginado(int tipoPropiedad, int pag) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -423,7 +439,8 @@ public class RepositorioPropiedades: RepositorioBase { public IQueryable ObtenerPropiedesPorHabitaciones_TipoPaginado(int cantidadHabitaciones, int tipoPropiedad, int pag) { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -443,7 +460,8 @@ public class RepositorioPropiedades: RepositorioBase { FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -468,7 +486,8 @@ public class RepositorioPropiedades: RepositorioBase { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -494,7 +513,8 @@ public class RepositorioPropiedades: RepositorioBase { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id @@ -520,7 +540,8 @@ public class RepositorioPropiedades: RepositorioBase { string serviciosEscapados = string.Join(",", servicios.Split(',').Select(s => s.Trim())); FormattableString sqlq = $""" SELECT DISTINCT p.id, p.ubicacion, p.canthabitaciones, p.piso, p.letra, tp.descripcion AS Tipo, - GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado + GROUP_CONCAT(DISTINCT s.descripcion SEPARATOR ', ') AS Servicios, p.monto as Monto, ep.descripcion AS Estado, + p.iddivisa as Iddivisa FROM Propiedades p JOIN EstadoPropiedad ep ON p.idestado = ep.id JOIN TipoPropiedad tp ON p.idtipropiedad = tp.id -- 2.52.0 From 013744d129cfa7af11cba5cb5a789c0a730f0a5e Mon Sep 17 00:00:00 2001 From: fede Date: Tue, 14 Jan 2025 04:13:13 -0300 Subject: [PATCH 04/24] falta mirar en la base de datos si guardo el tipo de moneda --- .../Controllers/NotificacionesController.cs | 19 +++++++----- Front/src/Componentes/AdminPropiedad.svelte | 8 ++++- .../Componentes/PublicacionPropiedad.svelte | 8 ++++- Front/src/Componentes/RowPropiedad.svelte | 15 +++++++--- .../Componentes/modificarPropiedadForm.svelte | 28 +++++++++++++++-- .../paginas/ControlAlquileresInquilino.svelte | 14 ++++++--- Front/src/paginas/MisPropiedades.svelte | 5 +++- Front/src/paginas/MisPropiedadesDeBaja.svelte | 3 +- Front/src/paginas/Notificaciones.svelte | 8 ++--- Front/src/paginas/PublicarPropiedad.svelte | 30 +++++++++++++++++-- Front/src/types.d.ts | 2 +- Modelo/RepositorioContratos.cs | 1 + Modelo/RepositorioNotificaciones.cs | 5 ++-- Modelo/RepositorioPropiedades.cs | 24 +++++++-------- Modelo/RepositorioUsuarios.cs | 4 +++ 15 files changed, 131 insertions(+), 43 deletions(-) diff --git a/Aspnet/Controllers/NotificacionesController.cs b/Aspnet/Controllers/NotificacionesController.cs index fa8a141..a7a6a99 100644 --- a/Aspnet/Controllers/NotificacionesController.cs +++ b/Aspnet/Controllers/NotificacionesController.cs @@ -15,22 +15,25 @@ public class NotificacionesController: ControllerBase { var cli = RepositorioUsuarios.Singleton.ObtenerClientePorToken(Auth); if (cli == null) return BadRequest(new {message = "Fallo al intentar encontrar tu usuario (puede que te hayas logeado desde otro dispositivo?)"}); - IQueryable notificaciones = RepositorioNotificaciones.Singleton.ObtenerNotificacionesDeUsuario(cli.Dni) .Where(x=>x.Leido == leido); + + List noti = new(); - Parallel.ForEach(notificaciones, i => { + foreach (Notificacione i in notificaciones) { + if(i.DniclienteNavigation == null || i.DniremitenteNavigation==null) return BadRequest(new { message = "Esta mal cargado el precontrato"}); var dto = new NotificacionDtoBuilder() - .SetRemitente(i.DniremitenteNavigation.Email) - .SetAccion(i.Accion) - .SetMensaje(i.Mensaje) + .SetRemitente(i.DniremitenteNavigation.Email??"") + .SetAccion(i.Accion??"") + .SetMensaje(i.Mensaje??"") .SetFecha(i.Fecha) - .SetPropiedad(i.IdpropiedadNavigation.Id.ToString()) - .SetReceptor(i.DniclienteNavigation.Email) + .SetPropiedad(i.Idpropiedad.ToString()??"") + .SetReceptor(i.DniclienteNavigation.Email??"") .Build(); noti.Add(dto); - }); + } + return Ok(noti); } diff --git a/Front/src/Componentes/AdminPropiedad.svelte b/Front/src/Componentes/AdminPropiedad.svelte index a4f478b..bb1ce56 100644 --- a/Front/src/Componentes/AdminPropiedad.svelte +++ b/Front/src/Componentes/AdminPropiedad.svelte @@ -43,7 +43,13 @@ Piso: {prop.piso || "N/A"}
Letra: {prop.letra || "N/A"}
Servicios: {prop.servicios || "Sin servicios especificados"}
- Monto: ${prop.monto}
+ Monto: + {#if prop.iddivisa == 0} + AR$ + {:else} + US$ + {/if} + {prop.monto}
Estado: {prop.estado}

{#if prop.estado == "Disponible"} diff --git a/Front/src/Componentes/PublicacionPropiedad.svelte b/Front/src/Componentes/PublicacionPropiedad.svelte index 8008fbb..44a8f43 100644 --- a/Front/src/Componentes/PublicacionPropiedad.svelte +++ b/Front/src/Componentes/PublicacionPropiedad.svelte @@ -68,7 +68,13 @@ Piso: {prop.piso || "N/A"}
Letra: {prop.letra || "N/A"}
Servicios: {prop.servicios || "Sin servicios especificados"}
- Monto: ${prop.monto}
+ Monto: + {#if prop.iddivisa == 0} + AR$ + {:else} + US$ + {/if} + {prop.monto}

diff --git a/Front/src/Componentes/RowPropiedad.svelte b/Front/src/Componentes/RowPropiedad.svelte index c9cdb15..d94093d 100644 --- a/Front/src/Componentes/RowPropiedad.svelte +++ b/Front/src/Componentes/RowPropiedad.svelte @@ -3,7 +3,7 @@ import ModalEstatico from "./ModalEstatico.svelte"; import ModificarPropiedadForm from "./modificarPropiedadForm.svelte"; - let { id, ubicacion, tipo, letra, piso,canthabitaciones, servicios, btnbaja = "Baja", monto } = $props(); + let { id, ubicacion, tipo, letra, piso,canthabitaciones, servicios, btnbaja = "Baja", monto, iddivisa = 0 } = $props(); import { urlG } from "../stores/urlStore"; @@ -45,10 +45,17 @@ {piso} {tipo} {servicios} + + {#if iddivisa == 0} + AR$ + {:else} + US$ + {/if} + {monto} - - + + {#if modal} @@ -57,7 +64,7 @@ {#if modificar} - + {/if} diff --git a/Front/src/Componentes/modificarPropiedadForm.svelte b/Front/src/Componentes/modificarPropiedadForm.svelte index 709ec9b..4911810 100644 --- a/Front/src/Componentes/modificarPropiedadForm.svelte +++ b/Front/src/Componentes/modificarPropiedadForm.svelte @@ -2,7 +2,7 @@ import { urlG } from "../stores/urlStore"; import { onMount } from "svelte"; - let { canthabitaciones, id, letra, piso, tipo, ubicacion, servicios, monto } = $props(); + let { canthabitaciones, id, letra, piso, tipo, ubicacion, servicios, monto, iddivisa} = $props(); let serviciosSeleccionados: string[] = $state([]); const serviciosDisponibles = ["Gas", "Internet", "Telefono", "Luz"]; @@ -53,7 +53,8 @@ ubicacion, email, servicios: serviciosSeleccionados, - monto + monto, + iddivisa }), }); if (response.ok) { @@ -151,6 +152,29 @@ +
+
Moneda
+
+ + +
+
+ + +
+
Servicios
{#each serviciosDisponibles as servicio} diff --git a/Front/src/paginas/ControlAlquileresInquilino.svelte b/Front/src/paginas/ControlAlquileresInquilino.svelte index 511886b..f2670d4 100644 --- a/Front/src/paginas/ControlAlquileresInquilino.svelte +++ b/Front/src/paginas/ControlAlquileresInquilino.svelte @@ -1,16 +1,22 @@ -
+
-
- +
+
+
+
+

a

+
+
+
\ No newline at end of file diff --git a/Front/src/paginas/MisPropiedades.svelte b/Front/src/paginas/MisPropiedades.svelte index 5f903a4..0f89e29 100644 --- a/Front/src/paginas/MisPropiedades.svelte +++ b/Front/src/paginas/MisPropiedades.svelte @@ -52,13 +52,16 @@ Piso Tipo Servicios + Divisa Monto {#each $propiedades as propiedad} - + {/each} diff --git a/Front/src/paginas/MisPropiedadesDeBaja.svelte b/Front/src/paginas/MisPropiedadesDeBaja.svelte index 8c8424e..b3c8e6a 100644 --- a/Front/src/paginas/MisPropiedadesDeBaja.svelte +++ b/Front/src/paginas/MisPropiedadesDeBaja.svelte @@ -53,13 +53,14 @@ Piso Tipo Servicios + Divisa Monto {#each $propiedades as propiedad} - + {/each} diff --git a/Front/src/paginas/Notificaciones.svelte b/Front/src/paginas/Notificaciones.svelte index 9ed6947..d43e2d7 100644 --- a/Front/src/paginas/Notificaciones.svelte +++ b/Front/src/paginas/Notificaciones.svelte @@ -170,7 +170,7 @@ cantidadGarantes: data.cantGarantes, idPropiedad: Selmens.propiedad, fechaprimernotificacion: fecha, - emailInquilino: localStorage.getItem("email"), + emailInquilino: Selmens.remitente, emailPropietario: Selmens.receptor, }; @@ -459,7 +459,7 @@ {#if mensajes.length <= 0} - +

No hay Mensajes para leer

@@ -481,8 +481,8 @@ Expandir {/if} - {#if men.accion === "ContratoCancelado" || men.accion === "Rechazo Contrato" || - men.accion === "Aceptado Contrato"} + {#if (men.accion === "ContratoCancelado" || men.accion === "Rechazo Contrato" || + men.accion === "Aceptado Contrato") && mostrarleidos == false}
+ +
+
Moneda
+
+ + +
+
+ + +
+
+
+
+ + +
+
+

+ +

+
+
+ + + + + + + + + + + + + {#if defectos.length == 0} + + + + {:else} + {#each defectos as defecto} + + + + + + + + + {/each} + {/if} + +
DescripciónCostoEstadoPaga InquilinoDivisa
No hay defectos que mostrar
{defecto.descripcion}{defecto.costo}{defecto.estado}{defecto.pagainquilino}{defecto.divisa} + {#if defecto.estado !== "Pagado"} + + + {/if} +
+
+
+
diff --git a/Front/src/types.d.ts b/Front/src/types.d.ts index 726983f..eaabcf9 100644 --- a/Front/src/types.d.ts +++ b/Front/src/types.d.ts @@ -118,4 +118,22 @@ export type ContratoPropiedadDto ={ letra:string, mesesAumento:number, mesesDuracion:number +} + +export type DefectoDto ={ + id:number, + descripcion:string, + costo:number, + estado:string, + idcontrato:number, + pagainquilino:string, + divisa:string, +} + +export type AltaDefectoDto ={ + descripcion:string, + costo:number, + pagainquilino:number, + iddivisa:number, + idcontrato:number } \ No newline at end of file diff --git a/Modelo/RepositorioDefectos.cs b/Modelo/RepositorioDefectos.cs index aebfb89..df62251 100644 --- a/Modelo/RepositorioDefectos.cs +++ b/Modelo/RepositorioDefectos.cs @@ -1,4 +1,5 @@ using Entidades; +using Microsoft.EntityFrameworkCore; namespace Modelo; @@ -21,7 +22,10 @@ public class RepositorioDefectos: RepositorioBase { public IQueryable ObtenerDefectosPorIdContrato(long idcontrato){ var con = Context; - var l = con.Defectos.Where(x=>x.Idcontrato == idcontrato); + var l = con.Defectos + .Include(x=>x.IdestadoNavigation) + .Include(x=>x.IddivisaNavigation) + .Where(x=>x.Idcontrato == idcontrato); return l; } } \ No newline at end of file -- 2.52.0 From 04a3deeae57b51c676d6d8d2ed2dfd9fb14cf537 Mon Sep 17 00:00:00 2001 From: fede Date: Wed, 22 Jan 2025 05:07:26 -0300 Subject: [PATCH 22/24] chore --- .gitignore | 1 + bun.lockb | Bin 0 -> 1583 bytes package.json | 1 + 3 files changed, 2 insertions(+) create mode 100755 bun.lockb create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 0a0f362..cfe669c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /Aspnet/obj/ /Modelo/bin/ Aspnet/bin/ +node_modules/ \ No newline at end of file diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..1893ab0c0b2eb2100e934338699a7a2df0a9b36e GIT binary patch literal 1583 zcmY#Z)GsYA(of3F(@)JSQ%EY!<4P*c)6L0G&Q8nBN!3luFUn0U(JeFJVq#!mD44gv zT5eJUm#E+CQ#VZRioV{s+hyCKU2_*)6yIKLlYVGED+3rXgGmMk4m7#}$}fj0fbtm_ zk~0#EO7yadEf^RWco`UA3K=pQGP6~bCVx2GQX3ScrO(O;*Fhcw}94lKt<#%KV?^ z^)*Yg^D?u{_3cr4k1g+CYkPQYH4g-frrIeO87LHIR;A{r=_r^eB<5tM z=jEqyA-VtGe+U2xfx{h|7&)Lcmrbd$k)47GE>l4MwScO1fYQY10ohdmRlfvEbJ;{2 znZ=e`*eMv9!R<3dxEhwvVfmT~WC+ON46vLJ%jryvaRz$EdIk&(@1SPGXw<+ePR%V# zEz)zXC`m2KOUwx_Day=Cw^J}gSZ@KhUIJP^O^4E4HXxT8VsU6jNl8JmmA-yaYIrx<1Sc`nqtYu8E$Bp1EF0dX+ Date: Wed, 22 Jan 2025 05:07:44 -0300 Subject: [PATCH 23/24] inicio soporte informe --- .../Builder/DtoBuilder/ContratoDtoBuilder.cs | 10 ++-- .../DtoBuilder/ContratoPropiedadDtoBuilder.cs | 10 ++-- Entidades/Dto/Chart/Chartjs.cs | 29 +++++++++++ Front/src/App.svelte | 14 ++++-- .../Componentes/Estadisticas/fChart.svelte | 49 +++++++++++++++++++ Front/src/paginas/Informes.svelte | 38 ++++++++++++++ Modelo/RepositorioCanons.cs | 16 +++++- 7 files changed, 151 insertions(+), 15 deletions(-) create mode 100644 Entidades/Dto/Chart/Chartjs.cs create mode 100644 Front/src/Componentes/Estadisticas/fChart.svelte create mode 100644 Front/src/paginas/Informes.svelte diff --git a/Aspnet/Builder/DtoBuilder/ContratoDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/ContratoDtoBuilder.cs index 038449b..5a3d4a0 100644 --- a/Aspnet/Builder/DtoBuilder/ContratoDtoBuilder.cs +++ b/Aspnet/Builder/DtoBuilder/ContratoDtoBuilder.cs @@ -36,14 +36,14 @@ public class ContratoDtoBuilder: Builder { bool Habilitado = habilitado == 0?false:true; bool Cancelado = cancelado == 0?false:true; - if (Habilitado == true && Cancelado == false){ + if (Habilitado == true && Cancelado == false){ data.Estado = "Alquiler Iniciado"; - } else if (Cancelado == true && Habilitado == true) { + } else if (Cancelado == true && Habilitado == false) { data.Estado = "Nunca Empezo Esta Cancelado"; - } - - if (Habilitado == false && Cancelado ==false){ + } else if (Habilitado == false && Cancelado ==false){ data.Estado = "Esta en Proceso"; + } else if (Habilitado == true && Cancelado == true){ + data.Estado = "Terminado"; } return this; } diff --git a/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs b/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs index e05d666..ab8a5e5 100644 --- a/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs +++ b/Aspnet/Builder/DtoBuilder/ContratoPropiedadDtoBuilder.cs @@ -36,14 +36,14 @@ public class ContratoPropiedadDtoBuilder : Builder{ bool Habilitado = habilitado == 0?false:true; bool Cancelado = cancelado == 0?false:true; - if (Habilitado == true && Cancelado == false){ + if (Habilitado == true && Cancelado == false){ data.Estado = "Alquiler Iniciado"; - } else if (Cancelado == true && Habilitado == true) { + } else if (Cancelado == true && Habilitado == false) { data.Estado = "Nunca Empezo Esta Cancelado"; - } - - if (Habilitado == false && Cancelado ==false){ + } else if (Habilitado == false && Cancelado ==false){ data.Estado = "Esta en Proceso"; + } else if (Habilitado == true && Cancelado == true){ + data.Estado = "Terminado"; } return this; } diff --git a/Entidades/Dto/Chart/Chartjs.cs b/Entidades/Dto/Chart/Chartjs.cs new file mode 100644 index 0000000..9c52544 --- /dev/null +++ b/Entidades/Dto/Chart/Chartjs.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +public class ChartData +{ + [JsonPropertyName("labels")] + public List Labels { get; set; }=new(); + + [JsonPropertyName("datasets")] + public List Datasets { get; set; }=new(); +} + +public class Dataset +{ + [JsonPropertyName("label")] + public string Label { get; set; } =""; + + [JsonPropertyName("data")] + public List Data { get; set; }= new(); +/* + [JsonPropertyName("backgroundColor")] + public List BackgroundColor { get; set; } + + [JsonPropertyName("borderColor")] + public List BorderColor { get; set; } +*/ + [JsonPropertyName("borderWidth")] + public int BorderWidth { get; set; }=1; +} diff --git a/Front/src/App.svelte b/Front/src/App.svelte index 2129670..8575022 100644 --- a/Front/src/App.svelte +++ b/Front/src/App.svelte @@ -17,10 +17,11 @@ import AdminUsuarios from "./paginas/AdminUsuarios.svelte"; import AdminPropiedades from "./paginas/AdminPropiedades.svelte"; import Notificaciones from "./paginas/Notificaciones.svelte"; - import ControlAlquileresInquilino from "./paginas/ControlAlquileresInquilino.svelte"; - import ControlAlquileresPropietario from "./paginas/ControlAlquileresPropietario.svelte"; - import ContratosPropietario from "./paginas/ContratosPropietario.svelte"; - import ContratoInquilino from "./paginas/ContratoInquilino.svelte"; + import ControlAlquileresInquilino from "./paginas/ControlAlquileresInquilino.svelte"; + import ControlAlquileresPropietario from "./paginas/ControlAlquileresPropietario.svelte"; + import ContratosPropietario from "./paginas/ContratosPropietario.svelte"; + import ContratoInquilino from "./paginas/ContratoInquilino.svelte"; + import Informes from "./paginas/Informes.svelte"; @@ -64,6 +65,11 @@
+ + + + + diff --git a/Front/src/Componentes/Estadisticas/fChart.svelte b/Front/src/Componentes/Estadisticas/fChart.svelte new file mode 100644 index 0000000..20f4451 --- /dev/null +++ b/Front/src/Componentes/Estadisticas/fChart.svelte @@ -0,0 +1,49 @@ + + +
+ +
\ No newline at end of file diff --git a/Front/src/paginas/Informes.svelte b/Front/src/paginas/Informes.svelte new file mode 100644 index 0000000..1a75d59 --- /dev/null +++ b/Front/src/paginas/Informes.svelte @@ -0,0 +1,38 @@ + + + + +
+
+
+ +
+ + + + + + + + + +
#UbicacionDivisa
+
+
+ +
+
+ +
\ No newline at end of file diff --git a/Modelo/RepositorioCanons.cs b/Modelo/RepositorioCanons.cs index 8e2cdc8..f1811da 100644 --- a/Modelo/RepositorioCanons.cs +++ b/Modelo/RepositorioCanons.cs @@ -29,14 +29,28 @@ public class RepositorioCanons: RepositorioBase { public bool SetRecibo(Canon c, Recibo re) { var con = Context; - var cc = con.Canons.FirstOrDefault(x=>x.Id == c.Id); + var cc = con.Canons + .Include(x=>x.Idcontratos) + .ThenInclude(x=>x.Idcanons) + .FirstOrDefault(x=>x.Id == c.Id); if (cc == null) return false; + if (cc.Idcontratos.Count()!=1) return false; + Contrato ccc = cc.Idcontratos.First(); + if (ccc.Cancelado == 1 || ccc.Habilitado == 0) return false; + con.Entry(ccc).Reference(x=>x.IdpropiedadNavigation).Load(); + re.Id = (con.Recibos.Any()?con.Recibos.Max(x=>x.Id):0)+1; con.Recibos.Add(re); cc.Idrecibo = re.Id; cc.Pagado = 1; + + if (ccc.Idcanons.Where(x=>x.Pagado==1).Count() == ccc.MesesDurationContrato){ + ccc.Cancelado = 1; + ccc.IdpropiedadNavigation.Idestado = 3; + } + return Guardar(con); } -- 2.52.0 From 6592afb3a7ff570f04e31e9c636d1e05b03f89ea Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 23 Jan 2025 05:17:07 -0300 Subject: [PATCH 24/24] estadisticas --- .../DtoBuilder/InformeAlquilerBuilder.cs | 17 ++ Aspnet/Controllers/EstadisticaController.cs | 60 ++++++ Aspnet/Controllers/ServiciosController.cs | 12 -- Entidades/Dto/Chart/Chartjs.cs | 8 +- Entidades/Informes/InfomesAlquiler.cs | 6 + Entidades/Informes/InformeMeses.cs | 17 ++ Front/bun.lockb | Bin 43971 -> 45942 bytes Front/index.html | 1 + Front/package.json | 1 + .../Componentes/Estadisticas/fChart.svelte | 104 +++++----- Front/src/paginas/Informes.svelte | 190 ++++++++++++++++-- Front/src/types.d.ts | 8 + Modelo/RepositorioContratos.cs | 5 + Modelo/RepositorioEstadisticas.cs | 72 +++++++ 14 files changed, 414 insertions(+), 87 deletions(-) create mode 100644 Aspnet/Builder/DtoBuilder/InformeAlquilerBuilder.cs create mode 100644 Aspnet/Controllers/EstadisticaController.cs delete mode 100644 Aspnet/Controllers/ServiciosController.cs create mode 100644 Entidades/Informes/InfomesAlquiler.cs create mode 100644 Entidades/Informes/InformeMeses.cs create mode 100644 Modelo/RepositorioEstadisticas.cs diff --git a/Aspnet/Builder/DtoBuilder/InformeAlquilerBuilder.cs b/Aspnet/Builder/DtoBuilder/InformeAlquilerBuilder.cs new file mode 100644 index 0000000..a0020ef --- /dev/null +++ b/Aspnet/Builder/DtoBuilder/InformeAlquilerBuilder.cs @@ -0,0 +1,17 @@ +using Entidades.Informes; + +namespace AlquilaFacil.Builder; +public class InformesAlquilerBuilder: Builder{ + public InformesAlquilerBuilder SetId(long id){ + data.Id = id; + return this; + } + public InformesAlquilerBuilder SetUbicacion(string Ubicacion){ + data.Ubicacion = Ubicacion; + return this; + } + public InformesAlquilerBuilder SetDivisa(string Divisa){ + data.Divisa = Divisa; + return this; + } +} \ No newline at end of file diff --git a/Aspnet/Controllers/EstadisticaController.cs b/Aspnet/Controllers/EstadisticaController.cs new file mode 100644 index 0000000..93db4df --- /dev/null +++ b/Aspnet/Controllers/EstadisticaController.cs @@ -0,0 +1,60 @@ +using AlquilaFacil.Builder; +using Entidades.Informes; +using Microsoft.AspNetCore.Mvc; +using Modelo; + +namespace AlquilaFacil.Controllers; +[ApiController] +public class EstadisticaController: ControllerBase { + [HttpGet("api/stats/alquileresIniciados")] + public IActionResult alquileresIniciadosEsteAño([FromHeader(Name ="Auth")]string Auth, int year) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + if (validacion1 == false) return Unauthorized(); + + var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); + if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año"}); + var a = RepositorioEstadisticas.Singleton.ObtenerDataIniciadosPorAño(year); + return Ok(a); + } + [HttpGet("api/tabla/alquileresIniciados")] + public IActionResult tablaalquileresIniciadosEsteAño([FromHeader(Name ="Auth")]string Auth, int year) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + if (validacion1 == false) return Unauthorized(); + + var validacion2 = RepositorioContratos.Singleton.HayContratosEnAño(year); + if (validacion2 == false) return BadRequest(new { message = "No hay contratos en ese año"}); + var a = RepositorioEstadisticas.Singleton.TablaObtenerContratosIniciadosPorAño(year); + if (a == null) return BadRequest(new { message = "Fallo al obtener el contrato"}); + + List informe =new(); + foreach (var i in a) { + var d = new InformesAlquilerBuilder() + .SetId(i.Id).SetUbicacion(i.IdpropiedadNavigation.Ubicacion) + .SetDivisa(i.IddivisaNavigation.Signo) + .Build(); + informe.Add(d); + } + return Ok(informe); + } + [HttpGet("api/stats/duracionContrato")] + public IActionResult DuracionContrato([FromHeader(Name ="Auth")]string Auth) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + if (validacion1 == false) return Unauthorized(); + + var a = RepositorioEstadisticas.Singleton.ObtenerDataDuracionContratos(); + return Ok(a); + } + + [HttpGet("api/tabla/duracionContrato")] + public IActionResult TablaDuracionContrato([FromHeader(Name ="Auth")]string Auth) { + if (String.IsNullOrWhiteSpace(Auth)) return BadRequest(""); + var validacion1 = RepositorioGrupos.Singleton.CheckGrupos(Auth, "Informes"); + if (validacion1 == false) return Unauthorized(); + + var a = RepositorioEstadisticas.Singleton.TablaObtenerDataDuracionContratos(); + return Ok(a); + } +} \ No newline at end of file diff --git a/Aspnet/Controllers/ServiciosController.cs b/Aspnet/Controllers/ServiciosController.cs deleted file mode 100644 index fea5d8b..0000000 --- a/Aspnet/Controllers/ServiciosController.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Entidades; -using Entidades.Dto; -using Microsoft.AspNetCore.Http.HttpResults; -using Microsoft.AspNetCore.Mvc; -using Modelo; - -namespace AlquilaFacil.Controllers; - -[ApiController] -public class ServiciosController: ControllerBase { - -} \ No newline at end of file diff --git a/Entidades/Dto/Chart/Chartjs.cs b/Entidades/Dto/Chart/Chartjs.cs index 9c52544..c208dd5 100644 --- a/Entidades/Dto/Chart/Chartjs.cs +++ b/Entidades/Dto/Chart/Chartjs.cs @@ -16,14 +16,8 @@ public class Dataset public string Label { get; set; } =""; [JsonPropertyName("data")] - public List Data { get; set; }= new(); -/* - [JsonPropertyName("backgroundColor")] - public List BackgroundColor { get; set; } + public List Data { get; set; }= new(); - [JsonPropertyName("borderColor")] - public List BorderColor { get; set; } -*/ [JsonPropertyName("borderWidth")] public int BorderWidth { get; set; }=1; } diff --git a/Entidades/Informes/InfomesAlquiler.cs b/Entidades/Informes/InfomesAlquiler.cs new file mode 100644 index 0000000..a5900ff --- /dev/null +++ b/Entidades/Informes/InfomesAlquiler.cs @@ -0,0 +1,6 @@ +namespace Entidades.Informes; +public class InformesAlquiler { + public long Id { get; set; } + public string Ubicacion { get; set; }=""; + public string Divisa { get; set; }=""; +} \ No newline at end of file diff --git a/Entidades/Informes/InformeMeses.cs b/Entidades/Informes/InformeMeses.cs new file mode 100644 index 0000000..7442417 --- /dev/null +++ b/Entidades/Informes/InformeMeses.cs @@ -0,0 +1,17 @@ +namespace Entidades.Informes; +public class InformesMeses { + public int Meses { get; set; } + public int Repes{ get; set; } + public string Semaforizacion {get { + switch(Repes.CompareTo(2)){ + case 1: + return "🟢"; + case 0: + return "🟡"; + case -1: + return "🔴"; + default: + return ""; + } + }} +} \ No newline at end of file diff --git a/Front/bun.lockb b/Front/bun.lockb index 502d03ba9d950912ca2cc160dc6df421f15de7ef..dba69aa9f2f4af05f2bb095cb6f7dbc33279cb40 100755 GIT binary patch delta 8503 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 delta 7162 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