can('manage-payslips')) { $query = Payslip::with(['employee', 'payrollEntry.payrollRun', 'creator'])->where(function ($q) { if (Auth::user()->can('manage-any-payslips')) { $q->whereIn('created_by', getCompanyAndUsersId()); } elseif (Auth::user()->can('manage-own-payslips')) { $q->orWhere('employee_id', Auth::id()); } else { $q->whereRaw('1 = 0'); } }); // Handle search if ($request->has('search') && ! empty($request->search)) { $query->where(function ($q) use ($request) { $q->where('payslip_number', 'like', '%'.$request->search.'%') ->orWhereHas('employee', function ($subQ) use ($request) { $subQ->where('name', 'like', '%'.$request->search.'%'); }); }); } // Handle employee filter if ($request->has('employee_id') && ! empty($request->employee_id) && $request->employee_id !== 'all') { $query->where('employee_id', $request->employee_id); } // Handle status filter if ($request->has('status') && ! empty($request->status) && $request->status !== 'all') { $query->where('status', $request->status); } // Handle date range filter if ($request->has('date_from') && ! empty($request->date_from)) { $query->where('pay_period_start', '>=', $request->date_from); } if ($request->has('date_to') && ! empty($request->date_to)) { $query->where('pay_period_end', '<=', $request->date_to); } // Handle sorting if ($request->has('sort_field') && ! empty($request->sort_field)) { $sortField = $request->sort_field; $sortDirection = $request->sort_direction ?? 'asc'; if (in_array($sortField, ['pay_date', 'created_at'])) { $query->orderBy($sortField, $sortDirection); } else { $query->orderBy('pay_date', 'desc'); } } else { $query->orderBy('pay_date', 'desc'); } $payslips = $query->paginate($request->per_page ?? 10); // Get employees for filter dropdown $employees = User::where('type', 'employee') ->whereIn('created_by', getCompanyAndUsersId()) ->get(['id', 'name']); return Inertia::render('hr/payslips/index', [ 'payslips' => $payslips, 'employees' => $employees, 'filters' => $request->all(['search', 'employee_id', 'status', 'date_from', 'date_to', 'sort_field', 'sort_direction', 'per_page']), ]); } else { return redirect()->back()->with('error', __('Permission Denied.')); } } public function generate(Request $request) { $validated = $request->validate([ 'payroll_entry_ids' => 'required|array', 'payroll_entry_ids.*' => 'exists:payroll_entries,id', ]); $generatedCount = 0; $errors = []; foreach ($validated['payroll_entry_ids'] as $entryId) { try { $payrollEntry = PayrollEntry::whereIn('created_by', getCompanyAndUsersId()) ->find($entryId); if (! $payrollEntry) { continue; } // Check if payslip already exists $exists = Payslip::where('payroll_entry_id', $entryId)->exists(); if ($exists) { continue; } $payslipNumber = Payslip::generatePayslipNumber( $payrollEntry->employee_id, $payrollEntry->payrollRun->pay_date ); $payslip = Payslip::create([ 'payroll_entry_id' => $entryId, 'employee_id' => $payrollEntry->employee_id, 'payslip_number' => $payslipNumber, 'pay_period_start' => $payrollEntry->payrollRun->pay_period_start, 'pay_period_end' => $payrollEntry->payrollRun->pay_period_end, 'pay_date' => $payrollEntry->payrollRun->pay_date, 'status' => 'generated', 'created_by' => creatorId(), ]); // Generate PDF $payslip->generatePDF(); $generatedCount++; } catch (\Exception $e) { $errors[] = "Failed to generate payslip for entry ID {$entryId}: ".$e->getMessage(); } } if ($generatedCount > 0) { $message = "Generated {$generatedCount} payslip(s) successfully."; if (! empty($errors)) { $message .= ' Some errors occurred: '.implode(', ', $errors); } return redirect()->back()->with('success', __($message)); } else { return redirect()->back()->with('error', __('No payslips were generated. :errors', ['errors' => implode(', ', $errors)])); } } // public function download($payslipId) // { // $payslip = Payslip::where('id', $payslipId) // ->whereIn('created_by', getCompanyAndUsersId()) // ->first(); // if (!$payslip) { // return redirect()->back()->with('error', __('Payslip not found.')); // } // if (!$payslip->file_path || !Storage::disk('public')->exists($payslip->file_path)) { // // Generate PDF if not exists // try { // $payslip->generatePDF(); // } catch (\Exception $e) { // return redirect()->back()->with('error', __('Failed to generate payslip PDF: :message', ['message' => $e->getMessage()])); // } // } // $payslip->markAsDownloaded(); // return Storage::disk('public')->download($payslip->file_path, 'payslip-' . $payslip->payslip_number . '.pdf'); // } public function download($payslipId) { try { $payslip = Payslip::with(['employee', 'payrollEntry.payrollRun', 'payrollEntry.employee.employee']) ->where('id', $payslipId) ->whereIn('created_by', getCompanyAndUsersId()) ->first(); if (!$payslip) { return response()->json(['error' => __('Payslip not found.')], 404); } $payrollEntry = $payslip->payrollEntry; $companySettings = settings(); $companyUser = User::find(getCompanyId(Auth::user()->id)); if ($companyUser) { $companySettings = array_merge($companySettings, [ 'companyEmail' => $companyUser->email ?? null, ]); } $data = [ 'payslip' => $payslip, 'payrollEntry' => $payrollEntry, 'employee' => $payrollEntry->employee, 'payrollRun' => $payrollEntry->payrollRun, 'earnings' => $payrollEntry->earnings_breakdown ?? [], 'deductions' => $payrollEntry->deductions_breakdown ?? [], 'employeeData' => $payrollEntry->employee->employee, 'companySettings' => $companySettings, ]; $payslip->markAsDownloaded(); return view('payslips.template', $data); } catch (\Exception $e) { return response()->json(['error' => __('Failed to download payslip: :message', ['message' => $e->getMessage()])], 500); } } public function bulkGenerate(Request $request) { $validated = $request->validate([ 'payroll_run_id' => 'required|exists:payroll_runs,id', ]); try { $payrollEntries = PayrollEntry::where('payroll_run_id', $validated['payroll_run_id']) ->whereIn('created_by', getCompanyAndUsersId()) ->get(); $generatedCount = 0; foreach ($payrollEntries as $entry) { // Check if payslip already exists $exists = Payslip::where('payroll_entry_id', $entry->id)->exists(); if ($exists) { continue; } $payslipNumber = Payslip::generatePayslipNumber( $entry->employee_id, $entry->payrollRun->pay_date ); Payslip::create([ 'payroll_entry_id' => $entry->id, 'employee_id' => $entry->employee_id, 'payslip_number' => $payslipNumber, 'pay_period_start' => $entry->payrollRun->pay_period_start, 'pay_period_end' => $entry->payrollRun->pay_period_end, 'pay_date' => $entry->payrollRun->pay_date, 'status' => 'generated', 'created_by' => creatorId(), ]); // Generate PDF // $payslip->generatePDF(); $generatedCount++; } return redirect()->back()->with('success', __('Generated :count payslips successfully.', ['count' => $generatedCount])); } catch (\Exception $e) { return redirect()->back()->with('error', __('Failed to generate payslips: :message', ['message' => $e->getMessage()])); } } }