From 3f7594355d69d7c508c3baab8d2a9bd07698966e Mon Sep 17 00:00:00 2001 From: velz Date: Tue, 31 Mar 2026 15:56:13 +0530 Subject: [PATCH] FEAT_NONEBR_API_ENHANCE --- app/Config/Routes.php | 4 +- .../Api/NonEbClaimApiController.php | 89 +++++++++++++ nonebapidocs.md | 125 ++++++++++++++++++ public/dev_logs/2026-03-31.md | 115 ++++++++++++++++ 4 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 public/dev_logs/2026-03-31.md diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 0ea0904e..33aa40e1 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -604,12 +604,14 @@ $routes->group("/api", ["filter" => [ 'ratelimit' , 'authJWT']], function ($rout }); // Non-EB Claims External API v1 -$routes->group("api/v1", ["filter" => ['ratelimit', 'authJWT']], function ($routes) { +$routes->group("employeeRest/api/v1", ["filter" => ['ratelimit', 'authJWT']], function ($routes) { $routes->group("non-eb-claim", function ($routes) { $routes->post('create', 'Api\NonEbClaimApiController::createClaim'); $routes->post('list', 'Api\NonEbClaimApiController::listClaims'); $routes->get('history/(:num)', 'Api\NonEbClaimApiController::claimHistory/$1'); $routes->post('(:num)/upload-required-doc', 'Api\NonEbClaimApiController::uploadRequiredDoc/$1'); + $routes->get('statuses', 'Api\NonEbClaimApiController::listClaimStatuses'); + $routes->post('policies', 'Api\NonEbClaimApiController::listPolicies'); }); }); diff --git a/app/Controllers/Api/NonEbClaimApiController.php b/app/Controllers/Api/NonEbClaimApiController.php index 7e23a47b..5a9fb8ef 100644 --- a/app/Controllers/Api/NonEbClaimApiController.php +++ b/app/Controllers/Api/NonEbClaimApiController.php @@ -504,6 +504,95 @@ class NonEbClaimApiController extends BaseController ], 200); } + /** + * GET /api/v1/non-eb-claim/statuses + * Returns Non-EB claim statuses (ticket_type = 50). + */ + public function listClaimStatuses() + { + $authUser = $this->getAuthUser(); + if (!$authUser) { + return $this->respond(['status' => false, 'code' => 401, 'message' => 'Unauthorized'], 401); + } + + $statuses = $this->claimStatusModel + ->select('id, claim_status, display_name') + ->where('ticket_type', 50) + ->where('is_active', 1) + ->orderBy('id', 'ASC') + ->findAll(); + + return $this->respond([ + 'status' => true, + 'code' => 200, + 'data' => $statuses, + ], 200); + } + + /** + * POST /api/v1/non-eb-claim/policies + * Returns Non-EB / Marine policies for a given client (md5) + branch. + * + * Body: + * client_id string MD5 hash of the client's numeric id (required) + * client_branch_id int client branch id (required) + */ + public function listPolicies() + { + $authUser = $this->getAuthUser(); + if (!$authUser) { + return $this->respond(['status' => false, 'code' => 401, 'message' => 'Unauthorized'], 401); + } + + $body = $this->request->getJSON(true) ?? $this->request->getPost(); + $client_id_md5 = trim($body['client_id'] ?? ''); + $client_branch_id = (int)($body['client_branch_id'] ?? 0); + + $errors = []; + if (empty($client_id_md5)) { + $errors['client_id'] = 'client_id is required'; + } elseif (!preg_match('/^[a-f0-9]{32}$/i', $client_id_md5)) { + $errors['client_id'] = 'client_id must be a valid MD5 hash'; + } + if ($client_branch_id <= 0) { + $errors['client_branch_id'] = 'client_branch_id is required'; + } + if (!empty($errors)) { + return $this->respond(['status' => false, 'code' => 400, 'message' => 'Input validation failed', 'errors' => $errors], 400); + } + + $db = db_connect(); + $builder = $db->table('client_policy cp'); + + $builder->select([ + 'cp.id', + 'cp.policy_no', + 'cp.policy_type_id', + 'pt.policy_type AS policy_type_name', + 'cp.insurer_id', + 'i.name AS insurer_name', + 'i.short_name AS insurer_short_name', + 'DATE_FORMAT(cp.policy_start_date, "%d-%m-%Y") AS policy_start_date', + 'DATE_FORMAT(cp.policy_end_date, "%d-%m-%Y") AS policy_end_date', + ]); + $builder->join('policy_type pt', 'pt.id = cp.policy_type_id', 'left'); + $builder->join('insurers i', 'i.id = cp.insurer_id AND i.is_active = 1', 'left'); + $builder->where('MD5(cp.client_id)', $client_id_md5); + $builder->where('cp.client_branch_id', $client_branch_id); + $builder->where('cp.is_active', 1); + $builder->whereIn('pt.allocg', ['Non-EB', 'Marine']); + $builder->orderBy('cp.id', 'DESC'); + + $policies = $builder->get()->getResultArray(); + + return $this->respond([ + 'status' => true, + 'code' => 200, + 'total' => count($policies), + 'data' => $policies, + ], 200); + } + public function uploadRequiredDoc(int $claim_id) { $authUser = $this->getAuthUser(); diff --git a/nonebapidocs.md b/nonebapidocs.md index fd65abeb..c161de0b 100644 --- a/nonebapidocs.md +++ b/nonebapidocs.md @@ -64,6 +64,8 @@ All responses follow this consistent shape: | 2 | `POST` | `/api/v1/non-eb-claim/list` | List / search claims | | 3 | `GET` | `/api/v1/non-eb-claim/history/{claim_id}` | Status timeline of a claim | | 4 | `POST` | `/api/v1/non-eb-claim/{claim_id}/upload-required-doc` | Upload a required document | +| 5 | `GET` | `/api/v1/non-eb-claim/statuses` | List Non-EB claim statuses | +| 6 | `POST` | `/api/v1/non-eb-claim/policies` | List Non-EB policies by client (MD5) + branch | --- @@ -413,6 +415,129 @@ file = --- +## 5. List Claim Statuses + +**GET** `/api/v1/non-eb-claim/statuses` + +### How it works + +Returns all Non-EB claim statuses. Use this to populate status dropdowns in the UI or filter screens. Statuses are ordered by `id ASC`. + +> Ticket type is hardcoded to `50` (Non-EB) on the server — you do not need to send it. + +### Request + +No body required. Only the `Authorization` header is needed. + +``` +GET /api/v1/non-eb-claim/statuses +Authorization: Bearer +``` + +### Success Response `200` + +```json +{ + "status": true, + "code": 200, + "data": [ + { "id": 1, "claim_status": "Claim Intimation", "display_name": "Claim Intimation" }, + { "id": 2, "claim_status": "Under Process", "display_name": "Under Process" }, + { "id": 3, "claim_status": "Claim Settled", "display_name": "Claim Settled" } + ] +} +``` + +> `display_name` is the user-facing label. `claim_status` is the internal name. Use `id` when sending `claim_status_id` as a filter in the list endpoint. + +### Error Responses + +| Code | Scenario | +|---|---| +| `401` | Missing / expired token | + +--- + +## 6. List Policies by Client + Branch + +**POST** `/api/v1/non-eb-claim/policies` + +### How it works + +Returns Non-EB and Marine policies for a specific client branch. Use this to populate the policy dropdown before raising a new claim. + +The client is identified by an **MD5 hash of their numeric ID** — the raw integer ID is never exposed to the API consumer. + +### Request + +**Content-Type:** `application/json` + +| Field | Required | Type | Notes | +|---|---|---|---| +| `client_id` | Yes | string | MD5 hash (32-char hex) of the client's numeric ID | +| `client_branch_id` | Yes | integer | The client branch to filter by | + +### Example Request + +```json +{ + "client_id": "d41d8cd98f00b204e9800998ecf8427e", + "client_branch_id": 3 +} +``` + +### Success Response `200` + +```json +{ + "status": true, + "code": 200, + "total": 2, + "data": [ + { + "id": 10, + "policy_no": "POL/2026/001", + "policy_type_id": 50, + "policy_type_name": "Fire", + "insurer_id": 7, + "insurer_name": "New India Assurance", + "insurer_short_name": "NIA", + "policy_start_date": "01-04-2025", + "policy_end_date": "31-03-2026" + }, + { + "id": 11, + "policy_no": "POL/2026/002", + "policy_type_name": "Marine Cargo", + "insurer_name": "HDFC Ergo", + "insurer_short_name": "HDFC", + "policy_start_date": "01-01-2026", + "policy_end_date": "31-12-2026" + } + ] +} +``` + +> Only **Non-EB** and **Marine** policy types are returned. EB policies are excluded automatically. +> When no policies exist for the given client + branch, `total` is `0` and `data` is `[]`. + +### How to use in create claim flow + +1. Call this endpoint with the selected client's MD5 and branch ID +2. Populate a dropdown with the returned policies — display `policy_no` + `policy_type_name` to the user +3. When the user picks a policy, send its `id` as `client_policy_id` in the **Create Claim** request + +### Error Responses + +| Code | Scenario | Message | +|---|---|---| +| `400` | `client_id` not sent | `"client_id is required"` | +| `400` | `client_id` is not a valid MD5 hash | `"client_id must be a valid MD5 hash"` | +| `400` | `client_branch_id` not sent or zero | `"client_branch_id is required"` | +| `401` | Missing / expired token | `"Unauthorized"` | + +--- + ## Common Error Reference | HTTP Code | Meaning | When it happens | diff --git a/public/dev_logs/2026-03-31.md b/public/dev_logs/2026-03-31.md new file mode 100644 index 00000000..26ef9ecc --- /dev/null +++ b/public/dev_logs/2026-03-31.md @@ -0,0 +1,115 @@ +# Dev Log — 2026-03-31 + +## Non-EB Claims Module — Session 5 + +--- + +### 1. Asset File Upload — `createClaim()` API Endpoint + +Replaced the silent `handleAssetFileUpload()` call with inline validation to give proper API error responses. + +**Problems fixed:** +- Invalid file extension was silently ignored — claim was created without the file, no error returned +- Upload failure had no error response +- Success response had no `asset_file` field + +**Changes in `app/Controllers/Api/NonEbClaimApiController.php`:** +- Reads `asset_file` from request directly +- Returns **415** with allowed types listed if extension is not in `UPLOAD_EXT_ASSET_FILES` (`pdf, xls, xlsx, csv`) +- Returns **400** if `loss_description` is missing when file is provided +- Returns **500** if `file_Upload()` fails +- Success response now includes `"asset_file": "filename.pdf"` (or `null` if none sent) +- `asset_file` is optional — omitting it creates the claim normally + +**How to call:** +``` +POST /api/v1/non-eb-claim/create +Content-Type: multipart/form-data +Authorization: Bearer + +client_policy_id, nature_of_loss, loss_location, loss_date, [asset_file] +``` + +--- + +### 2. Sidebar — Claims Menu Restructured + +**`app/Views/layout/header.php`** + +| Before | After | +|---|---| +| New claim | New EB Claim | +| Non EB Claims | EB Claim List | +| Claim List | New Non EB Claim | +| *(nothing)* | Non EB Claim List | + +Final menu order: +1. **New EB Claim** → `openTicketTypeAskModal()` +2. **EB Claim List** → `/ticket/list` +3. **New Non EB Claim** → `/non-eb-claim/new` +4. **Non EB Claim List** → `/non-eb-claim/list` + +--- + +### 3. New Non-EB Claim — Route Added + +**`app/Config/Routes.php`** +- Added `GET non-eb-claim/new` → `NonEbClaimController::claimForm/50` (bare route, policy type hardcoded to 50 temporarily) +- Existing `new/(:any)` route preserved for dynamic use + +--- + +### 4. Non-EB List Page — Add Button Bypasses Policy Type Modal + +**`app/Views/non_eb_claim_search.php`** +- `#policyTypeModal` HTML commented out +- `goToNewClaim()` JS function commented out + +**`app/Views/non_eb_claim_list.php`** +- Add button action changed from `openPolicyTypeModal()` → `window.location.href = base_url('non-eb-claim/new/50')` +- `openPolicyTypeModal()` JS function commented out + +--- + +### 5. New Non-EB Claim Form — Nhance Logo Loader on Client Select + +**`app/Views/non_eb_claim_form.php`** +- Shows global nhance gif loader (`.loader` / `.loader-mask`) when client is selected and AJAX fires to fetch branches/policies +- Hides loader on AJAX success and on AJAX error (so loader never gets stuck) + +--- + +### 6. New API Endpoints — Policies List & Claim Statuses + +**`app/Controllers/Api/NonEbClaimApiController.php`** — 2 new methods added + +#### `GET /api/v1/non-eb-claim/statuses` +- Returns all `ticket_claim_status` rows where `ticket_type = 50` (Non-EB, hardcoded) and `is_active = 1` +- Returns: `id`, `claim_status`, `display_name` +- No request body required + +#### `POST /api/v1/non-eb-claim/policies` +- Accepts: `client_id` (MD5 hash, required), `client_branch_id` (integer, required) +- Validates MD5 format — returns 400 if not a 32-char hex string +- Queries `client_policy` using `MD5(cp.client_id)` for secure lookup +- Filters: `client_branch_id`, `is_active = 1`, `policy_type.allocg IN ('Non-EB', 'Marine')` +- Returns: `id`, `policy_no`, `policy_type_id`, `policy_type_name`, `insurer_id`, `insurer_name`, `insurer_short_name`, `policy_start_date`, `policy_end_date` + +**`app/Config/Routes.php`** — 2 new routes added inside `api/v1/non-eb-claim` group: +``` +GET api/v1/non-eb-claim/statuses → listClaimStatuses +POST api/v1/non-eb-claim/policies → listPolicies +``` + +--- + +### Files Modified Today + +| File | Changes | +|---|---| +| `app/Controllers/Api/NonEbClaimApiController.php` | Asset file inline validation + 415/500 errors + asset_file in success response; added `listClaimStatuses()` and `listPolicies()` | +| `app/Config/Routes.php` | Added `non-eb-claim/new` bare route; added `statuses` and `policies` API routes | +| `app/Views/layout/header.php` | Claims sidebar menu restructured (4 items) | +| `app/Views/non_eb_claim_search.php` | policyTypeModal + goToNewClaim commented out | +| `app/Views/non_eb_claim_list.php` | Add button redirects directly; openPolicyTypeModal commented out | +| `app/Views/non_eb_claim_form.php` | Nhance loader shown/hidden around getBranchAndPolicy AJAX |