Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Purpose

This WS is designed to qualify Medication request (post) - check the ability to use Medication request within the Medication program and receive program participants

Specification

...

Link

...

https://ehealthmisapi1.docs.apiary.io/#reference/public.-reimbursement/medication-request/qualify-medication-request-by-id

...

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

...

Resource

...

/api/medication_requests/{{id}}/actions/qualify

...

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

...

Scope

...

medication_request:details

...

Scope для доступу

...

Components

...

ePrescription

...

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

...

Microservices

...

API paragraph not found

...

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

...

Protocol type

...

REST

...

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

...

Request type

...

POST

...

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

...

Sync/Async

...

Sync

...

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

...

Public/Private/Internal

...

Public

Logic

API paragraph not found

Preconditions

No

Global and configurable parameters

No

Input parameters

...

Input parameter

...

Values

...

Type

...

Description

...

Example

...

id

...

String

...

Medication request identifier. Required.

...

2848a935-5fd7-48ba-b235-a9b5d475c647

Filters

No

Request structure

See on Apiary

Example:

...

titleRequest example

...

Purpose

This WS is designed to qualify Medication request (post) - check the ability to use Medication request within the Medication program and receive program participants

Specification

Page Properties

Link

https://ehealthmisapi1.docs.apiary.io/#reference/public.-reimbursement/medication-request/qualify-medication-request-by-id

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

Resource

/api/medication_requests/{{id}}/actions/qualify

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

Scope

medication_request:details_pharm

Scope для доступу

Components

ePrescription

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

Microservices

API paragraph not found

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

Protocol type

REST

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

Request type

POST

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

Sync/Async

Sync

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

Public/Private/Internal

Public

Logic

Процеси роботи з погашенням електронних рецептів

Технічний опис бізнес-процесу погашення рецепту в ЦБД ЕСОЗ

Preconditions

MR should be found by number

Input parameters

Input parameter

Values

Type

Description

Example

id

String

Medication request identifier. Required.

2848a935-5fd7-48ba-b235-a9b5d475c647

Request structure

See on Apiary

Example:

Expand
titleRequest example
Code Block
{
  "division_id": "2848a935-5fd7-48ba-b235-a9b5d475c647",
  "programs": [
    {
      "id": "59781de0-2e64-4359-b716-bcc05a32c10f"
    }
  ]
}

Authorize

...

  1. For info - status charts: Medication_request.

  2. Check Medication Request `status` = ACTIVE

    1. if invalid - return 409 error (message: "Invalid status Medication request for qualify action!")'.

...

  1. Verify Care plan:

    1. It should be in active status

      1. in case of error - return 409 (message: "Invalid care plan status").

    2. Care plan's period end (if exist) should be greater than current date or equal

      1. in case of error - return 409 (message: “Care plan expired“).

  2. Verify care plan Activity:

    1. It has scheduled, in_progress status

      1. in case of error - return 409 (message: "Invalid activity status").

