@extends('layouts.app')
@section('title', 'Finance & Accounting')
@section('content')
@php
$money = fn ($value) => number_format((float) $value, 2);
$sections = [
'dashboard' => 'Overview', 'invoices' => 'AR & Invoices', 'ledger' => 'Ledger & COA',
'expenses' => 'Expenses', 'payables' => 'Suppliers & AP', 'banking' => 'Banking',
'government' => 'Government Clearing', 'periods' => 'Periods', 'automation' => 'Quotes & Recurring',
'reports' => 'Report Center', 'settings' => 'Finance Settings',
];
@endphp
Finance, accounting & reporting
Real double-entry postings with service revenue, VAT and government fees handled as separate accounting components.
@if(session('status'))
{{ session('status') }}
@endif
@if($errors->any())
@foreach($errors->all() as $error){{ $error }} @endforeach @endif
@foreach($sections as $key => $label)
{{ $label }}
@endforeach
@if($section === 'dashboard')
@foreach([
['Today Collection', $dashboard['today_collection'], 'payments'], ['Service Revenue', $dashboard['service_revenue'], 'profit_loss'],
['Government fees handled', $dashboard['government_fees'], 'government_fees'], ['VAT Payable', $dashboard['vat_payable'], 'vat'],
['Receivables', $dashboard['receivables'], 'receivables'], ['Payables', $dashboard['payables'], 'payables'],
['Expenses', $dashboard['expenses'], 'expenses'], ['Cash', $dashboard['cash'], 'cash_flow'],
['Bank Balance', $dashboard['bank'], 'cash_flow'], ['Net Profit', $dashboard['net_profit'], 'profit_loss'],
] as [$label, $amount, $report])
AED {{ $money($amount) }}
@endforeach
Company revenue only; pass-through fees excluded.
Open P&L →
@php $maxRevenue = max(1, collect($dashboard['revenue_trend'])->max() ?: 1); @endphp
@forelse($dashboard['revenue_trend'] as $date => $amount)
{{ substr($date, 5) }}
@empty
Post an invoice to begin the live trend.
@endforelse
@forelse($dashboard['collection_methods'] as $method => $amount)
{{ str_replace('_',' ',$method) }} AED {{ $money($amount) }}
@empty
No collections in this period.
@endforelse
@foreach([['Create Invoice',route('app.billing.invoices.create')],['Record Expense',route('app.accounting',['section'=>'expenses'])],['Create Journal',route('app.accounting',['section'=>'ledger'])],['Bank Transfer',route('app.accounting',['section'=>'banking'])],['Daily Closing',route('app.accounting',['section'=>'periods'])],['Government Settlement',route('app.accounting',['section'=>'government'])]] as [$label,$url])
{{ $label }} → @endforeach
@endif
@if($section === 'invoices')
Issued, partial, paid, overdue and credit-adjusted invoices.
Invoice Customer Workflow Total Paid Outstanding @forelse($invoices as $invoice){{ $invoice->invoice_number }} {{ $invoice->invoice_date->format('d M Y') }}
{{ $invoice->customer?->full_name_en ?? $invoice->company?->name_en }} {{ str_replace('_',' ',$invoice->workflow_status) }} AED {{ $money($invoice->total_amount) }} AED {{ $money($invoice->paid_amount) }} AED {{ $money($invoice->balance_due) }} @emptyNo invoices yet. @endforelse
@endif
@if($section === 'ledger')
System and tenant accounts. Posted accounts are never deleted.
Account Type Debit Credit @foreach($accounts as $account){{ $account->account_code }} {{ $account->account_name }} {{ $account->account_type }} {{ $money($account->debit_total) }} {{ $money($account->credit_total) }} @endforeach
@foreach($journals as $journal)
{{ $journal->entry_number }} {{ $journal->status }}
{{ $journal->entry_date->format('d M Y') }} · {{ $journal->narration }}
AED {{ $money($journal->total_debit) }} @if($journal->status==='draft')@elseif($journal->status==='posted')@endif
@endforeach
@endif
@if($section === 'expenses')
Draft → Submitted → Approved → Paid. Every approval and payment posts separately.
@forelse($expenses as $expense)
{{ $expense->expense_number }} · {{ ucwords(str_replace('_',' ',$expense->category)) }}
{{ $expense->description }} · {{ $expense->vendor?->name }}
AED {{ $money($expense->total_amount) }} {{ $expense->status }} @php $action=['draft'=>'submit','submitted'=>'approve','approved'=>'pay'][$expense->status]??null; @endphp @if($action)
@csrf{{ $action }} @endif@empty
No expenses recorded.
@endforelse
@endif
@if($section === 'payables')
@csrfCreate Supplier
@csrfSave Supplier Bill
@forelse($supplierBills as $bill)
@empty
No supplier bills.
@endforelse
@endif
@if($section === 'banking')
@forelse($bankAccounts as $bank)
{{ $bank->bank_name }}
{{ $bank->iban }}
AED {{ $money($bank->book_balance) }}
@empty
No bank accounts.
@endforelse
@foreach($bankTransactions as $tx)
{{ $tx->transaction_number }}
{{ str_replace('_',' ',$tx->type) }}
AED {{ $money($tx->amount) }}
@endforeach
@endif
@if($section === 'government')
@csrfDebit government fee clearing; credit cash or bank.
Bank transfer Cash Cheque
Post Settlement
@foreach([['Collected',$dashboard['government_fees']],['Settled',$settlements->sum('amount')],['Pending',$dashboard['government_fees']-$settlements->sum('amount')]] as [$label,$amount])
{{ $label }}
AED {{ $money($amount) }}
@endforeach
@forelse($settlements as $settlement)
{{ $settlement->settlement_number }} · {{ $settlement->authority_name }}
{{ $settlement->settlement_date->format('d M Y') }} · {{ $settlement->reference }}
AED {{ $money($settlement->amount) }}
@empty
No settlements posted.
@endforelse
@endif
@if($section === 'periods')
Locked periods reject invoices, payments, refunds, expenses, payroll, journals and bank postings.
@foreach($periods as $period)
@endforeach
@endif
@if($section === 'automation')
@forelse($quotations as $quote)
{{ $quote->quotation_number }}
{{ $quote->status }} · Expires {{ $quote->expires_on?->format('d M Y') }}
AED {{ $money($quote->total_amount) }} @if(!$quote->converted_invoice_id)
@csrfConvert @endif@empty
No quotations.
@endforelse
Scheduler-ready weekly, monthly, quarterly and yearly profiles.
@csrfGenerate Due @forelse($recurringProfiles as $profile)
{{ $profile->name }}
{{ $profile->frequency }} · Next {{ $profile->next_invoice_date->format('d M Y') }}
{{ $profile->status }} @empty
Create a recurring profile through the finance API or form integration.
@endforelse
@endif
@if($section === 'reports')
Financial & management reports Every report reads posted transactions and exports real rows to PDF, Excel-compatible XML and CSV.
One tenant-scoped analytics source for the non-ledger report families; salary values remain permission protected.
Open unified analytics → @foreach(['Applications','Services','Typist Performance','Customers','Renewals','Corporate','Employees','Attendance','Payroll & WPS','Gratuity','Documents','Branch Performance','Management Summary','Audit Activity','Custom Reports'] as $family)
{{ $family }} → @endforeach
@csrfSelect a module, fields, filter, group and sort; save the configuration for reuse.
@foreach(['applications'=>'Applications','invoices'=>'Invoices','payments'=>'Payments','expenses'=>'Expenses','customers'=>'Customers','corporate'=>'Corporate','employees'=>'Employees','attendance'=>'Attendance','payroll'=>'Payroll','renewals'=>'Renewals','documents'=>'Documents','finance'=>'Finance & Journals'] as $value=>$label){{ $label }} @endforeach @foreach(['application_number'=>'Application No','customer_code'=>'Customer Code','customer'=>'Customer','company_code'=>'Company Code','company'=>'Company','service'=>'Service','typist'=>'Typist','invoice_number'=>'Invoice No','payment_number'=>'Payment No','expense_number'=>'Expense No','employee_code'=>'Employee Code','employee'=>'Employee','attendance_date'=>'Attendance Date','run_number'=>'Payroll Run','period'=>'Period','renewal_number'=>'Renewal No','document_type'=>'Document Type','entry_number'=>'Journal No','status'=>'Status','branch_id'=>'Branch','branch'=>'Branch Name','department'=>'Department','revenue'=>'Revenue','total_amount'=>'Total','balance_due'=>'Outstanding','basic_salary'=>'Basic Salary','net_salary'=>'Net Salary','estimated_value'=>'Renewal Value','expiry_date'=>'Expiry Date','created_at'=>'Created Date'] as $field=>$label) {{ $label }} @endforeach
Ascending Descending Save & Run Custom Report
@forelse($reportExports as $export)
{{ ucwords(str_replace('_',' ',$export->report_type)) }}
{{ $export->format }} · {{ $export->status }}
@if($export->status==='completed')
Download @endif
@empty
Large exports will appear here and notify you when ready.
@endforelse
@endif
@if($section === 'settings')
@php
$formatLabels = ['invoice'=>'Invoice','corporate_invoice'=>'Corporate Invoice','receipt'=>'Receipt','credit_note'=>'Credit Note','debit_note'=>'Debit Note','quotation'=>'Quotation','journal'=>'Journal','expense'=>'Expense','supplier_bill'=>'Supplier Bill','supplier_payment'=>'Supplier Payment','bank_transaction'=>'Bank Transaction','government_settlement'=>'Government Settlement'];
$mappingLabels = ['cash'=>'Cash on Hand','card_clearing'=>'Card / Gateway Clearing','bank'=>'Bank','accounts_receivable'=>'Accounts Receivable','input_vat'=>'Input VAT Recoverable','government_fee_clearing'=>'Government Fee Clearing','vat_payable'=>'VAT Payable','accounts_payable'=>'Accounts Payable','typing_revenue'=>'Typing Revenue','service_revenue'=>'Service Revenue','other_revenue'=>'Other Revenue','discounts'=>'Discounts Allowed','general_expense'=>'General Expense'];
@endphp
@csrf @method('PUT')
Finance automation & compliance These defaults govern invoice timing, approval, VAT, numbering and posting accounts.
Every automated journal resolves a tenant-owned account through these mappings.
@foreach($mappingLabels as $key=>$label){{ $label }}@foreach($accounts as $account)account_mappings,$key)===$account->account_code)>{{ $account->account_code }} — {{ $account->account_name }} @endforeach @endforeach
@csrfA lower priority number wins over the tenant default.
Whole tenant Specific branch Specific service Specific corporate client No record for whole tenant @foreach($branches as $branch){{ $branch->code }} — {{ $branch->name }} @endforeach @foreach($services as $service){{ $service->service_code }} — {{ $service->name_en }} @endforeach @foreach($companies as $company){{ $company->name_en }} @endforeach @foreach(['application_created','application_confirmed','payment_requested','payment_received','service_completed','renewal_application','pos_transaction','corporate_bulk_service','custom_workflow_event'] as $event){{ ucwords(str_replace('_',' ',$event)) }} @endforeach Create draft Manual only
Save Override Rule
@forelse($generationRules as $rule)@php $scopeLabel = match($rule->scope_type){'branch'=>$branches->firstWhere('id',$rule->scope_id)?->name,'service'=>$services->firstWhere('id',$rule->scope_id)?->name_en,'corporate'=>$companies->firstWhere('id',$rule->scope_id)?->name_en,default=>'Whole tenant'}; @endphp
{{ $scopeLabel ?? strtoupper($rule->scope_type).' #'.$rule->scope_id }}
{{ str_replace('_',' ',$rule->generation_event) }} → {{ str_replace('_',' ',$rule->action) }} · Priority {{ $rule->priority }}
@csrf @method('DELETE')Remove @empty
No scoped overrides. The tenant default applies.
@endforelse
@endif
@endsection