diff --git a/Test Management.docx b/Test Management.docx deleted file mode 100644 index 04bc352..0000000 Binary files a/Test Management.docx and /dev/null differ diff --git a/app/Controllers/Tests.php b/app/Controllers/Tests.php index a8629b7..755b377 100644 --- a/app/Controllers/Tests.php +++ b/app/Controllers/Tests.php @@ -35,7 +35,8 @@ class Tests extends BaseController { } /** - * GET /api/tests + * GET /v1/tests + * GET /v1/tests/site * List all tests with optional filtering */ public function index() { @@ -82,11 +83,12 @@ class Tests extends BaseController { } /** - * GET /api/tests/{id} + * GET /v1/tests/{id} + * GET /v1/tests/site/{id} * Get single test by ID with all related details */ public function show($id = null) { - if (!$id) return $this->failValidationErrors('ID is required'); + if (!$id) return $this->failValidationErrors('TestSiteID is required'); $row = $this->model->select("testdefsite.*, valueset.VValue as TypeCode, valueset.VDesc as TypeName") ->join("valueset", "valueset.VID=testdefsite.TestType", "left") @@ -134,11 +136,9 @@ class Tests extends BaseController { } else { // TEST or PARAM - load technical details $row['testdeftech'] = $this->db->table('testdeftech') - ->select('testdeftech.*, d.DisciplineName, dept.DepartmentName, w.WorkstationName, e.EquipmentName') + ->select('testdeftech.*, d.DisciplineName, dept.DepartmentName') ->join('discipline d', 'd.DisciplineID=testdeftech.DisciplineID', 'left') ->join('department dept', 'dept.DepartmentID=testdeftech.DepartmentID', 'left') - ->join('workstation w', 'w.WorkstationID=testdeftech.WorkstationID', 'left') - ->join('equipment e', 'e.EquipmentID=testdeftech.EquipmentID', 'left') ->where('testdeftech.TestSiteID', $id) ->where('testdeftech.EndDate IS NULL') ->get()->getResultArray(); @@ -151,7 +151,8 @@ class Tests extends BaseController { } /** - * POST /api/tests + * POST /v1/tests + * POST /v1/tests/site * Create new test definition */ public function create() { @@ -196,9 +197,9 @@ class Tests extends BaseController { } return $this->respondCreated([ - 'status' => 'success', + 'status' => 'created', 'message' => "Test created successfully", - 'data' => ['TestSiteID' => $id] + 'data' => ['TestSiteId' => $id] ]); } catch (\Exception $e) { $this->db->transRollback(); @@ -207,7 +208,8 @@ class Tests extends BaseController { } /** - * PUT/PATCH /api/tests/{id} + * PUT/PATCH /v1/tests/{id} + * PUT/PATCH /v1/tests/site/{id} * Update existing test definition */ public function update($id = null) { @@ -254,7 +256,7 @@ class Tests extends BaseController { return $this->respond([ 'status' => 'success', 'message' => "Test updated successfully", - 'data' => ['TestSiteID' => $id] + 'data' => ['TestSiteId' => $id] ]); } catch (\Exception $e) { $this->db->transRollback(); @@ -263,7 +265,8 @@ class Tests extends BaseController { } /** - * DELETE /api/tests/{id} + * DELETE /v1/tests/{id} + * DELETE /v1/tests/site/{id} * Soft delete test by setting EndDate */ public function delete($id = null) { @@ -326,7 +329,7 @@ class Tests extends BaseController { return $this->respond([ 'status' => 'success', 'message' => "Test disabled successfully", - 'data' => ['TestSiteID' => $id, 'EndDate' => $now] + 'data' => ['TestSiteId' => $id, 'EndDate' => $now] ]); } catch (\Exception $e) { $this->db->transRollback(); @@ -392,17 +395,12 @@ class Tests extends BaseController { */ private function saveTechDetails($testSiteID, $data, $action, $typeCode) { $techData = [ - 'SiteID' => $data['SiteID'], 'TestSiteID' => $testSiteID, 'DisciplineID' => $data['DisciplineID'] ?? null, 'DepartmentID' => $data['DepartmentID'] ?? null, - 'WorkstationID' => $data['WorkstationID'] ?? null, - 'EquipmentID' => $data['EquipmentID'] ?? null, - 'ResultType' => $data['ResultType'] ?? ($typeCode === 'PARAM' ? 'Numeric' : null), + 'ResultType' => $data['ResultType'] ?? null, 'RefType' => $data['RefType'] ?? null, 'VSet' => $data['VSet'] ?? null, - 'SpcType' => $data['SpcType'] ?? null, - 'SpcDesc' => $data['SpcDesc'] ?? null, 'ReqQty' => $data['ReqQty'] ?? null, 'ReqQtyUnit' => $data['ReqQtyUnit'] ?? null, 'Unit1' => $data['Unit1'] ?? null, @@ -435,7 +433,6 @@ class Tests extends BaseController { */ private function saveCalcDetails($testSiteID, $data, $action) { $calcData = [ - 'SiteID' => $data['SiteID'], 'TestSiteID' => $testSiteID, 'DisciplineID' => $data['DisciplineID'] ?? null, 'DepartmentID' => $data['DepartmentID'] ?? null, @@ -484,7 +481,6 @@ class Tests extends BaseController { $memberID = is_array($m) ? ($m['Member'] ?? ($m['TestSiteID'] ?? null)) : $m; if ($memberID) { $this->modelGrp->insert([ - 'SiteID' => $data['SiteID'], 'TestSiteID' => $testSiteID, 'Member' => $memberID ]); diff --git a/app/Database/Migrations/2025-10-11-100001_Test.php b/app/Database/Migrations/2025-10-11-100001_Test.php index ad5656a..c8f783a 100644 --- a/app/Database/Migrations/2025-10-11-100001_Test.php +++ b/app/Database/Migrations/2025-10-11-100001_Test.php @@ -6,7 +6,7 @@ use CodeIgniter\Database\Migration; class CreateTestsTable extends Migration { public function up() { - // testdefsite - Main test definition table + // testdefsite - Main test definition table per site $this->forge->addField([ 'TestSiteID' => ['type' => 'INT', 'auto_increment' => true, 'unsigned' => true], 'SiteID' => ['type' => 'INT', 'null' => false], @@ -31,17 +31,12 @@ class CreateTestsTable extends Migration { // testdeftech - Technical definition for TEST and PARAM types $this->forge->addField([ 'TestTechID' => ['type' => 'INT', 'auto_increment' => true, 'unsigned' => true], - 'SiteID' => ['type' => 'INT', 'null' => false], 'TestSiteID' => ['type' => 'INT', 'null' => false], 'DisciplineID' => ['type' => 'int', 'null' => true], 'DepartmentID' => ['type' => 'int', 'null' => true], - 'WorkstationID' => ['type' => 'INT', 'null' => true], - 'EquipmentID' => ['type' => 'INT', 'null' => true], 'ResultType' => ['type' => 'varchar', 'constraint'=> 20, 'null' => true], 'RefType' => ['type' => 'varchar', 'constraint'=> 10, 'null' => true], 'VSet' => ['type' => 'int', 'null' => true], - 'SpcType' => ['type' => 'varchar', 'constraint'=> 10, 'null' => true], - 'SpcDesc' => ['type' => 'varchar', 'constraint'=> 100, 'null' => true], 'ReqQty' => ['type' => 'DECIMAL', 'constraint'=> '10,2', 'null' => true], 'ReqQtyUnit' => ['type' => 'varchar', 'constraint'=> 20, 'null' => true], 'Unit1' => ['type' => 'varchar', 'constraint'=> 20, 'null' => true], @@ -61,12 +56,11 @@ class CreateTestsTable extends Migration { // testdefcal - Calculation definition for CALC type $this->forge->addField([ 'TestCalID' => ['type' => 'INT', 'auto_increment' => true, 'unsigned' => true], - 'SiteID' => ['type' => 'INT', 'null' => false], 'TestSiteID' => ['type' => 'INT', 'null' => false], 'DisciplineID' => ['type' => 'INT', 'null' => true], 'DepartmentID' => ['type' => 'INT', 'null' => true], - 'FormulaInput' => ['type' => 'varchar', 'constraint'=> 255, 'null' => true], - 'FormulaCode' => ['type' => 'text', 'null' => true], + 'FormulaInput' => ['type' => 'text', 'null' => true], + 'FormulaCode' => ['type' => 'varchar', 'constraint'=> 255, 'null' => true], 'RefType' => ['type' => 'varchar', 'constraint'=> 10, 'null' => true, 'default' => 'NMRC'], 'Unit1' => ['type' => 'varchar', 'constraint'=> 20, 'null' => true], 'Factor' => ['type' => 'DECIMAL', 'constraint'=> '10,4', 'null' => true], @@ -83,7 +77,6 @@ class CreateTestsTable extends Migration { // testdefgrp - Group definition for GROUP type $this->forge->addField([ 'TestGrpID' => ['type' => 'INT', 'auto_increment' => true, 'unsigned' => true], - 'SiteID' => ['type' => 'INT', 'null' => false], 'TestSiteID' => ['type' => 'INT', 'null' => false], 'Member' => ['type' => 'INT', 'null' => true], 'CreateDate' => ['type' => 'Datetime', 'null' => true], diff --git a/app/Models/Test/TestDefCalModel.php b/app/Models/Test/TestDefCalModel.php index 219c3ab..492ad34 100644 --- a/app/Models/Test/TestDefCalModel.php +++ b/app/Models/Test/TestDefCalModel.php @@ -8,8 +8,7 @@ class TestDefCalModel extends BaseModel { protected $table = 'testdefcal'; protected $primaryKey = 'TestCalID'; protected $allowedFields = [ - 'SiteID', - 'TestSiteID', + 'TestSiteID', 'DisciplineID', 'DepartmentID', 'FormulaInput', @@ -23,11 +22,57 @@ class TestDefCalModel extends BaseModel { 'CreateDate', 'EndDate' ]; - + protected $useTimestamps = true; protected $createdField = 'CreateDate'; protected $updatedField = ''; protected $useSoftDeletes = true; protected $deletedField = "EndDate"; -} \ No newline at end of file + /** + * Get calculation details for a test + */ + public function getCalcDetails($testSiteID) { + $db = \Config\Database::connect(); + + return $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(); + } + + /** + * Get calculated tests by discipline + */ + public function getCalcsByDiscipline($disciplineID, $siteID = null) { + $builder = $this->select('testdefcal.*, testdefsite.TestSiteCode, testdefsite.TestSiteName') + ->join('testdefsite', 'testdefsite.TestSiteID=testdefcal.TestSiteID', 'left') + ->where('testdefcal.DisciplineID', $disciplineID) + ->where('testdefcal.EndDate IS NULL'); + + if ($siteID) { + $builder->where('testdefsite.SiteID', $siteID); + } + + return $builder->findAll(); + } + + /** + * Get calculated tests by department + */ + public function getCalcsByDepartment($departmentID, $siteID = null) { + $builder = $this->select('testdefcal.*, testdefsite.TestSiteCode, testdefsite.TestSiteName') + ->join('testdefsite', 'testdefsite.TestSiteID=testdefcal.TestSiteID', 'left') + ->where('testdefcal.DepartmentID', $departmentID) + ->where('testdefcal.EndDate IS NULL'); + + if ($siteID) { + $builder->where('testdefsite.SiteID', $siteID); + } + + return $builder->findAll(); + } +} diff --git a/app/Models/Test/TestDefGrpModel.php b/app/Models/Test/TestDefGrpModel.php index 76b926d..dcd6d0a 100644 --- a/app/Models/Test/TestDefGrpModel.php +++ b/app/Models/Test/TestDefGrpModel.php @@ -7,12 +7,43 @@ use App\Models\BaseModel; class TestDefGrpModel extends BaseModel { protected $table = 'testdefgrp'; protected $primaryKey = 'TestGrpID'; - protected $allowedFields = ['SiteID', 'TestSiteID', 'Member', 'CreateDate', 'EndDate']; - + protected $allowedFields = [ + 'TestSiteID', + 'Member', + 'CreateDate', + 'EndDate' + ]; + protected $useTimestamps = true; protected $createdField = 'CreateDate'; protected $updatedField = ''; protected $useSoftDeletes = true; protected $deletedField = "EndDate"; -} \ No newline at end of file + /** + * Get group members for a test group + */ + public function getGroupMembers($testSiteID) { + $db = \Config\Database::connect(); + + return $db->table('testdefgrp') + ->select('testdefgrp.*, t.TestSiteCode, t.TestSiteName, t.TestType, vs.VValue as MemberTypeCode') + ->join('testdefsite t', 't.TestSiteID=testdefgrp.Member', 'left') + ->join('valueset vs', 'vs.VID=t.TestType', 'left') + ->where('testdefgrp.TestSiteID', $testSiteID) + ->where('testdefgrp.EndDate IS NULL') + ->orderBy('testdefgrp.TestGrpID', 'ASC') + ->get()->getResultArray(); + } + + /** + * Get all groups that contain a specific test + */ + public function getGroupsContainingTest($memberTestSiteID) { + return $this->select('testdefgrp.*, t.TestSiteCode, t.TestSiteName') + ->join('testdefsite t', 't.TestSiteID=testdefgrp.TestSiteID', 'left') + ->where('testdefgrp.Member', $memberTestSiteID) + ->where('testdefgrp.EndDate IS NULL') + ->findAll(); + } +} diff --git a/app/Models/Test/TestDefTechModel.php b/app/Models/Test/TestDefTechModel.php index 876d0f8..069fc3a 100644 --- a/app/Models/Test/TestDefTechModel.php +++ b/app/Models/Test/TestDefTechModel.php @@ -8,17 +8,12 @@ class TestDefTechModel extends BaseModel { protected $table = 'testdeftech'; protected $primaryKey = 'TestTechID'; protected $allowedFields = [ - 'SiteID', - 'TestSiteID', + 'TestSiteID', 'DisciplineID', 'DepartmentID', - 'WorkstationID', - 'EquipmentID', 'ResultType', 'RefType', 'VSet', - 'SpcType', - 'SpcDesc', 'ReqQty', 'ReqQtyUnit', 'Unit1', @@ -31,11 +26,57 @@ class TestDefTechModel extends BaseModel { 'CreateDate', 'EndDate' ]; - + protected $useTimestamps = true; protected $createdField = 'CreateDate'; protected $updatedField = ''; protected $useSoftDeletes = true; protected $deletedField = "EndDate"; -} \ No newline at end of file + /** + * Get technical details for a test + */ + public function getTechDetails($testSiteID) { + $db = \Config\Database::connect(); + + return $db->table('testdeftech') + ->select('testdeftech.*, d.DisciplineName, dept.DepartmentName') + ->join('discipline d', 'd.DisciplineID=testdeftech.DisciplineID', 'left') + ->join('department dept', 'dept.DepartmentID=testdeftech.DepartmentID', 'left') + ->where('testdeftech.TestSiteID', $testSiteID) + ->where('testdeftech.EndDate IS NULL') + ->get()->getResultArray(); + } + + /** + * Get tests by discipline + */ + public function getTestsByDiscipline($disciplineID, $siteID = null) { + $builder = $this->select('testdeftech.*, testdefsite.TestSiteCode, testdefsite.TestSiteName') + ->join('testdefsite', 'testdefsite.TestSiteID=testdeftech.TestSiteID', 'left') + ->where('testdeftech.DisciplineID', $disciplineID) + ->where('testdeftech.EndDate IS NULL'); + + if ($siteID) { + $builder->where('testdefsite.SiteID', $siteID); + } + + return $builder->findAll(); + } + + /** + * Get tests by department + */ + public function getTestsByDepartment($departmentID, $siteID = null) { + $builder = $this->select('testdeftech.*, testdefsite.TestSiteCode, testdefsite.TestSiteName') + ->join('testdefsite', 'testdefsite.TestSiteID=testdeftech.TestSiteID', 'left') + ->where('testdeftech.DepartmentID', $departmentID) + ->where('testdeftech.EndDate IS NULL'); + + if ($siteID) { + $builder->where('testdefsite.SiteID', $siteID); + } + + return $builder->findAll(); + } +} diff --git a/app/Models/Test/TestMapModel.php b/app/Models/Test/TestMapModel.php index 9a02c1e..b1c66a2 100644 --- a/app/Models/Test/TestMapModel.php +++ b/app/Models/Test/TestMapModel.php @@ -30,4 +30,67 @@ class TestMapModel extends BaseModel { protected $useSoftDeletes = true; protected $deletedField = "EndDate"; -} \ No newline at end of file + /** + * Get test mappings by test site + */ + public function getMappingsByTestSite($testSiteID) { + return $this->where('TestSiteID', $testSiteID) + ->where('EndDate IS NULL') + ->findAll(); + } + + /** + * Get test mappings by client (equipment/workstation) + */ + public function getMappingsByClient($clientType, $clientID) { + return $this->where('ClientType', $clientType) + ->where('ClientID', $clientID) + ->where('EndDate IS NULL') + ->findAll(); + } + + /** + * Get test mappings by host (site/HIS) + */ + public function getMappingsByHost($hostType, $hostID) { + return $this->where('HostType', $hostType) + ->where('HostID', $hostID) + ->where('EndDate IS NULL') + ->findAll(); + } + + /** + * Get test mapping by client test code and container + */ + public function getMappingByClientCode($clientTestCode, $conDefID = null) { + $builder = $this->where('ClientTestCode', $clientTestCode) + ->where('EndDate IS NULL'); + + if ($conDefID) { + $builder->where('ConDefID', $conDefID); + } + + return $builder->findAll(); + } + + /** + * Get test mapping by host test code + */ + public function getMappingByHostCode($hostTestCode) { + return $this->where('HostTestCode', $hostTestCode) + ->where('EndDate IS NULL') + ->findAll(); + } + + /** + * Check if mapping exists for client and host + */ + public function mappingExists($testSiteID, $clientType, $clientID, $clientTestCode) { + return $this->where('TestSiteID', $testSiteID) + ->where('ClientType', $clientType) + ->where('ClientID', $clientID) + ->where('ClientTestCode', $clientTestCode) + ->where('EndDate IS NULL') + ->countAllResults() > 0; + } +} diff --git a/app/Views/v2/master/tests/calc_dialog.php b/app/Views/v2/master/tests/calc_dialog.php index 5c5d6e5..8fec5fc 100644 --- a/app/Views/v2/master/tests/calc_dialog.php +++ b/app/Views/v2/master/tests/calc_dialog.php @@ -84,7 +84,7 @@ @@ -105,31 +105,28 @@ -