feat: add professor import support, user account creation, and IBAN/card fields

This commit is contained in:
2026-08-21 12:56:15 +03:30
parent 22b57eeae2
commit 7c74950c95
8 changed files with 344 additions and 9 deletions
+147
View File
@@ -0,0 +1,147 @@
// /scripts/convert-professors.js
'use strict';
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const ODS_FILE = path.resolve(__dirname, '../../raw-data/Untitled spreadsheet.ods');
const OUTPUT_FILE = path.resolve(__dirname, '../../raw-data/professors-import.json');
const pythonExtractScript = `
import zipfile, xml.etree.ElementTree as ET, json, sys
ods_path = sys.argv[1]
with zipfile.ZipFile(ods_path) as z:
content = z.read('content.xml')
tree = ET.fromstring(content)
for table in tree.iter('{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table'):
rows = []
for row in table.iter('{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table-row'):
row_vals = []
for cell in row.iter('{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table-cell'):
texts = [t.text for t in cell.iter('{urn:oasis:names:tc:opendocument:xmlns:text:1.0}p') if t.text]
repeat = int(cell.attrib.get('{urn:oasis:names:tc:opendocument:xmlns:table:1.0}number-columns-repeated', 1))
val = ' '.join(texts).strip() if texts else ''
if repeat > 1 and not val:
pass
else:
for _ in range(min(repeat, 20)):
row_vals.append(val)
if any(row_vals):
rows.append(row_vals)
print(json.dumps(rows, ensure_ascii=False))
break
`;
const extractOdsRows = (filePath) => {
const output = execSync(`python3 -c "${pythonExtractScript.replace(/"/g, '\\"')}" "${filePath}"`, {
encoding: 'utf-8',
maxBuffer: 10 * 1024 * 1024
});
return JSON.parse(output);
};
const toEnglishDigits = (str = '') =>
String(str)
.replace(/[۰-۹]/g, (d) => '0123456789'['۰۱۲۳۴۵۶۷۸۹'.indexOf(d)])
.replace(/[٠-٩]/g, (d) => '0123456789'['٠١٢٣٤٥٦٧٨٩'.indexOf(d)]);
const cleanPhone = (raw) => {
if (!raw) return '';
let digits = toEnglishDigits(raw).replace(/\D/g, '');
if (digits.startsWith('98') && digits.length >= 12) digits = `0${digits.slice(2)}`;
if (digits.length === 10 && digits.startsWith('9')) digits = `0${digits}`;
if (digits.length === 11 && digits.startsWith('9')) digits = `0${digits.slice(0, 10)}`;
if (digits.length > 11 && digits.startsWith('09')) digits = digits.slice(0, 11);
return digits;
};
const cleanNationalId = (raw) => {
if (!raw) return '';
let digits = toEnglishDigits(raw).replace(/\D/g, '');
if (digits && digits.length < 10 && /^\d+$/.test(digits)) {
digits = digits.padStart(10, '0');
}
return digits;
};
const cleanCard = (raw) => {
if (!raw) return '';
return toEnglishDigits(raw).replace(/\D/g, '');
};
const cleanShaba = (raw) => {
if (!raw) return '';
let val = toEnglishDigits(raw).replace(/[^0-9A-Za-z]/g, '');
return val;
};
const main = () => {
if (!fs.existsSync(ODS_FILE)) {
console.error(`ODS file not found: ${ODS_FILE}`);
process.exit(1);
}
const rows = extractOdsRows(ODS_FILE);
if (!rows || rows.length < 2) {
console.error('No rows found in ODS file');
process.exit(1);
}
const header = rows[0];
console.log('Detected headers:', header);
const professors = [];
for (let i = 1; i < rows.length; i += 1) {
const r = rows[i];
// 0: ردیف, 1: نام, 2: نام خانوادگی, 3: کد ملی, 4: شماره تماس, 5: درصد, 6: شماره کارت, 7: شمار شبا
const rawName = r[1] || '';
const rawSurname = r[2] || '';
const rawNid = r[3] || '';
const rawPhone = r[4] || '';
const rawCard = r[6] || '';
const rawShaba = r[7] || '';
// Strip honorifics like 'سرکار'
const name = rawName.replace(/^(آقای|اقای|خانم|آقا|سرکار\s+خانم|سرکار)\s+/, '').trim();
const surname = rawSurname.trim();
const nationalIdCode = cleanNationalId(rawNid);
const phoneNumber = cleanPhone(rawPhone);
const cardNumber = cleanCard(rawCard);
const shabaNumber = cleanShaba(rawShaba);
professors.push({
name,
surname,
nationalIdCode,
phoneNumber,
cardNumber,
shabaNumber
});
}
const payload = {
version: 1,
generatedAt: new Date().toISOString(),
source: 'Untitled spreadsheet.ods',
summary: {
professors: professors.length
},
professors
};
fs.writeFileSync(OUTPUT_FILE, JSON.stringify(payload, null, 2), 'utf-8');
console.log(`Successfully wrote ${professors.length} professors to ${OUTPUT_FILE}`);
};
if (require.main === module) {
main();
}
module.exports = {
extractOdsRows,
main
};