Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Image Removed

Image Removed

Table of Contents

...

Anchor
Declaration Request JSON Schema
Declaration Request JSON Schema
Validate request

...


Validate request using JSON schema

JSON Schema
Code Block
languagexml
titleJSON Schema
collapsetrue
 {
  "$schema": "http://json-schema.org/draft-04/schema#",
  "definitions": {
    "phone": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enumdescription": [
"Dictionary: PHONE_TYPE"
           "MOBILE",
   },
        "LANDLINEnumber": {
         ] "type": "string",
      },
        "numberpattern": {
          "type": "string",
          "pattern": "^"^\\+38[0-9]{10}$"
        }
      },
      "required": [
        "type",
        "number"
      ],
      "additionalProperties": false
    },
    "addressname": {
      "type": "objectstring",
      "properties": {pattern": "^(?!.*[ЫЪЭЁыъэё@%&$^#])[a-zA-ZА-ЯҐЇІЄа-яґїіє0-9№\\\"!\\^\\*)\\]\\[(._-].*$"
    },
    "typeperson_name": {
          "type": "string",
  
       "enumpattern": "^(?!.*[ЫЪЭЁыъэё@%&$^#])[
     А-ЯҐЇІЄа-яґїіє\\'\\- ]+$",
      "RESIDENCEminLength": 1,
            "REGISTRATION"
          ]
   "maxLength": 255
    },
        "country"tax_id": {
          "type": "string",
        },"pattern": "^[0-9]{10}$",
        "areaminLength": {
   10,
      "typemaxLength": "string"255
    },
   }, "gender": {
      "regiontype": {
   "string",
      "typedescription": "stringDictionary: GENDER",
      "maxLength": 255
},    },
    "settlementaddress": {
  
       "type": "stringobject",
      "properties": {
},         "settlement_type": {
          "type": "string",
        },  "description": "Dictionary: ADDRESS_TYPE"
     "settlement_id   },
        "country": {
          "type": "string"
        },
        "street_typearea": {
          "type$ref": "string#/definitions/name",
        },
 "enum": [
            "BOULEVARDregion",: {
          "$ref": "STREET#/definitions/name",
            "AVENUE"},
        "settlement": {
  "SQUARE"           ]"$ref": "#/definitions/name"
        },
        "streetsettlement_type": {
          "type": "string",
        },  "description": "settlement type Dictionary: SETTLEMENT_TYPE"
        },
        "buildingsettlement_id": {
          "type": "string",
          "pattern": "^[0-9a-9f]{1,3}(([ \\-]{1})?(?![ЫЪЭЁыъэё])[А-ЯҐЇЄа-яґїє]{1})?((\\s)?(\\|/)(\\s)?[0-9]{1,3}(([ \\-]{1})?(?![ЫЪЭЁыъэё])[А-ЯҐЇЄа-яґїє]{1})?)?8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
        },
        "apartmentstreet_type": {
          "type": "string",
           },
  "description": "street type Dictionary: STREET_TYPE"
     "zip": {  },
        "typestreet": "string",{
          "pattern$ref": "^[0-9]{5}$#/definitions/name"
        }
    ,
 },       "requiredbuilding": [{
          "countrytype",
        "settlement_id",: "string",
          "buildingpattern":       ],"^[1-9]((?![ЫЪЭЁыъэё])()([А-ЯҐЇІЄа-яґїіє \\/\\'\\-0-9])){0,20}$"
      "additionalProperties": false },
   },     "documentapartment": {
          "type": "objectstring",
       "properties": { },
        "typezip": {
          "type": "string",
          "enumpattern": "^[0-9]{5}$"
        }
   "PASSPORT",      },
      "NATIONAL_IDrequired",: [
           "BIRTH_CERTIFICATE"type",
            "TEMPORARY_CERTIFICATE""country",
        "area",
 ]         }"settlement",
        "numbersettlement_type":,
{        "settlement_id"
  "type": "string"   ],
     } "additionalProperties": false
    },
 
    "requireddocument": [{
       "type": "typeobject",

       "numberproperties": {
     ],       "additionalPropertiestype": false{
     },     "authentication_methodtype": { "string",
          "typedescription": "object",Dictionary: DOCUMENT_TYPE"
       "properties": { },
        "typenumber": {
          "type": "string",
          "enumminLength": [ 1,
          "maxLength": 255
    "SMS",    },
        "SMSissued_TRUSTEEby",: {
          "type": "OFFLINEstring",
          "minLength": ]1
        },
        "phoneissued_numberat": {
          "type": "string",
          "patternformat": "^\\+38[0-9]{10}$""date"
        }
      },
      "required": [
        "type",
        "phone_number"
      ],
      "additionalProperties": false
 
  }   },
  "type": "object",
  "properties": {     "declarationdocument_requestrelationship": {
      "type": "object",
      "properties": {
        "start_datetype": {
          "type": "string",
          "formatdescription": "date-timeDictionary: DOCUMENT_RELATIONSHIP_TYPE",
          "descriptionminLength": "Should be defined on the client side."1
         },
        "end_datenumber": {
          "type": "string",
          "formatminLength": "date-time",1
        },
  "description": "Will be defined on eHealth side if it's not set." "issued_by": {
           }"type": "string",
          "personminLength": {1
          "type": "object",
},
         "propertiesissued_at": {
            "first_nametype": {
  "string",
           "typeformat": "stringdate"
          }
 },     },
       "last_namerequired": {[
        "type",
       "type": "stringnumber"
      ],
     }, "additionalProperties": false
     },
    "secondauthentication_namemethod": {
       
      "type": "stringobject",
      "properties": {
    },             "birth_date"type": {
  
           "type": "string",
   
          "formatdescription": "date-time"
  Dictionary: AUTHENTICATION_METHOD"
         },
   
        "birthphone_placenumber": {
 
            "type": "string"
            },

           "genderpattern": {"^\\+38[0-9]{10}$"
        }
     "type": "string",
    },
          "enumrequired": [
        "type"
       "MALE",],
      "additionalProperties": false
    }
  },
  "FEMALEtype": "object",
  "properties": {
    "declaration_request": {
   ]   "type": "object",
      "properties": {
},             "email"start_date": {
 
            "type": "string",
              "format": "emaildate-time",
          "description": "Should },be defined on the client side."
       "tax_id": {
  },
            "typeperson": "string",
   {
          "patterntype": "^[1-9]([0-9]{7}|[0-9]{9})$"object",
          "properties": {
},             "secretfirst_name": {
              "type": "string",
            },  "$ref": "#/definitions/person_name"
         "documents": {  },
            "typelast_name": "array",{
              "itemstype": {"string",
                "$ref": "#/definitions/document"
              }person_name"
            },
            "addressessecond_name": {
              "type": "arraystring",
              "items":
{                 "$ref": "#/definitions/addressperson_name"
            },
 }           "birth_date": {
 },             "phonestype": {"string",
              "typeformat": "array",date"
            },
            "itemsbirth_country": {
                "$reftype": "#/definitions/phone"string",
               }"minLength": 1,
            },  "maxLength": 255
         "authentication_methods": {  },
            "typebirth_settlement": "array",{
              "itemstype": {"string",
                "$ref": "#/definitions/authentication_methodname",
              }
"minLength": 1,
           },   "maxLength": 255
         "emergency_contact": {  },
            "typegender": "object",{
              "properties$ref": {"#/definitions/gender"
            },
   "first_name": {                   "type"email": "string"{
                }"type": "string",
                "last_nameformat": {
   "email",
              "typemaxLength": "string"
 255
              },
                "secondtax_nameid": {
 
                "type": "string",
              "$ref":  },"#/definitions/tax_id"
            },
            "phonesinvalid_tax_id": {
                  "type": "array",boolean"
            },
            "itemssecret": {
              "type": "string",
              "$ref": "#/definitions/phonename",
              "minLength": 6,
  }                 }"maxLength": 20
               },
 
            "requiredpreferred_way_communication": [{
              "type": "string",
   "first_name",           "enum": [
                "last_nameemail",
                "phonesphone"
              ]
            },
            "confidant_persondocuments": {
              "type": "objectarray",
              "propertiesminItems": {
1,
               "relation_typeitems": {
                  "type$ref": "string#/definitions/document",
              }
   "enum": [        },
            "TRUSTEEaddresses": {
              "type": "array",
 ]                 },"items": {
                "first_name$ref": {"#/definitions/address"
              },
      "type": "string"       "minItems": 2
        },    },
            "last_namephones": {
                  "type": "stringarray",
                },"items": {
                "second_name$ref": {"#/definitions/phone"
                  "type": "string"
   }
            },
 
              "birthauthentication_datemethods": {
 
                "type": "stringarray",
              "items": {
   "format": "date-time"             "$ref": "#/definitions/authentication_method"
              }
  },          },
            "birthemergency_placecontact": {
   
              "type": "stringobject",
              "properties": {
},                 "genderfirst_name": {
                  "type": "string",
                  "enum$ref": ["#/definitions/person_name"
                },
   "MALE",             "last_name": {
      "FEMALE"            "type": "string",
     ]             "$ref": "#/definitions/person_name"
                },
                "taxsecond_idname": {
                  "type": "string",
                  "pattern$ref": "^[1-9]([0-9]{7}|[0-9]{9})$#/definitions/person_name"
                },
                "documentsphones": {
                  "type": "array",
                  "items": {
                    "$ref": "#/definitions/documentphone"
                  },
                },
   "minItems": 1
              "phones": { }
              },
  "type": "array",           "required": [
      "items": {         "first_name",
           "$ref": "#/definitions/phone"    "last_name",
              }  "phones"
              }],
              },
