<?php
declare(strict_types=1);
namespace App\Controller;
use App\Data\NutritionalInfo;
use App\Entity\ProductionRecipe;
use App\Entity\Project;
use App\Entity\ProjectCalcs;
use App\Entity\RawMaterial;
use App\Entity\Recipe;
use App\Entity\RecipeTest;
use App\Entity\RecipeTestRawMaterial;
use App\Entity\Trial;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use http\Exception\InvalidArgumentException;
use phpDocumentor\Reflection\DocBlock\Tags\Method;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\Tests\Compiler\J;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Validator\Constraints\Json;
class ProjectController extends AbstractController
{
private readonly NutritionalInfo $nutricionalAmasada;
/**
* @var array[NutritionalInfo]
*/
private array $nutricionalAntesHorno;
private NutritionalInfo $nutricionalCookie;
/** @var array[NutritionalInfo] */
private array $nutricionalDespuesHorno;
#[Route('/api/projects/info/{project}')]
public function getInfo(Project $project): JsonResponse
{
$testMethods = (new \ReflectionClass(RecipeTest::class))->getProperties();
$toRet = [
"@context" => '/api/contexts/Project',
'@id' => "/api/projects/{$project->getId()}",
"@type" => "Project",
"id" => $project->getId(),
"code" => $project->getCode(),
"type" => $project->getType(),
"name" => $project->getName(),
"state" => $project->getState(),
"category" => "/api/categories/{$project->getCategory()->getId()}",
"humidity" => $project->getHumidity(),
"observations" => $project->getObservations(),
"recipes" => array_map(fn(Recipe $row) => [
'@id' => "/api/recipes/{$row->getId()}",
'id' => $row->getId(),
'phase' => $row->getPhase(),
'code' => $row->getCode(),
'baking' => $row->getBaking(),
'type' => $row->getType(),
'observations' => $row->getObservations(),
'nutriscore' => [],
'tests' => array_map(function (RecipeTest $test) use($testMethods){
$testArray = [];
$testMethod = null;
foreach ($testMethods as $testMethod) {
$methodName = 'get' . str_replace('_', '', ucwords($testMethod->name, '_'));
$methodType = $testMethod->getType()?->getName();
if (is_string($methodType) && !str_starts_with($methodType, 'App')) {
$testArray[$testMethod->name] = match ($methodType) {
'DateTimeInterface' => $test->$methodName()?->format('Y-m-d'),
default => $test?->$methodName(),
};
}
}
return $testArray;
}, $row->getRecipeTests()->toArray())
], $project->getRecipes()->toArray()),
];
return new JsonResponse($toRet);
}
#[Route('/api/project/trials/{project}', name: 'api_project_final_tests')]
public function getFinalTests(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$toRet = [];
foreach ($project->getRecipes() as $recipe) {
foreach($recipe->getRecipeTests() as $recipeTest) {
if ($recipeTest->getFinalTest()) {
$toRet[] = [
'id' => $recipeTest->getId(),
'type' => $recipeTest->getType()
];
}
}
}
return new JsonResponse($toRet);
}
/**
* Obtiene la información del valor de nutriscore y el precio del producto.
* Se llama en la ventana de presentación de la información del producto
*/
#[Route('/api/projects/calc-info/{project}', name: 'api_project_get_calc_info')]
public function calcInfo(Project $project): JsonResponse
{
$calcs = $project->getProjectCalcs();
if ($calcs) {
return new JsonResponse([
'nutriscore' => [
'value' => $calcs->getNutriscoreProductoValor(),
'letter' => $calcs->getNutriscoreProductoLetra(),
],
'price' => [
'amasada' => $calcs->getCosteAmasada(),
'total' => $calcs->getCosteProductoTerminado(),
]
]);
} else {
return new JsonResponse([]);
}
}
#[Route('/api/projects/finished-nutritional-info/{project}', name: 'api_project_get_finished_nutritional_info')]
public function finishedNutritionalInfo(Project $project): JsonResponse
{
$calcs = $project->getProjectCalcs();
if ($calcs) {
return new JsonResponse($calcs->getInformacionNutricionalProducto());
}
return new JsonResponse([]);
}
#[Route('/api/projects/close/{project}', name: 'api_close_project', methods: ["PATCH"])]
public function closeProject(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$recipeTypes = [
'Amasado' => false,
'Topping' => false,
'Relleno' => false,
'Cobertura' => false,
];
$recipes = $project->getRecipes();
foreach ($recipes as $recipe) {
$type = $recipe->getType();
$recipeTypes[$type] = true;
}
$project->setAmasado($recipeTypes['Amasado']);
$project->setTopping($recipeTypes['Topping']);
$project->setRelleno($recipeTypes['Relleno']);
$project->setCobertura($recipeTypes['Cobertura']);
$project->setState('Terminado');
$entityManager->persist($project);
$entityManager->flush();
return new JsonResponse($recipeTypes);
}
#[Route('/api/projects/recipe_ingredients_info/{project}', name: 'api_recipe_ingredients_info')]
public function ingredients(Project $project): JsonResponse
{
$calcs = $project->getProjectCalcs();
if ($calcs) {
return new JsonResponse([
'cookie' => $calcs->getIngredientesCookie(),
'totalPesoCookie' => $calcs->getTotalPesoCookie(),
'humedadHorneado' => $calcs->getHumedadHorneado(),
'perdidaEstimada' => $calcs->getPerdidaEstimada(),
'perdidaEstimadaPorcentaje' => $calcs->getPerdidaEstimadaPorcentaje(),
'totalHorneado' => $calcs->getTotalHorneado(),
'humedadGalleta' => $calcs->getHumedadGalleta(),
'terminado' => $calcs->getIngredientesProductoTerminado(),
]);
} else {
return new JsonResponse([]);
}
}
#[Route('/api/projects/list_costs/{project}', name: 'api_project_costs')]
public function listProjectCosts(Project $project): JsonResponse
{
$calcs = $project->getProjectCalcs();
if ($calcs) {
return new JsonResponse([
'amasada' => array_values($calcs->getCostesAmasada()),
'despuesHorno' => $calcs->getCostesDespuesHorno(),
]);
} else {
return new JsonResponse([]);
}
}
#[Route('/api/projects/list_materials/{project}', name: 'api_project_list_materials')]
public function listProjectMaterials(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$rawMaterials = [];
$totalWeight = 0;
$ingredientesProductoTerminado = $project->getProjectCalcs()?->getIngredientesProductoTerminado();
$rawMaterialsEntity = $entityManager->getRepository(RawMaterial::class);
if ($ingredientesProductoTerminado) {
foreach ($ingredientesProductoTerminado as $ingrediente) {
/** @var RawMaterial $material */
$material = $rawMaterialsEntity->findOneBy(['id' => $ingrediente[4]]);
$rawMaterials[$material->getId()] = [
'id' => $material->getId(),
'code' => $material->getCode(),
'name' => $material->getName(),
'marketName' => $material->getPublicName(),
'quantity' => $ingrediente[3] / 1000, // <- a Kg,
'raw_cost' => $material->getPrice(),
'percentage' => 0
];
$totalWeight += $ingrediente[3];
}
return new JsonResponse(array_map(function($r) use ($totalWeight) {
$r['percentage'] = $r['quantity'] / $totalWeight * 1000;
$r['cost'] = $r['percentage'] * $r['raw_cost'];
return $r;
}, $rawMaterials));
} else {
return new JsonResponse([]);
}
}
/**
* Crea nuevas pruebas finales para las recetas en producción así como un ensayo usando esas pruebas
*/
#[Route('/api/projects/production-recipes/{project}', name: 'api_project_create_production_recipes', methods: ["POST"])]
public function createProductionRecipes(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$params = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
$recetasFinalesProyecto = $entityManager->getRepository(Project::class)->getFinalRecipesIds($project->getId());
//var_dump($recetasFinalesProyecto);
foreach ($recetasFinalesProyecto as $idReceta) {
//echo "Comprando {$idReceta}\n";
if (array_search($idReceta, array_column($params, 'id')) === false) {
return new JsonResponse([], \Symfony\Component\HttpFoundation\Response::HTTP_SERVICE_UNAVAILABLE);
}
}
//return new JsonResponse(['msg' => 'Todas las recetas encontradas']);
$entityManager->getRepository(Project::class)->createRecipes($project->getId(), $params);
return new JsonResponse([], \Symfony\Component\HttpFoundation\Response::HTTP_CREATED);
}
#[Route('/api/list/by-category', name: 'api_projects_by_category')]
public function listByType(EntityManagerInterface $entityManager): JsonResponse
{
return new JsonResponse($entityManager->getRepository(Project::class)->getListado(), \Symfony\Component\HttpFoundation\Response::HTTP_OK);
}
#[Route('/api/list/by-category-dates/{fechaInicio1}/{fechaFin1}/{fechaInicio2}/{fechaFin2}')]
public function listByTypeAndDate(EntityManagerInterface $entityManager, string $fechaInicio1, string $fechaFin1, string $fechaInicio2, string $fechaFin2): \Symfony\Component\HttpFoundation\Response
{
$projectRepo = $entityManager->getRepository(Project::class);
return new JsonResponse([
'segment1' => $projectRepo->getListadoEntre($fechaInicio1, $fechaFin1),
'segment2' => $projectRepo->getListadoEntre($fechaInicio2, $fechaFin2),
]);
}
/**
* Obtiene la lista de recetas finales de un proyecto así como los materiales de las que está compuesto
*/
#[Route('/api/projects/production-recipes/{project}', name: 'api_project_get_production_recipes', methods: ["GET"])]
public function productionRecipes(EntityManagerInterface $entityManager, int $project): JsonResponse
{
return new JsonResponse(
$entityManager->getRepository(Project::class)->getProductionRecipes($project)
);
}
/**
*
* @todo Convertir las sentencias de Doctrine a una SQL
*
*/
#[Route('/api/projects/raw-material-resume/{project}', name: 'api_raw_material_resume')]
public function rawMaterialsResume(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$rawMaterials = [];
$totalWeight = 0;
// Compruebo si se ha guardado ya.
$productionRecipe = $project->getProductionRecipe();
if (null !== $productionRecipe) {
return new JsonResponse([
'materials' => $productionRecipe->getRawMaterials(),
'checklist' => $productionRecipe->getCheckList(),
]);
} else {
$recipes = $project->getRecipes();
$rawMaterialsEntity = $entityManager->getRepository(RecipeTestRawMaterial::class);
$recipeTestsEntity = $entityManager->getRepository(RecipeTest::class);
foreach ($recipes as $recipe) {
// Sí, no se hace automático
$recipesTests = $recipeTestsEntity->findBy([
'recipe' => $recipe,
'finalTest' => true,
]);
if (count($recipesTests) > 0) {
$testRawMaterials = $rawMaterialsEntity->findBy([
'recipeTest' => $recipesTests[0]
]);
/** @var RecipeTestRawMaterial $testRawMaterial */
foreach ($testRawMaterials as $testRawMaterial) {
$material = $testRawMaterial->getRawMaterial();
$materialId = $material->getId();
if (!isset($rawMaterials[$materialId])) {
$rawMaterials[$materialId] = [
'id' => $materialId,
'code' => $material->getCode(),
'name' => $material->getName(),
'marketName' => $material->getPublicName(),
'phases' => [],
'quantity' => 0,
'percentage' => 0,
'roundQuantity' => 0,
'roundPercentage' => 0,
];
}
$quantity = $testRawMaterial->getQuantity() / 1000;
$rawMaterials[$materialId]['quantity'] += $quantity;
$rawMaterials[$materialId]['roundQuantity'] = $rawMaterials[$materialId]['quantity'];
$totalWeight += $quantity;
$rawMaterials[$materialId]['phases'][] = $testRawMaterial->getPhase()->getCode();
}
}
}
return new JsonResponse([
'checklist' => [
'diagrama' => false,
'diagramaNombre' => '',
'etapaNueva' => false,
'etapaNombre' => '',
'riesgos' => false,
'riesgosNombres' => '',
'pcc' => false,
'pccNombre' => '',
'otros' => false,
'otrosNombre' => '',
'ingredientesAlergenos' => false,
'alergenosPresentes' => '',
'trazas' => '',
'nuevos' => '',
'vidaUtil' => '',
],
'materials' => array_values(
array_map(function ($row) use ($totalWeight) {
$row['percentage'] = sprintf('%01.2f', (100 * $row['quantity']) / $totalWeight);
$row['roundPercentage'] = $row['percentage'];
return $row;
}, $rawMaterials)
)
]);
}
}
/**
* @throws \HttpException
* @throws \JsonException
*/
#[Route('/api/projects/production-checklist/{project}', name: "api_save_production_recipe_checklist", methods: ["POST"])]
public function saveProductionRecipe(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$params = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
if (isset($params['checklist'])) {
$productionRecipe = $entityManager->getRepository(ProductionRecipe::class)->findOneBy(
[
'project' => $project
]
);
if (!$productionRecipe) {
$productionRecipe = new ProductionRecipe();
$productionRecipe->setProject($project);
}
$productionRecipe->setCheckList($params['checklist']);
$entityManager->persist($productionRecipe);
$entityManager->flush();
return new JsonResponse([]);
} else {
throw new HttpException(500,"Not valid params");
}
}
#[Route('/api/projects/{project}/print-final-trial', name: 'api_project_print_final_trial', methods: ["GET"])]
public function printFinalTrial(EntityManagerInterface $entityManager, Project $project): RedirectResponse
{
$trial = $entityManager->getRepository(Trial::class)->findOneBy([
'project' => $project,
'finalTrial' => true
]);
if (!$trial) {
$trials = $entityManager->getRepository(Trial::class)->findBy([
'project' => $project,
], [
'id' => 'DESC'
]);
if (count($trials) > 0) {
$trial = $trials[0];
}
}
if ($trial) {
return $this->redirectToRoute('api_print_trial', ['trial' => $trial->getId()]);
}
throw new \Exception('El proyecto no tiene ensayo final', 403);
}
#[Route('/api/projects/production-recipe/{project}', name: "api_get_production_recipe", methods: ["GET"])]
public function productionRecipe(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$toRet = [
'materials' => null,
'checklist' => null
];
/** @var ProductionRecipe $productionRecipe */
$productionRecipe = $entityManager->getRepository(ProductionRecipe::class)->findOneBy([
'project' => $project
]);
if ($productionRecipe) {
$toRet['materials'] = $productionRecipe->getRawMaterials();
$toRet['checklist'] = $productionRecipe->getCheckList();
}
return new JsonResponse($toRet);
}
/**
* Calcula todos los valores del proyecto solicitado.
* Guarda los resultados en la entidad ProjectCalcs
* Devuelve el nutriscore final del cálculo.
*
* @todo Hay que refactorizar esto MUCHO
*/
#[Route('/api/projects/calculate/{project}', name: 'api_project_calculate_all', methods: ['GET'])]
public function calculate(EntityManagerInterface $entityManager, Project $project): JsonResponse
{
$costes = [];
$projectCalcs = $project->getProjectCalcs();
if ($projectCalcs === null) {
$projectCalcs = new ProjectCalcs();
$project->setProjectCalcs($projectCalcs);
}
$projectCalcs->setCreation(new \DateTime());
$MaterialesUsados = [];
// Primero se identifican las recetas que vienen antes del horno
$beforeOvenKneading = null;
$beforeOvenOther = [];
$afterOven = [];
/** @var Recipe $recipe */
foreach ($project->getRecipes() as $recipe) {
if ($recipe->getPhase() === 0) {
if ($recipe->getType() === 'Amasado') {
$beforeOvenKneading = $recipe;
} else {
$beforeOvenOther[] = $recipe;
}
} else {
$afterOven[] = $recipe;
}
}
// Si no hay amasado no continuamos
if ($beforeOvenKneading === null) {
//$io->error("Este proyecto no tiene ninguna masa antes de horno");
throw new HttpException(501, 'Proyecto incompleto');
}
$recipeTestRawMaterialRepository = $entityManager->getRepository(RecipeTestRawMaterial::class);
// Estas son las recetas después del horno.
// Buscamos los tests finales para estas
$afterOvenTests = [];
$afterOvenBakingPercentage = [];
foreach ($afterOven as $recipe) {
$afterOvenBakingPercentage[] = $recipe->getBaking();
/** @var RecipeTest $recipeTest */
foreach ($recipe->getRecipeTests() as $recipeTest) {
if ($recipeTest->getFinalTest() === true) {
$afterOvenTests[] = $recipeTest;
}
}
}
unset ($afterOven);
// Obtenemos los detalles de la fase final del amasado
$kneadingRecipeTest = null;
foreach ($beforeOvenKneading->getRecipeTests() as $recipeTest) {
if ($recipeTest->getFinalTest() === true) {
$kneadingRecipeTest = $recipeTest;
break;
}
}
$beforeOvenTests = [];
//$io->note("Número de recetas adicionales antes de horno: " . \count($beforeOvenOther));
foreach ($beforeOvenOther as $recipe) {
/** @var RecipeTest $recipeTest */
foreach ($recipe->getRecipeTests() as $recipeTest) {
if ($recipeTest->getFinalTest() === true) {
$beforeOvenTests[] = $recipeTest;
//$io->note("Porcentaje " . $recipe->getBaking());
}
}
}
if ($kneadingRecipeTest === null) {
throw new HttpException(501, 'No hay ningún test definido como final en la receta de amasado');
}
// Cálculos de porcentajes para los totales antes de horno
$totalPercentageBeforeOven = 0;
$N4 = 0; $N5 = 0; $N6 = 0;
$M3 = 100; $M4 = 0; $M5 = 0; $M6 = 0;
$porcentajesRecetas = array_fill(0, \count($beforeOvenTests), 0);
$pesosInicialesRecetas = array_fill(0, \count($beforeOvenTests), 0);
$pesoRelacionAmasada = array_fill(0, \count($beforeOvenTests), 0);
if (\count($beforeOvenTests) > 0) {
$porcentajesRecetas[0] = $N4 = $beforeOvenOther[0]->getBaking() / 100;
$M4 = $M3 * $N4 / (1 - $N4);
}
if (\count($beforeOvenTests) > 1) {
$porcentajesRecetas[1] = $N5 = $beforeOvenOther[1]->getBaking() / 100;
$M5 = ($M3+$M4)*$N5/(1-$N5);
}
if (\count($beforeOvenTests) > 2) {
$porcentajesRecetas[2] = $N6 = $beforeOvenOther[2]->getBaking() / 100;
$M6 = ($M3+$M4+$M5)*$N6/(1-$N6);
}
$M7 = $M3 + $M4 + $M5 + $M6;
//var_dump($porcentajesRecetas);
/** Obtención de detalles de la masa para los cálculos del resto */
// Materiales de la receta masa
$materialesAmasado = $recipeTestRawMaterialRepository->findBy(['recipeTest' => $kneadingRecipeTest]);
// Porcentaje amasado
$pesoAmasada = array_reduce($materialesAmasado, fn($akk, $row)=> $akk + $row->getQuantity(), 0);
$J17 = $beforeOvenKneading->getBaking() / 100; //$M3 / $M7;
$recipesBeforeOvenCalcs = [];
$recipesAfterOvenCalcs = [];
$costes['before'] = [];
$costes['before']['others'] = [];
/** INGREDIENTES ANTES DE HORNO */
$BDIngredientesAntesHorno = [];
foreach ($beforeOvenTests as $key => $test) {
$recipeType = $test->getRecipe()->getType();
$costes['before']['others'][$recipeType] = [];
$this->nutricionalAntesHorno[$recipeType] = new NutritionalInfo();
$materials = $recipeTestRawMaterialRepository->findBy(['recipeTest' => $test]);
$pesosInicialesRecetas[$key] = array_reduce($materials, fn($akk, $row)=> $akk + $row->getQuantity(), 0);
// Sumatoria receta para una amasada [Total Masa Amasada * % Baking Receta / % Baking Masa Amasada]
$pesoRelacionAmasada[$key] = $pesoAmasada * $porcentajesRecetas[$key] / $J17;
//echo "Peso relación con la amasada para la receta {$key} => {$pesoAmasada} * {$porcentajesRecetas[$key]} / {$J17} => {$pesoRelacionAmasada[$key]}\n";
//echo "Peso inicial de la receta {$key}: {$pesosInicialesRecetas[$key]}\n";
$nombreTipo = $test->getRecipe()->getType();
$BDIngredientesAntesHorno[$nombreTipo] = [];
/** @var RecipeTestRawMaterial $material */
foreach($materials as $material) {
$quantity = $material->getQuantity();
$rawMaterial = $material->getRawMaterial();
if (!isset($MaterialesUsados[$rawMaterial->getId()])) {
$MaterialesUsados[$rawMaterial->getId()] = $rawMaterial;
}
// Se aplica el índice de corrección según los porcentajes de masa
$quantityKneaded = $quantity * $pesoRelacionAmasada[$key] / $pesosInicialesRecetas[$key];
$recipesBeforeOvenCalcs[$rawMaterial->getId()] = [$rawMaterial->getName(), $quantity, $quantity / 1000, $quantity / $pesosInicialesRecetas[$key], $quantityKneaded, $quantityKneaded / 1000];
$BDIngredientesAntesHorno[$nombreTipo][] = $recipesBeforeOvenCalcs[$rawMaterial->getId()];
/*echo "Información calculada para el material ", $rawMaterial->getName(), ":\n";
var_dump($recipesBeforeOvenCalcs[$rawMaterial->getId()]);
echo "\n\n";*/
$costes['before']['others'][$recipeType][$rawMaterial->getId()] = [$rawMaterial->getName(), $quantity / $pesosInicialesRecetas[$key], $rawMaterial->getPrice(), $rawMaterial->getPrice() * ($quantity / $pesosInicialesRecetas[$key])];
$this->nutricionalAntesHorno[$recipeType]->addRawMaterial($rawMaterial, $quantity / $pesosInicialesRecetas[$key]);
}
}
$projectCalcs->setIngredientesAntesHorno($BDIngredientesAntesHorno);
/** FIN INGREDIENTES ANTES DE HORNO */
/** INGREDIENTES DE LA MASA */
// Empezamos la cookie con la masa de amasado
$cookie = [];
$costes['before']['amasada'] = [];
foreach($materialesAmasado as $material) {
$rawMaterial = $material->getRawMaterial();
if (!isset($MaterialesUsados[$rawMaterial->getId()])) {
$MaterialesUsados[$rawMaterial->getId()] = $rawMaterial;
}
$quantity = $material->getQuantity();
$cookie[$rawMaterial->getId()] = [$rawMaterial->getName(), $quantity, $quantity / 1000, $quantity / $pesoAmasada];
$costes['before']['amasada'][$rawMaterial->getId()] = [$rawMaterial->getName(), $quantity / $pesoAmasada, $rawMaterial->getPrice(), ($quantity / $pesoAmasada) * $rawMaterial->getPrice()];
}
// $cookieOriginal = $cookie;
$projectCalcs->setIngredientesAmasada($cookie);
/** FIN INGREDIENTES DE LA MASA */
/** INGREDIENTES DE LA GALLETA */
// Creamos la receta combinando los distintos materiales de las recetas de horno
foreach ($recipesBeforeOvenCalcs as $id => $otherRecipe) {
if (isset($cookie[$id])) {
$cookie[$id][1] += $otherRecipe[4];
$cookie[$id][2] += $otherRecipe[5];
} else {
$cookie[$id] = [$otherRecipe[0], $otherRecipe[4], $otherRecipe[5], $otherRecipe[3],];
}
}
$cookieOriginal = $cookie;
// Ahora calculamos el total de cada material quitándole la humedad
$sumaHorneado = 0;
$this->nutricionalCookie = new NutritionalInfo();
foreach($cookie as $idMaterialCookie => $materialCookie) {
$cookie[$idMaterialCookie][1] = ($materialCookie[1] * (100 - $MaterialesUsados[$idMaterialCookie]->getHumidity()) / 100) * ((100 - $MaterialesUsados[$idMaterialCookie]->getLostVolatilization()) / 100);
$cookie[$idMaterialCookie][2] = $cookie[$idMaterialCookie][1] / 1000;
$sumaHorneado += $cookie[$idMaterialCookie][1];
}
$projectHumidity = $project->getHumidity()/100;
$humedadHorneado = $projectHumidity * $sumaHorneado / (1 - $projectHumidity);
$totalHorneado = $sumaHorneado + $humedadHorneado;
foreach($cookie as $idMaterialCookie => $materialCookie) {
$cookie[$idMaterialCookie][3] = $materialCookie[1] / $totalHorneado;
//$cookie[$idMaterialCookie][3] = $cookie[$idMaterialCookie][1] / $totalHorneado;
$this->nutricionalCookie->addRawMaterial($MaterialesUsados[$idMaterialCookie], $cookie[$idMaterialCookie][3]);
$cookie[$idMaterialCookie][4] = $cookieOriginal[$idMaterialCookie][1] / $totalHorneado;
$cookie[$idMaterialCookie][5] = $cookieOriginal[$idMaterialCookie][1];
}
$projectCalcs->setIngredientesCookie($cookie);
/*echo "\n\n== AMASADA TERMINADA ==\n\n";
echo var_export($cookie, true);
echo "\n\n";*/
$perdidaEstimada = $pesoAmasada + array_reduce($pesoRelacionAmasada, fn($a,$r)=>$a+$r,0) - $totalHorneado;
if ($pesoAmasada === 0) {
$perdidaEstimadaPorcentaje = $perdidaEstimada;
} else {
$perdidaEstimadaPorcentaje = $perdidaEstimada / $pesoAmasada;
}
$projectCalcs->setTotalPesoCookie(sprintf('%01.4f', $sumaHorneado / 1000)); // <- A kg
$projectCalcs->setHumedadHorneado(sprintf('%01.4f', $humedadHorneado / 1000)); // <- A kg
$projectCalcs->setTotalHorneado(sprintf('%01.4f', $totalHorneado / 1000)); // <- A Kg
$projectCalcs->setPerdidaEstimada(sprintf('%01.4f', $perdidaEstimada / 1000)); // <- A kg
$projectCalcs->setPerdidaEstimadaPorcentaje(sprintf('%01.5f', $perdidaEstimadaPorcentaje));
/** FIN INGREDIENTES DE LA GALLETA */
/** INGREDIENTES DESPUES DEL HORNO */
$afterOvenRecipeCalcs = [];
$costes['after'] = [];
$BDIngredientesDespuesHorno = [];
foreach ($afterOvenTests as $recipeKey => $recipeTest) {
$nombreTipo = $recipeTest->getRecipe()->getType();
$BDIngredientesDespuesHorno[$nombreTipo] = [];
$materials = $recipeTestRawMaterialRepository->findBy(['recipeTest' => $recipeTest]);
$recipeId = $recipeTest->getRecipe()->getId();
//$recipeName = $recipeTest->getRecipe()->getType();
$afterOvenRecipeCalcs[$recipeId] = [];
$costes['after'][$recipeKey] = [];
$this->nutricionalDespuesHorno[$recipeKey] = new NutritionalInfo();
$total = 0;
foreach ($materials as $material) {
$rawMaterial = $material->getRawMaterial();
if (!isset($MaterialesUsados[$rawMaterial->getId()])) {
$MaterialesUsados[$rawMaterial->getId()] = $rawMaterial;
}
$quantity = $material->getQuantity();
$afterOvenRecipeCalcs[$recipeId][$rawMaterial->getId()] = [$rawMaterial->getName(), $quantity, $quantity / 1000, 0];
$total += $quantity;
}
array_walk($afterOvenRecipeCalcs[$recipeId], fn(&$r)=> $r[3] = isset($r[1]) ? ($r[1] / $total) : '');
foreach ($materials as $material) {
$rawMaterial = $material->getRawMaterial();
$quantity = $material->getQuantity();
$costes['after'][$recipeKey][$rawMaterial->getId()] = [$rawMaterial->getName(), $quantity / $total, $rawMaterial->getPrice(), $rawMaterial->getPrice() * ($quantity / $total)];
$this->nutricionalDespuesHorno[$recipeKey]->addRawMaterialWithoutHumidity($rawMaterial, $quantity / $total);
}
$BDIngredientesDespuesHorno[$recipeKey] = $afterOvenRecipeCalcs[$recipeId];
}
/*echo "\n\n== INGREDIENTES DESPUES HORNO ==\n\n";
var_export($BDIngredientesDespuesHorno);
echo "\n\n";*/
$projectCalcs->setIngredientesDespuesHorno($BDIngredientesDespuesHorno);
unset($BDIngredientesDespuesHorno);
/** FIN INGREDIENTES DESPUES DEL HORNO */
/** INGREDIENTES PRODUCTO TERMINADO */
$productoTerminado = [];
$cookiePercentage = 100 - array_reduce($afterOvenBakingPercentage, fn($a,$r)=>$a+$r, 0);
//echo "Porcentaje galleta: {$cookiePercentage}\n\n";
foreach($cookie as $idMaterialCookie => $materialCookie) {
$productoTerminado[$idMaterialCookie] = [
$materialCookie[0],
$materialCookie[3] * $cookiePercentage,
isset($materialCookie[4]) ? $materialCookie[4] * $cookiePercentage : null,
$materialCookie[1],
$idMaterialCookie
];
}
//var_dump($this->nutricionalCookie);
$nutricionalProductoFinal = new NutritionalInfo();
$nutricionalProductoFinal->addSimple($this->nutricionalCookie, $cookiePercentage / 100);
foreach ($afterOvenTests as $recipeKey => $recipeTest) {
$nutricionalProductoFinal->addSimple($this->nutricionalDespuesHorno[$recipeKey], $recipeTest->getRecipe()->getBaking() / 100);
}
//var_dump($this->nutricionalProductoFinal);
$key = 0;
foreach ($afterOvenRecipeCalcs as $recipe) {
foreach ($recipe as $materialId => $materialInfo) {
if (!isset($productoTerminado[$materialId])) {
$productoTerminado[$materialId] = [
$materialInfo[0],
$materialInfo[3] * $afterOvenBakingPercentage[$key],
$materialInfo[3] * $afterOvenBakingPercentage[$key],
$materialInfo[1],
$materialId,
];
} else {
$productoTerminado[$materialId][1] += $materialInfo[3] * $afterOvenBakingPercentage[$key];
$productoTerminado[$materialId][2] += $materialInfo[3] * $afterOvenBakingPercentage[$key];
}
}
$key++;
}
$projectCalcs->setHumedadGalleta(sprintf('%01.4f', $projectHumidity * $cookiePercentage));
/*foreach ($productoTerminado as $materialId => $lineaMaterial) {
echo "Añadir material {$MaterialesUsados[$materialId]->getName()} {$MaterialesUsados[$materialId]->getGrease()} {$lineaMaterial[1]}\n";
//$this->nutricionalProductoFinal->addRawMaterialWithHumidity($MaterialesUsados[$materialId], $lineaMaterial[1] / 100);
}*/
$projectCalcs->setIngredientesProductoTerminado($productoTerminado);
/*echo "\n\n== INGREDIENTES PRODUCTO TERMINADO ==\n\n";
var_export($productoTerminado);
echo "\n\n";*/
/** FIN INGREDIENTES PRODUCTO TERMINADO */
/** COSTES AMASADA */
$recipeTotalCost = array_reduce($costes['before']['amasada'], fn($a,$r) => $a + $r[3], 0);
$recipeKneadingCost = $recipeTotalCost * $J17;
//$projectCalcs->setCosteAmasada(sprintf('%01.4f', $recipeTotalCost));
$projectCalcs->setCostesAmasada($costes['before']['amasada']);
/** FIN COSTES AMASADA */
/** COSTES ANTES HORNO */
$key = 0;
$BDCostesAntesHorno = [];
foreach ($costes['before']['others'] as $recipeType => $recipeCosts) {
$recipeTotalCosts = array_reduce($recipeCosts, fn($a,$r) => $a + $r[3], 0);
$BDCostesAntesHorno[$recipeType] = $recipeTotalCosts;
$recipeKneadingCost += $recipeTotalCosts * $porcentajesRecetas[$key];
$key++;
}
$projectCalcs->setCostesAntesHorno($BDCostesAntesHorno);
//$projectCalcs->setCosteAmasada(sprintf('%01.4f', $recipeKneadingCost));
unset($BDCostesAntesHorno);
/** FIN COSTES ANTES HORNO */
$totalKneadingCost = $recipeKneadingCost * ($pesoAmasada + array_reduce($pesoRelacionAmasada, fn($a,$k)=>$a + $k, 0)) / $totalHorneado;
$totalProductCost = $totalKneadingCost * ($cookiePercentage / 100);
$projectCalcs->setCosteAmasada(sprintf('%01.4f', $totalKneadingCost));
/** COSTES DESPUES HORNO */
$key = 0;
$BDCostesDespuesHorno = []; //var_dump($costes['after']);
foreach ($costes['after'] as $recipeKey => $recipeCosts) {
$recipeTotalCosts = array_reduce($recipeCosts, fn($a,$r) => $a + $r[3], 0);
$totalProductCost += $recipeTotalCosts * ($afterOvenBakingPercentage[$key] / 100);
$BDCostesDespuesHorno[$recipeKey] = $recipeCosts;
$key++;
}
$projectCalcs->setCostesDespuesHorno($BDCostesDespuesHorno);
unset($BDCostesDespuesHorno);
/** FIN COSTES DESPUES HORNO */
$projectCalcs->setCosteProductoTerminado(sprintf('%01.4f',$totalProductCost));
$projectCalcs
->setInformacionNutricionalCookie($this->nutricionalCookie->result())
->setCdrCookie($this->nutricionalCookie->cdr())
->setNutriscoreCookie($this->nutricionalCookie->nutriscore($entityManager));
/*$nutricionalDespues = [];
$cdrDespues = [];
$nutriscoreDespues = [];
foreach ($this->nutricionalDespuesHorno as $tipo => $nutricional) {
$nutricionalDespues[$tipo] = $nutricional->result();
$cdrDespues[$tipo] = $nutricional->cdr();
$nutriscoreDespues[$tipo] = $nutricional->nutriscore($entityManager);
}
$projectCalcs
->setInformacionNutricionalDespuesHorno($nutricionalDespues)
->setCdrDespuesHorno($cdrDespues)
->setNutriscoreDespuesHorno($nutriscoreDespues);
unset($nutricionalDespues);
unset($cdrDespues);
unset($nutriscoreDespues);*/
//var_dump($this->nutricionalProductoFinal->result());
$projectCalcs->setInformacionNutricionalProducto($nutricionalProductoFinal->result());
//$projectCalcs->setInformacionNutricionalProductoAjustado($this->nutricionalProductoFinal->result());
$projectCalcs->setCdrProducto($nutricionalProductoFinal->cdr());
$nutriscoreFinal = $nutricionalProductoFinal->nutriscore($entityManager);
$projectCalcs->setNutriscoreProducto($nutriscoreFinal);
$projectCalcs->setNutriscoreProductoValor(array_values(array_filter($nutriscoreFinal, fn($r) => $r['key'] === 'Nutriscore'))[0]['value']);
$projectCalcs->setNutriscoreProductoLetra(array_values(array_filter($nutriscoreFinal, fn($r) => $r['key'] === 'Nutriscore_letter'))[0]['value']);
$entityManager->persist($projectCalcs);
$entityManager->persist($project);
$entityManager->flush();
return new JsonResponse([
'nutriscore' => $nutriscoreFinal,
//'j' => $this->nutricionalProductoFinal->result(),
'id_calculo' => $projectCalcs->getId(),
]);
}
}