feat: Implement automated payroll closing with push notifications and refine payroll filtering and status management.
This commit is contained in:
parent
36004254c9
commit
40db1c006c
@ -3,7 +3,9 @@
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\IsPaid;
|
||||
use App\Jobs\StorePushNotification;
|
||||
use App\Models\Payroll;
|
||||
use App\Models\PushNotification;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
@ -23,14 +25,30 @@ public function handle(): void
|
||||
|
||||
$updatedCount = Payroll::where('period_month', $targetMonth)
|
||||
->where('is_paid', IsPaid::NOT_PAID)
|
||||
->update(['is_paid' => IsPaid::PAID]);
|
||||
->update([
|
||||
'is_paid' => IsPaid::PAID,
|
||||
'paid_at' => now(),
|
||||
]);
|
||||
|
||||
if ($updatedCount === 0) {
|
||||
$this->warn("Tidak ada payroll yang perlu ditutup untuk bulan {$targetMonth}.");
|
||||
$this->warn('Tidak ada payroll yang perlu ditutup untuk bulan '.formatDateLocalized($targetMonth, 'F Y').'.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->info("Payroll untuk bulan {$targetMonth} berhasil ditandai selesai. Total: {$updatedCount}");
|
||||
$userIds = Payroll::where('period_month', $targetMonth)
|
||||
->where('is_paid', IsPaid::PAID)
|
||||
->pluck('user_id')
|
||||
->unique();
|
||||
|
||||
StorePushNotification::dispatch(
|
||||
PushNotification::whereIn('user_id', $userIds)->get(),
|
||||
[
|
||||
'title' => 'Gaji Sudah Cair 💸',
|
||||
'body' => 'Kerja kerasmu terbayar. Gaji bulan '.formatDateLocalized($targetMonth, 'F Y').' sudah kami transfer. Semoga harimu menyenangkan.',
|
||||
],
|
||||
);
|
||||
|
||||
$this->info('Payroll untuk bulan '.formatDateLocalized($targetMonth, 'F Y')." berhasil ditandai selesai. Total: {$updatedCount}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ public function handle(): void
|
||||
|
||||
$users = User::whereHas('employee')
|
||||
->active()
|
||||
->withoutDeveloper()
|
||||
->with('employee')
|
||||
->get();
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ public function builder(): Builder
|
||||
'payrolls.id',
|
||||
'payrolls.user_id',
|
||||
'period_month',
|
||||
'base_salary',
|
||||
'payrolls.base_salary',
|
||||
'bonus',
|
||||
'deduction',
|
||||
'total_salary',
|
||||
@ -104,7 +104,7 @@ public function builder(): Builder
|
||||
'paid_at',
|
||||
'payrolls.created_at'
|
||||
)
|
||||
->where('period_month', '!=', now()->format('Y-m'))
|
||||
->paid()
|
||||
->with(['user', 'user.employee']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,12 @@ public function mount()
|
||||
private function loadPayrolls()
|
||||
{
|
||||
$this->payrolls = PayrollModel::with(['user', 'user.employee'])
|
||||
->notPaid()
|
||||
->where('period_month', now()->format('Y-m'))
|
||||
->whereHas('user', function ($query) {
|
||||
$query->active()
|
||||
->withoutDeveloper();
|
||||
})
|
||||
->get();
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,12 @@ public function paid(Builder $query): void
|
||||
$query->where('is_paid', IsPaid::PAID->value);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
public function notPaid(Builder $query): void
|
||||
{
|
||||
$query->where('is_paid', IsPaid::NOT_PAID->value);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
||||
@ -3,4 +3,5 @@
|
||||
use Illuminate\Support\Facades\Schedule;
|
||||
|
||||
Schedule::command('payroll:generate --current')->monthly();
|
||||
Schedule::command('payroll:close --current')->lastDayOfMonth('23:59');
|
||||
Schedule::command('stock-opname:generate')->monthlyOn(25, '00:00');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user