diff --git a/config/permissions.yaml b/config/permissions.yaml index 39e91b57..1aa0c43e 100644 --- a/config/permissions.yaml +++ b/config/permissions.yaml @@ -163,6 +163,8 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co label: "tools.builtin_footprints_viewer.title" ic_logos: label: "perm.tools.ic_logos" + multi_build: + label: "tools.multi_build.title" info_providers: label: "perm.part.info_providers" diff --git a/src/Controller/ToolsController.php b/src/Controller/ToolsController.php index 76dffb4d..b75f4ee1 100644 --- a/src/Controller/ToolsController.php +++ b/src/Controller/ToolsController.php @@ -31,9 +31,14 @@ use App\Services\System\GitVersionInfoProvider; use App\Services\System\UpdateAvailableFacade; use App\Settings\AppSettings; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Runtime\SymfonyRuntime; +use Doctrine\ORM\EntityManagerInterface; +use App\Entity\ProjectSystem\Project; +use App\Form\ProjectSystem\ProjectMultiBuildType; +use Psr\Log\LoggerInterface; #[Route(path: '/tools')] class ToolsController extends AbstractController @@ -122,6 +127,66 @@ class ToolsController extends AbstractController ]); } + #[Route(path: '/multi_build', name: 'tools_multi_build')] + public function multiBuild(LoggerInterface $logger, EntityManagerInterface $entityManager, Request $request): Response + { + //$this->denyAccessUnlessGranted('@tools.multi_build'); + $all_projects = $entityManager->getRepository(Project::class)->findAll(); + + $form = $this->createForm(ProjectMultiBuildType::class, [], ['projects'=>$all_projects]); + + $form->handleRequest($request); + $combined_bom=[]; + $needs_ordering = []; + $can_build = true; + if ($form->isSubmitted()) + { + if ($form->isValid()) + { + $submitted = "YES"; + foreach($all_projects as $p) + { + $count_for_project = $form->get($p->getID() . "_project")->getData() + 0; + $logger->Info("QTY", ['count_for_project'=>$count_for_project, 'name'=>$p->getName()]); + if ($count_for_project > 0) + { + $logger->Info("BOMSIZE", ['bomsize'=>count($p->getBomEntries())]); + foreach ($p->getBomEntries() as $bom_entry) + { + $part_id = $bom_entry->getPart()->getID(); + $logger->Info("ISAPART", ['q'=>$bom_entry->getQuantity(), 'name'=>$bom_entry->getPart()->getName()]); + if (array_key_exists($part_id, $combined_bom)) + { + $combined_bom[$part_id]['quantity'] += $bom_entry->getQuantity() * $count_for_project; + } + else + { + $combined_bom[$part_id] = array('quantity'=>$bom_entry->getQuantity() * $count_for_project, 'part'=>$bom_entry->getPart()); + } + } + } + } + + foreach($combined_bom as $cb) + { + $total_instock = $cb['part']->getAmountSum(); + $logger->Info("COMBINED BOM", ['total_instock'=>$total_instock, 'needed'=>$cb['quantity']]); + if ($total_instock < $cb['quantity']) + { + $needs_ordering[] = array('needed'=>($cb['quantity']-$total_instock), 'part'=>$cb['part']); + $can_build = false; + } + } + } + } + + return $this->render('tools/multi_build/multi_build.html.twig', [ + 'form'=>$form, + 'needs_ordering'=>$needs_ordering, + 'can_build'=>$can_build + ]); + } + #[Route(path: '/ic_logos', name: 'tools_ic_logos')] public function icLogos(): Response { diff --git a/src/Form/ProjectSystem/ProjectMultiBuildType.php b/src/Form/ProjectSystem/ProjectMultiBuildType.php new file mode 100644 index 00000000..4a949954 --- /dev/null +++ b/src/Form/ProjectSystem/ProjectMultiBuildType.php @@ -0,0 +1,68 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Form\ProjectSystem; + +use App\Services\InfoProviderSystem\ProviderRegistry; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Form\Extension\Core\Type\UrlType; +use Symfony\Component\Form\Extension\Core\Type\NumberType; +use Symfony\Component\Form\FormBuilderInterface; +use App\Entity\ProjectSystem\Project; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Psr\Log\LoggerInterface; + +class ProjectMultiBuildType extends AbstractType +{ + private LoggerInterface $logger; + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $this->logger->info("LEN {len}", ['len'=>count($options['projects'])]); + foreach($options['projects'] as $p) + { + $builder->add($p->getID() . '_project', NumberType::class, [ + 'label' => $p->getName(), + 'required' => false, + ],0); + } + + $builder->add('submit', SubmitType::class, [ + 'label' => 'info_providers.search.submit', + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'projects' => [], + ]); + $resolver->setAllowedTypes('projects', 'array'); + } +} diff --git a/src/Helpers/Projects/ProjectMultiBuildRequest.php b/src/Helpers/Projects/ProjectMultiBuildRequest.php new file mode 100644 index 00000000..108d63d0 --- /dev/null +++ b/src/Helpers/Projects/ProjectMultiBuildRequest.php @@ -0,0 +1,39 @@ +. + */ +namespace App\Helpers\Projects; + +use App\Entity\Parts\Part; +use App\Entity\Parts\PartLot; +use App\Entity\ProjectSystem\Project; +use App\Entity\ProjectSystem\ProjectBOMEntry; +use App\Validator\Constraints\ProjectSystem\ValidProjectBuildRequest; + +/** + * @see \App\Tests\Helpers\Projects\ProjectBuildRequestTest + */ +#[ValidProjectBuildRequest] +final class ProjectBuildRequest +{ + + +} diff --git a/src/Services/Trees/ToolsTreeBuilder.php b/src/Services/Trees/ToolsTreeBuilder.php index 6397e3af..df2fcb2e 100644 --- a/src/Services/Trees/ToolsTreeBuilder.php +++ b/src/Services/Trees/ToolsTreeBuilder.php @@ -131,6 +131,12 @@ class ToolsTreeBuilder $this->urlGenerator->generate('tools_builtin_footprints_viewer') ))->setIcon('fa-treeview fa-fw fa-solid fa-images'); } + if ($this->security->isGranted('@tools.multi_build')) { + $nodes[] = (new TreeViewNode( + "Multi Build", + $this->urlGenerator->generate('tools_multi_build') + ))->setIcon('fa-treeview fa-fw fa-solid fa-images'); + } if ($this->security->isGranted('@tools.ic_logos')) { $nodes[] = (new TreeViewNode( $this->translator->trans('perm.tools.ic_logos'), diff --git a/templates/tools/multi_build/multi_build.html.twig b/templates/tools/multi_build/multi_build.html.twig new file mode 100644 index 00000000..d611bf89 --- /dev/null +++ b/templates/tools/multi_build/multi_build.html.twig @@ -0,0 +1,28 @@ +{% extends "main_card.html.twig" %} + +{% block title %}Multi Build{% endblock %} + + +{% block card_title %} + Multi Build{% endblock %} + +{% block card_body %} + +