158 lines
6.5 KiB
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,
|
|
]);
|
|
}
|
|
}
|