"additionalProperties": false
             "required": [
  },
             "firstconfidant_nameperson",: {
              "type": "last_namearray",
              "items": {
"birth_date",                "type": "birth_placeobject",
                "genderproperties": {
             ],     "relation_type": {
          "description          "type": "string"Should,
be set if this Person is disabled, underage, etc."             },"enum": [
            "renewal_consent": {         "PRIMARY",
     "type": "boolean"             },   "SECONDARY"
         "patient_signed": {          ]
    "type": "boolean"             },
                  "disclosurefirst_consentname": {
                    "type": "booleanstring"
,
           },             "process_data_consent": {
  "$ref": "#/definitions/person_name"
           "type": "boolean"      },
      }           },
  "last_name": {
        "required": [            "type": "first_namestring",
            "last_name",            "$ref": "birth_date",#/definitions/person_name"
            "birth_place",      },
      "gender",
            "secretsecond_name": {
         ],           "descriptiontype": "Object that described a Patient. Confidant person should be set for disabled persons, underage persons, etc."
   "string",
                    "$ref": "#/definitions/person_name"
    },         "employee_id": {    },
      "type": "string",           "descriptionbirth_date": {
"Employee ID with `type=DOCTOR` selected from available Employees as a third contract party."         }"type": "string",
        "division_id": {           "typeformat": "stringdate",
             "description": "Registered Medical Service Provider Division},
identifier."         },         "legalbirth_entity_idcountry": {
                    "type": "string",
           "description": "Registered Medical Service Provider Division identifier."   "minLength": 1
    },         "scope": {    },
      "type": "string",           "enumbirth_settlement": [{
            "FAMILY DOCTOR"         "type": "string",
 ]         }       },   "$ref": "#/definitions/name",
                    "requiredminLength": [1
         "start_date",         "person"},
         "employee_id",         "division_id",gender": {
            "legal_entity_id",        "$ref": "scope#/definitions/gender"
      ]            },
    }
}

