From 6592afb3a7ff570f04e31e9c636d1e05b03f89ea Mon Sep 17 00:00:00 2001 From: fede Date: Thu, 23 Jan 2025 05:17:07 -0300 Subject: [PATCH] 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 zcmezNjOp-orU`nQRdc`aGEH%=a&O!IdWG3rA&qO^5_MnQ0;S%i?&f3heq_9w0Sxjc zhRfHR<$~D^3=C;S`FSM_3=HWE3=Dh>3=PQ{iA5z@#SH!o3=9$s3=PF)sW~O73=Bq0 z3=Gl?3=NV@3=EPC3=Qv?7#PGE7#diZ7#Ktu7#gNBL-^mAA^b0l3=9Gc3=Pj1A?Ds> zWMJTBU}!i4qIDP;8V)crFz_%iG;D#=s~8y=xEL537C`Cb;$q#BqSVx$$&!rnoHkHn zoF*qS%GbwmLe%CZ=H+LmFfgPRCzWRAq%hp%hB)FdHv@wh14F}FC_NoYH$v$gZipiz zxEUBk7#JE{ptJ#$mVwe7Q2GlOMBM`jUEgp9!f4pZ#lRrUz|gP^N>7H;4Ny9di-AFi zfuSJ=N_#^Xd2ok-ZWC60cEE5#z3=Eg07#P$T7#dPilS)BJB)6D>fuWv(f#IYS zBnl2lF)(m4Ff@QPq?Ix-Wap%o7BMg|ICDV6({u8Zic%{WjAbF}i!+PLK$eu`mn7z7 z7MJ7}EGj9^$xLEkV9=Sol36`MLy3Wbn}MMrwYVs;0F<k zWdhUW3G5k+rIUZM+cWKAnEZ>^j_D)AWGg;9#_Y+J9QKU9lXr61GtQs5d-7&Y0F z+n#aG7lXvpi zGl{TI{>5X*7&_UK*Pf|^eR36_9n&rL$-DUMm|8g||KhV_ddo4{ir*!3}JlodAs00%x6qvjhYg z7+k>WLg1_!aMm3-OF;;#j;UB^vXz(}Yo7=ML-b@@F>BVBA`A?XV3w08Ol+R? z5iJRm-6aWgfv^+G%$f;j&rg!1A`H$ zaGuO4V9s<@dUBPt9n(kY$-AWOIPGN^7_7i@jy&c}l`@m9Wb8PP%fK`^a+ovyl$pFs z#*WigmVv>HfuVt6vLmNCXR$0KZ7_grU|lcEz+f=hmdl#yyX@p$vUZ&MatsV6U6P5%U2=9zQu333$=R`b$b%A6EtfUtGxjFUln&d5*R zC2z;bH2J5zJ*$}l1B3PCzw*{hwF;A~6zrIGDooy`V8`@ZVe&5pJ0@$z$ySPXoF$43 z3>IL&9F#TZTm$Dda+@wtiGjh6fuVsB%q5DjveFO-i=i!(4Vq=3tP zFax3@1wt{6wn0bKD=K-W`h07yS4v;yT}U|{HGU|?WjU|{Hn#_uKr|?-Cqnrknh_LZlb`}18WiVKpnPN+6o=EH;wbdwUM+cW5YB+gl0vgHFfh!A zI&%S(UI;Y@MDsE*Fsy^}K{Uv98=&eoLd7?Nk}wAY1H(?J#4f1+LGtv;TlJ941j@(x|z$+^1TjO>$l>V{9w(BqvftLM$gIXP1=e6oZ-@8q+3-i+LnCH2E6pU~%> zT&wTR$UFI@e)!}H1K!EH2HuSPlPe9vCuy`P zIHU69ofhGYDw72*!x>d4XIh3cs!cv<8P2FaS<)(;QDbtURXC&Okw*U6bK;f!vR54waix=)sL4QKS2T<99k=sEeMYdE9VWJR}dM(@d$ZsC(pxbjZE z>*meqJ6Y2`d~$^w@8n*0Z$|&gH{HW0Yq;}Hw)OC444mBQ5kC2bJMZMT9^Q<>lPx{N zCwF-8PM+)O%@{iQrDynL3s2t3zFyvp;ge^2g-?Fr$vgS4mp5bNWKZw#$uqooC$IJP zW{jTv(>r{!hd1x!SRZf3*vTt>!YBXm=AF#z>&+NHInp*vjwJb9;I_+$=0-pR85-i)b}GyTIS@9^WDeAeHaF@3URK=|Ygf8NQp0p5(6 zlTQYOPnHPaoqRXYn=yN`W>EO#69K%FdxN|gb2r}%VrQCsfL&zrgAg7@pUH1Sq$hu1 zXHh)N4(Z~ZWd}FA8bG-f)c*wK(kc!H2JXopL+n8+Cm#sq5L?6v8G!()f(;Zr;oN*L z^d2KqiqPhL;c1LaRUDh|h3;dV{3J?;SBC*IF!5S}fk9yN!%%+4$sQ^?n+sw#iEvdw z$4z>2CmR;oNd5Z{0U(P(ea#(EX@~sDeMNq{pn7i;0|Ucm1_p*L3=9lg85kJ0F)%QI z>dQq83=E4I7#Nl?Ffc4-U|?7_`EQYU{aOYF22ia$lYxO@76SvrYz78~IncJ6Jp%)S z0|NttBeYFtz`(#@$iTp0%m8jhgBrpNmJHy=J-BfSYE*z4pP+^)sKy4h1=64+JsAuP z44{5>76SuAHUk4g4g&*2E(62l>BWkopsLA_fdM=M6u`j15Xiv55H$I0vAY_mh3Lb; zzyK-qOU%g(;DH2&f_zXQFfe2kP3|jFvjrInG8|+fC}a{D7#I>57#O4&zylfJ z7BDD6K$Wiqv=snqWQs8`FbGfHTcTVKD$Cdy7#KiJSWx2wM1#tAkQf&O0|ST#iSa?z zfM^f~HADm$z~eihu^q5}kT}S6kena`14BFm14A4G14AqW149f014A?e0|Usbpk{Fx z0|P@O1A`_*1Oo#@2-N=`P$z<%Zw~b_Xy^bGwv!i@Nl)HT%E~Fn0BPlmOg>v0EC_1X zD>8sbXCVE8$%bX-4ps~d;79_EQg}mc1r4=<0vr_ZAQymw*%N9ZF3ajcnqi7St^>sj zs3{3bkinoBV_;wiX8`wT7(y8s7^0v-2CB!Cp$?6NS^|m~kUr3W3nIz9l|H(%y zv{XS!37q~wt^o~W!p3Wu7~_oe42|^+7;G3Pf2h&o@M2_OP-I|en4D1Q$GBkf`btU0 zRg-tuNHT7jys%S@#gKvFz~ue4;>;!tXC_~)1`FJrY*;19_-wLwl_cYr$-6rxnOK-6 zH&jV5Nit0is1}tow1AI}{uE5j{%3M_CKF?vp`MAJp((?=$!Du1rD3C|=<+5EQztW4 zOF~SNkbw=JKKyrforVeT46rdqdWH-PV5=l>nqvTVtt68X)8u*864Ky7RtAO!yEvvj zSKf2nXJUkP3PGNdWCZz0jKzR~0qp6?(lxTCJ#3J&RQu}UqKny^V!&1#fUL&lc2lsO zVv{YqgeMnNva%V1VhCh1G(?$%I3}yqrZLHLOzx>QVgv=NFOw0+WWG8hCTEVxPIX#L zJ{*(t>Lgf`IT#qkC-3i;n!L2`t;|VK3C_UKFi}6MS8c1Ur3m9T=-A&Cj>+rlC72#? zOg>R>#1z9h`A@xs3|5DO!%U59vO$A{8EmXIbEnM;6SmxEEQ|(vMuvK(3=FW**yqzq zJ}tEWwi_W6!!^0CLBb3+d~4=&X4}F^TdEKWU<14cPP5{-v+*+_WF~V>KGPr}0~-HGGn{toAVLN4?t-?Atl)Bl%yjO_a!nFuumSkh zZke$~_UdyG3SdL@ISGsYUz@no5g~JvdvZ>b1ml^>txd*euyN_#B4R?Z{WF_b7)|ty zOh82eY~*_D|2Lnwq)w?KWbO-1e%B;n1{>;TE4h@CbM7+}LIG?re6uP`tig*`VT6pe z@MN222^rYvd3XQcIop*5Um+CK2v06(mN0`2w?A`K<@oCCas;6OHXv`VzShF%_XRhE z%w6Hh`NuH#kg*V%%+n$v1Dh4#e{|7M z=g;Xs2nB^AlO0;pm<~uyKF}p04I7)EsQlGFxL_VD6Jwl#o}rnZ0iY5R`6oltlOT$+Ola|TF3$9M)*Mo(t!lx31onyk<%0WQ(Oh4!<_!JWR~LLFLY zg9{*W7DGb~rO6*UaTleCVog>AHVfc6aqI1S7n|QQF*Ybqp4X)S31~=}CO(;~TaRg~ z^5i|;3X`L{g_s^HPtNN$Vl7i)U=W>LSSJdV<1%Oi*H8=vZIca)L?-|0j*}`>fHXB* zEKJWZR`C5>09B&BdU8=u(BxY^PLs8I(