Course Specialization
Task 1: Create SpecializationController
import { SpecializationService } from './specialization.service';
import { Body, Controller, Delete, Get, HttpCode, Param, Post, Put, Query, Request, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from 'src/guard/jwt-auth.guard';
import { MSpecializationService } from './mspecialization.service';
@Controller('api/v1/specializations')
export class SpecializationController {
constructor(private specializationService: MSpecializationService) {
}
@Get()
@HttpCode(200)
async getSpecializationsList(@Query('orgId') orgId: string) {
return this.specializationService.getAllSpecializations(orgId);
}
@UseGuards(JwtAuthGuard)
@Post()
@HttpCode(200)
async addSpecialization(@Request() request, @Body() specialization: any) {
const orgId = request.user.orgId;
specialization.orgId = orgId;
return this.specializationService.addSpecialization(specialization);
}
@UseGuards(JwtAuthGuard)
@Put(':id/courses/:courseId')
@HttpCode(200)
async updateCourse(@Param("id") id: string, @Param("courseId") courseId: string) {
return this.specializationService.assignCourse(id, courseId);
}
@UseGuards(JwtAuthGuard)
@Delete(':id/courses/:courseId')
@HttpCode(200)
async removeCourse(@Param("id") id: string, @Param("courseId") courseId: string) {
return this.specializationService.removeCourse(id, courseId);
}
@Delete(':id')
@HttpCode(200)
async deleteSpecialization(@Param("id") id: string) {
return this.specializationService.deleteSpecialization(id);
}
@Get('users/:userId')
@HttpCode(200)
async getSpecializationsUserList(@Param('userId') userId: string, @Query('orgId') orgId: string) {
return this.specializationService.getUserSpecializations(orgId, userId);
}
@UseGuards(JwtAuthGuard)
@Get('publish')
@HttpCode(200)
async publish(@Request() request) {
const orgId = request.user.orgId;
return this.specializationService.publish(orgId);
}
@Get(':id')
@HttpCode(200)
async getSpecializationList(@Param('id') id: string, @Query('userId') userId: string) {
return this.specializationService.getSpecialization(id);
}
}
Task 2: Create SpecializationService
import { CourseService } from './../course/course.service';
import { Injectable } from "@nestjs/common";
import { SpecializationDAO } from "src/course/specialization.dao";
import { MUserCourseDAO } from "src/usercourse/musercourse.dao";
import { UserCourseDAO } from "src/usercourse/usercourse.dao";
import { MSpecializationDAO } from 'src/course/mspecialization.dao';
@Injectable()
export class SpecializationService {
constructor(
private specializationDAO: SpecializationDAO,
private userCourseDAO: UserCourseDAO,
private muserCourseDAO: MUserCourseDAO,
private courseService: CourseService
) { }
async getAllSpecializations(orgId: string) {
const specializations = await this.specializationDAO.findAllWithCourses(orgId);
return specializations;
}
async getUserSpecializations(orgId: string, userId: string) {
const specializations = await this.specializationDAO.findAll(orgId);
console.table(specializations);
let completionData = await this.specializationDAO.findCompletionReport(
userId
);
if (completionData) {
specializations.forEach((s) => {
let data = completionData.find((obj: any) => obj.id == s.id);
s.percentage = data != null ? data["percentage"] : 0;
});
}
return specializations;
}
async addSpecialization(specialization: any) {
const result = await this.specializationDAO.save(
specialization
);
return result;
}
async deleteSpecialization(id: any) {
const result = await this.specializationDAO.delete(
id
);
return result;
}
async assignCourse(id: any, specializationCourse: any) {
specializationCourse.specializationId = id;
const result = await this.specializationDAO.addCourse(
specializationCourse
);
return result;
}
async removeCourse(id: any, courseId: string) {
const result = await this.specializationDAO.removeCourse(id, courseId);
return result;
}
async getSpecialization(specializationId: number, userId: string) {
const specialization = await this.specializationDAO.findOne(
specializationId
);
let courses: any;
if (specialization) {
let specializationCourses = await this.specializationDAO.findCourses(specializationId);
const courseIds = specializationCourses.map(obj => obj.course_id);
console.log(courseIds);
courses = await this.courseService.getCoursesForIds(courseIds);
let totalTopicsCompleted = 0;
if (userId) {
let userCourses = await this.muserCourseDAO.findCoursePercentage(userId, courseIds)
console.log("UserCoursePercentage:", userCourses);
if (!courses) {
specialization.percentage = 0;
}
else {
courses.forEach((c: any) => {
let userCourse = userCourses.find(obj => obj.courseCode == c.code);
if (userCourse) {
c.noOfTopics = userCourse.noOfTopics;
c.noOfTopicsCompleted = userCourse.noOfTopicsCompleted;
totalTopicsCompleted += parseInt(c.noOfTopicsCompleted);
c.percentage = Math.round(100 * parseInt(c.noOfTopicsCompleted) / c.noOfTopics);
}
})
specialization.topicsCompleted = totalTopicsCompleted;
}
} else {
}
specialization.courses = courses ?? [];
}
return specialization;
}
async publish(orgId: string) {
const specializations = await this.specializationDAO.findAll(orgId);
const courses = await this.specializationDAO.findAllCourses(orgId);
specializations.forEach((s) => {
s.courses = courses.filter((obj: any) => obj.specialization_id == s.id);
let total = 0;
courses.forEach(obj => {
total += obj.no_of_topics;
});
s.total_topics = total;
});
return specializations;
}
async updateTopics() { }
async updateUserTopics() { }
}
Task 3: Create SpecializationDAO
import { Injectable, Logger } from "@nestjs/common";
import { Connection } from "typeorm";
@Injectable()
export class SpecializationDAO {
private readonly logger = new Logger(SpecializationDAO.name);
constructor(private connection: Connection) { }
baseQuery = 'select * from specializations';
baseQuery1 = 'select s.*, (select count(*) from specialization_courses where specialization_id = s.id) as no_of_courses from specializations s';
async save(specialization: any) {
const sql =
"insert into specializations ( name,category,org_id) values ( ?,?,?)";
const results = await this.connection.query(sql, [
specialization.name,
specialization.category,
specialization.orgId
]);
return results.insertId;
}
async addCourse(specializationCourse: any) {
const sql =
"insert into specialization_courses ( specialization_id, course_id, no_of_topics) values ( ?,?,?)";
const results = await this.connection.query(sql, [
specializationCourse.specializationId,
specializationCourse.course.code,
specializationCourse.course.noOfTopics
]);
return results.insertId;
}
async removeCourse(specializationId: any, courseId: string) {
const sql =
"delete from specialization_courses where specialization_id = ? and course_id = ?";
const results = await this.connection.query(sql, [specializationId, courseId]);
return results.affectedRows;
}
async delete(id: any) {
const sql =
"delete from specializations where id = ? ";
const results = await this.connection.query(sql, [
id
]);
return results.affectedRows;
}
async findAll(orgId: string) {
const sql =
this.baseQuery + " where org_id = ? order by display_order";
const results = await this.connection.query(sql, [orgId]);
return results;
}
async findAllWithCourses(orgId: string) {
const sql =
this.baseQuery1 + " where org_id =? order by display_order";
const results = await this.connection.query(sql, [orgId]);
return results;
}
async findOne(id: number) {
const sql =
this.baseQuery + " where id = ?";
const results = await this.connection.query(sql, [id]);
return results.length > 0 ? results[0] : null;
}
async findSpecializationCourseIds(id: number) {
const sql = "select course_id from specialization_courses where specialization_id = ?";
const results = await this.connection.query(sql, [id]);
return results.map(obj => obj.course_id);
}
async findAllCourses(orgId: string) {
const sql =
'select sc.*,ct.title as course_title,( select name from ct_categories where id = ct.category) as category,ct.no_of_topics from specializations s, ct_courses ct, specialization_courses sc where s.id = sc.specialization_id and s.org_id =? and ct.code = sc.course_id order by s.display_order, sc.display_order';
const results = await this.connection.query(sql, [orgId]);
return results;
}
async findCoursesCount(orgId: string) {
const sql =
'select specialization_id, count(*) as no_of_courses from specialization_courses where specialization_id in (select id from specializations where org_id = ?) group by specialization_id ';
const results = await this.connection.query(sql, [orgId]);
return results;
}
async findCourses1(specializationId: number) {
const sql =
'select sc.*,ct.title as course_title, ( select name from ct_categories where id = ct.category) as category,ct.no_of_topics from specializations s, ct_courses ct, specialization_courses sc where s.id = sc.specialization_id and ct.code = sc.course_id and sc.specialization_id = ? order by sc.display_order';
const results = await this.connection.query(sql, [specializationId]);
return results;
}
async findCourses(specializationId: number) {
const sql =
'select * from specializations s, specialization_courses sc where s.id = sc.specialization_id and sc.specialization_id = ? order by sc.display_order';
const results = await this.connection.query(sql, [specializationId]);
return results;
}
async findCompletionReport(userId: string) {
const sql = 'select s.id, get_specialization_percentage(?,s.id) as percentage from specializations s';
const results = await this.connection.query(sql, [userId]);
return results;
}
async findCompletionReportOne(id: number, userId: string) {
const sql = 'select s.id, get_specialization_percentage(?,s.id) as percentage from specializations s where id = ?';
const results = await this.connection.query(sql, [userId, id]);
return results.length > 0 ? results[0] : null;
}
async findCourseTopicsCompletionReport(id: number, userId: string) {
const sql = " SELECT ct.code AS course_id,ct.title AS course_title,ct.no_of_topics, IFNULL(uce.no_of_topics_completed,0) AS topics_completed, ( select name from ct_categories where id = ct.category) as category FROM ct_courses ct LEFT OUTER JOIN user_course_enrollment uce ON (ct.code = uce.course_id AND uce.user_id = ?) where ct.code in (select course_id from specialization_courses where specialization_id = ?) order by ct.display_order"
const results = await this.connection.query(sql, [userId, id]);
return results;
}
async mfindCourseTopicsCompletionReport(id: number, userId: string) {
const sql = " SELECT ct.code AS course_id,ct.title AS course_title,ct.no_of_topics, IFNULL(uce.no_of_topics_completed,0) AS topics_completed, ( select name from ct_categories where id = ct.category) as category FROM ct_courses ct LEFT OUTER JOIN user_course_enrollment uce ON (ct.code = uce.course_id AND uce.user_id = ?) where ct.code in (select course_id from specialization_courses where specialization_id = ?) order by ct.display_order"
const results = await this.connection.query(sql, [userId, id]);
return results;
}
async updateTopics() {
const sql = 'update specializations s set total_topics = IFNULL( SELECT SUM(no_of_topics) FROM ct_courses WHERE CODE IN ( SELECT course_id FROM specialization_courses WHERE specialization_id = s.id )),0)';
const results = await this.connection.query(sql);
return results;
}
async updateUserTopics() {
const sql = 'update specializations s set total_topics = ( SELECT SUM(no_of_topics) FROM ct_courses WHERE CODE IN ( SELECT course_id FROM specialization_courses WHERE specialization_id = s.id ))';
const results = await this.connection.query(sql);
return results;
}
}
Task 4: Create MSpecializationDAO
import { specializationDoc } from './../schema/specialization.schema';
import { Injectable, Logger } from "@nestjs/common";
import { InjectModel } from "@nestjs/mongoose";
import { Model } from "mongoose";
import { courseModuleDoc } from "src/schema/course-module.schema";
import {
courseTopicDoc,
CourseTopicSchema,
} from "src/schema/course-topic.schema";
import { Course, courseDoc } from "src/schema/course.schema";
import { Connection } from "typeorm";
@Injectable()
export class MSpecializationDAO {
private readonly logger = new Logger(MSpecializationDAO.name);
constructor(
private connection: Connection,
@InjectModel("Course") private Course: Model<courseDoc>,
@InjectModel("Specialization") private Specialization: Model<specializationDoc>,
) { }
async save(specializationDTO: any) {
const specialization = new this.Specialization(specializationDTO);
return specialization.save();
}
async findAll(orgId: string) {
let specializations: any = await this.Specialization.find({
orgId: orgId
}).exec();
return specializations;
}
async delete(id: string) {
const result = await this.Specialization.deleteOne({ _id: id }).exec();
return result.deletedCount;
}
async findOne(id: string) {
const result = await this.Specialization.findOne({ _id: id }).exec();
return result;
}
async findByName(name: string) {
const result = await this.Specialization.findOne({ name: name }).exec();
return result;
}
}