/** * Generate PDF datasheets for specific serial numbers * For Quatronix customer request - 70 datasheets needed urgently */ const fs = require('fs'); const path = require('path'); const Database = require('better-sqlite3'); const PDFDocument = require('pdfkit'); const { loadAllSpecs, getSpecs } = require('../parsers/spec-reader'); const { generateExactDatasheet } = require('../templates/datasheet-exact'); const DB_PATH = path.join(__dirname, 'testdata.db'); const OUTPUT_DIR = process.argv[2] || path.join(process.env.USERPROFILE, 'Desktop', 'Quatronix-Datasheets'); // Build the list of needed serial numbers const needed = [ // SCM5B34-03: 177368-6~15 ...Array.from({length:10}, (_,i) => '177368-' + (i+6)), // SCM5B35-02: 177625-6~10 ...Array.from({length:5}, (_,i) => '177625-' + (i+6)), // SCM5B38-05: 177963-6 '177963-6', // SCM5B392-11: 177199-13 '177199-13', // SCM5B40-03: 178444-1 '178444-1', // SCM5B41-02: 178362-1 '178362-1', // SCM5B42-02: 177299-4, 177299-5 '177299-4', '177299-5', // SCM5B45-02D: 178607-1 '178607-1', // SCM5B45-04: 178385-4~8 ...Array.from({length:5}, (_,i) => '178385-' + (i+4)), // SCM5B48-01: 177593-1 '177593-1', // SCM5B49-05: 177000-15 '177000-15', // DSCA30-05C: 176566-2 '176566-2', // DSCA38-19C: 178001-22, 178001-23 '178001-22', '178001-23', // DSCA41-02: 178135-2 '178135-2', // DSCA38-1468: 178595-1 '178595-1', // SCM5B41-02: 177012-1~30 ...Array.from({length:30}, (_,i) => '177012-' + (i+1)), // SCM5B47S-10: 178768-8 '178768-8', // SCM5B45-04D: 177207-4~7 ...Array.from({length:4}, (_,i) => '177207-' + (i+4)), // 8B51-12: 178601-6~9 ...Array.from({length:4}, (_,i) => '178601-' + (i+6)), ]; async function generatePdf(txt, outputPath) { return new Promise((resolve, reject) => { const doc = new PDFDocument({ size: 'LETTER', margins: { top: 36, bottom: 36, left: 36, right: 36 } }); const stream = fs.createWriteStream(outputPath); stream.on('finish', resolve); stream.on('error', reject); doc.pipe(stream); doc.font('Courier').fontSize(9.5); const lines = txt.split(/\r?\n/); for (const line of lines) { doc.text(line, { lineGap: 1 }); } doc.end(); }); } async function run() { console.log('========================================'); console.log('Generate Customer PDFs'); console.log('========================================'); console.log(`Output: ${OUTPUT_DIR}`); console.log(`Serial numbers: ${needed.length}`); if (!fs.existsSync(OUTPUT_DIR)) { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); } const specMap = loadAllSpecs(); const db = new Database(DB_PATH, { readonly: true }); let generated = 0; let notFound = []; let noSpecs = []; let errors = []; for (const sn of needed) { const record = db.prepare( "SELECT * FROM test_records WHERE serial_number = ? AND overall_result = 'PASS' LIMIT 1" ).get(sn); if (!record) { notFound.push(sn); continue; } const specs = getSpecs(specMap, record.model_number); if (!specs) { noSpecs.push(sn + ' (' + record.model_number + ')'); continue; } const txt = generateExactDatasheet(record, specs); if (!txt) { errors.push(sn + ' (format failed)'); continue; } // Write TXT fs.writeFileSync(path.join(OUTPUT_DIR, sn + '.TXT'), txt, 'utf8'); // Write PDF try { await generatePdf(txt, path.join(OUTPUT_DIR, sn + '.pdf')); generated++; process.stdout.write(`\rGenerated: ${generated}`); } catch (err) { errors.push(sn + ' (PDF: ' + err.message + ')'); } } db.close(); console.log('\n\n========================================'); console.log('Results'); console.log('========================================'); console.log(`Generated: ${generated} (TXT + PDF)`); if (notFound.length > 0) { console.log(`\nNot in database (${notFound.length}):`); notFound.forEach(s => console.log(' ' + s)); } if (noSpecs.length > 0) { console.log(`\nNo spec data (${noSpecs.length}):`); noSpecs.forEach(s => console.log(' ' + s)); } if (errors.length > 0) { console.log(`\nErrors (${errors.length}):`); errors.forEach(s => console.log(' ' + s)); } } run().catch(console.error);