fix(payments,dates): improve duplicate payment detection and Jalali date parsing
This commit is contained in:
@@ -602,7 +602,15 @@ const checkDuplicatePayment = async (query = {}) => {
|
|||||||
const classObjectIds = rawClasses.map((id) => {
|
const classObjectIds = rawClasses.map((id) => {
|
||||||
return mongoose.isValidObjectId(id) ? new mongoose.Types.ObjectId(String(id)) : 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)
|
const payments = await Payment.find(filter)
|
||||||
|
|||||||
+23
-3
@@ -70,12 +70,32 @@ const parseImportDate = (raw) => {
|
|||||||
if (raw instanceof Date) {
|
if (raw instanceof Date) {
|
||||||
return Number.isNaN(raw.getTime()) ? null : raw;
|
return Number.isNaN(raw.getTime()) ? null : raw;
|
||||||
}
|
}
|
||||||
const text = String(raw).trim();
|
const text = toEnglishDigits(raw).trim();
|
||||||
if (!text) return null;
|
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);
|
const jalali = parseJalaliDate(text);
|
||||||
if (jalali) return new Date(`${jalali}T00:00:00.000Z`);
|
if (jalali) return new Date(`${jalali}T00:00:00.000Z`);
|
||||||
|
|
||||||
const date = new Date(text);
|
const date = new Date(text);
|
||||||
return Number.isNaN(date.getTime()) ? null : date;
|
return Number.isNaN(date.getTime()) ? null : date;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,5 +14,9 @@ describe('jalaliDate', () => {
|
|||||||
it('parses ISO and jalali values into UTC midnight dates', () => {
|
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('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.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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user