diff --git a/components/payments/paymentService.js b/components/payments/paymentService.js index e01fdc9..57f6a59 100644 --- a/components/payments/paymentService.js +++ b/components/payments/paymentService.js @@ -602,7 +602,15 @@ const checkDuplicatePayment = async (query = {}) => { const classObjectIds = rawClasses.map((id) => { return mongoose.isValidObjectId(id) ? new mongoose.Types.ObjectId(String(id)) : id; }); - filter.classes = { $in: classObjectIds }; + + const classDocs = await Class.find({ _id: { $in: classObjectIds } }).select('course').lean(); + const courseIds = classDocs.map((c) => c.course).filter(Boolean); + + const orConditions = [{ classes: { $in: classObjectIds } }]; + if (courseIds.length) { + orConditions.push({ course: { $in: courseIds } }); + } + filter.$or = orConditions; } const payments = await Payment.find(filter) diff --git a/utils/jalaliDate.js b/utils/jalaliDate.js index 70c20c4..8041727 100644 --- a/utils/jalaliDate.js +++ b/utils/jalaliDate.js @@ -70,12 +70,32 @@ const parseImportDate = (raw) => { if (raw instanceof Date) { return Number.isNaN(raw.getTime()) ? null : raw; } - const text = String(raw).trim(); + const text = toEnglishDigits(raw).trim(); if (!text) return null; - const gregorian = text.match(/^(\d{4}-\d{2}-\d{2})/); - if (gregorian) return new Date(`${gregorian[1]}T00:00:00.000Z`); + + if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(text)) { + const d = new Date(text); + return Number.isNaN(d.getTime()) ? null : d; + } + + const dateMatch = text.match(/^(\d{3,4})[./\-](\d{1,2})[./\-](\d{1,2})/); + if (dateMatch) { + const year = Number(dateMatch[1]); + const month = Number(dateMatch[2]); + const day = Number(dateMatch[3]); + if (year >= 1200 && year <= 1599) { + const gDate = jalaliToGregorian(year, month, day); + if (gDate) return new Date(`${gDate}T00:00:00.000Z`); + } else if (year >= 1900 && year <= 2200) { + const mStr = String(month).padStart(2, '0'); + const dStr = String(day).padStart(2, '0'); + return new Date(`${year}-${mStr}-${dStr}T00:00:00.000Z`); + } + } + const jalali = parseJalaliDate(text); if (jalali) return new Date(`${jalali}T00:00:00.000Z`); + const date = new Date(text); return Number.isNaN(date.getTime()) ? null : date; }; diff --git a/utils/jalaliDate.test.js b/utils/jalaliDate.test.js index 8c346f1..a067e16 100644 --- a/utils/jalaliDate.test.js +++ b/utils/jalaliDate.test.js @@ -14,5 +14,9 @@ describe('jalaliDate', () => { it('parses ISO and jalali values into UTC midnight dates', () => { assert.equal(parseImportDate('2026-07-14').toISOString(), '2026-07-14T00:00:00.000Z'); assert.equal(parseImportDate('1405.5.12').toISOString(), '2026-08-03T00:00:00.000Z'); + assert.equal(parseImportDate('1405/05/26').toISOString(), '2026-08-17T00:00:00.000Z'); + assert.equal(parseImportDate('1405-05-26').toISOString(), '2026-08-17T00:00:00.000Z'); + assert.equal(parseImportDate('۱۴۰۵/۰۵/۲۶').toISOString(), '2026-08-17T00:00:00.000Z'); + assert.equal(parseImportDate('2026-08-17T00:00:00.000Z').toISOString(), '2026-08-17T00:00:00.000Z'); }); });