with(['employee.user.userProfile']) ->latest() ->get(); } public function create(array $data): EmployeeAdvance { return DB::transaction(function () use ($data) { $cashAccount = CashAccount::firstOrFail(); $employee = auth()->user()->employee; if (! $employee) { throw new \Exception('Anda tidak terdaftar sebagai karyawan.'); } if ($cashAccount->balance < $data['amount']) { throw ValidationException::withMessages([ 'amount' => 'Saldo tidak mencukupi.', ]); } $newBalance = $cashAccount->balance - $data['amount']; $cashAccount->update(['balance' => $newBalance]); $cashTransaction = CashTransaction::create([ 'cash_account_id' => $cashAccount->id, 'created_by_id' => auth()->id(), 'amount' => $data['amount'], 'balance_after' => $newBalance, 'type' => CashTransactionType::EXPENSE, 'description' => 'Kasbon: '.$data['description'], ]); return EmployeeAdvance::create([ 'cash_transaction_id' => $cashTransaction->id, 'employee_id' => $employee->id, 'amount' => $data['amount'], 'description' => $data['description'], 'due_date' => $data['due_date'], 'status' => EmployeeAdvanceStatus::PENDING, ]); }); } public function update(EmployeeAdvance $employeeAdvance, array $data): EmployeeAdvance { return DB::transaction(function () use ($employeeAdvance, $data) { $cashAccount = CashAccount::firstOrFail(); $cashTransaction = $employeeAdvance->cashTransaction; $oldAmount = $employeeAdvance->amount; $newAmount = $data['amount']; $difference = $newAmount - $oldAmount; if ($difference > 0 && $cashAccount->balance < $difference) { throw ValidationException::withMessages([ 'amount' => 'Saldo tidak mencukupi.', ]); } $newBalance = $cashAccount->balance - $difference; $cashAccount->update(['balance' => $newBalance]); $cashTransaction->update([ 'amount' => $newAmount, 'balance_after' => $newBalance, 'description' => 'Kasbon: '.$data['description'], ]); $employeeAdvance->update([ 'amount' => $newAmount, 'description' => $data['description'], 'due_date' => $data['due_date'], ]); return $employeeAdvance; }); } public function delete(EmployeeAdvance $employeeAdvance): bool { return DB::transaction(function () use ($employeeAdvance) { $cashAccount = CashAccount::firstOrFail(); if ($employeeAdvance->status === EmployeeAdvanceStatus::PAID) { $newBalance = $cashAccount->balance + $employeeAdvance->amount; $cashAccount->update(['balance' => $newBalance]); } return $employeeAdvance->delete(); }); } public function approve(EmployeeAdvance $employeeAdvance): EmployeeAdvance { $employeeAdvance->update([ 'status' => EmployeeAdvanceStatus::APPROVED, 'verified_by_id' => auth()->id(), 'verified_at' => now(), ]); return $employeeAdvance; } public function pay(EmployeeAdvance $employeeAdvance): EmployeeAdvance { return DB::transaction(function () use ($employeeAdvance) { $cashAccount = CashAccount::firstOrFail(); $newBalance = $cashAccount->balance + $employeeAdvance->amount; $cashAccount->update(['balance' => $newBalance]); $cashTransaction = CashTransaction::create([ 'cash_account_id' => $cashAccount->id, 'created_by_id' => auth()->id(), 'amount' => $employeeAdvance->amount, 'balance_after' => $newBalance, 'type' => CashTransactionType::DEPOSIT, 'description' => 'Pembayaran kasbon: '.$employeeAdvance->description, ]); $employeeAdvance->update([ 'status' => EmployeeAdvanceStatus::PAID, 'paid_by_id' => auth()->id(), 'paid_amount' => $employeeAdvance->amount, 'paid_at' => now(), 'repayment_cash_transaction_id' => $cashTransaction->id, ]); return $employeeAdvance; }); } }