feat: implement certificate repository and service layer for claiming and generating internship certificates

This commit is contained in:
Kemas M. Aryadary Rasyad
2026-07-28 14:36:17 +07:00
parent e005fe32ab
commit 1ef478d7f8
2 changed files with 27 additions and 7 deletions
@@ -107,6 +107,24 @@ class CertificateRepository {
}); });
} }
async maxSequenceByProject(id_project) {
const certificates = await prisma.certificate.findMany({
// Menyebabkan collision certificate pada setiap projek, jadinya generate sertifikat sementara bersifat global [Kemas]
// where: { id_project: parseInt(id_project) },
select: { certificate_no: true },
});
if (certificates.length === 0) return 0;
const sequences = certificates.map((c) => {
const parts = c.certificate_no.split('/');
const last = parseInt(parts[parts.length - 1]);
return isNaN(last) ? 0 : last;
});
return Math.max(...sequences);
}
async updateProjectTemplate(id_project, templatePath) { async updateProjectTemplate(id_project, templatePath) {
return prisma.project.update({ return prisma.project.update({
where: { id: parseInt(id_project) }, where: { id: parseInt(id_project) },
@@ -57,15 +57,16 @@ class CertificateService {
); );
} }
// Generate certificate number berdsarkan format ini: CERT/YYYYMMDD/{count} [Rafi 12/07/2026 14:32] // Generate certificate number berdsarkan format ini: No.{year}/SPI3/CERT/{dateString}/{count} [Rafi 12/07/2026 14:32]
const now = new Date(); const now = new Date();
const year = String(now.getFullYear()).slice(-2); const fullYear = now.getFullYear();
const year = String(fullYear).slice(-2);
const day = String(now.getDate()).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0');
const month = String(now.getMonth() + 1).padStart(2, '0'); const month = String(now.getMonth() + 1).padStart(2, '0');
const dateString = `${year}${day}${month}`; const dateString = `${year}${day}${month}`;
const count = await certificateRepository.countByProject(id_project); const count = await certificateRepository.maxSequenceByProject(id_project);
const certificateNo = `CERT/${dateString}/${count + 1}`; const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${count + 1}`;
const certificateData = { const certificateData = {
id_project: parseInt(id_project), id_project: parseInt(id_project),
@@ -151,16 +152,17 @@ class CertificateService {
const generatedCertificates = []; const generatedCertificates = [];
const now = new Date(); const now = new Date();
const year = String(now.getFullYear()).slice(-2); const fullYear = now.getFullYear();
const year = String(fullYear).slice(-2);
const day = String(now.getDate()).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0');
const month = String(now.getMonth() + 1).padStart(2, '0'); const month = String(now.getMonth() + 1).padStart(2, '0');
const dateString = `${year}${day}${month}`; const dateString = `${year}${day}${month}`;
let currentCount = await certificateRepository.countByProject(id_project); let currentCount = await certificateRepository.maxSequenceByProject(id_project);
for (const userId of validatedUsers) { for (const userId of validatedUsers) {
currentCount++; currentCount++;
const certificateNo = `CERT/${dateString}/${currentCount}`; const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${currentCount}`;
const certificateData = { const certificateData = {
id_project: parseInt(id_project), id_project: parseInt(id_project),
id_user: parseInt(userId), id_user: parseInt(userId),