dstpabuaran.com/app/Services/Admin/Finance/EmployeeAdvanceService.php
Yoga Pangestu 912f576c74 feat: implement Employee Advance management functionality
- Add EmployeeAdvanceService for handling employee advance operations including create, update, delete, approve, and pay.
- Create new components for date picking and calendar UI.
- Develop Employee Advance columns for data table representation.
- Implement Employee Advance index page with CRUD operations and dialogs for creating, editing, approving, and paying advances.
- Update routes to include employee advances resource and specific actions for approval and payment.
- Add necessary dependencies for date handling and UI components.
2026-07-29 21:07:21 +07:00

151 lines
5.1 KiB
PHP

<?php
namespace App\Services\Admin\Finance;
use App\Enums\CashTransactionType;
use App\Enums\EmployeeAdvanceStatus;
use App\Models\CashAccount;
use App\Models\CashTransaction;
use App\Models\EmployeeAdvance;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
class EmployeeAdvanceService
{
public function getAll(): Collection
{
return EmployeeAdvance::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;
});
}
}