9.9 KiB
Dev Log — 2026-04-01
NonEbClaimApiController — Bug Fix, Enhancements & API Docs
1. Fix: JSON Parse 500 Error on createClaim
- Problem:
getJSON(true)throws a500 HTTPException(Syntax error) when the request body is multipart/form-data (file upload), not JSON. - Fix: Replaced
getJSON(true)withjson_decode(getBody()) ?? getPost()so multipart POST data is read correctly without throwing.
2. Fix: JSON Parse 500 Error on listClaims and listPolicies
- Problem: Same
getJSON(true)issue — any malformed or missing JSON body causes a 500 instead of a graceful 400. - Fix: Wrapped
getJSON(true)calls intry/catch (\Throwable)returning a proper400 Invalid JSON bodyresponse.
3. Add: Logging to all API endpoints
Added myLogger->logme('error', ...) calls to all 6 endpoints under employeeRest/api/v1/non-eb-claim that previously had no log coverage:
| Endpoint | Log event |
|---|---|
createClaim |
No ACM found, claim created with ID + user |
listClaims |
User + page + total count |
claimHistory |
Claim ID + history steps + user |
listClaimStatuses |
User + status count |
listPolicies |
User + client_md5 + branch + count |
uploadRequiredDoc |
Transaction failure + successful upload with doc/file/user |
All log tags follow the pattern [NON_EB_API][methodName] for easy log filtering.
4. Enhance: claimHistory endpoint — full claim detail response
Previously returned only status history array. Now returns 4 keys:
| Key | Source | Description |
|---|---|---|
claims_data |
non_eb_ticket_master + joins |
Major display fields (name, policy, status, surveyor, etc.) |
required_docs |
non_eb_ticket_master.required_docs (decoded) |
IR documents checklist |
claims_files |
claim_files table |
Uploaded documents for this claim |
ticket_data |
ticket_history table |
Claim status change history (renamed from history) |
Also removed early-return on empty history so all 4 keys are always present in the response.
Files Changed
app/Controllers/Api/NonEbClaimApiController.php
API Docs
dev_logs/non_eb_claim_api.md
5. Change: uploadRequiredDoc — rewritten to mirror uploadIRDocs
Old URL: POST /api/v1/non-eb-claim/{claim_id}/upload-required-doc
New URL: POST /api/v1/non-eb-claim/upload-required-doc
Old function copied as uploadRequiredDoc_v1 (preserved for reference).
What changed:
- Removed
claim_idfrom URL;ticket_idnow comes from POST body - Switched from single-file (
filefield) to multi-file (claim_docs[]field) usingmulti_file_Upload - Added
claim_doc_names[]— index-matched names for uploaded files required_docsJSON string now sent by client and stored directly tonon_eb_ticket_master.required_docs(no server-side checklist merging)- Each inserted
claim_filesrow now hasdocs_for_ir = 1 - Removed TPA push (
pushClaimFilesnot called) - Success response simplified to
{status, code, message}
Files Changed
app/Controllers/Api/NonEbClaimApiController.phpapp/Config/Routes.php
API Docs
nonebapidocs.mddev_logs/non_eb_claim_api.md
LeadsController — Bug Fix: createClientWithLeadData for Non-EB Leads
6. Fix: prepareClientPolicyData crashes on Non-EB leads
Problem: proposel_data is always null for Non-EB leads. The function unconditionally did:
$proposel_data = json_decode($data['proposel_data'], true);
list($insurer_branch_id, $insurer_id) = explode('-', $proposel_data['insurer'], 2);
This throws a PHP 8 TypeError (cannot access key on null) for any Non-EB lead, making createClientWithLeadData silently fail.
Fix: Split insurer resolution by lead_form_type:
- EB (
lead_form_type == 1): parse insurer fromproposel_data['insurer']as"{insurer_branch_id}-{insurer_id}"— unchanged - Non-EB: read
insurer_idandinsurer_branch_iddirectly from lead row columns
7. Fix: getPlacementJson null-safety for Non-EB leads
Problem: Same null proposel_data issue — json_decode($data['proposel_data'], true) returned null, and downstream $proposel_data['proposel_name'] access would crash if a Non-EB lead had QCR data.
Fix: json_decode($data['proposel_data'] ?? '', true) ?? [] — proposel_data is now always an array, so all ?? key accesses are safe.
Smoke Test Results
| Path | Step | Result |
|---|---|---|
| EB | proposel_data decode |
✅ decodes normally |
| EB | explode('-', proposel_data['insurer']) |
✅ insurer_branch_id + insurer_id parsed correctly |
| EB | preparePolicyTermsFromRFQ |
✅ unaffected |
| Non-EB | proposel_data null → [] |
✅ safe |
| Non-EB | insurer from lead row columns | ✅ insurer_id + insurer_branch_id read directly |
| Non-EB | getPlacementJson — no QCR data |
✅ returns null safely, policy terms skipped |
| Non-EB | getPlacementJson — QCR data exists |
⚠️ line 4356: $proposel_data['proposel_name'] missing ?? — pending clarification on whether Non-EB leads can have QCR data |
Files Changed
app/Controllers/LeadsController.php
Task Plan — Policy Transaction Inception Form JS Validation
Goal
Implement client-side form validation for app/Views/policy_transaction_inception_form.php by following the existing validation approach used in app/Views/ticket_form_gmc.php (centralized submit + reusable validator), but moving inception validation into a dedicated external JavaScript file.
Current-State Notes
policy_transaction_inception_form.phpcurrently contains inline submit and validation logic on#inception_form_id(Parsley validation + custom checks + toastr + AJAX submit flow).ticket_form_gmc.phpfollows a cleaner pattern where submit handler delegates validation and shows first invalid field feedback.- No dedicated inception validation
.jsfile currently exists.
Proposed File Changes
-
Create
public/assets/js/policy_transaction_inception_validation.js- Add a single public validation entry function (example:
window.validateInceptionFormInputs(form)). - Keep all custom rules here (beyond HTML
requiredand Parsley):follow_insurer_id[]must be selected for all rows.pt_form_sumbit_handlermust be1.- CD account selection rule for client/policy status condition.
- Any date/business-rule checks currently done during submit.
- Return a boolean result and handle user-facing messages consistently via toastr.
- Add a single public validation entry function (example:
-
Refactor
app/Views/policy_transaction_inception_form.php- Keep submit flow in one handler, but delegate custom validations to the new JS file.
- Minimize inline validation logic in view.
- Ensure first invalid field is focused/scrolled for better UX.
- Include the new script after shared dependencies (jQuery/Parsley/toastr), before submit logic usage.
-
(Optional Cleanup) Move remaining inline helper validation code to dedicated JS if it is inception-form-specific and not used elsewhere.
Implementation Steps (Execution Order)
- Step 1: Create new file
public/assets/js/pages/policy_transaction_inception_validation.js. - Step 2: Extract custom validation blocks from
#inception_form_idsubmit handler into reusable functions. - Step 3: Expose one callable function for submit handler (
validateInceptionFormInputs). - Step 4: Update
policy_transaction_inception_form.phpto include new JS file. - Step 5: Replace inline custom checks with function call and keep existing AJAX submit behavior unchanged.
- Step 6: Ensure invalid-field focus and warning message are preserved.
- Step 7: Verify create/edit journeys and conditional sections (renewal, co-insurer, CD account, policy status).
Validation Rules Checklist (to implement in JS)
- Parsley base validation must pass.
- Every
follow_insurer_id[]select must have value. pt_form_sumbit_handler != 0.- If
client_type == 1andpolicy_status == completedandpolicy_type_id > 7, at least onecd_ac_no_for_child[]must be selected. - Keep existing toastr wording (or align to one consistent warning style).
Testing Checklist
- Submit with empty required fields -> blocked with field-level indication.
- Submit with any empty co-insurer selector -> blocked with warning.
- Submit with base premium/CD mismatch (
pt_form_sumbit_handler = 0) -> blocked. - Submit valid data -> AJAX create request fires successfully.
- Edit existing inception record -> validation still works and submit succeeds.
- No regression in date conversion before submit (
policy_issue_date,policy_start_date,policy_end_date,renewal_date,rollover_date,month).
Risks / Attention Points
- Large inline script currently mixes validation and business logic; refactor should avoid changing API payload or field names.
- Multiple dynamic rows (
follow_insurer_id[],cd_ac_no_for_child[]) need delegated-safe selectors. - Script include order is critical (new validation JS must load before submit handler executes).
Completion Update (Implemented)
- Added
public/assets/js/pages/policy_transaction_inception_validation.jswith:window.validateInceptionFormInputs(form)as centralized entrypoint- Parsley validation gate
- Co-insurer (
follow_insurer_id[]) mandatory selection check pt_form_sumbit_handler(CD amount) guard check- Child CD account selection rule for applicable completed flow
- First invalid field focus/scroll helper
- Updated
app/Views/policy_transaction_inception_form.php:- Included external script:
assets/js/pages/policy_transaction_inception_validation.js - Refactored
#inception_form_idsubmit handler to delegate custom validation to new file - Preserved existing AJAX submit and payload/date conversion behavior
- Included external script:
- Technical validation done:
- JS syntax check passed (
node --check public/assets/js/pages/policy_transaction_inception_validation.js)
- JS syntax check passed (