Add DepartmentID filter to tests index endpoint
- Adds DepartmentID query parameter filter to /api/tests - Filters by COALESCE(testdefsite.DepartmentID, cal.DepartmentID) for calculated tests - Updates TestDefSiteModel::getTestsWithRelations() for backend filtering
This commit is contained in:
parent
66e9be2a04
commit
83278d332a
@ -2,16 +2,16 @@
|
||||
|
||||
namespace App\Controllers\Test;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Libraries\TestValidationService;
|
||||
use App\Libraries\ValueSet;
|
||||
use App\Traits\PatchValidationTrait;
|
||||
use App\Traits\ResponseTrait;
|
||||
use App\Controllers\BaseController;
|
||||
use App\Libraries\TestValidationService;
|
||||
use App\Libraries\ValueSet;
|
||||
use App\Traits\PatchValidationTrait;
|
||||
use App\Traits\ResponseTrait;
|
||||
|
||||
class TestsController extends BaseController
|
||||
{
|
||||
use ResponseTrait;
|
||||
use PatchValidationTrait;
|
||||
class TestsController extends BaseController
|
||||
{
|
||||
use ResponseTrait;
|
||||
use PatchValidationTrait;
|
||||
|
||||
protected $model;
|
||||
protected $modelCal;
|
||||
@ -32,24 +32,25 @@ class TestsController extends BaseController
|
||||
$this->modelRefNum = new \App\Models\RefRange\RefNumModel;
|
||||
$this->modelRefTxt = new \App\Models\RefRange\RefTxtModel;
|
||||
|
||||
$this->rules = [
|
||||
'TestSiteCode' => 'required',
|
||||
'TestSiteName' => 'required',
|
||||
'TestType' => 'required',
|
||||
];
|
||||
$this->rules = [
|
||||
'TestSiteCode' => 'required',
|
||||
'TestSiteName' => 'required',
|
||||
'TestType' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$search = $this->request->getGet('search');
|
||||
|
||||
$filters = [
|
||||
'SiteID' => $this->request->getGet('SiteID'),
|
||||
'TestType' => $this->request->getGet('TestType'),
|
||||
'isVisibleScr' => $this->request->getGet('isVisibleScr'),
|
||||
'isVisibleRpt' => $this->request->getGet('isVisibleRpt'),
|
||||
$filters = [
|
||||
'SiteID' => $this->request->getGet('SiteID'),
|
||||
'TestType' => $this->request->getGet('TestType'),
|
||||
'isVisibleScr' => $this->request->getGet('isVisibleScr'),
|
||||
'isVisibleRpt' => $this->request->getGet('isVisibleRpt'),
|
||||
'TestSiteName' => $this->request->getGet('TestSiteName'),
|
||||
'TestSiteCode' => $this->request->getGet('TestSiteCode'),
|
||||
'DepartmentID' => $this->request->getGet('DepartmentID'),
|
||||
'search' => $search,
|
||||
];
|
||||
|
||||
@ -92,36 +93,36 @@ class TestsController extends BaseController
|
||||
|
||||
$typeCode = $row['TestType'] ?? '';
|
||||
|
||||
if ($typeCode === 'CALC') {
|
||||
$row['testdefcal'] = $this->modelCal->getByTestSiteID($id);
|
||||
$row['testdefgrp'] = [
|
||||
'members' => $this->modelGrp->getGroupMembers($id),
|
||||
];
|
||||
} elseif ($typeCode === 'GROUP') {
|
||||
$row['testdefgrp'] = [
|
||||
'members' => $this->modelGrp->getGroupMembers($id),
|
||||
];
|
||||
} elseif ($typeCode !== 'TITLE') {
|
||||
$refType = $row['RefType'] ?? '';
|
||||
$resultType = $row['ResultType'] ?? '';
|
||||
|
||||
if (TestValidationService::usesRefNum($resultType, $refType)) {
|
||||
$row['refnum'] = $this->modelRefNum->getFormattedByTestSiteID($id);
|
||||
}
|
||||
|
||||
if (TestValidationService::usesRefTxt($resultType, $refType)) {
|
||||
$row['reftxt'] = $this->modelRefTxt->getFormattedByTestSiteID($id);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep /api/test payload focused on test definition fields.
|
||||
unset($row['testmap']);
|
||||
|
||||
return $this->respond([
|
||||
'status' => 'success',
|
||||
'message' => 'Data fetched successfully',
|
||||
'data' => $row,
|
||||
], 200);
|
||||
if ($typeCode === 'CALC') {
|
||||
$row['testdefcal'] = $this->modelCal->getByTestSiteID($id);
|
||||
$row['testdefgrp'] = [
|
||||
'members' => $this->modelGrp->getGroupMembers($id),
|
||||
];
|
||||
} elseif ($typeCode === 'GROUP') {
|
||||
$row['testdefgrp'] = [
|
||||
'members' => $this->modelGrp->getGroupMembers($id),
|
||||
];
|
||||
} elseif ($typeCode !== 'TITLE') {
|
||||
$refType = $row['RefType'] ?? '';
|
||||
$resultType = $row['ResultType'] ?? '';
|
||||
|
||||
if (TestValidationService::usesRefNum($resultType, $refType)) {
|
||||
$row['refnum'] = $this->modelRefNum->getFormattedByTestSiteID($id);
|
||||
}
|
||||
|
||||
if (TestValidationService::usesRefTxt($resultType, $refType)) {
|
||||
$row['reftxt'] = $this->modelRefTxt->getFormattedByTestSiteID($id);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep /api/test payload focused on test definition fields.
|
||||
unset($row['testmap']);
|
||||
|
||||
return $this->respond([
|
||||
'status' => 'success',
|
||||
'message' => 'Data fetched successfully',
|
||||
'data' => $row,
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function create()
|
||||
@ -156,50 +157,50 @@ class TestsController extends BaseController
|
||||
$db->transStart();
|
||||
|
||||
try {
|
||||
$testSiteData = [
|
||||
'SiteID' => array_key_exists('SiteID', $input) ? $input['SiteID'] : null,
|
||||
'TestSiteCode'=> $input['TestSiteCode'],
|
||||
'TestSiteName'=> $input['TestSiteName'],
|
||||
'TestType' => $input['TestType'],
|
||||
'Description' => $input['Description'] ?? null,
|
||||
'SeqScr' => array_key_exists('SeqScr', $input) ? $input['SeqScr'] : null,
|
||||
'SeqRpt' => array_key_exists('SeqRpt', $input) ? $input['SeqRpt'] : null,
|
||||
'IndentLeft' => $input['IndentLeft'] ?? 0,
|
||||
'FontStyle' => $input['FontStyle'] ?? null,
|
||||
'isVisibleScr' => $input['isVisibleScr'] ?? 1,
|
||||
'isVisibleRpt' => $input['isVisibleRpt'] ?? 1,
|
||||
'isCountStat' => $input['isCountStat'] ?? 1,
|
||||
'isRequestable' => $input['isRequestable'] ?? 1,
|
||||
$testSiteData = [
|
||||
'SiteID' => array_key_exists('SiteID', $input) ? $input['SiteID'] : null,
|
||||
'TestSiteCode'=> $input['TestSiteCode'],
|
||||
'TestSiteName'=> $input['TestSiteName'],
|
||||
'TestType' => $input['TestType'],
|
||||
'Description' => $input['Description'] ?? null,
|
||||
'SeqScr' => array_key_exists('SeqScr', $input) ? $input['SeqScr'] : null,
|
||||
'SeqRpt' => array_key_exists('SeqRpt', $input) ? $input['SeqRpt'] : null,
|
||||
'IndentLeft' => $input['IndentLeft'] ?? 0,
|
||||
'FontStyle' => $input['FontStyle'] ?? null,
|
||||
'isVisibleScr' => $input['isVisibleScr'] ?? 1,
|
||||
'isVisibleRpt' => $input['isVisibleRpt'] ?? 1,
|
||||
'isCountStat' => $input['isCountStat'] ?? 1,
|
||||
'isRequestable' => $input['isRequestable'] ?? 1,
|
||||
'StartDate' => $input['StartDate'] ?? date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
$id = $this->model->insert($testSiteData);
|
||||
if (!$id) {
|
||||
$dbError = $db->error();
|
||||
log_message('error', 'Test insert failed: ' . json_encode($dbError, JSON_UNESCAPED_SLASHES));
|
||||
$message = $dbError['message'] ?? 'Failed to insert main test definition';
|
||||
throw new \Exception('Failed to insert main test definition: ' . $message);
|
||||
}
|
||||
|
||||
$this->handleDetails($id, $input, 'insert');
|
||||
$id = $this->model->insert($testSiteData);
|
||||
if (!$id) {
|
||||
$dbError = $db->error();
|
||||
log_message('error', 'Test insert failed: ' . json_encode($dbError, JSON_UNESCAPED_SLASHES));
|
||||
$message = $dbError['message'] ?? 'Failed to insert main test definition';
|
||||
throw new \Exception('Failed to insert main test definition: ' . $message);
|
||||
}
|
||||
|
||||
$this->handleDetails($id, $input, 'insert');
|
||||
|
||||
$db->transComplete();
|
||||
|
||||
if ($db->transStatus() === false) {
|
||||
$dbError = $db->error();
|
||||
$lastQuery = $db->showLastQuery();
|
||||
log_message('error', 'TestController transaction failed: ' . json_encode([
|
||||
'error' => $dbError,
|
||||
'last_query' => $lastQuery,
|
||||
], JSON_UNESCAPED_SLASHES));
|
||||
return $this->failServerError('Transaction failed');
|
||||
}
|
||||
if ($db->transStatus() === false) {
|
||||
$dbError = $db->error();
|
||||
$lastQuery = $db->showLastQuery();
|
||||
log_message('error', 'TestController transaction failed: ' . json_encode([
|
||||
'error' => $dbError,
|
||||
'last_query' => $lastQuery,
|
||||
], JSON_UNESCAPED_SLASHES));
|
||||
return $this->failServerError('Transaction failed');
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 'success',
|
||||
'message' => 'Test created successfully',
|
||||
'data' => ['TestSiteId' => $id],
|
||||
]);
|
||||
return $this->respondCreated([
|
||||
'status' => 'success',
|
||||
'message' => 'Test created successfully',
|
||||
'data' => ['TestSiteId' => $id],
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$db->transRollback();
|
||||
|
||||
@ -207,30 +208,30 @@ class TestsController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
public function update($id = null)
|
||||
{
|
||||
$input = $this->requirePatchPayload($this->request->getJSON(true));
|
||||
if ($input === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$id && isset($input['TestSiteID'])) {
|
||||
$id = $input['TestSiteID'];
|
||||
}
|
||||
|
||||
$id = $this->requirePatchId($id, 'TestSiteID');
|
||||
if ($id === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$existing = $this->model->find($id);
|
||||
if (!$existing) {
|
||||
return $this->respond([
|
||||
'status' => 'failed',
|
||||
'message' => 'Test not found',
|
||||
'data' => []
|
||||
], 404);
|
||||
}
|
||||
public function update($id = null)
|
||||
{
|
||||
$input = $this->requirePatchPayload($this->request->getJSON(true));
|
||||
if ($input === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$id && isset($input['TestSiteID'])) {
|
||||
$id = $input['TestSiteID'];
|
||||
}
|
||||
|
||||
$id = $this->requirePatchId($id, 'TestSiteID');
|
||||
if ($id === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$existing = $this->model->find($id);
|
||||
if (!$existing) {
|
||||
return $this->respond([
|
||||
'status' => 'failed',
|
||||
'message' => 'Test not found',
|
||||
'data' => []
|
||||
], 404);
|
||||
}
|
||||
|
||||
$testType = $input['TestType'] ?? $existing['TestType'] ?? '';
|
||||
$details = $input['details'] ?? $input;
|
||||
@ -266,18 +267,18 @@ class TestsController extends BaseController
|
||||
'SeqRpt',
|
||||
'IndentLeft',
|
||||
'FontStyle',
|
||||
'isVisibleScr',
|
||||
'isVisibleRpt',
|
||||
'isCountStat',
|
||||
'isRequestable',
|
||||
'StartDate',
|
||||
];
|
||||
'isVisibleScr',
|
||||
'isVisibleRpt',
|
||||
'isCountStat',
|
||||
'isRequestable',
|
||||
'StartDate',
|
||||
];
|
||||
|
||||
foreach ($allowedUpdateFields as $field) {
|
||||
if (array_key_exists($field, $input)) {
|
||||
$testSiteData[$field] = $input[$field];
|
||||
}
|
||||
}
|
||||
foreach ($allowedUpdateFields as $field) {
|
||||
if (array_key_exists($field, $input)) {
|
||||
$testSiteData[$field] = $input[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($testSiteData)) {
|
||||
$this->model->update($id, $testSiteData);
|
||||
@ -389,9 +390,9 @@ class TestsController extends BaseController
|
||||
|
||||
$typeCode = $testTypeID;
|
||||
|
||||
$details = $input['details'] ?? $input;
|
||||
$details['TestSiteID'] = $testSiteID;
|
||||
$details['SiteID'] = array_key_exists('SiteID', $input) ? $input['SiteID'] : null;
|
||||
$details = $input['details'] ?? $input;
|
||||
$details['TestSiteID'] = $testSiteID;
|
||||
$details['SiteID'] = array_key_exists('SiteID', $input) ? $input['SiteID'] : null;
|
||||
|
||||
switch ($typeCode) {
|
||||
case 'CALC':
|
||||
@ -404,8 +405,8 @@ class TestsController extends BaseController
|
||||
|
||||
break;
|
||||
|
||||
case 'TITLE':
|
||||
break;
|
||||
case 'TITLE':
|
||||
break;
|
||||
|
||||
case 'TEST':
|
||||
case 'PARAM':
|
||||
@ -416,53 +417,53 @@ class TestsController extends BaseController
|
||||
$refType = (string) $details['RefType'];
|
||||
$resultType = $details['ResultType'] ?? '';
|
||||
|
||||
if (TestValidationService::usesRefNum($resultType, $refType) && isset($input['refnum']) && is_array($input['refnum'])) {
|
||||
$this->saveRefNumRanges($testSiteID, $input['refnum'], $action, array_key_exists('SiteID', $input) ? $input['SiteID'] : null);
|
||||
}
|
||||
|
||||
if (TestValidationService::usesRefTxt($resultType, $refType) && isset($input['reftxt']) && is_array($input['reftxt'])) {
|
||||
$this->saveRefTxtRanges($testSiteID, $input['reftxt'], $action, array_key_exists('SiteID', $input) ? $input['SiteID'] : null);
|
||||
}
|
||||
}
|
||||
if (TestValidationService::usesRefNum($resultType, $refType) && isset($input['refnum']) && is_array($input['refnum'])) {
|
||||
$this->saveRefNumRanges($testSiteID, $input['refnum'], $action, array_key_exists('SiteID', $input) ? $input['SiteID'] : null);
|
||||
}
|
||||
|
||||
if (TestValidationService::usesRefTxt($resultType, $refType) && isset($input['reftxt']) && is_array($input['reftxt'])) {
|
||||
$this->saveRefTxtRanges($testSiteID, $input['reftxt'], $action, array_key_exists('SiteID', $input) ? $input['SiteID'] : null);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private function saveTechDetails($testSiteID, $data, $action, $typeCode)
|
||||
{
|
||||
$allowedFields = [
|
||||
'DisciplineID',
|
||||
'DepartmentID',
|
||||
'ResultType',
|
||||
'RefType',
|
||||
'VSet',
|
||||
'ReqQty',
|
||||
'ReqQtyUnit',
|
||||
'Unit1',
|
||||
'Factor',
|
||||
'Unit2',
|
||||
'Decimal',
|
||||
'CollReq',
|
||||
'Method',
|
||||
'ExpectedTAT',
|
||||
];
|
||||
|
||||
$techData = [];
|
||||
foreach ($allowedFields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$techData[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if ($techData !== []) {
|
||||
$this->model->update($testSiteID, $techData);
|
||||
}
|
||||
}
|
||||
|
||||
private function saveRefNumRanges($testSiteID, $ranges, $action, $siteID)
|
||||
{
|
||||
private function saveTechDetails($testSiteID, $data, $action, $typeCode)
|
||||
{
|
||||
$allowedFields = [
|
||||
'DisciplineID',
|
||||
'DepartmentID',
|
||||
'ResultType',
|
||||
'RefType',
|
||||
'VSet',
|
||||
'ReqQty',
|
||||
'ReqQtyUnit',
|
||||
'Unit1',
|
||||
'Factor',
|
||||
'Unit2',
|
||||
'Decimal',
|
||||
'CollReq',
|
||||
'Method',
|
||||
'ExpectedTAT',
|
||||
];
|
||||
|
||||
$techData = [];
|
||||
foreach ($allowedFields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$techData[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if ($techData !== []) {
|
||||
$this->model->update($testSiteID, $techData);
|
||||
}
|
||||
}
|
||||
|
||||
private function saveRefNumRanges($testSiteID, $ranges, $action, $siteID)
|
||||
{
|
||||
if ($action === 'update') {
|
||||
$this->modelRefNum->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
@ -479,104 +480,104 @@ class TestsController extends BaseController
|
||||
$this->modelRefTxt->batchInsert($testSiteID, $siteID, $ranges);
|
||||
}
|
||||
|
||||
private function saveCalcDetails($testSiteID, $data, $input, $action)
|
||||
{
|
||||
$calcData = [];
|
||||
$fieldMap = [
|
||||
'DisciplineID' => 'DisciplineID',
|
||||
'DepartmentID' => 'DepartmentID',
|
||||
'Factor' => 'Factor',
|
||||
'Unit2' => 'Unit2',
|
||||
'Decimal' => 'Decimal',
|
||||
'Method' => 'Method',
|
||||
];
|
||||
|
||||
foreach ($fieldMap as $source => $target) {
|
||||
if (array_key_exists($source, $data)) {
|
||||
$calcData[$target] = $data[$source];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('FormulaCode', $data) || array_key_exists('Formula', $data)) {
|
||||
$calcData['FormulaCode'] = $data['FormulaCode'] ?? $data['Formula'] ?? null;
|
||||
}
|
||||
|
||||
if (array_key_exists('RefType', $data)) {
|
||||
$calcData['RefType'] = $data['RefType'];
|
||||
}
|
||||
|
||||
if (array_key_exists('Unit1', $data) || array_key_exists('ResultUnit', $data)) {
|
||||
$calcData['Unit1'] = $data['Unit1'] ?? $data['ResultUnit'] ?? null;
|
||||
}
|
||||
|
||||
$hasMemberPayload = isset($input['testdefgrp'])
|
||||
&& is_array($input['testdefgrp'])
|
||||
&& array_key_exists('members', $input['testdefgrp']);
|
||||
|
||||
if ($action === 'insert' && !array_key_exists('ResultType', $calcData)) {
|
||||
$calcData['ResultType'] = 'NMRIC';
|
||||
}
|
||||
|
||||
if ($action === 'insert' && !array_key_exists('RefType', $calcData)) {
|
||||
$calcData['RefType'] = 'RANGE';
|
||||
}
|
||||
|
||||
if ($calcData !== []) {
|
||||
$calcData['TestSiteID'] = $testSiteID;
|
||||
if ($action === 'update') {
|
||||
$exists = $this->modelCal->existsByTestSiteID($testSiteID);
|
||||
|
||||
if ($exists) {
|
||||
unset($calcData['TestSiteID']);
|
||||
$this->modelCal->update($exists['TestCalID'], $calcData);
|
||||
} else {
|
||||
if (!array_key_exists('ResultType', $calcData)) {
|
||||
$calcData['ResultType'] = 'NMRIC';
|
||||
}
|
||||
if (!array_key_exists('RefType', $calcData)) {
|
||||
$calcData['RefType'] = 'RANGE';
|
||||
}
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
} else {
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === 'update' && !$hasMemberPayload) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'update') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
$memberIDs = $this->resolveMemberIDs($input);
|
||||
|
||||
$validation = $this->validateMemberIDs($memberIDs);
|
||||
if (!$validation['valid']) {
|
||||
throw new \Exception('Invalid member TestSiteID(s): ' . implode(', ', $validation['invalid']) . '. Make sure to use TestSiteID, not SeqScr or other values.');
|
||||
}
|
||||
|
||||
foreach ($memberIDs as $memberID) {
|
||||
$this->modelGrp->insert([
|
||||
'TestSiteID' => $testSiteID,
|
||||
'Member' => $memberID,
|
||||
]);
|
||||
}
|
||||
private function saveCalcDetails($testSiteID, $data, $input, $action)
|
||||
{
|
||||
$calcData = [];
|
||||
$fieldMap = [
|
||||
'DisciplineID' => 'DisciplineID',
|
||||
'DepartmentID' => 'DepartmentID',
|
||||
'Factor' => 'Factor',
|
||||
'Unit2' => 'Unit2',
|
||||
'Decimal' => 'Decimal',
|
||||
'Method' => 'Method',
|
||||
];
|
||||
|
||||
foreach ($fieldMap as $source => $target) {
|
||||
if (array_key_exists($source, $data)) {
|
||||
$calcData[$target] = $data[$source];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('FormulaCode', $data) || array_key_exists('Formula', $data)) {
|
||||
$calcData['FormulaCode'] = $data['FormulaCode'] ?? $data['Formula'] ?? null;
|
||||
}
|
||||
|
||||
if (array_key_exists('RefType', $data)) {
|
||||
$calcData['RefType'] = $data['RefType'];
|
||||
}
|
||||
|
||||
if (array_key_exists('Unit1', $data) || array_key_exists('ResultUnit', $data)) {
|
||||
$calcData['Unit1'] = $data['Unit1'] ?? $data['ResultUnit'] ?? null;
|
||||
}
|
||||
|
||||
$hasMemberPayload = isset($input['testdefgrp'])
|
||||
&& is_array($input['testdefgrp'])
|
||||
&& array_key_exists('members', $input['testdefgrp']);
|
||||
|
||||
if ($action === 'insert' && !array_key_exists('ResultType', $calcData)) {
|
||||
$calcData['ResultType'] = 'NMRIC';
|
||||
}
|
||||
|
||||
if ($action === 'insert' && !array_key_exists('RefType', $calcData)) {
|
||||
$calcData['RefType'] = 'RANGE';
|
||||
}
|
||||
|
||||
if ($calcData !== []) {
|
||||
$calcData['TestSiteID'] = $testSiteID;
|
||||
if ($action === 'update') {
|
||||
$exists = $this->modelCal->existsByTestSiteID($testSiteID);
|
||||
|
||||
if ($exists) {
|
||||
unset($calcData['TestSiteID']);
|
||||
$this->modelCal->update($exists['TestCalID'], $calcData);
|
||||
} else {
|
||||
if (!array_key_exists('ResultType', $calcData)) {
|
||||
$calcData['ResultType'] = 'NMRIC';
|
||||
}
|
||||
if (!array_key_exists('RefType', $calcData)) {
|
||||
$calcData['RefType'] = 'RANGE';
|
||||
}
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
} else {
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === 'update' && !$hasMemberPayload) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'update') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
$memberIDs = $this->resolveMemberIDs($input);
|
||||
|
||||
$validation = $this->validateMemberIDs($memberIDs);
|
||||
if (!$validation['valid']) {
|
||||
throw new \Exception('Invalid member TestSiteID(s): ' . implode(', ', $validation['invalid']) . '. Make sure to use TestSiteID, not SeqScr or other values.');
|
||||
}
|
||||
|
||||
foreach ($memberIDs as $memberID) {
|
||||
$this->modelGrp->insert([
|
||||
'TestSiteID' => $testSiteID,
|
||||
'Member' => $memberID,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveMemberIDs(array $input): array
|
||||
{
|
||||
$memberIDs = [];
|
||||
|
||||
$rawMembers = $input['testdefgrp']['members'] ?? [];
|
||||
if (is_array($rawMembers)) {
|
||||
foreach ($rawMembers as $member) {
|
||||
if (is_array($member)) {
|
||||
$rawID = $member['TestSiteID'] ?? null;
|
||||
} else {
|
||||
$rawID = is_numeric($member) ? $member : null;
|
||||
private function resolveMemberIDs(array $input): array
|
||||
{
|
||||
$memberIDs = [];
|
||||
|
||||
$rawMembers = $input['testdefgrp']['members'] ?? [];
|
||||
if (is_array($rawMembers)) {
|
||||
foreach ($rawMembers as $member) {
|
||||
if (is_array($member)) {
|
||||
$rawID = $member['TestSiteID'] ?? null;
|
||||
} else {
|
||||
$rawID = is_numeric($member) ? $member : null;
|
||||
}
|
||||
|
||||
if ($rawID !== null && is_numeric($rawID)) {
|
||||
@ -615,21 +616,21 @@ class TestsController extends BaseController
|
||||
];
|
||||
}
|
||||
|
||||
private function saveGroupDetails($testSiteID, $data, $input, $action)
|
||||
{
|
||||
$hasMemberPayload = isset($input['testdefgrp'])
|
||||
&& is_array($input['testdefgrp'])
|
||||
&& array_key_exists('members', $input['testdefgrp']);
|
||||
|
||||
if ($action === 'update' && !$hasMemberPayload) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'update') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
$memberIDs = $this->resolveMemberIDs($input);
|
||||
private function saveGroupDetails($testSiteID, $data, $input, $action)
|
||||
{
|
||||
$hasMemberPayload = isset($input['testdefgrp'])
|
||||
&& is_array($input['testdefgrp'])
|
||||
&& array_key_exists('members', $input['testdefgrp']);
|
||||
|
||||
if ($action === 'update' && !$hasMemberPayload) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'update') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
$memberIDs = $this->resolveMemberIDs($input);
|
||||
|
||||
// Validate member IDs before insertion
|
||||
$validation = $this->validateMemberIDs($memberIDs);
|
||||
@ -645,9 +646,9 @@ class TestsController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
private function saveTestMap($testSiteID, $testSiteCode, $mappings, $action)
|
||||
{
|
||||
if ($action === 'update' && $testSiteCode) {
|
||||
private function saveTestMap($testSiteID, $testSiteCode, $mappings, $action)
|
||||
{
|
||||
if ($action === 'update' && $testSiteCode) {
|
||||
// Find existing mappings by test code through testmapdetail
|
||||
$existingMaps = $this->modelMap->getMappingsByTestCode($testSiteCode);
|
||||
|
||||
@ -658,78 +659,78 @@ class TestsController extends BaseController
|
||||
// Soft delete the testmap headers
|
||||
foreach ($existingMaps as $existingMap) {
|
||||
$this->modelMap->update($existingMap['TestMapID'], ['EndDate' => date('Y-m-d H:i:s')]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->normalizeTestMapPayload($mappings) as $map) {
|
||||
$mapData = [
|
||||
'HostType' => $map['HostType'] ?? null,
|
||||
'HostID' => $map['HostID'] ?? null,
|
||||
'ClientType' => $map['ClientType'] ?? null,
|
||||
'ClientID' => $map['ClientID'] ?? null,
|
||||
];
|
||||
|
||||
$testMapID = $this->modelMap->insert($mapData);
|
||||
if (!$testMapID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->extractTestMapDetails($map) as $detail) {
|
||||
$detailData = [
|
||||
'TestMapID' => $testMapID,
|
||||
'HostTestCode' => $detail['HostTestCode'] ?? null,
|
||||
'HostTestName' => $detail['HostTestName'] ?? null,
|
||||
'ConDefID' => $detail['ConDefID'] ?? null,
|
||||
'ClientTestCode' => $detail['ClientTestCode'] ?? null,
|
||||
'ClientTestName' => $detail['ClientTestName'] ?? null,
|
||||
];
|
||||
$this->modelMapDetail->insert($detailData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function normalizeTestMapPayload($mappings): array
|
||||
{
|
||||
if (!is_array($mappings)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($this->isAssoc($mappings)) {
|
||||
return [$mappings];
|
||||
}
|
||||
|
||||
return array_values(array_filter($mappings, static fn ($map) => is_array($map)));
|
||||
}
|
||||
|
||||
private function extractTestMapDetails(array $map): array
|
||||
{
|
||||
if (isset($map['details']) && is_array($map['details'])) {
|
||||
return array_values(array_filter($map['details'], static fn ($detail) => is_array($detail)));
|
||||
}
|
||||
|
||||
$flatDetail = [
|
||||
'HostTestCode' => $map['HostTestCode'] ?? null,
|
||||
'HostTestName' => $map['HostTestName'] ?? null,
|
||||
'ConDefID' => $map['ConDefID'] ?? null,
|
||||
'ClientTestCode' => $map['ClientTestCode'] ?? null,
|
||||
'ClientTestName' => $map['ClientTestName'] ?? null,
|
||||
];
|
||||
|
||||
foreach ($flatDetail as $value) {
|
||||
if ($value !== null && $value !== '') {
|
||||
return [$flatDetail];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private function isAssoc(array $array): bool
|
||||
{
|
||||
if ($array === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_keys($array) !== range(0, count($array) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->normalizeTestMapPayload($mappings) as $map) {
|
||||
$mapData = [
|
||||
'HostType' => $map['HostType'] ?? null,
|
||||
'HostID' => $map['HostID'] ?? null,
|
||||
'ClientType' => $map['ClientType'] ?? null,
|
||||
'ClientID' => $map['ClientID'] ?? null,
|
||||
];
|
||||
|
||||
$testMapID = $this->modelMap->insert($mapData);
|
||||
if (!$testMapID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->extractTestMapDetails($map) as $detail) {
|
||||
$detailData = [
|
||||
'TestMapID' => $testMapID,
|
||||
'HostTestCode' => $detail['HostTestCode'] ?? null,
|
||||
'HostTestName' => $detail['HostTestName'] ?? null,
|
||||
'ConDefID' => $detail['ConDefID'] ?? null,
|
||||
'ClientTestCode' => $detail['ClientTestCode'] ?? null,
|
||||
'ClientTestName' => $detail['ClientTestName'] ?? null,
|
||||
];
|
||||
$this->modelMapDetail->insert($detailData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function normalizeTestMapPayload($mappings): array
|
||||
{
|
||||
if (!is_array($mappings)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($this->isAssoc($mappings)) {
|
||||
return [$mappings];
|
||||
}
|
||||
|
||||
return array_values(array_filter($mappings, static fn ($map) => is_array($map)));
|
||||
}
|
||||
|
||||
private function extractTestMapDetails(array $map): array
|
||||
{
|
||||
if (isset($map['details']) && is_array($map['details'])) {
|
||||
return array_values(array_filter($map['details'], static fn ($detail) => is_array($detail)));
|
||||
}
|
||||
|
||||
$flatDetail = [
|
||||
'HostTestCode' => $map['HostTestCode'] ?? null,
|
||||
'HostTestName' => $map['HostTestName'] ?? null,
|
||||
'ConDefID' => $map['ConDefID'] ?? null,
|
||||
'ClientTestCode' => $map['ClientTestCode'] ?? null,
|
||||
'ClientTestName' => $map['ClientTestName'] ?? null,
|
||||
];
|
||||
|
||||
foreach ($flatDetail as $value) {
|
||||
if ($value !== null && $value !== '') {
|
||||
return [$flatDetail];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private function isAssoc(array $array): bool
|
||||
{
|
||||
if ($array === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_keys($array) !== range(0, count($array) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ class TestDefSiteModel extends BaseModel {
|
||||
'ResultType', 'RefType', 'Vset',
|
||||
'Unit1', 'Factor', 'Unit2', 'Decimal',
|
||||
'ReqQty', 'ReqQtyUnit', 'CollReq', 'Method', 'ExpectedTAT',
|
||||
'SeqScr', 'SeqRpt', 'IndentLeft', 'FontStyle', 'isVisibleScr', 'isVisibleRpt',
|
||||
'isCountStat', 'Level', 'isRequestable',
|
||||
'SeqScr', 'SeqRpt', 'IndentLeft', 'FontStyle', 'isVisibleScr', 'isVisibleRpt',
|
||||
'isCountStat', 'Level', 'isRequestable',
|
||||
'CreateDate', 'StartDate','EndDate'
|
||||
];
|
||||
|
||||
@ -28,9 +28,9 @@ class TestDefSiteModel extends BaseModel {
|
||||
protected $deletedField = "EndDate";
|
||||
|
||||
public function getTests($siteId = null, $testType = null, $visibleScr = null, $visibleRpt = null, $search = null, $page = 1, $perPage = 20) {
|
||||
$builder = $this->select("testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
|
||||
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.isVisibleScr, testdefsite.isVisibleRpt,
|
||||
testdefsite.isCountStat, testdefsite.StartDate, testdefsite.EndDate")
|
||||
$builder = $this->select("testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
|
||||
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.isVisibleScr, testdefsite.isVisibleRpt,
|
||||
testdefsite.isCountStat, testdefsite.StartDate, testdefsite.EndDate")
|
||||
->where('testdefsite.EndDate IS NULL');
|
||||
|
||||
if ($siteId) {
|
||||
@ -41,13 +41,13 @@ class TestDefSiteModel extends BaseModel {
|
||||
$builder->where('testdefsite.TestType', $testType);
|
||||
}
|
||||
|
||||
if ($visibleScr !== null) {
|
||||
$builder->where('testdefsite.isVisibleScr', $visibleScr);
|
||||
}
|
||||
|
||||
if ($visibleRpt !== null) {
|
||||
$builder->where('testdefsite.isVisibleRpt', $visibleRpt);
|
||||
}
|
||||
if ($visibleScr !== null) {
|
||||
$builder->where('testdefsite.isVisibleScr', $visibleScr);
|
||||
}
|
||||
|
||||
if ($visibleRpt !== null) {
|
||||
$builder->where('testdefsite.isVisibleRpt', $visibleRpt);
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$builder->groupStart()
|
||||
@ -83,10 +83,10 @@ class TestDefSiteModel extends BaseModel {
|
||||
*/
|
||||
public function getTestsWithRelations($filters = []) {
|
||||
$builder = $this->db->table('testdefsite')
|
||||
->select(
|
||||
"testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
|
||||
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.isVisibleScr, testdefsite.isVisibleRpt,
|
||||
testdefsite.isCountStat, testdefsite.StartDate, testdefsite.EndDate,
|
||||
->select(
|
||||
"testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
|
||||
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.isVisibleScr, testdefsite.isVisibleRpt,
|
||||
testdefsite.isCountStat, testdefsite.StartDate, testdefsite.EndDate,
|
||||
COALESCE(testdefsite.DisciplineID, cal.DisciplineID) as DisciplineID,
|
||||
COALESCE(testdefsite.DepartmentID, cal.DepartmentID) as DepartmentID,
|
||||
d.DisciplineName, dept.DepartmentName"
|
||||
@ -104,13 +104,13 @@ class TestDefSiteModel extends BaseModel {
|
||||
$builder->where('testdefsite.TestType', $filters['TestType']);
|
||||
}
|
||||
|
||||
if (isset($filters['isVisibleScr'])) {
|
||||
$builder->where('testdefsite.isVisibleScr', $filters['isVisibleScr']);
|
||||
}
|
||||
|
||||
if (isset($filters['isVisibleRpt'])) {
|
||||
$builder->where('testdefsite.isVisibleRpt', $filters['isVisibleRpt']);
|
||||
}
|
||||
if (isset($filters['isVisibleScr'])) {
|
||||
$builder->where('testdefsite.isVisibleScr', $filters['isVisibleScr']);
|
||||
}
|
||||
|
||||
if (isset($filters['isVisibleRpt'])) {
|
||||
$builder->where('testdefsite.isVisibleRpt', $filters['isVisibleRpt']);
|
||||
}
|
||||
|
||||
if (!empty($filters['TestSiteName'])) {
|
||||
$builder->like('testdefsite.TestSiteName', $filters['TestSiteName']);
|
||||
@ -120,6 +120,10 @@ class TestDefSiteModel extends BaseModel {
|
||||
$builder->like('testdefsite.TestSiteCode', $filters['TestSiteCode']);
|
||||
}
|
||||
|
||||
if (!empty($filters['DepartmentID'])) {
|
||||
$builder->where('COALESCE(testdefsite.DepartmentID, cal.DepartmentID)', $filters['DepartmentID']);
|
||||
}
|
||||
|
||||
if (!empty($filters['search'])) {
|
||||
$builder->groupStart()
|
||||
->like('testdefsite.TestSiteCode', $filters['search'])
|
||||
@ -145,32 +149,32 @@ class TestDefSiteModel extends BaseModel {
|
||||
|
||||
$typeCode = $row['TestType'] ?? '';
|
||||
|
||||
if (TestValidationService::isCalc($typeCode)) {
|
||||
$row['testdefcal'] = $db->table('testdefcal')
|
||||
->select('testdefcal.*, d.DisciplineName, dept.DepartmentName')
|
||||
->join('discipline d', 'd.DisciplineID=testdefcal.DisciplineID', 'left')
|
||||
->join('department dept', 'dept.DepartmentID=testdefcal.DepartmentID', 'left')
|
||||
->where('testdefcal.TestSiteID', $TestSiteID)
|
||||
->where('testdefcal.EndDate IS NULL')
|
||||
->get()->getResultArray();
|
||||
|
||||
} elseif (TestValidationService::isGroup($typeCode)) {
|
||||
$testDefGrpModel = new \App\Models\Test\TestDefGrpModel();
|
||||
$row['testdefgrp'] = $testDefGrpModel->getGroupMembers($TestSiteID);
|
||||
|
||||
} elseif (TestValidationService::isTitle($typeCode)) {
|
||||
|
||||
} elseif (TestValidationService::isTechnicalTest($typeCode)) {
|
||||
// Technical details are now flattened into the main row
|
||||
if ($row['DisciplineID']) {
|
||||
$discipline = $db->table('discipline')->where('DisciplineID', $row['DisciplineID'])->get()->getRowArray();
|
||||
$row['DisciplineName'] = $discipline['DisciplineName'] ?? null;
|
||||
if (TestValidationService::isCalc($typeCode)) {
|
||||
$row['testdefcal'] = $db->table('testdefcal')
|
||||
->select('testdefcal.*, d.DisciplineName, dept.DepartmentName')
|
||||
->join('discipline d', 'd.DisciplineID=testdefcal.DisciplineID', 'left')
|
||||
->join('department dept', 'dept.DepartmentID=testdefcal.DepartmentID', 'left')
|
||||
->where('testdefcal.TestSiteID', $TestSiteID)
|
||||
->where('testdefcal.EndDate IS NULL')
|
||||
->get()->getResultArray();
|
||||
|
||||
} elseif (TestValidationService::isGroup($typeCode)) {
|
||||
$testDefGrpModel = new \App\Models\Test\TestDefGrpModel();
|
||||
$row['testdefgrp'] = $testDefGrpModel->getGroupMembers($TestSiteID);
|
||||
|
||||
} elseif (TestValidationService::isTitle($typeCode)) {
|
||||
|
||||
} elseif (TestValidationService::isTechnicalTest($typeCode)) {
|
||||
// Technical details are now flattened into the main row
|
||||
if ($row['DisciplineID']) {
|
||||
$discipline = $db->table('discipline')->where('DisciplineID', $row['DisciplineID'])->get()->getRowArray();
|
||||
$row['DisciplineName'] = $discipline['DisciplineName'] ?? null;
|
||||
}
|
||||
if ($row['DepartmentID']) {
|
||||
$department = $db->table('department')->where('DepartmentID', $row['DepartmentID'])->get()->getRowArray();
|
||||
$row['DepartmentName'] = $department['DepartmentName'] ?? null;
|
||||
}
|
||||
}
|
||||
if ($row['DepartmentID']) {
|
||||
$department = $db->table('department')->where('DepartmentID', $row['DepartmentID'])->get()->getRowArray();
|
||||
$row['DepartmentName'] = $department['DepartmentName'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
@ -217,16 +221,16 @@ class TestDefSiteModel extends BaseModel {
|
||||
* @param int $id
|
||||
* @return array|null
|
||||
*/
|
||||
public function getTestById($id)
|
||||
{
|
||||
$row = $this->db->table('testdefsite')
|
||||
->select('testdefsite.*, d.DisciplineName, dept.DepartmentName')
|
||||
->join('discipline d', 'd.DisciplineID = testdefsite.DisciplineID', 'left')
|
||||
->join('department dept', 'dept.DepartmentID = testdefsite.DepartmentID', 'left')
|
||||
->where('testdefsite.TestSiteID', $id)
|
||||
->where('testdefsite.EndDate IS NULL')
|
||||
->get()
|
||||
->getRowArray();
|
||||
public function getTestById($id)
|
||||
{
|
||||
$row = $this->db->table('testdefsite')
|
||||
->select('testdefsite.*, d.DisciplineName, dept.DepartmentName')
|
||||
->join('discipline d', 'd.DisciplineID = testdefsite.DisciplineID', 'left')
|
||||
->join('department dept', 'dept.DepartmentID = testdefsite.DepartmentID', 'left')
|
||||
->where('testdefsite.TestSiteID', $id)
|
||||
->where('testdefsite.EndDate IS NULL')
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if (!$row) {
|
||||
return null;
|
||||
@ -239,4 +243,4 @@ class TestDefSiteModel extends BaseModel {
|
||||
return $rows[0];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user