Sindbad~EG File Manager

Current Path : /home/webg5288/www/laravel_kendal/app/Jobs/
Upload File :
Current File : /home/webg5288/www/laravel_kendal/app/Jobs/ImportMsStockJob.php

<?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