Authorize

    1. Verify the validity of access token
    2. Check user scope declaration_request:create in order to perform this action

Validate doctor

Image Removed

Get employee details

Invoke Get employee details

Validate Response $.data.employee_type == DOCTOR

Calculate patient age

Calculate patient age

Code Block
languagesql
age = MONTHS_BETWEEN (now(), $.declaration_request.person.birth_date) / 12

Check that doctor speciality meets the patient age requirements

Age requirements for doctor specialty

...

Check phone number

Validate phone number.

Invoke Check phone number WS in order to check phone number exists in DB

Code Block
languagexml
titleRequest example
curl -k -L 'http://ehealth.nebo15.com/api/otp_verifications/phone_number/+380508887700'

Search pending declaration requests

Search pending declarations in IL_DB.declaration_requests using patient's tax_id and filtered by employee_id to prevent requests duplication

Code Block
languagesql
WHERE IL_DB.declaration_requests.data.declaration_request.person.tax_id = :($.declaration_request.person.tax_id)
  AND IL_DB.declaration_requests.data.declaration_request.employee_id = :($.declaration_request.employee_id)
  AND IL_DB.declaration_requests.data.declaration_request.legal_entity_id = :($.declaration_request.legal_entity_id)
  AND IL_DB.declaration_requests.status IN ('NEW', 'APPROVED')

