Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

Purpose

This WS is designed to Pre-qualify data of Device Request (post) - check whether it's possible to create Device request with specified parameters and within the particular Medical program.

Key points

  1. Only authenticated and authorized users with appropriate scope can invoke Prequalify Device Request

  2. This method simply returns the result of data validation within each submitted medical program, but not creates any entities in the system.

  3. Each Medical program may have its unique conditions for the Device Request. It can be based on analysis of personal info, device definition list, terms, locations and combinations of them.

  4. Any Medical program can have separate block of branching logic configured at /wiki/spaces/CSI/pages/17467605147 by NHS administrator.

  5. Сompatibility is checked only for programs which are available in payload (array).

  6. Successful invocation of the method returns decision for each program if it is valid or not to create Device request with submitted combination of parameters in the payload. If program is invalid, the reason must be returned in the response.

  7. It is not allowed for prepersons, because dispense with program is forbidden for them

Specification

...

idAPI_Specification

...

Link

...

https://ehealthmedicaleventsapi.docs.apiary.io/#reference/device-requests/prequalify-device-request/prequalify-device-request

...

Посилання на Apiary або Swagger

...

Resource

...

/api/patients/{{patient_id}}/device_requests/prequalify

...

Посилання на ресурс, наприклад: /api/persons/create

...

Scope

...

device_request:write

...

Scope для доступу

...

Components

...

Зазначається перелік бізнес компонентів, які використовують цей метод, наприклад: ePrescription

...

Microservices

...

Перелік мікросервісів, які використовує метод API, наприклад: Auth, ABAC

...

Protocol type

...

Тип протоколу, який використовується запитом, наприклад: SOAP | REST

...

Request type

...

POST

...

Тип запиту API, наприклад: GET, POST, PATCH…

...

Sync/Async

...

Метод є синхронним чи асинхронним?

...

Public/Private/Internal

...

Потрібно зазначити тип методу за ступенем доступності

Logic

Generate structure for response

  1. If general error found at Validate device request section, that doesn’t depend on medical program, then return corresponding error code with error message

  2. If general validation passed, then collect array for all programs in payload with status for each (VALID or INVALID) and rejection_reason

  3. Generate response according to specification

Input parameters

...

Input parameter

...

Values

...

Type

...

Description

...

Example

...

patient_id

...

String

...

Unique patient identifier

...

7075e0e2-6b57-47fd-aff7-324806efa7e5

Request structure

See on Apiary

Example:

Expand
titleRequest example
Code Block
{
  "device_request": {
    "intent": "order",
    "code": {
      "coding": [
        {
          "system": "device_definition_classification_type",
          "code": "30221"
        }
      ]
    },
    "quantity": {
      "value": 10,
      "system": "device_unit",
      "code": "piece"
    },
    "encounter": {
      "identifier": {
        "type": {
          "coding": [
            {
              "system": "eHealth/resources",
              "code": "encounter"
            }
          ]
        },
        "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
      },
      "display_value": "null"
    },
    "reason": [
      {
        "identifier": {
          "type": {
            "coding": [
              {
                "system": "eHealth/resources",
                "code": "condition"
              }
            ]
          },
          "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
        },
        "display_value": "null"
      }
    ],
    "requester": {
      "identifier": {
        "type": {
          "coding": [
            {
              "system": "eHealth/resources",
              "code": "employee"
            }
          ]
        },
        "value": "b4a6d991-0bf7-476f-b3cf-bec83f044b1b"
      },
      "display_value": "null"
    },
    "authored_on": "2000-01-01T00:00:00.000Z",
    "occurrence_period": {
      "start": "2000-01-01T00:00:00.000Z",
      "end": "2018-08-02T11:00:00.000Z"
    }
  },
  "programs": [
    {
      "identifier": {
        "type": {
          "coding": [
            {
              "system": "eHealth/resources",
              "code": "medical_program"
            }
          ]
        },
        "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
      }
    }
  ]
}

Authorization

  1. Verify the validity of access token

    • in case of error - return 401 (“Invalid access token”) in case of validation fails

  2. Verify that token is not expired

    • in case of error - return 401 (“Invalid access token”)

  3. Check user and client scopes in order to perform this action (scope = 'device_request:write')

    • return 403 (“Your scope does not allow to access this resource. Missing allowances: device_request:write”) in case of invalid scope(s)

