mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-04-14 18:39:36 +00:00
Implement parsing of TME QR codes (#1324)
Some checks failed
Build assets artifact / Build assets artifact (push) Has been cancelled
Docker Image Build / build (linux/amd64, amd64, ubuntu-latest) (push) Has been cancelled
Docker Image Build / build (linux/arm/v7, armv7, ubuntu-24.04-arm) (push) Has been cancelled
Docker Image Build / build (linux/arm64, arm64, ubuntu-24.04-arm) (push) Has been cancelled
Docker Image Build (FrankenPHP) / build (linux/amd64, amd64, ubuntu-latest) (push) Has been cancelled
Docker Image Build (FrankenPHP) / build (linux/arm/v7, armv7, ubuntu-24.04-arm) (push) Has been cancelled
Docker Image Build (FrankenPHP) / build (linux/arm64, arm64, ubuntu-24.04-arm) (push) Has been cancelled
Static analysis / Static analysis (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, sqlite) (push) Has been cancelled
Docker Image Build / merge (push) Has been cancelled
Docker Image Build (FrankenPHP) / merge (push) Has been cancelled
Some checks failed
Build assets artifact / Build assets artifact (push) Has been cancelled
Docker Image Build / build (linux/amd64, amd64, ubuntu-latest) (push) Has been cancelled
Docker Image Build / build (linux/arm/v7, armv7, ubuntu-24.04-arm) (push) Has been cancelled
Docker Image Build / build (linux/arm64, arm64, ubuntu-24.04-arm) (push) Has been cancelled
Docker Image Build (FrankenPHP) / build (linux/amd64, amd64, ubuntu-latest) (push) Has been cancelled
Docker Image Build (FrankenPHP) / build (linux/arm/v7, armv7, ubuntu-24.04-arm) (push) Has been cancelled
Docker Image Build (FrankenPHP) / build (linux/arm64, arm64, ubuntu-24.04-arm) (push) Has been cancelled
Static analysis / Static analysis (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, sqlite) (push) Has been cancelled
Docker Image Build / merge (push) Has been cancelled
Docker Image Build (FrankenPHP) / merge (push) Has been cancelled
* Implement parsing of TME QR codes They are present on parts purchased on tme.eu. It's based on the LCSC parser. Some older codes I found are in upper-case so I handle those too. * Removed unused method * Fixed translation message keys * Try to find TME part via SPN --------- Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
This commit is contained in:
parent
34a84bce8f
commit
991daf0ead
7 changed files with 317 additions and 1 deletions
|
|
@ -105,6 +105,10 @@ final class BarcodeScanHelper
|
||||||
return new AmazonBarcodeScanResult($input);
|
return new AmazonBarcodeScanResult($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($type === BarcodeSourceType::TME) {
|
||||||
|
return TMEBarcodeScanResult::parse($input);
|
||||||
|
}
|
||||||
|
|
||||||
//Null means auto and we try the different formats
|
//Null means auto and we try the different formats
|
||||||
$result = $this->parseInternalBarcode($input);
|
$result = $this->parseInternalBarcode($input);
|
||||||
|
|
||||||
|
|
@ -144,6 +148,11 @@ final class BarcodeScanHelper
|
||||||
return new AmazonBarcodeScanResult($input);
|
return new AmazonBarcodeScanResult($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try TME barcode
|
||||||
|
if (TMEBarcodeScanResult::isTMEBarcode($input)) {
|
||||||
|
return TMEBarcodeScanResult::parse($input);
|
||||||
|
}
|
||||||
|
|
||||||
throw new InvalidArgumentException('Unknown barcode');
|
throw new InvalidArgumentException('Unknown barcode');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,6 +171,7 @@ final class BarcodeScanHelper
|
||||||
return LCSCBarcodeScanResult::parse($input);
|
return LCSCBarcodeScanResult::parse($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function parseUserDefinedBarcode(string $input): ?LocalBarcodeScanResult
|
private function parseUserDefinedBarcode(string $input): ?LocalBarcodeScanResult
|
||||||
{
|
{
|
||||||
$lot_repo = $this->entityManager->getRepository(PartLot::class);
|
$lot_repo = $this->entityManager->getRepository(PartLot::class);
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,10 @@ final readonly class BarcodeScanResultHandler
|
||||||
?? $this->em->getRepository(Part::class)->getPartBySPN($barcodeScan->asin);
|
?? $this->em->getRepository(Part::class)->getPartBySPN($barcodeScan->asin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($barcodeScan instanceof TMEBarcodeScanResult) {
|
||||||
|
return $this->resolvePartFromTME($barcodeScan);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,6 +240,26 @@ final readonly class BarcodeScanResultHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function resolvePartFromTME(TMEBarcodeScanResult $barcodeScan): ?Part
|
||||||
|
{
|
||||||
|
$pn = $barcodeScan->tmePartNumber;
|
||||||
|
if ($pn) {
|
||||||
|
$part = $this->em->getRepository(Part::class)->getPartByProviderInfo($pn);
|
||||||
|
if ($part !== null) {
|
||||||
|
return $part;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Try to find the part by SPN/SKU
|
||||||
|
$part = $this->em->getRepository(Part::class)->getPartBySPN($pn);
|
||||||
|
if ($part !== null) {
|
||||||
|
return $part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: search by MPN
|
||||||
|
return $this->em->getRepository(Part::class)->getPartByMPN($barcodeScan->mpn, $barcodeScan->manufacturer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to extract creation information for a part from the given barcode scan result. This can be used to
|
* Tries to extract creation information for a part from the given barcode scan result. This can be used to
|
||||||
* automatically fill in the info provider reference of a part, when creating a new part based on the scan result.
|
* automatically fill in the info provider reference of a part, when creating a new part based on the scan result.
|
||||||
|
|
@ -247,6 +271,20 @@ final readonly class BarcodeScanResultHandler
|
||||||
*/
|
*/
|
||||||
public function getCreateInfos(BarcodeScanResultInterface $scanResult): ?array
|
public function getCreateInfos(BarcodeScanResultInterface $scanResult): ?array
|
||||||
{
|
{
|
||||||
|
// TME
|
||||||
|
if ($scanResult instanceof TMEBarcodeScanResult) {
|
||||||
|
if ($scanResult->tmePartNumber === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'providerKey' => 'tme',
|
||||||
|
'providerId' => $scanResult->tmePartNumber,
|
||||||
|
'lotAmount' => $scanResult->quantity,
|
||||||
|
'lotName' => $scanResult->purchaseOrder,
|
||||||
|
'lotUserBarcode' => $scanResult->rawInput,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// LCSC
|
// LCSC
|
||||||
if ($scanResult instanceof LCSCBarcodeScanResult) {
|
if ($scanResult instanceof LCSCBarcodeScanResult) {
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -52,4 +52,7 @@ enum BarcodeSourceType: string
|
||||||
case LCSC = 'lcsc';
|
case LCSC = 'lcsc';
|
||||||
|
|
||||||
case AMAZON = 'amazon';
|
case AMAZON = 'amazon';
|
||||||
|
|
||||||
|
/** For TME (tme.eu) formatted QR codes */
|
||||||
|
case TME = 'tme';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
143
src/Services/LabelSystem/BarcodeScanner/TMEBarcodeScanResult.php
Normal file
143
src/Services/LabelSystem/BarcodeScanner/TMEBarcodeScanResult.php
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Services\LabelSystem\BarcodeScanner;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the content of a tme.eu barcode label.
|
||||||
|
* The format is space-separated KEY:VALUE tokens, e.g.:
|
||||||
|
* QTY:1000 PN:SMD0603-5K1-1% PO:32723349/7 MFR:ROYALOHM MPN:0603SAF5101T5E CoO:TH RoHS https://www.tme.eu/details/...
|
||||||
|
*/
|
||||||
|
readonly class TMEBarcodeScanResult implements BarcodeScanResultInterface
|
||||||
|
{
|
||||||
|
/** @var int|null Quantity (QTY) */
|
||||||
|
public ?int $quantity;
|
||||||
|
|
||||||
|
/** @var string|null TME part number (PN) */
|
||||||
|
public ?string $tmePartNumber;
|
||||||
|
|
||||||
|
/** @var string|null Purchase order number (PO) */
|
||||||
|
public ?string $purchaseOrder;
|
||||||
|
|
||||||
|
/** @var string|null Manufacturer name (MFR) */
|
||||||
|
public ?string $manufacturer;
|
||||||
|
|
||||||
|
/** @var string|null Manufacturer part number (MPN) */
|
||||||
|
public ?string $mpn;
|
||||||
|
|
||||||
|
/** @var string|null Country of origin (CoO) */
|
||||||
|
public ?string $countryOfOrigin;
|
||||||
|
|
||||||
|
/** @var bool Whether the part is RoHS compliant */
|
||||||
|
public bool $rohs;
|
||||||
|
|
||||||
|
/** @var string|null The product URL */
|
||||||
|
public ?string $productUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $fields Parsed key-value fields (keys uppercased)
|
||||||
|
* @param string $rawInput Original barcode string
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public array $fields,
|
||||||
|
public string $rawInput,
|
||||||
|
) {
|
||||||
|
$this->quantity = isset($this->fields['QTY']) ? (int) $this->fields['QTY'] : null;
|
||||||
|
$this->tmePartNumber = $this->fields['PN'] ?? null;
|
||||||
|
$this->purchaseOrder = $this->fields['PO'] ?? null;
|
||||||
|
$this->manufacturer = $this->fields['MFR'] ?? null;
|
||||||
|
$this->mpn = $this->fields['MPN'] ?? null;
|
||||||
|
$this->countryOfOrigin = $this->fields['COO'] ?? null;
|
||||||
|
$this->rohs = isset($this->fields['ROHS']);
|
||||||
|
$this->productUrl = $this->fields['URL'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSourceType(): BarcodeSourceType
|
||||||
|
{
|
||||||
|
return BarcodeSourceType::TME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDecodedForInfoMode(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Barcode type' => 'TME',
|
||||||
|
'TME Part No. (PN)' => $this->tmePartNumber ?? '',
|
||||||
|
'MPN' => $this->mpn ?? '',
|
||||||
|
'Manufacturer (MFR)' => $this->manufacturer ?? '',
|
||||||
|
'Qty' => $this->quantity !== null ? (string) $this->quantity : '',
|
||||||
|
'Purchase Order (PO)' => $this->purchaseOrder ?? '',
|
||||||
|
'Country of Origin (CoO)' => $this->countryOfOrigin ?? '',
|
||||||
|
'RoHS' => $this->rohs ? 'Yes' : 'No',
|
||||||
|
'URL' => $this->productUrl ?? '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the input looks like a TME barcode label (contains tme.eu URL).
|
||||||
|
*/
|
||||||
|
public static function isTMEBarcode(string $input): bool
|
||||||
|
{
|
||||||
|
return str_contains(strtolower($input), 'tme.eu');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the TME barcode string into a TMEBarcodeScanResult.
|
||||||
|
*/
|
||||||
|
public static function parse(string $input): self
|
||||||
|
{
|
||||||
|
$raw = trim($input);
|
||||||
|
|
||||||
|
if (!self::isTMEBarcode($raw)) {
|
||||||
|
throw new InvalidArgumentException('Not a TME barcode');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = [];
|
||||||
|
|
||||||
|
// Split on whitespace; each token is either KEY:VALUE, a bare keyword, or the URL
|
||||||
|
$tokens = preg_split('/\s+/', $raw);
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
if ($token === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The TME URL
|
||||||
|
if (str_starts_with(strtolower($token), 'http')) {
|
||||||
|
$fields['URL'] = $token;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$colonPos = strpos($token, ':');
|
||||||
|
if ($colonPos !== false) {
|
||||||
|
$key = strtoupper(substr($token, 0, $colonPos));
|
||||||
|
$value = substr($token, $colonPos + 1);
|
||||||
|
$fields[$key] = $value;
|
||||||
|
} else {
|
||||||
|
// Bare keyword like "RoHS"
|
||||||
|
$fields[strtoupper($token)] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new self($fields, $raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Tests\Services\LabelSystem\BarcodeScanner;
|
||||||
|
|
||||||
|
use App\Services\LabelSystem\BarcodeScanner\BarcodeSourceType;
|
||||||
|
use App\Services\LabelSystem\BarcodeScanner\TMEBarcodeScanResult;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class TMEBarcodeScanResultTest extends TestCase
|
||||||
|
{
|
||||||
|
private const EXAMPLE1 = 'QTY:1000 PN:SMD0603-5K1-1% PO:32723349/7 MFR:ROYALOHM MPN:0603SAF5101T5E CoO:TH RoHS https://www.tme.eu/details/SMD0603-5K1-1%25';
|
||||||
|
private const EXAMPLE2 = 'QTY:5 PN:ETQP3M6R8KVP PO:31199729/3 MFR:PANASONIC MPN:ETQP3M6R8KVP RoHS https://www.tme.eu/details/ETQP3M6R8KVP';
|
||||||
|
|
||||||
|
public function testIsTMEBarcode(): void
|
||||||
|
{
|
||||||
|
$this->assertFalse(TMEBarcodeScanResult::isTMEBarcode('invalid'));
|
||||||
|
$this->assertFalse(TMEBarcodeScanResult::isTMEBarcode('QTY:5 PN:ABC MPN:XYZ'));
|
||||||
|
$this->assertFalse(TMEBarcodeScanResult::isTMEBarcode(''));
|
||||||
|
|
||||||
|
$this->assertTrue(TMEBarcodeScanResult::isTMEBarcode(self::EXAMPLE1));
|
||||||
|
$this->assertTrue(TMEBarcodeScanResult::isTMEBarcode(self::EXAMPLE2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParseInvalidThrows(): void
|
||||||
|
{
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
TMEBarcodeScanResult::parse('not-a-tme-barcode');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParseExample1(): void
|
||||||
|
{
|
||||||
|
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE1);
|
||||||
|
|
||||||
|
$this->assertSame(1000, $scan->quantity);
|
||||||
|
$this->assertSame('SMD0603-5K1-1%', $scan->tmePartNumber);
|
||||||
|
$this->assertSame('32723349/7', $scan->purchaseOrder);
|
||||||
|
$this->assertSame('ROYALOHM', $scan->manufacturer);
|
||||||
|
$this->assertSame('0603SAF5101T5E', $scan->mpn);
|
||||||
|
$this->assertSame('TH', $scan->countryOfOrigin);
|
||||||
|
$this->assertTrue($scan->rohs);
|
||||||
|
$this->assertSame('https://www.tme.eu/details/SMD0603-5K1-1%25', $scan->productUrl);
|
||||||
|
$this->assertSame(self::EXAMPLE1, $scan->rawInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParseExample2(): void
|
||||||
|
{
|
||||||
|
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE2);
|
||||||
|
|
||||||
|
$this->assertSame(5, $scan->quantity);
|
||||||
|
$this->assertSame('ETQP3M6R8KVP', $scan->tmePartNumber);
|
||||||
|
$this->assertSame('31199729/3', $scan->purchaseOrder);
|
||||||
|
$this->assertSame('PANASONIC', $scan->manufacturer);
|
||||||
|
$this->assertSame('ETQP3M6R8KVP', $scan->mpn);
|
||||||
|
$this->assertNull($scan->countryOfOrigin);
|
||||||
|
$this->assertTrue($scan->rohs);
|
||||||
|
$this->assertSame('https://www.tme.eu/details/ETQP3M6R8KVP', $scan->productUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSourceType(): void
|
||||||
|
{
|
||||||
|
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE2);
|
||||||
|
$this->assertSame(BarcodeSourceType::TME, $scan->getSourceType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParseUppercaseUrl(): void
|
||||||
|
{
|
||||||
|
$input = 'QTY:500 PN:M0.6W-10K MFR:ROYAL.OHM MPN:MF006FF1002A50 PO:7792659/8 HTTPS://WWW.TME.EU/DETAILS/M0.6W-10K';
|
||||||
|
$this->assertTrue(TMEBarcodeScanResult::isTMEBarcode($input));
|
||||||
|
|
||||||
|
$scan = TMEBarcodeScanResult::parse($input);
|
||||||
|
$this->assertSame(500, $scan->quantity);
|
||||||
|
$this->assertSame('M0.6W-10K', $scan->tmePartNumber);
|
||||||
|
$this->assertSame('ROYAL.OHM', $scan->manufacturer);
|
||||||
|
$this->assertSame('MF006FF1002A50', $scan->mpn);
|
||||||
|
$this->assertSame('7792659/8', $scan->purchaseOrder);
|
||||||
|
$this->assertSame('HTTPS://WWW.TME.EU/DETAILS/M0.6W-10K', $scan->productUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetDecodedForInfoMode(): void
|
||||||
|
{
|
||||||
|
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE1);
|
||||||
|
$decoded = $scan->getDecodedForInfoMode();
|
||||||
|
|
||||||
|
$this->assertSame('TME', $decoded['Barcode type']);
|
||||||
|
$this->assertSame('SMD0603-5K1-1%', $decoded['TME Part No. (PN)']);
|
||||||
|
$this->assertSame('0603SAF5101T5E', $decoded['MPN']);
|
||||||
|
$this->assertSame('ROYALOHM', $decoded['Manufacturer (MFR)']);
|
||||||
|
$this->assertSame('1000', $decoded['Qty']);
|
||||||
|
$this->assertSame('Yes', $decoded['RoHS']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
|
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
|
||||||
<file id="messages.en">
|
<file id="messages.de">
|
||||||
<unit id="x_wTSQS" name="attachment_type.caption">
|
<unit id="x_wTSQS" name="attachment_type.caption">
|
||||||
<segment state="translated">
|
<segment state="translated">
|
||||||
<source>attachment_type.caption</source>
|
<source>attachment_type.caption</source>
|
||||||
|
|
@ -12861,6 +12861,12 @@ Buerklin-API-Authentication-Server:
|
||||||
<target>Amazon Barcode</target>
|
<target>Amazon Barcode</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="d.V2Pid" name="scan_dialog.mode.tme">
|
||||||
|
<segment state="translated">
|
||||||
|
<source>scan_dialog.mode.tme</source>
|
||||||
|
<target>TME Barcode</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
<unit id="BQWuR_G" name="settings.ips.canopy">
|
<unit id="BQWuR_G" name="settings.ips.canopy">
|
||||||
<segment state="translated">
|
<segment state="translated">
|
||||||
<source>settings.ips.canopy</source>
|
<source>settings.ips.canopy</source>
|
||||||
|
|
|
||||||
|
|
@ -12863,6 +12863,12 @@ Buerklin-API Authentication server:
|
||||||
<target>Amazon barcode</target>
|
<target>Amazon barcode</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="d.V2Pid" name="scan_dialog.mode.tme">
|
||||||
|
<segment state="translated">
|
||||||
|
<source>scan_dialog.mode.tme</source>
|
||||||
|
<target>TME barcode</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
<unit id="BQWuR_G" name="settings.ips.canopy">
|
<unit id="BQWuR_G" name="settings.ips.canopy">
|
||||||
<segment state="translated">
|
<segment state="translated">
|
||||||
<source>settings.ips.canopy</source>
|
<source>settings.ips.canopy</source>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue