defmodule HL7.Header do @moduledoc """ An HL7 header implementation that can be used to build MSH segments and HL7 messages. It is also exposed as metadata after parsing any HL7 message. """ @type t :: %HL7.Header{ message_type: binary(), trigger_event: binary(), sending_facility: binary(), sending_application: binary(), message_date_time: String.t(), security: String.t(), message_control_id: String.t(), processing_id: String.t(), separators: HL7.Separators.t(), hl7_version: binary() } defstruct message_type: "", trigger_event: "", sending_facility: "", sending_application: "", receiving_facility: "", receiving_application: "", message_date_time: "", security: "", message_control_id: "", processing_id: "", separators: %HL7.Separators{}, hl7_version: "" @spec new(String.t(), String.t(), String.t(), String.t() | list(), String.t()) :: HL7.Header.t() def new(message_type, trigger_event, message_control_id, processing_id \\ "P", version \\ "2.1") do %HL7.Header{ hl7_version: version, message_type: message_type, trigger_event: trigger_event, message_control_id: message_control_id, processing_id: processing_id, message_date_time: get_message_date_time() } end @spec to_msh(HL7.Header.t()) :: [any(), ...] def to_msh(%HL7.Header{} = h) do [ "MSH", h.separators.field, h.separators.encoding_characters, h.sending_application, h.sending_facility, h.receiving_application, h.receiving_facility, h.message_date_time, h.security, get_message_type_field(h), h.message_control_id, h.processing_id, h.hl7_version ] end @spec zero_pad(pos_integer(), pos_integer()) :: String.t() defp zero_pad(num, digits_needed) when is_integer(num) and is_integer(digits_needed) do string_num = Integer.to_string(num) pad_size = digits_needed - String.length(string_num) zeros = String.duplicate("0", pad_size) zeros <> string_num end @spec get_message_date_time() :: String.t() def get_message_date_time() do now = DateTime.utc_now() zero_pad(now.year, 4) <> zero_pad(now.month, 2) <> zero_pad(now.day, 2) <> zero_pad(now.hour, 2) <> zero_pad(now.minute, 2) <> zero_pad(now.second, 2) <> "+0000" end @spec get_message_type_field(HL7.Header.t()) :: [any()] def get_message_type_field(%HL7.Header{} = h) do v = case h.hl7_version do "2.1" -> [h.message_type, h.trigger_event] "2.2" -> [h.message_type, h.trigger_event] "2.3" -> [h.message_type, h.trigger_event] "2.3.1" -> [h.message_type, h.trigger_event] _ -> [h.message_type, h.trigger_event, h.message_type <> "_" <> h.trigger_event] end [v] end end