13 KiB
Non-EB Claims Module — Development Summary
Overview
Non-EB (Non-Employee Benefits) Claims module for nhance. Handles commercial/property/asset insurance claims (All Risk, Marine, Aviation, Cyber, etc. — 120+ policy types). Mirrors the existing EB Claims (TicketController) architecture.
Built across 4 sessions: 2026-03-24 (prerequisites), 2026-03-26 (form UI + edit sync sessions 2–3), 2026-03-27 (edit read-only + Claim Files tab, session 4).
Files Created
Controller
app/Controllers/NonEbClaimController.php- Extends BaseController, uses ResponseTrait
- Methods:
claimList,claimForm,createClaim,view_claim,updateClaim,removeClaim,mailTemplate,crudTemplate,crudNote,saveReply,claimReports,getBranchAndPolicyByClientID,getVisibleSectionsAjax,getMoreInfo,uploadFile,getClaimFiles,removeFile,saveIRDocs getBranchAndPolicyByClientID()returnsbranch_data[]+policy_datakeyed bybranch_id, filtered bypt.allocg IN ('Non-EB','Marine')
Models
app/Models/NonEbClaimAssetModel.php— Asset details per claimapp/Models/NonEbTicketMasterModel.php— Main ticket/claim mastergetTicketDataByTicketID()JOINsclient_branch cbto exposecb.branch_namefor read-only display in edit view
Views
app/Views/non_eb_claim_search.php— Search page with filter sidebar (Policy Type, Insurer, Claim No, Nhance Ref, Client, Status, Date Range). Contains the Policy Type selection modal for "Add New Claim" (survives AJAX list reload). UseslocalStorageto persist filters.app/Views/non_eb_claim_list.php— DataTable list with CSV/Excel export, action buttons. Modal HTML removed from here (lives in search view).app/Views/non_eb_claim_form.php— New claim form with 9 accordion sections. 3-level cascade: Client → Branch → Policy. Status-based section visibility via AJAX. Section 8 (Documents & Attachments) commented out (code preserved).app/Views/non_eb_claim_edit.php— Edit/view claim. Sections 1 & 2 are fully read-only. 5 tabs: General, Claim Files, Reply, Notes, History. Section 8 commented out.app/Views/non_eb_claim_mail_template.php— Mail template CRUD with Jodit editor, placeholder insertion, auto-mail toggle.app/Views/non_eb_claim_reports.php— Reports with filters (Policy Type, ACM, Date Range), AJAX DataTable with export.
Config Changes
app/Config/Routes.php— Added/non-eb-claimroute group (18 routes) underauthMVCfilter.app/Config/Acl.php— Added ACL entry#^/non-eb-claim#for HEAD, ADMIN, MANAGER, ACCOUNT_MANAGER roles + CLAIMS team.app/Config/Constants.php— AddedUPLOAD_EXT_ASSET_FILESconstant.
Routes Reference
/non-eb-claim/list GET|POST claimList
/non-eb-claim/remove GET removeClaim
/non-eb-claim/new/(:any) GET claimForm/$1
/non-eb-claim/create POST createClaim
/non-eb-claim/update POST updateClaim
/non-eb-claim/view/(:any) GET view_claim/$1
/non-eb-claim/mail_template GET mailTemplate
/non-eb-claim/crud_mail_template/(:any) POST crudTemplate/$1
/non-eb-claim/note/(:any) POST crudNote/$1
/non-eb-claim/reply POST saveReply
/non-eb-claim/reports GET|POST claimReports
/non-eb-claim/getBranchAndPolicy POST getBranchAndPolicyByClientID
/non-eb-claim/getVisibleSections POST getVisibleSectionsAjax
/non-eb-claim/getMoreInfo POST getMoreInfo
/non-eb-claim/uploadFile POST uploadFile
/non-eb-claim/getClaimFiles POST getClaimFiles
/non-eb-claim/removeFile GET removeFile
/non-eb-claim/saveIRDocs POST saveIRDocs
Section Order (Form & Edit Views)
| # | Section | Notes |
|---|---|---|
| 1 | Policy & Account Details | Read-only in edit view (Client, Branch, Policy, Insurer, Policy No, Policy Start/End Date, ACM) |
| 2 | Insured Contact Details | Read-only in edit view |
| 3 | Loss / Incident Details | Editable |
| 4 | Intimation & Claim Reference | Editable |
| 5 | Status & Tracking | Editable |
| 6 | Asset Details | Dynamic rows + file upload option |
| 7 | Surveyor Details | Conditional (status-based) |
| 8 | Documents & Attachments | Commented out in both form and edit (code preserved) |
| 9 | Settlement Details | Conditional (status-based) |
Edit view additionally has: Claim Files tab (IR Documents checklist + file upload + file list)
DB Schema — Key Columns
non_eb_ticket_master
| Column | Type | Notes |
|---|---|---|
branch_id |
INT | Added session 2 |
asset_file |
VARCHAR | Path to uploaded asset file |
policy_start_date |
VARCHAR(20) | Stored as YYYY-MM-DD, displayed as DD-MM-YYYY |
policy_end_date |
VARCHAR(20) | Same format |
required_docs |
TEXT | JSON array for IR Documents checklist |
policy_section |
— | Kept in DB but removed from all UI/model code |
policy_period |
— | Kept in DB but removed from all UI/model code |
claim_files
| Column | Type | Notes |
|---|---|---|
ticket_type |
TINYINT(1) DEFAULT 1 | 1=EB, 2=Non-EB. Added to share table without breaking EB records |
DB Trigger
non_eb_ticket_master_after_update — tracks 22 fields into ticket_history on every UPDATE. TEXT fields (loss_description, lor, surveyor_remarks, closure_remark) truncated to 500 chars. Skipped: set-once/bulk fields (client_id, branch_id, insured_contact_, google_drive_links, documents_, asset_file, required_docs).
Full DDL in db.md.
Key Patterns & Decisions
UI Style — Bootstrap Card/Collapse Accordion
All sections use Bootstrap card/collapse pattern (matching ticket_form_gmc.php):
<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"> ... </div>
</div>
</div>
</div>
Custom toggleAccordion() and .accordion/.accordion-content CSS fully removed.
CSS Classes
.readonly-color { background-color: #e0e0e0; color: #666; }
.readonly-select { pointer-events: none; background-color: #f0f0f0; color: #666; }
.label-font-size { font-size: 0.875rem; }
.is-invalid { border-color: #dc3545 !important; }
.invalid-feedback { display: none; color: #dc3545; font-size: 0.8rem; }
3-Level Dropdown Cascade (Create Form Only)
- Client change → AJAX
non-eb-claim/getBranchAndPolicy→ returnsbranch_data[]+policy_data{branch_id: [...]} - Branch change → populates policies from stored
noneb_policy_list[branch_id], auto-fills insured contact - Policy change → auto-fills insurer, policy_no, policy start/end dates (YYYY-MM-DD → dd-mm-yyyy)
- Select2 fix: All append/reset functions do
select2('destroy')before DOM changes, thenselect2()re-init after. Guard:.hasClass('select2-hidden-accessible')
Edit View — Read-Only Section 1 & 2 (Session 4)
Sections 1 and 2 are non-editable on the edit page. Strategy:
- All dropdowns replaced with readonly text inputs showing stored values
- Hidden inputs for
branch_idandacm_idcarry values on form submit - No AJAX cascade JS — all client/branch/policy change handlers removed from edit page
- Policy display:
policy_type_name + policy_nocombined in one text input - PHP date formatting at top of edit view: detects YYYY-MM-DD, converts to DD-MM-YYYY for display
validateNonEbForm()in edit page: removed client/branch/ACM/contact validation (those sections are read-only)
Form Submission — FormData
Both create and edit forms use new FormData() + $.ajax({ processData: false, contentType: false }) to support file uploads. X-Requested-With: XMLHttpRequest header added for CI4 isAJAX() detection.
Status-Based Section Visibility
$statusSectionVisibility mapping in controller. AJAX endpoint getVisibleSections returns which sections show/hide. Surveyor and Settlement sections are conditionally visible.
Modal Fix (List Page)
Modal HTML in non_eb_claim_search.php (parent), not inside the AJAX-replaced #claim_list_div. Reason: $('#claim_list_div').empty().html(response.html) destroys inner modals on filter. Uses new bootstrap.Modal() for AJAX-safe init.
URL Construction
base_urlJS var ='http://localhost/nhance/'(trailing slash from App.php)- All AJAX URLs:
base_url + 'non-eb-claim/...'(no leading slash — avoids double-slash)
Claim Files Tab (Edit Page — Session 4)
Reuses claim_files table with ticket_type=2 flag. Four controller methods handle Non-EB file operations:
| Method | Route | Purpose |
|---|---|---|
uploadFile() |
POST /uploadFile |
URL or physical file upload, inserts with ticket_type=2 |
getClaimFiles() |
POST /getClaimFiles |
Fetch files for ticket filtered by ticket_type=2 |
removeFile() |
GET /removeFile |
Soft delete (is_active=0) by file id |
saveIRDocs() |
POST /saveIRDocs |
Save IR Documents JSON to non_eb_ticket_master.required_docs |
Tab content: IR Documents checklist (JSON stored in required_docs, with freeze toggle + save button) + file upload form (URL/file toggle) + file list table + edit URL modal.
JS functions (all prefixed noneb to avoid collision with EB claims JS):
nonebLoadClaimFiles, nonebCreateFileList, nonebAddHTMLInput, nonebAddFileUploadHtml, nonebRemoveHTMLInput, nonebToggleUploadType, nonebLoadConfiguration, nonebRenderDocumentList, nonebCreateDocumentRow, nonebAddDocument, nonebRemoveDocument, nonebUpdateDocName, nonebUpdateDocReceived, nonebToggleActionFreeze, nonebSaveIRDocs
File downloads reuse the global downloadClaimFile/(:any) route (no ticket_type filtering needed for download).
saveIRDocs is a separate endpoint (non-eb-claim/saveIRDocs) from the EB equivalent (ticket/saveIRDocsJson) — EB updates ticket_master, Non-EB updates non_eb_ticket_master.
Frontend Validation (validateNonEbForm())
Full JS validation runs before AJAX submit on both create and edit forms.
| Field | Rules |
|---|---|
client_select |
Required (create only) |
branch_id |
Required (create only) |
acm_id |
Required (create only) |
claim_status_id |
Required |
insured_contact_name |
Required, min 3 chars, ^[a-zA-Z0-9\s_-]+$ (create only) |
insured_contact_number |
Required, numeric, 10–15 digits (create only) |
insured_contact_email |
Optional, email format (create only) |
nature_of_loss |
Required, min 3 chars |
loss_location |
Required |
loss_date |
Required |
loss_estimate |
Optional, numeric |
claim_number |
Optional, ^[a-zA-Z0-9\/_-]+$ |
nhance_claim_ref_no |
Optional, max 100 chars |
surveyor_contact_number |
Optional if section visible, numeric 10–15 digits |
surveyor_email |
Optional if section visible, email format |
loss_assessed_value |
Optional if section visible, numeric |
settled_amount |
Optional if section visible, numeric |
settlement_utr |
Optional if section visible, max 100 chars |
| Asset section | At least one asset row with data OR valid file upload |
On failure: toastr error, expands collapsed section containing first invalid field, scrolls + focuses it.
Post-Update Redirect (Edit Page)
After successful update AJAX, 800ms delay then redirect to list:
setTimeout(function() { window.location.href = base_url + 'non-eb-claim/list'; }, 800);
Toast remains visible during the delay.
Bugs Fixed
| Bug | Fix |
|---|---|
| Modal not showing on Add click | Moved modal outside AJAX-replaced div, used new bootstrap.Modal() |
| Policies not loading on client select | Fixed double-slash in AJAX URLs (base_url already has trailing /) |
| Select2 dropdowns not updating | Added select2('destroy') before DOM manipulation, select2() re-init after |
Policy dates showing as 2-Dec-2026 12:00 am |
Replaced formatDate() with inline string split; checks sp[0].length === 4 to detect YYYY |
Branch name missing in edit view $td |
Added JOIN client_branch cb + cb.branch_name select to getTicketDataByTicketID() |
| Edit Section 1 dropdowns not pre-selecting | Replaced dropdowns with readonly text inputs — simpler and reliable |
Removed Fields (policy_section & policy_period)
Removed from all UI and code but kept in DB (for historical data).
| Location | Change |
|---|---|
NonEbTicketMasterModel allowedFields |
Removed both |
claimSearch() select in controller |
Removed tm.policy_section, tm.policy_period |
getValidationRules() in controller |
Removed both validation rules |
non_eb_claim_edit.php Section 1 |
Removed from view |
non_eb_claim_list.php |
Removed hidden <th> and <td> columns |
db.md |
Commented-out DROP COLUMN statements added for future cleanup |
Pending / TODO
- Run DB ALTER TABLE statements (policy_start_date, policy_end_date, required_docs on
non_eb_ticket_master; ticket_type onclaim_files) - Run
non_eb_ticket_master_after_updatetrigger in DB - End-to-end testing: create claim → edit claim → Claim Files tab → IR docs → History tab trigger verification
- Verify status-based section visibility for all policy types
- Test filter persistence (localStorage) on search page
- Review
db.mdfor any missing DDL