У меня две модели InvoiceHeader
и InvoiceDetail
. InvoiceHeader имеет следующие атрибуты (среди прочего): id
, pos_id
, pos_description
и date
. InvoiceDetail имеет следующие атрибуты (среди прочего): id
, invoice_header_id
, pct
, price
. Между двумя моделями существует отношение «один ко многим».
Я хочу сгруппировать по pos_id
и date
из InvoiceHeader
и по pct
из InvoiceDetail
. И с этим я хотел бы получить сумму цены.
Из того, что я обнаружил, невозможно сгруппировать по обеим моделям одновременно, поскольку с Eloquent не выполняются фактические соединения. Итак, я решил, что могу сгруппировать по атрибуту pct
в файле InvoiceDetail
. Я делаю что-то вроде этого:
$invoices = \App\InvoiceHeader::with(['details' => function ($query) {
$query->select('pct')
->selectRaw('SUM(price) AS price')
->groupBy(['invoice_header_id', 'pct']);
}])
->whereBetween('date', ['2018-01-01', '2018-07-31'])
->select(['pos_id', 'pos_description', 'date'])
->get();
И именно здесь я застрял. Мне нужно сгруппировать по pos_id
, pos_description
по InvoiceHeader
и сгруппировать по pct
по InvoiceDetail
.
Отсюда я иду по маршруту, который я считаю не самым лучшим/простым. У меня есть коллекция Eloquent из InvoiceHeader, связанная с ее коллекцией InvoiceDetail. Я чувствую, что должен поработать над этим, но так как я не могу понять, как преобразовать его в коллекцию Laravel. Поскольку это единственное, что немного приблизило меня к тому, что я получил, я решил, что смогу с этим справиться. Однако, если у кого-то есть лучшее предложение, пожалуйста, поделитесь. А пока вот что у меня получилось.
Я делаю коллекцию Laravel из коллекции Eloquent как таковую:
$collection = collect();
foreach ($invoices as $invoice) {
foreach ($invoice->details as $detail) {
$collection->push([
'pos_id' => $invoice->pos_id,
'pos_description' => $invoice->pos_description,
'date' => $invoice->date,
'pct' => $detail->pct,
'price' => $detail->price,
]);
}
}
Это приводит меня к чему-то вроде
$collection = [
[
'pos_id' => 1,
'pos_description' => 'Somewhere',
'date' => '2018-02-28',
'pct' => 6,
'price' => 68.94
], [
'pos_id' => 1,
'pos_description' => 'Somewhere',
'date' => '2018-02-28',
'pct' => 21,
'price' => 99.99
], [
'pos_id' => 1,
'pos_description' => 'Somewhere',
'date' => '2018-02-28',
'pct' => 21,
'price' => 82.64
], [
'pos_id' => 1,
'pos_description' => 'Somewhere',
'date' => '2018-03-31',
'pct' => 21,
'price' => 431.45
]
]
Вот где я хочу получить или что-то подобное:
$newCollection = [
[
'pos_id' => 1,
'pos_description' => 'Somewhere',
'date' => '2018-02-28',
'details' => [
[
'pct' => 6,
'price' => 68.94
], [
'pct' => 21,
'price' => 182.63
]
]
], [
'pos_id' => 1,
'pos_description' => 'Somewhere',
'date' => '2018-03-31',
'details' => [
[
'pct' => 21,
'price' => 431.45
]
]
]
]
Я попробовал много функций из документов laravel, использующих each
, groupBy
, map
в коллекции. Также откуда-то взял эту ссылку. Но мне кажется, что я не могу добиться того, чего хочу. Я чувствую, что упускаю некоторые простые шаги, которые заставляют меня делать что-то слишком сложное.
Отказ от ответственности: большая часть кода основана на рабочем коде. Чтобы упростить вещи, я упростил некоторые вещи.