diff --git a/app/Controllers/Api/EntryApiController.php b/app/Controllers/Api/EntryApiController.php index a8d56c5..d17d358 100644 --- a/app/Controllers/Api/EntryApiController.php +++ b/app/Controllers/Api/EntryApiController.php @@ -88,26 +88,102 @@ class EntryApiController extends BaseController try { $controlId = $input['controlId'] ?? 0; - $testId = $input['testId'] ?? 0; - $dates = $input['dates'] ?? ''; - $resvalues = $input['resvalue'] ?? []; + $yearMonth = $input['yearMonth'] ?? ''; + $operation = $input['operation'] ?? 'replace'; + $tests = $input['tests'] ?? []; + $results = []; + $statistics = []; + $validations = []; - foreach ($resvalues as $day => $value) { - if (!empty($value)) { - $resultData = [ - 'control_ref_id' => $controlId, - 'test_ref_id' => $testId, - 'resdate' => $dates . '-' . str_pad($day, 2, '0', STR_PAD_LEFT), - 'resvalue' => $value, - 'rescomment' => '', - ]; - $this->resultModel->saveResult($resultData); + foreach ($tests as $testData) { + $testId = $testData['testId'] ?? 0; + $resvalues = $testData['resvalue'] ?? []; + + $controlTest = $this->controlTestModel->getByControlAndTest($controlId, $testId); + $mean = $controlTest['mean'] ?? 0; + $sd = $controlTest['sd'] ?? 0; + $sdLimit = $sd > 0 ? $sd * 2 : 0; + + $testValues = []; + $validCount = 0; + $validSum = 0; + $validSqSum = 0; + + foreach ($resvalues as $day => $value) { + if (!empty($value)) { + $resultData = [ + 'control_ref_id' => $controlId, + 'test_ref_id' => $testId, + 'resdate' => $yearMonth . '-' . str_pad($day, 2, '0', STR_PAD_LEFT), + 'resvalue' => $value, + 'rescomment' => '', + ]; + + if ($operation === 'replace') { + $this->resultModel->saveResult($resultData); + } else { + $existing = $this->resultModel->checkExisting($controlId, $testId, $resultData['resdate']); + if (!$existing) { + $this->resultModel->saveResult($resultData); + } + } + + $numValue = (float) $value; + $testValues[] = $numValue; + $validCount++; + $validSum += $numValue; + $validSqSum += $numValue * $numValue; + + $withinLimit = true; + if ($sdLimit > 0) { + $withinLimit = abs($numValue - $mean) <= $sdLimit; + } + + if (!$withinLimit) { + $validations[] = [ + 'testId' => $testId, + 'day' => $day, + 'value' => $value, + 'mean' => $mean, + 'sd' => $sd, + 'status' => 'out_of_range' + ]; + } + } } + + if ($validCount > 0) { + $calcMean = $validSum / $validCount; + $calcSd = 0; + if ($validCount > 1) { + $variance = ($validSqSum - ($validSum * $validSum) / $validCount) / ($validCount - 1); + $calcSd = $variance > 0 ? sqrt($variance) : 0; + } + $cv = $calcMean > 0 ? ($calcSd / $calcMean) * 100 : 0; + + $statistics[] = [ + 'testId' => $testId, + 'n' => $validCount, + 'mean' => round($calcMean, 3), + 'sd' => round($calcSd, 3), + 'cv' => round($cv, 2) + ]; + } + + $results[] = [ + 'testId' => $testId, + 'saved' => count($resvalues) + ]; } return $this->respond([ 'status' => 'success', - 'message' => 'save success' + 'message' => 'save success', + 'data' => [ + 'results' => $results, + 'statistics' => $statistics, + 'validations' => $validations + ] ]); } catch (\Exception $e) { return $this->failServerError('Something went wrong: ' . $e->getMessage()); diff --git a/app/Models/ResultModel.php b/app/Models/ResultModel.php index 9cc6a7e..9bb70a9 100644 --- a/app/Models/ResultModel.php +++ b/app/Models/ResultModel.php @@ -58,4 +58,15 @@ class ResultModel extends BaseModel return $builder->insert($data); } } + + public function checkExisting($controlId, $testId, $resdate) + { + $builder = $this->db->table('results'); + return $builder->select('result_id') + ->where('control_ref_id', $controlId) + ->where('test_ref_id', $testId) + ->where('resdate', $resdate) + ->get() + ->getRowArray(); + } } diff --git a/app/Views/entry/monthly.php b/app/Views/entry/monthly.php index 03f7e0f..c42cafa 100644 --- a/app/Views/entry/monthly.php +++ b/app/Views/entry/monthly.php @@ -133,8 +133,15 @@ -
-