- Rename all controllers from X.php to XController.php format - Add new RefTxtModel for text-based reference ranges - Rename group_dialog.php to grp_dialog.php and remove title_dialog.php - Add comprehensive test suite for v2/master/TestDef module - Update Routes.php to reflect controller renames - Remove obsolete data files (clqms_v2.sql, lab.dbml)
742 lines
28 KiB
PHP
742 lines
28 KiB
PHP
<?php
|
|
namespace App\Controllers;
|
|
|
|
use CodeIgniter\API\ResponseTrait;
|
|
use App\Controllers\BaseController;
|
|
|
|
class TestsController extends BaseController
|
|
{
|
|
use ResponseTrait;
|
|
|
|
protected $db;
|
|
protected $rules;
|
|
protected $model;
|
|
protected $modelCal;
|
|
protected $modelTech;
|
|
protected $modelGrp;
|
|
protected $modelMap;
|
|
protected $modelValueSet;
|
|
protected $modelRefNum;
|
|
protected $modelRefTxt;
|
|
|
|
// Valueset ID constants
|
|
const VALUESET_REF_TYPE = 44; // testdeftech.RefType
|
|
const VALUESET_RANGE_TYPE = 45; // refnum.RangeType
|
|
const VALUESET_NUM_REF_TYPE = 46; // refnum.NumRefType
|
|
const VALUESET_TXT_REF_TYPE = 47; // reftxt.TxtRefType
|
|
const VALUESET_SEX = 3; // Sex values
|
|
const VALUESET_MATH_SIGN = 41; // LowSign, HighSign
|
|
|
|
public function __construct()
|
|
{
|
|
$this->db = \Config\Database::connect();
|
|
$this->model = new \App\Models\Test\TestDefSiteModel;
|
|
$this->modelCal = new \App\Models\Test\TestDefCalModel;
|
|
$this->modelTech = new \App\Models\Test\TestDefTechModel;
|
|
$this->modelGrp = new \App\Models\Test\TestDefGrpModel;
|
|
$this->modelMap = new \App\Models\Test\TestMapModel;
|
|
$this->modelValueSet = new \App\Models\ValueSet\ValueSetModel;
|
|
$this->modelRefNum = new \App\Models\RefRange\RefNumModel;
|
|
$this->modelRefTxt = new \App\Models\RefRange\RefTxtModel;
|
|
|
|
// Validation rules for main test definition
|
|
$this->rules = [
|
|
'TestSiteCode' => 'required|min_length[3]|max_length[6]',
|
|
'TestSiteName' => 'required',
|
|
'TestType' => 'required',
|
|
'SiteID' => 'required'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* GET /v1/tests
|
|
* GET /v1/tests/site
|
|
* List all tests with optional filtering
|
|
*/
|
|
public function index()
|
|
{
|
|
$siteId = $this->request->getGet('SiteID');
|
|
$testType = $this->request->getGet('TestType');
|
|
$visibleScr = $this->request->getGet('VisibleScr');
|
|
$visibleRpt = $this->request->getGet('VisibleRpt');
|
|
$keyword = $this->request->getGet('TestSiteName');
|
|
|
|
$builder = $this->db->table('testdefsite')
|
|
->select("testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
|
|
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.VisibleScr, testdefsite.VisibleRpt,
|
|
testdefsite.CountStat, testdefsite.StartDate, testdefsite.EndDate,
|
|
valueset.VValue as TypeCode, valueset.VDesc as TypeName")
|
|
->join("valueset", "valueset.VID=testdefsite.TestType", "left")
|
|
->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.VisibleScr', $visibleScr);
|
|
}
|
|
|
|
if ($visibleRpt !== null) {
|
|
$builder->where('testdefsite.VisibleRpt', $visibleRpt);
|
|
}
|
|
|
|
if ($keyword) {
|
|
$builder->like('testdefsite.TestSiteName', $keyword);
|
|
}
|
|
|
|
$rows = $builder->orderBy('testdefsite.SeqScr', 'ASC')->get()->getResultArray();
|
|
|
|
if (empty($rows)) {
|
|
return $this->respond(['status' => 'success', 'message' => "No data.", 'data' => []], 200);
|
|
}
|
|
return $this->respond(['status' => 'success', 'message' => "Data fetched successfully", 'data' => $rows], 200);
|
|
}
|
|
|
|
/**
|
|
* 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('TestSiteID is required');
|
|
|
|
$row = $this->model->select("testdefsite.*, valueset.VValue as TypeCode, valueset.VDesc as TypeName")
|
|
->join("valueset", "valueset.VID=testdefsite.TestType", "left")
|
|
->where("testdefsite.TestSiteID", $id)
|
|
->find($id);
|
|
|
|
if (!$row) {
|
|
return $this->respond(['status' => 'success', 'message' => "No data.", 'data' => null], 200);
|
|
}
|
|
|
|
// Load related details based on TestType
|
|
$typeCode = $row['TypeCode'] ?? '';
|
|
|
|
if ($typeCode === 'CALC') {
|
|
// Load calculation details
|
|
$row['testdefcal'] = $this->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', $id)
|
|
->where('testdefcal.EndDate IS NULL')
|
|
->get()->getResultArray();
|
|
|
|
// Load test mappings
|
|
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
|
|
|
|
} elseif ($typeCode === 'GROUP') {
|
|
// Load group members with test details
|
|
$row['testdefgrp'] = $this->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', $id)
|
|
->where('testdefgrp.EndDate IS NULL')
|
|
->orderBy('testdefgrp.TestGrpID', 'ASC')
|
|
->get()->getResultArray();
|
|
|
|
// Load test mappings
|
|
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
|
|
|
|
} elseif ($typeCode === 'TITLE') {
|
|
// Load test mappings only for TITLE type
|
|
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
|
|
|
|
} else {
|
|
// TEST or PARAM - load technical details
|
|
$row['testdeftech'] = $this->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', $id)
|
|
->where('testdeftech.EndDate IS NULL')
|
|
->get()->getResultArray();
|
|
|
|
// Load test mappings
|
|
$row['testmap'] = $this->modelMap->where('TestSiteID', $id)->where('EndDate IS NULL')->findAll();
|
|
|
|
// Load refnum/reftxt based on RefType
|
|
if (!empty($row['testdeftech'])) {
|
|
$techData = $row['testdeftech'][0];
|
|
$refType = (int) $techData['RefType'];
|
|
|
|
// Load refnum for NMRC type (RefType = 1)
|
|
if ($refType === 1) {
|
|
$refnumData = $this->modelRefNum
|
|
->where('TestSiteID', $id)
|
|
->where('EndDate IS NULL')
|
|
->orderBy('Display', 'ASC')
|
|
->findAll();
|
|
|
|
// Add VValue for display
|
|
$row['refnum'] = array_map(function ($r) {
|
|
return [
|
|
'RefNumID' => $r['RefNumID'],
|
|
'NumRefType' => (int) $r['NumRefType'],
|
|
'NumRefTypeVValue' => $this->getVValue(46, $r['NumRefType']),
|
|
'RangeType' => (int) $r['RangeType'],
|
|
'RangeTypeVValue' => $this->getVValue(45, $r['RangeType']),
|
|
'Sex' => (int) $r['Sex'],
|
|
'SexVValue' => $this->getVValue(3, $r['Sex']),
|
|
'AgeStart' => (int) $r['AgeStart'],
|
|
'AgeEnd' => (int) $r['AgeEnd'],
|
|
'LowSign' => $r['LowSign'] !== null ? (int) $r['LowSign'] : null,
|
|
'LowSignVValue' => $this->getVValue(41, $r['LowSign']),
|
|
'Low' => $r['Low'] !== null ? (int) $r['Low'] : null,
|
|
'HighSign' => $r['HighSign'] !== null ? (int) $r['HighSign'] : null,
|
|
'HighSignVValue' => $this->getVValue(41, $r['HighSign']),
|
|
'High' => $r['High'] !== null ? (int) $r['High'] : null,
|
|
'Flag' => $r['Flag']
|
|
];
|
|
}, $refnumData ?? []);
|
|
|
|
$row['numRefTypeOptions'] = $this->getValuesetOptions(46);
|
|
$row['rangeTypeOptions'] = $this->getValuesetOptions(45);
|
|
}
|
|
|
|
// Load reftxt for TEXT type (RefType = 2)
|
|
if ($refType === 2) {
|
|
$reftxtData = $this->modelRefTxt
|
|
->where('TestSiteID', $id)
|
|
->where('EndDate IS NULL')
|
|
->orderBy('RefTxtID', 'ASC')
|
|
->findAll();
|
|
|
|
$row['reftxt'] = array_map(function ($r) {
|
|
return [
|
|
'RefTxtID' => $r['RefTxtID'],
|
|
'TxtRefType' => (int) $r['TxtRefType'],
|
|
'TxtRefTypeVValue' => $this->getVValue(47, $r['TxtRefType']),
|
|
'Sex' => (int) $r['Sex'],
|
|
'SexVValue' => $this->getVValue(3, $r['Sex']),
|
|
'AgeStart' => (int) $r['AgeStart'],
|
|
'AgeEnd' => (int) $r['AgeEnd'],
|
|
'RefTxt' => $r['RefTxt'],
|
|
'Flag' => $r['Flag']
|
|
];
|
|
}, $reftxtData ?? []);
|
|
|
|
$row['txtRefTypeOptions'] = $this->getValuesetOptions(47);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Include valueset options for dropdowns
|
|
$row['refTypeOptions'] = $this->getValuesetOptions(self::VALUESET_REF_TYPE);
|
|
$row['sexOptions'] = $this->getValuesetOptions(self::VALUESET_SEX);
|
|
$row['mathSignOptions'] = $this->getValuesetOptions(self::VALUESET_MATH_SIGN);
|
|
|
|
return $this->respond(['status' => 'success', 'message' => "Data fetched successfully", 'data' => $row], 200);
|
|
}
|
|
|
|
/**
|
|
* POST /v1/tests
|
|
* POST /v1/tests/site
|
|
* Create new test definition
|
|
*/
|
|
public function create()
|
|
{
|
|
$input = $this->request->getJSON(true);
|
|
|
|
if (!$this->validateData($input, $this->rules)) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
$this->db->transStart();
|
|
|
|
try {
|
|
// 1. Insert into Main Table (testdefsite)
|
|
$testSiteData = [
|
|
'SiteID' => $input['SiteID'],
|
|
'TestSiteCode' => $input['TestSiteCode'],
|
|
'TestSiteName' => $input['TestSiteName'],
|
|
'TestType' => $input['TestType'],
|
|
'Description' => $input['Description'] ?? null,
|
|
'SeqScr' => $input['SeqScr'] ?? 0,
|
|
'SeqRpt' => $input['SeqRpt'] ?? 0,
|
|
'IndentLeft' => $input['IndentLeft'] ?? 0,
|
|
'FontStyle' => $input['FontStyle'] ?? null,
|
|
'VisibleScr' => $input['VisibleScr'] ?? 1,
|
|
'VisibleRpt' => $input['VisibleRpt'] ?? 1,
|
|
'CountStat' => $input['CountStat'] ?? 1,
|
|
'StartDate' => $input['StartDate'] ?? date('Y-m-d H:i:s')
|
|
];
|
|
|
|
$id = $this->model->insert($testSiteData);
|
|
if (!$id) {
|
|
throw new \Exception("Failed to insert main test definition");
|
|
}
|
|
|
|
// 2. Handle Details based on TestType
|
|
$this->handleDetails($id, $input, 'insert');
|
|
|
|
$this->db->transComplete();
|
|
|
|
if ($this->db->transStatus() === false) {
|
|
return $this->failServerError('Transaction failed');
|
|
}
|
|
|
|
return $this->respondCreated([
|
|
'status' => 'created',
|
|
'message' => "Test created successfully",
|
|
'data' => ['TestSiteId' => $id]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
$this->db->transRollback();
|
|
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PUT/PATCH /v1/tests/{id}
|
|
* PUT/PATCH /v1/tests/site/{id}
|
|
* Update existing test definition
|
|
*/
|
|
public function update($id = null)
|
|
{
|
|
$input = $this->request->getJSON(true);
|
|
|
|
// Determine ID
|
|
if (!$id && isset($input["TestSiteID"])) {
|
|
$id = $input["TestSiteID"];
|
|
}
|
|
if (!$id) {
|
|
return $this->failValidationErrors('TestSiteID is required.');
|
|
}
|
|
|
|
// Verify record exists
|
|
$existing = $this->model->find($id);
|
|
if (!$existing) {
|
|
return $this->failNotFound('Test not found');
|
|
}
|
|
|
|
$this->db->transStart();
|
|
|
|
try {
|
|
// 1. Update Main Table
|
|
$testSiteData = [];
|
|
$allowedUpdateFields = [
|
|
'TestSiteCode',
|
|
'TestSiteName',
|
|
'TestType',
|
|
'Description',
|
|
'SeqScr',
|
|
'SeqRpt',
|
|
'IndentLeft',
|
|
'FontStyle',
|
|
'VisibleScr',
|
|
'VisibleRpt',
|
|
'CountStat',
|
|
'StartDate'
|
|
];
|
|
|
|
foreach ($allowedUpdateFields as $field) {
|
|
if (isset($input[$field])) {
|
|
$testSiteData[$field] = $input[$field];
|
|
}
|
|
}
|
|
|
|
if (!empty($testSiteData)) {
|
|
$this->model->update($id, $testSiteData);
|
|
}
|
|
|
|
// 2. Handle Details
|
|
$this->handleDetails($id, $input, 'update');
|
|
|
|
$this->db->transComplete();
|
|
|
|
if ($this->db->transStatus() === false) {
|
|
return $this->failServerError('Transaction failed');
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => "Test updated successfully",
|
|
'data' => ['TestSiteId' => $id]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
$this->db->transRollback();
|
|
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DELETE /v1/tests/{id}
|
|
* DELETE /v1/tests/site/{id}
|
|
* Soft delete test by setting EndDate
|
|
*/
|
|
public function delete($id = null)
|
|
{
|
|
$input = $this->request->getJSON(true);
|
|
|
|
// Determine ID
|
|
if (!$id && isset($input["TestSiteID"])) {
|
|
$id = $input["TestSiteID"];
|
|
}
|
|
if (!$id) {
|
|
return $this->failValidationErrors('TestSiteID is required.');
|
|
}
|
|
|
|
// Verify record exists
|
|
$existing = $this->model->find($id);
|
|
if (!$existing) {
|
|
return $this->failNotFound('Test not found');
|
|
}
|
|
|
|
// Check if already disabled
|
|
if (!empty($existing['EndDate'])) {
|
|
return $this->failValidationErrors('Test is already disabled');
|
|
}
|
|
|
|
$this->db->transStart();
|
|
|
|
try {
|
|
$now = date('Y-m-d H:i:s');
|
|
|
|
// 1. Soft delete main record
|
|
$this->model->update($id, ['EndDate' => $now]);
|
|
|
|
// 2. Get TestType to handle related records
|
|
$testType = $existing['TestType'];
|
|
$vs = $this->modelValueSet->find($testType);
|
|
$typeCode = $vs['VValue'] ?? '';
|
|
|
|
// 3. Soft delete related records based on TestType
|
|
if ($typeCode === 'CALC') {
|
|
$this->db->table('testdefcal')
|
|
->where('TestSiteID', $id)
|
|
->update(['EndDate' => $now]);
|
|
} elseif ($typeCode === 'GROUP') {
|
|
$this->db->table('testdefgrp')
|
|
->where('TestSiteID', $id)
|
|
->update(['EndDate' => $now]);
|
|
} elseif (in_array($typeCode, ['TEST', 'PARAM'])) {
|
|
$this->db->table('testdeftech')
|
|
->where('TestSiteID', $id)
|
|
->update(['EndDate' => $now]);
|
|
|
|
// Soft delete refnum and reftxt records
|
|
$this->modelRefNum->where('TestSiteID', $id)->set('EndDate', $now)->update();
|
|
$this->modelRefTxt->where('TestSiteID', $id)->set('EndDate', $now)->update();
|
|
}
|
|
|
|
// 4. Soft delete test mappings
|
|
$this->db->table('testmap')
|
|
->where('TestSiteID', $id)
|
|
->update(['EndDate' => $now]);
|
|
|
|
$this->db->transComplete();
|
|
|
|
if ($this->db->transStatus() === false) {
|
|
return $this->failServerError('Transaction failed');
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => "Test disabled successfully",
|
|
'data' => ['TestSiteId' => $id, 'EndDate' => $now]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
$this->db->transRollback();
|
|
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper to get valueset options
|
|
*/
|
|
private function getValuesetOptions($vsetID)
|
|
{
|
|
return $this->db->table('valueset')
|
|
->select('VID as vid, VValue as vvalue, VDesc as vdesc')
|
|
->where('VSetID', $vsetID)
|
|
->orderBy('VOrder', 'ASC')
|
|
->get()->getResultArray();
|
|
}
|
|
|
|
/**
|
|
* Helper to get VValue from VID for display
|
|
*/
|
|
private function getVValue($vsetID, $vid)
|
|
{
|
|
if ($vid === null || $vid === '')
|
|
return null;
|
|
$row = $this->db->table('valueset')
|
|
->select('VValue as vvalue')
|
|
->where('VSetID', $vsetID)
|
|
->where('VID', (int) $vid)
|
|
->get()->getRowArray();
|
|
return $row ? $row['vvalue'] : null;
|
|
}
|
|
|
|
/**
|
|
* Helper to handle inserting/updating sub-tables based on TestType
|
|
*/
|
|
private function handleDetails($testSiteID, $input, $action)
|
|
{
|
|
$testTypeID = $input['TestType'] ?? null;
|
|
|
|
// If update and TestType not in payload, fetch from DB
|
|
if (!$testTypeID && $action === 'update') {
|
|
$existing = $this->model->find($testSiteID);
|
|
$testTypeID = $existing['TestType'] ?? null;
|
|
}
|
|
|
|
if (!$testTypeID)
|
|
return;
|
|
|
|
// Get Type Code (TEST, PARAM, CALC, GROUP, TITLE)
|
|
$vs = $this->modelValueSet->find($testTypeID);
|
|
$typeCode = $vs['VValue'] ?? '';
|
|
|
|
// Get details data from input
|
|
$details = $input['details'] ?? $input;
|
|
$details['TestSiteID'] = $testSiteID;
|
|
$details['SiteID'] = $input['SiteID'] ?? 1;
|
|
|
|
switch ($typeCode) {
|
|
case 'CALC':
|
|
$this->saveCalcDetails($testSiteID, $details, $action);
|
|
break;
|
|
|
|
case 'GROUP':
|
|
$this->saveGroupDetails($testSiteID, $details, $input, $action);
|
|
break;
|
|
|
|
case 'TITLE':
|
|
// TITLE type only has testdefsite, no additional details needed
|
|
// But we should save test mappings if provided
|
|
if (isset($input['testmap']) && is_array($input['testmap'])) {
|
|
$this->saveTestMap($testSiteID, $input['testmap'], $action);
|
|
}
|
|
break;
|
|
|
|
case 'TEST':
|
|
case 'PARAM':
|
|
default:
|
|
$this->saveTechDetails($testSiteID, $details, $action, $typeCode);
|
|
|
|
// Save refnum/reftxt for TEST/PARAM types
|
|
if (in_array($typeCode, ['TEST', 'PARAM']) && isset($details['RefType'])) {
|
|
$refType = (int) $details['RefType'];
|
|
|
|
// Save refnum for NMRC type (RefType = 1)
|
|
if ($refType === 1 && isset($input['refnum']) && is_array($input['refnum'])) {
|
|
$this->saveRefNumRanges($testSiteID, $input['refnum'], $action, $input['SiteID'] ?? 1);
|
|
}
|
|
|
|
// Save reftxt for TEXT type (RefType = 2)
|
|
if ($refType === 2 && isset($input['reftxt']) && is_array($input['reftxt'])) {
|
|
$this->saveRefTxtRanges($testSiteID, $input['reftxt'], $action, $input['SiteID'] ?? 1);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Save test mappings for TEST and CALC types as well
|
|
if (in_array($typeCode, ['TEST', 'CALC']) && isset($input['testmap']) && is_array($input['testmap'])) {
|
|
$this->saveTestMap($testSiteID, $input['testmap'], $action);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save technical details for TEST and PARAM types
|
|
*/
|
|
private function saveTechDetails($testSiteID, $data, $action, $typeCode)
|
|
{
|
|
$techData = [
|
|
'TestSiteID' => $testSiteID,
|
|
'DisciplineID' => $data['DisciplineID'] ?? null,
|
|
'DepartmentID' => $data['DepartmentID'] ?? null,
|
|
'ResultType' => $data['ResultType'] ?? null,
|
|
'RefType' => $data['RefType'] ?? null,
|
|
'VSet' => $data['VSet'] ?? null,
|
|
'ReqQty' => $data['ReqQty'] ?? null,
|
|
'ReqQtyUnit' => $data['ReqQtyUnit'] ?? null,
|
|
'Unit1' => $data['Unit1'] ?? null,
|
|
'Factor' => $data['Factor'] ?? null,
|
|
'Unit2' => $data['Unit2'] ?? null,
|
|
'Decimal' => $data['Decimal'] ?? 2,
|
|
'CollReq' => $data['CollReq'] ?? null,
|
|
'Method' => $data['Method'] ?? null,
|
|
'ExpectedTAT' => $data['ExpectedTAT'] ?? null
|
|
];
|
|
|
|
if ($action === 'update') {
|
|
$exists = $this->db->table('testdeftech')
|
|
->where('TestSiteID', $testSiteID)
|
|
->where('EndDate IS NULL')
|
|
->get()->getRowArray();
|
|
|
|
if ($exists) {
|
|
$this->modelTech->update($exists['TestTechID'], $techData);
|
|
} else {
|
|
$this->modelTech->insert($techData);
|
|
}
|
|
} else {
|
|
$this->modelTech->insert($techData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save refnum ranges for NMRC type
|
|
*/
|
|
private function saveRefNumRanges($testSiteID, $ranges, $action, $siteID)
|
|
{
|
|
if ($action === 'update') {
|
|
$this->modelRefNum->where('TestSiteID', $testSiteID)
|
|
->set('EndDate', date('Y-m-d H:i:s'))
|
|
->update();
|
|
}
|
|
|
|
foreach ($ranges as $index => $range) {
|
|
$this->modelRefNum->insert([
|
|
'TestSiteID' => $testSiteID,
|
|
'SiteID' => $siteID,
|
|
'NumRefType' => (int) $range['NumRefType'],
|
|
'RangeType' => (int) $range['RangeType'],
|
|
'Sex' => (int) $range['Sex'],
|
|
'AgeStart' => (int) ($range['AgeStart'] ?? 0),
|
|
'AgeEnd' => (int) ($range['AgeEnd'] ?? 150),
|
|
'LowSign' => !empty($range['LowSign']) ? (int) $range['LowSign'] : null,
|
|
'Low' => !empty($range['Low']) ? (int) $range['Low'] : null,
|
|
'HighSign' => !empty($range['HighSign']) ? (int) $range['HighSign'] : null,
|
|
'High' => !empty($range['High']) ? (int) $range['High'] : null,
|
|
'Flag' => $range['Flag'] ?? null,
|
|
'Display' => $index,
|
|
'CreateDate' => date('Y-m-d H:i:s')
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save reftxt ranges for TEXT type
|
|
*/
|
|
private function saveRefTxtRanges($testSiteID, $ranges, $action, $siteID)
|
|
{
|
|
if ($action === 'update') {
|
|
$this->modelRefTxt->where('TestSiteID', $testSiteID)
|
|
->set('EndDate', date('Y-m-d H:i:s'))
|
|
->update();
|
|
}
|
|
|
|
foreach ($ranges as $range) {
|
|
$this->modelRefTxt->insert([
|
|
'TestSiteID' => $testSiteID,
|
|
'SiteID' => $siteID,
|
|
'TxtRefType' => (int) $range['TxtRefType'],
|
|
'Sex' => (int) $range['Sex'],
|
|
'AgeStart' => (int) ($range['AgeStart'] ?? 0),
|
|
'AgeEnd' => (int) ($range['AgeEnd'] ?? 150),
|
|
'RefTxt' => $range['RefTxt'] ?? '',
|
|
'Flag' => $range['Flag'] ?? null,
|
|
'CreateDate' => date('Y-m-d H:i:s')
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save calculation details for CALC type
|
|
*/
|
|
private function saveCalcDetails($testSiteID, $data, $action)
|
|
{
|
|
$calcData = [
|
|
'TestSiteID' => $testSiteID,
|
|
'DisciplineID' => $data['DisciplineID'] ?? null,
|
|
'DepartmentID' => $data['DepartmentID'] ?? null,
|
|
'FormulaInput' => $data['FormulaInput'] ?? null,
|
|
'FormulaCode' => $data['FormulaCode'] ?? $data['Formula'] ?? null,
|
|
'RefType' => $data['RefType'] ?? 'NMRC',
|
|
'Unit1' => $data['Unit1'] ?? $data['ResultUnit'] ?? null,
|
|
'Factor' => $data['Factor'] ?? null,
|
|
'Unit2' => $data['Unit2'] ?? null,
|
|
'Decimal' => $data['Decimal'] ?? 2,
|
|
'Method' => $data['Method'] ?? null
|
|
];
|
|
|
|
if ($action === 'update') {
|
|
$exists = $this->db->table('testdefcal')
|
|
->where('TestSiteID', $testSiteID)
|
|
->where('EndDate IS NULL')
|
|
->get()->getRowArray();
|
|
|
|
if ($exists) {
|
|
$this->modelCal->update($exists['TestCalID'], $calcData);
|
|
} else {
|
|
$this->modelCal->insert($calcData);
|
|
}
|
|
} else {
|
|
$this->modelCal->insert($calcData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save group details for GROUP type
|
|
*/
|
|
private function saveGroupDetails($testSiteID, $data, $input, $action)
|
|
{
|
|
if ($action === 'update') {
|
|
// Soft delete existing members
|
|
$this->db->table('testdefgrp')
|
|
->where('TestSiteID', $testSiteID)
|
|
->update(['EndDate' => date('Y-m-d H:i:s')]);
|
|
}
|
|
|
|
// Get members from details or input
|
|
$members = $data['members'] ?? ($input['Members'] ?? []);
|
|
|
|
if (is_array($members)) {
|
|
foreach ($members as $m) {
|
|
$memberID = is_array($m) ? ($m['Member'] ?? ($m['TestSiteID'] ?? null)) : $m;
|
|
if ($memberID) {
|
|
$this->modelGrp->insert([
|
|
'TestSiteID' => $testSiteID,
|
|
'Member' => $memberID
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save test mappings
|
|
*/
|
|
private function saveTestMap($testSiteID, $mappings, $action)
|
|
{
|
|
if ($action === 'update') {
|
|
// Soft delete existing mappings
|
|
$this->db->table('testmap')
|
|
->where('TestSiteID', $testSiteID)
|
|
->update(['EndDate' => date('Y-m-d H:i:s')]);
|
|
}
|
|
|
|
if (is_array($mappings)) {
|
|
foreach ($mappings as $map) {
|
|
$mapData = [
|
|
'TestSiteID' => $testSiteID,
|
|
'HostType' => $map['HostType'] ?? null,
|
|
'HostID' => $map['HostID'] ?? null,
|
|
'HostDataSource' => $map['HostDataSource'] ?? null,
|
|
'HostTestCode' => $map['HostTestCode'] ?? null,
|
|
'HostTestName' => $map['HostTestName'] ?? null,
|
|
'ClientType' => $map['ClientType'] ?? null,
|
|
'ClientID' => $map['ClientID'] ?? null,
|
|
'ClientDataSource' => $map['ClientDataSource'] ?? null,
|
|
'ConDefID' => $map['ConDefID'] ?? null,
|
|
'ClientTestCode' => $map['ClientTestCode'] ?? null,
|
|
'ClientTestName' => $map['ClientTestName'] ?? null
|
|
];
|
|
$this->modelMap->insert($mapData);
|
|
}
|
|
}
|
|
}
|
|
}
|