dress/app/Http/Controllers/Admin/Finance/PayrollController.php

114 lines
3.6 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\Finance;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Finance\SalaryAdjustmentRequest;
use App\Models\Payroll;
use App\Support\LogHelper;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Inertia\Response;
use Throwable;
class PayrollController extends Controller
{
public function index(): Response
{
$currentMonth = Carbon::now()->format('Y-m');
return Inertia::render('admin/finance/payroll/index', [
'payrolls' => Payroll::with(['user.profile', 'adjustments'])
->where('period_month', '!=', $currentMonth)
->latest()
->get(),
'currentMonthPayrolls' => Payroll::with(['user.profile', 'adjustments'])
->where('period_month', $currentMonth)
->get(),
]);
}
public function generate(): RedirectResponse
{
Artisan::call('payroll:generate');
$output = Artisan::output();
return redirect()->back()->with('success', $output ?: 'Proses generate selesai.');
}
public function update(SalaryAdjustmentRequest $request, Payroll $payroll): RedirectResponse
{
$validated = $request->validated();
try {
DB::transaction(function () use ($payroll, $validated) {
$payroll->adjustments()->delete();
$totalBonus = 0;
$totalDeduction = 0;
if (isset($validated['adjustments'])) {
foreach ($validated['adjustments'] as $adj) {
$payroll->adjustments()->create([
'type' => $adj['type'],
'amount' => $adj['amount'],
'description' => $adj['description'],
]);
if ($adj['type'] === 'bonus') {
$totalBonus += $adj['amount'];
} else {
$totalDeduction += $adj['amount'];
}
}
}
$payroll->update([
'bonus' => $totalBonus,
'deduction' => $totalDeduction,
'total_salary' => $payroll->base_salary + $totalBonus - $totalDeduction,
]);
});
} catch (Throwable $e) {
LogHelper::logException($e, 'Payroll update failed', [
'payroll_id' => $payroll->id,
]);
return back()->withInput()->with('error', 'Gagal memperbarui data. Silakan coba lagi.');
}
return redirect()->back()->with('success', 'Data berhasil diperbarui');
}
public function togglePaid(Payroll $payroll): RedirectResponse
{
$payroll->update([
'is_paid' => ! $payroll->is_paid,
'paid_at' => ! $payroll->is_paid ? Carbon::now() : null,
]);
return redirect()->back()->with('success', 'Status pembayaran berhasil diubah');
}
public function destroy(Payroll $payroll): RedirectResponse
{
$payroll->delete();
return redirect()->back()->with('success', 'Data berhasil dihapus');
}
public function bulkDestroy(Request $request): RedirectResponse
{
$ids = $request->input('ids');
Payroll::whereIn('id', $ids)->delete();
return redirect()->back()->with('success', 'Data terpilih berhasil dihapus');
}
}