feat: add date range filters and enhance transaction summary display

This commit is contained in:
Yoga Pangestu 2026-08-06 14:41:10 +07:00
parent 1d866d1b94
commit 1a5ac1dd85
4 changed files with 39 additions and 4 deletions

View File

@ -19,7 +19,7 @@ public function __construct(
public function index(PaginatedRequest $request): Response public function index(PaginatedRequest $request): Response
{ {
$filters = $request->only(['status', 'channel', 'payment_type', 'customer_id', 'marketing_id', 'created_by_id']); $filters = $request->only(['status', 'channel', 'payment_type', 'customer_id', 'marketing_id', 'created_by_id', 'date_from', 'date_to']);
return Inertia::render('admin/manage/transaction/index', [ return Inertia::render('admin/manage/transaction/index', [
'transactions' => $this->service->paginated( 'transactions' => $this->service->paginated(

View File

@ -63,6 +63,8 @@ public function paginated(int $perPage = 25, string $search = '', string $sort =
->when($filters['customer_id'] ?? null, fn($q, $customerId) => $q->where('customer_id', $customerId)) ->when($filters['customer_id'] ?? null, fn($q, $customerId) => $q->where('customer_id', $customerId))
->when($filters['marketing_id'] ?? null, fn($q, $marketingId) => $q->where('marketing_id', $marketingId)) ->when($filters['marketing_id'] ?? null, fn($q, $marketingId) => $q->where('marketing_id', $marketingId))
->when($filters['created_by_id'] ?? null, fn($q, $createdById) => $q->where('created_by_id', $createdById)) ->when($filters['created_by_id'] ?? null, fn($q, $createdById) => $q->where('created_by_id', $createdById))
->when($filters['date_from'] ?? null, fn($q, $dateFrom) => $q->whereDate('created_at', '>=', $dateFrom))
->when($filters['date_to'] ?? null, fn($q, $dateTo) => $q->whereDate('created_at', '<=', $dateTo))
->orderBy($sort, $direction) ->orderBy($sort, $direction)
->paginate($perPage); ->paginate($perPage);
@ -94,14 +96,17 @@ public function getSummary(array $filters = []): array
$query = Order::query() $query = Order::query()
->selectRaw('COUNT(*) as total_orders') ->selectRaw('COUNT(*) as total_orders')
->selectRaw('COALESCE(SUM(subtotal), 0) as total_subtotal') ->selectRaw('COALESCE(SUM(subtotal), 0) as total_subtotal')
->selectRaw('COALESCE(SUM(discount), 0) as total_discount') ->selectRaw('COALESCE(SUM(subtotal) - SUM(COALESCE(nego_price, subtotal)), 0) as total_discount')
->selectRaw('COALESCE(SUM(total_amount), 0) as total_amount') ->selectRaw('COALESCE(SUM(total_amount), 0) as total_amount')
->selectRaw('COALESCE(SUM(cogs), 0) as total_cogs')
->when($filters['status'] ?? null, fn($q, $status) => $q->where('status', $status)) ->when($filters['status'] ?? null, fn($q, $status) => $q->where('status', $status))
->when($filters['channel'] ?? null, fn($q, $channel) => $q->where('channel', $channel)) ->when($filters['channel'] ?? null, fn($q, $channel) => $q->where('channel', $channel))
->when($filters['payment_type'] ?? null, fn($q, $paymentType) => $q->where('payment_type', $paymentType)) ->when($filters['payment_type'] ?? null, fn($q, $paymentType) => $q->where('payment_type', $paymentType))
->when($filters['customer_id'] ?? null, fn($q, $customerId) => $q->where('customer_id', $customerId)) ->when($filters['customer_id'] ?? null, fn($q, $customerId) => $q->where('customer_id', $customerId))
->when($filters['marketing_id'] ?? null, fn($q, $marketingId) => $q->where('marketing_id', $marketingId)) ->when($filters['marketing_id'] ?? null, fn($q, $marketingId) => $q->where('marketing_id', $marketingId))
->when($filters['created_by_id'] ?? null, fn($q, $createdById) => $q->where('created_by_id', $createdById)) ->when($filters['created_by_id'] ?? null, fn($q, $createdById) => $q->where('created_by_id', $createdById))
->when($filters['date_from'] ?? null, fn($q, $dateFrom) => $q->whereDate('created_at', '>=', $dateFrom))
->when($filters['date_to'] ?? null, fn($q, $dateTo) => $q->whereDate('created_at', '<=', $dateTo))
->first(); ->first();
return [ return [
@ -109,7 +114,7 @@ public function getSummary(array $filters = []): array
'total_subtotal' => $query->total_subtotal, 'total_subtotal' => $query->total_subtotal,
'total_discount' => $query->total_discount, 'total_discount' => $query->total_discount,
'total_amount' => $query->total_amount, 'total_amount' => $query->total_amount,
'net_total' => $query->total_amount, 'net_total' => $query->total_amount - $query->total_cogs,
]; ];
} }

View File

@ -1,7 +1,9 @@
import { Head, Link, router } from '@inertiajs/react'; import { Head, Link, router } from '@inertiajs/react';
import { format } from 'date-fns';
import { Plus } from 'lucide-react'; import { Plus } from 'lucide-react';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { CardTable } from '@/components/card-table'; import { CardTable } from '@/components/card-table';
import { DatePicker } from '@/components/date-picker';
import { DeleteConfirmDialog } from '@/components/delete-confirm-dialog'; import { DeleteConfirmDialog } from '@/components/delete-confirm-dialog';
import { FilterPopover } from '@/components/filter-popover'; import { FilterPopover } from '@/components/filter-popover';
import { useCardTableExpand } from '@/components/hooks/use-card-table-expand'; import { useCardTableExpand } from '@/components/hooks/use-card-table-expand';
@ -67,6 +69,8 @@ type Props = {
customer_id?: string; customer_id?: string;
marketing_id?: string; marketing_id?: string;
created_by_id?: string; created_by_id?: string;
date_from?: string;
date_to?: string;
}; };
filterOptions: { filterOptions: {
statusOptions: StatusOption[]; statusOptions: StatusOption[];
@ -154,7 +158,9 @@ export default function TransactionIndex({
Boolean(filters.payment_type) || Boolean(filters.payment_type) ||
Boolean(filters.customer_id) || Boolean(filters.customer_id) ||
Boolean(filters.marketing_id) || Boolean(filters.marketing_id) ||
Boolean(filters.created_by_id) Boolean(filters.created_by_id) ||
Boolean(filters.date_from) ||
Boolean(filters.date_to)
} }
onClear={clearFilters} onClear={clearFilters}
> >
@ -320,6 +326,22 @@ export default function TransactionIndex({
</ComboboxContent> </ComboboxContent>
</Combobox> </Combobox>
</div> </div>
<div className="flex flex-col gap-2">
<label className="text-xs text-muted-foreground">Dari Tanggal</label>
<DatePicker
value={filters.date_from ?? null}
onChange={(date) => applyFilter('date_from', date ? format(date, 'yyyy-MM-dd') : '')}
placeholder="Pilih tanggal mulai"
/>
</div>
<div className="flex flex-col gap-2">
<label className="text-xs text-muted-foreground">Sampai Tanggal</label>
<DatePicker
value={filters.date_to ?? null}
onChange={(date) => applyFilter('date_to', date ? format(date, 'yyyy-MM-dd') : '')}
placeholder="Pilih tanggal akhir"
/>
</div>
</FilterPopover> </FilterPopover>
); );

View File

@ -152,6 +152,14 @@ export function TransactionCardRow({
{formatCurrency(transaction.discount)} {formatCurrency(transaction.discount)}
</span> </span>
)} )}
{transaction.nego_price != null && transaction.nego_price > 0 && (
<span>
<span className="text-muted-foreground">
Nego:{' '}
</span>
{formatCurrency(transaction.nego_price)}
</span>
)}
<span className="font-semibold"> <span className="font-semibold">
<span className="font-normal text-muted-foreground"> <span className="font-normal text-muted-foreground">
Total:{' '} Total:{' '}