Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ public CallSummaryRecordDto toDto() {
circle,
timestamp,
opt_in_call_eligibility,
opt_in_input
opt_in_input,
serviceId
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class CallSummaryRecordDto implements Serializable {

private String opt_in_input;

private String serviceId;

public CallSummaryRecordDto() { }

//CHECKSTYLE:OFF
Expand All @@ -53,7 +55,7 @@ public CallSummaryRecordDto(String subscriptionId, int statusCode, int finalStat
}

public CallSummaryRecordDto(String subscriptionId, int statusCode, int finalStatus, String contentFileName,
String weekId, String languageCode, String circleName, String targetFileTimeStamp, Boolean opt_in_call_eligibility, String opt_in_input) {
String weekId, String languageCode, String circleName, String targetFileTimeStamp, Boolean opt_in_call_eligibility, String opt_in_input,String serviceId) {
this.subscriptionId = subscriptionId;
this.statusCode = statusCode;
this.finalStatus = finalStatus;
Expand All @@ -64,6 +66,7 @@ public CallSummaryRecordDto(String subscriptionId, int statusCode, int finalStat
this.targetFileTimeStamp = targetFileTimeStamp;
this.opt_in_call_eligibility = opt_in_call_eligibility;
this.opt_in_input = opt_in_input;
this.serviceId = serviceId;
}

// Helper constructor for ITs
Expand Down Expand Up @@ -155,6 +158,14 @@ public void setTargetFileTimeStamp(String targetFileTimeStamp) {
this.targetFileTimeStamp = targetFileTimeStamp;
}

public String getServiceId() {
return serviceId;
}

public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}

@Ignore
public static CallSummaryRecordDto fromParams(Map<String, Object> params) {
CallSummaryRecordDto csr;
Expand All @@ -168,7 +179,8 @@ public static CallSummaryRecordDto fromParams(Map<String, Object> params) {
(String) params.get("circleName"),
(String) params.get("targetFileTimeStamp"),
(Boolean) params.get("opt_in_call_eligibility"),
(String) params.get("opt_in_input")
(String) params.get("opt_in_input"),
(String) params.get("serviceId")
);
return csr;
}
Expand All @@ -186,6 +198,7 @@ public static Map<String, Object> toParams(CallSummaryRecordDto csr) {
params.put("targetFileTimeStamp", csr.targetFileTimeStamp);
params.put("opt_in_call_eligibility", csr.opt_in_call_eligibility);
params.put("opt_in_input", csr.opt_in_input);
params.put("serviceId", csr.serviceId);
return params;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ Subscription createSubscription(Subscriber subscriber, long callingNumber, Langu

void deleteCallRetry(String subscriptionId);

void updateCallRetry(String subscriptionId,Long msisdn);

void deleteBlockedMsisdn(Long motherId, Long oldCallingNumber, Long newCallingNumber);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,19 @@
import org.motechproject.nms.kilkari.service.CsrVerifierService;
import org.motechproject.nms.kilkari.service.SubscriptionService;
import org.motechproject.nms.kilkari.utils.KilkariConstants;
import org.motechproject.nms.props.domain.DayOfTheWeek;
import org.motechproject.nms.props.domain.FinalCallStatus;
import org.motechproject.nms.props.domain.StatusCode;
import org.motechproject.nms.props.domain.WhatsAppOptInStatusCode;
import org.motechproject.server.config.SettingsFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

import static java.lang.Math.min;

Expand Down Expand Up @@ -145,7 +148,6 @@ private void handleDndForSubscription(Subscription subscription) {
private void doReschedule(Subscription subscription, CallRetry existingCallRetry, CallSummaryRecordDto csrDto) {

boolean invalidNr = StatusCode.fromInt(csrDto.getStatusCode()).equals(StatusCode.OBD_FAILED_INVALIDNUMBER);

if (existingCallRetry == null && SubscriptionStatus.ACTIVE.equals(subscription.getStatus())) {
// We've never retried this call, let's do it
callRetryDataService.create(new CallRetry(
Expand All @@ -167,7 +169,6 @@ private void doReschedule(Subscription subscription, CallRetry existingCallRetry

if ((subscription.getSubscriptionPack().retryCount() == 1) ||
(existingCallRetry !=null && existingCallRetry.getCallStage() == CallStage.RETRY_LAST)) {

// This call should not be retried

// Deactivate subscription for persistent invalid numbers
Expand Down Expand Up @@ -199,13 +200,13 @@ private void doReschedule(Subscription subscription, CallRetry existingCallRetry
)
);*/
existingCallRetry.setContentFileName("opt_in.wav");
if(!Objects.equals(existingCallRetry.getMsisdn(), subscription.getSubscriber().getCallingNumber())){
existingCallRetry.setMsisdn(subscription.getSubscriber().getCallingNumber());
}
callRetryDataService.update(existingCallRetry);
} else {
completeSubscriptionIfNeeded(subscription, csrDto.getContentFileName());
callRetryDataService.delete(existingCallRetry);
LOGGER.info("subscription is : {}", subscription);
LOGGER.info("csrDto is : {}", csrDto);
LOGGER.info("whatsAppOptSMSDataService is : {}", whatsAppOptSMSDataService);
// write message table logic here
whatsAppOptSMSDataService.create(new WhatsAppOptSMS(csrDto.getCircleName(),
"SMS_CONTENT",
Expand Down Expand Up @@ -237,6 +238,9 @@ private void doReschedule(Subscription subscription, CallRetry existingCallRetry
existingCallRetry.setCallStage(existingCallRetry.getCallStage().nextStage());
existingCallRetry.setInvalidNumberCount(existingCallRetry.getInvalidNumberCount() == null ? 0 :
(existingCallRetry.getInvalidNumberCount() + (invalidNr ? 1 : 0)));
if(!Objects.equals(existingCallRetry.getMsisdn(), subscription.getSubscriber().getCallingNumber())){
existingCallRetry.setMsisdn(subscription.getSubscriber().getCallingNumber());
}
callRetryDataService.update(existingCallRetry);
}

Expand Down Expand Up @@ -289,7 +293,6 @@ private void doRescheduleOptIn(Subscription subscription,CallSummaryRecordDto ca
@MotechListener(subjects = {KilkariConstants.NMS_IMI_KK_PROCESS_CSR_SUBJECT}) //NO CHECKSTYLE Cyclomatic Complexity
@Transactional
public void processCallSummaryRecord(MotechEvent event) { //NOPMD NcssMethodCount

Timer timer = new Timer();
String whatHappened = "##";

Expand Down Expand Up @@ -329,9 +332,13 @@ public void processCallSummaryRecord(MotechEvent event) { //NOPMD NcssMethodCoun
if(callRetry!=null){
callRetryDataService.delete(callRetry);
}
} else {
}else if(callRetry == null && !csrDto.getWeekId().equals("w1_1") && !subscription.getFirstMessageDayOfWeek().equals(DayOfTheWeek.getDayOfTheWeekFromTimestamp(csrDto.getTargetFileTimeStamp())) && "1".equals(extractRouteNumber(csrDto.getServiceId()))) {
LOGGER.info("Fresh call condition after rch update");
}else if(callRetry == null && !csrDto.getWeekId().equals("w1_1") && "2".equals(extractRouteNumber(csrDto.getServiceId()))){
LOGGER.info("Retry call condition after rch update");
}else {
if (callRetry == null ||
!csrDto.getTargetFileTimeStamp().equals(callRetry.getTargetFiletimestamp())) {
!csrDto.getTargetFileTimeStamp().equals(callRetry.getTargetFiletimestamp())){
doReschedule(subscription, callRetry, csrDto);
}
}
Expand Down Expand Up @@ -372,6 +379,16 @@ public void processCallSummaryRecord(MotechEvent event) { //NOPMD NcssMethodCoun
LOGGER.debug(String.format("processCallSummaryRecord %s %s %s", subscriptionId, whatHappened, timer.time()));
}

private String extractRouteNumber(String serviceId) {
if (serviceId != null && serviceId.contains("Retryonroute")) {
int startIndex = serviceId.indexOf("Retryonroute") + "Retryonroute".length();
if (startIndex < serviceId.length()) {
return String.valueOf(serviceId.charAt(startIndex));
}
}
return "";
}

@MotechListener(subjects = {KilkariConstants.NMS_IMI_KK_WHATSAPP_SMS_PROCESS_CSR_SUBJECT}) //NO CHECKSTYLE Cyclomatic Complexity
@Transactional
public void processWhatsAppSMSCsr(MotechEvent event) { //NOPMD NcssMethodCount
Expand All @@ -381,16 +398,13 @@ public void processWhatsAppSMSCsr(MotechEvent event) { //NOPMD NcssMethodCount

String subscriptionId = "###INVALID###";
try {
LOGGER.debug("test 20 - WhatsAppOptSMSCsrDto.fromParams");
WhatsAppOptSMSCsrDto csrDto = WhatsAppOptSMSCsrDto.fromParams(event.getParameters());
subscriptionId = csrDto.getRequestId();
// csrVerifierService.verify(csrDto);
LOGGER.debug("test 21 - subscriptionDataService.findBySubscriptionIdAndStatus");
Subscription subscription = subscriptionDataService.findBySubscriptionIdAndStatus(subscriptionId, SubscriptionStatus.ACTIVE);
if (subscription == null) {
throw new NoSuchSubscriptionException(subscriptionId);
}
LOGGER.debug("test 22 - updateSubscriptionServiceStatusForWhatsAppSMS");
updateSubscriptionServiceStatusForWhatsAppSMS(subscription, csrDto.getResponse(), (List<Subscription>) event.getParameters().get("subscriptions"));

} catch (NoSuchSubscriptionException e) {
Expand Down Expand Up @@ -419,18 +433,15 @@ public void processWhatsAppCsr(MotechEvent event) { //NOPMD NcssMethodCount

String subscriptionId = "###INVALID###";
try {
LOGGER.debug("test 20 - WhatsAppOptCsrDto.fromParams");
WhatsAppOptCsrDto csrDto = WhatsAppOptCsrDto.fromParams(event.getParameters());
LOGGER.debug("csrDto: {}", csrDto);
subscriptionId = csrDto.getExternalId();
// csrVerifierService.verify(csrDto);
LOGGER.debug("test 21 - subscriptionDataService.findBySubscriptionIdAndStatus");
Subscription subscription = subscriptionDataService.findBySubscriptionIdAndStatus(subscriptionId, SubscriptionStatus.ACTIVE);
LOGGER.debug("subscription: {}", subscription);
if (subscription == null) {
throw new NoSuchSubscriptionException(subscriptionId);
}
LOGGER.debug("test 22 - updateSubscriptionServiceStatusForWhatsApp");
updateSubscriptionServiceStatusForWhatsApp(subscription, csrDto.getMessageStatus(), (List<Subscription>) event.getParameters().get("subscriptions"));
LOGGER.debug("subscription: {}", subscription);
} catch (NoSuchSubscriptionException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,23 @@ public Subscription updateRchMotherSubscriber(Long msisdn, MctsMother motherUpda
subscriberByRchId.setCaseNo(caseNo);
motherUpdate.setMaxCaseNo(caseNo);
}


if(subscription != null){
if ( !((subscriberByRchId.getLastMenstrualPeriod().getDayOfYear() == lmp.getDayOfYear()) && (subscriberByRchId.getLastMenstrualPeriod().getYear() == lmp.getYear()))) {
subscriptionService.deleteCallRetry(subscription.getSubscriptionId());

}else {
subscriptionService.updateCallRetry(subscription.getSubscriptionId(), msisdn);
}
}
subscriberByRchId.setLastMenstrualPeriod(lmp);
subscriberByRchId.setModificationDate(DateTime.now());
motherUpdate.setName(name);
motherUpdate.setDateOfBirth(motherDOB);
motherUpdate.setLastMenstrualPeriod(lmp);
motherUpdate.setUpdatedDateNic(lastUpdatedDateNic);
motherUpdate.setRegistrationDate(motherRegistrationDate);
if(subscription != null){subscriptionService.deleteCallRetry(subscription.getSubscriptionId());}
return updateOrCreateSubscription(subscriberByRchId, subscription, lmp, pack, language, circle, SubscriptionOrigin.RCH_IMPORT, greaterCase);
} else { // we have a subscriber by phone# and also one with the RCH id
if (subscriptionService.activeSubscriptionByMsisdnRch(subscribersByMsisdn,msisdn, SubscriptionPackType.PREGNANCY, motherUpdate.getRchId(), null)) {
Expand Down Expand Up @@ -729,10 +738,25 @@ public ChildImportRejection updateRchChildSubscriber(Long msisdn, MctsChild chil
subscription = latestDeactivatedSubscription;
}
}

// Delete that record from retry table as beneficiary gets their mobile number update
if(subscription != null){
if ((subscriberByRchId.getDateOfBirth().getDayOfYear() != dob.getDayOfYear())){
subscriptionService.deleteCallRetry(subscription.getSubscriptionId());
}else {
subscriptionService.updateCallRetry(subscription.getSubscriptionId(), msisdn);
}
}
subscriberByRchId.setDateOfBirth(dob);
subscriberByRchId.setModificationDate(DateTime.now());
// Delete that record from retry table as beneficiary gets their mobile number update
if(subscription != null){subscriptionService.deleteCallRetry(subscription.getSubscriptionId());}
if(subscription != null){
if ((subscriberByRchId.getDateOfBirth().getDayOfYear() != dob.getDayOfYear())){
subscriptionService.deleteCallRetry(subscription.getSubscriptionId());
}else {
subscriptionService.updateCallRetry(subscription.getSubscriptionId(), msisdn);
}
}
finalSubscription = updateOrCreateSubscription(subscriberByRchId, subscription, dob, pack, language, circle, SubscriptionOrigin.RCH_IMPORT, false);
} else {
//subscriber found with provided msisdn
Expand Down Expand Up @@ -1023,6 +1047,13 @@ public Subscription updateOrCreateSubscription(Subscriber subscriber, Subscripti
return deactivatedSubscripion;
}
} else if (subscription != null && !subscription.getDeactivationReason().equals(DeactivationReason.INVALID_NUMBER)){
Set<Subscription> activeSubscriptions = subscriber.getActiveAndPendingSubscriptions();
if (activeSubscriptions != null && !activeSubscriptions.isEmpty()) {
for(Subscription sub : activeSubscriptions ){
sub.setModificationDate(DateTime.now());
}
}
subscription.setModificationDate(DateTime.now());
return subscription;
} else {
return subscriptionService.createSubscription(subscriber, subscriber.getCallingNumber(), language, circle, pack, origin);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,15 @@ public void deleteCallRetry(String subscriptionId) {
}
}

@Override
public void updateCallRetry(String subscriptionId,Long msisdn) {
CallRetry callRetry = callRetryDataService.findBySubscriptionId(subscriptionId);
if (callRetry != null) {
callRetry.setMsisdn(msisdn);
callRetryDataService.update(callRetry);
}
}

@Override
public void deactivateSubscription(Subscription subscription, DeactivationReason reason) {
if (subscription != null && (subscription.getStatus() == SubscriptionStatus.ACTIVE ||
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.motechproject.nms.props.domain;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public enum DayOfTheWeek {
MONDAY(1),
Expand Down Expand Up @@ -38,6 +40,16 @@ public static DayOfTheWeek fromDateTime(DateTime dt) {
return fromInt(dt.getDayOfWeek());
}

public static DayOfTheWeek getDayOfTheWeekFromTimestamp(String timestamp) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMddHHmmss");

DateTime dateTime = formatter.parseDateTime(timestamp);

int dayOfWeek = dateTime.getDayOfWeek(); // 1 = Monday, 7 = Sunday

return DayOfTheWeek.fromInt(dayOfWeek);
}
Comment on lines +43 to +51
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and documentation.

The method needs the following improvements:

  1. Add null check and proper exception handling for parsing errors
  2. Add javadoc to document the expected timestamp format
  3. Make the formatter a static final field for better performance

Here's the suggested implementation:

+    private static final DateTimeFormatter TIMESTAMP_FORMATTER = 
+            DateTimeFormat.forPattern("yyyyMMddHHmmss");
+
+    /**
+     * Converts a timestamp string to DayOfTheWeek.
+     *
+     * @param timestamp String in format "yyyyMMddHHmmss"
+     * @return DayOfTheWeek corresponding to the timestamp
+     * @throws IllegalArgumentException if timestamp is null or in invalid format
+     */
     public static DayOfTheWeek getDayOfTheWeekFromTimestamp(String timestamp) {
-        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMddHHmmss");
+        if (timestamp == null) {
+            throw new IllegalArgumentException("Timestamp cannot be null");
+        }
+        try {
+            DateTime dateTime = TIMESTAMP_FORMATTER.parseDateTime(timestamp);
+            return DayOfTheWeek.fromInt(dateTime.getDayOfWeek());
+        } catch (IllegalArgumentException e) {
+            throw new IllegalArgumentException(
+                "Invalid timestamp format. Expected: yyyyMMddHHmmss", e);
+        }
-        DateTime dateTime = formatter.parseDateTime(timestamp);
-
-        int dayOfWeek = dateTime.getDayOfWeek(); // 1 = Monday, 7 = Sunday
-
-        return DayOfTheWeek.fromInt(dayOfWeek);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static DayOfTheWeek getDayOfTheWeekFromTimestamp(String timestamp) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMddHHmmss");
DateTime dateTime = formatter.parseDateTime(timestamp);
int dayOfWeek = dateTime.getDayOfWeek(); // 1 = Monday, 7 = Sunday
return DayOfTheWeek.fromInt(dayOfWeek);
}
private static final DateTimeFormatter TIMESTAMP_FORMATTER =
DateTimeFormat.forPattern("yyyyMMddHHmmss");
/**
* Converts a timestamp string to DayOfTheWeek.
*
* @param timestamp String in format "yyyyMMddHHmmss"
* @return DayOfTheWeek corresponding to the timestamp
* @throws IllegalArgumentException if timestamp is null or in invalid format
*/
public static DayOfTheWeek getDayOfTheWeekFromTimestamp(String timestamp) {
if (timestamp == null) {
throw new IllegalArgumentException("Timestamp cannot be null");
}
try {
DateTime dateTime = TIMESTAMP_FORMATTER.parseDateTime(timestamp);
return DayOfTheWeek.fromInt(dateTime.getDayOfWeek());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(
"Invalid timestamp format. Expected: yyyyMMddHHmmss", e);
}
}


public DayOfTheWeek nextDay() {
if (value == SUNDAY.getValue()) {
return MONDAY;
Expand Down