Search code examples
laravellaravel-nova

Laravel Nova Value Metric For Later Days


Laravel Nova suggests Value Metrics and the ranges are for previous days until today. It is okay while we are using created_at as the default date column to show the result.
But, sometimes we need to show the result based on a date column that is able to contain a value for later days. For example, we may need to calculate the sum amount of a resource based on its settlement_date which might be tomorrow.

    /**
     * Calculate the value of the metric.
     *
     * @param NovaRequest $request
     * @return mixed
     */
    public function calculate(NovaRequest $request)
    {
        return $this->sum(
            $request,
            Settlement::where('status', 'PENDING'), 'amount', 'settlement_date')->format('0,0');
    }

    /**
     * Get the ranges available for the metric.
     *
     * @return array
     */
    public function ranges()
    {
        return [
            'TODAY' => 'Today',
            7 => 'Week',
            30 => '30 Days',
            60 => '60 Days',
            365 => '365 Days',
        ];
    }

WHAT IF, I want to know the value of this query for the later days like tomorrow. Something like this query does not work, any idea?

return $this->sum(
            $request,
            Settlement::where('status', 'PENDING')->where('settlement_date', Carbon::tomorrow()), 'amount', 'settlement_date')->format('0,0');

Solution

  • I solved it using Trends Metric, like this:

        /**
         * Calculate the value of the metric.
         *
         * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
         * @return mixed
         */
        public function calculate(NovaRequest $request)
        {
            $settlement  = new \App\Models\VmsSettlement\Settlement;
    
            $twoDaysAgoSum      = $settlement->where('status', 'PENDING')->where('settlement_date', Carbon::today()->subDays(2)->toDateString())->sum('amount');
            $yesterdaySum       = $settlement->where('status', 'PENDING')->where('settlement_date', Carbon::today()->subDay()->toDateString())->sum('amount');
            $todaySum           = $settlement->where('status', 'PENDING')->where('settlement_date', Carbon::today()->toDateString())->sum('amount');
            $tomorrowSum        = $settlement->where('status', 'PENDING')->where('settlement_date', Carbon::today()->addDay()->toDateString())->sum('amount');
            $twoDaysLaterSum    = $settlement->where('status', 'PENDING')->where('settlement_date', Carbon::today()->addDays(2)->toDateString())->sum('amount');
    
            return (new TrendResult)->trend([
                 Carbon::today()->subDays(2)->toDateString() . ' (2 days ago)'   => $twoDaysAgoSum,
                 Carbon::today()->subDay()->toDateString() . ' (Yesterday)'            => $yesterdaySum,
                 Carbon::today()->toDateString() . ' (Today)'                          => $todaySum,
                 Carbon::today()->addDay()->toDateString() . ' (Tomorrow)'             => $tomorrowSum,
                 Carbon::today()->addDays(2)->toDateString() . ' (2 days later)' => $twoDaysLaterSum,
            ])->format('0,0');
        }
    
        /**
         * Get the ranges available for the metric.
         *
         * @return array
         */
        public function ranges()
        {
            return [
                //30 => '30 Days',
                //60 => '60 Days',
                //90 => '90 Days',
            ];
        }