R45 A2-A7 员工附件与培训证书管理
这个提交包含在:
@@ -14,7 +14,7 @@ async function buildEmployeeStats(prisma, options = {}) {
|
||||
const next30DateTo = addDays(today, 30);
|
||||
const activeEmployeeWhere = { status: "active" };
|
||||
|
||||
const [employmentStatusRows, departmentRows, departments, recentHires, recentDepartures, expiringContracts] = await Promise.all([
|
||||
const [employmentStatusRows, departmentRows, departments, recentHires, recentDepartures, expiringContracts, validCertificateHolders, expiringCertificates] = await Promise.all([
|
||||
prisma.employee.groupBy({
|
||||
by: ["employment_status"],
|
||||
where: activeEmployeeWhere,
|
||||
@@ -55,6 +55,29 @@ async function buildEmployeeStats(prisma, options = {}) {
|
||||
employee: activeEmployeeWhere,
|
||||
},
|
||||
}),
|
||||
prisma.employeeCertificate.groupBy({
|
||||
by: ["employee_id"],
|
||||
where: {
|
||||
employee: activeEmployeeWhere,
|
||||
OR: [
|
||||
{ expiry_date: null },
|
||||
{
|
||||
expiry_date: {
|
||||
gte: today,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
prisma.employeeCertificate.count({
|
||||
where: {
|
||||
employee: activeEmployeeWhere,
|
||||
expiry_date: {
|
||||
gte: today,
|
||||
lte: new Date(`${next30DateTo.toISOString().slice(0, 10)}T23:59:59.999Z`),
|
||||
},
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
const departmentMap = new Map(departments.map((item) => [item.id, item.name]));
|
||||
@@ -88,6 +111,12 @@ async function buildEmployeeStats(prisma, options = {}) {
|
||||
dateTo: next30DateTo.toISOString().slice(0, 10),
|
||||
count: expiringContracts,
|
||||
},
|
||||
certificateSummary: {
|
||||
dateFrom: todayString,
|
||||
dateTo: next30DateTo.toISOString().slice(0, 10),
|
||||
validHolderCount: validCertificateHolders.length,
|
||||
expiringSoonCount: expiringCertificates,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户