0625d75aa6
independentScales=true (для регионов типа Вологды): - Левая и правая панели с разными показателями (надой vs цена) - Каждая со своей шкалой Y и Y-лейблами - Y-лейблы с тире (как в оригинале: '9500 –') - highlight=красный, остальные=серые independentScales=false (для ФО, по умолчанию): - Общая шкала, зелёный/оранжевый/жёлтый
96 lines
3.6 KiB
JavaScript
96 lines
3.6 KiB
JavaScript
/**
|
||
* index.js — главный entry point генератора отчётов
|
||
*/
|
||
|
||
const { chart1_priceAndMargin } = require('./charts/chart1')
|
||
const { chart2_leaders } = require('./charts/chart2')
|
||
const { chart3_ebitdaByOrg } = require('./charts/chart3')
|
||
const { chart4_regionCompare } = require('./charts/chart4')
|
||
const { chart5_scenarioMargins } = require('./charts/chart5')
|
||
const { buildDocument } = require('./generators/document')
|
||
const { PALETTE } = require('./data/palette')
|
||
|
||
/**
|
||
* Главная функция генерации отчёта.
|
||
*
|
||
* @param {Object} config — параметры отчёта
|
||
* @returns {Promise<Buffer>} — DOCX как буфер
|
||
*/
|
||
async function generateReport (config) {
|
||
const {
|
||
subject, // { name, shortName, type: 'region'|'farm'|'company' }
|
||
period, // { historicalFrom, historicalTo, forecastTo }
|
||
data, // { prices, costs, scenarios, kpi, leaders?, ebitda?, regionComparison? }
|
||
text, // { mainConclusion, conclusions, risks, recommendations }
|
||
meta = {} // { reportDate, brand: 'DairyTrends' }
|
||
} = config
|
||
|
||
// 1) Рендерим графики параллельно
|
||
const charts = {}
|
||
|
||
if (data.prices && data.costs && data.scenarios) {
|
||
charts.chart1 = await chart1_priceAndMargin({
|
||
priceData: data.prices,
|
||
costData: data.costs,
|
||
scenarios: data.scenarios,
|
||
marginBars: data.marginBars || [],
|
||
regionLabel: `${subject.name} · Закупочная цена и себестоимость молока · руб./кг · ${period.historicalFrom.slice(0,4)}–${period.forecastTo.slice(0,4)}`
|
||
})
|
||
}
|
||
|
||
if (data.scenarioMargins) {
|
||
charts.chart5 = await chart5_scenarioMargins({
|
||
quarters: data.scenarioMargins,
|
||
regionLabel: `${subject.name} · Прогноз маржинальности по сценариям · %`
|
||
})
|
||
}
|
||
|
||
if (data.leaders && data.leaders.items) {
|
||
charts.chart2 = await chart2_leaders({
|
||
items: data.leaders.items,
|
||
title: data.leaders.title || 'Топ-производители по чистой прибыли',
|
||
unit: data.leaders.unit || 'млн руб.',
|
||
...(data.leaders.volumeItems ? {
|
||
volumeItems: data.leaders.volumeItems,
|
||
volumeTitle: data.leaders.volumeTitle || 'Объём переработки',
|
||
volumeUnit: data.leaders.volumeUnit || 'тыс. тонн',
|
||
} : {}),
|
||
regionLabel: `${subject.name} · ${data.leaders.title || 'Лидеры рынка'} · ${data.leaders.unit || 'млн руб.'}`
|
||
})
|
||
}
|
||
|
||
if (data.ebitda) {
|
||
charts.chart3 = await chart3_ebitdaByOrg({
|
||
items: data.ebitda.groups || data.ebitda,
|
||
unit: (data.ebitda.unit) || 'EBITDA-маржа, %',
|
||
regionLabel: `${subject.name} · Эффективность по группам хозяйств · %`
|
||
})
|
||
}
|
||
|
||
if (data.regionComparison) {
|
||
charts.chart4 = await chart4_regionCompare({
|
||
left: data.regionComparison.left,
|
||
right: data.regionComparison.right,
|
||
independentScales: data.regionComparison.independentScales || false,
|
||
unit: data.regionComparison.unit || 'руб./кг',
|
||
regionLabel: `${subject.name} · Сравнение регионов · ${data.regionComparison.unit || 'руб./кг'}`
|
||
})
|
||
}
|
||
|
||
// 2) Собираем DOCX
|
||
return buildDocument({ subject, period, data, text, meta, charts })
|
||
}
|
||
|
||
module.exports = {
|
||
generateReport,
|
||
PALETTE,
|
||
// Экспортируем внутренности для возможности кастомизации
|
||
charts: {
|
||
chart1_priceAndMargin,
|
||
chart2_leaders,
|
||
chart3_ebitdaByOrg,
|
||
chart4_regionCompare,
|
||
chart5_scenarioMargins,
|
||
}
|
||
}
|