feat: import class sessions, attendance, and payments from JSON

Match students by name when national ID or phone is missing, parse Jalali dates, and allow sessions without a professor.
This commit is contained in:
2026-08-16 07:04:16 +03:30
parent 72be01fee3
commit 3348ca5798
7 changed files with 445 additions and 37 deletions
@@ -0,0 +1,51 @@
'use strict';
const { describe, it } = require('node:test');
const assert = require('node:assert/strict');
const {
normalizePersonName,
namesMatch,
normalizePhone,
mapAttendanceStatus,
projectSessionDates
} = require('./importHelpers');
describe('importHelpers', () => {
it('normalizes honorifics so spreadsheet names match database users', () => {
assert.equal(normalizePersonName('مریم خ پناهیان'), 'مریم پناهیان');
assert.ok(namesMatch('آقای رضایی', 'آقای رضایی'));
assert.equal(normalizePhone(9168942141), '09168942141');
});
it('maps spreadsheet attendance marks', () => {
assert.equal(mapAttendanceStatus('*'), 'present');
assert.equal(mapAttendanceStatus('غ'), 'absent');
assert.equal(mapAttendanceStatus(''), null);
});
it('projects remaining Teksa sessions from Sunday/Tuesday pattern', () => {
const firstNine = [
'2026-07-14',
'2026-07-19',
'2026-07-21',
'2026-07-26',
'2026-07-28',
'2026-08-02',
'2026-08-04',
'2026-08-09',
'2026-08-11'
];
const all = projectSessionDates(firstNine, 16);
assert.equal(all.length, 16);
assert.deepEqual(all.slice(0, 9), firstNine);
assert.deepEqual(all.slice(9), [
'2026-08-16',
'2026-08-18',
'2026-08-23',
'2026-08-25',
'2026-08-30',
'2026-09-01',
'2026-09-06'
]);
});
});