@After public void cleanAfter() { ivrAndSmsStatisticReportDataService.deleteAll(); visitDataService.deleteAll(); subjectEnrollmentsDataService.deleteAll(); subjectDataService.deleteAll(); }
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); } } }