54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
const cron = require('node-cron')
|
||
const BookingModel = require('../models/BookingModel')
|
||
const { notifyUser } = require('../utils/notifyUser')
|
||
|
||
const PAYMENT_TIMEOUT_MINUTES = 60
|
||
|
||
let ioInstance = null
|
||
|
||
/** Called once from index.js right after the socket.io server is created — cron jobs have no `req`. */
|
||
function setIo (io) {
|
||
ioInstance = io
|
||
}
|
||
|
||
/** Cancel unpaid bookings that missed the deposit-payment window, freeing their time slot back up. */
|
||
const autoCancelUnpaidBookings = async () => {
|
||
const cutoff = new Date(Date.now() - PAYMENT_TIMEOUT_MINUTES * 60 * 1000)
|
||
|
||
try {
|
||
const bookings = await BookingModel.find({
|
||
status: 'pending_payment',
|
||
createdAt: { $lte: cutoff }
|
||
})
|
||
|
||
for (const booking of bookings) {
|
||
try {
|
||
booking.status = 'cancelled'
|
||
await booking.save()
|
||
await notifyUser(ioInstance, booking.buyer, {
|
||
project_post_id: booking._id,
|
||
type: 'booking',
|
||
title: 'لغو رزرو',
|
||
description: `رزرو خدمت «${booking.serviceTitle}» به دلیل عدم پرداخت بیعانه در بازه زمانی مجاز لغو شد.`
|
||
})
|
||
} catch (err) {
|
||
console.error(`[BookingLifecycleCron] failed to cancel booking ${booking._id}:`, err)
|
||
}
|
||
}
|
||
|
||
if (bookings.length) {
|
||
console.log(`[BookingLifecycleCron] auto-cancelled ${bookings.length} unpaid booking(s)`)
|
||
}
|
||
} catch (error) {
|
||
console.error('[BookingLifecycleCron] auto-cancel failed:', error)
|
||
}
|
||
}
|
||
|
||
// هر ۱۰ دقیقه: لغو رزروهای بدون پرداخت بیعانه خارج از مهلت ۶۰ دقیقهای
|
||
cron.schedule('*/10 * * * *', autoCancelUnpaidBookings)
|
||
|
||
module.exports = {
|
||
autoCancelUnpaidBookings,
|
||
setIo
|
||
}
|