tiers = TierModel::with(['memberships.user.customer.orders.items']) ->withCount('memberships') ->orderBy('min_points', 'asc') ->get() ->map(function ($tier) { $topMembership = $tier->memberships() ->with(['user.customer.orders.items']) ->orderByDesc('tier_points') ->first(); $topMemberStats = null; if ($topMembership && $topMembership->user && $topMembership->user->customer) { $orders = $topMembership->user->customer->orders; $totalOrders = $orders->count(); // Sum items $totalPerfume = $orders->flatMap(fn ($order) => $order->items->where('orderable_type', Perfume::class))->sum('quantity'); $totalProduct = $orders->flatMap(fn ($order) => $order->items->where('orderable_type', Product::class))->sum('quantity'); $totalBottle = $orders->flatMap(fn ($order) => $order->items->where('orderable_type', Bottle::class))->sum('quantity'); // Sum total $subtotal = $orders->sum('subtotal'); $totalDiscount = $orders->sum('discount'); $grandTotal = $orders->sum('total'); $topMemberStats = [ 'name' => $topMembership->user->customer->name, 'points' => currency($topMembership->tier_points), 'total_orders' => currency($totalOrders), 'items' => [ 'total_perfume' => currency($totalPerfume), 'total_product' => currency($totalProduct), 'total_bottle' => currency($totalBottle), ], 'total' => [ 'subtotal' => currency($subtotal, 'Rp'), 'discount' => currency($totalDiscount, 'Rp'), 'grand_total' => currency($grandTotal, 'Rp'), ], ]; } return [ 'id' => $tier->id, 'hash' => $tier->hash, 'name' => $tier->name, 'min_points' => currency($tier->min_points), 'max_points' => currency($tier->max_points), 'total_members' => currency($tier->memberships_count), 'top_member' => $topMemberStats, ]; }) ->toArray(); } #[On('modal:open')] public function openModal(string $method, string $modalTitle, ?string $id = null) { $this->resetValidation(); $this->resetErrorBag(); $this->method = $method; $this->modalTitle = $modalTitle; if ($id) { $this->form->setTier(TierModel::byHashOrFail($id)); } } public function create() { $this->canOrAbort('create tier'); $tier = $this->form->store(); $tiers = $this->tiers; $tiers[] = [ 'hash' => $tier->hash, 'name' => $tier->name, 'min_points' => currency($tier->min_points, ''), 'max_points' => currency($tier->max_points, ''), 'total_members' => 0, 'top_member' => null, ]; usort($tiers, fn ($a, $b) => replaceCurrency($a['min_points']) <=> replaceCurrency($b['min_points'])); $this->tiers = $tiers; $this->toast('Tier berhasil ditambahkan.'); Flux::modals()->close(); } public function update() { $this->canOrAbort('update tier'); $tier = $this->form->update(); // update array tiers $tiers = $this->tiers; foreach ($tiers as $index => $item) { if ($item['hash'] === $tier->hash) { $tiers[$index] = [ 'hash' => $tier->hash, 'name' => $tier->name, 'min_points' => currency($tier->min_points, ''), 'max_points' => currency($tier->max_points, ''), ]; break; } } $this->tiers = $tiers; $this->toast('Tier berhasil diperbarui.'); Flux::modals()->close(); } public function delete(TierModel $tier) { $tier->delete(); // update array tiers $tiers = array_values(array_filter($this->tiers, fn ($item) => $item['hash'] !== $tier->hash)); $this->tiers = $tiers; $this->toast('Tier berhasil dihapus.'); Flux::modals()->close(); } public function render() { return view('livewire.studio.loyalty.tiers', [ 'pageTitle' => 'Tier', ]); } }