Cancel pending declaration requests

Change status of all found pending declarations to {CANCELED}. See available transitions

Code Block
languagesql
SET   IL_DB.declaration_requests.status = 'CANCELED'
WHERE IL_DB.declaration_requests.id IN (:LIST)

Save declaration request

Check and calculate declaration end date

If $.declaration_request.end_date is empty 

Code Block
languagesql
end_date = $.declaration_request.start_date + GLOBAL_PARAMETER('TERM')

Insert entity to IL_DB.declaration_request in {status} = NEW

Search MPI

Search patient in MPI using personal information

...

first_name

...

last_name

...

Code Block
languagexml
titleSample request
curl -k -L 'http://ehealth.nebo15.com/api/persons?first_name=Олена&last_name=Пчілка&birth_date=1991-08-19&tax_id=3126509816&phone_number=%2B380508887700'

Determine default auth method for new MPI

In case MPI not found

Invoke Gandalf API to determine Default auth method

Service description

Code Block
languagejs
themeMidnight
titleRequest example
linenumberstrue
collapsetrue
{
  "phone_availability": true,
  "preferable_auth_method": "OTP_TRUSTEE"
}

Determine preferable auth method for existing MPI

In case MPI found

Get auth method, channel from Search MPI response

Save auth method to request

Update request object in IL_DB.declaration_request with auth method in order to resend sms if needed in future

Code Block
languagesql
SET   IL_DB.declaration_request.authentication_method_current = Search MPI Response $.data.authentication_method
WHERE IL_DB.declaration_request.id = :id

Generate printout form

Invoke Man Template Rendering Service to obtain printout form. Service description

Request parameters

...

Save printout to IL_DB.declaration_request

Code Block
languagesql
SET   IL_DB.declaration_request.printout_content = Man Response $.data
WHERE IL_DB.declaration_request.id = :id

Generate upload URL

Get environment parameter DECLARATION_REQUEST_OFFLINE_DOCUMENTS

Generate FILE_NAME for each document in DECLARATION_REQUEST_OFFLINE_DOCUMENTS

Invoke Media Content Storage to generate upload URL for each document in DECLARATION_REQUEST_OFFLINE_DOCUMENTS

Save all DECLARATION_REQUEST_OFFLINE_DOCUMENTS to declaration request

Code Block
languagesql
SET   IL_DB.declaration_request.documents = :documents
WHERE IL_DB.declaration_request.id = :id

Documents structure

