@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

GOVIX finance control center

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())

The finance action was not posted.

@endif @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])

{{ $label }}

AED {{ $money($amount) }}

@endforeach

Revenue trend

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

Collection methods

@forelse($dashboard['collection_methods'] as $method => $amount)
{{ str_replace('_',' ',$method) }}AED {{ $money($amount) }}
@empty

No collections in this period.

@endforelse

Receivable aging

@foreach($dashboard['receivable_aging'] as $bucket => $amount)

{{ $bucket }}

AED {{ $money($amount) }}

@endforeach

Quick actions

@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')

Accounts receivable & invoices

Issued, partial, paid, overdue and credit-adjusted invoices.

@forelse($invoices as $invoice)@empty@endforelse
InvoiceCustomerWorkflowTotalPaidOutstanding
{{ $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) }}
No invoices yet.
@endif @if($section === 'ledger')

Chart of accounts

System and tenant accounts. Posted accounts are never deleted.

@foreach($accounts as $account)@endforeach
AccountTypeDebitCredit
{{ $account->account_code }} {{ $account->account_name }}{{ $account->account_type }}{{ $money($account->debit_total) }}{{ $money($account->credit_total) }}
@csrf
@csrf

Create account

@csrf

Manual journal

Unbalanced journals are rejected.

@for($i=0;$i<2;$i++)@endfor

Journal register

General Ledger →
@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')
@csrf
@elseif($journal->status==='posted')
@csrf
@endif
@endforeach
@csrf

Opening balances

Audited debit and credit totals must match.

@foreach(['debit','credit'] as $i=>$side)
@endforeach
@csrf

Employee salary advance

Debit employee advances; credit the funding account.

@csrf

Petty cash replenishment

Requests and expense approvals use the expense workflow; this funds the petty cash ledger.

Approval threshold: AED {{ $money($settings->petty_cash_approval_threshold) }}

@endif @if($section === 'expenses')
@csrf

Record expense

Expense approvals

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
@endif
@empty
No expenses recorded.
@endforelse
@endif @if($section === 'payables')
@csrf

New supplier

@csrf

Supplier bill

AP summary

AED {{ $money($dashboard['payables']) }}

Supplier outstanding

Open payable aging →

Supplier bills

@forelse($supplierBills as $bill)

{{ $bill->internal_number }} · {{ $bill->vendor?->name }}

Supplier ref {{ $bill->bill_number }} · Due {{ $bill->due_date?->format('d M Y') }}

AED {{ $money($bill->balance_due) }}{{ $bill->status }}@if($bill->status==='draft')
@csrf
@elseif(in_array($bill->status,['approved','partially_paid','overdue']))
@csrf
@endif
@empty
No supplier bills.
@endforelse
@endif @if($section === 'banking')
@csrf

Add bank account

@csrf

Cash & bank transfer

@csrf

Bank reconciliation

Compare bank statement and book balance.

Bank balances

@forelse($bankAccounts as $bank)

{{ $bank->bank_name }}

{{ $bank->iban }}

AED {{ $money($bank->book_balance) }}

@empty

No bank accounts.

@endforelse

Recent bank transactions

@foreach($bankTransactions as $tx)

{{ $tx->transaction_number }}

{{ str_replace('_',' ',$tx->type) }}

AED {{ $money($tx->amount) }}

@endforeach
@endif @if($section === 'government')
@csrf

Government authority payment

Debit government fee clearing; credit cash or bank.

@foreach([['Collected',$dashboard['government_fees']],['Settled',$settlements->sum('amount')],['Pending',$dashboard['government_fees']-$settlements->sum('amount')]] as [$label,$amount])

{{ $label }}

AED {{ $money($amount) }}

@endforeach

Settlement register

@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')

Fiscal year & monthly periods

Locked periods reject invoices, payments, refunds, expenses, payroll, journals and bank postings.

@foreach($periods as $period)

{{ $period->starts_on->format('F Y') }}

{{ $period->starts_on->format('d M') }} – {{ $period->ends_on->format('d M Y') }}

{{ $period->status }}
@csrf
@endforeach
@endif @if($section === 'automation')

Quotations

Convert accepted quotes without re-entry.

Create quote →
@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)
@csrf
@endif
@empty

No quotations.

@endforelse

Recurring invoices

Scheduler-ready weekly, monthly, quarterly and yearly profiles.

@csrf
@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')

Centralized report center

Financial & management reports

Every report reads posted transactions and exports real rows to PDF, Excel-compatible XML and CSV.

@foreach($reportTypes as $type=>$label)

{{ $label }}

Filter · drill down · export

@endforeach

Operations, customer & workforce analytics

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
@csrf

Custom report builder

Select a module, fields, filter, group and sort; save the configuration for reuse.

@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)@endforeach

Saved reports

@forelse($savedReports as $saved)

{{ $saved->name }}

{{ $saved->module }} · {{ count($saved->fields) }} fields

Run →
@empty

No saved custom reports.

@endforelse

Queued exports

@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')

Tenant-level control

Finance automation & compliance

These defaults govern invoice timing, approval, VAT, numbering and posting accounts.

Document number formats

Use placeholders such as {FINANCIAL_YEAR}, {YEAR}, {MONTH}, {BRANCH}, {SERVICE} and required {SEQUENCE}.

@foreach($formatLabels as $key=>$label)@endforeach

Account mappings

Every automated journal resolves a tenant-owned account through these mappings.

@foreach($mappingLabels as $key=>$label)@endforeach
@csrf

Scoped invoice generation rule

A lower priority number wins over the tenant default.

Active overrides

@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')
@empty

No scoped overrides. The tenant default applies.

@endforelse
@endif
@endsection