DoSoapCalc/backend/calculators/soap.js

126 lines
4.6 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/soap.js
// Калькулятор мыла
/**
* Схема полей калькулятора
*/
const fieldSchema = [
{ id: 'soapName', name: 'soapName', label: 'Название мыла', type: 'text', required: true },
{ id: 'weight', name: 'weight', label: 'Вес мыла, г', type: 'number', required: true },
{ id: 'basePrice', name: 'basePrice', label: 'Цена основы, руб', type: 'number', required: false },
{ id: 'aromaPrice', name: 'aromaPrice', label: 'Цена отдушки, руб', type: 'number', required: false },
{ id: 'aromaWeight', name: 'aromaWeight', label: 'Фасовка отдушки, г', type: 'number', required: false },
{ id: 'pigmentPrice', name: 'pigmentPrice', label: 'Цена пигмента, руб', type: 'number', required: false },
{ id: 'pigmentWeight', name: 'pigmentWeight', label: 'Фасовка пигмента, г', type: 'number', required: false },
{ id: 'moldPrice', name: 'moldPrice', label: 'Цена формы, руб', type: 'number', required: false },
{ id: 'box', name: 'box', label: 'Пакет/коробка, руб', type: 'number', required: false },
{ id: 'filler', name: 'filler', label: 'Наполнитель, руб', type: 'number', required: false },
{ id: 'ribbon', name: 'ribbon', label: 'Лента, руб', type: 'number', required: false },
{ id: 'labelValue', name: 'labelValue', 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,
basePrice = 0,
aromaPrice = 0,
aromaWeight = 1,
pigmentPrice = 0,
pigmentWeight = 1,
moldPrice = 0,
packaging = { box: 0, filler: 0, ribbon: 0, label: 0 },
} = data;
const base = (weight / 1000) * basePrice;
const aroma = ((weight * 0.01) / aromaWeight) * aromaPrice;
const pigment = ((weight * 0.005) / pigmentWeight) * pigmentPrice;
const mold = moldPrice / 100;
const packagingCost = (packaging.box || 0) + (packaging.filler || 0) + (packaging.ribbon || 0) + (packaging.label || 0);
const subtotal = base + aroma + pigment + mold + packagingCost;
const operational = subtotal * 0.05;
const total = subtotal + operational;
return {
base: round(base),
aroma: round(aroma),
pigment: round(pigment),
mold: round(mold),
packaging: round(packagingCost),
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 {
soapName,
weight = 0,
box = 0,
filler = 0,
ribbon = 0,
labelValue = 0,
markup = 0,
totalCost,
finalPrice,
pricePer100g,
} = data;
let text = `🧼 <b>Расчёт мыла:</b> <i>${soapName}</i>\n\n`;
text += `⚖️ <b>Вес мыла:</b> ${weight} г\n\n`;
text += `📦 <b>Упаковка:</b>\n`;
text += ` 📥 Пакет/коробка: ${box}\n`;
text += ` 🌾 Наполнитель: ${filler}\n`;
text += ` 🎀 Лента: ${ribbon}\n`;
text += ` 🏷️ Наклейка: ${labelValue}\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: 'soap',
name: 'Мыло',
fieldSchema,
calculate,
formatMessage,
getRequiredFields,
getNumericFields,
};