Code Block
languagexml
{
   "documents":[
      {
         "type":"PASSPORT"
      }
   ]
}

Generate verification code

Invoke Initialize OTP Verification

...

              "tax_id": {
                    "type": "string",
                    "$ref": "#/definitions/tax_id"
                  },
                  "secret": {
                    "type": "string",
                    "$ref": "#/definitions/name",
                    "minLength": 6
                  },
                  "documents_person": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/definitions/document"
                    }
                  },
                  "documents_relationship": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/definitions/document_relationship"
                    }
                  },
                  "phones": {
                    "type": "array",
                    "items": {
                      "$ref": "#/definitions/phone"
                    }
                  }
                },
                "required": [
                  "relation_type",
                  "first_name",
                  "last_name",
                  "birth_date",
                  "birth_country",
                  "birth_settlement",
                  "gender",
                  "secret",
                  "documents_person",
                  "documents_relationship"
                ],
                "additionalProperties": false
              },
              "description": "Should be set if this Person is disabled, underage, etc."
            },
            "patient_signed": {
              "type": "boolean",
              "enum": [
                false
              ]
            },
            "process_disclosure_data_consent": {
              "type": "boolean",
              "enum": [
                true
              ]
            }
          },
          "required": [
            "first_name",
            "last_name",
            "birth_date",
            "birth_country",
            "birth_settlement",
            "gender",
            "secret",
            "documents",
            "addresses",
            "authentication_methods",
            "emergency_contact",
            "patient_signed",
            "process_disclosure_data_consent"
          ],
          "additionalProperties": false,
          "description": "Object that described a Patient. Confidant person should be set for disabled persons, underage persons, etc."
        },
        "employee_id": {
          "type": "string",
          "minLength": 36,
          "description": "Employee ID with `type=DOCTOR` selected from available Employees as a third contract party."
        },
        "division_id": {
          "type": "string",
          "minLength": 36,
          "description": "Registered Medical Service Provider Division identifier."
        },
        "scope": {
          "type": "string",
          "minLength": 1
        },
        "seed": {
          "type": "string"
        },
        "overlimit": {
          "type": "boolean",
          "enum": [
            false
          ]
        }
      },
      "required": [
        "person",
        "employee_id",
        "division_id",
        "scope"
      ],
      "additionalProperties": false
    }
  }
}


Authorize

    1. Verify the validity of access token

    2. Check user scope declaration_request:create in order to perform this action

Validate Legal Entity Type

Validate legal entity from token:  legal_entities.type should be in DECLARATION_REQUEST_LEGAL_ENTITY_TYPES and legal_entities.status =='active' 

Validate doctor

...

Get employee details

Invoke Get employee details

Validate Response $.data.employee_type == DOCTOR

Calculate patient age

Calculate patient age

Code Block
languagesql
age = MONTHS_BETWEEN (now(), $.declaration_request.person.birth_date) / 12

Get global parameters

Invoke Global parameters to get following parameters:

  • ADULT_AGE

  • DECLARATION_TERM

  • phone_number_auth_limit


cURL example
Code Block
languagesql
curl -X GET \
  {:host}/prm/api/global_parameters


Response example
Code Block
languagejs
{
  "meta": {
    "url": "http://api-svc.prm/api/global_parameters",
    "type": "object",
    "request_id": "ikff7hcf0hhto5c06irl9i976kc3s41m",
    "code": 200
  },
  "data": {
    "verification_request_expiration": "30",
    "employ_request_expiration": "30",
    "declaration_term": "30",
    "declaration_request_expiration": "30",
    "billing_date": "2",
    "adult_age": "18",
    "type": "global_parameter"
  }
}


Check that doctor speciality meets the patient age requirements

  1. Get doctor's speciality_officio (speciality object where speciality_officio == true)

  2. Check age requirements according to global parameters

Speciality officio

Age

FAMILY DOCTOR

All ages

THERAPIST

