Laravel: сортировка выборки по связи и высчитываемому свойству
Я использую Laravel вместе с пакетом spatie/laravel-query-builder. У меня есть модели карты и платежа. Мне нужно сделать выборку карт, отсортировав их по сумме платежей за текущие сутки. Для этого я использую пакет spatie/laravel-query-builder, но это не так важно. По сути, это просто обёртка над билдером запроса. Чтобы понять проблему сначала нужно посмотреть на то как я пытаюсь решить задачу. Вот мои модели и сервисы:
Модель карты:
class Card extends Model {
protected $appends = [
'today_import',
];
public function payments(): HasMany
{
return $this->hasMany(
related: Payment::class,
foreignKey: 'card',
localKey: 'number');
}
public function getTodayImportAttribute(): float
{
return $this->payments()->incoming()->ofThisDay()->sum('sum');
}
}
Модель платежа
class Payment extends Model {
protected $casts = [
'sum' => 'decimal:2',
'date' => 'datetime'
];
public function scopeIncoming(Builder $query): Builder
{
return $query->where('type', 'In');
}
public function scopeOfThisDay(Builder $query): Builder
{
return $query->where('date', '>', Carbon::now()->startOfDay());
}
}
Сервис:
class ShowCardsService
{
public function __construct(protected array $data = [])
{
$this->data = Validator::validate($data, [
'cur_page' => ['required', 'integer', 'min:1'],
'per_page' => ['required', 'integer', 'min:1']
]);
}
public function execute(): LengthAwarePaginator
{
return QueryBuilder::for(
Card::class
)->allowedSorts([
AllowedSort::custom('today_import', new SortByTodayImport()),
])->paginate(
perPage: $this->data['per_page'],
page: $this->data['cur_page']
);
}
}
А ниже кастомный сортировщик, внутри которого должна быть логика сортировки
use Spatie\QueryBuilder\Sorts\Sort;
class SortByTodayImport implements Sort
{
public function __invoke(Builder $query, bool $descending, string $property)
{
// Что тут писать?
return $query;
}
}
Я совершенно не понимаю что нужно прописать в сортировщике. Пытался поставить задачу ИИ, но результата не было. Понимаю, что запрос будет тяжелым, но иного выхода я не знаю. По всей видимости, нужно делать вложенный запрос, который бы высчитывал сумму платежей, но что именно прописать мне не ведомо.