- 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.
408 lines
18 KiB
PHP
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);
|
|
}
|
|
}
|