Update filings.jq

Update filings.jq

import module namespace http-request = "http://www.28msec.com/modules/http/request";

import module namespace config = "http://apps.28.io/config";
import module namespace api = "http://apps.28.io/api";
import module namespace session = "http://apps.28.io/session";
import module namespace backend = "http://apps.28.io/test";

import module namespace csv = "http://zorba.io/modules/json-csv";

import module namespace archives = "http://28.io/modules/xbrl/archives";

import module namespace companies = "http://28.io/modules/xbrl/profiles/sec/companies";
import module namespace filings = "http://28.io/modules/xbrl/profiles/sec/filings";

import module namespace fiscal-core = "http://28.io/modules/xbrl/profiles/sec/fiscal/core";

(: Query parameters :)
declare  %rest:case-insensitive                 variable $token         as string? external;
declare  %rest:env                              variable $request-uri   as string  external;
declare  %rest:case-insensitive                 variable $format        as string? external;
declare  %rest:case-insensitive %rest:distinct  variable $eid           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $cik           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $tag           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $ticker        as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $sic           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $fiscalYear    as string* external := "LATEST";
declare  %rest:case-insensitive %rest:distinct  variable $fiscalPeriod  as string* external := "FY";
declare  %rest:case-insensitive %rest:distinct  variable $aid           as string* external;
declare  %rest:case-insensitive                 variable $profile-name  as string  external := $config:profile-name;

session:audit-call($token);

(: Post-processing :)
let $format as string? := api:preprocess-format($format, $request-uri)
let $fiscalYear as integer* := api:preprocess-fiscal-years($fiscalYear)
let $fiscalPeriod as string* := api:preprocess-fiscal-periods($fiscalPeriod)
let $tag as string* := api:preprocess-tags($tag)

(: Object resolution :)
let $entities :=
    switch($profile-name)
    case "sec" return companies:companies(
        $cik,
        $tag,
        $ticker,
        $sic)
    default return ()
let $archives as object* :=
    switch($profile-name)
    case "sec" return fiscal-core:filings(
        $entities,
        $fiscalPeriod,
        $fiscalYear,
        $aid)
    default return
        if(exists($eid)) then archives:archives-for-entities($eid)
                              else archives:archives()
let $summaries :=
    switch($profile-name)
    case "sec" return
        for $f in filings:summaries($archives)
        order by $f.Accepted descending
        return $f
    default return
        for $a in $archives
        return {
            AID: $a._id,
            Entity: $a.Entity
        }
let $summaries :=
  switch($profile-name)
  case "sec" return
    for $archive in $summaries
    return {|
      project($archive, "AccessionNumber"),
      {
        Components: backend:url("components",
          {
              aid: encode-for-uri($archive.AccessionNumber),
              format: $format,
              profile-name: $profile-name
          }, true)
      },
      trim($archive, "AccessionNumber")
    |}
  default return
    for $archive in $summaries
    return {|
      $archive,
      {
        Components: backend:url("components",
          {
              aid: encode-for-uri($archive.AID),
              format: $format,
              profile-name: $profile-name
          }, true)
      }
    |}

let $result := { "Archives" : [ $summaries ] }
let $comment :=
{
    NumArchives: count($summaries),
    TotalNumArchives: session:num-archives(),
    TotalNumEntities: session:num-entities()
}
let $serializers := {
    to-xml : function($res as object) as node() {
        switch($profile-name)
        case "sec" return
            <Filings>{
                filings:summaries-to-xml($res.Archives[])
            }</Filings>
        default return
            <Archives>{
                for $a in $res.Archives[]
                return <Archive>
                    <AID>{$a.AID}</AID>
                    <Entity>{$a.Entity}</Entity>
                </Archive>
            }
            </Archives>
    },
    to-csv : function($res as object) as string {
        switch($profile-name)
        case "sec" return
            string-join(filings:summaries-to-csv($res.Archives[]))
        default return
            string-join(
                csv:serialize($res.Archives[], { serialize-null-as : "" }
            ),
        "")
    }
}

let $results := api:serialize($result, $comment, $serializers, $format, "filings")
return api:check-and-return-results($token, $results, $format)

import module namespace http-request = "http://www.28msec.com/modules/http/request";

import module namespace config = "http://apps.28.io/config";
import module namespace api = "http://apps.28.io/api";
import module namespace session = "http://apps.28.io/session";
import module namespace backend = "http://apps.28.io/test";

import module namespace csv = "http://zorba.io/modules/json-csv";

import module namespace archives = "http://28.io/modules/xbrl/archives";

import module namespace companies = "http://28.io/modules/xbrl/profiles/sec/companies";
import module namespace filings = "http://28.io/modules/xbrl/profiles/sec/filings";

