add DashboardService for statistics calculation and update beranda view with stat cards
This commit is contained in:
parent
7acaf897c2
commit
50cf6ace25
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\{TransaksiBuket, BookingFoto};
|
||||
use Carbon\Carbon;
|
||||
|
||||
class DashboardService
|
||||
{
|
||||
public static function getStats()
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$prev = Carbon::now()->subMonth();
|
||||
|
||||
$curr = self::calculate($now);
|
||||
$past = self::calculate($prev);
|
||||
|
||||
return [
|
||||
'pendapatan' => $curr['income'],
|
||||
'pendapatan_grow' => self::growth($curr['income'], $past['income']),
|
||||
'masuk_count' => $curr['total'],
|
||||
'masuk_grow' => self::growth($curr['total'], $past['total']),
|
||||
'selesai_count' => $curr['done'],
|
||||
'selesai_grow' => self::growth($curr['done'], $past['done']),
|
||||
'batal_count' => $curr['cancel'],
|
||||
'batal_grow' => self::growth($curr['cancel'], $past['cancel']),
|
||||
];
|
||||
}
|
||||
|
||||
private static function calculate($date)
|
||||
{
|
||||
$m = $date->month;
|
||||
$y = $date->year;
|
||||
|
||||
// Gabungan query Buket & Foto
|
||||
return [
|
||||
'income' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_transaksi', 'diterima')->sum('total_bayar') +
|
||||
BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_booking', 'diterima')->sum('total_bayar'),
|
||||
'total' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->count() +
|
||||
BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->count(),
|
||||
'done' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_transaksi', 'selesai')->count() +
|
||||
BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_booking', 'selesai')->count(),
|
||||
'cancel' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_transaksi', 'ditolak')->count() +
|
||||
BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_booking', 'ditolak')->count(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function growth($current, $previous)
|
||||
{
|
||||
if ($previous <= 0) return $current > 0 ? 100 : 0;
|
||||
return round((($current - $previous) / $previous) * 100, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,115 +20,39 @@
|
|||
@endif
|
||||
<section class="row gy-3">
|
||||
<div class="col-12">
|
||||
<div class="row gx-3">
|
||||
@if (Auth::user()->role === 'pemilik')
|
||||
<div class="col-6 col-lg-3 col-md-6">
|
||||
<div class="card mb-0">
|
||||
<div class="card-body px-3 py-4">
|
||||
<div class="stat-header">
|
||||
<h6 class="stat-label">Pendapatan Bulan Ini</h6>
|
||||
<i class="bi bi-info-circle menu-dots" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="Total pendapatan dari pesanan buket dan foto dalam bulan ini"></i>
|
||||
</div>
|
||||
<div class="stat-body">
|
||||
<div class="stat-icon">
|
||||
<i class="bi bi-bank"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="stat-count">Rp {{ number_format($stat['pendapatan'], 0, ',', '.') }}</h6>
|
||||
<span
|
||||
class="stat-percent {{ $stat['pendapatan_grow'] >= 0 ? 'text-success' : 'text-danger' }} fw-bold">
|
||||
<i
|
||||
class="bi {{ $stat['pendapatan_grow'] >= 0 ? 'bi-arrow-up' : 'bi-arrow-down' }}"></i>
|
||||
{{ abs($stat['pendapatan_grow']) }}%
|
||||
</span>
|
||||
<small class="stat-month">dari bulan lalu</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-6 col-lg-3 col-md-6">
|
||||
<div class="card mb-0">
|
||||
<div class="card-body px-3 py-4">
|
||||
<div class="stat-header">
|
||||
<h6 class="stat-label">Total Pesanan Masuk</h6>
|
||||
<i class="bi bi-info-circle menu-dots" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="Total pesanan buket dan foto yang masuk dalam bulan ini"></i>
|
||||
</div>
|
||||
<div class="stat-body">
|
||||
<div class="stat-icon">
|
||||
<i class="bi bi-cart-fill"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="stat-count">{{ $stat['masuk_count'] }} Pesanan</h6>
|
||||
<span
|
||||
class="stat-percent {{ $stat['masuk_grow'] >= 0 ? 'text-success' : 'text-danger' }} fw-bold">
|
||||
<i
|
||||
class="bi {{ $stat['masuk_grow'] >= 0 ? 'bi-arrow-up' : 'bi-arrow-down' }}"></i>
|
||||
{{ abs($stat['masuk_grow']) }}%
|
||||
</span>
|
||||
<small class="stat-month">dari bulan lalu</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3 col-md-6">
|
||||
<div class="card mb-0">
|
||||
<div class="card-body px-3 py-4">
|
||||
<div class="stat-header">
|
||||
<h6 class="stat-label">Pesanan Selesai</h6>
|
||||
<i class="bi bi-info-circle menu-dots" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="Total pesanan buket dan foto yang selesai dalam bulan ini"></i>
|
||||
</div>
|
||||
<div class="stat-body">
|
||||
<div class="stat-icon">
|
||||
<i class="bi bi-cart-check-fill"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="stat-count">{{ $stat['selesai_count'] }} Pesanan</h6>
|
||||
<span
|
||||
class="stat-percent {{ $stat['selesai_grow'] >= 0 ? 'text-success' : 'text-danger' }} fw-bold">
|
||||
<i
|
||||
class="bi {{ $stat['selesai_grow'] >= 0 ? 'bi-arrow-up' : 'bi-arrow-down' }}"></i>{{ abs($stat['selesai_grow']) }}%
|
||||
</span>
|
||||
<small class="stat-month">dari bulan lalu</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3 col-md-6">
|
||||
<div class="card mb-0">
|
||||
<div class="card-body px-3 py-4">
|
||||
<div class="stat-header">
|
||||
<h6 class="stat-label">Pesanan Ditolak</h6>
|
||||
<i class="bi bi-info-circle menu-dots" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="Total pesanan buket dan foto yang ditolak dalam bulan ini"></i>
|
||||
</div>
|
||||
<div class="stat-body">
|
||||
<div class="stat-icon">
|
||||
<i class="bi bi-cart-x-fill"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="stat-count">{{ $stat['batal_count'] }} Pesanan</h6>
|
||||
<span
|
||||
class="stat-percent {{ $stat['batal_grow'] <= 0 ? 'text-success' : 'text-danger' }} fw-bold">
|
||||
<i
|
||||
class="bi {{ $stat['batal_grow'] >= 0 ? 'bi-arrow-up' : 'bi-arrow-down' }}"></i>
|
||||
{{ abs($stat['batal_grow']) }}%
|
||||
</span>
|
||||
<small class="stat-month">dari bulan lalu</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if (Auth::user()->role === 'pemilik')
|
||||
<div class="row">
|
||||
@include('admin.components._stat_card', [
|
||||
'label' => 'Pendapatan',
|
||||
'icon' => 'bi-bank',
|
||||
'value' => 'Rp ' . number_format($stat['pendapatan'], 0, ',', '.'),
|
||||
'grow' => $stat['pendapatan_grow'],
|
||||
'tooltip' => 'Total pendapatan dari pesanan buket dan foto bulan ini',
|
||||
])
|
||||
@include('admin.components._stat_card', [
|
||||
'label' => 'Pesanan Masuk',
|
||||
'icon' => 'bi-cart-fill',
|
||||
'value' => $stat['masuk_count'] . ' Pesanan',
|
||||
'grow' => $stat['masuk_grow'],
|
||||
'tooltip' => 'Total pesanan buket dan foto yang masuk bulan ini',
|
||||
])
|
||||
@include('admin.components._stat_card', [
|
||||
'label' => 'Pesanan Selesai',
|
||||
'icon' => 'bi-cart-check-fill',
|
||||
'value' => $stat['selesai_count'] . ' Pesanan',
|
||||
'grow' => $stat['selesai_grow'],
|
||||
'tooltip' => 'Total pesanan buket dan foto yang selesai bulan ini',
|
||||
])
|
||||
@include('admin.components._stat_card', [
|
||||
'label' => 'Pesanan Ditolak',
|
||||
'icon' => 'bi-cart-x-fill',
|
||||
'value' => $stat['batal_count'] . ' Pesanan',
|
||||
'grow' => $stat['batal_grow'],
|
||||
'tooltip' => 'Total pesanan buket dan foto yang ditolak bulan ini',
|
||||
'is_negative_metric' => true,
|
||||
])
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="row gx-3">
|
||||
|
|
@ -201,8 +125,7 @@ class="bi {{ $stat['batal_grow'] >= 0 ? 'bi-arrow-up' : 'bi-arrow-down' }}"></i>
|
|||
<td>{{ $p->paketFoto->nama }}</td>
|
||||
<td class="col-auto">
|
||||
<a href="#" class="btn icon btn-primary btn-action"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#foto{{ $p->id_booking }}">
|
||||
data-bs-toggle="modal" data-bs-target="#foto{{ $p->id_booking }}">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
|
@ -229,8 +152,7 @@ class="bi {{ $stat['batal_grow'] >= 0 ? 'bi-arrow-up' : 'bi-arrow-down' }}"></i>
|
|||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="nav nav-pills nav-fill mb-4" id="v-pills-tab" role="tablist"
|
||||
aria-orientation="horizontal">
|
||||
<div class="nav nav-pills nav-fill mb-4" id="v-pills-tab" role="tablist" aria-orientation="horizontal">
|
||||
<a class="nav-link active" id="v-pills-home-tab" data-bs-toggle="pill" href="#v-pills-home"
|
||||
role="tab" aria-controls="v-pills-home" aria-selected="true">
|
||||
Buket
|
||||
|
|
|
|||
Loading…
Reference in New Issue