66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import type { IngredientNutritionItem } from "@/types/ingredient-catalog.types";
|
|
|
|
export interface MacroTotals {
|
|
calories: number;
|
|
protein: number;
|
|
fat: number;
|
|
carbs: number;
|
|
}
|
|
|
|
export interface MacroIngredientInput {
|
|
catalogItemId?: number | null;
|
|
amountGrams?: number | null;
|
|
unit?: string | null;
|
|
name?: string;
|
|
}
|
|
|
|
export function hasNonMacroUnit(unit?: string | null): boolean {
|
|
if (!unit?.trim()) return false;
|
|
const u = unit.trim().toLowerCase();
|
|
return u === "do smaku" || u === "optional" || u === "opcjonalnie" || u === "szczypta";
|
|
}
|
|
|
|
export function shouldIncludeIngredientInMacroSum(ing: MacroIngredientInput): boolean {
|
|
return Boolean(
|
|
ing.catalogItemId && ing.amountGrams != null && ing.amountGrams > 0 && !hasNonMacroUnit(ing.unit),
|
|
);
|
|
}
|
|
|
|
export function isUnlinkedMacroIngredient(ing: MacroIngredientInput): boolean {
|
|
if (!ing.name?.trim()) return false;
|
|
if (hasNonMacroUnit(ing.unit)) return false;
|
|
return Boolean(ing.amountGrams != null && ing.amountGrams > 0 && !ing.catalogItemId);
|
|
}
|
|
|
|
export function countUnlinkedMacroIngredients(ingredients: MacroIngredientInput[]): number {
|
|
return ingredients.filter(isUnlinkedMacroIngredient).length;
|
|
}
|
|
|
|
export function estimateMacrosFromCatalog(
|
|
ingredients: MacroIngredientInput[],
|
|
catalogItems: Pick<
|
|
IngredientNutritionItem,
|
|
"id" | "caloriesPer100G" | "proteinGPer100G" | "fatGPer100G" | "carbsGPer100G"
|
|
>[],
|
|
): MacroTotals | null {
|
|
let calories = 0;
|
|
let protein = 0;
|
|
let fat = 0;
|
|
let carbs = 0;
|
|
let hasAny = false;
|
|
|
|
for (const ing of ingredients) {
|
|
if (!shouldIncludeIngredientInMacroSum(ing)) continue;
|
|
const cat = catalogItems.find((c) => c.id === ing.catalogItemId);
|
|
if (!cat) continue;
|
|
const scale = Number(ing.amountGrams) / 100;
|
|
calories += Math.round(cat.caloriesPer100G * scale);
|
|
protein += cat.proteinGPer100G * scale;
|
|
fat += cat.fatGPer100G * scale;
|
|
carbs += cat.carbsGPer100G * scale;
|
|
hasAny = true;
|
|
}
|
|
|
|
return hasAny ? { calories, protein, fat, carbs } : null;
|
|
}
|