Open apostaat opened 2 years ago
id: financial-transaction
resourceType: Mapping
returns: resource
body:
$let:
- performer_external_identifier:
- type:
coding:
- code: "EXTID"
value: $ performer.id
- referring_external_identifier:
- type:
coding:
- code: "EXTID"
value: $ referring.id
- named_identifiers:
$fn: ["ext_id", "id","entity"]
$body:
$if: $ ext_id && id && entity
$then:
$map: $ concat(ext_id, id)
$as: idn
$body:
last_name: $ entity.name.0.family
first_name: $ entity.name.0.given.0
middle_initial: $ entity.name.0.given.1
suffix: $ entity.name.0.suffix.0
identifier: $ idn.value
identifier_type:
$if: $ idn.value && idn.type.coding.0.code
$then: $ idn.type.coding.0.code
$else:
$if: $ idn.value
$then: "UPIN"
$body:
transaction_date:
from: $ currentDate
transaction_type: "CG"
department:
code: $ organization.id
name: $ organization.name
patient_location:
id: $ location.id
name: $ location.name
diagnosis:
$map: $ diagnosis
$as: dg
$body:
code: $ dg.code
display: $ dg.display
system:
$if: $ dg.system = "ICD10"
$then: "I10"
$else: "I9"
performing_provider:
$call: named_identifiers
$args:
- $ performer_external_identifier
- $ performer.identifier
- $ performer
referring_practitioner:
$call: named_identifiers
$args:
- $ referring_external_identifier
- $ referring.identifier
- $ referring
procedure: $ procedure
{ns financial-transaction
;; boilerplate like
;; resourceType, returns, body
;; should be wrapped programmatically
GetNameFn
{:zen/tag #{get-name}
:zj/type :lambda
:zj/code (fn [{:keys name}]
{:last_name (-> name
first
:family)
:first_name (-> name
first
:given
first)
:middle_initial (-> name
first
:given
second)
:suffix (-> name
first
:suffix
:first)})}
GetIdFn
{:zen/tag #{get-id-fn}
:zj/type :lambda
:zj/code (fn [{:keys [value]}]
{:identifier value
:identifier_type
(if-let [code (and value (-> value :type :coding first :code))]
code
(and value "UPIN"))})}
;; thus we use lambdas only and code is just a string
;; so our macro is just format function
;;
;; (defn pseudo-macro
;; [s & args]
;; (apply format s args))
;; (pseudo-macro "(merge (%s id) (%s entity))"
;; '(fn [x] {:k 5})
;; '(fn [y] {:j 9}))
;; => "(merge ((fn [x] {:k 5}) id) ((fn [y] {:j 9}) entity))"
;; so eval-fn and args is just a macro that
;; wraps string of code inside brackets and passes it
;; to reader
;; (TODO) if you have ideas how to realize closures and
;; pass functions and arguments 'from the outside'
;; without macro - it will be nice
GetNamedIdentifiers
{:zen/tag #{named-identifiers}
:zj/import-fn #{get-id-fn get-name-fn}
:zj/type :lambda
;; pred is called before evaluation of zj/code
;; if falsey -> returns nil as result
:zj/pred {:zj/code (fn [x y z] (and x y z))}
:zj/code {:zj/macro
(fn [extid id entity]
(mapv (fn [idn#] (merge (%s entity)
(%s idn#))))
[extid id])
:zj/args [{:zj/eval-fn get-id-fn}
{:zj/eval-fn get-name-fn}]}}
FT1
{:zen/tag #{ft1-mapping}
:zj/import-fn #{get-diagnosis named-identifiers}
:transaction_date {:from ^zj/path[:currentDate]}
:transaction_type "CG"
:department {:code ^zj/path[:organization :id]
:name ^zj/path[:organization :name]}
:patient_location {:id ^zj/path[:location :id ]
:name ^zj/path[:location :name]}
:diagnosis {:zj/eval-fn get-diagnosis
:zj/args ^zj/path[:diagnosis]}
:performing_provider {:zj/eval-fn named-identifiers
:zj/args [^zj/path[:performer_external_identifier]
^zj/path[:performer :identifier]
^zj/path[:performer]]}
:referring_practitioner {:zj/eval-fn named-identifiers
:zj/args [^zj/path[:referring_external_identifier]
^zj/path[:referring :identifier]
^zj/path[:referring]]}}
INB4:
What is Jute?
What Jute does?
[YAML] -> [JuteTemplate] -> [YAML]
What is jute.clj?
IDEA
What we want to improve?
Sometimes, the syntax of JUTE is quite verbose.
For example 'map' directive requires declaring 'as' and 'body' variables:
How it may look like?
The idea is to use native Clojure data structures and functions:
We expect that it may look like this:
We expect that zen library will be handy there: https://github.com/zen-lang/zen
What is Zen?
Plan
Team:
@mlapshin Mikhail Lapshin @VictorGus Victor Gusakov @thezorkij Mikhail Pravilenko @apostaat Artem Alexeev