estadisticas
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
using Entidades.Informes;
|
||||||
|
|
||||||
|
namespace AlquilaFacil.Builder;
|
||||||
|
public class InformesAlquilerBuilder: Builder<InformesAlquiler>{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<InformesAlquiler> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -16,14 +16,8 @@ public class Dataset
|
|||||||
public string Label { get; set; } ="";
|
public string Label { get; set; } ="";
|
||||||
|
|
||||||
[JsonPropertyName("data")]
|
[JsonPropertyName("data")]
|
||||||
public List<double> Data { get; set; }= new();
|
public List<string> Data { get; set; }= new();
|
||||||
/*
|
|
||||||
[JsonPropertyName("backgroundColor")]
|
|
||||||
public List<string> BackgroundColor { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("borderColor")]
|
|
||||||
public List<string> BorderColor { get; set; }
|
|
||||||
*/
|
|
||||||
[JsonPropertyName("borderWidth")]
|
[JsonPropertyName("borderWidth")]
|
||||||
public int BorderWidth { get; set; }=1;
|
public int BorderWidth { get; set; }=1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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; }="";
|
||||||
|
}
|
||||||
@@ -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 "";
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -5,6 +5,7 @@
|
|||||||
<link rel="icon" type="image/png" href="/favicon.svg" />
|
<link rel="icon" type="image/png" href="/favicon.svg" />
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"/>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Configura el tema desde localStorage antes de cargar la aplicación
|
// Configura el tema desde localStorage antes de cargar la aplicación
|
||||||
const savedTheme = localStorage.getItem("theme") || "light";
|
const savedTheme = localStorage.getItem("theme") || "light";
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"@sveltejs/kit": "^2.7.3",
|
"@sveltejs/kit": "^2.7.3",
|
||||||
"@sveltestrap/sveltestrap": "^6.2.7",
|
"@sveltestrap/sveltestrap": "^6.2.7",
|
||||||
"chartjs": "^0.3.24",
|
"chartjs": "^0.3.24",
|
||||||
|
"svelte-chartjs": "^3.1.5",
|
||||||
"svelte-routing": "^2.13.0"
|
"svelte-routing": "^2.13.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,59 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import {
|
import Chart from 'chart.js/auto';
|
||||||
Chart,
|
|
||||||
registerables
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
Chart.register(...registerables);
|
let {chartData, typec='bar'} = $props();
|
||||||
|
|
||||||
export let data;
|
let chartContainer;
|
||||||
|
let instance;
|
||||||
|
|
||||||
let chartCanvas;
|
|
||||||
let chartInstance;
|
|
||||||
|
|
||||||
onMount(() => {
|
onDestroy(() => {
|
||||||
if (chartCanvas) {
|
if (instance) {
|
||||||
chartInstance = new Chart(chartCanvas, {
|
instance.destroy();
|
||||||
type: "bar",
|
}
|
||||||
data: data,
|
});
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
position: "top"
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
enabled: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
y: {
|
|
||||||
beginAtZero: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
const createChart = () => {
|
||||||
if (chartInstance) {
|
if (instance) {
|
||||||
chartInstance.destroy();
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
};
|
||||||
|
onMount(createChart);
|
||||||
|
$effect(createChart);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="card card-body">
|
||||||
|
<canvas bind:this={chartContainer}></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card card-body">
|
|
||||||
<canvas bind:this={chartCanvas}></canvas>
|
|
||||||
</div>
|
|
||||||
@@ -4,35 +4,183 @@
|
|||||||
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
|
import NavBarAutocompletable from "../Componentes/NavBarAutocompletable.svelte";
|
||||||
import { Chart } from "chart.js";
|
import { Chart } from "chart.js";
|
||||||
import FChart from "../Componentes/Estadisticas/fChart.svelte";
|
import FChart from "../Componentes/Estadisticas/fChart.svelte";
|
||||||
|
import ModalEstatico from "../Componentes/ModalEstatico.svelte";
|
||||||
|
import {urlG} from "../stores/urlStore";
|
||||||
|
import type { ChartData } from "../types";
|
||||||
|
import { text } from "@sveltejs/kit";
|
||||||
|
|
||||||
let cdata = $state();
|
let token = sessionStorage.getItem("token")||"";
|
||||||
|
let y = $state(2025);
|
||||||
|
|
||||||
let myChart;
|
let cdata:ChartData|any = $state();
|
||||||
onMount(() => {
|
let aldata:{id:number, ubicacion:string, divisa:string}|any = $state();
|
||||||
|
|
||||||
|
let chartMesesDuracion:ChartData|any = $state();
|
||||||
|
let tablaMesesDuracion:{meses:number, repes:number, semaforizacion:string}|any = $state();
|
||||||
|
|
||||||
|
let modaldata:string = $state("");
|
||||||
|
|
||||||
|
onMount(async() => {
|
||||||
|
await dataAlquileresporAño();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function dataAlquileresporAño(year = 2025) {
|
||||||
|
try{
|
||||||
|
const rep = fetch($urlG+"/api/stats/alquileresIniciados?year="+year, {
|
||||||
|
method : "GET",
|
||||||
|
headers: {
|
||||||
|
"Auth": token,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const pre = fetch($urlG+"/api/tabla/alquileresIniciados?year="+year, {
|
||||||
|
method : "GET",
|
||||||
|
headers: {
|
||||||
|
"Auth": token,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let [r,p] = await Promise.all([rep, pre]);
|
||||||
|
|
||||||
|
let data = await r.json();
|
||||||
|
let data2 = await p.json();
|
||||||
|
|
||||||
|
cdata = data;
|
||||||
|
aldata = data2;
|
||||||
|
return;
|
||||||
|
}catch{
|
||||||
|
modaldata="Fallo al intentar alcanzar el servidor";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let visibleMesesDuracion:boolean = $state(false);
|
||||||
|
async function dataMesesDuracion() {
|
||||||
|
try{
|
||||||
|
const p1 = fetch($urlG+"/api/stats/duracionContrato", {
|
||||||
|
method : "GET",
|
||||||
|
headers: {
|
||||||
|
"Auth": token,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const p2 = fetch($urlG+"/api/tabla/duracionContrato", {
|
||||||
|
method : "GET",
|
||||||
|
headers: {
|
||||||
|
"Auth": token,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let [r1, r2] = await Promise.all([p1,p2]);
|
||||||
|
let [d1,d2] = await Promise.all([r1.json(), r2.json()])
|
||||||
|
chartMesesDuracion = d1;
|
||||||
|
tablaMesesDuracion = d2;
|
||||||
|
}catch {
|
||||||
|
modaldata="Fallo al intentar alcanzar el servidor";
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if modaldata}
|
||||||
|
<ModalEstatico payload={modaldata} close={()=>!!(modaldata = "")} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
<NavBarAutocompletable/>
|
<NavBarAutocompletable/>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container-fluid">
|
||||||
<br>
|
<div class="row mt-4" >
|
||||||
<div class="row">
|
<BarraHorizontalConTexto text="Estadisticas"/>
|
||||||
<BarraHorizontalConTexto text="Alquileres del ultimo año"/>
|
<div class="accordion" id="accordionExample">
|
||||||
<div class="col">
|
<div class="accordion-item">
|
||||||
<table class="table table-hover">
|
<h2 class="accordion-header" id="hea1">
|
||||||
<thead>
|
<button class="accordion-button"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#c1"
|
||||||
|
aria-expanded="true"
|
||||||
|
aria-controls="c1">
|
||||||
|
|
||||||
<tr>
|
Alquileres en el ultimo año
|
||||||
<th>#</th>
|
</button>
|
||||||
<th>Ubicacion</th>
|
</h2>
|
||||||
<th>Divisa</th>
|
<div class="accordion-collapse collapse show" id="c1" data-bs-parent="#accordionExample">
|
||||||
</tr>
|
<div class="accordion-body row">
|
||||||
</thead>
|
<div class="col">
|
||||||
</table>
|
<div class="d-flex input-group">
|
||||||
</div>
|
<input class="form-control" type="number" bind:value={y}>
|
||||||
<div class="col">
|
<button class="btn btn-primary" onclick={()=>dataAlquileresporAño(y)}><img src="/zoom.svg" aria-label="Lupa"></button>
|
||||||
<FChart data={null}/>
|
</div>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Ubicacion</th>
|
||||||
|
<th>Divisa</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each aldata as al}
|
||||||
|
<tr>
|
||||||
|
<td>{al.id}</td>
|
||||||
|
<td>{al.ubicacion}</td>
|
||||||
|
<td>{al.divisa}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
{#if cdata}
|
||||||
|
<FChart chartData={cdata}/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="hea2">
|
||||||
|
<button class="accordion-button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#c2"
|
||||||
|
onclick={()=>{
|
||||||
|
if(visibleMesesDuracion === true){
|
||||||
|
visibleMesesDuracion=false;
|
||||||
|
return;
|
||||||
|
} else if (visibleMesesDuracion== false){
|
||||||
|
dataMesesDuracion();
|
||||||
|
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Meses De Duracion
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div class="accordion-collapse collapse" id="c2" data-bs-parent="#accordionExample">
|
||||||
|
<div class="accordion-body row">
|
||||||
|
<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>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Cantidad de meses</th>
|
||||||
|
<th>Repeticiones</th>
|
||||||
|
<th>Semaforización</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each tablaMesesDuracion as mes}
|
||||||
|
<tr>
|
||||||
|
<td>{mes.meses}</td>
|
||||||
|
<td>{mes.repes}</td>
|
||||||
|
<td>{mes.semaforizacion}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
{#if chartMesesDuracion}
|
||||||
|
<FChart chartData={chartMesesDuracion} typec="pie"/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
Vendored
+8
@@ -137,3 +137,11 @@ export type AltaDefectoDto ={
|
|||||||
iddivisa:number,
|
iddivisa:number,
|
||||||
idcontrato:number
|
idcontrato:number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ChartData = {
|
||||||
|
labels: string[],
|
||||||
|
datasets: [{
|
||||||
|
label: string,
|
||||||
|
data:string[],
|
||||||
|
}]
|
||||||
|
}
|
||||||
@@ -196,4 +196,9 @@ public class RepositorioContratos: RepositorioBase<RepositorioContratos> {
|
|||||||
.FirstOrDefault(x=>x.Id == idcontrato);
|
.FirstOrDefault(x=>x.Id == idcontrato);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HayContratosEnAño(int year) {
|
||||||
|
var con = Context;
|
||||||
|
return con.Contratos.Where(x=>x.Fechainicio.Year == year).Any();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using Entidades;
|
||||||
|
using Entidades.Informes;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Modelo;
|
||||||
|
public class RepositorioEstadisticas: RepositorioBase<RepositorioEstadisticas> {
|
||||||
|
public ChartData? ObtenerDataIniciadosPorAño(int year){
|
||||||
|
var con = Context;
|
||||||
|
var contratosPorMes = con.Contratos
|
||||||
|
.Where(c => c.Habilitado == 1 && c.Fechainicio.Year == year)
|
||||||
|
.GroupBy(c => c.Fechainicio.Month)
|
||||||
|
.Select(g => new { Mes = g.Key, Cantidad = g.Count() })
|
||||||
|
.OrderBy(x => x.Mes).ToList();
|
||||||
|
|
||||||
|
if (!contratosPorMes.Any()) return null;
|
||||||
|
|
||||||
|
var data = new ChartData();
|
||||||
|
data.Labels = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"];
|
||||||
|
|
||||||
|
List<string> ddd = new List<string>(["0","0","0","0","0","0","0","0","0","0","0","0"]);
|
||||||
|
foreach (var contrato in contratosPorMes) {
|
||||||
|
ddd[contrato.Mes-1] = contrato.Cantidad.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dataset dd = new();
|
||||||
|
dd.Data = ddd;
|
||||||
|
dd.Label = $"Alquileres por Mes del año {year}";
|
||||||
|
data.Datasets.Add(dd);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChartData? ObtenerDataDuracionContratos() {
|
||||||
|
var con = Context;
|
||||||
|
var meses = con.Contratos.Where(x=>x.Habilitado ==1)
|
||||||
|
.GroupBy(x=>x.MesesDurationContrato).Select(g=> new {Duracion = g.Key, Cantidad = g.Count()});
|
||||||
|
if(!meses.Any()) return null;
|
||||||
|
|
||||||
|
var data = new ChartData();
|
||||||
|
Dataset dd = new();
|
||||||
|
|
||||||
|
foreach (var mes in meses){
|
||||||
|
data.Labels.Add(mes.Duracion.ToString());
|
||||||
|
dd.Data.Add(mes.Cantidad.ToString());
|
||||||
|
}
|
||||||
|
dd.Label="Duracion Contratos";
|
||||||
|
data.Datasets.Add(dd);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQueryable<Contrato> TablaObtenerContratosIniciadosPorAño(int year) {
|
||||||
|
var con = Context;
|
||||||
|
var contratosPorMes = con.Contratos.Include(x=>x.IddivisaNavigation).Include(x=>x.IdpropiedadNavigation)
|
||||||
|
.Where(c => c.Habilitado == 1 && c.Fechainicio.Year == year);
|
||||||
|
return contratosPorMes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InformesMeses> TablaObtenerDataDuracionContratos() {
|
||||||
|
var con = Context;
|
||||||
|
var meses = con.Contratos.Where(x=>x.Habilitado ==1)
|
||||||
|
.GroupBy(x=>x.MesesDurationContrato).Select(g=> new {Duracion = g.Key, Cantidad = g.Count()});
|
||||||
|
|
||||||
|
List<InformesMeses> l = new();
|
||||||
|
foreach (var mes in meses){
|
||||||
|
l.Add(new InformesMeses{
|
||||||
|
Meses = mes.Duracion,
|
||||||
|
Repes = mes.Cantidad
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user