// welcomeMessagePromptFlag
  private String validateCallDetailsMobileKunjiElements(
      CallDetailRecordRequest callDetailRecordRequest) {
    StringBuilder failureReasons = new StringBuilder();

    if (null == callDetailRecordRequest.getWelcomeMessagePromptFlag()) {
      failureReasons.append(String.format(NOT_PRESENT, "welcomeMessagePromptFlag"));
    }

    return failureReasons.toString();
  }
  // (callStartTime, callEndTime, callDurationInPulses, endOfUsagePromptCount, callStatus,
  // callDisconnectReason)
  private String validateCallDetailsCommonElements(
      CallDetailRecordRequest callDetailRecordRequest) {
    StringBuilder failureReasons = new StringBuilder();

    if (null == callDetailRecordRequest.getCallStartTime()) {
      failureReasons.append(String.format(NOT_PRESENT, "callStartTime"));
    }

    if (null == callDetailRecordRequest.getCallEndTime()) {
      failureReasons.append(String.format(NOT_PRESENT, "callEndTime"));
    }

    if (null == callDetailRecordRequest.getCallDurationInPulses()) {
      failureReasons.append(String.format(NOT_PRESENT, "callDurationInPulses"));
    }

    if (null == callDetailRecordRequest.getEndOfUsagePromptCounter()) {
      failureReasons.append(String.format(NOT_PRESENT, "endOfUsagePromptCount"));
    }

    if (null == callDetailRecordRequest.getCallStatus()) {
      failureReasons.append(String.format(NOT_PRESENT, "callStatus"));
    }

    if (null == callDetailRecordRequest.getCallDisconnectReason()) {
      failureReasons.append(String.format(NOT_PRESENT, "callDisconnectReason"));
    }

    return failureReasons.toString();
  }
  /**
   * 2.2.6 Save CallDetails API IVR shall invoke this API to send MA call details to MoTech.
   * /api/mobileacademy/callDetails
   *
   * <p>3.2.2 Save Call Details API This API enables IVR to send call details to NMS_MoTech_MK. This
   * data is further saved in NMS database and used for reporting purpose.
   * /api/mobilekunji/callDetails
   */
  @RequestMapping(
      value = "/{serviceName}/callDetails",
      method = RequestMethod.POST,
      headers = {"Content-type=application/json"})
  @ResponseStatus(HttpStatus.OK)
  @Transactional
  public void saveCallDetails(
      @PathVariable String serviceName,
      @RequestBody CallDetailRecordRequest callDetailRecordRequest) {
    Service service = null;
    StringBuilder failureReasons;

    if (!(MOBILE_ACADEMY.equals(serviceName) || MOBILE_KUNJI.equals(serviceName))) {
      throw new IllegalArgumentException(String.format(INVALID, "serviceName"));
    }

    failureReasons =
        validate(
            callDetailRecordRequest.getCallingNumber(),
            callDetailRecordRequest.getCallId(),
            callDetailRecordRequest.getOperator(),
            callDetailRecordRequest.getCircle());

    // Verify common elements
    // (callStartTime, callEndTime, callDurationInPulses, endOfUsagePromptCount, callStatus,
    // callDisconnectReason)
    failureReasons.append(validateCallDetailsCommonElements(callDetailRecordRequest));

    if (MOBILE_ACADEMY.equals(serviceName)) {
      service = Service.MOBILE_ACADEMY;
    }

    if (MOBILE_KUNJI.equals(serviceName)) {
      service = Service.MOBILE_KUNJI;

      // Verify MK elements (welcomeMessagePromptFlag)
      failureReasons.append(validateCallDetailsMobileKunjiElements(callDetailRecordRequest));
    }

    for (CallContentRequest callContentRequest : callDetailRecordRequest.getContent()) {
      failureReasons.append(validateCallContentRequest(service, callContentRequest));
    }

    if (failureReasons.length() > 0) {
      throw new IllegalArgumentException(failureReasons.toString());
    }

    FrontLineWorker flw =
        frontLineWorkerService.getByContactNumber(callDetailRecordRequest.getCallingNumber());
    if (null == flw) {
      throw new NotFoundException(String.format(NOT_FOUND, "callingNumber"));
    }

    createCallDetailRecord(flw, callDetailRecordRequest, service);

    // if this is the FLW's first time calling the service, set her status to ACTIVE
    if (flw.getStatus() == FrontLineWorkerStatus.INACTIVE) {
      flw.setStatus(FrontLineWorkerStatus.ACTIVE);
      frontLineWorkerService.update(flw);
    }
  }
  private void createCallDetailRecord(
      FrontLineWorker flw, CallDetailRecordRequest callDetailRecordRequest, Service service) {
    CallDetailRecord cdr = new CallDetailRecord();
    cdr.setFrontLineWorker(flw);
    cdr.setCallingNumber(callDetailRecordRequest.getCallingNumber());
    cdr.setCallId(callDetailRecordRequest.getCallId());
    cdr.setOperator(callDetailRecordRequest.getOperator());
    cdr.setCircle(callDetailRecordRequest.getCircle());
    cdr.setCallStartTime(
        new DateTime(callDetailRecordRequest.getCallStartTime() * MILLISECONDS_PER_SECOND));
    cdr.setCallEndTime(
        new DateTime(callDetailRecordRequest.getCallEndTime() * MILLISECONDS_PER_SECOND));
    cdr.setCallDurationInPulses(callDetailRecordRequest.getCallDurationInPulses());
    cdr.setEndOfUsagePromptCounter(callDetailRecordRequest.getEndOfUsagePromptCounter());
    cdr.setCallStatus(callDetailRecordRequest.getCallStatus());
    cdr.setCallDisconnectReason(callDetailRecordRequest.getCallDisconnectReason());

    if (service == Service.MOBILE_KUNJI) {
      cdr.setWelcomePrompt(callDetailRecordRequest.getWelcomeMessagePromptFlag());
    }

    callDetailRecordService.add(cdr);

    for (CallContentRequest callContentRequest : callDetailRecordRequest.getContent()) {
      CallContent content = new CallContent();

      content.setContentName(callContentRequest.getContentName());
      content.setContentFile(callContentRequest.getContentFileName());
      content.setStartTime(
          new DateTime(callContentRequest.getStartTime() * MILLISECONDS_PER_SECOND));
      content.setEndTime(new DateTime(callContentRequest.getEndTime() * MILLISECONDS_PER_SECOND));

      if (service == Service.MOBILE_KUNJI) {
        content.setMobileKunjiCardCode(callContentRequest.getMkCardCode());
      }

      if (service == Service.MOBILE_ACADEMY) {
        content.setType(callContentRequest.getType());
        content.setCompletionFlag(callContentRequest.getCompletionFlag());
      }

      content.setCallDetailRecord(cdr);

      callContentService.add(content);
    }
  }