akuntansi-sia/routes/web.php

210 lines
9.7 KiB
PHP

<?php
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Sale;
use App\Models\Product;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\StockController;
use Illuminate\Support\Facades\Auth;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
*/
Route::get('/', function () {
$top = Sale::select('product_id', DB::raw('SUM(quantity) as total'))
->groupBy('product_id')
->orderByDesc('total')
->limit(3)
->get();
$productIds = $top->pluck('product_id')->toArray();
$products = Product::whereIn('id', $productIds)->get()->keyBy('id');
$topProducts = collect();
foreach ($productIds as $id) {
$product = $products->get($id);
if ($product) {
$product->total_sold = $top->firstWhere('product_id', $id)->total ?? 0;
$topProducts->push($product);
}
}
if ($topProducts->count() < 3) {
$needed = 3 - $topProducts->count();
$excluded = $topProducts->pluck('id')->toArray();
$extras = Product::whereNotIn('id', $excluded)->limit($needed)->get();
foreach ($extras as $e) {
$e->total_sold = 0;
$topProducts->push($e);
}
}
return view('landing', ['topProducts' => $topProducts]);
});
// TEST PENGIRIMAN EMAIL ROUTE
Route::get('/test-email', [\App\Http\Controllers\SendEmailController::class, 'showForm']);
Route::post('/test-email', [\App\Http\Controllers\SendEmailController::class, 'sendEmail']);
// AUTH ROUTES
Route::get('/login', [AuthController::class, 'showLoginForm'])->name('login');
Route::post('/authenticate', [AuthController::class, 'authenticate']);
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
// PASSWORD RESET ROUTES (Khusus Admin)
Route::get('/forgot-password', [App\Http\Controllers\PasswordResetController::class, 'showLinkRequestForm'])->name('password.request');
Route::post('/forgot-password', [App\Http\Controllers\PasswordResetController::class, 'sendResetLinkEmail'])->name('password.email');
Route::get('/reset-password/{token}', [App\Http\Controllers\PasswordResetController::class, 'showResetForm'])->name('password.reset');
Route::post('/reset-password', [App\Http\Controllers\PasswordResetController::class, 'reset'])->name('password.update');
// PROTECTED ROUTES
Route::middleware(['auth'])->group(function () {
// DASHBOARD REDIRECTION
Route::get('/dashboard', [App\Http\Controllers\DashboardController::class, 'index']);
Route::get('/admin/dashboard', [App\Http\Controllers\DashboardController::class, 'adminIndex']);
Route::get('/landing', function () {
$top = Sale::select('product_id', DB::raw('SUM(quantity) as total'))
->groupBy('product_id')
->orderByDesc('total')
->limit(3)
->get();
$productIds = $top->pluck('product_id')->toArray();
$products = Product::whereIn('id', $productIds)->get()->keyBy('id');
$topProducts = collect();
foreach ($productIds as $id) {
$product = $products->get($id);
if ($product) {
$product->total_sold = $top->firstWhere('product_id', $id)->total ?? 0;
$topProducts->push($product);
}
}
if ($topProducts->count() < 3) {
$needed = 3 - $topProducts->count();
$excluded = $topProducts->pluck('id')->toArray();
$extras = Product::whereNotIn('id', $excluded)->limit($needed)->get();
foreach ($extras as $e) {
$e->total_sold = 0;
$topProducts->push($e);
}
}
return view('landing', ['topProducts' => $topProducts]);
});
Route::get('/transaksi', function () {
return view('transaksi');
});
Route::get('/laporan', function () {
return view('laporan');
});
// PRODUCT - CRUD for karyawan (restricted to their branch)
Route::get('/produk', [ProductController::class, 'index']);
Route::post('/produk', [ProductController::class, 'store']);
Route::put('/produk/{id}', [ProductController::class, 'update']);
Route::delete('/produk/{id}', [ProductController::class, 'destroy']);
// BAHAN BAKU (RAW MATERIALS) - View only, all management via purchase
Route::get('/bahan-baku', [App\Http\Controllers\RawMaterialController::class, 'index']);
// ADMIN ONLY ROUTES
Route::middleware(['can:admin-access'])->group(function () {
// Manajemen akun
Route::get('/manajemen-akun', [App\Http\Controllers\AccountController::class, 'index']);
Route::post('/manajemen-akun', [App\Http\Controllers\AccountController::class, 'store']);
Route::put('/manajemen-akun/{id}', [App\Http\Controllers\AccountController::class, 'update']);
Route::delete('/manajemen-akun/{id}', [App\Http\Controllers\AccountController::class, 'destroy']);
// Manajemen cabang
Route::get('/branches', [App\Http\Controllers\BranchController::class, 'index']);
Route::post('/branches', [App\Http\Controllers\BranchController::class, 'store']);
Route::delete('/branches/{id}', [App\Http\Controllers\BranchController::class, 'destroy']);
// OPERATIONAL COSTS
Route::get('/biaya-operasional', [App\Http\Controllers\OperationalCostController::class, 'index']);
Route::post('/biaya-operasional', [App\Http\Controllers\OperationalCostController::class, 'store']);
Route::put('/biaya-operasional/{id}', [App\Http\Controllers\OperationalCostController::class, 'update']);
Route::delete('/biaya-operasional/{id}', [App\Http\Controllers\OperationalCostController::class, 'destroy']);
// BAHAN BAKU (RAW MATERIALS) - Admin view only
Route::get('/bahan-baku', [App\Http\Controllers\RawMaterialController::class, 'index']);
Route::get('/laporan/neraca-laba-rugi', [App\Http\Controllers\FinancialReportController::class, 'profitAndLoss']);
Route::get('/laporan/neraca-laba-rugi/export-pdf', [App\Http\Controllers\FinancialReportController::class, 'exportProfitAndLossPdf']);
Route::get('/laporan/buku-besar', [App\Http\Controllers\FinancialReportController::class, 'generalLedger']);
Route::get('/laporan/jurnal-umum', [App\Http\Controllers\FinancialReportController::class, 'generalJournal']);
Route::get('/laporan/perubahan-modal', [App\Http\Controllers\FinancialReportController::class, 'equityStatement']);
Route::get('/laporan/neraca-keuangan', [App\Http\Controllers\FinancialReportController::class, 'balanceSheet']);
Route::get('/laporan/arus-kas', [App\Http\Controllers\FinancialReportController::class, 'cashFlow']);
});
// SHARED / GENERAL REPORTS
Route::get('/laporan/pembelian', [App\Http\Controllers\PurchaseController::class, 'index']);
Route::get('/transaksi/pembelian/create', [App\Http\Controllers\PurchaseController::class, 'create']);
Route::get('/laporan/pembelian/export-pdf', [App\Http\Controllers\PurchaseController::class, 'exportPdf'])->middleware('can:admin-access');
Route::post('/laporan/pembelian', [App\Http\Controllers\PurchaseController::class, 'store']);
Route::put('/laporan/pembelian/{id}', [App\Http\Controllers\PurchaseController::class, 'update']);
Route::delete('/laporan/pembelian/{id}', [App\Http\Controllers\PurchaseController::class, 'destroy']);
Route::get('/laporan/penjualan', [App\Http\Controllers\SaleController::class, 'index']);
Route::get('/transaksi/penjualan/create', [App\Http\Controllers\SaleController::class, 'create']);
Route::get('/laporan/penjualan/export-pdf', [App\Http\Controllers\SaleController::class, 'exportPdf'])->middleware('can:admin-access');
Route::post('/laporan/penjualan', [App\Http\Controllers\SaleController::class, 'store']);
Route::put('/laporan/penjualan/{id}', [App\Http\Controllers\SaleController::class, 'update']);
Route::delete('/laporan/penjualan/{id}', [App\Http\Controllers\SaleController::class, 'destroy']);
// DEBUG ROUTE - hapus setelah selesai debug
Route::get('/debug-stok', function () {
$rawMaterials = \App\Models\RawMaterial::all()->map(fn($rm) => [
'id' => $rm->id,
'name' => $rm->name,
'unit' => $rm->unit,
'stock_quantity' => $rm->stock_quantity,
]);
$recipes = \App\Models\ProductRecipe::with(['product', 'rawMaterial'])->get()->map(fn($r) => [
'product' => $r->product?->name,
'raw_material' => $r->rawMaterial?->name,
'quantity_needed' => $r->quantity_needed,
]);
$purchases = \App\Models\Purchase::orderBy('id', 'desc')->limit(10)->get()->map(fn($p) => [
'id' => $p->id,
'item' => $p->item,
'quantity' => $p->quantity,
'type' => $p->type,
'raw_material_id'=> $p->raw_material_id,
'branch' => $p->branch,
'date' => $p->date,
]);
$stocks = \App\Models\Stock::with('product')->get()->map(fn($s) => [
'product' => $s->product?->name,
'branch' => $s->branch,
'quantity' => $s->quantity,
]);
return response()->json([
'raw_materials' => $rawMaterials,
'product_recipes' => $recipes,
'recent_purchases' => $purchases,
'stocks' => $stocks,
], 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
});
});