mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-03-01 04:49:36 +00:00
130 lines
3.5 KiB
PHP
130 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\LabelSystem\BarcodeScanner;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
/**
|
|
* This class represents the content of a lcsc.com barcode
|
|
* Its data structure is represented by {pbn:...,on:...,pc:...,pm:...,qty:...}
|
|
*/
|
|
class LCSCBarcodeScanResult implements BarcodeScanResultInterface
|
|
{
|
|
/**
|
|
* @param array<string, string> $fields
|
|
*/
|
|
public function __construct(
|
|
public readonly array $fields,
|
|
public readonly string $raw_input,
|
|
) {}
|
|
|
|
public function getSourceType(): BarcodeSourceType
|
|
{
|
|
return BarcodeSourceType::LCSC;
|
|
}
|
|
|
|
/**
|
|
* @return string|null The manufactures part number
|
|
*/
|
|
public function getPM(): ?string
|
|
{
|
|
$v = $this->fields['pm'] ?? null;
|
|
$v = $v !== null ? trim($v) : null;
|
|
return ($v === '') ? null : $v;
|
|
}
|
|
|
|
/**
|
|
* @return string|null The lcsc.com part number
|
|
*/
|
|
public function getPC(): ?string
|
|
{
|
|
$v = $this->fields['pc'] ?? null;
|
|
$v = $v !== null ? trim($v) : null;
|
|
return ($v === '') ? null : $v;
|
|
}
|
|
|
|
/**
|
|
* @return array|float[]|int[]|null[]|string[] An array of fields decoded from the barcode
|
|
*/
|
|
public function getDecodedForInfoMode(): array
|
|
{
|
|
// Keep it human-friendly
|
|
return [
|
|
'Barcode type' => 'LCSC',
|
|
'MPN (pm)' => $this->getPM() ?? '',
|
|
'LCSC code (pc)' => $this->getPC() ?? '',
|
|
'Qty' => $this->fields['qty'] ?? '',
|
|
'Order No (on)' => $this->fields['on'] ?? '',
|
|
'Pick Batch (pbn)' => $this->fields['pbn'] ?? '',
|
|
'Warehouse (wc)' => $this->fields['wc'] ?? '',
|
|
'Country/Channel (cc)' => $this->fields['cc'] ?? '',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Parses the barcode data to see if the input matches the expected format used by lcsc.com
|
|
* @param string $input
|
|
* @return bool
|
|
*/
|
|
public static function looksLike(string $input): bool
|
|
{
|
|
$s = trim($input);
|
|
|
|
// Your example: {pbn:...,on:...,pc:...,pm:...,qty:...}
|
|
if (!str_starts_with($s, '{') || !str_ends_with($s, '}')) {
|
|
return false;
|
|
}
|
|
|
|
// Must contain at least pm: and pc: (common for LCSC labels)
|
|
return (stripos($s, 'pm:') !== false) && (stripos($s, 'pc:') !== false);
|
|
}
|
|
|
|
/**
|
|
* Parse the barcode input string into the fields used by lcsc.com
|
|
* @param string $input
|
|
* @return self
|
|
*/
|
|
public static function parse(string $input): self
|
|
{
|
|
$raw = trim($input);
|
|
|
|
if (!self::looksLike($raw)) {
|
|
throw new InvalidArgumentException('Not an LCSC barcode');
|
|
}
|
|
|
|
$inner = trim($raw);
|
|
$inner = substr($inner, 1, -1); // remove { }
|
|
|
|
$fields = [];
|
|
|
|
// This format is comma-separated pairs, values do not contain commas in your sample.
|
|
$pairs = array_filter(
|
|
array_map('trim', explode(',', $inner)),
|
|
static fn(string $s): bool => $s !== ''
|
|
);
|
|
|
|
foreach ($pairs as $pair) {
|
|
$pos = strpos($pair, ':');
|
|
if ($pos === false) {
|
|
continue;
|
|
}
|
|
|
|
$k = trim(substr($pair, 0, $pos));
|
|
$v = trim(substr($pair, $pos + 1));
|
|
|
|
if ($k === '') {
|
|
continue;
|
|
}
|
|
|
|
$fields[$k] = $v;
|
|
}
|
|
|
|
if (!isset($fields['pm']) || trim($fields['pm']) === '') {
|
|
throw new InvalidArgumentException('LCSC barcode missing pm field');
|
|
}
|
|
|
|
return new self($fields, $raw);
|
|
}
|
|
}
|