Files
supplier-dashboard/src/app/Http/Controllers/DashboardController.php

158 lines
6.5 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
class DashboardController extends Controller
{
public function index()
{
return view('dashboard');
}
public function summary(): JsonResponse
{
$totalSuppliers = DB::table('PL_SUPPLIERACCOUNT')->count();
$totalProducts = DB::table('STK_STOCKITEM')->where('ISACTVE', 'Y')->count();
$totalCustomers = DB::table('SL_CUSTOMERACCOUNT')->count();
$purchaseSpend = DB::table('PL_BILLTRAN')
->selectRaw('COALESCE(SUM(QTYTOINVOICE * COSTPRICE / COSTPRICEPER), 0) as total')
->value('total');
$salesRevenue = DB::table('SL_SALESINVOICETRAN')
->selectRaw('COALESCE(SUM(QTYTOINVOICE * SELLINGPRICE / SELLINGPRICEPER), 0) as total')
->value('total');
$salesCost = DB::table('SL_SALESINVOICETRAN')
->selectRaw('COALESCE(SUM(QTYTOINVOICE * COSTPRICE / COSTPRICEPER), 0) as total')
->value('total');
$grossProfit = $salesRevenue - $salesCost;
$margin = $salesRevenue > 0 ? round(($grossProfit / $salesRevenue) * 100, 1) : 0;
$totalInvoices = DB::table('PL_BILL')->count();
return response()->json([
'total_suppliers' => $totalSuppliers,
'total_products' => $totalProducts,
'total_customers' => $totalCustomers,
'purchase_spend' => round($purchaseSpend, 2),
'sales_revenue' => round($salesRevenue, 2),
'gross_profit' => round($grossProfit, 2),
'margin_percent' => $margin,
'total_invoices' => $totalInvoices,
]);
}
public function topSuppliers(): JsonResponse
{
$suppliers = DB::table('PL_BILLTRAN as il')
->join('PL_BILL as i', 'il.REFNO', '=', 'i.REFNO')
->selectRaw('i.ACCNO as code, i.SUPLNME as name, COUNT(DISTINCT i.REFNO) as invoice_count, SUM(il.QTYTOINVOICE * il.COSTPRICE / il.COSTPRICEPER) as total_spend, SUM(il.QTYTOINVOICE) as total_qty')
->groupBy('i.ACCNO', 'i.SUPLNME')
->orderByDesc('total_spend')
->limit(10)
->get();
return response()->json($suppliers);
}
public function topProducts(): JsonResponse
{
$products = DB::table('SL_SALESINVOICETRAN as sl')
->join('STK_STOCKITEM as p', 'sl.STOCKCODE', '=', 'p.STOCKCODE')
->selectRaw('sl.STOCKCODE as code, p.DESCRIPTION as name, SUM(sl.QTYTOINVOICE) as total_qty_sold, SUM(sl.QTYTOINVOICE * sl.SELLINGPRICE / sl.SELLINGPRICEPER) as total_revenue, SUM(sl.QTYTOINVOICE * sl.COSTPRICE / sl.COSTPRICEPER) as total_cost')
->groupBy('sl.STOCKCODE', 'p.DESCRIPTION')
->orderByDesc('total_revenue')
->limit(10)
->get()
->map(function ($item) {
$item->margin = $item->total_revenue > 0
? round((($item->total_revenue - $item->total_cost) / $item->total_revenue) * 100, 1)
: 0;
return $item;
});
return response()->json($products);
}
public function spendOverTime(): JsonResponse
{
$data = DB::table('PL_BILLTRAN as il')
->join('PL_BILL as i', 'il.REFNO', '=', 'i.REFNO')
->selectRaw("DATE_FORMAT(i.DOCDTETME, '%Y-%m') as month, SUM(il.QTYTOINVOICE * il.COSTPRICE / il.COSTPRICEPER) as total_spend")
->whereNotNull('i.DOCDTETME')
->groupByRaw("DATE_FORMAT(i.DOCDTETME, '%Y-%m')")
->orderBy('month')
->get();
return response()->json($data);
}
public function salesOverTime(): JsonResponse
{
$data = DB::table('SL_SALESINVOICETRAN as sl')
->join('SL_SALESINVOICE as si', 'sl.REFNO', '=', 'si.REFNO')
->selectRaw("DATE_FORMAT(si.DOCDTETME, '%Y-%m') as month, SUM(sl.QTYTOINVOICE * sl.SELLINGPRICE / sl.SELLINGPRICEPER) as total_revenue, SUM(sl.QTYTOINVOICE * sl.COSTPRICE / sl.COSTPRICEPER) as total_cost")
->whereNotNull('si.DOCDTETME')
->groupByRaw("DATE_FORMAT(si.DOCDTETME, '%Y-%m')")
->orderBy('month')
->get()
->map(function ($item) {
$item->gross_profit = round($item->total_revenue - $item->total_cost, 2);
return $item;
});
return response()->json($data);
}
public function categoryBreakdown(): JsonResponse
{
$data = DB::table('SL_SALESINVOICETRAN as sl')
->join('STK_STOCKITEM as p', 'sl.STOCKCODE', '=', 'p.STOCKCODE')
->leftJoin('STK_STOCKCATEGORY as c', 'p.CATEGORY', '=', 'c.STCKCTGRYCDE')
->selectRaw("COALESCE(c.STCKCTGRYDESC, 'Uncategorized') as category, SUM(sl.QTYTOINVOICE * sl.SELLINGPRICE / sl.SELLINGPRICEPER) as revenue, SUM(sl.QTYTOINVOICE * sl.COSTPRICE / sl.COSTPRICEPER) as cost, SUM(sl.QTYTOINVOICE) as qty")
->groupByRaw("COALESCE(c.STCKCTGRYDESC, 'Uncategorized')")
->orderByDesc('revenue')
->get();
return response()->json($data);
}
public function supplierProducts(string $supplierCode): JsonResponse
{
$products = DB::table('PL_BILLTRAN as il')
->join('PL_BILL as i', 'il.REFNO', '=', 'i.REFNO')
->join('STK_STOCKITEM as p', 'il.STOCKCODE', '=', 'p.STOCKCODE')
->where('i.ACCNO', $supplierCode)
->selectRaw('il.STOCKCODE as code, p.DESCRIPTION as name, SUM(il.QTYTOINVOICE) as total_qty, SUM(il.QTYTOINVOICE * il.COSTPRICE / il.COSTPRICEPER) as total_spend, COUNT(DISTINCT i.REFNO) as invoice_count')
->groupBy('il.STOCKCODE', 'p.DESCRIPTION')
->orderByDesc('total_spend')
->limit(20)
->get();
$timeline = DB::table('PL_BILLTRAN as il')
->join('PL_BILL as i', 'il.REFNO', '=', 'i.REFNO')
->where('i.ACCNO', $supplierCode)
->selectRaw("DATE_FORMAT(i.DOCDTETME, '%Y-%m') as month, SUM(il.QTYTOINVOICE * il.COSTPRICE / il.COSTPRICEPER) as total_spend")
->whereNotNull('i.DOCDTETME')
->groupByRaw("DATE_FORMAT(i.DOCDTETME, '%Y-%m')")
->orderBy('month')
->get();
$supplierName = DB::table('PL_SUPPLIERACCOUNT')
->where('SUPLCDE', $supplierCode)
->value('SUPLNME');
return response()->json([
'supplier_code' => $supplierCode,
'supplier_name' => $supplierName,
'products' => $products,
'timeline' => $timeline,
]);
}
}