import module namespace fiscal-core = "http://28.io/modules/xbrl/profiles/sec/fiscal/core";

(: Query parameters :)
declare  %rest:case-insensitive                 variable $token         as string? external;
declare  %rest:env                              variable $request-uri   as string  external;
declare  %rest:case-insensitive                 variable $format        as string? external;
declare  %rest:case-insensitive %rest:distinct  variable $eid           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $cik           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $tag           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $ticker        as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $sic           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $fiscalYear    as string* external := "LATEST";
declare  %rest:case-insensitive %rest:distinct  variable $fiscalPeriod  as string* external := "FY";
declare  %rest:case-insensitive %rest:distinct  variable $aid           as string* external;
declare  %rest:case-insensitive                 variable $profile-name  as string  external := $config:profile-name;

session:audit-call($token);

(: Post-processing :)
let $format as string? := api:preprocess-format($format, $request-uri)
let $fiscalYear as integer* := api:preprocess-fiscal-years($fiscalYear)
let $fiscalPeriod as string* := api:preprocess-fiscal-periods($fiscalPeriod)
let $tag as string* := api:preprocess-tags($tag)

(: Object resolution :)
let $entities :=
    switch($profile-name)
    case "sec" return companies:companies(
        $cik,
        $tag,
        $ticker,
        $sic)
    default return ()
let $archives as object* :=
    switch($profile-name)
    case "sec" return fiscal-core:filings(
        $entities,
        $fiscalPeriod,
        $fiscalYear,
        $aid)
    default return
        if(exists($eid)) then archives:archives-for-entities($eid)
                              else archives:archives()
let $summaries :=
    switch($profile-name)
    case "sec" return
        for $f in filings:summaries($archives)
        order by $f.Accepted descending
        return $f
    default return
        for $a in $archives
        return {
            AID: $a._id,
            Entity: $a.Entity
        }
let $summaries :=
  switch($profile-name)
  case "sec" return
    for $archive in $summaries
    return {|
      project($archive, "AccessionNumber"),
      {
        Components: backend:url("components",
          {
              aid: encode-for-uri($archive.AccessionNumber),
              format: $format,
              profile-name: $profile-name
          })
      },
      trim($archive, "AccessionNumber")
    |}
  default return
    for $archive in $summaries
    return {|
      $archive,
      {
        Components: backend:url("components",
          {
              aid: encode-for-uri($archive.AID),
              format: $format,
              profile-name: $profile-name
          })
      }
    |}

let $result := { "Archives" : [ $summaries ] }
let $comment :=
{
    NumArchives: count($summaries),
    TotalNumArchives: session:num-archives(),
    TotalNumEntities: session:num-entities()
}
let $serializers := {
    to-xml : function($res as object) as node() {
        switch($profile-name)
        case "sec" return
            <Filings>{
                filings:summaries-to-xml($res.Archives[])
            }</Filings>
        default return
            <Archives>{
                for $a in $res.Archives[]
                return <Archive>
                    <AID>{$a.AID}</AID>
                    <Entity>{$a.Entity}</Entity>
                </Archive>
            }
            </Archives>
    },
    to-csv : function($res as object) as string {
        switch($profile-name)
        case "sec" return
            string-join(filings:summaries-to-csv($res.Archives[]))
        default return
            string-join(
                csv:serialize($res.Archives[], { serialize-null-as : "" }
            ),
        "")
    }
}

let $results := api:serialize($result, $comment, $serializers, $format, "filings")
return api:check-and-return-results($token, $results, $format)


:green_heart: Fix tests.

:green_heart: Fix tests.

import module namespace config = "http://apps.28.io/config";
import module namespace api = "http://apps.28.io/api";
import module namespace session = "http://apps.28.io/session";
import module namespace backend = "http://apps.28.io/backend";

import module namespace archives = "http://28.io/modules/xbrl/archives";
import module namespace filings = "http://28.io/modules/xbrl/profiles/sec/filings";
import module namespace multiplexer = "http://28.io/modules/xbrl/profiles/multiplexer";
import module namespace xbrl-export = "http://28.io/modules/xbrl/export";

declare option rest:response "first-item";

(: Query parameters :)
declare  %rest:case-insensitive                 variable $token         as string? external;
declare  %rest:env                              variable $request-uri   as string  external;
declare  %rest:case-insensitive                 variable $format        as string? external;
declare  %rest:case-insensitive %rest:distinct  variable $eid           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $cik           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $edinetcode    as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $tag           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $ticker        as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $sic           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $fiscalYear    as string* external := "ALL";
declare  %rest:case-insensitive %rest:distinct  variable $fiscalPeriod  as string* external := "ALL";
declare  %rest:case-insensitive %rest:distinct  variable $filingKind    as string* external := ();
declare  %rest:case-insensitive %rest:distinct  variable $aid           as string* external;
declare  %rest:case-insensitive                 variable $profile-name  as string  external := $config:profile-name;
declare  %rest:case-insensitive                 variable $count         as boolean external := false;

