Skip to content
Snippets Groups Projects
Commit 85baa56f authored by Rinaldy Adin's avatar Rinaldy Adin
Browse files

Merge branch 'story/dashboard-tim-tesis' into 'development'

feat: dashboard tim tesis endpoint

See merge request !49
parents f65430b7 5d627fb2
2 merge requests!58final release,!49feat: dashboard tim tesis endpoint
import { Controller, Get, Query, Req, UseGuards } from "@nestjs/common";
import { DashboardService } from "./dashboard.service";
import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
import { RolesGuard } from "src/middlewares/roles.guard";
import {
ApiBearerAuth,
ApiCookieAuth,
ApiOkResponse,
ApiTags,
} from "@nestjs/swagger";
import { Request } from "express";
import { AuthDto } from "src/auth/auth.dto";
import { RoleEnum } from "src/entities/pengguna.entity";
import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
import { Roles } from "src/middlewares/roles.decorator";
import { AuthDto } from "src/auth/auth.dto";
import { Request } from "express";
import { RolesGuard } from "src/middlewares/roles.guard";
import {
DashboardDto,
GetDashboardDosbimQueryDto,
GetDashboardTimTesisReqQueryDto,
GetDashboardTimTesisRespDto,
JalurStatisticDto,
} from "./dashboard.dto";
import {
ApiBearerAuth,
ApiCookieAuth,
ApiOkResponse,
ApiTags,
} from "@nestjs/swagger";
import { DashboardService } from "./dashboard.service";
@ApiTags("Dashboard")
@ApiCookieAuth()
......@@ -47,4 +49,14 @@ export class DashboardController {
(request.user as AuthDto).id,
);
}
@UseGuards(CustomAuthGuard, RolesGuard)
@Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
@ApiOkResponse({ type: GetDashboardTimTesisRespDto })
@Get("/tim-tesis")
async getDashboardTimTesis(
@Query() query: GetDashboardTimTesisReqQueryDto,
): Promise<GetDashboardTimTesisRespDto> {
return this.dashboardService.getDashboardTimTesis(query);
}
}
......@@ -4,11 +4,11 @@ import {
OmitType,
PickType,
} from "@nestjs/swagger";
import { JalurEnum } from "../entities/pendaftaranTesis.entity";
import { Topik } from "src/entities/topik.entity";
import { Pengguna } from "src/entities/pengguna.entity";
import { IsOptional } from "class-validator";
import { IsNumberString, IsOptional, IsString } from "class-validator";
import { BimbinganStatus } from "src/entities/bimbingan.entity";
import { Pengguna } from "src/entities/pengguna.entity";
import { Topik } from "src/entities/topik.entity";
import { JalurEnum } from "../entities/pendaftaranTesis.entity";
class PickedTopikDashboard extends PickType(Topik, ["id", "judul"] as const) {}
class PickedMhsDashboard extends PickType(Pengguna, [
......@@ -52,3 +52,49 @@ export class GetDashboardDosbimQueryDto {
@IsOptional()
search: string;
}
export class GetDashboardTimTesisReqQueryDto {
@IsOptional()
@IsNumberString()
@ApiPropertyOptional({ description: "default: 1" })
page?: number;
@IsOptional()
@IsNumberString()
@ApiPropertyOptional({ description: "default: no limit" })
limit?: number;
@IsOptional()
@IsString()
@ApiPropertyOptional()
search?: string;
}
export enum DashboardTimTesisStatusEnum {
PENGAJUAN_TOPIK = "PENGAJUAN_TOPIK",
SEMINAR_1 = "SEMINAR_1",
SEMINAR_2 = "SEMINAR_2",
SIDANG = "SIDANG",
}
class GetDashboardTimTesisDataDto {
@ApiProperty()
nim_mahasiswa: string;
@ApiProperty()
nama_mahasiswa: string;
@ApiProperty({ isArray: true })
dosen_pembimbing: string[];
@ApiProperty({ isArray: true, enum: DashboardTimTesisStatusEnum })
status: DashboardTimTesisStatusEnum[];
}
export class GetDashboardTimTesisRespDto {
@ApiProperty()
maxPage: number;
@ApiProperty({ type: GetDashboardTimTesisDataDto })
data: GetDashboardTimTesisDataDto[];
}
import { BadRequestException, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Brackets, Repository } from "typeorm";
import { BimbinganService } from "src/bimbingan/bimbingan.service";
import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
import {
PendaftaranSidsem,
TipeSidsemEnum,
} from "src/entities/pendaftaranSidsem";
import { ArrayContains, Brackets, In, Like, Repository } from "typeorm";
import {
PendaftaranTesis,
RegStatus,
} from "../entities/pendaftaranTesis.entity";
import { Pengguna } from "../entities/pengguna.entity";
import { DashboardDto, JalurStatisticDto } from "./dashboard.dto";
import { BimbinganService } from "src/bimbingan/bimbingan.service";
import { Pengguna, RoleEnum } from "../entities/pengguna.entity";
import {
DashboardDto,
DashboardTimTesisStatusEnum,
GetDashboardTimTesisReqQueryDto,
GetDashboardTimTesisRespDto,
JalurStatisticDto,
} from "./dashboard.dto";
@Injectable()
export class DashboardService {
......@@ -16,6 +27,10 @@ export class DashboardService {
private pendaftaranTesisRepository: Repository<PendaftaranTesis>,
@InjectRepository(Pengguna)
private penggunaRepository: Repository<Pengguna>,
@InjectRepository(DosenBimbingan)
private dosenBimbinganRepository: Repository<DosenBimbingan>,
@InjectRepository(PendaftaranSidsem)
private pendaftaranSidsemRepository: Repository<PendaftaranSidsem>,
private bimbinganService: BimbinganService,
) {}
......@@ -113,4 +128,172 @@ export class DashboardService {
return statistics as JalurStatisticDto[];
}
async getDashboardTimTesis(
query: GetDashboardTimTesisReqQueryDto,
): Promise<GetDashboardTimTesisRespDto> {
const [foundMahasiswa, total] = await this.penggunaRepository.findAndCount({
select: {
id: true,
nama: true,
nim: true,
},
take: query.limit || undefined,
skip: (query.page - 1) * query.limit || undefined,
where: [
{
nim: Like(`%${query.search ?? ""}%`),
roles: ArrayContains([RoleEnum.S2_MAHASISWA]),
},
{
nama: Like(`%${query.search ?? ""}%`),
roles: ArrayContains([RoleEnum.S2_MAHASISWA]),
},
],
order: {
nim: "ASC",
},
});
const dosbimQuery = this.dosenBimbinganRepository.find({
select: {
pendaftaran: {
id: true,
mahasiswaId: true,
},
dosen: {
id: true,
nama: true,
},
},
relations: {
pendaftaran: true,
dosen: true,
},
where: {
pendaftaran: {
mahasiswaId: In(foundMahasiswa.map(({ id }) => id)),
},
},
});
const topicAcceptedQuery = this.pendaftaranTesisRepository.find({
select: {
id: true,
mahasiswaId: true,
},
where: {
status: RegStatus.APPROVED,
mahasiswaId: In(foundMahasiswa.map(({ id }) => id)),
},
});
const mhsSemProAcceptedQuery = this.pendaftaranSidsemRepository.find({
select: {
pendaftaranTesis: {
mahasiswaId: true,
},
},
relations: {
pendaftaranTesis: true,
},
where: {
tipe: TipeSidsemEnum.SEMINAR_1,
ditolak: false,
pendaftaranTesis: {
mahasiswaId: In(foundMahasiswa.map(({ id }) => id)),
},
},
});
const mhsSemTesAcceptedQuery = this.pendaftaranSidsemRepository.find({
select: {
pendaftaranTesis: {
mahasiswaId: true,
},
},
relations: {
pendaftaranTesis: true,
},
where: {
tipe: TipeSidsemEnum.SEMINAR_2,
ditolak: false,
pendaftaranTesis: {
mahasiswaId: In(foundMahasiswa.map(({ id }) => id)),
},
},
});
const mhsSidangAcceptedQuery = this.pendaftaranSidsemRepository.find({
select: {
pendaftaranTesis: {
mahasiswaId: true,
},
},
relations: {
pendaftaranTesis: true,
},
where: {
tipe: TipeSidsemEnum.SIDANG,
ditolak: false,
pendaftaranTesis: {
mahasiswaId: In(foundMahasiswa.map(({ id }) => id)),
},
},
});
const [
foundDosbim,
topicAccepted,
mhsSemProAccepted,
mhsSemTesAccepted,
mhsSidangAccepted,
] = await Promise.all([
dosbimQuery,
topicAcceptedQuery,
mhsSemProAcceptedQuery,
mhsSemTesAcceptedQuery,
mhsSidangAcceptedQuery,
]);
const mhsStatusMap: Record<string, DashboardTimTesisStatusEnum[]> = {};
const dosbimMap: Record<string, string[]> = {};
foundMahasiswa.forEach(({ id }) => {
mhsStatusMap[id] = [];
dosbimMap[id] = [];
});
foundDosbim.forEach(({ pendaftaran: { mahasiswaId }, dosen: { nama } }) => {
dosbimMap[mahasiswaId].push(nama);
});
topicAccepted.forEach(({ mahasiswaId }) => {
mhsStatusMap[mahasiswaId].push(
DashboardTimTesisStatusEnum.PENGAJUAN_TOPIK,
);
});
mhsSemProAccepted.forEach(({ pendaftaranTesis: { mahasiswaId } }) => {
mhsStatusMap[mahasiswaId].push(DashboardTimTesisStatusEnum.SEMINAR_1);
});
mhsSemTesAccepted.forEach(({ pendaftaranTesis: { mahasiswaId } }) => {
mhsStatusMap[mahasiswaId].push(DashboardTimTesisStatusEnum.SEMINAR_2);
});
mhsSidangAccepted.forEach(({ pendaftaranTesis: { mahasiswaId } }) => {
mhsStatusMap[mahasiswaId].push(DashboardTimTesisStatusEnum.SEMINAR_2);
});
return {
maxPage: !!query.limit ? Math.ceil(total / query.limit) : 1,
data: foundMahasiswa.map(({ nim, id, nama }) => ({
nim_mahasiswa: nim,
nama_mahasiswa: nama,
status: mhsStatusMap[id] ?? [],
dosen_pembimbing: dosbimMap[id] ?? [],
})),
};
}
}
import { ApiHideProperty, ApiProperty } from "@nestjs/swagger";
import {
Column,
Entity,
......@@ -6,7 +7,6 @@ import {
PrimaryGeneratedColumn,
} from "typeorm";
import { Pengguna } from "./pengguna.entity";
import { ApiHideProperty, ApiProperty } from "@nestjs/swagger";
@Entity()
export class Topik {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment