Capture User Information

This section details how to capture user information, such as the following:

  • Verification of the user's State, Country, and the zip code where the user’s car is registered.

  • Obtaining location and other required permissions for IQL to track user trips.

This section includes the following topics:

Capture User Information

Capture User Information

Capture User Information

Capture User Information

Capture User Information

1.0. Capture User and Insurer Information

Use this section to know how to prompt users to provide their local zip code and use this information to obtain the user's State and Country information. You will need the user's zip code in order to verify whether any offers are available or not. We also recommend that you prompt the user to provide their current insurer information.

2.0. Validate IQL Test Drive Availability

After the user provides their zip code and their current insurer's details, you need to check with IQL backend for the insurer's test drive availability in that zip code area. Refer to the supportedState Details API endpoint to know how to obtain this information.

class GetSupportedInsurerUseCase(
   private val repository: InsurerAvailabilityRepository,
   private val dispatcher: CoroutineDispatcher
) {

   operator fun invoke(
       countryCode: String,
       stateCode: String,
       insurerName: String
   ): Flow<InsurerSupportedStatus> = flow {
       Timber.d("CountryCode $countryCode, StateCode $stateCode, InsurerName $insurerName")

       val payload = RequestInsurerAvailable(
           countryCode = countryCode,
           stateCode = stateCode,
           currentInsurer = insurerName
       )
       emit(repository.insurerAvailabilityStatus(payload))
   }.flowOn(dispatcher)
}


interface InsurerAvailabilityRepository {
   suspend fun insurerAvailabilityStatus(payload: RequestInsurerAvailable): InsurerSupportedStatus
}

class InsurerAvailabilityRepositoryImpl(private val api: Api) : InsurerAvailabilityRepository {

   override suspend fun insurerAvailabilityStatus(payload: RequestInsurerAvailable): InsurerSupportedStatus {
       when (val response = api.supportedInsurerStateDetails(payload)) {
           is ApiResponse.Success -> {
               Timber.d("Insurer Capture success data ${response.data}")
               return Success(response.data, statusCode = 200)
           }
           is ApiResponse.Failure -> {
               Timber.e("Insurer Capture failure data ${response.failure}")

               return when (response.failure.errorCode) {
                   400 -> {
                       BadRequest(response.failure.message, statusCode = 400)
                   }
                   404 -> {
                       NotFound(response.failure.message, statusCode = 404)
                   }
                   422 -> {
                       UnProcessableEntity(response.failure.message, statusCode = 422)
                   }
                   else -> {
                       return Unknown(response.failure.message, statusCode = 500)
                   }
               }
           }
           is ApiResponse.Error -> {
               Timber.e(response.throwable, "Insurer Capture error data")
               return Unknown(throwable = response.throwable, statusCode = 500)
           }
           else -> {
               return Unknown(statusCode = 500)
           }
       }
   }
}

class Api(private val apiService: ApiService) {


   suspend fun supportedInsurerStateDetails(payload: RequestInsurerAvailable): ApiResponse<InsurerSupportedResponse> {
       return try {
           val resp = apiService.getSupportedStateDetailsOfInsurer(payload)
           if (resp.isSuccessful) {
               ApiResponse.Success(data = resp.body()!!)
           } else {
               ApiResponse.Failure(FailureResponse(resp.errorBody()?.string(), resp.code()))
           }
       } catch (io: IOException) {
           ApiResponse.Error(io)
       } catch (http: HttpException) {
           ApiResponse.Error(http)
       } catch (e: Exception) {
           ApiResponse.Error(e)
       }
   }

}

3.0. Integrate IQL DriverInfo Endpoint

Update the zip code, state, country and current insurer information to the IQL backend through the following API endpoint.

driverInfo Endpoint

class EnterZipCodeFragment : Fragment(R.layout.fragment_enter_zip_code) {
   ...
   ...
   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
       super.onViewCreated(view, savedInstanceState)
       ...
       ...
       viewLifecycleOwner.lifecycleScope.launch {
           viewModel.insurerAvailableFlow
               .flowWithLifecycle(lifecycle, Lifecycle.State.CREATED)
               .distinctUntilChanged()
               .collectLatest {
                   if (it is com.zendrive.iqlref.core.currentInsurer.state.Success) {
                       handleSupportedStateApiSuccess(it)
                   } else {
                       handleSupportedStateApiError(it)
                   }
               }
       }
       ...
       ...
   }
   ...
   ...

   private fun handleSupportedStateApiSuccess(it: com.zendrive.iqlref.core.currentInsurer.state.Success) {
       if (it.data.canReceiveOffer && it.data.isSupportedState) {
           driverInfo.apply {
               insurer = binding.editTextCurrentInsurer.text.toString()
           }
           callDriverInfoApi()
       } else {
           showNoProgrammeBottomSheet()
       }
   }

   private fun callDriverInfoApi() {
       viewModel.sendDriverInfo(driverInfo) { result ->
           when (result) {
               is ApiResponse.Success -> {
                   viewModel.saveUpdatedUserDetails(driverInfo)
                   viewModel.driverInfoState.postValue(
                       viewModel.driverInfoState.value?.copy(
                           updateDriverInfoStatus = Success
                       )
                   )
                   Timber.d("post driver info response success for user  ${result.data}")
               }
               is ApiResponse.Failure -> {
                   Timber.e("post driver info response failed for user  ${result.failure}")
                   viewModel.driverInfoState.postValue(
                       viewModel.driverInfoState.value?.copy(
                           updateDriverInfoStatus = Failure(result.failure.message)
                       )
                   )
                   showToastMessage(result.failure.message)
               }
               is ApiResponse.Error -> {
                   Timber.e("post driver info response error for user ${result.throwable}")
                   showToastMessage(result.throwable.message)
               }
           }
       }
   }
}

4.0. IQL Reference Application UX Design

Here is the overall design implementation for the IQL Reference Application:

5.0. Publisher Testing Integration Checklist

Use the following testing checklist to test the capture user information experience:

  • Zip Code Validity:Ensure that only valid zip codes are accepted, and that the corresponding state information is returned. In case of an invalid code, display an error message to inform the user.

  • Current Insurer: Ensure that a list of insurers is displayed for the user to select their current insurer. If their current insurer is not listed, make sure to provide an 'Other' option for them to select.

  • Program Availability: If the program availability is based on zip code and current insurer information, ensure that the 'Program Unavailable' message is displayed for unsupported zip codes and insurer combinations. If the program is indeed available, then ensure that the user is able to move forward.