Stöd för resultatberäkning av besvarat formulär

Issue #380 resolved
Peter Merikan created an issue

Behöver införa stöd för att kunna göra en eller flera beräkningar baserat på de svar som patienten angivit i formuläret.

Vi har idag implementerat lösning för att göra beräkningar i Inera Formulärmotor. Dock använder sig lösningen av interna api:er för att få denna funktionaliteten, som idag används av den fristående Formulärtjänsten. För att andra externa aktörer skall kunna tillgodogöra sig denna funktionaliteten både som konsument och producent så behöver RIV-TA tjänstekontrakten utökas, se nedan.

En eller flera beräkningsformler skall kunna anges på en mall som sedan kan användas för att beräkna resultat.

Beräkningen görs efter att patienten har godkänt ett ifyllt formulär (SaveForm). Beräkningen kan utföras av Producent och/eller Konsument beroende på om de har stöd för aktuella beräkningstyper.

Lösningen är generell och ställer inga krav på hur beräkningen skall beskrivas eller utföras, vi har dock valt att utöka elementet QuestionType med en unik identifierare (questionId) för att förenkla användandet av fråga/svar i beräkningen.

I Inera Formulärmotor har vi valt att använda Drools för att implementera stöd för beräkningar och har då pekat ut Formula.type ='inera:form-engine:drools-java:1' som identifierare. Om en formel med denna typen finns på mallen så kommer beräkning utföras av producenten, mao FM. Andra konsumenter behöver inte använda denna typen utan kan implementera eget stöd för beräkning och då använda en egen Formula.type. FM kommer då ignorera denna formel och inte göra någon beräkning.

Exempel på en formel i FM för att beräkna BMI

when  
  $q: Questions()
then  
  outcome.set($q.get("weight") / ($q.get("height")/100 * $q.get("height")/100));
end

Mallen som json

{
  "templateId": "{% uuid 'v4' %}",
  "templateVersion": 1,
  "careUnit": {
    "name": "CallistaCare",
    "id": "Callista-1234",
    "idType": {
      "code": "1.2.752.129.2.1.4.1",
      "codeSystem": "HSA"
    }
  },
  "status": "UNPUBLISHED",
  "name": "small template",
  "language": {
    "code": "SE",
    "codeSystem": "SS-ISO-639-2"
  },
    "category": "cat-1",
  "term": "term",
    "propagate": {
        "propagate": true
    },
  "pages": [
    {
      "page": {
        "subject": "page 1",
        "description": "page 1 desc",
        "pageNumber": 1,
        "questionBlocks": [
          {
            "subject": "Personal data",
            "description": "please, add some personal information",
            "blockNumber": 1,
            "numberOfQuestions": 2,
            "questions": [
              {
                "subject": "Weight",
                "description": "fyll i din vikt i kg",
                "questionNumber": 1,
                "questionId": "weight",
                "input": "text",
                "mandatory": true,
                "answerMin": 0,
                "answerMax": 0

              },
              {
                "subject": "Height",
                "description": "fyll i din längd i centimeter",
                "questionNumber": 2,
                "questionId": "height",
                "input": "text",
                "mandatory": true,
                "answerMin": 0,
                "answerMax": 0
              }
            ]
          }                 
        ]
      }
    }
  ],
  "calculationFormulas": [
    {
      "calculationId": "bmi",
      "subject": "beräkna bmi",
            "descriptionCareActor": "Beräkning av BMI",
      "descriptionSubjectOfCare": "Beräkning av ditt BMI",
            "approvedForSubjectOfCare": true,
      "type": "inera:form-engine:drools-java:1",
      "license": "copyleft",
      "formula": "when $q: Questions() then outcome.set($q.get(\"weight\") / ($q.get(\"height\")/100 * $q.get(\"height\")/100)); end"
    }
  ]
}

Föreslagna ändringar av RIV kontrakten

Vi har idag implementerat lösning för att göra beräkningari Inera Formulärmotor. Dock använder sig lösningen av interna api:er för att få denna funktionaliteten, som idag används av den fristående Formlärtjänsten. För att andra externa aktörer skall kunna tillgodogöra sig denna funktionaliteten både som konsument och producent så behöver RIV-TA tjänstekontrakten utökas, se nedan.

Nya elementtyper

ElementIdType

som är ett id för ett xml element. Har valt att skapa ett element istället för att använda xml:id attribute https://www.w3.org/TR/xml-id/

