feat: Enhance cooperation and reporting workflows with refined relationships, new payment management, and updated actions.

This commit is contained in:
Yoga Pangestu 2026-02-02 11:56:49 +07:00
parent 693d1f001c
commit 2d7f4ee0e8
25 changed files with 246 additions and 96 deletions

View File

@ -1,22 +0,0 @@
---
description: Automatic commit message generator and fast AI-powered commit for all current changes
---
// turbo-all
This workflow automatically stages all changes, generates a descriptive commit message, and commits them in one go.
### Steps:
1. **Stage All Changes**: Automatically stage all modified and new files.
```bash
git add .
```
2. **Analyze Changes**: Get the diff of staged changes to understand the context.
```bash
git diff --cached
```
3. **Generate & Commit**: Generate a professional message following [Conventional Commits](https://www.conventionalcommits.org/) and execute the commit.
```bash
git commit -m "<ai_generated_message>"
```

View File

@ -34,7 +34,7 @@ public function getColor(): string|array|null
self::PENDING => 'warning', self::PENDING => 'warning',
self::ASSIGNMENT => 'info', self::ASSIGNMENT => 'info',
self::VERIFICATION => 'primary', self::VERIFICATION => 'primary',
self::PAYMENT => 'secondary', self::PAYMENT => 'slate',
self::COMPLETED => 'success', self::COMPLETED => 'success',
}; };
} }

View File

@ -54,7 +54,7 @@ protected function setUp(): void
$record->update([ $record->update([
'payment_amount' => $totalPayment, 'payment_amount' => $totalPayment,
'payment_date' => now(), 'completed_at' => now(),
'status' => CooperationStatus::COMPLETED, 'status' => CooperationStatus::COMPLETED,
]); ]);

View File

@ -23,7 +23,10 @@ protected function setUp(): void
->modalHeading('Lanjutkan ke Pembayaran?') ->modalHeading('Lanjutkan ke Pembayaran?')
->modalDescription('Apakah Anda yakin ingin melanjutkan kerja sama ini ke tahap pembayaran? Pastikan semua laporan telah diverifikasi.') ->modalDescription('Apakah Anda yakin ingin melanjutkan kerja sama ini ke tahap pembayaran? Pastikan semua laporan telah diverifikasi.')
->action(function (Cooperation $record): void { ->action(function (Cooperation $record): void {
$record->update(['status' => CooperationStatus::PAYMENT]); $record->update([
'status' => CooperationStatus::PAYMENT,
'payment_date' => now()->toDateString(),
]);
CheerfulNotification::success( CheerfulNotification::success(
'Tahap Pembayaran Dimulai! 💸✨', 'Tahap Pembayaran Dimulai! 💸✨',

View File

@ -34,7 +34,9 @@ protected function setUp(): void
->autocomplete(false) ->autocomplete(false)
->autofocus() ->autofocus()
->nullable() ->nullable()
->url(), ->url()
->required()
->maxLength(200),
Textarea::make('description') Textarea::make('description')
->label('Deskripsi') ->label('Deskripsi')

View File

@ -4,8 +4,10 @@
use App\Enums\ApprovalStatus; use App\Enums\ApprovalStatus;
use App\Enums\CooperationStatus; use App\Enums\CooperationStatus;
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
use App\Filament\Support\CheerfulNotification; use App\Filament\Support\CheerfulNotification;
use App\Models\CooperationMedia; use App\Models\CooperationMedia;
use App\Notifications\BroadcastNotification;
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload; use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Textarea;
@ -64,6 +66,19 @@ protected function setUp(): void
'Pembayaran Berhasil! 💸✨', 'Pembayaran Berhasil! 💸✨',
"Pembayaran untuk {$record->partnerMedia->name} telah berhasil dicatat." "Pembayaran untuk {$record->partnerMedia->name} telah berhasil dicatat."
)->send(); )->send();
$partnerUser = $record->partnerMedia->company?->user;
if ($partnerUser) {
$partnerUser->notify(new BroadcastNotification([
'title' => 'Pembayaran Telah Dikirim! 💸✨',
'body' => "Halo! Pembayaran untuk kerja sama \"{$record->cooperation->title}\" telah berhasil dikirim oleh Admin. Silakan cek detailnya ya! 😊",
'action' => [
Action::make('view')
->label('Lihat')
->url(CooperationResource::getUrl('view', ['record' => $record->cooperation_id, 'relation' => 0])),
],
]));
}
}) })
->modalWidth(Width::Large); ->modalWidth(Width::Large);
} }