(: Post-processing :)
let $format as string? := api:preprocess-format($format, $request-uri)
let $fiscalYear as integer* := api:preprocess-fiscal-years($fiscalYear)
let $fiscalPeriod as string* := api:preprocess-fiscal-periods($fiscalPeriod)
let $tag as string* := api:preprocess-tags($tag)

let $cik as string* :=
    switch($profile-name)
    case "sec" return $cik
    case "japan" return $edinetcode
    default return ()

(: Entity resolution :)
let $entities := multiplexer:entities(
  $profile-name,
  $eid,
  $cik,
  $tag,
  $ticker,
  $sic,
  (),
  (),
  (),
  ())

let $entities-not-found as boolean :=
  exists(($eid, $cik, $tag, $ticker, $sic)) and empty($entities)

let $archives as object* := multiplexer:filings(
  $profile-name,
  $entities,
  $fiscalPeriod,
  $fiscalYear,
  $filingKind,
  $aid)

let $summaries :=
    switch($profile-name)
    case "sec" return
        for $f in $archives
        order by filings:acceptance-dateTimes($f) descending
        return $f
    case "japan" return
      for $a in $archives
      order by $a.Profiles.FSA.SubmissionDate descending
      return project($a, ("_id", "Entity", "Profiles"))
    default return $archives

let $summaries :=
    for $archive in $summaries
    return {|
      {
        AID: $archive._id,
        Entity: $archive.Entity,
        Components: backend:url("components",
          {
              token: $token,
              aid: encode-for-uri(archives:aid($archive)),
              format: $format,
              profile-name: $profile-name
          }),
        Sections: backend:url("sections",
          {
              token: $token,
              aid: encode-for-uri(archives:aid($archive)),
              format: $format,
              profile-name: $profile-name
          }),
        NumSections: archives:num-components($archive),
        NumFacts: archives:num-facts($archive),
        NumFootnotes: archives:num-footnotes($archive),
        NumReportElements: archives:num-report-elements($archive),
        NumHypercubes: archives:num-hypercubes($archive),
        NumDimensions: archives:num-dimensions($archive),
        NumMembers: archives:num-members($archive),
        NumLineItems: archives:num-line-items($archive),
        NumAbstracts: archives:num-abstracts($archive),
        NumConcepts: archives:num-concepts($archive)
      },
      {
          Profiles: {
            SEC: {|
              { Name: "SEC" },
              filings:summaries($archive)
            |}
          },
          AccessionNumber: $archive._id
      }[$profile-name eq "sec"],
      project($archive, "Profiles")[$profile-name eq "japan"]
    |}

let $result := { "Archives" : [ if($count) then () else $summaries ] }
let $comment :=
{
    NumArchives: count($summaries),
    TotalNumArchives: session:num-archives(),
    TotalNumEntities: session:num-entities()
}
let $serializers := {
    to-xml : function($res as object) as node() {
        switch($profile-name)
        case "sec" return
          <Filings>{
            api:json-to-xml($res.Archives[], "Filing")
          }</Filings>
        default return
          <Archives>{
            api:json-to-xml($res.Archives[], "Archive")
          }</Archives>
    },
    to-csv : function($res as object) as string {
        api:json-to-csv($res.Archives[])
    }
}

let $results :=
  if($format eq "xbrl")
  then switch(count($archives))
     case 1 return xbrl-export:archive($archives)
     case 0 return api:not-found("archive")
     default return (
       { status: 400, content-type: "application/json" },
       session:error("Cannot export more than one archive at a time.", "json")
     )
  else api:serialize($result, $comment, $serializers, $format, "filings")
return if($entities-not-found)
       then api:not-found("entity")
       else api:check-and-return-results($token, $results, $format)

import module namespace config = "http://apps.28.io/config";
import module namespace api = "http://apps.28.io/api";
import module namespace session = "http://apps.28.io/session";
import module namespace backend = "http://apps.28.io/backend";

import module namespace archives = "http://28.io/modules/xbrl/archives";
import module namespace filings = "http://28.io/modules/xbrl/profiles/sec/filings";
import module namespace multiplexer = "http://28.io/modules/xbrl/profiles/multiplexer";
import module namespace xbrl-export = "http://28.io/modules/xbrl/export";

declare option rest:response "first-item";

