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;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\Enums\IsPaid;
|
use App\Enums\IsPaid;
|
||||||
|
use App\Jobs\StorePushNotification;
|
||||||
use App\Models\Payroll;
|
use App\Models\Payroll;
|
||||||
|
use App\Models\PushNotification;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
@ -23,14 +25,30 @@ public function handle(): void
|
|||||||
|
|
||||||
$updatedCount = Payroll::where('period_month', $targetMonth)
|
$updatedCount = Payroll::where('period_month', $targetMonth)
|
||||||
->where('is_paid', IsPaid::NOT_PAID)
|
->where('is_paid', IsPaid::NOT_PAID)
|
||||||
->update(['is_paid' => IsPaid::PAID]);
|
->update([
|
||||||
|
'is_paid' => IsPaid::PAID,
|
||||||
|
'paid_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
if ($updatedCount === 0) {
|
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;
|
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')
|
$users = User::whereHas('employee')
|
||||||
->active()
|
->active()
|
||||||
|
->withoutDeveloper()
|
||||||
->with('employee')
|
->with('employee')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
|||||||
@ -96,7 +96,7 @@ public function builder(): Builder
|
|||||||
'payrolls.id',
|
'payrolls.id',
|
||||||
'payrolls.user_id',
|
'payrolls.user_id',
|
||||||
'period_month',
|
'period_month',
|
||||||
'base_salary',
|
'payrolls.base_salary',
|
||||||
'bonus',
|
'bonus',
|
||||||
'deduction',
|
'deduction',
|
||||||
'total_salary',
|
'total_salary',
|
||||||
@ -104,7 +104,7 @@ public function builder(): Builder
|
|||||||
'paid_at',
|
'paid_at',
|
||||||
'payrolls.created_at'
|
'payrolls.created_at'
|
||||||
)
|
)
|
||||||
->where('period_month', '!=', now()->format('Y-m'))
|
->paid()
|
||||||
->with(['user', 'user.employee']);
|
->with(['user', 'user.employee']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,7 +54,12 @@ public function mount()
|
|||||||
private function loadPayrolls()
|
private function loadPayrolls()
|
||||||
{
|
{
|
||||||
$this->payrolls = PayrollModel::with(['user', 'user.employee'])
|
$this->payrolls = PayrollModel::with(['user', 'user.employee'])
|
||||||
|
->notPaid()
|
||||||
->where('period_month', now()->format('Y-m'))
|
->where('period_month', now()->format('Y-m'))
|
||||||
|
->whereHas('user', function ($query) {
|
||||||
|
$query->active()
|
||||||
|
->withoutDeveloper();
|
||||||
|
})
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,12 @@ public function paid(Builder $query): void
|
|||||||
$query->where('is_paid', IsPaid::PAID->value);
|
$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
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
|
|||||||
@ -3,4 +3,5 @@
|
|||||||
use Illuminate\Support\Facades\Schedule;
|
use Illuminate\Support\Facades\Schedule;
|
||||||
|
|
||||||
Schedule::command('payroll:generate --current')->monthly();
|
Schedule::command('payroll:generate --current')->monthly();
|
||||||
|
Schedule::command('payroll:close --current')->lastDayOfMonth('23:59');
|
||||||
Schedule::command('stock-opname:generate')->monthlyOn(25, '00:00');
|
Schedule::command('stock-opname:generate')->monthlyOn(25, '00:00');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user