View File

@ -32,28 +32,21 @@ protected function setUp(): void
->success() ->success()
->send(); ->send();
// Notify all partners in this cooperation (since reports might be per media even if shared in DB) $partnerUser = $record->mediaTaskAssignment?->partnerMedia?->company?->user;
$partners = $record->taskAssignment?->cooperation?->partnerMedia() if ($partnerUser) {
->wherePivot('status', ApprovalStatus::ACCEPTED) $partnerUser->notify(new BroadcastNotification([
->get(); 'title' => 'Mantap! Laporan Diterima 🎊✨',
'body' => "Hore! Laporan \"{$record->title}\" pada kerja sama \"{$record->mediaTaskAssignment->taskAssignment->cooperation->title}\" telah disetujui oleh Admin. Satu langkah lebih dekat! 🚀",
foreach ($partners as $media) { 'action' => [
$partnerUser = $media->company?->user; Action::make('view')
if ($partnerUser) { ->label('Lihat')
$partnerUser->notify(new BroadcastNotification([ ->url(CooperationResource::getUrl('view', ['record' => $record->mediaTaskAssignment->taskAssignment->cooperation_id, 'relation' => 3])),
'title' => 'Mantap! Laporan Diterima 🎊✨', ],
'body' => "Hore! Laporan \"{$record->title}\" pada kerja sama \"{$record->taskAssignment->cooperation->title}\" telah disetujui oleh Admin. Satu langkah lebih dekat! 🚀", ]));
'action' => [
Action::make('view')
->label('Lihat')
->url(CooperationResource::getUrl('view', ['record' => $record->taskAssignment->cooperation_id, 'relation' => 3])),
],
]));
}
} }
}) })
->visible( ->visible(
fn (Report $record): bool => $record->taskAssignment?->cooperation?->status === CooperationStatus::VERIFICATION && fn (Report $record): bool => $record->mediaTaskAssignment?->taskAssignment?->cooperation?->status === CooperationStatus::VERIFICATION &&
! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) && ! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) &&
$record->status === ApprovalStatus::PENDING $record->status === ApprovalStatus::PENDING
); );

View File

@ -42,28 +42,21 @@ protected function setUp(): void
->warning() ->warning()
->send(); ->send();
// Notify all partners in this cooperation (since we can't tell which specific one) $partnerUser = $record->mediaTaskAssignment?->partnerMedia?->company?->user;
$partners = $record->taskAssignment?->cooperation?->partnerMedia() if ($partnerUser) {
->wherePivot('status', ApprovalStatus::ACCEPTED) $partnerUser->notify(new BroadcastNotification([
->get(); 'title' => 'Yah, Laporan Ditolak 🙁',
'body' => "Halo! Laporan \"{$record->title}\" pada kerja sama \"{$record->mediaTaskAssignment->taskAssignment->cooperation->title}\" ditolak oleh Admin. 💪\n\nCatatan Admin: {$data['reason']}",
foreach ($partners as $media) { 'action' => [
$partnerUser = $media->company?->user; Action::make('view')
if ($partnerUser) { ->label('Lihat')
$partnerUser->notify(new BroadcastNotification([ ->url(CooperationResource::getUrl('view', ['record' => $record->mediaTaskAssignment->taskAssignment->cooperation_id])),
'title' => 'Yah, Laporan Perlu Diperbaiki nih 📝', ],
'body' => "Halo! Laporan \"{$record->title}\" pada kerja sama \"{$record->taskAssignment->cooperation->title}\" ditolak oleh Admin. 💪\n\nCatatan Admin: {$data['reason']}", ]));
'action' => [
Action::make('view')
->label('Lihat')
->url(CooperationResource::getUrl('view', ['record' => $record->taskAssignment->cooperation_id])),
],
]));
}
} }
}) })
->visible( ->visible(
fn (Report $record): bool => $record->taskAssignment?->cooperation?->status === CooperationStatus::VERIFICATION && fn (Report $record): bool => $record->mediaTaskAssignment?->taskAssignment?->cooperation?->status === CooperationStatus::VERIFICATION &&
! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) && ! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) &&
$record->status === ApprovalStatus::PENDING $record->status === ApprovalStatus::PENDING
) )

