simedkom/app/Filament/Resources/Manage/Cooperations/Tables/CooperationsTable.php
Yoga Pangestu 2b49688f8f feat: Enhance cooperation proposal management with media handling and improved infolist display
- Removed debug statement from CreateCooperation.php.
- Updated CooperationProposalRelationManager to include a detailed infolist schema with media and status information.
- Improved proposal creation logic in CooperationsTable to handle proposal attachments and store them in the media library.
- Implemented media handling in CooperationProposal model for better integration with file uploads.
2026-01-12 10:33:47 +07:00

408 lines
18 KiB
PHP

<?php
namespace App\Filament\Resources\Manage\Cooperations\Tables;
use App\Enums\ApprovalStatus;
use App\Enums\CooperationStatus;
use App\Filament\Actions\DefaultBulkActions;
use App\Filament\Columns\TimestampColumns;
use App\Models\Cooperation;
use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload;
use Carbon\CarbonInterface;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Support\Enums\Width;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Storage;
class CooperationsTable
{
public static function configure(Table $table): Table
{
return $table
->columns([
TextColumn::make('title')
->label('Judul')
->searchable()
->sortable()
->wrap(),
TextColumn::make('partnerMedia.name')
->label('Media')
->listWithLineBreaks()
->limitList(3)
->expandableLimitedList()
->badge()
->visible(! auth()->user()->hasRole('Perusahaan')),
TextColumn::make('initial_submission_date')
->label('Tgl Pengajuan Awal')
->searchable()
->sortable()
->date('l, d F Y'),
TextColumn::make('final_submission_date')
->label('Tgl Pengajuan Akhir')
->searchable()
->sortable()
->date('l, d F Y')
->description(
fn (Cooperation $record): string => now()->greaterThan($record->final_submission_date)
? 'Waktu Pengajuan Habis'
: 'Sisa waktu pengajuan: '.now()->diffForHumans(
$record->final_submission_date,
['syntax' => CarbonInterface::DIFF_ABSOLUTE]
)
),
TextColumn::make('assignment_deadline')
->label('Deadline Penugasan')
->searchable()
->sortable()
->date('l, d F Y')
->placeholder('Belum ditentukan')
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('verification_deadline')
->label('Deadline Verifikasi')
->searchable()
->sortable()
->date('l, d F Y')
->placeholder('Belum ditentukan')
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('status')
->searchable()
->sortable()
->badge(),
TextColumn::make('media_count')
->label('Tanggapan Media')
->html()
->getStateUsing(function (Cooperation $record) {
$record->loadCount([
'partnerMedia as approved_count' => fn ($query) => $query->where('cooperation_media.status', ApprovalStatus::ACCEPTED),
'partnerMedia as rejected_count' => fn ($query) => $query->where('cooperation_media.status', ApprovalStatus::REJECTED),
'partnerMedia as pending_count' => fn ($query) => $query->where('cooperation_media.status', ApprovalStatus::PENDING),
]);
$totalCount = $record->partnerMedia()->count();
return "Menerima: {$record->approved_count}<br>
Menolak: {$record->rejected_count}<br>
Belum Menanggapi: {$record->pending_count}<br>
Total: {$totalCount}";
})
->visible(! auth()->user()->hasRole('Perusahaan')),
TextColumn::make('status_tanggapan')
->label('Tanggapan')
->getStateUsing(function ($record) {
if (auth()->user()->hasRole('Perusahaan')) {
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
return $cooperationMedia?->status;
}
return null;
})
->badge()
->visible(auth()->user()->hasRole('Perusahaan')),
TextColumn::make('payment_amount')
->label('Jumlah Pembayaran')
->money('IDR')
->sortable()
->placeholder('Belum ditentukan')
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('payment_date')
->label('Tanggal Pembayaran')
->date('l, d F Y')
->sortable()
->placeholder('Belum dibayar')
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('description')
->label('Deskripsi')
->searchable()
->limit(50)
->wrap()
->toggleable(isToggledHiddenByDefault: true),
...TimestampColumns::make(),
])
->filters([
TrashedFilter::make()->native(false),
])
->recordActions([
ViewAction::make(),
Action::make('accept')
->label('Terima')
->icon(Heroicon::OutlinedCheck)
->color('success')
->action(function ($record) {
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
if ($cooperationMedia) {
$cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]);
Notification::make()
->title('Kerja sama diterima')
->success()
->send();
}
})
->visible(function ($record) {
if (! auth()->user()->hasRole('Perusahaan')) {
return false;
}
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
return $cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING;
}),
Action::make('reject')
->label('Tolak')
->icon(Heroicon::XMark)
->color('danger')
->action(function ($record) {
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
if ($cooperationMedia) {
$cooperationMedia->update(['status' => ApprovalStatus::REJECTED]);
Notification::make()
->title('Kerja sama ditolak')
->success()
->send();
}
})
->visible(function ($record) {
if (! auth()->user()->hasRole('Perusahaan')) {
return false;
}
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
return $cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING;
}),
Action::make('send_proposal')
->label('Ajukan Proposal')
->icon(Heroicon::DocumentText)
->color('info')
->schema([
TextInput::make('e_catalog')
->label('E-Catalog')
->placeholder('https://katalog.inaproc.id/purwakarta-kita-media-karya')
->autocomplete(false)
->autofocus()
->nullable()
->url(),
Textarea::make('description')
->label('Deskripsi')
->autocomplete(false)
->required()
->rows(4)
->placeholder('...'),
AdvancedFileUpload::make('proposal_attachment')
->label('Lampiran')
->disk(config('filesystems.default'))
->acceptedFileTypes(['application/pdf'])
->maxSize(1024 * 10)
->directory(fn () => 'cooperations/proposal-attachment/'.now()->toDateString())
->required(),
])
->action(function ($record, array $data) {
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
if ($cooperationMedia) {
$proposal = $record->proposals()->create([
'partner_media_id' => $cooperationMedia->partner_media_id,
'description' => $data['description'],
'e_catalog' => $data['e_catalog'],
'status' => ApprovalStatus::PENDING->value,
]);
if (! empty($data['proposal_attachment'])) {
$filePath = collect($data['proposal_attachment'])->first();
$fullPath = Storage::disk(config('filesystems.default'))->path($filePath);
if (file_exists($fullPath)) {
$proposal->addMediaFromDisk($filePath, config('filesystems.default'))
->preservingOriginal()
->withCustomProperties([
'feature' => 'cooperations',
'date' => now()->toDateString(),
'doc_type' => 'proposal-attachment',
])
->toMediaCollection('cooperations');
}
}
Notification::make()
->title('Proposal kerja sama berhasil dikirim')
->success()
->send();
}
})
->modalHeading('Proposal Kerja Sama')
->modalSubmitActionLabel('Kirim Proposal')
->visible(function ($record) {
if (! auth()->user()->hasRole('Perusahaan')) {
return false;
}
$cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) {
$subQuery->where('user_id', auth()->id());
});
})
->first();
return $cooperationMedia
&& $cooperationMedia->status === ApprovalStatus::ACCEPTED
&& ! $record->proposals()
->where('partner_media_id', $cooperationMedia->partner_media_id)
->whereIn('status', [
ApprovalStatus::ACCEPTED,
ApprovalStatus::PENDING,
])
->exists();
})
->modalWidth(Width::Large),
Action::make('create_task_assignment')
->label('Buat Penugasan')
->icon(Heroicon::Plus)
->color('primary')
->schema([
DatePicker::make('start_date')
->label('Tanggal Mulai')
->placeholder(fn () => now()->translatedFormat('l, d F Y'))
->native(false)
->displayFormat('l, d F Y')
->locale('id')
->required(),
DatePicker::make('end_date')
->label('Tanggal Seleisa')
->placeholder(fn () => now()->addDays(30)->translatedFormat('l, d F Y'))
->native(false)
->displayFormat('l, d F Y')
->required()
->after('start_date'),
TextInput::make('report_amount')
->label('Jumlah Laporan')
->placeholder(10)
->numeric()
->minValue(1)
->required(),
Textarea::make('task_description')
->label('Deskripsi Tugas')
->required()
->rows(4)
->placeholder('...'),
])
->action(function (array $data, Cooperation $record) {
$taskAssignment = $record->taskAssignments()->create([
'start_date' => $data['start_date'],
'end_date' => $data['end_date'],
'task_description' => $data['task_description'],
'report_amount' => $data['report_amount'],
]);
$partnerMedias = $record->partnerMedia()
->wherePivot('status', ApprovalStatus::ACCEPTED)
->get();
foreach ($partnerMedias as $partnerMedia) {
$taskAssignment->mediaTaskAssignments()->create([
'partner_media_id' => $partnerMedia->id,
'status' => ApprovalStatus::PENDING,
]);
}
Notification::make()
->title('Penugasan berhasil dibuat')
->success()
->send();
})
->modalHeading('Buat Penugasan')
->modalSubmitActionLabel('Simpan')
->visible(
fn (Cooperation $record): bool => ! auth()->user()->hasRole('Perusahaan')
&& ! $record->taskAssignments()->exists()
&& $record->status === CooperationStatus::ASSIGNMENT
)
->modalWidth(Width::Large),
EditAction::make()
->visible(fn () => ! auth()->user()->hasRole('Perusahaan')),
DeleteAction::make()
->visible(fn () => ! auth()->user()->hasRole('Perusahaan')),
])
->toolbarActions([
BulkActionGroup::make([
...DefaultBulkActions::make('Kerja Sama'),
]),
])
->emptyStateIcon(Heroicon::HandRaised)
->emptyStateDescription('Setelah Anda membuat data pertama, maka akan muncul disini.')
->defaultSort('created_at', 'desc')
->deferFilters(false);
}
}