full
This commit is contained in:
53
services/BookingLifecycleCron.js
Normal file
53
services/BookingLifecycleCron.js
Normal file
@@ -0,0 +1,53 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user