Table of Contents |
---|
...
This WS is designed to create Device DispenseDevice Request
This method allows to create Device Request for a person (or preperson) in eHealth. Method receives signed message (pkcs7) that consists of signed content, digital signature and signer public key. All signature fields will be validated (including signer certificate authority). Service will store signed copy of Device Request in Media Content Storage if all checks is passed.
Key points
Only authenticated and authorized users with appropriate scope can invoke Create Device DispenseRequest
Device Dispense Request is created in async way. Successful result of the job should return a link on the created Device Dispense Request (look at /wiki/spaces/CSI/pages/1746750686917467310277 ).
Device Dispense can be created only under active Device Request within valid dispense period
Several devices of different manufacturers with the same code can be dispensed at a time
Multiple dispenses to the same Device Request is not allowed
It is allowed to create Device Dispense for not active or not verified persons (for the same reasons as in the medication reimbursement process)
...
Request should be signed with DS. Signed content stores in the media storage.
All validations within Device request attributes should be executed by internal call of /wiki/spaces/CSI/pages/17467474119 function
Device Request can be created for a person only
Medical program is optional in the Device Request
Specification
Page Properties | ||
---|---|---|
| ||
...
...
...
Page Properties | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||
|
Logic
Save signed content to media storage, in bucket pointed in MEDIA_STORAGE_DEVICE_REQUEST_BUCKET chart parameter
Fill in the following fields:
...
requisition. Generate requisition number as described at Human readable Medication request number , but based on the Device Request identifier and put it in the field.
signed_content_links. Add string item in the array with a link on saved content in media storage
status = ACTIVE
status_reason = null
subject. Set hashed patient_id from URL
...
requester_legal_entity. Set client_id from token
quantity.unit. Set description according to quantity code and system
dispense_valid_to. Set (current_date + dispense_period_day) if medical program was set and it has dispense_period_day setting. Otherwise, set the value using device_dispense_period global parameter.
verification_code. Generate random 4-digit code
context_episode_id. Set episode from the $.encounter
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
Send verification code:
Determine patient's default authentication method as described at Determination of a default authentication method and return person's active auth_methods :
if OTP defined, then generate text according to TEMPLATE_SMS_FOR_CREATE_DEVICE_REQUEST and send SMS with verification_code
Save data to device_
...
requests collection in MongoDB according to /wiki/spaces/CSI/pages/
...
Send
StatusChangeEvent
to Event Manager
Input parameters
Input parameter | Values | Type | Description | Example |
---|---|---|---|---|
patient_id | String | MPI identifier of the person |
|
Request structure
See on Apiary
Example:
Expand | ||
---|---|---|
| ||
|
Authorize
Verify the validity of access token
in case of error - return 401 (“Invalid access token”) in case of validation fails
Verify that token is not expired
in case of error - return 401 (“Invalid access token”)
Check user and client scopes in order to perform this action (scope = 'device_dispenserequest:write')
return 403 (“Your scope does not allow to access this resource. Missing allowances: device_dispenserequest:write”) in case of invalid scope(s)
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")
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):
in case of error - return 403 ("Access denied. Party is deceased")
Headers
Content-Type:application/json
Authorization:Bearer mF_9.B5f-4.1JqM
api-key:aFBLVTZ6Z2dON1V
Request data validation
Validate
...
Extract client_id from token
Check legal entity exists and its status is ACTIVE
...
digital signature
Validate request is signed
in case of error - return
...
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')
...
400 (“Invalid signed content”)
Check DS is valid and not expired
Validate that DS belongs to the requester
Check that DRFO from DS and party.tax_id matches
in case of error - return 422 (
...
“Signer DRFO doesn't match with requester tax_id“)
Validate legal entity
Extract 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 division resource, required.
Check that division exists
in case of error - return 409 ("Division not found")
Check that division is active
inCheck legal entity status is ACTIVE
In case of error - return 409 ("Division is not active")
'
client_id
in case of error - return 409 ("Division does not belong to user's legal entity")
refers to legal entity that is not active')
Check legal entity type in ME_ALLOWED_TRANSACTIONS_LE_TYPES config parameter
in case of error - return 409 "Division is not verified in DLS"
Validate status
The target status value must be submitted in the order of display in the signed content (media storage)
Validate $.status is in_progress
in case of error - return 422 ("value is not allowed in enum")
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 ('Only device request with intent = 'order' can 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 that Device request is valid and available for dispense under this medical program
Invoke /('client_id refers to legal entity with type that is not allowed to create medical events transactions')
Validate Patient
Get Patient identifier from the URL
Check it exists in persons table (MPI) and has status active
Return 404 ('Person is not found') in case of error
Validate person'sverification_status is not equal to NOT_VERIFIED
in case NOT_VERIFIED - return error 409 ("Patient is not verified")
Validate person isnot a preperson
in case error - return error 409 ("Forbidden to create device request for a preperson")
Validate request
Validate request using schema.
Invoke validations described at https://e-health-ua.atlassian.net/wiki/spaces/CSI/pages/
17467834459Check that program_id is in Qualify response
Device request is prohibited for dispense in case $.data[?(@.program_id=device_request.program.identifier.value)].status = 'INVALID' or program_id is absent in qualify response
In case of error - return 409 error ('Device request can not be dispensed. Invoke qualify dispense request API to get detailed info')
Device request is allowed for dispense in case $.data[?(@.program_id=device_request.program.identifier.value)].status = 'VALID' and program_id is present in qualify response
Check for existing Device dispenses
Check that there is no other
IN_PROGRESS
device dispenses based on the same device requestFind all device dispenses related to the same device request ($.based_on)
Check that there are no records in status
in-progress
whereinserted_at
+ configdevice_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 todevice_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
recordsfind 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 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“)
Processing
Response structure
See on Apiary
Example:
...
title | Response example |
---|
...
17467474119/PreQualify+Device+request#Validate-Device-request
If Device Request has a medical program, then in addition execute validations described at https://e-health-ua.atlassian.net/wiki/spaces/CSI/pages/17467474119/PreQualify+Device+request#Validate-Medical-programs . Also, quantity is required in this case
Validate status
The target status value must be submitted in the order of display in the signed content (media storage)
Validate $.status is active
in case of error - return 422 ("value is not allowed in enum")
Response structure
See on Apiary
Example:
Expand | ||
---|---|---|
| ||
|
HTTP status codes
Page Properties | |||||||||
---|---|---|---|---|---|---|---|---|---|
| |||||||||
|