Versions Compared

Key

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

...

 

Specification

Apiary

Purpose

This WS is designed to create Request fo Medication request

There are two types of medication request:

  • plan - The request represents an intention to ensure something occurs without providing an authorization for others to act. Medication request with type plan can't be dispensed and only provide the instruction to administer the medicine. 

  • order - The request represents a request/demand and authorization for action. Medication request with type order can be dispensed

Authorize

  1. Verify the validity of access token

  2. Check user scope (scope = 'medication_request_request:write') in order to perform this action

    1. In case error - generate 401 response

Validate request (JSON schema)

Validate request using JSON schema. 

  1. in case of error return 422 error with msg ("required property %{property} was not present")

Validate employee

Purpose validation: Validation of an employee for the possibility of creating a medication request.

  1. Invoke employee_id from request

  2. Validate employee

    1. Validate that exists

      1. in case invalid return 422 error with msg ("Employee not found")

    2. Validate that $.employees.status == APPROVED

      1. in case invalid return 409 error with msg ("Employee is not active")

    3. Validate that $.employees.legal_entity_id == client_id from token

      1. in case invalid return 422 error with msg ("Employee does not belong to legal entity from token")

    4. Validate that $.employees.employee_type == <employee_type>

      1. in case medical_program_id present in request validate medical_program_settings.skip_employee_validation == false (or absent)

        1. validate <employee_type>

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

            1. validate that employee_type present in employee_types_for_create_medication_request variable

              1. in case invalid return 422 error with msg ("Employee type can't create medication request with medical program from request") 

              2. in case employee_type = DOCTOR

                1. get $.declarations by employee_id, person_id, status=ACTIVE or check MEDICATION_REQUEST_DECLARATION_VERIFY param (which allow to create medication request for any doctor from LE where person have declaration)

                  1. if not found - return 422 error  (message: "Employee must have an active declaration with the patient to create medication request!")

              3. in case employee_type = SPECIALIST

                1. get $.employees.speciality.speciality(speciality_officio == true)

                2. validate that speciality present in$.medical_programs.medical_program_setting.speciality_types_allowed variable

                  1. in case invalid return 422 error with msg ("Employee's specialty doesn't allow create medication request with medical program from request") 

              4. in case employee_type = <XXX>

                1. in case invalid return 422 error with msg ("Employee type can't create medication request with medical program from request")

      2. in case medical_program_settings.skip_employee_validation == true or there is no medical_program_id in the request, any user who has a scope can create medication request

Validate division

Purpose validation: Validation of division for the possibility of creating a medication request.

  1. Invoke Get division details

  2. Validate division_id - division_id exists

    • in case invalid return 422 error with msg ("Division not found")

  3. Validate Response $.data.status==ACTIVE

    1. if not found - return 422 error (message: "Only employee of active divisions can create medication request!")

  4. Division should be active and refers to current legal_entity

    • is_active = true

    • status = 'ACTIVE'

    • division.legal_entity_id = client_id (context)

Validate legal entity

Purpose validation: Validation of legal entity for the possibility of creating a medication request.

  1. Get client_id from token

  2. Validate client_id=legal_entity_id

    1. check that legal_entity exist

      1. in case invalid return 422 error with msg (422 Legal entity not found)

    2. check that legal_entities.status == ACTIVE

      1. in case invalid return 422 error with msg ("Only active legal entity can provide medication request")

Validate person

Purpose validation: Validation of person for the possibility of creating a medication request.

  1. Invoke Get patient by ID

  2. Validate person_id - mpi_id exists

    • in case invalid return 422 (422 Person not found)

  3. Save temporary variables from: $.data.authentication_methods

  4. Validate Response $.data.is_active==TRUE 

    1. if not found - return 422 error (message: "Only for active MPI record can be created medication request!")

Validate dates

  1. created_at - similar to assertion date in FHIR -> Actual date medication request being created

  2. inserted_at - date when Medication request was registered in E-Health

  3. dispence_valid_from - Used for dispense validation. As for now equals Created at.

  4. dispense_valid_to - Dispense valid from + medication_dispense_period parameter value. Implements dispense expiration period.

