DoSoapCalc/backend/calculators/candle.js

115 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// calculators/candle.js
// Калькулятор свечей (пример нового калькулятора)
/**
* Схема полей калькулятора
*/
const fieldSchema = [
{ id: 'candleName', name: 'candleName', label: 'Название свечи', type: 'text', required: true },
{ id: 'weight', name: 'weight', label: 'Вес свечи, г', type: 'number', required: true },
{ id: 'waxPrice', name: 'waxPrice', label: 'Цена воска за 1 кг, руб', type: 'number', required: false },
{ id: 'wickPrice', name: 'wickPrice', label: 'Цена фитиля, руб', type: 'number', required: false },
{ id: 'aromaPrice', name: 'aromaPrice', label: 'Цена отдушки, руб', type: 'number', required: false },
{ id: 'aromaWeight', name: 'aromaWeight', label: 'Фасовка отдушки, г', type: 'number', required: false },
{ id: 'moldPrice', name: 'moldPrice', label: 'Цена формы, руб', type: 'number', required: false },
{ id: 'box', name: 'box', label: 'Упаковка, руб', type: 'number', required: false },
{ id: 'markup', name: 'markup', label: 'Наценка, %', type: 'number', required: false },
];
/**
* Расчёт себестоимости свечи
* @param {Object} data - Данные для расчёта
* @returns {Object} Результаты расчёта
*/
function calculate(data) {
const {
weight = 0,
waxPrice = 0,
wickPrice = 0,
aromaPrice = 0,
aromaWeight = 1,
moldPrice = 0,
box = 0,
} = data;
const wax = (weight / 1000) * waxPrice;
const wick = wickPrice;
const aroma = ((weight * 0.08) / aromaWeight) * aromaPrice; // 8% отдушки для свечей
const mold = moldPrice / 50; // Амортизация формы на 50 свечей
const packaging = box;
const subtotal = wax + wick + aroma + mold + packaging;
const operational = subtotal * 0.05;
const total = subtotal + operational;
return {
wax: round(wax),
wick: round(wick),
aroma: round(aroma),
mold: round(mold),
packaging: round(packaging),
operational: round(operational),
total: round(total),
};
}
function round(val) {
return Math.round(val * 10) / 10;
}
/**
* Форматирует сообщение для Telegram
* @param {Object} data - Исходные данные
* @param {Object} result - Результаты расчёта
* @returns {string} Отформатированное сообщение
*/
function formatMessage(data, result) {
const {
candleName,
weight = 0,
box = 0,
markup = 0,
totalCost,
finalPrice,
pricePer100g,
} = data;
let text = `🕯️ <b>Расчёт свечи:</b> <i>${candleName}</i>\n\n`;
text += `⚖️ <b>Вес свечи:</b> ${weight} г\n\n`;
text += `📦 <b>Упаковка:</b> ${box}\n\n`;
text += `💹 <b>Наценка:</b> ${markup}%\n\n`;
text += `📊 <b>Итоги расчёта:</b>\n`;
text += ` 💵 Себестоимость: ${Number(totalCost).toFixed(1)}\n`;
text += ` 🎯 Итоговая цена с наценкой: ${Number(finalPrice).toFixed(1)}\n`;
text += ` ⚗️ Цена за 100 г: ${Number(pricePer100g).toFixed(1)}`;
return text;
}
/**
* Получить обязательные поля для валидации
* @returns {string[]} Массив имён обязательных полей
*/
function getRequiredFields() {
return fieldSchema.filter((f) => f.required).map((f) => f.name);
}
/**
* Получить числовые поля для валидации
* @returns {string[]} Массив имён числовых полей
*/
function getNumericFields() {
return fieldSchema.filter((f) => f.type === 'number').map((f) => f.name);
}
module.exports = {
id: 'candle',
name: 'Свеча',
fieldSchema,
calculate,
formatMessage,
getRequiredFields,
getNumericFields,
};