refactor: rewrite ke codebase lama
This commit is contained in:
+361
@@ -0,0 +1,361 @@
|
||||
const mahasiswaModel = require("../models/mahasiswa");
|
||||
const lowonganMagangModel = require("../models/lowonganMagang");
|
||||
const lamaranMagangModel = require("../models/lamaranMagang");
|
||||
const transporter = require("../config/mail");
|
||||
const ExcelJS = require('exceljs');
|
||||
require("dotenv").config();
|
||||
const path = require('path');
|
||||
const { deleteFileIfExists } = require('../config/fileHelper');
|
||||
|
||||
const addLamaranMagang = async (req, res) => {
|
||||
const { id_lowongan_magang } = req.params;
|
||||
const {
|
||||
nama_depan,
|
||||
nama_belakang,
|
||||
email,
|
||||
kontak,
|
||||
jurusan,
|
||||
motivasi,
|
||||
relevant_skills,
|
||||
} = req.body;
|
||||
|
||||
const CV = req.files.cv?.[0];
|
||||
const Portofolio = req.files.portofolio?.[0];
|
||||
const status = "diproses";
|
||||
const role = "student";
|
||||
|
||||
try {
|
||||
const cv_path = await uploadCV(CV);
|
||||
const portofolio_path = await uploadPortofolio(Portofolio);
|
||||
|
||||
const [lowonganMagang] = await lowonganMagangModel.getLowonganMagangById(
|
||||
id_lowongan_magang
|
||||
);
|
||||
|
||||
if (lowonganMagang.length === 0) {
|
||||
return res.status(404).json({
|
||||
message: "Internship vacancy not found.",
|
||||
});
|
||||
}
|
||||
|
||||
const namaBelakangFinal = nama_belakang?.trim() || null;
|
||||
|
||||
const dataMahasiswa = {
|
||||
nama_depan,
|
||||
nama_belakang: namaBelakangFinal,
|
||||
email,
|
||||
kontak,
|
||||
jurusan,
|
||||
role,
|
||||
cv_path,
|
||||
portofolio_path,
|
||||
motivasi,
|
||||
relevant_skills,
|
||||
};
|
||||
|
||||
const result = await mahasiswaModel.addMahasiswa(
|
||||
nama_depan,
|
||||
namaBelakangFinal,
|
||||
email,
|
||||
kontak,
|
||||
jurusan,
|
||||
role,
|
||||
cv_path,
|
||||
portofolio_path,
|
||||
motivasi,
|
||||
relevant_skills
|
||||
);
|
||||
|
||||
const id_mahasiswa = result[0].insertId;
|
||||
|
||||
await lamaranMagangModel.addlowonganMagang(
|
||||
id_mahasiswa,
|
||||
id_lowongan_magang,
|
||||
status
|
||||
);
|
||||
|
||||
await sendEmail(dataMahasiswa, lowonganMagang[0]);
|
||||
|
||||
res.status(200).json({
|
||||
message: "Internship application submitted successfully.",
|
||||
data: {
|
||||
id_lowongan_magang,
|
||||
dataMahasiswa,
|
||||
status,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error adding internship application:", error);
|
||||
res.status(500).json({
|
||||
message: "Internal server error.",
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const uploadCV = async (CV) => {
|
||||
try {
|
||||
if (!CV) {
|
||||
throw new Error("Please upload your CV.");
|
||||
}
|
||||
|
||||
const file = `/uploads/${CV.filename}`;
|
||||
return file;
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
throw new Error("Failed to upload CV.");
|
||||
}
|
||||
};
|
||||
|
||||
const uploadPortofolio = async (portofolio) => {
|
||||
try {
|
||||
if (!portofolio) {
|
||||
throw new Error("Please upload your portfolio.");
|
||||
}
|
||||
const file = `/uploads/${portofolio.filename}`;
|
||||
return file;
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
throw new Error("Failed to upload portfolio.");
|
||||
}
|
||||
};
|
||||
|
||||
const getAllLamaranMagang = async (req, res) => {
|
||||
try {
|
||||
const [result] = await lamaranMagangModel.getAllLamaranMagang();
|
||||
if (result.length === 0) {
|
||||
return res.status(404).json({
|
||||
message: "No internship applications found.",
|
||||
});
|
||||
}
|
||||
res.status(200).json({
|
||||
message: "Internship applications retrieved successfully.",
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error fetching all internship applications:", error);
|
||||
res.status(500).json({
|
||||
message: "Internal server error.",
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getLamaranByID = async (req, res) => {
|
||||
const { id_lamaran_magang } = req.params;
|
||||
try {
|
||||
const [result] = await lamaranMagangModel.getLamaranByID(
|
||||
id_lamaran_magang
|
||||
);
|
||||
if (result.length === 0) {
|
||||
return res.status(404).json({
|
||||
message: "No internship applications found.",
|
||||
});
|
||||
}
|
||||
res.status(200).json({
|
||||
message: "Internship applications retrieved successfully.",
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error fetching internship applications by ID:", error);
|
||||
res.status(500).json({
|
||||
message: "Internal server error.",
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const updateStatusLamaran = async (req, res) => {
|
||||
const { id_lamaran_magang } = req.params;
|
||||
const { status } = req.body;
|
||||
const role = req.role;
|
||||
|
||||
try {
|
||||
if (role !== "admin") {
|
||||
return res.status(403).json({
|
||||
message: "Unauthorized access.",
|
||||
});
|
||||
}
|
||||
|
||||
const [lamaran] = await lamaranMagangModel.getDetailLamaranById(
|
||||
id_lamaran_magang
|
||||
);
|
||||
// console.log(lamaran[0]);
|
||||
if (lamaran.length === 0) {
|
||||
return res.status(404).json({
|
||||
message: "Internship application not found.",
|
||||
});
|
||||
}
|
||||
|
||||
await lamaranMagangModel.updateStatusLamaran(id_lamaran_magang, status);
|
||||
res.status(200).json({
|
||||
message: "Internship application status successfully updated.",
|
||||
});
|
||||
|
||||
await sendStatusEmail(lamaran[0], status)
|
||||
} catch (error) {
|
||||
console.error("Error updating internship application status:", error);
|
||||
res.status(500).json({
|
||||
message: "Internal server error.",
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const sendEmail = async (dataMahasiswa, dataPekerjaan) => {
|
||||
try {
|
||||
const fullName = `${dataMahasiswa.nama_depan}${dataMahasiswa.nama_belakang ? ' ' + dataMahasiswa.nama_belakang : ''}`;
|
||||
|
||||
const mailOptions = {
|
||||
from: process.env.AUTH_EMAIL,
|
||||
to: dataMahasiswa.email,
|
||||
subject: "Konfirmasi Penerimaan Lamaran Anda",
|
||||
headers: {
|
||||
"X-Priority": "1",
|
||||
"X-MSMail-Priority": "High",
|
||||
Importance: "high",
|
||||
},
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 10px;">
|
||||
<h2 style="color: #333;">Lamaran Anda Telah Kami Terima</h2>
|
||||
<p>Halo ${fullName},</p>
|
||||
|
||||
<p>Terima kasih telah mengirimkan lamaran untuk posisi <strong>${dataPekerjaan.posisi}</strong> di <strong>Humic Engineering</strong>.</p>
|
||||
|
||||
<p>Kami telah menerima dokumen dan informasi yang Anda kirimkan, dan saat ini tim rekrutmen kami sedang meninjaunya dengan seksama.</p>
|
||||
|
||||
<p>Jika profil Anda sesuai dengan kebutuhan kami, tim kami akan menghubungi Anda untuk tahapan seleksi berikutnya. Proses ini dapat memakan waktu hingga beberapa minggu.</p>
|
||||
|
||||
<p>Kami sangat menghargai minat Anda untuk bergabung bersama tim kami.</p>
|
||||
|
||||
<p>Salam hangat,</p>
|
||||
<p><strong>Tim Rekrutmen Humic Engineering</strong></p>
|
||||
|
||||
<hr style="margin: 30px 0;">
|
||||
<p style="font-size: 12px; color: #888;">Email ini dikirim secara otomatis. Jika Anda memiliki pertanyaan lebih lanjut, silakan hubungi kami melalui email resmi yang tersedia di website kami.</p>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
await transporter.sendMail(mailOptions);
|
||||
} catch (error) {
|
||||
console.error("Error mengirim email lamaran magang:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const sendStatusEmail = async (dataLamaran, statusLamaran) => {
|
||||
try {
|
||||
const isAccepted = statusLamaran === "diterima";
|
||||
const fullName = `${dataLamaran.nama_depan}${dataLamaran.nama_belakang ? ' ' + dataLamaran.nama_belakang : ''}`;
|
||||
|
||||
const subject = isAccepted
|
||||
? "Selamat! Lamaran Anda Diterima"
|
||||
: "Pemberitahuan Status Lamaran Anda";
|
||||
|
||||
const messageContent = isAccepted
|
||||
? `
|
||||
<p>Halo ${fullName},</p>
|
||||
<p>Selamat! Lamaran Anda untuk posisi <strong>${dataLamaran.posisi}</strong> di <strong>Humic Engineering</strong> telah diterima.</p>
|
||||
<p>Tim kami sangat terkesan dengan profil dan kualifikasi Anda. Kami akan segera menghubungi Anda terkait tahapan selanjutnya.</p>
|
||||
<p>Terima kasih telah melamar dan kami menantikan kerja sama yang luar biasa bersama Anda.</p>
|
||||
`
|
||||
: `
|
||||
<p>Halo ${fullName},</p>
|
||||
<p>Terima kasih atas lamaran Anda untuk posisi <strong>${dataLamaran.posisi}</strong> di <strong>Humic Engineering</strong>.</p>
|
||||
<p>Setelah mempertimbangkan secara seksama, kami memutuskan untuk tidak melanjutkan proses lamaran Anda ke tahap berikutnya.</p>
|
||||
<p>Jangan berkecil hati—kami sangat menghargai waktu dan usaha Anda. Kami mendorong Anda untuk terus mencoba dan semoga sukses dalam perjalanan karier Anda.</p>
|
||||
`;
|
||||
|
||||
const mailOptions = {
|
||||
from: process.env.AUTH_EMAIL,
|
||||
to: dataLamaran.email,
|
||||
subject,
|
||||
headers: {
|
||||
"X-Priority": "1",
|
||||
"X-MSMail-Priority": "High",
|
||||
Importance: "high",
|
||||
},
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 10px;">
|
||||
${messageContent}
|
||||
<p>Salam hangat,</p>
|
||||
<p><strong>Tim Rekrutmen Humic Engineering</strong></p>
|
||||
<hr style="margin: 30px 0;">
|
||||
<p style="font-size: 12px; color: #888;">Email ini dikirim secara otomatis. Untuk informasi lebih lanjut, silakan hubungi kami melalui kontak resmi.</p>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
await transporter.sendMail(mailOptions);
|
||||
} catch (error) {
|
||||
console.error("Gagal mengirim email status lamaran:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const exportDataToExcel = async (req, res) => {
|
||||
try {
|
||||
const [rows] = await lamaranMagangModel.getAllExportData();
|
||||
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('Data');
|
||||
|
||||
// Add header
|
||||
const headers = Object.keys(rows[0]);
|
||||
worksheet.addRow(headers);
|
||||
|
||||
// Add rows
|
||||
rows.forEach(row => {
|
||||
worksheet.addRow(Object.values(row));
|
||||
});
|
||||
|
||||
// setting header buat file excel
|
||||
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=data.xlsx');
|
||||
|
||||
await workbook.xlsx.write(res);
|
||||
res.end();
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).send('Error generating Excel file');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const deleteAllLamaranMagang = async (req, res) => {
|
||||
try {
|
||||
// Ambil semua mahasiswa
|
||||
const [mahasiswaList] = await mahasiswaModel.getAllMahasiswa();
|
||||
|
||||
for (const mhs of mahasiswaList) {
|
||||
const files = [mhs.cv_path, mhs.portofolio_path];
|
||||
for (const filePath of files) {
|
||||
if (filePath) {
|
||||
const fileName = path.basename(filePath);
|
||||
await deleteFileIfExists(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hapus semua lamaran & mahasiswa
|
||||
await lamaranMagangModel.deleteAllLamaranMagang();
|
||||
await mahasiswaModel.deleteAllMahasiswa();
|
||||
|
||||
res.status(200).json({
|
||||
message: "All student data, applications, and files were successfully deleted.",
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Failed to delete all:", err);
|
||||
res.status(500).json({ message: "Failed to delete all data.", error: err.message });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
addLamaranMagang,
|
||||
getAllLamaranMagang,
|
||||
getLamaranByID,
|
||||
updateStatusLamaran,
|
||||
exportDataToExcel,
|
||||
deleteAllLamaranMagang
|
||||
};
|
||||
Reference in New Issue
Block a user