View File

@ -8,6 +8,7 @@
use App\Filament\Resources\Manage\Cooperations\Pages\ListCooperations; use App\Filament\Resources\Manage\Cooperations\Pages\ListCooperations;
use App\Filament\Resources\Manage\Cooperations\Pages\ViewCooperation; use App\Filament\Resources\Manage\Cooperations\Pages\ViewCooperation;
use App\Filament\Resources\Manage\Cooperations\RelationManagers\CooperationMediaRelationManager; use App\Filament\Resources\Manage\Cooperations\RelationManagers\CooperationMediaRelationManager;
use App\Filament\Resources\Manage\Cooperations\RelationManagers\CooperationPaymentRelationManager;
use App\Filament\Resources\Manage\Cooperations\RelationManagers\CooperationProposalRelationManager; use App\Filament\Resources\Manage\Cooperations\RelationManagers\CooperationProposalRelationManager;
use App\Filament\Resources\Manage\Cooperations\RelationManagers\ReportRelationManager; use App\Filament\Resources\Manage\Cooperations\RelationManagers\ReportRelationManager;
use App\Filament\Resources\Manage\Cooperations\RelationManagers\TaskAssignmentRelationManager; use App\Filament\Resources\Manage\Cooperations\RelationManagers\TaskAssignmentRelationManager;
@ -120,6 +121,11 @@ public static function infolist(Schema $schema): Schema
->label('Tanggal Pembayaran') ->label('Tanggal Pembayaran')
->date('l, d F Y') ->date('l, d F Y')
->placeholder('Belum dibayar'), ->placeholder('Belum dibayar'),
TextEntry::make('completed_at')
->label('Tanggal Selesai')
->date('l, d F Y')
->placeholder('Masih berjalan'),
]), ]),
Grid::make(3) Grid::make(3)
@ -153,6 +159,7 @@ public static function getRelations(): array
CooperationProposalRelationManager::class, CooperationProposalRelationManager::class,
TaskAssignmentRelationManager::class, TaskAssignmentRelationManager::class,
ReportRelationManager::class, ReportRelationManager::class,
CooperationPaymentRelationManager::class,
]; ];
} }

View File

@ -19,6 +19,8 @@
class CooperationMediaRelationManager extends RelationManager class CooperationMediaRelationManager extends RelationManager
{ {
protected static ?string $recordTitleAttribute = 'partnerMedia.name';
protected static string $relationship = 'cooperationMedia'; protected static string $relationship = 'cooperationMedia';
protected static ?string $title = 'Media'; protected static ?string $title = 'Media';
@ -59,7 +61,8 @@ public function table(Table $table): Table
->visible(fn (CooperationMedia $record): bool => $record->status === ApprovalStatus::ACCEPTED && $record->payment()->exists()), ->visible(fn (CooperationMedia $record): bool => $record->status === ApprovalStatus::ACCEPTED && $record->payment()->exists()),
]) ])
->emptyStateIcon(Heroicon::Newspaper) ->emptyStateIcon(Heroicon::Newspaper)
->emptyStateDescription('Tidak ada media yang diikutsertakan.'); ->emptyStateDescription('Tidak ada media yang diikutsertakan.')
->defaultSort('created_at', 'desc');
} }
public function infolist(Schema $infolist): Schema public function infolist(Schema $infolist): Schema
@ -70,11 +73,11 @@ public function infolist(Schema $infolist): Schema
->schema([ ->schema([
TextEntry::make('payment.amount') TextEntry::make('payment.amount')
->label('Nominal') ->label('Nominal')
->money('IDR'), ->money('IDR', decimalPlaces: 0),
TextEntry::make('payment.payment_date') TextEntry::make('payment.payment_date')
->label('Tanggal Bayar') ->label('Tanggal Bayar')
->dateTime(), ->dateTime('l, d F Y'),
]), ]),
TextEntry::make('payment.description') TextEntry::make('payment.description')

