From 973400301ea741b6afdb8cacf882d8cd6aec70fc Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Fri, 6 Sep 2024 11:18:43 -0400
Subject: [PATCH 1/8] add Kindling, bulk fhir parser, sample bulk fhir data
---
config/config.exs | 2 +
lib/epiviewpoint/bulk_fhir_parser.ex | 161 +++++++++++++++
lib/epiviewpoint/cases.ex | 1 +
lib/epiviewpoint/cases/import.ex | 9 +
lib/epiviewpoint/data_file.ex | 8 +
lib/epiviewpoint/r4/address.ex | 68 +++++++
lib/epiviewpoint/r4/age.ex | 47 +++++
lib/epiviewpoint/r4/annotation.ex | 46 +++++
lib/epiviewpoint/r4/attachment.ex | 44 +++++
lib/epiviewpoint/r4/codeable_concept.ex | 32 +++
lib/epiviewpoint/r4/coding.ex | 38 ++++
lib/epiviewpoint/r4/contact_detail.ex | 32 +++
lib/epiviewpoint/r4/contact_point.ex | 61 ++++++
lib/epiviewpoint/r4/contributor.ex | 43 ++++
lib/epiviewpoint/r4/count.ex | 47 +++++
lib/epiviewpoint/r4/data_requirement.ex | 57 ++++++
.../r4/data_requirement/code_filter.ex | 38 ++++
.../r4/data_requirement/date_filter.ex | 52 +++++
lib/epiviewpoint/r4/data_requirement/sort.ex | 41 ++++
lib/epiviewpoint/r4/distance.ex | 47 +++++
lib/epiviewpoint/r4/dosage.ex | 68 +++++++
lib/epiviewpoint/r4/dosage/dose_and_rate.ex | 60 ++++++
lib/epiviewpoint/r4/duration.ex | 47 +++++
lib/epiviewpoint/r4/element.ex | 26 +++
lib/epiviewpoint/r4/expression.ex | 46 +++++
lib/epiviewpoint/r4/extension.ex | 132 +++++++++++++
lib/epiviewpoint/r4/human_name.ex | 57 ++++++
lib/epiviewpoint/r4/identifier.ex | 52 +++++
lib/epiviewpoint/r4/meta.ex | 41 ++++
lib/epiviewpoint/r4/money.ex | 32 +++
lib/epiviewpoint/r4/narrative.ex | 43 ++++
lib/epiviewpoint/r4/observation.ex | 184 ++++++++++++++++++
lib/epiviewpoint/r4/observation/component.ex | 100 ++++++++++
.../r4/observation/reference_range.ex | 44 +++++
lib/epiviewpoint/r4/organization.ex | 68 +++++++
lib/epiviewpoint/r4/organization/contact.ex | 38 ++++
lib/epiviewpoint/r4/parameter_definition.ex | 42 ++++
lib/epiviewpoint/r4/patient.ex | 108 ++++++++++
lib/epiviewpoint/r4/patient/communication.ex | 36 ++++
lib/epiviewpoint/r4/patient/contact.ex | 53 +++++
lib/epiviewpoint/r4/patient/link.ex | 43 ++++
lib/epiviewpoint/r4/period.ex | 32 +++
lib/epiviewpoint/r4/quantity.ex | 47 +++++
lib/epiviewpoint/r4/range.ex | 32 +++
lib/epiviewpoint/r4/ratio.ex | 32 +++
lib/epiviewpoint/r4/reference.ex | 38 ++++
lib/epiviewpoint/r4/related_artifact.ex | 57 ++++++
lib/epiviewpoint/r4/resource_list.ex | 21 ++
lib/epiviewpoint/r4/sampled_data.ex | 44 +++++
lib/epiviewpoint/r4/signature.ex | 44 +++++
lib/epiviewpoint/r4/timing.ex | 37 ++++
lib/epiviewpoint/r4/timing/repeat.ex | 100 ++++++++++
lib/epiviewpoint/r4/trigger_definition.ex | 71 +++++++
lib/epiviewpoint/r4/usage_context.ex | 50 +++++
.../controllers/import_controller.ex | 26 +++
.../live/import_live.html.heex | 9 +
lib/epiviewpoint_web/router.ex | 1 +
lib/epiviewpoint_web/uploaded_file.ex | 4 +
mix.exs | 1 +
mix.lock | 10 +
.../bulk_fhir_download/Observation.ndjson | 2 +
.../bulk_fhir_download/Organization.ndjson | 2 +
sample_data/bulk_fhir_download/Patient.ndjson | 2 +
63 files changed, 2856 insertions(+)
create mode 100644 lib/epiviewpoint/bulk_fhir_parser.ex
create mode 100644 lib/epiviewpoint/r4/address.ex
create mode 100644 lib/epiviewpoint/r4/age.ex
create mode 100644 lib/epiviewpoint/r4/annotation.ex
create mode 100644 lib/epiviewpoint/r4/attachment.ex
create mode 100644 lib/epiviewpoint/r4/codeable_concept.ex
create mode 100644 lib/epiviewpoint/r4/coding.ex
create mode 100644 lib/epiviewpoint/r4/contact_detail.ex
create mode 100644 lib/epiviewpoint/r4/contact_point.ex
create mode 100644 lib/epiviewpoint/r4/contributor.ex
create mode 100644 lib/epiviewpoint/r4/count.ex
create mode 100644 lib/epiviewpoint/r4/data_requirement.ex
create mode 100644 lib/epiviewpoint/r4/data_requirement/code_filter.ex
create mode 100644 lib/epiviewpoint/r4/data_requirement/date_filter.ex
create mode 100644 lib/epiviewpoint/r4/data_requirement/sort.ex
create mode 100644 lib/epiviewpoint/r4/distance.ex
create mode 100644 lib/epiviewpoint/r4/dosage.ex
create mode 100644 lib/epiviewpoint/r4/dosage/dose_and_rate.ex
create mode 100644 lib/epiviewpoint/r4/duration.ex
create mode 100644 lib/epiviewpoint/r4/element.ex
create mode 100644 lib/epiviewpoint/r4/expression.ex
create mode 100644 lib/epiviewpoint/r4/extension.ex
create mode 100644 lib/epiviewpoint/r4/human_name.ex
create mode 100644 lib/epiviewpoint/r4/identifier.ex
create mode 100644 lib/epiviewpoint/r4/meta.ex
create mode 100644 lib/epiviewpoint/r4/money.ex
create mode 100644 lib/epiviewpoint/r4/narrative.ex
create mode 100644 lib/epiviewpoint/r4/observation.ex
create mode 100644 lib/epiviewpoint/r4/observation/component.ex
create mode 100644 lib/epiviewpoint/r4/observation/reference_range.ex
create mode 100644 lib/epiviewpoint/r4/organization.ex
create mode 100644 lib/epiviewpoint/r4/organization/contact.ex
create mode 100644 lib/epiviewpoint/r4/parameter_definition.ex
create mode 100644 lib/epiviewpoint/r4/patient.ex
create mode 100644 lib/epiviewpoint/r4/patient/communication.ex
create mode 100644 lib/epiviewpoint/r4/patient/contact.ex
create mode 100644 lib/epiviewpoint/r4/patient/link.ex
create mode 100644 lib/epiviewpoint/r4/period.ex
create mode 100644 lib/epiviewpoint/r4/quantity.ex
create mode 100644 lib/epiviewpoint/r4/range.ex
create mode 100644 lib/epiviewpoint/r4/ratio.ex
create mode 100644 lib/epiviewpoint/r4/reference.ex
create mode 100644 lib/epiviewpoint/r4/related_artifact.ex
create mode 100644 lib/epiviewpoint/r4/resource_list.ex
create mode 100644 lib/epiviewpoint/r4/sampled_data.ex
create mode 100644 lib/epiviewpoint/r4/signature.ex
create mode 100644 lib/epiviewpoint/r4/timing.ex
create mode 100644 lib/epiviewpoint/r4/timing/repeat.ex
create mode 100644 lib/epiviewpoint/r4/trigger_definition.ex
create mode 100644 lib/epiviewpoint/r4/usage_context.ex
create mode 100644 sample_data/bulk_fhir_download/Observation.ndjson
create mode 100644 sample_data/bulk_fhir_download/Organization.ndjson
create mode 100644 sample_data/bulk_fhir_download/Patient.ndjson
diff --git a/config/config.exs b/config/config.exs
index b4c9e1e9..84a71c71 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -50,6 +50,8 @@ config :dart_sass,
cd: Path.expand("../assets", __DIR__)
]
+config :kindling, root_resources: ["Patient", "Observation", "Organization"]
+
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs"
diff --git a/lib/epiviewpoint/bulk_fhir_parser.ex b/lib/epiviewpoint/bulk_fhir_parser.ex
new file mode 100644
index 00000000..1f4dac32
--- /dev/null
+++ b/lib/epiviewpoint/bulk_fhir_parser.ex
@@ -0,0 +1,161 @@
+defmodule EpiViewpoint.BulkFhirParser do
+ def parse_bulk_fhir(file_list) do
+ file_list
+ |> load_resources()
+ |> extract_resources()
+ |> join_resources()
+ |> to_map()
+ end
+
+ def load_resources(file_list) do
+ file_list
+ |> Enum.reduce(%{}, fn file, acc ->
+ resources = load_resource_file(file.contents)
+
+ Enum.reduce(resources, acc, fn resource, inner_acc ->
+ type = resource.resource_type
+ Map.update(inner_acc, type, [resource], &[resource | &1])
+ end)
+ end)
+ end
+
+ def load_resource_file(file_content) do
+ file_content
+ |> String.split("\n")
+ |> Stream.map(&String.trim/1)
+ |> Stream.map(&json_to_kindle_schema(&1, "EpiViewpoint.R4"))
+ |> Enum.to_list()
+ end
+
+ def extract_resources(resources) do
+ resources
+ |> Enum.reduce(%{}, fn {resource_type, resource_list}, acc ->
+ Map.put(acc, resource_type, extract_resource(resource_type, resource_list))
+ end)
+ end
+
+ def extract_resource("Patient", resource_list) do
+ resource_list
+ |> Enum.map(fn
+ %Epiviewpoint.R4.Patient{
+ id: caseid,
+ identifier: [%Epiviewpoint.R4.Identifier{value: person_tid}],
+ name: [%Epiviewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
+ birth_date: dateofbirth,
+ gender: sex,
+ address: [
+ %Epiviewpoint.R4.Address{
+ line: [diagaddress_street1],
+ city: diagaddress_city,
+ state: diagaddress_state,
+ postal_code: diagaddress_zip
+ }
+ ],
+ telecom: [%Epiviewpoint.R4.ContactPoint{value: phonenumber}],
+ extension: extensions
+ } = _resource ->
+ %{
+ caseid: caseid,
+ person_tid: person_tid,
+ search_firstname: search_firstname,
+ search_lastname: search_lastname,
+ dateofbirth: Calendar.strftime(dateofbirth, "%m/%d/%Y"),
+ sex: sex |> to_string() |> String.capitalize(),
+ diagaddress_street1: diagaddress_street1,
+ diagaddress_city: diagaddress_city,
+ diagaddress_state: diagaddress_state,
+ diagaddress_zip: diagaddress_zip,
+ phonenumber: phonenumber,
+ ethnicity: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"),
+ occupation: find_extension(extensions),
+ race: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race")
+ }
+ end)
+ end
+
+ def extract_resource("Observation", resource_list) do
+ resource_list
+ |> Enum.map(fn
+ %Epiviewpoint.R4.Observation{
+ id: lab_result_tid,
+ subject: %Epiviewpoint.R4.Reference{reference: "Patient/" <> pat_id},
+ effective_date_time: datecollected,
+ issued: resultdate,
+ code: %Epiviewpoint.R4.CodeableConcept{text: testname},
+ interpretation: [%Epiviewpoint.R4.CodeableConcept{coding: [%Epiviewpoint.R4.Coding{display: result}]}],
+ performer: [%Epiviewpoint.R4.Reference{reference: "Organization/" <> org_id}],
+ extension: extensions
+ } = _resource ->
+ %{
+ lab_result_tid: lab_result_tid,
+ pat_id: pat_id,
+ datecollected: datecollected,
+ resultdate: resultdate |> DateTime.to_date() |> Calendar.strftime("%m/%d/%Y"),
+ testname: testname,
+ result: result,
+ org_id: org_id,
+ datereportedtolhd: find_extension(extensions)
+ }
+ end)
+ end
+
+ def extract_resource("Organization", resource_list) do
+ resource_list
+ |> Enum.map(fn
+ %Epiviewpoint.R4.Organization{
+ id: orgnization_id,
+ name: orderingfacilityname
+ } = _resource ->
+ %{
+ orgnization_id: orgnization_id,
+ orderingfacilityname: orderingfacilityname
+ }
+ end)
+ end
+
+ # Helper function to find extension values
+ defp find_extension(extensions, url \\ nil) do
+ Enum.find_value(extensions, fn
+ %Epiviewpoint.R4.Extension{
+ url: ^url,
+ extension: [%Epiviewpoint.R4.Extension{url: "ombCategory", value_coding: %Epiviewpoint.R4.Coding{display: value}}, _]
+ } ->
+ value
+
+ %Epiviewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/patient-occupation", value_string: value} ->
+ value
+
+ %Epiviewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/datereportedtolhd", value_date: value} ->
+ value
+
+ _ ->
+ nil
+ end)
+ end
+
+ defp json_to_kindle_schema(json, version_namespace) do
+ map = Jason.decode!(json)
+ Kindling.Converter.convert(version_namespace, map)
+ end
+
+ def join_resources(resources) do
+ patients = Map.get(resources, "Patient", [])
+ observations = Map.get(resources, "Observation", [])
+ organizations = Map.get(resources, "Organization", [])
+
+ observations
+ |> Enum.map(fn observation ->
+ patient = Enum.find(patients, &(&1.caseid == observation.pat_id))
+ organization = Enum.find(organizations, &(&1.orgnization_id == observation.org_id))
+
+ observation
+ |> Map.merge(patient || %{})
+ |> Map.merge(organization || %{})
+ |> Map.drop([:pat_id, :org_id, :orgnization_id])
+ end)
+ end
+
+ def to_map(resources) do
+ %{file_name: "load.bulk_fhir", contents: resources}
+ end
+end
diff --git a/lib/epiviewpoint/cases.ex b/lib/epiviewpoint/cases.ex
index e39db651..7929aff9 100644
--- a/lib/epiviewpoint/cases.ex
+++ b/lib/epiviewpoint/cases.ex
@@ -34,6 +34,7 @@ defmodule EpiViewpoint.Cases do
def count_lab_results(), do: LabResult |> Repo.aggregate(:count)
def create_lab_result!({attrs, audit_meta}), do: %LabResult{} |> change_lab_result(attrs) |> AuditingRepo.insert!(audit_meta)
def import_lab_results(lab_result_data_file_string, originator), do: Import.import_data_file(lab_result_data_file_string, originator)
+ def import_bulk_fhir_lab_results(lab_result_data_file_list, originator), do: Import.import_bulk_fhir_data_file(lab_result_data_file_list, originator)
def list_lab_results(), do: LabResult.Query.all() |> Repo.all()
def preload_initiating_lab_result(case_investigations_or_nil), do: case_investigations_or_nil |> Repo.preload(:initiating_lab_result)
def preload_lab_results(person_or_people_or_nil), do: person_or_people_or_nil |> Repo.preload(lab_results: LabResult.Query.display_order())
diff --git a/lib/epiviewpoint/cases/import.ex b/lib/epiviewpoint/cases/import.ex
index e9a20f81..0a89c42b 100644
--- a/lib/epiviewpoint/cases/import.ex
+++ b/lib/epiviewpoint/cases/import.ex
@@ -1,6 +1,7 @@
defmodule EpiViewpoint.Cases.Import do
alias EpiViewpoint.Accounts
alias EpiViewpoint.AuditLog
+ alias EpiViewpoint.BulkFhirParser
alias EpiViewpoint.Cases
alias EpiViewpoint.Cases.Import
alias EpiViewpoint.Cases.LabResult
@@ -59,6 +60,13 @@ defmodule EpiViewpoint.Cases.Import do
]
end
+ def import_bulk_fhir_data_file(lab_result_data_file_list, originator) do
+ lab_result_data_file_list
+ |> BulkFhirParser.parse_bulk_fhir()
+ |> import_data_file(originator)
+ end
+
+
def import_data_file(_file, %{admin: false}), do: {:error, "Originator must be an admin"}
def import_data_file(file, %Accounts.User{} = originator) do
@@ -103,6 +111,7 @@ defmodule EpiViewpoint.Cases.Import do
case Path.extname(file.file_name) do
".csv" -> DataFile.read(file.contents, :csv, &rename_headers/1, @fields)
".ndjson" -> DataFile.read(file.contents, :ndjson, &rename_headers/1, @fields)
+ ".bulk_fhir" -> DataFile.read(file.contents, :bulk_fhir, &rename_headers/1, @fields)
_ -> {:error, "Unsupported file type: #{file.extension}"}
end
end
diff --git a/lib/epiviewpoint/data_file.ex b/lib/epiviewpoint/data_file.ex
index cd645c9b..d34a2bf7 100644
--- a/lib/epiviewpoint/data_file.ex
+++ b/lib/epiviewpoint/data_file.ex
@@ -21,6 +21,10 @@ defmodule EpiViewpoint.DataFile do
read(string, header_transformer, headers, &parse_ndjson/1)
end
+ def read(string, :bulk_fhir, header_transformer, headers) when is_binary(string) do
+ read(string, header_transformer, headers, &parse_bulk_fhir/1)
+ end
+
def read(input, header_transformer, [required: required_headers, optional: optional_headers], parser) do
with {:ok, df} <- parser.(input),
{:ok, provided_headers} <- extract_provided_headers(df, header_transformer),
@@ -84,6 +88,10 @@ defmodule EpiViewpoint.DataFile do
DataFrame.load_ndjson(input)
end
+ defp parse_bulk_fhir(input) do
+ DataFrame.new(input)
+ end
+
defp validate_csv(input) do
EpiViewpoint.DataFile.Parser.parse_string(input, headers: true)
input
diff --git a/lib/epiviewpoint/r4/address.ex b/lib/epiviewpoint/r4/address.ex
new file mode 100644
index 00000000..028b97cd
--- /dev/null
+++ b/lib/epiviewpoint/r4/address.ex
@@ -0,0 +1,68 @@
+defmodule Epiviewpoint.R4.Address do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :city,
+ :country,
+ :district,
+ :id,
+ :line,
+ :postal_code,
+ :state,
+ :text,
+ :type,
+ :use
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:city, :string)
+ field(:country, :string)
+ field(:district, :string)
+ field(:postal_code, :string)
+ field(:state, :string)
+ field(:text, :string)
+
+ field(:line, {:array, :string})
+
+ # Enum
+ field(:type, Ecto.Enum,
+ values: [
+ :postal,
+ :physical,
+ :both
+ ]
+ )
+
+ field(:use, Ecto.Enum,
+ values: [
+ :home,
+ :work,
+ :temp,
+ :old,
+ :billing
+ ]
+ )
+
+ # Embed One
+ embeds_one(:period, Epiviewpoint.R4.Period)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:period)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/age.ex b/lib/epiviewpoint/r4/age.ex
new file mode 100644
index 00000000..df1305c5
--- /dev/null
+++ b/lib/epiviewpoint/r4/age.ex
@@ -0,0 +1,47 @@
+defmodule Epiviewpoint.R4.Age do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :code,
+ :comparator,
+ :id,
+ :system,
+ :unit,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:code, :string)
+ field(:system, :string)
+ field(:unit, :string)
+ field(:value, :decimal)
+
+ # Enum
+ field(:comparator, Ecto.Enum,
+ values: [
+ :<,
+ :<=,
+ :>=,
+ :>
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/annotation.ex b/lib/epiviewpoint/r4/annotation.ex
new file mode 100644
index 00000000..bd103fc7
--- /dev/null
+++ b/lib/epiviewpoint/r4/annotation.ex
@@ -0,0 +1,46 @@
+defmodule Epiviewpoint.R4.Annotation do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :author_string,
+ :id,
+ :text,
+ :time
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:author_string, :string)
+ field(:text, :string)
+ field(:time, :utc_datetime_usec)
+
+ # Embed One
+ embeds_one(:author_reference, Epiviewpoint.R4.Reference)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("author") do
+ [:author_reference, :author_string]
+ end
+
+ def choices("authorReference"), do: :error
+
+ def choices("authorstring"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:author_reference)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/attachment.ex b/lib/epiviewpoint/r4/attachment.ex
new file mode 100644
index 00000000..6d3121b1
--- /dev/null
+++ b/lib/epiviewpoint/r4/attachment.ex
@@ -0,0 +1,44 @@
+defmodule Epiviewpoint.R4.Attachment do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :content_type,
+ :creation,
+ :data,
+ :hash,
+ :id,
+ :language,
+ :size,
+ :title,
+ :url
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:content_type, :string)
+ field(:creation, :utc_datetime_usec)
+ field(:data, :string)
+ field(:hash, :string)
+ field(:language, :string)
+ field(:size, :integer)
+ field(:title, :string)
+ field(:url, :string)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/codeable_concept.ex b/lib/epiviewpoint/r4/codeable_concept.ex
new file mode 100644
index 00000000..a7924e17
--- /dev/null
+++ b/lib/epiviewpoint/r4/codeable_concept.ex
@@ -0,0 +1,32 @@
+defmodule Epiviewpoint.R4.CodeableConcept do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :text
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:text, :string)
+
+ # Embed Many
+ embeds_many(:coding, Epiviewpoint.R4.Coding)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:coding)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/coding.ex b/lib/epiviewpoint/r4/coding.ex
new file mode 100644
index 00000000..8f9edad0
--- /dev/null
+++ b/lib/epiviewpoint/r4/coding.ex
@@ -0,0 +1,38 @@
+defmodule Epiviewpoint.R4.Coding do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :code,
+ :display,
+ :id,
+ :system,
+ :user_selected,
+ :version
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:code, :string)
+ field(:display, :string)
+ field(:system, :string)
+ field(:user_selected, :boolean)
+ field(:version, :string)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/contact_detail.ex b/lib/epiviewpoint/r4/contact_detail.ex
new file mode 100644
index 00000000..1439daca
--- /dev/null
+++ b/lib/epiviewpoint/r4/contact_detail.ex
@@ -0,0 +1,32 @@
+defmodule Epiviewpoint.R4.ContactDetail do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :name
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:name, :string)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> cast_embed(:telecom)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/contact_point.ex b/lib/epiviewpoint/r4/contact_point.ex
new file mode 100644
index 00000000..a23e86ab
--- /dev/null
+++ b/lib/epiviewpoint/r4/contact_point.ex
@@ -0,0 +1,61 @@
+defmodule Epiviewpoint.R4.ContactPoint do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :rank,
+ :system,
+ :use,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:rank, :integer)
+ field(:value, :string)
+
+ # Enum
+ field(:system, Ecto.Enum,
+ values: [
+ :phone,
+ :fax,
+ :email,
+ :pager,
+ :url,
+ :sms,
+ :other
+ ]
+ )
+
+ field(:use, Ecto.Enum,
+ values: [
+ :home,
+ :work,
+ :temp,
+ :old,
+ :mobile
+ ]
+ )
+
+ # Embed One
+ embeds_one(:period, Epiviewpoint.R4.Period)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:period)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/contributor.ex b/lib/epiviewpoint/r4/contributor.ex
new file mode 100644
index 00000000..c7241ca0
--- /dev/null
+++ b/lib/epiviewpoint/r4/contributor.ex
@@ -0,0 +1,43 @@
+defmodule Epiviewpoint.R4.Contributor do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :name,
+ :type
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:name, :string)
+
+ # Enum
+ field(:type, Ecto.Enum,
+ values: [
+ :author,
+ :editor,
+ :reviewer,
+ :endorser
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:contact, Epiviewpoint.R4.ContactDetail)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:contact)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/count.ex b/lib/epiviewpoint/r4/count.ex
new file mode 100644
index 00000000..89bfe065
--- /dev/null
+++ b/lib/epiviewpoint/r4/count.ex
@@ -0,0 +1,47 @@
+defmodule Epiviewpoint.R4.Count do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :code,
+ :comparator,
+ :id,
+ :system,
+ :unit,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:code, :string)
+ field(:system, :string)
+ field(:unit, :string)
+ field(:value, :decimal)
+
+ # Enum
+ field(:comparator, Ecto.Enum,
+ values: [
+ :<,
+ :<=,
+ :>=,
+ :>
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/data_requirement.ex b/lib/epiviewpoint/r4/data_requirement.ex
new file mode 100644
index 00000000..546433d9
--- /dev/null
+++ b/lib/epiviewpoint/r4/data_requirement.ex
@@ -0,0 +1,57 @@
+defmodule Epiviewpoint.R4.DataRequirement do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :limit,
+ :must_support,
+ :profile,
+ :type
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:limit, :integer)
+ field(:type, :string)
+
+ field(:must_support, {:array, :string})
+ field(:profile, {:array, :string})
+
+ # Embed One
+ embeds_one(:subject_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:subject_reference, Epiviewpoint.R4.Reference)
+
+ # Embed Many
+ embeds_many(:code_filter, Epiviewpoint.R4.DataRequirement.CodeFilter)
+ embeds_many(:date_filter, Epiviewpoint.R4.DataRequirement.DateFilter)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:sort, Epiviewpoint.R4.DataRequirement.Sort)
+ end
+
+ def choices("subject") do
+ [:subject_codeable_concept, :subject_reference]
+ end
+
+ def choices("subjectCodeableConcept"), do: :error
+
+ def choices("subjectReference"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:subject_codeable_concept)
+ |> cast_embed(:subject_reference)
+ |> cast_embed(:code_filter)
+ |> cast_embed(:date_filter)
+ |> cast_embed(:extension)
+ |> cast_embed(:sort)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/data_requirement/code_filter.ex b/lib/epiviewpoint/r4/data_requirement/code_filter.ex
new file mode 100644
index 00000000..6c5d50ff
--- /dev/null
+++ b/lib/epiviewpoint/r4/data_requirement/code_filter.ex
@@ -0,0 +1,38 @@
+defmodule Epiviewpoint.R4.DataRequirement.CodeFilter do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :path,
+ :search_param,
+ :value_set
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:path, :string)
+ field(:search_param, :string)
+ field(:value_set, :string)
+
+ # Embed Many
+ embeds_many(:code, Epiviewpoint.R4.Coding)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:code)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/data_requirement/date_filter.ex b/lib/epiviewpoint/r4/data_requirement/date_filter.ex
new file mode 100644
index 00000000..2b9dce0f
--- /dev/null
+++ b/lib/epiviewpoint/r4/data_requirement/date_filter.ex
@@ -0,0 +1,52 @@
+defmodule Epiviewpoint.R4.DataRequirement.DateFilter do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :path,
+ :search_param,
+ :value_date_time
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:path, :string)
+ field(:search_param, :string)
+ field(:value_date_time, :string)
+
+ # Embed One
+ embeds_one(:value_duration, Epiviewpoint.R4.Duration)
+ embeds_one(:value_period, Epiviewpoint.R4.Period)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("value") do
+ [:value_date_time, :value_period, :value_duration]
+ end
+
+ def choices("valuedateTime"), do: :error
+
+ def choices("valuePeriod"), do: :error
+
+ def choices("valueDuration"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:value_duration)
+ |> cast_embed(:value_period)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/data_requirement/sort.ex b/lib/epiviewpoint/r4/data_requirement/sort.ex
new file mode 100644
index 00000000..f465cf05
--- /dev/null
+++ b/lib/epiviewpoint/r4/data_requirement/sort.ex
@@ -0,0 +1,41 @@
+defmodule Epiviewpoint.R4.DataRequirement.Sort do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :direction,
+ :id,
+ :path
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:path, :string)
+
+ # Enum
+ field(:direction, Ecto.Enum,
+ values: [
+ :ascending,
+ :descending
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/distance.ex b/lib/epiviewpoint/r4/distance.ex
new file mode 100644
index 00000000..e70e5554
--- /dev/null
+++ b/lib/epiviewpoint/r4/distance.ex
@@ -0,0 +1,47 @@
+defmodule Epiviewpoint.R4.Distance do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :code,
+ :comparator,
+ :id,
+ :system,
+ :unit,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:code, :string)
+ field(:system, :string)
+ field(:unit, :string)
+ field(:value, :decimal)
+
+ # Enum
+ field(:comparator, Ecto.Enum,
+ values: [
+ :<,
+ :<=,
+ :>=,
+ :>
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/dosage.ex b/lib/epiviewpoint/r4/dosage.ex
new file mode 100644
index 00000000..0b2e21e4
--- /dev/null
+++ b/lib/epiviewpoint/r4/dosage.ex
@@ -0,0 +1,68 @@
+defmodule Epiviewpoint.R4.Dosage do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :as_needed_boolean,
+ :id,
+ :patient_instruction,
+ :sequence,
+ :text
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:as_needed_boolean, :boolean)
+ field(:patient_instruction, :string)
+ field(:sequence, :integer)
+ field(:text, :string)
+
+ # Embed One
+ embeds_one(:as_needed_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:max_dose_per_administration, Epiviewpoint.R4.Quantity)
+ embeds_one(:max_dose_per_lifetime, Epiviewpoint.R4.Quantity)
+ embeds_one(:max_dose_per_period, Epiviewpoint.R4.Ratio)
+ embeds_one(:method, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:route, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:site, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:timing, Epiviewpoint.R4.Timing)
+
+ # Embed Many
+ embeds_many(:additional_instruction, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:dose_and_rate, Epiviewpoint.R4.Dosage.DoseAndRate)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("asNeeded") do
+ [:asNeeded_boolean, :asNeeded_codeable_concept]
+ end
+
+ def choices("asNeededboolean"), do: :error
+
+ def choices("asNeededCodeableConcept"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:as_needed_codeable_concept)
+ |> cast_embed(:max_dose_per_administration)
+ |> cast_embed(:max_dose_per_lifetime)
+ |> cast_embed(:max_dose_per_period)
+ |> cast_embed(:method)
+ |> cast_embed(:route)
+ |> cast_embed(:site)
+ |> cast_embed(:timing)
+ |> cast_embed(:additional_instruction)
+ |> cast_embed(:dose_and_rate)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/dosage/dose_and_rate.ex b/lib/epiviewpoint/r4/dosage/dose_and_rate.ex
new file mode 100644
index 00000000..2fff6029
--- /dev/null
+++ b/lib/epiviewpoint/r4/dosage/dose_and_rate.ex
@@ -0,0 +1,60 @@
+defmodule Epiviewpoint.R4.Dosage.DoseAndRate do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Embed One
+ embeds_one(:dose_quantity, Epiviewpoint.R4.Quantity)
+ embeds_one(:dose_range, Epiviewpoint.R4.Range)
+ embeds_one(:rate_quantity, Epiviewpoint.R4.Quantity)
+ embeds_one(:rate_range, Epiviewpoint.R4.Range)
+ embeds_one(:rate_ratio, Epiviewpoint.R4.Ratio)
+ embeds_one(:type, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("dose") do
+ [:dose_range, :dose_simple_quantity]
+ end
+
+ def choices("doseRange"), do: :error
+
+ def choices("doseSimpleQuantity"), do: :error
+
+ def choices("rate") do
+ [:rate_ratio, :rate_range, :rate_simple_quantity]
+ end
+
+ def choices("rateRatio"), do: :error
+
+ def choices("rateRange"), do: :error
+
+ def choices("rateSimpleQuantity"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:dose_quantity)
+ |> cast_embed(:dose_range)
+ |> cast_embed(:rate_quantity)
+ |> cast_embed(:rate_range)
+ |> cast_embed(:rate_ratio)
+ |> cast_embed(:type)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/duration.ex b/lib/epiviewpoint/r4/duration.ex
new file mode 100644
index 00000000..4c4cdb30
--- /dev/null
+++ b/lib/epiviewpoint/r4/duration.ex
@@ -0,0 +1,47 @@
+defmodule Epiviewpoint.R4.Duration do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :code,
+ :comparator,
+ :id,
+ :system,
+ :unit,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:code, :string)
+ field(:system, :string)
+ field(:unit, :string)
+ field(:value, :decimal)
+
+ # Enum
+ field(:comparator, Ecto.Enum,
+ values: [
+ :<,
+ :<=,
+ :>=,
+ :>
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/element.ex b/lib/epiviewpoint/r4/element.ex
new file mode 100644
index 00000000..5af02ad7
--- /dev/null
+++ b/lib/epiviewpoint/r4/element.ex
@@ -0,0 +1,26 @@
+defmodule Epiviewpoint.R4.Element do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/expression.ex b/lib/epiviewpoint/r4/expression.ex
new file mode 100644
index 00000000..241c3e34
--- /dev/null
+++ b/lib/epiviewpoint/r4/expression.ex
@@ -0,0 +1,46 @@
+defmodule Epiviewpoint.R4.Expression do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :description,
+ :expression,
+ :id,
+ :language,
+ :name,
+ :reference
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:description, :string)
+ field(:expression, :string)
+ field(:name, :binary_id)
+ field(:reference, :string)
+
+ # Enum
+ field(:language, Ecto.Enum,
+ values: [
+ :"text/cql",
+ :"text/fhirpath",
+ :"application/x_fhir_query"
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/extension.ex b/lib/epiviewpoint/r4/extension.ex
new file mode 100644
index 00000000..c8ab3b50
--- /dev/null
+++ b/lib/epiviewpoint/r4/extension.ex
@@ -0,0 +1,132 @@
+defmodule Epiviewpoint.R4.Extension do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :value_time,
+ :value_positive_int,
+ :value_date_time,
+ :value_markdown,
+ :value_date,
+ :value_unsigned_int,
+ :value_string,
+ :value_url,
+ :value_uri,
+ :value_integer,
+ :value_canonical,
+ :value_instant,
+ :url,
+ :value_oid,
+ :value_code,
+ :value_base64_binary,
+ :value_decimal,
+ :id,
+ :value_uuid,
+ :value_boolean,
+ :value_id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:value_time, :string)
+ field(:value_positive_int, :integer)
+ field(:value_date_time, :string)
+ field(:value_markdown, :string)
+ field(:value_date, :string)
+ field(:value_unsigned_int, :integer)
+ field(:value_string, :string)
+ field(:value_url, :string)
+ field(:value_uri, :string)
+ field(:value_integer, :integer)
+ field(:value_canonical, :string)
+ field(:value_instant, :string)
+ field(:url, :string)
+ field(:value_oid, :string)
+ field(:value_code, :string)
+ field(:value_base64_binary, :string)
+ field(:value_decimal, :decimal)
+ field(:value_uuid, :string)
+ field(:value_boolean, :boolean)
+ field(:value_id, :string)
+
+ # Embed One
+ embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
+ embeds_one(:value_expression, Epiviewpoint.R4.Expression)
+ embeds_one(:value_attachment, Epiviewpoint.R4.Attachment)
+ embeds_one(:value_identifier, Epiviewpoint.R4.Identifier)
+ embeds_one(:value_sampled_data, Epiviewpoint.R4.SampledData)
+ embeds_one(:value_parameter_definition, Epiviewpoint.R4.ParameterDefinition)
+ embeds_one(:value_timing, Epiviewpoint.R4.Timing)
+ embeds_one(:value_reference, Epiviewpoint.R4.Reference)
+ embeds_one(:value_contact_point, Epiviewpoint.R4.ContactPoint)
+ embeds_one(:value_age, Epiviewpoint.R4.Age)
+ embeds_one(:value_meta, Epiviewpoint.R4.Meta)
+ embeds_one(:value_annotation, Epiviewpoint.R4.Annotation)
+ embeds_one(:value_money, Epiviewpoint.R4.Money)
+ embeds_one(:value_usage_context, Epiviewpoint.R4.UsageContext)
+ embeds_one(:value_related_artifact, Epiviewpoint.R4.RelatedArtifact)
+ embeds_one(:value_contact_detail, Epiviewpoint.R4.ContactDetail)
+ embeds_one(:value_ratio, Epiviewpoint.R4.Ratio)
+ embeds_one(:value_distance, Epiviewpoint.R4.Distance)
+ embeds_one(:value_duration, Epiviewpoint.R4.Duration)
+ embeds_one(:value_human_name, Epiviewpoint.R4.HumanName)
+ embeds_one(:value_period, Epiviewpoint.R4.Period)
+ embeds_one(:value_range, Epiviewpoint.R4.Range)
+ embeds_one(:value_dosage, Epiviewpoint.R4.Dosage)
+ embeds_one(:value_contributor, Epiviewpoint.R4.Contributor)
+ embeds_one(:value_address, Epiviewpoint.R4.Address)
+ embeds_one(:value_signature, Epiviewpoint.R4.Signature)
+ embeds_one(:value_trigger_definition, Epiviewpoint.R4.TriggerDefinition)
+ embeds_one(:value_data_requirement, Epiviewpoint.R4.DataRequirement)
+ embeds_one(:value_count, Epiviewpoint.R4.Count)
+ embeds_one(:value_coding, Epiviewpoint.R4.Coding)
+ embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:value_quantity)
+ |> cast_embed(:value_expression)
+ |> cast_embed(:value_attachment)
+ |> cast_embed(:value_identifier)
+ |> cast_embed(:value_sampled_data)
+ |> cast_embed(:value_parameter_definition)
+ |> cast_embed(:value_timing)
+ |> cast_embed(:value_reference)
+ |> cast_embed(:value_contact_point)
+ |> cast_embed(:value_age)
+ |> cast_embed(:value_meta)
+ |> cast_embed(:value_annotation)
+ |> cast_embed(:value_money)
+ |> cast_embed(:value_usage_context)
+ |> cast_embed(:value_related_artifact)
+ |> cast_embed(:value_contact_detail)
+ |> cast_embed(:value_ratio)
+ |> cast_embed(:value_distance)
+ |> cast_embed(:value_duration)
+ |> cast_embed(:value_human_name)
+ |> cast_embed(:value_period)
+ |> cast_embed(:value_range)
+ |> cast_embed(:value_dosage)
+ |> cast_embed(:value_contributor)
+ |> cast_embed(:value_address)
+ |> cast_embed(:value_signature)
+ |> cast_embed(:value_trigger_definition)
+ |> cast_embed(:value_data_requirement)
+ |> cast_embed(:value_count)
+ |> cast_embed(:value_coding)
+ |> cast_embed(:value_codeable_concept)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/human_name.ex b/lib/epiviewpoint/r4/human_name.ex
new file mode 100644
index 00000000..8ed99171
--- /dev/null
+++ b/lib/epiviewpoint/r4/human_name.ex
@@ -0,0 +1,57 @@
+defmodule Epiviewpoint.R4.HumanName do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :family,
+ :given,
+ :id,
+ :prefix,
+ :suffix,
+ :text,
+ :use
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:family, :string)
+ field(:text, :string)
+
+ field(:given, {:array, :string})
+ field(:prefix, {:array, :string})
+ field(:suffix, {:array, :string})
+
+ # Enum
+ field(:use, Ecto.Enum,
+ values: [
+ :usual,
+ :official,
+ :temp,
+ :nickname,
+ :anonymous,
+ :old,
+ :maiden
+ ]
+ )
+
+ # Embed One
+ embeds_one(:period, Epiviewpoint.R4.Period)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:period)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/identifier.ex b/lib/epiviewpoint/r4/identifier.ex
new file mode 100644
index 00000000..d2471bc7
--- /dev/null
+++ b/lib/epiviewpoint/r4/identifier.ex
@@ -0,0 +1,52 @@
+defmodule Epiviewpoint.R4.Identifier do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :system,
+ :use,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:system, :string)
+ field(:value, :string)
+
+ # Enum
+ field(:use, Ecto.Enum,
+ values: [
+ :usual,
+ :official,
+ :temp,
+ :secondary,
+ :old
+ ]
+ )
+
+ # Embed One
+ embeds_one(:assigner, Epiviewpoint.R4.Reference)
+ embeds_one(:period, Epiviewpoint.R4.Period)
+ embeds_one(:type, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:assigner)
+ |> cast_embed(:period)
+ |> cast_embed(:type)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/meta.ex b/lib/epiviewpoint/r4/meta.ex
new file mode 100644
index 00000000..8632b8b7
--- /dev/null
+++ b/lib/epiviewpoint/r4/meta.ex
@@ -0,0 +1,41 @@
+defmodule Epiviewpoint.R4.Meta do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :last_updated,
+ :profile,
+ :source,
+ :version_id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:last_updated, :utc_datetime_usec)
+ field(:source, :string)
+ field(:version_id, :binary_id)
+
+ field(:profile, {:array, :string})
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:security, Epiviewpoint.R4.Coding)
+ embeds_many(:tag, Epiviewpoint.R4.Coding)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> cast_embed(:security)
+ |> cast_embed(:tag)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/money.ex b/lib/epiviewpoint/r4/money.ex
new file mode 100644
index 00000000..6014c0af
--- /dev/null
+++ b/lib/epiviewpoint/r4/money.ex
@@ -0,0 +1,32 @@
+defmodule Epiviewpoint.R4.Money do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :currency,
+ :id,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:currency, :string)
+ field(:value, :decimal)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/narrative.ex b/lib/epiviewpoint/r4/narrative.ex
new file mode 100644
index 00000000..6798aa4d
--- /dev/null
+++ b/lib/epiviewpoint/r4/narrative.ex
@@ -0,0 +1,43 @@
+defmodule Epiviewpoint.R4.Narrative do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :div,
+ :id,
+ :status
+ ]
+ @required_fields [
+ :div
+ ]
+
+ embedded_schema do
+ # Fields
+ field(:div, :string)
+
+ # Enum
+ field(:status, Ecto.Enum,
+ values: [
+ :generated,
+ :extensions,
+ :additional,
+ :empty
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/observation.ex b/lib/epiviewpoint/r4/observation.ex
new file mode 100644
index 00000000..81449b4c
--- /dev/null
+++ b/lib/epiviewpoint/r4/observation.ex
@@ -0,0 +1,184 @@
+defmodule Epiviewpoint.R4.Observation do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :value_time,
+ :effective_date_time,
+ :value_date_time,
+ :effective_instant,
+ :value_string,
+ :language,
+ :value_integer,
+ :implicit_rules,
+ :status,
+ :id,
+ :issued,
+ :value_boolean
+ ]
+ @required_fields []
+
+ @primary_key {:id, :binary_id, autogenerate: true}
+ schema "observation" do
+ # Constants
+ field(:resource_type, :string, virtual: true, default: "Observation")
+
+ # Fields
+ field(:value_time, :string)
+ field(:effective_date_time, :string)
+ field(:value_date_time, :string)
+ field(:effective_instant, :string)
+ field(:value_string, :string)
+ field(:language, :string)
+ field(:value_integer, :integer)
+ field(:implicit_rules, :string)
+ field(:issued, :utc_datetime_usec)
+ field(:value_boolean, :boolean)
+
+ # Enum
+ field(:status, Ecto.Enum,
+ values: [
+ :registered,
+ :preliminary,
+ :final,
+ :amended,
+ :corrected,
+ :cancelled,
+ :entered_in_error,
+ :unknown
+ ]
+ )
+
+ # Embed One
+ embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
+ embeds_one(:effective_timing, Epiviewpoint.R4.Timing)
+ embeds_one(:value_sampled_data, Epiviewpoint.R4.SampledData)
+ embeds_one(:specimen, Epiviewpoint.R4.Reference)
+ embeds_one(:effective_period, Epiviewpoint.R4.Period)
+ embeds_one(:value_ratio, Epiviewpoint.R4.Ratio)
+ embeds_one(:encounter, Epiviewpoint.R4.Reference)
+ embeds_one(:code, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:subject, Epiviewpoint.R4.Reference)
+ embeds_one(:data_absent_reason, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:text, Epiviewpoint.R4.Narrative)
+ embeds_one(:body_site, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:meta, Epiviewpoint.R4.Meta)
+ embeds_one(:value_period, Epiviewpoint.R4.Period)
+ embeds_one(:value_range, Epiviewpoint.R4.Range)
+ embeds_one(:method, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:device, Epiviewpoint.R4.Reference)
+ embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:contained, Epiviewpoint.R4.ResourceList)
+ embeds_many(:reference_range, Epiviewpoint.R4.Observation.ReferenceRange)
+ embeds_many(:derived_from, Epiviewpoint.R4.Reference)
+ embeds_many(:focus, Epiviewpoint.R4.Reference)
+ embeds_many(:based_on, Epiviewpoint.R4.Reference)
+ embeds_many(:component, Epiviewpoint.R4.Observation.Component)
+ embeds_many(:performer, Epiviewpoint.R4.Reference)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:identifier, Epiviewpoint.R4.Identifier)
+ embeds_many(:part_of, Epiviewpoint.R4.Reference)
+ embeds_many(:has_member, Epiviewpoint.R4.Reference)
+ embeds_many(:category, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:note, Epiviewpoint.R4.Annotation)
+ embeds_many(:interpretation, Epiviewpoint.R4.CodeableConcept)
+ end
+
+ def choices("effective") do
+ [:effective_date_time, :effective_period, :effective_timing, :effective_instant]
+ end
+
+ def choices("effectivedateTime"), do: :error
+
+ def choices("effectivePeriod"), do: :error
+
+ def choices("effectiveTiming"), do: :error
+
+ def choices("effectiveinstant"), do: :error
+
+ def choices("value") do
+ [
+ :value_quantity,
+ :value_codeable_concept,
+ :value_string,
+ :value_boolean,
+ :value_integer,
+ :value_range,
+ :value_ratio,
+ :value_sampled_data,
+ :value_time,
+ :value_date_time,
+ :value_period
+ ]
+ end
+
+ def choices("valueQuantity"), do: :error
+
+ def choices("valueCodeableConcept"), do: :error
+
+ def choices("valuestring"), do: :error
+
+ def choices("valueboolean"), do: :error
+
+ def choices("valueinteger"), do: :error
+
+ def choices("valueRange"), do: :error
+
+ def choices("valueRatio"), do: :error
+
+ def choices("valueSampledData"), do: :error
+
+ def choices("valuetime"), do: :error
+
+ def choices("valuedateTime"), do: :error
+
+ def choices("valuePeriod"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+ def path, do: "/Observation"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:value_quantity)
+ |> cast_embed(:effective_timing)
+ |> cast_embed(:value_sampled_data)
+ |> cast_embed(:specimen)
+ |> cast_embed(:effective_period)
+ |> cast_embed(:value_ratio)
+ |> cast_embed(:encounter)
+ |> cast_embed(:code)
+ |> cast_embed(:subject)
+ |> cast_embed(:data_absent_reason)
+ |> cast_embed(:text)
+ |> cast_embed(:body_site)
+ |> cast_embed(:meta)
+ |> cast_embed(:value_period)
+ |> cast_embed(:value_range)
+ |> cast_embed(:method)
+ |> cast_embed(:device)
+ |> cast_embed(:value_codeable_concept)
+ |> cast_embed(:extension)
+ |> cast_embed(:contained)
+ |> cast_embed(:reference_range)
+ |> cast_embed(:derived_from)
+ |> cast_embed(:focus)
+ |> cast_embed(:based_on)
+ |> cast_embed(:component)
+ |> cast_embed(:performer)
+ |> cast_embed(:modifier_extension)
+ |> cast_embed(:identifier)
+ |> cast_embed(:part_of)
+ |> cast_embed(:has_member)
+ |> cast_embed(:category)
+ |> cast_embed(:note)
+ |> cast_embed(:interpretation)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/observation/component.ex b/lib/epiviewpoint/r4/observation/component.ex
new file mode 100644
index 00000000..a72301fa
--- /dev/null
+++ b/lib/epiviewpoint/r4/observation/component.ex
@@ -0,0 +1,100 @@
+defmodule Epiviewpoint.R4.Observation.Component do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :value_boolean,
+ :value_date_time,
+ :value_integer,
+ :value_string,
+ :value_time
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:value_boolean, :boolean)
+ field(:value_date_time, :string)
+ field(:value_integer, :integer)
+ field(:value_string, :string)
+ field(:value_time, :string)
+
+ # Embed One
+ embeds_one(:code, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:data_absent_reason, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:value_period, Epiviewpoint.R4.Period)
+ embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
+ embeds_one(:value_range, Epiviewpoint.R4.Range)
+ embeds_one(:value_ratio, Epiviewpoint.R4.Ratio)
+ embeds_one(:value_sampled_data, Epiviewpoint.R4.SampledData)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:interpretation, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:reference_range, Epiviewpoint.R4.Observation.ReferenceRange)
+ end
+
+ def choices("value") do
+ [
+ :value_quantity,
+ :value_codeable_concept,
+ :value_string,
+ :value_boolean,
+ :value_integer,
+ :value_range,
+ :value_ratio,
+ :value_sampled_data,
+ :value_time,
+ :value_date_time,
+ :value_period
+ ]
+ end
+
+ def choices("valueQuantity"), do: :error
+
+ def choices("valueCodeableConcept"), do: :error
+
+ def choices("valuestring"), do: :error
+
+ def choices("valueboolean"), do: :error
+
+ def choices("valueinteger"), do: :error
+
+ def choices("valueRange"), do: :error
+
+ def choices("valueRatio"), do: :error
+
+ def choices("valueSampledData"), do: :error
+
+ def choices("valuetime"), do: :error
+
+ def choices("valuedateTime"), do: :error
+
+ def choices("valuePeriod"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:code)
+ |> cast_embed(:data_absent_reason)
+ |> cast_embed(:value_codeable_concept)
+ |> cast_embed(:value_period)
+ |> cast_embed(:value_quantity)
+ |> cast_embed(:value_range)
+ |> cast_embed(:value_ratio)
+ |> cast_embed(:value_sampled_data)
+ |> cast_embed(:extension)
+ |> cast_embed(:interpretation)
+ |> cast_embed(:modifier_extension)
+ |> cast_embed(:reference_range)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/observation/reference_range.ex b/lib/epiviewpoint/r4/observation/reference_range.ex
new file mode 100644
index 00000000..94f11e5b
--- /dev/null
+++ b/lib/epiviewpoint/r4/observation/reference_range.ex
@@ -0,0 +1,44 @@
+defmodule Epiviewpoint.R4.Observation.ReferenceRange do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :text
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:text, :string)
+
+ # Embed One
+ embeds_one(:age, Epiviewpoint.R4.Range)
+ embeds_one(:high, Epiviewpoint.R4.Quantity)
+ embeds_one(:low, Epiviewpoint.R4.Quantity)
+ embeds_one(:type, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:applies_to, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:age)
+ |> cast_embed(:high)
+ |> cast_embed(:low)
+ |> cast_embed(:type)
+ |> cast_embed(:applies_to)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/organization.ex b/lib/epiviewpoint/r4/organization.ex
new file mode 100644
index 00000000..ebb3f13c
--- /dev/null
+++ b/lib/epiviewpoint/r4/organization.ex
@@ -0,0 +1,68 @@
+defmodule Epiviewpoint.R4.Organization do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :active,
+ :alias,
+ :id,
+ :implicit_rules,
+ :language,
+ :name
+ ]
+ @required_fields []
+
+ @primary_key {:id, :binary_id, autogenerate: true}
+ schema "organization" do
+ # Constants
+ field(:resource_type, :string, virtual: true, default: "Organization")
+
+ # Fields
+ field(:active, :boolean)
+ field(:implicit_rules, :string)
+ field(:language, :string)
+ field(:name, :string)
+
+ field(:alias, {:array, :string})
+
+ # Embed One
+ embeds_one(:meta, Epiviewpoint.R4.Meta)
+ embeds_one(:part_of, Epiviewpoint.R4.Reference)
+ embeds_one(:text, Epiviewpoint.R4.Narrative)
+
+ # Embed Many
+ embeds_many(:address, Epiviewpoint.R4.Address)
+ embeds_many(:contact, Epiviewpoint.R4.Organization.Contact)
+ embeds_many(:contained, Epiviewpoint.R4.ResourceList)
+ embeds_many(:endpoint, Epiviewpoint.R4.Reference)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:identifier, Epiviewpoint.R4.Identifier)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ embeds_many(:type, Epiviewpoint.R4.CodeableConcept)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+ def path, do: "/Organization"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:meta)
+ |> cast_embed(:part_of)
+ |> cast_embed(:text)
+ |> cast_embed(:address)
+ |> cast_embed(:contact)
+ |> cast_embed(:contained)
+ |> cast_embed(:endpoint)
+ |> cast_embed(:extension)
+ |> cast_embed(:identifier)
+ |> cast_embed(:modifier_extension)
+ |> cast_embed(:telecom)
+ |> cast_embed(:type)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/organization/contact.ex b/lib/epiviewpoint/r4/organization/contact.ex
new file mode 100644
index 00000000..a1ba4fa3
--- /dev/null
+++ b/lib/epiviewpoint/r4/organization/contact.ex
@@ -0,0 +1,38 @@
+defmodule Epiviewpoint.R4.Organization.Contact do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Embed One
+ embeds_one(:address, Epiviewpoint.R4.Address)
+ embeds_one(:name, Epiviewpoint.R4.HumanName)
+ embeds_one(:purpose, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:address)
+ |> cast_embed(:name)
+ |> cast_embed(:purpose)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> cast_embed(:telecom)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/parameter_definition.ex b/lib/epiviewpoint/r4/parameter_definition.ex
new file mode 100644
index 00000000..6c4bd521
--- /dev/null
+++ b/lib/epiviewpoint/r4/parameter_definition.ex
@@ -0,0 +1,42 @@
+defmodule Epiviewpoint.R4.ParameterDefinition do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :documentation,
+ :id,
+ :max,
+ :min,
+ :name,
+ :profile,
+ :type,
+ :use
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:documentation, :string)
+ field(:max, :string)
+ field(:min, :integer)
+ field(:name, :string)
+ field(:profile, :string)
+ field(:type, :string)
+ field(:use, :string)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/patient.ex b/lib/epiviewpoint/r4/patient.ex
new file mode 100644
index 00000000..e760829b
--- /dev/null
+++ b/lib/epiviewpoint/r4/patient.ex
@@ -0,0 +1,108 @@
+defmodule Epiviewpoint.R4.Patient do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :active,
+ :multiple_birth_boolean,
+ :language,
+ :implicit_rules,
+ :birth_date,
+ :multiple_birth_integer,
+ :id,
+ :deceased_boolean,
+ :gender,
+ :deceased_date_time
+ ]
+ @required_fields []
+
+ @primary_key {:id, :binary_id, autogenerate: true}
+ schema "patient" do
+ # Constants
+ field(:resource_type, :string, virtual: true, default: "Patient")
+
+ # Fields
+ field(:active, :boolean)
+ field(:multiple_birth_boolean, :boolean)
+ field(:language, :string)
+ field(:implicit_rules, :string)
+ field(:birth_date, :date)
+ field(:multiple_birth_integer, :integer)
+ field(:deceased_boolean, :boolean)
+ field(:deceased_date_time, :string)
+
+ # Enum
+ field(:gender, Ecto.Enum,
+ values: [
+ :male,
+ :female,
+ :other,
+ :unknown
+ ]
+ )
+
+ # Embed One
+ embeds_one(:marital_status, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:managing_organization, Epiviewpoint.R4.Reference)
+ embeds_one(:text, Epiviewpoint.R4.Narrative)
+ embeds_one(:meta, Epiviewpoint.R4.Meta)
+
+ # Embed Many
+ embeds_many(:photo, Epiviewpoint.R4.Attachment)
+ embeds_many(:communication, Epiviewpoint.R4.Patient.Communication)
+ embeds_many(:name, Epiviewpoint.R4.HumanName)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ embeds_many(:contained, Epiviewpoint.R4.ResourceList)
+ embeds_many(:link, Epiviewpoint.R4.Patient.Link)
+ embeds_many(:contact, Epiviewpoint.R4.Patient.Contact)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:identifier, Epiviewpoint.R4.Identifier)
+ embeds_many(:general_practitioner, Epiviewpoint.R4.Reference)
+ embeds_many(:address, Epiviewpoint.R4.Address)
+ end
+
+ def choices("deceased") do
+ [:deceased_boolean, :deceased_date_time]
+ end
+
+ def choices("deceasedboolean"), do: :error
+
+ def choices("deceaseddateTime"), do: :error
+
+ def choices("multipleBirth") do
+ [:multipleBirth_boolean, :multipleBirth_integer]
+ end
+
+ def choices("multipleBirthboolean"), do: :error
+
+ def choices("multipleBirthinteger"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+ def path, do: "/Patient"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:marital_status)
+ |> cast_embed(:managing_organization)
+ |> cast_embed(:text)
+ |> cast_embed(:meta)
+ |> cast_embed(:photo)
+ |> cast_embed(:communication)
+ |> cast_embed(:name)
+ |> cast_embed(:extension)
+ |> cast_embed(:telecom)
+ |> cast_embed(:contained)
+ |> cast_embed(:link)
+ |> cast_embed(:contact)
+ |> cast_embed(:modifier_extension)
+ |> cast_embed(:identifier)
+ |> cast_embed(:general_practitioner)
+ |> cast_embed(:address)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/patient/communication.ex b/lib/epiviewpoint/r4/patient/communication.ex
new file mode 100644
index 00000000..11aa016b
--- /dev/null
+++ b/lib/epiviewpoint/r4/patient/communication.ex
@@ -0,0 +1,36 @@
+defmodule Epiviewpoint.R4.Patient.Communication do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :preferred
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:preferred, :boolean)
+
+ # Embed One
+ embeds_one(:language, Epiviewpoint.R4.CodeableConcept)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:language)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/patient/contact.ex b/lib/epiviewpoint/r4/patient/contact.ex
new file mode 100644
index 00000000..d552e4fa
--- /dev/null
+++ b/lib/epiviewpoint/r4/patient/contact.ex
@@ -0,0 +1,53 @@
+defmodule Epiviewpoint.R4.Patient.Contact do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :gender,
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Enum
+ field(:gender, Ecto.Enum,
+ values: [
+ :male,
+ :female,
+ :other,
+ :unknown
+ ]
+ )
+
+ # Embed One
+ embeds_one(:address, Epiviewpoint.R4.Address)
+ embeds_one(:name, Epiviewpoint.R4.HumanName)
+ embeds_one(:organization, Epiviewpoint.R4.Reference)
+ embeds_one(:period, Epiviewpoint.R4.Period)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:relationship, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:address)
+ |> cast_embed(:name)
+ |> cast_embed(:organization)
+ |> cast_embed(:period)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> cast_embed(:relationship)
+ |> cast_embed(:telecom)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/patient/link.ex b/lib/epiviewpoint/r4/patient/link.ex
new file mode 100644
index 00000000..6aa952d1
--- /dev/null
+++ b/lib/epiviewpoint/r4/patient/link.ex
@@ -0,0 +1,43 @@
+defmodule Epiviewpoint.R4.Patient.Link do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :type
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Enum
+ field(:type, Ecto.Enum,
+ values: [
+ :replaced_by,
+ :replaces,
+ :refer,
+ :seealso
+ ]
+ )
+
+ # Embed One
+ embeds_one(:other, Epiviewpoint.R4.Reference)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:other)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/period.ex b/lib/epiviewpoint/r4/period.ex
new file mode 100644
index 00000000..b4de40d4
--- /dev/null
+++ b/lib/epiviewpoint/r4/period.ex
@@ -0,0 +1,32 @@
+defmodule Epiviewpoint.R4.Period do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :end,
+ :id,
+ :start
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:end, :utc_datetime_usec)
+ field(:start, :utc_datetime_usec)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/quantity.ex b/lib/epiviewpoint/r4/quantity.ex
new file mode 100644
index 00000000..22aab8b5
--- /dev/null
+++ b/lib/epiviewpoint/r4/quantity.ex
@@ -0,0 +1,47 @@
+defmodule Epiviewpoint.R4.Quantity do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :code,
+ :comparator,
+ :id,
+ :system,
+ :unit,
+ :value
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:code, :string)
+ field(:system, :string)
+ field(:unit, :string)
+ field(:value, :decimal)
+
+ # Enum
+ field(:comparator, Ecto.Enum,
+ values: [
+ :<,
+ :<=,
+ :>=,
+ :>
+ ]
+ )
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/range.ex b/lib/epiviewpoint/r4/range.ex
new file mode 100644
index 00000000..d51e9c8e
--- /dev/null
+++ b/lib/epiviewpoint/r4/range.ex
@@ -0,0 +1,32 @@
+defmodule Epiviewpoint.R4.Range do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Embed One
+ embeds_one(:high, Epiviewpoint.R4.Quantity)
+ embeds_one(:low, Epiviewpoint.R4.Quantity)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:high)
+ |> cast_embed(:low)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/ratio.ex b/lib/epiviewpoint/r4/ratio.ex
new file mode 100644
index 00000000..50a3790f
--- /dev/null
+++ b/lib/epiviewpoint/r4/ratio.ex
@@ -0,0 +1,32 @@
+defmodule Epiviewpoint.R4.Ratio do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Embed One
+ embeds_one(:denominator, Epiviewpoint.R4.Quantity)
+ embeds_one(:numerator, Epiviewpoint.R4.Quantity)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:denominator)
+ |> cast_embed(:numerator)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/reference.ex b/lib/epiviewpoint/r4/reference.ex
new file mode 100644
index 00000000..92b83c7b
--- /dev/null
+++ b/lib/epiviewpoint/r4/reference.ex
@@ -0,0 +1,38 @@
+defmodule Epiviewpoint.R4.Reference do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :display,
+ :id,
+ :reference,
+ :type
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:display, :string)
+ field(:reference, :string)
+ field(:type, :string)
+
+ # Embed One
+ embeds_one(:identifier, Epiviewpoint.R4.Identifier)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:identifier)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/related_artifact.ex b/lib/epiviewpoint/r4/related_artifact.ex
new file mode 100644
index 00000000..faabd573
--- /dev/null
+++ b/lib/epiviewpoint/r4/related_artifact.ex
@@ -0,0 +1,57 @@
+defmodule Epiviewpoint.R4.RelatedArtifact do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :citation,
+ :display,
+ :id,
+ :label,
+ :resource,
+ :type,
+ :url
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:citation, :string)
+ field(:display, :string)
+ field(:label, :string)
+ field(:resource, :string)
+ field(:url, :string)
+
+ # Enum
+ field(:type, Ecto.Enum,
+ values: [
+ :documentation,
+ :justification,
+ :citation,
+ :predecessor,
+ :successor,
+ :derived_from,
+ :depends_on,
+ :composed_of
+ ]
+ )
+
+ # Embed One
+ embeds_one(:document, Epiviewpoint.R4.Attachment)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:document)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/resource_list.ex b/lib/epiviewpoint/r4/resource_list.ex
new file mode 100644
index 00000000..1fb62b10
--- /dev/null
+++ b/lib/epiviewpoint/r4/resource_list.ex
@@ -0,0 +1,21 @@
+defmodule Epiviewpoint.R4.ResourceList do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields []
+ @required_fields []
+
+ embedded_schema do
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/sampled_data.ex b/lib/epiviewpoint/r4/sampled_data.ex
new file mode 100644
index 00000000..4ee45d48
--- /dev/null
+++ b/lib/epiviewpoint/r4/sampled_data.ex
@@ -0,0 +1,44 @@
+defmodule Epiviewpoint.R4.SampledData do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :data,
+ :dimensions,
+ :factor,
+ :id,
+ :lower_limit,
+ :period,
+ :upper_limit
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:data, :string)
+ field(:dimensions, :integer)
+ field(:factor, :decimal)
+ field(:lower_limit, :decimal)
+ field(:period, :decimal)
+ field(:upper_limit, :decimal)
+
+ # Embed One
+ embeds_one(:origin, Epiviewpoint.R4.Quantity)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:origin)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/signature.ex b/lib/epiviewpoint/r4/signature.ex
new file mode 100644
index 00000000..7dd9298d
--- /dev/null
+++ b/lib/epiviewpoint/r4/signature.ex
@@ -0,0 +1,44 @@
+defmodule Epiviewpoint.R4.Signature do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :data,
+ :id,
+ :sig_format,
+ :target_format,
+ :when
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:data, :string)
+ field(:sig_format, :string)
+ field(:target_format, :string)
+ field(:when, :utc_datetime_usec)
+
+ # Embed One
+ embeds_one(:on_behalf_of, Epiviewpoint.R4.Reference)
+ embeds_one(:who, Epiviewpoint.R4.Reference)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:type, Epiviewpoint.R4.Coding)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:on_behalf_of)
+ |> cast_embed(:who)
+ |> cast_embed(:extension)
+ |> cast_embed(:type)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/timing.ex b/lib/epiviewpoint/r4/timing.ex
new file mode 100644
index 00000000..77524b79
--- /dev/null
+++ b/lib/epiviewpoint/r4/timing.ex
@@ -0,0 +1,37 @@
+defmodule Epiviewpoint.R4.Timing do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :event,
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ field(:event, {:array, :utc_datetime_usec})
+
+ # Embed One
+ embeds_one(:code, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:repeat, Epiviewpoint.R4.Timing.Repeat)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:code)
+ |> cast_embed(:repeat)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/timing/repeat.ex b/lib/epiviewpoint/r4/timing/repeat.ex
new file mode 100644
index 00000000..321f3071
--- /dev/null
+++ b/lib/epiviewpoint/r4/timing/repeat.ex
@@ -0,0 +1,100 @@
+defmodule Epiviewpoint.R4.Timing.Repeat do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :day_of_week,
+ :duration_unit,
+ :count,
+ :count_max,
+ :period_unit,
+ :when,
+ :frequency,
+ :period_max,
+ :duration_max,
+ :time_of_day,
+ :duration,
+ :frequency_max,
+ :offset,
+ :period,
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:count, :integer)
+ field(:count_max, :integer)
+ field(:frequency, :integer)
+ field(:period_max, :decimal)
+ field(:duration_max, :decimal)
+ field(:duration, :decimal)
+ field(:frequency_max, :integer)
+ field(:offset, :integer)
+ field(:period, :decimal)
+
+ field(:day_of_week, {:array, :string})
+ field(:when, {:array, :string})
+ field(:time_of_day, {:array, :time_usec})
+
+ # Enum
+ field(:duration_unit, Ecto.Enum,
+ values: [
+ :s,
+ :min,
+ :h,
+ :d,
+ :wk,
+ :mo,
+ :a
+ ]
+ )
+
+ field(:period_unit, Ecto.Enum,
+ values: [
+ :s,
+ :min,
+ :h,
+ :d,
+ :wk,
+ :mo,
+ :a
+ ]
+ )
+
+ # Embed One
+ embeds_one(:bounds_duration, Epiviewpoint.R4.Duration)
+ embeds_one(:bounds_range, Epiviewpoint.R4.Range)
+ embeds_one(:bounds_period, Epiviewpoint.R4.Period)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("bounds") do
+ [:bounds_duration, :bounds_range, :bounds_period]
+ end
+
+ def choices("boundsDuration"), do: :error
+
+ def choices("boundsRange"), do: :error
+
+ def choices("boundsPeriod"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:bounds_duration)
+ |> cast_embed(:bounds_range)
+ |> cast_embed(:bounds_period)
+ |> cast_embed(:extension)
+ |> cast_embed(:modifier_extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/trigger_definition.ex b/lib/epiviewpoint/r4/trigger_definition.ex
new file mode 100644
index 00000000..febc5075
--- /dev/null
+++ b/lib/epiviewpoint/r4/trigger_definition.ex
@@ -0,0 +1,71 @@
+defmodule Epiviewpoint.R4.TriggerDefinition do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id,
+ :name,
+ :timing_date,
+ :timing_date_time,
+ :type
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Fields
+ field(:name, :string)
+ field(:timing_date, :string)
+ field(:timing_date_time, :string)
+
+ # Enum
+ field(:type, Ecto.Enum,
+ values: [
+ :named_event,
+ :periodic,
+ :data_changed,
+ :data_added,
+ :data_modified,
+ :data_removed,
+ :data_accessed,
+ :data_access_ended
+ ]
+ )
+
+ # Embed One
+ embeds_one(:condition, Epiviewpoint.R4.Expression)
+ embeds_one(:timing_reference, Epiviewpoint.R4.Reference)
+ embeds_one(:timing_timing, Epiviewpoint.R4.Timing)
+
+ # Embed Many
+ embeds_many(:data, Epiviewpoint.R4.DataRequirement)
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("timing") do
+ [:timing_timing, :timing_reference, :timing_date, :timing_date_time]
+ end
+
+ def choices("timingTiming"), do: :error
+
+ def choices("timingReference"), do: :error
+
+ def choices("timingdate"), do: :error
+
+ def choices("timingdateTime"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:condition)
+ |> cast_embed(:timing_reference)
+ |> cast_embed(:timing_timing)
+ |> cast_embed(:data)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint/r4/usage_context.ex b/lib/epiviewpoint/r4/usage_context.ex
new file mode 100644
index 00000000..b96c15a6
--- /dev/null
+++ b/lib/epiviewpoint/r4/usage_context.ex
@@ -0,0 +1,50 @@
+defmodule Epiviewpoint.R4.UsageContext do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @fields [
+ :id
+ ]
+ @required_fields []
+
+ embedded_schema do
+ # Embed One
+ embeds_one(:code, Epiviewpoint.R4.Coding)
+ embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
+ embeds_one(:value_range, Epiviewpoint.R4.Range)
+ embeds_one(:value_reference, Epiviewpoint.R4.Reference)
+
+ # Embed Many
+ embeds_many(:extension, Epiviewpoint.R4.Extension)
+ end
+
+ def choices("value") do
+ [:value_codeable_concept, :value_quantity, :value_range, :value_reference]
+ end
+
+ def choices("valueCodeableConcept"), do: :error
+
+ def choices("valueQuantity"), do: :error
+
+ def choices("valueRange"), do: :error
+
+ def choices("valueReference"), do: :error
+
+ def choices(_), do: nil
+
+ def version_namespace, do: Epiviewpoint.R4
+ def version, do: "R4"
+
+ def changeset(data \\ %__MODULE__{}, attrs) do
+ data
+ |> cast(attrs, @fields)
+ |> cast_embed(:code)
+ |> cast_embed(:value_codeable_concept)
+ |> cast_embed(:value_quantity)
+ |> cast_embed(:value_range)
+ |> cast_embed(:value_reference)
+ |> cast_embed(:extension)
+ |> validate_required(@required_fields)
+ end
+end
\ No newline at end of file
diff --git a/lib/epiviewpoint_web/controllers/import_controller.ex b/lib/epiviewpoint_web/controllers/import_controller.ex
index 20706d19..a8efc1c7 100644
--- a/lib/epiviewpoint_web/controllers/import_controller.ex
+++ b/lib/epiviewpoint_web/controllers/import_controller.ex
@@ -41,6 +41,32 @@ defmodule EpiViewpointWeb.ImportController do
end
end
+ def create_bulk_fhir(conn, %{"files" => plug_uploads}) do
+
+ result = UploadedFile.from_plug_uploads(plug_uploads) |> Cases.import_bulk_fhir_lab_results(conn.assigns.current_user)
+
+ case result do
+ {:ok, import_info} ->
+ {_imported_people, popped_import_info} = import_info |> Map.pop(:imported_people)
+
+ conn
+ |> Session.set_last_file_import_info(popped_import_info)
+ |> redirect(to: ~p"/import/complete")
+
+ {:error, [user_readable: user_readable_message]} ->
+ conn
+ |> Session.set_import_error_message(user_readable_message)
+ |> redirect(to: ~p"/import/start")
+
+ {:error, %DateParsingError{user_readable: user_readable_message}} ->
+ conn
+ |> Session.set_import_error_message(user_readable_message)
+ |> redirect(to: ~p"/import/start")
+ end
+
+ end
+
+
def show(conn, _params) do
conn
|> assign_defaults(@common_assigns)
diff --git a/lib/epiviewpoint_web/live/import_live.html.heex b/lib/epiviewpoint_web/live/import_live.html.heex
index 59c83bdf..96ff9085 100644
--- a/lib/epiviewpoint_web/live/import_live.html.heex
+++ b/lib/epiviewpoint_web/live/import_live.html.heex
@@ -14,4 +14,13 @@
type="submit"
value="Upload"
/>
+
+ Choose bulk FHIR NDJSON files from your computer, click “Upload”, and then wait for the file to upload.
+
+ <%= form_tag("/import/upload_bulk_fhir", multipart: true, method: :post) %>
diff --git a/lib/epiviewpoint_web/router.ex b/lib/epiviewpoint_web/router.ex
index 44e0b9df..af77d70f 100644
--- a/lib/epiviewpoint_web/router.ex
+++ b/lib/epiviewpoint_web/router.ex
@@ -56,6 +56,7 @@ defmodule EpiViewpointWeb.Router do
live "/import/start", ImportLive, as: :import_start
get "/import/complete", ImportController, :show
post "/import/upload", ImportController, :create
+ post "/import/upload_bulk_fhir", ImportController, :create_bulk_fhir
live "/case-investigations/:case_investigation_id/contact", CaseInvestigationContactLive, as: :create_case_investigation_contact
live "/case-investigations/:case_investigation_id/contact/:id", CaseInvestigationContactLive, as: :edit_case_investigation_contact
diff --git a/lib/epiviewpoint_web/uploaded_file.ex b/lib/epiviewpoint_web/uploaded_file.ex
index 70a44c20..1967fed0 100644
--- a/lib/epiviewpoint_web/uploaded_file.ex
+++ b/lib/epiviewpoint_web/uploaded_file.ex
@@ -3,4 +3,8 @@ defmodule EpiViewpointWeb.UploadedFile do
def from_plug_upload(%{path: path, filename: file_name}) do
%{file_name: Zarex.sanitize(file_name), contents: File.read!(path)}
end
+
+ def from_plug_uploads(plug_uploads) do
+ Enum.map(plug_uploads, &from_plug_upload/1)
+ end
end
diff --git a/mix.exs b/mix.exs
index ca4885e2..a9fa3dd9 100644
--- a/mix.exs
+++ b/mix.exs
@@ -56,6 +56,7 @@ defmodule EpiViewpoint.MixProject do
{:gettext, "~> 0.11"},
{:inflex, "~> 2.1"},
{:jason, "~> 1.0"},
+ {:kindling, "~> 1.0.1"},
{:logger_json, "~> 4.3"},
{:mix_audit, "~> 1.0", runtime: false},
{:mix_test_watch, "~> 1.0", only: :dev, runtime: false},
diff --git a/mix.lock b/mix.lock
index 2467b680..07177a7a 100644
--- a/mix.lock
+++ b/mix.lock
@@ -20,21 +20,28 @@
"explorer": {:hex, :explorer, "0.9.1", "9c6f175dfd2fa2f432d5fe9a86b81875438a9a1110af5b952c284842bee434e4", [:mix], [{:adbc, "~> 0.1", [hex: :adbc, repo: "hexpm", optional: true]}, {:aws_signature, "~> 0.3", [hex: :aws_signature, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:flame, "~> 0.3", [hex: :flame, repo: "hexpm", optional: true]}, {:fss, "~> 0.1", [hex: :fss, repo: "hexpm", optional: false]}, {:nx, "~> 0.4", [hex: :nx, repo: "hexpm", optional: true]}, {:rustler, "~> 0.34.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}, {:table, "~> 0.1.2", [hex: :table, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1 or ~> 4.0.0", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "d88ec0e78f904c5eaf0b37c4a0ce4632de133515f3740a29fbddd2c0d0a78e77"},
"expo": {:hex, :expo, "0.4.1", "1c61d18a5df197dfda38861673d392e642649a9cef7694d2f97a587b2cfb319b", [:mix], [], "hexpm", "2ff7ba7a798c8c543c12550fa0e2cbc81b95d4974c65855d8d15ba7b37a1ce47"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
+ "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
"fss": {:hex, :fss, "0.1.1", "9db2344dbbb5d555ce442ac7c2f82dd975b605b50d169314a20f08ed21e08642", [:mix], [], "hexpm", "78ad5955c7919c3764065b21144913df7515d52e228c09427a004afe9c1a16b0"},
"gettext": {:hex, :gettext, "0.23.1", "821e619a240e6000db2fc16a574ef68b3bd7fe0167ccc264a81563cc93e67a31", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "19d744a36b809d810d610b57c27b934425859d158ebd56561bc41f7eeb8795db"},
"hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"},
+ "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
+ "kindling": {:hex, :kindling, "1.0.1", "1ddab6923d66ae400b5a4f130391546b6d3245ee072fbda4d3279e8708db0f1d", [:mix], [{:ecto, "~> 3.11", [hex: :ecto, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:recase, "~> 0.7.0", [hex: :recase, repo: "hexpm", optional: false]}, {:req, "~> 0.4.11", [hex: :req, repo: "hexpm", optional: false]}, {:saxy, "~> 1.5.0", [hex: :saxy, repo: "hexpm", optional: false]}], "hexpm", "8e9831e1a5ce063cfa8332e4bf34899380f5eb540d89b04fc38314443cdd016a"},
"logger_json": {:hex, :logger_json, "4.3.0", "41aaaab2c2e1c071bfddbcc5a3f567884fdf312d222c7f1a7e3de6ab667774f7", [:mix], [{:ecto, "~> 2.1 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "001bbc34d7c451cfeed298c8384cb3aab10b364db2eb095c466c7a1a28bee6e0"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
+ "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"},
"mix_audit": {:hex, :mix_audit, "1.0.0", "d2b5adbd69f34ba6b5b7d52812b1ba06f9110367e196d3ba5dba7753124cf8be", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.8.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "1b1ff6694e6eb12818ce5dcc276a39bbe03e27fcd11376c381bfe6b4900f2aa8"},
"mix_test_watch": {:hex, :mix_test_watch, "1.1.0", "330bb91c8ed271fe408c42d07e0773340a7938d8a0d281d57a14243eae9dc8c3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "52b6b1c476cbb70fd899ca5394506482f12e5f6b0d6acff9df95c7f1e0812ec3"},
"mox": {:hex, :mox, "1.0.1", "b651bf0113265cda0ba3a827fcb691f848b683c373b77e7d7439910a8d754d6e", [:mix], [], "hexpm", "35bc0dea5499d18db4ef7fe4360067a59b06c74376eb6ab3bd67e6295b133469"},
"nimble_csv": {:hex, :nimble_csv, "1.1.0", "b1dba4a86be9e03065c9de829050468e591f569100332db949e7ce71be0afc25", [:mix], [], "hexpm", "e986755bc302832cac429be6deda0fc9d82d3c82b47abefb68b3c17c9d949a3f"},
+ "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
+ "nimble_ownership": {:hex, :nimble_ownership, "0.3.2", "d4fa4056ade0ae33b5a9eb64554a1b3779689282e37513260125d2d6b32e4874", [:mix], [], "hexpm", "28b9a9f4094fda1aa8ca72f732ff3223eb54aa3eda4fed9022254de2c152b138"},
+ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
"nimble_totp": {:hex, :nimble_totp, "0.1.3", "fb7db78c672b4a96dc4386d46809d66d4a6ee2b3d2e69f22f38b394676c1ed6c", [:mix], [], "hexpm", "1263ac5bcef8e73ba2729d09cf125906d4f87c6dad602730e854740ef65d6040"},
"number": {:hex, :number, "1.0.3", "932c8a2d478a181c624138958ca88a78070332191b8061717270d939778c9857", [:mix], [{:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "dd397bbc096b2ca965a6a430126cc9cf7b9ef7421130def69bcf572232ca0f18"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
@@ -54,7 +61,10 @@
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
"postgrex": {:hex, :postgrex, "0.19.0", "f7d50e50cb42e0a185f5b9a6095125a9ab7e4abccfbe2ab820ab9aa92b71dbab", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "dba2d2a0a8637defbf2307e8629cb2526388ba7348f67d04ec77a5d6a72ecfae"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
+ "recase": {:hex, :recase, "0.7.0", "3f2f719f0886c7a3b7fe469058ec539cb7bbe0023604ae3bce920e186305e5ae", [:mix], [], "hexpm", "36f5756a9f552f4a94b54a695870e32f4e72d5fad9c25e61bc4a3151c08a4e0c"},
+ "req": {:hex, :req, "0.4.14", "103de133a076a31044e5458e0f850d5681eef23dfabf3ea34af63212e3b902e2", [:mix], [{:aws_signature, "~> 0.3.2", [hex: :aws_signature, repo: "hexpm", optional: true]}, {:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:nimble_ownership, "~> 0.2.0 or ~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2ddd3d33f9ab714ced8d3c15fd03db40c14dbf129003c4a3eb80fac2cc0b1b08"},
"rustler_precompiled": {:hex, :rustler_precompiled, "0.7.2", "097f657e401f02e7bc1cab808cfc6abdc1f7b9dc5e5adee46bf2fd8fdcce9ecf", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "7663faaeadc9e93e605164dcf9e69168e35f2f8b7f2b9eb4e400d1a8e0fe2999"},
+ "saxy": {:hex, :saxy, "1.5.0", "0141127f2d042856f135fb2d94e0beecda7a2306f47546dbc6411fc5b07e28bf", [:mix], [], "hexpm", "ea7bb6328fbd1f2aceffa3ec6090bfb18c85aadf0f8e5030905e84235861cf89"},
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"table": {:hex, :table, "0.1.2", "87ad1125f5b70c5dea0307aa633194083eb5182ec537efc94e96af08937e14a8", [:mix], [], "hexpm", "7e99bc7efef806315c7e65640724bf165c3061cdc5d854060f74468367065029"},
diff --git a/sample_data/bulk_fhir_download/Observation.ndjson b/sample_data/bulk_fhir_download/Observation.ndjson
new file mode 100644
index 00000000..972027c8
--- /dev/null
+++ b/sample_data/bulk_fhir_download/Observation.ndjson
@@ -0,0 +1,2 @@
+{"resourceType":"Observation","id":"alice-result-1","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab"]},"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/datereportedtolhd","valueDate":"08/05/2020"}],"category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"laboratory","display":"Laboratory"}]}],"status":"final","code":{"text":"TestTest"},"subject":{"reference":"Patient/10000"},"effectiveDateTime":"08/01/2020","issued":"2020-08-03T00:00:00Z","performer":[{"reference":"Organization/city-hospital-lab"}],"valueCodeableConcept":{"coding":[{"system":"http://snomed.info/sct","code":"10828004","display":"Positive"}]},"interpretation":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation","code":"POS","display":"Positive"}]}]}
+{"resourceType":"Observation","id":"billy-result-1","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab"]},"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/datereportedtolhd","valueDate":"08/05/2020"}],"category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"laboratory","display":"Laboratory"}]}],"status":"final","code":{"text":"TestTest"},"subject":{"reference":"Patient/10004"},"effectiveDateTime":"08/02/2020","issued":"2020-08-04T00:00:00Z","performer":[{"reference":"Organization/city-hospital-lab"}],"valueCodeableConcept":{"coding":[{"system":"http://snomed.info/sct","code":"260385009","display":"Negative"}]},"interpretation":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation","code":"NEG","display":"Negative"}]}]}
\ No newline at end of file
diff --git a/sample_data/bulk_fhir_download/Organization.ndjson b/sample_data/bulk_fhir_download/Organization.ndjson
new file mode 100644
index 00000000..d29695df
--- /dev/null
+++ b/sample_data/bulk_fhir_download/Organization.ndjson
@@ -0,0 +1,2 @@
+{"resourceType":"Organization","id":"city-hospital-lab","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-organization|7.0.0"]},"active":true,"name":"City Hospital Lab"}
+{"resourceType":"Organization","id":"lab-co-south","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-organization|7.0.0"]},"active":true,"name":"Lab Co South"}
\ No newline at end of file
diff --git a/sample_data/bulk_fhir_download/Patient.ndjson b/sample_data/bulk_fhir_download/Patient.ndjson
new file mode 100644
index 00000000..04b6d91f
--- /dev/null
+++ b/sample_data/bulk_fhir_download/Patient.ndjson
@@ -0,0 +1,2 @@
+{"resourceType":"Patient","id":"10000","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"]},"identifier":[{"system":"urn:example:person_tid","value":"alice"}],"name":[{"family":"Testuser","given":["Alice"]}],"birthDate":"1970-01-01","telecom":[{"system":"phone","value":"1111111000"}],"address":[{"line":["1234 Test St"],"city":"City","state":"TS","postalCode":"00000"}],"gender":"female","extension":[{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2106-3","display":"White"}},{"url":"text","valueString":"White"}]},{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2186-5","display":"Not Hispanic or Latino"}},{"url":"text","valueString":"Not Hispanic or Latino"}]},{"url":"http://hl7.org/fhir/StructureDefinition/patient-occupation","valueString":"Doctor"}]}
+{"resourceType":"Patient","id":"10004","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"]},"identifier":[{"system":"urn:example:person_tid","value":"billy"}],"name":[{"family":"Testuser","given":["Billy"]}],"birthDate":"1971-01-01","telecom":[{"system":"phone","value":"1111111004"}],"address":[{"line":["1234 Test St"],"city":"City","state":"TS","postalCode":"00000"}],"gender":"female","extension":[{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2106-3","display":"White"}},{"url":"text","valueString":"White"}]},{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2186-5","display":"Not Hispanic or Latino"}},{"url":"text","valueString":"Not Hispanic or Latino"}]},{"url":"http://hl7.org/fhir/StructureDefinition/patient-occupation","valueString":"Doctor"}]}
\ No newline at end of file
From 74f15535bbd2123348baf47c7ac6d6bf758fb330 Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Fri, 6 Sep 2024 16:43:06 -0400
Subject: [PATCH 2/8] add tests; all tests passed
---
lib/epiviewpoint/bulk_fhir_parser.ex | 39 +++---
lib/epiviewpoint/cases.ex | 5 +-
lib/epiviewpoint/cases/import.ex | 3 +-
lib/epiviewpoint/data_file.ex | 4 +-
lib/epiviewpoint/r4/address.ex | 10 +-
lib/epiviewpoint/r4/age.ex | 8 +-
lib/epiviewpoint/r4/annotation.ex | 10 +-
lib/epiviewpoint/r4/attachment.ex | 8 +-
lib/epiviewpoint/r4/codeable_concept.ex | 10 +-
lib/epiviewpoint/r4/coding.ex | 8 +-
lib/epiviewpoint/r4/contact_detail.ex | 10 +-
lib/epiviewpoint/r4/contact_point.ex | 10 +-
lib/epiviewpoint/r4/contributor.ex | 10 +-
lib/epiviewpoint/r4/count.ex | 8 +-
lib/epiviewpoint/r4/data_requirement.ex | 18 +--
.../r4/data_requirement/code_filter.ex | 12 +-
.../r4/data_requirement/date_filter.ex | 14 +-
lib/epiviewpoint/r4/data_requirement/sort.ex | 10 +-
lib/epiviewpoint/r4/distance.ex | 8 +-
lib/epiviewpoint/r4/dosage.ex | 30 ++--
lib/epiviewpoint/r4/dosage/dose_and_rate.ex | 22 +--
lib/epiviewpoint/r4/duration.ex | 8 +-
lib/epiviewpoint/r4/element.ex | 8 +-
lib/epiviewpoint/r4/expression.ex | 8 +-
lib/epiviewpoint/r4/extension.ex | 70 +++++-----
lib/epiviewpoint/r4/human_name.ex | 10 +-
lib/epiviewpoint/r4/identifier.ex | 14 +-
lib/epiviewpoint/r4/meta.ex | 12 +-
lib/epiviewpoint/r4/money.ex | 8 +-
lib/epiviewpoint/r4/narrative.ex | 8 +-
lib/epiviewpoint/r4/observation.ex | 72 +++++-----
lib/epiviewpoint/r4/observation/component.ex | 30 ++--
.../r4/observation/reference_range.ex | 20 +--
lib/epiviewpoint/r4/organization.ex | 30 ++--
lib/epiviewpoint/r4/organization/contact.ex | 18 +--
lib/epiviewpoint/r4/parameter_definition.ex | 8 +-
lib/epiviewpoint/r4/patient.ex | 38 +++---
lib/epiviewpoint/r4/patient/communication.ex | 12 +-
lib/epiviewpoint/r4/patient/contact.ex | 22 +--
lib/epiviewpoint/r4/patient/link.ex | 12 +-
lib/epiviewpoint/r4/period.ex | 8 +-
lib/epiviewpoint/r4/quantity.ex | 8 +-
lib/epiviewpoint/r4/range.ex | 12 +-
lib/epiviewpoint/r4/ratio.ex | 12 +-
lib/epiviewpoint/r4/reference.ex | 10 +-
lib/epiviewpoint/r4/related_artifact.ex | 10 +-
lib/epiviewpoint/r4/resource_list.ex | 6 +-
lib/epiviewpoint/r4/sampled_data.ex | 10 +-
lib/epiviewpoint/r4/signature.ex | 14 +-
lib/epiviewpoint/r4/timing.ex | 14 +-
lib/epiviewpoint/r4/timing/repeat.ex | 16 +--
lib/epiviewpoint/r4/trigger_definition.ex | 16 +--
lib/epiviewpoint/r4/usage_context.ex | 18 +--
.../controllers/import_controller.ex | 3 -
.../live/import_live.html.heex | 2 +-
test/epiviewpoint/data_file_test.exs | 129 ++++++++++++++++++
.../controllers/import_controller_test.exs | 40 ++++++
57 files changed, 582 insertions(+), 411 deletions(-)
diff --git a/lib/epiviewpoint/bulk_fhir_parser.ex b/lib/epiviewpoint/bulk_fhir_parser.ex
index 1f4dac32..89caeb1e 100644
--- a/lib/epiviewpoint/bulk_fhir_parser.ex
+++ b/lib/epiviewpoint/bulk_fhir_parser.ex
@@ -1,10 +1,12 @@
defmodule EpiViewpoint.BulkFhirParser do
def parse_bulk_fhir(file_list) do
+ contents = file_list |> Enum.map(& &1.contents) |> List.to_string()
+
file_list
|> load_resources()
|> extract_resources()
|> join_resources()
- |> to_map()
+ |> to_map(contents)
end
def load_resources(file_list) do
@@ -23,6 +25,7 @@ defmodule EpiViewpoint.BulkFhirParser do
file_content
|> String.split("\n")
|> Stream.map(&String.trim/1)
+ |> Stream.filter(&(&1 != ""))
|> Stream.map(&json_to_kindle_schema(&1, "EpiViewpoint.R4"))
|> Enum.to_list()
end
@@ -37,21 +40,21 @@ defmodule EpiViewpoint.BulkFhirParser do
def extract_resource("Patient", resource_list) do
resource_list
|> Enum.map(fn
- %Epiviewpoint.R4.Patient{
+ %EpiViewpoint.R4.Patient{
id: caseid,
- identifier: [%Epiviewpoint.R4.Identifier{value: person_tid}],
- name: [%Epiviewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
+ identifier: [%EpiViewpoint.R4.Identifier{value: person_tid}],
+ name: [%EpiViewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
birth_date: dateofbirth,
gender: sex,
address: [
- %Epiviewpoint.R4.Address{
+ %EpiViewpoint.R4.Address{
line: [diagaddress_street1],
city: diagaddress_city,
state: diagaddress_state,
postal_code: diagaddress_zip
}
],
- telecom: [%Epiviewpoint.R4.ContactPoint{value: phonenumber}],
+ telecom: [%EpiViewpoint.R4.ContactPoint{value: phonenumber}],
extension: extensions
} = _resource ->
%{
@@ -76,14 +79,14 @@ defmodule EpiViewpoint.BulkFhirParser do
def extract_resource("Observation", resource_list) do
resource_list
|> Enum.map(fn
- %Epiviewpoint.R4.Observation{
+ %EpiViewpoint.R4.Observation{
id: lab_result_tid,
- subject: %Epiviewpoint.R4.Reference{reference: "Patient/" <> pat_id},
+ subject: %EpiViewpoint.R4.Reference{reference: "Patient/" <> pat_id},
effective_date_time: datecollected,
issued: resultdate,
- code: %Epiviewpoint.R4.CodeableConcept{text: testname},
- interpretation: [%Epiviewpoint.R4.CodeableConcept{coding: [%Epiviewpoint.R4.Coding{display: result}]}],
- performer: [%Epiviewpoint.R4.Reference{reference: "Organization/" <> org_id}],
+ code: %EpiViewpoint.R4.CodeableConcept{text: testname},
+ interpretation: [%EpiViewpoint.R4.CodeableConcept{coding: [%EpiViewpoint.R4.Coding{display: result}]}],
+ performer: [%EpiViewpoint.R4.Reference{reference: "Organization/" <> org_id}],
extension: extensions
} = _resource ->
%{
@@ -102,7 +105,7 @@ defmodule EpiViewpoint.BulkFhirParser do
def extract_resource("Organization", resource_list) do
resource_list
|> Enum.map(fn
- %Epiviewpoint.R4.Organization{
+ %EpiViewpoint.R4.Organization{
id: orgnization_id,
name: orderingfacilityname
} = _resource ->
@@ -116,16 +119,16 @@ defmodule EpiViewpoint.BulkFhirParser do
# Helper function to find extension values
defp find_extension(extensions, url \\ nil) do
Enum.find_value(extensions, fn
- %Epiviewpoint.R4.Extension{
+ %EpiViewpoint.R4.Extension{
url: ^url,
- extension: [%Epiviewpoint.R4.Extension{url: "ombCategory", value_coding: %Epiviewpoint.R4.Coding{display: value}}, _]
+ extension: [%EpiViewpoint.R4.Extension{url: "ombCategory", value_coding: %EpiViewpoint.R4.Coding{display: value}}, _]
} ->
value
- %Epiviewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/patient-occupation", value_string: value} ->
+ %EpiViewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/patient-occupation", value_string: value} ->
value
- %Epiviewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/datereportedtolhd", value_date: value} ->
+ %EpiViewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/datereportedtolhd", value_date: value} ->
value
_ ->
@@ -155,7 +158,7 @@ defmodule EpiViewpoint.BulkFhirParser do
end)
end
- def to_map(resources) do
- %{file_name: "load.bulk_fhir", contents: resources}
+ def to_map(resources, contents) do
+ %{file_name: "load.bulk_fhir", contents: contents, list: resources}
end
end
diff --git a/lib/epiviewpoint/cases.ex b/lib/epiviewpoint/cases.ex
index 7929aff9..f656664d 100644
--- a/lib/epiviewpoint/cases.ex
+++ b/lib/epiviewpoint/cases.ex
@@ -34,7 +34,10 @@ defmodule EpiViewpoint.Cases do
def count_lab_results(), do: LabResult |> Repo.aggregate(:count)
def create_lab_result!({attrs, audit_meta}), do: %LabResult{} |> change_lab_result(attrs) |> AuditingRepo.insert!(audit_meta)
def import_lab_results(lab_result_data_file_string, originator), do: Import.import_data_file(lab_result_data_file_string, originator)
- def import_bulk_fhir_lab_results(lab_result_data_file_list, originator), do: Import.import_bulk_fhir_data_file(lab_result_data_file_list, originator)
+
+ def import_bulk_fhir_lab_results(lab_result_data_file_list, originator),
+ do: Import.import_bulk_fhir_data_file(lab_result_data_file_list, originator)
+
def list_lab_results(), do: LabResult.Query.all() |> Repo.all()
def preload_initiating_lab_result(case_investigations_or_nil), do: case_investigations_or_nil |> Repo.preload(:initiating_lab_result)
def preload_lab_results(person_or_people_or_nil), do: person_or_people_or_nil |> Repo.preload(lab_results: LabResult.Query.display_order())
diff --git a/lib/epiviewpoint/cases/import.ex b/lib/epiviewpoint/cases/import.ex
index 0a89c42b..7f667744 100644
--- a/lib/epiviewpoint/cases/import.ex
+++ b/lib/epiviewpoint/cases/import.ex
@@ -66,7 +66,6 @@ defmodule EpiViewpoint.Cases.Import do
|> import_data_file(originator)
end
-
def import_data_file(_file, %{admin: false}), do: {:error, "Originator must be an admin"}
def import_data_file(file, %Accounts.User{} = originator) do
@@ -111,7 +110,7 @@ defmodule EpiViewpoint.Cases.Import do
case Path.extname(file.file_name) do
".csv" -> DataFile.read(file.contents, :csv, &rename_headers/1, @fields)
".ndjson" -> DataFile.read(file.contents, :ndjson, &rename_headers/1, @fields)
- ".bulk_fhir" -> DataFile.read(file.contents, :bulk_fhir, &rename_headers/1, @fields)
+ ".bulk_fhir" -> DataFile.read(file.list, :bulk_fhir, &rename_headers/1, @fields)
_ -> {:error, "Unsupported file type: #{file.extension}"}
end
end
diff --git a/lib/epiviewpoint/data_file.ex b/lib/epiviewpoint/data_file.ex
index d34a2bf7..d4015242 100644
--- a/lib/epiviewpoint/data_file.ex
+++ b/lib/epiviewpoint/data_file.ex
@@ -21,7 +21,7 @@ defmodule EpiViewpoint.DataFile do
read(string, header_transformer, headers, &parse_ndjson/1)
end
- def read(string, :bulk_fhir, header_transformer, headers) when is_binary(string) do
+ def read(string, :bulk_fhir, header_transformer, headers) when is_list(string) do
read(string, header_transformer, headers, &parse_bulk_fhir/1)
end
@@ -89,7 +89,7 @@ defmodule EpiViewpoint.DataFile do
end
defp parse_bulk_fhir(input) do
- DataFrame.new(input)
+ {:ok, DataFrame.new(input)}
end
defp validate_csv(input) do
diff --git a/lib/epiviewpoint/r4/address.ex b/lib/epiviewpoint/r4/address.ex
index 028b97cd..d74338b9 100644
--- a/lib/epiviewpoint/r4/address.ex
+++ b/lib/epiviewpoint/r4/address.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Address do
+defmodule EpiViewpoint.R4.Address do
use Ecto.Schema
import Ecto.Changeset
@@ -47,15 +47,15 @@ defmodule Epiviewpoint.R4.Address do
)
# Embed One
- embeds_one(:period, Epiviewpoint.R4.Period)
+ embeds_one(:period, EpiViewpoint.R4.Period)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -65,4 +65,4 @@ defmodule Epiviewpoint.R4.Address do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/age.ex b/lib/epiviewpoint/r4/age.ex
index df1305c5..8ba38614 100644
--- a/lib/epiviewpoint/r4/age.ex
+++ b/lib/epiviewpoint/r4/age.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Age do
+defmodule EpiViewpoint.R4.Age do
use Ecto.Schema
import Ecto.Changeset
@@ -30,12 +30,12 @@ defmodule Epiviewpoint.R4.Age do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -44,4 +44,4 @@ defmodule Epiviewpoint.R4.Age do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/annotation.ex b/lib/epiviewpoint/r4/annotation.ex
index bd103fc7..af33ac59 100644
--- a/lib/epiviewpoint/r4/annotation.ex
+++ b/lib/epiviewpoint/r4/annotation.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Annotation do
+defmodule EpiViewpoint.R4.Annotation do
use Ecto.Schema
import Ecto.Changeset
@@ -17,10 +17,10 @@ defmodule Epiviewpoint.R4.Annotation do
field(:time, :utc_datetime_usec)
# Embed One
- embeds_one(:author_reference, Epiviewpoint.R4.Reference)
+ embeds_one(:author_reference, EpiViewpoint.R4.Reference)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices("author") do
@@ -33,7 +33,7 @@ defmodule Epiviewpoint.R4.Annotation do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -43,4 +43,4 @@ defmodule Epiviewpoint.R4.Annotation do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/attachment.ex b/lib/epiviewpoint/r4/attachment.ex
index 6d3121b1..2ec77fb3 100644
--- a/lib/epiviewpoint/r4/attachment.ex
+++ b/lib/epiviewpoint/r4/attachment.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Attachment do
+defmodule EpiViewpoint.R4.Attachment do
use Ecto.Schema
import Ecto.Changeset
@@ -27,12 +27,12 @@ defmodule Epiviewpoint.R4.Attachment do
field(:url, :string)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -41,4 +41,4 @@ defmodule Epiviewpoint.R4.Attachment do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/codeable_concept.ex b/lib/epiviewpoint/r4/codeable_concept.ex
index a7924e17..720022ef 100644
--- a/lib/epiviewpoint/r4/codeable_concept.ex
+++ b/lib/epiviewpoint/r4/codeable_concept.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.CodeableConcept do
+defmodule EpiViewpoint.R4.CodeableConcept do
use Ecto.Schema
import Ecto.Changeset
@@ -13,13 +13,13 @@ defmodule Epiviewpoint.R4.CodeableConcept do
field(:text, :string)
# Embed Many
- embeds_many(:coding, Epiviewpoint.R4.Coding)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:coding, EpiViewpoint.R4.Coding)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -29,4 +29,4 @@ defmodule Epiviewpoint.R4.CodeableConcept do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/coding.ex b/lib/epiviewpoint/r4/coding.ex
index 8f9edad0..c4818428 100644
--- a/lib/epiviewpoint/r4/coding.ex
+++ b/lib/epiviewpoint/r4/coding.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Coding do
+defmodule EpiViewpoint.R4.Coding do
use Ecto.Schema
import Ecto.Changeset
@@ -21,12 +21,12 @@ defmodule Epiviewpoint.R4.Coding do
field(:version, :string)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -35,4 +35,4 @@ defmodule Epiviewpoint.R4.Coding do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/contact_detail.ex b/lib/epiviewpoint/r4/contact_detail.ex
index 1439daca..a02981ea 100644
--- a/lib/epiviewpoint/r4/contact_detail.ex
+++ b/lib/epiviewpoint/r4/contact_detail.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.ContactDetail do
+defmodule EpiViewpoint.R4.ContactDetail do
use Ecto.Schema
import Ecto.Changeset
@@ -13,13 +13,13 @@ defmodule Epiviewpoint.R4.ContactDetail do
field(:name, :string)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:telecom, EpiViewpoint.R4.ContactPoint)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -29,4 +29,4 @@ defmodule Epiviewpoint.R4.ContactDetail do
|> cast_embed(:telecom)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/contact_point.ex b/lib/epiviewpoint/r4/contact_point.ex
index a23e86ab..b62d4840 100644
--- a/lib/epiviewpoint/r4/contact_point.ex
+++ b/lib/epiviewpoint/r4/contact_point.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.ContactPoint do
+defmodule EpiViewpoint.R4.ContactPoint do
use Ecto.Schema
import Ecto.Changeset
@@ -40,15 +40,15 @@ defmodule Epiviewpoint.R4.ContactPoint do
)
# Embed One
- embeds_one(:period, Epiviewpoint.R4.Period)
+ embeds_one(:period, EpiViewpoint.R4.Period)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -58,4 +58,4 @@ defmodule Epiviewpoint.R4.ContactPoint do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/contributor.ex b/lib/epiviewpoint/r4/contributor.ex
index c7241ca0..29165086 100644
--- a/lib/epiviewpoint/r4/contributor.ex
+++ b/lib/epiviewpoint/r4/contributor.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Contributor do
+defmodule EpiViewpoint.R4.Contributor do
use Ecto.Schema
import Ecto.Changeset
@@ -24,13 +24,13 @@ defmodule Epiviewpoint.R4.Contributor do
)
# Embed Many
- embeds_many(:contact, Epiviewpoint.R4.ContactDetail)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:contact, EpiViewpoint.R4.ContactDetail)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -40,4 +40,4 @@ defmodule Epiviewpoint.R4.Contributor do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/count.ex b/lib/epiviewpoint/r4/count.ex
index 89bfe065..d087f028 100644
--- a/lib/epiviewpoint/r4/count.ex
+++ b/lib/epiviewpoint/r4/count.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Count do
+defmodule EpiViewpoint.R4.Count do
use Ecto.Schema
import Ecto.Changeset
@@ -30,12 +30,12 @@ defmodule Epiviewpoint.R4.Count do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -44,4 +44,4 @@ defmodule Epiviewpoint.R4.Count do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/data_requirement.ex b/lib/epiviewpoint/r4/data_requirement.ex
index 546433d9..24b4a9de 100644
--- a/lib/epiviewpoint/r4/data_requirement.ex
+++ b/lib/epiviewpoint/r4/data_requirement.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.DataRequirement do
+defmodule EpiViewpoint.R4.DataRequirement do
use Ecto.Schema
import Ecto.Changeset
@@ -20,14 +20,14 @@ defmodule Epiviewpoint.R4.DataRequirement do
field(:profile, {:array, :string})
# Embed One
- embeds_one(:subject_codeable_concept, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:subject_reference, Epiviewpoint.R4.Reference)
+ embeds_one(:subject_codeable_concept, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:subject_reference, EpiViewpoint.R4.Reference)
# Embed Many
- embeds_many(:code_filter, Epiviewpoint.R4.DataRequirement.CodeFilter)
- embeds_many(:date_filter, Epiviewpoint.R4.DataRequirement.DateFilter)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:sort, Epiviewpoint.R4.DataRequirement.Sort)
+ embeds_many(:code_filter, EpiViewpoint.R4.DataRequirement.CodeFilter)
+ embeds_many(:date_filter, EpiViewpoint.R4.DataRequirement.DateFilter)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:sort, EpiViewpoint.R4.DataRequirement.Sort)
end
def choices("subject") do
@@ -40,7 +40,7 @@ defmodule Epiviewpoint.R4.DataRequirement do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -54,4 +54,4 @@ defmodule Epiviewpoint.R4.DataRequirement do
|> cast_embed(:sort)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/data_requirement/code_filter.ex b/lib/epiviewpoint/r4/data_requirement/code_filter.ex
index 6c5d50ff..73c9530f 100644
--- a/lib/epiviewpoint/r4/data_requirement/code_filter.ex
+++ b/lib/epiviewpoint/r4/data_requirement/code_filter.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.DataRequirement.CodeFilter do
+defmodule EpiViewpoint.R4.DataRequirement.CodeFilter do
use Ecto.Schema
import Ecto.Changeset
@@ -17,14 +17,14 @@ defmodule Epiviewpoint.R4.DataRequirement.CodeFilter do
field(:value_set, :string)
# Embed Many
- embeds_many(:code, Epiviewpoint.R4.Coding)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:code, EpiViewpoint.R4.Coding)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -35,4 +35,4 @@ defmodule Epiviewpoint.R4.DataRequirement.CodeFilter do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/data_requirement/date_filter.ex b/lib/epiviewpoint/r4/data_requirement/date_filter.ex
index 2b9dce0f..63684556 100644
--- a/lib/epiviewpoint/r4/data_requirement/date_filter.ex
+++ b/lib/epiviewpoint/r4/data_requirement/date_filter.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.DataRequirement.DateFilter do
+defmodule EpiViewpoint.R4.DataRequirement.DateFilter do
use Ecto.Schema
import Ecto.Changeset
@@ -17,12 +17,12 @@ defmodule Epiviewpoint.R4.DataRequirement.DateFilter do
field(:value_date_time, :string)
# Embed One
- embeds_one(:value_duration, Epiviewpoint.R4.Duration)
- embeds_one(:value_period, Epiviewpoint.R4.Period)
+ embeds_one(:value_duration, EpiViewpoint.R4.Duration)
+ embeds_one(:value_period, EpiViewpoint.R4.Period)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices("value") do
@@ -37,7 +37,7 @@ defmodule Epiviewpoint.R4.DataRequirement.DateFilter do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -49,4 +49,4 @@ defmodule Epiviewpoint.R4.DataRequirement.DateFilter do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/data_requirement/sort.ex b/lib/epiviewpoint/r4/data_requirement/sort.ex
index f465cf05..e99d7e19 100644
--- a/lib/epiviewpoint/r4/data_requirement/sort.ex
+++ b/lib/epiviewpoint/r4/data_requirement/sort.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.DataRequirement.Sort do
+defmodule EpiViewpoint.R4.DataRequirement.Sort do
use Ecto.Schema
import Ecto.Changeset
@@ -22,13 +22,13 @@ defmodule Epiviewpoint.R4.DataRequirement.Sort do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -38,4 +38,4 @@ defmodule Epiviewpoint.R4.DataRequirement.Sort do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/distance.ex b/lib/epiviewpoint/r4/distance.ex
index e70e5554..f4d0a7f5 100644
--- a/lib/epiviewpoint/r4/distance.ex
+++ b/lib/epiviewpoint/r4/distance.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Distance do
+defmodule EpiViewpoint.R4.Distance do
use Ecto.Schema
import Ecto.Changeset
@@ -30,12 +30,12 @@ defmodule Epiviewpoint.R4.Distance do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -44,4 +44,4 @@ defmodule Epiviewpoint.R4.Distance do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/dosage.ex b/lib/epiviewpoint/r4/dosage.ex
index 0b2e21e4..7bd05eac 100644
--- a/lib/epiviewpoint/r4/dosage.ex
+++ b/lib/epiviewpoint/r4/dosage.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Dosage do
+defmodule EpiViewpoint.R4.Dosage do
use Ecto.Schema
import Ecto.Changeset
@@ -19,20 +19,20 @@ defmodule Epiviewpoint.R4.Dosage do
field(:text, :string)
# Embed One
- embeds_one(:as_needed_codeable_concept, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:max_dose_per_administration, Epiviewpoint.R4.Quantity)
- embeds_one(:max_dose_per_lifetime, Epiviewpoint.R4.Quantity)
- embeds_one(:max_dose_per_period, Epiviewpoint.R4.Ratio)
- embeds_one(:method, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:route, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:site, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:timing, Epiviewpoint.R4.Timing)
+ embeds_one(:as_needed_codeable_concept, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:max_dose_per_administration, EpiViewpoint.R4.Quantity)
+ embeds_one(:max_dose_per_lifetime, EpiViewpoint.R4.Quantity)
+ embeds_one(:max_dose_per_period, EpiViewpoint.R4.Ratio)
+ embeds_one(:method, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:route, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:site, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:timing, EpiViewpoint.R4.Timing)
# Embed Many
- embeds_many(:additional_instruction, Epiviewpoint.R4.CodeableConcept)
- embeds_many(:dose_and_rate, Epiviewpoint.R4.Dosage.DoseAndRate)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:additional_instruction, EpiViewpoint.R4.CodeableConcept)
+ embeds_many(:dose_and_rate, EpiViewpoint.R4.Dosage.DoseAndRate)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices("asNeeded") do
@@ -45,7 +45,7 @@ defmodule Epiviewpoint.R4.Dosage do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -65,4 +65,4 @@ defmodule Epiviewpoint.R4.Dosage do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/dosage/dose_and_rate.ex b/lib/epiviewpoint/r4/dosage/dose_and_rate.ex
index 2fff6029..965eade0 100644
--- a/lib/epiviewpoint/r4/dosage/dose_and_rate.ex
+++ b/lib/epiviewpoint/r4/dosage/dose_and_rate.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Dosage.DoseAndRate do
+defmodule EpiViewpoint.R4.Dosage.DoseAndRate do
use Ecto.Schema
import Ecto.Changeset
@@ -9,16 +9,16 @@ defmodule Epiviewpoint.R4.Dosage.DoseAndRate do
embedded_schema do
# Embed One
- embeds_one(:dose_quantity, Epiviewpoint.R4.Quantity)
- embeds_one(:dose_range, Epiviewpoint.R4.Range)
- embeds_one(:rate_quantity, Epiviewpoint.R4.Quantity)
- embeds_one(:rate_range, Epiviewpoint.R4.Range)
- embeds_one(:rate_ratio, Epiviewpoint.R4.Ratio)
- embeds_one(:type, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:dose_quantity, EpiViewpoint.R4.Quantity)
+ embeds_one(:dose_range, EpiViewpoint.R4.Range)
+ embeds_one(:rate_quantity, EpiViewpoint.R4.Quantity)
+ embeds_one(:rate_range, EpiViewpoint.R4.Range)
+ embeds_one(:rate_ratio, EpiViewpoint.R4.Ratio)
+ embeds_one(:type, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices("dose") do
@@ -41,7 +41,7 @@ defmodule Epiviewpoint.R4.Dosage.DoseAndRate do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -57,4 +57,4 @@ defmodule Epiviewpoint.R4.Dosage.DoseAndRate do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/duration.ex b/lib/epiviewpoint/r4/duration.ex
index 4c4cdb30..f0004082 100644
--- a/lib/epiviewpoint/r4/duration.ex
+++ b/lib/epiviewpoint/r4/duration.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Duration do
+defmodule EpiViewpoint.R4.Duration do
use Ecto.Schema
import Ecto.Changeset
@@ -30,12 +30,12 @@ defmodule Epiviewpoint.R4.Duration do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -44,4 +44,4 @@ defmodule Epiviewpoint.R4.Duration do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/element.ex b/lib/epiviewpoint/r4/element.ex
index 5af02ad7..06fef920 100644
--- a/lib/epiviewpoint/r4/element.ex
+++ b/lib/epiviewpoint/r4/element.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Element do
+defmodule EpiViewpoint.R4.Element do
use Ecto.Schema
import Ecto.Changeset
@@ -9,12 +9,12 @@ defmodule Epiviewpoint.R4.Element do
embedded_schema do
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -23,4 +23,4 @@ defmodule Epiviewpoint.R4.Element do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/expression.ex b/lib/epiviewpoint/r4/expression.ex
index 241c3e34..a62ea029 100644
--- a/lib/epiviewpoint/r4/expression.ex
+++ b/lib/epiviewpoint/r4/expression.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Expression do
+defmodule EpiViewpoint.R4.Expression do
use Ecto.Schema
import Ecto.Changeset
@@ -29,12 +29,12 @@ defmodule Epiviewpoint.R4.Expression do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -43,4 +43,4 @@ defmodule Epiviewpoint.R4.Expression do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/extension.ex b/lib/epiviewpoint/r4/extension.ex
index c8ab3b50..c902bef8 100644
--- a/lib/epiviewpoint/r4/extension.ex
+++ b/lib/epiviewpoint/r4/extension.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Extension do
+defmodule EpiViewpoint.R4.Extension do
use Ecto.Schema
import Ecto.Changeset
@@ -51,45 +51,45 @@ defmodule Epiviewpoint.R4.Extension do
field(:value_id, :string)
# Embed One
- embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
- embeds_one(:value_expression, Epiviewpoint.R4.Expression)
- embeds_one(:value_attachment, Epiviewpoint.R4.Attachment)
- embeds_one(:value_identifier, Epiviewpoint.R4.Identifier)
- embeds_one(:value_sampled_data, Epiviewpoint.R4.SampledData)
- embeds_one(:value_parameter_definition, Epiviewpoint.R4.ParameterDefinition)
- embeds_one(:value_timing, Epiviewpoint.R4.Timing)
- embeds_one(:value_reference, Epiviewpoint.R4.Reference)
- embeds_one(:value_contact_point, Epiviewpoint.R4.ContactPoint)
- embeds_one(:value_age, Epiviewpoint.R4.Age)
- embeds_one(:value_meta, Epiviewpoint.R4.Meta)
- embeds_one(:value_annotation, Epiviewpoint.R4.Annotation)
- embeds_one(:value_money, Epiviewpoint.R4.Money)
- embeds_one(:value_usage_context, Epiviewpoint.R4.UsageContext)
- embeds_one(:value_related_artifact, Epiviewpoint.R4.RelatedArtifact)
- embeds_one(:value_contact_detail, Epiviewpoint.R4.ContactDetail)
- embeds_one(:value_ratio, Epiviewpoint.R4.Ratio)
- embeds_one(:value_distance, Epiviewpoint.R4.Distance)
- embeds_one(:value_duration, Epiviewpoint.R4.Duration)
- embeds_one(:value_human_name, Epiviewpoint.R4.HumanName)
- embeds_one(:value_period, Epiviewpoint.R4.Period)
- embeds_one(:value_range, Epiviewpoint.R4.Range)
- embeds_one(:value_dosage, Epiviewpoint.R4.Dosage)
- embeds_one(:value_contributor, Epiviewpoint.R4.Contributor)
- embeds_one(:value_address, Epiviewpoint.R4.Address)
- embeds_one(:value_signature, Epiviewpoint.R4.Signature)
- embeds_one(:value_trigger_definition, Epiviewpoint.R4.TriggerDefinition)
- embeds_one(:value_data_requirement, Epiviewpoint.R4.DataRequirement)
- embeds_one(:value_count, Epiviewpoint.R4.Count)
- embeds_one(:value_coding, Epiviewpoint.R4.Coding)
- embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:value_quantity, EpiViewpoint.R4.Quantity)
+ embeds_one(:value_expression, EpiViewpoint.R4.Expression)
+ embeds_one(:value_attachment, EpiViewpoint.R4.Attachment)
+ embeds_one(:value_identifier, EpiViewpoint.R4.Identifier)
+ embeds_one(:value_sampled_data, EpiViewpoint.R4.SampledData)
+ embeds_one(:value_parameter_definition, EpiViewpoint.R4.ParameterDefinition)
+ embeds_one(:value_timing, EpiViewpoint.R4.Timing)
+ embeds_one(:value_reference, EpiViewpoint.R4.Reference)
+ embeds_one(:value_contact_point, EpiViewpoint.R4.ContactPoint)
+ embeds_one(:value_age, EpiViewpoint.R4.Age)
+ embeds_one(:value_meta, EpiViewpoint.R4.Meta)
+ embeds_one(:value_annotation, EpiViewpoint.R4.Annotation)
+ embeds_one(:value_money, EpiViewpoint.R4.Money)
+ embeds_one(:value_usage_context, EpiViewpoint.R4.UsageContext)
+ embeds_one(:value_related_artifact, EpiViewpoint.R4.RelatedArtifact)
+ embeds_one(:value_contact_detail, EpiViewpoint.R4.ContactDetail)
+ embeds_one(:value_ratio, EpiViewpoint.R4.Ratio)
+ embeds_one(:value_distance, EpiViewpoint.R4.Distance)
+ embeds_one(:value_duration, EpiViewpoint.R4.Duration)
+ embeds_one(:value_human_name, EpiViewpoint.R4.HumanName)
+ embeds_one(:value_period, EpiViewpoint.R4.Period)
+ embeds_one(:value_range, EpiViewpoint.R4.Range)
+ embeds_one(:value_dosage, EpiViewpoint.R4.Dosage)
+ embeds_one(:value_contributor, EpiViewpoint.R4.Contributor)
+ embeds_one(:value_address, EpiViewpoint.R4.Address)
+ embeds_one(:value_signature, EpiViewpoint.R4.Signature)
+ embeds_one(:value_trigger_definition, EpiViewpoint.R4.TriggerDefinition)
+ embeds_one(:value_data_requirement, EpiViewpoint.R4.DataRequirement)
+ embeds_one(:value_count, EpiViewpoint.R4.Count)
+ embeds_one(:value_coding, EpiViewpoint.R4.Coding)
+ embeds_one(:value_codeable_concept, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -129,4 +129,4 @@ defmodule Epiviewpoint.R4.Extension do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/human_name.ex b/lib/epiviewpoint/r4/human_name.ex
index 8ed99171..145b3340 100644
--- a/lib/epiviewpoint/r4/human_name.ex
+++ b/lib/epiviewpoint/r4/human_name.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.HumanName do
+defmodule EpiViewpoint.R4.HumanName do
use Ecto.Schema
import Ecto.Changeset
@@ -36,15 +36,15 @@ defmodule Epiviewpoint.R4.HumanName do
)
# Embed One
- embeds_one(:period, Epiviewpoint.R4.Period)
+ embeds_one(:period, EpiViewpoint.R4.Period)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -54,4 +54,4 @@ defmodule Epiviewpoint.R4.HumanName do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/identifier.ex b/lib/epiviewpoint/r4/identifier.ex
index d2471bc7..a4be948a 100644
--- a/lib/epiviewpoint/r4/identifier.ex
+++ b/lib/epiviewpoint/r4/identifier.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Identifier do
+defmodule EpiViewpoint.R4.Identifier do
use Ecto.Schema
import Ecto.Changeset
@@ -27,17 +27,17 @@ defmodule Epiviewpoint.R4.Identifier do
)
# Embed One
- embeds_one(:assigner, Epiviewpoint.R4.Reference)
- embeds_one(:period, Epiviewpoint.R4.Period)
- embeds_one(:type, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:assigner, EpiViewpoint.R4.Reference)
+ embeds_one(:period, EpiViewpoint.R4.Period)
+ embeds_one(:type, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -49,4 +49,4 @@ defmodule Epiviewpoint.R4.Identifier do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/meta.ex b/lib/epiviewpoint/r4/meta.ex
index 8632b8b7..0fd539fb 100644
--- a/lib/epiviewpoint/r4/meta.ex
+++ b/lib/epiviewpoint/r4/meta.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Meta do
+defmodule EpiViewpoint.R4.Meta do
use Ecto.Schema
import Ecto.Changeset
@@ -20,14 +20,14 @@ defmodule Epiviewpoint.R4.Meta do
field(:profile, {:array, :string})
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:security, Epiviewpoint.R4.Coding)
- embeds_many(:tag, Epiviewpoint.R4.Coding)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:security, EpiViewpoint.R4.Coding)
+ embeds_many(:tag, EpiViewpoint.R4.Coding)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -38,4 +38,4 @@ defmodule Epiviewpoint.R4.Meta do
|> cast_embed(:tag)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/money.ex b/lib/epiviewpoint/r4/money.ex
index 6014c0af..0f9aa005 100644
--- a/lib/epiviewpoint/r4/money.ex
+++ b/lib/epiviewpoint/r4/money.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Money do
+defmodule EpiViewpoint.R4.Money do
use Ecto.Schema
import Ecto.Changeset
@@ -15,12 +15,12 @@ defmodule Epiviewpoint.R4.Money do
field(:value, :decimal)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -29,4 +29,4 @@ defmodule Epiviewpoint.R4.Money do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/narrative.ex b/lib/epiviewpoint/r4/narrative.ex
index 6798aa4d..4f59f03f 100644
--- a/lib/epiviewpoint/r4/narrative.ex
+++ b/lib/epiviewpoint/r4/narrative.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Narrative do
+defmodule EpiViewpoint.R4.Narrative do
use Ecto.Schema
import Ecto.Changeset
@@ -26,12 +26,12 @@ defmodule Epiviewpoint.R4.Narrative do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -40,4 +40,4 @@ defmodule Epiviewpoint.R4.Narrative do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/observation.ex b/lib/epiviewpoint/r4/observation.ex
index 81449b4c..298c2703 100644
--- a/lib/epiviewpoint/r4/observation.ex
+++ b/lib/epiviewpoint/r4/observation.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Observation do
+defmodule EpiViewpoint.R4.Observation do
use Ecto.Schema
import Ecto.Changeset
@@ -50,41 +50,41 @@ defmodule Epiviewpoint.R4.Observation do
)
# Embed One
- embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
- embeds_one(:effective_timing, Epiviewpoint.R4.Timing)
- embeds_one(:value_sampled_data, Epiviewpoint.R4.SampledData)
- embeds_one(:specimen, Epiviewpoint.R4.Reference)
- embeds_one(:effective_period, Epiviewpoint.R4.Period)
- embeds_one(:value_ratio, Epiviewpoint.R4.Ratio)
- embeds_one(:encounter, Epiviewpoint.R4.Reference)
- embeds_one(:code, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:subject, Epiviewpoint.R4.Reference)
- embeds_one(:data_absent_reason, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:text, Epiviewpoint.R4.Narrative)
- embeds_one(:body_site, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:meta, Epiviewpoint.R4.Meta)
- embeds_one(:value_period, Epiviewpoint.R4.Period)
- embeds_one(:value_range, Epiviewpoint.R4.Range)
- embeds_one(:method, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:device, Epiviewpoint.R4.Reference)
- embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:value_quantity, EpiViewpoint.R4.Quantity)
+ embeds_one(:effective_timing, EpiViewpoint.R4.Timing)
+ embeds_one(:value_sampled_data, EpiViewpoint.R4.SampledData)
+ embeds_one(:specimen, EpiViewpoint.R4.Reference)
+ embeds_one(:effective_period, EpiViewpoint.R4.Period)
+ embeds_one(:value_ratio, EpiViewpoint.R4.Ratio)
+ embeds_one(:encounter, EpiViewpoint.R4.Reference)
+ embeds_one(:code, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:subject, EpiViewpoint.R4.Reference)
+ embeds_one(:data_absent_reason, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:text, EpiViewpoint.R4.Narrative)
+ embeds_one(:body_site, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:meta, EpiViewpoint.R4.Meta)
+ embeds_one(:value_period, EpiViewpoint.R4.Period)
+ embeds_one(:value_range, EpiViewpoint.R4.Range)
+ embeds_one(:method, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:device, EpiViewpoint.R4.Reference)
+ embeds_one(:value_codeable_concept, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:contained, Epiviewpoint.R4.ResourceList)
- embeds_many(:reference_range, Epiviewpoint.R4.Observation.ReferenceRange)
- embeds_many(:derived_from, Epiviewpoint.R4.Reference)
- embeds_many(:focus, Epiviewpoint.R4.Reference)
- embeds_many(:based_on, Epiviewpoint.R4.Reference)
- embeds_many(:component, Epiviewpoint.R4.Observation.Component)
- embeds_many(:performer, Epiviewpoint.R4.Reference)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
- embeds_many(:identifier, Epiviewpoint.R4.Identifier)
- embeds_many(:part_of, Epiviewpoint.R4.Reference)
- embeds_many(:has_member, Epiviewpoint.R4.Reference)
- embeds_many(:category, Epiviewpoint.R4.CodeableConcept)
- embeds_many(:note, Epiviewpoint.R4.Annotation)
- embeds_many(:interpretation, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:contained, EpiViewpoint.R4.ResourceList)
+ embeds_many(:reference_range, EpiViewpoint.R4.Observation.ReferenceRange)
+ embeds_many(:derived_from, EpiViewpoint.R4.Reference)
+ embeds_many(:focus, EpiViewpoint.R4.Reference)
+ embeds_many(:based_on, EpiViewpoint.R4.Reference)
+ embeds_many(:component, EpiViewpoint.R4.Observation.Component)
+ embeds_many(:performer, EpiViewpoint.R4.Reference)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
+ embeds_many(:identifier, EpiViewpoint.R4.Identifier)
+ embeds_many(:part_of, EpiViewpoint.R4.Reference)
+ embeds_many(:has_member, EpiViewpoint.R4.Reference)
+ embeds_many(:category, EpiViewpoint.R4.CodeableConcept)
+ embeds_many(:note, EpiViewpoint.R4.Annotation)
+ embeds_many(:interpretation, EpiViewpoint.R4.CodeableConcept)
end
def choices("effective") do
@@ -139,7 +139,7 @@ defmodule Epiviewpoint.R4.Observation do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def path, do: "/Observation"
@@ -181,4 +181,4 @@ defmodule Epiviewpoint.R4.Observation do
|> cast_embed(:interpretation)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/observation/component.ex b/lib/epiviewpoint/r4/observation/component.ex
index a72301fa..7116f81a 100644
--- a/lib/epiviewpoint/r4/observation/component.ex
+++ b/lib/epiviewpoint/r4/observation/component.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Observation.Component do
+defmodule EpiViewpoint.R4.Observation.Component do
use Ecto.Schema
import Ecto.Changeset
@@ -21,20 +21,20 @@ defmodule Epiviewpoint.R4.Observation.Component do
field(:value_time, :string)
# Embed One
- embeds_one(:code, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:data_absent_reason, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:value_period, Epiviewpoint.R4.Period)
- embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
- embeds_one(:value_range, Epiviewpoint.R4.Range)
- embeds_one(:value_ratio, Epiviewpoint.R4.Ratio)
- embeds_one(:value_sampled_data, Epiviewpoint.R4.SampledData)
+ embeds_one(:code, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:data_absent_reason, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:value_codeable_concept, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:value_period, EpiViewpoint.R4.Period)
+ embeds_one(:value_quantity, EpiViewpoint.R4.Quantity)
+ embeds_one(:value_range, EpiViewpoint.R4.Range)
+ embeds_one(:value_ratio, EpiViewpoint.R4.Ratio)
+ embeds_one(:value_sampled_data, EpiViewpoint.R4.SampledData)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:interpretation, Epiviewpoint.R4.CodeableConcept)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
- embeds_many(:reference_range, Epiviewpoint.R4.Observation.ReferenceRange)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:interpretation, EpiViewpoint.R4.CodeableConcept)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
+ embeds_many(:reference_range, EpiViewpoint.R4.Observation.ReferenceRange)
end
def choices("value") do
@@ -77,7 +77,7 @@ defmodule Epiviewpoint.R4.Observation.Component do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -97,4 +97,4 @@ defmodule Epiviewpoint.R4.Observation.Component do
|> cast_embed(:reference_range)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/observation/reference_range.ex b/lib/epiviewpoint/r4/observation/reference_range.ex
index 94f11e5b..c04b7a0f 100644
--- a/lib/epiviewpoint/r4/observation/reference_range.ex
+++ b/lib/epiviewpoint/r4/observation/reference_range.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Observation.ReferenceRange do
+defmodule EpiViewpoint.R4.Observation.ReferenceRange do
use Ecto.Schema
import Ecto.Changeset
@@ -13,20 +13,20 @@ defmodule Epiviewpoint.R4.Observation.ReferenceRange do
field(:text, :string)
# Embed One
- embeds_one(:age, Epiviewpoint.R4.Range)
- embeds_one(:high, Epiviewpoint.R4.Quantity)
- embeds_one(:low, Epiviewpoint.R4.Quantity)
- embeds_one(:type, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:age, EpiViewpoint.R4.Range)
+ embeds_one(:high, EpiViewpoint.R4.Quantity)
+ embeds_one(:low, EpiViewpoint.R4.Quantity)
+ embeds_one(:type, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:applies_to, Epiviewpoint.R4.CodeableConcept)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:applies_to, EpiViewpoint.R4.CodeableConcept)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -41,4 +41,4 @@ defmodule Epiviewpoint.R4.Observation.ReferenceRange do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/organization.ex b/lib/epiviewpoint/r4/organization.ex
index ebb3f13c..00bfc582 100644
--- a/lib/epiviewpoint/r4/organization.ex
+++ b/lib/epiviewpoint/r4/organization.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Organization do
+defmodule EpiViewpoint.R4.Organization do
use Ecto.Schema
import Ecto.Changeset
@@ -26,25 +26,25 @@ defmodule Epiviewpoint.R4.Organization do
field(:alias, {:array, :string})
# Embed One
- embeds_one(:meta, Epiviewpoint.R4.Meta)
- embeds_one(:part_of, Epiviewpoint.R4.Reference)
- embeds_one(:text, Epiviewpoint.R4.Narrative)
+ embeds_one(:meta, EpiViewpoint.R4.Meta)
+ embeds_one(:part_of, EpiViewpoint.R4.Reference)
+ embeds_one(:text, EpiViewpoint.R4.Narrative)
# Embed Many
- embeds_many(:address, Epiviewpoint.R4.Address)
- embeds_many(:contact, Epiviewpoint.R4.Organization.Contact)
- embeds_many(:contained, Epiviewpoint.R4.ResourceList)
- embeds_many(:endpoint, Epiviewpoint.R4.Reference)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:identifier, Epiviewpoint.R4.Identifier)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
- embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
- embeds_many(:type, Epiviewpoint.R4.CodeableConcept)
+ embeds_many(:address, EpiViewpoint.R4.Address)
+ embeds_many(:contact, EpiViewpoint.R4.Organization.Contact)
+ embeds_many(:contained, EpiViewpoint.R4.ResourceList)
+ embeds_many(:endpoint, EpiViewpoint.R4.Reference)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:identifier, EpiViewpoint.R4.Identifier)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
+ embeds_many(:telecom, EpiViewpoint.R4.ContactPoint)
+ embeds_many(:type, EpiViewpoint.R4.CodeableConcept)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def path, do: "/Organization"
@@ -65,4 +65,4 @@ defmodule Epiviewpoint.R4.Organization do
|> cast_embed(:type)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/organization/contact.ex b/lib/epiviewpoint/r4/organization/contact.ex
index a1ba4fa3..06531120 100644
--- a/lib/epiviewpoint/r4/organization/contact.ex
+++ b/lib/epiviewpoint/r4/organization/contact.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Organization.Contact do
+defmodule EpiViewpoint.R4.Organization.Contact do
use Ecto.Schema
import Ecto.Changeset
@@ -9,19 +9,19 @@ defmodule Epiviewpoint.R4.Organization.Contact do
embedded_schema do
# Embed One
- embeds_one(:address, Epiviewpoint.R4.Address)
- embeds_one(:name, Epiviewpoint.R4.HumanName)
- embeds_one(:purpose, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:address, EpiViewpoint.R4.Address)
+ embeds_one(:name, EpiViewpoint.R4.HumanName)
+ embeds_one(:purpose, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
- embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
+ embeds_many(:telecom, EpiViewpoint.R4.ContactPoint)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -35,4 +35,4 @@ defmodule Epiviewpoint.R4.Organization.Contact do
|> cast_embed(:telecom)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/parameter_definition.ex b/lib/epiviewpoint/r4/parameter_definition.ex
index 6c4bd521..5bf17c9f 100644
--- a/lib/epiviewpoint/r4/parameter_definition.ex
+++ b/lib/epiviewpoint/r4/parameter_definition.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.ParameterDefinition do
+defmodule EpiViewpoint.R4.ParameterDefinition do
use Ecto.Schema
import Ecto.Changeset
@@ -25,12 +25,12 @@ defmodule Epiviewpoint.R4.ParameterDefinition do
field(:use, :string)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -39,4 +39,4 @@ defmodule Epiviewpoint.R4.ParameterDefinition do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/patient.ex b/lib/epiviewpoint/r4/patient.ex
index e760829b..8318feb8 100644
--- a/lib/epiviewpoint/r4/patient.ex
+++ b/lib/epiviewpoint/r4/patient.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Patient do
+defmodule EpiViewpoint.R4.Patient do
use Ecto.Schema
import Ecto.Changeset
@@ -42,24 +42,24 @@ defmodule Epiviewpoint.R4.Patient do
)
# Embed One
- embeds_one(:marital_status, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:managing_organization, Epiviewpoint.R4.Reference)
- embeds_one(:text, Epiviewpoint.R4.Narrative)
- embeds_one(:meta, Epiviewpoint.R4.Meta)
+ embeds_one(:marital_status, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:managing_organization, EpiViewpoint.R4.Reference)
+ embeds_one(:text, EpiViewpoint.R4.Narrative)
+ embeds_one(:meta, EpiViewpoint.R4.Meta)
# Embed Many
- embeds_many(:photo, Epiviewpoint.R4.Attachment)
- embeds_many(:communication, Epiviewpoint.R4.Patient.Communication)
- embeds_many(:name, Epiviewpoint.R4.HumanName)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
- embeds_many(:contained, Epiviewpoint.R4.ResourceList)
- embeds_many(:link, Epiviewpoint.R4.Patient.Link)
- embeds_many(:contact, Epiviewpoint.R4.Patient.Contact)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
- embeds_many(:identifier, Epiviewpoint.R4.Identifier)
- embeds_many(:general_practitioner, Epiviewpoint.R4.Reference)
- embeds_many(:address, Epiviewpoint.R4.Address)
+ embeds_many(:photo, EpiViewpoint.R4.Attachment)
+ embeds_many(:communication, EpiViewpoint.R4.Patient.Communication)
+ embeds_many(:name, EpiViewpoint.R4.HumanName)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:telecom, EpiViewpoint.R4.ContactPoint)
+ embeds_many(:contained, EpiViewpoint.R4.ResourceList)
+ embeds_many(:link, EpiViewpoint.R4.Patient.Link)
+ embeds_many(:contact, EpiViewpoint.R4.Patient.Contact)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
+ embeds_many(:identifier, EpiViewpoint.R4.Identifier)
+ embeds_many(:general_practitioner, EpiViewpoint.R4.Reference)
+ embeds_many(:address, EpiViewpoint.R4.Address)
end
def choices("deceased") do
@@ -80,7 +80,7 @@ defmodule Epiviewpoint.R4.Patient do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def path, do: "/Patient"
@@ -105,4 +105,4 @@ defmodule Epiviewpoint.R4.Patient do
|> cast_embed(:address)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/patient/communication.ex b/lib/epiviewpoint/r4/patient/communication.ex
index 11aa016b..dee2bebd 100644
--- a/lib/epiviewpoint/r4/patient/communication.ex
+++ b/lib/epiviewpoint/r4/patient/communication.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Patient.Communication do
+defmodule EpiViewpoint.R4.Patient.Communication do
use Ecto.Schema
import Ecto.Changeset
@@ -13,16 +13,16 @@ defmodule Epiviewpoint.R4.Patient.Communication do
field(:preferred, :boolean)
# Embed One
- embeds_one(:language, Epiviewpoint.R4.CodeableConcept)
+ embeds_one(:language, EpiViewpoint.R4.CodeableConcept)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -33,4 +33,4 @@ defmodule Epiviewpoint.R4.Patient.Communication do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/patient/contact.ex b/lib/epiviewpoint/r4/patient/contact.ex
index d552e4fa..7faf2b52 100644
--- a/lib/epiviewpoint/r4/patient/contact.ex
+++ b/lib/epiviewpoint/r4/patient/contact.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Patient.Contact do
+defmodule EpiViewpoint.R4.Patient.Contact do
use Ecto.Schema
import Ecto.Changeset
@@ -20,21 +20,21 @@ defmodule Epiviewpoint.R4.Patient.Contact do
)
# Embed One
- embeds_one(:address, Epiviewpoint.R4.Address)
- embeds_one(:name, Epiviewpoint.R4.HumanName)
- embeds_one(:organization, Epiviewpoint.R4.Reference)
- embeds_one(:period, Epiviewpoint.R4.Period)
+ embeds_one(:address, EpiViewpoint.R4.Address)
+ embeds_one(:name, EpiViewpoint.R4.HumanName)
+ embeds_one(:organization, EpiViewpoint.R4.Reference)
+ embeds_one(:period, EpiViewpoint.R4.Period)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
- embeds_many(:relationship, Epiviewpoint.R4.CodeableConcept)
- embeds_many(:telecom, Epiviewpoint.R4.ContactPoint)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
+ embeds_many(:relationship, EpiViewpoint.R4.CodeableConcept)
+ embeds_many(:telecom, EpiViewpoint.R4.ContactPoint)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -50,4 +50,4 @@ defmodule Epiviewpoint.R4.Patient.Contact do
|> cast_embed(:telecom)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/patient/link.ex b/lib/epiviewpoint/r4/patient/link.ex
index 6aa952d1..8798d8c7 100644
--- a/lib/epiviewpoint/r4/patient/link.ex
+++ b/lib/epiviewpoint/r4/patient/link.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Patient.Link do
+defmodule EpiViewpoint.R4.Patient.Link do
use Ecto.Schema
import Ecto.Changeset
@@ -20,16 +20,16 @@ defmodule Epiviewpoint.R4.Patient.Link do
)
# Embed One
- embeds_one(:other, Epiviewpoint.R4.Reference)
+ embeds_one(:other, EpiViewpoint.R4.Reference)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -40,4 +40,4 @@ defmodule Epiviewpoint.R4.Patient.Link do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/period.ex b/lib/epiviewpoint/r4/period.ex
index b4de40d4..9d083edc 100644
--- a/lib/epiviewpoint/r4/period.ex
+++ b/lib/epiviewpoint/r4/period.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Period do
+defmodule EpiViewpoint.R4.Period do
use Ecto.Schema
import Ecto.Changeset
@@ -15,12 +15,12 @@ defmodule Epiviewpoint.R4.Period do
field(:start, :utc_datetime_usec)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -29,4 +29,4 @@ defmodule Epiviewpoint.R4.Period do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/quantity.ex b/lib/epiviewpoint/r4/quantity.ex
index 22aab8b5..5db0642c 100644
--- a/lib/epiviewpoint/r4/quantity.ex
+++ b/lib/epiviewpoint/r4/quantity.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Quantity do
+defmodule EpiViewpoint.R4.Quantity do
use Ecto.Schema
import Ecto.Changeset
@@ -30,12 +30,12 @@ defmodule Epiviewpoint.R4.Quantity do
)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -44,4 +44,4 @@ defmodule Epiviewpoint.R4.Quantity do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/range.ex b/lib/epiviewpoint/r4/range.ex
index d51e9c8e..eef453e4 100644
--- a/lib/epiviewpoint/r4/range.ex
+++ b/lib/epiviewpoint/r4/range.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Range do
+defmodule EpiViewpoint.R4.Range do
use Ecto.Schema
import Ecto.Changeset
@@ -9,16 +9,16 @@ defmodule Epiviewpoint.R4.Range do
embedded_schema do
# Embed One
- embeds_one(:high, Epiviewpoint.R4.Quantity)
- embeds_one(:low, Epiviewpoint.R4.Quantity)
+ embeds_one(:high, EpiViewpoint.R4.Quantity)
+ embeds_one(:low, EpiViewpoint.R4.Quantity)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -29,4 +29,4 @@ defmodule Epiviewpoint.R4.Range do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/ratio.ex b/lib/epiviewpoint/r4/ratio.ex
index 50a3790f..2b61c8c4 100644
--- a/lib/epiviewpoint/r4/ratio.ex
+++ b/lib/epiviewpoint/r4/ratio.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Ratio do
+defmodule EpiViewpoint.R4.Ratio do
use Ecto.Schema
import Ecto.Changeset
@@ -9,16 +9,16 @@ defmodule Epiviewpoint.R4.Ratio do
embedded_schema do
# Embed One
- embeds_one(:denominator, Epiviewpoint.R4.Quantity)
- embeds_one(:numerator, Epiviewpoint.R4.Quantity)
+ embeds_one(:denominator, EpiViewpoint.R4.Quantity)
+ embeds_one(:numerator, EpiViewpoint.R4.Quantity)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -29,4 +29,4 @@ defmodule Epiviewpoint.R4.Ratio do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/reference.ex b/lib/epiviewpoint/r4/reference.ex
index 92b83c7b..8eeb1625 100644
--- a/lib/epiviewpoint/r4/reference.ex
+++ b/lib/epiviewpoint/r4/reference.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Reference do
+defmodule EpiViewpoint.R4.Reference do
use Ecto.Schema
import Ecto.Changeset
@@ -17,15 +17,15 @@ defmodule Epiviewpoint.R4.Reference do
field(:type, :string)
# Embed One
- embeds_one(:identifier, Epiviewpoint.R4.Identifier)
+ embeds_one(:identifier, EpiViewpoint.R4.Identifier)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -35,4 +35,4 @@ defmodule Epiviewpoint.R4.Reference do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/related_artifact.ex b/lib/epiviewpoint/r4/related_artifact.ex
index faabd573..ce9afc08 100644
--- a/lib/epiviewpoint/r4/related_artifact.ex
+++ b/lib/epiviewpoint/r4/related_artifact.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.RelatedArtifact do
+defmodule EpiViewpoint.R4.RelatedArtifact do
use Ecto.Schema
import Ecto.Changeset
@@ -36,15 +36,15 @@ defmodule Epiviewpoint.R4.RelatedArtifact do
)
# Embed One
- embeds_one(:document, Epiviewpoint.R4.Attachment)
+ embeds_one(:document, EpiViewpoint.R4.Attachment)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -54,4 +54,4 @@ defmodule Epiviewpoint.R4.RelatedArtifact do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/resource_list.ex b/lib/epiviewpoint/r4/resource_list.ex
index 1fb62b10..530cc946 100644
--- a/lib/epiviewpoint/r4/resource_list.ex
+++ b/lib/epiviewpoint/r4/resource_list.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.ResourceList do
+defmodule EpiViewpoint.R4.ResourceList do
use Ecto.Schema
import Ecto.Changeset
@@ -10,7 +10,7 @@ defmodule Epiviewpoint.R4.ResourceList do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -18,4 +18,4 @@ defmodule Epiviewpoint.R4.ResourceList do
|> cast(attrs, @fields)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/sampled_data.ex b/lib/epiviewpoint/r4/sampled_data.ex
index 4ee45d48..2625bc49 100644
--- a/lib/epiviewpoint/r4/sampled_data.ex
+++ b/lib/epiviewpoint/r4/sampled_data.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.SampledData do
+defmodule EpiViewpoint.R4.SampledData do
use Ecto.Schema
import Ecto.Changeset
@@ -23,15 +23,15 @@ defmodule Epiviewpoint.R4.SampledData do
field(:upper_limit, :decimal)
# Embed One
- embeds_one(:origin, Epiviewpoint.R4.Quantity)
+ embeds_one(:origin, EpiViewpoint.R4.Quantity)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -41,4 +41,4 @@ defmodule Epiviewpoint.R4.SampledData do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/signature.ex b/lib/epiviewpoint/r4/signature.ex
index 7dd9298d..d25a7213 100644
--- a/lib/epiviewpoint/r4/signature.ex
+++ b/lib/epiviewpoint/r4/signature.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Signature do
+defmodule EpiViewpoint.R4.Signature do
use Ecto.Schema
import Ecto.Changeset
@@ -19,17 +19,17 @@ defmodule Epiviewpoint.R4.Signature do
field(:when, :utc_datetime_usec)
# Embed One
- embeds_one(:on_behalf_of, Epiviewpoint.R4.Reference)
- embeds_one(:who, Epiviewpoint.R4.Reference)
+ embeds_one(:on_behalf_of, EpiViewpoint.R4.Reference)
+ embeds_one(:who, EpiViewpoint.R4.Reference)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:type, Epiviewpoint.R4.Coding)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:type, EpiViewpoint.R4.Coding)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -41,4 +41,4 @@ defmodule Epiviewpoint.R4.Signature do
|> cast_embed(:type)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/timing.ex b/lib/epiviewpoint/r4/timing.ex
index 77524b79..3c4a5394 100644
--- a/lib/epiviewpoint/r4/timing.ex
+++ b/lib/epiviewpoint/r4/timing.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Timing do
+defmodule EpiViewpoint.R4.Timing do
use Ecto.Schema
import Ecto.Changeset
@@ -12,17 +12,17 @@ defmodule Epiviewpoint.R4.Timing do
field(:event, {:array, :utc_datetime_usec})
# Embed One
- embeds_one(:code, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:repeat, Epiviewpoint.R4.Timing.Repeat)
+ embeds_one(:code, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:repeat, EpiViewpoint.R4.Timing.Repeat)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -34,4 +34,4 @@ defmodule Epiviewpoint.R4.Timing do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/timing/repeat.ex b/lib/epiviewpoint/r4/timing/repeat.ex
index 321f3071..5ecf31ed 100644
--- a/lib/epiviewpoint/r4/timing/repeat.ex
+++ b/lib/epiviewpoint/r4/timing/repeat.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.Timing.Repeat do
+defmodule EpiViewpoint.R4.Timing.Repeat do
use Ecto.Schema
import Ecto.Changeset
@@ -63,13 +63,13 @@ defmodule Epiviewpoint.R4.Timing.Repeat do
)
# Embed One
- embeds_one(:bounds_duration, Epiviewpoint.R4.Duration)
- embeds_one(:bounds_range, Epiviewpoint.R4.Range)
- embeds_one(:bounds_period, Epiviewpoint.R4.Period)
+ embeds_one(:bounds_duration, EpiViewpoint.R4.Duration)
+ embeds_one(:bounds_range, EpiViewpoint.R4.Range)
+ embeds_one(:bounds_period, EpiViewpoint.R4.Period)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
- embeds_many(:modifier_extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
+ embeds_many(:modifier_extension, EpiViewpoint.R4.Extension)
end
def choices("bounds") do
@@ -84,7 +84,7 @@ defmodule Epiviewpoint.R4.Timing.Repeat do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -97,4 +97,4 @@ defmodule Epiviewpoint.R4.Timing.Repeat do
|> cast_embed(:modifier_extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/trigger_definition.ex b/lib/epiviewpoint/r4/trigger_definition.ex
index febc5075..9364e4fd 100644
--- a/lib/epiviewpoint/r4/trigger_definition.ex
+++ b/lib/epiviewpoint/r4/trigger_definition.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.TriggerDefinition do
+defmodule EpiViewpoint.R4.TriggerDefinition do
use Ecto.Schema
import Ecto.Changeset
@@ -32,13 +32,13 @@ defmodule Epiviewpoint.R4.TriggerDefinition do
)
# Embed One
- embeds_one(:condition, Epiviewpoint.R4.Expression)
- embeds_one(:timing_reference, Epiviewpoint.R4.Reference)
- embeds_one(:timing_timing, Epiviewpoint.R4.Timing)
+ embeds_one(:condition, EpiViewpoint.R4.Expression)
+ embeds_one(:timing_reference, EpiViewpoint.R4.Reference)
+ embeds_one(:timing_timing, EpiViewpoint.R4.Timing)
# Embed Many
- embeds_many(:data, Epiviewpoint.R4.DataRequirement)
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:data, EpiViewpoint.R4.DataRequirement)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices("timing") do
@@ -55,7 +55,7 @@ defmodule Epiviewpoint.R4.TriggerDefinition do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -68,4 +68,4 @@ defmodule Epiviewpoint.R4.TriggerDefinition do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint/r4/usage_context.ex b/lib/epiviewpoint/r4/usage_context.ex
index b96c15a6..31c7f2f1 100644
--- a/lib/epiviewpoint/r4/usage_context.ex
+++ b/lib/epiviewpoint/r4/usage_context.ex
@@ -1,4 +1,4 @@
-defmodule Epiviewpoint.R4.UsageContext do
+defmodule EpiViewpoint.R4.UsageContext do
use Ecto.Schema
import Ecto.Changeset
@@ -9,14 +9,14 @@ defmodule Epiviewpoint.R4.UsageContext do
embedded_schema do
# Embed One
- embeds_one(:code, Epiviewpoint.R4.Coding)
- embeds_one(:value_codeable_concept, Epiviewpoint.R4.CodeableConcept)
- embeds_one(:value_quantity, Epiviewpoint.R4.Quantity)
- embeds_one(:value_range, Epiviewpoint.R4.Range)
- embeds_one(:value_reference, Epiviewpoint.R4.Reference)
+ embeds_one(:code, EpiViewpoint.R4.Coding)
+ embeds_one(:value_codeable_concept, EpiViewpoint.R4.CodeableConcept)
+ embeds_one(:value_quantity, EpiViewpoint.R4.Quantity)
+ embeds_one(:value_range, EpiViewpoint.R4.Range)
+ embeds_one(:value_reference, EpiViewpoint.R4.Reference)
# Embed Many
- embeds_many(:extension, Epiviewpoint.R4.Extension)
+ embeds_many(:extension, EpiViewpoint.R4.Extension)
end
def choices("value") do
@@ -33,7 +33,7 @@ defmodule Epiviewpoint.R4.UsageContext do
def choices(_), do: nil
- def version_namespace, do: Epiviewpoint.R4
+ def version_namespace, do: EpiViewpoint.R4
def version, do: "R4"
def changeset(data \\ %__MODULE__{}, attrs) do
@@ -47,4 +47,4 @@ defmodule Epiviewpoint.R4.UsageContext do
|> cast_embed(:extension)
|> validate_required(@required_fields)
end
-end
\ No newline at end of file
+end
diff --git a/lib/epiviewpoint_web/controllers/import_controller.ex b/lib/epiviewpoint_web/controllers/import_controller.ex
index a8efc1c7..17fe7ca1 100644
--- a/lib/epiviewpoint_web/controllers/import_controller.ex
+++ b/lib/epiviewpoint_web/controllers/import_controller.ex
@@ -42,7 +42,6 @@ defmodule EpiViewpointWeb.ImportController do
end
def create_bulk_fhir(conn, %{"files" => plug_uploads}) do
-
result = UploadedFile.from_plug_uploads(plug_uploads) |> Cases.import_bulk_fhir_lab_results(conn.assigns.current_user)
case result do
@@ -63,10 +62,8 @@ defmodule EpiViewpointWeb.ImportController do
|> Session.set_import_error_message(user_readable_message)
|> redirect(to: ~p"/import/start")
end
-
end
-
def show(conn, _params) do
conn
|> assign_defaults(@common_assigns)
diff --git a/lib/epiviewpoint_web/live/import_live.html.heex b/lib/epiviewpoint_web/live/import_live.html.heex
index 96ff9085..70a02288 100644
--- a/lib/epiviewpoint_web/live/import_live.html.heex
+++ b/lib/epiviewpoint_web/live/import_live.html.heex
@@ -17,7 +17,7 @@
Choose bulk FHIR NDJSON files from your computer, click “Upload”, and then wait for the file to upload.
- <%= form_tag("/import/upload_bulk_fhir", multipart: true, method: :post) %> "Alice",
+ "last_name" => "Ant",
+ "dob" => "01/02/1970",
+ "sample_date" => "06/01/2020",
+ "result_date" => "06/03/2020",
+ "result" => "positive"
+ },
+ %{
+ "first_name" => "Billy",
+ "last_name" => "Bat",
+ "dob" => "03/04/1990",
+ "sample_date" => "06/06/2020",
+ "result_date" => "06/07/2020",
+ "result" => "negative"
+ }
+ ]
+
+ assert {:ok, result} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{first_name last_name dob sample_date result_date result},
+ optional: ~w{}
+ )
+
+ assert result == [
+ %{
+ "first_name" => "Alice",
+ "last_name" => "Ant",
+ "dob" => "01/02/1970",
+ "sample_date" => "06/01/2020",
+ "result_date" => "06/03/2020",
+ "result" => "positive"
+ },
+ %{
+ "first_name" => "Billy",
+ "last_name" => "Bat",
+ "dob" => "03/04/1990",
+ "sample_date" => "06/06/2020",
+ "result_date" => "06/07/2020",
+ "result" => "negative"
+ }
+ ]
+ end
+
+ test "ignores unspecified headers in bulk FHIR" do
+ input = [
+ %{
+ "column_a" => "value_a",
+ "column_b" => "value_b",
+ "column_c" => "value_c"
+ }
+ ]
+
+ assert {:ok, result} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{column_a},
+ optional: ~w{column_b}
+ )
+
+ assert result == [%{"column_a" => "value_a", "column_b" => "value_b"}]
+ end
+
+ test "fails if required header is missing in bulk FHIR" do
+ input = [
+ %{
+ "column_a" => "value_a",
+ "column_b" => "value_b"
+ }
+ ]
+
+ assert {:error, :missing_headers, missing} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{column_a column_b column_c column_d},
+ optional: ~w{}
+ )
+
+ assert Enum.sort(missing) == ["column_c", "column_d"]
+ end
+
+ test "allows optional headers in bulk FHIR" do
+ input = [
+ %{
+ "column_a" => "value_a",
+ "column_b" => "value_b",
+ "optional_c" => "value_c"
+ }
+ ]
+
+ assert {:ok, result} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{column_a column_b},
+ optional: ~w{optional_c optional_d}
+ )
+
+ assert result == [%{"column_a" => "value_a", "column_b" => "value_b", "optional_c" => "value_c"}]
+ end
+
+ test "header transformer transforms headers in bulk FHIR" do
+ input = [
+ %{
+ "first_name" => "Alice",
+ "last_name" => "Ant"
+ },
+ %{
+ "first_name" => "Billy",
+ "last_name" => "Bat"
+ }
+ ]
+
+ assert {:ok, result} =
+ DataFile.read(input, :bulk_fhir, fn headers -> Enum.map(headers, &String.upcase/1) end,
+ required: ~w{FIRST_NAME LAST_NAME},
+ optional: ~w{}
+ )
+
+ assert result == [
+ %{
+ "FIRST_NAME" => "Alice",
+ "LAST_NAME" => "Ant"
+ },
+ %{
+ "FIRST_NAME" => "Billy",
+ "LAST_NAME" => "Bat"
+ }
+ ]
+ end
end
end
diff --git a/test/epiviewpoint_web/controllers/import_controller_test.exs b/test/epiviewpoint_web/controllers/import_controller_test.exs
index fedb422a..441b6f7e 100644
--- a/test/epiviewpoint_web/controllers/import_controller_test.exs
+++ b/test/epiviewpoint_web/controllers/import_controller_test.exs
@@ -129,6 +129,46 @@ defmodule EpiViewpointWeb.ImportControllerTest do
assert conn |> redirected_to() == "/import/start"
assert "Invalid mm-dd-yyyy format: 06/02/bb" = Session.get_import_error_message(conn)
end
+
+ test "accepts multiple NDJSON files for bulk FHIR upload", %{conn: conn, tmp_dir: tmp_dir} do
+ patient_data = """
+ {"resourceType":"Patient","id":"10000","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"]},"identifier":[{"system":"urn:example:person_tid","value":"alice"}],"name":[{"family":"Testuser","given":["Alice"]}],"birthDate":"1970-01-01","telecom":[{"system":"phone","value":"1111111000"}],"address":[{"line":["1234 Test St"],"city":"City","state":"TS","postalCode":"00000"}],"gender":"female","extension":[{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2106-3","display":"White"}},{"url":"text","valueString":"White"}]},{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2186-5","display":"Not Hispanic or Latino"}},{"url":"text","valueString":"Not Hispanic or Latino"}]},{"url":"http://hl7.org/fhir/StructureDefinition/patient-occupation","valueString":"Doctor"}]}
+ {"resourceType":"Patient","id":"10004","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"]},"identifier":[{"system":"urn:example:person_tid","value":"billy"}],"name":[{"family":"Testuser","given":["Billy"]}],"birthDate":"1971-01-01","telecom":[{"system":"phone","value":"1111111004"}],"address":[{"line":["1234 Test St"],"city":"City","state":"TS","postalCode":"00000"}],"gender":"female","extension":[{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2106-3","display":"White"}},{"url":"text","valueString":"White"}]},{"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity","extension":[{"url":"ombCategory","valueCoding":{"system":"urn:oid:2.16.840.1.113883.6.238","code":"2186-5","display":"Not Hispanic or Latino"}},{"url":"text","valueString":"Not Hispanic or Latino"}]},{"url":"http://hl7.org/fhir/StructureDefinition/patient-occupation","valueString":"Doctor"}]}
+ """
+
+ observation_data = """
+ {"resourceType":"Observation","id":"alice-result-1","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab"]},"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/datereportedtolhd","valueDate":"08/05/2020"}],"category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"laboratory","display":"Laboratory"}]}],"status":"final","code":{"text":"TestTest"},"subject":{"reference":"Patient/10000"},"effectiveDateTime":"08/01/2020","issued":"2020-08-03T00:00:00Z","performer":[{"reference":"Organization/city-hospital-lab"}],"valueCodeableConcept":{"coding":[{"system":"http://snomed.info/sct","code":"10828004","display":"Positive"}]},"interpretation":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation","code":"POS","display":"Positive"}]}]}
+ {"resourceType":"Observation","id":"billy-result-1","meta":{"profile":["http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab"]},"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/datereportedtolhd","valueDate":"08/05/2020"}],"category":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/observation-category","code":"laboratory","display":"Laboratory"}]}],"status":"final","code":{"text":"TestTest"},"subject":{"reference":"Patient/10004"},"effectiveDateTime":"08/02/2020","issued":"2020-08-04T00:00:00Z","performer":[{"reference":"Organization/city-hospital-lab"}],"valueCodeableConcept":{"coding":[{"system":"http://snomed.info/sct","code":"260385009","display":"Negative"}]},"interpretation":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation","code":"NEG","display":"Negative"}]}]}
+ """
+
+ organization_data = """
+ {"resourceType":"Organization","id":"org1","name":"Lab Co South"}
+ {"resourceType":"Organization","id":"org2","name":"City Hospital Lab"}
+ """
+
+ patient_file_path = Tempfile.write_ndjson!(patient_data, tmp_dir)
+ observation_file_path = Tempfile.write_ndjson!(observation_data, tmp_dir)
+ organization_file_path = Tempfile.write_ndjson!(organization_data, tmp_dir)
+
+ conn =
+ conn
+ |> post(~p"/import/upload_bulk_fhir", %{
+ "files" => [
+ %Plug.Upload{path: patient_file_path, filename: "Patient.ndjson"},
+ %Plug.Upload{path: observation_file_path, filename: "Observation.ndjson"},
+ %Plug.Upload{path: organization_file_path, filename: "Organization.ndjson"}
+ ]
+ })
+
+ assert conn |> redirected_to() == "/import/complete"
+
+ assert %EpiViewpoint.Cases.Import.ImportInfo{
+ imported_lab_result_count: 2,
+ imported_person_count: 2,
+ total_lab_result_count: 2,
+ total_person_count: 2
+ } = Session.get_last_file_import_info(conn)
+ end
end
describe "show" do
From 3106aea0a5448f9aeef96ccd4f1b3c1b0285a9f6 Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Fri, 6 Sep 2024 17:16:18 -0400
Subject: [PATCH 3/8] code refactoring
---
lib/epiviewpoint/bulk_fhir_parser.ex | 249 +++++++++++++++------------
lib/epiviewpoint/cases/import.ex | 5 +-
2 files changed, 145 insertions(+), 109 deletions(-)
diff --git a/lib/epiviewpoint/bulk_fhir_parser.ex b/lib/epiviewpoint/bulk_fhir_parser.ex
index 89caeb1e..e4641906 100644
--- a/lib/epiviewpoint/bulk_fhir_parser.ex
+++ b/lib/epiviewpoint/bulk_fhir_parser.ex
@@ -1,122 +1,155 @@
defmodule EpiViewpoint.BulkFhirParser do
def parse_bulk_fhir(file_list) do
- contents = file_list |> Enum.map(& &1.contents) |> List.to_string()
+ with {:ok, contents} <- combine_contents(file_list),
+ {:ok, resources} <- load_resources(file_list),
+ {:ok, extracted} <- extract_resources(resources),
+ {:ok, joined} <- join_resources(extracted) do
+ {:ok, to_map(joined, contents)}
+ end
+ end
- file_list
- |> load_resources()
- |> extract_resources()
- |> join_resources()
- |> to_map(contents)
+ defp combine_contents(file_list) do
+ contents = file_list |> Enum.map(& &1.contents) |> List.to_string()
+ {:ok, contents}
end
- def load_resources(file_list) do
- file_list
- |> Enum.reduce(%{}, fn file, acc ->
- resources = load_resource_file(file.contents)
+ defp load_resources(file_list) do
+ result = Enum.reduce_while(file_list, {:ok, %{}}, fn file, {:ok, acc} ->
+ case load_resource_file(file.contents) do
+ {:ok, resources} -> {:cont, {:ok, group_resources(resources, acc)}}
+ {:error, reason} -> {:halt, {:error, reason}}
+ end
+ end)
- Enum.reduce(resources, acc, fn resource, inner_acc ->
- type = resource.resource_type
- Map.update(inner_acc, type, [resource], &[resource | &1])
- end)
+ case result do
+ {:ok, resources} -> {:ok, resources}
+ {:error, reason} -> {:error, reason}
+ end
+ end
+
+ defp group_resources(resources, acc) do
+ Enum.reduce(resources, acc, fn resource, acc ->
+ Map.update(acc, resource.resource_type, [resource], &[resource | &1])
end)
end
- def load_resource_file(file_content) do
- file_content
+ defp load_resource_file(file_content) do
+ result = file_content
|> String.split("\n")
|> Stream.map(&String.trim/1)
- |> Stream.filter(&(&1 != ""))
- |> Stream.map(&json_to_kindle_schema(&1, "EpiViewpoint.R4"))
+ |> Stream.filter(&filter_empty_lines/1)
+ |> Stream.map(&json_to_kindle_schema/1)
|> Enum.to_list()
+
+ {:ok, result}
+ rescue
+ e -> {:error, "Failed to load resource file: #{inspect(e)}"}
end
- def extract_resources(resources) do
- resources
- |> Enum.reduce(%{}, fn {resource_type, resource_list}, acc ->
- Map.put(acc, resource_type, extract_resource(resource_type, resource_list))
- end)
+ defp json_to_kindle_schema(json) do
+ case Jason.decode(json) do
+ {:ok, map} -> Kindling.Converter.convert("EpiViewpoint.R4", map)
+ {:error, reason} -> {:error, "Failed to decode JSON: #{inspect(reason)}"}
+ end
end
- def extract_resource("Patient", resource_list) do
- resource_list
- |> Enum.map(fn
- %EpiViewpoint.R4.Patient{
- id: caseid,
- identifier: [%EpiViewpoint.R4.Identifier{value: person_tid}],
- name: [%EpiViewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
- birth_date: dateofbirth,
- gender: sex,
- address: [
- %EpiViewpoint.R4.Address{
- line: [diagaddress_street1],
- city: diagaddress_city,
- state: diagaddress_state,
- postal_code: diagaddress_zip
- }
- ],
- telecom: [%EpiViewpoint.R4.ContactPoint{value: phonenumber}],
- extension: extensions
- } = _resource ->
- %{
- caseid: caseid,
- person_tid: person_tid,
- search_firstname: search_firstname,
- search_lastname: search_lastname,
- dateofbirth: Calendar.strftime(dateofbirth, "%m/%d/%Y"),
- sex: sex |> to_string() |> String.capitalize(),
- diagaddress_street1: diagaddress_street1,
- diagaddress_city: diagaddress_city,
- diagaddress_state: diagaddress_state,
- diagaddress_zip: diagaddress_zip,
- phonenumber: phonenumber,
- ethnicity: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"),
- occupation: find_extension(extensions),
- race: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race")
- }
+ defp extract_resources(resources) do
+ result = Enum.reduce_while(resources, {:ok, %{}}, fn {resource_type, resource_list}, {:ok, acc} ->
+ case extract_resource(resource_type, resource_list) do
+ {:ok, extracted} -> {:cont, {:ok, Map.put(acc, resource_type, extracted)}}
+ {:error, reason} -> {:halt, {:error, reason}}
+ end
end)
+
+ case result do
+ {:ok, extracted} -> {:ok, extracted}
+ {:error, reason} -> {:error, reason}
+ end
end
- def extract_resource("Observation", resource_list) do
- resource_list
- |> Enum.map(fn
- %EpiViewpoint.R4.Observation{
- id: lab_result_tid,
- subject: %EpiViewpoint.R4.Reference{reference: "Patient/" <> pat_id},
- effective_date_time: datecollected,
- issued: resultdate,
- code: %EpiViewpoint.R4.CodeableConcept{text: testname},
- interpretation: [%EpiViewpoint.R4.CodeableConcept{coding: [%EpiViewpoint.R4.Coding{display: result}]}],
- performer: [%EpiViewpoint.R4.Reference{reference: "Organization/" <> org_id}],
- extension: extensions
- } = _resource ->
- %{
- lab_result_tid: lab_result_tid,
- pat_id: pat_id,
- datecollected: datecollected,
- resultdate: resultdate |> DateTime.to_date() |> Calendar.strftime("%m/%d/%Y"),
- testname: testname,
- result: result,
- org_id: org_id,
- datereportedtolhd: find_extension(extensions)
- }
- end)
+ defp extract_resource("Patient", resource_list) do
+ {:ok, Enum.map(resource_list, &extract_patient/1)}
end
- def extract_resource("Organization", resource_list) do
- resource_list
- |> Enum.map(fn
- %EpiViewpoint.R4.Organization{
- id: orgnization_id,
- name: orderingfacilityname
- } = _resource ->
- %{
- orgnization_id: orgnization_id,
- orderingfacilityname: orderingfacilityname
- }
- end)
+ defp extract_resource("Observation", resource_list) do
+ {:ok, Enum.map(resource_list, &extract_observation/1)}
+ end
+
+ defp extract_resource("Organization", resource_list) do
+ {:ok, Enum.map(resource_list, &extract_organization/1)}
+ end
+
+ defp extract_resource(unknown_type, _) do
+ {:error, "Unknown resource type: #{unknown_type}"}
+ end
+
+ defp extract_patient(%EpiViewpoint.R4.Patient{
+ id: caseid,
+ identifier: [%EpiViewpoint.R4.Identifier{value: person_tid}],
+ name: [%EpiViewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
+ birth_date: dateofbirth,
+ gender: sex,
+ address: [
+ %EpiViewpoint.R4.Address{
+ line: [diagaddress_street1],
+ city: diagaddress_city,
+ state: diagaddress_state,
+ postal_code: diagaddress_zip
+ }
+ ],
+ telecom: [%EpiViewpoint.R4.ContactPoint{value: phonenumber}],
+ extension: extensions
+ }) do
+ %{
+ caseid: caseid,
+ person_tid: person_tid,
+ search_firstname: search_firstname,
+ search_lastname: search_lastname,
+ dateofbirth: format_date(dateofbirth),
+ sex: String.capitalize(to_string(sex)),
+ diagaddress_street1: diagaddress_street1,
+ diagaddress_city: diagaddress_city,
+ diagaddress_state: diagaddress_state,
+ diagaddress_zip: diagaddress_zip,
+ phonenumber: phonenumber,
+ ethnicity: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"),
+ occupation: find_extension(extensions),
+ race: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race")
+ }
+ end
+
+ defp extract_observation(%EpiViewpoint.R4.Observation{
+ id: lab_result_tid,
+ subject: %EpiViewpoint.R4.Reference{reference: "Patient/" <> pat_id},
+ effective_date_time: datecollected,
+ issued: resultdate,
+ code: %EpiViewpoint.R4.CodeableConcept{text: testname},
+ interpretation: [%EpiViewpoint.R4.CodeableConcept{coding: [%EpiViewpoint.R4.Coding{display: result}]}],
+ performer: [%EpiViewpoint.R4.Reference{reference: "Organization/" <> org_id}],
+ extension: extensions
+ }) do
+ %{
+ lab_result_tid: lab_result_tid,
+ pat_id: pat_id,
+ datecollected: datecollected,
+ resultdate: format_date(resultdate),
+ testname: testname,
+ result: result,
+ org_id: org_id,
+ datereportedtolhd: find_extension(extensions)
+ }
+ end
+
+ defp extract_organization(%EpiViewpoint.R4.Organization{
+ id: organization_id,
+ name: ordering_facility_name
+ }) do
+ %{
+ organization_id: organization_id,
+ ordering_facility_name: ordering_facility_name
+ }
end
- # Helper function to find extension values
defp find_extension(extensions, url \\ nil) do
Enum.find_value(extensions, fn
%EpiViewpoint.R4.Extension{
@@ -136,29 +169,33 @@ defmodule EpiViewpoint.BulkFhirParser do
end)
end
- defp json_to_kindle_schema(json, version_namespace) do
- map = Jason.decode!(json)
- Kindling.Converter.convert(version_namespace, map)
- end
-
- def join_resources(resources) do
+ defp join_resources(resources) do
patients = Map.get(resources, "Patient", [])
observations = Map.get(resources, "Observation", [])
organizations = Map.get(resources, "Organization", [])
- observations
+ joined = observations
|> Enum.map(fn observation ->
patient = Enum.find(patients, &(&1.caseid == observation.pat_id))
- organization = Enum.find(organizations, &(&1.orgnization_id == observation.org_id))
+ organization = Enum.find(organizations, &(&1.organization_id == observation.org_id))
observation
|> Map.merge(patient || %{})
|> Map.merge(organization || %{})
- |> Map.drop([:pat_id, :org_id, :orgnization_id])
+ |> Map.drop([:pat_id, :org_id, :organization_id])
end)
+
+ {:ok, joined}
end
- def to_map(resources, contents) do
+ defp to_map(resources, contents) do
%{file_name: "load.bulk_fhir", contents: contents, list: resources}
end
+
+ defp filter_empty_lines(line) do
+ line != ""
+ end
+
+ defp format_date(date) when is_struct(date, Date), do: Calendar.strftime(date, "%m/%d/%Y")
+ defp format_date(datetime) when is_struct(datetime, DateTime), do: datetime |> DateTime.to_date() |> format_date()
end
diff --git a/lib/epiviewpoint/cases/import.ex b/lib/epiviewpoint/cases/import.ex
index 7f667744..ee31ba47 100644
--- a/lib/epiviewpoint/cases/import.ex
+++ b/lib/epiviewpoint/cases/import.ex
@@ -61,9 +61,8 @@ defmodule EpiViewpoint.Cases.Import do
end
def import_bulk_fhir_data_file(lab_result_data_file_list, originator) do
- lab_result_data_file_list
- |> BulkFhirParser.parse_bulk_fhir()
- |> import_data_file(originator)
+ {:ok, bulk_fhir_data} = BulkFhirParser.parse_bulk_fhir(lab_result_data_file_list)
+ import_data_file(bulk_fhir_data, originator)
end
def import_data_file(_file, %{admin: false}), do: {:error, "Originator must be an admin"}
From 20cb94ad4d370da5e1dcffdbbe118d4cd42a29a7 Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Fri, 6 Sep 2024 18:29:11 -0400
Subject: [PATCH 4/8] manual browser test passed
---
.../controllers/import_controller.ex | 6 ++-
.../live/import_live.html.heex | 38 +++++++++++--------
2 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/lib/epiviewpoint_web/controllers/import_controller.ex b/lib/epiviewpoint_web/controllers/import_controller.ex
index 17fe7ca1..71d100d6 100644
--- a/lib/epiviewpoint_web/controllers/import_controller.ex
+++ b/lib/epiviewpoint_web/controllers/import_controller.ex
@@ -41,8 +41,12 @@ defmodule EpiViewpointWeb.ImportController do
end
end
+ def create_bulk_fhir(%{assigns: %{current_user: %{admin: false}}} = conn, _file) do
+ redirect(conn, to: "/")
+ end
+
def create_bulk_fhir(conn, %{"files" => plug_uploads}) do
- result = UploadedFile.from_plug_uploads(plug_uploads) |> Cases.import_bulk_fhir_lab_results(conn.assigns.current_user)
+ result = plug_uploads |> UploadedFile.from_plug_uploads() |> Cases.import_bulk_fhir_lab_results(conn.assigns.current_user)
case result do
{:ok, import_info} ->
diff --git a/lib/epiviewpoint_web/live/import_live.html.heex b/lib/epiviewpoint_web/live/import_live.html.heex
index 70a02288..783949d6 100644
--- a/lib/epiviewpoint_web/live/import_live.html.heex
+++ b/lib/epiviewpoint_web/live/import_live.html.heex
@@ -6,21 +6,29 @@
<% end %>
- Choose a CSV or NDJSON file from your computer, click “Upload”, and then wait for the file to upload.
+ Choose a CSV or NDJSON file from your computer, click "Upload", and then wait for the file to upload.
- <%= form_tag("/import/upload", multipart: true, method: :post) %>
+ <%= form_tag("/import/upload", multipart: true, method: :post) do %>
+
+
+ <% end %>
+
+
+ <%= form_tag("/import/upload_bulk_fhir", multipart: true, method: :post) do %>
+
+
+ <% end %>
+
\ No newline at end of file
From b86d94f9352ef67b169934b9cda16b3f2664c9bc Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Fri, 6 Sep 2024 18:53:04 -0400
Subject: [PATCH 5/8] code refactoring
---
lib/epiviewpoint/bulk_fhir_parser.ex | 60 ++++++++++---------
.../live/import_live.html.heex | 20 ++-----
2 files changed, 37 insertions(+), 43 deletions(-)
diff --git a/lib/epiviewpoint/bulk_fhir_parser.ex b/lib/epiviewpoint/bulk_fhir_parser.ex
index e4641906..9aa0ba66 100644
--- a/lib/epiviewpoint/bulk_fhir_parser.ex
+++ b/lib/epiviewpoint/bulk_fhir_parser.ex
@@ -14,12 +14,13 @@ defmodule EpiViewpoint.BulkFhirParser do
end
defp load_resources(file_list) do
- result = Enum.reduce_while(file_list, {:ok, %{}}, fn file, {:ok, acc} ->
- case load_resource_file(file.contents) do
- {:ok, resources} -> {:cont, {:ok, group_resources(resources, acc)}}
- {:error, reason} -> {:halt, {:error, reason}}
- end
- end)
+ result =
+ Enum.reduce_while(file_list, {:ok, %{}}, fn file, {:ok, acc} ->
+ case load_resource_file(file.contents) do
+ {:ok, resources} -> {:cont, {:ok, group_resources(resources, acc)}}
+ {:error, reason} -> {:halt, {:error, reason}}
+ end
+ end)
case result do
{:ok, resources} -> {:ok, resources}
@@ -34,12 +35,13 @@ defmodule EpiViewpoint.BulkFhirParser do
end
defp load_resource_file(file_content) do
- result = file_content
- |> String.split("\n")
- |> Stream.map(&String.trim/1)
- |> Stream.filter(&filter_empty_lines/1)
- |> Stream.map(&json_to_kindle_schema/1)
- |> Enum.to_list()
+ result =
+ file_content
+ |> String.split("\n")
+ |> Stream.map(&String.trim/1)
+ |> Stream.filter(&filter_empty_lines/1)
+ |> Stream.map(&json_to_kindle_schema/1)
+ |> Enum.to_list()
{:ok, result}
rescue
@@ -54,12 +56,13 @@ defmodule EpiViewpoint.BulkFhirParser do
end
defp extract_resources(resources) do
- result = Enum.reduce_while(resources, {:ok, %{}}, fn {resource_type, resource_list}, {:ok, acc} ->
- case extract_resource(resource_type, resource_list) do
- {:ok, extracted} -> {:cont, {:ok, Map.put(acc, resource_type, extracted)}}
- {:error, reason} -> {:halt, {:error, reason}}
- end
- end)
+ result =
+ Enum.reduce_while(resources, {:ok, %{}}, fn {resource_type, resource_list}, {:ok, acc} ->
+ case extract_resource(resource_type, resource_list) do
+ {:ok, extracted} -> {:cont, {:ok, Map.put(acc, resource_type, extracted)}}
+ {:error, reason} -> {:halt, {:error, reason}}
+ end
+ end)
case result do
{:ok, extracted} -> {:ok, extracted}
@@ -174,20 +177,21 @@ defmodule EpiViewpoint.BulkFhirParser do
observations = Map.get(resources, "Observation", [])
organizations = Map.get(resources, "Organization", [])
- joined = observations
- |> Enum.map(fn observation ->
- patient = Enum.find(patients, &(&1.caseid == observation.pat_id))
- organization = Enum.find(organizations, &(&1.organization_id == observation.org_id))
-
- observation
- |> Map.merge(patient || %{})
- |> Map.merge(organization || %{})
- |> Map.drop([:pat_id, :org_id, :organization_id])
- end)
+ joined = Enum.map(observations, &merge_resources(&1, patients, organizations))
{:ok, joined}
end
+ defp merge_resources(observation, patients, organizations) do
+ patient = Enum.find(patients, &(&1.caseid == observation.pat_id))
+ organization = Enum.find(organizations, &(&1.organization_id == observation.org_id))
+
+ observation
+ |> Map.merge(patient || %{})
+ |> Map.merge(organization || %{})
+ |> Map.drop([:pat_id, :org_id, :organization_id])
+ end
+
defp to_map(resources, contents) do
%{file_name: "load.bulk_fhir", contents: contents, list: resources}
end
diff --git a/lib/epiviewpoint_web/live/import_live.html.heex b/lib/epiviewpoint_web/live/import_live.html.heex
index 783949d6..7fbb09c5 100644
--- a/lib/epiviewpoint_web/live/import_live.html.heex
+++ b/lib/epiviewpoint_web/live/import_live.html.heex
@@ -10,25 +10,15 @@
<%= form_tag("/import/upload", multipart: true, method: :post) do %>
-
+
<% end %>
-
-
\ No newline at end of file
+
From f494a98aa3e464e46ba5f2b66793db7560aa06cb Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Fri, 6 Sep 2024 19:50:19 -0400
Subject: [PATCH 6/8] limit upload file type to ndjson
---
lib/epiviewpoint_web/live/import_live.html.heex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/epiviewpoint_web/live/import_live.html.heex b/lib/epiviewpoint_web/live/import_live.html.heex
index 7fbb09c5..d2774cee 100644
--- a/lib/epiviewpoint_web/live/import_live.html.heex
+++ b/lib/epiviewpoint_web/live/import_live.html.heex
@@ -18,7 +18,7 @@
Choose bulk FHIR NDJSON files from your computer, click "Upload", and then wait for the file to upload.
<%= form_tag("/import/upload_bulk_fhir", multipart: true, method: :post) do %>
-
+
<% end %>
From be670088e910f2b4233833a84ad98cd56543489b Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Mon, 9 Sep 2024 16:12:18 -0400
Subject: [PATCH 7/8] refactoring
---
lib/epiviewpoint/bulk_fhir_parser.ex | 125 +++++++++++-------
.../controllers/import_controller.ex | 4 +-
test/epiviewpoint/data_file_test.exs | 40 +++---
3 files changed, 99 insertions(+), 70 deletions(-)
diff --git a/lib/epiviewpoint/bulk_fhir_parser.ex b/lib/epiviewpoint/bulk_fhir_parser.ex
index 9aa0ba66..9ffa6cbe 100644
--- a/lib/epiviewpoint/bulk_fhir_parser.ex
+++ b/lib/epiviewpoint/bulk_fhir_parser.ex
@@ -39,7 +39,7 @@ defmodule EpiViewpoint.BulkFhirParser do
file_content
|> String.split("\n")
|> Stream.map(&String.trim/1)
- |> Stream.filter(&filter_empty_lines/1)
+ |> Stream.filter(&(&1 != ""))
|> Stream.map(&json_to_kindle_schema/1)
|> Enum.to_list()
@@ -86,23 +86,25 @@ defmodule EpiViewpoint.BulkFhirParser do
{:error, "Unknown resource type: #{unknown_type}"}
end
- defp extract_patient(%EpiViewpoint.R4.Patient{
- id: caseid,
- identifier: [%EpiViewpoint.R4.Identifier{value: person_tid}],
- name: [%EpiViewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
- birth_date: dateofbirth,
- gender: sex,
- address: [
- %EpiViewpoint.R4.Address{
- line: [diagaddress_street1],
- city: diagaddress_city,
- state: diagaddress_state,
- postal_code: diagaddress_zip
- }
- ],
- telecom: [%EpiViewpoint.R4.ContactPoint{value: phonenumber}],
- extension: extensions
- }) do
+ defp extract_patient(%EpiViewpoint.R4.Patient{} = patient) do
+ %EpiViewpoint.R4.Patient{
+ id: caseid,
+ identifier: [%EpiViewpoint.R4.Identifier{value: person_tid}],
+ name: [%EpiViewpoint.R4.HumanName{given: [search_firstname], family: search_lastname}],
+ birth_date: dateofbirth,
+ gender: sex,
+ address: [
+ %EpiViewpoint.R4.Address{
+ line: [diagaddress_street1],
+ city: diagaddress_city,
+ state: diagaddress_state,
+ postal_code: diagaddress_zip
+ }
+ ],
+ telecom: [%EpiViewpoint.R4.ContactPoint{value: phonenumber}],
+ extension: extensions
+ } = patient
+
%{
caseid: caseid,
person_tid: person_tid,
@@ -115,22 +117,24 @@ defmodule EpiViewpoint.BulkFhirParser do
diagaddress_state: diagaddress_state,
diagaddress_zip: diagaddress_zip,
phonenumber: phonenumber,
- ethnicity: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"),
- occupation: find_extension(extensions),
- race: find_extension(extensions, "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race")
+ ethnicity: find_extension(extensions, :ethnicity),
+ occupation: find_extension(extensions, :occupation),
+ race: find_extension(extensions, :race)
}
end
- defp extract_observation(%EpiViewpoint.R4.Observation{
- id: lab_result_tid,
- subject: %EpiViewpoint.R4.Reference{reference: "Patient/" <> pat_id},
- effective_date_time: datecollected,
- issued: resultdate,
- code: %EpiViewpoint.R4.CodeableConcept{text: testname},
- interpretation: [%EpiViewpoint.R4.CodeableConcept{coding: [%EpiViewpoint.R4.Coding{display: result}]}],
- performer: [%EpiViewpoint.R4.Reference{reference: "Organization/" <> org_id}],
- extension: extensions
- }) do
+ defp extract_observation(%EpiViewpoint.R4.Observation{} = observation) do
+ %EpiViewpoint.R4.Observation{
+ id: lab_result_tid,
+ subject: %EpiViewpoint.R4.Reference{reference: "Patient/" <> pat_id},
+ effective_date_time: datecollected,
+ issued: resultdate,
+ code: %EpiViewpoint.R4.CodeableConcept{text: testname},
+ interpretation: [%EpiViewpoint.R4.CodeableConcept{coding: [%EpiViewpoint.R4.Coding{display: result}]}],
+ performer: [%EpiViewpoint.R4.Reference{reference: "Organization/" <> org_id}],
+ extension: extensions
+ } = observation
+
%{
lab_result_tid: lab_result_tid,
pat_id: pat_id,
@@ -139,31 +143,60 @@ defmodule EpiViewpoint.BulkFhirParser do
testname: testname,
result: result,
org_id: org_id,
- datereportedtolhd: find_extension(extensions)
+ datereportedtolhd: find_extension(extensions, :datereportedtolhd)
}
end
- defp extract_organization(%EpiViewpoint.R4.Organization{
- id: organization_id,
- name: ordering_facility_name
- }) do
+ defp extract_organization(%EpiViewpoint.R4.Organization{} = organization) do
+ %EpiViewpoint.R4.Organization{
+ id: organization_id,
+ name: ordering_facility_name
+ } = organization
+
%{
organization_id: organization_id,
ordering_facility_name: ordering_facility_name
}
end
- defp find_extension(extensions, url \\ nil) do
- Enum.find_value(extensions, fn
+ defp find_extension(extensions, :race) do
+ Enum.find_value(extensions, nil, fn
+ %EpiViewpoint.R4.Extension{
+ url: "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
+ extension: [%EpiViewpoint.R4.Extension{url: "ombCategory", value_coding: %EpiViewpoint.R4.Coding{display: value}}, _]
+ } ->
+ value
+
+ _ ->
+ nil
+ end)
+ end
+
+ defp find_extension(extensions, :ethnicity) do
+ Enum.find_value(extensions, nil, fn
%EpiViewpoint.R4.Extension{
- url: ^url,
+ url: "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity",
extension: [%EpiViewpoint.R4.Extension{url: "ombCategory", value_coding: %EpiViewpoint.R4.Coding{display: value}}, _]
} ->
value
+ _ ->
+ nil
+ end)
+ end
+
+ defp find_extension(extensions, :occupation) do
+ Enum.find_value(extensions, nil, fn
%EpiViewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/patient-occupation", value_string: value} ->
value
+ _ ->
+ nil
+ end)
+ end
+
+ defp find_extension(extensions, :datereportedtolhd) do
+ Enum.find_value(extensions, nil, fn
%EpiViewpoint.R4.Extension{url: "http://hl7.org/fhir/StructureDefinition/datereportedtolhd", value_date: value} ->
value
@@ -183,12 +216,12 @@ defmodule EpiViewpoint.BulkFhirParser do
end
defp merge_resources(observation, patients, organizations) do
- patient = Enum.find(patients, &(&1.caseid == observation.pat_id))
- organization = Enum.find(organizations, &(&1.organization_id == observation.org_id))
+ patient = Enum.find(patients, %{}, &(&1.caseid == observation.pat_id))
+ organization = Enum.find(organizations, %{}, &(&1.organization_id == observation.org_id))
observation
- |> Map.merge(patient || %{})
- |> Map.merge(organization || %{})
+ |> Map.merge(patient)
+ |> Map.merge(organization)
|> Map.drop([:pat_id, :org_id, :organization_id])
end
@@ -196,10 +229,6 @@ defmodule EpiViewpoint.BulkFhirParser do
%{file_name: "load.bulk_fhir", contents: contents, list: resources}
end
- defp filter_empty_lines(line) do
- line != ""
- end
-
defp format_date(date) when is_struct(date, Date), do: Calendar.strftime(date, "%m/%d/%Y")
- defp format_date(datetime) when is_struct(datetime, DateTime), do: datetime |> DateTime.to_date() |> format_date()
+ defp format_date(datetime) when is_struct(datetime, DateTime), do: DateTime.to_date(datetime) |> format_date()
end
diff --git a/lib/epiviewpoint_web/controllers/import_controller.ex b/lib/epiviewpoint_web/controllers/import_controller.ex
index 71d100d6..9c250747 100644
--- a/lib/epiviewpoint_web/controllers/import_controller.ex
+++ b/lib/epiviewpoint_web/controllers/import_controller.ex
@@ -23,7 +23,7 @@ defmodule EpiViewpointWeb.ImportController do
case result do
{:ok, import_info} ->
- {_imported_people, popped_import_info} = import_info |> Map.pop(:imported_people)
+ {_imported_people, popped_import_info} = Map.pop(import_info, :imported_people)
conn
|> Session.set_last_file_import_info(popped_import_info)
@@ -50,7 +50,7 @@ defmodule EpiViewpointWeb.ImportController do
case result do
{:ok, import_info} ->
- {_imported_people, popped_import_info} = import_info |> Map.pop(:imported_people)
+ {_imported_people, popped_import_info} = Map.pop(import_info, :imported_people)
conn
|> Session.set_last_file_import_info(popped_import_info)
diff --git a/test/epiviewpoint/data_file_test.exs b/test/epiviewpoint/data_file_test.exs
index 53bd540a..a07f13aa 100644
--- a/test/epiviewpoint/data_file_test.exs
+++ b/test/epiviewpoint/data_file_test.exs
@@ -218,11 +218,11 @@ defmodule EpiViewpoint.DataFileTest do
}
]
- assert {:ok, result} =
- DataFile.read(input, :bulk_fhir, &Function.identity/1,
- required: ~w{first_name last_name dob sample_date result_date result},
- optional: ~w{}
- )
+ {:ok, result} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{first_name last_name dob sample_date result_date result},
+ optional: ~w{}
+ )
assert result == [
%{
@@ -253,11 +253,11 @@ defmodule EpiViewpoint.DataFileTest do
}
]
- assert {:ok, result} =
- DataFile.read(input, :bulk_fhir, &Function.identity/1,
- required: ~w{column_a},
- optional: ~w{column_b}
- )
+ {:ok, result} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{column_a},
+ optional: ~w{column_b}
+ )
assert result == [%{"column_a" => "value_a", "column_b" => "value_b"}]
end
@@ -288,11 +288,11 @@ defmodule EpiViewpoint.DataFileTest do
}
]
- assert {:ok, result} =
- DataFile.read(input, :bulk_fhir, &Function.identity/1,
- required: ~w{column_a column_b},
- optional: ~w{optional_c optional_d}
- )
+ {:ok, result} =
+ DataFile.read(input, :bulk_fhir, &Function.identity/1,
+ required: ~w{column_a column_b},
+ optional: ~w{optional_c optional_d}
+ )
assert result == [%{"column_a" => "value_a", "column_b" => "value_b", "optional_c" => "value_c"}]
end
@@ -309,11 +309,11 @@ defmodule EpiViewpoint.DataFileTest do
}
]
- assert {:ok, result} =
- DataFile.read(input, :bulk_fhir, fn headers -> Enum.map(headers, &String.upcase/1) end,
- required: ~w{FIRST_NAME LAST_NAME},
- optional: ~w{}
- )
+ {:ok, result} =
+ DataFile.read(input, :bulk_fhir, fn headers -> Enum.map(headers, &String.upcase/1) end,
+ required: ~w{FIRST_NAME LAST_NAME},
+ optional: ~w{}
+ )
assert result == [
%{
From 49426d7bf6ced1036d04c643dc8a9341896d607d Mon Sep 17 00:00:00 2001
From: Lei Zhou
Date: Tue, 10 Sep 2024 15:23:34 -0400
Subject: [PATCH 8/8] minor refactoring
---
lib/epiviewpoint/bulk_fhir_parser.ex | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/lib/epiviewpoint/bulk_fhir_parser.ex b/lib/epiviewpoint/bulk_fhir_parser.ex
index 9ffa6cbe..834e0a42 100644
--- a/lib/epiviewpoint/bulk_fhir_parser.ex
+++ b/lib/epiviewpoint/bulk_fhir_parser.ex
@@ -148,14 +148,9 @@ defmodule EpiViewpoint.BulkFhirParser do
end
defp extract_organization(%EpiViewpoint.R4.Organization{} = organization) do
- %EpiViewpoint.R4.Organization{
- id: organization_id,
- name: ordering_facility_name
- } = organization
-
%{
- organization_id: organization_id,
- ordering_facility_name: ordering_facility_name
+ organization_id: organization.id,
+ ordering_facility_name: organization.name
}
end