41
41
42
42
namespace App \Services \LabelSystem \Barcodes ;
43
43
44
+ use App \Entity \LabelSystem \LabelSupportedElement ;
44
45
use InvalidArgumentException ;
45
46
46
47
/**
47
48
* @see \App\Tests\Services\LabelSystem\Barcodes\BarcodeNormalizerTest
48
49
*/
49
- final class BarcodeNormalizer
50
+ final class BarcodeScanHelper
50
51
{
51
52
private const PREFIX_TYPE_MAP = [
52
- 'L ' => ' lot ' ,
53
- 'P ' => ' part ' ,
54
- 'S ' => ' location ' ,
53
+ 'L ' => LabelSupportedElement:: PART_LOT ,
54
+ 'P ' => LabelSupportedElement:: PART ,
55
+ 'S ' => LabelSupportedElement:: STORELOCATION ,
55
56
];
56
57
58
+ public const QR_TYPE_MAP = [
59
+ 'lot ' => LabelSupportedElement::PART_LOT ,
60
+ 'part ' => LabelSupportedElement::PART ,
61
+ 'location ' => LabelSupportedElement::STORELOCATION ,
62
+ ];
63
+
64
+ /**
65
+ * Parse the given barcode content and return the target type and ID.
66
+ * If the barcode could not be parsed, an exception is thrown.
67
+ * Using the $type parameter, you can specify how the barcode should be parsed. If set to null, the function
68
+ * will try to guess the type.
69
+ * @param string $input
70
+ * @param BarcodeSourceType|null $type
71
+ * @return BarcodeScanResult
72
+ */
73
+ public function scanBarcodeContent (string $ input , ?BarcodeSourceType $ type = null ): BarcodeScanResult
74
+ {
75
+ //Do specific parsing
76
+ if ($ type === BarcodeSourceType::INTERNAL ) {
77
+ return $ this ->parseInternalBarcode ($ input ) ?? throw new InvalidArgumentException ('Could not parse barcode ' );
78
+ }
79
+
80
+ //Null means auto and we try the different formats
81
+ $ result = $ this ->parseInternalBarcode ($ input );
82
+
83
+ if ($ result !== null ) {
84
+ return $ result ;
85
+ }
86
+ throw new InvalidArgumentException ('Unknown barcode format ' );
87
+ }
88
+
57
89
/**
58
- * Parses barcode content and normalizes it.
59
- * Returns an array in the format ['part', 1]: First entry contains element type, second the ID of the element.
90
+ * This function tries to interpret the given barcode content as an internal barcode.
91
+ * If the barcode could not be parsed at all, null is returned. If the barcode is a valid format, but could
92
+ * not be found in the database, an exception is thrown.
93
+ * @param string $input
94
+ * @return BarcodeScanResult|null
60
95
*/
61
- public function normalizeBarcodeContent (string $ input ): array
96
+ private function parseInternalBarcode (string $ input ): ? BarcodeScanResult
62
97
{
63
98
$ input = trim ($ input );
64
99
$ matches = [];
@@ -68,7 +103,11 @@ public function normalizeBarcodeContent(string $input): array
68
103
69
104
//Extract parts from QR code's URL
70
105
if (preg_match ('#^https?://.*/scan/(\w+)/(\d+)/?$# ' , $ input , $ matches )) {
71
- return [$ matches [1 ], (int ) $ matches [2 ]];
106
+ return new BarcodeScanResult (
107
+ target_type: self ::QR_TYPE_MAP [strtolower ($ matches [1 ])],
108
+ target_id: (int ) $ matches [2 ],
109
+ source_type: BarcodeSourceType::INTERNAL
110
+ );
72
111
}
73
112
74
113
//New Code39 barcode use L0001 format
@@ -80,7 +119,11 @@ public function normalizeBarcodeContent(string $input): array
80
119
throw new InvalidArgumentException ('Unknown prefix ' .$ prefix );
81
120
}
82
121
83
- return [self ::PREFIX_TYPE_MAP [$ prefix ], $ id ];
122
+ return new BarcodeScanResult (
123
+ target_type: self ::PREFIX_TYPE_MAP [$ prefix ],
124
+ target_id: $ id ,
125
+ source_type: BarcodeSourceType::INTERNAL
126
+ );
84
127
}
85
128
86
129
//During development the L-000001 format was used
@@ -92,19 +135,32 @@ public function normalizeBarcodeContent(string $input): array
92
135
throw new InvalidArgumentException ('Unknown prefix ' .$ prefix );
93
136
}
94
137
95
- return [self ::PREFIX_TYPE_MAP [$ prefix ], $ id ];
138
+ return new BarcodeScanResult (
139
+ target_type: self ::PREFIX_TYPE_MAP [$ prefix ],
140
+ target_id: $ id ,
141
+ source_type: BarcodeSourceType::INTERNAL
142
+ );
96
143
}
97
144
98
145
//Legacy Part-DB location labels used $L00336 format
99
146
if (preg_match ('#^\$L(\d{5,})$# ' , $ input , $ matches )) {
100
- return ['location ' , (int ) $ matches [1 ]];
147
+ return new BarcodeScanResult (
148
+ target_type: LabelSupportedElement::STORELOCATION ,
149
+ target_id: (int ) $ matches [1 ],
150
+ source_type: BarcodeSourceType::INTERNAL
151
+ );
101
152
}
102
153
103
154
//Legacy Part-DB used EAN8 barcodes for part labels. Format 0000001(2) (note the optional 8th digit => checksum)
104
155
if (preg_match ('#^(\d{7})\d?$# ' , $ input , $ matches )) {
105
- return ['part ' , (int ) $ matches [1 ]];
156
+ return new BarcodeScanResult (
157
+ target_type: LabelSupportedElement::PART ,
158
+ target_id: (int ) $ matches [1 ],
159
+ source_type: BarcodeSourceType::INTERNAL
160
+ );
106
161
}
107
162
108
- throw new InvalidArgumentException ('Unknown barcode format! ' );
163
+ //This function abstain from further parsing
164
+ return null ;
109
165
}
110
166
}
0 commit comments