(: Query parameters :)
declare  %rest:case-insensitive                 variable $token         as string? external;
declare  %rest:env                              variable $request-uri   as string  external;
declare  %rest:case-insensitive                 variable $format        as string? external;
declare  %rest:case-insensitive %rest:distinct  variable $eid           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $cik           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $edinetcode    as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $tag           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $ticker        as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $sic           as string* external;
declare  %rest:case-insensitive %rest:distinct  variable $fiscalYear    as string* external := "ALL";
declare  %rest:case-insensitive %rest:distinct  variable $fiscalPeriod  as string* external := "ALL";
declare  %rest:case-insensitive %rest:distinct  variable $filingKind    as string* external := ();
declare  %rest:case-insensitive %rest:distinct  variable $aid           as string* external;
declare  %rest:case-insensitive                 variable $profile-name  as string  external := $config:profile-name;
declare  %rest:case-insensitive                 variable $count         as boolean external := false;

(: Post-processing :)
let $format as string? := api:preprocess-format($format, $request-uri)
let $fiscalYear as integer* := api:preprocess-fiscal-years($fiscalYear)
let $fiscalPeriod as string* := api:preprocess-fiscal-periods($fiscalPeriod)
let $tag as string* := api:preprocess-tags($tag)

let $cik as string* :=
    switch($profile-name)
    case "sec" return $cik
    case "japan" return $edinetcode
    default return ()

(: Entity resolution :)
let $entities := multiplexer:entities(
  $profile-name,
  $eid,
  $cik,
  $tag,
  $ticker,
  $sic,
  (),
  (),
  (),
  ())

let $entities-not-found as boolean :=
  exists(($eid, $cik, $tag, $ticker, $sic)) and empty($entities)

let $archives as object* := multiplexer:filings(
  $profile-name,
  $entities,
  $fiscalPeriod,
  $fiscalYear,
  $filingKind,
  $aid)

let $summaries :=
    switch($profile-name)
    case "sec" return
        for $f in $archives
        order by filings:acceptance-dateTimes($f) descending
        return $f
    case "japan" return
      for $a in $archives
      order by $a.Profiles.FSA.SubmissionDate descending
      return project($a, ("_id", "Entity", "Profiles"))
    default return $archives

let $summaries :=
    for $archive in $summaries
    return {|
      {
        AID: $archive._id,
        Entity: $archive.Entity,
        Components: backend:url("components",
          {
              token: $token,
              aid: encode-for-uri(switch($profile-name)
                                  case "sec" return $archive.AccessionNumber
                                  default return archives:aid($archive)),
              format: $format,
              profile-name: $profile-name
          }),
        Sections: backend:url("sections",
          {
              token: $token,
              aid: encode-for-uri(switch($profile-name)
                                  case "sec" return $archive.AccessionNumber
                                  default return archives:aid($archive)),
              format: $format,
              profile-name: $profile-name
          }),
        NumSections: archives:num-components($archive),
        NumFacts: archives:num-facts($archive),
        NumFootnotes: archives:num-footnotes($archive),
        NumReportElements: archives:num-report-elements($archive),
        NumHypercubes: archives:num-hypercubes($archive),
        NumDimensions: archives:num-dimensions($archive),
        NumMembers: archives:num-members($archive),
        NumLineItems: archives:num-line-items($archive),
        NumAbstracts: archives:num-abstracts($archive),
        NumConcepts: archives:num-concepts($archive)
      },
      {
          Profiles: {
            SEC: {|
              { Name: "SEC" },
              filings:summaries($archive)
            |}
          },
          AccessionNumber: $archive._id
      }[$profile-name eq "sec"],
      project($archive, "Profiles")[$profile-name eq "japan"]
    |}

let $result := { "Archives" : [ if($count) then () else $summaries ] }
let $comment :=
{
    NumArchives: count($summaries),
    TotalNumArchives: session:num-archives(),
    TotalNumEntities: session:num-entities()
}
let $serializers := {
    to-xml : function($res as object) as node() {
        switch($profile-name)
        case "sec" return
          <Filings>{
            api:json-to-xml($res.Archives[], "Filing")
          }</Filings>
        default return
          <Archives>{
            api:json-to-xml($res.Archives[], "Archive")
          }</Archives>
    },
    to-csv : function($res as object) as string {
        api:json-to-csv($res.Archives[])
    }
}

let $results :=
  if($format eq "xbrl")
  then switch(count($archives))
     case 1 return xbrl-export:archive($archives)
     case 0 return api:not-found("archive")
     default return (
       { status: 400, content-type: "application/json" },
       session:error("Cannot export more than one archive at a time.", "json")
     )
  else api:serialize($result, $comment, $serializers, $format, "filings")
return if($entities-not-found)
       then api:not-found("entity")
       else api:check-and-return-results($token, $results, $format)