feat: add date range filters and enhance transaction summary display
This commit is contained in:
parent
1d866d1b94
commit
1a5ac1dd85
@ -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(
|
||||||
|
|||||||
@ -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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -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:{' '}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user