killbill-memoizeit

overdue,jaxrs: Add some validation and business logic when

9/12/2016 10:04:21 PM

Details

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java
index f59c110..c2284be 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java
@@ -32,6 +32,7 @@ import org.killbill.billing.overdue.config.DefaultOverdueStatesAccount;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
@@ -99,14 +100,27 @@ public class OverdueJson {
         return result;
     }
 
-    public static OverdueConfig toOverdueConfig(final OverdueJson input) {
+    public static OverdueConfig toOverdueConfigWithValidation(final OverdueJson input) {
         final DefaultOverdueConfig result = new DefaultOverdueConfig();
         final DefaultOverdueStatesAccount overdueStateAccount = new DefaultOverdueStatesAccount();
         result.setOverdueStates(overdueStateAccount);
 
         final DefaultOverdueState [] states = new DefaultOverdueState[input.getOverdueStates().size()];
         int i = 0;
+
+
+        int prevTimeSinceEarliestUnpaidInvoice = -1;
         for (final OverdueStateConfigJson cur : input.getOverdueStates()) {
+
+            Preconditions.checkNotNull(cur.getName());
+
+            // We only support timeSinceEarliestUnpaidInvoiceEqualsOrExceeds condition (see #611)
+            Preconditions.checkNotNull(cur.getCondition());
+            Preconditions.checkNotNull(cur.getCondition().getTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds());
+            Preconditions.checkNotNull(cur.getCondition().getTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds().getUnit());
+            Preconditions.checkState(cur.getCondition().getTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds().getUnit() == TimeUnit.DAYS);
+            Preconditions.checkState(cur.getCondition().getTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds().getNumber() > 0);
+
             final DefaultOverdueState state = new DefaultOverdueState();
             state.setName(cur.getName());
             state.setExternalMessage(cur.getExternalMessage());
@@ -114,12 +128,29 @@ public class OverdueJson {
             state.setDisableEntitlement(cur.getDisableEntitlement());
             state.setSubscriptionCancellationPolicy(cur.getSubscriptionCancellationPolicy());
             state.setClearState(cur.isClearState());
-            state.setAutoReevaluationInterval((new DefaultDuration()).setUnit(TimeUnit.DAYS).setNumber(cur.getAutoReevaluationIntervalDays()));
+            state.setAutoReevaluationInterval(computeReevaluationInterval(cur.getAutoReevaluationIntervalDays(), prevTimeSinceEarliestUnpaidInvoice, cur.getCondition().getTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds().getNumber()));
             state.setCondition(OverdueConditionJson.toOverdueCondition(cur.getCondition()));
             states[i++] = state;
+
+            prevTimeSinceEarliestUnpaidInvoice = cur.getCondition().getTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds().getNumber();
         }
         overdueStateAccount.setAccountOverdueStates(states);
-        overdueStateAccount.setInitialReevaluationInterval(null);
+        overdueStateAccount.setInitialReevaluationInterval(computeReevaluationInterval(null, prevTimeSinceEarliestUnpaidInvoice, 0));
         return result;
     }
+
+    // Unless the user knows what it's doing (inputReevaluationInterval != null), for time based condition we set the reevaluation interval to match the transition to the next state
+    private static DefaultDuration computeReevaluationInterval(final Integer inputReevaluationInterval,  int prevTimeSinceEarliestUnpaidInvoice, int curTimeSinceEarliestUnpaidInvoice) {
+        if (inputReevaluationInterval != null && inputReevaluationInterval > 0) {
+            return new DefaultDuration().setUnit(TimeUnit.DAYS).setNumber(inputReevaluationInterval);
+        }
+
+        if (prevTimeSinceEarliestUnpaidInvoice == -1) {
+            return null;
+        }
+
+        Preconditions.checkState(prevTimeSinceEarliestUnpaidInvoice - curTimeSinceEarliestUnpaidInvoice > 0);
+
+        return new DefaultDuration().setUnit(TimeUnit.DAYS).setNumber(prevTimeSinceEarliestUnpaidInvoice - curTimeSinceEarliestUnpaidInvoice);
+    }
 }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java
index def105f..534d07e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java
@@ -20,8 +20,6 @@ package org.killbill.billing.jaxrs.resources;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -30,22 +28,14 @@ import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
 import org.killbill.billing.account.api.AccountUserApi;
-import org.killbill.billing.catalog.StandaloneCatalog;
-import org.killbill.billing.catalog.VersionedCatalog;
-import org.killbill.billing.catalog.api.StaticCatalog;
-import org.killbill.billing.jaxrs.json.CatalogJson;
 import org.killbill.billing.jaxrs.json.OverdueJson;
 import org.killbill.billing.jaxrs.util.Context;
 import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
-import org.killbill.billing.overdue.api.DefaultOverdueApi;
 import org.killbill.billing.overdue.api.OverdueApi;
 import org.killbill.billing.overdue.api.OverdueConfig;
 import org.killbill.billing.overdue.config.DefaultOverdueConfig;
@@ -148,7 +138,7 @@ public class OverdueResource extends JaxRsResourceBase {
                                   @javax.ws.rs.core.Context final UriInfo uriInfo) throws Exception {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
-        final OverdueConfig overdueConfig = OverdueJson.toOverdueConfig(overdueJson);
+        final OverdueConfig overdueConfig = OverdueJson.toOverdueConfigWithValidation(overdueJson);
         overdueApi.uploadOverdueConfig(overdueConfig, callContext);
         return uriBuilder.buildResponse(uriInfo, OverdueResource.class, null, null);
     }