// lib/calculators/soap.ts // Калькулятор мыла для frontend import type { Calculator, CalculatorField, CalculationResult } from '@/types/calculator'; const fieldSchema: CalculatorField[] = [ { 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, group: 'packaging' }, { id: 'filler', name: 'filler', label: 'Наполнитель, руб', type: 'number', required: false, group: 'packaging' }, { id: 'ribbon', name: 'ribbon', label: 'Лента, руб', type: 'number', required: false, group: 'packaging' }, { id: 'labelValue', name: 'labelValue', label: 'Наклейка, руб', type: 'number', required: false, group: 'packaging' }, { id: 'markup', name: 'markup', label: 'Наценка, %', type: 'number', required: false }, ]; function round(val: number): number { return Math.round(val * 10) / 10; } function calculate(data: Record): CalculationResult { 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 getRequiredFields(): string[] { return fieldSchema.filter((f) => f.required).map((f) => f.name); } function getNumericFields(): string[] { return fieldSchema.filter((f) => f.type === 'number').map((f) => f.name); } const soapCalculator: Calculator = { id: 'soap', name: 'Мыло', fieldSchema, calculate, getRequiredFields, getNumericFields, }; export default soapCalculator;