Enrollment Status Response Integration Point

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

In the request, the calling system can (optionally) specify what kind of response is required. Each calling system can have their 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 are configured to set up an enrollment status response definition:

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 GET request with query parameters containing the information of a person or object code along with the start date and end date and line of business 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.

Example:

GET
http:{__contextroot__}/{api-contextroot}/enrollments?insurableEntityType='<usageName>'&insurableEntityCode='<personor object's code>'&lineOfBusinessCode=<lineOfBusinessCode>&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 as per the default enrollment status response definition is created. 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:

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 cross area 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 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()
          , startDate: startDate
         )
  }

  products {
    peps.each{ pep ->

      if (pep.policyEnrollment.policy.lineOfBusiness.code != lineOfBusinessCode) {
          return
      }

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

        product( code: enrollmentProductDetail.product.code
               , startDate: pep.startDate
               , endDate: pep.endDate
               , contractDate: pep.startDate
               , 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: pep.startDate
                         , endDate: pep.endDate
                         )
          }
        }

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

Example 2: Policy with contract period(s)

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 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.lineOfBusiness.code != lineOfBusinessCode) {
          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, we should by default set it to the startDate and endDate of the PEP
      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()
}