Greater or equal to $.data.adult_age

PEDIATRICIAN

Less than $.data.adult_age

Check phone number

Invoke Check phone number WS in order to check phone number exists in DB.

Phone number: $.declaration_request.person.phones.[0].number

cURL example
Code Block
languagexml
curl -k -L '{:host}/verifications/+380508887700'


Successful response example
Code Block
languagejs
{
    "meta": {
        "url": "http://dev.ehealth.world/verifications/+380936235985",
        "type": "object",
        "request_id": "b98ie5d0j3fn7vcbbmksa4k45ptue2ca",
        "code": 200
    },
    "data": {
        "phone_number": "+380936235985"
    }
}


Failed response example
Code Block
languagejs
{
    "meta": {
        "url": "http://dev.ehealth.world/verifications/+380936235986",
        "type": "object",
        "request_id": "b4adrhrj5og9ogqanb57dqj0v1qkbb9j",
        "code": 404
    },
    "error": {
        "type": "not_found"
    }
}


Search pending declaration requests

Search declarations in IL_DB.declaration_requests to prevent requests duplication:

  • if tax_id is not null

Code Block
languagesql
WHERE IL_DB.declaration_requests.data.person.tax_id = :($.declaration_request.person.tax_id)
  AND IL_DB.declaration_requests.data.person.documents.number = :($.declaration_request.person.documents.number)
  AND IL_DB.declaration_requests.status IN ('NEW', 'APPROVED')
  • if tax_id is null

Code Block
WHERE IL_DB.declaration_requests.data.person.documents.number = :($.declaration_request.person.documents.number)
  AND IL_DB.declaration_requests.data.person.first_name = :($.declaration_request.person.first_name)
  AND IL_DB.declaration_requests.data.person.last_name = :($.declaration_request.person.last_name)
  AND IL_DB.declaration_requests.status IN ('NEW', 'APPROVED')


Cancel declaration requests

Change status of all found declarations:

Code Block
languagesql
SET   IL_DB.declaration_requests.status = 'CANCELED'
WHERE IL_DB.declaration_requests.id IN (:LIST)

Search pending declaration requests

Search persons request inIL_DB.person_requests to prevent requests duplication:

  • if tax_id is not null

Code Block
languagesql
WHERE IL_DB.person_requests.data.tax_id = :($.declaration_requests.person.tax_id)
  AND IL_DB.person_requests.status IN ('NEW', 'APPROVED')


  • if tax_id is null

Code Block
languagesql
WHERE IL_DB.person_requests.data.documents.number = :($.declaration_requests.person.documents.number)
  AND IL_DB.person_requests.status IN ('NEW', 'APPROVED')


If found person request - don't create person request. Return error "This person already has a person request"

Calculate declaration end/start date

Declaration 

Start date:

Code Block
start_date = Current_date()

Anchor
end_date
end_date
End date:

Code Block
if (person.age < 18)&(doctor.speciality = PEDIATRICIAN) {
  end_date = min(birth_date + 18y - 1d, start_date + declaration_term);
} else {
  end_date = start_date + declaration_term;
}


Validate confidant person

If person age < 14 check existence of confidant_person

 - in case error return 422 - msg "Confidant person is mandatory for children"

Save declaration request

Insert record to IL.declaration_request in status 'NEW'

Check "no_tax_id" flag

  • If "no_tax_id"= true, tax_id field should be empty, in case error return 422

  • If "no_tax_id"=false and age>14, tax_id should be present, in case error return 422

Validate person_id

USE_DEDUPLICATION_MODEL - is a flag in in ehealth.charts that turn on logic:

If person.id is in request then 

  • validate person.id is UUID

    • in case error return 422

  • search person by person.id in MPI 

    • in case error return 422, "such person doesn't exist"

  • search persons in mpi (Пошук персон. Версія 3)

    • If new person's tax_id and authentication_number match with founded person by passed person.id - add mpi_id to declaration request

      • else validate person be deduplication model (if score >  PERSON_ONLINE_DEDUPLICATION_MATCH_SCORE, then add mpi_id to declaration request)

        • else return error 409, "such person can't be updated. New person should be created instead"

