Enrollment Status Response Integration Point

This synchronous integration point services the other applications that require real-time enrollment data. The incoming request inquires about a person or object, including the time window and the insurance type the calling system is interested in. The payload and structure of the response message are configurable.

In the request, the calling system can (optionally) specify what kind of response is required. Each calling system can have its own response payload and structure. Each type of response is specified by an enrollment status response definition record. This integration point requires at least one such record to operate.

The following fields that need to be configured to set up an enrollment status response definition:

Table 1. Enrollment Status Response Integration Point
Field Description

Code

Uniquely identifies the enrollment status response definition

Description

The description of the enrollment status response definition

Response Mapping

The dynamic logic that is executed to generate the response message for the external system

Default?

Indicates that this is the default enrollment status response definition (only one enrollment status response definition can be marked as default)

Once the definition is setup and the function dynamic logic implemented, the external system can request the enrollment data for one or more persons or objects by sending a POST request with query parameters containing the information of a person or object code along with the start-date and end-date and insurance-type for which the policy enrollment information is desired.

When calling the enrollment status response end-point, the requesting system can pass along the responseDefinitionCode as an accept header parameter.

Oracle Health Insurance stores the relation code with a copy of each relation and a list of relation identifiers. The person’s code that is passed along with the request is matched against the relation code and (enabled) relation identifiers.

Request example:

POST http://[hostName]:[portNumber]/[api-context-root]/enrollments/search

Request body
<enrollments insurableEntityType="usageName" insurableEntityCode="person or object's code" identifierTypeCode="relation identifier type" insuranceTypeCode="insuranceTypeCode" startDate="startDate" endDate="endDate"/>

Once the request is acknowledged, the system processes the request and generates the response based on the details of the enrollment status response definition. If no responseDefinitionCode is specified in the URL, then the response is created as per the default enrollment status response definition. This response is then sent to the external system.

Error Processing

The following error messages that are specific to the enrollment response integration point may be returned in the response message:

Table 2. Error Processing
Code Severity Message

POL-IP-POEN-001

Fatal

Enrollment Status Response Definition code {0} is unknown

POL-IP-POEN-002

Fatal

Enrollment Status Response Definition code is not specified in the request and no code is set as default

In case of a processing error like an error in executing the function dynamic logic, the error response, as described in the Developer Guide, is sent to the external system.

In case of other errors, for example the combination of insurable entity type and code is unknown, whether an error should be reported or not in the response is determined by the function dynamic logic. The system does not detect them as error conditions. The system will send the response in the structure returned by the function dynamic logic as a success response.

If the function dynamic logic returns empty (null) response; the integration point sends HTTP Response code 204 (No Content).

Example 1: Policy Without Contract Period

Consider the following enrollment status response:

<enrollment>
  <families>
   <family
      code=""
      startDate=""
    />
  </families>
 <products>
   <product
      code=""
      startDate=""
      endDate=""
      contractDate=""
      factor="">
      <parameters>
        <parameter
          aliasCode=""
          startDate=""
          endDate=""
          percentage=""
          number=""
          serviceDays="">
          <parameterAmount/>
        </parameter>
      </parameters>
      <providerGroups>
        <providerGroup
          assignmentLabel=""
          providerGroupCode=""
          startDate=""
          endDate=""
        />
      </providerGroups>
    </product>
  </products>
</enrollment>

The <balance/> and <parameterAmount/> elements are Money objects including an amount and a currency.

The following pseudo code represents the 'Enrollment Status Response Definition' logic that generated the message:

// The insurable person and its policy enrollment product details can be obtained by using
// the predefined method getEnrollmentProducts

def calculateFactor(Date startDatePeriod, Date endDatePeriod) {
    return Math.min(1D, ((endDatePeriod - startDatePeriod) + 1) / 365).round(6)
}
def writer = new StringWriter()
def XMLresponse = new groovy.xml.MarkupBuilder(writer)

