# Task 11 — General Ledger

## Goal
Build the General Ledger report module to display journal entry line movements for a selected account and date/period filters.
This report provides detailed transaction-level accounting history.

---

## Scope

This task covers:
- general ledger query logic
- filters by account / branch / fiscal year / fiscal period / date range
- report UI
- running balance display structure

This task does NOT cover:
- Trial Balance
- Income Statement
- export implementation
- advanced drilldown widgets

---

## Data Source

Primary source tables:
- `journal_entries`
- `journal_entry_lines`

Supporting tables:
- `accounts`
- `journals`
- `branches`
- `fiscal_years`
- `fiscal_periods`
- `cost_centers`

---

## Required Output

For each movement row:
- entry_number
- entry_date
- journal_name
- account_code
- account_name
- line_description
- cost_center_name (nullable)
- debit
- credit
- running_debit_balance
- running_credit_balance

---

## Business Rules

1. General Ledger must read from `journal_entry_lines` joined with `journal_entries`.
2. Only posted entries should be shown.
3. Filters must support:
   - account_id (required)
   - branch_id (required)
   - fiscal_year_id (optional if date range provided)
   - fiscal_period_id (optional)
   - date_from (optional)
   - date_to (optional)
4. Results must be ordered by entry_date then entry id.
5. Running balance must be calculated in application/service layer.
6. Account name must use translated JSON field.
7. Cost center is optional.

---

## Query Rules

Main joins:
- journal_entry_lines
- journal_entries
- accounts
- journals
- cost_centers (left join)

Required where filters:
- journal_entries.status = posted
- journal_entry_lines.account_id = selected account
- journal_entries.branch_id = selected branch

Optional filters:
- fiscal_year_id
- fiscal_period_id
- date range

Order by:
- journal_entries.entry_date asc
- journal_entries.id asc
- journal_entry_lines.id asc

---

## Files

### Service
- app/Services/Finance/Reports/GeneralLedgerService.php

### Controller
- app/Http/Controllers/Admin/Finance/GeneralLedgerController.php

### Requests
- app/Http/Requests/Admin/Finance/GeneralLedgerFilterRequest.php

### Views
- resources/views/dashboard/finance/reports/general_ledger/index.blade.php

### Lang files
- lang/ar/finance.php
- lang/en/finance.php

---

## Permissions

- reports.general_ledger.view

---

## Validation Rules

- account_id: required, exists:accounts,id
- branch_id: required, exists:branches,id
- fiscal_year_id: nullable, exists:fiscal_years,id
- fiscal_period_id: nullable, exists:fiscal_periods,id
- date_from: nullable, date
- date_to: nullable, date, after_or_equal:date_from

---

## UI

Views path:
`resources/views/dashboard/finance/reports/general_ledger/`

### Filter fields
- account
- branch
- fiscal_year
- fiscal_period
- date_from
- date_to
- submit button

### Table columns
- entry_number
- entry_date
- journal
- description
- cost_center
- debit
- credit
- running_balance

### Opening balance section (optional later)
- opening debit/credit before selected range

---

## Lang Keys

Suggested keys:
- general_ledger
- account
- account_code
- account_name
- entry_number
- entry_date
- journal
- description
- cost_center
- debit
- credit
- running_balance
- date_from
- date_to
- branch
- fiscal_year
- fiscal_period

---

## Seeder

Update RolePermissionSeeder with:
- reports.general_ledger.view

---

## Steps

### Step 1
Create `GeneralLedgerFilterRequest`.

### Step 2
Create `GeneralLedgerService`.

### Step 3
Create `GeneralLedgerController`.

### Step 4
Add routes in `routes/admin.php`.

### Step 5
Create general ledger view.

### Step 6
Update lang files.

### Step 7
Update `RolePermissionSeeder` with `reports.general_ledger.view`.

---

## Notes for AI

- Follow docs/ai/AI_MASTER_PROJECT.md
- Follow docs/ai/ARCHITECTURE_RULES.md
- Follow docs/ai/DATABASE_SCHEMA.md
- Follow docs/ai/DATABASE_RELATION_DIAGRAM.md
- Follow docs/ai/MODULE_STRUCTURE.md
- Execute one step at a time
- Do not modify unrelated files
- Do not generate tests in this task
- Wait for confirmation after each step

