# Implementation Plan: SOW_03 My Merchants v2 — Gap Analysis

## Context

The My Merchants module is ~28% complete (5 of 151 gap items done). The codebase has a solid foundation — the listing page, merchant detail with 8 tabs, and transaction models all exist — but 8 of 11 sub-pages are stubs, 3 critical detail tabs are missing entirely, and the batches tab lacks its KPI carousel. This plan implements the 6-phase roadmap from the gap analysis document.

**Key files already in place:**
- `app/Http/Controllers/Merchants/MyMerchantController.php` — `index()`, `show()`, `export()`
- `app/Http/Controllers/Merchants/MerchantController.php` — stub methods for all specialized pages
- `app/Models/Merchants/Merchant.php` — full model with `getListing()`, relationships
- `app/Models/Merchants/MerchantTransaction.php` — `getCardTypesSummeryForMerchants()`, `getPortfolioBreakdown()`, etc.
- `resources/views/admin/my-merchants/` — index, show, 8 partials
- `resources/views/admin/merchants/` — all stub page views exist
- `public/assets/js/my-merchants-portfolio.js`, `my-merchant-batches.js`

---

## Phase 1 — Critical Missing Tabs + KPI Cards (GAP-4.5, 4.6, 4.7, 4.9)

**Goal:** Fill the most visible gaps in the merchant detail view.

### 1a. Authorizations Tab (GAP-4.5)
- Create `resources/views/admin/my-merchants/partials/authorizations.blade.php`
  - Date range filter dropdown, KPI cards (total/approved/declined/approval%), table with Date/Time, Card Type, Amount, Auth Code, Status badge
- Add `authorizations()` scope to `MerchantTransaction.php`
- Add `authorizations` case to `MyMerchantController::show()` tab switch
- Add tab link in `show.blade.php` between Batches and Account Status

### 1b. Memos Tab (GAP-4.6)
- Create migration: `create_merchant_memos_table` (merchant_id, user_id, company_id, memo_type ENUM, memo_text, timestamps, softDeletes)
- Create `app/Models/Merchants/MerchantMemo.php` (fillable, SoftDeletes, belongsTo Merchant/User)
- Add `memos()` hasMany to `Merchant.php`
- Create `resources/views/admin/my-merchants/partials/memos.blade.php` (type filter tabs, add memo form, memo list with user/type badge)
- Add `memos` tab to `show.blade.php` and controller
- Add POST route `my-merchants.memos.store` → new `storeMemo()` method in `MyMerchantController`

### 1c. 1099K Tab (GAP-4.7)
- Create `resources/views/admin/my-merchants/partials/1099k.blade.php` (annual summary table: Tax Year, Gross Volume, Transaction Count, IRS Filing Status badge)
- Data: `MerchantTransaction` grouped by `YEAR(settlement_date)` in `MyMerchantController::show()`
- Add `1099k` tab to `show.blade.php` and controller

### 1d. Batches KPI Carousel (GAP-4.9)
- In `MyMerchantController::show()` batches section, compute 11 KPIs: Volume Rank, Avg Batch Amount, Best Processing Day, Last Processing Date, Total Volume, Highest Volume Day, Account Age, Chargeback Ratio, Avg Transaction, Next Event, Profit
- Add horizontally scrollable carousel to `partials/batches.blade.php` (d-flex overflow-auto, left/right arrow JS)
- Reuse `Carbon::parse()` (already used in controller) for Account Age

---

## Phase 2 — Portfolio Overview Fixes (GAP-3.1 to 3.21)

**Goal:** Complete the My Merchants listing page.