If person.id is not in request then 

  • search persons in mpi (Пошук персон. Версія 3)

    • If we found person by tax_id and authentication_number

      • return error 409, "such person exists. Update this person."

    • In case authentication_method = OFFLINE, or don't found authentication_number, or we found authentication_number but tax_id don't match - We create pairs of new person with people from cluster and send to the model.

      • in case deduplication model gave score <  PERSON_ONLINE_DEDUPLICATION_MATCH_SCORE, create new person

      • else return error 409, "such person exists. Update this person.

Validate phone number limit

USE_PHONE_NUMBER_AUTH_LIMIT is a flag in ehealth.charts that shows whether we count phones or not.

  • in case person is found, person_id will be saved to declaration_request, and person has the same authentication_methods.phone_number, we do not count phone numbers and do not compare the phone number with global_parameters.phone_number_auth_limit. So that we can update person, but still can not use phone over limit.

  • In case person is not found

    • Check if (SELECT count(*) from persons where authentication_methods::json->0->>'phone_number'='$.phone_number' and persons.status='active' and is_active=true)<global_parameters.phone_number_auth_limit
      in case error return 422, msg "This phone number is present more then $.global_parameters.phone_number_auth_limit times in the system"

Validate declaration limit

  1. Count all declarations in status active where OPS.declarations.employee_id==$.declaration_request.employee_id
    1.1 If there is an active declaration with the current person, exclude it from the selection in order to let doctor resign declaration with current patient

  2. Count all declaration_requests in status approved where IL.declaration_requests.data($.employee.id) ==$.declaration_request.employee_id

  3. Get all specialities of current doctor

    1. Select speciality from PRM.employees where PRM.employees.party_id == (select PRM.employees.party_id where PRM.employees.id=$.declaration_request.employee_id)

  4. Select config parameter for declarations_limit where speciality == select 3 

  5. Compare the result of selections 1+2 with the lowest config parameter from select 4. In case count (declarations+declaration_requests )> config_parameter, return 409 "The employee has reached the declaration limit"

Validate person authentication phone

USE_DEDUPLICATION_MODEL - is a flag in in ehealth.charts that turn on logic:

If person have confidant_person, then person.auth_phone = person.confident_person.phone

  • in case error return 422 - msg "Person must have same phone as the confidant person"

