260 lines
10 KiB
PHP
260 lines
10 KiB
PHP
<?php
|
||
/**
|
||
* SI Enhancement (employee Excel upload) — content only
|
||
* app/Views/docs/si-enhancement.php
|
||
*
|
||
* Based on:
|
||
* - app/Views/employee_upload.php
|
||
* - app/Controllers/EmployeeServiceController.php
|
||
* (excelFileFormatValidation, excelFileDataValidation, employeesSIEnhanceProcess)
|
||
* - app/Controllers/EmployeeController.php (employeesUplodWithEvents)
|
||
* - app/Controllers/JobWorker.php
|
||
*/
|
||
?>
|
||
|
||
<p>
|
||
<strong>SI Enhancement</strong> increases sum insured for active members on a policy via Excel upload
|
||
(<code>files.action = si_enhancement</code>). The process recalculates premium from slab/rack rates and
|
||
creates <strong>pending SI endorsements</strong> on <code>employee_polices</code> — SI and premium are not
|
||
updated in place until endorsements are applied downstream.
|
||
</p>
|
||
|
||
<p>
|
||
Core logic: <code>EmployeeServiceController::employeesSIEnhanceProcess</code>.
|
||
Premium math uses <code>transform_si_excel_row_to_calculatable_format</code> and
|
||
<code>premium_calculation_manager</code> (see
|
||
<a href="<?= base_url('docs/eb-rack-rate-calculation') ?>">EB rack rate calculation</a>).
|
||
</p>
|
||
|
||
<h2 id="overview">Overview</h2>
|
||
|
||
<div class="mermaid-wrapper">
|
||
<div class="mermaid">
|
||
flowchart LR
|
||
A["Upload Excel action si_enhancement"] --> B["excelFileFormatValidation"]
|
||
B --> C["excelFileDataValidation"]
|
||
C --> D["employeesSIEnhanceProcess job"]
|
||
D --> E["Recalc premium plus pending SI endorsements"]
|
||
B -->|errors| F["files.status failed"]
|
||
C -->|errors| F
|
||
D -->|loop done| G["files.status success"]
|
||
</div>
|
||
</div>
|
||
|
||
<p><strong>In short:</strong></p>
|
||
<ul>
|
||
<li><strong>Step 1 — Format:</strong> 5 columns (A–E); <strong>Augmented SI</strong> validated against slabs (<code>check_si</code>).</li>
|
||
<li><strong>Step 2 — Data:</strong> Member must exist on active policy; code <strong>10</strong> if not found.</li>
|
||
<li><strong>Step 3 — SI enhance:</strong> Picks rack rate by relationship, recalculates premium, inserts 3 pending endorsements per member.</li>
|
||
<li>One Excel row = one member SI change (not whole-family in one row).</li>
|
||
</ul>
|
||
|
||
<h2 id="key-files-routes">Key files and routes</h2>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>Area</th><th>Location</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>UI</td>
|
||
<td><code>app/Views/employee_upload.php</code> — action <strong>SI Enhancement</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Upload</td>
|
||
<td><code>EmployeeController::employeesUplodWithEvents</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Validation</td>
|
||
<td><code>excelFileFormatValidation</code>, <code>excelFileDataValidation</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>SI process</td>
|
||
<td><code>employeesSIEnhanceProcess</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Onboard SI path</td>
|
||
<td><code>employeesSIEnhanceProcessWhileOnbboard</code> — SI during dependent addition onboard (not Excel)</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Job</td>
|
||
<td><code>employeesSIEnhanceProcess</code> in <code>JobWorker.php</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Helpers</td>
|
||
<td><code>excel_util_helper.php</code> — <code>transform_si_excel_row_to_calculatable_format</code>, <code>premium_calculation_manager</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p><strong>Routes</strong> (group <code>/employee</code>, <code>authMVC</code>):</p>
|
||
<ul>
|
||
<li><code>GET /employee/upload</code> — upload screen</li>
|
||
<li><code>POST /employee/upload</code> — <code>upload-action-type=si_enhancement</code></li>
|
||
<li><code>GET /employee/excel_error/{file_id}</code> — validation errors</li>
|
||
</ul>
|
||
|
||
<div class="callout info">
|
||
<span>i</span>
|
||
<div>
|
||
<strong><code>files.policy_id</code></strong> is the client policy id. Slab rates load via
|
||
<code>getPolicySlabRatesForEmpOnboard(policy_id, client_id)</code>.
|
||
</div>
|
||
</div>
|
||
|
||
<h2 id="sync-vs-jobs">Sync vs background jobs</h2>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>Step</th><th>< 1 MB</th><th>≥ 1 MB</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>Format validation</td><td>Inline on upload</td><td>Job <code>excelFileFormatValidation</code></td></tr>
|
||
<tr><td>Data validation</td><td>Job <code>excelFileDataValidation</code></td><td>Same</td></tr>
|
||
<tr><td>SI enhance</td><td>Job <code>employeesSIEnhanceProcess</code></td><td>Same</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="format-validation">Step 1: excelFileFormatValidation</h2>
|
||
|
||
<ul>
|
||
<li>Uses <code>$si_enhance_excel_columns</code> — <strong>5 columns (A–E)</strong>.</li>
|
||
<li>Action code <code>SI</code> for mandatory rules.</li>
|
||
<li><strong>Augmented SI</strong> (D): custom <code>check_si</code> against policy slabs (same helper as inception SI column).</li>
|
||
<li><strong>Date of SI Enhancement</strong> (E): <code>d-M-Y</code>.</li>
|
||
<li>Policy must have slab/rack configuration or format step fails early (code 5).</li>
|
||
</ul>
|
||
|
||
<h3 id="format-errors">Format error codes</h3>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>Code</th><th>Meaning</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>1</td><td>Mandatory missing</td></tr>
|
||
<tr><td>2</td><td>Wrong format</td></tr>
|
||
<tr><td>3</td><td>Not in allowed list</td></tr>
|
||
<tr><td>4</td><td>Custom validation failed (e.g. invalid Augmented SI for slab)</td></tr>
|
||
<tr><td>5</td><td>File / policy / slab problem</td></tr>
|
||
<tr><td>6</td><td>Column headers wrong</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="data-validation">Step 2: excelFileDataValidation</h2>
|
||
|
||
<p><code>name_and_empid_check_in_db</code> for <code>si_enhancement</code>:</p>
|
||
<ul>
|
||
<li>Row must match active employee + active <code>employee_polices</code> on the policy.</li>
|
||
<li>Not found → error code <strong>10</strong> (“Record Not found”).</li>
|
||
</ul>
|
||
|
||
<p>On success → queues <code>employeesSIEnhanceProcess</code>.</p>
|
||
|
||
<h2 id="si-process">Step 3: employeesSIEnhanceProcess</h2>
|
||
|
||
<div class="mermaid-wrapper">
|
||
<div class="mermaid">
|
||
flowchart TD
|
||
A["Read row Augmented SI and date"] --> B["Match active employee and policy"]
|
||
B --> C{"Pending SI on basic_cover_si?"}
|
||
C -->|Yes| D["Skip row log error"]
|
||
C -->|No| E["Resolve rack rate by relationship"]
|
||
E --> F["premium_calculation_manager"]
|
||
F --> G["Insert 3 pending endorsements actions si"]
|
||
</div>
|
||
</div>
|
||
|
||
<p><strong>Per row:</strong></p>
|
||
<ol>
|
||
<li>Strip number formatting from Augmented SI (<code>removeNumberFormatting</code>).</li>
|
||
<li>Load employee (emp code + name + branch) and active <code>employee_polices</code> row.</li>
|
||
<li>Find applicable slab/rack rate from member <strong>relationship</strong> (Son/Daughter → childrens, parents, etc.).</li>
|
||
<li>Build calculatable member payload via <code>transform_si_excel_row_to_calculatable_format</code> (uses family max age/count).</li>
|
||
<li><code>premium_calculation_manager</code> → new premium for the augmented SI.</li>
|
||
<li>Insert pending endorsements on <code>employee_polices</code> (<code>actions = si</code>):</li>
|
||
</ol>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>field_name</th><th>new_value source</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>basic_cover_si</code></td><td>Excel Augmented SI (column D)</td></tr>
|
||
<tr><td><code>premium</code></td><td>Recalculated premium from rack logic</td></tr>
|
||
<tr><td><code>si_enhancement_date</code></td><td>Excel Date of SI Enhancement (column E)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>
|
||
Sets <code>files.status = success</code> when the loop completes. Skipped rows (duplicate pending SI, missing member)
|
||
are logged only — the file still succeeds.
|
||
</p>
|
||
|
||
<h2 id="excel-columns">SI Enhancement Excel columns</h2>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>Col</th><th>Header</th><th>Required</th><th>Notes</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>A</td><td>S.No</td><td>Yes</td><td></td></tr>
|
||
<tr><td>B</td><td>EMP ID</td><td>Yes</td><td></td></tr>
|
||
<tr><td>C</td><td>NAME OF EMP/DEP</td><td>Yes</td><td>Must match DB</td></tr>
|
||
<tr><td>D</td><td>Augmented SI</td><td>Yes</td><td>New SI; validated via <code>check_si</code></td></tr>
|
||
<tr><td>E</td><td>Date of SI Enhancement</td><td>Yes</td><td><code>d-M-Y</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="row-example">Row layout examples</h2>
|
||
|
||
<p><strong>Enhance Self SI</strong> — one row:</p>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>EMP ID</th><th>NAME</th><th>Augmented SI</th><th>Date of SI Enhancement</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>EMP001</td><td>Raj Kumar</td><td>1000000</td><td>19-May-2026</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p><strong>Enhance spouse only</strong> — separate row (premium uses that member’s relationship for rack selection):</p>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr><th>EMP ID</th><th>NAME</th><th>Augmented SI</th><th>Date of SI Enhancement</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>EMP001</td><td>Priya Kumar</td><td>500000</td><td>19-May-2026</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="developer-steps">Developer steps</h2>
|
||
|
||
<ol>
|
||
<li>Confirm slab/rack rates exist for the client policy (same as inception).</li>
|
||
<li>Upload with <code>upload-action-type=si_enhancement</code>; note <code>file_id</code>.</li>
|
||
<li>On validation failure, check <code>/employee/excel_error/{file_id}</code> — codes <strong>4</strong> (SI/slab) or <strong>10</strong> (member missing).</li>
|
||
<li>After success, query <code>emp_endorsement</code> where <code>file_id</code> = upload id, <code>actions = 'si'</code>, <code>status = 'pending'</code> — expect up to 3 rows per member (same <code>group_key</code>).</li>
|
||
<li>Compare <code>new_value</code> on <code>basic_cover_si</code> and <code>premium</code> to Excel and rack expectations.</li>
|
||
</ol>
|
||
|
||
<h2 id="pitfalls">Common pitfalls</h2>
|
||
|
||
<ul>
|
||
<li><strong>Slab / rack not configured</strong> — format step or premium calc fails; relationship must map to a non-zero rack key.</li>
|
||
<li><strong>Augmented SI vs slab</strong> — <code>check_si</code> in step 1 must pass before the job runs.</li>
|
||
<li><strong>Pending SI already exists</strong> — duplicate upload for same member skipped until prior endorsement cleared.</li>
|
||
<li><strong>Per-member rows</strong> — enhancing whole family requires one row per member (unlike deletion Self = whole family).</li>
|
||
<li><strong>File success vs rows</strong> — <code>files.status = success</code> does not guarantee every row created endorsements.</li>
|
||
<li><strong>Not live SI update</strong> — <code>employee_polices.basic_cover_si</code> changes after endorsement processing.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
Related:
|
||
<a href="<?= base_url('docs/inception') ?>">Inception</a>,
|
||
<a href="<?= base_url('docs/correction') ?>">Correction</a>,
|
||
<a href="<?= base_url('docs/eb-rack-rate-calculation') ?>">EB rack rate calculation</a>.
|
||
</p>
|