7 * @link http://www.open-emr.org
8 * @author Yash Bothra <yashrajbothra786gmail.com>
9 * @copyright Copyright (c) 2020 Yash Bothra <yashrajbothra786gmail.com>
10 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
13 namespace OpenEMR\Services
;
15 use OpenEMR\Common\Database\QueryUtils
;
16 use OpenEMR\Common\Uuid\UuidRegistry
;
17 use OpenEMR\Services\Search\FhirSearchWhereClauseBuilder
;
18 use OpenEMR\Services\Search\ISearchField
;
19 use OpenEMR\Services\Search\SearchModifier
;
20 use OpenEMR\Services\Search\StringSearchField
;
21 use OpenEMR\Services\Search\TokenSearchField
;
22 use OpenEMR\Validators\ConditionValidator
;
23 use OpenEMR\Validators\ProcessingResult
;
25 class ConditionService
extends BaseService
27 private const CONDITION_TABLE
= "lists";
28 private const PATIENT_TABLE
= "patient_data";
29 private const ENCOUNTER_TABLE
= "form_encounter";
30 private $uuidRegistry;
31 private $conditionValidator;
34 * Default constructor.
36 public function __construct()
38 parent
::__construct('lists');
39 $this->uuidRegistry
= new UuidRegistry(['table_name' => self
::CONDITION_TABLE
]);
40 $this->uuidRegistry
->createMissingUuids();
41 (new UuidRegistry(['table_name' => self
::PATIENT_TABLE
]))->createMissingUuids();
42 (new UuidRegistry(['table_name' => self
::ENCOUNTER_TABLE
]))->createMissingUuids();
43 $this->conditionValidator
= new ConditionValidator();
46 public function search($search, $isAndCondition = true)
48 $sql = "SELECT lists.*,
49 lists.pid AS patient_id,
51 encounter.uuid as encounter_uuid,
54 condition_ids.condition_uuid,
55 verification.title as verification_title
58 SELECT lists.uuid AS condition_uuid FROM lists
59 ) condition_ids ON lists.uuid = condition_ids.condition_uuid
60 LEFT JOIN list_options as verification ON verification.option_id = lists.verification and verification.list_id = 'condition-verification'
63 patient_data.uuid AS puuid
65 ,patient_data.uuid AS patient_uuid
67 ) patient ON patient.pid = lists.pid
68 LEFT JOIN issue_encounter as issue ON issue.list_id =lists.id
69 LEFT JOIN form_encounter as encounter ON encounter.encounter =issue.encounter";
71 $search['type'] = new StringSearchField('type', ['medical_problem'], SearchModifier
::EXACT
);
72 $whereClause = FhirSearchWhereClauseBuilder
::build($search, $isAndCondition);
74 $sql .= $whereClause->getFragment();
75 $sqlBindArray = $whereClause->getBoundValues();
76 $statementResults = QueryUtils
::sqlStatementThrowException($sql, $sqlBindArray);
79 $processingResult = new ProcessingResult();
80 while ($row = sqlFetchArray($statementResults)) {
81 $resultRecord = $this->createResultRecordFromDatabaseResult($row);
82 $processingResult->addData($resultRecord);
84 return $processingResult;
87 public function getUuidFields(): array
89 return ['condition_uuid', 'puuid', 'encounter_uuid', 'uuid', 'patient_uuid'];
92 public function createResultRecordFromDatabaseResult($row)
94 $row = parent
::createResultRecordFromDatabaseResult($row);
95 if ($row['diagnosis'] != "") {
96 $row['diagnosis'] = $this->addCoding($row['diagnosis']);
102 * Returns a list of condition matching optional search criteria.
103 * Search criteria is conveyed by array where key = field/column name, value = field value.
104 * If no search criteria is provided, all records are returned.
106 * @param $search search array parameters
107 * @param $isAndCondition specifies if AND condition is used for multiple criteria. Defaults to true.
108 * @param $puuidBind - Optional variable to only allow visibility of the patient with this puuid.
109 * @return ProcessingResult which contains validation messages, internal error messages, and the data
112 public function getAll($search = array(), $isAndCondition = true, $puuidBind = null)
115 foreach ($search as $key => $value) {
116 if (!$value instanceof ISearchField
) {
117 $newSearch[] = new StringSearchField($key, [$value], SearchModifier
::EXACT
);
119 $newSearch[$key] = $value;
123 // override puuid, this replaces anything in search if it is already specified.
124 if (isset($puuidBind)) {
125 $search['puuid'] = new TokenSearchField('puuid', $puuidBind, true);
128 return $this->search($search, $isAndCondition);
132 * Returns a single condition record by uuid.
133 * @param $uuid - The condition uuid identifier in string format.
134 * @param $puuidBind - Optional variable to only allow visibility of the patient with this puuid.
135 * @return ProcessingResult which contains validation messages, internal error messages, and the data
138 public function getOne($uuid, $puuidBind = null)
140 $search['condition_uuid'] = new TokenSearchField('condition_uuid', $uuid, true);
141 if (isset($puuidBind)) {
142 $search['puuid'] = new TokenSearchField('puuid', $puuidBind, true);
144 return $this->search($search);
149 * Inserts a new condition record.
151 * @param $data The condition fields (array) to insert.
152 * @return ProcessingResult which contains validation messages, internal error messages, and the data
155 public function insert($data)
157 $processingResult = $this->conditionValidator
->validate(
159 ConditionValidator
::DATABASE_INSERT_CONTEXT
162 if (!$processingResult->isValid()) {
163 return $processingResult;
166 $puuidBytes = UuidRegistry
::uuidToBytes($data['puuid']);
167 $data['pid'] = $this->getIdByUuid($puuidBytes, self
::PATIENT_TABLE
, "pid");
168 $data['uuid'] = (new UuidRegistry(['table_name' => self
::CONDITION_TABLE
]))->createUuid();
170 $query = $this->buildInsertColumns($data);
171 $sql = " INSERT INTO lists SET";
172 $sql .= " date=NOW(),";
173 $sql .= " activity=1,";
174 $sql .= " type='medical_problem',";
175 $sql .= $query['set'];
176 $results = sqlInsert(
182 $processingResult->addData(array(
184 'uuid' => UuidRegistry
::uuidToString($data['uuid'])
187 $processingResult->addInternalError("error processing SQL Insert");
190 return $processingResult;
194 * Updates an existing condition record.
196 * @param $uuid - The condition uuid identifier in string format used for update.
197 * @param $data - The updated condition data fields
198 * @return ProcessingResult which contains validation messages, internal error messages, and the data
201 public function update($uuid, $data)
204 $processingResult = new ProcessingResult();
205 $processingResult->setValidationMessages("Invalid Data");
206 return $processingResult;
209 $data["uuid"] = $uuid;
210 $processingResult = $this->conditionValidator
->validate(
212 ConditionValidator
::DATABASE_UPDATE_CONTEXT
214 if (!$processingResult->isValid()) {
215 return $processingResult;
218 $query = $this->buildUpdateColumns($data);
219 $sql = " UPDATE lists SET ";
220 $sql .= $query['set'];
221 $sql .= " WHERE `uuid` = ?";
222 $sql .= " AND `type` = 'medical_problem'";
224 $uuidBinary = UuidRegistry
::uuidToBytes($uuid);
225 array_push($query['bind'], $uuidBinary);
226 $sqlResult = sqlStatement($sql, $query['bind']);
229 $processingResult->addErrorMessage("error processing SQL Update");
231 $processingResult = $this->getOne($uuid);
233 return $processingResult;
237 * Deletes an existing condition record.
239 * @param $puuid - The patient uuid identifier in string format used for update.
240 * @param $uuid - The condition uuid identifier in string format used for update.
241 * @return ProcessingResult which contains validation messages, internal error messages, and the data
244 public function delete($puuid, $uuid)
246 $processingResult = new ProcessingResult();
248 $isValid = $this->conditionValidator
->validateId("uuid", "lists", $uuid, true);
249 $isPatientValid = $this->conditionValidator
->validateId("uuid", "patient_data", $puuid, true);
251 if ($isValid !== true ||
$isPatientValid !== true) {
252 $validationMessages = [
253 'UUID' => ["invalid or nonexisting value"]
255 $processingResult->setValidationMessages($validationMessages);
256 return $processingResult;
259 $puuidBytes = UuidRegistry
::uuidToBytes($puuid);
260 $auuid = UuidRegistry
::uuidToBytes($uuid);
261 $pid = $this->getIdByUuid($puuidBytes, self
::PATIENT_TABLE
, "pid");
262 $sql = "DELETE FROM lists WHERE pid=? AND uuid=? AND type='medical_problem'";
264 $results = sqlStatement($sql, array($pid, $auuid));
267 $processingResult->addData(array(
271 $processingResult->addInternalError("error processing SQL Insert");
274 return $processingResult;