156 lines
6.6 KiB
PHP
156 lines
6.6 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\StockPosition;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Validation\ValidationException;
|
||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||
use Illuminate\Support\Facades\Log;
|
||
|
||
// Replace these with your actual model classes
|
||
use App\Models\StockBatch;
|
||
use App\Models\StockSection;
|
||
use Metzli\Encoder\Encoder;
|
||
use Metzli\Renderer\PngRenderer;
|
||
|
||
class ScannerController extends Controller {
|
||
|
||
|
||
public function barcodeScan(Request $request)
|
||
{
|
||
// 1) Validate the incoming JSON structure
|
||
// {"barcode_type": "stock_batch","payload":{"id": 7}}
|
||
try {
|
||
$data = $request->validate([
|
||
'barcode_type' => 'required|string|in:stock_batch,stock_section,stock_position,label_scanned,carrier_scanned',
|
||
'payload' => 'required|array',
|
||
'payload.id' => 'required|integer|min:1',
|
||
]);
|
||
} catch (ValidationException $e) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => 'validation_failed',
|
||
'message' => $e->errors(),
|
||
], 422);
|
||
}
|
||
|
||
$type = $data['barcode_type'];
|
||
$id = $data['payload']['id'];
|
||
|
||
try {
|
||
switch ($type) {
|
||
// ─────────────────────────────────────────────────────────────
|
||
case 'stock_batch':
|
||
// Attempt to load a StockBatch by ID. Adjust with(...) if you have relationships you want to return.
|
||
$batch = StockBatch::with(['stockEntries.physicalItem', 'stockEntries.sections.position.shelf.rack.line.room', 'stockEntries.supplier', 'files', 'supplier', 'stockEntries.statusHistory'])
|
||
->findOrFail($id);
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $batch,
|
||
], 200);
|
||
|
||
// ─────────────────────────────────────────────────────────────
|
||
case 'stock_section':
|
||
// Attempt to load a StockSection by ID.
|
||
$section = StockSection::with(['position.sections.entries.physicalItem', 'entries.physicalItem'])
|
||
->findOrFail($id);
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $section,
|
||
], 200);
|
||
|
||
// ─────────────────────────────────────────────────────────────
|
||
case 'stock_position':
|
||
// Attempt to load a StockPosition by ID.
|
||
$position = StockPosition::with(['shelf', 'sections.entries.physicalItem'])
|
||
->findOrFail($id);
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $position,
|
||
], 200);
|
||
|
||
// ─────────────────────────────────────────────────────────────
|
||
case 'label_scanned':
|
||
// Attempt to load a Label by ID. Replace with your real model/relations.
|
||
$label = Label::with(['product', 'batch'])
|
||
->findOrFail($id);
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $label,
|
||
], 200);
|
||
|
||
// ─────────────────────────────────────────────────────────────
|
||
case 'carrier_scanned':
|
||
// “Do something” for carrier scans. For example, mark the carrier as checked‐in.
|
||
// Here we just look up a Carrier and flip a boolean. Adjust to your real logic.
|
||
$carrier = Carrier::findOrFail($id);
|
||
$carrier->last_scanned_at = now();
|
||
$carrier->save();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
], 200);
|
||
|
||
// ─────────────────────────────────────────────────────────────
|
||
default:
|
||
// This will never run because our validator already limits barcode_type to the four values.
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => 'invalid_barcode_type',
|
||
], 400);
|
||
}
|
||
} catch (ModelNotFoundException $e) {
|
||
// Any of the findOrFail(...) calls threw a ModelNotFoundException
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => 'not_found',
|
||
'message' => "No record found for ID {$id} under type '{$type}'.",
|
||
], 404);
|
||
|
||
} catch (\Exception $e) {
|
||
// Log the exception so you can inspect it later
|
||
Log::error('Error in BarcodeController@scan', [
|
||
'barcode_type' => $type,
|
||
'id' => $id,
|
||
'exception' => $e->getMessage(),
|
||
'trace' => $e->getTraceAsString(),
|
||
]);
|
||
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => 'server_error',
|
||
'message' => 'An unexpected error occurred.',
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
public function batchBarcodePrint(Request $request) {
|
||
|
||
$code = Encoder::encode(json_encode(
|
||
[
|
||
"barcode_type" => "stock_batch",
|
||
"payload" => [
|
||
'id' => $request->input('id'),
|
||
]
|
||
]
|
||
));
|
||
$renderer = new PngRenderer();
|
||
|
||
$aztec_code = $renderer->render($code);
|
||
|
||
$base64_aztec_img = base64_encode($aztec_code);
|
||
$base64_aztec_src = "data:image/png;base64,{$base64_aztec_img}";
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $base64_aztec_src,
|
||
], 200);
|
||
}
|
||
|
||
}
|