Compare commits

...

2 Commits

Author SHA1 Message Date
sulthan 1450aa9833 fix lamaran magang services and controller 2026-09-18 17:45:08 +07:00
sulthan 684b93ad88 add whatsapp group to the email helper 2026-09-16 12:39:40 +07:00
3 changed files with 92 additions and 91 deletions
@@ -69,7 +69,10 @@ class LamaranMagangController {
async getAllLamaranMagang(req, res) { async getAllLamaranMagang(req, res) {
try { try {
const validatePayload = isValidPayload(req.query, getAllLamaranMagangModel); const validatePayload = isValidPayload(
req.query,
getAllLamaranMagangModel
);
if (validatePayload.err) { if (validatePayload.err) {
return response( return response(
@@ -83,15 +86,29 @@ class LamaranMagangController {
const query = validatePayload.data; const query = validatePayload.data;
const result = await lamaranMagangService.getAllLamaranMagang(query); const result =
await lamaranMagangService.getAllLamaranMagang(query);
if (result.err) { if (result.err) {
return response(res, 'fail', result); return response(res, 'fail', result);
} }
return paginationResponse(res, 'success', result, 'Lamaran magang berhasil diambil', SUCCESS.OK); return response(
res,
'success',
result,
'Lamaran magang berhasil diambil',
SUCCESS.OK
);
} catch (err) { } catch (err) {
return response(res, 'fail', error(new InternalServerError(err.message)), 'Terjadi kesalahan yang tidak terduga', ERROR.INTERNAL_ERROR); return response(
res,
'fail',
error(new InternalServerError(err.message)),
'Terjadi kesalahan yang tidak terduga',
ERROR.INTERNAL_ERROR
);
} }
} }
@@ -1,21 +1,21 @@
const transporter = require('../../../helpers/utils/mail'); const transporter = require('../../../helpers/utils/mail');
const sendConfirmationEmail = async (mahasiswa, lowongan) => { const sendConfirmationEmail = async (mahasiswa, lowongan) => {
try { try {
const { nama_depan, nama_belakang, email } = mahasiswa; const { nama_depan, nama_belakang, email } = mahasiswa;
const { posisi } = lowongan; const { posisi } = lowongan;
const fullName = `${nama_depan}${nama_belakang ? ' ' + nama_belakang : ''}`; const fullName = `${nama_depan}${nama_belakang ? ' ' + nama_belakang : ''}`;
const mailOptions = { const mailOptions = {
from: process.env.MAIL_USER, from: process.env.MAIL_USER,
to: email, to: email,
subject: 'Konfirmasi Penerimaan Lamaran Anda', subject: 'Konfirmasi Penerimaan Lamaran Anda',
headers: { headers: {
'X-Priority': '1', 'X-Priority': '1',
'X-MSMail-Priority': 'High', 'X-MSMail-Priority': 'High',
Importance: 'high', Importance: 'high',
}, },
html: ` html: `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 10px;"> <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> <h2 style="color: #333;">Lamaran Anda Telah Kami Terima</h2>
<p>Halo ${fullName},</p> <p>Halo ${fullName},</p>
@@ -35,29 +35,29 @@ const sendConfirmationEmail = async (mahasiswa, lowongan) => {
<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> <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> </div>
`, `,
}; };
await transporter.sendMail(mailOptions); await transporter.sendMail(mailOptions);
} catch (error) { } catch (error) {
console.error('Error sending confirmation email:', error); console.error('Error sending confirmation email:', error);
} }
}; };
const sendStatusEmail = async (lamaran, status, generatedPassword = null) => { const sendStatusEmail = async (lamaran, status, generatedPassword = null) => {
try { try {
const { mahasiswa, lowongan_magang } = lamaran; const { mahasiswa, lowongan_magang } = lamaran;
const { nama_depan, nama_belakang, email } = mahasiswa; const { nama_depan, nama_belakang, email } = mahasiswa;
const { posisi } = lowongan_magang; const { posisi } = lowongan_magang;
const isAccepted = status === 'diterima'; const isAccepted = status === 'diterima';
const fullName = `${nama_depan}${nama_belakang ? ' ' + nama_belakang : ''}`; const fullName = `${nama_depan}${nama_belakang ? ' ' + nama_belakang : ''}`;
const subject = isAccepted const subject = isAccepted
? 'Selamat! Lamaran Anda Diterima' ? 'Selamat! Lamaran Anda Diterima'
: 'Pemberitahuan Status Lamaran Anda'; : 'Pemberitahuan Status Lamaran Anda';
const message = isAccepted const message = isAccepted
? ` ? `
<p>Halo ${fullName},</p> <p>Halo ${fullName},</p>
<p>Selamat! Lamaran Anda untuk posisi <strong>${posisi}</strong> di <strong>Humic Engineering</strong> telah diterima.</p> <p>Selamat! Lamaran Anda untuk posisi <strong>${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>Tim kami sangat terkesan dengan profil dan kualifikasi Anda. Kami akan segera menghubungi Anda terkait tahapan selanjutnya.</p>
@@ -65,15 +65,16 @@ const sendStatusEmail = async (lamaran, status, generatedPassword = null) => {
<div style="background-color: #f9f9f9; padding: 15px; border-radius: 5px; margin: 15px 0; border: 1px solid #e0e0e0; font-family: monospace;"> <div style="background-color: #f9f9f9; padding: 15px; border-radius: 5px; margin: 15px 0; border: 1px solid #e0e0e0; font-family: monospace;">
<p style="margin-top: 0; font-weight: bold; color: #333; font-family: sans-serif;">Akun Portal Intern Anda:</p> <p style="margin-top: 0; font-weight: bold; color: #333; font-family: sans-serif;">Akun Portal Intern Anda:</p>
<p style="margin: 5px 0;"><strong>Email:</strong> ${email}</p> <p style="margin: 5px 0;"><strong>Email:</strong> ${email}</p>
${ ${generatedPassword
generatedPassword ? `<p style="margin: 5px 0;"><strong>Password:</strong> ${generatedPassword}</p>`
? `<p style="margin: 5px 0;"><strong>Password:</strong> ${generatedPassword}</p>` : `<p style="margin: 5px 0;"><strong>Password:</strong> Gunakan password akun portal Anda sebelumnya.</p>`
: `<p style="margin: 5px 0;"><strong>Password:</strong> Gunakan password akun portal Anda sebelumnya.</p>` }
}
<p style="margin: 5px 0;"> <p style="margin: 5px 0;">
<strong>Portal Intern: </strong> <a href="http://internify.humicprototyping.net/internship" style="color: #007bff;"> http://internify.humicprototyping.net/internship </a> <strong>Portal Intern: </strong> <a href="http://internify.humicprototyping.net/internship" style="color: #007bff;"> http://internify.humicprototyping.net/internship </a>
</p> </p>
<p style="margin: 5px 0;">
<strong>Grup Internship: </strong> <a href="https://chat.whatsapp.com/CjmUhXdZy5p5yHYTCwbcwd?mode=gi_t" style="color: #007bff;">https://chat.whatsapp.com/CjmUhXdZy5p5yHYTCwbcwd?mode=gi_t</a>
</p>
<p style="margin-bottom: 0; font-size: 13px; color: #555; font-family: sans-serif;"> <p style="margin-bottom: 0; font-size: 13px; color: #555; font-family: sans-serif;">
Silakan masuk menggunakan akun ini untuk melihat project dan tugas magang Anda. Silakan masuk menggunakan akun ini untuk melihat project dan tugas magang Anda.
</p> </p>
@@ -81,23 +82,23 @@ const sendStatusEmail = async (lamaran, status, generatedPassword = null) => {
<p>Terima kasih telah melamar dan kami menantikan kerja sama yang luar biasa bersama Anda.</p> <p>Terima kasih telah melamar dan kami menantikan kerja sama yang luar biasa bersama Anda.</p>
` `
: ` : `
<p>Halo ${fullName},</p> <p>Halo ${fullName},</p>
<p>Terima kasih atas lamaran Anda untuk posisi <strong>${posisi}</strong> di <strong>Humic Engineering</strong>.</p> <p>Terima kasih atas lamaran Anda untuk posisi <strong>${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>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> <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 = { const mailOptions = {
from: process.env.MAIL_USER, from: process.env.MAIL_USER,
to: email, to: email,
subject, subject,
headers: { headers: {
'X-Priority': '1', 'X-Priority': '1',
'X-MSMail-Priority': 'High', 'X-MSMail-Priority': 'High',
Importance: 'high', Importance: 'high',
}, },
html: ` html: `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 10px;"> <div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 10px;">
${message} ${message}
<p>Salam hangat,</p> <p>Salam hangat,</p>
@@ -106,15 +107,15 @@ const sendStatusEmail = async (lamaran, status, generatedPassword = null) => {
<p style="font-size: 12px; color: #888;">Email ini dikirim secara otomatis. Untuk informasi lebih lanjut, silakan hubungi kami melalui kontak resmi.</p> <p style="font-size: 12px; color: #888;">Email ini dikirim secara otomatis. Untuk informasi lebih lanjut, silakan hubungi kami melalui kontak resmi.</p>
</div> </div>
`, `,
}; };
await transporter.sendMail(mailOptions); await transporter.sendMail(mailOptions);
} catch (error) { } catch (error) {
console.error('Gagal mengirim email status lamaran:', error); console.error('Gagal mengirim email status lamaran:', error);
} }
}; };
module.exports = { module.exports = {
sendConfirmationEmail, sendConfirmationEmail,
sendStatusEmail, sendStatusEmail,
}; };
@@ -123,37 +123,20 @@ class LamaranMagangService {
async getAllLamaranMagang(query = {}) { async getAllLamaranMagang(query = {}) {
try { try {
const { const {
page = 1,
limit = 10,
posisi, posisi,
status, status,
universitas, universitas,
id_lowongan, id_lowongan,
} = query; } = query;
const offset = (page - 1) * limit;
const lamaranList = await lamaranMagangRepository.findAll({ const lamaranList = await lamaranMagangRepository.findAll({
offset,
limit,
status,
posisi,
universitas,
id_lowongan,
});
const total = await lamaranMagangRepository.countAllLamaran({
status, status,
posisi, posisi,
universitas, universitas,
id_lowongan, id_lowongan,
}); });
const totalPages = Math.ceil(total / limit); return data(lamaranList);
const meta = {
page: Number(page),
limit: Number(limit),
total,
totalPages,
};
return paginationData(lamaranList, meta);
} catch (err) { } catch (err) {
return error(err); return error(err);
} }
@@ -240,20 +223,20 @@ class LamaranMagangService {
const { nama_depan, nama_belakang } = checkResult.data.mahasiswa; const { nama_depan, nama_belakang } = checkResult.data.mahasiswa;
const fullName = [nama_depan, nama_belakang].filter(Boolean).join(" "); const fullName = [nama_depan, nama_belakang].filter(Boolean).join(" ");
await prisma.user.update({ await prisma.user.update({
where: { where: {
id: existingUser.id, id: existingUser.id,
}, },
data: { data: {
id_mahasiswa: checkResult.data.id_mahasiswa, id_mahasiswa: checkResult.data.id_mahasiswa,
id_lamaran_magang: parseInt(id_lamaran_magang), id_lamaran_magang: parseInt(id_lamaran_magang),
full_name: fullName, full_name: fullName,
email: checkResult.data.mahasiswa.email, email: checkResult.data.mahasiswa.email,
intern_position: internPosition, intern_position: internPosition,
intern_interest_group: internInterestGroup, intern_interest_group: internInterestGroup,
is_active: true is_active: true
}, },
}); });
} }
} }