### 2a. KPI/Chart fixes
- **GAP-3.1:** Compute `$dateRangeLabel` in `MyMerchantController::index()`, pass to view, render in teal span after title
- **GAP-3.6:** Extend `MerchantTransaction::getPortfolioBreakdown()` to return `not_processing_count`; add orange segment to ApexCharts in `my-merchants-portfolio.js`
- **GAP-3.2/3.7:** Convert checkboxes to Bootstrap form-switches in card type table and pie chart legend
- **GAP-3.8:** Enable ApexCharts `dataLabels` with percentage formatter in `my-merchants-portfolio.js`
- **GAP-3.3/3.4:** Add card brand logos + EBT/Pin-Debit/Fleet/Other rows to card type table; extend `getCardTypesSummeryForMerchants()`
- **GAP-3.5/3.9/3.10:** Add Bootstrap tooltips (info icons on Total row, pie legend items); add "Showing N Merchants" counter

### 2b. Column/table fixes
- **GAP-3.11:** Add Column Visibility gear icon with searchable dropdown; follow pattern from `resources/views/admin/leads/index.blade.php`
- **GAP-3.12–3.16:** Add VIM, Last Lead Note, Active, Processor, Last Batch Date, and 18 per-card-type columns to `MyMerchantDynamicHeadersSeeder`; update `MyMerchantController::index()` query
- **GAP-3.15:** Change `paginate(10)` → `paginate(25)` in `MyMerchantController::index()`

### 2c. Filter panel
- **GAP-3.17:** Add Date Range dropdown (This Month default) + custom date pickers; wire to `MyMerchantController::index()`
- **GAP-3.18/3.19/3.20:** Add Sales Rep Number (Select2 multi-tag), Pricing (Select2 multi-tag), Lead Type (select) filters
- **GAP-3.21:** Add Clear (X) and Apply (✓) icon buttons to filter panel header

---

## Phase 3 — Merchant Detail Remaining Gaps (GAP-4.x)

### 3a. Header UI (GAP-4.1–4.4)
- Breadcrumb nav, teal MID display, clipboard copy icon, bookmark/favorite icon
- Bookmark requires new `user_favorite_merchants` table (small migration), new route + controller method

### 3b. Batches tab (GAP-4.8, 4.21, 4.22)
- Uncomment/implement date range selector; add AJAX `batches()` endpoint to `MyMerchantController`
- Add Prev/Next month navigator with AJAX reload
- Add "Find in Merchant" inline row-filter button

### 3c. Account Status tab (GAP-4.26)
- Remove `d-none` from hidden accordion sections (Processing Info, Card Type Info, Settlement Info, Account Activity, Income/Expense, Discount Rates)
- Null-check fields before rendering

### 3d. Financials tab (GAP-4.30)
- Add Monthly/Quarterly/Annual tab selector + ApexCharts bar+line chart (reuse `my-merchant-batches.js` pattern)
- Compute aggregations in `MyMerchantController::show()` financials case

### 3e. Retrievals tab (GAP-4.31–4.33)
- Add Reason Code column (already exists in `merchant_transactions`)
- Add `response_due_date` migration if missing; add Response Due Date column
- Add/update `getRetrievalStatusTextAttribute()` accessor (Open/Responded/Expired logic)

### 3f. Chargebacks tab (GAP-4.34–4.35)
- Add `representment_deadline` migration if missing; add column with orange warning if ≤3 days away
- Update `getChargebackStatusTextAttribute()` → Open/Won/Lost/Represented

### 3g. Statements tab (GAP-4.37–4.38)
- Create migration `create_merchant_statements_table` (merchant_id, statement_date, period_start/end, total_volume, total_fees, net_volume, file_path)
- Create `app/Models/Merchants/MerchantStatement.php`
- Add `statements()` hasMany to `Merchant.php`
- Replace `collect()` stub in `MyMerchantController::show()` with real query
- Add download route + `downloadStatement()` method (Storage::download with company_id auth check)

---

## Phase 4 — Stub Pages: High Business Value (GAP-5.x, 6.x, 9.x, 10.x)

### 4a. Portfolio Activity (GAP-5.1, 5.9, 5.11)
- Implement `resources/views/admin/merchants/portfolio-activity.blade.php`
- Filter bar (processors, datasources, groups, users, date range)
- ApexCharts horizontal bar chart: Monthly Booked Volume (last 12 months)
- Data table with Merchant (TurboApp/Lead sub-links), Processing History (colored dot)
- Implement `MerchantController::portfolioActivity()` with real data queries

