private void createIvrAndSmsStatisticReport(
      CallDetailRecord initialRecord) { // NO CHECKSTYLE CyclomaticComplexity
    DateTimeFormatter motechTimestampFormatter =
        DateTimeFormat.forPattern(EbodacConstants.IVR_CALL_DETAIL_RECORD_TIME_FORMAT);
    DateTimeFormatter votoTimestampFormatter =
        DateTimeFormat.forPattern(EbodacConstants.VOTO_TIMESTAMP_FORMAT);

    String providerCallId = initialRecord.getProviderCallId();
    Map<String, String> providerExtraData = initialRecord.getProviderExtraData();

    if (StringUtils.isBlank(providerCallId)) {
      throw new EbodacReportException(
          "Cannot generate report for Call Detail Record with Motech Call Id: %s, because Provider Call Id is empty",
          "", initialRecord.getMotechCallId());
    }
    if (providerExtraData == null || providerExtraData.isEmpty()) {
      throw new EbodacReportException(
          "Cannot generate report for Call Detail Record with Motech Call Id: %s, because Provider Extra Data Map is empty",
          "", initialRecord.getMotechCallId());
    }

    String subjectIds = providerExtraData.get(EbodacConstants.SUBJECT_IDS);
    List<Subject> subjects = new ArrayList<>();

    if (StringUtils.isBlank(subjectIds)) {
      throw new EbodacReportException(
          "Cannot generate report for Call Detail Record with Motech Call Id: %s, because no ParticipantId found In Provider Extra Data Map",
          "", initialRecord.getMotechCallId());
    }

    for (String subjectId : subjectIds.split(",")) {
      Subject subject = subjectService.findSubjectBySubjectId(subjectId.trim());
      if (subject != null) {
        subjects.add(subject);
      } else {
        LOGGER.warn(
            "Cannot generate report for Provider Call Id: {} and ParticipantId: {}, because no Participant with this Id found",
            providerCallId,
            subjectId);
      }
    }

    if (subjects.isEmpty()) {
      throw new EbodacReportException(
          "Cannot generate report for Call Detail Record with Motech Call Id: %s, because No Participants found with Ids: %s",
          "", initialRecord.getMotechCallId(), subjectIds);
    }

    List<CallDetailRecord> callDetailRecords =
        callDetailRecordDataService.findByExactProviderCallId(
            providerCallId,
            QueryParams.ascOrder(EbodacConstants.IVR_CALL_DETAIL_RECORD_MOTECH_TIMESTAMP_FIELD));

    List<CallDetailRecord> failed = new ArrayList<>();
    List<CallDetailRecord> finished = new ArrayList<>();
    boolean sms = false;
    boolean smsFailed = false;
    String messageId = providerExtraData.get(EbodacConstants.MESSAGE_ID);
    DateTime sendDate =
        DateTime.parse(initialRecord.getMotechTimestamp(), motechTimestampFormatter);
    int attempts = 0;
    DateTime receivedDate = null;
    DateTime smsReceivedDate = null;
    double expectedDuration = 0;
    double timeListenedTo = 0;
    double messagePercentListened = 0;

    for (CallDetailRecord callDetailRecord : callDetailRecords) {
      if (callDetailRecord.getCallStatus() == null) {
        continue;
      }
      if (callDetailRecord
          .getCallStatus()
          .contains(EbodacConstants.IVR_CALL_DETAIL_RECORD_STATUS_SUBMITTED)) {
        sms = true;
      } else if (callDetailRecord
          .getCallStatus()
          .contains(EbodacConstants.IVR_CALL_DETAIL_RECORD_STATUS_FINISHED)) {
        finished.add(callDetailRecord);
      } else if (callDetailRecord
          .getCallStatus()
          .contains(EbodacConstants.IVR_CALL_DETAIL_RECORD_STATUS_FAILED)) {
        failed.add(callDetailRecord);
      }
    }

    Integer recordsCount = failed.size() + finished.size();
    CallDetailRecord callRecord;

    if (sms) {
      if (failed.isEmpty()) {
        throw new EbodacReportException(
            "Cannot generate report for Call Detail Record with Provider Call Id: %s for Providers with Ids %s, because SMS was sent but no failed record found for the Call",
            "", providerCallId, subjectIds);
      }
      if (recordsCount > 2) {
        throw new EbodacReportException(
            "Cannot generate report for Call Detail Record with Provider Call Id: %s for Providers with Ids %s, because there is too much records with failed/finished status (%s)",
            "", providerCallId, subjectIds, recordsCount.toString());
      }
      if (failed.size() == 2) {
        smsFailed = true;
        LOGGER.warn(
            "Failed to sent SMS for Call Detail Record with Provider Call Id: {} for Providers with Ids {}",
            providerCallId,
            subjectIds);
      } else if (finished.isEmpty()) {
        LOGGER.warn(
            "SMS is sent but not yet received for Call Detail Record with Provider Call Id: {} for Providers with Ids {}",
            providerCallId,
            subjectIds);
        Config config = configService.getConfig();
        config.getIvrAndSmsStatisticReportsToUpdate().add(initialRecord.getMotechCallId());
        configService.updateConfig(config);
      } else {
        String providerTimestamp =
            finished
                .get(0)
                .getProviderExtraData()
                .get(EbodacConstants.IVR_CALL_DETAIL_RECORD_END_TIMESTAMP);
        if (StringUtils.isBlank(providerTimestamp)) {
          throw new EbodacReportException(
              "Cannot generate report for Call Detail Record with Provider Call Id: %s for Providers with Ids %s, because end_timestamp for SMS Record not found",
              "", providerCallId, subjectIds);
        }
        smsReceivedDate = DateTime.parse(providerTimestamp, votoTimestampFormatter);
      }

      callRecord = failed.get(0);
    } else if (recordsCount == 2 && failed.size() == 2) {
      callRecord = failed.get(0);
      smsFailed = true;
      LOGGER.warn(
          "Failed to sent SMS for Call Detail Record with Provider Call Id: {} for Providers with Ids {}",
          providerCallId,
          subjectIds);
    } else {
      if (recordsCount > 1) {
        throw new EbodacReportException(
            "Cannot generate report for Call Detail Record with Provider Call Id: %s for Providers with Ids %s, because there is too much records with failed/finished status (%s)",
            "", providerCallId, subjectIds, recordsCount.toString());
      }
      if (finished.isEmpty()) {
        throw new EbodacReportException(
            "Cannot generate report for Call Detail Record with Provider Call Id: %s for Providers with Ids %s, because no SMS was sent but there is no record with finished status",
            "", providerCallId, subjectIds);
      }

      callRecord = finished.get(0);
      String providerTimestamp =
          callRecord
              .getProviderExtraData()
              .get(EbodacConstants.IVR_CALL_DETAIL_RECORD_START_TIMESTAMP);
      if (StringUtils.isBlank(providerTimestamp)) {
        throw new EbodacReportException(
            "Cannot generate report for Call Detail Record with Provider Call Id: %s for Providers with Ids %s, because start_timestamp for Call Record not found",
            "", providerCallId, subjectIds);
      }
      receivedDate = DateTime.parse(providerTimestamp, votoTimestampFormatter);

      if (StringUtils.isNotBlank(callRecord.getCallDuration())) {
        timeListenedTo = Double.parseDouble(callRecord.getCallDuration());
        if (StringUtils.isNotBlank(callRecord.getMessagePercentListened())) {
          messagePercentListened = Double.parseDouble(callRecord.getMessagePercentListened());
          String messageSecondsCompleted =
              callRecord
                  .getProviderExtraData()
                  .get(EbodacConstants.IVR_CALL_DETAIL_RECORD_MESSAGE_SECOND_COMPLETED);
          if (StringUtils.isNotBlank(messageSecondsCompleted)) {
            expectedDuration =
                Double.parseDouble(messageSecondsCompleted)
                    * HUNDRED_PERCENT
                    / messagePercentListened;
          }
        }
      }
    }

    String attemptsString =
        callRecord
            .getProviderExtraData()
            .get(EbodacConstants.IVR_CALL_DETAIL_RECORD_NUMBER_OF_ATTEMPTS);
    if (StringUtils.isNotBlank(attemptsString)) {
      attempts = Integer.parseInt(attemptsString);
    }

    for (Subject subject : subjects) {
      IvrAndSmsStatisticReport ivrAndSmsStatisticReport =
          ivrAndSmsStatisticReportDataService.findByProviderCallIdAndSubjectId(
              providerCallId, subject.getSubjectId());
      if (ivrAndSmsStatisticReport == null) {
        ivrAndSmsStatisticReport =
            new IvrAndSmsStatisticReport(
                providerCallId,
                subject,
                messageId,
                sendDate,
                expectedDuration,
                timeListenedTo,
                messagePercentListened,
                receivedDate,
                attempts,
                sms,
                smsFailed,
                smsReceivedDate);
        ivrAndSmsStatisticReportDataService.create(ivrAndSmsStatisticReport);
      } else {
        ivrAndSmsStatisticReport.updateReportData(
            providerCallId,
            subject,
            messageId,
            sendDate,
            expectedDuration,
            timeListenedTo,
            messagePercentListened,
            receivedDate,
            attempts,
            sms,
            smsFailed,
            smsReceivedDate);
        ivrAndSmsStatisticReportDataService.update(ivrAndSmsStatisticReport);
      }
    }
  }
