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\Part;
|
||||
use App\Entity\Parts\PartLot;
|
||||
use App\Entity\Parts\StorageLocation;
|
||||
use App\Repository\Parts\PartRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityNotFoundException;
|
||||
|
|
@ -72,51 +73,36 @@ final readonly class BarcodeScanResultHandler
|
|||
*/
|
||||
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
|
||||
$localPart = $this->resolvePart($barcodeScan);
|
||||
if ($localPart !== null) {
|
||||
return $this->urlGenerator->generate('app_part_show', ['id' => $localPart->getID()]);
|
||||
$entity = $this->resolveEntity($barcodeScan);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
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 Part) {
|
||||
return $this->urlGenerator->generate('app_part_show', ['id' => $entity->getID()]);
|
||||
}
|
||||
|
||||
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,
|
||||
* or the barcode doesn't contain information allowing to resolve to a local part.
|
||||
* 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.
|
||||
* Returns null if no matching entity could be found.
|
||||
* @param BarcodeScanResultInterface $barcodeScan
|
||||
* @return Part|null
|
||||
* @throws \InvalidArgumentException if the barcode scan result type is unknown and cannot be handled this function
|
||||
* @return Part|PartLot|StorageLocation
|
||||
*/
|
||||
public function resolvePart(BarcodeScanResultInterface $barcodeScan): ?Part
|
||||
public function resolveEntity(BarcodeScanResultInterface $barcodeScan): Part|PartLot|StorageLocation|null
|
||||
{
|
||||
if ($barcodeScan instanceof LocalBarcodeScanResult) {
|
||||
return $this->resolvePartFromLocal($barcodeScan);
|
||||
|
|
@ -134,27 +120,37 @@ final readonly class BarcodeScanResultHandler
|
|||
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) {
|
||||
case LabelSupportedElement::PART:
|
||||
$part = $this->em->find(Part::class, $barcodeScan->target_id);
|
||||
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;
|
||||
$entity = $this->resolveEntity($barcodeScan);
|
||||
if ($entity instanceof Part) {
|
||||
return $entity;
|
||||
}
|
||||
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