nhance/public/dev_logs/2026-03-26.md
2026-03-31 12:04:35 +05:30

342 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dev Log — 2026-03-26
## Feature: Non-EB Claim Form — UI Overhaul, Validation & Asset File Upload
### Objective
Continued development of the Non-EB Claims creation form (`non_eb_claim_form.php`). This session covered three major areas: (1) UI restyling to match the GMC ticket form, (2) comprehensive frontend validation with JS-only form submission, and (3) asset section enhancement with file upload support.
---
## 1. UI Restyling — Match `ticket_form_gmc.php` Accordion & Card Style
### What Changed
Replaced the custom accordion implementation with Bootstrap card/collapse pattern used in the existing GMC ticket form.
### Before
- Custom CSS classes: `.accordion`, `.accordion-content`, `.arrow`, `.rotate`
- Custom JS `toggleAccordion(el)` function using `classList.toggle('show')`
- Section headers: `<h4 onclick="toggleAccordion(this)">Title <span class="arrow">&#9654;</span></h4>`
- Section body: `<div class="accordion-content show">`
- Labels had no consistent font-size class
### After
- Bootstrap card/collapse pattern: `<div class="card mb-1">``<div class="collapse show">`
- Section headers: `<h4 class="m-1">Title <a data-toggle="collapse" href="#collapseX"><i class="mdi mdi-chevron-down"></i></a></h4>`
- Section body: `<div id="collapseX" class="collapse show" data-parent="#accordionX"><div class="card-body">`
- Removed `toggleAccordion()` JS function entirely
- All labels now use `class="label-font-size"` (0.875rem) matching GMC form
### CSS Classes Added (matching `ticket_form_gmc.php`)
```css
.readonly-color { background-color: #e0e0e0; color: #666; }
.readonly-select { pointer-events: none; background-color: #f0f0f0; color: #666; }
.label-font-size { font-size: 0.875rem; }
```
### Readonly Fields Styled
- Insurer, Policy No, Policy Start Date, Policy Expiry Date inputs — added `readonly-color` class for darker background on auto-filled fields
### Section ID Mapping
| Section | Accordion ID | Collapse ID |
|---|---|---|
| Policy & Account Details | accordion1 | collapseOne |
| Insured Contact Details | accordion2 | collapseTwo |
| Loss / Incident Details | accordion3 | collapseThree |
| Intimation & Claim Reference | accordion4 | collapseFour |
| Status & Tracking | accordion5 | collapseFive |
| Asset Details | accordion6 | collapseSix |
| Surveyor Details | section_surveyor | collapseSeven |
| Documents & Attachments | accordion8 | collapseEight |
| Settlement Details | section_settlement | collapseNine |
- Surveyor and Settlement sections use `section_surveyor` / `section_settlement` as parent IDs (for JS show/hide toggling based on status)
---
## 2. Frontend Validation & JS-Only Form Submit
### What Changed
Removed reliance on native HTML5 form submission. Implemented full JavaScript validation matching backend rules in `NonEbClaimController::getValidationRules()`.
### Form Changes
- Added `onsubmit="return false;"` to `<form>` to prevent native submit
- Submit button remains `type="button"` with `onclick="submitNonEbClaim()"`
- `submitNonEbClaim()` now calls `validateNonEbForm()` first — only proceeds to AJAX if validation passes
### Validation CSS Added
```css
.is-invalid { border-color: #dc3545 !important; }
.invalid-feedback { display: none; color: #dc3545; font-size: 0.8rem; }
.is-invalid ~ .invalid-feedback, .is-invalid + .invalid-feedback { display: block; }
.select2-container .select2-selection--single.is-invalid-select2 { border-color: #dc3545 !important; }
```
### Validation Rules (matching backend)
| Field | Type | Rules |
|---|---|---|
| `client_select` | Select2 | Required |
| `branch_id` | Select2 | Required |
| `acm_id` | Select2 | Required |
| `claim_status_id` | Select | Required |
| `insured_contact_name` | Text | Required, min 3 chars, pattern `^[a-zA-Z0-9\s_-]+$` |
| `insured_contact_number` | Text | Required, numeric only, 10-15 digits |
| `insured_contact_email` | Email | Optional, email format regex |
| `nature_of_loss` | Text | Required, min 3 chars |
| `loss_location` | Text | Required |
| `loss_date` | Date | Required |
| `loss_estimate` | Number | Optional, must be numeric |
| `claim_number` | Text | Optional, pattern `^[a-zA-Z0-9\/_-]+$` |
| `nhance_claim_ref_no` | Text | Optional, max 100 chars |
| `surveyor_contact_number` | Text | Optional (only if section visible), numeric, 10-15 digits |
| `surveyor_email` | Email | Optional (only if section visible), email format |
| `loss_assessed_value` | Number | Optional (only if section visible), numeric |
| `settled_amount` | Number | Optional (only if section visible), numeric |
| `settlement_utr` | Text | Optional (only if section visible), max 100 chars |
### HTML Validation Attributes Added
- `minlength`, `maxlength`, `pattern`, `min`, `required` attributes on relevant input fields
- `<div class="invalid-feedback">` added after each validated field with descriptive error message
### JS Validation Functions Added
- **`clearValidation()`** — Removes `.is-invalid` and `.is-invalid-select2` from all form elements
- **`setInvalid(field, msg)`** — Marks a field invalid with custom message
- **`validateNonEbForm()`** — Main validation function:
- Validates all required and optional fields per rules above
- Select2 dropdowns: highlights the `.select2-selection` border red via `.is-invalid-select2`
- Surveyor/Settlement fields: only validated if their parent section is visible
- On failure: shows all errors via `toastr.error()`, expands collapsed section if first invalid field is hidden, scrolls to first invalid field and focuses it
- Returns `true`/`false`
### Real-time Validation Clearing
- `input`/`change` events on `.form-control` → removes `.is-invalid`
- `change` event on `select` → removes both `.is-invalid` and `.is-invalid-select2` from Select2 container
---
## 3. Asset Section — File Upload with OR Divider
### What Changed
Added a file upload option in the Asset Details section as an alternative to manually filling asset rows.
### UI Structure
```
[Asset Row 1: ID/Code | Serial No | Vehicle No | Description]
[+ Add More Asset] button
─────────────────── OR ───────────────────
[Upload Asset File (Excel or PDF)] [Browse...]
```
### OR Divider
- Flexbox layout with two `<hr>` elements and centered "OR" text
- Styled with `font-weight-bold text-muted`, `0.9rem` font size
### File Upload Field
- `<input type="file" name="asset_file" id="asset_file" accept=".xlsx,.xls,.csv,.pdf">`
- Accepts: `.xlsx`, `.xls`, `.csv`, `.pdf`
- Error message div: `#asset_section_error` — shown when neither asset row nor file is provided
### Validation Logic
On form submit, checks:
1. **Has any asset row with data?** — Iterates all `.asset-row` elements, checks if any input has a non-empty value
2. **Has a valid file?** — Checks if file is selected and extension is one of `.xlsx`, `.xls`, `.csv`, `.pdf`
3. If **neither** condition met → shows error "Please fill at least one asset row or upload an asset file."
4. If file has **invalid extension** → marks file input invalid with specific message
### Form Submit Changed to FormData
- Form tag: added `enctype="multipart/form-data"`
- `submitNonEbClaim()`: replaced `$('#nonEbClaimForm').serialize()` with `new FormData(document.getElementById('nonEbClaimForm'))`
- AJAX call: switched from `sendAjaxRequestForGlobal()` to `$.ajax()` with `processData: false, contentType: false` to support file upload
- Added `X-Requested-With: XMLHttpRequest` header for CI4 `$this->request->isAJAX()` detection
### Real-time Error Clearing
- Asset row input change → hides `#asset_section_error`
- File input change → removes `.is-invalid` and hides `#asset_section_error`
---
## 4. Policy Date Format Fix (Continued from Previous Session)
### Issue
Policy start/end dates displayed as `2-Dec-2026 12:00 am` instead of `12-02-2026` when selecting a policy.
### Root Cause
API returns dates in MySQL format `YYYY-MM-DD` (e.g., `2026-02-12`). The JS `formatDate()` function was not being applied correctly.
### Fix Applied
Replaced `formatDate()` call with inline string split conversion in policy change handler:
```js
var startRaw = sel.attr('data-start-date') || '';
if (startRaw && startRaw.indexOf('-') > -1) {
var sp = startRaw.split('-');
if (sp[0].length === 4) startRaw = sp[2] + '-' + sp[1] + '-' + sp[0];
}
```
- Splits `2026-02-12``['2026','02','12']`
- Checks first part is 4 digits (year)
- Rearranges to `12-02-2026`
---
## Files Modified
| File | Changes |
|---|---|
| `app/Views/non_eb_claim_form.php` | Full UI restyle, validation, asset file upload |
| `app/Controllers/NonEbClaimController.php` | Minor — reverted PHP date formatting (not needed, API already returns MySQL format) |
---
## Notes
- Backend controller `asset_file` upload handling — implemented in both `createClaim()` and `updateClaim()`
- The `sendAjaxRequestForGlobal()` utility was replaced with raw `$.ajax()` in submit because it doesn't support `FormData` with `processData: false`
---
## 5. Edit View (`non_eb_claim_edit.php`) — Sync with Create Form
### Objective
Bring the edit view in line with the create form's UI, validation, and scripting changes from sections 14 above.
### A. CSS Changes
| Change | Before (Edit) | After (Edit) |
|---|---|---|
| Accordion CSS | Custom `.accordion`, `.accordion-content`, `.arrow`, `.rotate` | Removed — replaced by Bootstrap card/collapse |
| `toggleAccordion()` JS | Present | Removed |
| Validation CSS | Missing | Added `.is-invalid`, `.invalid-feedback`, `.is-invalid-select2` |
| Readonly CSS | Missing | Added `.readonly-color`, `.readonly-select` |
### B. HTML Section Changes — All 9 Sections Converted to Bootstrap Card/Collapse
Each section changed from:
```html
<div class="accordion">
<h4 onclick="toggleAccordion(this)">Title <span class="arrow rotate">&#9654;</span></h4>
<div class="accordion-content show">
```
To:
```html
<div id="accordionX" class="mb-3">
<div class="card mb-1">
<h4 class="m-1">Title <a data-toggle="collapse" href="#collapseX"><i class="mdi mdi-chevron-down"></i></a></h4>
<div id="collapseX" class="collapse show" data-parent="#accordionX">
<div class="card-body">
```
### Section-Specific HTML Changes
| Section | ID Mapping | Key Field Changes |
|---|---|---|
| 1. Policy & Account | accordion1 / collapseOne | Added Policy Start Date & Expiry Date fields (readonly, `readonly-color`). Insurer field gets `readonly-color`. Policy No gets `readonly-color`. All labels get `label-font-size`. |
| 2. Insured Contact | accordion2 / collapseTwo | Added `id` attrs on inputs. Added `minlength="3"`, `pattern` on contact name. Added `minlength="10" maxlength="15" pattern="^[0-9]+$"` on contact number. Added `invalid-feedback` divs. |
| 3. Loss / Incident | accordion3 / collapseThree | Added `id` attrs, `minlength="3"` on nature_of_loss, `min="0"` on loss_estimate. Added `invalid-feedback` divs. Date placeholder changed to `dd-mm-yyyy`. |
| 4. Intimation & Ref | accordion4 / collapseFour | Added `id` attrs, `maxlength="100"` on nhance_claim_ref_no, `pattern` on claim_number. Added `invalid-feedback` divs. Date placeholder `dd-mm-yyyy`. |
| 5. Status & Tracking | accordion5 / collapseFive | Labels get `label-font-size`. |
| 6. Asset Details | accordion6 / collapseSix | Labels get `label-font-size`. |
| 7. Surveyor Details | section_surveyor / collapseSeven | Added `minlength="10" maxlength="15" pattern="^[0-9]+$"` on contact number. Added `invalid-feedback` divs on contact number and email. `maxlength="255"` on name/contact person. |
| 8. Documents | accordion8 / collapseEight | Labels get `label-font-size`. Date placeholder `dd-mm-yyyy`. |
| 9. Settlement | section_settlement / collapseNine | Added `min="0"` on numeric fields, `maxlength="100"` on UTR. Added `invalid-feedback` divs. |
### Form Tag Changes
- Added `onsubmit="return false;"` to prevent native submit
### C. JavaScript Changes
| Change | Details |
|---|---|
| Removed `toggleAccordion()` | No longer needed — Bootstrap collapse handles it |
| Added `validateNonEbForm()` | Full JS validation matching create form — all 16+ field rules |
| Added `clearValidation()` | Removes `.is-invalid` / `.is-invalid-select2` |
| Added `setInvalid()` | Marks field invalid with message |
| Added `formatDate()` | Handles MySQL YYYY-MM-DD to dd-mm-yyyy conversion |
| Added `resetContact()` | Clears insured contact fields |
| Added `noneb_contact_list` | Stores contact data from AJAX |
| Branch change handler | Added contact auto-fill from `noneb_contact_list` |
| `appendPolicies()` | Added `data-policy-type`, `data-start-date`, `data-end-date` attrs |
| Policy change handler | Added date auto-fill (policy start/end date) with YYYY-MM-DD → dd-mm-yyyy |
| `resetPolicy()` | Added clearing of policy start/end date fields |
| `submitNonEbClaim()` | Now calls `validateNonEbForm()` before AJAX |
| Real-time validation clearing | `input`/`change` on `.form-control` removes `.is-invalid`. `change` on `select` removes `.is-invalid-select2`. Asset file change clears error. |
| flatpickr dateFormat | Changed from `d/m/Y` to `d-m-Y` to match create form |
---
## Files Modified (Updated)
| File | Changes |
|---|---|
| `app/Views/non_eb_claim_form.php` | Full UI restyle, validation, asset file upload (session 1) |
| `app/Views/non_eb_claim_edit.php` | Full UI restyle sync, validation, contact auto-fill, date fields (session 2) |
| `app/Controllers/NonEbClaimController.php` | `asset_file` upload handling in create/update |
| `app/Models/NonEbTicketMasterModel.php` | Added `asset_file`, `branch_id` to allowedFields |
| `app/Config/Constants.php` | Added `UPLOAD_EXT_ASSET_FILES` |
| `db.md` | Added `branch_id`, `asset_file` columns + ALTER TABLE queries |
---
## 6. Edit View (`non_eb_claim_edit.php`) — Full Sync with Create Form (Session 3)
### Objective
Complete remaining sections (39) and all JS that were still using the old accordion pattern. This session fully brings `non_eb_claim_edit.php` in parity with `non_eb_claim_form.php`.
---
### A. HTML — Sections 39 Converted to Bootstrap Card/Collapse
| Section | Old | New |
|---|---|---|
| 3. Loss / Incident Details | `<div class="accordion">` + `onclick="toggleAccordion(this)"` | `<div id="accordion3" class="mb-3">` + Bootstrap card/collapse (`collapseThree`) |
| 4. Intimation & Claim Reference | Same old pattern | `<div id="accordion4" class="mb-3">` (`collapseFour`) |
| 5. Status & Tracking | Same old pattern | `<div id="accordion5" class="mb-3">` (`collapseFive`) |
| 6. Asset Details | Same old pattern | `<div id="accordion6" class="mb-3">` (`collapseSix`) |
| 7. Surveyor Details | `<div class="accordion" id="section_surveyor">` | `<div id="section_surveyor" class="mb-3">` + inner Bootstrap card/collapse (`collapseSeven`) |
| 8. Documents & Attachments | Same old pattern | `<div id="accordion8" class="mb-3">` (`collapseEight`) |
| 9. Settlement Details | `<div class="accordion" id="section_settlement">` | `<div id="section_settlement" class="mb-3">` + inner Bootstrap card/collapse (`collapseNine`) |
### Section-Specific Field Changes
| Section | Field Changes |
|---|---|
| 3. Loss / Incident | Added `id` attrs on all inputs. Added `minlength="3"` on `nature_of_loss`. Added `min="0"` on `loss_estimate`. Added `invalid-feedback` divs. Date placeholder `dd/mm/yyyy``dd-mm-yyyy`. All labels get `label-font-size`. |
| 4. Intimation | Added `id` attrs. Added `maxlength="100"` on `nhance_claim_ref_no`. Added `pattern="^[a-zA-Z0-9\/_-]+$"` on `claim_number`. Added `invalid-feedback` divs. Date placeholders `dd/mm/yyyy``dd-mm-yyyy`. Labels get `label-font-size`. |
| 5. Status & Tracking | Labels get `label-font-size`. |
| 6. Asset Details | Asset row labels get `label-font-size`. Asset file upload label gets `label-font-size`. |
| 7. Surveyor Details | Added `minlength="10" maxlength="15" pattern="^[0-9]+$"` on contact number. Added `maxlength="255"` on name and contact person. Added `invalid-feedback` on contact number and email. Labels get `label-font-size`. |
| 8. Documents | Labels get `label-font-size`. Date placeholder `dd/mm/yyyy``dd-mm-yyyy`. |
| 9. Settlement | Added `min="0"` on `loss_assessed_value` and `settled_amount`. Added `maxlength="100"` on `settlement_utr`. Added `invalid-feedback` divs on all three. Labels get `label-font-size`. |
---
### B. JavaScript Changes
| Change | Details |
|---|---|
| Removed `toggleAccordion()` | No longer needed — Bootstrap collapse handles it |
| `appendPolicies()` | Added `data-policy-type`, `data-start-date`, `data-end-date` attrs; also added `insurer_short_name`/`insurer_branch_code` display logic matching create form |
| `resetPolicy()` | Added `$('#policy_start_date').val('')` and `$('#policy_end_date').val('')` |
| Added `noneb_contact_list` | Variable to store contact data keyed by branch |
| Removed `noneb_branch_list` | Was unused; removed |
| Added `resetContact()` | Clears `insured_contact_name`, `insured_contact_number`, `insured_contact_email` |
| Client change handler | Added `resetContact()` call; populates `noneb_contact_list` from `response.contact_data`; added error toastr on failure |
| Branch change handler | Added contact auto-fill from `noneb_contact_list[branch_id]` (name, number, email) |
| Policy change handler | Changed `.data()` to `.attr()` for custom data attributes. Added date auto-fill: reads `data-start-date`/`data-end-date`, converts YYYY-MM-DD → dd-mm-yyyy via inline split, writes to `#policy_start_date`/`#policy_end_date` |
| Added `formatDate()` | Handles both `dd-Mon-yyyy hh:mm` and `YYYY-MM-DD` formats → `dd-mm-yyyy` |
| Added `clearValidation()` | Removes `.is-invalid` and `.is-invalid-select2` from all form elements |
| Added `setInvalid()` | Marks a field invalid with optional custom message |
| Added `validateNonEbForm()` | Full validation matching backend rules — 16+ fields including conditional surveyor/settlement sections and asset row/file check |
| `submitNonEbClaim()` | Added `if (!validateNonEbForm()) return;` before AJAX |
| `flatpickr` dateFormat | Changed from `d/m/Y` to `d-m-Y` |
| Select2 init | Added `$('#client_select').select2()`, `$('#branch_id').select2()`, `$('#client_policy_id').select2()` alongside existing `.select2-init` |
| Real-time validation clearing | `input`/`change` on `.form-control` removes `.is-invalid`; `change` on `select` removes `.is-invalid` and `.is-invalid-select2`; `#asset_file` change hides `#asset_section_error`; asset row input hides `#asset_section_error` |
---
## Files Modified (Session 3)
| File | Changes |
|---|---|
| `app/Views/non_eb_claim_edit.php` | Sections 39 HTML converted to Bootstrap card/collapse; full JS sync — validation, contact auto-fill, policy date auto-fill, real-time clearing |