// pdfGenerator.js - АЛЬТЕРНАТИВНАЯ ВЕРСИЯ (для pdfmake 0.1.72) const pdfmake = require('pdfmake'); // Для версии 0.1.72 используется другой способ const fonts = { Roboto: { normal: 'C:/Windows/Fonts/arial.ttf', bold: 'C:/Windows/Fonts/arialbd.ttf', italics: 'C:/Windows/Fonts/ariali.ttf', bolditalics: 'C:/Windows/Fonts/arialbi.ttf' } }; // Для старой версии pdfmake const printer = new pdfmake(fonts); function buildDocDefinition(data) { return { pageSize: { width: 80 * 2.83465, height: 297 * 2.83465 }, pageMargins: [5, 5, 5, 5], content: [ { text: 'РАСЧЕТНЫЙ ЛИСТОК', style: 'header' }, { text: `${data.month || ''} ${data.year || ''} (${data.period || ''})`, style: 'subheader' }, { text: ' ', style: 'divider' }, { text: `ФИО: ${data.fullName || ''}`, style: 'row' }, { text: `Таб.№: ${data.tabNumber || ''}`, style: 'row' }, { text: `Подразделение: ${data.department || ''}`, style: 'row' }, { text: `Должность: ${data.position || ''}`, style: 'row' }, { text: `Отработано: ${data.daysWorked || ''}`, style: 'row' }, { text: ' ', style: 'divider' }, { text: 'НАЧИСЛЕНО', style: 'sectionTitle' }, ...(data.accrued || []).map(item => ({ columns: [ { text: `${item.code || ''} ${item.description || ''}`, width: '*', style: 'itemDesc' }, { text: (item.amount || 0).toFixed(2), alignment: 'right', style: 'itemAmount' } ], style: 'itemRow' })), { text: `ИТОГО НАЧИСЛЕНО: ${(data.totalAccrued || 0).toFixed(2)}`, style: 'totalRow' }, { text: ' ', style: 'divider' }, { text: 'УДЕРЖАНО', style: 'sectionTitle' }, ...(data.deductions || []).map(item => ({ columns: [ { text: `${item.code || ''} ${item.description || ''}`, width: '*', style: 'itemDesc' }, { text: (item.amount || 0).toFixed(2), alignment: 'right', style: 'itemAmount' } ], style: 'itemRow' })), { text: `ИТОГО УДЕРЖАНО: ${(data.totalDeductions || 0).toFixed(2)}`, style: 'totalRow' }, { text: ' ', style: 'divider' }, { text: `К ВЫПЛАТЕ: ${(data.totalPaid || 0).toFixed(2)}`, style: 'totalRow big' }, { text: ' ', style: 'divider' }, ...(data.bankTransfers && data.bankTransfers.length > 0 ? [ { text: 'БАНКОВСКИЕ ПЕРЕВОДЫ', style: 'sectionTitle' }, ...data.bankTransfers.map(bank => ({ columns: [ { text: bank.bank || '', width: '*', style: 'itemDesc' }, { text: (bank.amount || 0).toFixed(2), alignment: 'right', style: 'itemAmount' } ], style: 'itemRow' })) ] : []), ...(data.other && data.other.length > 0 ? [ { text: 'ПРОЧЕЕ', style: 'sectionTitle' }, ...data.other.map(item => ({ columns: [ { text: `${item.code || ''} ${item.description || ''}`, width: '*', style: 'itemDesc' }, { text: (item.amount || 0).toFixed(2), alignment: 'right', style: 'itemAmount' } ], style: 'itemRow' })), { text: `ИТОГО ПРОЧЕЕ: ${(data.totalOther || 0).toFixed(2)}`, style: 'totalRow' } ] : []), { text: ' ', style: 'divider' }, { text: `Сформировано: ${new Date().toLocaleString('ru-RU')}`, style: 'footer' } ], styles: { header: { fontSize: 14, bold: true, alignment: 'center', margin: [0, 0, 0, 4] }, subheader: { fontSize: 12, alignment: 'center', margin: [0, 0, 0, 4] }, row: { fontSize: 10, margin: [0, 2, 0, 2] }, divider: { margin: [0, 4, 0, 4], border: [false, true, false, false] }, sectionTitle: { fontSize: 12, bold: true, margin: [0, 6, 0, 2] }, itemRow: { fontSize: 10, margin: [0, 1, 0, 1] }, itemDesc: { fontSize: 10 }, itemAmount: { fontSize: 10, alignment: 'right' }, totalRow: { fontSize: 12, bold: true, margin: [0, 4, 0, 0] }, 'totalRow big': { fontSize: 14, bold: true, margin: [0, 8, 0, 0] }, footer: { fontSize: 8, alignment: 'center', color: '#666', margin: [0, 8, 0, 0] } } }; } function generatePayslipPDF(data) { const docDefinition = buildDocDefinition(data); const pdfDoc = printer.createPdfKitDocument(docDefinition); return new Promise((resolve, reject) => { const chunks = []; pdfDoc.on('data', chunk => chunks.push(chunk)); pdfDoc.on('end', () => resolve(Buffer.concat(chunks))); pdfDoc.on('error', reject); pdfDoc.end(); }); } module.exports = { generatePayslipPDF };