<xs:simpleType name="ElementIdType">
  <xs:annotation>
    <xs:documentation>Id for a xml element</xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:string">
    <xs:minLength value="1"/>
    <xs:maxLength value="1024"/>
  </xs:restriction>
</xs:simpleType>

CalculationFormulaType

är en komplex typ som håller värden för beräkningen.

<xs:complexType name="CalculationFormulaType">
  <xs:annotation>
    <xs:documentation>
      Element som håller beräkningsformel som används vid beräkning av resultat
      - calculationId : unikt id för beräkningsformel
      - subject : rubrik för formeln
      - descriptionCareActor : beskrivning för vårdgivaren
      - descriptionSubjectOfCare : beskrivning för vårdtagaren
      - approvedForSubjectOfCare : får reseultatet visas för vårdtagaren
      - type : typ av DSL för formeln t.ex drools, json etc
      - license : licens för beräkningsformeln
      - formula : beräkningformeln
    </xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element name="calculationId" type="tns:ElementIdType" minOccurs="1" maxOccurs="1" />
    <xs:element name="subject" type="xs:string" minOccurs="1" maxOccurs="1" />
    <xs:element name="descriptionCareActor" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="descriptionSubjectOfCare" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="approvedForSubjectOfCare" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="type" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="license" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="formula" type="xs:string" minOccurs="1" maxOccurs="1" />
    <xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
  </xs:sequence>
</xs:complexType>

CalculationOutcomeType

CalculationOutcomeType innehåller resultatet efter att en beräkning utförts av producenten.

<xs:complexType name="CalculationOutcomeType">
  <xs:annotation>
    <xs:documentation>
      Håller resultat från beräkningen
      - outcome : resultat från beräkningformel
      - calculationId : id för beräkningformel i mallen
      - subject : rubrik för formeln
      - descriptionCareActor : beskrivning för vårdgivaren
      - descriptionSubjectOfCare : beskrivning för vårdtagaren
      - approvedForSubjectOfCare : får resultatet visas för vårdtagaren
      - errorMessage: meddelande om fel vid beräkning, medför att outcome = null
    </xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element name="outcome" type="xs:double" minOccurs="0" maxOccurs="1" />
    <xs:element name="calculationId" type="tns:ElementIdType" minOccurs="1" maxOccurs="1"/>
    <xs:element name="subject" type="xs:string" minOccurs="1" maxOccurs="1" />
    <xs:element name="descriptionCareActor" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="descriptionSubjectOfCare" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="approvedForSubjectOfCare" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:element name="errorMessage" type="xs:string" minOccurs="0" maxOccurs="1" />
    <xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
  </xs:sequence>
</xs:complexType>

Utökade elementtyper

FormTemplateType

Lagt till element ‘formula’ av typen CalculationFormulaType (collection)

<xs:complexType name="FormTemplateType">
  <xs:sequence>
    ... 
    <xs:element name="formula" type="tns:CalculationFormulaType" minOccurs="0" maxOccurs="unbounded" />
    <xs:any namespace='##other' processContents='lax'
      minOccurs='0' maxOccurs='unbounded' />
  </xs:sequence>
</xs:complexType>

FormType

Lagt till element ‘calculationOutcome’ av typen CalculationOutcomeType (collection)

<xs:complexType name="FormType">
  <xs:sequence>
    ...
    <xs:element name="calculationOutcome" type="tns:CalculationOutcomeType" minOccurs="0" maxOccurs="unbounded" />
    <xs:any namespace='##other' processContents='lax'
      minOccurs='0' maxOccurs='unbounded' />
  </xs:sequence>
</xs:complexType>

QuestionType

Lagt till element ElementIdType

<xs:complexType name="QuestionType">
  <xs:sequence>
    ...
    <xs:element name="questionId" type="tns:ElementIdType" minOccurs="0"/>
    <xs:any namespace='##other' processContents='lax'
      minOccurs='0' maxOccurs='unbounded' />
  </xs:sequence>
</xs:complexType>

TemplateQuestionType

Lagt till element ElementIdType

<xs:complexType name="TemplateQuestionType">
  <xs:sequence>
    ...
    <xs:element name="questionId" type="tns:ElementIdType" minOccurs="0"/>
    <xs:any namespace='##other' processContents='lax'
      minOccurs='0' maxOccurs='unbounded' />
  </xs:sequence>
</xs:complexType>

Comments (8)

  1. Log in to comment