548 lines
26 KiB
JavaScript
548 lines
26 KiB
JavaScript
// pdfFillDataPGE.js
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const cheerio = require('cheerio'); // Библиотека для парсинга
|
||
const pdfFillData = require('./pdfFillData'); // Родительский класс
|
||
const { rgb } = require('pdf-lib');
|
||
const randomData = require('./randomDataGenerator');
|
||
|
||
class pdfFillDataPGE extends pdfFillData {
|
||
constructor() {
|
||
super('PGE');
|
||
this.baselineCorrectionFactor = 0.85;
|
||
|
||
// --- Свойства для динамических данных (СТР. 1) ---
|
||
this.service_for_name = '';
|
||
this.service_for_address = '';
|
||
this.account_no = '';
|
||
this.statement_date = '';
|
||
this.due_date = '';
|
||
|
||
// Account Summary
|
||
this.previous_statement = '';
|
||
this.payment_received = '';
|
||
this.previous_unpaid_balance = '';
|
||
this.pge_delivery_charges = '';
|
||
this.svce_generation_charges = '';
|
||
this.total_amount_due_date = ''; // e.g., "08/28/2019"
|
||
this.total_amount_due = '';
|
||
|
||
// Remittance Slip (отрывной купон)
|
||
this.remit_account_number = '';
|
||
this.remit_due_date = '';
|
||
this.remit_total_amount_due = '';
|
||
|
||
// --- ДАННЫЕ ДЛЯ ГРАФИКОВ ---
|
||
this.monthly_billing_history = []; // Массив объектов { month, year, electric, gas }
|
||
this.daily_usage_electric = {}; // { year_ago, last_period, current_period }
|
||
this.daily_usage_gas = {}; // { year_ago, last_period, current_period }
|
||
|
||
this.electric_conservation_incentive = '';
|
||
this.electric_transmission = '';
|
||
this.electric_distribution = '';
|
||
this.electric_public_purpose = '';
|
||
this.electric_nuclear_decommissioning = '';
|
||
this.electric_dwr_bond = '';
|
||
this.electric_ctc = '';
|
||
this.electric_ecra = '';
|
||
this.electric_pcia = '';
|
||
this.electric_taxes_and_other = '';
|
||
this.electric_total_charges = '';
|
||
|
||
// --- СВОЙСТВА ДЛЯ СТР. 3 ---
|
||
this.delivery_charges_period = '';
|
||
this.service_agreement_id = '';
|
||
this.rate_schedule = '';
|
||
this.meter_number = '';
|
||
this.current_meter_reading = '';
|
||
this.prior_meter_reading = '';
|
||
this.total_usage_kwh = '';
|
||
this.baseline_territory = '';
|
||
this.heat_source = '';
|
||
this.tier1_allowance_detail = '';
|
||
this.tier1_usage_amount = '';
|
||
this.tier2_usage_amount = '';
|
||
this.generation_credit = '';
|
||
this.pcia_adjustment = '';
|
||
this.franchise_fee_surcharge = '';
|
||
this.electric_usage_period_title = '';
|
||
this.daily_electric_usage_history = [];
|
||
// В constructor()
|
||
this.average_daily_usage = 0;
|
||
|
||
this.svce_rate_schedule = '';
|
||
this.svce_generation_detail = '';
|
||
this.svce_generation_amount = '';
|
||
this.svce_energy_surcharge = '';
|
||
this.svce_total_charges = '';
|
||
|
||
// --- СВОЙСТВА ДЛЯ СТР. 5 (Gas Charges) ---
|
||
this.gas_charges_period = '';
|
||
this.gas_service_agreement_id = '';
|
||
this.gas_rate_schedule = '';
|
||
this.gas_meter_number = '';
|
||
this.gas_current_reading = '';
|
||
this.gas_prior_reading = '';
|
||
this.gas_difference = '';
|
||
this.gas_multiplier = '';
|
||
this.gas_total_usage = '';
|
||
this.gas_baseline_territory = '';
|
||
this.gas_serial = '';
|
||
this.gas_tier1_allowance_detail = '';
|
||
this.gas_tier1_usage_detail = '';
|
||
this.gas_tier1_usage_amount = '';
|
||
this.gas_ppp_surcharge_detail = '';
|
||
this.gas_ppp_surcharge_amount = '';
|
||
this.gas_total_charges = '';
|
||
this.gas_procurement_period = '';
|
||
this.gas_procurement_amount = '';
|
||
this.gas_usage_period_title = '';
|
||
this.gas_average_daily_usage = 0;
|
||
this.daily_gas_usage_history = [];
|
||
|
||
this.fontMap = {
|
||
// "Имя шрифта из SVG-атрибута font-family": индекс_из_routes.js
|
||
'Helvetica': 0, // Базовый шрифт, всегда индекс 0
|
||
'Arial-BoldMT': 1,
|
||
'Arial': 2,
|
||
'ArialNarrow-Bold': 3,
|
||
'ArialNarrow': 4,
|
||
'Arial-ItalicMT': 5,
|
||
'MyriadPro-Regular': 2,
|
||
|
||
// Добавьте другие шрифты, если они есть в SVG
|
||
};
|
||
|
||
|
||
}
|
||
|
||
async setFields(fields) {
|
||
if (!fields || Object.keys(fields).length === 0) {
|
||
fields = randomData.pge(); // <-- Замените на entergy(), aep_ohio() и т.д.
|
||
}
|
||
this.service_for_name = fields.service_for_name;
|
||
this.service_for_address = fields.service_for_address;
|
||
this.account_no = fields.account_no;
|
||
this.statement_date = fields.statement_date;
|
||
this.due_date = fields.due_date;
|
||
|
||
this.previous_statement = fields.previous_statement;
|
||
this.payment_received = fields.payment_received;
|
||
this.previous_unpaid_balance = fields.previous_unpaid_balance;
|
||
this.pge_delivery_charges = fields.pge_delivery_charges;
|
||
this.svce_generation_charges = fields.svce_generation_charges;
|
||
this.total_amount_due_date = fields.total_amount_due_date;
|
||
this.total_amount_due = fields.total_amount_due;
|
||
|
||
this.remit_account_number = fields.remit_account_number;
|
||
this.remit_due_date = fields.remit_due_date;
|
||
this.remit_total_amount_due = fields.remit_total_amount_due;
|
||
|
||
// Данные для графиков
|
||
this.monthly_billing_history = fields.monthly_billing_history || [];
|
||
this.daily_usage_electric = fields.daily_usage_electric || {};
|
||
this.daily_usage_gas = fields.daily_usage_gas || {};
|
||
|
||
this.electric_conservation_incentive = fields.electric_conservation_incentive;
|
||
this.electric_transmission = fields.electric_transmission;
|
||
this.electric_distribution = fields.electric_distribution;
|
||
this.electric_public_purpose = fields.electric_public_purpose;
|
||
this.electric_nuclear_decommissioning = fields.electric_nuclear_decommissioning;
|
||
this.electric_dwr_bond = fields.electric_dwr_bond;
|
||
this.electric_ctc = fields.electric_ctc;
|
||
this.electric_ecra = fields.electric_ecra;
|
||
this.electric_pcia = fields.electric_pcia;
|
||
this.electric_taxes_and_other = fields.electric_taxes_and_other;
|
||
this.electric_total_charges = fields.electric_total_charges;
|
||
|
||
// --- ДАННЫЕ ДЛЯ СТР. 3 ---
|
||
this.delivery_charges_period = fields.delivery_charges_period;
|
||
this.service_agreement_id = fields.service_agreement_id;
|
||
this.rate_schedule = fields.rate_schedule;
|
||
this.meter_number = fields.meter_number;
|
||
this.current_meter_reading = fields.current_meter_reading;
|
||
this.prior_meter_reading = fields.prior_meter_reading;
|
||
this.total_usage_kwh = fields.total_usage_kwh;
|
||
this.baseline_territory = fields.baseline_territory;
|
||
this.heat_source = fields.heat_source;
|
||
this.tier1_allowance_detail = fields.tier1_allowance_detail;
|
||
this.tier1_usage_amount = fields.tier1_usage_amount;
|
||
this.tier2_usage_amount = fields.tier2_usage_amount;
|
||
this.generation_credit = fields.generation_credit;
|
||
this.pcia_adjustment = fields.pcia_adjustment;
|
||
this.franchise_fee_surcharge = fields.franchise_fee_surcharge;
|
||
this.electric_usage_period_title = fields.electric_usage_period_title;
|
||
|
||
this.svce_rate_schedule = fields.svce_rate_schedule;
|
||
this.svce_generation_detail = fields.svce_generation_detail;
|
||
this.svce_generation_amount = fields.svce_generation_amount;
|
||
this.svce_energy_surcharge = fields.svce_energy_surcharge;
|
||
this.svce_total_charges = fields.svce_total_charges;
|
||
|
||
// --- ДАННЫЕ ДЛЯ СТР. 5 ---
|
||
this.gas_charges_period = fields.gas_charges_period;
|
||
this.gas_service_agreement_id = fields.gas_service_agreement_id;
|
||
this.gas_rate_schedule = fields.gas_rate_schedule;
|
||
this.gas_meter_number = fields.gas_meter_number;
|
||
this.gas_current_reading = fields.gas_current_reading;
|
||
this.gas_prior_reading = fields.gas_prior_reading;
|
||
this.gas_difference = fields.gas_difference;
|
||
this.gas_multiplier = fields.gas_multiplier;
|
||
this.gas_total_usage = fields.gas_total_usage;
|
||
this.gas_baseline_territory = fields.gas_baseline_territory;
|
||
this.gas_serial = fields.gas_serial;
|
||
this.gas_tier1_allowance_detail = fields.gas_tier1_allowance_detail;
|
||
this.gas_tier1_usage_detail = fields.gas_tier1_usage_detail;
|
||
this.gas_tier1_usage_amount = fields.gas_tier1_usage_amount;
|
||
this.gas_ppp_surcharge_detail = fields.gas_ppp_surcharge_detail;
|
||
this.gas_ppp_surcharge_amount = fields.gas_ppp_surcharge_amount;
|
||
this.gas_total_charges = fields.gas_total_charges;
|
||
this.gas_procurement_period = fields.gas_procurement_period;
|
||
this.gas_procurement_amount = fields.gas_procurement_amount;
|
||
this.gas_usage_period_title = fields.gas_usage_period_title;
|
||
this.gas_average_daily_usage = parseFloat(fields.gas_average_daily_usage) || 0;
|
||
// В файле pdfFillDataPGE.js, метод setFields()
|
||
|
||
// ... (после строки this.gas_average_daily_usage = ...)
|
||
|
||
// --- НОВАЯ, УМНАЯ ПРОВЕРКА И ПАРСИНГ ---
|
||
if (typeof fields.daily_gas_usage_history === 'string') {
|
||
// Если пришли данные из формы (строка), парсим их
|
||
try {
|
||
this.daily_gas_usage_history = JSON.parse(fields.daily_gas_usage_history || '[]');
|
||
} catch (e) {
|
||
this.daily_gas_usage_history = [];
|
||
console.error("Error parsing daily_gas_usage_history JSON from string");
|
||
}
|
||
} else {
|
||
// Если пришли данные из генератора (уже массив), просто присваиваем
|
||
this.daily_gas_usage_history = fields.daily_gas_usage_history || [];
|
||
}
|
||
|
||
if (typeof fields.daily_electric_usage_history === 'string') {
|
||
try {
|
||
this.daily_electric_usage_history = JSON.parse(fields.daily_electric_usage_history || '[]');
|
||
} catch (e) {
|
||
this.daily_electric_usage_history = [];
|
||
console.error("Error parsing daily_electric_usage_history JSON from string");
|
||
}
|
||
} else {
|
||
this.daily_electric_usage_history = fields.daily_electric_usage_history || [];
|
||
}
|
||
|
||
// Удаляем старый `try/catch` для average_daily_usage, он уже обработан
|
||
this.average_daily_usage = parseFloat(fields.average_daily_usage) || 0;
|
||
}
|
||
/**
|
||
* Универсальный метод для отрисовки столбчатых диаграмм.
|
||
* Имеет два режима:
|
||
* 1. ТОЧНЫЙ: Если находит в SVG метки id="chart-label-start" и id="chart-label-end",
|
||
* строит сетку между их центрами.
|
||
* 2. ЗАПАСНОЙ: Если метки не найдены, строит равномерную сетку по всей ширине
|
||
* контейнера id="chart-area".
|
||
* @param {object} options - Объект с параметрами для диаграммы.
|
||
*/
|
||
async _drawBarChart(options) {
|
||
const { ipage, $, historyData, maxAxisValue, barWidth, electricColor, gasColor } = options;
|
||
|
||
if (!historyData || historyData.length === 0) return;
|
||
|
||
const page = this.getPageByIndex(ipage);
|
||
if (!page) return;
|
||
const pageHeight = this.getPageHeight(ipage);
|
||
|
||
const chartRect = $('#chart-area');
|
||
if (chartRect.length === 0) {
|
||
console.error(`Could not find boundary element with id='chart-area' in SVG for page ${ipage}.`);
|
||
return;
|
||
}
|
||
|
||
const chartArea = {
|
||
x_ill: parseFloat(chartRect.attr('x')),
|
||
y_ill: parseFloat(chartRect.attr('y')),
|
||
width: parseFloat(chartRect.attr('width')),
|
||
height: parseFloat(chartRect.attr('height'))
|
||
};
|
||
if (Object.values(chartArea).some(isNaN)) {
|
||
console.error(`Invalid attributes for #chart-area in SVG for page ${ipage}.`);
|
||
return;
|
||
}
|
||
|
||
// --- АЛГОРИТМ ВЫБОРА РЕЖИМА ---
|
||
const startLabel = $('#chart-label-start');
|
||
const endLabel = $('#chart-label-end');
|
||
const numBars = historyData.length;
|
||
|
||
let startPointX, stepX;
|
||
|
||
if (startLabel.length > 0 && endLabel.length > 0) {
|
||
// --- РЕЖИМ 1: ТОЧНЫЙ (по меткам) ---
|
||
console.log(`Page ${ipage} chart: Using 'chart-label-start/end' for precise layout.`);
|
||
|
||
const getLabelCenter = (element) => {
|
||
const transformAttr = element.attr('transform');
|
||
const matrix = transformAttr ? transformAttr.match(/matrix\(([^)]+)\)/) : null;
|
||
if (!matrix) return NaN;
|
||
const [scaleX, , , , x_svg] = matrix[1].split(/[ ,]+/).map(parseFloat);
|
||
const font = this.getCustomerFontByIndex(0);
|
||
const textWidth = font.widthOfTextAtSize(element.text(), 7 * scaleX);
|
||
return x_svg + (textWidth / 2);
|
||
};
|
||
|
||
startPointX = getLabelCenter(startLabel);
|
||
const endPointX = getLabelCenter(endLabel);
|
||
|
||
if (isNaN(startPointX) || isNaN(endPointX)) {
|
||
console.error("Could not parse coordinates from start/end labels.");
|
||
return;
|
||
}
|
||
|
||
stepX = (numBars > 1) ? (endPointX - startPointX) / (numBars - 1) : 0;
|
||
|
||
} else {
|
||
// --- РЕЖИМ 2: ЗАПАСНОЙ (по ширине chart-area) ---
|
||
console.log(`Page ${ipage} chart: Using '#chart-area' for uniform layout.`);
|
||
|
||
const spacePerBar = chartArea.width / (numBars + 1);
|
||
startPointX = chartArea.x_ill + spacePerBar;
|
||
stepX = spacePerBar;
|
||
}
|
||
|
||
// --- ОБЩАЯ ЛОГИКА ОТРИСОВКИ ---
|
||
historyData.forEach((dataPoint, index) => {
|
||
const electricValue = parseFloat(dataPoint.electric || dataPoint.kwh) || 0;
|
||
const gasValue = parseFloat(dataPoint.gas) || 0;
|
||
const totalValue = electricValue + gasValue;
|
||
|
||
if (totalValue <= 0) return;
|
||
|
||
const electricBarHeight = (electricValue / maxAxisValue) * chartArea.height;
|
||
const gasBarHeight = (gasValue / maxAxisValue) * chartArea.height;
|
||
|
||
const barCenterX = startPointX + (index * stepX);
|
||
const barX = barCenterX - (barWidth / 2);
|
||
const baseY = pageHeight - chartArea.y_ill - chartArea.height;
|
||
|
||
if (gasValue > 0 && gasColor) {
|
||
page.drawRectangle({ x: barX, y: baseY, width: barWidth, height: gasBarHeight, color: gasColor });
|
||
}
|
||
if (electricValue > 0 && electricColor) {
|
||
page.drawRectangle({ x: barX, y: baseY + gasBarHeight, width: barWidth, height: electricBarHeight, color: electricColor });
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Рисует пунктирную линию среднего потребления на графике.
|
||
* @param {number} ipage - Индекс страницы.
|
||
* @param {CheerioAPI} $ - Распарсенный Cheerio объект с содержимым SVG.
|
||
*/
|
||
async _drawAverageLine(ipage, $, average_daily = this.average_daily_usage, max = 30) {
|
||
if (!average_daily || average_daily <= 0) return;
|
||
|
||
const page = this.getPageByIndex(ipage);
|
||
if (!page) return;
|
||
const pageHeight = this.getPageHeight(ipage);
|
||
|
||
const chartRect = $('#chart-area');
|
||
if (chartRect.length === 0) {
|
||
console.error("Could not find #chart-area for average line.");
|
||
return;
|
||
}
|
||
|
||
const chartArea = {
|
||
x_ill: parseFloat(chartRect.attr('x')),
|
||
y_ill: parseFloat(chartRect.attr('y')),
|
||
width: parseFloat(chartRect.attr('width')),
|
||
height: parseFloat(chartRect.attr('height'))
|
||
};
|
||
|
||
if (Object.values(chartArea).some(isNaN)) {
|
||
console.error("Invalid attributes for #chart-area for average line.");
|
||
return;
|
||
}
|
||
|
||
// Вычисляем Y-координату для линии
|
||
const avgLineY = (pageHeight - chartArea.y_ill - chartArea.height) + (average_daily / max) * chartArea.height;
|
||
|
||
// Рисуем линию по всей ширине графика
|
||
page.drawLine({
|
||
start: { x: chartArea.x_ill, y: avgLineY },
|
||
end: { x: chartArea.x_ill + chartArea.width, y: avgLineY },
|
||
thickness: 0.5,
|
||
color: rgb(0, 0, 0),
|
||
dashArray: [3, 3],
|
||
});
|
||
}
|
||
|
||
// --- Новый главный метод отрисовки ---
|
||
// В файле pdfFillDataPGE.js
|
||
|
||
// --- ПОЛНОСТЬЮ ЗАМЕНИТЕ СТАРЫЙ МЕТОД draw() НА ЭТОТ ---
|
||
|
||
async draw() {
|
||
const svgDir = path.join(__dirname, `../../../public/template/svg/pge/`);
|
||
|
||
const replacements = {
|
||
// Заголовок
|
||
'1234567890-1': this.account_no,
|
||
'09/07/2019': this.statement_date,
|
||
'09/28/2019': this.due_date,
|
||
|
||
// Service For
|
||
'SPARKY JOULE': this.service_for_name,
|
||
'12345 ENERGY CT': this.service_for_address,
|
||
|
||
// Account Summary
|
||
'$91.57': "$" + this.previous_statement,
|
||
'-91.57': this.payment_received,
|
||
'$0.00': "$" + this.previous_unpaid_balance,
|
||
'$55.66': "$" + this.pge_delivery_charges,
|
||
'$32.48': "$" + this.svce_generation_charges,
|
||
'08/28/2019': this.total_amount_due_date,
|
||
'$88.14': "$" + this.total_amount_due,
|
||
|
||
// Remittance Slip (отрывной купон)
|
||
// Примечание: '123456789-1' в SVG может быть другим текстом, чем '1234567890-1'
|
||
// Проверьте SVG и используйте правильный ключ. Для примера я использую два разных.
|
||
'123456789-1': this.remit_account_number,
|
||
// Дата и сумма на купоне могут совпадать с основными, но могут и отличаться,
|
||
// поэтому используем отдельные переменные.
|
||
// '09/28/2019': this.remit_due_date, // Конфликтует с Due Date в заголовке
|
||
// '$88.14': this.remit_total_amount_due, // Конфликтует с Total Amount Due выше
|
||
|
||
// Daily Usage Comparison (маленькие графики)
|
||
'12.50': this.daily_usage_gas.year_ago,
|
||
'12.16': this.daily_usage_gas.last_period,
|
||
'12.67': this.daily_usage_gas.current_period,
|
||
'0.12': this.daily_usage_electric.year_ago,
|
||
'0.16': this.daily_usage_electric.last_period,
|
||
'0.17': this.daily_usage_electric.current_period,
|
||
|
||
// --- НОВЫЕ ПЛЕЙСХОЛДЕРЫ СО СТРАНИЦЫ 2 ---
|
||
'-$9.50': "-$" + this.electric_conservation_incentive * -1,
|
||
'12.42': this.electric_transmission,
|
||
'35.08': this.electric_distribution,
|
||
'4.71': this.electric_public_purpose,
|
||
'0.33': this.electric_nuclear_decommissioning,
|
||
'1.91': this.electric_dwr_bond,
|
||
'0.42': this.electric_ctc,
|
||
'-0.22': this.electric_ecra,
|
||
'10.26': this.electric_pcia,
|
||
'0.25': this.electric_taxes_and_other,
|
||
|
||
// --- ПЛЕЙСХОЛДЕРЫ СО СТР. 3 ---
|
||
'08/02/2019 - 08/31/2019 (30 billing days)': this.delivery_charges_period,
|
||
'Service For: 12345 ENERGY CT': `Service For: ${this.service_for_address}`,
|
||
'Service Agreement ID: 111111111': `Service Agreement ID: ${this.service_agreement_id}`,
|
||
'Rate Schedule: E1 X Residential Service': `Rate Schedule: ${this.rate_schedule}`,
|
||
'1111111111': this.meter_number,
|
||
'37,710': this.current_meter_reading,
|
||
'37,330': this.prior_meter_reading,
|
||
'380.000000 kWh': this.total_usage_kwh,
|
||
'X': this.baseline_territory,
|
||
'B - Not Electric': this.heat_source,
|
||
'297.00 kWh (30 days x 9.9 kWh/day)': this.tier1_allowance_detail,
|
||
'$66.46': this.tier1_usage_amount,
|
||
'23.37': this.tier2_usage_amount,
|
||
'-44.68': this.generation_credit,
|
||
'10.26': this.pcia_adjustment,
|
||
'0.25': this.franchise_fee_surcharge,
|
||
'Electric Usage This Period: 380.000000 kWh, 30 billing days': this.electric_usage_period_title,
|
||
|
||
// --- НОВЫЕ ПЛЕЙСХОЛДЕРЫ СО СТРАНИЦЫ 4 ---
|
||
'E-1': this.svce_rate_schedule,
|
||
'380.000000 kWh @ $0.08519': this.svce_generation_detail,
|
||
'380.000000 kWh': `${this.svce_generation_detail.split(" ")[0]} kWh`,
|
||
'$32.37': "$" + this.svce_generation_amount,
|
||
'32.37': this.svce_generation_amount,
|
||
'0.11': this.svce_energy_surcharge,
|
||
'$32.48': "$" + this.svce_total_charges,
|
||
|
||
// --- ПЛЕЙСХОЛДЕРЫ СО СТРАНИЦЫ 5 ---
|
||
'08/02/2019 - 08/31/2019 (30 billing days)': this.gas_charges_period,
|
||
'Service Agreement ID: 1111111111': `Service Agreement ID: ${this.gas_service_agreement_id}`,
|
||
'Rate Schedule: G1 X Residential Service': `Rate Schedule: ${this.gas_rate_schedule}`,
|
||
'11111111': this.gas_meter_number,
|
||
'2,588': this.gas_current_reading,
|
||
'2,583': this.gas_prior_reading,
|
||
'diff5': this.gas_difference,
|
||
'1.031647': this.gas_multiplier,
|
||
'5.000000 Therms': this.gas_total_usage,
|
||
// 'X': this.gas_baseline_territory, // "X" слишком общий, может вызвать проблемы
|
||
// 'G': this.gas_serial, // "G" слишком общий
|
||
'17.70 Therms (30 days x 0.59 Therms/day)': this.gas_tier1_allowance_detail,
|
||
'5.000000 Therms @ $1.28395': this.gas_tier1_usage_detail,
|
||
'$6.42': "$" + this.gas_tier1_usage_amount,
|
||
'($0.09047 /Therm)': "$" + this.gas_ppp_surcharge_detail,
|
||
'0.45': this.gas_ppp_surcharge_amount,
|
||
'$6.87': "$" + this.gas_total_charges,
|
||
'07/02/2019 - 07/31/2019': this.gas_procurement_period,
|
||
'$0.28462': "$" + this.gas_procurement_amount,
|
||
'Gas Usage This Period: 5.000000 Therms, 30 billing days': this.gas_usage_period_title,
|
||
};
|
||
|
||
|
||
for (let i = 0; i < this.countPages(); i++) {
|
||
const svgPath = path.join(svgDir, `${i + 1}.svg`);
|
||
if (fs.existsSync(svgPath)) {
|
||
console.log(`Processing all elements for page ${i}: ${svgPath}`);
|
||
|
||
// --- ПАРСИМ SVG ОДИН РАЗ НА СТРАНИЦУ ---
|
||
const svgContent = fs.readFileSync(svgPath, 'utf8');
|
||
const $ = cheerio.load(svgContent, { xmlMode: true });
|
||
|
||
// --- ВЫЗЫВАЕМ СПЕЦИФИЧНЫЕ ДЛЯ СТРАНИЦЫ ФУНКЦИИ ---
|
||
|
||
// Графики на первой странице (индекс 0)
|
||
// График на первой странице
|
||
if (i === 0) {
|
||
await this._drawBarChart({
|
||
ipage: i,
|
||
$: $,
|
||
historyData: this.monthly_billing_history,
|
||
maxAxisValue: 200,
|
||
barWidth: 6.5,
|
||
electricColor: rgb(0, 0, 0),
|
||
gasColor: rgb(0.8, 0.8, 0.8)
|
||
});
|
||
}
|
||
|
||
// Графики на третьей странице (индекс 2)
|
||
if (i === 2) {
|
||
await this._drawBarChart({
|
||
ipage: i,
|
||
$: $, // Передаем распарсенный объект
|
||
historyData: this.daily_electric_usage_history,
|
||
maxAxisValue: 30,
|
||
barWidth: 4,
|
||
electricColor: rgb(0, 0, 0),
|
||
gasColor: null
|
||
});
|
||
|
||
await this._drawAverageLine(i, $); // Вызываем отрисовку средней линии
|
||
}
|
||
|
||
if (i === 4) { // График на пятой странице (индекс 4)
|
||
await this._drawBarChart({
|
||
ipage: i,
|
||
$: $,
|
||
historyData: this.daily_gas_usage_history,
|
||
maxAxisValue: 5, // Максимум на оси Y для газа
|
||
barWidth: 4,
|
||
electricColor: null,
|
||
gasColor: rgb(0.8, 0.8, 0.8)
|
||
});
|
||
|
||
// Рисуем линию среднего, если нужно
|
||
await this._drawAverageLine(i, $, this.gas_average_daily_usage, 5);
|
||
}
|
||
// Текст рисуется для каждой страницы в конце
|
||
await super.parseAndDrawSVG(i, $, replacements);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
module.exports = pdfFillDataPGE; |