Minor changes to FHIR

Minor changes to FHIR

module namespace page = 'http://basex.org/modules/web-page';
import module namespace csd_bl = "https://github.com/openhie/openinfoman/csd_bl";
import module namespace functx = 'http://www.functx.com';
import module namespace csr_proc = "https://github.com/openhie/openinfoman/csr_proc";
import module namespace csd_webui =  "https://github.com/openhie/openinfoman/csd_webui";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace svs_lsvs = "https://github.com/openhie/openinfoman/svs_lsvs";
declare namespace csd =  "urn:ihe:iti:csd:2013";
declare namespace svs = "urn:ihe:iti:svs:2008";
declare default element  namespace   "urn:ihe:iti:csd:2013";

declare function page:get_location ($doc_name,$_id,$page,$_count,$_since)
{
  <CSD xmlns:csd="urn:ihe:iti:csd:2013">
    {
      let $search_collection :=
      <collection>
        <search directory="facilityDirectory">urn:ihe:iti:csd:2014:stored-function:facility-search</search>
        <search directory="organizationDirectory">urn:ihe:iti:csd:2014:stored-function:organization-search</search>
      </collection>
      for $search in $search_collection/search
      let $search_name := $search/text()
      return
      (
        let $careServicesSubRequest :=
        <csd:careServicesRequest>
          <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL('')}">
            <csd:requestParams>
              {
                let $id := $_id
                return if (functx:all-whitespace($id)) then () else <csd:id entityID="{$id}"/>
              }

              {
                let $t_start := $page
                return if (functx:is-a-number($t_start))
                  then
                    let $start := max((xs:int($t_start),1))
                    let $t_count := $_count
                    let $count := if(functx:is-a-number($t_count)) then  max((xs:int($t_count),1)) else 50
                    let $startIndex := ($start - 1)*$count + 1
                    return <csd:start>{$startIndex}</csd:start>
                  else ()
              }
         {
           let $count := $_count
           return
              if(functx:is-a-number($count))
              then  <csd:max>{max((xs:int($count),1))} </csd:max>
              else ()
         }
         {
          let $since := $_since
          return if (functx:all-whitespace($since)) then () else <csd:record updated="{$since}"/>
         }
            </csd:requestParams>
          </csd:function>
        </csd:careServicesRequest>

        let $doc :=  csd_dm:open_document($doc_name)
        let $contents := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
        let $directory := $search/@directory/string()
        return $contents/*[name() = $directory]
      )
    }
  </CSD>
};

declare function page:get_provider ($doc_name,$_id,$page,$_count,$_since,$organization,$location)
{
  let $search_name := "urn:ihe:iti:csd:2014:stored-function:provider-search"
  return
  <CSD xmlns:csd="urn:ihe:iti:csd:2013">
    {
      let $careServicesSubRequest :=
      <csd:careServicesRequest>
        <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL('')}">
          <csd:requestParams>
            {
              let $id := $_id
              return if (functx:all-whitespace($id)) then () else <csd:id entityID="{$id}"/>
            }

            {
              let $t_start := $page
              return if (functx:is-a-number($t_start))
                then
                  let $start := max((xs:int($t_start),1))
                  let $t_count := $_count
                  let $count := if(functx:is-a-number($t_count)) then  max((xs:int($t_count),1)) else 50
                  let $startIndex := ($start - 1)*$count + 1
                  return <csd:start>{$startIndex}</csd:start>
                else ()
            }
            {
              let $org := $organization
              return if (functx:all-whitespace($org)) then () else  <csd:organizations><csd:organization>{$org}</csd:organization></csd:organizations>
            }
            {
              let $loc := $location
              return if (functx:all-whitespace($loc)) then () else <csd:facilities><csd:facility>{$loc}</csd:facility></csd:facilities>
            }
       {
         let $count := $_count
         return
            if(functx:is-a-number($count))
            then  <csd:max>{max((xs:int($count),1))} </csd:max>
            else ()
       }
       {
        let $since := $_since
        return if (functx:all-whitespace($since)) then () else <csd:record updated="{$since}"/>
       }
          </csd:requestParams>
        </csd:function>
      </csd:careServicesRequest>

      let $doc :=  csd_dm:open_document($doc_name)
      let $contents := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
      return $contents/providerDirectory
    }
  </CSD>
};

declare function page:get_services ($doc_name,$_id,$page,$_count,$_since)
{
  let $search_name := "urn:ihe:iti:csd:2014:stored-function:service-search"
  return
  <CSD xmlns:csd="urn:ihe:iti:csd:2013">
    {
      let $careServicesSubRequest :=
      <csd:careServicesRequest>
        <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL('')}">
          <csd:requestParams>
            {
              let $id := $_id
              return if (functx:all-whitespace($id)) then () else <csd:id entityID="{$id}"/>
            }

            {
              let $t_start := $page
              return if (functx:is-a-number($t_start))
                then
                  let $start := max((xs:int($t_start),1))
                  let $t_count := $_count
                  let $count := if(functx:is-a-number($t_count)) then  max((xs:int($t_count),1)) else 50
                  let $startIndex := ($start - 1)*$count + 1
                  return <csd:start>{$startIndex}</csd:start>
                else ()
            }
            {
              let $count := $_count
              return
                  if(functx:is-a-number($count))
                  then  <csd:max>{max((xs:int($count),1))} </csd:max>
                  else ()
            }
            {
              let $since := $_since
              return if (functx:all-whitespace($since)) then () else <csd:record updated="{$since}"/>
            }
          </csd:requestParams>
        </csd:function>
      </csd:careServicesRequest>

      let $doc :=  csd_dm:open_document($doc_name)
      let $contents := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
      return $contents/serviceDirectory
    }
  </CSD>
};

declare
  %rest:path("/fhir/{$doc_name}/Location/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRLocationID($id,$page,$_count,$_since,$doc_name)
{
  page:FHIRLocation($id,$page,$_count,$_since,$doc_name)
};

declare
  %rest:path("/fhir/{$doc_name}/Location/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRLocation($_id,$page,$_count,$_since,$doc_name)
{
let $contents := page:get_location ($doc_name,$_id,$page,$_count,$_since)

let $location :=
<json type='object'>
<resourceType>Bundle</resourceType>
<total>{count($contents/facilityDirectory/facility) + count($contents/organizationDirectory/organization)}</total>
<type>history</type>
<entry type="array">
{
for $content in ($contents/facilityDirectory/facility,$contents/organizationDirectory/organization)
return
<_ type="object">
  <fullURL>{csd_webui:generateURL("fhir/" || $doc_name || "/Location/" || $content/@entityID)}</fullURL>
  {
    if($content/record/@created/string() != $content/record/@updated/string())
    then
    <request type="object">
      <method>PUT</method>
      <url>{$doc_name}/Location/{$content/@entityID/string()}</url>
    </request>
    else()
  }
  <resource type="object">
    <resourceType>Location</resourceType>
    <id>{$content/@entityID/string()}</id>
    {
     if(exists($content/otherID))
     then
     <identifier type="array">
      {
      for $otherid in $content/otherID
      return
      <_ type="object">
        <system>{$otherid/@assigningAuthorityName/string()}</system>
        <value>{$otherid/text()}</value>
      </_>
      }
     </identifier>
     else ()
    }
    {
      let $search_name := "urn:ihe:iti:csd:2014:stored-function:organization-search"
      let $parent :=
      if(exists($content/organizations/organization))
      then
      $content/organizations/organization/@entityID/string()
      else
      if (exists($content/parent))
      then $content/parent/@entityID/string()
      else ()

      return if($parent)
      then
      let $careServicesSubRequest :=
      <csd:careServicesRequest>
        <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL()}">
          <csd:requestParams>
            <csd:id entityID="{$parent}"/>
          </csd:requestParams>
        </csd:function>
      </csd:careServicesRequest>
      let $doc :=  csd_dm:open_document($doc_name)
      let $organization := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
      return if(exists($organization/organizationDirectory/organization))
      then
      <partOf type="object">
        <reference>{csd_webui:generateURL("fhir/" || $doc_name || "/Location/" || $organization/organizationDirectory/organization/@entityID/string())}</reference>
        <display>{$organization/organizationDirectory/organization/primaryName/text()}</display>
      </partOf>
      else ()
      else ()
    }
    {
    if(exists($content/contactPoint))
    then
    <telecom type="array">
     {
     for $contactPoint in $content/contactPoint
     return ()
     }
    </telecom>
    else ()
    }
    {
      if(exists($content/geocode))
      then
      <position type="object">
        <longitude>{$content/geocode/longitude/text()}</longitude>
        <latitude>{$content/geocode/latitude/text()}</latitude>
      </position>
      else ()
    }
    <meta type="object">
      <lastUpdated>{$content/record/@updated/string()}</lastUpdated>
      <tag type="array">
        <_ type="object">
          {$content/record/@sourceDirectory/string()}
          <system>https://github.com/openhie/openinfoman/tags/fhir/sourceDirectory</system>
        </_>
      </tag>
    </meta>
    {
      if(exists($content/codedType))
      then
        <type type="object">
          <coding type="array">
            {
              for $codedType in $content/codedType
                return
                <_ type="object">
                  {$codedType/@code/string()}
                  <system>{$codedType/@codingScheme/string()}</system>
                  {
                  if(functx:all-whitespace($codedType/text()))
                  then ()
                  else
                  <display>{$codedType/text()}</display>
                  }
                </_>
            }
          </coding>
        </type>
      else ()
    }
    <status>{$content/record/@status/string()}</status>
    <name>{$content/primaryName/text()}</name>
    <mode>instance</mode>
  </resource>
</_>
}
</entry>
</json>

return (
  <rest:response>
    <output:serialization-parameters>
      <output:media-type value='application/json'/>
    </output:serialization-parameters>
  </rest:response>,
  json:serialize($location,map{"format":"direct",'escape': 'no'})
  )

};

declare
  %rest:path("/fhir/{$doc_name}/Practitioner/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitionerID($id,$page,$_count,$_since,$doc_name,$organization,$location)
{
  page:FHIRPractitioner($id,$page,$_count,$_since,$doc_name,$organization,$location)
};

declare
  %rest:path("/fhir/{$doc_name}/Practitioner/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitioner($_id,$page,$_count,$_since,$doc_name,$organization,$location)
{
let $contents := page:get_provider ($doc_name,$_id,$page,$_count,$_since,$organization,$location)
let $practitioner :=
<json type='object'>
<resourceType>Bundle</resourceType>
<total>{count($contents/providerDirectory/provider)}</total>
<type>history</type>
<entry type="array">
{
  for $content in $contents/providerDirectory/provider
  return
  <_ type="object">
    <fullURL>{csd_webui:generateURL("fhir/" || $doc_name || "/Practitioner/" || $content/@entityID)}</fullURL>
    {
      if($content/record/@created/string() != $content/record/@updated/string())
      then
      <request type="object">
        <method>PUT</method>
        <url>{$doc_name}/Practitioner/{$content/@entityID/string()}</url>
      </request>
      else()
    }
    <resource type="object">
      <resourceType>Practitioner</resourceType>
      <id>{$content/@entityID/string()}</id>
      {
        if(exists($content/otherID))
        then
        <identifier type="array">
        {
          for $otherid in $content/otherID
          return
          <_ type="object">
            <system>{$otherid/@assigningAuthorityName/string()}</system>
            <value>{$otherid/text()}</value>
          </_>
        }
          <_ type="object">
            <system>urn:ihe:iti:csd:2013:entityID</system>
            <value>{$content/@entityID/string()}</value>
          </_>
        </identifier>
        else ()
      }
      <active>
        {
          let $status := lower-case($content/record/@status/string())
          return if($status = "active") then "true"
                  else if($status = "inactive" or $status = "in-active") then "false"
                  else()
        }
      </active>
      {
        if(exists($content/demographic/contactPoint/codedType))
        then
        <telecom type="array">
          {
            for $contactPoint in $content/demographic/contactPoint
            return if (exists($contactPoint/codedType))
                    then
                    <_ type="object">
                      <system>
                      {
                        let $code := $contactPoint/codedType/@code/string()
                        return if($code = "BP") then "phone"
                               else if ($code = "EMAIL") then "email"
                               else if ($code = "FAX") then "fax"
                               else "other"
                      }
                      </system>
                      <value>{$contactPoint/codedType/text()}</value>
                    </_>
                   else ()
          }
        </telecom>
        else ()
      }
      {
        if(exists($content/demographic/address/addressLine))
        then
        <address type="array">
          {
            for $address in $content/demographic/address
            return
              if(exists($address/addressLine))
              then
              <_ type="object">
                {
                  let $csdtype := lower-case($address/@type/string())
                  let $fhirtype := if($csdtype = "mailing" or $csdtype = "mailing address") then "postal"
                                    else if ($csdtype = "physical" or $csdtype = "physical address") then "physical"
                                    else ()
                  return if($fhirtype)
                          then <type>{$fhirtype}</type>
                          else ()
                }
                {
                  for $addressLine in $address/addressLine
                  return if($addressLine/@component = "streetAddress")
                          then <line>{$addressLine/text()}</line>
                          else if($addressLine/@component = "city")
                          then <city>{$addressLine/text()}</city>
                          else if($addressLine/@component = "stateProvince")
                          then <state>{$addressLine/text()}</state>
                          else if($addressLine/@component = "country")
                          then <country>{$addressLine/text()}</country>
                          else if($addressLine/@component = "postalCode")
                          then <postalCode>{$addressLine/text()}</postalCode>
                          else()
                }
              </_>
              else ()
          }
        </address>
        else ()
      }
      {
        if(exists($content/credential)) then
        <qualification type="array">
        {
          for $credential in $content/credential
          return
          <_ type="object">

              <coding type="array">
              {
                for $codedType in $credential/codedType
                return
                <_ type="object">
                  {
                    if($codedType/@codingScheme/string()) then
                    <system>{$codedType/@codingScheme/string()}</system>
                    else ()
                  }
                  {
                    if($codedType/@code/string()) then
                    {$codedType/@code/string()}
                    else ()
                  }
                </_>
              }
              </coding>
              {
                if($credential/codedType/text()) then
                <text>{($credential/codedType/text())[1]}</text>
                else ()
              }

            {
              if($credential/issuingAuthority/text()) then
              <issuer type="object">
                <display>{$credential/issuingAuthority/text()}</display>
              </issuer>
              else ()
            }
            {
              if(exists($credential/credentialIssueDate) or exists($credential/credentialRenewalDate)) then
              <period type="object">
              {
                if($credential/credentialIssueDate/text()) then
                <start>{$credential/credentialIssueDate/text()}</start>
                else ()
              }
              {
                if($credential/credentialRenewalDate/text()) then
                <end>{$credential/credentialRenewalDate/text()}</end>
                else ()
              }
              </period>
              else ()
            }
          </_>
        }
        </qualification>
        else ()
      }
      {
        if(exists($content/language)) then
        <communication type="array">
        {
          for $language in $content/language
          return
          <_ type="object">
            <coding type="array">
              {
                <_ type="object">
                  {
                    if($language/@codingScheme/string()) then
                    <system>{$language/@codingScheme/string()}</system>
                    else ()
                  }
                  {
                    if($language/@code/string()) then
                    {$language/@code/string()}
                    else ()
                  }
                    <display>{$language/text()}</display>
                </_>
              }
            </coding>
            {
              if($language/text()) then
              <text>{($language/text())}</text>
              else ()
            }
          </_>
        }
        </communication>
        else ()
      }
      <name type="array">
      {
        for $name in $content/demographic/name
        return
        <_ type="object">
          <text>{($name/commonName/text())[1]}</text>
          <family>{($name/surname/text())[1]}</family>
          <given>{($name/forename/text())[1] || ' ' || ($name/otherName/text())[1]}</given>
          <prefix>{($name/honorific/text())[1]}</prefix>
          <suffix>{($name/suffix/text())[1]}</suffix>
        </_>
      }
      </name>
      {
        if(exists($content/demographic/gender))
        then
        <gender>
          {
            let $gender := $content/demographic/gender/text()
            return if($gender = "F") then "female"
                    else if($gender = "M") then "male"
                    else lower-case($gender)
          }
        </gender>
        else ()
      }
      {
        if(exists($content/demographic/dateOfBirth))
        then
        <birthDate>{$content/demographic/dateOfBirth/text()}</birthDate>
        else ()
      }
      <meta type="object">
        <lastUpdated>{$content/record/@updated/string()}</lastUpdated>
        <tag type="array">
          <_ type="object">
            {$content/record/@sourceDirectory/string()}
            <system>https://github.com/openhie/openinfoman/tags/fhir/sourceDirectory</system>
          </_>
        </tag>
      </meta>
    </resource>
  </_>
}
</entry>
</json>
return (
          <rest:response>
            <output:serialization-parameters>
              <output:media-type value='application/json'/>
            </output:serialization-parameters>
          </rest:response>,
          json:serialize($practitioner,map{"format":"direct",'escape': 'no'})
        )
};

declare
  %rest:path("/fhir/{$doc_name}/PractitionerRole/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitionerRoleID($id,$page,$_count,$_since,$doc_name,$organization,$location)
{
  page:FHIRPractitionerRole($id,$page,$_count,$_since,$doc_name,$organization,$location)
};

declare
  %rest:path("/fhir/{$doc_name}/PractitionerRole/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitionerRole($_id,$page,$_count,$_since,$doc_name,$organization,$location)
{
let $contents := page:get_provider ($doc_name,$_id,$page,$_count,$_since,$organization,$location)
let $practitionerRole :=
<json type='object'>
<resourceType>Bundle</resourceType>
<total>{count($contents/providerDirectory/provider)}</total>
<type>history</type>
<entry type="array">
{
  for $content in $contents/providerDirectory/provider
  return
  <_ type="object">
    <fullURL>{csd_webui:generateURL("fhir/" || $doc_name || "/PractitionerRole/" || $content/@entityID)}</fullURL>
    {
      if($content/record/@created/string() != $content/record/@updated/string())
      then
      <request type="object">
        <method>PUT</method>
        <url>{$doc_name}/PractitionerRole/{$content/@entityID/string()}</url>
      </request>
      else()
    }
    <resource type="object">
      <resourceType>PractitionerRole</resourceType>
      <id>{$content/@entityID/string()}</id>
      {
        if(exists($content/otherID))
        then
        <identifier type="array">
        {
          for $otherid in $content/otherID
          return
          <_ type="object">
            <system>{$otherid/@assigningAuthorityName/string()}</system>
            <value>{$otherid/text()}</value>
          </_>
        }
        </identifier>
        else ()
      }
      <active>
        {
          let $status := lower-case($content/record/@status/string())
          return if($status = "active") then "true"
                  else if($status = "inactive" or $status = "in-active") then "false"
                  else()
        }
      </active>
      <practitioner type="object">
        <reference>{csd_webui:generateURL("fhir/" || $doc_name || "/Practitioner/" || $content/@entityID)}</reference>
        <display>{$content/demographic/name[1]/commonName[1]/string()}</display>
      </practitioner>
      <specialty type="array">
        {
        for $specialty at $index in $content/specialty
        return
        <_ type="object">

            <coding type="array">
            {
              for $codedType in $specialty/codedType
              return
              <_ type="object">
                {
                  if($codedType/@codingScheme/string()) then
                  <system>{$codedType/@codingScheme/string()}</system>
                  else ()
                }
                {
                  if($codedType/@code/string()) then
                  {$codedType/@code/string()}
                  else ()
                }
                {
                  let $svsCode := svs_lsvs:get_single_version_code($codedType/@code/string(),$codedType/@codingScheme/string(),"")
                  return <display>{$svsCode//svs:Concept/@displayName/string()}</display>
                }
              </_>
            }
            </coding>
            {
              if($specialty/codedType/text()) then
              <text>{($specialty/codedType/text())[1]}</text>
              else ()
            }

        </_>
        }
      </specialty>
      <location type="array">
        {
        for $facility at $index in $content/facilities/facility
        return
        <_ type="object">
          <reference>{csd_webui:generateURL("fhir/" || $doc_name || "/Location/" || $facility/@entityID/string())}</reference>
          {
            let $search_name := "urn:ihe:iti:csd:2014:stored-function:facility-search"
            let $careServicesSubRequest :=
            <csd:careServicesRequest>
              <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL()}">
                <csd:requestParams>
                  <csd:id entityID="{$facility/@entityID/string()}"/>
                </csd:requestParams>
              </csd:function>
            </csd:careServicesRequest>
            let $doc :=  csd_dm:open_document($doc_name)
            let $fac := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
            return <display>{$fac//primaryName/text()}</display>
          }
        </_>
        }
      </location>
      <availableTime type="array">
        {
          for $service in $content/facilities/facility/service
          return <_ type="object">
            {
              for $operatingHours in $service/operatingHours
              let $CSDdayOfTheWeek := $operatingHours/dayOfTheWeek/text()
              let $FHIRdayOfTheWeek := page:getDayOfTheWeek($CSDdayOfTheWeek)
              return (
                      <daysOfWeek>{$FHIRdayOfTheWeek}</daysOfWeek>,
                      <availableStartTime>{$operatingHours/beginningHour/text()}</availableStartTime>,
                      <availableEndTime>{$operatingHours/endingHour/text()}</availableEndTime>
                      )
            }
            </_>
        }
        {
          for $operatingHours in $content/facilities/facility/operatingHours
          return
          <_ type="object">
          {
            let $CSDdayOfTheWeek := $operatingHours/dayOfTheWeek/text()
              let $FHIRdayOfTheWeek := page:getDayOfTheWeek($CSDdayOfTheWeek)
              return (
                      <daysOfWeek>{$FHIRdayOfTheWeek}</daysOfWeek>,
                      <availableStartTime>{$operatingHours/beginningHour/text()}</availableStartTime>,
                      <availableEndTime>{$operatingHours/endingHour/text()}</availableEndTime>
                      )
          }
          </_>
        }
      </availableTime>
      <healthcareService type="array">
        {
        for $facility at $index in $content/facilities/facility
        for $service in $facility/service
        return
        <_ type="object">
          <reference>{csd_webui:generateURL("fhir/" || $doc_name || "/HealthcareService/" || $service/@entityID/string())}</reference>
          {
            let $search_name := "urn:ihe:iti:csd:2014:stored-function:service-search"
            let $careServicesSubRequest :=
            <csd:careServicesRequest>
              <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL()}">
                <csd:requestParams>
                  <csd:id entityID="{$service/@entityID/string()}"/>
                </csd:requestParams>
              </csd:function>
            </csd:careServicesRequest>
            let $doc :=  csd_dm:open_document($doc_name)
            let $serv := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
            let $codedType := $serv//codedType
            let $svsCode := svs_lsvs:get_single_version_code($codedType/@code/string(),$codedType/@codingScheme/string(),"")
            return <display>{$svsCode//svs:Concept/@displayName/string()}</display>
          }
        </_>
        }
      </healthcareService>
      {
        if(exists($content/demographic/contactPoint/codedType))
        then
        <telecom type="array">
          {
            for $contactPoint in $content/demographic/contactPoint
            return if (exists($contactPoint/codedType))
                    then
                    <_ type="object">
                      <system>
                      {
                        let $code := $contactPoint/codedType/@code/string()
                        return if($code = "BP") then "phone"
                               else if ($code = "EMAIL") then "email"
                               else if ($code = "FAX") then "fax"
                               else "other"
                      }
                      </system>
                      <value>{$contactPoint/codedType/text()}</value>
                    </_>
                   else ()
          }
        </telecom>
        else ()
      }
      <meta type="object">
        <lastUpdated>{$content/record/@updated/string()}</lastUpdated>
        <tag type="array">
          <_ type="object">
            {$content/record/@sourceDirectory/string()}
            <system>https://github.com/openhie/openinfoman/tags/fhir/sourceDirectory</system>
          </_>
        </tag>
      </meta>
    </resource>
  </_>
}
</entry>
</json>
return (
          <rest:response>
            <output:serialization-parameters>
              <output:media-type value='application/json'/>
            </output:serialization-parameters>
          </rest:response>,
          json:serialize($practitionerRole,map{"format":"direct",'escape': 'no'})
        )
};

declare
  %rest:path("/fhir/{$doc_name}/HealthcareService/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRHealthcareServiceID($id,$page,$_count,$_since,$doc_name)
{
  page:FHIRHealthcareService($id,$page,$_count,$_since,$doc_name)
};

declare
  %rest:path("/fhir/{$doc_name}/HealthcareService/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRHealthcareService($_id,$page,$_count,$_since,$doc_name)
{
let $contents := page:get_services ($doc_name,$_id,$page,$_count,$_since)
let $HealthcareService :=
<json type='object'>
  <resourceType>Bundle</resourceType>
  <total>{count($contents/serviceDirectory/service)}</total>
  <type>history</type>
  <entry type="array">
  {
    for $content in $contents/serviceDirectory/service
    return
    <_ type="object">
      <fullURL>{csd_webui:generateURL("fhir/" || $doc_name || "/HealthcareService/" || $content/@entityID)}</fullURL>
      {
        if($content/record/@created/string() != $content/record/@updated/string())
        then
        <request type="object">
          <method>PUT</method>
          <url>{$doc_name}/HealthcareService/{$content/@entityID/string()}</url>
        </request>
        else()
      }
      <resource type="object">
        <resourceType>HealthcareService</resourceType>
        <id>{$content/@entityID/string()}</id>
        {
          let $codedType := $content/codedType
          let $svsCode := svs_lsvs:get_single_version_code($codedType/@code/string(),$codedType/@codingScheme/string(),"")
          return <name>{$svsCode//svs:Concept/@displayName/string()}</name>
        }
        {
          if(exists($content/otherID))
          then
          <identifier type="array">
          {
            for $otherid in $content/otherID
            return
            <_ type="object">
              <system>{$otherid/@assigningAuthorityName/string()}</system>
              <value>{$otherid/text()}</value>
            </_>
          }
          </identifier>
          else ()
        }
        <active>
          {
            let $status := lower-case($content/record/@status/string())
            return if($status = "active") then "true"
                    else if($status = "inactive" or $status = "in-active") then "false"
                    else()
          }
        </active>
      </resource>
    </_>
  }
  </entry>
</json>

return (
          <rest:response>
            <output:serialization-parameters>
              <output:media-type value='application/json'/>
            </output:serialization-parameters>
          </rest:response>,
          json:serialize($HealthcareService,map{"format":"direct",'escape': 'no'})
        )
};

declare function page:getDayOfTheWeek ($day) {
  if($day = 1) then "mon"
                else if ($day = 2) then "tue"
                else if ($day = 3) then "wed"
                else if ($day = 4) then "thu"
                else if ($day = 5) then "fri"
                else if ($day = 6) then "sat"
                else if ($day = 7) then "sun"
                else ()
};

declare
  %rest:path("/test")
  %rest:GET
  function page:test()
{
  let $val := svs_lsvs:get_single_version_code("101-001","1.3.6.1.4.1.21367.200.107","")
  return
  <display>{$val//svs:Concept/@displayName/string()}</display>

};

module namespace page = 'http://basex.org/modules/web-page';
import module namespace csd_bl = "https://github.com/openhie/openinfoman/csd_bl";
import module namespace functx = 'http://www.functx.com';
import module namespace csr_proc = "https://github.com/openhie/openinfoman/csr_proc";
import module namespace csd_webui =  "https://github.com/openhie/openinfoman/csd_webui";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace svs_lsvs = "https://github.com/openhie/openinfoman/svs_lsvs";
declare namespace csd =  "urn:ihe:iti:csd:2013";
declare namespace svs = "urn:ihe:iti:svs:2008";
declare default element  namespace   "urn:ihe:iti:csd:2013";

declare function page:get_location ($doc_name,$_id,$page,$_count,$_since)
{
  <CSD xmlns:csd="urn:ihe:iti:csd:2013">
    {
      let $search_collection :=
      <collection>
        <search directory="facilityDirectory">urn:ihe:iti:csd:2014:stored-function:facility-search</search>
        <search directory="organizationDirectory">urn:ihe:iti:csd:2014:stored-function:organization-search</search>
      </collection>
      for $search in $search_collection/search
      let $search_name := $search/text()
      return
      (
        let $careServicesSubRequest :=
        <csd:careServicesRequest>
          <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL('')}">
            <csd:requestParams>
              {
                let $id := $_id
                return if (functx:all-whitespace($id)) then () else <csd:id entityID="{$id}"/>
              }

              {
                let $t_start := $page
                return if (functx:is-a-number($t_start))
                  then
                    let $start := max((xs:int($t_start),1))
                    let $t_count := $_count
                    let $count := if(functx:is-a-number($t_count)) then  max((xs:int($t_count),1)) else 50
                    let $startIndex := ($start - 1)*$count + 1
                    return <csd:start>{$startIndex}</csd:start>
                  else ()
              }
         {
           let $count := $_count
           return
              if(functx:is-a-number($count))
              then  <csd:max>{max((xs:int($count),1))} </csd:max>
              else ()
         }
         {
          let $since := $_since
          return if (functx:all-whitespace($since)) then () else <csd:record updated="{$since}"/>
         }
            </csd:requestParams>
          </csd:function>
        </csd:careServicesRequest>

        let $doc :=  csd_dm:open_document($doc_name)
        let $contents := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
        let $directory := $search/@directory/string()
        return $contents/*[name() = $directory]
      )
    }
  </CSD>
};

declare function page:get_provider ($doc_name,$_id,$page,$_count,$_since,$organization,$location)
{
  let $search_name := "urn:ihe:iti:csd:2014:stored-function:provider-search"
  return
  <CSD xmlns:csd="urn:ihe:iti:csd:2013">
    {
      let $careServicesSubRequest :=
      <csd:careServicesRequest>
        <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL('')}">
          <csd:requestParams>
            {
              let $id := $_id
              return if (functx:all-whitespace($id)) then () else <csd:id entityID="{$id}"/>
            }

            {
              let $t_start := $page
              return if (functx:is-a-number($t_start))
                then
                  let $start := max((xs:int($t_start),1))
                  let $t_count := $_count
                  let $count := if(functx:is-a-number($t_count)) then  max((xs:int($t_count),1)) else 50
                  let $startIndex := ($start - 1)*$count + 1
                  return <csd:start>{$startIndex}</csd:start>
                else ()
            }
            {
              let $org := $organization
              return if (functx:all-whitespace($org)) then () else  <csd:organizations><csd:organization>{$org}</csd:organization></csd:organizations>
            }
            {
              let $loc := $location
              return if (functx:all-whitespace($loc)) then () else <csd:facilities><csd:facility>{$loc}</csd:facility></csd:facilities>
            }
       {
         let $count := $_count
         return
            if(functx:is-a-number($count))
            then  <csd:max>{max((xs:int($count),1))} </csd:max>
            else ()
       }
       {
        let $since := $_since
        return if (functx:all-whitespace($since)) then () else <csd:record updated="{$since}"/>
       }
          </csd:requestParams>
        </csd:function>
      </csd:careServicesRequest>

      let $doc :=  csd_dm:open_document($doc_name)
      let $contents := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
      return $contents/providerDirectory
    }
  </CSD>
};

declare function page:get_services ($doc_name,$_id,$page,$_count,$_since)
{
  let $search_name := "urn:ihe:iti:csd:2014:stored-function:service-search"
  return
  <CSD xmlns:csd="urn:ihe:iti:csd:2013">
    {
      let $careServicesSubRequest :=
      <csd:careServicesRequest>
        <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL('')}">
          <csd:requestParams>
            {
              let $id := $_id
              return if (functx:all-whitespace($id)) then () else <csd:id entityID="{$id}"/>
            }

            {
              let $t_start := $page
              return if (functx:is-a-number($t_start))
                then
                  let $start := max((xs:int($t_start),1))
                  let $t_count := $_count
                  let $count := if(functx:is-a-number($t_count)) then  max((xs:int($t_count),1)) else 50
                  let $startIndex := ($start - 1)*$count + 1
                  return <csd:start>{$startIndex}</csd:start>
                else ()
            }
            {
              let $count := $_count
              return
                  if(functx:is-a-number($count))
                  then  <csd:max>{max((xs:int($count),1))} </csd:max>
                  else ()
            }
            {
              let $since := $_since
              return if (functx:all-whitespace($since)) then () else <csd:record updated="{$since}"/>
            }
          </csd:requestParams>
        </csd:function>
      </csd:careServicesRequest>

      let $doc :=  csd_dm:open_document($doc_name)
      let $contents := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
      return $contents/serviceDirectory
    }
  </CSD>
};

declare
  %rest:path("/FHIR/{$doc_name}/Location/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRLocationID($id,$page,$_count,$_since,$doc_name)
{
  page:FHIRLocation($id,$page,$_count,$_since,$doc_name)
};

declare
  %rest:path("/FHIR/{$doc_name}/Location/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRLocation($_id,$page,$_count,$_since,$doc_name)
{
let $contents := page:get_location ($doc_name,$_id,$page,$_count,$_since)

let $location :=
<json type='object'>
<resourceType>Bundle</resourceType>
<total>{count($contents/facilityDirectory/facility) + count($contents/organizationDirectory/organization)}</total>
<type>history</type>
<entry type="array">
{
for $content in ($contents/facilityDirectory/facility,$contents/organizationDirectory/organization)
return
<_ type="object">
  <fullURL>{csd_webui:generateURL("FHIR/" || $doc_name || "/Location/" || $content/@entityID)}</fullURL>
  {
    if($content/record/@created/string() != $content/record/@updated/string())
    then
    <request type="object">
      <method>PUT</method>
      <url>{$doc_name}/Location/{$content/@entityID/string()}</url>
    </request>
    else()
  }
  <resource type="object">
    <resourceType>Location</resourceType>
    <id>{$content/@entityID/string()}</id>
    {
     if(exists($content/otherID))
     then
     <identifier type="array">
      {
      for $otherid in $content/otherID
      return
      <_ type="object">
        <system>{$otherid/@assigningAuthorityName/string()}/{$otherid/@code/string()}</system>
        <value>{$otherid/text()}</value>
      </_>
      }
     </identifier>
     else ()
    }
    {
      let $search_name := "urn:ihe:iti:csd:2014:stored-function:organization-search"
      let $parent :=
      if(exists($content/organizations/organization))
      then
      $content/organizations/organization/@entityID/string()
      else
      if (exists($content/parent))
      then $content/parent/@entityID/string()
      else ()

      return if($parent)
      then
      let $careServicesSubRequest :=
      <csd:careServicesRequest>
        <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL()}">
          <csd:requestParams>
            <csd:id entityID="{$parent}"/>
          </csd:requestParams>
        </csd:function>
      </csd:careServicesRequest>
      let $doc :=  csd_dm:open_document($doc_name)
      let $organization := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
      return if(exists($organization/organizationDirectory/organization))
      then
      <partOf type="object">
        <reference>{csd_webui:generateURL("FHIR/" || $doc_name || "/Location/" || $organization/organizationDirectory/organization/@entityID/string())}</reference>
        <display>{$organization/organizationDirectory/organization/primaryName/text()}</display>
      </partOf>
      else ()
      else ()
    }
    {
    if(exists($content/contactPoint))
    then
    <telecom type="array">
     {
     for $contactPoint in $content/contactPoint
     return ()
     }
    </telecom>
    else ()
    }
    {
      if(exists($content/geocode))
      then
      <position type="object">
        <longitude>{$content/geocode/longitude/text()}</longitude>
        <latitude>{$content/geocode/latitude/text()}</latitude>
      </position>
      else ()
    }
    <meta type="object">
      <lastUpdated>{$content/record/@updated/string()}</lastUpdated>
      <tag type="array">
        <_ type="object">
          {$content/record/@sourceDirectory/string()}
          <system>https://github.com/openhie/openinfoman/tags/fhir/sourceDirectory</system>
        </_>
      </tag>
    </meta>
    {
      if(exists($content/codedType))
      then
        <type type="object">
          <coding type="array">
            {
              for $codedType in $content/codedType
                return
                <_ type="object">
                  {$codedType/@code/string()}
                  <system>{$codedType/@codingScheme/string()}</system>
                  {
                  if(functx:all-whitespace($codedType/text()))
                  then ()
                  else
                  <display>{$codedType/text()}</display>
                  }
                </_>
            }
          </coding>
        </type>
      else ()
    }
    <status>{$content/record/@status/string()}</status>
    <name>{$content/primaryName/text()}</name>
    <mode>instance</mode>
  </resource>
</_>
}
</entry>
</json>

return (
  <rest:response>
    <output:serialization-parameters>
      <output:media-type value='application/json'/>
    </output:serialization-parameters>
  </rest:response>,
  json:serialize($location,map{"format":"direct",'escape': 'no'})
  )

};

declare
  %rest:path("/FHIR/{$doc_name}/Practitioner/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitionerID($id,$page,$_count,$_since,$doc_name,$organization,$location)
{
  page:FHIRPractitioner($id,$page,$_count,$_since,$doc_name,$organization,$location)
};

declare
  %rest:path("/FHIR/{$doc_name}/Practitioner/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitioner($_id,$page,$_count,$_since,$doc_name,$organization,$location)
{
let $contents := page:get_provider ($doc_name,$_id,$page,$_count,$_since,$organization,$location)
let $practitioner :=
<json type='object'>
<resourceType>Bundle</resourceType>
<total>{count($contents/providerDirectory/provider)}</total>
<type>history</type>
<entry type="array">
{
  for $content in $contents/providerDirectory/provider
  return
  <_ type="object">
    <fullURL>{csd_webui:generateURL("FHIR/" || $doc_name || "/Practitioner/" || $content/@entityID)}</fullURL>
    {
      if($content/record/@created/string() != $content/record/@updated/string())
      then
      <request type="object">
        <method>PUT</method>
        <url>{$doc_name}/Practitioner/{$content/@entityID/string()}</url>
      </request>
      else()
    }
    <resource type="object">
      <resourceType>Practitioner</resourceType>
      <id>{$content/@entityID/string()}</id>
      {
        if(exists($content/otherID))
        then
        <identifier type="array">
        {
          for $otherid in $content/otherID
          return
          <_ type="object">
            <system>{$otherid/@assigningAuthorityName/string()}/{$otherid/@code/string()}</system>
            <value>{$otherid/text()}</value>
          </_>
        }
        </identifier>
        else ()
      }
      <active>
        {
          let $status := lower-case($content/record/@status/string())
          return if($status = "active") then "true"
                  else if($status = "inactive" or $status = "in-active") then "false"
                  else()
        }
      </active>
      {
        if(exists($content/demographic/contactPoint/codedType))
        then
        <telecom type="array">
          {
            for $contactPoint in $content/demographic/contactPoint
            return if (exists($contactPoint/codedType))
                    then
                    <_ type="object">
                      <system>
                      {
                        let $code := $contactPoint/codedType/@code/string()
                        return if($code = "BP") then "phone"
                               else if ($code = "EMAIL") then "email"
                               else if ($code = "FAX") then "fax"
                               else "other"
                      }
                      </system>
                      <value>{$contactPoint/codedType/text()}</value>
                    </_>
                   else ()
          }
        </telecom>
        else ()
      }
      {
        if(exists($content/demographic/address/addressLine))
        then
        <address type="array">
          {
            for $address in $content/demographic/address
            return
              if(exists($address/addressLine))
              then
              <_ type="object">
                {
                  let $csdtype := lower-case($address/@type/string())
                  let $fhirtype := if($csdtype = "mailing" or $csdtype = "mailing address") then "postal"
                                    else if ($csdtype = "physical" or $csdtype = "physical address") then "physical"
                                    else ()
                  return if($fhirtype)
                          then <type>{$fhirtype}</type>
                          else ()
                }
                {
                  for $addressLine in $address/addressLine
                  return if($addressLine/@component = "streetAddress")
                          then <line>{$addressLine/text()}</line>
                          else if($addressLine/@component = "city")
                          then <city>{$addressLine/text()}</city>
                          else if($addressLine/@component = "stateProvince")
                          then <state>{$addressLine/text()}</state>
                          else if($addressLine/@component = "country")
                          then <country>{$addressLine/text()}</country>
                          else if($addressLine/@component = "postalCode")
                          then <postalCode>{$addressLine/text()}</postalCode>
                          else()
                }
              </_>
              else ()
          }
        </address>
        else ()
      }
      {
        if(exists($content/credential)) then
        <qualification type="array">
        {
          for $credential in $content/credential
          return
          <_ type="object">

              <coding type="array">
              {
                for $codedType in $credential/codedType
                return
                <_ type="object">
                  {
                    if($codedType/@codingScheme/string()) then
                    <system>{$codedType/@codingScheme/string()}</system>
                    else ()
                  }
                  {
                    if($codedType/@code/string()) then
                    {$codedType/@code/string()}
                    else ()
                  }
                </_>
              }
              </coding>
              {
                if($credential/codedType/text()) then
                <text>{($credential/codedType/text())[1]}</text>
                else ()
              }

            {
              if($credential/issuingAuthority/text()) then
              <issuer type="object">
                <display>{$credential/issuingAuthority/text()}</display>
              </issuer>
              else ()
            }
            {
              if(exists($credential/credentialIssueDate) or exists($credential/credentialRenewalDate)) then
              <period type="object">
              {
                if($credential/credentialIssueDate/text()) then
                <start>{$credential/credentialIssueDate/text()}</start>
                else ()
              }
              {
                if($credential/credentialRenewalDate/text()) then
                <end>{$credential/credentialRenewalDate/text()}</end>
                else ()
              }
              </period>
              else ()
            }
          </_>
        }
        </qualification>
        else ()
      }
      {
        if(exists($content/language)) then
        <communication type="array">
        {
          for $language in $content/language
          return
          <_ type="object">
            <coding type="array">
              {
                <_ type="object">
                  {
                    if($language/@codingScheme/string()) then
                    <system>{$language/@codingScheme/string()}</system>
                    else ()
                  }
                  {
                    if($language/@code/string()) then
                    {$language/@code/string()}
                    else ()
                  }
                </_>
              }
            </coding>
            {
              if($language/text()) then
              <text>{($language/text())}</text>
              else ()
            }
          </_>
        }
        </communication>
        else ()
      }
      <name type="array">
      {
        for $name in $content/demographic/name
        return
        <_ type="object">
          <text>{($name/commonName/text())[1]}</text>
          <family>{($name/surname/text())[1]}</family>
          <given>{($name/forename/text())[1] || ' ' || ($name/otherName/text())[1]}</given>
          <prefix>{($name/honorific/text())[1]}</prefix>
          <suffix>{($name/suffix/text())[1]}</suffix>
        </_>
      }
      </name>
      {
        if(exists($content/demographic/gender))
        then
        <gender>
          {
            let $gender := $content/demographic/gender/text()
            return if($gender = "F") then "female"
                    else if($gender = "M") then "male"
                    else lower-case($gender)
          }
        </gender>
        else ()
      }
      {
        if(exists($content/demographic/dateOfBirth))
        then
        <birthDate>{$content/demographic/dateOfBirth/text()}</birthDate>
        else ()
      }
      <meta type="object">
        <lastUpdated>{$content/record/@updated/string()}</lastUpdated>
        <tag type="array">
          <_ type="object">
            {$content/record/@sourceDirectory/string()}
            <system>https://github.com/openhie/openinfoman/tags/fhir/sourceDirectory</system>
          </_>
        </tag>
      </meta>
    </resource>
  </_>
}
</entry>
</json>
return (
          <rest:response>
            <output:serialization-parameters>
              <output:media-type value='application/json'/>
            </output:serialization-parameters>
          </rest:response>,
          json:serialize($practitioner,map{"format":"direct",'escape': 'no'})
        )
};

declare
  %rest:path("/FHIR/{$doc_name}/PractitionerRole/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitionerRoleID($id,$page,$_count,$_since,$doc_name,$organization,$location)
{
  page:FHIRPractitionerRole($id,$page,$_count,$_since,$doc_name,$organization,$location)
};

declare
  %rest:path("/FHIR/{$doc_name}/PractitionerRole/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:query-param("organization", "{$organization}")
  %rest:query-param("location", "{$location}")
  %rest:GET
  function page:FHIRPractitionerRole($_id,$page,$_count,$_since,$doc_name,$organization,$location)
{
let $contents := page:get_provider ($doc_name,$_id,$page,$_count,$_since,$organization,$location)
let $practitionerRole :=
<json type='object'>
<resourceType>Bundle</resourceType>
<total>{count($contents/providerDirectory/provider)}</total>
<type>history</type>
<entry type="array">
{
  for $content in $contents/providerDirectory/provider
  return
  <_ type="object">
    <fullURL>{csd_webui:generateURL("FHIR/" || $doc_name || "/PractitionerRole/" || $content/@entityID)}</fullURL>
    {
      if($content/record/@created/string() != $content/record/@updated/string())
      then
      <request type="object">
        <method>PUT</method>
        <url>{$doc_name}/PractitionerRole/{$content/@entityID/string()}</url>
      </request>
      else()
    }
    <resource type="object">
      <resourceType>PractitionerRole</resourceType>
      <id>{$content/@entityID/string()}</id>
      {
        if(exists($content/otherID))
        then
        <identifier type="array">
        {
          for $otherid in $content/otherID
          return
          <_ type="object">
            <system>{$otherid/@assigningAuthorityName/string()}/{$otherid/@code/string()}</system>
            <value>{$otherid/text()}</value>
          </_>
        }
        </identifier>
        else ()
      }
      <active>
        {
          let $status := lower-case($content/record/@status/string())
          return if($status = "active") then "true"
                  else if($status = "inactive" or $status = "in-active") then "false"
                  else()
        }
      </active>
      <practitioner type="object">
        <reference>{csd_webui:generateURL("FHIR/" || $doc_name || "/Practitioner/" || $content/@entityID)}</reference>
        <display>{$content/demographic/name[1]/commonName[1]/string()}</display>
      </practitioner>
      <specialty type="array">
        {
        for $specialty at $index in $content/specialty
        return
        <_ type="object">

            <coding type="array">
            {
              for $codedType in $specialty/codedType
              return
              <_ type="object">
                {
                  if($codedType/@codingScheme/string()) then
                  <system>{$codedType/@codingScheme/string()}</system>
                  else ()
                }
                {
                  if($codedType/@code/string()) then
                  {$codedType/@code/string()}
                  else ()
                }
                {
                  let $svsCode := svs_lsvs:get_single_version_code($codedType/@code/string(),$codedType/@codingScheme/string(),"")
                  return <display>{$svsCode//svs:Concept/@displayName/string()}</display>
                }
              </_>
            }
            </coding>
            {
              if($specialty/codedType/text()) then
              <text>{($specialty/codedType/text())[1]}</text>
              else ()
            }

        </_>
        }
      </specialty>
      <location type="array">
        {
        for $facility at $index in $content/facilities/facility
        return
        <_ type="object">
          <reference>{csd_webui:generateURL("FHIR/" || $doc_name || "/Location/" || $facility/@entityID/string())}</reference>
          {
            let $search_name := "urn:ihe:iti:csd:2014:stored-function:facility-search"
            let $careServicesSubRequest :=
            <csd:careServicesRequest>
              <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL()}">
                <csd:requestParams>
                  <csd:id entityID="{$facility/@entityID/string()}"/>
                </csd:requestParams>
              </csd:function>
            </csd:careServicesRequest>
            let $doc :=  csd_dm:open_document($doc_name)
            let $fac := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
            return <display>{$fac//primaryName/text()}</display>
          }
        </_>
        }
      </location>
      <availableTime type="array">
        {
          for $service in $content/facilities/facility/service
          return <_ type="object">
            {
              for $operatingHours in $service/operatingHours
              let $CSDdayOfTheWeek := $operatingHours/dayOfTheWeek/text()
              let $FHIRdayOfTheWeek := page:getDayOfTheWeek($CSDdayOfTheWeek)
              return (
                      <daysOfWeek>{$FHIRdayOfTheWeek}</daysOfWeek>,
                      <availableStartTime>{$operatingHours/beginningHour/text()}</availableStartTime>,
                      <availableEndTime>{$operatingHours/endingHour/text()}</availableEndTime>
                      )
            }
            </_>
        }
        {
          for $operatingHours in $content/facilities/facility/operatingHours
          return
          <_ type="object">
          {
            let $CSDdayOfTheWeek := $operatingHours/dayOfTheWeek/text()
              let $FHIRdayOfTheWeek := page:getDayOfTheWeek($CSDdayOfTheWeek)
              return (
                      <daysOfWeek>{$FHIRdayOfTheWeek}</daysOfWeek>,
                      <availableStartTime>{$operatingHours/beginningHour/text()}</availableStartTime>,
                      <availableEndTime>{$operatingHours/endingHour/text()}</availableEndTime>
                      )
          }
          </_>
        }
      </availableTime>
      <healthcareService type="array">
        {
        for $facility at $index in $content/facilities/facility
        for $service in $facility/service
        return
        <_ type="object">
          <reference>{csd_webui:generateURL("FHIR/" || $doc_name || "/HealthcareService/" || $service/@entityID/string())}</reference>
          {
            let $search_name := "urn:ihe:iti:csd:2014:stored-function:service-search"
            let $careServicesSubRequest :=
            <csd:careServicesRequest>
              <csd:function urn="{$search_name}" resource="{$doc_name}" base_url="{csd_webui:generateURL()}">
                <csd:requestParams>
                  <csd:id entityID="{$service/@entityID/string()}"/>
                </csd:requestParams>
              </csd:function>
            </csd:careServicesRequest>
            let $doc :=  csd_dm:open_document($doc_name)
            let $serv := csr_proc:process_CSR_stored_results( $doc , $careServicesSubRequest)
            let $codedType := $serv//codedType
            let $svsCode := svs_lsvs:get_single_version_code($codedType/@code/string(),$codedType/@codingScheme/string(),"")
            return <display>{$svsCode//svs:Concept/@displayName/string()}</display>
          }
        </_>
        }
      </healthcareService>
      {
        if(exists($content/demographic/contactPoint/codedType))
        then
        <telecom type="array">
          {
            for $contactPoint in $content/demographic/contactPoint
            return if (exists($contactPoint/codedType))
                    then
                    <_ type="object">
                      <system>
                      {
                        let $code := $contactPoint/codedType/@code/string()
                        return if($code = "BP") then "phone"
                               else if ($code = "EMAIL") then "email"
                               else if ($code = "FAX") then "fax"
                               else "other"
                      }
                      </system>
                      <value>{$contactPoint/codedType/text()}</value>
                    </_>
                   else ()
          }
        </telecom>
        else ()
      }
      <meta type="object">
        <lastUpdated>{$content/record/@updated/string()}</lastUpdated>
        <tag type="array">
          <_ type="object">
            {$content/record/@sourceDirectory/string()}
            <system>https://github.com/openhie/openinfoman/tags/fhir/sourceDirectory</system>
          </_>
        </tag>
      </meta>
    </resource>
  </_>
}
</entry>
</json>
return (
          <rest:response>
            <output:serialization-parameters>
              <output:media-type value='application/json'/>
            </output:serialization-parameters>
          </rest:response>,
          json:serialize($practitionerRole,map{"format":"direct",'escape': 'no'})
        )
};

declare
  %rest:path("/FHIR/{$doc_name}/HealthcareService/{$id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRHealthcareServiceID($id,$page,$_count,$_since,$doc_name)
{
  page:FHIRHealthcareService($id,$page,$_count,$_since,$doc_name)
};

declare
  %rest:path("/FHIR/{$doc_name}/HealthcareService/_history")
  %rest:query-param("_id", "{$_id}")
  %rest:query-param("page", "{$page}")
  %rest:query-param("_count", "{$_count}")
  %rest:query-param("_since", "{$_since}")
  %rest:GET
  function page:FHIRHealthcareService($_id,$page,$_count,$_since,$doc_name)
{
let $contents := page:get_services ($doc_name,$_id,$page,$_count,$_since)
let $HealthcareService :=
<json type='object'>
  <resourceType>Bundle</resourceType>
  <total>{count($contents/serviceDirectory/service)}</total>
  <type>history</type>
  <entry type="array">
  {
    for $content in $contents/serviceDirectory/service
    return
    <_ type="object">
      <fullURL>{csd_webui:generateURL("FHIR/" || $doc_name || "/HealthcareService/" || $content/@entityID)}</fullURL>
      {
        if($content/record/@created/string() != $content/record/@updated/string())
        then
        <request type="object">
          <method>PUT</method>
          <url>{$doc_name}/HealthcareService/{$content/@entityID/string()}</url>
        </request>
        else()
      }
      <resource type="object">
        <resourceType>HealthcareService</resourceType>
        <id>{$content/@entityID/string()}</id>
        {
          let $codedType := $content/codedType
          let $svsCode := svs_lsvs:get_single_version_code($codedType/@code/string(),$codedType/@codingScheme/string(),"")
          return <name>{$svsCode//svs:Concept/@displayName/string()}</name>
        }
        {
          if(exists($content/otherID))
          then
          <identifier type="array">
          {
            for $otherid in $content/otherID
            return
            <_ type="object">
              <system>{$otherid/@assigningAuthorityName/string()}/{$otherid/@code/string()}</system>
              <value>{$otherid/text()}</value>
            </_>
          }
          </identifier>
          else ()
        }
        <active>
          {
            let $status := lower-case($content/record/@status/string())
            return if($status = "active") then "true"
                    else if($status = "inactive" or $status = "in-active") then "false"
                    else()
          }
        </active>
      </resource>
    </_>
  }
  </entry>
</json>

return (
          <rest:response>
            <output:serialization-parameters>
              <output:media-type value='application/json'/>
            </output:serialization-parameters>
          </rest:response>,
          json:serialize($HealthcareService,map{"format":"direct",'escape': 'no'})
        )
};

declare function page:getDayOfTheWeek ($day) {
  if($day = 1) then "mon"
                else if ($day = 2) then "tue"
                else if ($day = 3) then "wed"
                else if ($day = 4) then "thu"
                else if ($day = 5) then "fri"
                else if ($day = 6) then "sat"
                else if ($day = 7) then "sun"
                else ()
};

declare
  %rest:path("/test")
  %rest:GET
  function page:test()
{
  let $val := svs_lsvs:get_single_version_code("101-001","1.3.6.1.4.1.21367.200.107","")
  return
  <display>{$val//svs:Concept/@displayName/string()}</display>

};


[ignore] force trailing slash so relative URLs resolve properly.  (calling "http://localhost:8080/exist/functions" would result in a 500 error, since "../sidebar.xml" could not be resolved.)

svn path=/trunk/eXist/; revision=14635

xquery version "1.0";

(: $Id$ :)

(:~
	Controller XQuery for the RESTful function docs application.

	Demonstrates how to use in URL Rewriting for RESTful applications, e.g.:
	   - functions/ forwards transparently to functions/functions.xql
	   - functions/xmldb displays the docs for the xmldb module
	   - functions/xmldb/login displays the docs for the xmldb:login() module
	   - functions/xmldb:login() redirects to functions/xmldb/login
	       in order to display the docs for the xmldb:login() module

    Un-comment logging functions and monitor EXIST_HOME/webapp/WEB-INF/logs/exist.log
    to follow the construction of these parameters.
:)

import module namespace request="http://exist-db.org/xquery/request";

(: standard variables passed automatically to controller.xql  :)

declare variable $exist:root external;
declare variable $exist:prefix external;
declare variable $exist:controller external;
declare variable $exist:path external;
declare variable $exist:resource external;

(: variables from the HTTP Request module :)
let $url := request:get-url()
let $uri := request:get-uri()
let $context := request:get-context-path()
let $effective-uri := request:get-effective-uri()

(: the default query for this app:)
let $app-default-query := 'functions.xql'

(: used to forward matching requests to the correct 'internal' path to the main query :)
let $internal-path-to-app := concat($exist:controller, '/', $app-default-query)

(: the 'external' path to app to the for use in constructing URLs  :)
let $external-path-to-app := concat($context, $exist:prefix, $exist:controller, '/')

(: prepare the URL parameters for use :)
let $post-query-url-params := subsequence(tokenize($exist:path, '/'), 2)

(: logging to demonstrate how variables are constructed for use in URL Rewriting :)
(:
let $log := util:log("DEBUG", concat("URL Info: request:get-url():           ", $url))
let $log := util:log("DEBUG", concat("URL Info: request:get-uri():           ", $uri))
let $log := util:log("DEBUG", concat("URL Info: request:get-effective-uri(): ", $effective-uri))
let $log := util:log("DEBUG", concat("URL Info: request:get-context-path():  ", $context))

let $log := util:log("DEBUG", concat("URL Info: $exist:root:                 ", $exist:root))
let $log := util:log("DEBUG", concat("URL Info: $exist:prefix:               ", $exist:prefix))
let $log := util:log("DEBUG", concat("URL Info: $exist:controller:           ", $exist:controller))
let $log := util:log("DEBUG", concat("URL Info: $exist:path:                 ", $exist:path))
let $log := util:log("DEBUG", concat("URL Info: $exist:resource:             ", $exist:resource))

let $log := util:log("DEBUG", concat("URL Info: $internal-path-to-app:       ", $internal-path-to-app))
let $log := util:log("DEBUG", concat("URL Info: $external-path-to-app:       ", $external-path-to-app))
:)

return
    (: force trailing slash so relative URLs (e.g. "../sidebar.xml") resolve properly :)
    if ($exist:path eq '') then
        let $newPath := concat($url, '/')
        return
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
                <redirect url="{$newPath}"/>
            </dispatch>

	(: make sure the global css, js and image files are resolved :)
    else if (matches($exist:path, '((styles|scripts|resources)/|logo.jpg)')) then
        let $newPath := replace($exist:path, '^.*(((styles|scripts|resources)/|logo).*)$', '/$1')
        return
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
    			<forward url="{$newPath}"/>
    			<cache-control cache="yes"/>
    		</dispatch>

    (: catch requests like 'functions/xmldb:login()' and redirect them to 'functions/xmldb/login',
       thereby making it easier to paste in functions :)
    else if (contains($post-query-url-params[1], ':')) then
        let $module := substring-before($post-query-url-params[1], ':')
        let $function := replace(substring-after($post-query-url-params[1], ':'), '\(\)', '')
        let $newPath := string-join(($external-path-to-app, $module, $function), '/')
        return
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
                <redirect url="{$newPath}"/>
            </dispatch>

	(: Execute RESTful queries by passing URL parameters to the query :)
    else
        let $module := $post-query-url-params[1]
        let $function := $post-query-url-params[2]

        (: logging to demonstrate the RESTful URL parameters :)
        (:
        let $log := util:log("DEBUG", concat("Functions App module:                  ", $module))
        let $log := util:log("DEBUG", concat("Functions App function:                ", $function))
        :)

        return
        (: handle the special case of "xpath-functions", which this app redirects to "fn" :)
        if ($module eq 'xpath-functions') then
            let $newPath := string-join(($external-path-to-app, 'fn', $function), '/')
            return
                <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
                    <redirect url="{$newPath}"/>
                </dispatch>
        else
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
    			<forward url="{$internal-path-to-app}">
        			<add-parameter name="basepath" value="{$external-path-to-app}"/>
            	    <add-parameter name="module" value="{$module}"/>,
            	    <add-parameter name="function" value="{$function}"/>
            	    <!-- query results are passed to XSLT servlet via request attribute -->
              		<set-attribute name="xquery.attribute" value="model"/>
    			</forward>
          		<view>
              	    <!-- Apply db2xhtml stylesheet -->
          			<forward servlet="XSLTServlet">
          				<set-attribute name="xslt.input" value="model"/>
          				<set-attribute name="xslt.root" value="{request:get-context-path()}{$exist:prefix}"/>
          				<set-attribute name="xslt.stylesheet" value="{$exist:root}/stylesheets/db2xhtml.xsl"/>
          				<set-attribute name="xslt.output.media-type" value="text/html"/>
          				<set-attribute name="xslt.output.doctype-public" value="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
          				<set-attribute name="xslt.output.doctype-system" value="resources/xhtml1-transitional.dtd"/>
          			</forward>
          		</view>
    		</dispatch>

xquery version "1.0";

(: $Id$ :)

(:~
	Controller XQuery for the RESTful function docs application.

	Demonstrates how to use in URL Rewriting for RESTful applications, e.g.:
	   - functions/ forwards transparently to functions/functions.xql
	   - functions/xmldb displays the docs for the xmldb module
	   - functions/xmldb/login displays the docs for the xmldb:login() module
	   - functions/xmldb:login() redirects to functions/xmldb/login
	       in order to display the docs for the xmldb:login() module

    Un-comment logging functions and monitor EXIST_HOME/webapp/WEB-INF/logs/exist.log
    to follow the construction of these parameters.
:)

import module namespace request="http://exist-db.org/xquery/request";

(: standard variables passed automatically to controller.xql  :)

declare variable $exist:root external;
declare variable $exist:prefix external;
declare variable $exist:controller external;
declare variable $exist:path external;
declare variable $exist:resource external;

(: variables from the HTTP Request module :)
let $url := request:get-url()
let $uri := request:get-uri()
let $context := request:get-context-path()
let $effective-uri := request:get-effective-uri()

(: the default query for this app:)
let $app-default-query := 'functions.xql'

(: used to forward matching requests to the correct 'internal' path to the main query :)
let $internal-path-to-app := concat($exist:controller, '/', $app-default-query)

(: the 'external' path to app to the for use in constructing URLs  :)
let $external-path-to-app := concat($context, $exist:prefix, $exist:controller, '/')

(: prepare the URL parameters for use :)
let $post-query-url-params := subsequence(tokenize($exist:path, '/'), 2)

(: logging to demonstrate how variables are constructed for use in URL Rewriting :)
(:
let $log := util:log("DEBUG", concat("URL Info: request:get-url():           ", $url))
let $log := util:log("DEBUG", concat("URL Info: request:get-uri():           ", $uri))
let $log := util:log("DEBUG", concat("URL Info: request:get-effective-uri(): ", $effective-uri))
let $log := util:log("DEBUG", concat("URL Info: request:get-context-path():  ", $context))

let $log := util:log("DEBUG", concat("URL Info: $exist:root:                 ", $exist:root))
let $log := util:log("DEBUG", concat("URL Info: $exist:prefix:               ", $exist:prefix))
let $log := util:log("DEBUG", concat("URL Info: $exist:controller:           ", $exist:controller))
let $log := util:log("DEBUG", concat("URL Info: $exist:path:                 ", $exist:path))
let $log := util:log("DEBUG", concat("URL Info: $exist:resource:             ", $exist:resource))

let $log := util:log("DEBUG", concat("URL Info: $internal-path-to-app:       ", $internal-path-to-app))
let $log := util:log("DEBUG", concat("URL Info: $external-path-to-app:       ", $external-path-to-app))
:)

return
	(: make sure the global css, js and image files are resolved :)
    if (matches($exist:path, '((styles|scripts|resources)/|logo.jpg)')) then
        let $newPath := replace($exist:path, '^.*(((styles|scripts|resources)/|logo).*)$', '/$1')
        return
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
    			<forward url="{$newPath}"/>
    			<cache-control cache="yes"/>
    		</dispatch>

    (: catch requests like 'functions/xmldb:login()' and redirect them to 'functions/xmldb/login',
       thereby making it easier to paste in functions :)
    else if (contains($post-query-url-params[1], ':')) then
        let $module := substring-before($post-query-url-params[1], ':')
        let $function := replace(substring-after($post-query-url-params[1], ':'), '\(\)', '')
        let $newPath := string-join(($external-path-to-app, $module, $function), '/')
        return
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
                <redirect url="{$newPath}"/>
            </dispatch>

	(: Execute RESTful queries by passing URL parameters to the query :)
    else
        let $module := $post-query-url-params[1]
        let $function := $post-query-url-params[2]

        (: logging to demonstrate the RESTful URL parameters :)
        (:
        let $log := util:log("DEBUG", concat("Functions App module:                  ", $module))
        let $log := util:log("DEBUG", concat("Functions App function:                ", $function))
        :)

        return
        (: handle the special case of "xpath-functions", which this app redirects to "fn" :)
        if ($module eq 'xpath-functions') then
            let $newPath := string-join(($external-path-to-app, 'fn', $function), '/')
            return
                <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
                    <redirect url="{$newPath}"/>
                </dispatch>
        else
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
    			<forward url="{$internal-path-to-app}">
        			<add-parameter name="basepath" value="{$external-path-to-app}"/>
            	    <add-parameter name="module" value="{$module}"/>,
            	    <add-parameter name="function" value="{$function}"/>
            	    <!-- query results are passed to XSLT servlet via request attribute -->
              		<set-attribute name="xquery.attribute" value="model"/>
    			</forward>
          		<view>
              	    <!-- Apply db2xhtml stylesheet -->
          			<forward servlet="XSLTServlet">
          				<set-attribute name="xslt.input" value="model"/>
          				<set-attribute name="xslt.root" value="{request:get-context-path()}{$exist:prefix}"/>
          				<set-attribute name="xslt.stylesheet" value="{$exist:root}/stylesheets/db2xhtml.xsl"/>
          				<set-attribute name="xslt.output.media-type" value="text/html"/>
          				<set-attribute name="xslt.output.doctype-public" value="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
          				<set-attribute name="xslt.output.doctype-system" value="resources/xhtml1-transitional.dtd"/>
          			</forward>
          		</view>
    		</dispatch>