Generalized interpretation of format06 barcodes, added ids for mouser

This commit is contained in:
jona 2024-12-22 17:57:59 +01:00 committed by Jan Böhmer
parent 67bf365b4a
commit 03ec4a9f84
3 changed files with 116 additions and 46 deletions

View file

@ -90,7 +90,7 @@ final class BarcodeScanHelper
return $this->parseIPNBarcode($input) ?? throw new InvalidArgumentException('Could not parse barcode');
}
if ($type === BarcodeSourceType::VENDOR) {
return $this->parseDigikeyBarcode($input) ?? throw new InvalidArgumentException('Could not parse barcode');
return $this->parseFormat06Barcode($input) ?? throw new InvalidArgumentException('Could not parse barcode');
}
//Null means auto and we try the different formats
@ -112,7 +112,7 @@ final class BarcodeScanHelper
return $result;
}
$result = $this->parseDigikeyBarcode($input);
$result = $this->parseFormat06Barcode($input);
if ($result !== null) {
return $result;
}
@ -120,51 +120,99 @@ final class BarcodeScanHelper
throw new InvalidArgumentException('Unknown barcode');
}
private function parseDigikeyBarcode(string $input): ?VendorBarcodeScanResult
/**
* Parses Format 06 Barcodes according to ISO/IEC 15434. That standard calls on ASC MH10 to specify
* the data identifiers, but these are way too many to incorporate here. EIGP 114.2018 is yet another standard
* based on Format 06 which specifies identifiers for the electronics industry. I've included the identifiers
* from that standard, plus the extra ones I found on Digikey and Mouser Bags.
* @param string $input what was read from the barcode
* @return ?array Array of the form ["Meaning" => "Value"]
*/
private function decodeFormat06Barcode(string $input): ?array
{
if(!str_starts_with($input, "[)>\u{1E}06\u{1D}")){
return null;
}
if(str_ends_with($input, "\u{04}")){
$input = substr($input, 0, -1);
}
$barcodeParts = explode("\u{1D}",$input);
if (count($barcodeParts) !== 16){
//get rid of the Format 06 identifier
array_shift($barcodeParts);
if (count($barcodeParts) < 2){
return null;
}
$fieldIds = [
['id' => '', 'name' => ''],
['id' => 'P', 'name' => 'Customer Part Number'],
['id' => '1P', 'name' => 'Supplier Part Number'],
['id' => '30P','name' => 'Digikey Part Number'],
['id' => 'K', 'name' => 'Purchase Order Part Number'],
['id' => '1K', 'name' => 'Digikey Sales Order Number'],
['id' => '10K','name' => 'Digikey Invoice Number'],
['id' => '9D', 'name' => 'Date Code'],
['id' => '1T', 'name' => 'Lot Code'],
['id' => '11K','name' => 'Packing List Number'],
['id' => '4L', 'name' => 'Country of Origin'],
['id' => 'Q', 'name' => 'Quantity'],
['id' => '11Z','name' => 'Label Type'],
['id' => '12Z','name' => 'Part ID'],
['id' => '13Z','name' => 'NA'],
['id' => '20Z','name' => 'Padding']
//IDs per EIGP 114.2018
'6D' => 'Ship Date',
'P' => 'Customer Part Number',
'1P' => 'Supplier Part Number',
'Q' => 'Quantity',
'K' => 'Purchase Order Part Number',
'4K' => 'Purchase Order Line Number',
'9D' => 'Date Code',
'10D' => 'Alternative Date Code',
'1T' => 'Lot Code',
'4L' => 'Country of Origin',
'3S' => 'Package ID 1',
'4S' => 'Package ID 2',
'5S' => 'Package ID 3',
'11K' => 'Packing List Number',
'S' => 'Serial Number',
'33P' => 'BIN Code',
'13Q' => 'Package Count',
'2P' => 'Revision Number',
//IDs used by Digikey
'30P' => 'Digikey Part Number',
'1K' => 'Sales Order Number',
'10K' => 'Invoice Number',
'11Z' => 'Label Type',
'12Z' => 'Part ID',
'13Z' => 'NA',
'20Z' => 'Padding',
//IDs used by Mouser
'14K' => 'Position in Order',
'1V' => 'Manufacturer',
];
$results = [];
foreach ($barcodeParts as $index => $part) {
$fieldProps = $fieldIds[$index];
if(!str_starts_with($part, $fieldProps['id'])){
foreach($barcodeParts as $part) {
//^ 0* ([1-9]? \d* [A-Z])
//Start of the string Leading zeros are discarded Not a zero Any number of digits single uppercase Letter
// 00 1 4 K
if(!preg_match('/^0*([1-9]?\d*[A-Z])/', $part, $matches)) {
return null;
}
$results[$fieldProps['name']] = substr($part, strlen($fieldProps['id']));
$meaning = $fieldIds[$matches[0]];
$fieldValue = substr($part, strlen($matches[0]));
$results[$meaning] = $fieldValue;
}
return $results;
}
/**
* Decodes a Format06 Barcode and puts it into a VendorBarcodeScanResult
* See decodeFormat06Barcode for details
*/
private function parseFormat06Barcode(string $input): ?VendorBarcodeScanResult{
$results = $this->decodeFormat06Barcode($input);
if($results === null){
return null;
}
return new VendorBarcodeScanResult(
'Digikey',
$results['Supplier Part Number'],
$results['Digikey Part Number'],
$results['Date Code'],
$results['Quantity']
manufacturer_part_number: $results['Supplier Part Number'] ?? null,
vendor_part_number: $results['Digikey Part Number'] ?? null,
date_code: $results['Date Code'] ?? null,
quantity: $results['Quantity'] ?? null,
manufacturer: $results['Manufacturer'] ?? null,
);
}