killbill-memoizeit

jaxrs: Fixes issue #530 Populate the priceOverrides fields

5/24/2016 7:19:00 PM

Details

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java
index 7537ada..0cb8603 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.UUID;
 
 import org.killbill.billing.account.api.Account;
+import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.entitlement.api.SubscriptionBundle;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceItem;
@@ -62,11 +63,11 @@ public class AccountTimelineJson {
                                final List<Payment> payments,
                                final List<InvoicePayment> invoicePayments,
                                final List<SubscriptionBundle> bundles,
-                               final AccountAuditLogs accountAuditLogs) {
+                               final AccountAuditLogs accountAuditLogs) throws CatalogApiException {
         this.account = new AccountJson(account, null, null, accountAuditLogs);
         this.bundles = new LinkedList<BundleJson>();
         for (final SubscriptionBundle bundle : bundles) {
-            final BundleJson jsonWithSubscriptions = new BundleJson(bundle, accountAuditLogs);
+            final BundleJson jsonWithSubscriptions = new BundleJson(bundle, account.getCurrency(), accountAuditLogs);
             this.bundles.add(jsonWithSubscriptions);
         }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java
index 22effcd..0dbd4b5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java
@@ -23,6 +23,8 @@ import java.util.List;
 
 import javax.annotation.Nullable;
 
+import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.entitlement.api.Subscription;
 import org.killbill.billing.entitlement.api.SubscriptionBundle;
 import org.killbill.billing.util.audit.AccountAuditLogs;
@@ -56,18 +58,20 @@ public class BundleJson extends JsonBase {
         this.timeline = timeline;
     }
 
-    public BundleJson(final SubscriptionBundle bundle, @Nullable final AccountAuditLogs accountAuditLogs) {
+    public BundleJson(final SubscriptionBundle bundle, @Nullable final Currency currency, @Nullable final AccountAuditLogs accountAuditLogs) throws CatalogApiException {
         super(toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForBundle(bundle.getId())));
         this.accountId = bundle.getAccountId().toString();
         this.bundleId = bundle.getId().toString();
         this.externalKey = bundle.getExternalKey();
         this.subscriptions = new LinkedList<SubscriptionJson>();
         for (final Subscription subscription : bundle.getSubscriptions()) {
-            this.subscriptions.add(new SubscriptionJson(subscription, accountAuditLogs));
+            this.subscriptions.add(new SubscriptionJson(subscription, currency, accountAuditLogs));
         }
         this.timeline = new BundleTimelineJson(bundle.getTimeline(), accountAuditLogs);
     }
 
+
+
     public List<SubscriptionJson> getSubscriptions() {
         return subscriptions;
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
index c860f33..38059d7 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
@@ -18,6 +18,8 @@
 
 package org.killbill.billing.jaxrs.json;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -25,6 +27,9 @@ import javax.annotation.Nullable;
 
 import org.joda.time.LocalDate;
 import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanPhase;
 import org.killbill.billing.catalog.api.PriceList;
 import org.killbill.billing.catalog.api.Product;
@@ -67,7 +72,6 @@ public class SubscriptionJson extends JsonBase {
     private final List<EventSubscriptionJson> events;
     private final List<PhasePriceOverrideJson> priceOverrides;
 
-
     public static class EventSubscriptionJson extends JsonBase {
 
         private final String eventId;
@@ -310,7 +314,7 @@ public class SubscriptionJson extends JsonBase {
         this.priceOverrides = priceOverrides;
     }
 
-    public SubscriptionJson(final Subscription subscription, @Nullable final AccountAuditLogs accountAuditLogs) {
+    public SubscriptionJson(final Subscription subscription, @Nullable final Currency currency, @Nullable final AccountAuditLogs accountAuditLogs) throws CatalogApiException {
         super(toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForSubscription(subscription.getId())));
         this.startDate = subscription.getEffectiveStartDate();
 
@@ -356,8 +360,20 @@ public class SubscriptionJson extends JsonBase {
         for (final SubscriptionEvent subscriptionEvent : subscription.getSubscriptionEvents()) {
             this.events.add(new EventSubscriptionJson(subscriptionEvent, accountAuditLogs));
         }
-        // It may be nice to recreate the override that were applied on the plans associated with that subscription
-        this.priceOverrides = new LinkedList<PhasePriceOverrideJson>();
+
+        // We fill the catalog info every time we get the currency from the account (even if this is not overridden Plan)
+        this.priceOverrides = new ArrayList<PhasePriceOverrideJson>();
+        if (currency != null) {
+            final Plan plan = subscription.getLastActivePlan();
+            if (plan != null) {
+                for (final PlanPhase cur : plan.getAllPhases()) {
+                    final BigDecimal fixedPrice = cur.getFixed() != null ? cur.getFixed().getPrice().getPrice(currency) : null;
+                    final BigDecimal recurringPrice = cur.getRecurring() != null ? cur.getRecurring().getRecurringPrice().getPrice(currency) : null;
+                    final PhasePriceOverrideJson phase = new PhasePriceOverrideJson(cur.getName(), cur.getPhaseType().toString(), fixedPrice, recurringPrice);
+                    priceOverrides.add(phase);
+                }
+            }
+        }
     }
 
     public String getAccountId() {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 0a75de9..30a96c2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -58,6 +58,7 @@ import org.killbill.billing.account.api.AccountEmail;
 import org.killbill.billing.account.api.AccountInternalApi;
 import org.killbill.billing.account.api.AccountUserApi;
 import org.killbill.billing.account.api.MutableAccountData;
+import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.entitlement.api.SubscriptionApi;
 import org.killbill.billing.entitlement.api.SubscriptionApiException;
@@ -265,7 +266,7 @@ public class AccountResource extends JaxRsResourceBase {
         final TenantContext tenantContext = context.createContext(request);
 
         final UUID uuid = UUID.fromString(accountId);
-        accountUserApi.getAccountById(uuid, tenantContext);
+       final Account account = accountUserApi.getAccountById(uuid, tenantContext);
 
         final List<SubscriptionBundle> bundles = (externalKey != null) ?
                                                  subscriptionApi.getSubscriptionBundlesForAccountIdAndExternalKey(uuid, externalKey, tenantContext) :
@@ -274,7 +275,12 @@ public class AccountResource extends JaxRsResourceBase {
         final Collection<BundleJson> result = Collections2.transform(bundles, new Function<SubscriptionBundle, BundleJson>() {
             @Override
             public BundleJson apply(final SubscriptionBundle input) {
-                return new BundleJson(input, null);
+                try {
+                    return new BundleJson(input, account.getCurrency(), null);
+                } catch (final CatalogApiException e) {
+                    // Not the cleanest thing, but guava Api don't allow throw..
+                    throw new RuntimeException(e);
+                }
             }
         });
         return Response.status(Status.OK).entity(result).build();
@@ -383,7 +389,7 @@ public class AccountResource extends JaxRsResourceBase {
     public Response getAccountTimeline(@PathParam("accountId") final String accountIdString,
                                        @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                        @QueryParam(QUERY_PARALLEL) @DefaultValue("false") final Boolean parallel,
-                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException, SubscriptionApiException, InvoiceApiException {
+                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException, SubscriptionApiException, InvoiceApiException, CatalogApiException {
         final TenantContext tenantContext = context.createContext(request);
 
         final UUID accountId = UUID.fromString(accountIdString);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index 7f3432a..d74eacd 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -41,9 +41,11 @@ import javax.ws.rs.core.UriInfo;
 
 import org.joda.time.LocalDate;
 import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountUserApi;
 import org.killbill.billing.catalog.api.BillingActionPolicy;
+import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.entitlement.api.EntitlementApi;
 import org.killbill.billing.entitlement.api.EntitlementApiException;
 import org.killbill.billing.entitlement.api.SubscriptionApi;
@@ -113,10 +115,13 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
     public Response getBundle(@PathParam("bundleId") final String bundleId,
-                              @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
+                              @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
         final UUID id = UUID.fromString(bundleId);
-        final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(id, context.createContext(request));
-        final BundleJson json = new BundleJson(bundle, null);
+
+        final TenantContext tenantContext = this.context.createContext(request);
+        final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(id, tenantContext);
+        final Account account = accountUserApi.getAccountById(bundle.getAccountId(), tenantContext);
+        final BundleJson json = new BundleJson(bundle, account.getCurrency(), null);
         return Response.status(Status.OK).entity(json).build();
     }
 
@@ -126,9 +131,13 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a bundle by external key", response = BundleJson.class)
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Bundle not found")})
     public Response getBundleByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
-                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
-        final SubscriptionBundle bundle = subscriptionApi.getActiveSubscriptionBundleForExternalKey(externalKey, context.createContext(request));
-        final BundleJson json = new BundleJson(bundle, null);
+                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
+
+        final TenantContext tenantContext = this.context.createContext(request);
+
+        final SubscriptionBundle bundle = subscriptionApi.getActiveSubscriptionBundleForExternalKey(externalKey, tenantContext);
+        final Account account = accountUserApi.getAccountById(bundle.getAccountId(), tenantContext);
+        final BundleJson json = new BundleJson(bundle, account.getCurrency(), null);
         return Response.status(Status.OK).entity(json).build();
     }
 
@@ -154,7 +163,13 @@ public class BundleResource extends JaxRsResourceBase {
                                                         if (accountsAuditLogs.get().get(bundle.getAccountId()) == null) {
                                                             accountsAuditLogs.get().put(bundle.getAccountId(), auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext));
                                                         }
-                                                        return new BundleJson(bundle, accountsAuditLogs.get().get(bundle.getAccountId()));
+
+                                                        try {
+                                                            return new BundleJson(bundle, null, accountsAuditLogs.get().get(bundle.getAccountId()));
+                                                        } catch (final CatalogApiException unused) {
+                                                            // Does not happen because we pass a null Currency
+                                                            throw new RuntimeException(unused);
+                                                        }
                                                     }
                                                 },
                                                 nextPageUri);
@@ -184,7 +199,12 @@ public class BundleResource extends JaxRsResourceBase {
                                                         if (accountsAuditLogs.get().get(bundle.getAccountId()) == null) {
                                                             accountsAuditLogs.get().put(bundle.getAccountId(), auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext));
                                                         }
-                                                        return new BundleJson(bundle, accountsAuditLogs.get().get(bundle.getAccountId()));
+                                                        try {
+                                                            return new BundleJson(bundle, null, accountsAuditLogs.get().get(bundle.getAccountId()));
+                                                        } catch (final CatalogApiException unused) {
+                                                            // Does not happen because we pass a null Currency
+                                                            throw new RuntimeException(unused);
+                                                        }
                                                     }
                                                 },
                                                 nextPageUri);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
index 35db125..7875ea5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
@@ -76,9 +76,6 @@ public class CatalogResource extends JaxRsResourceBase {
 
     private final CatalogUserApi catalogUserApi;
 
-    // Catalog API don't quite support multiple catalogs per tenant
-    private static final String catalogName = "unused";
-
     @Inject
     public CatalogResource(final JaxrsUriBuilder uriBuilder,
                            final TagUserApi tagUserApi,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
index 45f207f..b800815 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -110,6 +110,10 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
 
     static final Logger log = LoggerFactory.getLogger(JaxRsResourceBase.class);
 
+    // Catalog API don't quite support multiple catalogs per tenant
+    protected static final String catalogName = "unused";
+
+
     protected static final ObjectMapper mapper = new ObjectMapper();
 
     protected final JaxrsUriBuilder uriBuilder;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index 62ddc79..5032362 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
@@ -47,6 +47,8 @@ import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountUserApi;
 import org.killbill.billing.catalog.api.BillingActionPolicy;
 import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.CatalogUserApi;
 import org.killbill.billing.catalog.api.PhaseType;
 import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
 import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
@@ -138,10 +140,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Subscription not found")})
     public Response getEntitlement(@PathParam("subscriptionId") final String subscriptionId,
-                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
+                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
         final UUID uuid = UUID.fromString(subscriptionId);
-        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(uuid, context.createContext(request));
-        final SubscriptionJson json = new SubscriptionJson(subscription, null);
+        final TenantContext tenantContext = this.context.createContext(request);
+        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(uuid, tenantContext);
+
+        final Account account = accountUserApi.getAccountById(subscription.getAccountId(), tenantContext);
+        final SubscriptionJson json = new SubscriptionJson(subscription, account.getCurrency(), null);
         return Response.status(Status.OK).entity(json).build();
     }
 
@@ -420,7 +425,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             }
 
             @Override
-            public Response doResponseOk(final Response operationResponse) throws SubscriptionApiException {
+            public Response doResponseOk(final Response operationResponse) throws SubscriptionApiException, AccountApiException, CatalogApiException {
                 if (operationResponse.getStatus() != Status.OK.getStatusCode()) {
                     return operationResponse;
                 }
@@ -557,7 +562,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
 
         public boolean isImmOperation();
 
-        public Response doResponseOk(final T operationResponse) throws SubscriptionApiException;
+        public Response doResponseOk(final T operationResponse) throws SubscriptionApiException, AccountApiException, CatalogApiException;
     }
 
     private class EntitlementCallCompletion<T> {
@@ -565,7 +570,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
         public Response withSynchronization(final EntitlementCallCompletionCallback<T> callback,
                                             final long timeoutSec,
                                             final boolean callCompletion,
-                                            final CallContext callContext) throws SubscriptionApiException, AccountApiException, EntitlementApiException {
+                                            final CallContext callContext) throws SubscriptionApiException, AccountApiException, EntitlementApiException{
             final CompletionUserRequestEntitlement waiter = callCompletion ? new CompletionUserRequestEntitlement(callContext.getUserToken()) : null;
             try {
                 if (waiter != null) {
@@ -578,6 +583,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
                 return callback.doResponseOk(operationValue);
             } catch (final InterruptedException e) {
                 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+            } catch (final CatalogApiException e) {
+                throw new EntitlementApiException(e);
             } catch (final TimeoutException e) {
                 return Response.status(408).build();
             } finally {
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
index 1d3cb3f..7a73f09 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
@@ -66,6 +66,16 @@ public class TestEntitlement extends TestJaxrsBase {
 
         // Retrieves with GET
         Subscription objFromJson = killBillClient.getSubscription(entitlementJson.getSubscriptionId());
+        Assert.assertEquals(objFromJson.getPriceOverrides().size(), 2);
+        Assert.assertEquals(objFromJson.getPriceOverrides().get(0).getFixedPrice(), BigDecimal.ZERO);
+        Assert.assertNull(objFromJson.getPriceOverrides().get(0).getRecurringPrice());
+
+        Assert.assertNull(objFromJson.getPriceOverrides().get(1).getFixedPrice());
+        Assert.assertEquals(objFromJson.getPriceOverrides().get(1).getRecurringPrice(), new BigDecimal("249.95"));
+
+        // Equality in java client is not correctly implemented so manually check PriceOverrides section and then reset before equality
+        objFromJson.setPriceOverrides(null);
+        entitlementJson.setPriceOverrides(null);
         Assert.assertTrue(objFromJson.equals(entitlementJson));
 
         // Change plan IMM