Sindbad~EG File Manager
<?php
namespace App\Jobs;
use App\Models\ImportRun;
use App\Models\ms_stock;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate;
class ImportMsStockJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $timeout = 1200; // 20 menit
public int $tries = 1;
public function __construct(public int $importRunId) {}
public function handle(): void
{
$run = ImportRun::findOrFail($this->importRunId);
$run->update([
'status' => 'running',
'processed_rows' => 0,
'missing_items' => null,
'message' => null,
]);
$path = Storage::disk('local')->path($run->file_path);
$sheet = Excel::toCollection(null, $path)->first();
if (!$sheet || $sheet->count() < 2) {
$run->update(['status' => 'failed', 'message' => 'File kosong / format salah.']);
return;
}
// $header = $sheet->first()->toArray();
// $rows = $sheet->slice(1)->values();
// $map = $this->buildHeaderMap($header);
// $total = $rows->count();
// $run->update(['total_rows' => $total]);
$header = $sheet->first()->toArray();
// 1) buat map dulu
$map = $this->buildHeaderMap($header);
// 2) ambil rows lalu FILTER hanya baris yang punya no_inv & kode_brg
$rows = $sheet->slice(1)
->filter(function ($r) use ($map) {
$arr = $r->toArray();
// $noInvIdx = $map['gudang'] ?? null;
$kodeIdx = $map['kode_brg'] ?? null;
// if ($noInvIdx === null || $kodeIdx === null) {
if ($kodeIdx === null) {
// kalau header tidak ada, jangan buang semua baris
return true;
}
// $noInv = trim((string)($arr[$noInvIdx] ?? ''));
$kode = trim((string)($arr[$kodeIdx] ?? ''));
// return $noInv !== '' && $kode !== '';
return $kode !== '';
})
->values();
// 3) total setelah difilter (jadi sesuai data beneran)
$total = $rows->count();
$run->update(['total_rows' => $total]);
// Untuk master barang: updateOrCreate berdasarkan kode_brg
DB::beginTransaction();
try {
foreach ($rows as $i => $r) {
$kode = trim((string)($this->val($r, $map, 'kode_brg') ?? ''));
if ($kode === '') {
$run->update(['processed_rows' => $i + 1]);
continue;
}
ms_stock::updateOrCreate(
['kode_brg' => $kode],
[
'nama_brg' => trim((string)($this->val($r, $map, 'nama_brg') ?? '')) ?: '-',
'kelompok' => trim((string)($this->val($r, $map, 'kelompok') ?? '')) ?: '-',
'jenis' => trim((string)($this->val($r, $map, 'jenis') ?? '')) ?: '-',
'merk' => trim((string)($this->val($r, $map, 'merk') ?? '')) ?: '-',
'satuan' => trim((string)($this->val($r, $map, 'satuan') ?? '')) ?: '-',
'status' => trim((string)($this->val($r, $map, 'status') ?? '')) ?: '-',
'tglid' => now(),
]
);
$run->update(['processed_rows' => $i + 1]);
}
DB::commit();
$run->update(['status' => 'done', 'message' => 'Import master barang selesai.']);
} catch (\Throwable $e) {
DB::rollBack();
$run->update(['status' => 'failed', 'message' => $e->getMessage()]);
throw $e;
}
}
private function buildHeaderMap(array $header): array
{
$map = [];
foreach ($header as $idx => $h) {
$key = strtolower(trim((string)$h));
$key = str_replace([' ', '-'], '_', $key);
$map[$key] = $idx;
}
return $map;
}
// private function val($row, array $map, string $key)
// {
// $arr = $row->toArray();
// $key = strtolower($key);
// return isset($map[$key]) ? ($arr[$map[$key]] ?? null) : null;
// }
private function val($row, array $map, string $key)
{
$arr = $row->toArray();
$k = strtolower($key);
$aliases = [
'tgl_inv' => ['tgl_inv', 'tglinv', 'tanggal_invoice', 'tanggal_inv'],
'tgl_kirim' => ['tgl_kirim', 'tglkirim', 'tanggal_kirim'],
];
if (isset($map[$k])) return $arr[$map[$k]] ?? null;
if (isset($aliases[$k])) {
foreach ($aliases[$k] as $a) {
$a = strtolower($a);
if (isset($map[$a])) return $arr[$map[$a]] ?? null;
}
}
return null;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists