113 lines
5.3 KiB
JavaScript
113 lines
5.3 KiB
JavaScript
// 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 }; |