Merge branch 'dev' of bitbucket.org:jubilian/nhance into dev
This commit is contained in:
commit
76d3f529b0
@ -517,7 +517,7 @@ class LeadsController extends BaseController
|
|||||||
'regex_match' => 'Date of Loss must be inValid format.'],
|
'regex_match' => 'Date of Loss must be inValid format.'],
|
||||||
];
|
];
|
||||||
$rules['first_cause_of_loss.*'] = [
|
$rules['first_cause_of_loss.*'] = [
|
||||||
'rules' => 'required|regex_match[/^[a-zA-Z0-9\s_-]+$/]',
|
'rules' => 'required|regex_match[/^[a-zA-Z0-9 _-]+$/]',
|
||||||
'errors' => [
|
'errors' => [
|
||||||
'required' => 'Cause of Loss is required.',
|
'required' => 'Cause of Loss is required.',
|
||||||
'regex_match' => 'Cause of Loss only letters, numbers, space, hyphens and underscores are allowed',
|
'regex_match' => 'Cause of Loss only letters, numbers, space, hyphens and underscores are allowed',
|
||||||
@ -5409,31 +5409,32 @@ class LeadsController extends BaseController
|
|||||||
$this->myLogger->logme('error', "QCR Sheet: copied from RFQ sheet | lead_id={$leadId}, rfq_sheet_id={$rfqSheetId}, new_sheet_id={$newSheetId}");
|
$this->myLogger->logme('error', "QCR Sheet: copied from RFQ sheet | lead_id={$leadId}, rfq_sheet_id={$rfqSheetId}, new_sheet_id={$newSheetId}");
|
||||||
|
|
||||||
// Apply permissions: sales team as editors
|
// Apply permissions: sales team as editors
|
||||||
$salesTeam = $this->userModel
|
// $salesTeam = $this->userModel
|
||||||
->select('user_profiles.email')
|
// ->select('user_profiles.email')
|
||||||
->join('user_teams', 'user_profiles.id = user_teams.user_id')
|
// ->join('user_teams', 'user_profiles.id = user_teams.user_id')
|
||||||
->where('user_teams.team_id', 5)
|
// ->where('user_teams.team_id', 5)
|
||||||
->where('user_teams.is_active', 1)
|
// ->where('user_teams.is_active', 1)
|
||||||
->where('user_profiles.is_active', 1)
|
// ->where('user_profiles.is_active', 1)
|
||||||
->findAll();
|
// ->findAll();
|
||||||
$editorEmails = array_values(array_filter(array_unique(array_column($salesTeam, 'email'))));
|
// $editorEmails = array_values(array_filter(array_unique(array_column($salesTeam, 'email'))));
|
||||||
|
|
||||||
// Decode rfq_qcr_viewers from lead and add as viewers
|
// Decode rfq_qcr_viewers from lead and add as viewers
|
||||||
$viewerEmails = [];
|
$editorEmails = [];
|
||||||
if (! empty($lead['rfq_qcr_viewers'])) {
|
if (! empty($lead['rfq_qcr_viewers'])) {
|
||||||
$decoded = json_decode($lead['rfq_qcr_viewers'], true);
|
$decoded = json_decode($lead['rfq_qcr_viewers'], true);
|
||||||
if (is_array($decoded)) {
|
if (is_array($decoded)) {
|
||||||
$viewerEmails = array_values(array_filter(array_unique($decoded)));
|
$editorEmails = array_values(array_filter(array_unique($decoded)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! empty($editorEmails) || ! empty($viewerEmails)) {
|
// !dd($editorEmails);
|
||||||
|
if (! empty($editorEmails)) {
|
||||||
try {
|
try {
|
||||||
$sheetLib->applyPermissions($newSheetId, [
|
$sheetLib->applyPermissions($newSheetId, [
|
||||||
'editors' => $editorEmails,
|
'editors' => $editorEmails,
|
||||||
'viewers' => $viewerEmails,
|
// 'viewers' => $viewerEmails,
|
||||||
]);
|
]);
|
||||||
$this->myLogger->logme('error', "QCR Sheet: permissions applied | sheet_id={$newSheetId}, editors=" . count($editorEmails) . ", viewers=" . count($viewerEmails));
|
$this->myLogger->logme('error', "QCR Sheet: permissions applied | sheet_id={$newSheetId}, editors=" . count($editorEmails));
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->myLogger->logme('error', "QCR Sheet: failed to apply permissions | sheet_id={$newSheetId}, error=" . $e->getMessage());
|
$this->myLogger->logme('error', "QCR Sheet: failed to apply permissions | sheet_id={$newSheetId}, error=" . $e->getMessage());
|
||||||
}
|
}
|
||||||
@ -5650,30 +5651,30 @@ class LeadsController extends BaseController
|
|||||||
$this->myLogger->logme('error', "Placement Sheet: copied from QCR | lead_id={$leadId}, qcr_sheet_id={$qcrSheetId}, placement_sheet_id={$placementSheetId}");
|
$this->myLogger->logme('error', "Placement Sheet: copied from QCR | lead_id={$leadId}, qcr_sheet_id={$qcrSheetId}, placement_sheet_id={$placementSheetId}");
|
||||||
|
|
||||||
// Apply same permissions as QCR (editors: sales team, viewers: rfq_qcr_viewers)
|
// Apply same permissions as QCR (editors: sales team, viewers: rfq_qcr_viewers)
|
||||||
$salesTeam = $this->userModel
|
// $salesTeam = $this->userModel
|
||||||
->select('user_profiles.email')
|
// ->select('user_profiles.email')
|
||||||
->join('user_teams', 'user_profiles.id = user_teams.user_id')
|
// ->join('user_teams', 'user_profiles.id = user_teams.user_id')
|
||||||
->where('user_teams.team_id', 5)
|
// ->where('user_teams.team_id', 5)
|
||||||
->where('user_teams.is_active', 1)
|
// ->where('user_teams.is_active', 1)
|
||||||
->where('user_profiles.is_active', 1)
|
// ->where('user_profiles.is_active', 1)
|
||||||
->findAll();
|
// ->findAll();
|
||||||
$editorEmails = array_values(array_filter(array_unique(array_column($salesTeam, 'email'))));
|
// $editorEmails = array_values(array_filter(array_unique(array_column($salesTeam, 'email'))));
|
||||||
|
|
||||||
$viewerEmails = [];
|
$editorEmails = [];
|
||||||
if (! empty($lead_data['rfq_qcr_viewers'])) {
|
if (! empty($lead_data['rfq_qcr_viewers'])) {
|
||||||
$decoded = json_decode($lead_data['rfq_qcr_viewers'], true);
|
$decoded = json_decode($lead_data['rfq_qcr_viewers'], true);
|
||||||
if (is_array($decoded)) {
|
if (is_array($decoded)) {
|
||||||
$viewerEmails = array_values(array_filter(array_unique($decoded)));
|
$editorEmails = array_values(array_filter(array_unique($decoded)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! empty($editorEmails) || ! empty($viewerEmails)) {
|
if (! empty($editorEmails) ) {
|
||||||
try {
|
try {
|
||||||
$sheetLib->applyPermissions($placementSheetId, [
|
$sheetLib->applyPermissions($placementSheetId, [
|
||||||
'editors' => $editorEmails,
|
'editors' => $editorEmails,
|
||||||
'viewers' => $viewerEmails,
|
// 'viewers' => $viewerEmails,
|
||||||
]);
|
]);
|
||||||
$this->myLogger->logme('error', "Placement Sheet: permissions applied | sheet_id={$placementSheetId}, editors=" . count($editorEmails) . ", viewers=" . count($viewerEmails));
|
$this->myLogger->logme('error', "Placement Sheet: permissions applied | sheet_id={$placementSheetId}, editors=" . count($editorEmails));
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->myLogger->logme('error', "Placement Sheet: failed to apply permissions | sheet_id={$placementSheetId}, error=" . $e->getMessage());
|
$this->myLogger->logme('error', "Placement Sheet: failed to apply permissions | sheet_id={$placementSheetId}, error=" . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -845,6 +845,7 @@ class MediAssistApiController extends BaseController
|
|||||||
tm.id,
|
tm.id,
|
||||||
tm.tpa_no as memberId,
|
tm.tpa_no as memberId,
|
||||||
tm.tpa_claim_push_reference_no as claimRefNo,
|
tm.tpa_claim_push_reference_no as claimRefNo,
|
||||||
|
tm.doa,
|
||||||
cp.policy_no as policyNo,
|
cp.policy_no as policyNo,
|
||||||
cp.policy_start_date as startDate,
|
cp.policy_start_date as startDate,
|
||||||
cp.policy_end_date as endDate,
|
cp.policy_end_date as endDate,
|
||||||
|
|||||||
@ -537,13 +537,21 @@ class SalesController extends BaseController
|
|||||||
$value = trim($this->request->getGet('value') ?? '');
|
$value = trim($this->request->getGet('value') ?? '');
|
||||||
$exclude_id = $this->request->getGet('exclude_id');
|
$exclude_id = $this->request->getGet('exclude_id');
|
||||||
|
|
||||||
// ── Whitelist ─────────────────────────────────────────────
|
// ── Whitelist (table → model, pk, allowed fields) ─────────
|
||||||
$allowed = [
|
$allowed = [
|
||||||
'clients' => ['model' => $this->clientModel, 'pk' => 'id'],
|
'clients' => [
|
||||||
|
'model' => $this->clientModel,
|
||||||
|
'pk' => 'id',
|
||||||
|
'fields' => ['short_name', 'client_name'],
|
||||||
|
],
|
||||||
|
'sales_actual_leads' => [
|
||||||
|
'model' => $this->leadModel,
|
||||||
|
'pk' => 'lead_id',
|
||||||
|
'fields' => ['company_name'],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// ── Allowed fields per table ──────────────────────────────
|
if (! isset($allowed[$table]) || ! in_array($field, $allowed[$table]['fields'], true)) {
|
||||||
if (!array_key_exists($table, $allowed) || !in_array($field, ['short_name', 'client_name'])) {
|
|
||||||
return $this->response
|
return $this->response
|
||||||
->setStatusCode(400)
|
->setStatusCode(400)
|
||||||
->setContentType('application/json')
|
->setContentType('application/json')
|
||||||
|
|||||||
@ -465,6 +465,7 @@ class VidalApiController extends BaseController
|
|||||||
tm.tpa_no as memberId,
|
tm.tpa_no as memberId,
|
||||||
tm.tpa_claim_push_reference_no as claimRefNo,
|
tm.tpa_claim_push_reference_no as claimRefNo,
|
||||||
tm.tpa_claim_id as claimID,
|
tm.tpa_claim_id as claimID,
|
||||||
|
tm.doa,
|
||||||
cp.policy_no as policyNo,
|
cp.policy_no as policyNo,
|
||||||
cp.policy_start_date as startDate,
|
cp.policy_start_date as startDate,
|
||||||
cp.policy_end_date as endDate,
|
cp.policy_end_date as endDate,
|
||||||
|
|||||||
@ -50,7 +50,7 @@ class SalesActualLeadModel extends Model
|
|||||||
'company_name' => [
|
'company_name' => [
|
||||||
'required' => 'Company Name is Missing',
|
'required' => 'Company Name is Missing',
|
||||||
// 'alpha_space' => 'Company Name must contain only letters and spaces',
|
// 'alpha_space' => 'Company Name must contain only letters and spaces',
|
||||||
'regex_match' => 'Company Name can only contain letters, numbers, spaces, hyphens and underscores.',
|
'regex_match' => 'Company Name can only contain letters, numbers.',
|
||||||
'min_length' => 'Company Name must be at least 2 characters long',
|
'min_length' => 'Company Name must be at least 2 characters long',
|
||||||
'max_length' => 'Company Name must be at most 255 characters long'
|
'max_length' => 'Company Name must be at most 255 characters long'
|
||||||
],
|
],
|
||||||
|
|||||||
@ -74,6 +74,43 @@ Old function copied as `uploadRequiredDoc_v1` (preserved for reference).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
```php
|
||||||
|
$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 from `proposel_data['insurer']` as `"{insurer_branch_id}-{insurer_id}"` — unchanged
|
||||||
|
- **Non-EB:** read `insurer_id` and `insurer_branch_id` directly 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
|
## Task Plan — Policy Transaction Inception Form JS Validation
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
@ -145,3 +182,4 @@ Implement client-side form validation for `app/Views/policy_transaction_inceptio
|
|||||||
- Preserved existing AJAX submit and payload/date conversion behavior
|
- Preserved existing AJAX submit and payload/date conversion behavior
|
||||||
- Technical validation done:
|
- Technical validation done:
|
||||||
- JS syntax check passed (`node --check public/assets/js/pages/policy_transaction_inception_validation.js`)
|
- JS syntax check passed (`node --check public/assets/js/pages/policy_transaction_inception_validation.js`)
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user