XMLresponse.enrollment( lineOfBusiness: lineOfBusinessCode
                      , startDate: startDate
                      , endDate: endDate
                      ) {
   products{
       getEnrollmentProducts(insurableEntityType, insurableEntityCode, identifierTypeCode, startDate, endDate).each { pep ->

           if (pep.policyEnrollment.policy.lineOfBusiness.code != lineOfBusinessCode) {
               return
           }
           pep.getDerivedEnrollmentProduct().enrollmentProductDetailList.each { enrollmentProductDetail ->
               def startDatePeriod = pep.startDate < startDate ? startDate : pep.startDate
               def endDatePeriod = pep.endDate == null || pep.endDate > endDate ? endDate : pep.endDate
               product(code: enrollmentProductDetail.product.code
                       , startDate: startDatePeriod
                       , endDate: endDatePeriod
                       , contractDate: pep.startDate
                       , factor: calculateFactor(startDatePeriod, endDatePeriod)
                       ) {
                    parameters{
                        parameterList = []
                        pep.parameterValueList.each{ pav ->
                            if (pav.amount!=null) {
                                parameter( aliasCode: pav.parameterAlias.code
                                         , startDate: pav.startDate
                                         , endDate  : pav.endDate
                                         ){
                                   parameterAmount( pav.amount.amount
                                                  , currency: pav.amount.currencyCode
                                                  )
                                }
                            } else{
                                parameter( aliasCode: pav.parameterAlias.code
                                         , startDate: pav.startDate
                                         , endDate  : pav.endDate
                                         , percentage: pav.percentage
                                         , serviceDays: pav.serviceDays
                                         , numberOfUnits: pav.numberOfUnits
                                         )
                            }
                            parameterList.add(pav.parameterAlias.code)
                        }
                    }
                }
            }
           pep.policyAddOnList.each{ policyAddon->
                policyAddon.addOn.addOnDetailList.each{ addonProductDetail->
                    product( code: addonProductDetail.product.code
                           , startDate: policyAddon.startDate < startDate ? startDate : policyAddon.startDate
                           , endDate: policyAddon.endDate == null || policyAddon.endDate > endDate ? endDate : policyAddon.endDate
                           , contractDate: pep.startDate
                           )
                }
            }
        }
    }
}
return writer.toString()

Example 2: Policy With Contract Periods

Consider the following enrollment status response:

<enrollment>
  <families>
   <family
      code=""
      startDate=""/>
  </families>
 <products>
   <product
      code=""
      startDate=""
      endDate=""
      contractDate=""
      contractEndDate=""
      factor="">
      <parameters>
        <parameter
          aliasCode=""
          startDate=""
          endDate=""
          percentage=""
          number=""
          serviceDays="">
          <parameterAmount/>
        </parameter>
      </parameters>
      <providerGroups>
        <providerGroup
          assignmentLabel=""
          providerGroupCode=""
          startDate=""
          endDate=""
        />
      </providerGroups>
    </product>
  </products>
</enrollment>

The <balance/> and <parameterAmount/> elements are Money objects including an amount and a currency.

The following pseudo code represents the 'Enrollment Status Response Definition' logic that generated the message:

// The insurable person and it's policy enrollment product details can be obtained by using the predefined method getEnrollmentProducts
/**
 * @returns the factor calculated based on the number of days that the policy is active, capped at maximum 1.0
 */
def calculateFactor(Date startDatePeriod, Date endDatePeriod) {

    return Math.min(1D, ((endDatePeriod - startDatePeriod) + 1) / 365).round(6)
}

def writer = new StringWriter()

