184 lines
4.5 KiB
PHP
184 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Traits\ResponseTrait;
|
|
use App\Services\CalculatorService;
|
|
use App\Models\Test\TestDefCalModel;
|
|
use CodeIgniter\Controller;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
|
|
class CalculatorController extends Controller
|
|
{
|
|
use ResponseTrait;
|
|
|
|
protected CalculatorService $calculator;
|
|
protected TestDefCalModel $calcModel;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->calculator = new CalculatorService();
|
|
$this->calcModel = new TestDefCalModel();
|
|
}
|
|
|
|
/**
|
|
* POST api/calculate
|
|
* Calculate a formula with provided variables
|
|
*
|
|
* Request: {
|
|
* "formula": "{result} * {factor} + {gender}",
|
|
* "variables": {
|
|
* "result": 100,
|
|
* "factor": 0.5,
|
|
* "gender": "female"
|
|
* }
|
|
* }
|
|
*/
|
|
public function calculate(): ResponseInterface
|
|
{
|
|
try {
|
|
$data = $this->request->getJSON(true);
|
|
|
|
if (empty($data['formula'])) {
|
|
return $this->respond([
|
|
'status' => 'failed',
|
|
'message' => 'Formula is required'
|
|
], 400);
|
|
}
|
|
|
|
$result = $this->calculator->calculate(
|
|
$data['formula'],
|
|
$data['variables'] ?? []
|
|
);
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'data' => [
|
|
'result' => $result,
|
|
'formula' => $data['formula'],
|
|
'variables' => $data['variables'] ?? []
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return $this->respond([
|
|
'status' => 'failed',
|
|
'message' => $e->getMessage()
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* POST api/calculate/validate
|
|
* Validate a formula syntax
|
|
*
|
|
* Request: {
|
|
* "formula": "{result} * 2 + 5"
|
|
* }
|
|
*/
|
|
public function validateFormula(): ResponseInterface
|
|
{
|
|
try {
|
|
$data = $this->request->getJSON(true);
|
|
|
|
if (empty($data['formula'])) {
|
|
return $this->respond([
|
|
'status' => 'failed',
|
|
'message' => 'Formula is required'
|
|
], 400);
|
|
}
|
|
|
|
$validation = $this->calculator->validate($data['formula']);
|
|
|
|
return $this->respond([
|
|
'status' => $validation['valid'] ? 'success' : 'failed',
|
|
'data' => [
|
|
'valid' => $validation['valid'],
|
|
'error' => $validation['error'],
|
|
'variables' => $this->calculator->extractVariables($data['formula'])
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return $this->respond([
|
|
'status' => 'failed',
|
|
'message' => $e->getMessage()
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* POST api/calculate/test-site/{testSiteID}
|
|
* Calculate using TestDefCal definition
|
|
*
|
|
* Request: {
|
|
* "result": 85,
|
|
* "gender": "female",
|
|
* "age": 30
|
|
* }
|
|
*/
|
|
public function calculateByTestSite($testSiteID): ResponseInterface
|
|
{
|
|
try {
|
|
$calcDef = $this->calcModel->existsByTestSiteID($testSiteID);
|
|
|
|
if (!$calcDef) {
|
|
return $this->respond([
|
|
'status' => 'failed',
|
|
'message' => 'No calculation defined for this test site'
|
|
], 404);
|
|
}
|
|
|
|
$testValues = $this->request->getJSON(true);
|
|
$result = $this->calculator->calculateFromDefinition($calcDef, $testValues);
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'data' => [
|
|
'result' => $result,
|
|
'testSiteID' => $testSiteID,
|
|
'formula' => $calcDef['FormulaCode'],
|
|
'variables' => $testValues
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return $this->respond([
|
|
'status' => 'failed',
|
|
'message' => $e->getMessage()
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* POST api/calc/{codeOrName}
|
|
* Evaluate a configured calculation by its code or name and return only the result map.
|
|
*/
|
|
public function calculateByCodeOrName($codeOrName): ResponseInterface
|
|
{
|
|
try {
|
|
$calcDef = $this->calcModel->findActiveByCodeOrName($codeOrName);
|
|
|
|
if (!$calcDef || empty($calcDef['FormulaCode'])) {
|
|
return $this->response->setJSON(new \stdClass());
|
|
}
|
|
|
|
$input = $this->request->getJSON(true);
|
|
$variables = is_array($input) ? $input : [];
|
|
|
|
$result = $this->calculator->calculate($calcDef['FormulaCode'], $variables);
|
|
|
|
if ($result === null) {
|
|
return $this->response->setJSON(new \stdClass());
|
|
}
|
|
|
|
$responseKey = $calcDef['TestSiteCode'] ?? strtoupper($codeOrName);
|
|
|
|
return $this->response->setJSON([ $responseKey => $result ]);
|
|
} catch (\Exception $e) {
|
|
log_message('error', "Calc lookup failed for {$codeOrName}: " . $e->getMessage());
|
|
return $this->response->setJSON(new \stdClass());
|
|
}
|
|
}
|
|
}
|