feat: implement cooperation payment workflow with invoice submission, approval, and rejection actions
This commit is contained in:
parent
ba115a4502
commit
ec7a9bdf30
@ -2,12 +2,15 @@
|
||||
|
||||
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 App\Models\User;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CompleteCooperationAction extends Action
|
||||
{
|
||||
@ -27,7 +30,23 @@ protected function setUp(): void
|
||||
->modalHeading(fn () => CheerfulNotification::getByKey('cooperation.complete_title'))
|
||||
->modalDescription(fn () => CheerfulNotification::getByKey('cooperation.complete_desc'))
|
||||
->action(function (Cooperation $record): void {
|
||||
// Verify all accepted media are paid
|
||||
// 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()) {
|
||||
@ -39,8 +58,17 @@ protected function setUp(): void
|
||||
return;
|
||||
}
|
||||
|
||||
$unpaidMedia = $acceptedMedia->filter(function ($media) {
|
||||
return ! $media->payment()->exists();
|
||||
// 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()) {
|
||||
@ -54,8 +82,9 @@ protected function setUp(): void
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate total payment from media payments
|
||||
$totalPayment = $acceptedMedia->sum(fn ($media) => $media->payment->amount);
|
||||
// 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,
|
||||
@ -69,7 +98,8 @@ protected function setUp(): void
|
||||
)->send();
|
||||
})
|
||||
->visible(function (Cooperation $record): bool {
|
||||
$user = auth()->user();
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
|
||||
return $user && ! $user->hasRole(RoleEnum::PERUSAHAAN->value)
|
||||
&& $record->status === CooperationStatus::PAYMENT;
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Media;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\CooperationStatus;
|
||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\CooperationMedia;
|
||||
use App\Notifications\BroadcastNotification;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Support\RawJs;
|
||||
|
||||
class PayAction extends Action
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'pay';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->label('Bayar')
|
||||
->icon(Heroicon::OutlinedCreditCard)
|
||||
->color('success')
|
||||
->visible(fn (CooperationMedia $record): bool => $record->cooperation->status === CooperationStatus::PAYMENT && ! $record->payment()->exists() && $record->status === ApprovalStatus::ACCEPTED)
|
||||
->schema([
|
||||
TextInput::make('amount')
|
||||
->label('Nominal Pembayaran')
|
||||
->placeholder('1,000,000')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->mask(RawJs::make('$money($input)'))
|
||||
->prefix('Rp'),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('payment_proof')
|
||||
->label('Bukti Pembayaran')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('cooperations')
|
||||
->customProperties(fn (): array => [
|
||||
'feature' => 'cooperations',
|
||||
'date' => now()->toDateString(),
|
||||
'doc_type' => 'payment-proof',
|
||||
])
|
||||
->image()
|
||||
->helperText('Format yang diterima: JPEG, PNG, GIF, WEBP. Ukuran maksimum: 3 MB.')
|
||||
->required(),
|
||||
|
||||
Textarea::make('description')
|
||||
->label('Keterangan')
|
||||
->placeholder('...')
|
||||
->autocomplete(false),
|
||||
])
|
||||
->action(function (CooperationMedia $record, array $data): void {
|
||||
$record->payment()->create([
|
||||
'amount' => str_replace(['Rp ', ','], '', $data['amount']),
|
||||
'description' => $data['description'],
|
||||
'payment_date' => now(),
|
||||
]);
|
||||
|
||||
CheerfulNotification::success(
|
||||
CheerfulNotification::getByKey('cooperation.payment_recorded_success'),
|
||||
CheerfulNotification::getByKey('notification.payment_processed', ['record__partnerMedia__name' => $record->partnerMedia->name])
|
||||
)->send();
|
||||
|
||||
$partnerUser = $record->partnerMedia->company?->user;
|
||||
if ($partnerUser) {
|
||||
$partnerUser->notify(new BroadcastNotification([
|
||||
'title' => CheerfulNotification::getByKey('cooperation.payment_sent'),
|
||||
'body' => CheerfulNotification::getByKey('notification.payment_sent_desc', ['record__cooperation__title' => $record->cooperation->title]),
|
||||
'action' => [
|
||||
Action::make('view')
|
||||
->label('Lihat')
|
||||
->url(CooperationResource::getUrl('view', ['record' => $record->cooperation_id, 'relation' => 0])),
|
||||
],
|
||||
]));
|
||||
}
|
||||
})
|
||||
->modalWidth(Width::Large);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Payment;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\CooperationStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\CooperationPayment;
|
||||
use App\Notifications\BroadcastNotification;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class AcceptAction extends Action
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'accept';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->label('Terima')
|
||||
->icon(Heroicon::OutlinedCheck)
|
||||
->color('success')
|
||||
->action(function (CooperationPayment $record): void {
|
||||
$record->update([
|
||||
'status' => ApprovalStatus::ACCEPTED,
|
||||
'payment_date' => now(),
|
||||
]);
|
||||
|
||||
CheerfulNotification::success(
|
||||
CheerfulNotification::getByKey('cooperation.payment_approved'),
|
||||
CheerfulNotification::getByKey('notification.payment_approved_notice', ['record__partnerMedia__name' => $record->cooperationMedia->partnerMedia->name])
|
||||
)->send();
|
||||
|
||||
$partnerUser = $record->cooperationMedia->partnerMedia->company?->user;
|
||||
if ($partnerUser) {
|
||||
$partnerUser->notify(new BroadcastNotification([
|
||||
'title' => CheerfulNotification::getByKey('cooperation.payment_approved'),
|
||||
'body' => CheerfulNotification::getByKey('notification.payment_approved_notice', ['record__partnerMedia__name' => $record->cooperationMedia->partnerMedia->name]),
|
||||
'action' => [
|
||||
Action::make('view')
|
||||
->label('Lihat')
|
||||
->url(CooperationResource::getUrl('view', ['record' => $record->cooperationMedia->cooperation_id, 'relation' => 4])),
|
||||
],
|
||||
]));
|
||||
}
|
||||
})
|
||||
->visible(
|
||||
fn (CooperationPayment $record): bool => $record->cooperationMedia->cooperation->status === CooperationStatus::PAYMENT &&
|
||||
! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) &&
|
||||
$record->status === ApprovalStatus::PENDING
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Payment;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\CooperationStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\CooperationPayment;
|
||||
use App\Notifications\BroadcastNotification;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class RejectAction extends Action
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'reject';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->label('Tolak')
|
||||
->icon(Heroicon::OutlinedXMark)
|
||||
->color('danger')
|
||||
->schema([
|
||||
Textarea::make('reason')
|
||||
->label('Alasan Penolakan')
|
||||
->placeholder('Jelaskan alasan pengajuan ditolak...')
|
||||
->required(),
|
||||
])
|
||||
->modalHeading(fn () => CheerfulNotification::getByKey('cooperation.reject_payment_title'))
|
||||
->modalDescription(fn () => CheerfulNotification::getByKey('cooperation.reject_payment_desc'))
|
||||
->action(function (CooperationPayment $record, array $data): void {
|
||||
$record->update([
|
||||
'status' => ApprovalStatus::REJECTED,
|
||||
]);
|
||||
|
||||
$record->rejectionReasons()->create(['reason' => $data['reason']]);
|
||||
|
||||
CheerfulNotification::warning(
|
||||
CheerfulNotification::getByKey('cooperation.payment_rejected'),
|
||||
CheerfulNotification::getByKey('notification.payment_rejected_reason', ['record__partnerMedia__name' => $record->cooperationMedia->partnerMedia->name, 'data__reason' => $data['reason']])
|
||||
)->send();
|
||||
|
||||
$partnerUser = $record->cooperationMedia->partnerMedia->company?->user;
|
||||
if ($partnerUser) {
|
||||
$partnerUser->notify(new BroadcastNotification([
|
||||
'title' => CheerfulNotification::getByKey('cooperation.payment_rejected'),
|
||||
'body' => CheerfulNotification::getByKey('notification.payment_rejected_reason', ['record__partnerMedia__name' => $record->cooperationMedia->partnerMedia->name, 'data__reason' => $data['reason']]),
|
||||
'action' => [
|
||||
Action::make('view')
|
||||
->label('Lihat')
|
||||
->url(CooperationResource::getUrl('view', ['record' => $record->cooperationMedia->cooperation_id, 'relation' => 4])),
|
||||
],
|
||||
]));
|
||||
}
|
||||
})
|
||||
->visible(
|
||||
fn (CooperationPayment $record): bool => $record->cooperationMedia->cooperation->status === CooperationStatus::PAYMENT &&
|
||||
! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) &&
|
||||
$record->status === ApprovalStatus::PENDING
|
||||
)
|
||||
->modalWidth(Width::Large);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Payment;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\CooperationStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\CooperationPayment;
|
||||
use App\Models\User;
|
||||
use App\Notifications\BroadcastNotification;
|
||||
use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\RawJs;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SubmitInvoiceAction extends CreateAction
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'submit_invoice';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->label('Ajukan Pembayaran')
|
||||
->modalWidth(Width::Large)
|
||||
->modalHeading(fn () => CheerfulNotification::getByKey('cooperation.create_payment_title'))
|
||||
->modalDescription(fn () => CheerfulNotification::getByKey('cooperation.create_payment_desc'))
|
||||
->schema([
|
||||
TextInput::make('amount')
|
||||
->label('Nominal Pembayaran')
|
||||
->placeholder('1,000,000')
|
||||
->autocomplete(false)
|
||||
->autofocus()
|
||||
->required()
|
||||
->mask(RawJs::make('$money($input)'))
|
||||
->prefix('Rp'),
|
||||
|
||||
Textarea::make('description')
|
||||
->label('Keterangan')
|
||||
->placeholder('Silakan isi keterangan atau rujukan pembayaran...'),
|
||||
|
||||
AdvancedFileUpload::make('payment_attachment')
|
||||
->label('Lampiran Penagihan')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['application/pdf'])
|
||||
->maxSize(1024 * 10)
|
||||
->directory(fn (): string => 'cooperations/payment-attachment/'.now()->toDateString())
|
||||
->helperText('Format yang diterima: PDF. Ukuran maksimum: 10 MB.')
|
||||
->required(),
|
||||
])
|
||||
->mutateDataUsing(function (array $data): array {
|
||||
$cooperation = $this->getLivewire()->getOwnerRecord();
|
||||
|
||||
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
$cooperationMedia = $cooperation->cooperationMedia()
|
||||
->whereHas('partnerMedia.company', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
})
|
||||
->first();
|
||||
|
||||
$data['cooperation_media_id'] = $cooperationMedia?->id;
|
||||
$data['amount'] = str_replace(['Rp ', ' ', ','], '', $data['amount']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
})
|
||||
->successNotification(null)
|
||||
->after(function (CooperationPayment $record, array $data): void {
|
||||
if (! empty($data['payment_attachment'])) {
|
||||
$filePath = collect($data['payment_attachment'])->first();
|
||||
$fullPath = Storage::disk(config('filesystems.default'))->path($filePath);
|
||||
|
||||
if (file_exists($fullPath)) {
|
||||
$record->addMediaFromDisk($filePath, config('filesystems.default'))
|
||||
->preservingOriginal()
|
||||
->withCustomProperties([
|
||||
'feature' => 'cooperations',
|
||||
'date' => now()->toDateString(),
|
||||
'doc_type' => 'payment-attachment',
|
||||
])
|
||||
->toMediaCollection('cooperations');
|
||||
}
|
||||
}
|
||||
|
||||
CheerfulNotification::success(
|
||||
CheerfulNotification::getByKey('cooperation.payment_requested_success'),
|
||||
CheerfulNotification::getByKey('cooperation.payment_requested_desc')
|
||||
)->send();
|
||||
|
||||
// Notify Admins
|
||||
User::query()
|
||||
->superAdmin()
|
||||
->get()
|
||||
->each(function ($admin) use ($record): void {
|
||||
$user = auth()->user();
|
||||
|
||||
$admin->notify(new BroadcastNotification([
|
||||
'title' => CheerfulNotification::getByKey('cooperation.create_payment_title'),
|
||||
'body' => CheerfulNotification::getByKey('notification.payment_requested', ['user__name' => $user->name, 'record__partnerMedia__name' => $record->cooperationMedia->partnerMedia->name, 'record__cooperation__title' => $this->getLivewire()->getOwnerRecord()->title]),
|
||||
'action' => [
|
||||
Action::make('view')
|
||||
->label('Lihat')
|
||||
->url(CooperationResource::getUrl('view', ['record' => $this->getLivewire()->getOwnerRecord()->id, 'relation' => 4])),
|
||||
],
|
||||
]));
|
||||
});
|
||||
})
|
||||
->visible(function (): bool {
|
||||
$user = auth()->user();
|
||||
|
||||
if (! $user || ! $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cooperation = $this->getLivewire()->getOwnerRecord();
|
||||
|
||||
return $cooperation->status === CooperationStatus::PAYMENT
|
||||
&& $cooperation->proposal()
|
||||
->whereHas('partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
|
||||
->accepted()
|
||||
->exists()
|
||||
&& ! $cooperation->payments()
|
||||
->whereHas('cooperationMedia.partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
|
||||
->where('cooperation_payments.status', '!=', ApprovalStatus::REJECTED)
|
||||
->exists();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Report;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\CooperationStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\Report;
|
||||
use App\Models\User;
|
||||
use App\Notifications\BroadcastNotification;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SubmitReportAction extends CreateAction
|
||||
{
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'submit_report';
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->label('Buat Bukti Tayang')
|
||||
->modalWidth(Width::Large)
|
||||
->modalHeading(fn () => CheerfulNotification::getByKey('cooperation.create_report_title'))
|
||||
->modalDescription(fn () => CheerfulNotification::getByKey('cooperation.create_report_desc'))
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->placeholder('Dirgahayu Purwakarta')
|
||||
->required()
|
||||
->autocomplete(false)
|
||||
->autofocus(),
|
||||
|
||||
DatePicker::make('publication_date')
|
||||
->label('Tanggal Publikasi')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required(),
|
||||
|
||||
TextInput::make('link')
|
||||
->label('Tautan')
|
||||
->placeholder('https://example.com')
|
||||
->maxLength(255)
|
||||
->url()
|
||||
->required()
|
||||
->autocomplete(false),
|
||||
|
||||
Textarea::make('description')
|
||||
->label('Deskripsi')
|
||||
->placeholder('....')
|
||||
->required()
|
||||
->autocomplete(false),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('image')
|
||||
->label('Gambar')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('reports')
|
||||
->image()
|
||||
->helperText('Format yang diterima: JPEG, PNG, GIF, WEBP. Ukuran maksimum: 3 MB.')
|
||||
->required(),
|
||||
])
|
||||
->using(function (array $data, string $model): Model {
|
||||
return $model::create($data);
|
||||
})
|
||||
->mutateDataUsing(function (array $data): array {
|
||||
$taskAssignment = $this->getLivewire()->getOwnerRecord()->taskAssignment;
|
||||
|
||||
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
$mediaTaskAssignment = $taskAssignment?->mediaTaskAssignments()
|
||||
->whereHas('partnerMedia.company', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
})
|
||||
->first();
|
||||
|
||||
$data['media_task_assignment_id'] = $mediaTaskAssignment?->id;
|
||||
}
|
||||
|
||||
return $data;
|
||||
})
|
||||
->successNotification(null)
|
||||
->after(function (Report $record): void {
|
||||
CheerfulNotification::success(
|
||||
CheerfulNotification::getByKey('cooperation.report_sent_success'),
|
||||
CheerfulNotification::getByKey('cooperation.report_sent_desc')
|
||||
)->send();
|
||||
|
||||
// Notify Admins
|
||||
User::query()
|
||||
->superAdmin()
|
||||
->get()
|
||||
->each(function ($admin) use ($record): void {
|
||||
$user = auth()->user();
|
||||
|
||||
$admin->notify(new BroadcastNotification([
|
||||
'title' => CheerfulNotification::getByKey('cooperation.new_report'),
|
||||
'body' => CheerfulNotification::getByKey('notification.user_submitted_report', ['user__name' => $user->name, 'record__title' => $record->title, 'this__getOwnerRecord____title' => $this->getLivewire()->getOwnerRecord()->title]),
|
||||
'action' => [
|
||||
Action::make('view')
|
||||
->label('Lihat')
|
||||
->url(CooperationResource::getUrl('view', ['record' => $this->getLivewire()->getOwnerRecord()->id, 'relation' => 3])),
|
||||
],
|
||||
]));
|
||||
});
|
||||
})
|
||||
->visible(function (): bool {
|
||||
$user = auth()->user();
|
||||
|
||||
if (! $user || ! $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cooperation = $this->getLivewire()->getOwnerRecord();
|
||||
$taskAssignment = $cooperation->taskAssignment;
|
||||
|
||||
if (! $taskAssignment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $cooperation->status === CooperationStatus::ASSIGNMENT
|
||||
&& $taskAssignment->start_date->toDateString() <= now()->toDateString()
|
||||
&& $taskAssignment->end_date->toDateString() >= now()->toDateString()
|
||||
&& $cooperation->proposal()
|
||||
->whereHas('partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
|
||||
->accepted()
|
||||
->exists()
|
||||
&& $taskAssignment->reports()
|
||||
->whereHas('mediaTaskAssignment.partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
|
||||
->where('reports.status', '!=', ApprovalStatus::REJECTED)
|
||||
->count() < $taskAssignment->report_amount;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -2,18 +2,10 @@
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Columns\RowIndexColumn;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Media\PayAction;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\CooperationMedia;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
@ -45,51 +37,13 @@ public function table(Table $table): Table
|
||||
->label('Nama')
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('payment.amount')
|
||||
->label('Jumlah Pembayaran')
|
||||
->money('IDR', decimalPlaces: 0)
|
||||
->placeholder('Belum ditentukan'),
|
||||
|
||||
TextColumn::make('status')
|
||||
->label('Status')
|
||||
->badge(),
|
||||
])
|
||||
->recordActions([
|
||||
PayAction::make(),
|
||||
|
||||
ViewAction::make()
|
||||
->visible(fn (CooperationMedia $record): bool => $record->status === ApprovalStatus::ACCEPTED && $record->payment()->exists()),
|
||||
])
|
||||
->emptyStateIcon(Heroicon::OutlinedNewspaper)
|
||||
->emptyStateHeading(fn () => CheerfulNotification::getByKey('cooperation.media_data_empty_heading'))
|
||||
->emptyStateDescription(fn () => CheerfulNotification::getByKey('cooperation.media_data_empty'))
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function infolist(Schema $infolist): Schema
|
||||
{
|
||||
return $infolist
|
||||
->components([
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
TextEntry::make('payment.amount')
|
||||
->label('Nominal')
|
||||
->money('IDR', decimalPlaces: 0),
|
||||
|
||||
TextEntry::make('payment.payment_date')
|
||||
->label('Tanggal Bayar')
|
||||
->dateTime('l, d F Y'),
|
||||
]),
|
||||
|
||||
TextEntry::make('payment.description')
|
||||
->label('Keterangan')
|
||||
->visible(fn (CooperationMedia $record): bool => $record->description !== null),
|
||||
|
||||
ImageEntry::make('payment_proof')
|
||||
->label('Bukti Pembayaran')
|
||||
->getStateUsing(fn (CooperationMedia $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'payment-proof')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
|
||||
->disk(config('filesystems.default')),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,17 +2,24 @@
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Columns\RowIndexColumn;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Payment\AcceptAction;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Payment\RejectAction;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Payment\SubmitInvoiceAction;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\CooperationPayment;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Joaopaulolndev\FilamentPdfViewer\Infolists\Components\PdfViewerEntry;
|
||||
|
||||
class CooperationPaymentRelationManager extends RelationManager
|
||||
{
|
||||
@ -20,53 +27,133 @@ class CooperationPaymentRelationManager extends RelationManager
|
||||
|
||||
protected static ?string $title = 'Pembayaran';
|
||||
|
||||
public function isReadOnly(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
|
||||
{
|
||||
if (! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
return false;
|
||||
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
return $ownerRecord->cooperationMedia()
|
||||
->whereHas('partnerMedia.company', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
})
|
||||
->accepted()
|
||||
->exists();
|
||||
}
|
||||
|
||||
return $ownerRecord->cooperationMedia()
|
||||
->whereHas('partnerMedia.company', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
})
|
||||
->accepted()
|
||||
->exists();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
|
||||
{
|
||||
$query = $ownerRecord->payments();
|
||||
|
||||
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
$query->whereHas('cooperationMedia.partnerMedia.company', function ($q) {
|
||||
$q->where('user_id', auth()->id());
|
||||
});
|
||||
}
|
||||
|
||||
return (string) $query->count();
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
...RowIndexColumn::make(),
|
||||
TextColumn::make('cooperationMedia.partnerMedia.name')
|
||||
->label('Media')
|
||||
->searchable()
|
||||
->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
|
||||
|
||||
TextColumn::make('amount')
|
||||
->label('Nominal')
|
||||
->money('IDR', decimalPlaces: 0),
|
||||
->money('IDR', decimalPlaces: 0)
|
||||
->placeholder('Menunggu Verifikasi'),
|
||||
|
||||
TextColumn::make('payment_date')
|
||||
->label('Tanggal Bayar')
|
||||
->date('l, d F Y'),
|
||||
->date('l, d F Y')
|
||||
->placeholder('-'),
|
||||
|
||||
TextColumn::make('description')
|
||||
->label('Keterangan')
|
||||
->limit(50),
|
||||
|
||||
ImageColumn::make('payment_proof')
|
||||
->label('Bukti Pembayaran')
|
||||
->getStateUsing(fn (CooperationPayment $record): ?string => optional($record->cooperationMedia->getMedia('cooperations')->where('custom_properties.doc_type', 'payment-proof')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
|
||||
->disk(config('filesystems.default')),
|
||||
TextColumn::make('status')
|
||||
->label('Status')
|
||||
->badge(),
|
||||
|
||||
TextColumn::make('rejectionReasons.reason')
|
||||
->label('Alasan Penolakan')
|
||||
->searchable(),
|
||||
])
|
||||
->recordActions([
|
||||
ViewAction::make(),
|
||||
|
||||
AcceptAction::make(),
|
||||
|
||||
RejectAction::make(),
|
||||
])
|
||||
->headerActions([
|
||||
SubmitInvoiceAction::make(),
|
||||
])
|
||||
->emptyStateIcon(Heroicon::OutlinedCreditCard)
|
||||
->emptyStateHeading(fn () => CheerfulNotification::getByKey('cooperation.payment_empty_heading'))
|
||||
->emptyStateDescription(fn () => CheerfulNotification::getByKey('cooperation.payment_empty'))
|
||||
->defaultSort('created_at', 'desc')
|
||||
->modifyQueryUsing(function (Builder $query): void {
|
||||
$query->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $subQuery): void {
|
||||
$subQuery->whereHas('partnerMedia.company', function (Builder $q): void {
|
||||
$q->where('user_id', auth()->id());
|
||||
$query->with(['cooperationMedia.media'])
|
||||
->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $subQuery): void {
|
||||
$subQuery->whereHas('cooperationMedia.partnerMedia.company', function (Builder $q): void {
|
||||
$q->where('user_id', auth()->id());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function infolist(Schema $infolist): Schema
|
||||
{
|
||||
return $infolist
|
||||
->components([
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
TextEntry::make('cooperationMedia.partnerMedia.name')
|
||||
->label('Media')
|
||||
->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
|
||||
|
||||
TextEntry::make('status')
|
||||
->label('Status')
|
||||
->badge(),
|
||||
|
||||
TextEntry::make('amount')
|
||||
->label('Nominal Penagihan')
|
||||
->money('IDR', decimalPlaces: 0),
|
||||
|
||||
TextEntry::make('created_at')
|
||||
->label('Diajukan')
|
||||
->dateTime('l, d F Y H:i:s'),
|
||||
]),
|
||||
|
||||
TextEntry::make('description')
|
||||
->label('Keterangan')
|
||||
->columnSpanFull()
|
||||
->placeholder('-'),
|
||||
|
||||
PdfViewerEntry::make('payment_attachment')
|
||||
->label('Lampiran Penagihan')
|
||||
->disk(config('filesystems.default'))
|
||||
->getStateUsing(fn (CooperationPayment $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'payment-attachment')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
|
||||
->columnSpanFull(),
|
||||
|
||||
TextEntry::make('rejectionReasons.reason')
|
||||
->label('Alasan Penolakan')
|
||||
->listWithLineBreaks()
|
||||
->visible(fn (CooperationPayment $record): bool => $record->status === ApprovalStatus::REJECTED && $record->rejectionReasons->isNotEmpty())
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,26 +2,14 @@
|
||||
|
||||
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use App\Enums\CooperationStatus;
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Filament\Columns\RowIndexColumn;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Report\AcceptAction;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Report\RejectAction;
|
||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||
use App\Filament\Resources\Manage\Cooperations\Actions\Report\SubmitReportAction;
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Models\Report;
|
||||
use App\Models\User;
|
||||
use App\Notifications\BroadcastNotification;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
@ -66,51 +54,6 @@ public static function getBadge(Model $ownerRecord, string $pageClass): ?string
|
||||
return (string) $query->count();
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('title')
|
||||
->label('Judul')
|
||||
->placeholder('Dirgahayu Purwakarta')
|
||||
->required()
|
||||
->autocomplete(false)
|
||||
->autofocus(),
|
||||
|
||||
DatePicker::make('publication_date')
|
||||
->label('Tanggal Publikasi')
|
||||
->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->required(),
|
||||
|
||||
TextInput::make('link')
|
||||
->label('Tautan')
|
||||
->placeholder('https://example.com')
|
||||
->maxLength(255)
|
||||
->url()
|
||||
->required()
|
||||
->autocomplete(false),
|
||||
|
||||
Textarea::make('description')
|
||||
->label('Deskripsi')
|
||||
->placeholder('....')
|
||||
->required()
|
||||
->autocomplete(false),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('image')
|
||||
->label('Gambar')
|
||||
->disk(config('filesystems.default'))
|
||||
->acceptedFileTypes(['image/*'])
|
||||
->maxSize(1024 * 3)
|
||||
->collection('reports')
|
||||
->image()
|
||||
->helperText('Format yang diterima: JPEG, PNG, GIF, WEBP. Ukuran maksimum: 3 MB.')
|
||||
->required(),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
@ -150,79 +93,7 @@ public function table(Table $table): Table
|
||||
RejectAction::make(),
|
||||
])
|
||||
->headerActions([
|
||||
CreateAction::make()
|
||||
->label('Buat Bukti Tayang')
|
||||
->modalWidth(Width::Large)
|
||||
->modalHeading(fn () => CheerfulNotification::getByKey('cooperation.create_report_title'))
|
||||
->modalDescription(fn () => CheerfulNotification::getByKey('cooperation.create_report_desc'))
|
||||
->using(function (array $data, string $model): Model {
|
||||
return $model::create($data);
|
||||
})
|
||||
->mutateDataUsing(function (array $data): array {
|
||||
$taskAssignment = $this->getOwnerRecord()->taskAssignment;
|
||||
|
||||
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
$mediaTaskAssignment = $taskAssignment?->mediaTaskAssignments()
|
||||
->whereHas('partnerMedia.company', function ($query) {
|
||||
$query->where('user_id', auth()->id());
|
||||
})
|
||||
->first();
|
||||
|
||||
$data['media_task_assignment_id'] = $mediaTaskAssignment?->id;
|
||||
}
|
||||
|
||||
return $data;
|
||||
})
|
||||
->successNotification(null)
|
||||
->after(function (Report $record): void {
|
||||
CheerfulNotification::success(
|
||||
CheerfulNotification::getByKey('cooperation.report_sent_success'),
|
||||
CheerfulNotification::getByKey('cooperation.report_sent_desc')
|
||||
)->send();
|
||||
|
||||
// Notify Admins
|
||||
User::query()
|
||||
->superAdmin()
|
||||
->get()
|
||||
->each(function ($admin) use ($record): void {
|
||||
$user = auth()->user();
|
||||
|
||||
$admin->notify(new BroadcastNotification([
|
||||
'title' => CheerfulNotification::getByKey('cooperation.new_report'),
|
||||
'body' => CheerfulNotification::getByKey('notification.user_submitted_report', ['user__name' => $user->name, 'record__title' => $record->title, 'this__getOwnerRecord____title' => $this->getOwnerRecord()->title]),
|
||||
'action' => [
|
||||
Action::make('view')
|
||||
->label('Lihat')
|
||||
->url(CooperationResource::getUrl('view', ['record' => $this->getOwnerRecord()->id, 'relation' => 3])),
|
||||
],
|
||||
]));
|
||||
});
|
||||
})
|
||||
->visible(function (): bool {
|
||||
$user = auth()->user();
|
||||
|
||||
if (! $user || ! $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$taskAssignment = $this->getOwnerRecord()->taskAssignment;
|
||||
|
||||
if (! $taskAssignment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getOwnerRecord()->status === CooperationStatus::ASSIGNMENT
|
||||
&& $taskAssignment->start_date->toDateString() <= now()->toDateString()
|
||||
&& $taskAssignment->end_date->toDateString() >= now()->toDateString()
|
||||
&& $this->getOwnerRecord()->proposal()
|
||||
->whereHas('partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
|
||||
->accepted()
|
||||
->exists()
|
||||
&& $taskAssignment->reports()
|
||||
->whereHas('mediaTaskAssignment.partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
|
||||
->where('reports.status', '!=', ApprovalStatus::REJECTED)
|
||||
->count() < $taskAssignment->report_amount;
|
||||
}),
|
||||
SubmitReportAction::make(),
|
||||
])
|
||||
->toolbarActions([])
|
||||
->emptyStateIcon(Heroicon::OutlinedInboxArrowDown)
|
||||
|
||||
@ -34,19 +34,19 @@ protected function casts(): array
|
||||
#[Scope]
|
||||
protected function pending(Builder $query): void
|
||||
{
|
||||
$query->where('status', ApprovalStatus::PENDING);
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::PENDING);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function accepted(Builder $query): void
|
||||
{
|
||||
$query->where('status', ApprovalStatus::ACCEPTED);
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::ACCEPTED);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function rejected(Builder $query): void
|
||||
{
|
||||
$query->where('status', ApprovalStatus::REJECTED);
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::REJECTED);
|
||||
}
|
||||
|
||||
public function cooperation(): BelongsTo
|
||||
|
||||
@ -2,9 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use Illuminate\Database\Eloquent\Attributes\Scope;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use Swindon\FilamentHashids\Traits\HasHashid;
|
||||
@ -20,11 +24,35 @@ protected function casts(): array
|
||||
return [
|
||||
'amount' => 'integer',
|
||||
'payment_date' => 'date',
|
||||
'status' => ApprovalStatus::class,
|
||||
];
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function accepted(Builder $query): void
|
||||
{
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::ACCEPTED);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function pending(Builder $query): void
|
||||
{
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::PENDING);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function rejected(Builder $query): void
|
||||
{
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::REJECTED);
|
||||
}
|
||||
|
||||
public function cooperationMedia(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CooperationMedia::class);
|
||||
}
|
||||
|
||||
public function rejectionReasons(): MorphMany
|
||||
{
|
||||
return $this->morphMany(RejectionReason::class, 'rejectable');
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,19 +31,19 @@ protected function casts(): array
|
||||
#[Scope]
|
||||
protected function accepted(Builder $query): void
|
||||
{
|
||||
$query->where('status', ApprovalStatus::ACCEPTED);
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::ACCEPTED);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function pending(Builder $query): void
|
||||
{
|
||||
$query->where('status', ApprovalStatus::PENDING);
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::PENDING);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function rejected(Builder $query): void
|
||||
{
|
||||
$query->where('status', ApprovalStatus::REJECTED);
|
||||
$query->where($this->getTable().'.status', ApprovalStatus::REJECTED);
|
||||
}
|
||||
|
||||
public function mediaTaskAssignment(): BelongsTo
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\ApprovalStatus;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
@ -16,7 +17,8 @@ public function up(): void
|
||||
$table->foreignId('cooperation_media_id')->constrained('cooperation_media')->cascadeOnDelete();
|
||||
$table->unsignedInteger('amount')->index();
|
||||
$table->text('description')->nullable();
|
||||
$table->date('payment_date')->useCurrent()->index();
|
||||
$table->date('payment_date')->nullable()->index();
|
||||
$table->enum('status', ApprovalStatus::values())->default(ApprovalStatus::PENDING->value)->comment(ApprovalStatus::comment())->index();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
|
||||
});
|
||||
|
||||
@ -1105,6 +1105,14 @@
|
||||
'cheerful' => 'Masih ada media yang belum dibayar. Harap selesaikan pembayaran untuk semua media yang menerima kerja sama.',
|
||||
'formal' => 'Terdapat kewajiban pembayaran yang belum diselesaikan untuk media terkait.',
|
||||
],
|
||||
'payment_pending' => [
|
||||
'cheerful' => 'Pembayaran Masih Pending! ⏳',
|
||||
'formal' => 'Pembayaran Masih Menunggu Verifikasi',
|
||||
],
|
||||
'payment_pending_desc' => [
|
||||
'cheerful' => 'Ada media yang sudah mengajukan pembayaran tapi belum diverifikasi. Cek dulu yuk! 🧐',
|
||||
'formal' => 'Terdapat pengajuan pembayaran yang masih menunggu proses verifikasi oleh pihak Admin.',
|
||||
],
|
||||
'completed_success' => [
|
||||
'cheerful' => 'Kerja Sama Selesai! 🎉✨',
|
||||
'formal' => 'Kerja Sama Berhasil Diselesaikan',
|
||||
@ -1217,6 +1225,38 @@
|
||||
'cheerful' => 'Pembayaran Telah Dikirim! 💸✨',
|
||||
'formal' => 'Pembayaran Kerja Sama Telah Dikirim',
|
||||
],
|
||||
'create_payment_title' => [
|
||||
'cheerful' => 'Ajukan Pembayaran Baru 📝💸',
|
||||
'formal' => 'Ajukan Pembayaran Baru',
|
||||
],
|
||||
'create_payment_desc' => [
|
||||
'cheerful' => 'Sudah waktunya gajian! Unggah dokumen penagihanmu (invoice/kwitansi) agar admin bisa segera memproses pembayarannya ya! 🚀💰',
|
||||
'formal' => 'Silakan unggah dokumen penagihan (invoice/kwitansi) Anda untuk diproses oleh admin.',
|
||||
],
|
||||
'payment_requested_success' => [
|
||||
'cheerful' => 'Pengajuan Pembayaran Berhasil! 🚀✨',
|
||||
'formal' => 'Pengajuan Pembayaran Berhasil',
|
||||
],
|
||||
'payment_requested_desc' => [
|
||||
'cheerful' => 'Sip! Pengajuan pembayaran Anda sudah masuk ke sistem. Admin akan segera memprosesnya. Mohon ditunggu ya! 😊💰',
|
||||
'formal' => 'Pengajuan pembayaran Anda telah berhasil dikirimkan dan sedang menunggu verifikasi admin.',
|
||||
],
|
||||
'payment_approved' => [
|
||||
'cheerful' => 'Pembayaran Disetujui! ✅💰',
|
||||
'formal' => 'Pembayaran Disetujui',
|
||||
],
|
||||
'payment_rejected' => [
|
||||
'cheerful' => 'Pembayaran Ditolak 🛑',
|
||||
'formal' => 'Pembayaran Ditolak',
|
||||
],
|
||||
'reject_payment_title' => [
|
||||
'cheerful' => 'Tolak Pengajuan Pembayaran? 🛑🤔',
|
||||
'formal' => 'Tolak Pengajuan Pembayaran',
|
||||
],
|
||||
'reject_payment_desc' => [
|
||||
'cheerful' => 'Apakah Anda yakin ingin menolak pengajuan pembayaran ini? Berikan alasan agar media bisa memperbaikinya! 📝',
|
||||
'formal' => 'Apakah Anda yakin ingin menolak pengajuan pembayaran ini? Silakan berikan alasan penolakan.',
|
||||
],
|
||||
'new_offer' => [
|
||||
'cheerful' => 'Ada Penawaran Kerja Sama Baru! 🤝✨',
|
||||
'formal' => 'Penawaran Kerja Sama Baru',
|
||||
@ -1571,6 +1611,18 @@
|
||||
'cheerful' => 'Halo Admin! :user__name baru saja mengirimkan bukti tayang ":record__title" untuk kerja sama terkait. Yuk, dicek! 😊',
|
||||
'formal' => 'Pengguna :user__name telah mengirimkan bukti tayang baru ":record__title" untuk pengajuan kerja sama.',
|
||||
],
|
||||
'payment_requested' => [
|
||||
'cheerful' => 'Halo Admin! 👋 :user__name baru saja mengajukan pembayaran untuk media :record__partnerMedia__name pada kerja sama :record__cooperation__title. Yuk, segera diproses! 💸🚀',
|
||||
'formal' => 'Pengguna :user__name telah mengajukan pembayaran untuk media :record__partnerMedia__name pada kerja sama :record__cooperation__title.',
|
||||
],
|
||||
'payment_approved_notice' => [
|
||||
'cheerful' => 'Mantap! Pengajuan pembayaran untuk :record__partnerMedia__name telah disetujui. 💸✨',
|
||||
'formal' => 'Pengajuan pembayaran untuk :record__partnerMedia__name telah berhasil disetujui.',
|
||||
],
|
||||
'payment_rejected_reason' => [
|
||||
'cheerful' => 'Duh, pengajuan pembayaran untuk :record__partnerMedia__name terpaksa ditolak. Alasan: :data__reason 🛑',
|
||||
'formal' => 'Pengajuan pembayaran untuk :record__partnerMedia__name telah ditolak dengan alasan: :data__reason',
|
||||
],
|
||||
'data_change_rejected' => [
|
||||
'cheerful' => 'Halo! Mohon maaf, permohonan perubahan data Anda untuk :record__change_reason ditolak oleh admin. Alasan: :data__rejection_reason 😔',
|
||||
'formal' => 'Permohonan perubahan data Anda untuk :record__change_reason telah ditolak oleh Admin. Alasan: :data__rejection_reason',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user