This page documents the Non-EB Claims web workflow: list and filter claims, create and edit tickets, status-driven form sections, document uploads, manual email reply, mail template CRUD, auto-mail on create/status change, and claim reports.

Scope: authenticated MVC routes under /non-eb-claim/* only. Mobile/REST endpoints in Api\NonEbClaimApiController are not covered here.

Policy types are limited to policy_type.allocg IN ('Non-EB', 'Marine'). Claim records live in non_eb_ticket_master; claim files use ticket_type = 2 in claim_files.

End-to-end flow

flowchart TD L["GET /non-eb-claim/list"] --> F["Filter sidebar → POST /list"] F --> T["Table non_eb_claim_list.php"] T --> A{"Action"} A -->|Add| N["GET /non-eb-claim/new/50 or new/{policy_type_id}"] N --> C["POST /non-eb-claim/create"] C --> AM["sendAutoMailTrigger if template is_auto_mail=1"] A -->|Row click / View| V["GET /non-eb-claim/view/{id}"] V --> U["POST /non-eb-claim/update"] U --> SC{"claim_status_id changed?"} SC -->|yes| AM2["sendAutoMailTrigger"] MT["GET /non-eb-claim/mail_template"] --> CRUD["POST crud_mail_template/1|2|3"] R["GET /non-eb-claim/reports"] --> RP["POST /reports — UI only; see pitfalls"]

Typical user path:

  1. Open claim list (default: open claims excluding settled/closed/rejected/withdrawn).
  2. Add claim → form opens with canonical status policy type 50 — see why 50 is hardcoded.
  3. On save, optional auto-mail fires if a matching template has is_auto_mail = 1.
  4. Open claim from list → edit view with history, messages, files, notes.
  5. Change status → allowed next statuses from ticket_claim_status.allowed_status; section visibility updates.
  6. Configure templates at /non-eb-claim/mail_template (direct URL; not in main Claims sidebar today).

Why policy type 50 is hardcoded (read this before changing Non-EB Claims)

Non-EB has many real policy products (Fire, Marine, Liability, etc. — each row in policy_type with allocg Non-EB or Marine). Claim status workflows are not stored separately per product today. The team configured one canonical policy type, id 50, in the database as the single source of status definitions. The application assumes every Non-EB/Marine claim uses that same status set unless you deliberately change backend and frontend.

Design assumption

Claim statuses live in ticket_claim_status, keyed by ticket_type (which equals policy_type.id). Mail templates in ticket_mail_template also key off ticket_type + trigger_type from that status row.

Instead of maintaining duplicate status trees for every Non-EB product, developers assumed:

All Non-EB and Marine policy types share one identical claim status lifecycle. That lifecycle is configured only under policy type 50 in ticket_claim_status (and matching templates under ticket_type = 50).

New claims opened via the list Add button or New Non EB Claim menu therefore pass 50 into the form URL. Status dropdowns, section visibility, and initial status resolution in getClaimStatusForPolicyType($policy_type_id) all use that id on create — not the id of the policy the user later picks from client_policy.

Policy type 50 vs policy selected on the form

On create (non_eb_claim_form.php):

On edit (non_eb_claim_edit.php), policy_type_id comes from non_eb_ticket_master as saved. Status changes and templates use that stored id.

Where 50 appears in code (change all if this design changes)

LocationUsage
app/Config/Routes.phpGET non-eb-claim/newclaimForm/50
app/Views/non_eb_claim_list.phpDataTable Add button → /non-eb-claim/new/50
app/Views/non_eb_claim_form.phpHidden policy_type_id from route; status/section AJAX uses this value
ticket_claim_status (DB)Master status rows maintained with ticket_type = 50
ticket_mail_template (DB)Non-EB auto-mail templates should use ticket_type = 50 if they follow the shared workflow
Api\NonEbClaimApiController::listClaimStatuses()API hardcodes where('ticket_type', 50) (out of scope for this page but same assumption)

When a Non-EB product needs a different status set

If a new (or existing) policy type must have its own statuses, triggers, or allowed transitions (not the shared tree under 50), you cannot only change the product row in policy_type. You must update both backend and frontend:

  1. Database — Add full ticket_claim_status rows with ticket_type = <that policy_type.id> (claim_status, display_name, trigger_type, allowed_status JSON). Add matching ticket_mail_template rows for that ticket_type if auto-mail applies.
  2. Routes / entry URL — Stop routing every new claim through 50: e.g. change claimForm/50, restore policy-type picker modal (commented in non_eb_claim_search.php), or pass the correct policy_type_id per product.
  3. List Add button — Replace hardcoded new/50 in non_eb_claim_list.php with the correct id or dynamic selection.
  4. Create form — On policy selection, set hidden #policy_type_id to the real policy_type_id from getBranchAndPolicy (field p.policy_type_id is already returned) so create/update and getVisibleSections use the right status tree.
  5. Controller logic — Ensure getClaimStatusForPolicyType, getTemplateDataByTicketID, and filters that assume a single Non-EB status catalog are tested for the new ticket_type.
  6. API — Replace hardcoded 50 in listClaimStatuses() if mobile clients need per-product statuses.

Until those steps are done, pointing Add at another id without cloning the full status + template set under that id will produce empty status lists, wrong section visibility, or missing auto-mail.

Key files and routes

AreaFile / route
Controllerapp/Controllers/NonEbClaimController.php
Modelapp/Models/NonEbTicketMasterModel.php
List + filtersapp/Views/non_eb_claim_search.php, non_eb_claim_list.php
New claimapp/Views/non_eb_claim_form.php
View / editapp/Views/non_eb_claim_edit.php
Mail templatesapp/Views/non_eb_claim_mail_template.php
Reportsapp/Views/non_eb_claim_reports.php
Routesapp/Config/Routes.php — group /non-eb-claim, filter authMVC
ACLapp/Config/Acl.php#^/non-eb-claim# (Claims team roles)
App menuapp/Views/layout/header.php — New / List only (EB mail template link is separate)

MVC route map

MethodRouteControllerPurpose
GET/non-eb-claim/listclaimListSearch page + default open claims
POST/non-eb-claim/listclaimListFilter → HTML partial for DataTable
GET/non-eb-claim/newclaimForm/50New claim (default policy type 50)
GET/non-eb-claim/new/{policy_type_id}claimFormNew claim for selected product
POST/non-eb-claim/createcreateClaimCreate ticket + assets + history + auto-mail
GET/non-eb-claim/view/{id}view_claimEdit layout (non_eb_claim_edit)
POST/non-eb-claim/updateupdateClaimUpdate; auto-mail on status change
GET/non-eb-claim/remove?ticket_id=removeClaimSoft delete (is_active = 0)
GET/non-eb-claim/mail_templatemailTemplateTemplate list + modal CRUD UI
POST/non-eb-claim/crud_mail_template/1crudTemplateSave template
POST/non-eb-claim/crud_mail_template/2crudTemplateFetch one template (edit)
POST/non-eb-claim/crud_mail_template/3crudTemplateSoft delete template
POST/non-eb-claim/note/1crudNoteGet note
POST/non-eb-claim/note/2crudNoteSave note
POST/non-eb-claim/replysaveReplyManual outbound mail + message row
GET/non-eb-claim/reportsclaimReportsReports UI shell
POST/non-eb-claim/reportsclaimReportsNot implemented in controller — see Reports
POST/non-eb-claim/getBranchAndPolicygetBranchAndPolicyByClientIDBranches, policies, contacts for client
POST/non-eb-claim/getVisibleSectionsgetVisibleSectionsAjaxSection keys for status
POST/non-eb-claim/getMoreInfogetMoreInfoTicket row JSON
POST/non-eb-claim/uploadFileuploadFileClaim docs (file or Drive URL)
POST/non-eb-claim/getClaimFilesgetClaimFilesList files for ticket
GET/non-eb-claim/removeFile?id=removeFileSoft delete file
POST/non-eb-claim/saveIRDocssaveIRDocsPersist required-docs JSON on ticket
GET/non-eb-claim/testAutoMail/{id}testAutoMailTriggerDev/test auto-mail (optional)

Access control

All routes in the /non-eb-claim group use the authMVC filter. Acl.php allows roles HEAD, ADMIN, MANAGER, ACCOUNT_MANAGER on the Claims team.

List row actions (view / delete) render only for roles 1, 2, 5 in non_eb_claim_list.php.

List and filter

GET /non-eb-claim/list loads non_eb_claim_search.php, which includes the table partial. Initial data comes from claimSearch(1): active tickets where status display name is not in Claim Settled, Claim Closed, Claim Rejected, Claim Withdrawn.

Filter sidebar posts the same URL with criteria (at least one required):

Response is JSON { status: true, html: "…" }; JS replaces #claim_list_div and re-initializes the DataTable. Row click navigates to /non-eb-claim/view/{id}.

Add button: window.location.href = '/non-eb-claim/new/50'. Header menu uses /non-eb-claim/new (routes to claimForm/50). See Policy type 50 for why this id is fixed and what to change if a product needs its own statuses.

Create and edit claim

Create

  1. GET /non-eb-claim/new/{policy_type_id}getFormData(): ACMs (role 3), clients, insurers, initial claim status for product, visible sections.
  2. User selects client → POST getBranchAndPolicy fills branch, policy (Non-EB/Marine only), branch contact.
  3. Status change → POST getVisibleSections toggles accordion sections client-side.
  4. POST /non-eb-claim/create — validation via getValidationRules(), sanitizeInputArrayAdvanced, date normalization, optional asset file upload.
  5. Duplicate guard: same client_id + loss_date + policy_no (if policy set) → HTTP 409-style JSON.
  6. On success: insert non_eb_ticket_master, saveAssets(), history row, sendAutoMailTrigger(), redirect to list.

View / edit

view_claim($id) loads ticket via NonEbTicketMasterModel::getTicketDataByTicketID(), merges mail template preview (getTemplateDataByTicketID + placeholder replace), messages, history, assets, and reuses the edit view non_eb_claim_edit.php.

POST /non-eb-claim/update mirrors create validation. If claim_status_id changes, auto-mail runs again. remark_mode=append appends to closure_remark with a separator.

Status-driven sections

$statusSectionVisibility in the controller maps each ticket_claim_status.claim_status label to section keys: policy_account, loss_incident, intimation, insured_contact, asset, documents, surveyor, settlement.

Allowed next statuses come from getClaimStatusForPolicyType(): current status plus IDs in allowed_status JSON on the status row. Both create and edit forms call getVisibleSectionsAjax when the user changes status.

Auto-mail and placeholders

Template lookup (NonEbTicketMasterModel::getTemplateDataByTicketID):

sendAutoMailTrigger($ticket_id) sends only when the matched template has is_auto_mail = 1. Mail goes to insured_contact_email from constructMailContent(); from address claims@nhanceindia.in via MailHelper::send_email(). Successful sends insert a ticket_messages row via autoMessageInsertBasedOnMailResponse().

Placeholders (subject/body):

TokenTicket field
((ACM))acm
((ACM_CONTACT))acm_mobile
((INSURED_NAME))insured_contact_name
((CORPORATE_NAME))client_name
((CLAIM_NO))claim_number
((POLICY_TYPE))policy_type_name
((NHANCE_REF_NO))nhance_claim_ref_no
((LOSS_DATE))loss_date
((LOSS_LOCATION))loss_location
((NATURE_OF_LOSS))nature_of_loss

Edit screen also supports manual reply: POST /non-eb-claim/reply validates To/Subject, inserts ticket_messages, sends via sendReplyMessage() with placeholder replacement.

Mail template CRUD

Page: GET /non-eb-claim/mail_template. DataTable lists rows from ticket_mail_template (is_active = 1). Tooltip on each row shows the matching ticket_claim_status.claim_status for that policy type + trigger type.

flowchart LR UI["mail_template UI"] --> S1["POST crud_mail_template/1 Save"] UI --> S2["POST crud_mail_template/2 Fetch"] UI --> S3["POST crud_mail_template/3 Delete"] S1 --> DB["ticket_mail_template"] S2 --> DB S3 --> DB

Template fields

Trigger ↔ status: Each ticket_claim_status row for a Non-EB/Marine ticket_type has a trigger_type. The template’s trigger_type must match that column for auto-mail and for the “Claim Status” readonly hint (tool_tip from server on fetch).

UI actions

ActionEndpointBodyResult
Add / SavePOST …/crud_mail_template/1Form fields + mail_content + is_auto_mail{ status: bool } → reload
Edit loadPOST …/crud_mail_template/2id{ status, data } opens modal
DeletePOST …/crud_mail_template/3idSoft delete (is_active = 0)

Placeholder dropdown in the modal inserts tokens into subject (focused input) or Jodit body. Validation errors return HTTP 400 with errors map (shown via toastr).

Notes

On the edit screen:

Documents and IR checklist

Reports

GET /non-eb-claim/reports renders filters: policy type, ACM name, date range (default last 60 days). generateReport() in the view POSTs to the same URL and expects { status: true, data: [ rows ] } for DataTable columns (status, policy type, claim/ref, client, insurer, loss fields, surveyor, settlement, ACM, created date).

Gap: NonEbClaimController::claimReports() only handles GET (layout load). There is no POST handler to return report data — Generate Report will fail until POST logic is added (mirror EB ticket_reports or reuse claimSearch with report-specific selects).

Data model (summary)

TableRole
non_eb_ticket_masterMain claim ticket
non_eb_claim_assetRepeating asset lines per ticket
ticket_claim_statusStatuses per ticket_type (policy type id); trigger_type, allowed_status
ticket_mail_templateTemplates; ticket_type = policy type id
ticket_historyField-level audit (status, ACM, priority, …)
ticket_messagesOutbound mail log
ticket_notesUser notes per ticket
claim_filesAttachments; ticket_type = 2 for Non-EB

Controller reference

MethodUsed for
claimList / claimSearchList UI and filtered HTML
claimForm / getFormDataNew claim form bootstrap
view_claimEdit view
createClaim / updateClaimPersist ticket
getClaimStatusForPolicyType / getVisibleSections*Status dropdown + sections
mailTemplate / crudTemplateTemplate admin
sendAutoMailTrigger / constructMailContentAutomated email
saveReply / getTicketMessageManual email thread
crudNoteNotes
uploadFile / getClaimFiles / removeFile / saveIRDocsDocuments
saveAssets / getAssetsAsset grid
claimHistory / putHistoryAfterInsertAudit trail
getBranchAndPolicyByClientIDClient cascade
claimReportsReports page (GET only today)
testAutoMailTriggerDev preview/send test

Developer checklist

  1. Ensure ticket_claim_status rows exist per Non-EB/Marine policy_type.id with correct trigger_type and allowed_status.
  2. Create mail templates at /non-eb-claim/mail_template with matching ticket_type + trigger_type; enable Auto Mail only where intended.
  3. Verify insured email is present before relying on auto-mail.
  4. Before changing Add/new URLs: read Policy type 50 — clone statuses + templates in DB and update every hardcoded 50 if a product needs its own workflow.
  5. Implement POST branch in claimReports() if reports Generate must work.
  6. Claim files: always set ticket_type = 2 in new file-related code paths.
  7. ACL: extend #^/non-eb-claim# if new roles need access.

Common pitfalls