From 548bb0cdb26569a69de49c7581552f32cc46e8e5 Mon Sep 17 00:00:00 2001
From: Nicolas
Date: Thu, 16 Apr 2026 16:01:45 -0400
Subject: [PATCH] estadisticas de osp expandida
---
.../src/features/training/training.service.ts | 139 ++++++++++-
.../estadisticas/socioproductiva/page.tsx | 12 +-
.../components/training-statistics.tsx | 233 +++++++++++++++++-
.../feactures/training/schemas/statistics.ts | 10 +-
4 files changed, 374 insertions(+), 20 deletions(-)
diff --git a/apps/api/src/features/training/training.service.ts b/apps/api/src/features/training/training.service.ts
index a568a51..84a79f7 100644
--- a/apps/api/src/features/training/training.service.ts
+++ b/apps/api/src/features/training/training.service.ts
@@ -105,13 +105,21 @@ export class TrainingService {
// Ejecutamos todas las consultas en paralelo con Promise.all para mayor velocidad
const [
totalOspsResult,
- totalProducersResult,
- totalProductsResult, // Nuevo: Calculado desde el JSON
+ // totalProducersResult,
+ totalProductsResult,
statusDistribution,
activityDistribution,
typeDistribution,
stateDistribution,
yearDistribution,
+ ecoSectorDistribution,
+ productiveSectorDistribution,
+ centralActivityDistribution,
+ mainActivityDistribution,
+ structureTypeDistribution,
+ isOpenSpaceDistribution,
+ hasTransportDistribution,
+ genderResult,
] = await Promise.all([
// 1. Total OSPs
this.drizzle
@@ -120,12 +128,12 @@ export class TrainingService {
.where(whereCondition),
// 2. Total Productores (Columna plana que mantuviste)
- this.drizzle
- .select({
- sum: sql`SUM(${trainingSurveys.womenCount} + ${trainingSurveys.menCount})`,
- })
- .from(trainingSurveys)
- .where(whereCondition),
+ // this.drizzle
+ // .select({
+ // sum: sql`SUM(${trainingSurveys.womenCount} + ${trainingSurveys.menCount})`,
+ // })
+ // .from(trainingSurveys)
+ // .where(whereCondition),
// 3. NUEVO: Total Productos (Contamos el largo del array JSON productList)
this.drizzle
@@ -145,7 +153,7 @@ export class TrainingService {
.where(whereCondition)
.groupBy(trainingSurveys.currentStatus),
- // 5. Distribución por Actividad
+ // 5. Distribución por Actividad (General)
this.drizzle
.select({
name: trainingSurveys.productiveActivity,
@@ -188,11 +196,90 @@ export class TrainingService {
.where(whereCondition)
.groupBy(trainingSurveys.companyConstitutionYear)
.orderBy(trainingSurveys.companyConstitutionYear),
+
+ // 9. Distribución por Sector Económico
+ this.drizzle
+ .select({
+ name: trainingSurveys.ecoSector,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.ecoSector),
+
+ // 10. Distribución por Sector Productivo
+ this.drizzle
+ .select({
+ name: trainingSurveys.productiveSector,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.productiveSector),
+
+ // 11. Distribución por Actividad Central Productiva
+ this.drizzle
+ .select({
+ name: trainingSurveys.centralProductiveActivity,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.centralProductiveActivity),
+
+ // 12. Distribución por Actividad Productiva Principal
+ this.drizzle
+ .select({
+ name: trainingSurveys.mainProductiveActivity,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.mainProductiveActivity),
+
+ // 13. Distribución por Tipo de Estructura
+ this.drizzle
+ .select({
+ name: trainingSurveys.structureType,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.structureType),
+
+ // 14. Distribución por Espacio Abierto
+ this.drizzle
+ .select({
+ name: sql`case when ${trainingSurveys.isOpenSpace} then 'Sí' else 'No' end`,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.isOpenSpace),
+
+ // 15. Distribución por Transporte
+ this.drizzle
+ .select({
+ name: sql`case when ${trainingSurveys.hasTransport} then 'Sí' else 'No' end`,
+ value: sql`count(*)`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition)
+ .groupBy(trainingSurveys.hasTransport),
+
+ // 16. Distribución por Género
+ this.drizzle
+ .select({
+ women: sql`sum(${trainingSurveys.womenCount})`,
+ men: sql`sum(${trainingSurveys.menCount})`,
+ })
+ .from(trainingSurveys)
+ .where(whereCondition),
]);
return {
totalOsps: Number(totalOspsResult[0]?.count || 0),
- totalProducers: Number(totalProducersResult[0]?.sum || 0),
+ // totalProducers: Number(totalProducersResult[0]?.sum || 0),
totalProducts: Number(totalProductsResult[0]?.sum || 0), // Dato extraído del JSON
statusDistribution: statusDistribution.map((item) => ({
@@ -215,6 +302,38 @@ export class TrainingService {
...item,
value: Number(item.value),
})),
+ ecoSectorDistribution: ecoSectorDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ productiveSectorDistribution: productiveSectorDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ centralActivityDistribution: centralActivityDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ mainActivityDistribution: mainActivityDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ structureTypeDistribution: structureTypeDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ isOpenSpaceDistribution: isOpenSpaceDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ hasTransportDistribution: hasTransportDistribution.map((item) => ({
+ ...item,
+ value: Number(item.value),
+ })),
+ genderDistribution: [
+ { name: 'Mujeres', value: Number(genderResult[0]?.women || 0) },
+ { name: 'Hombres', value: Number(genderResult[0]?.men || 0) },
+ ],
};
}
diff --git a/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx b/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx
index 4cbc28c..6d949f5 100644
--- a/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx
+++ b/apps/web/app/dashboard/estadisticas/socioproductiva/page.tsx
@@ -9,11 +9,11 @@ export const metadata: Metadata = {
export default function SocioproductivaStatisticsPage() {
return (
-
-
-
Estadísticas Socioproductivas
-
-
-
+ //
+
+
Estadísticas Socioproductivas
+
+
+ //
);
}
diff --git a/apps/web/feactures/training/components/training-statistics.tsx b/apps/web/feactures/training/components/training-statistics.tsx
index e2cd34c..9317efe 100644
--- a/apps/web/feactures/training/components/training-statistics.tsx
+++ b/apps/web/feactures/training/components/training-statistics.tsx
@@ -103,12 +103,20 @@ export function TrainingStatistics() {
const {
totalOsps,
- totalProducers,
+ // totalProducers,
statusDistribution,
activityDistribution,
typeDistribution,
stateDistribution,
yearDistribution,
+ ecoSectorDistribution,
+ productiveSectorDistribution,
+ centralActivityDistribution,
+ mainActivityDistribution,
+ structureTypeDistribution,
+ isOpenSpaceDistribution,
+ hasTransportDistribution,
+ genderDistribution,
} = data;
const COLORS = [
@@ -230,7 +238,8 @@ export function TrainingStatistics() {
-
+
+ {/*
Total de Productores
@@ -242,7 +251,8 @@ export function TrainingStatistics() {
Productores asociados
-
+ */}
+
@@ -367,6 +377,223 @@ export function TrainingStatistics() {
+
+ {/* ECO SECTOR DISTRIBUTION */}
+
+
+ Sector Económico
+
+ Distribución por sector económico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* PRODUCTIVE SECTOR DISTRIBUTION */}
+
+
+ Sector Productivo
+
+ Distribución por sector productivo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* CENTRAL PRODUCTIVE ACTIVITY DISTRIBUTION */}
+
+
+ Actividad Central Productiva
+
+ Distribución por actividad central productiva
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* MAIN PRODUCTIVE ACTIVITY DISTRIBUTION */}
+
+
+ Actividad Productiva Principal
+
+ Distribución por actividad productiva principal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* STRUCTURE TYPE DISTRIBUTION */}
+
+
+ Tipo de Estructura
+ Distribución física
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* GENDER DISTRIBUTION */}
+
+
+ Distribución de Género
+ Conteo total por género
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* OPEN SPACE AND TRANSPORT (PIE CHARTS) */}
+
+
+
+ Espacio Abierto
+ ¿Poseen áreas libres?
+
+
+
+
+
+ {isOpenSpaceDistribution.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+
+
+
+
+
+ Transporte
+ ¿Tienen vehículo propio?
+
+
+
+
+
+ {hasTransportDistribution.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+
+
+
);
diff --git a/apps/web/feactures/training/schemas/statistics.ts b/apps/web/feactures/training/schemas/statistics.ts
index 3edf814..7eeb775 100644
--- a/apps/web/feactures/training/schemas/statistics.ts
+++ b/apps/web/feactures/training/schemas/statistics.ts
@@ -10,13 +10,21 @@ export const statisticsItemSchema = z.object({
export const trainingStatisticsSchema = z.object({
totalOsps: z.number(),
- totalProducers: z.number(),
+ // totalProducers: z.number(),
totalProducts: z.number(),
statusDistribution: z.array(statisticsItemSchema),
activityDistribution: z.array(statisticsItemSchema),
typeDistribution: z.array(statisticsItemSchema),
stateDistribution: z.array(statisticsItemSchema),
yearDistribution: z.array(statisticsItemSchema),
+ ecoSectorDistribution: z.array(statisticsItemSchema),
+ productiveSectorDistribution: z.array(statisticsItemSchema),
+ centralActivityDistribution: z.array(statisticsItemSchema),
+ mainActivityDistribution: z.array(statisticsItemSchema),
+ structureTypeDistribution: z.array(statisticsItemSchema),
+ isOpenSpaceDistribution: z.array(statisticsItemSchema),
+ hasTransportDistribution: z.array(statisticsItemSchema),
+ genderDistribution: z.array(statisticsItemSchema),
});
export type TrainingStatisticsData = z.infer;