getTable(); $orderItemsTable = (new OfflineOrderItem())->getTable(); $stores = Store::pluck('title', 'id'); $productCategories = OfflineProductCategory::pluck('name', 'id'); $builder = OfflineOrderItem::select([ "{$orderItemsTable}.product_category_id", "{$ordersTable}.store_id", DB::raw("SUM({$orderItemsTable}.points_deduction_amount) AS points_deduction_amount"), DB::raw("SUM({$orderItemsTable}.payment_amount) AS payment_amount"), ]) ->join("{$ordersTable}", "{$orderItemsTable}.order_id", '=', "{$ordersTable}.id") ->where("{$ordersTable}.status", OfflineOrderStatus::Paid) ->when($start || $end, function ($builder) use ($start, $end, $ordersTable) { if ($start && $end) { return $builder->whereBetween("{$ordersTable}.payment_time", [$start, $end]); } return $builder->when($start, fn ($builder) => $builder->where("{$ordersTable}.payment_time", '>=', $start)) ->when($end, fn ($builder) => $builder->where("{$ordersTable}.payment_time", '<=', $end)); }) ->groupBy(["{$orderItemsTable}.product_category_id", "{$ordersTable}.store_id"]); $grid = Grid::make($builder); $grid->filter(function (Grid\Filter $filter) use ($stores, $productCategories) { $filter->panel(); $filter->equal('store_id')->select($stores)->width(4); $filter->equal('product_category_id')->select($productCategories)->width(4); $filter->between('datetime')->datetime()->ignore()->width(4); }); $grid->column('product_category_id')->display(fn ($v) => $productCategories->get($v) ?: '其它'); $grid->column('store_id')->display(fn ($v) => $stores->get($v) ?: '其它'); $grid->column('products_total_amount')->display(fn ($v) => bcdiv($this->points_deduction_amount + $this->payment_amount, 100, 2)); $grid->column('points_deduction_amount')->display(fn ($v) => bcdiv($v, 100, 2)); $grid->column('payment_amount')->display(fn ($v) => bcdiv($v, 100, 2)); $grid->disablePagination(); $grid->disableFilterButton(); $grid->disableActions(); $grid->footer(function ($collection) use ($grid, $start, $end, $ordersTable, $orderItemsTable) { $query = OfflineOrderItem::select([ DB::raw("SUM({$orderItemsTable}.points_deduction_amount) AS points_deduction_amount"), DB::raw("SUM({$orderItemsTable}.payment_amount) AS payment_amount"), ]) ->join("{$ordersTable}", "{$orderItemsTable}.order_id", '=', "{$ordersTable}.id") ->where("{$ordersTable}.status", OfflineOrderStatus::Paid) ->when($start || $end, function ($builder) use ($start, $end, $ordersTable) { if ($start && $end) { return $builder->whereBetween("{$ordersTable}.payment_time", [$start, $end]); } return $builder->when($start, fn ($builder) => $builder->where("{$ordersTable}.payment_time", '>=', $start)) ->when($end, fn ($builder) => $builder->where("{$ordersTable}.payment_time", '<=', $end)); }); $grid->model()->getQueries()->unique()->each(function ($value) use (&$query) { if (in_array($value['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) { return; } $query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []); }); $results = $query->first(); // $onlineOrdersCount = $results['orders_count'] ?? 0; $pointsDeductionAmount = bcdiv($results['points_deduction_amount'] ?? 0, 100, 2); $paymentAmount = bcdiv($results['payment_amount'] ?? 0, 100, 2); $totalAmount = bcadd($pointsDeductionAmount, $paymentAmount, 2); return <<