2025-04-16 10:03:13 -03:00

137 lines
4.0 KiB
Elixir

defmodule Api.Studies do
import Ecto.Query
alias Api.Repo
def studies_sql_query(filters) do
page = filters["page"] || 1
size = filters["size"] || 24
filter = filters["filter"] || []
sort = filters["sort"] || [%{"dir" => "desc", "field" => "studydate"}]
# Construcción de condiciones de filtro dinámicas
filter_conditions =
Enum.reduce(filter, dynamic(true), fn f, acc ->
field = f["field"]
value = f["value"]
condition =
case field do
"modality" ->
dynamic([s], ilike(s.modality, ^"%#{value}%"))
"idstudy" ->
dynamic([s], s.idstudy == ^String.to_integer(value))
"studydate" ->
dynamic([s], fragment("CAST(? AS DATE)::text LIKE ?", s.studydate, ^"%#{value}%"))
"studydate_start" ->
if value == "" do
dynamic(true)
else
dynamic([s], fragment("CAST(? AS DATE)::text", s.studydate) >= ^value)
end
"studydate_end" ->
if value == "" do
dynamic(true)
else
dynamic([s], fragment("CAST(? AS DATE)::text", s.studydate) <= ^value)
end
"accessionnumber" ->
dynamic([s], ilike(s.accessionnumber, ^"%#{value}%"))
"proceduredescription" ->
dynamic([s], ilike(s.studydescription, ^"%#{value}%"))
"insurer" ->
dynamic([s], ilike(s.insurer, ^"%#{value}%"))
"sitename" ->
dynamic([s], ilike(s.institutionname, ^"%#{value}%"))
"nrodocumento" ->
dynamic([s, p], ilike(p.patientid, ^"%#{value}%"))
"patientname" ->
dynamic([s, p], ilike(p.patientname, ^"%#{value}%"))
"region" ->
dynamic([s], s.region == ^value)
"studytime" ->
dynamic([s], fragment("CAST(? AS TIME)::text LIKE ?", s.studytime, ^"#{value}%"))
_ ->
dynamic(true)
end
# Combina las condiciones dinámicas
dynamic([s, p], ^condition and ^acc)
end)
sort_conditions =
Enum.map(sort, fn v ->
direction = String.to_atom(v["dir"])
field = String.to_atom(v["field"])
{direction, field}
end)
query =
from s in "study",
join: p in "patient",
on: p.idpatient == s.idpatient,
left_join: sr in "studyreport",
on: sr.idstudy == s.idstudy,
left_join: st in "statuses",
on: st.idstatus == sr.idstudyreport,
where: ^filter_conditions,
select: %{
recordstotal: fragment("count(*) over()"),
idstudy: fragment("substring(encrypt(?::text::bytea, '1nf0rm3', 'aes')::text from 3)", s.idstudy),
#idstudy: s.idstudy,
accessionnumber: s.accessionnumber,
studydate: s.studydate,
studytime: s.studytime,
patientname: fragment("select replace(?, '^', ' ')", p.patientname),
proceduredescription: s.studydescription,
modality: s.modality,
sitename: s.institutionname,
insurer: s.insurer,
nrodocumento: fragment("substring(encrypt(?::text::bytea, '1nf0rm3', 'aes')::text from 3)", p.patientid),
#nrodocumento: p.patientid,
hasaudio: fragment("CASE WHEN ? IS NOT NULL THEN true ELSE false END", s.audiofile)
},
order_by: ^sort_conditions,
limit: ^size,
offset: ^((page - 1) * size)
result = Repo.one(
from q in subquery(query),
group_by: q.recordstotal,
select: %{
data: fragment("json_agg(?)::text", q),
recordstotal: q.recordstotal
}
)
case result do
nil ->
%{data: [], last_page: 0}
result ->
# Calcula last_page
last_page = div(result.recordstotal + size - 1, size)
%{data: Jason.decode!(result.data), last_page: last_page}
end
end
end