FIX_CLAIM_STATUS_MISS_MATCH
This commit is contained in:
parent
5dc49f7108
commit
998a74906d
@ -968,6 +968,58 @@ class TicketController extends BaseController
|
|||||||
return $extra_fields;
|
return $extra_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overlay conditional `required` rules onto a base validation rule-set based on the
|
||||||
|
* submitted `claim_status_id`. For example, when claim_status_id is a "Settled" status
|
||||||
|
* (11/24/34/44), fields like `utr_details` and `settled_date` are promoted from
|
||||||
|
* `permit_empty` to `required` so the request is rejected when they are blank.
|
||||||
|
*
|
||||||
|
* Letter URL fields (`approved_letter`, `settle_letter`) accept an alternative PDF
|
||||||
|
* upload, so they are intentionally not promoted here; that pairing is enforced by
|
||||||
|
* the upload validation flow. `approved_description` stays optional to match the
|
||||||
|
* existing UI contract.
|
||||||
|
*/
|
||||||
|
private function applyClaimStatusConditionalRules(array $rules): array
|
||||||
|
{
|
||||||
|
$claimStatusId = (int) $this->request->getPost('claim_status_id');
|
||||||
|
if ($claimStatusId <= 0) {
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($this->extraFields[$claimStatusId]) || !is_array($this->extraFields[$claimStatusId])) {
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
$requiredFields = $this->extraFields[$claimStatusId];
|
||||||
|
$skipFields = ['approved_letter', 'settle_letter', 'approved_description'];
|
||||||
|
|
||||||
|
foreach ($requiredFields as $field) {
|
||||||
|
if (in_array($field, $skipFields, true) || !isset($rules[$field])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingRules = $rules[$field]['rules'] ?? '';
|
||||||
|
$parts = $existingRules === ''
|
||||||
|
? []
|
||||||
|
: array_values(array_filter(array_map('trim', explode('|', $existingRules)), function ($part) {
|
||||||
|
return $part !== '' && $part !== 'permit_empty';
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!in_array('required', $parts, true)) {
|
||||||
|
array_unshift($parts, 'required');
|
||||||
|
}
|
||||||
|
$rules[$field]['rules'] = implode('|', array_unique($parts));
|
||||||
|
|
||||||
|
if (!isset($rules[$field]['errors']) || !is_array($rules[$field]['errors'])) {
|
||||||
|
$rules[$field]['errors'] = [];
|
||||||
|
}
|
||||||
|
$label = $rules[$field]['label'] ?? ucwords(str_replace('_', ' ', $field));
|
||||||
|
$rules[$field]['errors']['required'] = $label . ' is required for the selected claim status.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
public function view_ticket($ticket_id)
|
public function view_ticket($ticket_id)
|
||||||
{
|
{
|
||||||
// $ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first();
|
// $ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first();
|
||||||
@ -1456,6 +1508,8 @@ class TicketController extends BaseController
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rules = $this->applyClaimStatusConditionalRules($rules);
|
||||||
|
|
||||||
if (!$this->validate($rules)) {
|
if (!$this->validate($rules)) {
|
||||||
return $this->response->setStatusCode(400)->setJSON([
|
return $this->response->setStatusCode(400)->setJSON([
|
||||||
'status' => false,
|
'status' => false,
|
||||||
@ -1944,6 +1998,9 @@ class TicketController extends BaseController
|
|||||||
'return_remark' => ['label' => 'Return Remark','rules' => 'permit_empty','errors' => []],
|
'return_remark' => ['label' => 'Return Remark','rules' => 'permit_empty','errors' => []],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rules = $this->applyClaimStatusConditionalRules($rules);
|
||||||
|
|
||||||
if (!$this->validate($rules)) {
|
if (!$this->validate($rules)) {
|
||||||
return $this->response->setStatusCode(400)->setJSON([
|
return $this->response->setStatusCode(400)->setJSON([
|
||||||
'status' => false,
|
'status' => false,
|
||||||
@ -3053,7 +3110,7 @@ class TicketController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastMatchedStatus($incoming_form_values, $old_ticket_data)
|
public function getLastMatchedStatusOld($incoming_form_values, $old_ticket_data)
|
||||||
{
|
{
|
||||||
if (empty($incoming_form_values) || !isset($incoming_form_values['claim_status_id']) || !isset($incoming_form_values['extra_fields_array_for_validate'])) {
|
if (empty($incoming_form_values) || !isset($incoming_form_values['claim_status_id']) || !isset($incoming_form_values['extra_fields_array_for_validate'])) {
|
||||||
return null;
|
return null;
|
||||||
@ -3122,6 +3179,71 @@ class TicketController extends BaseController
|
|||||||
return $lastMatchedStatus;
|
return $lastMatchedStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLastMatchedStatus($incoming_form_values, $old_ticket_data)
|
||||||
|
{
|
||||||
|
// Preserve the incoming claim_status_id (if any) as the safe fallback so callers
|
||||||
|
// never accidentally nullify the status when validation inputs are missing.
|
||||||
|
$incomingStatus = $incoming_form_values['claim_status_id'] ?? null;
|
||||||
|
|
||||||
|
if (empty($incoming_form_values) || !isset($incoming_form_values['extra_fields_array_for_validate'])) {
|
||||||
|
return $incomingStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastMatchedStatus = $incomingStatus;
|
||||||
|
|
||||||
|
$statusMapping = json_decode($incoming_form_values['extra_fields_array_for_validate'], true);
|
||||||
|
if (!is_array($statusMapping) || empty($statusMapping)) {
|
||||||
|
return $incomingStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop transitional / aggregate statuses that should never be auto-selected.
|
||||||
|
$removeKeys = is_array($this->removeArrayKey) ? $this->removeArrayKey : [];
|
||||||
|
$statusMapping = array_diff_key($statusMapping, $removeKeys);
|
||||||
|
|
||||||
|
$oldStatusId = is_array($old_ticket_data) ? ($old_ticket_data['claim_status_id'] ?? null) : null;
|
||||||
|
|
||||||
|
$skipFields = ['approved_description'];
|
||||||
|
|
||||||
|
foreach ($statusMapping as $status => $requiredFields) {
|
||||||
|
if (empty($requiredFields)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the current/old status — we only advance forward to a newer status.
|
||||||
|
if ($oldStatusId !== null && (int) $status === (int) $oldStatusId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($requiredFields)) {
|
||||||
|
$requiredFields = [$requiredFields];
|
||||||
|
}
|
||||||
|
|
||||||
|
$allFieldsMatched = true;
|
||||||
|
foreach ($requiredFields as $field) {
|
||||||
|
if (in_array($field, $skipFields, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($incoming_form_values[$field]) || $incoming_form_values[$field] === '' || $incoming_form_values[$field] === null) {
|
||||||
|
$allFieldsMatched = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($allFieldsMatched) {
|
||||||
|
$lastMatchedStatus = $status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When a TPA number is present, promote the base "registered" statuses
|
||||||
|
// (1 -> 2 for standard, 67 -> 68 for the alternate flow).
|
||||||
|
if (!empty($incoming_form_values['tpa_no']) && in_array((int) $lastMatchedStatus, [1, 67], true)) {
|
||||||
|
$lastMatchedStatus = ((int) $lastMatchedStatus === 1) ? 2 : 68;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $lastMatchedStatus;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPolicyStartDate()
|
public function getPolicyStartDate()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -579,6 +579,42 @@
|
|||||||
var doa;
|
var doa;
|
||||||
var STATUS_SECTION_CLASSES = ['cda_ir', 'settled', 'approved', 'rejected', 'up_qdr', 'up_cnu', 'canceled', 'returned', 'payment', 'non_id'];
|
var STATUS_SECTION_CLASSES = ['cda_ir', 'settled', 'approved', 'rejected', 'up_qdr', 'up_cnu', 'canceled', 'returned', 'payment', 'non_id'];
|
||||||
var statusSectionInitialValues = {};
|
var statusSectionInitialValues = {};
|
||||||
|
// Cached full mapping of claim_status_id -> required fields.
|
||||||
|
// The hidden input gets destructively reduced when the status dropdown changes,
|
||||||
|
// so we capture the full map once at load time for use by frontend required-logic.
|
||||||
|
var STATUS_REQUIRED_FIELDS_MAP = {};
|
||||||
|
|
||||||
|
function initStatusRequiredFieldsMap() {
|
||||||
|
var raw = $('#extra_fields_array_for_validate').val();
|
||||||
|
if (!raw) {
|
||||||
|
STATUS_REQUIRED_FIELDS_MAP = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var parsed = JSON.parse(raw);
|
||||||
|
STATUS_REQUIRED_FIELDS_MAP = (parsed && typeof parsed === 'object') ? parsed : {};
|
||||||
|
} catch (e) {
|
||||||
|
STATUS_REQUIRED_FIELDS_MAP = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRequiredFieldsForSelectedStatus() {
|
||||||
|
if (!STATUS_REQUIRED_FIELDS_MAP) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var selected = $('#claim_status_id').val();
|
||||||
|
if (selected === undefined || selected === null || selected === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var fields = STATUS_REQUIRED_FIELDS_MAP[selected];
|
||||||
|
if (Array.isArray(fields)) {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
if (fields) {
|
||||||
|
return [fields];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
function captureSectionInitialValues(sectionClass) {
|
function captureSectionInitialValues(sectionClass) {
|
||||||
if (!sectionClass) {
|
if (!sectionClass) {
|
||||||
@ -656,8 +692,36 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sectionClass === 'approved' || sectionClass === 'settled') {
|
if (sectionClass === 'approved' || sectionClass === 'settled') {
|
||||||
|
// The URL-or-File letter pair has its own validity rules (see enforceLetterPairRules).
|
||||||
|
// We still need to enforce required on the other status-mandated fields
|
||||||
|
// (e.g. utr_details, settled_date, approved_amount, approved_date), which the
|
||||||
|
// previous early-return was skipping.
|
||||||
enforceLetterPairRules();
|
enforceLetterPairRules();
|
||||||
updateSectionRequiredLabels(sectionClass, hasSectionChanged(sectionClass));
|
|
||||||
|
var letterPairIds = sectionClass === 'approved'
|
||||||
|
? ['approved_letter', 'approved_letter_file', 'approved_description']
|
||||||
|
: ['settle_letter', 'settle_letter_file'];
|
||||||
|
|
||||||
|
var statusRequiredFields = getRequiredFieldsForSelectedStatus();
|
||||||
|
var sectionChanged = hasSectionChanged(sectionClass);
|
||||||
|
|
||||||
|
$('.' + sectionClass).find('input, textarea, select').each(function () {
|
||||||
|
var id = this.id;
|
||||||
|
if (!id || letterPairIds.indexOf(id) !== -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var statusRequires = statusRequiredFields.indexOf(id) !== -1;
|
||||||
|
$(this).prop('required', statusRequires || sectionChanged);
|
||||||
|
});
|
||||||
|
|
||||||
|
var statusMandatesSection = false;
|
||||||
|
for (var i = 0; i < statusRequiredFields.length; i++) {
|
||||||
|
if ($('.' + sectionClass + ' #' + statusRequiredFields[i]).length > 0) {
|
||||||
|
statusMandatesSection = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateSectionRequiredLabels(sectionClass, sectionChanged || statusMandatesSection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var changed = hasSectionChanged(sectionClass);
|
var changed = hasSectionChanged(sectionClass);
|
||||||
@ -738,6 +802,7 @@
|
|||||||
allowInput: false
|
allowInput: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
initStatusRequiredFieldsMap();
|
||||||
updateClaimStatusDisplay("<?= isset($ticket_data['claim_status_id']) ? $ticket_data['claim_status_id'] : 0 ?>")
|
updateClaimStatusDisplay("<?= isset($ticket_data['claim_status_id']) ? $ticket_data['claim_status_id'] : 0 ?>")
|
||||||
var extraFields = <?= json_encode(isset($extra_fields) ? $extra_fields : []); ?>;
|
var extraFields = <?= json_encode(isset($extra_fields) ? $extra_fields : []); ?>;
|
||||||
GlobelExtraFields = extraFields;
|
GlobelExtraFields = extraFields;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user