def XMLresponse = new groovy.xml.MarkupBuilder(writer)
XMLresponse.enrollment( insuranceType: insuranceTypeCode
                      , startDate: startDate
                      , endDate: endDate
                      ) {
   products{
       getEnrollmentProducts(insurableEntityType, insurableEntityCode, identifierTypeCode, startDate, endDate).each { pep ->

           if (pep.policyEnrollment.policy.insuranceType.code != insuranceTypeCode) {
               return
           }
           pep.getDerivedEnrollmentProduct().enrollmentProductDetailList.each { enrollmentProductDetail ->
               def startDatePeriod = pep.startDate < startDate ? startDate : pep.startDate
               def endDatePeriod = pep.endDate == null || pep.endDate > endDate ? endDate : pep.endDate
               product(code: enrollmentProductDetail.product.code
                       , startDate: startDatePeriod
                       , endDate: endDatePeriod
                       , contractDate: pep.startDate
                       , factor: calculateFactor(startDatePeriod, endDatePeriod)
                       ) {
                    parameters{
                        parameterList = []
                        pep.parameterValueList.each{ pav ->
                            if (pav.amount!=null) {
                                parameter( aliasCode: pav.parameterAlias.code
                                         , startDate: pav.startDate
                                         , endDate  : pav.endDate
                                         ){
                                   parameterAmount( pav.amount.amount
                                                  , currency: pav.amount.currencyCode
                                                  )
                                }
                            } else{
                                parameter( aliasCode: pav.parameterAlias.code
                                         , startDate: pav.startDate
                                         , endDate  : pav.endDate
                                         , percentage: pav.percentage
                                         , serviceDays: pav.serviceDays
                                         , numberOfUnits: pav.numberOfUnits
                                         )
                            }
                            parameterList.add(pav.parameterAlias.code)
                        }
                    }
                }
            }
            pep.policyAddOnList.each{ policyAddon->
                policyAddon.addOn.addOnDetailList.each{ addonProductDetail->
                    product( code: addonProductDetail.product.code
                           , startDate: policyAddon.startDate < startDate ? startDate : policyAddon.startDate
                           , endDate: policyAddon.endDate == null || policyAddon.endDate > endDate ? endDate : policyAddon.endDate
                           , contractDate: pep.startDate
                           )
                }
            }
        }
    }
}
return writer.toString()
// The policy enrollment product details can be obtained by using the predefined method getPolicyEnrollmentProducts

/**
 * @return the factor calculated based on the number of days that the policy is active, capped at maximum 1.0
 */
def calculateFactor(Date startDatePeriod, Date endDatePeriod) {

    if (endDatePeriod == null) {
        return 1
    } else {
        return Math.min(1D, ((endDatePeriod - startDatePeriod) + 1) / 365).round(6)
    }
}

def insurableEntity = lookUpInsurableEntity(insurableEntityCode, insurableEntityType)
peps = insurableEntity?.getPolicyEnrollmentProducts(null, null)