Purpose validation:  Must be: ended_at >= started_at >= created_at

  1. Validate that created_at, started_at, ended_at in date format

    1. in case invalid return 422 with msg ("expected \"%{actual}\" to be a valid ISO 8601 date")

  2. Validate ended_at >= started_at

    1. if invalid - return 422 error  (message: "Ended date must be >= Started date!")

  3. Validate started_at` >= created_at

    1. if invalid - return 422 error  (message: "Started date must be >= Created date!")

  4. Validate started_at >= current_date()

    1. if invalid - return 422 error  (message: "Started date must be >= current date!")

  5. Validate created_at >= current_date() - mrr_delay_input

    1. if invalid - return 422 error  (message: "Create date must be = current date!")

  6. Validate started_at regarding frequency of receiving drugs

    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: PreQualify Medication request#2.Checkabsencethesamemedicationsfortheprograms

        2. in case skip_mnn_in_treatment_period == TRUE

          1. skip validating frequency of receiving drugs

  7. Validate created_at regarding frequency of receiving drugs

    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: PreQualify Medication request#2.Checkabsencethesamemedicationsfortheprograms

        2. in case skip_mnn_in_treatment_period == TRUE

          1. skip validating frequency of receiving drugs

  8. Validate period length (ended_at - started_at):

    1. If medical program has been submitted:

      1. validate request according to logic: PreQualify Medication request: 7. Validate period

    2. else:

      1. Check that medication request period less than or equal to MEDICATION_REQUEST_MAX_PERIOD_DAY parameter from charts

        1. in case of error - return 409 “Period length exceeds default maximum value“

Validate medication

Purpose validation: Check FK, status `is_active`=TRUE, type = INNM_DOSAGE

  1. Invoke Get INNM Dosage by ID

  2. Validate medication_id - medication_id exists

    1. in case of error return 422 ("Medication not found")

  3. Validate Response code == 200

    1. if invalid - return 422 error (message: "Only medication with type `INNM_DOSAGE` can be use for created medication request!")\

  4. Validate Response $.is_active==TRUE

    1. if not found - return 422 error (message: "Only active innm_dosage can be use for created medication request!")

Validate context

  1. Validate "context" is present in the request

    1. in case of error return 422 ("required property context was not present")

  2. Validate "context" is an active (not entered-in-error) entity from corresponding dictionary, that belongs to the current patient

    1. Validate there is an entity in collection $.data.context.identifier.type.coding[0].code with id == $.data.context.identifier.value that belongs to the current patient

      1.  in case of error 409 "{$.data.context.identifier.type.coding[*].code} not found"

    2. Validate that entity is not in status "entered-in-error"

      1. in case of error 409 "Entity in status "entered-in-error" can not be referenced"

Validate dosage instruction

Each non-empty attribute must be valid and reference to appropriate dictionary or object

  1. Sequence must be unique within dosage instruction array

    1. in case of error  return (422, "Sequence must be unique")

  2. Additional instruction must refer to a valid dictionary

    1. $.dosage_instruction[*].additional_instruction.coding[*].system == "eHealth/SNOMED/additional_dosage_instructions"

    2. $.dosage_instruction[*].additional_instruction.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/additional_dosage_instructions"

      1. in case of error return 409 "Incorrect additional instruction"

  3. Site must refer to a valid dictionary

    1. $.dosage_instruction[*].site.coding[*].system == "eHealth/SNOMED/anatomical_structure_administration_site_codes"

    2. $.dosage_instruction[*].site.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/anatomical_structure_administration_site_codes"

      1. in case of error return 409 "Incorrect site"

  4. Route must refer to a valid dictionary

    1. $.dosage_instruction[*].route.coding[*].system == "eHealth/SNOMED/route_codes"

    2. $.dosage_instruction[*].route.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/route_codes"

      1. in case of error return 409 "Incorrect route"

  5. Method must refer to a valid dictionary

    1. $.dosage_instruction[*].method.coding[*].system == "eHealth/SNOMED/administration_methods"

    2. $.dosage_instruction[*].method.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/administration_methods"

      1. in case of error return 409 "Incorrect method"

  6. Dose and rate type must refer to a valid dictionary

    1. $.dosage_instruction[*].dose_and_rate.type.coding[*].system == "eHealth/SNOMED/dose_and_rate"

    2. $.dosage_instruction[*].dose_and_rate.type.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/dose_and_rate"

      1. in case of error return 409 "Incorrect dose and rate type"

Validate based_on

If submitted, check field has array with two values of Reference type: one is valid Care plan resource, another - Activity resource.

  1. Verify Care plan:

    1. It should belong to the same person as set in MRR

      1. in case of error return 422 with msg ("Care plan not found")

    2. It should be in active status

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

  2. Verify submitted Activity:

    1. It belongs to the Care plan.

      1. in case of error return 422 with msg ("Activity not found")

    2. It has activity.detail.kind=medication_request;

      1. in case of error return 422 with msg ("Invalid activity kind")

    3. activity.detail.product_reference=medication_id.

      1. in case of error return 422 with msg ("Invalid activity product reference")

    4. It has scheduled, in_progress status

    5. If it has quantity then calculate remaining quantity:

      1. select all MRR in status NEW which based on current activity

      2. select all MR in statuses ACTIVE, COMPLETED based on current activity

      3. calculate reserved at the moment medication quantity as sum of medication_qty in the filtered MRR  and MR list, including medication_qty from current MRR

      4. calculate remaining quantity by subtracting reserved quantity from activity quantity

      5. Check remaining quantity is greater then or equal to zero 

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

    6. check that medical_program_id equal to $.activity[].program

      1. in case of error return 422 with msg ("Medical program from activity should be equal to medical program from request")

  3. Verify activity period: 

    1. If it has scheduled_timing:

      1. if bounds_period.end defined then check it greater than current date or equal.

    2. If it has scheduled_period:

      1. if scheduled_period.end defined then check it greater than current date or equal.

  4. Validate started_at/ended_at of Medication request Request: 

    1. if care plan activity has detail.scheduled_timing.repeat.bounds_period - validate started_at/ended_at within bounds_period

    2. if care plan activity has detail.scheduled_period - validate started_at/ended_at within scheduled_period

    3. else - validate started_at/ended_at within care_plan.period

      1. in the case of started_at/ended_at is not within care_plan.period return 422 with msg  ("Invalid care plan period")

Validate medical program

  1. Validate medical_program_id is present in the request

    1. in case of error return 422 ("required property medical_program_id was not present")

  2. Validate medical_program_id - medical_program_id exists

    1. in case of error return 422 ("Medical program not found")

  3. Validate context with encounter is present in the request

    1. in case of error return 422 ("Context with encounter is required as medical program is present in the request")

  4. Validate medical_programs.medical_program_setting parameters

    1. check if care_plan_required == true then the request should contain a based_on with care plan and activity that contains the same medical program

      1. in case of error return 422 with msg ("Care plan and activity with the same medical program should be present in request")

    2. If there is CONDITIONS_ICD10_AM_ALLOWED parameter, then:

      1. Check if primary diagnosis from the encounter in context has code from eHealth/ICD10_AM/condition_codes dictionary

        1. Check diagnosis code in CONDITIONS_ICD10_AM_ALLOWED

          1. in case of error - return 422 “Encounter in context has no primary diagnosis allowed for the medical program“

    3. If there is CONDITIONS_ICPC2_ALLOWED parameter, then:

      1. Check if primary diagnosis from the encounter in context has code from eHealth/ICPC2/condition_codes dictionary

        1. Check diagnosis code in CONDITIONS_ICPC2_ALLOWED

          1. in case of error - return 422 “Encounter in context has no primary diagnosis allowed for the medical program“

Validate multiplicity & medication request allowed for participants

Purpose validation:  Request quantity must have multiplicity package_min_qty for linked medications.  Result (Mod or % operator) must = 0 . 
Also if present Medical_program - must exists medications with `medication_request_allowed`== TRUE for participants.

If `$.medical_program_id` present in payload (non null) - Check exist (IF EXIST()) medication & participant 

if not exist - return 404 error (message: "Not found any medications allowed for create medication request for this medical program!")

Code Block
SELECT *
FROM medications MI											-- 2nd level: Medication - type = INNM_DOSAGE
	INNER JOIN ingredients I
		ON I.medication_child_id = MI.id
			AND I.is_primary =TRUE
    INNER JOIN medications MED                              -- 3rd level: Medication - type = BRAND
        ON MED.type == BRAND
            AND I.parent_id = MED.id
			AND MED.is_active == TRUE
	INNER JOIN program_medications MP
		ON MP.medical_program_id == `DOSTUPNI LIKI`
			MED.id = MP.medication_id
            AND MP.is_active == TRUE
            AND MP.medication_request_allowed == TRUE
WHERE MI.id == $.medication_id
	AND MI.type == INNM_DOSAGE
	AND MI.is_active == TRUE

Check exist (IF EXIST()) medication & get combinations of manufacture

if not exist - return 404 error (message: "Not found any active linked medication for this innm dosage!")

Code Block
SELECT DISTINCT MED.package_min_qty
FROM medications MI											-- 2nd level: Medication - type = INNM_DOSAGE
	INNER JOIN ingredients I
		ON I.medication_child_id = MI.id
			AND I.is_primary =TRUE
    INNER JOIN medications MED                              -- 3rd level: Medication - type = BRAND
        ON MED.type == BRAND
            AND I.parent_id = MED.id
			AND MED.is_active == TRUE
WHERE MI.id == $.medication_id
	AND MI.type == INNM_DOSAGE
	AND MI.is_active == TRUE

...

Vaildate multiplicity (Mod == 0) for all elements in result (`$.medication_qty` Mod `MED.package_min_qty` == 0)

  1. if all result of Mod operator  - NOT 0 - return 409 eror (message: "The amount of medications in medication request must be divisible to package minimum quantity") 

Generate number & verification_code for Medication request

Generate human readable number for receipt (See specs)

Code Block
Structure number XXXX-1234-5678-9012-345-C , where:
- XXXX - series: numbers + only some letters (A, E, H, K, M, P, T, X)
- 1234-5678-9012-345 - randomly generated numbers
- C - checksum: Should be calculated using the Damn algorithm or Verhoeff algorithm
After new Request number was generated we should check that it is unique in the DB (entity: medication_request + medication_request_request

Generate verification_code for MPI.person_authentication_methods == OTP or OFFLINE

Code Block
Structure code 1234, where:
- 1234 - randomly generated numbers 

Create Medication request Request

  1. set:

    1. dispense_valid_from = created_at

    2. dispensed_valid_to = dispensed_valid_from + dispense_period

  2. Fill 'data' structure for Response & save in IL.medication_request_requests

Generate content for response

  • Generate data structure with Responce WS structure

    • Set IL.medication_request_requests this structure

  • in case if response is VALID enrich response with urgent_data:

    • get authetification_method by person_id and return masked number (in case if any)

...

Table of Contents

Purpose

This WS is designed to create Request for Medication request

There are two types of medication request:

  • plan - The request represents an intention to ensure something occurs without providing an authorization for others to act. Medication request with type plan can't be dispensed and only provide the instruction to administer the medicine. 

  • order - The request represents a request/demand and authorization for action. Medication request with type order can be dispensed

Specification

Page Properties

Link

https://ehealthmisapi1.docs.apiary.io/#reference/public.-reimbursement/medication-request-requests/create-medication-request-request

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

Resource

/api/medication_request_requests

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

Scope

medication_request_request:write

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

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

Logic

Технічний опис бізнес-процесу виписування рецепту в ЕСОЗ (загальний процес для усіх рецептурних ЛЗ, в т.ч. і тих, які підлягають реімбурсації)

Процеси роботи з випискою електронних рецептів

Preconditions

  1. Only authenticated and authorized users with appropriate scope can Create Medication Request Request (MRR)

  2. Patient should be stored in hashed form according to security requirements.

Input parameters

ATTRIBUTES - see on Apiary

Request structure

See on Apiary

Example:

Expand
titleRequest example
Code Block
{
  "medication_request_request": {
    "person_id": "585044f5-1272-4bca-8d41-8440eefe7d26",
    "employee_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "division_id": "881d6dee-dd3d-43f3-8983-922354c0e6ce",
    "created_at": "2017-08-17",
    "started_at": "2017-08-17",
    "ended_at": "2017-09-16",
    "medication_id": "1349a693-4db1-4a3f-9ac6-8c2f9e541982",
    "medication_qty": 10.34,
    "medical_program_id": "59781de0-2e64-4359-b716-bcc05a32c10f",
    "intent": "plan",
    "category": "community",
    "based_on": [
      {
        "identifier": {
          "type": {
            "coding": [
              {
                "system": "eHealth/resources",
                "code": "care_plan"
              }
            ]
          },
          "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
        }
      },
      {
        "identifier": {
          "type": {
            "coding": [
              {
                "system": "eHealth/resources",
                "code": "activity"
              }
            ]
          },
          "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
        }
      }
    ],
    "context": {
      "identifier": {
        "type": {
          "coding": [
            {
              "system": "eHealth/resources",
              "code": "encounter"
            }
          ]
        },
        "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
      }
    },
    "dosage_instruction": [
      {
        "sequence": 1,
        "text": "0.25mg PO every 6-12 hours as needed for menses from Jan 15-20, 2015.  Do not exceed more than 4mg per day",
        "additional_instruction": [
          {
            "coding": [
              {
                "system": "eHealth/SNOMED/additional_dosage_instructions",
                "code": "311504000"
              }
            ]
          }
        ],
        "patient_instruction": "0.25mg PO every 6-12 hours as needed for menses from Jan 15-20, 2015.  Do not exceed more than 4mg per day",
        "timing": {
          "event": [
            "2017-04-20T19:14:13Z"
          ],
          "repeat": {
            "bounds_duration": {
              "value": 10,
              "unit": "days",
              "system": "eHealth/ucum/units",
              "code": "d"
            },
            "count": 2,
            "count_max": 4,
            "duration": 4,
            "duration_max": 6,
            "duration_unit": "d",
            "frequency": 1,
            "frequency_max": 2,
            "period": 4,
            "period_max": 6,
            "period_unit": "d",
            "day_of_week": [
              "mon"
            ],
            "time_of_day": [
              "2017-04-20T19:14:13Z"
            ],
            "when": [
              "WAKE"
            ],
            "offset": 4
          },
          "code": {
            "coding": [
              {
                "system": "TIMING_ABBREVIATIONS",
                "code": "patient"
              }
            ]
          }
        },
        "as_needed_boolean": true,
        "site": {
          "coding": [
            {
              "system": "eHealth/SNOMED/anatomical_structure_administration_site_codes",
              "code": "344001"
            }
          ]
        },
        "route": {
          "coding": [
            {
              "system": "eHealth/SNOMED/route_codes",
              "code": "46713006"
            }
          ]
        },
        "method": {
          "coding": [
            {
              "system": "eHealth/SNOMED/administration_methods",
              "code": "419747000"
            }
          ]
        },
        "dose_and_rate": {
          "type": {
            "coding": [
              {
                "system": "eHealth/dose_and_rate",
                "code": "'ordered'"
              }
            ]
          },
          "dose_range": {
            "low": {
              "value": 0,
              "unit": "mg",
              "system": "eHealth/ucum/units",
              "code": "mg"
            },
            "high": {
              "value": 0,
              "unit": "mg",
              "system": "eHealth/ucum/units",
              "code": "mg"
            }
          },
          "rate_ratio": {
            "numerator": {
              "value": 0,
              "unit": "mg",
              "system": "eHealth/ucum/units",
              "code": "mg"
            },
            "denominator": {
              "value": 0,
              "unit": "mg",
              "system": "eHealth/ucum/units",
              "code": "mg"
            }
          }
        },
        "max_dose_per_period": {
          "numerator": {
            "value": 0,
            "unit": "mg",
            "system": "eHealth/ucum/units",
            "code": "mg"
          },
          "denominator": {
            "value": 0,
            "unit": "mg",
            "system": "eHealth/ucum/units",
            "code": "mg"
          }
        },
        "max_dose_per_administration": {
          "value": 0,
          "unit": "mg",
          "system": "eHealth/ucum/units",
          "code": "mg"
        },
        "max_dose_per_lifetime": {
          "value": 0,
          "unit": "mg",
          "system": "eHealth/ucum/units",
          "code": "mg"
        }
      }
    ],
    "priority": "routine",
    "prior_prescription": {
      "identifier": {
        "type": {
          "coding": [
            {
              "system": "eHealth/resources",
              "code": "medication_request"
            }
          ]
        },
        "value": "9183a36b-4d45-4244-9339-63d81cd08d9c"
      }
    },
    "container_dosage": {
      "system": "MEDICATION_UNIT",
      "code": "ML",
      "value": 4
    }
  }
}

Authorize

  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 scopes in order to perform this action (scope = 'medication_request_request:write')

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

  4. If BLOCK_UNVERIFIED_PARTY_USERS is true, then check party's data match following condition: verification_status != NOT_VERIFIED or (verification_status = NOT_VERIFIED and updated_at <= current_date - UNVERIFIED_PARTY_PERIOD_DAYS_ALLOWED):

    • in case not match - return 403 ("Access denied. Party is not verified")

Headers

Content-Type:application/json

Authorization:Bearer c2778f3064753ea70de870a53795f5c9

Validate request

  1. Validate request according to JSON Schema

    1. Return 422 with list of validation errors in case validation fails.

Request data validation

Validate container_dosage field

$.container_dosage - volume of a medication’s primary container, which is requested by a doctor or issuer of a medication request, to be dispensed to patient.

  1. Validate $.container_dosage field by schemata

    1. $.container_dosage.code and $.container_dosage.value should be both filled

      1. in case of error return 422 error ("required property %{property} was not present")

    2. $.container_dosage.system should be “MEDICATION_UNIT”

      1. in case of error return 422 error ("value is not allowed in enum")

    3. if $.container_dosage is filled then $.container_dosage.unit should be checked with the MEDICATION_UNIT dictionary by $.container_dosage.code as a key.

      1. in case of error return 422 error ("value is not allowed in enum")

  2. Check if there is at list one record of Brand with requested primary container volume
    a. if not exist - return 404 error (message: "Not found any appropriate medication with such container parameters")

Validate priority

  1. Check by schemata if $.priority is filled with the value of MEDICATION_REQUEST_PRIORITY dictionary

    1. in case of error return 422 error ("value is not allowed in enum")

Validate prior_prescription

  1. Check that $.prior_prescription is UUID, exists and belongs to this person:

    1. is_active = true, and the same person. 

      1. in case of error - return 422 (message: "Prior prescription is not found")

Validate employee

Validation of an employee for the possibility of creating a medication request.

  1. Invoke employee_id from request

  2. Validate employee

    1. Validate that exists

      1. in case invalid return 422 error with msg ("Employee not found")

    2. Validate that $.employees.status == APPROVED

      1. in case invalid return 409 error with msg ("Employee is not active")

    3. Validate that $.employees.legal_entity_id == client_id from token

      1. in case invalid return 422 error with msg ("Employee does not belong to legal entity from token")

    4. If medical program has medical_program_settings.skip_employee_validation == false (or absent), then validate <employee_type>:

      1. validate if employee_type is present in medical_program_settings employee_types_for_create_medication_request employee_types_to_create_requestvariable

        1. in case invalid return 422 error with msg ("Employee type can't create medication request with medical program from request") 

        2. in case employee_type = DOCTOR

          1. if variable skip_medication_request_employee_declaration_verify skip_request_employee_declaration_verify = false or null/absent

            1. then: get $.declarations by employee_id, person_id, status=ACTIVE

              1. if not found - return 422 error  "Only doctors with an active declaration with the patient can create medication request with medical program from request!"

            2. else skip declaration verification on employee level (if true)

          2. if variable skip_medication_request_legal_entity_declaration_verify skip_request_legal_entity_declaration_verify = false or null/absent

            1. then: get $.declarations by employee's legal_entity_id, person_id, status=ACTIVE

              1. if not found - return 422 error "Only legal entity with an active declaration with the patient can create medication request with medical program from request!"

            2. else skip declaration verification on legal entity level (if true)

          3. else if both are true - skip declaration verification at all

        3. in case employee_type = SPECIALIST

          1. get $.employees.speciality.speciality(speciality_officio == true)

          2. validate that speciality present in $.medical_programs.medical_program_setting.speciality_types_allowed variable

            1. in case invalid return 422 error with msg ("Employee's specialty doesn't allow create medication request with medical program from request") 

        4. in case employee_type = MED_COORDINATOR

          1. skip validation that speciality present in $.medical_programs.medical_program_setting.speciality_types_allowed variable

    5. If medical program has medical_program_settings with medical_program_settings.skip_employee_validation == true any user who has a scope can create medication request

Validate division

Validation of the division for the possibility of creating a medication request.

  1. Invoke Get division details

  2. Validate division_id - division_id exists

    1. in case invalid return 422 error with msg ("Division not found")

  3. Validate Response $.data.status==ACTIVE

    1. if not found - return 422 error (message: "Only employee of active divisions can create medication request!")

  4. Division should be active and refers to current legal_entity

    1. is_active = true

    2. status = 'ACTIVE'

    3. division.legal_entity_id = client_id (context)

Validate legal entity

Validation of the legal entity for the possibility of creating a medication request.

  1. Get client_id from token

  2. Validate client_id=legal_entity_id

    1. check that legal_entity exist

      1. in case invalid return 422 error with msg (422 Legal entity not found)

    2. check that legal_entities.status == ACTIVE

      1. in case invalid return 422 error with msg ("Only active legal entity can provide medication request")

    3. check legal entity type in chart parameter MEDICATION_REQUEST_REQUEST_LEGAL_ENTITY_TYPES

      1. in case invalid return 409 error with msg (“Invalid legal entity type“)

Validate person

Validation of person for the possibility of creating a medication request.

  1. Invoke Get patient by ID

  2. Validate person_id - mpi_id exists

    1. in case invalid return 422 (422 Person not found)

  3. Save temporary variables from: $.data.authentication_methods

  4. Validate Response $.data.is_active==TRUE

    1. if not found - return 422 error (message: "Only for active MPI record can be created medication request!")

  5. Validate person's verification status:

    1. If MRR has based_on with valid activity, then skip this validation.

    2. Else check patient's verification_status is not equal to NOT_VERIFIED.

      1. in case NOT_VERIFIED - return error 409, "Patient is not verified"

Validate dates

  1. created_at - similar to assertion date in FHIR -> Actual date medication request being created

  2. inserted_at - date when Medication request was registered in E-Health

  3. started_at/ended_at - Treatment period. Cannot be less than MR expiration period. Defined by doctor.

  4. dispence_valid_from - Used for dispense validation. As for now equals Created at.

  5. dispense_valid_to -  Implements dispense expiration period. If MR has medical program setting with not empty parameter medication_dispense_period_day dispense_period_day, then dispence_valid_from + medication_dispense_period_day dispense_period_day, else Dispense valid from + medication_dispense_period global parameter value.

Purpose validation:  Must be: ended_at >= started_at >= created_at

  1. Validate that created_at, started_at, ended_at in date format

    1. in case invalid return 422 with msg ("expected \"%{actual}\" to be a valid ISO 8601 date")

  2. Validate ended_at >= started_at

    1. if invalid - return 422 error  (message: "Ended date must be >= Started date!")

  3. Validate started_at >= created_at, but not greater than (created_at + MEDICATION_REQUEST_REQUEST_EXTENDED_LIMIT_STARTED_AT_DAYS)

    1. if invalid - return 422 error  (message: "The start date should be equal to or greater than the creation date, but the difference between them should be not exceed {{MEDICATION_REQUEST_REQUEST_EXTENDED_LIMIT_STARTED_AT_DAYS}} day(s).")

  4. Validate started_at >= current_date()

    1. if invalid - return 422 error  (message: "Started date must be >= current date!")

  5. Validate created_at >= current_date() - MEDICATION_REQUEST_REQUEST_DELAY_INPUT chart param

    1. if invalid - return 422 error  (message: "Create date must be >= Current date - MRR delay input!")

  6. Validate started_at regarding frequency of receiving drugs

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

      1. validate skip_mnn_in_treatment_period skip_treatment_period variable

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

          1. validate request according to logic: PreQualify Medication request: 2. Check absence the same medications for the programs

        2. in case skip_mnn_in_treatment_period skip_treatment_period == TRUE

          1. skip validating frequency of receiving drugs

  7. Validate created_at regarding frequency of receiving drugs

    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: PreQualify Medication request: 2. Check absence the same medications for the programs

        2. in case skip_mnn_in_treatment_period == TRUE

          1. skip validating frequency of receiving drugs

  8. Validate period length (ended_at - started_at):

    1. If medical program has been submitted:

      1. validate request according to logic: PreQualify Medication request: 7. Validate period

    2. else:

      1. Check that medication request period less than or equal to MEDICATION_REQUEST_MAX_PERIOD_DAY request_max_period_dayparameter from charts

        1. in case of error - return 409 “Period length exceeds default maximum value“ 

Validate medication

Check FK, status `is_active`=TRUE, type = INNM_DOSAGE

  1. Invoke Get INNM Dosage by ID

  2. Validate medication_id - medication_id exists

    1. in case of error return 422 ("Medication not found")

  3. Validate Response code == 200

    1. if invalid - return 422 error (message: "Only medication with type `INNM_DOSAGE` can be use for created medication request!")\

  4. Validate Response $.is_active==TRUE

    1. if not found - return 422 error (message: "Only active innm_dosage can be use for created medication request!")

Validate context

  1. Validate "context" is present in the request

    1. in case of error return 422 ("required property context was not present")

  2. Validate "context" is an active (not entered-in-error) entity from corresponding dictionary, that belongs to the current patient

    1. Validate there is an entity in collection $.data.context.identifier.type.coding[0].code with id == $.data.context.identifier.value that belongs to the current patient

      1.  in case of error 409 "{$.data.context.identifier.type.coding[*].code} not found"

    2. Validate that entity is not in status "entered-in-error"

      1. in case of error 409 "Entity in status "entered-in-error" can not be referenced"

    3. Validate that related episode exist

      1. in case of error 409 "Entity without related episode can not be referenced"

Validate dosage instruction

Each non-empty attribute must be valid and reference to appropriate dictionary or object

  1. Sequence must be unique within dosage instruction array

    1. in case of error  return (422, "Sequence must be unique")

  2. Additional instruction must refer to a valid dictionary

    1. $.dosage_instruction[*].additional_instruction.coding[*].system == "eHealth/SNOMED/additional_dosage_instructions"

    2. $.dosage_instruction[*].additional_instruction.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/additional_dosage_instructions"

      1. in case of error return 409 "Incorrect additional instruction"

  3. Site must refer to a valid dictionary

    1. $.dosage_instruction[*].site.coding[*].system == "eHealth/SNOMED/anatomical_structure_administration_site_codes"

    2. $.dosage_instruction[*].site.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/anatomical_structure_administration_site_codes"

      1. in case of error return 409 "Incorrect site"

  4. Route must refer to a valid dictionary

    1. $.dosage_instruction[*].route.coding[*].system == "eHealth/SNOMED/route_codes"

    2. $.dosage_instruction[*].route.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/route_codes"

      1. in case of error return 409 "Incorrect route"

  5. Method must refer to a valid dictionary

    1. $.dosage_instruction[*].method.coding[*].system == "eHealth/SNOMED/administration_methods"

    2. $.dosage_instruction[*].method.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/administration_methods"

      1. in case of error return 409 "Incorrect method"

  6. Dose and rate type must refer to a valid dictionary

    1. $.dosage_instruction[*].dose_and_rate.type.coding[*].system == "eHealth/SNOMED/dose_and_rate"

    2. $.dosage_instruction[*].dose_and_rate.type.coding[*].code is a valid entry in dictionary "eHealth/SNOMED/dose_and_rate"

      1. in case of error return 409 "Incorrect dose and rate type"

Validate based_on

If submitted, check field has array with two values of Reference type: one is valid Care plan resource, another - Activity resource.

  1. Verify Care plan:

    1. It should belong to the same person as set in MRR

      1. in case of error return 422 with msg ("Care plan not found")

    2. It should be in active status

  2. Verify submitted Activity:

    1. It belongs to the Care plan.

      1. in case of error return 422 with msg ("Activity not found")

    2. It has activity.detail.kind=medication_request; activity.detail.product_reference=medication_id.

      1. in case of error return 422 with msg ("Invalid activity kind")

    3. It has scheduled, in_progress status.

      1. in case of error return 422 with msg ("Invalid activity status")

    4. if it has quantity then calculate remaining quantity:

      1. validate $.activity.details.remaining_quantity_type:

        1. if $.activity.details.remaining_quantity_type =for_request than:

          1. select all MRR in status NEW which based on current activity

          2. select all MR in statuses ACTIVE based on current activity

          3. select all MD (medication dispenses) in status PROCESSED related to the Medication requests which are in status COMPLETE, REJECTED, EXPIRED

          4. calculate:

            1. reserved_qty as sum of medication_qty in the filtered MRR  and MR list

            2. dispensed_qty as sum of medication_qty in the filtered MD list

            3. current_qty as medication_qty from current MRR

          5. calculate remaining quantity by subtracting reserved_quantity, dispensed_qty, current_qty from activity quantity

        2. if $.activity.details.remaining_quantity_type = for_use than:

          1. select all MRR in status NEW which based on current activity

          2. select all MR in statuses ACTIVE, COMPLETED based on current activity

          3. calculate reserved at the moment medication quantity as sum of medication_qty in the filtered MRR  and MR list, including medication_qty from current MRR

          4. calculate remaining quantity by subtracting reserved quantity from activity quantity

      2. Check remaining quantity is greater then or equal to zero

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

    5. check that medical_program_id equal to $.activity[].program

      1. in case of error return 422 with msg ("Medical program from activity should be equal to medical program from request")

  3. Validate started_at/ended_at of Medication request Request: 

    1. if care plan activity has detail.scheduled_timing.repeat.bounds_period - validate started_at/ended_at within bounds_period

    2. if care plan activity has detail.scheduled_period - validate started_at/ended_at within scheduled_period

    3. else - validate started_at/ended_at crossing within care_plan.period

      1. in the case of started_at/ended_at is not within care_plan.period return 422 with msg  ("Invalid care plan period")

Validate medical program

  1. Validate medical_program_id is present in the request

    1. in case of error return 422 ("required property medical_program_id was not present")

  2. Validate medical_program_id - medical_program_id exists

    1. in case of error return 422 ("Medical program not found")

  3. Validate medical_programs.medication_request_allowed parameter

    1. check if medication_request_allowed == true

      1. in case of error return 422 with msg ("Forbidden to create medication request for this medical program!")

  4. Validate medical_programs.medical_program_setting parameters

    1. check if care_plan_required == true then the request should contain a based_on with care plan and activity that contains the same medical program

      1. in case of error return 422 with msg ("Care plan and activity with the same medical program should be present in request")

    2. If there is conditions_icd10_am_allowed parameter, then:

      1. Check if primary diagnosis from the encounter in context has code from eHealth/ICD10_AM/condition_codes dictionary

        1. Check diagnosis code in conditions_icd10_am_allowed

          1. in case of error - return 422 “Encounter in context has no primary diagnosis allowed for the medical program“

    3. If there is conditions_icpc2_allowed parameter, then:

      1. Check if primary diagnosis from the encounter in context has code from eHealth/ICPC2/condition_codes dictionary

        1. Check diagnosis code in conditions_icpc2_allowed

          1. in case of error - return 422 “Encounter in context has no primary diagnosis allowed for the medical program“.

    4. if skip_medication_request_employee_declaration_verify = false or null/absent

      1. then: get $.declarations by employee_id, person_id, status=ACTIVE

        1. if not found - return 422 error  "Only doctors with an active declaration with the patient can create medication request!"

      2. else skip declaration verification on employee level (if true).

    5. if skip_medication_request_legal_entity_declaration_verify = false or null/absent

      1. then: get $.declarations by employee's legal_entity_id, person_id, status=ACTIVE

        1. if not found - return 422 error "Only legal entity with an active declaration with the patient can create medication request!"

      2. else skip declaration verification on legal entity level (if true).

  5. If medical program has funding_source = LOCAL , then invoke validation described at PreQualify Medication request request | 11.-Check-provision-for-a-programs

Validate multiplicity & medication request allowed for participants

  1. Perform validation as described at https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/583405343/PreQualify+Medication+Request+Request#1.-Check-INNM-complience-for-the-programs .

  2. Perform validation as described at

PreQalify Medication Request: Check absence the same medications for the programs.

Parameters that are used when processing the request

Configuration parameters

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

Dictionaries

  • MEDICATION_REQUEST_INTENT

  • MEDICATION_REQUEST_CATEGORY

  • MEDICATION_REQUEST_PRIORITY

  • eHealth/SNOMED/additional_dosage_instructions

  • eHealth/SNOMED/anatomical_structure_administration_site_codes

  • eHealth/SNOMED/route_codes

  • eHealth/SNOMED/administration_methods

  • eHealth/SNOMED/dose_and_rate

  • eHealth/ICD10_AM/condition_codes

  • eHealth/ICPC2/condition_codes

Processing

Generate number & verification_code for Medication request

  1. Generate human readable number for receipt (See specs)

    Code Block
    Structure number XXXX-XXXX-XXXX-XXXX, where:
    - XXXX - series: numbers + some letters (A, E, H, K, M, P, T, X)
    - first block - always "0000" for medication requests
      - pattern: ^[0]{4}-[#{symbols}]{4}-[#{symbols}]{4}-[#{symbols}]{4}
    - example: 0000-TP42-M36M-H6TH
    After new Request number was generated we should check that it is unique in the DB
    (entity: medication_request + medication_request_request), if Request number is
    already reserved - generate new
  2. Generate verification_code for MPI.person_authentication_methods == OTP or OFFLINE

    Code Block
    Structure code 1234, where:
    - 1234 - randomly generated numbers 
    

Create Medication request Request

  1. set:

    1. dispense_valid_from = created_at

    2. dispensed_valid_to = dispensed_valid_from + dispense_period

  2. Fill 'data' structure for Response & save in IL.medication_request_requests

    1. If encounter is present in the request context then based on it - fill the IL.medication_request_requests.context_episode_id

  3. Fill separately

    1. data_employee_id,
      data_intent,
      data_based_on_care_plan_id,
      data_based_on_activity_id,
      data_context_id,
      data_patient_id,
      data_legal_entity_id

Update based_on

  1. If the medication request request is based on activity with quantity - set remaining_quantity for the activity which was calculated at validation Create Medication Request: Validate based_on (p. 2.d.1 )

Generate content for response

  • Generate data structure with Responce WS structure

    • Set IL.medication_request_requests this structure

  • in case if response is VALID enrich response with urgent_data:

    • get authetification_method by person_id and return masked number (in case if any)

Code Block
"urgent": {
    "authentication_method_current": {
      "type": "OTP",
      "number": "+38093*****85"
    }
  }

Response structure

See on Apiary

Example:

Expand
titleResponse example
Code Block
{
  "meta": {
    "code": "422",
    "url": "https://example.com/resource",
    "type": "object",
    "request_id": "req-adasdoijasdojsda"
  },
  "error": {
    "type": "unverified",
    "message": "Only active employee with type DOCTOR can create medication request!"
  }
}

HTTP status codes

HTTP status code

Message

What caused the error

201

Response

 

403

Your scope does not allow to access this resource. Missing allowances: medication_request_request:write

409

  • Employee is not active

  • Invalid legal entity type

  • Patient is not verified

  • Period length exceeds default maximum value

  • {$.data.context.identifier.type.coding[*].code} not found

  • Entity in status "entered-in-error" can not be referenced

  • Entity without related episode can not be referenced

  • Incorrect additional instruction

  • Incorrect site

  • Incorrect route

  • Incorrect method

  • Incorrect dose and rate type

  • The total amount of the prescribed medication quantity exceeds quantity in care plan activity

422

  • required property %{property} was not present

  • value is not allowed in enum

  • Prior prescription is not found

  • Employee not found

  • Employee does not belong to legal entity from token

  • Employee type can't create medication request with medical program from request

  • Only doctors with an active declaration with the patient can create medication request with medical program from request!

  • Only legal entity with an active declaration with the patient can create medication request with medical program from request!

  • Employee's specialty doesn't allow create medication request with medical program from request

  • Division not found

  • Only employee of active divisions can create medication request!

  • Legal entity not found

  • Only active legal entity can provide medication request

  • Person not found

  • Only for active MPI record can be created medication request!

  • expected \"%{actual}\" to be a valid ISO 8601 date

  • Ended date must be >= Started date!

  • Started date must be >= Created date!

  • Started date must be >= current date!

  • Create date must be >= Current date - MRR delay input!

  • Medication not found

  • Only medication with type `INNM_DOSAGE` can be use for created medication request!

  • Only active innm_dosage can be use for created medication request!

  • required property context was not present

  • Sequence must be unique

  • Care plan not found

  • Activity not found

  • Invalid activity kind

  • Medical program from activity should be equal to medical program from request

  • Invalid care plan period

  • required property medical_program_id was not present

  • Medical program not found

  • Care plan and activity with the same medical program should be present in request

  • Encounter in context has no primary diagnosis allowed for the medical program

  • Only doctors with an active declaration with the patient can create medication request!

  • Only legal entity with an active declaration with the patient can create medication request!

  • Employee's specialty doesn't allow create medication request with medical program from request

  • Division not found

  • Only employee of active divisions can create medication request!

  • Only active legal entity can provide medication request

  • Only for active MPI record can be created medication request!

  • Started date must be >= current date!

  • Create date must be >= Current date - MRR delay input!

  • Medication not found

  • Care plan not found

  • Medical program from activity should be equal to medical program from request

  • required property medical_program_id was not present