Specification
Purpose
This WS is designed to create contract request from Legal Entity side by Owner or Admin. Before the request is created the documents must have been uploaded. Then request can be approved or declined by NHS side. After that, MSP must approve the request from their side. In case the request was two-side approved, it can be two-side 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- Contract: Reimbursment version Data model
Input parameters
Input is signed data in PKCS7 format. The data must be unpacked and validated using JSON schema (capitation contract) or JSON schema (reimbursement contract)
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.
In case this contract request is changes for another one, the previous contract request id (Public. Create Contract Request#previous_request) should be send in payload.
Authorize
- Verify the validity of access token
- in case of error return 401 ('Access denied')
- Check user scope contract_request:create in order to perform this action
- in case of error generate 401 response ('Invalid scopes')
- Verify the validity of access token
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:
- Get client_id from token
- Find prn.legal_entities by client_id
- Check EDRPOU or DRFO matches prn.legal_entities.EDRPOU
- Check if EDRPOU in Certificate details exists and not empty
- Check if Certificate_details.EDRPOU=prn.legal_entities.EDRPOU
- in case validation from a. didn't pass - Check that DRFO in Certificate details exists and not empty
- Convert DRFO and prn.legal_entities.EDRPOU to uppercase
- Compare DRFO and prn.legal_entities.EDRPOU as Cyrillic letters
- Convert DRFO to Cyrillic and compare as Cyrillic letters
- Check if Certificate_details.DRFO=prn.legal_entities.EDRPOU
- Check if EDRPOU in Certificate details exists and not empty
- In case validation fails - generate 422 error
- Check that SURNAME in Certificate details is equal to LAST_NAME in Party
- Get user_id → user_parties.party_id → parties.last_name and compare to surname from DS
- Convert prm.parties.LAST_NAME and Certificate details.SURNAME to uppercase
- Compare prm.parties.LAST_NAME and Certificate details.SURNAME as Cyrillic letters
- In case validation fails - generate 422 error
- Get user_id → user_parties.party_id → parties.last_name and compare to surname from DS
Validate DRFO
- Get parties.tax_id using party_users.party_id by user_id.
- Compare DRFO in Certificate with party.tax_id
- Convert DRFO and TAX_ID to uppercase
- Compare DRFO and TAX_ID as Cyrillic letters
- Convert DRFO to Cyrillic and compare as Cyrillic letters
- In case validation fails - generate 422 error
Verify role
Extract from token:
- Validate client_id (is_blocked=false)
- in case of error return 403 Error ('Client is blocked')
- Check contractor_legal_entity is active or suspended
- in case error return 403 - ('Client is not active')
Validate request
- Validate contract_type: legal entities with types in capitation_contract_le_types can create only capitation contracts when reimbursement_contract_le_types can create only reimbursement contracts
- in case of error 409 - "Contract type "{contract_type}" is not allowed for legal_entity with type "{legal_entity_type}" "
- Validate previous_request_id
- select id from contract_request where id=$.previous_request_id
- in case no data found return 422 ("previous_request does not exist")
- Check previous_request status not in ('SIGNED')
- in case error return 422 ('In case contract exists new contract request should be created')
- Check that contractor_legal_entity_id of previous request is equal to contractor_legal_entity_id of current request
- in case of error return 422 ('Previous request doesn't belong to legal entity')
- select id from contract_request where id=$.previous_request_id
- Validate contractor_divisions
- Check divisions belongs to legal_entity and divisions.status='active'
- in case of error return 422 error view $divisions ('Division must be active and within current legal_entity')
- Validate each division in array present exactly one time
- in case of error return 422 error view $divisions ('Division duplicates')
- Check divisions belongs to legal_entity and divisions.status='active'
- For capitation contract: Validate contractor_employee_divisions
- Employees from employee_divisions has employee_type='DOCTOR', status='APPROVED'
- in case of error return 422 error view $employee ('Employee must be an active DOCTOR')
- Check contractor_employee_divisions.division_id is present in contractor_divisions.id
- in case of error return 422 error $divisions ('The division is not belong to contractor_divisions')
- Check employee present in divisions for one time: count(employee_id)=1 by contractor_employee_divisions.division_id
- in case of error return 422 error $divisions ('Employee in division duplicates)
- Employees from employee_divisions has employee_type='DOCTOR', status='APPROVED'
- For capitation contract: Validate external_contractors
- Check external_contractors.divisions.id is present in contractor_divisions.id
- in case of error return 422 error $divisions ('The division is not belong to contractor_divisions')
- Check external_contractors.contract.expires_at>start_date
- in case of error return 422 error $contract.expires_at ('Expires date must be greater than contract start_date')
- Set external_contractors.legal_entity_id='client_id'
- 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 counterparty of this division_id.
- Check external_contractors.divisions.id is present in contractor_divisions.id
- For capitation contract: Validate external_contractor_flag:
- If external_contractors is not null then external_contractor_flag must be
true
- If external_contractors is null then external_contractor_flag must be set to
false
- in case of error return 422 error $external_contractor_flag ('Invalid external_contractor_flag').
If external_contractors wasn't sent in request then set external_contractor_flag to false.
- If external_contractors is not null then external_contractor_flag must be
- Validate start_date
- the year in start_date must be equal to current or next year (current+1).
- in case of error return 422 error $start_date ('Start date must be within this or next year')
- the year in start_date must be equal to current or next year (current+1).
- Validate end_date
- the year in $end_date must be equal to year in $start_date
- in case of error return 422 error $end_date ('The year of start date and end date must be equal')
- the $end_date must be greater than the $start_date
- in case of error return 422 ('The end date must be greater than the start date')
- the year in $end_date must be equal to year in $start_date
- Valide contractor_owner_id
- 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
- In case of error return 422 Error ('Contractor owner must be an active OWNER or ADMIN and within current legal entity in contract request')
- If in request was sent contract_number check format contract_number:
- contract request number structure XXXX-1234-5678-C , where:
- XXXX - series: numbers + only some letters (A, E, H, K, M, P, T, X)
- 1234-5678 - randomly generated numbers and letters A, E, H, K, M, P, T, X.
- check there is a contract with such contract_number
- in case of error return 422 error ('Contract with such contract number does not exist')
- check if contract is not in status 'TERMINATED'
- in case of error return 409 error ('Can not update terminated contract')
- 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.
- in case of error return 422 error
- check submitted contract_type is the same as in existing contract with number =contract_number
- in case of error 409 ('Submitted contract_type does not correspond to previously created content`)
- in case it is reimbursement contract, check medical_program_id is the same
- in case of error 409 ('Submitted medical_program_id does not correspond to previously created content`)
- contract request number structure XXXX-1234-5678-C , where:
- Validate id_from is from dictionary CONTRACT_TYPE
- in case of error return 422 error ('Invalid contract type')
- 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 program_id( in case of reimbursement contract)- in case of error return 422 error ('There is an active contract. Contract number must be sent in request')
- For reimbursement contracts: Validate program with submitted id exists
- in case of error return 422 error ('Reimbursement program with such id does not exist ')
- For reimbursement contracts: Validate program with submitted id is an active program
- in case of error return 409 error ('Reimbursement program is not active')
- For reimbursement contracts: Validate program with submitted id has 'medication' type
- in case of error return 409 error ('Program with such id is not a reimbursement program')
- Validate contractor_payment_details:
- if payer_account not like
^UA[0-9]{22}$
or^UA[0-9]{27}$
-> MFO must be required
- if payer_account not like
Determine parent contract (optional)
In case contract request contains parameter '$.contract_number':
- find contract that matches transmitted '$contract_number':
- if there is no contract with specified contract number, return 422 error ('Contract with such contract number does not exist')
- if contract is in 'Terminated' status, return 409 error ('Can not update terminated contract')
- 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
- medical_program_id
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
Get url for contract request upload.
ParameterSourceaction 'GET' bucket 'CONTRACT_REQUEST' resource_id : CONTRACT_REQUEST_ID resource_name : INITIAL_CONTRACT_REQUEST timestamp :TIMESTAMP - Upload signed contract request to media storage