Skip to content

Commit

Permalink
Refactor and handle villages for given country queries
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjyhy committed Jan 6, 2025
1 parent 66c8864 commit 82cc14a
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 25 deletions.
16 changes: 16 additions & 0 deletions server/stats/helpers/addPhaseFilteringToQuery.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { SelectQueryBuilder } from 'typeorm';

import { getPhasePeriod, phaseWasSelected } from '.';
import type { Student } from '../../entities/student';
import type { User } from '../../entities/user';
import type { Village, VillagePhase } from '../../entities/village';

export const addPhaseFilteringToQuery = async <T extends User | Student>(query: SelectQueryBuilder<T>, phase: VillagePhase, village: Village) => {
if (phaseWasSelected(phase)) {
const phaseValue = phase as number;
const { debut, end } = await getPhasePeriod(village.id, phaseValue);
query.andWhere('student.createdAt >= :debut', { debut });
if (phaseValue != village?.activePhase) query.andWhere('student.createdAt <= :end', { end });
}
return query;
};
8 changes: 8 additions & 0 deletions server/stats/helpers/createChildrenCodesQuery.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Student } from '../../entities/student';
import { AppDataSource } from '../../utils/data-source';

const studentRepository = AppDataSource.getRepository(Student);
export const createChildrenCodesQuery = () => {
const query = studentRepository.createQueryBuilder('student').innerJoin('student.classroom', 'classroom').innerJoin('classroom.village', 'village');
return query;
};
11 changes: 11 additions & 0 deletions server/stats/helpers/createConnectedFamilyQuery.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Student } from '../../entities/student';
import { AppDataSource } from '../../utils/data-source';

