has('per_page') ? $request->input('per_page') : 10; $corporate = Corporate::where('code', 'PRAY')->first(); if (!$corporate) { return response()->json([ 'message' => 'Corporate Primayan Medicare (PRAY) not found', 'data' => [] ], 404); } // Subquery to aggregate amounts from request_log_benefits $subQueryAmount = DB::table('request_log_benefits') ->select('request_log_id', DB::raw('SUM(amount_incurred) as total_incurred'), DB::raw('SUM(amount_approved) as total_approved'), DB::raw('SUM(excess_paid) as total_excess')) ->whereNull('deleted_at') ->groupBy('request_log_id'); $query = DB::table('claim_requests') ->join('members', 'claim_requests.member_id', '=', 'members.id') ->join('corporate_employees', 'corporate_employees.member_id', '=', 'members.id') ->leftJoin('organizations', 'claim_requests.organization_id', '=', 'organizations.id') ->leftJoin('claims', 'claim_requests.claim_id', '=', 'claims.id') ->leftJoin('request_logs', 'claim_requests.request_log_id', '=', 'request_logs.id') ->leftJoinSub($subQueryAmount, 'log_amounts', function ($join) { $join->on('request_logs.id', '=', 'log_amounts.request_log_id'); }) ->leftJoin('plans', 'claims.plan_id', '=', 'plans.id') ->leftJoin('benefits', 'claims.benefit_id', '=', 'benefits.id') ->where('corporate_employees.corporate_id', $corporate->id) ->whereNull('corporate_employees.deleted_at') ->whereNull('claim_requests.deleted_at') ->when($request->input('search'), function ($query, $search) { $query->where(function ($query) use ($search) { $query->orWhere('members.name', 'like', "%" . $search . "%") ->orWhere('members.member_id', 'like', "%" . $search . "%") ->orWhere('claim_requests.code', 'like', "%" . $search . "%") ->orWhere('corporate_employees.nik', 'like', "%" . $search . "%"); }); }) ->when($request->input('start_date'), function ($query, $start_date) { $query->where('claim_requests.created_at', '>=', $start_date); }) ->when($request->input('end_date'), function ($query, $end_date) { $query->where('claim_requests.created_at', '<=', $end_date . ' 23:59:59'); }) ->when($request->input('status'), function ($query, $status) { if ($status !== 'all') { $query->where('claim_requests.status', $status); } }) ->when($request->input('provider_id'), function ($query, $provider_id) { if ($provider_id !== 'all') { $query->where('claim_requests.organization_id', $provider_id); } }) ->select( 'claim_requests.id', 'claim_requests.code as request_code', 'claim_requests.status', 'claim_requests.created_at as request_date', 'claim_requests.service_code', 'claims.code as claim_code', 'request_logs.code as log_code', DB::raw('COALESCE(log_amounts.total_incurred, claims.amount_incurred, 0) as amount_incurred'), DB::raw('COALESCE(log_amounts.total_approved, claims.amount_approved, 0) as amount_approved'), DB::raw('COALESCE(claims.amount_not_approved, 0) as amount_not_approved'), DB::raw('COALESCE(log_amounts.total_excess, claims.excess_paid, 0) as excess_paid'), 'claims.benefit_code', 'claims.benefit_desc', 'members.name as member_name', 'members.member_id as member_number', 'members.birth_date', 'members.gender', 'corporate_employees.nik', 'corporate_employees.branch_code', 'organizations.name as provider_name', 'plans.code as plan_code', 'benefits.code as benefit_code_ref' ) ->orderBy('claim_requests.created_at', 'desc'); $results = $query->paginate($limit)->appends($request->all()); // Get Providers for filter $providers = DB::table('claim_requests') ->join('members', 'claim_requests.member_id', '=', 'members.id') ->join('corporate_employees', 'corporate_employees.member_id', '=', 'members.id') ->join('organizations', 'claim_requests.organization_id', '=', 'organizations.id') ->where('corporate_employees.corporate_id', $corporate->id) ->whereNull('claim_requests.deleted_at') ->select('organizations.id', 'organizations.name') ->groupBy('organizations.id', 'organizations.name') ->get(); return Helper::responseJson([ 'results' => Helper::paginateResources($results), 'providers' => $providers, ]); } /** * Export transactions to Excel */ public function export(Request $request) { $corporate = Corporate::where('code', 'PRAY')->first(); if (!$corporate) { return response()->json([ 'message' => 'Corporate Primayan Medicare (PRAY) not found', ], 404); } $exportType = $request->input('export_type', 'list'); if ($exportType === 'summary') { return $this->exportSummary($corporate); } // Subquery to aggregate amounts from request_log_benefits $subQueryAmount = DB::table('request_log_benefits') ->select('request_log_id', DB::raw('SUM(amount_incurred) as total_incurred'), DB::raw('SUM(amount_approved) as total_approved'), DB::raw('SUM(excess_paid) as total_excess')) ->whereNull('deleted_at') ->groupBy('request_log_id'); $results = DB::table('claim_requests') ->join('members', 'claim_requests.member_id', '=', 'members.id') ->join('corporate_employees', 'corporate_employees.member_id', '=', 'members.id') ->leftJoin('organizations', 'claim_requests.organization_id', '=', 'organizations.id') ->leftJoin('claims', 'claim_requests.claim_id', '=', 'claims.id') ->leftJoin('request_logs', 'claim_requests.request_log_id', '=', 'request_logs.id') ->leftJoinSub($subQueryAmount, 'log_amounts', function ($join) { $join->on('request_logs.id', '=', 'log_amounts.request_log_id'); }) ->leftJoin('plans', 'claims.plan_id', '=', 'plans.id') ->leftJoin('benefits', 'claims.benefit_id', '=', 'benefits.id') ->where('corporate_employees.corporate_id', $corporate->id) ->whereNull('corporate_employees.deleted_at') ->whereNull('claim_requests.deleted_at') ->when($request->input('search'), function ($query, $search) { $query->where(function ($query) use ($search) { $query->orWhere('members.name', 'like', "%" . $search . "%") ->orWhere('members.member_id', 'like', "%" . $search . "%") ->orWhere('claim_requests.code', 'like', "%" . $search . "%") ->orWhere('corporate_employees.nik', 'like', "%" . $search . "%"); }); }) ->when($request->input('start_date'), function ($query, $start_date) { $query->where('claim_requests.created_at', '>=', $start_date); }) ->when($request->input('end_date'), function ($query, $end_date) { $query->where('claim_requests.created_at', '<=', $end_date . ' 23:59:59'); }) ->when($request->input('status'), function ($query, $status) { if ($status !== 'all') { $query->where('claim_requests.status', $status); } }) ->when($request->input('provider_id'), function ($query, $provider_id) { if ($provider_id !== 'all') { $query->where('claim_requests.organization_id', $provider_id); } }) ->select( 'claim_requests.id', 'claim_requests.code as request_code', 'claim_requests.status', 'claim_requests.created_at as request_date', 'claim_requests.service_code', 'claims.code as claim_code', 'request_logs.code as log_code', DB::raw('COALESCE(log_amounts.total_incurred, claims.amount_incurred, 0) as amount_incurred'), DB::raw('COALESCE(log_amounts.total_approved, claims.amount_approved, 0) as amount_approved'), DB::raw('COALESCE(claims.amount_not_approved, 0) as amount_not_approved'), DB::raw('COALESCE(log_amounts.total_excess, claims.excess_paid, 0) as excess_paid'), 'claims.benefit_code', 'claims.benefit_desc', 'members.name as member_name', 'members.member_id as member_number', 'members.birth_date', 'members.gender', 'corporate_employees.nik', 'corporate_employees.branch_code', 'organizations.name as provider_name', 'plans.code as plan_code', 'benefits.code as benefit_code_ref' ) ->orderBy('claim_requests.created_at', 'desc') ->get(); $fileName = 'PrimayanMedicare-List-' . now()->format('Y-m-d_H-i-s') . '.xlsx'; $filePath = storage_path('app/public/temp/' . $fileName); if (!is_dir(storage_path('app/public/temp'))) { mkdir(storage_path('app/public/temp'), 0755, true); } $writer = WriterEntityFactory::createXLSXWriter(); $writer->openToFile($filePath); $serviceCodeMap = [ 'OP' => 'Outpatient', 'IP' => 'Inpatient', 'DE' => 'Dental', 'MA' => 'Maternal', 'GL' => 'Optical', 'MCU' => 'Medical Check Up', 'MEDIVAC' => 'Medical Emergency Evacuation', ]; $headers = [ 'No', 'Code Claim / Code LOG', 'Member Name', 'Member Number', 'NIK', 'Birth Date', 'Gender', 'Plan', 'Benefit', 'Service', 'Provider', 'Request Date', 'Amount Incurred', 'Amount Approved', 'Amount Not Approved', 'Excess Paid', 'Status', ]; $headerRow = WriterEntityFactory::createRowFromArray($headers); $writer->addRow($headerRow); $no = 1; foreach ($results as $row) { $serviceCode = $row->service_code ?? '-'; $serviceName = $serviceCodeMap[$serviceCode] ?? $serviceCode; $rowData = [ $no++, ($row->claim_code && $row->log_code) ? $row->claim_code . ' / ' . $row->log_code : ($row->claim_code ?? $row->log_code ?? $row->request_code ?? '-'), $row->member_name ?? '-', $row->member_number ?? '-', $row->nik ?? '-', $row->birth_date ?? '-', $row->gender ?? '-', $row->plan_code ?? '-', $row->benefit_name ?? $row->benefit_desc ?? '-', $serviceName, $row->provider_name ?? '-', $row->request_date ?? '-', $row->amount_incurred ?? 0, $row->amount_approved ?? 0, $row->amount_not_approved ?? 0, $row->excess_paid ?? 0, $row->status ?? '-', ]; $dataRow = WriterEntityFactory::createRowFromArray($rowData); $writer->addRow($dataRow); } $writer->close(); return Helper::responseJson([ 'file_name' => 'Primayan Medicare List ' . now()->format('Y-m-d H:i:s'), 'file_url' => Storage::disk('public')->url('temp/' . $fileName), ]); } private function exportSummary($corporate) { // Get all branch codes $branches = DB::table('corporate_employees') ->where('corporate_id', $corporate->id) ->whereNull('deleted_at') ->select('branch_code') ->groupBy('branch_code') ->get(); $fileName = 'PrimayanMedicare-Summary-' . now()->format('Y-m-d_H-i-s') . '.xlsx'; $filePath = storage_path('app/public/temp/' . $fileName); if (!is_dir(storage_path('app/public/temp'))) { mkdir(storage_path('app/public/temp'), 0755, true); } $codeRSMap = [ 'AI' => 'ABI', 'BB' => 'PHBB', 'BT' => 'PHBT', 'BU' => 'PHBU', 'BW' => 'PHBW', 'CI' => 'PHPC', 'CO' => 'FABS', 'DE' => 'PHDE', 'EV' => 'PHEV', 'HE' => 'PHHE', 'KG' => 'PHKG', 'KI' => 'KMI', 'KR' => 'PHKA', 'KV' => 'KAVA', 'LM' => 'LMS', 'LY' => 'LYNAS', 'MK' => 'PHMA', 'MS' => 'EYEQU', 'PF' => 'FMC', 'PS' => 'PHPK', 'PY' => 'PHBP', 'RA' => 'PHRA', 'SB' => 'PHSB', 'SF' => 'SFI', 'SG' => 'PHSM', 'SM' => 'SIM', 'SO' => 'PHSW', 'SS' => 'SAS', 'TG' => 'PHTA', 'UP' => 'UKRIDA', 'WS' => 'WEST' ]; $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Header Date Range (Row 1) $dateRange = now()->startOfMonth()->format('j F') . ' - ' . now()->format('j F Y'); $sheet->setCellValue('A1', strtoupper($dateRange)); $sheet->mergeCells('A1:G1'); $sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // Table Headers (Row 3) $headers = ['Code RS', 'Branch Code', 'Total Benefit', 'Deposit 10%', 'Pemakaian Benefit Obat & Rujukan', 'Pemakaian Telekonsultasi', 'Sisa Deposit']; $sheet->fromArray($headers, null, 'A3'); $sheet->getStyle('A3:G3')->applyFromArray([ 'font' => [ 'bold' => true, ], 'fill' => [ 'fillType' => Fill::FILL_SOLID, 'startColor' => [ 'rgb' => 'C6E0B4' ] ], 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, ] ] ]); $row = 4; foreach ($branches as $branch) { $branchCode = $branch->branch_code ?? '-'; $codeRS = $codeRSMap[$branchCode] ?? '-'; $totalDeposit = DB::table('corporate_employees') ->join('member_plans', 'corporate_employees.member_id', '=', 'member_plans.member_id') ->join('plans', 'member_plans.plan_id', '=', 'plans.id') ->where('corporate_employees.corporate_id', $corporate->id) ->where(function($query) use ($branchCode) { if ($branchCode === '-') { $query->whereNull('corporate_employees.branch_code')->orWhere('corporate_employees.branch_code', ''); } else { $query->where('corporate_employees.branch_code', $branchCode); } }) ->whereNull('corporate_employees.deleted_at') ->whereNull('member_plans.deleted_at') ->sum(DB::raw('CAST(plans.limit_rules as UNSIGNED)')); $deposit10 = $totalDeposit * 0.1; $usageMedicines = DB::table('request_log_medicines') ->join('request_logs', 'request_log_medicines.request_log_id', '=', 'request_logs.id') ->join('corporate_employees', 'request_logs.member_id', '=', 'corporate_employees.member_id') ->where('corporate_employees.corporate_id', $corporate->id) ->where(function($query) use ($branchCode) { if ($branchCode === '-') { $query->whereNull('corporate_employees.branch_code')->orWhere('corporate_employees.branch_code', ''); } else { $query->where('corporate_employees.branch_code', $branchCode); } }) ->whereIn('request_logs.log_type', ['prescription', 'reference']) ->sum('request_log_medicines.price'); $consultationCount = DB::table('request_logs') ->join('corporate_employees', 'request_logs.member_id', '=', 'corporate_employees.member_id') ->where('corporate_employees.corporate_id', $corporate->id) ->where(function($query) use ($branchCode) { if ($branchCode === '-') { $query->whereNull('corporate_employees.branch_code') ->orWhere('corporate_employees.branch_code', ''); } else { $query->where('corporate_employees.branch_code', $branchCode); } }) ->where('request_logs.log_type', 'consultation') ->count(); $usageConsultation = $consultationCount * 11100; $remainingDeposit = $deposit10 - $usageMedicines - $usageConsultation; $sheet->setCellValue('A' . $row, $codeRS); $sheet->setCellValue('B' . $row, $branchCode); $sheet->setCellValue('C' . $row, $totalDeposit); $sheet->setCellValue('D' . $row, $deposit10); $sheet->setCellValue('E' . $row, $usageMedicines); $sheet->setCellValue('F' . $row, $usageConsultation); $sheet->setCellValue('G' . $row, $remainingDeposit); // Number format with thousand separator $sheet->getStyle('C' . $row . ':G' . $row)->getNumberFormat()->setFormatCode('#,##0'); $row++; } $lastRow = $row - 1; foreach (range('A', 'G') as $col) { $sheet->getColumnDimension($col)->setAutoSize(true); } $sheet->getStyle('A3:G' . $lastRow)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => '000000'] ] ] ]); $sheet->freezePane('A4'); $sheet->setCellValue('E1', '=SUM(E4:E' . $lastRow . ')'); $sheet->setCellValue('F1', '=SUM(F4:F' . $lastRow . ')'); $sheet->getStyle('E1:F1') ->getNumberFormat() ->setFormatCode('#,##0'); $sheet->getStyle('E1:F1')->applyFromArray([ 'font' => [ 'bold' => true, 'size' => 12, ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, ] ]); $writer = new Xlsx($spreadsheet); $writer->save($filePath); return Helper::responseJson([ 'file_name' => $fileName, 'file_url' => Storage::disk('public')->url('temp/' . $fileName), ]); } }