View File

@ -0,0 +1,74 @@
<?php
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
use App\Enums\ApprovalStatus;
use App\Enums\RoleEnum;
use App\Models\CooperationPayment;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
class CooperationPaymentRelationManager extends RelationManager
{
protected static ?string $recordTitleAttribute = 'description';
protected static string $relationship = 'payments';
protected static ?string $title = 'Pembayaran';
public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
{
if (! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
return false;
}
return $ownerRecord->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($query) {
$query->where('user_id', auth()->id());
});
})
->where('status', ApprovalStatus::ACCEPTED)
->exists();
}
public function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('amount')
->label('Nominal')
->money('IDR', decimalPlaces: 0),
TextColumn::make('payment_date')
->label('Tanggal Bayar')
->date('l, d F Y'),
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')),
])
->filters([])
->headerActions([])
->recordActions([])
->emptyStateIcon(Heroicon::CreditCard)
->emptyStateDescription('Belum ada data pembayaran.')
->defaultSort('created_at', 'desc')
->modifyQueryUsing(function ($query) {
$user = auth()->user();
return $query->whereHas('cooperationMedia.partnerMedia.company', function ($q) use ($user) {
$q->where('user_id', $user->id);
});
});
}
}

View File

@ -23,6 +23,8 @@
class CooperationProposalRelationManager extends RelationManager class CooperationProposalRelationManager extends RelationManager
{ {
protected static ?string $recordTitleAttribute = 'e_catalog';
protected static string $relationship = 'proposal'; protected static string $relationship = 'proposal';
protected static ?string $title = 'Proposal'; protected static ?string $title = 'Proposal';
@ -110,6 +112,7 @@ public function table(Table $table): Table
]) ])
->emptyStateIcon(Heroicon::DocumentText) ->emptyStateIcon(Heroicon::DocumentText)
->emptyStateDescription('Tidak ada proposal yang diajukan.') ->emptyStateDescription('Tidak ada proposal yang diajukan.')
->defaultSort('created_at', 'desc')
->modifyQueryUsing(function ($query) { ->modifyQueryUsing(function ($query) {
$user = auth()->user(); $user = auth()->user();

View File

@ -32,6 +32,11 @@ class ReportRelationManager extends RelationManager
protected static ?string $title = 'Laporan'; protected static ?string $title = 'Laporan';
public function isReadOnly(): bool
{
return false;
}
public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
{ {
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) { if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
@ -48,13 +53,16 @@ public static function canViewForRecord(Model $ownerRecord, string $pageClass):
return true; return true;
} }
public function isReadOnly(): bool
{
return false;
}
public static function getBadge(Model $ownerRecord, string $pageClass): ?string public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{ {
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
return $ownerRecord->reports()
->whereHas('mediaTaskAssignment.partnerMedia.company', function ($q) {
$q->where('user_id', auth()->id());
})
->count();
}
return $ownerRecord->reports()->count(); return $ownerRecord->reports()->count();
} }
@ -106,6 +114,11 @@ public function table(Table $table): Table
{ {
return $table return $table
->columns([ ->columns([
TextColumn::make('mediaTaskAssignment.partnerMedia.name')
->label('Media')
->searchable()
->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
TextColumn::make('title') TextColumn::make('title')
->label('Judul') ->label('Judul')
->searchable(), ->searchable(),
@ -140,7 +153,17 @@ public function table(Table $table): Table
->modalWidth(Width::Large) ->modalWidth(Width::Large)
->modalHeading('Buat Laporan') ->modalHeading('Buat Laporan')
->mutateDataUsing(function (array $data): array { ->mutateDataUsing(function (array $data): array {
$data['task_assignment_id'] = $this->getOwnerRecord()->taskAssignment?->id; $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; return $data;
}) })
@ -185,12 +208,25 @@ public function table(Table $table): Table
&& $taskAssignment->start_date->toDateString() <= now()->toDateString() && $taskAssignment->start_date->toDateString() <= now()->toDateString()
&& $taskAssignment->end_date->toDateString() >= now()->toDateString() && $taskAssignment->end_date->toDateString() >= now()->toDateString()
&& $taskAssignment->reports() && $taskAssignment->reports()
->where('status', '!=', ApprovalStatus::REJECTED) ->whereHas('mediaTaskAssignment.partnerMedia.company', fn ($q) => $q->where('user_id', auth()->id()))
->where('reports.status', '!=', ApprovalStatus::REJECTED)
->count() < $taskAssignment->report_amount; ->count() < $taskAssignment->report_amount;
}), }),
]) ])
->toolbarActions([]) ->toolbarActions([])
->emptyStateIcon(Heroicon::InboxArrowDown) ->emptyStateIcon(Heroicon::InboxArrowDown)
->emptyStateDescription('Tidak ada laporan yang diajukan.'); ->emptyStateDescription('Tidak ada laporan yang diajukan.')
->defaultSort('created_at', 'desc')
->modifyQueryUsing(function ($query) {
$user = auth()->user();
if (! $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
return $query;
}
$query->whereHas('mediaTaskAssignment.partnerMedia.company', function ($q) use ($user) {
$q->where('user_id', $user->id);
});
});
} }
} }

