mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-02-28 20:39:35 +00:00
Refactored BarcodeScanResultHandler to be able to resolve arbitary entities from scans
This commit is contained in:
parent
35222f19cc
commit
caa71bbdda
1 changed files with 49 additions and 53 deletions
|
|
@ -45,6 +45,7 @@ use App\Entity\LabelSystem\LabelSupportedElement;
|
||||||
use App\Entity\Parts\Manufacturer;
|
use App\Entity\Parts\Manufacturer;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use App\Entity\Parts\PartLot;
|
use App\Entity\Parts\PartLot;
|
||||||
|
use App\Entity\Parts\StorageLocation;
|
||||||
use App\Repository\Parts\PartRepository;
|
use App\Repository\Parts\PartRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityNotFoundException;
|
use Doctrine\ORM\EntityNotFoundException;
|
||||||
|
|
@ -72,51 +73,36 @@ final readonly class BarcodeScanResultHandler
|
||||||
*/
|
*/
|
||||||
public function getInfoURL(BarcodeScanResultInterface $barcodeScan): string
|
public function getInfoURL(BarcodeScanResultInterface $barcodeScan): string
|
||||||
{
|
{
|
||||||
//For our internal barcode format we can directly determine the target without looking up the part
|
|
||||||
//Also here we can encounter different types of barcodes, like storage location barcodes, which are not resolvable to a part
|
|
||||||
if($barcodeScan instanceof LocalBarcodeScanResult) {
|
|
||||||
return $this->getURLLocalBarcode($barcodeScan);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For other barcodes try to resolve the part first and then redirect to the part page
|
//For other barcodes try to resolve the part first and then redirect to the part page
|
||||||
$localPart = $this->resolvePart($barcodeScan);
|
$entity = $this->resolveEntity($barcodeScan);
|
||||||
if ($localPart !== null) {
|
|
||||||
return $this->urlGenerator->generate('app_part_show', ['id' => $localPart->getID()]);
|
if ($entity === null) {
|
||||||
|
throw new EntityNotFoundException("No entity could be resolved for the given barcode scan result");
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new EntityNotFoundException('Could not resolve a local part for the given barcode scan result');
|
if ($entity instanceof Part) {
|
||||||
}
|
return $this->urlGenerator->generate('app_part_show', ['id' => $entity->getID()]);
|
||||||
|
|
||||||
private function getURLLocalBarcode(LocalBarcodeScanResult $barcodeScan): string
|
|
||||||
{
|
|
||||||
switch ($barcodeScan->target_type) {
|
|
||||||
case LabelSupportedElement::PART:
|
|
||||||
return $this->urlGenerator->generate('app_part_show', ['id' => $barcodeScan->target_id]);
|
|
||||||
case LabelSupportedElement::PART_LOT:
|
|
||||||
//Try to determine the part to the given lot
|
|
||||||
$lot = $this->em->find(PartLot::class, $barcodeScan->target_id);
|
|
||||||
if (!$lot instanceof PartLot) {
|
|
||||||
throw new EntityNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->urlGenerator->generate('app_part_show', ['id' => $lot->getPart()->getID(), 'highlightLot' => $lot->getID()]);
|
|
||||||
|
|
||||||
case LabelSupportedElement::STORELOCATION:
|
|
||||||
return $this->urlGenerator->generate('part_list_store_location', ['id' => $barcodeScan->target_id]);
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new InvalidArgumentException('Unknown $type: '.$barcodeScan->target_type->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($entity instanceof PartLot) {
|
||||||
|
return $this->urlGenerator->generate('app_part_show', ['id' => $entity->getPart()->getID(), 'highlightLot' => $entity->getID()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entity instanceof StorageLocation) {
|
||||||
|
return $this->urlGenerator->generate('part_list_store_location', ['id' => $entity->getID()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@phpstan-ignore-next-line This should never happen, since resolveEntity should only return Part, PartLot or StorageLocation
|
||||||
|
throw new \LogicException("Resolved entity is of unknown type: ".get_class($entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to resolve a Part from the given barcode scan result. Returns null if no part could be found for the given barcode,
|
* Tries to resolve the given barcode scan result to a local entity. This can be a Part, a PartLot or a StorageLocation, depending on the type of the barcode and the information contained in it.
|
||||||
* or the barcode doesn't contain information allowing to resolve to a local part.
|
* Returns null if no matching entity could be found.
|
||||||
* @param BarcodeScanResultInterface $barcodeScan
|
* @param BarcodeScanResultInterface $barcodeScan
|
||||||
* @return Part|null
|
* @return Part|PartLot|StorageLocation
|
||||||
* @throws \InvalidArgumentException if the barcode scan result type is unknown and cannot be handled this function
|
|
||||||
*/
|
*/
|
||||||
public function resolvePart(BarcodeScanResultInterface $barcodeScan): ?Part
|
public function resolveEntity(BarcodeScanResultInterface $barcodeScan): Part|PartLot|StorageLocation|null
|
||||||
{
|
{
|
||||||
if ($barcodeScan instanceof LocalBarcodeScanResult) {
|
if ($barcodeScan instanceof LocalBarcodeScanResult) {
|
||||||
return $this->resolvePartFromLocal($barcodeScan);
|
return $this->resolvePartFromLocal($barcodeScan);
|
||||||
|
|
@ -134,27 +120,37 @@ final readonly class BarcodeScanResultHandler
|
||||||
return $this->resolvePartFromLCSC($barcodeScan);
|
return $this->resolvePartFromLCSC($barcodeScan);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException("Unknown barcode scan result type: ".get_class($barcodeScan));
|
throw new \InvalidArgumentException("Barcode does not support resolving to a local entity: ".get_class($barcodeScan));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolvePartFromLocal(LocalBarcodeScanResult $barcodeScan): ?Part
|
/**
|
||||||
|
* Tries to resolve a Part from the given barcode scan result. Returns null if no part could be found for the given barcode,
|
||||||
|
* or the barcode doesn't contain information allowing to resolve to a local part.
|
||||||
|
* @param BarcodeScanResultInterface $barcodeScan
|
||||||
|
* @return Part|null
|
||||||
|
* @throws \InvalidArgumentException if the barcode scan result type is unknown and cannot be handled this function
|
||||||
|
*/
|
||||||
|
public function resolvePart(BarcodeScanResultInterface $barcodeScan): ?Part
|
||||||
{
|
{
|
||||||
switch ($barcodeScan->target_type) {
|
$entity = $this->resolveEntity($barcodeScan);
|
||||||
case LabelSupportedElement::PART:
|
if ($entity instanceof Part) {
|
||||||
$part = $this->em->find(Part::class, $barcodeScan->target_id);
|
return $entity;
|
||||||
return $part instanceof Part ? $part : null;
|
|
||||||
|
|
||||||
case LabelSupportedElement::PART_LOT:
|
|
||||||
$lot = $this->em->find(PartLot::class, $barcodeScan->target_id);
|
|
||||||
if (!$lot instanceof PartLot) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $lot->getPart();
|
|
||||||
|
|
||||||
default:
|
|
||||||
// STORELOCATION etc. doesn't map to a Part
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
if ($entity instanceof PartLot) {
|
||||||
|
return $entity->getPart();
|
||||||
|
}
|
||||||
|
//Storage locations are not associated with a specific part, so we cannot resolve a part for
|
||||||
|
//a storage location barcode
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolvePartFromLocal(LocalBarcodeScanResult $barcodeScan): Part|PartLot|StorageLocation|null
|
||||||
|
{
|
||||||
|
return match ($barcodeScan->target_type) {
|
||||||
|
LabelSupportedElement::PART => $this->em->find(Part::class, $barcodeScan->target_id),
|
||||||
|
LabelSupportedElement::PART_LOT => $this->em->find(PartLot::class, $barcodeScan->target_id),
|
||||||
|
LabelSupportedElement::STORELOCATION => $this->em->find(StorageLocation::class, $barcodeScan->target_id),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue