refactor: migrate to HasManyDeep for cooperation reports and standardize query filtering across relation managers

This commit is contained in:
Yoga Pangestu 2026-04-10 13:12:50 +07:00
parent 1977d08339
commit a03f3e3a7b
7 changed files with 153 additions and 45 deletions

View File

@ -27,7 +27,8 @@ protected function getHeaderActions(): array
CooperationExcelExport::make(),
])
->color('success')
->icon(null),
->icon(null)
->visible(! auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
];
}
}

View File

@ -60,14 +60,13 @@ public function table(Table $table): Table
->emptyStateIcon(Heroicon::OutlinedCreditCard)
->emptyStateHeading(fn () => CheerfulNotification::getByKey('cooperation.payment_empty_heading'))
->emptyStateDescription(fn () => CheerfulNotification::getByKey('cooperation.payment_empty'))
->defaultSort('created_at', 'desc');
}
public function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->whereHas('cooperationMedia.partnerMedia.company', function (Builder $query): void {
$query->where('user_id', auth()->id());
->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());
});
});
});
}
}

View File

@ -111,7 +111,14 @@ public function table(Table $table): Table
->emptyStateIcon(Heroicon::OutlinedDocumentText)
->emptyStateHeading(fn () => CheerfulNotification::getByKey('cooperation.proposal_empty_heading'))
->emptyStateDescription(fn () => CheerfulNotification::getByKey('cooperation.proposal_empty'))
->defaultSort('created_at', 'desc');
->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());
});
});
});
}
public function infolist(Schema $infolist): Schema
@ -161,14 +168,4 @@ public function infolist(Schema $infolist): Schema
])
->columns(1);
}
public function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $query): void {
$query->whereHas('partnerMedia.company', function (Builder $q): void {
$q->where('user_id', auth()->id());
});
});
}
}

View File

@ -55,15 +55,15 @@ public static function canViewForRecord(Model $ownerRecord, string $pageClass):
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{
$query = $ownerRecord->reports();
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)) {
return $ownerRecord->reports()
->whereHas('mediaTaskAssignment.partnerMedia.company', function ($q) {
$q->where('user_id', auth()->id());
})
->count();
$query->whereHas('mediaTaskAssignment.partnerMedia.company', function ($q) {
$q->where('user_id', auth()->id());
});
}
return $ownerRecord->reports()->count();
return (string) $query->count();
}
public function form(Schema $schema): Schema
@ -155,6 +155,9 @@ public function table(Table $table): Table
->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;
@ -221,15 +224,12 @@ public function table(Table $table): Table
->emptyStateIcon(Heroicon::OutlinedInboxArrowDown)
->emptyStateHeading(fn () => CheerfulNotification::getByKey('cooperation.report_empty_heading'))
->emptyStateDescription(fn () => CheerfulNotification::getByKey('cooperation.report_empty'))
->defaultSort('created_at', 'desc');
}
public function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $query): void {
$query->whereHas('mediaTaskAssignment.partnerMedia.company', function (Builder $q): void {
$q->where('user_id', auth()->id());
->defaultSort('created_at', 'desc')
->modifyQueryUsing(function (Builder $query): void {
$query->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $query): void {
$query->whereHas('mediaTaskAssignment.partnerMedia.company', function (Builder $q): void {
$q->where('user_id', auth()->id());
});
});
});
}

View File

@ -14,11 +14,13 @@
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
use Swindon\FilamentHashids\Traits\HasHashid;
class Cooperation extends Model implements HasMedia
{
use HasFactory, HasHashid, InteractsWithMedia, SoftDeletes;
use HasFactory, HasHashid, HasRelationships, InteractsWithMedia, SoftDeletes;
protected $guarded = ['id'];
@ -92,13 +94,13 @@ public function proposal(): HasMany
return $this->hasMany(CooperationProposal::class);
}
public function reports(): HasManyThrough
public function reports(): HasManyDeep
{
return $this->hasManyThrough(
return $this->hasManyDeep(
Report::class,
MediaTaskAssignment::class,
'task_assignment_id',
'media_task_assignment_id'
[TaskAssignment::class, MediaTaskAssignment::class],
['cooperation_id', 'task_assignment_id', 'media_task_assignment_id'],
['id', 'id', 'id']
);
}

View File

@ -26,6 +26,7 @@
"spatie/laravel-settings": "^3.6",
"spatie/laravel-sluggable": "^3.7",
"spatie/laravel-tags": "^4.10",
"staudenmeir/eloquent-has-many-deep": "^1.21",
"swindon/filament-hashids": "^1.0",
"swisnl/filament-backgrounds": "^2.0",
"symfony/css-selector": "^7.4",

116
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "658bd2d05451d69b51335e1dc205775e",
"content-hash": "56c24787e6cbc418cfa67149242373d2",
"packages": [
{
"name": "achyutn/filament-log-viewer",
@ -8102,6 +8102,114 @@
],
"time": "2026-01-12T07:42:22+00:00"
},
{
"name": "staudenmeir/eloquent-has-many-deep",
"version": "v1.21.3",
"source": {
"type": "git",
"url": "https://github.com/staudenmeir/eloquent-has-many-deep.git",
"reference": "627986482120e1d5787167bdeb953afa0835bc5d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/staudenmeir/eloquent-has-many-deep/zipball/627986482120e1d5787167bdeb953afa0835bc5d",
"reference": "627986482120e1d5787167bdeb953afa0835bc5d",
"shasum": ""
},
"require": {
"illuminate/database": "^12.0",
"php": "^8.2",
"staudenmeir/eloquent-has-many-deep-contracts": "^1.3"
},
"require-dev": {
"awobaz/compoships": "^2.3",
"barryvdh/laravel-ide-helper": "^3.0",
"korridor/laravel-has-many-merged": "^1.2",
"larastan/larastan": "^3.0",
"laravel/framework": "^12.0",
"mockery/mockery": "^1.6",
"orchestra/testbench-core": "^10.0",
"phpunit/phpunit": "^11.0",
"staudenmeir/eloquent-json-relations": "^1.14",
"staudenmeir/laravel-adjacency-list": "^1.24"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Staudenmeir\\EloquentHasManyDeep\\IdeHelperServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Staudenmeir\\EloquentHasManyDeep\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonas Staudenmeir",
"email": "mail@jonas-staudenmeir.de"
}
],
"description": "Laravel Eloquent HasManyThrough relationships with unlimited levels",
"support": {
"issues": "https://github.com/staudenmeir/eloquent-has-many-deep/issues",
"source": "https://github.com/staudenmeir/eloquent-has-many-deep/tree/v1.21.3"
},
"funding": [
{
"url": "https://paypal.me/JonasStaudenmeir",
"type": "custom"
}
],
"time": "2026-03-14T10:49:35+00:00"
},
{
"name": "staudenmeir/eloquent-has-many-deep-contracts",
"version": "v1.3",
"source": {
"type": "git",
"url": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts.git",
"reference": "37ce351e4db919b3af606bc8ca0e62e2e4939cde"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/staudenmeir/eloquent-has-many-deep-contracts/zipball/37ce351e4db919b3af606bc8ca0e62e2e4939cde",
"reference": "37ce351e4db919b3af606bc8ca0e62e2e4939cde",
"shasum": ""
},
"require": {
"illuminate/database": "^12.0",
"php": "^8.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Staudenmeir\\EloquentHasManyDeepContracts\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonas Staudenmeir",
"email": "mail@jonas-staudenmeir.de"
}
],
"description": "Contracts for staudenmeir/eloquent-has-many-deep",
"support": {
"issues": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts/issues",
"source": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts/tree/v1.3"
},
"time": "2025-02-15T17:11:01+00:00"
},
{
"name": "swindon/filament-hashids",
"version": "v1.0.0",
@ -15396,12 +15504,12 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^8.2"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
"platform-dev": {},
"plugin-api-version": "2.9.0"
}