ЕСОЗ - публічна документація

RC_Create Device dispense

Purpose

This WS is designed to create Device Dispense

Key points

  1. Only authenticated and authorized users with appropriate scope can invoke Create Device Dispense

  2. Device Dispense is created in async way. Successful result of the job should return a link on the created Device Dispense (look at Get Device dispense details ).

  3. Device Dispense can be created only under active Device Request within valid dispense period

  4. Several devices of different manufacturers with the same code can be dispensed at a time

  5. Multiple dispenses to the same Device Request is not allowed

Specification

https://ehealthmedicaleventsapi.docs.apiary.io/#reference/device-dispenses/create-device-dispense/create-device-dispense

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_dispense:write')

    • return 403 (“Your scope does not allow to access this resource. Missing allowances: device_dispense: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):

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

  5. If BLOCK_DECEASED_PARTY_USERS is true, check that party is not deceased (party_verification record does not equal to: dracs_death_verification_status = VERIFIED and dracs_death_verification_reason = MANUAL_CONFIRMED):

    1. in case of error - return 403 ("Access denied. Party is deceased")

Validate legal entity

  • Extract client_id from token

  • Check legal entity exists and its status is ACTIVE

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

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's verification_status is not equal to NOT_VERIFIED.

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

Validate dispense

Validate performer

Validate value in the field $.performer, 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 performer is an active and approved employee.

    • in case of error - return 422 ('Employee is not active ')

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

    • in case of error - return 422 ('Employee does not belong to legal entity from token')

Validate location

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

  • Check that division exists

    • in case of error - return 409 ("Division not found")

  • Check that division is active

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

  • Validate division belongs to user's legal entity (client_id from token)

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

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

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

Validate when_handed_over

  • Check that when_handed_over is in period specified in Device request (when_handed_over = current_date() and when_handed_over <= device_request.dispense_valid_to)

    • in case of error - return 409 error ('Invalid dispense period')

Validate Device request

Validate value in the field $.based_on ($.based_on.identifier.value), Reference on device request, required.

  • Check that device request exists

    • in case of error - return 422 ('Device request not found')

  • Check that intent specified in Device request is order

    • in case of error - return 409 error ('Device request with intent PLAN cannot be dispensed')

  • Сheck that Device request is in status 'ACTIVE'

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