View File

@ -132,6 +132,13 @@ public static function configure(Table $table): Table
->placeholder('Belum dibayar') ->placeholder('Belum dibayar')
->toggleable(isToggledHiddenByDefault: true), ->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('completed_at')
->label('Tanggal Selesai')
->date('l, d F Y')
->sortable()
->placeholder('Masih berjalan')
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('description') TextColumn::make('description')
->label('Deskripsi') ->label('Deskripsi')
->searchable() ->searchable()

View File

@ -8,6 +8,7 @@
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
@ -28,6 +29,7 @@ protected function casts(): array
'final_submission_date' => 'date', 'final_submission_date' => 'date',
'payment_amount' => 'integer', 'payment_amount' => 'integer',
'payment_date' => 'date', 'payment_date' => 'date',
'completed_at' => 'date',
'status' => CooperationStatus::class, 'status' => CooperationStatus::class,
]; ];
} }
@ -62,30 +64,46 @@ protected function completed(Builder $query): void
$query->where('status', CooperationStatus::COMPLETED); $query->where('status', CooperationStatus::COMPLETED);
} }
public function cooperationMedia(): HasOne public function cooperationMedia(): HasMany
{ {
return $this->hasOne(CooperationMedia::class); return $this->hasMany(CooperationMedia::class);
} }
public function partnerMedia(): BelongsToMany public function partnerMedia(): BelongsToMany
{ {
return $this->belongsToMany(PartnerMedia::class, 'cooperation_media') return $this->belongsToMany(PartnerMedia::class, 'cooperation_media')
->using(CooperationMedia::class)
->withPivot(['status']) ->withPivot(['status'])
->withTimestamps(); ->withTimestamps();
} }
public function proposal(): HasOne public function proposal(): HasMany
{ {
return $this->hasOne(CooperationProposal::class); return $this->hasMany(CooperationProposal::class);
} }
public function reports(): HasManyThrough public function reports(): HasManyThrough
{ {
return $this->hasManyThrough(Report::class, TaskAssignment::class); return $this->hasManyThrough(
Report::class,
MediaTaskAssignment::class,
'task_assignment_id',
'media_task_assignment_id'
);
} }
public function taskAssignment(): HasOne public function taskAssignment(): HasOne
{ {
return $this->hasOne(TaskAssignment::class); return $this->hasOne(TaskAssignment::class);
} }
public function payments(): HasManyThrough
{
return $this->hasManyThrough(
CooperationPayment::class,
CooperationMedia::class,
'cooperation_id',
'cooperation_media_id'
);
}
} }