Example #2
0
  private void resetTestFields() {
    firstSubject =
        new Subject(
            "1000000161",
            "Michal",
            "Abacki",
            "Cabacki",
            "729402018364",
            "address",
            Language.English,
            "community",
            "B05-SL10001");

    secondSubject =
        new Subject(
            "1000000162",
            "Rafal",
            "Dabacki",
            "Ebacki",
            "44443333222",
            "address1",
            Language.Susu,
            "community",
            "B05-SL10001");

    firstSubject.setDateOfBirth(LocalDate.parse("1967-09-17", formatter));
    firstSubject.setGender(Gender.Male);
    firstSubject.setPrimerVaccinationDate(LocalDate.parse("2014-10-17", formatter));
    firstSubject.setBoosterVaccinationDate(LocalDate.parse("2014-10-20", formatter));

    secondSubject.setDateOfBirth(LocalDate.parse("2005-08-04", formatter));
    secondSubject.setGender(Gender.Male);
    secondSubject.setPrimerVaccinationDate(LocalDate.parse("2014-10-17", formatter));
    secondSubject.setBoosterVaccinationDate(LocalDate.parse("2014-10-20", formatter));

    testVisits.add(
        VisitUtils.createVisit(
            firstSubject,
            VisitType.SCREENING,
            LocalDate.parse("2014-10-17", formatter),
            LocalDate.parse("2014-10-17", formatter),
            "owner"));

    testVisits.add(
        VisitUtils.createVisit(
            firstSubject,
            VisitType.PRIME_VACCINATION_FOLLOW_UP_VISIT,
            LocalDate.parse("2014-10-19", formatter),
            LocalDate.parse("2014-10-19", formatter),
            "owner"));

    testVisits.add(
        VisitUtils.createVisit(
            secondSubject,
            VisitType.SCREENING,
            LocalDate.parse("2014-10-19", formatter),
            LocalDate.parse("2014-10-19", formatter),
            "owner"));

    testVisits.add(
        VisitUtils.createVisit(
            secondSubject,
            VisitType.PRIME_VACCINATION_FOLLOW_UP_VISIT,
            LocalDate.parse("2014-10-21", formatter),
            LocalDate.parse("2014-10-21", formatter),
            "owner"));

    testVisits.add(
        VisitUtils.createVisit(
            firstSubject,
            VisitType.BOOST_VACCINATION_DAY,
            LocalDate.parse("2014-10-17", formatter),
            LocalDate.parse("2014-10-17", formatter),
            "owner"));
  }
  private void generateOrUpdatePrimerVaccinationReport(List<Subject> subjects, LocalDate date) {
    LocalDate age6 = date.minusYears(SIX_YEARS);
    LocalDate age12 = date.minusYears(TWELVE_YEARS);
    LocalDate age18 = date.minusYears(EIGHTEEN_YEARS);

    int childrenFrom1To5 = 0;
    int childrenFrom6To11 = 0;
    int childrenFrom12To17 = 0;
    int adultMales = 0;
    int adultFemales = 0;
    int adultUndifferentiated = 0;
    int adultUnidentified = 0;

    for (Subject subject : subjects) {
      if (subject.getDateOfBirth() == null) {
        LOGGER.warn("Subject with id: {} has no birth date", subject.getSubjectId());
      } else if (subject.getDateOfBirth().isAfter(age6)) {
        childrenFrom1To5++;
      } else if (subject.getDateOfBirth().isAfter(age12)) {
        childrenFrom6To11++;
      } else if (subject.getDateOfBirth().isAfter(age18)) {
        childrenFrom12To17++;
      } else if (Gender.Male.equals(subject.getGender())) {
        adultMales++;
      } else if (Gender.Female.equals(subject.getGender())) {
        adultFemales++;
      } else if (Gender.Undifferentiated.equals(subject.getGender())) {
        adultUndifferentiated++;
      } else {
        adultUnidentified++;
      }
    }

    int peopleVaccinated =
        childrenFrom1To5 + childrenFrom6To11 + childrenFrom12To17 + adultMales + adultFemales;

    ReportPrimerVaccination existingReport = primerVaccinationDataService.findByDate(date);

    if (existingReport != null) {
      existingReport.updateReportData(
          adultMales,
          adultFemales,
          childrenFrom1To5,
          childrenFrom6To11,
          childrenFrom12To17,
          adultUnidentified,
          adultUndifferentiated,
          peopleVaccinated);
      primerVaccinationDataService.update(existingReport);

      LOGGER.debug(
          "Primer Vaccination Daily Report for date: {} updated",
          date.toString(DateTimeFormat.forPattern(EbodacConstants.REPORT_DATE_FORMAT)));
    } else {
      ReportPrimerVaccination reportPrimerVaccination =
          new ReportPrimerVaccination(
              date,
              adultMales,
              adultFemales,
              childrenFrom1To5,
              childrenFrom6To11,
              childrenFrom12To17,
              adultUnidentified,
              adultUndifferentiated,
              peopleVaccinated);

      primerVaccinationDataService.create(reportPrimerVaccination);

      LOGGER.debug(
          "Primer Vaccination Daily Report for date: {} created",
          date.toString(DateTimeFormat.forPattern(EbodacConstants.REPORT_DATE_FORMAT)));
    }
  }