Files
modstagram-back/services/OrderLifecycleCron.js
payacom 3f416a7a60 full
2026-08-31 20:45:41 +03:30

82 lines
2.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const cron = require('node-cron')
const OrderModel = require('../models/OrderModel')
const { releaseOrderFunds, PAYMENT_TIMEOUT_MINUTES } = require('../controllers/application/orders/orderController')
const { notifyUser } = require('../utils/notifyUser')
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
}
/** Auto-release seller funds 7 days after fulfillment if the buyer never confirmed receipt. */
const autoReleaseFulfilledOrders = async () => {
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
try {
const orders = await OrderModel.find({
status: { $in: ['shipped', 'ready_for_pickup'] },
walletReleased: false,
fulfilledAt: { $lte: sevenDaysAgo }
})
for (const order of orders) {
try {
await releaseOrderFunds(order, 'auto_released', ioInstance)
} catch (err) {
console.error(`[OrderLifecycleCron] failed to release order ${order._id}:`, err)
}
}
if (orders.length) {
console.log(`[OrderLifecycleCron] auto-released ${orders.length} order(s)`)
}
} catch (error) {
console.error('[OrderLifecycleCron] auto-release query failed:', error)
}
}
/** Cancel unpaid orders that missed the 60-minute payment window. */
const autoCancelUnpaidOrders = async () => {
const cutoff = new Date(Date.now() - PAYMENT_TIMEOUT_MINUTES * 60 * 1000)
try {
const orders = await OrderModel.find({ status: 'pending_payment', createdAt: { $lte: cutoff } })
for (const order of orders) {
try {
order.status = 'cancelled'
order.cancelReason = 'عدم پرداخت در بازه زمانی مجاز'
await order.save()
await notifyUser(ioInstance, order.buyer, {
project_post_id: order._id,
type: 'shop_order',
title: 'لغو سفارش',
description: 'سفارش شما به دلیل عدم پرداخت در بازه زمانی مجاز لغو شد.'
})
} catch (err) {
console.error(`[OrderLifecycleCron] failed to cancel order ${order._id}:`, err)
}
}
if (orders.length) {
console.log(`[OrderLifecycleCron] auto-cancelled ${orders.length} unpaid order(s)`)
}
} catch (error) {
console.error('[OrderLifecycleCron] auto-cancel failed:', error)
}
}
// هر ساعت: بررسی سفارش‌های تحویل‌شده‌ی بدون تایید خریدار برای آزادسازی خودکار وجه
cron.schedule('0 * * * *', autoReleaseFulfilledOrders)
// هر ۱۰ دقیقه: لغو سفارش‌های پرداخت‌نشده‌ی خارج از مهلت ۶۰ دقیقه‌ای
cron.schedule('*/10 * * * *', autoCancelUnpaidOrders)
module.exports = {
autoReleaseFulfilledOrders,
autoCancelUnpaidOrders,
setIo
}