clqms-be/app/Models/Test/TestDefSiteModel.php
mahdahar 76c528564c fix: simplify test detail retrieval and clean tracked index artifacts
Use the base test row's RefType and ResultType to decide refnum/reftxt loading, and fetch discipline/department joins directly in getTestById to avoid redundant relation queries. Add feature coverage for show response behavior and include the related workspace cleanup changes so the branch state is consistent.
2026-03-25 14:06:00 +07:00

254 lines
8.8 KiB
PHP

<?php
namespace App\Models\Test;
use App\Models\BaseModel;
use App\Libraries\ValueSet;
use App\Libraries\TestValidationService;
class TestDefSiteModel extends BaseModel {
protected $table = 'testdefsite';
protected $primaryKey = 'TestSiteID';
protected $allowedFields = [
'SiteID',
'TestSiteCode', 'TestSiteName', 'TestType', 'Description',
'DisciplineID', 'DepartmentID',
'ResultType', 'RefType', 'Vset',
'Unit1', 'Factor', 'Unit2', 'Decimal',
'ReqQty', 'ReqQtyUnit', 'CollReq', 'Method', 'ExpectedTAT',
'SeqScr', 'SeqRpt', 'IndentLeft', 'FontStyle', 'isVisibleScr', 'isVisibleRpt',
'isCountStat', 'Level', 'isRequestable',
'CreateDate', 'StartDate','EndDate'
];
protected $useTimestamps = true;
protected $createdField = 'CreateDate';
protected $updatedField = 'StartDate';
protected $useSoftDeletes = true;
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")
->where('testdefsite.EndDate IS NULL');
if ($siteId) {
$builder->where('testdefsite.SiteID', $siteId);
}
if ($testType) {
$builder->where('testdefsite.TestType', $testType);
}
if ($visibleScr !== null) {
$builder->where('testdefsite.isVisibleScr', $visibleScr);
}
if ($visibleRpt !== null) {
$builder->where('testdefsite.isVisibleRpt', $visibleRpt);
}
if ($search) {
$builder->groupStart()
->like('testdefsite.TestSiteCode', $search)
->orLike('testdefsite.TestSiteName', $search)
->groupEnd();
}
// Get total count before pagination
$totalBuilder = clone $builder;
$total = $totalBuilder->countAllResults();
// Apply pagination
$offset = ($page - 1) * $perPage;
$rows = $builder->orderBy('testdefsite.SeqScr', 'ASC')
->limit($perPage, $offset)
->findAll();
$rows = ValueSet::transformLabels($rows, [
'TestType' => 'test_type',
]);
return [
'data' => $rows,
'pagination' => [
'total' => $total
]
];
}
/**
* Get tests list with discipline and department info
*/
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,
COALESCE(testdefsite.DisciplineID, cal.DisciplineID) as DisciplineID,
COALESCE(testdefsite.DepartmentID, cal.DepartmentID) as DepartmentID,
d.DisciplineName, dept.DepartmentName"
)
->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('department dept', 'dept.DepartmentID = COALESCE(testdefsite.DepartmentID, cal.DepartmentID)', 'left')
->where('testdefsite.EndDate IS NULL');
if (!empty($filters['SiteID'])) {
$builder->where('testdefsite.SiteID', $filters['SiteID']);
}
if (!empty($filters['TestType'])) {
$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 (!empty($filters['TestSiteName'])) {
$builder->like('testdefsite.TestSiteName', $filters['TestSiteName']);
}
if (!empty($filters['TestSiteCode'])) {
$builder->like('testdefsite.TestSiteCode', $filters['TestSiteCode']);
}
if (!empty($filters['search'])) {
$builder->groupStart()
->like('testdefsite.TestSiteCode', $filters['search'])
->orLike('testdefsite.TestSiteName', $filters['search'])
->groupEnd();
}
return $builder->orderBy('testdefsite.SeqScr', 'ASC')->get()->getResultArray();
}
public function getTest($TestSiteID) {
$db = \Config\Database::connect();
$row = $this->select("testdefsite.*")
->where("testdefsite.TestSiteID", $TestSiteID)
->find($TestSiteID);
if (!$row) return null;
$row = ValueSet::transformLabels([$row], [
'TestType' => 'test_type',
])[0];
$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();
$testMapModel = new \App\Models\Test\TestMapModel();
$row['testmap'] = $testMapModel->getMappingsByTestCode($row['TestSiteCode']);
} elseif (TestValidationService::isGroup($typeCode)) {
$testDefGrpModel = new \App\Models\Test\TestDefGrpModel();
$row['testdefgrp'] = $testDefGrpModel->getGroupMembers($TestSiteID);
$testMapModel = new \App\Models\Test\TestMapModel();
$row['testmap'] = $testMapModel->getMappingsByTestCode($row['TestSiteCode']);
} elseif (TestValidationService::isTitle($typeCode)) {
$testMapModel = new \App\Models\Test\TestMapModel();
$row['testmap'] = $testMapModel->getMappingsByTestCode($row['TestSiteCode']);
} 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;
}
$testMapModel = new \App\Models\Test\TestMapModel();
$row['testmap'] = $testMapModel->getMappingsByTestCode($row['TestSiteCode']);
}
return $row;
}
/**
* Validate test type combination
*
* @param string $testType
* @param string $resultType
* @param string $refType
* @return array ['valid' => bool, 'error' => string|null]
*/
public function validateTypes(string $testType, string $resultType, string $refType): array
{
return TestValidationService::validate($testType, $resultType, $refType);
}
/**
* Check if test needs reference ranges
*
* @param string $resultType
* @return bool
*/
public function needsReferenceRanges(string $resultType): bool
{
return TestValidationService::needsReferenceRanges($resultType);
}
/**
* Get reference table name
*
* @param string $resultType
* @param string $refType
* @return string|null
*/
public function getReferenceTable(string $resultType, string $refType): ?string
{
return TestValidationService::getReferenceTable($resultType, $refType);
}
/**
* Get test by ID with ValueSet transformation
*
* @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();
if (!$row) {
return null;
}
$rows = ValueSet::transformLabels([$row], [
'TestType' => 'test_type',
]);
return $rows[0];
}
}