// Конфигурация калькулятора свечей
import { CalculatorConfig } from '@/lib/calculator-types';
import { calculateCandleStep, calculateCandleSubtotal, round } from './calc';
export const candlesCalculatorConfig: CalculatorConfig = {
id: 'candles',
name: 'Калькулятор свечей',
description: 'Расчет себестоимости свечей ручной работы',
icon: '🕯️',
fields: [
{
id: 'candleName',
type: 'text',
label: 'Название свечи',
placeholder: 'Введите название',
defaultValue: '',
gridCols: 1,
required: false,
},
{
id: 'photo',
type: 'file',
label: 'Фото свечи (необязательно)',
accept: 'image/*',
gridCols: 1,
required: false,
},
{
id: 'waxWeight',
type: 'number',
label: 'Вес воска, г',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'wax',
showStepAfter: 'wax',
},
{
id: 'waxPrice',
type: 'number',
label: 'Цена воска за 1 кг, руб',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'wax',
},
{
id: 'wickCount',
type: 'number',
label: 'Количество фитилей',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'wick',
showStepAfter: 'wick',
},
{
id: 'wickPrice',
type: 'number',
label: 'Цена одного фитиля, руб',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'wick',
},
{
id: 'fragrancePrice',
type: 'number',
label: 'Цена отдушки, руб',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'fragrance',
showStepAfter: 'fragrance',
},
{
id: 'fragranceWeight',
type: 'number',
label: 'Фасовка отдушки, г',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'fragrance',
},
{
id: 'dyePrice',
type: 'number',
label: 'Цена красителя, руб',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'dye',
showStepAfter: 'dye',
},
{
id: 'dyeWeight',
type: 'number',
label: 'Фасовка красителя, г',
defaultValue: '',
gridCols: 2,
required: false,
groupName: 'dye',
},
{
id: 'moldPrice',
type: 'number',
label: 'Стоимость формы/банки, руб',
defaultValue: '',
gridCols: 1,
required: false,
groupName: 'mold',
showStepAfter: 'mold',
},
{
id: 'packaging',
type: 'number',
label: 'Упаковка, руб',
defaultValue: '',
gridCols: 1,
required: false,
groupName: 'packaging',
showStepAfter: 'packaging',
},
{
id: 'markup',
type: 'number',
label: 'Наценка, %',
defaultValue: '',
gridCols: 2,
required: false,
},
],
calculationSteps: [
{
id: 'wax',
name: 'Себестоимость воска',
formula: (values) => round(calculateCandleStep('wax', values)),
formulaDescription: '(вес_воска / 1000) * цена_воска',
},
{
id: 'wick',
name: 'Себестоимость фитилей',
formula: (values) => round(calculateCandleStep('wick', values)),
formulaDescription: 'количество_фитилей * цена_фитиля',
},
{
id: 'fragrance',
name: 'Себестоимость отдушки (10 %)',
formula: (values) => round(calculateCandleStep('fragrance', values)),
formulaDescription: '((вес_воска * 0.10) / фасовка_отдушки) * цена_отдушки',
},
{
id: 'dye',
name: 'Себестоимость красителя (1 %)',
formula: (values) => round(calculateCandleStep('dye', values)),
formulaDescription: '((вес_воска * 0.01) / фасовка_красителя) * цена_красителя',
},
{
id: 'mold',
name: 'Стоимость формы/банки',
formula: (values) => {
const moldPrice = values.moldPrice || 0;
// Предположим, форма рассчитана на 100 использований
return round(moldPrice / 100);
},
formulaDescription: 'стоимость_формы / 100',
},
{
id: 'packaging',
name: 'Стоимость упаковки',
formula: (values) => {
const packaging = values.packaging || 0;
return round(packaging);
},
formulaDescription: 'стоимость_упаковки',
},
],
subtotals: [
{
id: 'operational',
name: 'Операционные расходы (5 %)',
formula: (values, steps) => round(calculateCandleSubtotal('operational', values, steps)),
formulaDescription: '(воск + фитили + отдушка + краситель + форма + упаковка) * 0.05',
},
{
id: 'total',
name: 'Итого себестоимость',
formula: (values, steps) => round(calculateCandleSubtotal('total', values, steps)),
highlight: true,
formulaDescription: 'воск + фитили + отдушка + краситель + форма + упаковка + операционные',
},
],
additionalCalculations: [
{
id: 'finalPrice',
name: 'Итоговая цена с наценкой',
formula: (values, steps, subtotals) => {
const total = subtotals.total || 0;
const markup = values.markup || 0;
return round(total * (1 + markup / 100));
},
formulaDescription: 'итого_себестоимость * (1 + наценка / 100)',
},
{
id: 'pricePer100g',
name: 'Цена за 100 г',
formula: (values, steps, subtotals, additional) => {
const weight = values.waxWeight || 0;
const finalPrice = additional?.finalPrice || 0;
if (weight > 0) {
return round((finalPrice / weight) * 100);
}
return 0;
},
formulaDescription: '(итоговая_цена / вес_воска) * 100',
},
],
formatTelegramMessage: (values, steps, subtotals, additional) => {
const candleName = values.candleName || 'Без названия';
const waxWeight = values.waxWeight || 0;
const wickCount = values.wickCount || 0;
const packaging = values.packaging || 0;
const markup = values.markup || 0;
const totalCost = subtotals.total || 0;
const finalPrice = additional?.finalPrice || 0;
const pricePer100g = additional?.pricePer100g || 0;
let text = `🕯️ Расчёт свечи: ${candleName}\n\n`;
text += `⚖️ Вес воска: ${waxWeight} г\n`;
text += `🕯️ Количество фитилей: ${wickCount} шт\n`;
text += `📦 Упаковка: ${packaging} ₽\n\n`;
text += `💹 Наценка: ${markup}%\n\n`;
text += `📊 Итоги расчёта:\n`;
text += ` 💵 Себестоимость: ${totalCost.toFixed(1)} ₽\n`;
text += ` 🎯 Итоговая цена с наценкой: ${finalPrice.toFixed(1)} ₽\n`;
text += ` ⚗️ Цена за 100 г: ${pricePer100g.toFixed(1)} ₽`;
return text;
},
};