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>
76 lines
2.6 KiB
PHP
76 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\AccountingEntry;
|
|
use App\Models\ChartOfAccount;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class TrialBalanceController extends Controller
|
|
{
|
|
/**
|
|
* Display the trial balance
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
$startDate = $request->input('start_date', now()->startOfYear()->format('Y-m-d'));
|
|
$endDate = $request->input('end_date', now()->format('Y-m-d'));
|
|
|
|
// Get all active accounts with their balances
|
|
$accounts = ChartOfAccount::where('is_active', true)
|
|
->orderBy('account_code')
|
|
->get()
|
|
->map(function ($account) use ($startDate, $endDate) {
|
|
// Get debit and credit totals for this account
|
|
$debitTotal = AccountingEntry::where('chart_of_account_id', $account->id)
|
|
->whereBetween('entry_date', [$startDate, $endDate])
|
|
->where('entry_type', AccountingEntry::ENTRY_TYPE_DEBIT)
|
|
->sum('amount');
|
|
|
|
$creditTotal = AccountingEntry::where('chart_of_account_id', $account->id)
|
|
->whereBetween('entry_date', [$startDate, $endDate])
|
|
->where('entry_type', AccountingEntry::ENTRY_TYPE_CREDIT)
|
|
->sum('amount');
|
|
|
|
// Only include accounts with activity
|
|
if ($debitTotal == 0 && $creditTotal == 0) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'account' => $account,
|
|
'debit_total' => $debitTotal,
|
|
'credit_total' => $creditTotal,
|
|
];
|
|
})
|
|
->filter() // Remove null entries
|
|
->values();
|
|
|
|
// Calculate grand totals
|
|
$grandDebitTotal = $accounts->sum('debit_total');
|
|
$grandCreditTotal = $accounts->sum('credit_total');
|
|
|
|
// Check if balanced
|
|
$isBalanced = bccomp((string)$grandDebitTotal, (string)$grandCreditTotal, 2) === 0;
|
|
$difference = $grandDebitTotal - $grandCreditTotal;
|
|
|
|
// Group accounts by type
|
|
$accountsByType = $accounts->groupBy(function ($item) {
|
|
return $item['account']->account_type;
|
|
});
|
|
|
|
return view('admin.trial-balance.index', compact(
|
|
'accounts',
|
|
'accountsByType',
|
|
'startDate',
|
|
'endDate',
|
|
'grandDebitTotal',
|
|
'grandCreditTotal',
|
|
'isBalanced',
|
|
'difference'
|
|
));
|
|
}
|
|
}
|