Validate program

  • Check that program in dispense is the same as program in device request (request.program.identifier.value = device_requests.program.identifier.value)

    • in case of error - return 409 ('Program in dispense doesn't match the one in device request')

Qualify Device request

This validation must be done only if medical_program exists in request and medical_program is the same as in device request

Check for existing Device dispenses

  • Check that there is no other IN_PROGRESS device dispenses based on the same device request

    • Find all device dispenses related to the same device request ($.based_on)

    • Check that there are no records in status in-progress where when_handed_over + config device_dispense_ttl >= current date-time()

      • in case of error - return 422 "Other active device dispense already exist."

Validate Dispense details

Validate device

  • Check device (device definition) to be dispensed ($.dispense_details.device)

    • Check code ($.dispense_details.device.identifier.type.coding.code) = device_definition

      • in case of error - return 422 ('Only device definition is allowed for dispense')

    • Get device definition by id ($.dispense_details.device.identifier.value)

      • device_definition.is_active = true

        • in case of error - return 422 ('Device definition not found')

    • Check that this device definition is compliant with prescribed device

      • If device_request.code is of type Reference

        • Check that device_definition_id in dispense is equal to device_definition_id in request

      • If device_request.code is of type CodeableConcept

        • Check that device_definition.classification_type is equal to prescribed device definition code in device request (device_request.code)

      • in case of error - return 422 ('Dispensed device doesn’t match with prescribed device')

    • Check that packaging_unit matches with quantity.code of the Device Request

      • in case of error - return 422 (Dispensed packaging unit doesn’t match with prescribed packaging unit)

Validate program device

  • Check program device

    • Is applicable only if program was passed to request and program device passed to request

      • Check code ($.dispense_details.program_device.identifier.type.coding.code) = program_device

        • in case of error - return 422 ('Invalid code. Expected 'program_device'')

      • Check that program device is active

      • Check that program device has validity period (start_date and end_date) within current date

        • in case of error - return 422 ('Program device is not active')

      • Check that max daily count is not exceeded - max_daily_count is null or max_daily_count >= quantity.value/(occurence_period.end - occurence_period.start) of the Device Request

        • in case of error - return 422 ('max daily count exceeded')

      • Check that program device relates to the device definition in $.dispense_details.device

        • in case of error - return 422 ('Program device doesn’t match with device')

      • Check that program device relates to the program in $.program

        • in case of error - return 422 ('Program device doesn’t match with program')

    • if program was passed to request and no program device specified

      • find program device related to dispensed device definition and selected program

        • find active records

        • find program devices where validity period (start_date and end_date) within current date

          • if no records found - return 422 ('No active program devices under this program')

        • Check that max daily count is not exceeded - max_daily_count is null or max_daily_count >= quantity.value/(occurence_period.end - occurence_period.start) of the Device Request

          • in case of error - return 422 ('max daily count exceeded')

Valdate quantity

  • Validate quantity

    • Check that dispensed device quantity is equal to prescribed quantity in Device Request

    • sum($.dispense_details.quantity.value) = device_request.quantity

      • in case of error - return 422 ('Dispensed quantity must be equal to prescribed quantity in Device Request')

Validate discount

  • Validate sell_price

    • Check it is present if medical program is present and has funding_source = "NHS"

      • in case of error - return 422 ('Required property sell_price was not present')

  • Validate sell_amount

    • Check it is present if $.sell_price has been set

      • in case of error - return 422 ('Required property sell_amount was not present')

    • Check that $.sell_amount = $.sell_price * $.dispense_details.quantity.value + DEVICE_DISPENSE_TOLERANCE

      • in case of error - return 422 ('Sell amount doesn’t comply with quantity and sell price')

  • Validate discount_amount

    • Check it is present if medical program is present and has funding_source = "NHS"

      • in case of error - return 422 ('Required property discount_amount was not present')

    • Check it is absent if medical program is absent

      • in case of error - return 422 ('Property discount_amount shouldn’t be submitted if medical program is absent')

    • Calculate allowed reimbursement amount:

      • If reimbursement_type of program_device is PERCENTAGE:

        • If reimbursement_percentage_discount of program_device is zero, then check $.discount_amount is equal to zero too

          • in case of error - return 422 ('Requested discount amount must be equal to 0')

        • Calculate allowed_reimbursement_amount = $.sell_price * program_device.reimbursement_percentage_discount/100

      • If reimbursement_type of program_device is FIXED:

        • Get allowed_reimbursement_amount = program_device.reimbursement_amount

    • Check $.discount_amount <= allowed_reimbursement_amount * ($.dispense_details.quantity.value/device_definition.packaging_count) + DEVICE_DISPENSE_TOLERANCE

      • in case of error - return 422 ('Requested discount amount must be less or equal to allowed reimbursement amount')

    • Check the ratio of discount amount to reimbursement amount as $.discount_amount/ (allowed_reimbursement_amount * ($.dispense_details.quantity.value/device_definition.packaging_count)) >= 1 - DEVICE_DISPENSE_DEVIATION

      • In case of error - return 422 ('The ratio of requested discount amount to allowed reimbursement amount must be greater or equal to <1 - DEVICE_DISPENSE_DEVIATION>')

Validate verification code

  • Check that $.verification_code in request is equal to verification_code in device_request

    • In case code exists in request - it should match with code in device_request

      • in case of error - return 403 (message: “Incorrect code“)

Service logic

  • Fill in the following fields:

    • status = IN_PROGRESS

    • status_reason = null

    • subject. Set hashed patient_id from URL

    • performer_legal_entity. Set client_id from token

    • quantity.unit. Set description according to quantity code and system

    • inserted_at. Set current date and time

    • updated_at. Set current date and time

    • inserted_by. Set current user from token

    • updated_by. Set current user from token

  • Save data to device_dispenses collection in MongoDB according to RC_Device dispense data modelarchived

  • Send StatusChangeEvent to Event Manager

ЕСОЗ - публічна документація