Validate division

  1. Validate division is active

    1. in case of error - return 409 ("Division is not active")

  2. Validate division belongs to user's legal entity

    1. in case of error - return 409 ("Division does not belong to user's legal entity")

  3. If chart parameter DISPENSE_DIVISION_DLS_VERIFY is on, then validate division is DLS verified (dls_verified=true)

    1. in case of error - return 409 "Division is not verified in DLS"

  4. Check division participates in submitted programs. Validate Provision for each Medical Program:

    1. If the medical program has no setting skip_contract_provision_verify or it is equal to false/null:

      1. if medical program in the request has funding_source one of NHS, LOCAL

        1. In case of error - return status=INVALID for a program, rejection_reason="Program was configured incorrectly. Either incorrect source of funding or option skip_contract_provision_verify"

      2. provision exist and active for the division:

        1. in case of error - return status=INVALID for a program, rejection_reason= "Division does not provide the medical program"

      3. if medical program in the request has funding_source = NHS:

        1. provision relates to the actual reimbursement contract: contract.start_date <= current_date <= contract.end_date, is_active = true, status = VERIFIED, contracts.type==reimbursement, contracts.contractor_legal_entity_id=token.client_id, contracts.medical_program_id==$.medical_program_id

          1. in case of error - return status=INVALID for a program, rejection_reason="Medical program provision is not related to any actual contract for the current date"

        2. contract is_suspended = false

          1. in case of error - return status=INVALID for a program, rejection_reason="Contract with number <contract_number> is suspended"

      4. if medical program in the request has funding_source = LOCAL, then check medical_program_provision.msp_legal_entity_id = medication_request.legal_entity_id

        1. in case of error - return status=INVALID for a program, rejection_reson = "Medical program can not be provided for the legal entity specified in the medication request"

    2. else if skip_contract_provision_verify = true, then skip provision verification for the medical program

  5. Get license_types_allowed parameter from settings of medical program from request $.medical_program_id:

    1. if it is exists and not empty, get list of all license types from parameter.
      Check that division has active healthcare services with following parameters:

      1. legal_entity_id = client_id from access token

      2. division_id = division_id from request

      3. status = 'ACTIVE'

      4. licensed_healthcare_service.status = 'ACTIVE'

      5. healthcare_service.license_id is not null and licenses.type = value from license_types_allowed parameter

        1. in case of error - return status=INVALID for a program, rejection_reason = 'Division does not have active licenses to provide the medical program'

Logic for qualify (analyze compliance with programs)

  • Each Medical program may have its unique conditions for the medication dispense. It can be based on analysis of personal info, medications list, terms, locations and combinations of them.

    Also, it is possible to have the medication dispense without any Medical program.

    However for any Medical program we need a separate block of branching logic.

    Check compatibility only for programs which are available in payload (array)

    If program status is invalid, the reason must be saved and returned in response.

Check compliance for programs

  1. Validate 2 checks (below in the text) for programs

    1. if passed - save status this program for response = VALID.

Check INNM_dosage compliance for the programs

Validation purpose:  There is a list of medications (which links to innm_dosage) which can be used for the program. It must be check whether there is at least one available medication for the innm_dosage for the particular program.

  1. Get info from Medication request  by id in payload, set temp variable object `_MR`.

  2. Validate the compatibility of innm with the medication program list 

    1. if data is not found:

      1. add to response: status = INVALID

        add to response: rejection_reason = "Innm not on the list of approved innms for program '#{program.name}"

...

Code Block
IF EXISTS
    (SELECT * FROM program_medications MP
        INNER JOIN medications M
            ON M.id = MP.medication_id
                AND M.type =  BRANDS
        INNER JOIN ingredients I
            ON I.parend_id = M.id
                AND I.is_primary = TRUE
                AND I.medication_child_id = _MR.medication_id
    WHERE MP.medical_program_id == $.id
        AND MP.is_active == TRUE
        AND M.is_active == TRUE)

Check absence a same medication for the programs

Validation purpose: It could be done several dispenses for one medication request per one innm for one patient until sum(medication_dispenses.medication_qty) < medication_request.medication_qty

Example validation: without crossing time

...

EP

...

 Preconditions # 1

...

Result validate #1 

...

 Preconditions #2

...

Result validate #2 

...

 Preconditions #3

...

Result validate #2 

...

PreQualifyMedicationRequestRequest

...

No records in
MedicationRequestRequest 
and in MedicationRequest

...

OK

...

Create record in
MedicationRequestRequest 
or in MedicationRequest

...

Not valid

...

Medications request
dispensed (COMPLETED)

...

Not valid

...

QualifyMedicationRequestByID

...

No records in
MedicationRequestRequest 
and in MedicationRequest

...

Not possible

...

Create record in
MedicationRequestRequest 
or in MedicationRequest

...

OK

...

Medications request
dispensed (COMPLETED) 

...

