refactor: move TestsController to Test namespace and update routes

- Move TestsController from App\Controllers to App\Controllers\Test namespace

- Update routes from 'api/tests' to 'api/test' group

- Clean up empty lines in Routes.php

- Improve code formatting and indentation in TestsController
This commit is contained in:
mahdahar 2026-03-02 07:02:51 +07:00
parent 24e0293824
commit 49d3a69308
2 changed files with 204 additions and 209 deletions

View File

@ -29,8 +29,6 @@ $routes->group('v2/auth', function ($routes) {
$routes->post('logout', 'AuthV2Controller::logout'); $routes->post('logout', 'AuthV2Controller::logout');
}); });
// Faker // Faker
$routes->get('faker/faker-patient/(:num)', 'faker\FakerPatient::sendMany/$1'); $routes->get('faker/faker-patient/(:num)', 'faker\FakerPatient::sendMany/$1');
@ -287,16 +285,12 @@ $routes->group('api', function ($routes) {
$routes->patch('/', 'Specimen\SpecimenController::update'); $routes->patch('/', 'Specimen\SpecimenController::update');
}); });
// Tests
$routes->group('tests', function ($routes) {
$routes->get('/', 'TestsController::index');
$routes->get('(:num)', 'TestsController::show/$1');
$routes->post('/', 'TestsController::create');
$routes->patch('/', 'TestsController::update');
});
// Test Mapping // Test Mapping
$routes->group('test', function ($routes) { $routes->group('test', function ($routes) {
$routes->get('/', 'Test\TestsController::index');
$routes->get('(:num)', 'Test\TestsController::show/$1');
$routes->post('/', 'Test\TestsController::create');
$routes->patch('/', 'Test\TestsController::update');
$routes->group('testmap', function ($routes) { $routes->group('testmap', function ($routes) {
$routes->get('/', 'Test\TestMapController::index'); $routes->get('/', 'Test\TestMapController::index');
$routes->get('(:num)', 'Test\TestMapController::show/$1'); $routes->get('(:num)', 'Test\TestMapController::show/$1');

View File

@ -1,32 +1,31 @@
<?php <?php
namespace App\Controllers;
use App\Traits\ResponseTrait; namespace App\Controllers\Test;
use App\Controllers\BaseController; use App\Controllers\BaseController;
use App\Libraries\ValueSet;
use App\Libraries\TestValidationService; use App\Libraries\TestValidationService;
use App\Libraries\ValueSet;
use App\Traits\ResponseTrait;
class TestsController extends BaseController class TestsController extends BaseController
{ {
use ResponseTrait; use ResponseTrait;
protected $db; protected $db;
protected $rules;
protected $model; protected $model;
protected $modelCal; protected $modelCal;
protected $modelGrp; protected $modelGrp;
protected $modelMap; protected $modelMap;
protected $modelMapDetail; protected $modelMapDetail;
protected $modelRefNum; protected $modelRefNum;
protected $modelRefTxt; protected $modelRefTxt;
protected $rules;
public function __construct() public function __construct()
{ {
$this->db = \Config\Database::connect(); $this->db = \Config\Database::connect();
$this->model = new \App\Models\Test\TestDefSiteModel; $this->model = new \App\Models\Test\TestDefSiteModel;
$this->modelCal = new \App\Models\Test\TestDefCalModel; $this->modelCal = new \App\Models\Test\TestDefCalModel;
$this->modelGrp = new \App\Models\Test\TestDefGrpModel; $this->modelGrp = new \App\Models\Test\TestDefGrpModel;
$this->modelMap = new \App\Models\Test\TestMapModel; $this->modelMap = new \App\Models\Test\TestMapModel;
$this->modelMapDetail = new \App\Models\Test\TestMapDetailModel; $this->modelMapDetail = new \App\Models\Test\TestMapDetailModel;
@ -37,7 +36,7 @@ class TestsController extends BaseController
'TestSiteCode' => 'required', 'TestSiteCode' => 'required',
'TestSiteName' => 'required', 'TestSiteName' => 'required',
'TestType' => 'required', 'TestType' => 'required',
'SiteID' => 'required' 'SiteID' => 'required',
]; ];
} }
@ -47,15 +46,18 @@ class TestsController extends BaseController
$testType = $this->request->getGet('TestType'); $testType = $this->request->getGet('TestType');
$visibleScr = $this->request->getGet('VisibleScr'); $visibleScr = $this->request->getGet('VisibleScr');
$visibleRpt = $this->request->getGet('VisibleRpt'); $visibleRpt = $this->request->getGet('VisibleRpt');
$keyword = $this->request->getGet('TestSiteName'); $testSiteName = $this->request->getGet('TestSiteName');
$testSiteCode = $this->request->getGet('TestSiteCode');
$builder = $this->db->table('testdefsite') $builder = $this->db->table('testdefsite')
->select("testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType, ->select(
"testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.VisibleScr, testdefsite.VisibleRpt, testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.VisibleScr, testdefsite.VisibleRpt,
testdefsite.CountStat, testdefsite.StartDate, testdefsite.EndDate, testdefsite.CountStat, testdefsite.StartDate, testdefsite.EndDate,
COALESCE(testdefsite.DisciplineID, cal.DisciplineID) as DisciplineID, COALESCE(testdefsite.DisciplineID, cal.DisciplineID) as DisciplineID,
COALESCE(testdefsite.DepartmentID, cal.DepartmentID) as DepartmentID, COALESCE(testdefsite.DepartmentID, cal.DepartmentID) as DepartmentID,
d.DisciplineName, dept.DepartmentName") d.DisciplineName, dept.DepartmentName"
)
->join('testdefcal cal', 'cal.TestSiteID = testdefsite.TestSiteID AND cal.EndDate IS NULL', 'left') ->join('testdefcal cal', 'cal.TestSiteID = testdefsite.TestSiteID AND cal.EndDate IS NULL', 'left')
->join('discipline d', 'd.DisciplineID = COALESCE(testdefsite.DisciplineID, cal.DisciplineID)', 'left') ->join('discipline d', 'd.DisciplineID = COALESCE(testdefsite.DisciplineID, cal.DisciplineID)', 'left')
->join('department dept', 'dept.DepartmentID = COALESCE(testdefsite.DepartmentID, cal.DepartmentID)', 'left') ->join('department dept', 'dept.DepartmentID = COALESCE(testdefsite.DepartmentID, cal.DepartmentID)', 'left')
@ -77,34 +79,51 @@ class TestsController extends BaseController
$builder->where('testdefsite.VisibleRpt', $visibleRpt); $builder->where('testdefsite.VisibleRpt', $visibleRpt);
} }
if ($keyword) { if ($testSiteName) {
$builder->like('testdefsite.TestSiteName', $keyword); $builder->like('testdefsite.TestSiteName', $testSiteName);
}
if ($testSiteCode) {
$builder->like('testdefsite.TestSiteCode', $testSiteCode);
} }
$rows = $builder->orderBy('testdefsite.SeqScr', 'ASC')->get()->getResultArray(); $rows = $builder->orderBy('testdefsite.SeqScr', 'ASC')->get()->getResultArray();
if (empty($rows)) { if (empty($rows)) {
return $this->respond(['status' => 'success', 'message' => "No data.", 'data' => []], 200); return $this->respond([
'status' => 'success',
'message' => 'No data.',
'data' => [],
], 200);
} }
$rows = ValueSet::transformLabels($rows, [ $rows = ValueSet::transformLabels($rows, [
'TestType' => 'test_type', 'TestType' => 'test_type',
]); ]);
return $this->respond(['status' => 'success', 'message' => "Data fetched successfully", 'data' => $rows], 200); return $this->respond([
'status' => 'success',
'message' => 'Data fetched successfully',
'data' => $rows,
], 200);
} }
public function show($id = null) public function show($id = null)
{ {
if (!$id) if (!$id) {
return $this->failValidationErrors('TestSiteID is required'); return $this->failValidationErrors('TestSiteID is required');
}
$row = $this->model->select("testdefsite.*") $row = $this->model->select('testdefsite.*')
->where("testdefsite.TestSiteID", $id) ->where('testdefsite.TestSiteID', $id)
->find($id); ->find($id);
if (!$row) { if (!$row) {
return $this->respond(['status' => 'success', 'message' => "No data.", 'data' => null], 200); return $this->respond([
'status' => 'success',
'message' => 'No data.',
'data' => null,
], 200);
} }
$row = ValueSet::transformLabels([$row], [ $row = ValueSet::transformLabels([$row], [
@ -121,9 +140,6 @@ class TestsController extends BaseController
->where('testdefcal.TestSiteID', $id) ->where('testdefcal.TestSiteID', $id)
->where('testdefcal.EndDate IS NULL') ->where('testdefcal.EndDate IS NULL')
->get()->getResultArray(); ->get()->getResultArray();
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
} elseif ($typeCode === 'GROUP') { } elseif ($typeCode === 'GROUP') {
$row['testdefgrp'] = $this->db->table('testdefgrp') $row['testdefgrp'] = $this->db->table('testdefgrp')
->select('testdefgrp.*, t.TestSiteCode, t.TestSiteName, t.TestType') ->select('testdefgrp.*, t.TestSiteCode, t.TestSiteName, t.TestType')
@ -136,14 +152,8 @@ class TestsController extends BaseController
$row['testdefgrp'] = ValueSet::transformLabels($row['testdefgrp'], [ $row['testdefgrp'] = ValueSet::transformLabels($row['testdefgrp'], [
'TestType' => 'test_type', 'TestType' => 'test_type',
]); ]);
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
} elseif ($typeCode === 'TITLE') { } elseif ($typeCode === 'TITLE') {
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
} else { } else {
// Technical details are now stored directly in testdefsite
$row['testdeftech'] = $this->db->table('testdefsite') $row['testdeftech'] = $this->db->table('testdefsite')
->select('testdefsite.*, d.DisciplineName, dept.DepartmentName') ->select('testdefsite.*, d.DisciplineName, dept.DepartmentName')
->join('discipline d', 'd.DisciplineID=testdefsite.DisciplineID', 'left') ->join('discipline d', 'd.DisciplineID=testdefsite.DisciplineID', 'left')
@ -152,14 +162,11 @@ class TestsController extends BaseController
->where('testdefsite.EndDate IS NULL') ->where('testdefsite.EndDate IS NULL')
->get()->getResultArray(); ->get()->getResultArray();
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
if (!empty($row['testdeftech'])) { if (!empty($row['testdeftech'])) {
$techData = $row['testdeftech'][0]; $techData = $row['testdeftech'][0];
$refType = $techData['RefType']; $refType = $techData['RefType'];
$resultType = $techData['ResultType'] ?? ''; $resultType = $techData['ResultType'] ?? '';
// Use TestValidationService to determine reference table
if (TestValidationService::usesRefNum($resultType, $refType)) { if (TestValidationService::usesRefNum($resultType, $refType)) {
$refnumData = $this->modelRefNum $refnumData = $this->modelRefNum
->where('TestSiteID', $id) ->where('TestSiteID', $id)
@ -185,10 +192,9 @@ class TestsController extends BaseController
'AgeStart' => (int) $r['AgeStart'], 'AgeStart' => (int) $r['AgeStart'],
'AgeEnd' => (int) $r['AgeEnd'], 'AgeEnd' => (int) $r['AgeEnd'],
'Flag' => $r['Flag'], 'Flag' => $r['Flag'],
'Interpretation' => $r['Interpretation'] 'Interpretation' => $r['Interpretation'],
]; ];
}, $refnumData ?? []); }, $refnumData ?? []);
} }
if (TestValidationService::usesRefTxt($resultType, $refType)) { if (TestValidationService::usesRefTxt($resultType, $refType)) {
@ -208,18 +214,18 @@ class TestsController extends BaseController
'AgeStart' => (int) $r['AgeStart'], 'AgeStart' => (int) $r['AgeStart'],
'AgeEnd' => (int) $r['AgeEnd'], 'AgeEnd' => (int) $r['AgeEnd'],
'RefTxt' => $r['RefTxt'], 'RefTxt' => $r['RefTxt'],
'Flag' => $r['Flag'] 'Flag' => $r['Flag'],
]; ];
}, $reftxtData ?? []); }, $reftxtData ?? []);
} }
} }
} }
// $row['refTypeOptions'] = ValueSet::getOptions('reference_type'); return $this->respond([
// $row['sexOptions'] = ValueSet::getOptions('gender'); 'status' => 'success',
// $row['mathSignOptions'] = ValueSet::getOptions('math_sign'); 'message' => 'Data fetched successfully',
'data' => $row,
return $this->respond(['status' => 'success', 'message' => "Data fetched successfully", 'data' => $row], 200); ], 200);
} }
public function create() public function create()
@ -230,13 +236,11 @@ class TestsController extends BaseController
return $this->failValidationErrors($this->validator->getErrors()); return $this->failValidationErrors($this->validator->getErrors());
} }
// Validate TestType, ResultType, and RefType combinations
$testType = $input['TestType'] ?? ''; $testType = $input['TestType'] ?? '';
$details = $input['details'] ?? $input; $details = $input['details'] ?? $input;
$resultType = $details['ResultType'] ?? ''; $resultType = $details['ResultType'] ?? '';
$refType = $details['RefType'] ?? ''; $refType = $details['RefType'] ?? '';
// Set defaults for CALC, GROUP, TITLE types
if (TestValidationService::isCalc($testType)) { if (TestValidationService::isCalc($testType)) {
$resultType = 'NMRIC'; $resultType = 'NMRIC';
$refType = $refType ?: 'RANGE'; $refType = $refType ?: 'RANGE';
@ -268,12 +272,12 @@ class TestsController extends BaseController
'VisibleScr' => $input['VisibleScr'] ?? 1, 'VisibleScr' => $input['VisibleScr'] ?? 1,
'VisibleRpt' => $input['VisibleRpt'] ?? 1, 'VisibleRpt' => $input['VisibleRpt'] ?? 1,
'CountStat' => $input['CountStat'] ?? 1, 'CountStat' => $input['CountStat'] ?? 1,
'StartDate' => $input['StartDate'] ?? date('Y-m-d H:i:s') 'StartDate' => $input['StartDate'] ?? date('Y-m-d H:i:s'),
]; ];
$id = $this->model->insert($testSiteData); $id = $this->model->insert($testSiteData);
if (!$id) { if (!$id) {
throw new \Exception("Failed to insert main test definition"); throw new \Exception('Failed to insert main test definition');
} }
$this->handleDetails($id, $input, 'insert'); $this->handleDetails($id, $input, 'insert');
@ -286,11 +290,12 @@ class TestsController extends BaseController
return $this->respondCreated([ return $this->respondCreated([
'status' => 'created', 'status' => 'created',
'message' => "Test created successfully", 'message' => 'Test created successfully',
'data' => ['TestSiteId' => $id] 'data' => ['TestSiteId' => $id],
]); ]);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->db->transRollback(); $this->db->transRollback();
return $this->failServerError('Something went wrong: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage());
} }
} }
@ -299,8 +304,8 @@ class TestsController extends BaseController
{ {
$input = $this->request->getJSON(true); $input = $this->request->getJSON(true);
if (!$id && isset($input["TestSiteID"])) { if (!$id && isset($input['TestSiteID'])) {
$id = $input["TestSiteID"]; $id = $input['TestSiteID'];
} }
if (!$id) { if (!$id) {
return $this->failValidationErrors('TestSiteID is required.'); return $this->failValidationErrors('TestSiteID is required.');
@ -311,13 +316,11 @@ class TestsController extends BaseController
return $this->failNotFound('Test not found'); return $this->failNotFound('Test not found');
} }
// Validate TestType, ResultType, and RefType combinations if provided
$testType = $input['TestType'] ?? $existing['TestType'] ?? ''; $testType = $input['TestType'] ?? $existing['TestType'] ?? '';
$details = $input['details'] ?? $input; $details = $input['details'] ?? $input;
$resultType = $details['ResultType'] ?? $existing['ResultType'] ?? ''; $resultType = $details['ResultType'] ?? $existing['ResultType'] ?? '';
$refType = $details['RefType'] ?? $existing['RefType'] ?? ''; $refType = $details['RefType'] ?? $existing['RefType'] ?? '';
// Set defaults for CALC, GROUP, TITLE types
if (TestValidationService::isCalc($testType)) { if (TestValidationService::isCalc($testType)) {
$resultType = 'NMRIC'; $resultType = 'NMRIC';
$refType = $refType ?: 'RANGE'; $refType = $refType ?: 'RANGE';
@ -349,7 +352,7 @@ class TestsController extends BaseController
'VisibleScr', 'VisibleScr',
'VisibleRpt', 'VisibleRpt',
'CountStat', 'CountStat',
'StartDate' 'StartDate',
]; ];
foreach ($allowedUpdateFields as $field) { foreach ($allowedUpdateFields as $field) {
@ -372,11 +375,12 @@ class TestsController extends BaseController
return $this->respond([ return $this->respond([
'status' => 'success', 'status' => 'success',
'message' => "Test updated successfully", 'message' => 'Test updated successfully',
'data' => ['TestSiteId' => $id] 'data' => ['TestSiteId' => $id],
]); ]);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->db->transRollback(); $this->db->transRollback();
return $this->failServerError('Something went wrong: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage());
} }
} }
@ -385,8 +389,8 @@ class TestsController extends BaseController
{ {
$input = $this->request->getJSON(true); $input = $this->request->getJSON(true);
if (!$id && isset($input["TestSiteID"])) { if (!$id && isset($input['TestSiteID'])) {
$id = $input["TestSiteID"]; $id = $input['TestSiteID'];
} }
if (!$id) { if (!$id) {
return $this->failValidationErrors('TestSiteID is required.'); return $this->failValidationErrors('TestSiteID is required.');
@ -420,7 +424,6 @@ class TestsController extends BaseController
->where('TestSiteID', $id) ->where('TestSiteID', $id)
->update(['EndDate' => $now]); ->update(['EndDate' => $now]);
} elseif (TestValidationService::isTechnicalTest($typeCode)) { } elseif (TestValidationService::isTechnicalTest($typeCode)) {
$this->modelRefNum->where('TestSiteID', $id)->set('EndDate', $now)->update(); $this->modelRefNum->where('TestSiteID', $id)->set('EndDate', $now)->update();
$this->modelRefTxt->where('TestSiteID', $id)->set('EndDate', $now)->update(); $this->modelRefTxt->where('TestSiteID', $id)->set('EndDate', $now)->update();
} }
@ -437,11 +440,12 @@ class TestsController extends BaseController
return $this->respond([ return $this->respond([
'status' => 'success', 'status' => 'success',
'message' => "Test disabled successfully", 'message' => 'Test disabled successfully',
'data' => ['TestSiteId' => $id, 'EndDate' => $now] 'data' => ['TestSiteId' => $id, 'EndDate' => $now],
]); ]);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->db->transRollback(); $this->db->transRollback();
return $this->failServerError('Something went wrong: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage());
} }
} }
@ -455,8 +459,9 @@ class TestsController extends BaseController
$testTypeID = $existing['TestType'] ?? null; $testTypeID = $existing['TestType'] ?? null;
} }
if (!$testTypeID) if (!$testTypeID) {
return; return;
}
$typeCode = $testTypeID; $typeCode = $testTypeID;
@ -467,16 +472,19 @@ class TestsController extends BaseController
switch ($typeCode) { switch ($typeCode) {
case 'CALC': case 'CALC':
$this->saveCalcDetails($testSiteID, $details, $action); $this->saveCalcDetails($testSiteID, $details, $action);
break; break;
case 'GROUP': case 'GROUP':
$this->saveGroupDetails($testSiteID, $details, $input, $action); $this->saveGroupDetails($testSiteID, $details, $input, $action);
break; break;
case 'TITLE': case 'TITLE':
if (isset($input['testmap']) && is_array($input['testmap'])) { if (isset($input['testmap']) && is_array($input['testmap'])) {
$this->saveTestMap($testSiteID, $input['testmap'], $action); $this->saveTestMap($testSiteID, $input['testmap'], $action);
} }
break; break;
case 'TEST': case 'TEST':
@ -488,7 +496,6 @@ class TestsController extends BaseController
$refType = (string) $details['RefType']; $refType = (string) $details['RefType'];
$resultType = $details['ResultType'] ?? ''; $resultType = $details['ResultType'] ?? '';
// Use TestValidationService to determine which reference table to use
if (TestValidationService::usesRefNum($resultType, $refType) && isset($input['refnum']) && is_array($input['refnum'])) { if (TestValidationService::usesRefNum($resultType, $refType) && isset($input['refnum']) && is_array($input['refnum'])) {
$this->saveRefNumRanges($testSiteID, $input['refnum'], $action, $input['SiteID'] ?? 1); $this->saveRefNumRanges($testSiteID, $input['refnum'], $action, $input['SiteID'] ?? 1);
} }
@ -497,6 +504,7 @@ class TestsController extends BaseController
$this->saveRefTxtRanges($testSiteID, $input['reftxt'], $action, $input['SiteID'] ?? 1); $this->saveRefTxtRanges($testSiteID, $input['reftxt'], $action, $input['SiteID'] ?? 1);
} }
} }
break; break;
} }
@ -507,7 +515,6 @@ class TestsController extends BaseController
private function saveTechDetails($testSiteID, $data, $action, $typeCode) private function saveTechDetails($testSiteID, $data, $action, $typeCode)
{ {
// Technical details are now stored directly in testdefsite table
$techData = [ $techData = [
'DisciplineID' => $data['DisciplineID'] ?? null, 'DisciplineID' => $data['DisciplineID'] ?? null,
'DepartmentID' => $data['DepartmentID'] ?? null, 'DepartmentID' => $data['DepartmentID'] ?? null,
@ -522,10 +529,9 @@ class TestsController extends BaseController
'Decimal' => $data['Decimal'] ?? 2, 'Decimal' => $data['Decimal'] ?? 2,
'CollReq' => $data['CollReq'] ?? null, 'CollReq' => $data['CollReq'] ?? null,
'Method' => $data['Method'] ?? null, 'Method' => $data['Method'] ?? null,
'ExpectedTAT' => $data['ExpectedTAT'] ?? null 'ExpectedTAT' => $data['ExpectedTAT'] ?? null,
]; ];
// Update the testdefsite record directly
$this->model->update($testSiteID, $techData); $this->model->update($testSiteID, $techData);
} }
@ -553,7 +559,7 @@ class TestsController extends BaseController
'Flag' => $range['Flag'] ?? null, 'Flag' => $range['Flag'] ?? null,
'Interpretation'=> $range['Interpretation'] ?? null, 'Interpretation'=> $range['Interpretation'] ?? null,
'Display' => $index, 'Display' => $index,
'CreateDate' => date('Y-m-d H:i:s') 'CreateDate' => date('Y-m-d H:i:s'),
]); ]);
} }
} }
@ -576,7 +582,7 @@ class TestsController extends BaseController
'AgeEnd' => (int) ($range['AgeEnd'] ?? 150), 'AgeEnd' => (int) ($range['AgeEnd'] ?? 150),
'RefTxt' => $range['RefTxt'] ?? '', 'RefTxt' => $range['RefTxt'] ?? '',
'Flag' => $range['Flag'] ?? null, 'Flag' => $range['Flag'] ?? null,
'CreateDate' => date('Y-m-d H:i:s') 'CreateDate' => date('Y-m-d H:i:s'),
]); ]);
} }
} }
@ -589,13 +595,13 @@ class TestsController extends BaseController
'DepartmentID' => $data['DepartmentID'] ?? null, 'DepartmentID' => $data['DepartmentID'] ?? null,
'FormulaInput' => $data['FormulaInput'] ?? null, 'FormulaInput' => $data['FormulaInput'] ?? null,
'FormulaCode' => $data['FormulaCode'] ?? $data['Formula'] ?? null, 'FormulaCode' => $data['FormulaCode'] ?? $data['Formula'] ?? null,
'ResultType' => 'NMRIC', // CALC always has NMRIC result type 'ResultType' => 'NMRIC',
'RefType' => $data['RefType'] ?? 'RANGE', 'RefType' => $data['RefType'] ?? 'RANGE',
'Unit1' => $data['Unit1'] ?? $data['ResultUnit'] ?? null, 'Unit1' => $data['Unit1'] ?? $data['ResultUnit'] ?? null,
'Factor' => $data['Factor'] ?? null, 'Factor' => $data['Factor'] ?? null,
'Unit2' => $data['Unit2'] ?? null, 'Unit2' => $data['Unit2'] ?? null,
'Decimal' => $data['Decimal'] ?? 2, 'Decimal' => $data['Decimal'] ?? 2,
'Method' => $data['Method'] ?? null 'Method' => $data['Method'] ?? null,
]; ];
if ($action === 'update') { if ($action === 'update') {
@ -630,7 +636,7 @@ class TestsController extends BaseController
if ($memberID) { if ($memberID) {
$this->modelGrp->insert([ $this->modelGrp->insert([
'TestSiteID' => $testSiteID, 'TestSiteID' => $testSiteID,
'Member' => $memberID 'Member' => $memberID,
]); ]);
} }
} }
@ -640,20 +646,17 @@ class TestsController extends BaseController
private function saveTestMap($testSiteID, $mappings, $action) private function saveTestMap($testSiteID, $mappings, $action)
{ {
if ($action === 'update') { if ($action === 'update') {
// Soft delete existing testmaps and their details for this test site
$existingMaps = $this->modelMap->where('TestSiteID', $testSiteID) $existingMaps = $this->modelMap->where('TestSiteID', $testSiteID)
->where('EndDate IS NULL') ->where('EndDate IS NULL')
->findAll(); ->findAll();
foreach ($existingMaps as $existingMap) { foreach ($existingMaps as $existingMap) {
// Soft delete details first
$this->modelMapDetail->where('TestMapID', $existingMap['TestMapID']) $this->modelMapDetail->where('TestMapID', $existingMap['TestMapID'])
->where('EndDate IS NULL') ->where('EndDate IS NULL')
->set('EndDate', date('Y-m-d H:i:s')) ->set('EndDate', date('Y-m-d H:i:s'))
->update(); ->update();
} }
// Soft delete the testmap headers
$this->db->table('testmap') $this->db->table('testmap')
->where('TestSiteID', $testSiteID) ->where('TestSiteID', $testSiteID)
->where('EndDate IS NULL') ->where('EndDate IS NULL')
@ -662,7 +665,6 @@ class TestsController extends BaseController
if (is_array($mappings)) { if (is_array($mappings)) {
foreach ($mappings as $map) { foreach ($mappings as $map) {
// Create testmap header
$mapData = [ $mapData = [
'TestSiteID' => $testSiteID, 'TestSiteID' => $testSiteID,
'HostType' => $map['HostType'] ?? null, 'HostType' => $map['HostType'] ?? null,
@ -672,7 +674,6 @@ class TestsController extends BaseController
]; ];
$testMapID = $this->modelMap->insert($mapData); $testMapID = $this->modelMap->insert($mapData);
// Create testmapdetail records if details are provided
if ($testMapID && isset($map['details']) && is_array($map['details'])) { if ($testMapID && isset($map['details']) && is_array($map['details'])) {
foreach ($map['details'] as $detail) { foreach ($map['details'] as $detail) {
$detailData = [ $detailData = [