<?php
// ─────────────────────────────────────────────────────────────────────────────
// Nowills SQC ERP — Central CRUD Registry. One entry drives list/search/create/
// edit/show/delete + transitions for an entity. Dedicated document controllers
// reuse these entries for their index/show pages.
// Field keys: label|type|required|width|options|model|label_field|where|default|
// placeholder|help|rows|min|max|step|unique|filter|readonly_on_edit
// Column format: 'field' => 'Label' or 'Label|fmt' (fmt: bool|money|qty|date|badge)
// ─────────────────────────────────────────────────────────────────────────────
namespace App\Support;
use App\Models as M;

class CrudRegistry {
    public static function all(): array {
        $active = ['label' => 'Active', 'type' => 'checkbox', 'default' => 1, 'width' => 3];
        $remarks = ['label' => 'Remarks', 'type' => 'textarea', 'rows' => 2, 'width' => 12];
        return [
        // ═══════════ QUARRY ═══════════
        'quarries' => ['model' => M\Quarry::class, 'title' => 'Quarries / Sites', 'singular' => 'Quarry', 'perm' => 'quarry',
            'columns' => ['code' => 'Code', 'name' => 'Quarry', 'location' => 'Location', 'region' => 'Region', 'licence_expiry' => 'Licence Exp.|date', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name', 'location'], 'sort' => 'name',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'quarries,code', 'width' => 3],
                'name' => ['label' => 'Quarry name', 'required' => 1, 'width' => 5],
                'location' => ['label' => 'Location', 'width' => 4],
                'region' => ['label' => 'Region', 'default' => 'Greater Accra', 'width' => 4],
                'gps_coordinates' => ['label' => 'GPS coordinates', 'width' => 4, 'placeholder' => '5.6037, -0.1870'],
                'manager_id' => ['label' => 'Quarry manager', 'type' => 'select', 'model' => M\Employee::class, 'width' => 4],
                'licence_no' => ['label' => 'Minerals Comm. licence', 'width' => 3],
                'licence_expiry' => ['label' => 'Licence expiry', 'type' => 'date', 'width' => 3],
                'epa_permit_no' => ['label' => 'EPA permit no.', 'width' => 3],
                'epa_expiry' => ['label' => 'EPA expiry', 'type' => 'date', 'width' => 3],
                'is_active' => $active]],
        'pit-benches' => ['model' => M\PitBench::class, 'title' => 'Pits / Benches', 'singular' => 'Pit Bench', 'perm' => 'quarry',
            'columns' => ['quarry.name' => 'Quarry', 'code' => 'Code', 'name' => 'Bench', 'bench_height' => 'Height (m)', 'status' => 'Status|badge'],
            'search' => ['code', 'name'], 'sort' => 'code',
            'fields' => [
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'filter' => 1],
                'code' => ['label' => 'Code', 'required' => 1, 'width' => 4],
                'name' => ['label' => 'Bench name', 'required' => 1, 'width' => 4],
                'bench_height' => ['label' => 'Bench height (m)', 'type' => 'decimal', 'width' => 4],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['active' => 'Active', 'development' => 'Development', 'depleted' => 'Depleted'], 'default' => 'active', 'width' => 4]]],
        'crusher-lines' => ['model' => M\CrusherLine::class, 'title' => 'Crusher Lines', 'singular' => 'Crusher Line', 'perm' => 'quarry',
            'columns' => ['quarry.name' => 'Quarry', 'code' => 'Code', 'name' => 'Line', 'crusher_type' => 'Type|badge', 'rated_capacity_tph' => 'Rated (tph)', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'code',
            'fields' => [
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'filter' => 1],
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'crusher_lines,code', 'width' => 4],
                'name' => ['label' => 'Line name', 'required' => 1, 'width' => 4],
                'crusher_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['jaw' => 'Jaw', 'cone' => 'Cone', 'impact' => 'Impact', 'vsi' => 'VSI', 'screen' => 'Screen'], 'default' => 'jaw', 'width' => 4],
                'rated_capacity_tph' => ['label' => 'Rated capacity (t/h)', 'type' => 'decimal', 'width' => 4],
                'is_active' => $active]],
        'blast-logs' => ['model' => M\BlastLog::class, 'title' => 'Blasting Logs', 'singular' => 'Blast Log', 'perm' => 'quarry',
        'columns' => ['blast_no' => 'Blast No.', 'blast_date' => 'Date|date', 'quarry.name' => 'Quarry', 'tonnage_broken' => 'Tonnage|qty', 'status' => 'Status|badge'],
            'search' => ['blast_no', 'blaster_name'], 'sort' => '-blast_date',
            'transitions' => ['approve' => ['label' => 'Approve blast', 'to' => 'approved', 'from' => ['planned', 'fired'], 'class' => 'ok']],
            'fields' => [
                'blast_no' => ['label' => 'Blast no. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'blast_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'blast_time' => ['label' => 'Time', 'type' => 'time', 'width' => 3],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'bench_id' => ['label' => 'Bench', 'type' => 'select', 'model' => M\PitBench::class, 'label_field' => 'name', 'width' => 3],
                'holes_drilled' => ['label' => 'Holes drilled', 'type' => 'number', 'width' => 3],
                'total_depth_m' => ['label' => 'Total depth (m)', 'type' => 'decimal', 'width' => 3],
                'explosive_used_kg' => ['label' => 'Explosives (kg)', 'type' => 'decimal', 'width' => 3],
                'detonators_used' => ['label' => 'Detonators', 'type' => 'number', 'width' => 3],
                'blaster_name' => ['label' => 'Blaster', 'width' => 3],
                'volume_broken_m3' => ['label' => 'Volume broken (m³)', 'type' => 'decimal', 'width' => 3],
                'tonnage_broken' => ['label' => 'Tonnage broken (t)', 'type' => 'decimal', 'width' => 3],
                'weather' => ['label' => 'Weather', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['planned' => 'Planned', 'fired' => 'Fired', 'approved' => 'Approved'], 'default' => 'planned', 'width' => 3],
                'remarks' => $remarks]],
        'drill-logs' => ['model' => M\DrillLog::class, 'title' => 'Drilling Logs', 'singular' => 'Drill Log', 'perm' => 'quarry',
        'columns' => ['drill_no' => 'Drill No.', 'drill_date' => 'Date|date', 'quarry.name' => 'Quarry', 'pattern' => 'Pattern|badge', 'holes_drilled' => 'Holes', 'total_meters' => 'Meters|qty', 'status' => 'Status|badge'],
        'search' => ['drill_no', 'operator_name'], 'sort' => '-drill_date',
        'transitions' => ['start' => ['label' => 'Start drilling', 'to' => 'in-progress', 'from' => ['planned'], 'class' => 'ok'], 'complete' => ['label' => 'Complete', 'to' => 'completed', 'from' => ['in-progress', 'planned'], 'class' => 'ok']],
        'fields' => [
            'drill_no' => ['label' => 'Drill no. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
            'drill_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
            'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'width' => 3, 'filter' => 1],
            'bench_id' => ['label' => 'Bench', 'type' => 'select', 'model' => M\PitBench::class, 'label_field' => 'name', 'width' => 3],
            'equipment_id' => ['label' => 'Drill rig', 'type' => 'select', 'model' => M\Equipment::class, 'width' => 3],
            'pattern' => ['label' => 'Pattern', 'type' => 'select', 'options' => ['staggered' => 'Staggered', 'square' => 'Square', 'single-row' => 'Single row'], 'default' => 'staggered', 'width' => 3],
            'burden_m' => ['label' => 'Burden (m)', 'type' => 'decimal', 'width' => 3],
            'spacing_m' => ['label' => 'Spacing (m)', 'type' => 'decimal', 'width' => 3],
            'hole_diameter_mm' => ['label' => 'Hole Ø (mm)', 'type' => 'number', 'default' => 89, 'width' => 3],
            'holes_planned' => ['label' => 'Holes planned', 'type' => 'number', 'width' => 3],
            'holes_drilled' => ['label' => 'Holes drilled', 'type' => 'number', 'width' => 3],
            'depth_per_hole_m' => ['label' => 'Depth/hole (m)', 'type' => 'decimal', 'width' => 3],
            'operator_name' => ['label' => 'Operator', 'width' => 3],
            'remarks' => ['label' => 'Remarks', 'type' => 'textarea', 'width' => 9]]],
        'extraction-logs' => ['model' => M\ExtractionLog::class, 'title' => 'Extraction Logs', 'singular' => 'Extraction Log', 'perm' => 'quarry',
            'columns' => ['log_date' => 'Date|date', 'quarry.name' => 'Quarry', 'shift' => 'Shift|badge', 'tonnage_extracted' => 'Tonnes|qty', 'dumper_trips' => 'Trips', 'operator_name' => 'Operator'],
            'search' => ['operator_name'], 'sort' => '-log_date',
            'fields' => [
                'log_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'shift' => ['label' => 'Shift', 'type' => 'select', 'options' => ['day' => 'Day', 'night' => 'Night'], 'default' => 'day', 'width' => 3],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'bench_id' => ['label' => 'Bench', 'type' => 'select', 'model' => M\PitBench::class, 'label_field' => 'name', 'width' => 3],
                'equipment_id' => ['label' => 'Excavator', 'type' => 'select', 'model' => M\Equipment::class, 'width' => 4],
                'dumper_trips' => ['label' => 'Dumper trips', 'type' => 'number', 'width' => 4],
                'tonnage_extracted' => ['label' => 'Tonnes extracted', 'type' => 'decimal', 'width' => 4],
                'overburden_m3' => ['label' => 'Overburden (m³)', 'type' => 'decimal', 'width' => 4],
                'operator_name' => ['label' => 'Operator', 'width' => 4],
                'remarks' => $remarks]],
        'downtime-logs' => ['model' => M\DowntimeLog::class, 'title' => 'Downtime Logs', 'singular' => 'Downtime Log', 'perm' => 'quarry',
            'columns' => ['log_date' => 'Date|date', 'crusherLine.name' => 'Crusher line', 'duration_hours' => 'Hours', 'reason_category' => 'Reason|badge'],
            'search' => ['description'], 'sort' => '-log_date',
            'fields' => [
                'log_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'crusher_line_id' => ['label' => 'Crusher line', 'type' => 'select', 'model' => M\CrusherLine::class, 'width' => 3],
                'equipment_id' => ['label' => 'Equipment (opt.)', 'type' => 'select', 'model' => M\Equipment::class, 'width' => 3],
                'reason_category' => ['label' => 'Reason', 'type' => 'select', 'options' => ['mechanical' => 'Mechanical', 'electrical' => 'Electrical', 'no-feedstock' => 'No feedstock', 'power' => 'Power outage', 'blasting' => 'Blasting', 'weather' => 'Weather', 'other' => 'Other'], 'width' => 3],
                'start_time' => ['label' => 'Start', 'type' => 'time', 'width' => 3],
                'end_time' => ['label' => 'End', 'type' => 'time', 'width' => 3],
                'duration_hours' => ['label' => 'Duration (h)', 'type' => 'decimal', 'width' => 3],
                'resolved_by' => ['label' => 'Resolved by', 'width' => 3],
                'description' => ['label' => 'Description', 'type' => 'textarea', 'rows' => 2, 'width' => 12]]],
        'stockpiles' => ['model' => M\Stockpile::class, 'title' => 'Stockpiles', 'singular' => 'Stockpile', 'perm' => 'quarry',
            'columns' => ['code' => 'Code', 'quarry.name' => 'Quarry', 'product.display_name' => 'Product', 'location' => 'Location', 'current_qty' => 'Stock (t)|qty'],
            'search' => ['code', 'location'], 'sort' => 'code', 'no_delete' => 1,
            'fields' => [
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'filter' => 1],
                'product_id' => ['label' => 'Product', 'type' => 'select', 'model' => M\Product::class, 'required' => 1],
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'stockpiles,code', 'width' => 4],
                'location' => ['label' => 'Location', 'width' => 4],
                'capacity_tonnes' => ['label' => 'Capacity (t)', 'type' => 'decimal', 'width' => 4],
                'current_qty' => ['label' => 'Current qty (t)', 'type' => 'display', 'width' => 4]]],
        'stockpile-movements' => ['model' => M\StockpileMovement::class, 'title' => 'Stockpile Movements', 'singular' => 'Movement', 'perm' => 'quarry',
            'columns' => ['movement_date' => 'Date|date', 'stockpile.code' => 'Stockpile', 'movement_type' => 'Type|badge', 'qty_in' => 'In|qty', 'qty_out' => 'Out|qty', 'balance_after' => 'Balance|qty', 'ref_type' => 'Ref'],
            'search' => ['remarks', 'ref_type'], 'sort' => '-movement_date', 'no_create' => 1, 'no_edit' => 1, 'no_delete' => 1,
            'fields' => []],
        // ═══════════ PRODUCTION ═══════════
        'units' => ['model' => M\Unit::class, 'title' => 'Units of Measure', 'singular' => 'Unit', 'perm' => 'production',
            'columns' => ['name' => 'Name', 'symbol' => 'Symbol', 'is_active' => 'Active|bool'],
            'search' => ['name', 'symbol'], 'sort' => 'name',
            'fields' => ['name' => ['label' => 'Name', 'required' => 1], 'symbol' => ['label' => 'Symbol', 'required' => 1, 'unique' => 'units,symbol', 'width' => 4], 'description' => ['label' => 'Description', 'width' => 5], 'is_active' => $active]],
        'product-categories' => ['model' => M\ProductCategory::class, 'title' => 'Product Categories', 'singular' => 'Category', 'perm' => 'production',
            'columns' => ['code' => 'Code', 'name' => 'Category', 'description' => 'Description'],
            'search' => ['code', 'name'], 'sort' => 'name',
            'fields' => ['code' => ['label' => 'Code', 'required' => 1, 'unique' => 'product_categories,code', 'width' => 4], 'name' => ['label' => 'Name', 'required' => 1, 'width' => 4], 'description' => ['label' => 'Description', 'width' => 4]]],
        'products' => ['model' => M\Product::class, 'title' => 'Products (Aggregates)', 'singular' => 'Product', 'perm' => 'production',
            'columns' => ['code' => 'Code', 'name' => 'Product', 'category.name' => 'Category', 'unit.symbol' => 'Unit', 'standard_rate' => 'Std rate|money', 'is_sellable' => 'Sell|bool', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'name',
            'fields' => [
                'category_id' => ['label' => 'Category', 'type' => 'select', 'model' => M\ProductCategory::class, 'required' => 1, 'filter' => 1],
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'products,code', 'width' => 4],
                'name' => ['label' => 'Product name', 'required' => 1, 'width' => 4],
                'unit_id' => ['label' => 'Unit', 'type' => 'select', 'model' => M\Unit::class, 'required' => 1, 'width' => 4],
                'description' => ['label' => 'Description', 'width' => 6],
                'standard_rate' => ['label' => 'Standard rate (GH₵)', 'type' => 'decimal', 'width' => 3],
                'cost_rate' => ['label' => 'Cost rate (GH₵)', 'type' => 'decimal', 'width' => 3],
                'min_stock_level' => ['label' => 'Min stock (t)', 'type' => 'decimal', 'width' => 3],
                'taxable' => ['label' => 'Taxable', 'type' => 'checkbox', 'default' => 1, 'width' => 3],
                'is_sellable' => ['label' => 'Sellable', 'type' => 'checkbox', 'default' => 1, 'width' => 3],
                'is_active' => $active]],
        'production-entries' => ['model' => M\ProductionEntry::class, 'title' => 'Daily Production', 'singular' => 'Production Entry', 'perm' => 'production',
            'columns' => ['entry_no' => 'Entry', 'entry_date' => 'Date|date', 'quarry.name' => 'Quarry', 'crusherLine.name' => 'Line', 'product.display_name' => 'Product', 'produced_tonnes' => 'Tonnes|qty', 'status' => 'Status|badge'],
            'search' => ['entry_no'], 'sort' => '-entry_date', 'dedicated' => 'production',
            'fields' => []],
        'qc-tests' => ['model' => M\QcTest::class, 'title' => 'QC Lab Tests', 'singular' => 'QC Test', 'perm' => 'production',
            'columns' => ['test_no' => 'Test', 'test_date' => 'Date|date', 'product.display_name' => 'Product', 'los_angeles_abrasion' => 'LAAV', 'aggregate_crushing_value' => 'ACV', 'verdict' => 'Verdict|badge'],
            'search' => ['test_no'], 'sort' => '-test_date',
            'transitions' => ['pass' => ['label' => 'Pass', 'to' => 'pass', 'from' => ['pending', 'conditional'], 'class' => 'ok'], 'fail' => ['label' => 'Fail', 'to' => 'fail', 'from' => ['pending', 'conditional'], 'class' => 'danger']],
            'fields' => [
                'test_no' => ['label' => 'Test no. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'test_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'product_id' => ['label' => 'Product', 'type' => 'select', 'model' => M\Product::class, 'required' => 1, 'width' => 3],
                'stockpile_id' => ['label' => 'Stockpile', 'type' => 'select', 'model' => M\Stockpile::class, 'width' => 3],
                'sample_source' => ['label' => 'Sample source', 'type' => 'select', 'options' => ['stockpile' => 'Stockpile', 'dispatch' => 'Dispatch', 'project' => 'Project', 'supplier' => 'Supplier'], 'default' => 'stockpile', 'width' => 3],
                'gradation_pass' => ['label' => 'Gradation pass', 'type' => 'checkbox', 'width' => 3],
                'flakiness_index' => ['label' => 'Flakiness index', 'type' => 'decimal', 'width' => 3],
                'los_angeles_abrasion' => ['label' => 'LAAV (%)', 'type' => 'decimal', 'width' => 3],
                'aggregate_crushing_value' => ['label' => 'ACV (%)', 'type' => 'decimal', 'width' => 3],
                'water_absorption' => ['label' => 'Water absorp. (%)', 'type' => 'decimal', 'width' => 3],
                'silt_content' => ['label' => 'Silt (%)', 'type' => 'decimal', 'width' => 3],
                'tested_by' => ['label' => 'Tested by', 'width' => 3],
                'verdict' => ['label' => 'Verdict', 'type' => 'select', 'options' => ['pending' => 'Pending', 'pass' => 'Pass', 'conditional' => 'Conditional', 'fail' => 'Fail'], 'default' => 'pending', 'width' => 3],
                'remarks' => $remarks]],
        // ═══════════ INVENTORY ═══════════
        'warehouses' => ['model' => M\Warehouse::class, 'title' => 'Warehouses / Stores', 'singular' => 'Warehouse', 'perm' => 'inventory',
            'columns' => ['code' => 'Code', 'name' => 'Store', 'quarry.name' => 'Quarry', 'location' => 'Location', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'name',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'warehouses,code', 'width' => 3],
                'name' => ['label' => 'Store name', 'required' => 1, 'width' => 5],
                'quarry_id' => ['label' => 'Quarry (site store)', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 4],
                'location' => ['label' => 'Location', 'width' => 5],
                'keeper_name' => ['label' => 'Store keeper', 'width' => 4],
                'is_active' => $active]],
        'stock-items' => ['model' => M\StockItem::class, 'title' => 'Stock Items (Spares, Fuel, Consumables)', 'singular' => 'Stock Item', 'perm' => 'inventory',
            'columns' => ['code' => 'Code', 'name' => 'Item', 'category' => 'Category|badge', 'unit.symbol' => 'Unit', 'current_qty' => 'On hand|qty', 'reorder_level' => 'Reorder|qty', 'avg_cost_rate' => 'Avg cost|money'],
            'search' => ['code', 'name'], 'sort' => 'name',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'stock_items,code', 'width' => 3],
                'name' => ['label' => 'Item name', 'required' => 1, 'width' => 5],
                'category' => ['label' => 'Category', 'type' => 'select', 'options' => ['spare-part' => 'Spare part', 'fuel-lubricant' => 'Fuel / Lubricant', 'explosive' => 'Explosive', 'consumable' => 'Consumable', 'raw-material' => 'Raw material', 'ppe' => 'PPE', 'other' => 'Other'], 'default' => 'consumable', 'width' => 4, 'filter' => 1],
                'unit_id' => ['label' => 'Unit', 'type' => 'select', 'model' => M\Unit::class, 'required' => 1, 'width' => 3],
                'default_warehouse_id' => ['label' => 'Default store', 'type' => 'select', 'model' => M\Warehouse::class, 'width' => 3],
                'reorder_level' => ['label' => 'Reorder level', 'type' => 'decimal', 'width' => 3],
                'max_level' => ['label' => 'Max level', 'type' => 'decimal', 'width' => 3],
                'current_qty' => ['label' => 'On hand', 'type' => 'display', 'width' => 3],
                'is_active' => $active]],
        'stock-ledgers' => ['model' => M\StockLedger::class, 'title' => 'Stock Ledger', 'singular' => 'Ledger Entry', 'perm' => 'inventory',
            'columns' => ['txn_date' => 'Date|date', 'item.display_name' => 'Item', 'warehouse.name' => 'Store', 'txn_type' => 'Type|badge', 'qty_in' => 'In|qty', 'qty_out' => 'Out|qty', 'balance_after' => 'Balance|qty'],
            'search' => ['ref_type', 'remarks'], 'sort' => '-txn_date', 'no_create' => 1, 'no_edit' => 1, 'no_delete' => 1, 'fields' => []],
        'stock-adjustments' => ['model' => M\StockAdjustment::class, 'title' => 'Stock Adjustments (Count)', 'singular' => 'Adjustment', 'perm' => 'inventory',
            'columns' => ['adjustment_no' => 'Adj No.', 'adjustment_date' => 'Date|date', 'warehouse.name' => 'Store', 'reason' => 'Reason', 'status' => 'Status|badge'],
            'search' => ['adjustment_no'], 'sort' => '-adjustment_date', 'dedicated' => 'stock-adjustments', 'fields' => []],
        'explosives-registers' => ['model' => M\ExplosivesRegister::class, 'title' => 'Explosives Magazine Register', 'singular' => 'Register Entry', 'perm' => 'inventory',
            'columns' => ['register_date' => 'Date|date', 'quarry.name' => 'Quarry', 'explosive_type' => 'Type', 'opening_balance' => 'Opening|qty', 'received_qty' => 'Received|qty', 'issued_qty' => 'Issued|qty', 'closing_balance' => 'Closing|qty'],
            'search' => ['explosive_type', 'permit_no'], 'sort' => '-register_date',
            'fields' => [
                'register_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'magazine' => ['label' => 'Magazine', 'default' => 'Main Magazine', 'width' => 3],
                'explosive_type' => ['label' => 'Explosive type', 'type' => 'select', 'options' => ['ANFO' => 'ANFO', 'Emulsion' => 'Emulsion', 'Detonator' => 'Detonator', 'Cordtex' => 'Cordtex', 'Booster' => 'Booster', 'Other' => 'Other'], 'required' => 1, 'width' => 3],
                'unit' => ['label' => 'Unit', 'default' => 'kg', 'width' => 3],
                'opening_balance' => ['label' => 'Opening', 'type' => 'decimal', 'width' => 3],
                'received_qty' => ['label' => 'Received', 'type' => 'decimal', 'width' => 3],
                'issued_qty' => ['label' => 'Issued', 'type' => 'decimal', 'width' => 3],
                'issued_to' => ['label' => 'Issued to (blaster)', 'width' => 3],
                'blast_log_id' => ['label' => 'Blast log', 'type' => 'select', 'model' => M\BlastLog::class, 'label_field' => 'blast_no', 'width' => 3],
                'permit_no' => ['label' => 'Permit no.', 'width' => 3],
                'remarks' => $remarks]],
        // ═══════════ FLEET ═══════════
        'equipment' => ['model' => M\Equipment::class, 'title' => 'Fleet & Equipment Register', 'singular' => 'Equipment', 'perm' => 'fleet',
            'columns' => ['code' => 'Code', 'name' => 'Equipment', 'category' => 'Category|badge', 'registration_no' => 'Reg No.', 'current_hours' => 'Hours', 'status' => 'Status|badge'],
            'search' => ['code', 'name', 'registration_no', 'serial_no'], 'sort' => 'code',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'equipment,code', 'width' => 3],
                'name' => ['label' => 'Equipment name', 'required' => 1, 'width' => 5],
                'category' => ['label' => 'Category', 'type' => 'select', 'options' => ['excavator' => 'Excavator', 'wheel-loader' => 'Wheel loader', 'dump-truck' => 'Dump truck', 'dozer' => 'Dozer', 'drill-rig' => 'Drill rig', 'crusher' => 'Crusher', 'generator' => 'Generator', 'water-bowser' => 'Water bowser', 'pickup' => 'Pickup', 'compactor' => 'Compactor', 'other' => 'Other'], 'width' => 4, 'filter' => 1],
                'make' => ['label' => 'Make', 'width' => 3], 'model_no' => ['label' => 'Model', 'width' => 3],
                'year_of_manufacture' => ['label' => 'Year', 'type' => 'number', 'width' => 3],
                'serial_no' => ['label' => 'Serial / Chassis', 'width' => 3],
                'engine_no' => ['label' => 'Engine no.', 'width' => 3],
                'registration_no' => ['label' => 'Registration', 'width' => 3],
                'ownership' => ['label' => 'Ownership', 'type' => 'select', 'options' => ['owned' => 'Owned', 'leased' => 'Leased', 'hired' => 'Hired'], 'default' => 'owned', 'width' => 3],
                'purchase_date' => ['label' => 'Purchase date', 'type' => 'date', 'width' => 3],
                'purchase_cost' => ['label' => 'Purchase cost', 'type' => 'decimal', 'width' => 3],
                'current_quarry_id' => ['label' => 'Current quarry', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['available' => 'Available', 'deployed' => 'Deployed', 'down-maintenance' => 'Down – maintenance', 'standby' => 'Standby', 'disposed' => 'Disposed'], 'default' => 'available', 'width' => 3],
                'meter_type' => ['label' => 'Meter', 'type' => 'select', 'options' => ['hours' => 'Hours', 'km' => 'KM', 'both' => 'Both'], 'default' => 'hours', 'width' => 3],
                'current_hours' => ['label' => 'Current hours', 'type' => 'decimal', 'width' => 3],
                'current_km' => ['label' => 'Current KM', 'type' => 'decimal', 'width' => 3],
                'fuel_type' => ['label' => 'Fuel', 'type' => 'select', 'options' => ['diesel' => 'Diesel', 'petrol' => 'Petrol', 'electric' => 'Electric'], 'default' => 'diesel', 'width' => 3],
                'operator_name' => ['label' => 'Operator', 'width' => 3],
                'is_active' => $active]],
        'equipment-documents' => ['model' => M\EquipmentDocument::class, 'title' => 'Equipment Documents (Insurance, Roadworthy)', 'singular' => 'Document', 'perm' => 'fleet',
            'columns' => ['equipment.display_name' => 'Equipment', 'doc_type' => 'Type|badge', 'doc_no' => 'Doc No.', 'expiry_date' => 'Expiry|date', 'cost' => 'Cost|money'],
            'search' => ['doc_no'], 'sort' => 'expiry_date',
            'fields' => [
                'equipment_id' => ['label' => 'Equipment', 'type' => 'select', 'model' => M\Equipment::class, 'required' => 1, 'filter' => 1],
                'doc_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['insurance' => 'Insurance', 'roadworthy' => 'Roadworthy', 'permit' => 'Permit', 'service' => 'Service certificate', 'other' => 'Other'], 'required' => 1, 'width' => 4],
                'doc_no' => ['label' => 'Doc no.', 'width' => 4],
                'issued_by' => ['label' => 'Issued by', 'width' => 4],
                'issue_date' => ['label' => 'Issue date', 'type' => 'date', 'width' => 4],
                'expiry_date' => ['label' => 'Expiry date', 'type' => 'date', 'width' => 4],
                'cost' => ['label' => 'Cost', 'type' => 'decimal', 'width' => 4]]],
        'meter-readings' => ['model' => M\MeterReading::class, 'title' => 'Meter Readings', 'singular' => 'Reading', 'perm' => 'fleet',
            'columns' => ['reading_date' => 'Date|date', 'equipment.display_name' => 'Equipment', 'meter_type' => 'Meter|badge', 'reading_value' => 'Reading', 'previous_value' => 'Previous'],
            'search' => [], 'sort' => '-reading_date',
            'fields' => [
                'equipment_id' => ['label' => 'Equipment', 'type' => 'select', 'model' => M\Equipment::class, 'required' => 1, 'filter' => 1],
                'reading_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'default' => 'today'],
                'meter_type' => ['label' => 'Meter', 'type' => 'select', 'options' => ['hours' => 'Hours', 'km' => 'KM'], 'default' => 'hours'],
                'reading_value' => ['label' => 'Reading', 'type' => 'decimal', 'required' => 1],
                'source' => ['label' => 'Source', 'type' => 'select', 'options' => ['manual' => 'Manual', 'fuel-log' => 'Fuel log', 'trip-log' => 'Trip log'], 'default' => 'manual'],
                'recorded_by' => ['label' => 'Recorded by']]],
        'fuel-logs' => ['model' => M\FuelLog::class, 'title' => 'Fuel Logs', 'singular' => 'Fuel Log', 'perm' => 'fleet',
            'columns' => ['log_no' => 'Log', 'log_date' => 'Date|date', 'equipment.display_name' => 'Equipment', 'qty_litres' => 'Litres|qty', 'amount' => 'Amount|money'],
            'search' => ['log_no', 'receipt_no'], 'sort' => '-log_date',
            'fields' => [
                'log_no' => ['label' => 'Log no. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'log_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'equipment_id' => ['label' => 'Equipment', 'type' => 'select', 'model' => M\Equipment::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'warehouse_id' => ['label' => 'Fuel store', 'type' => 'select', 'model' => M\Warehouse::class, 'width' => 3],
                'fuel_type' => ['label' => 'Fuel', 'type' => 'select', 'options' => ['diesel' => 'Diesel', 'petrol' => 'Petrol'], 'default' => 'diesel', 'width' => 3],
                'qty_litres' => ['label' => 'Qty (L)', 'type' => 'decimal', 'required' => 1, 'width' => 3],
                'rate_per_litre' => ['label' => 'Rate/L', 'type' => 'decimal', 'width' => 3],
                'meter_hours' => ['label' => 'Meter hours', 'type' => 'decimal', 'width' => 3],
                'meter_km' => ['label' => 'Meter KM', 'type' => 'decimal', 'width' => 3],
                'issued_by' => ['label' => 'Issued by', 'width' => 3],
                'received_by' => ['label' => 'Received by', 'width' => 3],
                'receipt_no' => ['label' => 'Receipt no.', 'width' => 3]]],
        'trip-logs' => ['model' => M\TripLog::class, 'title' => 'Trip Logs', 'singular' => 'Trip', 'perm' => 'fleet',
            'columns' => ['trip_no' => 'Trip', 'trip_date' => 'Date|date', 'equipment.display_name' => 'Truck', 'from_location' => 'From', 'to_location' => 'To', 'tonnage' => 'Tonnes|qty', 'trips_count' => 'Trips'],
            'search' => ['trip_no', 'from_location', 'to_location'], 'sort' => '-trip_date',
            'fields' => [
                'trip_no' => ['label' => 'Trip no. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'trip_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'equipment_id' => ['label' => 'Truck', 'type' => 'select', 'model' => M\Equipment::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'product_id' => ['label' => 'Material', 'type' => 'select', 'model' => M\Product::class, 'width' => 3],
                'from_location' => ['label' => 'From', 'width' => 3], 'to_location' => ['label' => 'To', 'width' => 3],
                'customer_id' => ['label' => 'Customer', 'type' => 'select', 'model' => M\Customer::class, 'width' => 3],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'width' => 3],
                'trips_count' => ['label' => 'Trips', 'type' => 'number', 'default' => 1, 'width' => 3],
                'tonnage' => ['label' => 'Tonnage', 'type' => 'decimal', 'width' => 3],
                'start_km' => ['label' => 'Start KM', 'type' => 'decimal', 'width' => 3],
                'end_km' => ['label' => 'End KM', 'type' => 'decimal', 'width' => 3],
                'driver_name' => ['label' => 'Driver', 'width' => 3],
                'transport_cost' => ['label' => 'Transport cost', 'type' => 'decimal', 'width' => 3],
                'remarks' => $remarks]],
        'maintenance-work-orders' => ['model' => M\MaintenanceWorkOrder::class, 'title' => 'Maintenance Work Orders', 'singular' => 'Work Order', 'perm' => 'fleet',
            'columns' => ['wo_no' => 'WO', 'reported_date' => 'Reported|date', 'equipment.display_name' => 'Equipment', 'maintenance_type' => 'Type|badge', 'priority' => 'Priority|badge', 'total_cost' => 'Cost|money', 'status' => 'Status|badge'],
            'search' => ['wo_no'], 'sort' => '-reported_date', 'dedicated' => 'work-orders', 'fields' => []],
        'maintenance-schedules' => ['model' => M\MaintenanceSchedule::class, 'title' => 'Preventive Maintenance Schedules', 'singular' => 'Schedule', 'perm' => 'fleet',
            'columns' => ['equipment.display_name' => 'Equipment', 'service_type' => 'Service', 'interval_value' => 'Every', 'interval_unit' => 'Unit', 'next_due_date' => 'Due|date', 'is_active' => 'Active|bool'],
            'search' => ['service_type'], 'sort' => 'next_due_date',
            'fields' => [
                'equipment_id' => ['label' => 'Equipment', 'type' => 'select', 'model' => M\Equipment::class, 'required' => 1, 'filter' => 1],
                'service_type' => ['label' => 'Service type', 'required' => 1, 'placeholder' => 'e.g. 250-hour service'],
                'interval_value' => ['label' => 'Interval', 'type' => 'decimal', 'required' => 1, 'width' => 4],
                'interval_unit' => ['label' => 'Unit', 'type' => 'select', 'options' => ['hours' => 'Hours', 'km' => 'KM', 'days' => 'Days'], 'default' => 'hours', 'width' => 4],
                'last_service_date' => ['label' => 'Last service', 'type' => 'date', 'width' => 4],
                'last_service_meter' => ['label' => 'Last meter', 'type' => 'decimal', 'width' => 4],
                'next_due_date' => ['label' => 'Next due', 'type' => 'date', 'width' => 4],
                'next_due_meter' => ['label' => 'Due at meter', 'type' => 'decimal', 'width' => 4],
                'is_active' => $active]],
        // ═══════════ SALES ═══════════
        'customers' => ['model' => M\Customer::class, 'title' => 'Customers', 'singular' => 'Customer', 'perm' => 'sales',
            'columns' => ['code' => 'Code', 'name' => 'Customer', 'customer_type' => 'Type|badge', 'phone' => 'Phone', 'current_balance' => 'Balance|money', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name', 'phone'], 'sort' => 'name',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'customers,code', 'width' => 3],
                'name' => ['label' => 'Customer name', 'required' => 1, 'width' => 5],
                'customer_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['company' => 'Company', 'individual' => 'Individual', 'government' => 'Government'], 'default' => 'company', 'width' => 4, 'filter' => 1],
                'default_currency' => ['label' => 'Currency', 'default' => 'GHS', 'width' => 3],
                'contact_person' => ['label' => 'Contact person', 'width' => 4],
                'phone' => ['label' => 'Phone', 'width' => 4], 'phone2' => ['label' => 'Phone 2', 'width' => 4],
                'email' => ['label' => 'Email', 'type' => 'email', 'width' => 4],
                'address' => ['label' => 'Address', 'width' => 4], 'city' => ['label' => 'City', 'width' => 4],
                'region' => ['label' => 'Region', 'width' => 4], 'tin' => ['label' => 'TIN', 'width' => 4],
                'price_list_id' => ['label' => 'Price list', 'type' => 'select', 'model' => M\PriceList::class, 'width' => 4],
                'credit_limit' => ['label' => 'Credit limit', 'type' => 'decimal', 'width' => 4],
                'payment_terms_days' => ['label' => 'Terms (days)', 'type' => 'number', 'default' => 30, 'width' => 4],
                'opening_balance' => ['label' => 'Opening balance', 'type' => 'decimal', 'width' => 4],
                'current_balance' => ['label' => 'Current balance', 'type' => 'display', 'width' => 4],
                'is_active' => $active]],
        'transporters' => ['model' => M\Transporter::class, 'title' => 'Transporters', 'singular' => 'Transporter', 'perm' => 'sales',
            'columns' => ['name' => 'Transporter', 'contact_person' => 'Contact', 'phone' => 'Phone', 'vehicle_no' => 'Vehicle', 'rate_per_tonne' => 'Rate/t|money'],
            'search' => ['name', 'phone', 'vehicle_no'], 'sort' => 'name',
            'fields' => [
                'name' => ['label' => 'Name', 'required' => 1], 'contact_person' => ['label' => 'Contact person'],
                'phone' => ['label' => 'Phone', 'width' => 4], 'vehicle_no' => ['label' => 'Vehicle no.', 'width' => 4],
                'rate_per_tonne' => ['label' => 'Rate/tonne', 'type' => 'decimal', 'width' => 4], 'is_active' => $active]],
        'price-lists' => ['model' => M\PriceList::class, 'title' => 'Price Lists', 'singular' => 'Price List', 'perm' => 'sales',
            'columns' => ['name' => 'List', 'effective_from' => 'From|date', 'effective_to' => 'To|date', 'is_default' => 'Default|bool', 'is_active' => 'Active|bool'],
            'search' => ['name'], 'sort' => 'name',
            'fields' => [
                'name' => ['label' => 'Name', 'required' => 1], 'currency' => ['label' => 'Currency', 'default' => 'GHS', 'width' => 4],
                'effective_from' => ['label' => 'Effective from', 'type' => 'date', 'required' => 1, 'width' => 4, 'default' => 'today'],
                'effective_to' => ['label' => 'Effective to', 'type' => 'date', 'width' => 4],
                'is_default' => ['label' => 'Default', 'type' => 'checkbox', 'width' => 3], 'is_active' => $active]],
        'price-list-lines' => ['model' => M\PriceListLine::class, 'title' => 'Price List Lines', 'singular' => 'Price Line', 'perm' => 'sales',
            'columns' => ['priceList.name' => 'List', 'product.display_name' => 'Product', 'rate_per_tonne' => 'Rate/t|money', 'min_qty' => 'Min qty|qty'],
            'search' => [], 'sort' => 'id',
            'fields' => [
                'price_list_id' => ['label' => 'Price list', 'type' => 'select', 'model' => M\PriceList::class, 'required' => 1, 'filter' => 1],
                'product_id' => ['label' => 'Product', 'type' => 'select', 'model' => M\Product::class, 'required' => 1],
                'rate_per_tonne' => ['label' => 'Rate/tonne', 'type' => 'decimal', 'required' => 1],
                'min_qty' => ['label' => 'Min qty', 'type' => 'decimal']]],
        'quotations' => ['model' => M\Quotation::class, 'title' => 'Quotations', 'singular' => 'Quotation', 'perm' => 'sales',
            'columns' => ['quotation_no' => 'Quote', 'quotation_date' => 'Date|date', 'customer.display_name' => 'Customer', 'grand_total' => 'Total|money', 'status' => 'Status|badge'],
            'search' => ['quotation_no', 'subject'], 'sort' => '-quotation_date', 'dedicated' => 'quotations', 'fields' => []],
        'sales-orders' => ['model' => M\SalesOrder::class, 'title' => 'Sales Orders', 'singular' => 'Sales Order', 'perm' => 'sales',
            'columns' => ['order_no' => 'Order', 'order_date' => 'Date|date', 'customer.display_name' => 'Customer', 'grand_total' => 'Total|money', 'status' => 'Status|badge'],
            'search' => ['order_no'], 'sort' => '-order_date', 'dedicated' => 'sales-orders', 'fields' => []],
        'weighbridge-tickets' => ['model' => M\WeighbridgeTicket::class, 'title' => 'Weighbridge Tickets', 'singular' => 'Ticket', 'perm' => 'sales',
            'columns' => ['ticket_no' => 'Ticket', 'ticket_date' => 'Date|date', 'vehicle_no' => 'Vehicle', 'transaction_type' => 'Type|badge', 'gross_weight' => 'Gross|qty', 'tare_weight' => 'Tare|qty', 'net_weight' => 'Net|qty', 'status' => 'Status|badge'],
            'search' => ['ticket_no', 'vehicle_no', 'driver_name'], 'sort' => '-ticket_date', 'dedicated' => 'weighbridge', 'fields' => []],
        'delivery-notes' => ['model' => M\DeliveryNote::class, 'title' => 'Delivery Notes / Dispatch', 'singular' => 'Delivery Note', 'perm' => 'sales',
            'columns' => ['dn_no' => 'DN', 'dn_date' => 'Date|date', 'customer.display_name' => 'Customer', 'vehicle_no' => 'Vehicle', 'gate_pass_no' => 'Gate pass', 'grand_total' => 'Total|money', 'status' => 'Status|badge'],
            'search' => ['dn_no', 'vehicle_no', 'gate_pass_no'], 'sort' => '-dn_date', 'dedicated' => 'delivery', 'fields' => []],
        'sales-invoices' => ['model' => M\SalesInvoice::class, 'title' => 'Sales Invoices', 'singular' => 'Invoice', 'perm' => 'sales',
            'columns' => ['invoice_no' => 'Invoice', 'invoice_date' => 'Date|date', 'customer.display_name' => 'Customer', 'grand_total' => 'Total|money', 'balance_due' => 'Due|money', 'status' => 'Status|badge'],
            'search' => ['invoice_no'], 'sort' => '-invoice_date', 'dedicated' => 'sales-invoices', 'fields' => []],
        'customer-payments' => ['model' => M\CustomerPayment::class, 'title' => 'Customer Receipts', 'singular' => 'Receipt', 'perm' => 'sales',
            'columns' => ['receipt_no' => 'Receipt', 'payment_date' => 'Date|date', 'customer.display_name' => 'Customer', 'invoice.invoice_no' => 'Invoice', 'amount' => 'Amount|money', 'payment_mode' => 'Mode|badge'],
            'search' => ['receipt_no', 'reference', 'cheque_no'], 'sort' => '-payment_date', 'dedicated' => 'customer-payments', 'fields' => []],
        'sales-credit-notes' => ['model' => M\SalesCreditNote::class, 'title' => 'Sales Credit Notes', 'singular' => 'Credit Note', 'perm' => 'sales',
            'columns' => ['cn_no' => 'CN', 'cn_date' => 'Date|date', 'customer.display_name' => 'Customer', 'amount' => 'Amount|money', 'status' => 'Status|badge'],
            'search' => ['cn_no'], 'sort' => '-cn_date', 'dedicated' => 'credit-notes', 'fields' => []],
        // ═══════════ PURCHASE ═══════════
        'suppliers' => ['model' => M\Supplier::class, 'title' => 'Suppliers / Vendors', 'singular' => 'Supplier', 'perm' => 'purchase',
            'columns' => ['code' => 'Code', 'name' => 'Supplier', 'supplier_type' => 'Type|badge', 'phone' => 'Phone', 'current_balance' => 'Balance|money', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name', 'phone'], 'sort' => 'name',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'suppliers,code', 'width' => 3],
                'name' => ['label' => 'Supplier name', 'required' => 1, 'width' => 5],
                'supplier_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['materials' => 'Materials', 'fuel' => 'Fuel', 'explosives' => 'Explosives', 'spares' => 'Spares', 'services' => 'Services', 'contractor' => 'Contractor', 'other' => 'Other'], 'default' => 'materials', 'width' => 4, 'filter' => 1],
                'contact_person' => ['label' => 'Contact person', 'width' => 4],
                'phone' => ['label' => 'Phone', 'width' => 4], 'email' => ['label' => 'Email', 'type' => 'email', 'width' => 4],
                'address' => ['label' => 'Address', 'width' => 4], 'city' => ['label' => 'City', 'width' => 4], 'tin' => ['label' => 'TIN', 'width' => 4],
                'payment_terms_days' => ['label' => 'Terms (days)', 'type' => 'number', 'default' => 30, 'width' => 4],
                'opening_balance' => ['label' => 'Opening balance', 'type' => 'decimal', 'width' => 4],
                'current_balance' => ['label' => 'Current balance', 'type' => 'display', 'width' => 4],
                'is_active' => $active,
                'default_currency' => ['label' => 'Currency', 'default' => 'GHS', 'width' => 3]]],
        'purchase-requisitions' => ['model' => M\PurchaseRequisition::class, 'title' => 'Purchase Requisitions', 'singular' => 'Requisition', 'perm' => 'purchase',
            'columns' => ['pr_no' => 'PR', 'pr_date' => 'Date|date', 'requester.name' => 'Requested by', 'purpose' => 'Purpose', 'status' => 'Status|badge'],
            'search' => ['pr_no', 'purpose'], 'sort' => '-pr_date', 'dedicated' => 'purchase-requisitions', 'approval_type' => 'purchase_requisition', 'fields' => []],
        'purchase-orders' => ['model' => M\PurchaseOrder::class, 'title' => 'Purchase Orders (LPO)', 'singular' => 'Purchase Order', 'perm' => 'purchase',
            'columns' => ['po_no' => 'LPO', 'po_date' => 'Date|date', 'supplier.display_name' => 'Supplier', 'grand_total' => 'Total|money', 'status' => 'Status|badge'],
            'search' => ['po_no'], 'sort' => '-po_date', 'dedicated' => 'purchase-orders', 'approval_type' => 'purchase_order', 'fields' => []],
        'goods-receipts' => ['model' => M\GoodsReceipt::class, 'title' => 'Goods Received Notes (GRN)', 'singular' => 'GRN', 'perm' => 'purchase',
            'columns' => ['grn_no' => 'GRN', 'grn_date' => 'Date|date', 'supplier.display_name' => 'Supplier', 'warehouse.name' => 'Store', 'status' => 'Status|badge'],
            'search' => ['grn_no'], 'sort' => '-grn_date', 'dedicated' => 'goods-receipts', 'fields' => []],
        'purchase-invoices' => ['model' => M\PurchaseInvoice::class, 'title' => 'Supplier Bills', 'singular' => 'Supplier Bill', 'perm' => 'purchase',
            'columns' => ['pin_no' => 'Bill', 'invoice_date' => 'Date|date', 'supplier.display_name' => 'Supplier', 'grand_total' => 'Total|money', 'balance_due' => 'Due|money', 'status' => 'Status|badge'],
            'search' => ['pin_no', 'supplier_invoice_no'], 'sort' => '-invoice_date', 'dedicated' => 'purchase-invoices', 'fields' => []],
        'supplier-payments' => ['model' => M\SupplierPayment::class, 'title' => 'Supplier Payments', 'singular' => 'Payment', 'perm' => 'purchase',
            'columns' => ['payment_no' => 'Payment', 'payment_date' => 'Date|date', 'supplier.display_name' => 'Supplier', 'invoice.pin_no' => 'Bill', 'amount' => 'Amount|money', 'payment_mode' => 'Mode|badge'],
            'search' => ['payment_no', 'reference', 'cheque_no'], 'sort' => '-payment_date', 'dedicated' => 'supplier-payments', 'fields' => []],
        // ═══════════ PROJECTS ═══════════
        'projects' => ['model' => M\Project::class, 'title' => 'Construction Projects', 'singular' => 'Project', 'perm' => 'projects',
            'columns' => ['code' => 'Code', 'name' => 'Project', 'client_name' => 'Client', 'contract_value' => 'Contract|money', 'progress_percent' => 'Prog %', 'status' => 'Status|badge'],
            'search' => ['code', 'name', 'client_name'], 'sort' => 'name',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'projects,code', 'width' => 3],
                'name' => ['label' => 'Project name', 'required' => 1, 'width' => 5],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['tender' => 'Tender', 'awarded' => 'Awarded', 'mobilization' => 'Mobilization', 'active' => 'Active', 'on-hold' => 'On hold', 'completed' => 'Completed', 'closed' => 'Closed'], 'default' => 'active', 'width' => 4, 'filter' => 1],
                'client_name' => ['label' => 'Client name', 'width' => 4],
                'client_id' => ['label' => 'Client (customer)', 'type' => 'select', 'model' => M\Customer::class, 'width' => 4],
                'contract_no' => ['label' => 'Contract no.', 'width' => 4],
                'contract_value' => ['label' => 'Contract value', 'type' => 'decimal', 'width' => 4],
                'location' => ['label' => 'Location', 'width' => 4], 'region' => ['label' => 'Region', 'width' => 4],
                'start_date' => ['label' => 'Start', 'type' => 'date', 'width' => 3], 'end_date' => ['label' => 'End', 'type' => 'date', 'width' => 3],
                'actual_end_date' => ['label' => 'Actual end', 'type' => 'date', 'width' => 3],
                'project_manager' => ['label' => 'Project manager', 'width' => 3],
                'progress_percent' => ['label' => 'Progress %', 'type' => 'decimal', 'width' => 3],
                'retention_percent' => ['label' => 'Retention %', 'type' => 'decimal', 'default' => 5, 'width' => 3],
                'description' => ['label' => 'Description', 'type' => 'textarea', 'rows' => 2, 'width' => 9],
                'is_active' => $active]],
        'boq-items' => ['model' => M\BoqItem::class, 'title' => 'BOQ Items', 'singular' => 'BOQ Item', 'perm' => 'projects',
            'columns' => ['project.display_name' => 'Project', 'item_no' => 'Item', 'description' => 'Description', 'qty' => 'Qty|qty', 'rate' => 'Rate|money', 'amount' => 'Amount|money', 'qty_executed' => 'Exec.|qty'],
            'search' => ['item_no', 'description'], 'sort' => 'item_no',
            'fields' => [
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'required' => 1, 'width' => 4, 'filter' => 1],
                'item_no' => ['label' => 'Item no.', 'required' => 1, 'width' => 4],
                'unit' => ['label' => 'Unit', 'default' => 'lot', 'width' => 4],
                'description' => ['label' => 'Description', 'type' => 'textarea', 'rows' => 2, 'required' => 1, 'width' => 12],
                'qty' => ['label' => 'Qty', 'type' => 'decimal', 'width' => 4], 'rate' => ['label' => 'Rate', 'type' => 'decimal', 'width' => 4],
                'amount' => ['label' => 'Amount (= qty × rate)', 'type' => 'decimal', 'width' => 4],
                'qty_executed' => ['label' => 'Qty executed', 'type' => 'decimal', 'width' => 4],
                'amount_executed' => ['label' => 'Amount executed', 'type' => 'decimal', 'width' => 4]]],
        'project-tasks' => ['model' => M\ProjectTask::class, 'title' => 'Project Tasks (WBS)', 'singular' => 'Task', 'perm' => 'projects',
            'columns' => ['project.display_name' => 'Project', 'wbs_code' => 'WBS', 'task_name' => 'Task', 'assigned_to' => 'Assigned', 'progress_percent' => 'Prog %', 'status' => 'Status|badge'],
            'search' => ['task_name', 'wbs_code'], 'sort' => 'wbs_code',
            'fields' => [
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'required' => 1, 'width' => 4, 'filter' => 1],
                'parent_id' => ['label' => 'Parent task', 'type' => 'select', 'model' => M\ProjectTask::class, 'label_field' => 'task_name', 'width' => 4],
                'wbs_code' => ['label' => 'WBS code', 'width' => 4],
                'task_name' => ['label' => 'Task name', 'required' => 1, 'width' => 6],
                'assigned_to' => ['label' => 'Assigned to', 'width' => 3],
                'start_date' => ['label' => 'Start', 'type' => 'date', 'width' => 3], 'end_date' => ['label' => 'End', 'type' => 'date', 'width' => 3],
                'progress_percent' => ['label' => 'Progress %', 'type' => 'decimal', 'width' => 3],
                'weight_factor' => ['label' => 'Weight', 'type' => 'decimal', 'default' => 1, 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['not-started' => 'Not started', 'in-progress' => 'In progress', 'delayed' => 'Delayed', 'completed' => 'Completed'], 'default' => 'not-started', 'width' => 3],
                'remarks' => $remarks]],
        'site-diaries' => ['model' => M\SiteDiary::class, 'title' => 'Site Diaries', 'singular' => 'Site Diary', 'perm' => 'projects',
            'columns' => ['project.display_name' => 'Project', 'diary_date' => 'Date|date', 'weather' => 'Weather', 'labour_count' => 'Labour', 'prepared_by' => 'Prepared by'],
            'search' => ['work_progress'], 'sort' => '-diary_date',
            'fields' => [
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'required' => 1, 'width' => 4, 'filter' => 1],
                'diary_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 4, 'default' => 'today'],
                'weather' => ['label' => 'Weather', 'type' => 'select', 'options' => ['sunny' => 'Sunny', 'cloudy' => 'Cloudy', 'rainy' => 'Rainy', 'stormy' => 'Stormy'], 'width' => 4],
                'labour_count' => ['label' => 'Labour count', 'type' => 'number', 'width' => 4],
                'staff_on_site' => ['label' => 'Staff on site', 'type' => 'textarea', 'rows' => 2, 'width' => 4],
                'equipment_on_site' => ['label' => 'Equipment on site', 'type' => 'textarea', 'rows' => 2, 'width' => 4],
                'work_progress' => ['label' => 'Work progress', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'materials_received' => ['label' => 'Materials received', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'visitors' => ['label' => 'Visitors', 'type' => 'textarea', 'rows' => 2, 'width' => 4],
                'issues_delays' => ['label' => 'Issues / delays', 'type' => 'textarea', 'rows' => 2, 'width' => 4],
                'prepared_by' => ['label' => 'Prepared by', 'width' => 4]]],
        'subcontracts' => ['model' => M\Subcontract::class, 'title' => 'Subcontracts', 'singular' => 'Subcontract', 'perm' => 'projects',
            'columns' => ['subcontract_no' => 'Subcontract', 'project.display_name' => 'Project', 'subcontractor_name' => 'Subcontractor', 'contract_amount' => 'Amount|money', 'status' => 'Status|badge'],
            'search' => ['subcontract_no', 'subcontractor_name'], 'sort' => 'subcontract_no',
            'fields' => [
                'subcontract_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'subcontractor_name' => ['label' => 'Subcontractor', 'required' => 1, 'width' => 3],
                'supplier_id' => ['label' => 'Supplier link', 'type' => 'select', 'model' => M\Supplier::class, 'width' => 3],
                'contract_amount' => ['label' => 'Contract amount', 'type' => 'decimal', 'width' => 3],
                'start_date' => ['label' => 'Start', 'type' => 'date', 'width' => 3], 'end_date' => ['label' => 'End', 'type' => 'date', 'width' => 3],
                'retention_percent' => ['label' => 'Retention %', 'type' => 'decimal', 'default' => 5, 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['draft' => 'Draft', 'active' => 'Active', 'completed' => 'Completed', 'closed' => 'Closed'], 'default' => 'active', 'width' => 3],
                'scope_of_work' => ['label' => 'Scope of work', 'type' => 'textarea', 'rows' => 2, 'width' => 12]]],
        'subcontractor-claims' => ['model' => M\SubcontractorClaim::class, 'title' => 'Subcontractor Claims', 'singular' => 'Claim', 'perm' => 'projects',
            'columns' => ['claim_no' => 'Claim', 'claim_date' => 'Date|date', 'subcontract.subcontractor_name' => 'Subcontractor', 'amount_claimed' => 'Claimed|money', 'net_payable' => 'Payable|money', 'status' => 'Status|badge'],
            'search' => ['claim_no'], 'sort' => '-claim_date', 'dedicated' => 'subcontractor-claims', 'approval_type' => 'subcontractor_claim', 'fields' => []],
        'client-ipcs' => ['model' => M\ClientIpc::class, 'title' => 'Client IPCs (Payment Certificates)', 'singular' => 'IPC', 'perm' => 'projects',
            'columns' => ['ipc_no' => 'IPC', 'ipc_date' => 'Date|date', 'project.display_name' => 'Project', 'gross_valuation' => 'Gross|money', 'net_certified' => 'Net|money', 'status' => 'Status|badge'],
            'search' => ['ipc_no'], 'sort' => '-ipc_date', 'dedicated' => 'client-ipcs', 'fields' => []],
        'project-expenses' => ['model' => M\ProjectExpense::class, 'title' => 'Project Expenses', 'singular' => 'Expense', 'perm' => 'projects',
            'columns' => ['expense_date' => 'Date|date', 'project.display_name' => 'Project', 'category' => 'Category|badge', 'description' => 'Description', 'amount' => 'Amount|money'],
            'search' => ['description'], 'sort' => '-expense_date',
            'fields' => [
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'required' => 1, 'width' => 4, 'filter' => 1],
                'expense_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 4, 'default' => 'today'],
                'category' => ['label' => 'Category', 'type' => 'select', 'options' => ['labour' => 'Labour', 'material' => 'Material', 'equipment' => 'Equipment', 'fuel' => 'Fuel', 'subcontract' => 'Subcontract', 'overhead' => 'Overhead', 'other' => 'Other'], 'default' => 'other', 'width' => 4],
                'description' => ['label' => 'Description', 'required' => 1, 'width' => 6],
                'amount' => ['label' => 'Amount', 'type' => 'decimal', 'required' => 1, 'width' => 3],
                'incurred_by' => ['label' => 'Incurred by', 'width' => 3]]],
        'equipment-deployments' => ['model' => M\EquipmentDeployment::class, 'title' => 'Equipment Deployments', 'singular' => 'Deployment', 'perm' => 'projects',
            'columns' => ['equipment.display_name' => 'Equipment', 'project.display_name' => 'Project', 'quarry.name' => 'Quarry', 'deployed_date' => 'Deployed|date', 'released_date' => 'Released|date', 'status' => 'Status|badge'],
            'search' => [], 'sort' => '-deployed_date',
            'fields' => [
                'equipment_id' => ['label' => 'Equipment', 'type' => 'select', 'model' => M\Equipment::class, 'required' => 1, 'filter' => 1],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class],
                'deployed_date' => ['label' => 'Deployed', 'type' => 'date', 'required' => 1, 'width' => 4, 'default' => 'today'],
                'released_date' => ['label' => 'Released', 'type' => 'date', 'width' => 4],
                'meter_start' => ['label' => 'Meter start', 'type' => 'decimal', 'width' => 4],
                'meter_end' => ['label' => 'Meter end', 'type' => 'decimal', 'width' => 4],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['deployed' => 'Deployed', 'released' => 'Released'], 'default' => 'deployed', 'width' => 4],
                'remarks' => $remarks]],
        // ═══════════ HR ═══════════
        'departments' => ['model' => M\Department::class, 'title' => 'Departments', 'singular' => 'Department', 'perm' => 'hr',
            'columns' => ['code' => 'Code', 'name' => 'Department', 'head_of_dept' => 'Head', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'name',
            'fields' => ['code' => ['label' => 'Code', 'required' => 1, 'unique' => 'departments,code', 'width' => 4], 'name' => ['label' => 'Name', 'required' => 1, 'width' => 4], 'head_of_dept' => ['label' => 'Head of dept', 'width' => 4], 'is_active' => $active]],
        'designations' => ['model' => M\Designation::class, 'title' => 'Designations / Job Titles', 'singular' => 'Designation', 'perm' => 'hr',
            'columns' => ['title' => 'Title', 'department.name' => 'Department', 'grade' => 'Grade', 'is_active' => 'Active|bool'],
            'search' => ['title'], 'sort' => 'title',
            'fields' => ['title' => ['label' => 'Title', 'required' => 1], 'department_id' => ['label' => 'Department', 'type' => 'select', 'model' => M\Department::class, 'filter' => 1], 'grade' => ['label' => 'Grade', 'width' => 4], 'is_active' => $active]],
        'employees' => ['model' => M\Employee::class, 'title' => 'Employees', 'singular' => 'Employee', 'perm' => 'hr',
            'columns' => ['employee_no' => 'Staff ID', 'full_name' => 'Name', 'department.name' => 'Department', 'designation.title' => 'Designation', 'phone' => 'Phone', 'status' => 'Status|badge'],
            'search' => ['employee_no', 'first_name', 'last_name', 'phone'], 'sort' => 'first_name',
            'fields' => [
                'employee_no' => ['label' => 'Staff ID (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'first_name' => ['label' => 'First name', 'required' => 1, 'width' => 3],
                'last_name' => ['label' => 'Last name', 'required' => 1, 'width' => 3],
                'other_names' => ['label' => 'Other names', 'width' => 3],
                'gender' => ['label' => 'Gender', 'type' => 'select', 'options' => ['male' => 'Male', 'female' => 'Female'], 'width' => 3],
                'date_of_birth' => ['label' => 'Date of birth', 'type' => 'date', 'width' => 3],
                'national_id' => ['label' => 'Ghana Card', 'width' => 3], 'ssnit_no' => ['label' => 'SSNIT no.', 'width' => 3],
                'tin' => ['label' => 'TIN', 'width' => 3],
                'phone' => ['label' => 'Phone', 'width' => 3], 'phone2' => ['label' => 'Phone 2', 'width' => 3],
                'email' => ['label' => 'Email', 'type' => 'email', 'width' => 3],
                'address' => ['label' => 'Address', 'width' => 3], 'city' => ['label' => 'City', 'width' => 3],
                'department_id' => ['label' => 'Department', 'type' => 'select', 'model' => M\Department::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'designation_id' => ['label' => 'Designation', 'type' => 'select', 'model' => M\Designation::class, 'required' => 1, 'width' => 3],
                'employment_type' => ['label' => 'Employment', 'type' => 'select', 'options' => ['permanent' => 'Permanent', 'contract' => 'Contract', 'casual' => 'Casual'], 'default' => 'permanent', 'width' => 3],
                'date_employed' => ['label' => 'Date employed', 'type' => 'date', 'width' => 3],
                'date_confirmed' => ['label' => 'Confirmed', 'type' => 'date', 'width' => 3],
                'date_exited' => ['label' => 'Exited', 'type' => 'date', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['active' => 'Active', 'on-leave' => 'On leave', 'suspended' => 'Suspended', 'exited' => 'Exited'], 'default' => 'active', 'width' => 3],
                'basic_salary' => ['label' => 'Basic salary', 'type' => 'decimal', 'width' => 3],
                'allowances' => ['label' => 'Allowances (one per line: Name=amount)', 'type' => 'textarea', 'rows' => 2, 'width' => 6, 'placeholder' => 'Housing=800
Transport=300'],
                'quarry_id' => ['label' => 'Duty station (quarry)', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 3],
                'bank_name' => ['label' => 'Bank', 'width' => 3], 'bank_branch' => ['label' => 'Branch', 'width' => 3],
                'account_no' => ['label' => 'Account no.', 'width' => 3],
                'next_of_kin' => ['label' => 'Next of kin', 'width' => 3], 'nok_phone' => ['label' => 'Kin phone', 'width' => 3],
                'user_id' => ['label' => 'Login user', 'type' => 'select', 'model' => M\User::class, 'label_field' => 'name', 'width' => 3]]],
        'employee-documents' => ['model' => M\EmployeeDocument::class, 'title' => 'Employee Documents', 'singular' => 'Document', 'perm' => 'hr',
            'columns' => ['employee.display_name' => 'Employee', 'doc_type' => 'Type|badge', 'doc_name' => 'Name', 'expiry_date' => 'Expiry|date'],
            'search' => ['doc_name'], 'sort' => 'doc_type',
            'fields' => [
                'employee_id' => ['label' => 'Employee', 'type' => 'select', 'model' => M\Employee::class, 'required' => 1, 'filter' => 1],
                'doc_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['appointment-letter' => 'Appointment letter', 'contract' => 'Contract', 'national-id' => 'National ID', 'ssnit' => 'SSNIT card', 'medical' => 'Medical', 'certificate' => 'Certificate', 'other' => 'Other'], 'required' => 1],
                'doc_name' => ['label' => 'Name'], 'file_path' => ['label' => 'File ref'],
                'issue_date' => ['label' => 'Issued', 'type' => 'date', 'width' => 4], 'expiry_date' => ['label' => 'Expiry', 'type' => 'date', 'width' => 4]]],
        'attendances' => ['model' => M\Attendance::class, 'title' => 'Attendance', 'singular' => 'Attendance', 'perm' => 'hr',
            'columns' => ['attendance_date' => 'Date|date', 'employee.display_name' => 'Employee', 'shift' => 'Shift|badge', 'check_in' => 'In', 'check_out' => 'Out', 'hours_worked' => 'Hrs', 'overtime_hours' => 'OT', 'status' => 'Status|badge'],
            'search' => [], 'sort' => '-attendance_date',
            'fields' => [
                'employee_id' => ['label' => 'Employee', 'type' => 'select', 'model' => M\Employee::class, 'required' => 1, 'filter' => 1],
                'attendance_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'default' => 'today'],
                'shift' => ['label' => 'Shift', 'type' => 'select', 'options' => ['day' => 'Day', 'night' => 'Night'], 'default' => 'day'],
                'check_in' => ['label' => 'Check in', 'type' => 'time'], 'check_out' => ['label' => 'Check out', 'type' => 'time'],
                'hours_worked' => ['label' => 'Hours', 'type' => 'decimal'], 'overtime_hours' => ['label' => 'Overtime', 'type' => 'decimal'],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['present' => 'Present', 'absent' => 'Absent', 'late' => 'Late', 'half-day' => 'Half day', 'on-leave' => 'On leave', 'off-duty' => 'Off duty'], 'default' => 'present'],
                'remarks' => ['label' => 'Remarks']]],
        'leave-types' => ['model' => M\LeaveType::class, 'title' => 'Leave Types', 'singular' => 'Leave Type', 'perm' => 'hr',
            'columns' => ['name' => 'Type', 'days_allowed' => 'Days', 'is_paid' => 'Paid|bool'],
            'search' => ['name'], 'sort' => 'name',
            'fields' => ['name' => ['label' => 'Name', 'required' => 1], 'days_allowed' => ['label' => 'Days allowed', 'type' => 'number', 'width' => 4], 'is_paid' => ['label' => 'Paid', 'type' => 'checkbox', 'default' => 1, 'width' => 4]]],
        'leave-applications' => ['model' => M\LeaveApplication::class, 'title' => 'Leave Applications', 'singular' => 'Leave', 'perm' => 'hr',
            'columns' => ['leave_no' => 'Leave', 'employee.display_name' => 'Employee', 'leaveType.name' => 'Type', 'from_date' => 'From|date', 'to_date' => 'To|date', 'days_requested' => 'Days', 'status' => 'Status|badge'],
            'search' => ['leave_no'], 'sort' => '-from_date', 'approval_type' => 'leave_application',
            'transitions' => ['approve' => ['label' => 'Approve', 'to' => 'approved', 'from' => ['pending'], 'class' => 'ok'], 'reject' => ['label' => 'Reject', 'to' => 'rejected', 'from' => ['pending'], 'class' => 'danger']],
            'fields' => [
                'leave_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'employee_id' => ['label' => 'Employee', 'type' => 'select', 'model' => M\Employee::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'leave_type_id' => ['label' => 'Leave type', 'type' => 'select', 'model' => M\LeaveType::class, 'required' => 1, 'width' => 3],
                'from_date' => ['label' => 'From', 'type' => 'date', 'required' => 1, 'width' => 3],
                'to_date' => ['label' => 'To', 'type' => 'date', 'required' => 1, 'width' => 3],
                'days_requested' => ['label' => 'Days', 'type' => 'number', 'width' => 3],
                'covering_officer' => ['label' => 'Covering officer', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['pending' => 'Pending', 'approved' => 'Approved', 'rejected' => 'Rejected', 'cancelled' => 'Cancelled'], 'default' => 'pending', 'width' => 3],
                'reason' => ['label' => 'Reason', 'type' => 'textarea', 'rows' => 2, 'width' => 12]]],
        'staff-advances' => ['model' => M\StaffAdvance::class, 'title' => 'Staff Advances', 'singular' => 'Advance', 'perm' => 'hr',
            'columns' => ['advance_no' => 'Advance', 'advance_date' => 'Date|date', 'employee.display_name' => 'Employee', 'amount' => 'Amount|money', 'balance' => 'Balance|money', 'status' => 'Status|badge'],
            'search' => ['advance_no'], 'sort' => '-advance_date', 'approval_type' => 'staff_advance',
            'transitions' => ['approve' => ['label' => 'Approve', 'to' => 'approved', 'from' => ['pending'], 'class' => 'ok'], 'reject' => ['label' => 'Decline', 'to' => 'declined', 'from' => ['pending'], 'class' => 'danger']],
            'fields' => [
                'advance_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'employee_id' => ['label' => 'Employee', 'type' => 'select', 'model' => M\Employee::class, 'required' => 1, 'width' => 3, 'filter' => 1],
                'advance_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'amount' => ['label' => 'Amount', 'type' => 'decimal', 'required' => 1, 'width' => 3],
                'purpose' => ['label' => 'Purpose', 'width' => 6],
                'repayment_months' => ['label' => 'Repay months', 'type' => 'number', 'default' => 1, 'width' => 3],
                'monthly_deduction' => ['label' => 'Monthly deduction', 'type' => 'decimal', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['pending' => 'Pending', 'approved' => 'Approved', 'declined' => 'Declined', 'settled' => 'Settled'], 'default' => 'pending', 'width' => 3]]],
        'payroll-runs' => ['model' => M\PayrollRun::class, 'title' => 'Payroll Runs', 'singular' => 'Payroll Run', 'perm' => 'payroll',
            'columns' => ['payroll_no' => 'Run', 'payroll_month' => 'Month|date', 'total_gross' => 'Gross|money', 'total_deductions' => 'Deductions|money', 'total_net' => 'Net|money', 'status' => 'Status|badge'],
            'search' => ['payroll_no'], 'sort' => '-payroll_month', 'dedicated' => 'payroll', 'fields' => []],
        // ═══════════ FINANCE ═══════════
        'accounts' => ['model' => M\Account::class, 'title' => 'Chart of Accounts', 'singular' => 'GL Account', 'perm' => 'finance',
            'columns' => ['code' => 'Code', 'name' => 'Account', 'account_type' => 'Type|badge', 'account_subtype' => 'Sub-type', 'current_balance' => 'Balance|money', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'code',
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'unique' => 'accounts,code', 'width' => 3],
                'name' => ['label' => 'Account name', 'required' => 1, 'width' => 5],
                'account_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['asset' => 'Asset', 'liability' => 'Liability', 'equity' => 'Equity', 'income' => 'Income', 'expense' => 'Expense'], 'required' => 1, 'width' => 4, 'filter' => 1],
                'account_subtype' => ['label' => 'Sub-type', 'type' => 'select', 'options' => ['current-asset' => 'Current asset', 'fixed-asset' => 'Fixed asset', 'current-liability' => 'Current liability', 'long-term-liability' => 'Long-term liability', 'capital' => 'Capital', 'retained-earnings' => 'Retained earnings', 'operating-income' => 'Operating income', 'other-income' => 'Other income', 'cost-of-sales' => 'Cost of sales', 'operating-expense' => 'Operating expense'], 'width' => 4],
                'parent_id' => ['label' => 'Parent account', 'type' => 'select', 'model' => M\Account::class, 'width' => 4],
                'opening_balance' => ['label' => 'Opening balance', 'type' => 'decimal', 'width' => 4],
                'current_balance' => ['label' => 'Current balance', 'type' => 'display', 'width' => 4],
                'is_active' => $active]],
        'journals' => ['model' => M\Journal::class, 'title' => 'Journal Vouchers', 'singular' => 'Journal', 'perm' => 'finance',
            'columns' => ['journal_no' => 'JV', 'journal_date' => 'Date|date', 'narration' => 'Narration', 'total_debit' => 'Debit|money', 'total_credit' => 'Credit|money', 'status' => 'Status|badge'],
            'search' => ['journal_no', 'narration', 'reference'], 'sort' => '-journal_date', 'dedicated' => 'journals', 'fields' => []],
        'bank-accounts' => ['model' => M\BankAccount::class, 'title' => 'Banks, MoMo & Cash', 'singular' => 'Bank Account', 'perm' => 'finance',
            'columns' => ['bank_name' => 'Bank', 'account_no' => 'Acc No.', 'account_name' => 'Name', 'account_type' => 'Type|badge', 'current_balance' => 'Balance|money'],
            'search' => ['bank_name', 'account_no'], 'sort' => 'bank_name',
            'fields' => [
                'bank_name' => ['label' => 'Bank / wallet', 'required' => 1, 'width' => 4],
                'account_no' => ['label' => 'Account no.', 'required' => 1, 'unique' => 'bank_accounts,account_no', 'width' => 4],
                'account_name' => ['label' => 'Account name', 'required' => 1, 'width' => 4],
                'branch' => ['label' => 'Branch', 'width' => 4],
                'account_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['current' => 'Current', 'savings' => 'Savings', 'momo' => 'Mobile money', 'petty-cash' => 'Petty cash'], 'default' => 'current', 'width' => 4],
                'currency' => ['label' => 'Currency', 'default' => 'GHS', 'width' => 4],
                'gl_account_id' => ['label' => 'GL account', 'type' => 'select', 'model' => M\Account::class, 'width' => 4],
                'opening_balance' => ['label' => 'Opening balance', 'type' => 'decimal', 'width' => 4],
                'current_balance' => ['label' => 'Current balance', 'type' => 'display', 'width' => 4],
                'is_active' => $active]],
        'bank-transactions' => ['model' => M\BankTransaction::class, 'title' => 'Bank Transactions', 'singular' => 'Transaction', 'perm' => 'finance',
            'columns' => ['txn_no' => 'Txn', 'txn_date' => 'Date|date', 'bankAccount.display_name' => 'Account', 'txn_type' => 'Type|badge', 'amount' => 'Amount|money', 'narration' => 'Narration', 'reconciled' => 'Rec.|bool'],
            'search' => ['txn_no', 'narration', 'reference'], 'sort' => '-txn_date', 'dedicated' => 'bank-transactions', 'fields' => []],
        'expense-claims' => ['model' => M\ExpenseClaim::class, 'title' => 'Expense Claims', 'singular' => 'Expense Claim', 'perm' => 'finance',
            'columns' => ['claim_no' => 'Claim', 'claim_date' => 'Date|date', 'employee.display_name' => 'Employee', 'purpose' => 'Purpose', 'total_amount' => 'Total|money', 'status' => 'Status|badge'],
            'search' => ['claim_no', 'purpose'], 'sort' => '-claim_date', 'dedicated' => 'expense-claims', 'approval_type' => 'expense_claim', 'fields' => []],
        'budgets' => ['model' => M\Budget::class, 'title' => 'Budgets', 'singular' => 'Budget', 'perm' => 'finance',
            'columns' => ['name' => 'Budget', 'fiscalYear.name' => 'FY', 'department' => 'Dept', 'total_amount' => 'Total|money', 'status' => 'Status|badge'],
            'search' => ['name'], 'sort' => 'name',
            'fields' => [
                'name' => ['label' => 'Budget name', 'required' => 1],
                'fiscal_year_id' => ['label' => 'Fiscal year', 'type' => 'select', 'model' => M\FiscalYear::class, 'required' => 1],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 4],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'width' => 4],
                'department' => ['label' => 'Department', 'width' => 4],
                'total_amount' => ['label' => 'Total', 'type' => 'decimal', 'width' => 4],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['draft' => 'Draft', 'approved' => 'Approved', 'closed' => 'Closed'], 'default' => 'draft', 'width' => 4]]],
        'budget-lines' => ['model' => M\BudgetLine::class, 'title' => 'Budget Lines', 'singular' => 'Budget Line', 'perm' => 'finance',
            'columns' => ['budget.name' => 'Budget', 'account.display_name' => 'Account', 'month' => 'Month', 'budgeted_amount' => 'Budgeted|money', 'actual_amount' => 'Actual|money'],
            'search' => [], 'sort' => 'month',
            'fields' => [
                'budget_id' => ['label' => 'Budget', 'type' => 'select', 'model' => M\Budget::class, 'required' => 1, 'filter' => 1],
                'account_id' => ['label' => 'Account', 'type' => 'select', 'model' => M\Account::class, 'required' => 1],
                'month' => ['label' => 'Month (1-12)', 'type' => 'number', 'default' => 1, 'min' => 1, 'max' => 12],
                'budgeted_amount' => ['label' => 'Budgeted', 'type' => 'decimal', 'required' => 1],
                'actual_amount' => ['label' => 'Actual', 'type' => 'display']]],
        'budget-virements' => ['model' => M\BudgetVirement::class, 'title' => 'Budget Virements', 'singular' => 'Virement', 'perm' => 'finance',
            'columns' => ['virement_no' => 'Virement', 'fromLine.account.display_name' => 'From', 'toLine.account.display_name' => 'To', 'amount' => 'Amount|money', 'status' => 'Status|badge'],
            'search' => ['virement_no', 'reason'], 'sort' => '-id', 'dedicated' => 'budget-virements', 'approval_type' => 'budget_virement', 'fields' => []],
        'fixed-assets' => ['model' => M\FixedAsset::class, 'title' => 'Fixed Assets Register', 'singular' => 'Asset', 'perm' => 'finance',
            'columns' => ['asset_no' => 'Asset', 'name' => 'Name', 'category' => 'Category|badge', 'purchase_cost' => 'Cost|money', 'net_book_value' => 'NBV|money', 'status' => 'Status|badge'],
            'search' => ['asset_no', 'name'], 'sort' => 'asset_no',
            'fields' => [
                'asset_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'name' => ['label' => 'Asset name', 'required' => 1, 'width' => 5],
                'category' => ['label' => 'Category', 'type' => 'select', 'options' => ['land' => 'Land', 'building' => 'Building', 'plant-machinery' => 'Plant & machinery', 'vehicle' => 'Vehicle', 'furniture' => 'Furniture', 'computer' => 'Computer', 'other' => 'Other'], 'default' => 'plant-machinery', 'width' => 4],
                'purchase_date' => ['label' => 'Purchase date', 'type' => 'date', 'width' => 3],
                'purchase_cost' => ['label' => 'Purchase cost', 'type' => 'decimal', 'width' => 3],
                'supplier_id' => ['label' => 'Supplier', 'type' => 'select', 'model' => M\Supplier::class, 'width' => 3],
                'useful_life_years' => ['label' => 'Life (yrs)', 'type' => 'number', 'default' => 5, 'width' => 3],
                'salvage_value' => ['label' => 'Salvage', 'type' => 'decimal', 'width' => 3],
                'location' => ['label' => 'Location', 'width' => 3],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['active' => 'Active', 'disposed' => 'Disposed'], 'default' => 'active', 'width' => 3]]],
        'tax-rates' => ['model' => M\TaxRate::class, 'title' => 'Tax Rates (GRA)', 'singular' => 'Tax Rate', 'perm' => 'finance',
            'columns' => ['code' => 'Code', 'name' => 'Tax', 'rate_percent' => 'Rate %', 'applies_on' => 'Applies on', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'code', 'no_delete' => 1,
            'fields' => [
                'code' => ['label' => 'Code', 'required' => 1, 'width' => 4, 'readonly_on_edit' => 1],
                'name' => ['label' => 'Name', 'required' => 1, 'width' => 4],
                'rate_percent' => ['label' => 'Rate %', 'type' => 'decimal', 'required' => 1, 'width' => 4],
                'applies_on' => ['label' => 'Applies on', 'default' => 'subtotal', 'width' => 4],
                'effective_from' => ['label' => 'Effective from', 'type' => 'date', 'width' => 4],
                'is_active' => $active]],
        'currencies' => ['model' => M\Currency::class, 'title' => 'Currencies & Exchange Rates', 'singular' => 'Currency', 'perm' => 'finance',
            'columns' => ['code' => 'Code', 'name' => 'Currency', 'symbol' => 'Symbol', 'rate_to_ghs' => 'Rate to GHS', 'is_base' => 'Base|bool', 'is_active' => 'Active|bool'],
            'search' => ['code', 'name'], 'sort' => 'code', 'no_delete' => 1,
            'fields' => [
                'code' => ['label' => 'Code (ISO)', 'required' => 1, 'width' => 3, 'placeholder' => 'USD', 'readonly_on_edit' => 1],
                'name' => ['label' => 'Name', 'required' => 1, 'width' => 4],
                'symbol' => ['label' => 'Symbol', 'width' => 2, 'placeholder' => '$'],
                'rate_to_ghs' => ['label' => 'Rate to GHS (1 unit = ? GHS)', 'type' => 'decimal', 'required' => 1, 'width' => 4],
                'is_active' => $active]],
        'tax-filings' => ['model' => M\TaxFiling::class, 'title' => 'Tax Filing Tracker (GRA/SSNIT)', 'singular' => 'Tax Filing', 'perm' => 'finance',
            'columns' => ['tax_type' => 'Tax', 'period' => 'Period', 'due_date' => 'Due|date', 'liability' => 'Liability|money', 'amount_paid' => 'Paid|money', 'outstanding' => 'Outstanding|money', 'status' => 'Status|badge', 'overdue' => 'Overdue|bool'],
            'search' => ['period', 'gra_receipt_no'], 'sort' => '-due_date',
            'transitions' => ['file' => ['label' => 'Mark filed', 'to' => 'filed', 'from' => ['draft'], 'class' => 'ok'], 'pay' => ['label' => 'Mark paid', 'to' => 'paid', 'from' => ['filed'], 'class' => 'ok'], 'reopen' => ['label' => 'Reopen', 'to' => 'draft', 'from' => ['filed'], 'class' => 'danger']],
            'fields' => [
                'tax_type' => ['label' => 'Tax type', 'type' => 'select', 'options' => ['vat' => 'VAT (15%)', 'levies' => 'NHIL/GETFund/COVID levies', 'wht' => 'Withholding tax', 'paye' => 'PAYE', 'ssnit1' => 'SSNIT Tier 1', 'ssnit2' => 'SSNIT Tier 2', 'cit' => 'Corporate income tax'], 'required' => 1, 'width' => 4],
                'period' => ['label' => 'Period (YYYY-MM)', 'required' => 1, 'width' => 3, 'placeholder' => 'YYYY-MM'],
                'due_date' => ['label' => 'Due date', 'type' => 'date', 'required' => 1, 'width' => 3],
                'taxable_base' => ['label' => 'Taxable base', 'type' => 'decimal', 'width' => 3],
                'liability' => ['label' => 'Liability', 'type' => 'decimal', 'width' => 3],
                'amount_paid' => ['label' => 'Amount paid', 'type' => 'decimal', 'width' => 3],
                'credit_cf' => ['label' => 'Credit carried fwd', 'type' => 'decimal', 'width' => 3],
                'gra_receipt_no' => ['label' => 'GRA receipt no.', 'width' => 3],
                'notes' => ['label' => 'Notes', 'type' => 'textarea', 'width' => 9]]],
        // ═══════════ HSE ═══════════
        'hse-incidents' => ['model' => M\HseIncident::class, 'title' => 'HSE Incidents & Near-Miss', 'singular' => 'Incident', 'perm' => 'hse',
            'columns' => ['incident_no' => 'Incident', 'incident_date' => 'Date|date', 'incident_type' => 'Type|badge', 'severity' => 'Severity|badge', 'lost_time_days' => 'LTI days', 'status' => 'Status|badge'],
            'search' => ['incident_no', 'location'], 'sort' => '-incident_date',
            'transitions' => ['close' => ['label' => 'Close', 'to' => 'closed', 'from' => ['open', 'investigating'], 'class' => 'ok']],
            'fields' => [
                'incident_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'incident_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 3],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'width' => 3],
                'incident_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['injury' => 'Injury', 'near-miss' => 'Near-miss', 'property-damage' => 'Property damage', 'environmental' => 'Environmental', 'fatality' => 'Fatality'], 'default' => 'near-miss', 'width' => 3],
                'severity' => ['label' => 'Severity', 'type' => 'select', 'options' => ['low' => 'Low', 'medium' => 'Medium', 'high' => 'High', 'critical' => 'Critical'], 'default' => 'low', 'width' => 3],
                'location' => ['label' => 'Location', 'width' => 3],
                'persons_involved' => ['label' => 'Persons involved', 'width' => 3],
                'lost_time_days' => ['label' => 'Lost-time days', 'type' => 'number', 'width' => 3],
                'reported_by' => ['label' => 'Reported by', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['open' => 'Open', 'investigating' => 'Investigating', 'closed' => 'Closed'], 'default' => 'open', 'width' => 3],
                'description' => ['label' => 'Description', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'immediate_action' => ['label' => 'Immediate action', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'root_cause' => ['label' => 'Root cause', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'corrective_action' => ['label' => 'Corrective action', 'type' => 'textarea', 'rows' => 2, 'width' => 6]]],
        'hse-inspections' => ['model' => M\HseInspection::class, 'title' => 'HSE Inspections', 'singular' => 'Inspection', 'perm' => 'hse',
            'columns' => ['inspection_no' => 'Inspection', 'inspection_date' => 'Date|date', 'inspection_type' => 'Type|badge', 'inspector' => 'Inspector', 'status' => 'Status|badge'],
            'search' => ['inspection_no'], 'sort' => '-inspection_date',
            'transitions' => ['close' => ['label' => 'Close', 'to' => 'closed', 'from' => ['open'], 'class' => 'ok']],
            'fields' => [
                'inspection_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'inspection_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 3],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'width' => 3],
                'inspection_type' => ['label' => 'Type', 'type' => 'select', 'options' => ['daily' => 'Daily', 'weekly' => 'Weekly', 'monthly' => 'Monthly', 'audit' => 'Audit'], 'default' => 'weekly', 'width' => 3],
                'inspector' => ['label' => 'Inspector', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['open' => 'Open', 'closed' => 'Closed'], 'default' => 'open', 'width' => 3],
                'findings' => ['label' => 'Findings', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'corrective_actions' => ['label' => 'Corrective actions', 'type' => 'textarea', 'rows' => 2, 'width' => 6]]],
        'ppe-issues' => ['model' => M\PpeIssue::class, 'title' => 'PPE Issuance', 'singular' => 'PPE Issue', 'perm' => 'hse',
            'columns' => ['issue_date' => 'Date|date', 'employee.display_name' => 'Employee', 'item_name' => 'Item', 'qty' => 'Qty', 'issued_by' => 'Issued by'],
            'search' => ['item_name'], 'sort' => '-issue_date',
            'fields' => [
                'issue_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'default' => 'today'],
                'employee_id' => ['label' => 'Employee', 'type' => 'select', 'model' => M\Employee::class, 'required' => 1, 'filter' => 1],
                'item_name' => ['label' => 'PPE item', 'required' => 1],
                'qty' => ['label' => 'Qty', 'type' => 'decimal', 'default' => 1],
                'warehouse_id' => ['label' => 'Store', 'type' => 'select', 'model' => M\Warehouse::class],
                'issued_by' => ['label' => 'Issued by'],
                'returnable' => ['label' => 'Returnable', 'type' => 'checkbox', 'width' => 3],
                'remarks' => $remarks]],
        'work-permits' => ['model' => M\WorkPermit::class, 'title' => 'Permits to Work', 'singular' => 'Permit', 'perm' => 'hse',
            'columns' => ['permit_no' => 'Permit', 'permit_date' => 'Date|date', 'work_type' => 'Work|badge', 'valid_to' => 'Valid to|date', 'status' => 'Status|badge'],
            'search' => ['permit_no'], 'sort' => '-permit_date',
            'transitions' => ['approve' => ['label' => 'Approve', 'to' => 'approved', 'from' => ['pending'], 'class' => 'ok'], 'reject' => ['label' => 'Reject', 'to' => 'rejected', 'from' => ['pending'], 'class' => 'danger'], 'close' => ['label' => 'Close', 'to' => 'closed', 'from' => ['approved'], 'class' => 'info']],
            'fields' => [
                'permit_no' => ['label' => 'No. (auto)', 'width' => 3, 'placeholder' => 'Auto-generated'],
                'permit_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'width' => 3, 'default' => 'today'],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'width' => 3],
                'project_id' => ['label' => 'Project', 'type' => 'select', 'model' => M\Project::class, 'width' => 3],
                'work_type' => ['label' => 'Work type', 'type' => 'select', 'options' => ['hot-work' => 'Hot work', 'confined-space' => 'Confined space', 'working-at-height' => 'Working at height', 'blasting' => 'Blasting', 'electrical' => 'Electrical', 'excavation' => 'Excavation', 'general' => 'General'], 'default' => 'general', 'width' => 3],
                'requested_by' => ['label' => 'Requested by', 'width' => 3],
                'valid_from' => ['label' => 'Valid from', 'type' => 'date', 'width' => 3],
                'valid_to' => ['label' => 'Valid to', 'type' => 'date', 'width' => 3],
                'approved_by' => ['label' => 'Approved by', 'width' => 3],
                'status' => ['label' => 'Status', 'type' => 'select', 'options' => ['pending' => 'Pending', 'approved' => 'Approved', 'rejected' => 'Rejected', 'closed' => 'Closed'], 'default' => 'pending', 'width' => 3],
                'description' => ['label' => 'Description', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'precautions' => ['label' => 'Precautions', 'type' => 'textarea', 'rows' => 2, 'width' => 6]]],
        'hse-trainings' => ['model' => M\HseTraining::class, 'title' => 'HSE Trainings / Toolbox Talks', 'singular' => 'Training', 'perm' => 'hse',
            'columns' => ['training_date' => 'Date|date', 'topic' => 'Topic', 'trainer' => 'Trainer', 'venue' => 'Venue', 'attendees_count' => 'Attendees', 'expiry_date' => 'Cert expiry|date'],
            'search' => ['topic', 'trainer'], 'sort' => '-training_date',
            'fields' => [
                'training_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'default' => 'today'],
                'topic' => ['label' => 'Topic', 'required' => 1],
                'trainer' => ['label' => 'Trainer'], 'venue' => ['label' => 'Venue'],
                'attendees_count' => ['label' => 'Attendees', 'type' => 'number', 'width' => 4],
                'duration_hours' => ['label' => 'Hours', 'type' => 'decimal', 'width' => 4],
                'expiry_date' => ['label' => 'Cert expiry', 'type' => 'date', 'width' => 4],
                'attendee_list' => ['label' => 'Attendee list', 'type' => 'textarea', 'rows' => 2, 'width' => 6],
                'remarks' => ['label' => 'Remarks', 'type' => 'textarea', 'rows' => 2, 'width' => 6]]],
        'environmental-monitorings' => ['model' => M\EnvironmentalMonitoring::class, 'title' => 'Environmental Monitoring (EPA)', 'singular' => 'Reading', 'perm' => 'hse',
            'columns' => ['monitoring_date' => 'Date|date', 'quarry.name' => 'Quarry', 'parameter' => 'Parameter|badge', 'reading_value' => 'Reading', 'permissible_limit' => 'Limit', 'compliant' => 'OK|bool'],
            'search' => ['parameter'], 'sort' => '-monitoring_date',
            'fields' => [
                'monitoring_date' => ['label' => 'Date', 'type' => 'date', 'required' => 1, 'default' => 'today'],
                'quarry_id' => ['label' => 'Quarry', 'type' => 'select', 'model' => M\Quarry::class, 'required' => 1, 'filter' => 1],
                'parameter' => ['label' => 'Parameter', 'type' => 'select', 'options' => ['dust-pm10' => 'Dust (PM10)', 'noise' => 'Noise (dB)', 'vibration' => 'Vibration (mm/s)', 'water-ph' => 'Water pH', 'water-turbidity' => 'Water turbidity'], 'required' => 1],
                'reading_value' => ['label' => 'Reading', 'type' => 'decimal', 'required' => 1],
                'unit' => ['label' => 'Unit'], 'permissible_limit' => ['label' => 'Limit', 'type' => 'decimal'],
                'location_point' => ['label' => 'Point'], 'monitored_by' => ['label' => 'Monitored by'],
                'compliant' => ['label' => 'Compliant', 'type' => 'checkbox', 'default' => 1, 'width' => 3],
                'remarks' => $remarks]],
        // ═══════════ SETTINGS / ADMIN ═══════════
        'fiscal-years' => ['model' => M\FiscalYear::class, 'title' => 'Fiscal Years', 'singular' => 'Fiscal Year', 'perm' => 'settings',
            'columns' => ['name' => 'Year', 'start_date' => 'Start|date', 'end_date' => 'End|date', 'is_current' => 'Current|bool', 'is_closed' => 'Closed|bool'],
            'search' => ['name'], 'sort' => '-start_date',
            'fields' => [
                'name' => ['label' => 'Name', 'required' => 1, 'unique' => 'fiscal_years,name', 'placeholder' => 'FY 2026'],
                'start_date' => ['label' => 'Start', 'type' => 'date', 'required' => 1],
                'end_date' => ['label' => 'End', 'type' => 'date', 'required' => 1],
                'is_current' => ['label' => 'Current', 'type' => 'checkbox', 'width' => 3],
                'is_closed' => ['label' => 'Closed', 'type' => 'checkbox', 'width' => 3]]],
        'document-sequences' => ['model' => M\DocumentSequence::class, 'title' => 'Document Numbering', 'singular' => 'Sequence', 'perm' => 'settings',
            'columns' => ['label' => 'Document', 'key' => 'Key', 'prefix' => 'Prefix', 'next_number' => 'Next #', 'include_fy' => 'FY|bool'],
            'search' => ['label', 'key'], 'sort' => 'label', 'no_create' => 1, 'no_delete' => 1,
            'fields' => [
                'label' => ['label' => 'Document', 'type' => 'display'],
                'key' => ['label' => 'Key', 'type' => 'display'],
                'prefix' => ['label' => 'Prefix', 'required' => 1, 'width' => 4],
                'next_number' => ['label' => 'Next number', 'type' => 'number', 'required' => 1, 'width' => 4],
                'padding' => ['label' => 'Padding', 'type' => 'number', 'width' => 4],
                'include_fy' => ['label' => 'Include FY', 'type' => 'checkbox', 'width' => 3]]],
        'audit-logs' => ['model' => M\AuditLog::class, 'title' => 'Audit Trail', 'singular' => 'Log', 'perm' => 'settings',
            'columns' => ['created_at' => 'When', 'user.name' => 'User', 'action' => 'Action|badge', 'auditable_type' => 'Entity', 'auditable_id' => '#', 'ip' => 'IP'],
            'search' => ['action', 'auditable_type', 'ip'], 'sort' => '-id', 'no_create' => 1, 'no_edit' => 1, 'no_delete' => 1, 'fields' => []],
        ];
    }
    public static function get(string $key): array {
        $all = self::all();
        abort_unless(isset($all[$key]), 404, 'Unknown module: '.$key);
        return $all[$key];
    }
    /** Map dedicated slugs to their document controllers (create/store/edit/update/print/actions). */
    public static function dedicatedController(string $slug): ?string {
        return [
            'production' => \App\Http\Controllers\ProductionEntryController::class,
            'stock-adjustments' => \App\Http\Controllers\StockAdjustmentController::class,
            'work-orders' => \App\Http\Controllers\MaintenanceWorkOrderController::class,
            'quotations' => \App\Http\Controllers\QuotationController::class,
            'sales-orders' => \App\Http\Controllers\SalesOrderController::class,
            'weighbridge' => \App\Http\Controllers\WeighbridgeTicketController::class,
            'delivery' => \App\Http\Controllers\DeliveryNoteController::class,
            'sales-invoices' => \App\Http\Controllers\SalesInvoiceController::class,
            'customer-payments' => \App\Http\Controllers\CustomerPaymentController::class,
            'credit-notes' => \App\Http\Controllers\SalesCreditNoteController::class,
            'purchase-requisitions' => \App\Http\Controllers\PurchaseRequisitionController::class,
            'purchase-orders' => \App\Http\Controllers\PurchaseOrderController::class,
            'goods-receipts' => \App\Http\Controllers\GoodsReceiptController::class,
            'purchase-invoices' => \App\Http\Controllers\PurchaseInvoiceController::class,
            'supplier-payments' => \App\Http\Controllers\SupplierPaymentController::class,
            'subcontractor-claims' => \App\Http\Controllers\SubcontractorClaimController::class,
            'client-ipcs' => \App\Http\Controllers\ClientIpcController::class,
            'payroll' => \App\Http\Controllers\PayrollRunController::class,
            'journals' => \App\Http\Controllers\JournalController::class,
            'bank-transactions' => \App\Http\Controllers\BankTransactionController::class,
            'expense-claims' => \App\Http\Controllers\ExpenseClaimController::class,
        ][$slug] ?? null;
    }
}
