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

Public. Create Contract Request

Purpose

This WS is designed to create contract request from Legal Entity side by Owner or Admin

Specification

Link

https://ehealthmisapi1.docs.apiary.io/#reference/public.-contracts/contract-request/public.-create-contract-request

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

Resource

/api/contract_requests/{{contract_type}}/{{id}}

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

Scope

contract_request:create

Scope для доступу

Components

Contracts

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

Microservices

API paragraph not found

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

Protocol type

REST

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

Request type

POST

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

Sync/Async

API paragraph not found

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

Public/Private/Internal

Public

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

Preconditions

Before the request is created the contract should be initialized the documents must be uploaded.

Logic

After using thit WS request can be approved or declined by NHS side. After that, MSP must approve the request from their side (actually only for Capitation contract).

In case the request was two-sided approved, it can be two-sided signed. 

Using this endpoint a reimbursement contract could be created as well as a capitation contract. The difference between those two types of contract is described here- Reimbursement version Data model

Input parameters

Input is signed data in PKCS7 format. The data must be unpacked and validated using schema (Capitation Contract_request) or JSON schema (Reimbursement Contract_request)

In order to change signed contract contract_number should be send. In this case start_date and end_date are taken from existing contract and should not be present in payload (except in cases of contract prolongation. For these cases, validations are described below).

