F
Filament5mo ago
kool

Export a resource model with a HasMany relation

I have order resource that I need to export order with its items (each order has a number of items). So how can I use/customize ExportAction in order to achieve that detailed export Example: given 4 orders with two items each has 2 so a total of 8 records to be exported
4 Replies
prnl.
prnl.4w ago
I'm looking for the same export functionality, would be nice to be able to export the OrderItems along with the Orders. Either in one sheet or in one CSV or 1 xlsx with 2 sheets, one sheet for the Orders and one sheet for the OrderItems. I've tried various possible solutions with "modifyQuery", the best result I got is one record for an Order and the OrderLine.columns were comma separated into a single column. @kool maybe change the word HadsMany to HasMany in the subject, so people can better find this question.
kool
kool4w ago
That's an approach. There are two other ways - Filament Way: Change the export model to OrderItem so you can have multiple rows same order data with different order items data - Laravel/Excel: Use custom query to load orders with items. I have achieved both and works well
prnl.
prnl.4w ago
Would you be able to share your "Filament Way"? I changed the model to OrderItem but unfortunately without a good result. Found the solution, for anyone else looking to export a HasMany, below you'll find an example of the modifyQuery method. 1) Changed the $model to the LineItem model. 2) Write your query in the modifyQuery method.
public static function modifyQuery(Builder $query): Builder
{
return \App\Models\LineItem::query()
->join('orders', 'line_items.order_id', '=', 'orders.id')
->select([
'line_items.id as id',
'orders.reference as order_reference',
'orders.status as order_status',
'line_items.sku as line_item_sku',
'line_items.quantity as line_item_quantity',
'line_items.unit_price_incl_tax as line_item_unit_price_incl_tax',
'line_items.unit_price_excl_tax as line_item_unit_price_excl_tax',
])
->mergeWheres($query->getQuery()->wheres, $query->getQuery()->bindings['where']);
}
public static function modifyQuery(Builder $query): Builder
{
return \App\Models\LineItem::query()
->join('orders', 'line_items.order_id', '=', 'orders.id')
->select([
'line_items.id as id',
'orders.reference as order_reference',
'orders.status as order_status',
'line_items.sku as line_item_sku',
'line_items.quantity as line_item_quantity',
'line_items.unit_price_incl_tax as line_item_unit_price_incl_tax',
'line_items.unit_price_excl_tax as line_item_unit_price_excl_tax',
])
->mergeWheres($query->getQuery()->wheres, $query->getQuery()->bindings['where']);
}
prnl.
prnl.4w ago
Additionally you'll also have to overwrite/extend the PrepareCsvExport class and change the following code
$baseQuery
->select([$qualifiedKeyName])
->orderedChunkById(
$chunkKeySize,
fn (Collection $records) => $dispatchRecords(
Arr::pluck($records->all(), $keyName),
),
column: $keyName,
descending: ($baseQueryOrders[0]['direction'] ?? 'asc') === 'desc',
);
$baseQuery
->select([$qualifiedKeyName])
->orderedChunkById(
$chunkKeySize,
fn (Collection $records) => $dispatchRecords(
Arr::pluck($records->all(), $keyName),
),
column: $keyName,
descending: ($baseQueryOrders[0]['direction'] ?? 'asc') === 'desc',
);
into
$baseQuery
->select([$qualifiedKeyName])
->orderedChunkById(
$chunkKeySize,
fn (Collection $records) => $dispatchRecords(
Arr::pluck($records->all(), $keyName),
),
column: $qualifiedKeyName,
alias: $keyName,
descending: ($baseQueryOrders[0]['direction'] ?? 'asc') === 'desc',
);
$baseQuery
->select([$qualifiedKeyName])
->orderedChunkById(
$chunkKeySize,
fn (Collection $records) => $dispatchRecords(
Arr::pluck($records->all(), $keyName),
),
column: $qualifiedKeyName,
alias: $keyName,
descending: ($baseQueryOrders[0]['direction'] ?? 'asc') === 'desc',
);
Than add the ->job() to your export, see https://filamentphp.com/docs/3.x/actions/prebuilt-actions/export#customizing-the-export-job