def writer = new StringWriter()
def XMLresponse = new groovy.xml.MarkupBuilder(writer)
XMLresponse.enrollment() {
  families {
    family.code = peps.policyEnrollment.policy.code.first()
    family.startDate = startDate
  }

  products {
    peps.each{ pep ->

      if (pep.policyEnrollment.policy.insuranceType.code != insuranceTypeCode) {
          return
      }

      def startDatePeriod = pep.startDate
      def endDatePeriod = pep.endDate
      def contractStartDatePeriod = pep.startDate
      def contractEndDatePeriod = pep.endDate

      /**
        *Fetching the contract period in which the product starts
      **/
      PolicyContractPeriod ctr = contractPeriods.each{ pcp ->
        if(pep.startDate >= pcp.startDate && pep.startDate <= pcp.endDate) {
            return pcp
        }
      }

      // if no contract is found for above, set it to the startDate and endDate of the PEP, by default.
      if(ctr!=null) {
        contractStartDatePeriod = (ctr.startDate >= pep.startDate) ? ctr.startDate : pep.startDate
        contractEndDatePeriod = (pep.endDate == null || (ctr.endDate <= pep.endDate)) ? ctr.endDate : pep.endDate
      }

      pep.getDerivedEnrollmentProduct().enrollmentProductDetailList.each{ enrollmentProductDetail->

        product( code: enrollmentProductDetail.product.code
               , startDate: startDatePeriod
               , endDate: endDatePeriod
               , contractDate: contractStartDatePeriod
               , contractEndDate: contractEndDatePeriod
               , factor: calculateFactor(startDatePeriod, endDatePeriod)
               ){
          parameters{
            parameterList = []
            pep.parameterValueList.each{ pav ->
              if(pav.amount!=null) {
                parameter( aliasCode: pav.parameterAlias.code){
                  parameterAmount( currency: pav.amount.currencyCode,
                                   pav.amount.amount
                                 )
                }
              }else{
                parameter( aliasCode: pav.parameterAlias.code
                         , percentage: pav.percentage
                         , serviceDays: pav.serviceDays
                         , numberOfUnits: pav.numberOfUnits
                         )
              }
              parameterList.add(pav.parameterAlias.code)
            }
            pep.groupAccountProduct?.parameterValueList.each{ pav ->
              if(!parameterList.contains(pav.parameterAlias.code)){
                if(pav.amount!=null) {
                  parameter( aliasCode: pav.parameterAlias.code){
                    parameterAmount( amount: pav.amount.amount
                                   , currencyCode: pav.amount.currencyCode
                                   )
                  }
                }else{
                  parameter( aliasCode: pav.parameterAlias.code
                           , percentage: pav.percentage
                           , serviceDays: pav.serviceDays
                           , numberOfUnits: pav.numberOfUnits
                           )
                }
               parameterList.add(pav.parameterAlias.code)
              }
            }
            pep.enrollmentProduct?.parameterValueList.each{ pav ->
              if(!parameterList.contains(pav.parameterAlias.code)){
                if(pav.amount!=null) {
                  parameter( aliasCode: pav.parameterAlias.code){
                    parameterAmount( amount: pav.amount.amount
                                   , currencyCode: pav.amount.currencyCode
                                   )
                  }
                }else{
                  parameter( aliasCode: pav.parameterAlias.code
                           , percentage: pav.percentage
                           , serviceDays: pav.serviceDays
                           , numberOfUnits: pav.numberOfUnits
                           )
                }
              }
            }

// Add a parameter to the parameterList for every balance that exists for the policy (at personal or policy level)
            personLevelBalance = getBalance(enrollmentProduct, pep.policyEnrollment.insurableEntity)
            if (personLevelBalanceBalance) {
                parameter( aliasCode: enrollmentProduct.enrollmentProductAccountDefinition.policyAccountDefinition.code.first()){
                   parameterAmount( amount: personLevelBalance.amount
                               , currencyCode: personLevelBalance.currencyCode
                               )
              }
            }
            policyLevelBalance = getBalance(enrollmentProduct, null)
            if (policyLevelBalance) {
            parameter( aliasCode: enrollmentProduct.enrollmentProductAccountDefinition.policyAccountDefinition.code.first()){
                   parameterAmount( amount: policyLevelBalance.amount
                                  , currencyCode: policyLevelBalance.currencyCode
                                  )
              }
          }
        }
      }

        providerGroups{
          pep.getProviderGroups(startDate, endDate).each{ pvg ->
            providerGroup( assignmentLabel: pvg.assignedProviderGroupLabel.code
                         , providerGroupCode: pvg.providerGroup.code
                         , startDate: startDatePeriod
                         , endDate: endDatePeriod
                         )
          }
        }

      pep.policyAddOnList.each{ policyAddon->
        policyAddon.addOn.addOnDetailList.each{ addonProductDetail->
             product( code: addonProductDetail.product.code
                    , startDate: policyAddon.startDate
                    , endDate: policyAddon.endDate
                    , contractDate: contractStartDatePeriod
                    , contactEndDate: contractEndDatePeriod
                    )
        }
      }
    }
  }
}
return writer.toString()
}