View File

@ -5,6 +5,7 @@
use App\Enums\ApprovalStatus; use App\Enums\ApprovalStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\Pivot; use Illuminate\Database\Eloquent\Relations\Pivot;
use Swindon\FilamentHashids\Traits\HasHashid; use Swindon\FilamentHashids\Traits\HasHashid;
@ -38,4 +39,9 @@ public function rejectionReasons(): MorphMany
{ {
return $this->morphMany(RejectionReason::class, 'rejectable'); return $this->morphMany(RejectionReason::class, 'rejectable');
} }
public function reports(): HasMany
{
return $this->hasMany(Report::class);
}
} }

View File

@ -85,6 +85,7 @@ public function cooperationProposals(): HasMany
public function cooperations(): BelongsToMany public function cooperations(): BelongsToMany
{ {
return $this->belongsToMany(Cooperation::class, 'cooperation_media') return $this->belongsToMany(Cooperation::class, 'cooperation_media')
->using(CooperationMedia::class)
->withPivot(['status']) ->withPivot(['status'])
->withTimestamps(); ->withTimestamps();
} }
@ -102,6 +103,7 @@ public function mediaTaskAssignments(): HasMany
public function taskAssignments(): BelongsToMany public function taskAssignments(): BelongsToMany
{ {
return $this->belongsToMany(TaskAssignment::class, 'media_task_assignment') return $this->belongsToMany(TaskAssignment::class, 'media_task_assignment')
->using(MediaTaskAssignment::class)
->withPivot(['status']) ->withPivot(['status'])
->withTimestamps(); ->withTimestamps();
} }

View File

@ -26,9 +26,9 @@ protected function casts(): array
]; ];
} }
public function taskAssignment(): BelongsTo public function mediaTaskAssignment(): BelongsTo
{ {
return $this->belongsTo(TaskAssignment::class); return $this->belongsTo(MediaTaskAssignment::class);
} }
public function rejectionReasons(): MorphMany public function rejectionReasons(): MorphMany

View File

@ -7,6 +7,7 @@
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphMany;
use Swindon\FilamentHashids\Traits\HasHashid; use Swindon\FilamentHashids\Traits\HasHashid;
@ -29,9 +30,16 @@ public function cooperation(): BelongsTo
return $this->belongsTo(Cooperation::class); return $this->belongsTo(Cooperation::class);
} }
public function reports(): HasMany public function reports(): HasManyThrough
{ {
return $this->hasMany(Report::class); return $this->hasManyThrough(
Report::class,
MediaTaskAssignment::class,
'task_assignment_id', // Foreign key di tabel media_task_assignment
'media_task_assignment_id', // Foreign key di tabel reports
'id', // Local key di tabel task_assignments
'id' // Local key di tabel media_task_assignment
);
} }
public function rejectionReasons(): MorphMany public function rejectionReasons(): MorphMany
@ -44,9 +52,10 @@ public function mediaTaskAssignments(): HasMany
return $this->hasMany(MediaTaskAssignment::class); return $this->hasMany(MediaTaskAssignment::class);
} }
public function partnerMedias(): BelongsToMany public function partnerMedia(): BelongsToMany
{ {
return $this->belongsToMany(PartnerMedia::class, 'media_task_assignment') return $this->belongsToMany(PartnerMedia::class, 'media_task_assignment')
->using(MediaTaskAssignment::class)
->withPivot(['status']) ->withPivot(['status'])
->withTimestamps(); ->withTimestamps();
} }

View File

