feat(analysis): membuat chart
This commit is contained in:
parent
4db29ba622
commit
98995d9f5e
50
app/Livewire/Chart/ChannelRevenue.php
Normal file
50
app/Livewire/Chart/ChannelRevenue.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Chart;
|
||||||
|
|
||||||
|
use App\Enums\OrderChannel;
|
||||||
|
use App\Models\Order;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class ChannelRevenue extends Component
|
||||||
|
{
|
||||||
|
public array $channels = [];
|
||||||
|
|
||||||
|
public array $revenues = [];
|
||||||
|
|
||||||
|
public array $backgroundColors = [];
|
||||||
|
|
||||||
|
public array $borderColors = [];
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$outlets = auth()->user()->outlets()->pluck('name', 'outlets.id');
|
||||||
|
|
||||||
|
$orders = Order::select('channel', 'total')
|
||||||
|
->whereIn('outlet_id', $outlets->keys())
|
||||||
|
->get()
|
||||||
|
->groupBy('channel');
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
$count = count(OrderChannel::cases());
|
||||||
|
|
||||||
|
foreach (OrderChannel::cases() as $channel) {
|
||||||
|
$channelOrders = $orders[$channel->value] ?? collect();
|
||||||
|
$total = $channelOrders->sum('total');
|
||||||
|
|
||||||
|
$data[] = $total;
|
||||||
|
$this->channels[] = $channel->label();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->revenues = $data;
|
||||||
|
|
||||||
|
$this->backgroundColors = randomColors($count, 0.2);
|
||||||
|
$this->borderColors = randomColors($count, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.chart.channel-revenue');
|
||||||
|
}
|
||||||
|
}
|
||||||
51
app/Livewire/Chart/OutletExpense.php
Normal file
51
app/Livewire/Chart/OutletExpense.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Chart;
|
||||||
|
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\Payroll;
|
||||||
|
use App\Models\Purchase;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class OutletExpense extends Component
|
||||||
|
{
|
||||||
|
public array $outlets = [];
|
||||||
|
|
||||||
|
public array $expenses = [];
|
||||||
|
|
||||||
|
public array $backgroundColors = [];
|
||||||
|
|
||||||
|
public array $borderColors = [];
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$outlets = auth()->user()->outlets()->pluck('name', 'outlets.id');
|
||||||
|
|
||||||
|
$expensesData = [];
|
||||||
|
|
||||||
|
foreach ($outlets as $id => $name) {
|
||||||
|
$expenseTotal = Expense::where('outlet_id', $id)->sum('amount');
|
||||||
|
|
||||||
|
$purchaseTotal = Purchase::where('outlet_id', $id)->sum('total');
|
||||||
|
|
||||||
|
$payrollTotal = Payroll::whereHas('user.outlets', fn ($q) => $q->where('outlet_id', $id))->sum('total_salary');
|
||||||
|
|
||||||
|
$total = $expenseTotal + $purchaseTotal + $payrollTotal;
|
||||||
|
|
||||||
|
$expensesData[$name] = $total;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->outlets = array_keys($expensesData);
|
||||||
|
|
||||||
|
$this->expenses = array_values($expensesData);
|
||||||
|
|
||||||
|
$count = count($this->outlets);
|
||||||
|
$this->backgroundColors = randomColors($count, 0.2);
|
||||||
|
$this->borderColors = randomColors($count, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.chart.outlet-expense');
|
||||||
|
}
|
||||||
|
}
|
||||||
41
app/Livewire/Chart/OutletRevenue.php
Normal file
41
app/Livewire/Chart/OutletRevenue.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Chart;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class OutletRevenue extends Component
|
||||||
|
{
|
||||||
|
public array $outlets = [];
|
||||||
|
|
||||||
|
public array $revenues = [];
|
||||||
|
|
||||||
|
public array $backgroundColors = [];
|
||||||
|
|
||||||
|
public array $borderColors = [];
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$outlets = auth()->user()->outlets()->pluck('name', 'outlets.id');
|
||||||
|
|
||||||
|
$revenues = DB::table('orders')
|
||||||
|
->select('outlet_id', DB::raw('SUM(total) as total_revenue'))
|
||||||
|
->whereIn('outlet_id', $outlets->keys())
|
||||||
|
->groupBy('outlet_id')
|
||||||
|
->pluck('total_revenue', 'outlet_id');
|
||||||
|
|
||||||
|
$this->outlets = $outlets->values()->toArray();
|
||||||
|
|
||||||
|
$this->revenues = $outlets->map(fn ($name, $id) => $revenues[$id] ?? 0)->values()->toArray();
|
||||||
|
|
||||||
|
$count = count($this->outlets);
|
||||||
|
$this->backgroundColors = randomColors($count, 0.2);
|
||||||
|
$this->borderColors = randomColors($count, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.chart.outlet-revenue');
|
||||||
|
}
|
||||||
|
}
|
||||||
48
app/Livewire/Chart/OutletRevenueExpense.php
Normal file
48
app/Livewire/Chart/OutletRevenueExpense.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Chart;
|
||||||
|
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\Order;
|
||||||
|
use App\Models\Payroll;
|
||||||
|
use App\Models\Purchase;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class OutletRevenueExpense extends Component
|
||||||
|
{
|
||||||
|
public array $outlets = [];
|
||||||
|
|
||||||
|
public array $revenues = [];
|
||||||
|
|
||||||
|
public array $expenses = [];
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$outlets = auth()->user()->outlets()->pluck('name', 'outlets.id');
|
||||||
|
|
||||||
|
$revenueData = [];
|
||||||
|
|
||||||
|
$expenseData = [];
|
||||||
|
|
||||||
|
foreach ($outlets as $id => $name) {
|
||||||
|
$totalRevenue = Order::where('outlet_id', $id)->sum('total');
|
||||||
|
$revenueData[$name] = $totalRevenue;
|
||||||
|
|
||||||
|
$expenseTotal = Expense::where('outlet_id', $id)->sum('amount');
|
||||||
|
$purchaseTotal = Purchase::where('outlet_id', $id)->sum('total');
|
||||||
|
$payrollTotal = Payroll::whereHas('user.outlets', fn ($q) => $q->where('outlet_id', $id))->sum('total_salary');
|
||||||
|
$expenseData[$name] = $expenseTotal + $purchaseTotal + $payrollTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->outlets = $outlets->values()->toArray();
|
||||||
|
|
||||||
|
$this->revenues = array_values($revenueData);
|
||||||
|
|
||||||
|
$this->expenses = array_values($expenseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.chart.outlet-revenue-expense');
|
||||||
|
}
|
||||||
|
}
|
||||||
32
resources/views/livewire/chart/channel-revenue.blade.php
Normal file
32
resources/views/livewire/chart/channel-revenue.blade.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<div>
|
||||||
|
<h3>Pendapatan per Channel</h3>
|
||||||
|
<flux:card class="mb-6 mt-2 bg-zinc-200 dark:bg-zinc-700">
|
||||||
|
<canvas id="channelRevenueChart" width="400" height="200"></canvas>
|
||||||
|
</flux:card>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('livewire:navigated', function() {
|
||||||
|
var ctx = document.getElementById('channelRevenueChart').getContext('2d');
|
||||||
|
var channelRevenueChart = new Chart(ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: @json($channels),
|
||||||
|
datasets: [{
|
||||||
|
label: 'Rp',
|
||||||
|
data: @json($revenues),
|
||||||
|
backgroundColor: @json($backgroundColors),
|
||||||
|
borderColor: @json($borderColors),
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
28
resources/views/livewire/chart/outlet-expense.blade.php
Normal file
28
resources/views/livewire/chart/outlet-expense.blade.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<div>
|
||||||
|
<h3>Pengeluaran per Outlet</h3>
|
||||||
|
<flux:card class="mb-6 mt-2 bg-zinc-200 dark:bg-zinc-700">
|
||||||
|
<canvas id="outletExpenseChart" width="400" height="200"></canvas>
|
||||||
|
</flux:card>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('livewire:navigated', function() {
|
||||||
|
var ctx = document.getElementById('outletExpenseChart').getContext('2d');
|
||||||
|
var outletExpenseChart = new Chart(ctx, {
|
||||||
|
type: 'polarArea',
|
||||||
|
data: {
|
||||||
|
labels: @json($outlets),
|
||||||
|
datasets: [{
|
||||||
|
data: @json($expenses),
|
||||||
|
backgroundColor: @json($backgroundColors),
|
||||||
|
borderColor: @json($borderColors),
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<div>
|
||||||
|
<h3>Pengeluaran per Outlet</h3>
|
||||||
|
<flux:card class="mb-6 mt-2 bg-zinc-200 dark:bg-zinc-700">
|
||||||
|
<canvas id="outletRevenueExpenseChart" width="400" height="200"></canvas>
|
||||||
|
</flux:card>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('livewire:navigated', function() {
|
||||||
|
var ctx = document.getElementById('outletRevenueExpenseChart').getContext('2d');
|
||||||
|
var outletRevenueExpenseChart = new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: @json($outlets),
|
||||||
|
datasets: [{
|
||||||
|
label: 'Pendapatan',
|
||||||
|
data: @json($revenues),
|
||||||
|
backgroundColor: 'rgba(75, 192, 192, 0.5)',
|
||||||
|
borderColor: 'rgba(0, 128, 0, 1)',
|
||||||
|
borderWidth: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Pengeluaran',
|
||||||
|
data: @json($expenses),
|
||||||
|
backgroundColor: 'rgba(255, 99, 132, 0.5)',
|
||||||
|
borderColor: 'rgba(255, 0, 0, 1)',
|
||||||
|
borderWidth: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
29
resources/views/livewire/chart/outlet-revenue.blade.php
Normal file
29
resources/views/livewire/chart/outlet-revenue.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<div>
|
||||||
|
<h3>Pendapatan per Outlet</h3>
|
||||||
|
<flux:card class="mb-6 mt-2 bg-zinc-200 dark:bg-zinc-700">
|
||||||
|
<canvas id="outletRevenueChart" width="400" height="200"></canvas>
|
||||||
|
</flux:card>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('livewire:navigated', function() {
|
||||||
|
var ctx = document.getElementById('outletRevenueChart').getContext('2d');
|
||||||
|
var outletRevenueChart = new Chart(ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: @json($outlets),
|
||||||
|
datasets: [{
|
||||||
|
label: 'Rp',
|
||||||
|
data: @json($revenues),
|
||||||
|
backgroundColor: @json($backgroundColors),
|
||||||
|
borderColor: @json($borderColors),
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
@ -125,5 +125,12 @@
|
|||||||
</flux:card>
|
</flux:card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6 mt-2">
|
||||||
|
<livewire:chart.outlet-revenue />
|
||||||
|
<livewire:chart.outlet-expense />
|
||||||
|
<livewire:chart.channel-revenue />
|
||||||
|
</div>
|
||||||
|
<livewire:chart.outlet-revenue-expense />
|
||||||
</div>
|
</div>
|
||||||
</flux:main>
|
</flux:main>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user