Not valid

  1. For info - status charts: Medication Request Status Chart & Medication Dispense Status Chart

  2. Get `check_innm_id`

    Code Block
    SELECT I.innm_child_id
    	FROM ingredients I
    WHERE I.parent_id = _MR.medication_id 
    	AND I.is_primary = TRUE
    

    Get Medication requests with their linked completed Medication dispense by person_id & innm_id

    Code Block
    SELECT * FROM medication_requests MR
    	INNER JOIN medication_dispense MD
    		ON MD.medication_request_id = MR.id 
    			AND MD.status IN (PROCESSED)
        INNER JOIN ingredients I
            ON I.parent_id = MR.medication_id			-- type = INNM_DOSAGE
                AND I.innm_child_id = `check_innm_id`
                AND I.is_primary = TRUE
        WHERE MR.person_id == _MR.person_id
            AND MR.status IN (ACTIVE, COMPLETED)
            AND NOT($.started_at> MR.ended_at OR $.ended_at < MR.started_at)
    

    Validate medication request_id

  3. for medication_dispense.medication_request_id !== $.id

    1. Validate exist (IF EXIST ()  - that is any crossing  calculating term (started_at + ended_at) for payload with terms selecting Medication requests with linked Medication dispense (started_at + ended_at))

    2. if found 

      1. get $.medical_programs.medical_program_setting by medical_program_id from request

        1. validate skip_mnn_in_treatment_period variable

          1. in case skip_mnn_in_treatment_period == FALSE (or absent) 

            1. validate request according to logic:

              1. add to response: status = INVALID

                add to response: rejection_reason = "For the patient at the same term there can be only 1 dispensed medication request per one and the same innm!"

          2. in case skip_mnn_in_treatment_period == TRUE

            1. skip validating frequency of receiving drugs

  4. for medication_dispense.medication_request_id = $.id

  5. Validate medication request qty: sum(medication_dispenses.medication_qty) >= medication_request.medication_qty 

  6. if found

    add to response: status = INVALID

    add to response: rejection_reason = "Sum of dispense's medication quantity can not be more then medication_request.medication_qty".

    care plan Activity:

    1. It has scheduled, in_progress status

      1. in case of error - return 409 (message: "Invalid activity status").

    2. Validate quantity is not exceeded

      1. Select all MD (medication dispenses) in status PROCESSED related to the Medication requests which based_on one activity 

        1. Sum medication_qty in the filtered Medication dispenses as dispensed_qty

        2. medication_qty from current MR as current_qty

        3. Calculate remaining_qty = activity.quantity - (dispensed_qty+current_qty)

      2. Check remaining_qty is greater then zero

        1. error return 409 "The total amount of the dispensed medication quantity exceeds quantity in care plan activity"

