Generate Students
unknown
javascript
4 years ago
16 kB
22
Indexable
import { Request, Response } from 'lambda-api';
import { ClientBase } from 'pg';
// import { Endpoint } from 'aws-sdk';
import { failure, success } from '../../../shared/libs/response';
import { getAuth, setAuth } from '../../../shared/libs/auth';
import code from '../../../shared/libs/code';
import { AuthModel } from '../../../shared/models/auth.model';
import lambda from '../../../shared/libs/lambda';
import config from '../../../shared/libs/config';
import { ApiModel } from '../../../shared/models/api.model';
async function queryGetPeriodsByAcademicYear(
db: ClientBase,
auth: AuthModel,
academicYear: string
): Promise<any> {
try {
const queryResult = await db.query(
`
SELECT DISTINCT period.period_id,
period.period_name
FROM period
JOIN academic_calendar
ON academic_calendar.period_id = period.period_id
AND academic_calendar.deleted_at IS NULL
AND academic_calendar.tenant_uuid = $1
WHERE period.deleted_at IS NULL
AND period.tenant_uuid = $1
AND academic_calendar.academic_year = $2
ORDER BY period.period_id
`,
[auth.tenant_uuid, academicYear]
);
if (queryResult.rowCount === 0) {
return null;
}
return queryResult.rows;
} catch (e) {
console.error('[ERROR-QUERY] - func: queryGetPeriodsByAcademicYear', e);
throw Error(code.database_error);
}
}
async function queryGetYearLevelsBySchoolLevel(
db: ClientBase,
auth: AuthModel,
params: {
school_level_id: number;
school_location_id: number;
}
): Promise<any> {
try {
const queryResult = await db.query(
`
SELECT DISTINCT school_level_relation.year_level_id,
year_level.year_level_name,
school_level_relation.order_number
FROM year_level
JOIN school_level_relation
ON school_level_relation.year_level_id = year_level.year_level_id
AND school_level_relation.deleted_at IS NULL
AND school_level_relation.tenant_uuid = $1
WHERE year_level.deleted_at IS NULL
AND year_level.tenant_uuid = $1
AND school_level_relation.school_level_id = $2
AND school_level_relation.school_location_id = $3
ORDER BY school_level_relation.order_number
`,
[auth.tenant_uuid, params.school_level_id, params.school_location_id]
);
if (queryResult.rowCount === 0) {
return null;
}
return queryResult.rows;
} catch (e) {
console.error('[ERROR-QUERY] - func: queryGetYearLevelsBySchoolLevel', e);
throw Error(code.database_error);
}
}
async function queryGetClassMembers(db: ClientBase, auth: AuthModel, params: any): Promise<any> {
try {
let filterQueryIndex = 1;
const filteredColumns = {
academic_year: 'academic_calendar.academic_year',
period_id: 'academic_calendar.period_id',
school_level_id: 'school_level_relation.school_level_id',
school_location_id: 'school_level_relation.school_location_id',
year_level_id: 'school_level_relation.year_level_id',
};
const queryStrings = [];
const queryValues = [];
for (const key in filteredColumns) {
if (Object.prototype.hasOwnProperty.call(filteredColumns, key)) {
const value = filteredColumns[key];
if (!params[key] || params[key] === 'null' || params[key] === 'undefined') {
continue;
}
queryStrings.push(`AND ${value} = $${++filterQueryIndex}`);
queryValues.push(params[key] || null);
}
}
const queryResult = await db.query(
`
SELECT DISTINCT class_member.student_id,
class.class_name,
academic_calendar.academic_start_date,
academic_calendar.academic_end_date
FROM class_member
JOIN class
ON class.class_id = class_member.class_id
AND class.deleted_at IS NULL
AND class.tenant_uuid = $1
JOIN academic_calendar
ON academic_calendar.academic_calendar_id = class.academic_calendar_id
AND academic_calendar.deleted_at IS NULL
AND academic_calendar.tenant_uuid = $1
JOIN school_level_relation
ON school_level_relation.school_level_relation_id = academic_calendar.school_level_relation_id
AND school_level_relation.deleted_at IS NULL
AND school_level_relation.tenant_uuid = $1
WHERE class_member.deleted_at IS NULL
AND class_member.tenant_uuid = $1
${queryStrings.join(' ')}
ORDER BY class_member.student_id ASC
`,
[auth.tenant_uuid, ...queryValues]
);
if (queryResult.rowCount === 0) {
return null;
}
return queryResult.rows;
} catch (e) {
console.error('[ERROR-QUERY] - func: queryGetClassMembers', e);
throw Error(code.database_error);
}
}
async function getDetailStudents(req: Request, studentIds: Array<number>): Promise<any> {
let students = [];
try {
// lambda.endpoint = new Endpoint('http://localhost:3012');
const result = await lambda
.invoke({
FunctionName: `student-service-${config.stage}-api-v1`,
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: JSON.stringify({
...setAuth(req),
httpMethod: 'POST',
path: '/student/api/v1/student-by-student-ids',
body: {
student_ids: studentIds,
},
}),
})
.promise();
const payload = JSON.parse(result.Payload as string);
const body: ApiModel<any> = JSON.parse(payload.body);
if (body.status) {
students = body.data;
} else {
console.error(body.message);
throw Error(body.message);
}
} catch (e) {
console.error('[ERROR-INVOKE] - func: getDetailStudents', e);
throw Error(e);
}
return students;
}
async function getReligions(req: Request): Promise<any> {
let religions = [];
try {
// lambda.endpoint = new Endpoint('http://localhost:3014');
const result = await lambda
.invoke({
FunctionName: `general-service-${config.stage}-api-v1`,
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: JSON.stringify({
...setAuth(req),
httpMethod: 'GET',
path: '/general/v1/religion-list',
}),
})
.promise();
const payload = JSON.parse(result.Payload as string);
const body: ApiModel<any> = JSON.parse(payload.body);
if (body.status) {
religions = body.data;
} else {
console.error(body.message);
throw Error(body.message);
}
} catch (e) {
console.error(e);
throw e;
}
return religions;
}
async function getStudentsByJoinDate(req: Request, params: any): Promise<any> {
let students = [];
try {
// lambda.endpoint = new Endpoint('http://localhost:3012');
const result = await lambda
.invoke({
FunctionName: `student-service-${config.stage}-api-v1`,
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: JSON.stringify({
...setAuth(req),
httpMethod: 'GET',
path: '/student/api/v1/students/join-date',
queryStringParameters: {
year: params.year,
school_level_id: params.school_level_id,
school_location_id: params.school_location_id,
year_level_id: params.year_level_id,
}
}),
})
.promise();
const payload = JSON.parse(result.Payload as string);
const body: ApiModel<any> = JSON.parse(payload.body);
if (body.status) {
students = body.data;
} else {
console.error(body.message);
throw Error(body.message);
}
} catch (e) {
console.error('[ERROR-INVOKE] - func: getStudentsByJoinDate', e);
throw Error(e);
}
return students;
}
export default async function classGenerateStudents(req: Request, res: Response): Promise<any> {
try {
const auth = getAuth(req);
const params = req.body;
if (
!params.academic_year ||
!params.periods ||
!params.school_level_id ||
!params.school_location_id ||
!params.year_level_id
) {
throw Error(code.input_invalid);
}
const periods = params.periods;
const previousSchoolLocationsIds = params.previous_school_location_ids;
const otherSchoolLocationIds = params.other_school_location_ids;
let schoolLocationIds = [+params.school_location_id];
if (otherSchoolLocationIds) {
schoolLocationIds = schoolLocationIds.concat(otherSchoolLocationIds);
}
if (previousSchoolLocationsIds) {
schoolLocationIds = schoolLocationIds.concat(previousSchoolLocationsIds);
}
const isFirstYearLevel = params.is_first_year_level;
const isEdit = params.is_edit;
const classMembers = [];
// [START] logic class members from previous class
const masterPeriods = await queryGetPeriodsByAcademicYear(req.namespace.db, auth, params.academic_year);
if (!masterPeriods) {
throw Error(code.data_not_found);
}
// Masih Hardcode
const oddPeriod = masterPeriods[0];
const evenPeriod = masterPeriods[1];
const yearLevelsParams = {
school_level_id: +params.school_level_id,
school_location_id: +params.school_location_id,
};
// check year level
const yearLevels = await queryGetYearLevelsBySchoolLevel(req.namespace.db, auth, yearLevelsParams);
if (!yearLevels) {
throw Error(code.data_not_found);
}
const currentYearLevel = yearLevels.find((i) => +i.year_level_id === +params.year_level_id);
if (!currentYearLevel) {
throw Error(code.data_not_found);
}
for (const period of periods) {
// odd period
if (+period === +oddPeriod.period_id) {
if (isFirstYearLevel) {
/**
* TODO
*/
}
// const currentAcademicYear = params.academic_year;
// const previousAcademicYear = currentAcademicYear
// .split('-')
// .map((i) => +(i - 1))
// .join('-');
// get previous year_level
// const currentYearLevelIndex = yearLevels.findIndex((i) => +i.year_level_id === +currentYearLevel.year_level_id);
// const previousYearLevel = yearLevels[currentYearLevelIndex - 1];
//
// const previousAcademicDataParams = {
// academic_year: previousAcademicYear,
// period_id: +period,
// school_level_id: +params.school_level_id,
// school_location_id: null,
// year_level_id: previousYearLevel,
// };
/**
* TODO
* previous class members (graduate status === PASSED)
*/
}
// even period
if (+period === +evenPeriod.period_id) {
/**
* TODO
* previous class members (graduate status === PASSED)
*/
// unallocated class members from odd period
for (const schoolLocationId of schoolLocationIds) {
const unallocatedClassMemberParams = {
academic_year: params.academic_year,
period_id: +oddPeriod.period_id,
school_level_id: +params.school_level_id,
school_location_id: +schoolLocationId,
year_level_id: +params.year_level_id,
}
const unallocatedClassMembers = await queryGetClassMembers(req.namespace.db, auth, unallocatedClassMemberParams);
if (unallocatedClassMembers) {
for (const classMember of unallocatedClassMembers) {
classMembers.push(classMember);
}
}
}
}
}
// new students
for (const schoolLocationId of schoolLocationIds) {
const newStudentsParams = {
year: params.academic_year.slice(0, 4),
school_level_id: +params.school_level_id,
school_location_id: +schoolLocationId,
year_level_id: +params.year_level_id,
}
const newStudents = await getStudentsByJoinDate(req, newStudentsParams);
if (newStudents) {
for (const student of newStudents) {
classMembers.push(student);
}
}
}
const masterClassMembers = [];
// get allocated class members
for (const period of periods) {
for (const schoolLocationId of schoolLocationIds) {
const allocatedClassMemberParams = {
academic_year: params.academic_year,
period_id: +period,
school_level_id: +params.school_level_id,
school_location_id: +schoolLocationId,
year_level_id: +params.year_level_id,
}
const allocatedClassMembers = await queryGetClassMembers(req.namespace.db, auth, allocatedClassMemberParams);
if (allocatedClassMembers) {
for (const classMember of allocatedClassMembers) {
masterClassMembers.push(classMember);
}
}
}
}
// check allocated class members with unallocated class members
for (const masterClassMember of masterClassMembers) {
const index = classMembers.findIndex(i => +i.student_id === +masterClassMember.student_id);
if (index > -1) {
classMembers.splice(index, 1);
}
}
// get students detail and religions
if (classMembers.length > 0) {
// get students detail
const studentsDetail = await getDetailStudents(req, classMembers.map((i) => +i.student_id));
if (!studentsDetail) {
throw Error(code.data_not_found);
}
// get religions
const religions = await getReligions(req);
if (!religions) {
throw Error(code.data_not_found);
}
for (const classMember of classMembers) {
const index = studentsDetail.findIndex((i) => +i.student_id === +classMember.student_id);
if (index < 0) {
continue;
}
classMember.student_name = studentsDetail[index].student_name;
classMember.nis = studentsDetail[index].nis;
classMember.religion_id = +studentsDetail[index].religion_id;
}
for (const classMember of classMembers) {
const index = religions.findIndex((i) => +i.religion_id === +classMember.religion_id);
if (index < 0) {
continue;
}
classMember.religion_name = religions[index].religion_name;
}
}
if (!isEdit) {
// rules
const rules = {
religion_checked: params.rules_religion_checked,
max_religions: params.rules_max_religions,
gender_checked: params.rules_gender_checked,
sibling_checked: params.rules_sibling_checked,
}
if (rules.religion_checked) {
/**
* TODO
* generate students by max students have the same religion in the same class
*/
}
if (rules.gender_checked) {
/**
* TODO
* generate students equally by gender
*/
}
if (rules.sibling_checked) {
/**
* TODO
* student siblings can not be in the same class
*/
}
}
success(res, {
status: true,
version: req.version,
message: 'success',
data: classMembers,
meta: null,
});
} catch (e) {
failure(res, e);
}
}
Editor is loading...