104 lines
4.1 KiB
PHP
104 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
|
|
|
use App\Enums\ApprovalStatus;
|
|
use App\Enums\CooperationStatus;
|
|
use App\Enums\RoleEnum;
|
|
use App\Filament\Support\CheerfulNotification;
|
|
use App\Models\Cooperation;
|
|
use Filament\Actions\Action;
|
|
use Filament\Support\Icons\Heroicon;
|
|
|
|
class CompleteCooperationAction extends Action
|
|
{
|
|
public static function getDefaultName(): ?string
|
|
{
|
|
return 'completeCooperation';
|
|
}
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->label('Selesaikan Kerjasama')
|
|
->icon(Heroicon::OutlinedCheckBadge)
|
|
->color('success')
|
|
->requiresConfirmation()
|
|
->modalHeading(fn () => CheerfulNotification::getByKey('cooperation.complete_title'))
|
|
->modalDescription(fn () => CheerfulNotification::getByKey('cooperation.complete_desc'))
|
|
->action(function (Cooperation $record): void {
|
|
// Check for any pending payments first (globally for this cooperation)
|
|
$hasPendingPayments = $record->payments()
|
|
->where('cooperation_payments.status', ApprovalStatus::PENDING)
|
|
->exists();
|
|
|
|
if ($hasPendingPayments) {
|
|
CheerfulNotification::danger(
|
|
CheerfulNotification::getByKey('cooperation.payment_pending'),
|
|
CheerfulNotification::getByKey('cooperation.payment_pending_desc')
|
|
)->send();
|
|
|
|
$this->halt();
|
|
|
|
return;
|
|
}
|
|
|
|
// 1. Media whose proposal was accepted
|
|
$acceptedMedia = $record->cooperationMedia()->accepted()->get();
|
|
|
|
if ($acceptedMedia->isEmpty()) {
|
|
CheerfulNotification::danger(
|
|
CheerfulNotification::getByKey('cooperation.media_empty'),
|
|
CheerfulNotification::getByKey('cooperation.media_empty_desc')
|
|
)->send();
|
|
|
|
return;
|
|
}
|
|
|
|
// 2. Filter media that have at least one accepted report
|
|
$mediaWithObligation = $acceptedMedia->filter(function ($media) use ($record) {
|
|
return $record->reports()
|
|
->whereHas('mediaTaskAssignment.partnerMedia', fn ($q) => $q->where('partner_media.id', $media->partner_media_id))
|
|
->accepted()
|
|
->exists();
|
|
});
|
|
|
|
// 3. Of those media, verify they all have an ACCEPTED payment
|
|
$unpaidMedia = $mediaWithObligation->filter(function ($media) {
|
|
return ! $media->payment()->accepted()->exists();
|
|
});
|
|
|
|
if ($unpaidMedia->isNotEmpty()) {
|
|
CheerfulNotification::danger(
|
|
CheerfulNotification::getByKey('cooperation.payment_unfulfilled'),
|
|
CheerfulNotification::getByKey('cooperation.payment_unfulfilled_desc')
|
|
)->send();
|
|
|
|
$this->halt();
|
|
|
|
return;
|
|
}
|
|
|
|
// Calculate total payment from all accepted media payments
|
|
// This will count all accepted payments, even if they didn't have reports (unlikely but possible)
|
|
$totalPayment = $record->payments()->accepted()->sum('amount');
|
|
|
|
$record->update([
|
|
'payment_amount' => $totalPayment,
|
|
'completed_at' => now(),
|
|
'status' => CooperationStatus::COMPLETED,
|
|
]);
|
|
|
|
CheerfulNotification::success(
|
|
CheerfulNotification::getByKey('cooperation.completed_success'),
|
|
CheerfulNotification::getByKey('cooperation.completed_desc')
|
|
)->send();
|
|
})
|
|
->visible(function (Cooperation $record): bool {
|
|
return auth()->user()->hasRole([RoleEnum::ADMINISTRATOR->value, RoleEnum::DEVELOPER->value])
|
|
&& $record->status === CooperationStatus::PAYMENT;
|
|
});
|
|
}
|
|
}
|