Validate division

  1. Validate division is active

    1. in case of error - return 409 ("Division is not active")

  2. Validate division belongs to user's legal entity

    1. in case of error - return 409 ("Division does not belong to user's legal entity")

  3. If chart parameter DISPENSE_DIVISION_DLS_VERIFY is on, then validate division is DLS verified (dls_verified=true)

    1. in case of error - return 409 "Division is not verified in DLS"

  4. If the medical program has no setting skip_dispense_division_dls_verify or it is set in false/null validate:

    • Check $.division.dls_verify == true:

      • In case of error - return 409 "Invalid division dls status"

    else if skip_dispense_division_dls_verify = true, then skip license verification for the division

  5. Check division participates in submitted programs. Validate Provision for each Medical Program:

    1. If the medical program has no setting skip_contract_provision_verify or it is equal to false/null:

      1. if medical program in the request has funding_source one of NHS, LOCAL

        1. In case of error - return status=INVALID for a program, rejection_reason="Program was configured incorrectly. Either incorrect source of funding or option skip_contract_provision_verify"

      2. provision exist and active for the division:

        1. in case of error - return status=INVALID for a program, rejection_reason= "Division does not provide the medical program"

      3. if medical program in the request has funding_source = NHS:

        1. provision relates to the actual reimbursement contract: contract.start_date <= current_date <= contract.end_date, is_active = true, status = VERIFIED, contracts.type==reimbursement, contracts.contractor_legal_entity_id=token.client_id, contracts.medical_program_id==$.medical_program_id

          1. in case of error - return status=INVALID for a program, rejection_reason="Medical program provision is not related to any actual contract for the current date"

        2. contract is_suspended = false

          1. in case of error - return status=INVALID for a program, rejection_reason="Contract with number <contract_number> is suspended"

      4. if medical program in the request has funding_source = LOCAL, then check medical_program_provision.msp_legal_entity_id = medication_request.legal_entity_id

        1. in case of error - return status=INVALID for a program, rejection_reson = "Medical program can not be provided for the legal entity specified in the medication request"

    2. else if skip_contract_provision_verify = true, then skip provision verification for the medical program

  6. Get license_types_allowed parameter from settings of medical program from request $.medical_program_id:

    1. if it is exists and not empty, get list of all license types from parameter.
      Check that division has active healthcare services with following parameters:

      1. legal_entity_id = client_id from access token

      2. division_id = division_id from request

      3. status = 'ACTIVE'

      4. licensed_healthcare_service.status = 'ACTIVE'

      5. healthcare_service.license_id is not null and licenses.type = value from license_types_allowed parameter

        1. in case of error - return status=INVALID for a program, rejection_reason = 'Division does not have active licenses to provide the medical program'

Logic for qualify (analyze compliance with programs)

  • Each Medical program may have its unique conditions for the medication dispense. It can be based on analysis of personal info, medications list, terms, locations and combinations of them.

  • For now there are only conditions for the following programs "Dostupni liky", "Netsukrovyy diabet", "Insuliny z doplatoyu", "Insuliny bezoplatno" and we check them.

  • Also, it is possible to have the medication dispense without any Medical program.

  • However for any Medical program we need a separate block of branching logic.

  • Check compatibility only for programs which are available in payload (array)

  • If program status is invalid, the reason must be saved and returned in response

Check compliance for programs

  1. Validate 2 checks (below in the text) for programs

    1. if passed - save status this program for response = VALID

Check INNM_dosage compliance for the programs

Applies to the following programs:

  1. Dostupni liky

  2. Netsukrovyy diabet

  3. Insuliny z doplatoyu

  4. Insuliny bezoplatno

Validation purpose:  There is a list of medications (which links to innm_dosage) which can be used for the program. It must be check whether there is at least one available medication for the innm_dosage for the particular program.

  1. Get info from Medication request  by id in payload, set temp variable object `_MR`

  2. Validate the compatibility of innm with the medication program list 

    1. if data is not found:

      1. add to response: status = INVALID

      2. add to response: rejection_reason = "Innm not on the list of approved innms for program '#{program.name}"

...

  • of personal info, medications list, terms, locations and combinations of them.

    Also, it is possible to have the medication dispense without any Medical program.

    However for any Medical program we need a separate block of branching logic.

    Check compatibility only for programs which are available in payload (array)

    If program status is invalid, the reason must be saved and returned in response.

Check compliance for programs

  1. Validate 2 checks (below in the text) for programs

    1. if passed - save status this program for response = VALID.

Check INNM_dosage compliance for the programs

Validation purpose:  There is a list of medications (which links to innm_dosage) which can be used for the program. It must be check whether there is at least one available medication for the innm_dosage for the particular program.

Check that there is at least one medication (brand or innm_dosage) associated with medical program that can be dispensed to the patient

  1. Get info from Medication request  by id in payload, set temp variable object `_MR`

  2. Validate the compatibility of innm with the medication program list 

    1. Search for active innm_dosages that associated with medical program

      1. medications.is_active = true

      2. medications.type = INNM_DOSAGE

      3. program_medications.is_active = true

    2. Search for active brands that have innm_dosage as primary ingredient and are associated with medical program

      1. medications.is_active = true

      2. medications.type = BRAND

      3. ingredients.is_primary = true

      4. program_medications.is_active = true

    3. if nothing found:

      1. add to response: status = INVALID

      2. add to response: rejection_reason = "Innm not on the list of approved innms for program '#{program.name}"