### 4b. Merchant Tracker (GAP-6.1, 6.5, 6.7)
- Implement `resources/views/admin/merchants/merchant-tracker.blade.php`
- Filters + "not processed since N period" selector
- Table: #, Enabled toggle (AJAX), Last Batch, Merchant sub-lines (in system/first batch/last batch dates), Assigned Users, Action
- Add `tracker_enabled` migration on merchants table
- Add `trackerToggle()` route + method in `MerchantController`

### 4c. Dispute Reporting (GAP-9.1)
- Implement `resources/views/admin/merchants/dispute-reporting.blade.php`
- Tag-pill filter bar, 14-column table, row click to select (green highlight), export (CSV/XLSX)
- Masked cardholder account (show last 4 only)
- Implement `MerchantController::disputeReporting()` — query `merchant_transactions` with join

### 4d. Risk Reporting (GAP-10.1)
- Implement `resources/views/admin/merchants/risk-reporting.blade.php`
- 14-column sortable table with row highlighting: yellow (Return Ratio > 5%), orange (CB Ratio > 1%)
- Implement `MerchantController::riskReporting()` — grouped aggregations per merchant

---

## Phase 5 — Stub Pages Continued (GAP-7.x, 8.x, 11.x)

### 5a. The Scoop (GAP-7.1)
- Implement `resources/views/admin/merchants/the-scoop.blade.php`
- Month/Year/Group/Agent filter bar + "Show Primary User Data Only" checkbox
- Two tabs: Portfolio Overview | Agents — each with 4 ApexCharts quadrants (2x2 grid):
  - Total Volume Shown (bar chart, 15-month history)
  - Total Residual Contribution (donut chart, per-agent)
  - Total Approvals Shown (bar chart)
  - Total Approved (donut chart)
- Create `public/assets/js/the-scoop.js` for chart initialization
- Implement `MerchantController::theScoop()` with real aggregation queries

### 5b. Deposit Exceptions (GAP-8.1)
- Implement `resources/views/admin/merchants/deposit-exceptions.blade.php`
- Filter bar (processors, groups, users, date range, keyword multi-select)
- Results grouped by 18 exception categories (teal group-header rows)
- Per-group DBA inline filter input
- Implement `MerchantController::depositExceptions()` — LIKE query on transaction description/memo per 18 keywords

### 5c. Risk Alerts (GAP-11.1)
- Create migration `create_merchant_risk_alert_configs_table` (company_id, alert_type ENUM, threshold_value, threshold_type, is_active)
- Create `app/Models/Merchants/MerchantRiskAlertConfig.php`
- Implement `resources/views/admin/merchants/risk-alerts.blade.php` with two tabs:
  - Triggered Alerts: 9-column sortable table, empty-state message
  - Set Alerts: configuration form with threshold inputs + active toggles → AJAX save
- Implement `MerchantController::riskAlerts()` with trigger evaluation (CB ratio > threshold OR volume > 150% of 6-month avg)
- Add `merchants.risk-alerts.save` route

---

## Phase 6 — Business Rules, Statements, Merchant Management (GAP-12.x, 14.x, 4.37)

### 6a. Merchant Management fixes (GAP-12.1, 12.4, 12.6, 12.9)
- Add "Search By" dropdown (DBA/MID/Legal Name) to `merchants/index.blade.php`; update `MerchantController::index()` to conditionally apply column filter
- Add bulk-select checkbox column with "select all" JS
- Add edit (pencil) icon in Action column
- Add "Show Deactivated Merchants" checkbox → `->withTrashed()` in query

### 6b. Business Rules (GAP-14.2)
- Add Seasonal (3) and Hold (4) to `Merchant::$statuses` — update `getStatusTextAttribute()` and `getStatusBadgeAttribute()` accessors (Seasonal = blue, Hold = yellow)
- Update all merchant status dropdowns in forms