Headers

  • Content-Type:application/json

  • Authorization:Bearer mF_9.B5f-4.1JqM

  • api-key:aFBLVTZ6Z2dON1V

Request data validation

Validate legal entity

  • Extract client_id from token

  • Check legal entity status (status = ACTIVE)

    • In case of error - return 409 ('client_id refers to legal entity that is not active')

  • Check legal entity type in ME_ALLOWED_TRANSACTIONS_LE_TYPES config parameter

    • in case of error - return 409 ('client_id refers to legal entity with type that is not allowed to create medical events transactions')

Validate Patient

...

Get Patient identifier from the URL

...

Check it exists in persons table (MPI)

  • Return 404 ('not found') in case of error

...

Validate person status is active

  • in case of error - return 409 ('Patient is not active')

...

  • in case NOT_VERIFIED - return error 409 ("Patient is not verified")

Validate request

Validate request using schema. Return 422 with the list of validation errors in case validation fails. In addition, check following:

Validate Device request

Invoke common validations of root attributes first that are independent of medical programs.

1. Validate requester

Validate value in the field $.requester, Reference on employee resource, required.

  • Extract user_id from token. Check that requester belongs to one of the user’s employee.

    • in case of error - return 422 ('User is not allowed to create device request for the requester')

  • Check requester is an active and approved employee.

    • in case of error - return 422 ('Invalid employee status')

  • Check requester relates to the legal entity (client_id from token).

    • in case of error - return 422 ('Employee <id> doesn't belong to your legal entity')

2. Validate intent

Validate value in the field $.intent, string, required.

  • Check that value is in allowed active values from device_request_intent dictionary.

    • in case of error - return 422 ('value is not allowed in enum')

3. Validate code

Validate value in the field $.code, CodeableConcept type, required.

  • Check that value is in allowed active values from device_definition_classification_type dictionary.

    • in case of error - return 422 ('value is not allowed in enum')

4. Validate quantity

Validate value in the field $.quantity, SimpleQuantity type, required.

  • Check that $.quantity.system is device_unit dictionary, required

    • in case of error - return 422 ('value is not allowed in enum')

  • Check that $.quantity.code comply with $.quantity.system, required

    • in case of error - return 422 ('value is not allowed in enum')

  • Check that $.quantity.value is integer, required

    • in case of error - return 422 ('Value should be an integer')

5. Validate encounter

Validate value in the field $.encounter, Reference on encounter resource, required

...

Validate that entity is not in status "entered_in_error"

  • in case of error - return 422 ("Entity in status "entered_in_error" can not be referenced")

...

Validate diagnosis in the encounter is not empty

  • in case of error - return 422 ("Encounter without diagnosis can not be referenced")

...

Check that encounter belongs to the patient ($.subject)

  • in case of error - return 422 ('Encounter with such id is not found')

...

Table of Contents

Purpose

This WS is designed to Pre-qualify data of Device Request (post) - check whether it's possible to create Device request with specified parameters and within the particular Medical program.

Key points

  1. Only authenticated and authorized users with appropriate scope can invoke Prequalify Device Request

  2. This method simply returns the result of data validation within each submitted medical program, but not creates any entities in the system.

  3. Each Medical program may have its unique conditions for the Device Request. It can be based on analysis of personal info, device definition list, terms, locations and combinations of them.

  4. Any Medical program can have separate block of branching logic configured at /wiki/spaces/CSI/pages/17467605147 by NHS administrator.

  5. Сompatibility is checked only for programs which are available in payload (array).

  6. Successful invocation of the method returns decision for each program if it is valid or not to create Device request with submitted combination of parameters in the payload. If program is invalid, the reason must be returned in the response.

  7. It is not allowed for prepersons, because dispense with program is forbidden for them

Specification

Apiary

Authorization

  1. Verify the validity of access token

    • in case of error - return 401 (“Invalid access token”) in case of validation fails

  2. Verify that token is not expired

    • in case of error - return 401 (“Invalid access token”)

  3. Check user and client scopes in order to perform this action (scope = 'device_request:write')

    • return 403 (“Your scope does not allow to access this resource. Missing allowances: device_request:write”) in case of invalid scope(s)

Validate legal entity

  • Extract client_id from token

  • Check legal entity status (status = ACTIVE)

    • In case of error - return 409 ('client_id refers to legal entity that is not active')

  • Check legal entity type in ME_ALLOWED_TRANSACTIONS_LE_TYPES config parameter

    • in case of error - return 409 ('client_id refers to legal entity with type that is not allowed to create medical events transactions')

Validate Patient

  • Get Patient identifier from the URL

  • Check it exists in persons table (MPI)

    • Return 404 ('not found') in case of error

  • Validate person status is active

    • in case of error - return 409 ('Patient is not active')

  • Validate person'sverification_status is not equal to NOT_VERIFIED.

    • in case NOT_VERIFIED - return error 409 ("Patient is not verified")

Validate request

Validate request using schema. Return 422 with the list of validation errors in case validation fails. In addition, check following:

Validate Device request

Invoke common validations of root attributes first that are independent of medical programs.

1. Validate requester

Validate value in the field $.requester, Reference on employee resource, required.

  • Extract user_id from token. Check that requester belongs to one of the user’s employee.

    • in case of error - return 422 ('Encounter was not created at the requester’s legal entity')

6. Validate authored on

Validate value in the field $.authored_on, datetime type, required

  • Check current date >= authored_on >= (current date - DEVICE_REQUEST_DELAY_INPUT)
    • User is not allowed to create device request for the requester')

  • Check requester is an active and approved employee.

    • in case of error - return 422 ('Invalid employee status')

  • Check requester relates to the legal entity (client_id from token).

    • in case of error - return 422 “Authored on date must be in range of <current date> and <current date - DEVICE_REQUEST_DELAY_INPUT>”

    Check authored_on comply with the encounter dates

    • if encounter has ‘date’ attribute, then check $.authored_on >= $.encounter.date('Employee <id> doesn't belong to your legal entity')

2. Validate intent

Validate value in the field $.intent, string, required.

  • Check that value is in allowed active values from device_request_intent dictionary.

    • in case of error - return 422 ('

      Authored on date must be greater or equal to Encounter start date')

      if encounter has ‘period’ attribute, then check $.authored_on >= $.encounter.period.startvalue is not allowed in enum')

3. Validate code

Validate value in the field $.code, CodeableConcept type, required.

  • Check that value is in allowed active values from device_definition_classification_type dictionary.

    • in case of error - return 422 ('

      Authored on date must be greater than or equal to Encounter period start

      value is not allowed in enum')

...

4. Validate

...

quantity

Validate value in the field $.occurrence_period, Period type, required.

...

the field $.quantity, SimpleQuantity type, required.

  • Check that $.quantity.system is device_unit dictionary, required

    • in case of error - return 422 error ('Start date must be greater than or equal to <authored_on> date, but less than or equal to <authoredOn + DEVICE_REQUEST_EXTENDED_LIMIT_START_DAYS> date('value is not allowed in enum')

  • Check $occurrence_period.end >= $.occurrence_period.startthat $.quantity.code comply with $.quantity.system, required

    • in case of error - return 422 error ('Occurrence end date must be greater than or equal to start date')

    Check occurrence comply with the encounter dates

    • if encounter has ‘date’ attribute, then check $.occurrence_period.start >= $.encounter.date('value is not allowed in enum')

  • Check that $.quantity.value is integer, required

    • in case of error - return 422 ('

      Occurrence start date must be greater than or equal to Encounter start date

      Value should be an integer')if encounter has ‘period’ attribute, then check $.occurrence_period.start >= $.encounter.period.start

5. Validate encounter

Validate value in the field $.encounter, Reference on encounter resource, required

  • Validate that entity is not in status "entered_in_error"

    Check that reason is an array with References on condition resource
    • in case of error - return 422 (

      'Occurrence start date must be greater than or equal to Encounter period start')

8. Validate reason

Validate value in the field $.reason, optional.

    • "Entity in status "entered_in_error" can not be referenced")

  • Validate diagnosis in the encounter is not empty

    • in case of error - return 422 ('value is not allowed in enum'"Encounter without diagnosis can not be referenced")

  • Check that each condition encounter belongs to the patient ($.subject)

    • in case of error - return 422 ('Condition Encounter with such id is not found')

  • Check that verification_status of each condition is not "entered_in_error"encounter created in the same legal entity as the requester

    • in case of error - return 422 ("Entity in status "entered_in_error" can not be referenced")

9. Validate Device definition

Check there is at least one Device Definition:

  • which classification_type attribute is equal to $.code, that:

    • is active

    • has packaging_unit that matches to $.quantity.code of the Device Request'Encounter was not created at the requester’s legal entity')

6. Validate authored on

Validate value in the field $.authored_on, datetime type, required

  • Check current date >= authored_on >= (current date - DEVICE_REQUEST_DELAY_INPUT)

    • in case of error - return 422

      “Not found any active Device Definition with the same units of measure as pointed in the quantity of the Device Request”
  • which package quantity compliant with prescribed quantity

    • Find all active device definitions with the same classification_type (device_definition.classification_type = device_request.code)

    • Check that there is at least on device definition where remainder of division device_request.quantity / device_definition.packaging_count equal to zero

      • i. in case there is no such definitions - return 422 “The amount of devices in device request must be divisible to device package quantity“

10. Validate Medical programs

If all checks below in the text passed for the program - save the response for this program with status = VALID; if not passed - save response with status = INVALID and corresponding reject_reason. Response for such validations should be returned with code 200.

Validate each medical program in the $.programs array:

...

Check the program exists, is of type DEVICE, and is active

  • in case of error - return reject_reason = “Medical program not found”

...

Check request_allowed = true for the program

  • in case of error - return reject_reason = “It is not allowed to create Device requests for the program”

...

Check there is at least one appropriate participant for a program:

  • Find program_devices, that:

    • is active

    • has device_request_allowed=true

    • its validity period (start_date and end_date) includes current date

    • has max_daily_count is null or max_daily_count >= $.quantity.value/(occurence_period.end - occurence_period.start)

    • relates to the Device Definition found at the Validate Device definition step

      • in case not found - return reject_reason = “No appropriate participants found for this medical program“

Make validation according to /wiki/spaces/CSI/pages/17467605147:

If skip_employee_validation = false (null/absent), then $.requester should be validated:

...

  • in case is not found - return reject_reason = “Employee type of the requester doesn't allow to create Device Request with the medical program”

...

In case employee type of the requester is SPECIALIST, then additional validations may be performed:

  • If speciality_types_allowed is set, then check if it contains speciality of the requester (speciality_officio=true):

    • in case is not found - return reject_reason = "Employee's specialty of the requester doesn't allow to create Device Request with the medical program"

...

In case employee type of the requester is DOCTOR, then additional validations may be performed:

  • if skip_request_employee_declaration_verify = false (null/absent), then get declaration by employee_id of the requester, person_id and status=ACTIVE

    • in case is not found - return reject_reason = "Only doctors with an active declaration with the patient can create Device Request with the medical program"

  • if skip_request_legal_entity_declaration_verify = false (null/absent), then get declaration by requester's legal_entity_id, person_id and status=ACTIVE

    • in case is not found - return reject_reason = "Only legal entity with an active declaration with the patient can create Device Request with the medical program"

...

If conditions_icd10_am_allowed is set and $.encounter has primary diagnosis code from the eHealth/ICD10_AM/condition_codes dictionary, then check this code is in the conditions_icd10_am_allowed parameter

  • in case is not found - return reject_reason = "Encounter in the request has no primary diagnosis allowed for the medical program”

...

If conditions_icpc2_allowed is set and $.encounter has primary diagnosis code from the eHealth/ICD10_AM/condition_codes dictionary, then check this code is in the conditions_icpc2_allowed parameter

  • in case is not found - return reject_reason = "Encounter in the request has no primary diagnosis allowed for the medical program”

...

If skip_treatment_period = false (null/absent), then:

  • Get all active/completed Device Requests with $.code, $.medical_program_id, $person_id

  • If such was found, get the Device Request with the latest occurrence_period.end date and check:

    • its occurrence_period.end less then $.occurrence_period.start from the request

      • in case of error - return reject_reason = ”It can be only one active / completed Device Request for the same code and patient at the same period of time”

    • if its occurrence_period.end greater than or equal to current date, then in addition check:

      • If occurrence_period of found Device Request is greater than or equal to DEVICE_REQUEST_STANDARD_DURATION, then $.authored_on from the request should be greater then (occurrence_period.ended at - DEVICE_REQUEST_MAX_RENEW_DAY) of the found Device Request

      • else $.authored_on from the request should be greater then (occurrence_period.ended at - DEVICE_REQUEST_MIN_RENEW_DAY)

        • in case of error - return reject_reason = “It's to early to create new Device Request for such code and medical program”

If request_max_period_day is set, then check if it is not exceeded by the number of days in the $.occurrence_period of the request

...

if exceeded - return reject_reason = “Occurrence period length exceeds allowed value for the medical program“

Processing

API paragraph not found

Response structure

See on Apiary

Example:

Expand
titleResponse example
Code Block
{
  "meta": {
    "code": 200,
    "url": "http://example.com/resource",
    "type": "object",
    "request_id": "req-adasdoijasdojsda"
  },
  "data": [
    {
      "program_id": "59781de0-2e64-4359-b716-bcc05a32c10f",
      "program_name": "Доступні медичні вироби",
      "status": "INVALID",
      "rejection_reason": "No appropriate participants found for this medical program"
    }
  ]
}

Expand
titleResponse example
Code Block
{
  "meta": {
    "code": "422",
    "url": "http://example.com/resource",
    "type": "object",
    "request_id": "req-adasdoijasdojsda"
  },
  "error": {
    "type": "unverified",
    "message": "Patient is not active"
  }
}

Post-processing processes

API paragraph not found

HTTP status codes

...

idAPI_HTTP status codes

...

HTTP status code

...

Message

...

What caused the error

...

 200

...

 

...

 

...

 422

...

 

...

    • “Authored on date must be in range of <current date> and <current date - DEVICE_REQUEST_DELAY_INPUT>”

  • Check authored_on comply with the encounter dates

    • if encounter has ‘date’ attribute, then check $.authored_on >= $.encounter.date

      • in case of error - return 422 ('Authored on date must be greater or equal to Encounter start date')

    • if encounter has ‘period’ attribute, then check $.authored_on >= $.encounter.period.start

      • in case of error - return 422 ('Authored on date must be greater than or equal to Encounter period start')

7. Validate occurrence

Validate value in the field $.occurrence_period, Period type, required.

  • Check ($.authored_on + DEVICE_REQUEST_EXTENDED_LIMIT_START_DAYS) >= $.occurrence_period.start >= $.authored_on

    • in case of error - return 422 error ('Start date must be greater than or equal to <authored_on> date, but less than or equal to <authoredOn + DEVICE_REQUEST_EXTENDED_LIMIT_START_DAYS> date')

  • Check $occurrence_period.end >= $.occurrence_period.start

    • in case of error - return 422 error ('Occurrence end date must be greater than or equal to start date')

  • Check occurrence comply with the encounter dates

    • if encounter has ‘date’ attribute, then check $.occurrence_period.start >= $.encounter.date

      • in case of error - return 422 ('Occurrence start date must be greater than or equal to Encounter start date')

    • if encounter has ‘period’ attribute, then check $.occurrence_period.start >= $.encounter.period.start

      • in case of error - return 422 ('Occurrence start date must be greater than or equal to Encounter period start')

8. Validate reason

Validate value in the field $.reason, optional.

  • Check that reason is an array with References on condition resource

    • in case of error - return 422 ('value is not allowed in enum')

  • Check that each condition belongs to the patient ($.subject)

    • in case of error - return 422 ('Condition with such id is not found')

  • Check that verification_status of each condition is not "entered_in_error"

    • in case of error - return 422 ("Entity in status "entered_in_error" can not be referenced")

9. Validate Device definition

Check there is at least one Device Definition:

  • which classification_type attribute is equal to $.code, that:

    • is active

    • has packaging_unit that matches to $.quantity.code of the Device Request

      • in case of error - return 422 “Not found any active Device Definition with the same units of measure as pointed in the quantity of the Device Request”

  • which package quantity compliant with prescribed quantity

    • Find all active device definitions with the same classification_type (device_definition.classification_type = device_request.code)

    • Check that there is at least on device definition where remainder of division device_request.quantity / device_definition.packaging_count equal to zero

      • i. in case there is no such definitions - return 422 “The amount of devices in device request must be divisible to device package quantity“

10. Validate Medical programs

If all checks below in the text passed for the program - save the response for this program with status = VALID; if not passed - save response with status = INVALID and corresponding reject_reason. Response for such validations should be returned with code 200.

Validate each medical program in the $.programs array:

  • Check the program exists, is of type DEVICE, and is active

    • in case of error - return reject_reason = “Medical program not found”

  • Check request_allowed = true for the program

    • in case of error - return reject_reason = “It is not allowed to create Device requests for the program”

  • Check there is at least one appropriate participant for a program:

    • Find program_devices, that:

      • is active

      • has device_request_allowed=true

      • its validity period (start_date and end_date) includes current date

      • has max_daily_count is null or max_daily_count >= $.quantity.value/(occurence_period.end - occurence_period.start)

      • relates to the Device Definition found at the Validate Device definition step

        • in case not found - return reject_reason = “No appropriate participants found for this medical program“

  • Make validation according to /wiki/spaces/CSI/pages/17467605147:

    • If skip_employee_validation = false (null/absent), then $.requester should be validated:

      • If employee_types_to_create_request parameteris set, then check if it contains employee type of the requester

        • in case is not found - return reject_reason = “Employee type of the requester doesn't allow to create Device Request with the medical program”

      • In case employee type of the requester is SPECIALIST, then additional validations may be performed:

        • If speciality_types_allowed is set, then check if it contains speciality of the requester (speciality_officio=true):

          • in case is not found - return reject_reason = "Employee's specialty of the requester doesn't allow to create Device Request with the medical program"

      • In case employee type of the requester is DOCTOR, then additional validations may be performed:

        • if skip_request_employee_declaration_verify = false (null/absent), then get declaration by employee_id of the requester, person_id and status=ACTIVE

          • in case is not found - return reject_reason = "Only doctors with an active declaration with the patient can create Device Request with the medical program"

        • if skip_request_legal_entity_declaration_verify = false (null/absent), then get declaration by requester's legal_entity_id, person_id and status=ACTIVE

          • in case is not found - return reject_reason = "Only legal entity with an active declaration with the patient can create Device Request with the medical program"

    • If conditions_icd10_am_allowed is set and $.encounter has primary diagnosis code from the eHealth/ICD10_AM/condition_codes dictionary, then check this code is in the conditions_icd10_am_allowed parameter

      • in case is not found - return reject_reason = "Encounter in the request has no primary diagnosis allowed for the medical program”

    • If conditions_icpc2_allowed is set and $.encounter has primary diagnosis code from the eHealth/ICD10_AM/condition_codes dictionary, then check this code is in the conditions_icpc2_allowed parameter

      • in case is not found - return reject_reason = "Encounter in the request has no primary diagnosis allowed for the medical program”

    • If skip_treatment_period = false (null/absent), then:

      • Get all active/completed Device Requests with $.code, $.medical_program_id, $person_id

      • If such was found, get the Device Request with the latest occurrence_period.end date and check:

        • its occurrence_period.end less then $.occurrence_period.start from the request

          • in case of error - return reject_reason = ”It can be only one active / completed Device Request for the same code and patient at the same period of time”

        • if its occurrence_period.end greater than or equal to current date, then in addition check:

          • If occurrence_period of found Device Request is greater than or equal to DEVICE_REQUEST_STANDARD_DURATION, then $.authored_on from the request should be greater then (occurrence_period.ended at - DEVICE_REQUEST_MAX_RENEW_DAYS) of the found Device Request

          • else $.authored_on from the request should be greater then (occurrence_period.ended at - DEVICE_REQUEST_MIN_RENEW_DAYS)

            • in case of error - return reject_reason = “It's to early to create new Device Request for such code and medical program”

    • If request_max_period_day is set, then check if it is not exceeded by the number of days in the $.occurrence_period of the request

      • if exceeded - return reject_reason = “Occurrence period length exceeds allowed value for the medical program“

Service logic

Generate structure for response

  1. If general error found at Validate device request section, that doesn’t depend on medical program, then return corresponding error code with error message

  2. If general validation passed, then collect array for all programs in payload with status for each (VALID or INVALID) and rejection_reason

  3. Generate response according to specification