Code Block
IF EXISTS
    (SELECT * FROM program_medications MP
        INNER JOIN medications M
            ON M.id = MP.medication_id
                AND M.type =  BRANDS
        INNER JOIN ingredients I
            ON I.parend_id = M.id
                AND I.is_primary = TRUE
                AND I.medication_child_id = _MR.medication_id
   
    WHERE
 WHERE MP.medical_program_id == $.id
        AND
        AND MP.is_active == TRUE
        AND

        AND M.is_active == TRUE)

Check absence a same medication for the programs

Applies to the following programs:

  1. Dostupni liky

  2. Netsukrovyy diabet

  3. Insuliny z doplatoyu

  4. Insuliny bezoplatno

Validation purpose: It could be done several dispenses for one medication request per one innm for one patient until sum(medication_dispenses.medication_qty) < medication_request.medication_qty

Example validation: without crossing time

EP

 Preconditions # 1

Result validate #1 

 Preconditions #2

Result validate #2 

 Preconditions #3

Result validate #2 

PreQualifyMedicationRequestRequest

No records in
MedicationRequestRequest 
and in MedicationRequest

OK

Create record in
MedicationRequestRequest 
or in MedicationRequest

Not valid

Medications request
dispensed (COMPLETED)

Not valid

QualifyMedicationRequestByID

No records in
MedicationRequestRequest 
and in MedicationRequest

Not possible

Create record in
MedicationRequestRequest 
or in MedicationRequest

OK

Medications request
dispensed (COMPLETED) 