Validate person documents

  1. issued_at, issued_by is mandatory for documents

  2. Validate dates

    1. issued_at <= now() and issued_at => birth_date

      1.  in case `issued_at > now()` show error 422, "Document issued date should be in the past"

      2.  in case `issued_at < person.birth_date` show error 422, "Document issued date should greater than person.birth_date "

    2. expiration_date > now()

      1.  in case error show 422, "Document expiration_date should be in future"

      2. expiration_date is mandatory for document_type

        • NATIONAL_ID

        • COMPLEMENTARY_PROTECTION_CERTIFICATE

        • PERMANENT_RESIDENCE_PERMIT

        • REFUGEE_CERTIFICATE

        • TEMPORARY_CERTIFICATE

        • TEMPORARY_PASSPORT

      3. in case error return 422, "expiration_date is mandatory for document_type $.documents.type"

  3. Validate documents_type.number according to json schema 

    1. PASSPORT - `^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$`

    2. NATIONAL_ID - `^[0-9]{9}$`

    3. BIRTH_CERTIFICATE - ` ^(?![ЫЪЭЁыъэё@%&$^#`~:,.*|}{?!])[A-ZА-ЯҐЇІЄ0-9№\\/()-]+$ `

    4. COMPLEMENTARY_PROTECTION_CERTIFICATE - `^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$`

    5. PERMANENT_RESIDENCE_PERMIT - `^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$`

    6. REFUGEE_CERTIFICATE - `^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$`

    7. TEMPORARY_CERTIFICATE - `^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$`

    8. TEMPORARY_PASSPORT - `` ^(?![ыъэ@%&$^#`~:,.*|}{?!])[А-ЯҐЇІЄа-яґїіє0-9 №\\\"()-]+$ `

  4. if `unzr`exists and is not null and matches "^[0-9]{8}-[0-9]{5}$" check if first 8 symbols = birth_date

    1. in case error return 422, msg "unzr or birthdate are not correct"

  5. if documents.type=NATIONAL_ID

    1. check if unzr exists in request, in case error return 422, msg "unzr is mandatory for document type NATIONAL_ID"

  6. Document numbersmaxLength < 25 

Determine auth method

Determine Channel

  1. channel from url

    1. if url is for cabinet сhannel set declaration_request.сhannel = CABINET

      1. if not - set declaration_request.сhannel = MIS


Generate printout form

Invoke MAN to render print form.

Request mapping:

Parameter

Source

id

DECLARATION REQUEST


cURL example
Code Block
languagejs
curl --request POST \
     --header 'Accept: text/html' \
     --header 'Content-Type: application/json' \
     {:host}/templates/{:declaration_printout_id}/actions/render


Set IL.declaration_request.printout_content:

Code Block
languagesql
MANResponse.$.data


Generate upload URL

Depending on the payload system generates list of signed urls for document scan-copies upload.

Signed URLs to be expired after some period of time (configurable `SECRETS_TTL`). If it has been expired - new declaration request should be created.

Each link is generated for one one-page document in jpeg format. Document should be no more than 10MB.


For On-line

  1. if no_tax_id = true

    1. Generate URL with type person.no_tax_id

For Offline

1. If $.declaration_request.person.tax_id not null:

  • Generate URL with type person.tax_id

2. For each $.declaration_request.person.documents:

  • Generate URL's with type person.{$.declaration_request.person.documents.[:].type}

3. If $.declaration_request.person.confidant_person.[:].tax_id not null, for each:

  • Generate URL with type confidant_person.{confidant_person.type}.tax_id

4. For each $.declaration_request.person.confidant_person.[:].documents_person:

  • Generate URL's with type confidant_person.{confidant_person.type}.{$.declaration_request.person.confidant_person.[:].documents_person.[:].type}

5. For each $.declaration_request.person.confidant_person.[:].documents_relationship:

  • Generate URL's with type confidant_person.{confidant_person.type}.{$.declaration_request.person.confidant_person.[:].documents_relationship.[:].type}

6.  If no_tax_id = true

  1. Generate URL with type person.no_tax_id

Invoke Media Content Storage to generate upload URL for each document obtained by executing logic above

IL.declaration_request.documents structure:


Code Block
languagexml
{
   "documents":[
      {
         "type":"person.tax_id",
		 "url": "https://storage.googleapis.com/..."
      }
   ]
}

Save documents to DB.

Generate verification code

Invoke Initialize OTP to generate one time password and send it to client number.

Phone_number: IL.declaration_request.authentication_method_current.$.authentication_number

cURL example
Code Block
languagejs
curl -X POST \
  http://localhost:4000/verifications \
  -H 'content-type: application/json' \
  -d '{
  "phone_number": "+380936235985"
}'

Generate human readable declaration number

  • Use algorithm to generate declaration_number

  • Declaration number should consist of a 4 serial symbols and 8 number symbols and looks like XXXX-12H4-245D

  • Add field to ops.declarations and il.declaration_requests - declaration_number 

  • Add declaration_number to print out form

Validate uniqueness of human readable declaration number

  • generate declaration_number

  • Search declaration_number in declaration_requests.declaration_number

  • if exists = go to 'generate declaration_number'

  • else save declaration_number to declaration_request