diff --git a/app/Http/Controllers/AssetController.php b/app/Http/Controllers/AssetController.php index 8891084..de1db9e 100644 --- a/app/Http/Controllers/AssetController.php +++ b/app/Http/Controllers/AssetController.php @@ -198,6 +198,7 @@ class AssetController extends Controller { $request->validate([ 'file' => ['required','file','mimes:csv,txt'], + 'images_zip' => ['nullable','file','mimes:zip'], 'action' => ['nullable','in:preview,import'], ]); @@ -208,6 +209,24 @@ class AssetController extends Controller return back()->withErrors(['file' => 'File tidak bisa dibaca']); } + // Jika ada ZIP gambar, siapkan mapping filename => binary + $images = []; + if ($request->hasFile('images_zip')) { + $zipPath = $request->file('images_zip')->getRealPath(); + $zip = new \ZipArchive(); + if ($zip->open($zipPath) === true) { + for ($i = 0; $i < $zip->numFiles; $i++) { + $name = $zip->getNameIndex($i); + // abaikan folder + if (str_ends_with($name, '/')) { + continue; + } + $images[basename($name)] = $zip->getFromIndex($i); + } + $zip->close(); + } + } + $header = fgetcsv($handle); $rows = []; $line = 1; @@ -257,6 +276,7 @@ class AssetController extends Controller 'available_quantity' => (int) ($row['available_quantity'] ?? $row['quantity'] ?? 1), 'is_pool' => !empty($row['is_pool']), 'image_url' => $row['image_url'] ?? null, + 'image_file' => $row['image_file'] ?? null, ], 'target_id' => $targetId, ]; @@ -281,7 +301,8 @@ class AssetController extends Controller if ($row['status'] === 'invalid') { $invalid++; continue; } $payload = $row['payload']; $imageUrl = $payload['image_url'] ?? null; - unset($payload['image_url']); + $imageFile = $payload['image_file'] ?? null; + unset($payload['image_url'], $payload['image_file']); $assetModel = null; if ($row['target_id']) { @@ -296,21 +317,30 @@ class AssetController extends Controller $created++; } - // Download image jika disediakan - if ($assetModel && $imageUrl) { - try { - $resp = \Illuminate\Support\Facades\Http::get($imageUrl); - if ($resp->ok()) { - $path = "assets/{$assetModel->id}/import-".Str::random(6).".jpg"; - \Illuminate\Support\Facades\Storage::disk('public')->put($path, $resp->body()); - \App\Models\AssetPhoto::create([ - 'asset_id' => $assetModel->id, - 'path' => $path, - 'is_primary' => $assetModel->photos()->count() === 0, - ]); + // Tambahkan foto jika disediakan via URL atau file name di ZIP + if ($assetModel) { + $binary = null; + if ($imageUrl) { + try { + $resp = \Illuminate\Support\Facades\Http::get($imageUrl); + if ($resp->ok()) { + $binary = $resp->body(); + } + } catch (\Throwable $e) { + // abaikan error download agar import tetap lanjut } - } catch (\Throwable $e) { - // abaikan error download agar import tetap lanjut + } elseif ($imageFile && isset($images[$imageFile])) { + $binary = $images[$imageFile]; + } + + if ($binary) { + $path = "assets/{$assetModel->id}/import-".Str::random(6).".jpg"; + \Illuminate\Support\Facades\Storage::disk('public')->put($path, $binary); + \App\Models\AssetPhoto::create([ + 'asset_id' => $assetModel->id, + 'path' => $path, + 'is_primary' => $assetModel->photos()->count() === 0, + ]); } } } diff --git a/public/samples/assets_import_sample.csv b/public/samples/assets_import_sample.csv index 6693ddc..93899bc 100644 --- a/public/samples/assets_import_sample.csv +++ b/public/samples/assets_import_sample.csv @@ -1,6 +1,6 @@ -code,name,serial_number,status,category,location,rfid_tag,nfc_tag,is_consumable,quantity,available_quantity,is_pool,image_url -AST-90001,Laptop Dell XPS 13,SN-XPS-90001,Active,Laptop,Warehouse,RFID-10001,NFC-10001,0,1,1,0,https://images.unsplash.com/photo-1517336714731-489689fd1ca8?auto=format&fit=crop&w=800&q=80 -AST-90002,Printer HP LaserJet,SN-HP-90002,Active,Printer,Warehouse,RFID-10002,NFC-10002,0,1,1,0,https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?auto=format&fit=crop&w=800&q=80 -AST-90003,Kursi Ergonomis,SN-CHAIR-90003,Active,Furniture,Office A,RFID-10003,NFC-10003,0,10,10,1,https://images.unsplash.com/photo-1433838552652-f9a46b332c40?auto=format&fit=crop&w=800&q=80 -AST-90004,Tinta Printer Hitam,,Active,Consumable,Warehouse,,,1,50,50,0,https://images.unsplash.com/photo-1504384308090-c894fdcc538d?auto=format&fit=crop&w=800&q=80 -AST-90005,Router Mikrotik CCR,SN-RT-90005,Active,Network,Data Center,RFID-10005,NFC-10005,0,1,1,0,https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=800&q=80 +code,name,serial_number,status,category,location,rfid_tag,nfc_tag,is_consumable,quantity,available_quantity,is_pool,image_url,image_file +AST-90001,Laptop Dell XPS 13,SN-XPS-90001,Active,Laptop,Warehouse,RFID-10001,NFC-10001,0,1,1,0,https://images.unsplash.com/photo-1517336714731-489689fd1ca8?auto=format&fit=crop&w=800&q=80, +AST-90002,Printer HP LaserJet,SN-HP-90002,Active,Printer,Warehouse,RFID-10002,NFC-10002,0,1,1,0,,printer.jpg +AST-90003,Kursi Ergonomis,SN-CHAIR-90003,Active,Furniture,Office A,RFID-10003,NFC-10003,0,10,10,1,https://images.unsplash.com/photo-1433838552652-f9a46b332c40?auto=format&fit=crop&w=800&q=80, +AST-90004,Tinta Printer Hitam,,Active,Consumable,Warehouse,,,1,50,50,0,,tinta.jpg +AST-90005,Router Mikrotik CCR,SN-RT-90005,Active,Network,Data Center,RFID-10005,NFC-10005,0,1,1,0,https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=800&q=80, diff --git a/resources/views/assets/index.blade.php b/resources/views/assets/index.blade.php index 1fab8d8..49aa02a 100644 --- a/resources/views/assets/index.blade.php +++ b/resources/views/assets/index.blade.php @@ -327,14 +327,19 @@
Unggah file CSV (Excel bisa ekspor ke CSV). Header yang didukung:
- code,name,serial_number,status,category,location,rfid_tag,nfc_tag,is_consumable,quantity,available_quantity,is_pool,image_url.
- Baris tanpa nama akan ditandai invalid. Contoh file:
+ code,name,serial_number,status,category,location,rfid_tag,nfc_tag,is_consumable,quantity,available_quantity,is_pool,image_url,image_file.
+ Kolom image_url akan di-download; kolom image_file akan dicari di ZIP gambar (opsional). Baris tanpa nama akan ditandai invalid. Contoh file:
assets_import_sample.csv
image_file (misal printer.jpg, tinta.jpg).
+