const studentRepository = AppDataSource.getRepository(Student);
export const createConnectedFamilyQuery = () => {
const query = studentRepository
.createQueryBuilder('student')
.innerJoin('classroom', 'classroom', 'classroom.id = student.classroomId')
.andWhere('student.numLinkedAccount >= 1');
return query;
};
1 change: 0 additions & 1 deletion server/stats/helpers/createFamilyAccountQuery.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export const createFamilyAccountQuery = async (villageId: number, phase: number
.innerJoin('student', 'student', 'student.classroomId = classroom.id')
.where('user.type = 3')
.andWhere('classroom.villageId = :villageId', { villageId });

if (phaseWasSelected(phase)) {
const { debut, end } = await getPhasePeriod(villageId, phase as number);
query.andWhere('user.createdAt >= :debut', { debut });
Expand Down
3 changes: 3 additions & 0 deletions server/stats/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ export * from './createFamilyAccountQuery.helper';
export * from './generateEmptyFilterParams.helper';
export * from './getPhasePeriod.helper';
export * from './phaseWasSelected.helper';
export * from './createConnectedFamilyQuery.helper';
export * from './createChildrenCodesQuery.helper';
export * from './addPhaseFilteringToQuery.helper';
74 changes: 50 additions & 24 deletions server/stats/queryStatsByFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { Student } from '../entities/student';
import { User } from '../entities/user';
import { Village } from '../entities/village';
import { AppDataSource } from '../utils/data-source';
import { createFamilyAccountQuery, getPhasePeriod, phaseWasSelected } from './helpers';
import {
createFamilyAccountQuery,
getPhasePeriod,
phaseWasSelected,
createConnectedFamilyQuery,
addPhaseFilteringToQuery,
createChildrenCodesQuery,
} from './helpers';

const studentRepository = AppDataSource.getRepository(Student);
const villageRepository = AppDataSource.getRepository(Village);
Expand Down Expand Up @@ -36,20 +43,28 @@ export const getFamiliesWithoutAccount = async (condition?: string, conditionVal

export const getConnectedFamiliesCount = async (filterParams: StatsFilterParams) => {
const { villageId, classroomId, countryId, phase } = filterParams;
const query = studentRepository
.createQueryBuilder('student')
.innerJoin('classroom', 'classroom', 'classroom.id = student.classroomId')
.andWhere('student.numLinkedAccount >= 1');
let connectedFamiliesCount = 0;

if (classroomId) {
const query = createConnectedFamilyQuery();
query.andWhere('classroom.id = :classroomId', { classroomId });
}

if (countryId) {
query.andWhere('classroom.countryCode = :countryId', { countryId });
}
connectedFamiliesCount = await query.getCount();
} else if (countryId) {
const villages = await villageRepository
.createQueryBuilder('village')
.where('village.countryCodes LIKE :countryId', { countryId: `%${countryId}%` })
.getMany();
const countPromises = villages.map(async (vil) => {
let query = createConnectedFamilyQuery();
query.andWhere('classroom.villageId = :villageId', { villageId: vil.id });
if (phase) query = await addPhaseFilteringToQuery(query, phase, vil);
return query.getCount();
});

if (villageId) {
const results = await Promise.all(countPromises);
connectedFamiliesCount = results.reduce((total, count) => total + count, 0);
} else if (villageId) {
const query = createConnectedFamilyQuery();
query.andWhere('classroom.villageId = :villageId', { villageId });

if (phaseWasSelected(phase)) {
Expand All @@ -60,9 +75,10 @@ export const getConnectedFamiliesCount = async (filterParams: StatsFilterParams)
query.andWhere('student.createdAt <= :end', { end });
}
}
connectedFamiliesCount = await query.getCount();
}

return await query.getCount();
return connectedFamiliesCount;
};

export const getFloatingAccounts = async (filterParams: StatsFilterParams) => {
Expand Down Expand Up @@ -90,7 +106,8 @@ export const getFamilyAccountsCount = async (filterParams: StatsFilterParams) =>
.where('village.countryCodes LIKE :countryId', { countryId: `%${countryId}%` })
.getMany();
const countPromises = villages.map(async (vil) => {
const query = await createFamilyAccountQuery(vil.id, phase);
let query = await createFamilyAccountQuery(vil.id, phase);
if (phase) query = await addPhaseFilteringToQuery(query, phase, vil);
return query.getCount();
});

Expand All @@ -102,17 +119,26 @@ export const getFamilyAccountsCount = async (filterParams: StatsFilterParams) =>
};

export const getChildrenCodesCount = async (filterParams: StatsFilterParams, whereClause?: WhereClause) => {
const { villageId, phase } = filterParams;
const village = await villageRepository.findOne({ where: { id: villageId } });
const query = studentRepository.createQueryBuilder('student').innerJoin('student.classroom', 'classroom').innerJoin('classroom.village', 'village');
if (whereClause) query.where(whereClause.clause, whereClause.value);

if (phaseWasSelected(phase) && villageId) {
const phaseValue = phase as number;
const { debut, end } = await getPhasePeriod(villageId, phaseValue);
query.andWhere('student.createdAt >= :debut', { debut });
if (phaseValue != village?.activePhase) query.andWhere('student.createdAt <= :end', { end });
const { villageId, countryId, phase } = filterParams;
let childrenCodesCount = 0;
if (villageId) {
const query = createChildrenCodesQuery();
if (whereClause) query.where(whereClause.clause, whereClause.value);
childrenCodesCount = await query.getCount();
} else if (countryId) {
const villages = await villageRepository
.createQueryBuilder('village')
.where('village.countryCodes LIKE :countryId', { countryId: `%${countryId}%` })
.getMany();
const countPromises = villages.map(async (vil) => {
let query = createChildrenCodesQuery();
query.where('classroom.village = :villageId', { villageId: vil.id });
if (phase) query = await addPhaseFilteringToQuery(query, phase, vil);
return query.getCount();
});
const results = await Promise.all(countPromises);
childrenCodesCount = results.reduce((total, count) => total + count, 0);
}

return await query.getCount();
return childrenCodesCount;
};

0 comments on commit 82cc14a

Please sign in to comment.