Not valid

  1. For info - status charts:   Medication Request Status Chart & Medication Dispense Status Chart

  2. Get `check_innm_id`

    Code Block
    SELECT I.innm_child_id
        FROM	FROM ingredients I
    WHERE I.parent_id = _MR.medication_id 
        AND	AND I.is_primary = TRUE
    

  3. Get Medication requests with their linked completed Medication dispense by person_id & innm_id

    Code Block
    SELECT * FROM medication_requests MR
    

    MR    INNER

    	INNER JOIN medication_dispense MD
    

    MD        ON

    		ON MD.medication_request_id = MR.id 
    

                AND

    			AND MD.status IN (PROCESSED)

        INNER

    
        INNER JOIN ingredients

    I        ON

     I
            ON I.parent_id = MR.medication_

    id          

    id			-- type = INNM_

    DOSAGE            AND

    DOSAGE
                AND I.innm_child_id = `check_innm_

    id`            AND

    id`
                AND I.is_primary =

    TRUE    WHERE

     TRUE
        WHERE MR.person_id == _MR.

    person_id        AND

    person_id
            AND MR.status IN (ACTIVE, COMPLETED)

            AND

    
            AND NOT($.started_at> MR.ended_at OR $.ended_at < MR.started_at)
    

  4. Validate medication request_id

    1. for medication_dispense.medication_request_id !== $.id

      1. Validate exist (IF EXIST ()  - that is any crossing  calculating term (started_at + ended_at) for payload with terms selecting Medication requests with linked Medication dispense (started_at + ended_at)).  

      2. if found 

        1. get $.medical_programs.medical_program_setting by medical_program_id from request

          1. validate skipvalidate skip_mnn_in_treatment_period skip_treatment_period variable

            1. in case skipcase skip_mnn_in_treatment_period skip_treatment_period period== FALSE (or absent) 

              1. validate request according to logic:

                1. add to response: status = INVALID

                  add to response: rejection_reason = "For the patient at the same term there can be only 1 dispensed medication request per one and the same innm!"

            2. in case skipcase skip_mnn_in_treatment_period period skip_treatment_period== TRUE

              1. skip validating frequency of receiving drugs

    2. for medication_dispense.medication_request_id = $.id

      1. Validate medication request qty: sum(medication_dispenses.medication_qty) >= medication_request.medication_qty 

      2. if found

        1. add to response: status = INVALID

          add to response: rejection_reason = "Sum of dispense's medication quantity can not be more then medication_request.medication_qty".

Parameters that are used when processing the request

...

Access to the method is defined by the scope medication_request:details. Permission for this scope is determined by the System administrator by configuring scopes in the context of clients and roles.

Dictionaries

API paragraph not found

Processing

...

  • MEDICATION_FORM

  • COUNTRY

  • MEDICATION_UNIT

Response structure

Generate structure for response

  • Collect response array for all programs in payload with status for each (VALID or INVALID) and rejection_reason

  • For all VALID programs - Get linked medications (type = BRAND) with reimbursement info 

  • Show only active program medications based on start_date and end (start_date must be earlier or equal to current date or empty, end_date must be greater or equal to current date or empty)

    • Filter participants simultaneously by container_dosage and max_request_dosage

Code Block
SELECT *
FROM program_medications pm
    INNER JOIN ingredients i ON (i.parent_id = pm.medication_id
                                 AND i.medication_child_id = :medication_request_medication_id
                                 AND i.is_primary = TRUE)
    INNER JOIN medications m ON (m.id = pm.medication_id)
WHERE pm.medical_program_id = $.id
      AND pm.is_active = TRUE
      AND m.is_active = TRUE
      AND (pm.start_date <= now() OR pm.start_date IS NULL)
      AND (pm.end_date >= now() OR pm.end_date IS NULL)
 
-- added 2022-05-20:
      AND (
      ((M.container ->> 'numerator_unit' = $mr.container_dosage.code) AND
      (M.container ->> 'numerator_value' <>  $mr.container_dosage.value)) OR
           ( ($mr.dosage_container.code is NULL) AND ($mr.container_dosage.value is NULL) )
        )
      AND (M.max_request_dosage >= $.medication_qty or M.max_request_dosage is null)

Prepare & return response data structure

...

Expand
titleResponse example 200
Code Block
{
  "meta": {
    "code": 200,
    "url": "https://example.com/resource",
    "type": "object",
    "request_id": "req-adasdoijasdojsda"
  },
  "data": [
    {
      "program_id": "59781de0-2e64-4359-b716-bcc05a32c10f",
      "program_name": "Програма \"Доступні ліки\"",
      "status": "INVALID",
      "rejection_reason": "Innm not on the list of approved innms for program 'DOSTUPNI LIKI' !",
      "participants": [
        {
          "id": "0f2fbf93-3041-4c0d-a3cf-ff558c861df8",
          "medication_id": "59781de0-2e64-4359-b716-bcc05a32c10f",
          "medication_name": "Амлодипін-КВ",
          "form": "PILL",
          "manufacturer": {
            "name": "ПАТ \"Київський вітамінний завод\"",
            "country": "UA"
          },
          "reimbursement_amount": 15,
          "wholesale_price": 25.14,
          "consumer_price": 34.03,
          "reimbursement_daily_dosage": 1.4438,
          "estimated_payment_amount": 5.15,
          "container_dosage": {
            "numerator_unit": "PILL",
            "numerator_value": 1,
            "denumerator_unit": "PILL",
            "denumerator_value": 1
          },
          "package_min_qty": 20,
          "package_qty": 20,
          "start_date": "2019-01-01",
          "end_date": "2019-06-30",
          "registry_number": "REG-1111"
        }
      ]
    }
  ]
}

Post-processing processes

...

HTTP status codes

Page Properties

HTTP status code

Message

What caused the error

200

Response

 

401

Invalid access token

 

404

Not found medication request in DB with this ID

409

  • Invalid status Medication request for qualify action!

  • Invalid care plan status

  • Care plan expired

  • Invalid activity status

  • Division is not active

  • Division does not belong to user's legal entity

  • Division is not verified in DLS

422

  1. Error

  2. Not found medical program in DB with this ID

  1. Response validation failed

Backward compatibility

...