diff --git a/src/Controller/ScanController.php b/src/Controller/ScanController.php index aebadd89..63787767 100644 --- a/src/Controller/ScanController.php +++ b/src/Controller/ScanController.php @@ -46,6 +46,8 @@ use App\Services\LabelSystem\BarcodeScanner\BarcodeRedirector; use App\Services\LabelSystem\BarcodeScanner\BarcodeScanHelper; use App\Services\LabelSystem\BarcodeScanner\BarcodeSourceType; use App\Services\LabelSystem\BarcodeScanner\LocalBarcodeScanResult; +use App\Services\LabelSystem\BarcodeScanner\LCSCBarcodeScanResult; +use App\Services\LabelSystem\BarcodeScanner\EIGP114BarcodeScanResult; use Doctrine\ORM\EntityNotFoundException; use InvalidArgumentException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -53,6 +55,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\MapQueryParameter; use Symfony\Component\Routing\Attribute\Route; +use App\Services\InfoProviderSystem\PartInfoRetriever; +use App\Services\InfoProviderSystem\ProviderRegistry; /** * @see \App\Tests\Controller\ScanControllerTest @@ -60,9 +64,12 @@ use Symfony\Component\Routing\Attribute\Route; #[Route(path: '/scan')] class ScanController extends AbstractController { - public function __construct(protected BarcodeRedirector $barcodeParser, protected BarcodeScanHelper $barcodeNormalizer) - { - } + public function __construct( + protected BarcodeRedirector $barcodeParser, + protected BarcodeScanHelper $barcodeNormalizer, + private readonly ProviderRegistry $providerRegistry, + private readonly PartInfoRetriever $infoRetriever, + ) {} #[Route(path: '', name: 'scan_dialog')] public function dialog(Request $request, #[MapQueryParameter] ?string $input = null): Response @@ -72,26 +79,113 @@ class ScanController extends AbstractController $form = $this->createForm(ScanDialogType::class); $form->handleRequest($request); + $mode = null; if ($input === null && $form->isSubmitted() && $form->isValid()) { $input = $form['input']->getData(); $mode = $form['mode']->getData(); } $infoModeData = null; + $createUrl = null; if ($input !== null) { try { $scan_result = $this->barcodeNormalizer->scanBarcodeContent($input, $mode ?? null); + //Perform a redirect if the info mode is not enabled if (!$form['info_mode']->getData()) { try { + // redirect user to part page return $this->redirect($this->barcodeParser->getRedirectURL($scan_result)); } catch (EntityNotFoundException) { - $this->addFlash('success', 'scan.qr_not_found'); + // Fallback: show decoded info like info-mode as part does not exist + $infoModeData = $scan_result->getDecodedForInfoMode(); + + $locale = $request->getLocale(); + + // If it's an LCSC scan, offer "create part" link + if ($scan_result instanceof LCSCBarcodeScanResult) { + $lcscCode = $scan_result->getPC(); + + if (is_string($lcscCode) && $lcscCode !== '') { + // Prefer generating a relative URL; browser will use current host + $createUrl = "/{$locale}/part/from_info_provider/lcsc/{$lcscCode}/create"; + } + } + + // If EIGP114 (Mouser / Digi-Key), offer "create part" link + if ($scan_result instanceof EIGP114BarcodeScanResult) { + // Use guessed vendor and supplierPartNumber. + $vendor = $scan_result->guessBarcodeVendor(); + + if ($vendor === 'mouser' && is_string($scan_result->supplierPartNumber) + && $scan_result->supplierPartNumber !== '') { + + try { + $mouserProvider = $this->providerRegistry->getProviderByKey('mouser'); + + if (!$mouserProvider->isActive()) { + $this->addFlash('warning', 'Mouser provider is disabled / not configured.'); + } else { + // Search Mouser using the MPN + $dtos = $this->infoRetriever->searchByKeyword( + keyword: $scan_result->supplierPartNumber, + providers: [$mouserProvider] + ); + + // If there are results, provider_id is MouserPartNumber (per MouserProvider.php) + $best = $dtos[0] ?? null; + + if ($best !== null && is_string($best->provider_id) && $best->provider_id !== '') { + $createUrl = '/' + . rawurlencode($locale) + . '/part/from_info_provider/mouser/' + . rawurlencode($best->provider_id) + . '/create'; + } else { + $this->addFlash('warning', 'No Mouser match found for this MPN.'); + } + } + } catch (\InvalidArgumentException $e) { + // provider key not found in registry + $this->addFlash('warning', 'Mouser provider is not installed/enabled.'); + } catch (\Throwable $e) { + // Don’t break scanning UX if provider lookup fails + $this->addFlash('warning', 'Mouser lookup failed: ' . $e->getMessage()); + } + } + + // Digikey can keep using customerPartNumber if present (it is in their barcode) + if ($vendor === 'digikey') { + + try { + $provider = $this->providerRegistry->getProviderByKey('digikey'); + + if (!$provider->isActive()) { + $this->addFlash('warning', 'Digi-Key provider is disabled / not configured (API key missing).'); + } else { + $id = $scan_result->customerPartNumber ?: $scan_result->supplierPartNumber; + + if (is_string($id) && $id !== '') { + $createUrl = '/' + . rawurlencode($locale) + . '/part/from_info_provider/digikey/' + . rawurlencode($id) + . '/create'; + } + } + } catch (\InvalidArgumentException $e) { + $this->addFlash('warning', 'Digi-Key provider is not installed/enabled'); + } + } + } + + if ($createUrl === null) { + $this->addFlash('warning', 'scan.qr_not_found'); + } } } else { //Otherwise retrieve infoModeData $infoModeData = $scan_result->getDecodedForInfoMode(); - } } catch (InvalidArgumentException) { $this->addFlash('error', 'scan.format_unknown'); @@ -101,6 +195,7 @@ class ScanController extends AbstractController return $this->render('label_system/scanner/scanner.html.twig', [ 'form' => $form, 'infoModeData' => $infoModeData, + 'createUrl' => $createUrl, ]); } diff --git a/templates/label_system/scanner/scanner.html.twig b/templates/label_system/scanner/scanner.html.twig index 1f978a9b..ef293d1a 100644 --- a/templates/label_system/scanner/scanner.html.twig +++ b/templates/label_system/scanner/scanner.html.twig @@ -26,7 +26,16 @@ {% if infoModeData %}
-

{% trans %}label_scanner.decoded_info.title{% endtrans %}

+
+

{% trans %}label_scanner.decoded_info.title{% endtrans %}

+ + {% if createUrl %} + + + + {% endif %} +