File size: 6,242 Bytes
8c7b7ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
const dayjs = require('dayjs');
const {
  Document,
  Employee,
  Vendor,
  User,
  SafetyBadge,
  GatePass,
  AlertLog
} = require('../models');
const { sendEmail, sendWhatsApp } = require('./notificationService');

async function ensureMandatoryDocuments(employeeId) {
  const rows = await Document.find({ employee_id: employeeId }, { type: 1, verified_by_hr: 1 }).lean();

  const hasAadhar = rows.some((r) => r.type === 'Aadhar');
  const hasUan = rows.some((r) => r.type === 'UAN');
  const hasEsi = rows.some((r) => r.type === 'ESI');
  const hasCompPolicy = rows.some((r) => r.type === 'Compensation_Policy');
  const hasPvc = rows.some((r) => r.type === 'PVC');

  return hasAadhar && hasUan && (hasEsi || hasCompPolicy) && hasPvc;
}

async function countVendorWorkers(vendorId) {
  return Employee.countDocuments({
    vendor_id: vendorId,
    is_active: true,
    status: { $in: ['Pending', 'HR_Approved', 'Safety_Approved', 'Active'] }
  });
}

async function findVendorContact(vendorId) {
  return User.findOne({ vendor_id: vendorId, role: 'Vendor', is_active: true }, { email: 1, phone: 1 }).lean();
}

async function sendAlert(alertType, table, refId, recipientEmail, recipientPhone, subject, message) {
  if (!recipientEmail) return;

  const existing = await AlertLog.findOne({
    alert_type: alertType,
    reference_table: table,
    reference_id: String(refId),
    recipient_email: recipientEmail,
    channel: 'Email'
  }).lean();

  if (!existing) {
    await sendEmail(recipientEmail, subject, message);
    await AlertLog.create({
      alert_type: alertType,
      reference_table: table,
      reference_id: String(refId),
      recipient_email: recipientEmail,
      channel: 'Email',
      message,
      sent_at: new Date()
    });
  }

  if (recipientPhone) {
    const existingWa = await AlertLog.findOne({
      alert_type: alertType,
      reference_table: table,
      reference_id: String(refId),
      recipient_email: recipientEmail,
      channel: 'WhatsApp'
    }).lean();

    if (!existingWa) {
      await sendWhatsApp(`whatsapp:${recipientPhone}`, message);
      await AlertLog.create({
        alert_type: alertType,
        reference_table: table,
        reference_id: String(refId),
        recipient_email: recipientEmail,
        channel: 'WhatsApp',
        message,
        sent_at: new Date()
      });
    }
  }
}

async function processBadgeAlerts(adminUsers) {
  const today = dayjs().startOf('day');
  const maxDate = today.add(30, 'day').endOf('day').toDate();

  const badges = await SafetyBadge.find({ expiry_date: { $lte: maxDate } })
    .populate({ path: 'employee_id', model: 'Employee', select: 'name vendor_id is_active' })
    .lean();

  for (const badge of badges) {
    const employee = badge.employee_id;
    if (!employee || !employee.is_active) continue;

    const vendor = await Vendor.findById(employee.vendor_id, { name: 1, is_active: 1 }).lean();
    if (!vendor || !vendor.is_active) continue;

    const daysToExpiry = dayjs(badge.expiry_date).startOf('day').diff(today, 'day');
    let alertType;
    let subject;

    if (daysToExpiry <= 0) {
      alertType = 'SAFETY_BADGE_EXPIRED';
      subject = `Safety Badge Expired - ${employee.name}`;
    } else if (daysToExpiry === 7) {
      alertType = 'SAFETY_BADGE_7_DAYS';
      subject = `Safety Badge Expires in 7 Days - ${employee.name}`;
    } else if (daysToExpiry === 30) {
      alertType = 'SAFETY_BADGE_30_DAYS';
      subject = `Safety Badge Expires in 30 Days - ${employee.name}`;
    } else {
      continue;
    }

    const message = `${employee.name} (${vendor.name}) safety badge due date: ${dayjs(badge.expiry_date).format('DD/MM/YYYY')}.`;

    const vendorUser = await findVendorContact(vendor._id);
    if (vendorUser) {
      await sendAlert(alertType, 'safety_badges', badge._id, vendorUser.email, vendorUser.phone, subject, message);
    }

    for (const adminUser of adminUsers) {
      await sendAlert(alertType, 'safety_badges', badge._id, adminUser.email, adminUser.phone, subject, message);
    }
  }
}

async function processGatePassAlerts(adminUsers) {
  const today = dayjs().startOf('day');
  const maxDate = today.add(30, 'day').endOf('day').toDate();

  const gatePasses = await GatePass.find({ expiry_date: { $lte: maxDate } })
    .populate({ path: 'employee_id', model: 'Employee', select: 'name vendor_id is_active' })
    .lean();

  for (const gatePass of gatePasses) {
    const employee = gatePass.employee_id;
    if (!employee || !employee.is_active) continue;

    const vendor = await Vendor.findById(employee.vendor_id, { name: 1, is_active: 1 }).lean();
    if (!vendor || !vendor.is_active) continue;

    const daysToExpiry = dayjs(gatePass.expiry_date).startOf('day').diff(today, 'day');
    let alertType;
    let subject;

    if (daysToExpiry <= 0) {
      alertType = 'GATE_PASS_EXPIRED';
      subject = `Gate Pass Expired - ${employee.name}`;
    } else if (daysToExpiry === 7) {
      alertType = 'GATE_PASS_7_DAYS';
      subject = `Gate Pass Expires in 7 Days - ${employee.name}`;
    } else if (daysToExpiry === 30) {
      alertType = 'GATE_PASS_30_DAYS';
      subject = `Gate Pass Expires in 30 Days - ${employee.name}`;
    } else {
      continue;
    }

    const message = `${employee.name} (${vendor.name}) gate pass due date: ${dayjs(gatePass.expiry_date).format('DD/MM/YYYY')}.`;

    const vendorUser = await findVendorContact(vendor._id);
    if (vendorUser) {
      await sendAlert(alertType, 'gate_passes', gatePass._id, vendorUser.email, vendorUser.phone, subject, message);
    }

    for (const adminUser of adminUsers) {
      await sendAlert(alertType, 'gate_passes', gatePass._id, adminUser.email, adminUser.phone, subject, message);
    }
  }
}

async function sendExpiryAlerts() {
  const adminUsers = await User.find({ role: 'Admin', is_active: true }, { email: 1, phone: 1 }).lean();

  await processBadgeAlerts(adminUsers);
  await processGatePassAlerts(adminUsers);

  await GatePass.updateMany(
    { expiry_date: { $lt: dayjs().startOf('day').toDate() }, status: { $ne: 'Expired' } },
    { $set: { status: 'Expired' } }
  );
}

module.exports = {
  ensureMandatoryDocuments,
  countVendorWorkers,
  sendExpiryAlerts
};