filters = $filters; } public function collection() { $query = DB::table('invoice_payments') ->leftJoin('invoice_payment_details', 'invoice_payment_details.invoice_payment_id', '=', 'invoice_payments.id') ->leftJoin('claim_requests', 'claim_requests.id', '=', 'invoice_payment_details.claim_request_id') ->leftJoin('request_logs', 'request_logs.id', '=', 'claim_requests.request_log_id') ->leftJoin('organizations', 'organizations.id', '=', 'request_logs.organization_id') ->leftJoin('members', 'members.id', '=', 'request_logs.member_id') ->leftJoin('specialities', 'specialities.id', '=', 'request_logs.specialities_id') ->leftJoin('icd', DB::raw("icd.code"), '=', DB::raw("SUBSTRING_INDEX(request_logs.diagnosis, ',', 1)")) ->orderBy('request_logs.service_code', 'desc') ->select( 'invoice_payments.*', 'organizations.name as organization_name', 'members.name as member_name', 'request_logs.diagnosis as code_diagnosis', 'request_logs.service_code', 'request_logs.dppj', 'specialities.name as specialities_name', 'request_logs.submission_date as in', 'request_logs.discharge_date as out', 'request_logs.code as code_log', 'members.payor_id', 'request_logs.nominal as amount', 'claim_requests.request_log_id', 'members.member_id as batch_number', 'request_logs.keterangan', 'icd.name as diagnosis', 'request_logs.type_of_member' ); if (!empty($this->filters['search'])) { $query->where('invoice_number', 'like', '%' . $this->filters['search'] . '%'); } if (!empty($this->filters['start_date'])) { $query->whereDate('invoice_payments.created_at', '>=', $this->filters['start_date']); } if (!empty($this->filters['end_date'])) { $query->whereDate('invoice_payments.created_at', '<=', $this->filters['end_date']); } if (!empty($this->filters['orderBy'])) { $query->orderBy( $this->filters['orderBy'], $this->filters['order'] ?? 'asc' ); } $items = $query->get(); // ambil request_log_id $requestLogIds = $items ->pluck('request_log_id') ->filter() ->unique() ->values(); // set benefit header (hanya yg dipakai) $this->benefits = DB::table('request_log_benefits') ->join('benefits', 'benefits.id', '=', 'request_log_benefits.benefit_id') ->whereIn('request_log_benefits.request_log_id', $requestLogIds) ->select('benefits.id', 'benefits.description') ->distinct() ->orderBy('benefits.id') ->pluck('benefits.description', 'benefits.id') ->toArray(); // 🔥 preload benefit amount SEKALI (anti N+1) $this->benefitAmounts = DB::table('request_log_benefits') ->whereIn('request_log_id', $requestLogIds) ->get() ->groupBy('request_log_id'); return $items; } public function map($item): array { $this->no++; $this->grandTotal += (float) $item->amount_paid; $benefitData = $this->getBenefitAmountsWithTotal($item->request_log_id); return array_merge([ // $this->no, (string) $item->invoice_number, // (string) $item->payment_number, '', '', '', (string) $item->no_reference, '', '', (string) ($item->code_log ?? '-'), (string) ($item->payor_id ?? '-'), '', '', (string) ($item->organization_name ?? '-'), (string) ($item->member_name ?? '-'), (string) ($item->batch_number ?? '-'), (string) $benefitData['total'], '', '', ], $benefitData['amounts'], [ (string) ($item->in ?? '-'), (string) ($item->out ?? '-'), '', (string) ($item->diagnosis ?? '-'), (string) ($item->type_of_member ?? '-'), // omt (string) ($item->service_code == 'OP' ? 'RJ' : 'RI'), '', '', '', (string) ($item->dppj ?? '-'), (string) ($item->in ?? '-'), (string) ($item->out ?? '-'), (string) ($item->specialities_name ?? '-'), 'Karyawan', '', '', '', (string) ($item->keterangan ?? '-'), // (string) $item->invoice_date, // (string) $item->start_date, // (string) $item->end_date, // (float) $item->amount_paid, // (string) $item->created_at, // (string) $item->updated_at, ]); } public function headings(): array { $this->initBenefits(); return array_merge([ // 'No', 'No Invoice', //ok // 'Pembayaran Ke', 'MONTH', //ok 'PERIODE SES', //ok 'SUBMIT INV/SES', //ok 'REFERENCE', //ok 'RECEIVED', //ok 'INV. DATE', //ok 'CODE', //ok 'VENDOR', //ok 'PO', //ok 'SES', //ok 'MAIN DESCRIPTION', //ok 'DESCRIPTION', //ok 'BN', //ok 'AMOUNT', //ok 'WBS', // ok 'NOTE', // ok ], array_values($this->benefits), [ 'DEPARTURE', // ok 'ARRIVED', // ok 'TEMPORARY DIAGNOSA', // ok 'FINAL DIAGNOSA', 'NOTE (OMT / NON OMT)', 'RI/RJ', // OK 'Dept', // OK 'Cost Center', // OK 'No.TA', // OK 'DPJP', // OK 'IN', // OK 'OUT', // OK 'SPECIALIST', // OK 'Employee', // OK 'Total Invoice sebelum BPJS', // OK 'BPJS', // OK 'Ditanggung Perusahaan', // OK 'KETERANGAN', // OK // 'Tanggal Invoice', // 'Start Date', // 'End Date', // 'Nominal Pembayaran', // 'Created At', // 'Updated At', ]); } public function title(): string { return 'VOP & VIP'; } /** * FOOTER: Grand Total */ public function registerEvents(): array { return [ AfterSheet::class => function (AfterSheet $event) { // $event->sheet->getStyle('A1:AO1') // ->getFont() // ->setBold(true); $highestColumn = $event->sheet->getDelegate()->getHighestColumn(); $event->sheet->getStyle('A1:' . $highestColumn . '1') ->getFont() ->setBold(true); // $row = $event->sheet->getHighestRow() + 1; // $event->sheet->setCellValue("A{$row}", 'Grand Total'); // $event->sheet->setCellValue("G{$row}", $this->grandTotal); // // Bold footer // $event->sheet->getStyle("A{$row}:G{$row}") // ->getFont() // ->setBold(true); }, ]; } /** * FORCE: object → string */ public function bindValue(Cell $cell, $value) { if (is_object($value) || is_array($value)) { $value = json_encode($value); } $cell->setValueExplicit($value, DataType::TYPE_STRING); return true; } protected function getBenefitAmountsWithTotal(?int $requestLogId): array { if (!$requestLogId || !isset($this->benefitAmounts[$requestLogId])) { return [ 'amounts' => array_fill(0, count($this->benefits), 0), 'total' => 0, ]; } $rows = $this->benefitAmounts[$requestLogId] ->pluck('amount_approved', 'benefit_id') ->toArray(); $amounts = []; $total = 0; foreach ($this->benefits as $benefitId => $desc) { $amount = (float) ($rows[$benefitId] ?? 0); $amounts[] = $amount; $total += $amount; } // 🔥 kalau ini memang mau jadi grand total global $this->grandTotal += $total; return [ 'amounts' => $amounts, 'total' => $total, ]; } protected function initBenefits(): void { if ($this->benefitInitialized) { return; } // ambil request_log_id dulu $requestLogIds = DB::table('invoice_payments') ->leftJoin('invoice_payment_details', 'invoice_payment_details.invoice_payment_id', '=', 'invoice_payments.id') ->leftJoin('claim_requests', 'claim_requests.id', '=', 'invoice_payment_details.claim_request_id') ->whereNotNull('claim_requests.request_log_id') ->pluck('claim_requests.request_log_id') ->unique() ->values(); if ($requestLogIds->isEmpty()) { $this->benefits = []; return; } $this->benefits = DB::table('request_log_benefits') ->join('benefits', 'benefits.id', '=', 'request_log_benefits.benefit_id') ->whereIn('request_log_benefits.request_log_id', $requestLogIds) ->select('benefits.id', 'benefits.description') ->distinct() ->orderBy('benefits.id') ->pluck('benefits.description', 'benefits.id') ->toArray(); $this->benefitInitialized = true; } }