In case this contract request is changes for another one, the previous contract request id (Create Contract Request#previous_request) should be send in payload. 

Input parameter

Values

Type

Description

Example

Input parameter

Values

Type

Description

Example

contract_type

CAPITATION

REIMBURSEMENT

String

Required

 

id

 

String

Contract_request ID. Required

09106b70-18b0-4726-b0ed-6bda1369fd52

Request structure

Example:

{ "signed_content": "ew0KICAiY29udHJhY3Rvcl9vd25lcl9pZCI6ICJkZjlmNzBlZS00YjEyLTQ3NDAtYjBmNS1iYjVhZWExMTY4NjMiLA0KICAiY29udHJhY3Rvcl9iYXNlIjogItC90LAg0L/RltC00YHRgtCw0LLRliDQt9Cw0LrQvtC90YMg0L/RgNC+INCc0LXQtNC40YfQvdC1INC+0LHRgdC70YPQs9C+0LLRg9Cy0LDQvdC90Y8g0L3QsNGB0LXQu9C10L3QvdGPIiwNCiAgImNvbnRyYWN0b3JfcGF5bWVudF9kZXRhaWxzIjogew0KICAgICJiYW5rX25hbWUiOiAi0JHQsNC90Log0L3QvtC80LXRgCAxIiwNCiAgICAiTUZPIjogIjM1MTAwNSIsDQogICAgInBheWVyX2FjY291bnQiOiAiMzIwMDkxMDI3MDEwMjYiDQogIH0sDQogICJjb250cmFjdG9yX3Jtc3BfYW1vdW50IjogNTAwMDAsDQogICJjb250cmFjdG9yX2RpdmlzaW9ucyI6IFsNCiAgICAiaWQ6IGAyOTIyYTI0MC02M2RiLTQwNGUtYjczMC0wOTIyMmJmZWIyZGRgIg0KICBdLA0KICAiY29udHJhY3Rvcl9lbXBsb3llZV9kaXZpc2lvbnMiOiBbDQogICAgew0KICAgICAgImVtcGxveWVlX2lkIjogIjI5MjJhMjQwLTYzZGItNDA0ZS1iNzMwLTA5MjIyYmZlYjJkZCIsDQogICAgICAic3RhZmZfdW5pdHMiOiAwLjUsDQogICAgICAiZGVjbGFyYXRpb25fbGltaXQiOiAyMDAwLA0KICAgICAgImRpdmlzaW9uX2lkIjogIjI5MjJhMjQwLTYzZGItNDA0ZS1iNzMwLTA5MjIyYmZlYjJkZCINCiAgICB9DQogIF0sDQogICJleHRlcm5hbF9jb250cmFjdG9yX2ZsYWciOiB0cnVlLA0KICAiZXh0ZXJuYWxfY29udHJhY3RvcnMiOiB7DQogICAgImxlZ2FsX2VudGl0eV9pZCI6ICIyOTIyYTI0MC02M2RiLTQwNGUtYjczMC0wOTIyMmJmZWIyZGQiLA0KICAgICJjb250cmFjdCI6IHsNCiAgICAgICJudW1iZXIiOiAiMTIzNDU2NyIsDQogICAgICAiaXNzdWVkX2F0IjogIjIwMTgtMDEtMDEiLA0KICAgICAgImV4cGlyZXNfYXQiOiAiMjAxOS0wMS0wMSINCiAgICB9LA0KICAgICJkaXZpc2lvbnMiOiBbDQogICAgICB7DQogICAgICAgICJpZCI6ICIyOTIyYTI0MC02M2RiLTQwNGUtYjczMC0wOTIyMmJmZWIyZGQiLA0KICAgICAgICAibWVkaWNhbF9zZXJ2aWNlIjogItCf0L7RgdC70YPQs9CwINCf0JzQlCINCiAgICAgIH0NCiAgICBdDQogIH0sDQogICJzdGFydF9kYXRlIjogIjIwMTctMDQtMjAiLA0KICAiZW5kX2RhdGUiOiAiMjAxNy0wNC0yMCIsDQogICJpZF9mb3JtIjogIjUiLA0KICAiY29udHJhY3RfbnVtYmVyIjogIjAwMDAtOUVBWC1YVDdYLTMxMTUiLA0KICAic3RhdHV0ZSI6ImJhc2U2NF9kb2N1bWVudCINCiAgImVxdWlwbWVudF9hZ3JlZW1lbnQiOiJiYXNlNjRfZG9jdW1lbnQiDQp9", "signed_content_encoding": "base64" }

Dummy example (Capitation version):

{ "contractor_owner_id": "df9f70ee-4b12-4740-b0f5-bb5aea116863", "contractor_base": "на підставі статуту", "previous_request_id": "df9f70ee-4b12-4740-b0f5-bb5aea116863", "contractor_payment_details": { "payer_account": "UA3412345678901234567890", "bank_name": "Банк №1" }, "contractor_divisions": [ "adeac295-0d39-4a8e-8e16-9526787de3f1" ], "external_contractor_flag": true, "external_contractors": [ { "legal_entity_id": "443e901e-b365-45d2-be14-083ee0aba657", "contract": { "number": "1234567", "issued_at": "2018-01-01", "expires_at": "2019-01-01" }, "divisions": [ { "id": "2922a240-63db-404e-b730-09222bfeb2dd", "medical_service": "PHC_SERVICES" } ] } ], "start_date": "2017-04-20", "end_date": "2017-04-20", "id_form": "PMD_1", "contract_number": "0000-9EAX-XT7X-3115", "statute_md5": "db218b04eff70f86f40c1572ce8ca16a", "additional_document_md5": "ac642b04eff40f86f40c1572ce8ca16a", "consent_text": "Цією заявою Заявник висловлює бажання укласти договір про медичне обслуговування населення за програмою державних гарантій медичного обслуговування населення (далі – Договір) на умовах, визначених в оголошенні про укладення договорів про медичне обслуговування населення (далі – Оголошення). Заявник підтверджує, що: 1. на момент подання цієї заяви Заявник має чинну ліцензію на провадження господарської діяльності з медичної практики та відповідає ліцензійним умовам з медичної практики; 2. Заявник надає медичні послуги, пов’язані з первинною медичною допомогою (далі – ПМД); 3. Заявник зареєстрований в електронній системі охорони здоров’я (далі – Система); 4. уповноважені особи та медичні працівники, які будуть залучені до виконання Договору, зареєстровані в Системі та отримали електронний цифровий підпис (далі – ЕЦП); 5. в кожному місці надання медичних послуг Заявника наявне матеріально-технічне оснащення, передбачене розділом І Примірного табелю матеріально-технічного оснащення закладів охорони здоров’я та фізичних осіб – підприємців, які надають ПМД, затвердженого наказом Міністерства охорони здоров’я України від 26 січня 2018 року № 148; 6. установчими або іншими документами не обмежено право керівника Заявника підписувати договори від імені Заявника без попереднього погодження власника. Якщо таке право обмежено, у тому числі щодо укладання договорів, ціна яких перевищує встановлену суму, Заявник повідомить про це Національну службу здоров’я та отримає необхідні погодження від власника до моменту підписання договору зі сторони Заявника; 7. інформація, зазначена Заявником у цій Заяві та доданих до неї документах, а також інформація, внесена Заявником (його уповноваженими особами) до Системи, є повною та достовірною. Заявник усвідомлює, що у разі зміни інформації, зазначеної Заявником у цій заяві та (або) доданих до неї документах Заявник зобов’язаний повідомити про такі зміни НСЗУ протягом трьох робочих днів з дня настання таких змін шляхом надсилання інформації про такі зміни на електронну пошту dohovir@nszu.gov.ua, з одночасним внесенням таких змін в Систему. Заявник усвідомлює, що законодавством України передбачена відповідальність за подання недостовірної інформації органам державної влади." }

Dummy example (Reimbursement version):

{ "contractor_owner_id": "df9f70ee-4b12-4740-b0f5-bb5aea116863", "contractor_base": "на підставі статуту", "previous_request_id": "df9f70ee-4b12-4740-b0f5-bb5aea116863", "contractor_payment_details": { "payer_account": "UA3412345678901234567890", "bank_name": "Банк №1" }, "start_date": "2019-04-20", "end_date": "2020-04-19", "id_form": "PMD_1", "contract_number": "0000-9EAX-XT7X", "statute_md5": "db218b04eff70f86f40c1572ce8ca16a", "additional_document_md5": "ac642b04eff40f86f40c1572ce8ca16a", "medical_programs": [ "3922a240-63db-404e-b730-09222bfeb2d1" ] "consent_text": "Цією заявою Заявник висловлює бажання укласти договір про реімбурсацію з Національною службою здоров'я України та підтверджує, що на момент подання цієї заяви Заявник провадить господарську діяльність на підставі ліцензії на провадження господарської діяльності з роздрібної торгівлі лікарськими засобами та відповідає ліцензійним умовам. Заявник усвідомлює, що у разі зміни інформації, зазначеної Заявником у цій заяві та (або) доданих до неї документах Заявник зобов'язаний повідомити про такі зміни НСЗУ протягом трьох робочих днів з дня настання таких змін шляхом надсилання інформації про такі зміни на електронну пошту dohovir@nszu.gov.ua, з одночасним внесенням таких змін в Систему. Заявник усвідомлює, що законодавством України передбачена відповідальність за подання недостовірної інформації органам державної влади." }

Authorize

  1. Verify the validity of access token

    • in case of error return 401 ('Invalid access token')

    • Check user scope contract_request:create in order to perform this action

      1. in case of error generate 401 response ('Invalid access token')

Headers

Наприклад:

Content-Type:application/json

Authorization:Bearer c2778f3064753ea70de870a53795f5c9

Request data validation

Digital signature

Decode content that is encrypted in an electronic digital signature.
Use Digital signature WS. Method checks digital signature and returns result.

Validate DS

We need to check DS based on legal entity legal form. DS can belong to individual entrepreneur or to legal entity. As previous version of DS can contain tax_id in EDRPOU field, not in DRFO validation must be done as described below:

  1. Get client_id from token

  2. Find prm.legal_entities by client_id

  3. Check EDRPOU or DRFO matches prm.legal_entities.EDRPOU

    1. Check if  EDRPOU in Certificate details exists and not empty

      1. Check if  Certificate_details.EDRPOU=prm.legal_entities.EDRPOU

    2. in case validation from a. didn't pass - Check that DRFO in Certificate details exists and not empty

      1. Convert DRFO and prm.legal_entities.EDRPOU to uppercase

      2. Compare DRFO and prm.legal_entities.EDRPOU as Cyrillic letters

      3. Convert DRFO to Cyrillic and compare as Cyrillic letters

      4. Check if  Certificate_details.DRFO=prm.legal_entities.EDRPOU 

  4. In case validation fails - generate 422 error

  5. Check that SURNAME in Certificate details is equal to LAST_NAME in Party

    1. Get user_id → user_parties.party_id → parties.last_name and compare to surname from DS

      1. Convert prm.parties.LAST_NAME and Certificate details.SURNAME to uppercase

      2. Compare prm.parties.LAST_NAME and Certificate details.SURNAME as Cyrillic letters

      3. In case validation fails - generate 422 error

Validate DRFO

  1. Get parties.tax_id using party_users.party_id by user_id.

  2. Compare DRFO in Certificate with party.tax_id

    1. Convert DRFO and TAX_ID to uppercase

    2. Compare DRFO and TAX_ID as Cyrillic letters

    3. Convert DRFO to Cyrillic and compare as Cyrillic letters

  3. In case validation fails - generate 422 error

Verify role

Extract from token:

  1. Validate client_id (is_blocked=false)

    1. in case of error return 403 Error ('Client is blocked')

  2. Check contractor_legal_entity is active or suspended

    1. in case error return 403 - ('Client is not active')

Validate request

  1. Validate contract_type

    1. legal entities with types in (MSP,PRIMARY_CARE) can create only capitation contracts, legal entities with types in (PHARMACY) can create only reimbursement contracts

      1. in case of error 409 - "Contract type "{contract_type}" is not allowed for legal_entity with type "{legal_entity_type}" "

  2. Validate previous_request_id 

    1. select id from contract_request where id=$.previous_request_id

      1. in case no data found return 422 ("previous_request does not exist")

    2. Check previous_request status not in ('SIGNED')

      1. in case error return 422 ('In case contract exists new contract request should be created')

    3. Check that contractor_legal_entity_id of previous request is equal to contractor_legal_entity_id of current request

      1. in case of error return 422 ('Previous request doesn't belong to legal entity')

    4. For reimbursement contracts: Check that id_form from $.previous_request_id equal to id_form from request

      1. in case of error return 422 ('Id_form from previous request is not equal to id_form from request')

  3. Validate contractor_divisions

    1. Check divisions belongs to legal_entity and divisions.status='active'

      1. in case of error return 422  error view $divisions ('Division must be active and within current legal_entity')

    2. Validate each division in array present exactly one time

      1. in case of error return 422  error view $divisions ('Division duplicates')

  4. Validate start_date

    1. validate that start_date in a date format (^(\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))?)?$)

      1. in case of error return 422 error $start_date ('"expected \"<start_date>" to be a valid ISO 8601 date"')

    2. the year in start_date must be equal to current or next year (current+1).

      1. in case of error return 422 error $start_date ('Start date must be within this or next year')

  5. Validate end_date (Note. These validations are applied for cases when the contract_number isn't passed in the request. If the contract_number is passed, validations from 7.f are applied)

    1. validate that end_date in a date format (^(\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))?)?$)

      1. in case of error return 422 error $end_date ('"expected \"<end_date>" to be a valid ISO 8601 date"')

    2. the year in $end_date can be next year after 'start_date' if the total period of the contract doesn't exceed 1 year.

    3. the $end_date must be greater or equal than the $start_date

      1. in case of error return 422 ('The end_date should be greater or equal than the start_date')

    4. the different between $end_date and $start_date should be no more than than reimbursement(capitation)_contract_max_period_day global param

      1. in case of error return 422 ('The difference between end_date and start_date is more than <reimbursement(capitation)_contract_max_period_day> days') one year')

  6. Validate contractor_owner_id

    1. Check employees.employee_id=contractor_owner_id and client_id=employee.legal_entity_id and employee_type in('OWNER', 'ADMIN') and status='APPROVED' and is_active=true

      1. In case of error return 422 Error ('Contractor owner must be an active OWNER or ADMIN and within current legal entity in contract request')

  7. If in request was sent contract_number:

    1. check contract request number structure XXXX-1234-5678-C , where:

      1. XXXX - series: numbers + only some letters (A, E, H, K, M, P, T, X)

      2. 1234-5678 - randomly generated numbers and letters A, E, H, K, M, P, T, X.

    2. check there is a contract with such contract_number 

      1. in case of error return 422 error ('Contract with such contract number does not exist')

    3. check if contract is not in status 'TERMINATED'

      1. in case of error return 409 error ('Can not update terminated contract')

    4. employee_divisions, start_date, end_date can't be updated. If there is an active contract with such contract_number copy start_date, end_date and contractor_legal_entity_id from existing contract. It's not allowed in response.

      1. in case of error return 422 error

    5. check submitted contract_type is the same as in existing contract with number =contract_number

      1. in case of error 409 ('Submitted contract_type does not correspond to previously created content`)

    6. for capitation and reimbursement contract requests:

      1. if $contract_number and $end_date is passed in request:

        1. the year of $end_date must be one year greater or equal then the $start_date

          1. in case of error return 422 ('The year of end_date should be one year greater or equal to start_date')

        2. the $end_date should be equal or greater than today and less than or equal to three month from $end_date the previous contract

          1. in case of error return 422 ('The end_date may be equal or greater than today and less than or equal to three month from end_date the previous contract')

      2. if $contract_number w/o $end_date is passed in request:

        1. $end_date is taken from the previous contract.

    7. in case it is reimbursement contract:

      1. check id_form is the same

        1. in case of error 409 ('Submitted id_form does not correspond to previously created content`)

      2. if medical_programs passed - validate them as described at p.13 below

  8. Validate contractor_payment_details:

    1. if payer_account not like ^UA[0-9]{22}$ or ^UA[0-9]{27}$ -> MFO must be required

  9. Validate id_from is from dictionary CONTRACT_TYPE:

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

  10.  Validate there is no other active (VERIFIED) contract created by this legal_entity_id in this period(contract_request.start_date <= contract.end_date and contract_request.end_date => contract.start_date) by same contract_type and id_form (in case of reimbursement contract)

    1. in case of error return 422 error ('Active contract is found. Contract number must be sent in request')

  11. For capitation contract: Validate external_contractors

    1. Check external_contractors.divisions.id is present in contractor_divisions.id

      1. in case of error return 422 error $divisions ('The division is not belong to contractor_divisions')

    2. Check external_contractors.contract.expires_at>start_date

      1. in case of error return 422 error $contract.expires_at ('Expires date must be greater than contract start_date')

    3. Set external_contractors.legal_entity_id='client_id'

    4. division_id from the external_contractors block must be a part of the legal entity that enters into the capitation contract. In the external_contractors.legal_entity_id must be specify the legal entity that is the counter-party of this division_id.

  12. For capitation contract: Validate external_contractor_flag:

    1. If external_contractors is not null then external_contractor_flag must be true

    2. If external_contractors is null then external_contractor_flag must be set to false 

      1. in case of error return 422 error $external_contractor_flag ('Invalid external_contractor_flag')

    3. If external_contractors wasn't sent in request then set external_contractor_flag to false.

  13. For reimbursement contracts: Validate medical_programs:

    1. Validate that all medical_programs with submitted ids exists

      1. in case of error return 422 error view $medical_programs[...] ('Reimbursement program with such id does not exist')

    2. Validate that medical_programs with submitted id is an active program

      1. in case of error return 422 error view $medical_programs[...] ('Reimbursement program is not active')

    3. Validate that all medical program and with MEDICATION type:

      1. in case of error return 422 error view $medical_programs[...] (‘Program with such id is not a reimbursement program')

    4. Check that medical_programs with submitted id correspond to id_form is in the allowed list:

      1. in case of error return 422 error view $medical_programs[...] ('Medical program is not allowed for this action')
        Note. For id_form=INSULIN_1 and PSYCHIATRY two medical programs must be present.

        1. in case of error return 409 error view $medical_programs ('The composition of medical programs does not correspond to the allowed composition')

    5. Validate that list of medical programs in array doesn't contain duplicates ids:

      1. in case of error return 409 error view $medical_programs (‘The list of medical programs contains duplicates')

id_form

medical_programs

id_form

medical_programs

PMD_1

REIMBURSEMENT_CONTRACT_REQUEST_MEDICAL_PROGRAM_ID_DOSTUPNI_LIKY

INSULIN_1

REIMBURSEMENT_CONTRACT_REQUEST_MEDICAL_PROGRAM_IDS_INSULIN

ND_1

REIMBURSEMENT_CONTRACT_REQUEST_MEDICAL_PROGRAM_ID_NETSUKROVYY_DIABET

PSYCHIATRY

REIMBURSEMENT_CONTRACT_REQUEST_MEDICAL_PROGRAM_IDS_PSYCHIATRY

GENERAL

REIMBURSEMENT_CONTRACT_REQUEST_MEDICAL_PROGRAM_IDS_GENERAL

  1. Note. For GENERAL id_form user can specify any qty of programs (but at least one) from the configuration list. Also user can update list of medical programs using logic from p.7

Dictionaries

  • CONTRACT_PAYMENT_METHOD

  • CONTRACT_TYPE

  • REIMBURSEMENT_CONTRACT_TYPE

  • ADDRESS_TYPE

  • COUNTRY

  • SETTLEMENT_TYPE

  • STREET_TYPE

  • PHONE_TYPE

  • SPECIALITY_TYPE

  • SPECIALITY_LEVEL

  • SPEC_QUALIFICATION_TYPE

Processing

Determine parent contract (optional)

In case contract request contains parameter '$.contract_number':

  1. find contract that matches transmitted '$contract_number':

    1. if there is no contract with specified contract number, return 422 error ('Contract with such contract number does not exist')

    2. if contract is in 'Terminated' status, return 409 error ('Can not update terminated contract')

  2. set parent_contract_id value as contract.id

Search pending contract requests

  1. Find there is no contract request 

  • for same contractor_legal_entity_id

  • within same period [start_date, end_date]

  • status in ('NEW', 'IN_PROCESS','APPROVED', 'NHS_SIGNED', 'PENGIND_NHS_SIGN')

  • id_form

In case there is such contract request change its status to 'TERMINATE'

Save contract request

Insert record to IL.contract_request in status 'NEW'

set  - contractor_legal_entity_id=$client_id

Save signed contract request to media storage

  1. Get url for contract request upload

Parameter

Source

Parameter

Source

action

'GET'

bucket

'CONTRACT_REQUEST'

resource_id

:CONTRACT_REQUEST_ID

resource_name

:INITIAL_CONTRACT_REQUEST

timestamp

:TIMESTAMP

2. Upload signed contract request to media storage.

Response structure

Example:

 

HTTP status codes

HTTP status code

Message

What caused the error

HTTP status code

Message

What caused the error

 201

 Response

 

 401

 Invalid access token

 

403

  • Client is blocked

  • Client is not active

 

409

 

Validation failed

422

 

Validation failed

 

 

 

 

 

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