@ -38,9 +38,9 @@ protected function casts(): array
public function canAccessPanel(Panel $panel): bool public function canAccessPanel(Panel $panel): bool
{ {
// if ($this->company?->verificationRequest?->status === VerificationStatus::REJECTED) { if ($this->company?->verificationRequest?->status === VerificationStatus::REJECTED) {
// return false; return false;
// } }
return $this->is_active === IsActive::ACTIVE; return $this->is_active === IsActive::ACTIVE;
} }

View File

@ -20,7 +20,8 @@ public function up(): void
$table->text('description'); $table->text('description');
$table->unsignedInteger('payment_amount')->nullable(); $table->unsignedInteger('payment_amount')->nullable();
$table->date('payment_date')->nullable(); $table->date('payment_date')->nullable();
$table->enum('status', [CooperationStatus::values()])->default(CooperationStatus::PENDING)->comment(CooperationStatus::comment()); $table->date('completed_at')->nullable();
$table->enum('status', CooperationStatus::values())->default(CooperationStatus::PENDING)->comment(CooperationStatus::comment());
$table->timestamp('created_at')->useCurrent(); $table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate(); $table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->softDeletes(); $table->softDeletes();

View File

@ -18,7 +18,7 @@ public function up(): void
$table->id(); $table->id();
$table->foreignIdFor(Cooperation::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(Cooperation::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(PartnerMedia::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(PartnerMedia::class)->constrained()->cascadeOnDelete();
$table->enum('status', [ApprovalStatus::values()])->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment()); $table->enum('status', ApprovalStatus::values())->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment());
$table->timestamp('created_at')->useCurrent(); $table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate(); $table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
}); });

View File

@ -19,8 +19,8 @@ public function up(): void
$table->foreignIdFor(Cooperation::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(Cooperation::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(PartnerMedia::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(PartnerMedia::class)->constrained()->cascadeOnDelete();
$table->text('description')->nullable(); $table->text('description')->nullable();
$table->string('e_catalog', 50)->nullable(); $table->string('e_catalog', 200)->nullable();
$table->enum('status', [ApprovalStatus::values()])->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment()); $table->enum('status', ApprovalStatus::values())->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment());
$table->timestamp('submitted_at')->useCurrent(); $table->timestamp('submitted_at')->useCurrent();
$table->timestamp('responded_at')->nullable(); $table->timestamp('responded_at')->nullable();
$table->timestamp('created_at')->useCurrent(); $table->timestamp('created_at')->useCurrent();

View File

@ -18,7 +18,7 @@ public function up(): void
$table->id(); $table->id();
$table->foreignIdFor(TaskAssignment::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(TaskAssignment::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(PartnerMedia::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(PartnerMedia::class)->constrained()->cascadeOnDelete();
$table->enum('status', [ApprovalStatus::values()])->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment()); $table->enum('status', ApprovalStatus::values())->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment());
$table->timestamp('created_at')->useCurrent(); $table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate(); $table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
}); });

View File

@ -1,7 +1,7 @@
<?php <?php
use App\Enums\ApprovalStatus; use App\Enums\ApprovalStatus;
use App\Models\TaskAssignment; use App\Models\MediaTaskAssignment;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
@ -15,12 +15,12 @@ public function up(): void
{ {
Schema::create('reports', function (Blueprint $table) { Schema::create('reports', function (Blueprint $table) {
$table->id(); $table->id();
$table->foreignIdFor(TaskAssignment::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(MediaTaskAssignment::class)->constrained()->cascadeOnDelete();
$table->string('title', 200); $table->string('title', 200);
$table->date('publication_date'); $table->date('publication_date');
$table->string('link', 50); $table->string('link', 50);
$table->text('description'); $table->text('description');
$table->enum('status', [ApprovalStatus::values()])->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment()); $table->enum('status', ApprovalStatus::values())->default(ApprovalStatus::PENDING)->comment(ApprovalStatus::comment());
$table->timestamp('created_at')->useCurrent(); $table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate(); $table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->softDeletes(); $table->softDeletes();