Add membership fee system with disability discount and fix document permissions
Features: - Implement two fee types: entrance fee and annual fee (both NT$1,000) - Add 50% discount for disability certificate holders - Add disability certificate upload in member profile - Integrate disability verification into cashier approval workflow - Add membership fee settings in system admin Document permissions: - Fix hard-coded role logic in Document model - Use permission-based authorization instead of role checks Additional features: - Add announcements, general ledger, and trial balance modules - Add income management and accounting entries - Add comprehensive test suite with factories - Update UI translations to Traditional Chinese 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,9 @@ use App\Http\Controllers\PaymentVerificationController;
|
||||
use App\Http\Controllers\PublicDocumentController;
|
||||
use App\Http\Controllers\Admin\DocumentController;
|
||||
use App\Http\Controllers\Admin\DocumentCategoryController;
|
||||
use App\Http\Controllers\Admin\AnnouncementController;
|
||||
use App\Http\Controllers\PublicBugReportController;
|
||||
use App\Http\Controllers\IncomeController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
@@ -60,7 +62,16 @@ Route::get('/dashboard', function () {
|
||||
->get()
|
||||
->filter(fn($doc) => $doc->canBeViewedBy(auth()->user()));
|
||||
|
||||
return view('dashboard', compact('recentDocuments'));
|
||||
$recentAnnouncements = \App\Models\Announcement::query()
|
||||
->published()
|
||||
->active()
|
||||
->forAccessLevel(auth()->user())
|
||||
->orderByDesc('is_pinned')
|
||||
->orderByDesc('published_at')
|
||||
->limit(5)
|
||||
->get();
|
||||
|
||||
return view('dashboard', compact('recentDocuments', 'recentAnnouncements'));
|
||||
})->middleware(['auth', 'verified'])->name('dashboard');
|
||||
|
||||
// Public Member Registration Routes
|
||||
@@ -92,12 +103,18 @@ Route::middleware('auth')->group(function () {
|
||||
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
|
||||
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
|
||||
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
|
||||
|
||||
// Disability Certificate Routes
|
||||
Route::post('/profile/disability-certificate', [ProfileController::class, 'uploadDisabilityCertificate'])->name('profile.disability-certificate.upload');
|
||||
Route::get('/profile/disability-certificate', [ProfileController::class, 'viewDisabilityCertificate'])->name('profile.disability-certificate.view');
|
||||
});
|
||||
|
||||
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
|
||||
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
|
||||
|
||||
Route::get('/members', [AdminMemberController::class, 'index'])->name('members.index');
|
||||
Route::post('/members/batch-destroy', [AdminMemberController::class, 'batchDestroy'])->name('members.batch-destroy');
|
||||
Route::post('/members/batch-update-status', [AdminMemberController::class, 'batchUpdateStatus'])->name('members.batch-update-status');
|
||||
Route::get('/members/create', [AdminMemberController::class, 'create'])->name('members.create');
|
||||
Route::post('/members', [AdminMemberController::class, 'store'])->name('members.store');
|
||||
Route::get('/members/import', [AdminMemberController::class, 'importForm'])->name('members.import-form');
|
||||
@@ -122,6 +139,9 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun
|
||||
Route::post('/finance-documents/{financeDocument}/approve', [FinanceDocumentController::class, 'approve'])->name('finance.approve');
|
||||
Route::post('/finance-documents/{financeDocument}/reject', [FinanceDocumentController::class, 'reject'])->name('finance.reject');
|
||||
Route::get('/finance-documents/{financeDocument}/download', [FinanceDocumentController::class, 'download'])->name('finance.download');
|
||||
// 新工作流程:出帳確認與入帳確認
|
||||
Route::post('/finance-documents/{financeDocument}/confirm-disbursement', [FinanceDocumentController::class, 'confirmDisbursement'])->name('finance.confirm-disbursement');
|
||||
Route::post('/finance-documents/{financeDocument}/confirm-recording', [FinanceDocumentController::class, 'confirmRecording'])->name('finance.confirm-recording');
|
||||
|
||||
// Payment Orders (Stage 2: Payment)
|
||||
Route::get('/payment-orders', [PaymentOrderController::class, 'index'])->name('payment-orders.index');
|
||||
@@ -152,6 +172,17 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun
|
||||
Route::get('/bank-reconciliations/{bankReconciliation}/export-pdf', [BankReconciliationController::class, 'exportPdf'])->name('bank-reconciliations.export-pdf');
|
||||
Route::get('/bank-reconciliations/{bankReconciliation}/pdf', [BankReconciliationController::class, 'exportPdf'])->name('bank-reconciliations.pdf');
|
||||
|
||||
// Income Management (收入管理)
|
||||
Route::get('/incomes', [IncomeController::class, 'index'])->name('incomes.index');
|
||||
Route::get('/incomes/create', [IncomeController::class, 'create'])->name('incomes.create');
|
||||
Route::get('/incomes/statistics', [IncomeController::class, 'statistics'])->name('incomes.statistics');
|
||||
Route::get('/incomes/export', [IncomeController::class, 'export'])->name('incomes.export');
|
||||
Route::post('/incomes', [IncomeController::class, 'store'])->name('incomes.store');
|
||||
Route::get('/incomes/{income}', [IncomeController::class, 'show'])->name('incomes.show');
|
||||
Route::get('/incomes/{income}/download', [IncomeController::class, 'download'])->name('incomes.download');
|
||||
Route::post('/incomes/{income}/confirm', [IncomeController::class, 'confirm'])->name('incomes.confirm');
|
||||
Route::post('/incomes/{income}/cancel', [IncomeController::class, 'cancel'])->name('incomes.cancel');
|
||||
|
||||
Route::get('/audit-logs', [AdminAuditLogController::class, 'index'])->name('audit.index');
|
||||
Route::get('/audit-logs/export', [AdminAuditLogController::class, 'export'])->name('audit.export');
|
||||
|
||||
@@ -184,6 +215,10 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun
|
||||
Route::patch('/transactions/{transaction}', [TransactionController::class, 'update'])->name('transactions.update');
|
||||
Route::delete('/transactions/{transaction}', [TransactionController::class, 'destroy'])->name('transactions.destroy');
|
||||
|
||||
// General Ledger & Trial Balance Routes
|
||||
Route::get('/general-ledger', [\App\Http\Controllers\Admin\GeneralLedgerController::class, 'index'])->name('general-ledger.index');
|
||||
Route::get('/trial-balance', [\App\Http\Controllers\Admin\TrialBalanceController::class, 'index'])->name('trial-balance.index');
|
||||
|
||||
// Issue Tracker Routes
|
||||
Route::get('/issues', [IssueController::class, 'index'])->name('issues.index');
|
||||
Route::get('/issues/create', [IssueController::class, 'create'])->name('issues.create');
|
||||
@@ -233,6 +268,7 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun
|
||||
// Membership Activation Routes
|
||||
Route::get('/members/{member}/activate', [AdminMemberController::class, 'showActivate'])->name('members.activate');
|
||||
Route::post('/members/{member}/activate', [AdminMemberController::class, 'activate'])->name('members.activate.store');
|
||||
Route::get('/members/{member}/disability-certificate', [AdminMemberController::class, 'viewDisabilityCertificate'])->name('members.disability-certificate');
|
||||
|
||||
// Document Categories Management
|
||||
Route::get('/document-categories', [DocumentCategoryController::class, 'index'])->name('document-categories.index');
|
||||
@@ -263,6 +299,21 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun
|
||||
Route::post('/documents/{document}/archive', [DocumentController::class, 'archive'])->name('documents.archive');
|
||||
Route::post('/documents/{document}/restore', [DocumentController::class, 'restore'])->name('documents.restore');
|
||||
|
||||
// Announcement Management
|
||||
Route::get('/announcements', [AnnouncementController::class, 'index'])->name('announcements.index');
|
||||
Route::get('/announcements/create', [AnnouncementController::class, 'create'])->name('announcements.create');
|
||||
Route::post('/announcements', [AnnouncementController::class, 'store'])->name('announcements.store');
|
||||
Route::get('/announcements/{announcement}', [AnnouncementController::class, 'show'])->name('announcements.show');
|
||||
Route::get('/announcements/{announcement}/edit', [AnnouncementController::class, 'edit'])->name('announcements.edit');
|
||||
Route::patch('/announcements/{announcement}', [AnnouncementController::class, 'update'])->name('announcements.update');
|
||||
Route::delete('/announcements/{announcement}', [AnnouncementController::class, 'destroy'])->name('announcements.destroy');
|
||||
|
||||
// Announcement Actions
|
||||
Route::post('/announcements/{announcement}/publish', [AnnouncementController::class, 'publish'])->name('announcements.publish');
|
||||
Route::post('/announcements/{announcement}/archive', [AnnouncementController::class, 'archive'])->name('announcements.archive');
|
||||
Route::post('/announcements/{announcement}/pin', [AnnouncementController::class, 'pin'])->name('announcements.pin');
|
||||
Route::post('/announcements/{announcement}/unpin', [AnnouncementController::class, 'unpin'])->name('announcements.unpin');
|
||||
|
||||
// System Settings (requires manage_system_settings permission)
|
||||
Route::middleware('can:manage_system_settings')->prefix('settings')->name('settings.')->group(function () {
|
||||
Route::get('/', [\App\Http\Controllers\Admin\SystemSettingsController::class, 'index'])->name('index');
|
||||
@@ -281,6 +332,9 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun
|
||||
|
||||
Route::get('/advanced', [\App\Http\Controllers\Admin\SystemSettingsController::class, 'advanced'])->name('advanced');
|
||||
Route::post('/advanced', [\App\Http\Controllers\Admin\SystemSettingsController::class, 'updateAdvanced'])->name('advanced.update');
|
||||
|
||||
Route::get('/membership', [\App\Http\Controllers\Admin\SystemSettingsController::class, 'membership'])->name('membership');
|
||||
Route::post('/membership', [\App\Http\Controllers\Admin\SystemSettingsController::class, 'updateMembership'])->name('membership.update');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user