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, ]); } }