### 6c. Merchant Importer (GAP-13.1)
- Implement 5-step wizard in `resources/views/admin/merchants/merchant-importer.blade.php`
  - Step 1: Drag-and-drop CSV upload zone
  - Step 2: Select defaults (Processor, Group, Sales Rep, Assigned User)
  - Step 3: Field mapping (CSV columns → CRM fields)
  - Step 4: Preview (first 5 rows)
  - Step 5: Import Activity (progress, summary, error table, error CSV download)
- Create `app/Services/MerchantImportService.php` — `process()` method: reads CSV, validates MID uniqueness, creates Merchant records in bulk, returns success/failed/errors
- Create `public/assets/js/merchant-importer.js` — step navigation, drag-drop handlers, AJAX calls
- Add routes: `merchants.importer.upload`, `merchants.importer.process` → new methods in `MerchantController`

---

## New Files Required

| File | Phase |
|------|-------|
| `database/migrations/XXXX_create_merchant_memos_table.php` | 1b |
| `database/migrations/XXXX_create_merchant_statements_table.php` | 3g |
| `database/migrations/XXXX_create_merchant_risk_alert_configs_table.php` | 5c |
| `database/migrations/XXXX_add_tracker_enabled_to_merchants_table.php` | 4b |
| `database/migrations/XXXX_add_response_due_date_to_merchant_transactions.php` | 3e |
| `database/migrations/XXXX_add_representment_deadline_to_merchant_transactions.php` | 3f |
| `database/migrations/XXXX_create_user_favorite_merchants_table.php` | 3a |
| `app/Models/Merchants/MerchantMemo.php` | 1b |
| `app/Models/Merchants/MerchantStatement.php` | 3g |
| `app/Models/Merchants/MerchantRiskAlertConfig.php` | 5c |
| `resources/views/admin/my-merchants/partials/authorizations.blade.php` | 1a |
| `resources/views/admin/my-merchants/partials/memos.blade.php` | 1b |
| `resources/views/admin/my-merchants/partials/1099k.blade.php` | 1c |
| `app/Services/MerchantImportService.php` | 6c |
| `public/assets/js/merchant-importer.js` | 6c |
| `public/assets/js/the-scoop.js` | 5a |

---

## Patterns to Reuse

- **JSON response:** `Helper::resp()` / `Helper::rj()` — used in all AJAX responses
- **File downloads:** `File::upload()` / `Storage::download()` — follow `MerchantHelpdeskTicket` attachment pattern
- **Dynamic headers:** `MasterDynamicHeader::dynamicHeaderColumns()` — reuse for new columns in seeders
- **ApexCharts pattern:** `my-merchant-batches.js` — reuse for all new charts (portfolio activity, the scoop, financials)
- **Soft deletes:** All new models must use `SoftDeletes` trait
- **Error logging:** All catch blocks use `ErrorLog::Log($e)`
- **Select2 multi-select:** Follow leads index pattern for tag-style multi-selects (never reinitialize on already-bound elements)
- **Bootstrap form-switch:** `<div class="form-check form-switch"><input class="form-check-input" type="checkbox">` — GAP-3.2 pattern applies throughout

---

## Verification Steps

After each phase:
1. `php artisan migrate` — run new migrations
2. `php artisan db:seed --class=MyMerchantDynamicHeadersSeeder` — for column additions
3. `npm run dev` — recompile assets
4. `php artisan test` — run full test suite
5. Manual smoke test:
   - **Phase 1:** Visit merchant detail, confirm Authorizations/Memos/1099K tabs appear and load; verify KPI carousel scrolls
   - **Phase 2:** My Merchants listing: confirm date range label, pie chart "Not Processing" segment, form-switches, column visibility gear, filter panel
   - **Phase 3:** All accordion sections visible in Account Status; Statements tab loads (even if empty); Retrievals/Chargebacks show new columns
   - **Phase 4–5:** Each stub page shows real data/charts (not just subtitle)
   - **Phase 6:** Merchant Importer uploads CSV, previews, imports successfully; Merchant Management bulk-select and deactivated toggle work
