killbill-uncached
Changes
.circleci/config.yml 10(+8 -2)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java 4(+3 -1)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java 26(+14 -12)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java 138(+74 -64)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java 57(+29 -28)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java 24(+15 -9)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java 16(+9 -7)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java 13(+8 -5)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceSystemDisabling.java 4(+2 -2)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java 24(+12 -12)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java 2(+1 -1)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java 64(+22 -42)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestInArrearWithCatalogVersions.java 231(+231 -0)
beatrix/src/test/resources/catalogs/default/catalogTest.xml 1465(+1465 -0)
entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java 58(+30 -28)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java 29(+15 -14)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java 68(+34 -34)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java 30(+16 -14)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java 5(+3 -2)
entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java 3(+2 -1)
entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java 18(+11 -7)
invoice/src/main/java/org/killbill/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java 70(+0 -70)
invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java 36(+34 -2)
invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableUsageInArrear.java 26(+12 -14)
invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java 14(+12 -2)
junction/pom.xml 3(+1 -2)
junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java 12(+12 -0)
junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java 5(+3 -2)
payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultInvoicePaymentInternalApi.java 150(+150 -0)
payment/src/main/java/org/killbill/billing/payment/api/svcs/InvoicePaymentPaymentOptions.java 70(+70 -0)
payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java 20(+10 -10)
pom.xml 2(+1 -1)
profiles/killbill/src/main/java/org/killbill/billing/server/modules/DefaultHealthcheckPluginRegistry.java 65(+65 -0)
profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java 5(+5 -0)
README.md 24(+8 -16)
subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java 13(+7 -6)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 8(+4 -4)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java 29(+12 -17)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 29(+15 -14)
subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java 7(+5 -2)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java 13(+7 -6)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java 7(+5 -2)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java 51(+34 -17)
Details
.circleci/config.yml 10(+8 -2)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index b81ff31..528284c 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -176,10 +176,16 @@ jobs:
set -e
bundle exec rake ci:core | tee /tmp/test-results/test.txt 2>&1
+ - run:
+ name: Save test results
+ command: |
+ mkdir -p ~/junit/
+ find test/reports -type f -name "*.xml" -exec cp {} ~/junit/ \;
+ when: always
- store_test_results:
- path: test/reports/
+ path: ~/junit
- store_artifacts:
- path: /tmp/test-results
+ path: ~/junit
workflows:
version: 2
diff --git a/api/src/main/java/org/killbill/billing/glue/InvoiceModule.java b/api/src/main/java/org/killbill/billing/glue/InvoiceModule.java
index ce939ec..6ebf2b5 100644
--- a/api/src/main/java/org/killbill/billing/glue/InvoiceModule.java
+++ b/api/src/main/java/org/killbill/billing/glue/InvoiceModule.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -22,7 +24,5 @@ public interface InvoiceModule {
public void installInvoiceUserApi();
- public void installInvoicePaymentApi();
-
public void installInvoiceInternalApi();
}
diff --git a/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java b/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
index 8dabb05..ffe6ad5 100644
--- a/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2011 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -20,6 +20,7 @@ package org.killbill.billing.invoice.api;
import java.math.BigDecimal;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -28,6 +29,7 @@ import org.joda.time.LocalDate;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.util.callcontext.TenantContext;
public interface InvoiceInternalApi {
@@ -77,4 +79,10 @@ public interface InvoiceInternalApi {
public Map<UUID, BigDecimal> validateInvoiceItemAdjustments(final UUID paymentId, final Map<UUID, BigDecimal> idWithAmount, final InternalTenantContext context) throws InvoiceApiException;
public void commitInvoice(UUID invoiceId, InternalCallContext context) throws InvoiceApiException;
+
+ public List<InvoicePayment> getInvoicePayments(UUID paymentId, TenantContext context);
+
+ public List<InvoicePayment> getInvoicePaymentsByAccount(UUID accountId, TenantContext context);
+
+ public InvoicePayment getInvoicePaymentByCookieId(String cookieId, TenantContext context);
}
diff --git a/api/src/main/java/org/killbill/billing/junction/BillingEvent.java b/api/src/main/java/org/killbill/billing/junction/BillingEvent.java
index dfbe4f6..7af38bf 100644
--- a/api/src/main/java/org/killbill/billing/junction/BillingEvent.java
+++ b/api/src/main/java/org/killbill/billing/junction/BillingEvent.java
@@ -33,11 +33,10 @@ import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
public interface BillingEvent extends Comparable<BillingEvent> {
-
/**
* @return the billCycleDay in the account timezone as seen for that subscription at that time
- * <p/>
- * Note: The billCycleDay may come from the Account, or the bundle or the subscription itself
+ * <p/>
+ * Note: The billCycleDay may come from the Account, or the bundle or the subscription itself
*/
int getBillCycleDayLocal();
@@ -97,9 +96,13 @@ public interface BillingEvent extends Comparable<BillingEvent> {
Long getTotalOrdering();
/**
- *
* @return the list of {@code Usage} section
*/
List<Usage> getUsages();
-}
+ /**
+ *
+ * @return the catalog version (effective date) associated with this billing event.
+ */
+ public DateTime getCatalogEffectiveDate();
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java
index 6b9dca9..a9f6125 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java
@@ -26,14 +26,13 @@ import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
-import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Blockable;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementSourceType;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransition;
import org.killbill.billing.util.callcontext.CallContext;
@@ -54,19 +53,18 @@ public interface SubscriptionBase extends Entity, Blockable {
throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime changePlan(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final CallContext context)
+ public DateTime changePlan(final EntitlementSpecifier spec, final CallContext context)
throws SubscriptionBaseApiException;
public boolean undoChangePlan(final CallContext context)
throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime changePlanWithDate(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final DateTime requestedDate, final CallContext context)
+ public DateTime changePlanWithDate(final EntitlementSpecifier spec, final DateTime requestedDate, final CallContext context)
throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime changePlanWithPolicy(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides,
- final BillingActionPolicy policy, final CallContext context)
+ public DateTime changePlanWithPolicy(final EntitlementSpecifier spec, final BillingActionPolicy policy, final CallContext context)
throws SubscriptionBaseApiException;
public UUID getBundleId();
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
index 0728a12..4d8b6b9 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
@@ -34,6 +34,7 @@ import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
@@ -84,7 +85,7 @@ public interface SubscriptionBaseInternalApi {
public List<EffectiveSubscriptionInternalEvent> getBillingTransitions(SubscriptionBase subscription, InternalTenantContext context);
- public DateTime getDryRunChangePlanEffectiveDate(SubscriptionBase subscription, PlanPhaseSpecifier spec, DateTime requestedDate, BillingActionPolicy policy, List<PlanPhasePriceOverride> overrides, InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException;
+ public DateTime getDryRunChangePlanEffectiveDate(SubscriptionBase subscription, EntitlementSpecifier spec, DateTime requestedDate, BillingActionPolicy policy, InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException;
public List<EntitlementAOStatusDryRun> getDryRunChangePlanStatus(UUID subscriptionId, @Nullable String baseProductName,
DateTime requestedDate, InternalTenantContext context) throws SubscriptionBaseApiException;
diff --git a/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java b/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java
index e8ba29b..ad5349b 100644
--- a/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java
+++ b/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java
@@ -58,6 +58,7 @@ import org.killbill.billing.lifecycle.glue.BusModule;
import org.killbill.billing.notification.plugin.api.BlockingStateMetadata;
import org.killbill.billing.notification.plugin.api.BroadcastMetadata;
import org.killbill.billing.notification.plugin.api.ExtBusEventType;
+import org.killbill.billing.notification.plugin.api.InvoiceNotificationMetadata;
import org.killbill.billing.notification.plugin.api.InvoicePaymentMetadata;
import org.killbill.billing.notification.plugin.api.PaymentMetadata;
import org.killbill.billing.notification.plugin.api.SubscriptionMetadata;
@@ -192,10 +193,10 @@ public class BeatrixListener {
} else {
eventBusType = ExtBusEventType.BLOCKING_STATE;
- final BlockingStateMetadata metaDataObj = new BlockingStateMetadata(realEventBS.getBlockableId(), realEventBS.getService(), realEventBS.getStateName(), realEventBS.getBlockingType(), realEventBS.getEffectiveDate(),
+ final BlockingStateMetadata blockingStateMetadata = new BlockingStateMetadata(realEventBS.getBlockableId(), realEventBS.getService(), realEventBS.getStateName(), realEventBS.getBlockingType(), realEventBS.getEffectiveDate(),
realEventBS.isTransitionedToBlockedBilling(), realEventBS.isTransitionedToUnblockedBilling(),
realEventBS.isTransitionedToBlockedEntitlement(), realEventBS.isTransitionedToUnblockedEntitlement());
- metaData = objectMapper.writeValueAsString(metaDataObj);
+ metaData = objectMapper.writeValueAsString(blockingStateMetadata);
}
break;
@@ -212,6 +213,11 @@ public class BeatrixListener {
objectId = null;
accountId = realEventInvNotification.getAccountId(); // has to be set here because objectId is null with a dryRun Invoice
eventBusType = ExtBusEventType.INVOICE_NOTIFICATION;
+
+ final InvoiceNotificationMetadata invoiceNotificationMetadata = new InvoiceNotificationMetadata(realEventInvNotification.getTargetDate(),
+ realEventInvNotification.getAmountOwed(),
+ realEventInvNotification.getCurrency());
+ metaData = objectMapper.writeValueAsString(invoiceNotificationMetadata);
break;
@@ -338,8 +344,8 @@ public class BeatrixListener {
objectType = ObjectType.SERVICE_BROADCAST;
objectId = null;
eventBusType = ExtBusEventType.BROADCAST_SERVICE;
- final BroadcastMetadata metaDataObj = new BroadcastMetadata(realBroadcastEvent.getServiceName(), realBroadcastEvent.getType(), realBroadcastEvent.getJsonEvent());
- metaData = objectMapper.writeValueAsString(metaDataObj);
+ final BroadcastMetadata broadcastMetadata = new BroadcastMetadata(realBroadcastEvent.getServiceName(), realBroadcastEvent.getType(), realBroadcastEvent.getJsonEvent());
+ metaData = objectMapper.writeValueAsString(broadcastMetadata);
break;
default:
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/BeatrixTestSuiteWithEmbeddedDB.java b/beatrix/src/test/java/org/killbill/billing/beatrix/BeatrixTestSuiteWithEmbeddedDB.java
index 29350d9..82bf4fe 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/BeatrixTestSuiteWithEmbeddedDB.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/BeatrixTestSuiteWithEmbeddedDB.java
@@ -21,10 +21,24 @@ package org.killbill.billing.beatrix;
import org.killbill.billing.GuicyKillbillTestSuiteWithEmbeddedDB;
import org.killbill.billing.platform.api.KillbillConfigSource;
+import com.google.common.collect.ImmutableMap;
+
public abstract class BeatrixTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuiteWithEmbeddedDB {
+ final static protected ImmutableMap DEFAULT_BEATRIX_PROPERTIES = ImmutableMap.builder()
+ .put("org.killbill.catalog.uri", "catalogs/default/catalogTest.xml")
+ .put("org.killbill.invoice.maxDailyNumberOfItemsSafetyBound", "30")
+ .put("org.killbill.payment.retry.days", "8,8,8,8,8,8,8,8")
+ .put("org.killbill.osgi.bundle.install.dir", "/var/tmp/beatrix-bundles")
+ // The default value is 50, i.e. wait 50 x 100ms = 5s to get the lock. This isn't always enough and can lead to random tests failures
+ // in the listener status: after moving the clock, if there are two notifications triggering an invoice run, we typically expect
+ // both an INVOICE and a NULL_INVOICE event. If the invoice generation takes too long, the NULL_INVOICE event is never generated
+ // (LockFailedException): the test itself doesn't fail (the correct invoice is generated), but assertListenerStatus() would.
+ .put("org.killbill.invoice.globalLock.retries", 150)
+ .build();
+
@Override
protected KillbillConfigSource getConfigSource() {
- return getConfigSource("/beatrix.properties");
+ return getConfigSource(null, DEFAULT_BEATRIX_PROPERTIES);
}
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/db/TestDBRouter.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/db/TestDBRouter.java
index 94cb0ac..6cd9b9b 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/db/TestDBRouter.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/db/TestDBRouter.java
@@ -76,6 +76,10 @@ public class TestDBRouter extends TestIntegrationBase {
@AfterMethod(groups = "slow")
public void afterMethod() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
+
externalBus.unregister(publicListener);
super.afterMethod();
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index bbcbbab..5c5b4aa 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -40,6 +40,7 @@ import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.BlockingApiException;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.EntitlementApiException;
import org.killbill.billing.invoice.api.Invoice;
@@ -1197,7 +1198,8 @@ public class TestOverdueIntegration extends TestOverdueBase {
private void checkChangePlanWithOverdueState(final Entitlement entitlement, final boolean shouldFail, final boolean expectedPayment) {
if (shouldFail) {
try {
- entitlement.changePlan(new PlanPhaseSpecifier("Pistol", term, PriceListSet.DEFAULT_PRICELIST_NAME), null, ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", term, PriceListSet.DEFAULT_PRICELIST_NAME);
+ entitlement.changePlan(new DefaultEntitlementSpecifier(spec), ImmutableList.<PluginProperty>of(), callContext);
} catch (EntitlementApiException e) {
assertTrue(e.getCause() instanceof BlockingApiException || e.getCode() == ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode(),
String.format("Cause is %s, message is %s", e.getCause(), e.getMessage()));
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
index 965a5fb..40d0ff6 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
@@ -31,6 +31,7 @@ import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementApiException;
@@ -40,6 +41,7 @@ import org.killbill.billing.platform.api.KillbillConfigSource;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -50,7 +52,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
@Override
protected KillbillConfigSource getConfigSource() {
- return super.getConfigSource("/beatrixCatalogRetireElements.properties");
+ return super.getConfigSource(null, ImmutableMap.of("org.killbill.catalog.uri", "catalogs/testCatalogRetireElements"));
}
@Test(groups = "slow")
@@ -86,7 +88,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, PriceListSet.DEFAULT_PRICELIST_NAME, null);
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey2", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail(); // force to fail is there is not an exception
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_PLAN_NOT_FOUND.getCode());
@@ -151,7 +153,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, PriceListSet.DEFAULT_PRICELIST_NAME, null);
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey2", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail(); // force to fail is there is not an exception
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_PLAN_NOT_FOUND.getCode());
@@ -190,7 +192,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier(productName, term, "DEFAULT", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec1, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec1), "externalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
@@ -214,7 +216,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
// Note that we need to trigger a CHANGE outside a TRIAL phase to generate a CHANGE event (otherwise, a CREATE is generated)
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
- bpEntitlement = bpEntitlement.changePlanWithDate(spec2, null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
+ bpEntitlement = bpEntitlement.changePlanWithDate( new DefaultEntitlementSpecifier(spec2), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
assertEquals(entitlementApi.getEntitlementForId(bpEntitlement.getId(), callContext).getLastActivePhase().getPhaseType(), PhaseType.DISCOUNT);
@@ -250,7 +252,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
// Catalog v3 should start now.
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec2, "externalKey2", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec2), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail(); // force to fail is there is not an exception
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_NO_SUCH_PRODUCT.getCode());
@@ -281,7 +283,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier(productName, term, "DEFAULT", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec1, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec1), "externalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
@@ -305,7 +307,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
// Note that we need to trigger a CHANGE outside a TRIAL phase to generate a CHANGE event (otherwise, a CREATE is generated)
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
- bpEntitlement = bpEntitlement.changePlanWithDate(spec2, null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
+ bpEntitlement = bpEntitlement.changePlanWithDate( new DefaultEntitlementSpecifier(spec2), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
assertEquals(entitlementApi.getEntitlementForId(bpEntitlement.getId(), callContext).getLastActivePhase().getPhaseType(), PhaseType.DISCOUNT);
@@ -351,7 +353,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
// Catalog v3 should start now.
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec2, "externalKey2", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec2), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail(); // force to fail is there is not an exception
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_NO_SUCH_PRODUCT.getCode());
@@ -404,7 +406,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, PriceListSet.DEFAULT_PRICELIST_NAME, null);
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey2", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail(); // force to fail is there is not an exception
} catch (final EntitlementApiException e) {
assertTrue(e.getLocalizedMessage().startsWith("Could not find any product named 'Pistol'"));
@@ -440,7 +442,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
@@ -460,7 +462,7 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
// PriceList "SpecialDiscount" at this point.
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey2", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "externalKey2", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail(); // force to fail is there is not an exception
} catch (final EntitlementApiException e) {
assertTrue(e.getLocalizedMessage().startsWith("Could not find any product named 'Pistol'"));
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java
index 50b114a..6abcdad 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java
@@ -115,7 +115,7 @@ public class TestIntegration extends TestIntegrationBase {
final DryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, null, null, null, null, null, SubscriptionEventType.STOP_BILLING, bpSubscription.getId(),
bpSubscription.getBundleId(), null, null);
try {
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2012, 6, 1), dryRun, callContext);
+ invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2012, 6, 1), dryRun, callContext);
fail();
} catch (final InvoiceApiException e) {
assertEquals(e.getCode(), INVOICE_NOTHING_TO_DO.getCode());
@@ -175,7 +175,7 @@ public class TestIntegration extends TestIntegrationBase {
final DryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, null, null, null, null, null, SubscriptionEventType.STOP_BILLING, bpSubscription.getId(),
bpSubscription.getBundleId(), null, null);
try {
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2012, 6, 1), dryRun, callContext);
+ invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2012, 6, 1), dryRun, callContext);
fail();
} catch (final InvoiceApiException e) {
assertEquals(e.getCode(), INVOICE_NOTHING_TO_DO.getCode());
@@ -204,7 +204,7 @@ public class TestIntegration extends TestIntegrationBase {
TestDryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, null, null,
SubscriptionEventType.START_BILLING, null, null, null, null);
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -219,7 +219,7 @@ public class TestIntegration extends TestIntegrationBase {
//
dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, null, null,
SubscriptionEventType.START_BILLING, null, bpSubscription.getBundleId(), null, null);
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -235,7 +235,7 @@ public class TestIntegration extends TestIntegrationBase {
//
dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, null, null, null, null, null, SubscriptionEventType.STOP_BILLING, bpSubscription.getId(),
bpSubscription.getBundleId(), null, null);
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-399.95")));
// The second invoice should be adjusted for the AO (we paid for the full period) and since we paid we should also see a CBA
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 4, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("399.95"),
@@ -279,7 +279,7 @@ public class TestIntegration extends TestIntegrationBase {
//
TestDryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, null, null, SubscriptionEventType.CHANGE,
subscription.getId(), subscription.getBundleId(), null, null);
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -304,7 +304,7 @@ public class TestIntegration extends TestIntegrationBase {
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 3, 2), new LocalDate(2012, 3, 31), InvoiceItemType.RECURRING, new BigDecimal("561.24")));
// Verify first next targetDate
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(nextDate, testTimeZone), dryRun, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(nextDate, testTimeZone), dryRun, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -328,7 +328,7 @@ public class TestIntegration extends TestIntegrationBase {
nextDate = clock.getUTCNow().plusDays(31);
dryRun = new TestDryRunArguments(DryRunType.TARGET_DATE);
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(nextDate, testTimeZone), dryRun, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(nextDate, testTimeZone), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2012, 3, 31), new LocalDate(2012, 4, 30), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -412,7 +412,7 @@ public class TestIntegration extends TestIntegrationBase {
final TestDryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, null, null, SubscriptionEventType.CHANGE,
subscription.getId(), subscription.getBundleId(), null, null);
try {
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
Assert.fail("Call should return no invoices");
} catch (final InvoiceApiException e) {
assertEquals(e.getCode(), INVOICE_NOTHING_TO_DO.getCode());
@@ -1094,15 +1094,16 @@ public class TestIntegration extends TestIntegrationBase {
clock.addDays(30);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 2, callContext,
- new ExpectedInvoiceItemCheck(new LocalDate(2015, 10, 1), new LocalDate(2016, 10, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
+ new ExpectedInvoiceItemCheck(new LocalDate(2015, 10, 1), new LocalDate(2016, 10, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")),
+ new ExpectedInvoiceItemCheck(new LocalDate(2015, 9, 1), new LocalDate(2015, 10, 1), InvoiceItemType.USAGE, BigDecimal.ZERO));
// 2015-11-1
- busHandler.pushExpectedEvent(NextEvent.NULL_INVOICE);
+ busHandler.pushExpectedEvent(NextEvent.INVOICE);
clock.addMonths(1);
assertListenerStatus();
// 2015-12-1
- busHandler.pushExpectedEvent(NextEvent.NULL_INVOICE);
+ busHandler.pushExpectedEvent(NextEvent.INVOICE);
clock.addMonths(1);
assertListenerStatus();
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index 8de650c..66eea8c 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -20,7 +20,6 @@ package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -60,10 +59,12 @@ import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
import org.killbill.billing.entitlement.api.EntitlementApi;
import org.killbill.billing.entitlement.api.EntitlementApiException;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionApi;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.ParkedAccountsManager;
@@ -72,7 +73,7 @@ import org.killbill.billing.invoice.api.DryRunType;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceItem;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
+import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.api.InvoiceService;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.junction.BlockingInternalApi;
@@ -89,6 +90,7 @@ import org.killbill.billing.overdue.listener.OverdueListener;
import org.killbill.billing.overdue.wrapper.OverdueWrapper;
import org.killbill.billing.overdue.wrapper.OverdueWrapperFactory;
import org.killbill.billing.payment.api.AdminPaymentApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -108,12 +110,17 @@ import org.killbill.billing.subscription.api.timeline.SubscriptionBaseTimelineAp
import org.killbill.billing.subscription.api.transfer.SubscriptionBaseTransferApi;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.tenant.api.TenantUserApi;
+import org.killbill.billing.usage.api.SubscriptionUsageRecord;
+import org.killbill.billing.usage.api.UnitUsageRecord;
+import org.killbill.billing.usage.api.UsageApiException;
+import org.killbill.billing.usage.api.UsageRecord;
import org.killbill.billing.usage.api.UsageUserApi;
import org.killbill.billing.util.api.RecordIdApi;
import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.config.definition.InvoiceConfig;
import org.killbill.billing.util.config.definition.PaymentConfig;
import org.killbill.billing.util.dao.NonEntityDao;
@@ -123,6 +130,8 @@ import org.killbill.bus.api.PersistentBus;
import org.killbill.bus.api.PersistentBus.EventBusException;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.config.TimeSpan;
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.tweak.HandleCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
@@ -311,13 +320,9 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
return;
}
+
final InvoiceConfig defaultInvoiceConfig = new ConfigurationObjectFactory(skifeConfigSource).build(InvoiceConfig.class);
invoiceConfig = new ConfigurableInvoiceConfig(defaultInvoiceConfig);
- // The default value is 50, i.e. wait 50 x 100ms = 5s to get the lock. This isn't always enough and can lead to random tests failures
- // in the listener status: after moving the clock, if there are two notifications triggering an invoice run, we typically expect
- // both an INVOICE and a NULL_INVOICE event. If the invoice generation takes too long, the NULL_INVOICE event is never generated
- // (LockFailedException): the test itself doesn't fail (the correct invoice is generated), but assertListenerStatus() would.
- invoiceConfig.setMaxGlobalLockRetries(150);
final Injector g = Guice.createInjector(Stage.PRODUCTION, new BeatrixIntegrationModule(configSource, invoiceConfig));
g.injectMembers(this);
}
@@ -372,7 +377,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
protected void checkNoMoreInvoiceToGenerate(final Account account) {
busHandler.pushExpectedEvent(NextEvent.NULL_INVOICE);
try {
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), null, callContext);
+ invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), callContext);
fail("Should not have generated an extra invoice");
} catch (final InvoiceApiException e) {
assertListenerStatus();
@@ -523,11 +528,19 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
@Override
public Payment apply(@Nullable final Void input) {
try {
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false);
- properties.add(prop1);
- return paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, amount, currency, null, UUID.randomUUID().toString(),
- UUID.randomUUID().toString(), properties, PAYMENT_OPTIONS, callContext);
+ final InvoicePayment invoicePayment = invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ amount,
+ currency,
+ null,
+ UUID.randomUUID().toString(),
+ UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(),
+ PAYMENT_OPTIONS,
+ callContext);
+ return paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
} catch (final PaymentApiException e) {
fail(e.toString());
return null;
@@ -537,22 +550,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
}
protected Payment createPaymentAndCheckForCompletion(final Account account, final Invoice invoice, final NextEvent... events) {
- return doCallAndCheckForCompletion(new Function<Void, Payment>() {
- @Override
- public Payment apply(@Nullable final Void input) {
- try {
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false);
- properties.add(prop1);
-
- return paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, invoice.getBalance(), invoice.getCurrency(), null, UUID.randomUUID().toString(),
- UUID.randomUUID().toString(), properties, PAYMENT_OPTIONS, callContext);
- } catch (final PaymentApiException e) {
- fail(e.toString());
- return null;
- }
- }
- }, events);
+ return createPaymentAndCheckForCompletion(account, invoice, invoice.getBalance(), invoice.getCurrency(), events);
}
protected Payment createExternalPaymentAndCheckForCompletion(final Account account, final Invoice invoice, final NextEvent... events) {
@@ -560,13 +558,19 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
@Override
public Payment apply(@Nullable final Void input) {
try {
-
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false);
- properties.add(prop1);
-
- return paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, invoice.getBalance(), invoice.getCurrency(), null, UUID.randomUUID().toString(),
- UUID.randomUUID().toString(), properties, EXTERNAL_PAYMENT_OPTIONS, callContext);
+ final InvoicePayment invoicePayment = invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ invoice.getBalance(),
+ invoice.getCurrency(),
+ null,
+ UUID.randomUUID().toString(),
+ UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(),
+ EXTERNAL_PAYMENT_OPTIONS,
+ callContext);
+ return paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
} catch (final PaymentApiException e) {
fail(e.toString());
return null;
@@ -603,15 +607,10 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
return doCallAndCheckForCompletion(new Function<Void, Payment>() {
@Override
public Payment apply(@Nullable final Void input) {
- final Collection<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_WITH_ADJUSTMENTS, "true", false);
- properties.add(prop1);
- final PluginProperty prop2 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_IDS_WITH_AMOUNT_KEY, iias, false);
- properties.add(prop2);
-
try {
- return paymentApi.createRefundWithPaymentControl(account, payment.getId(), amount, currency, null, UUID.randomUUID().toString(),
- properties, PAYMENT_OPTIONS, callContext);
+ final InvoicePayment invoicePayment = invoicePaymentApi.createRefundForInvoicePayment(true, iias, account, payment.getId(), amount, currency, null, UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(), PAYMENT_OPTIONS, callContext);
+ return paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
} catch (final PaymentApiException e) {
fail(e.toString());
return null;
@@ -701,7 +700,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
public Entitlement apply(@Nullable final Void dontcare) {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, billingPeriod, priceList, null);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, overrides, null, billingEffectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(accountId, new DefaultEntitlementSpecifier(spec, null, overrides), bundleExternalKey, null, billingEffectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertNotNull(entitlementId);
return entitlementApi.getEntitlementForId(entitlementId, callContext);
} catch (final EntitlementApiException e) {
@@ -735,7 +734,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
public Entitlement apply(@Nullable final Void dontcare) {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID entitlementId = entitlementApi.addEntitlement(bundleId, spec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.addEntitlement(bundleId, new DefaultEntitlementSpecifier(spec), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertNotNull(entitlementId);
return entitlementApi.getEntitlementForId(entitlementId, callContext);
} catch (final EntitlementApiException e) {
@@ -758,10 +757,11 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
try {
// Need to fetch again to get latest CTD updated from the system
Entitlement refreshedEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, billingPeriod, priceList);
if (billingPolicy == null) {
- refreshedEntitlement = refreshedEntitlement.changePlan(new PlanPhaseSpecifier(productName, billingPeriod, priceList), null, ImmutableList.<PluginProperty>of(), callContext);
+ refreshedEntitlement = refreshedEntitlement.changePlan(new DefaultEntitlementSpecifier(spec), ImmutableList.<PluginProperty>of(), callContext);
} else {
- refreshedEntitlement = refreshedEntitlement.changePlanOverrideBillingPolicy(new PlanPhaseSpecifier(productName, billingPeriod, priceList), null, null, billingPolicy, ImmutableList.<PluginProperty>of(), callContext);
+ refreshedEntitlement = refreshedEntitlement.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(spec), null, billingPolicy, ImmutableList.<PluginProperty>of(), callContext);
}
return refreshedEntitlement;
} catch (final EntitlementApiException e) {
@@ -920,10 +920,32 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
return result;
}
+ protected void recordUsageData(final UUID subscriptionId, final String unitType, final LocalDate startDate, final Long amount, final CallContext context) throws UsageApiException {
+ final List<UsageRecord> usageRecords = new ArrayList<UsageRecord>();
+ usageRecords.add(new UsageRecord(startDate, amount));
+ final List<UnitUsageRecord> unitUsageRecords = new ArrayList<UnitUsageRecord>();
+ unitUsageRecords.add(new UnitUsageRecord(unitType, usageRecords));
+ final SubscriptionUsageRecord record = new SubscriptionUsageRecord(subscriptionId, UUID.randomUUID().toString(), unitUsageRecords);
+ usageUserApi.recordRolledUpUsage(record, context);
+ }
+
+
+ protected void removeUsageData(final UUID subscriptionId, final String unitType, final LocalDate recordedDate) {
+ dbi.withHandle(new HandleCallback<Void>() {
+ @Override
+ public Void withHandle(final Handle handle) throws Exception {
+ handle.execute("delete from rolled_up_usage where subscription_id = ? and unit_type = ? and record_date = ?",
+ subscriptionId, unitType, recordedDate);
+ return null;
+ }
+ });
+ }
+
+
protected static class TestDryRunArguments implements DryRunArguments {
private final DryRunType dryRunType;
- private final PlanPhaseSpecifier spec;
+ private final EntitlementSpecifier spec;
private final SubscriptionEventType action;
private final UUID subscriptionId;
private final UUID bundleId;
@@ -952,7 +974,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
final LocalDate effectiveDate,
final BillingActionPolicy billingPolicy) {
this.dryRunType = dryRunType;
- this.spec = new PlanPhaseSpecifier(productName, billingPeriod, priceList, phaseType);
+ this.spec = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier(productName, billingPeriod, priceList, phaseType));
this.action = action;
this.subscriptionId = subscriptionId;
this.bundleId = bundleId;
@@ -966,7 +988,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
}
@Override
- public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ public EntitlementSpecifier getEntitlementSpecifier() {
return spec;
}
@@ -994,11 +1016,6 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
public BillingActionPolicy getBillingActionPolicy() {
return billingPolicy;
}
-
- @Override
- public List<PlanPhasePriceOverride> getPlanPhasePriceOverrides() {
- return null;
- }
}
private class TestPaymentMethodPlugin extends TestPaymentMethodPluginBase {
@@ -1015,13 +1032,10 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
static class ConfigurableInvoiceConfig implements InvoiceConfig {
private final InvoiceConfig defaultInvoiceConfig;
-
- private int maxGlobalLockRetries;
private boolean isInvoicingSystemEnabled;
public ConfigurableInvoiceConfig(final InvoiceConfig defaultInvoiceConfig) {
this.defaultInvoiceConfig = defaultInvoiceConfig;
- maxGlobalLockRetries = defaultInvoiceConfig.getMaxGlobalLockRetries();
isInvoicingSystemEnabled = defaultInvoiceConfig.isInvoicingSystemEnabled();
}
@@ -1077,7 +1091,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
@Override
public int getMaxGlobalLockRetries() {
- return maxGlobalLockRetries;
+ return defaultInvoiceConfig.getMaxGlobalLockRetries();
}
@Override
@@ -1125,10 +1139,6 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
return getItemResultBehaviorMode();
}
- public void setMaxGlobalLockRetries(final int maxGlobalLockRetries) {
- this.maxGlobalLockRetries = maxGlobalLockRetries;
- }
-
public void setInvoicingSystemEnabled(final boolean invoicingSystemEnabled) {
isInvoicingSystemEnabled = invoicingSystemEnabled;
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java
index 9107ffe..52596df 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java
@@ -34,6 +34,7 @@ import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.api.DryRunArguments;
@@ -84,7 +85,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 6, 14), new LocalDate(2015, 7, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
// This will verify that the upcoming Phase is found and the invoice is generated at the right date, with correct items
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
// Move through time and verify we get the same invoice
@@ -97,7 +98,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// This will verify that the upcoming invoice notification is found and the invoice is generated at the right date, with correct items
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 7, 14), new LocalDate(2015, 8, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
// Move through time and verify we get the same invoice
@@ -110,7 +111,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// One more time, this will verify that the upcoming invoice notification is found and the invoice is generated at the right date, with correct items
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 8, 14), new LocalDate(2015, 9, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
}
@@ -145,7 +146,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2014, 2, 1), new LocalDate(2015, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
@@ -157,7 +158,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Since we only have one subscription next dryRun will show the annual
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -182,7 +183,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Verify next dryRun invoice and then move the clock to that date to also verify real invoice is the same
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 1, 14), new LocalDate(2015, 2, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 1, 14), new LocalDate(2015, 2, 14), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.NULL_INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
@@ -196,7 +197,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final DryRunArguments dryRunUpcomingInvoiceWithFilterArg1 = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, subscriptionMonthly1.getId(), null, null, null);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg1, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg1, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 14));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -204,14 +205,14 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final DryRunArguments dryRunUpcomingInvoiceWithFilterArg2 = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, subscriptionMonthly2.getId(), null, null, null);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg2, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg2, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 14));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
// Then we test first the next expected invoice at the account level
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
@@ -223,7 +224,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
}
@@ -241,7 +242,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final LocalDate futureDate = new LocalDate(2017, 5, 1);
// No CREATE event as this is set in the future
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
@@ -249,7 +250,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
assertListenerStatus();
// Generate a dryRun invoice on the billing startDate
- final Invoice dryRunInvoice1 = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, DRY_RUN_TARGET_DATE_ARG, callContext);
+ final Invoice dryRunInvoice1 = invoiceUserApi.triggerDryRunInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, DRY_RUN_TARGET_DATE_ARG, callContext);
assertEquals(dryRunInvoice1.getInvoiceItems().size(), 1);
assertEquals(dryRunInvoice1.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
assertEquals(dryRunInvoice1.getInvoiceItems().get(0).getAmount().compareTo(BigDecimal.ZERO), 0);
@@ -262,14 +263,14 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// First one day prior subscription starts
try {
- invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate.minusDays(1), dryRunSubscriptionActionArg, callContext);
+ invoiceUserApi.triggerDryRunInvoiceGeneration(createdEntitlement.getAccountId(), futureDate.minusDays(1), dryRunSubscriptionActionArg, callContext);
fail("Should fail to trigger dryRun invoice prior subscription starts");
} catch (final InvoiceApiException e) {
assertEquals(e.getCode(), ErrorCode.INVOICE_NOTHING_TO_DO.getCode());
}
// Second, on the startDate
- final Invoice dryRunInvoice2 = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, dryRunSubscriptionActionArg, callContext);
+ final Invoice dryRunInvoice2 = invoiceUserApi.triggerDryRunInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, dryRunSubscriptionActionArg, callContext);
assertEquals(dryRunInvoice2.getInvoiceItems().size(), 1);
assertEquals(dryRunInvoice2.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
assertEquals(dryRunInvoice2.getInvoiceItems().get(0).getAmount().compareTo(BigDecimal.ZERO), 0);
@@ -281,7 +282,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
assertEquals(refreshedAccount1.getBillCycleDayLocal(), new Integer(0));
busHandler.pushExpectedEvents(NextEvent.INVOICE);
- final Invoice realInvoice = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, null, callContext);
+ final Invoice realInvoice = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureDate, callContext);
assertListenerStatus();
assertEquals(realInvoice.getInvoiceItems().size(), 1);
@@ -319,7 +320,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final LocalDate futureStartDate = new LocalDate(2017, 5, 1);
// No CREATE event as this is set in the future
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureStartDate, futureStartDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), futureStartDate, futureStartDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureStartDate), 0);
@@ -328,7 +329,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Generate an invoice using a future targetDate
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- final Invoice firstInvoice = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureStartDate, null, callContext);
+ final Invoice firstInvoice = invoiceUserApi.triggerInvoiceGeneration(createdEntitlement.getAccountId(), futureStartDate, callContext);
assertListenerStatus();
assertEquals(firstInvoice.getInvoiceItems().size(), 1);
@@ -344,7 +345,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 5, 1), new LocalDate(2017, 6, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-19.95")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 4, 1), new LocalDate(2017, 4, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("19.95")));
- final Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ final Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2017, 5, 1));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -414,7 +415,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// 1. We verify that a DryRunType.TARGET_DATE for 2015-2-14 leads to an invoice that **only** contains the MONTHLY item (fix for #774)
//
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 14), new LocalDate(2015, 3, 14), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 14), DRY_RUN_TARGET_DATE_ARG, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 14), DRY_RUN_TARGET_DATE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 14));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -422,14 +423,14 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// 2. We verify that a DryRunType.TARGET_DATE for 2015-2-3 leads to an invoice that **only** contains the 2nd ANNUAL item (fix for #774)
//
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 3), new LocalDate(2016, 2, 3), InvoiceItemType.RECURRING, new BigDecimal("199.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 3), DRY_RUN_TARGET_DATE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2015, 2, 3), DRY_RUN_TARGET_DATE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 3));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
// 3. We verify that UPCOMING_INVOICE leads to next invoice fo the ANNUAL
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 2, 1), new LocalDate(2016, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2015, 2, 1));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -447,7 +448,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// No CREATE event as this is set in the future
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial", null);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -463,19 +464,19 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Specify AO subscriptionId filter
final DryRunArguments dryRunUpcomingInvoiceWithFilterArg1 = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, aoEntitlement.getId(), null, null, null);
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg1, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg1, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2018, 2, 1));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
// Specify BP subscriptionId filter
final DryRunArguments dryRunUpcomingInvoiceWithFilterArg2 = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, baseEntitlement.getId(), null, null, null);
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg2, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg2, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2018, 2, 1));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
// Specify bundleId filter
final DryRunArguments dryRunUpcomingInvoiceWithFilterArg3 = new TestDryRunArguments(DryRunType.UPCOMING_INVOICE, null, null, null, null, null, null, null, baseEntitlement.getBundleId(), null, null);
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg3, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, dryRunUpcomingInvoiceWithFilterArg3, callContext);
assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2018, 2, 1));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -500,7 +501,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Verify the next invoice based on the PHASE event is correctly seen in the dryRun scenario
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 12, 1), new LocalDate(2018, 1, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -517,7 +518,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Verify the next invoice based on the PAUSE event is correctly seen in the dryRun scenario
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 12, 15), new LocalDate(2018, 1, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-137.07")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 12, 1), new LocalDate(2017, 12, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("137.07")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
@@ -539,7 +540,7 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// Verify the next invoice based on the RESUME event is correctly seen in the dryRun scenario
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 12, 25), new LocalDate(2018, 1, 1), InvoiceItemType.RECURRING, new BigDecimal("56.44")));
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2017, 12, 15), new LocalDate(2017, 12, 15), InvoiceItemType.CBA_ADJ, new BigDecimal("-56.44")));
- dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
+ dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), null, DRY_RUN_UPCOMING_INVOICE_ARG, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
expectedInvoices.clear();
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
index 09e779f..19461a2 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
@@ -36,6 +36,7 @@ import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceItem;
@@ -181,7 +182,7 @@ public class TestIntegrationInvoice extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// 2017-02-28
@@ -216,7 +217,7 @@ public class TestIntegrationInvoice extends TestIntegrationBase {
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, overrides), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -232,7 +233,7 @@ public class TestIntegrationInvoice extends TestIntegrationBase {
new ExpectedInvoiceItemCheck(new LocalDate(2017, 2, 1), new LocalDate(2017, 3, 1), InvoiceItemType.RECURRING, BigDecimal.ZERO));
// Do the change mid-month so the repair triggers the bug in https://github.com/killbill/killbill/issues/783
- entitlement.changePlanWithDate(spec, ImmutableList.<PlanPhasePriceOverride>of(), new LocalDate("2017-02-15"), ImmutableList.<PluginProperty>of(), callContext);
+ entitlement.changePlanWithDate( new DefaultEntitlementSpecifier(spec), new LocalDate("2017-02-15"), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// 2017-02-15
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java
index 1916de5..a0d0dcf 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java
@@ -18,7 +18,6 @@
package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
@@ -40,6 +39,7 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.invoice.api.DefaultInvoiceService;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceApiException;
@@ -50,7 +50,6 @@ import org.killbill.billing.invoice.notification.ParentInvoiceCommitmentNotifier
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
import org.killbill.notificationq.api.NotificationEvent;
import org.killbill.notificationq.api.NotificationEventWithMetadata;
import org.killbill.notificationq.api.NotificationQueue;
@@ -208,7 +207,8 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
// upgrade plan
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
- baseEntitlementChild.changePlanWithDate(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, baseEntitlementChild.getLastActivePriceList().getName()), null, null, null, callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, baseEntitlementChild.getLastActivePriceList().getName());
+ baseEntitlementChild.changePlanWithDate(new DefaultEntitlementSpecifier(spec), null, null, callContext);
assertListenerStatus();
// check parent invoice. Expected to have the same invoice item with the amount updated
@@ -1157,17 +1157,23 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
assertEquals(invoiceUserApi.getAccountBalance(parentAccount.getId(), callContext).compareTo(new BigDecimal("249.95")), 0);
assertEquals(invoiceUserApi.getAccountBalance(childAccount.getId(), callContext).compareTo(new BigDecimal("249.95")), 0);
-
// Verify Invoice apis getParentAccountId/getParentInvoiceId
assertEquals(childInvoices.get(1).getParentAccountId(), parentAccount.getId());
assertEquals(childInvoices.get(1).getParentInvoiceId(), parentInvoice.getId());
try {
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, childInvoices.get(1).getId().toString(), false);
- properties.add(prop1);
- paymentApi.createPurchaseWithPaymentControl(childAccount, childAccount.getPaymentMethodId(), null, childInvoices.get(1).getBalance(), childInvoices.get(1).getCurrency(), null, UUID.randomUUID().toString(),
- UUID.randomUUID().toString(), properties, PAYMENT_OPTIONS, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(childAccount,
+ childInvoices.get(1).getId(),
+ childAccount.getPaymentMethodId(),
+ null,
+ childInvoices.get(1).getBalance(),
+ childInvoices.get(1).getCurrency(),
+ null,
+ UUID.randomUUID().toString(),
+ UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(),
+ PAYMENT_OPTIONS,
+ callContext);
Assert.fail("Payment should fail, invoice belongs to parent");
} catch (final PaymentApiException e) {
assertEquals(ErrorCode.PAYMENT_PLUGIN_API_ABORTED.getCode(), e.getCode());
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
index 2553410..bd4e224 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
@@ -46,6 +46,7 @@ import org.killbill.billing.catalog.api.SimplePlanDescriptor;
import org.killbill.billing.catalog.api.StaticCatalog;
import org.killbill.billing.catalog.api.TimeUnit;
import org.killbill.billing.catalog.api.user.DefaultSimplePlanDescriptor;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.EntitlementApiException;
import org.killbill.billing.entitlement.api.Subscription;
@@ -119,7 +120,8 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
// Change Plan to the newly added Plan and verify correct default rules behavior (IMMEDIATE change)
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- baseEntitlement.changePlan(new PlanPhaseSpecifier("SuperFoo", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, ImmutableList.<PluginProperty>of(), testCallContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("SuperFoo", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ baseEntitlement.changePlan(new DefaultEntitlementSpecifier(spec), ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 2, testCallContext,
@@ -185,7 +187,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Zoe", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
fail("Creating entitlement should fail");
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.CAT_MULTIPLE_MATCHING_PLANS_FOR_PRICELIST.getCode());
@@ -222,7 +224,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
// Change plan to original (non overridden plan)
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- baseEntitlement.changePlan(spec, null, ImmutableList.<PluginProperty>of(), testCallContext);
+ baseEntitlement.changePlan( new DefaultEntitlementSpecifier(spec), ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, testCallContext);
@@ -287,7 +289,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier specZero = new PlanPhaseSpecifier("zeroDesc-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), specZero, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(specZero), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, testCallContext);
@@ -317,7 +319,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier specNonZero = new PlanPhaseSpecifier("superfoo-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- final UUID baseEntitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), specNonZero, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID baseEntitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(specNonZero), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
final Entitlement baseEntitlement2 = entitlementApi.getEntitlementForId(baseEntitlement2Id, testCallContext);
@@ -379,7 +381,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier planPhaseSpec = new PlanPhaseSpecifier("hello-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), planPhaseSpec, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(planPhaseSpec), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, testCallContext);
@@ -414,7 +416,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
} else {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
}
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, overrides), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
return entitlementApi.getEntitlementForId(entitlementId, testCallContext);
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java
index cabc048..c2e73aa 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java
@@ -27,6 +27,7 @@ import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.platform.api.KillbillConfigSource;
@@ -39,10 +40,11 @@ public class TestInvoiceNotifications extends TestIntegrationBase {
@Override
protected KillbillConfigSource getConfigSource() {
- ImmutableMap additionalProperties = new ImmutableMap.Builder()
+
+ return getConfigSource(null, new ImmutableMap.Builder()
+ .putAll(DEFAULT_BEATRIX_PROPERTIES)
.put("org.killbill.invoice.dryRunNotificationSchedule", "7d")
- .build();
- return getConfigSource("/beatrix.properties", additionalProperties);
+ .build());
}
@Test(groups = "slow")
@@ -82,7 +84,7 @@ public class TestInvoiceNotifications extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial");
busHandler.pushExpectedEvents(NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, null, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleKey", null, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
busHandler.assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -94,7 +96,8 @@ public class TestInvoiceNotifications extends TestIntegrationBase {
final LocalDate futureChangeDate = new LocalDate(2018, 3, 28);
- entitlement.changePlanWithDate(new PlanPhaseSpecifier("shotgun-monthly"), null, futureChangeDate, null, callContext);
+ final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("shotgun-monthly");
+ entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), futureChangeDate, null, callContext);
assertListenerStatus();
// Move to the notification before the start date => 2018, 3, 21
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java
index a8b45dc..b00c5e3 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java
@@ -20,7 +20,6 @@ package org.killbill.billing.beatrix.integration;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -1065,12 +1064,19 @@ public class TestInvoicePayment extends TestIntegrationBase {
// We expect an INVOICE_PAYMENT that indicates the invoice was repaired, and also an exception because plugin aborts payment call since there is nothing to do.
//
busHandler.pushExpectedEvents(NextEvent.INVOICE_PAYMENT);
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, updateInvoice2.getId().toString(), false);
- properties.add(prop1);
try {
- paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, updateInvoice2.getBalance(), updateInvoice2.getCurrency(), null, UUID.randomUUID().toString(),
- UUID.randomUUID().toString(), properties, PAYMENT_OPTIONS, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ updateInvoice2.getId(),
+ account.getPaymentMethodId(),
+ null,
+ updateInvoice2.getBalance(),
+ updateInvoice2.getCurrency(),
+ null,
+ UUID.randomUUID().toString(),
+ UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(),
+ PAYMENT_OPTIONS,
+ callContext);
Assert.fail("The payment should not succeed (and yet it will repair the broken state....)");
} catch (final PaymentApiException expected) {
Assert.assertEquals(expected.getCode(), ErrorCode.PAYMENT_PLUGIN_API_ABORTED.getCode());
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceSystemDisabling.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceSystemDisabling.java
index 6c848e7..30ff650 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceSystemDisabling.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceSystemDisabling.java
@@ -76,7 +76,7 @@ public class TestInvoiceSystemDisabling extends TestIntegrationBase {
assertEquals(invoices.size(), 0);
// Dry-run generation
- Invoice invoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), new TestDryRunArguments(DryRunType.TARGET_DATE), callContext);
+ Invoice invoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), new TestDryRunArguments(DryRunType.TARGET_DATE), callContext);
assertListenerStatus();
final ImmutableList<ExpectedInvoiceItemCheck> expected = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, BigDecimal.ZERO),
new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
@@ -89,7 +89,7 @@ public class TestInvoiceSystemDisabling extends TestIntegrationBase {
// Non dry-run generation
busHandler.pushExpectedEvents(NextEvent.TAG, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- invoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), null, callContext);
+ invoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), callContext);
assertListenerStatus();
// Now unparked
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
index 072f857..577c17e 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
@@ -86,7 +86,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Entitlement wil be created in PENDING state
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleKey", entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.PENDING);
@@ -143,7 +143,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleKey", entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -189,7 +189,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleKey", entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
@@ -244,8 +244,8 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
final PlanPhaseSpecifier addOnSpec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final String externalKey = "baseExternalKey";
- EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec, null);
- EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1, null);
+ EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec);
+ EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1);
final List<EntitlementSpecifier> specifierList = new ArrayList<EntitlementSpecifier>();
specifierList.add(baseEntitlementSpecifier);
@@ -293,8 +293,8 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
final PlanPhaseSpecifier addOnSpec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final String externalKey = "baseExternalKey";
- EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec, null);
- EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1, null);
+ EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec);
+ EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1);
final List<EntitlementSpecifier> specifierList = new ArrayList<EntitlementSpecifier>();
specifierList.add(baseEntitlementSpecifier);
@@ -356,7 +356,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
clock.addMonths(1);
@@ -385,7 +385,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Unlike the previous scenario, we create the subscription and set the blocking state at the same time
busHandler.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK);
subscriptionApi.addBlockingState(blockingState1, null, ImmutableList.<PluginProperty>of(), callContext);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
clock.addMonths(1);
@@ -424,7 +424,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Add less than a day between the CREATE and the BLOCK, to verify invoicing behavior
@@ -468,7 +468,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -477,7 +477,7 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Add an add-on while bundle is already blocked
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("cleaning-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec2, ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec2), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
clock.addMonths(1);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java
index 9b1379b..ad12eae 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentRefund.java
@@ -22,7 +22,6 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -48,7 +47,6 @@ import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionStatus;
-import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -56,8 +54,8 @@ import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
-import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -116,13 +114,9 @@ public class TestPaymentRefund extends TestIntegrationBase {
@Test(groups = "slow")
public void testFailedRefundWithInvoiceAdjustment() throws Exception {
-
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_WITH_ADJUSTMENTS, "true", false);
- properties.add(prop1);
try {
- paymentApi.createRefundWithPaymentControl(account, payment.getId(), payment.getPurchasedAmount(), payment.getCurrency(), null, UUID.randomUUID().toString(),
- properties, PAYMENT_OPTIONS, callContext);
+ invoicePaymentApi.createRefundForInvoicePayment(true, null, account, payment.getId(), payment.getPurchasedAmount(), payment.getCurrency(), null, UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(), PAYMENT_OPTIONS, callContext);
fail("Refund with invoice adjustment should now throw an Exception");
} catch (final PaymentApiException e) {
Assert.assertEquals(e.getCause(), null);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java
index 2c9aa27..8cd0266 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java
@@ -19,6 +19,7 @@
package org.killbill.billing.beatrix.integration;
import java.io.IOException;
+import java.math.BigDecimal;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
@@ -28,10 +29,12 @@ import org.killbill.billing.account.api.Account;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.callcontext.DefaultCallContext;
import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.notification.plugin.api.ExtBusEvent;
import org.killbill.billing.notification.plugin.api.ExtBusEventType;
+import org.killbill.billing.notification.plugin.api.InvoiceNotificationMetadata;
import org.killbill.billing.notification.plugin.api.SubscriptionMetadata;
import org.killbill.billing.overdue.api.OverdueConfig;
import org.killbill.billing.platform.api.KillbillConfigSource;
@@ -66,9 +69,11 @@ public class TestPublicBus extends TestIntegrationBase {
@Override
protected KillbillConfigSource getConfigSource() {
- final ImmutableMap<String, String> additionalProperties = new ImmutableMap.Builder<String, String>().put("org.killbill.billing.util.broadcast.rate", "500ms")
- .build();
- return getConfigSource("/beatrix.properties", additionalProperties);
+ return getConfigSource(null, new ImmutableMap.Builder()
+ .putAll(DEFAULT_BEATRIX_PROPERTIES)
+ .put("org.killbill.billing.util.broadcast.rate", "500ms")
+ .put("org.killbill.invoice.dryRunNotificationSchedule", "1d")
+ .build());
}
@Override
@@ -124,12 +129,13 @@ public class TestPublicBus extends TestIntegrationBase {
final DateTime initialDate = new DateTime(2012, 2, 1, 0, 3, 42, 0, testTimeZone);
final int billingDay = 2;
+ // set clock to the initial start date
+ clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
+
log.info("Beginning test with BCD of " + billingDay);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(billingDay));
assertNotNull(account);
- // set clock to the initial start date
- clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
//
// CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
@@ -145,13 +151,15 @@ public class TestPublicBus extends TestIntegrationBase {
}
});
- addDaysAndCheckForCompletion(31, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+ addDaysAndCheckForCompletion(29, NextEvent.INVOICE_NOTIFICATION);
+
+ addDaysAndCheckForCompletion(1, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
await().atMost(10, SECONDS).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
// 5 + SUBSCRIPTION_TRANSITION, INVOICE, PAYMENT, INVOICE_PAYMENT
- return externalBusCount.get() == 10;
+ return externalBusCount.get() == 11;
}
});
}
@@ -181,27 +189,31 @@ public class TestPublicBus extends TestIntegrationBase {
public void handleExternalEvents(final ExtBusEvent event) {
log.info("GOT EXT EVENT " + event);
- if (event.getEventType() == ExtBusEventType.SUBSCRIPTION_CREATION ||
- event.getEventType() == ExtBusEventType.SUBSCRIPTION_CANCEL ||
- event.getEventType() == ExtBusEventType.SUBSCRIPTION_PHASE ||
- event.getEventType() == ExtBusEventType.SUBSCRIPTION_CHANGE ||
- event.getEventType() == ExtBusEventType.SUBSCRIPTION_UNCANCEL ||
- event.getEventType() == ExtBusEventType.SUBSCRIPTION_BCD_CHANGE) {
- try {
+ try {
+ if (event.getEventType() == ExtBusEventType.SUBSCRIPTION_CREATION ||
+ event.getEventType() == ExtBusEventType.SUBSCRIPTION_CANCEL ||
+ event.getEventType() == ExtBusEventType.SUBSCRIPTION_PHASE ||
+ event.getEventType() == ExtBusEventType.SUBSCRIPTION_CHANGE ||
+ event.getEventType() == ExtBusEventType.SUBSCRIPTION_UNCANCEL ||
+ event.getEventType() == ExtBusEventType.SUBSCRIPTION_BCD_CHANGE) {
final SubscriptionMetadata obj = mapper.readValue(event.getMetaData(), SubscriptionMetadata.class);
Assert.assertNotNull(obj.getBundleExternalKey());
Assert.assertNotNull(obj.getActionType());
- } catch (final JsonParseException e) {
- Assert.fail("Could not deserialize metada section", e);
- } catch (final JsonMappingException e) {
- Assert.fail("Could not deserialize metada section", e);
- } catch (final IOException e) {
- Assert.fail("Could not deserialize metada section", e);
+ } else if (event.getEventType() == ExtBusEventType.INVOICE_NOTIFICATION) {
+ final InvoiceNotificationMetadata obj = mapper.readValue(event.getMetaData(), InvoiceNotificationMetadata.class);
+ Assert.assertEquals(obj.getAmountOwed().compareTo(new BigDecimal("249.95")), 0);
+ Assert.assertEquals(obj.getCurrency(), Currency.USD);
+ Assert.assertNotNull(obj.getTargetDate());
}
- }
+ } catch (final JsonParseException e) {
+ Assert.fail("Could not deserialize metada section", e);
+ } catch (final JsonMappingException e) {
+ Assert.fail("Could not deserialize metada section", e);
+ } catch (final IOException e) {
+ Assert.fail("Could not deserialize metada section", e);
+ }
externalBusCount.incrementAndGet();
-
}
}
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java
index c4edb51..a9bc6a6 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java
@@ -104,7 +104,7 @@ public class TestSubscription extends TestIntegrationBase {
TestDryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, productName, ProductCategory.BASE, BillingPeriod.MONTHLY, null, null,
SubscriptionEventType.CHANGE, bpEntitlement.getId(), bpEntitlement.getBundleId(), null, BillingActionPolicy.IMMEDIATE);
- Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, toBeChecked);
changeEntitlementAndCheckForCompletion(bpEntitlement, productName, BillingPeriod.MONTHLY, BillingActionPolicy.IMMEDIATE, NextEvent.CHANGE, NextEvent.INVOICE);
@@ -202,9 +202,9 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier addOnSpec2 = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final String externalKeyA = "baseExternalKeyAAA";
- final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec, null);
- final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1, null);
- final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2, null);
+ final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec);
+ final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1);
+ final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2);
final List<EntitlementSpecifier> specifierListA = new ArrayList<EntitlementSpecifier>();
specifierListA.add(baseEntitlementSpecifier);
@@ -290,9 +290,9 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier addOnSpec2 = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final String externalKeyA = "baseExternalKeyAAA";
- final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec, null);
- final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1, null);
- final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2, null);
+ final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec);
+ final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1);
+ final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2);
final List<EntitlementSpecifier> specifierListA = new ArrayList<EntitlementSpecifier>();
specifierListA.add(baseEntitlementSpecifier);
@@ -340,9 +340,9 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier addOnSpec2 = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final String externalKeyA = "baseExternalKeyAAA";
- final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec, null);
- final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1, null);
- final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2, null);
+ final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec);
+ final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1);
+ final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2);
final List<EntitlementSpecifier> specifierListA = new ArrayList<EntitlementSpecifier>();
specifierListA.add(baseEntitlementSpecifier);
@@ -375,17 +375,17 @@ public class TestSubscription extends TestIntegrationBase {
// Create first add_on subscription
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec1), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Create second add_on subscription with the same plan
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec2, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec2), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Trying to add the third add_on with the same plan should throw an exception (the limit is 2 for this plan)
try {
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec3, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec3), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE.getCode());
}
@@ -408,24 +408,24 @@ public class TestSubscription extends TestIntegrationBase {
// Create first add_on subscription
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec1), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Create second add_on subscription with the same plan
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec2, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec2), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Create third add_on subscription with another plan
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- final UUID addOn3Id = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec3, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOn3Id = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec3), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement addOn3 = entitlementApi.getEntitlementForId(addOn3Id, callContext);
// Trying to change the plan of the third add_on to 'Laser-Scope' plan, should throw an exception (the limit is 2 for this plan)
try {
final PlanPhaseSpecifier addOnSpecChangedPlan = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- addOn3.changePlan(addOnSpecChangedPlan, null, ImmutableList.<PluginProperty>of(), callContext);
+ addOn3.changePlan(new DefaultEntitlementSpecifier(addOnSpecChangedPlan), ImmutableList.<PluginProperty>of(), callContext);
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE.getCode());
}
@@ -443,7 +443,7 @@ public class TestSubscription extends TestIntegrationBase {
final LocalDate futureDate = new LocalDate(2015, 10, 1);
// No CREATE event as this is set in the future
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -476,7 +476,7 @@ public class TestSubscription extends TestIntegrationBase {
final LocalDate futureDate = new LocalDate(2015, 10, 1);
// No CREATE event as this is set in the future
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getState(), EntitlementState.PENDING);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
@@ -521,7 +521,7 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(initialDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -551,7 +551,7 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(initialDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java
index 1ad2a6a..7e49d27 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java
@@ -39,6 +39,7 @@ import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
import org.killbill.billing.entitlement.api.Subscription;
@@ -572,7 +573,7 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// BP creation : Will set Account BCD to the first (DateOfFirstRecurringNonZeroCharge is the subscription start date in this case)
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, overrides), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -595,7 +596,7 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
// Change to the paying plan (alignment is CHANGE_OF_PLAN: we end up in TRIAL)
final PlanPhaseSpecifier specWithTrial = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "trial", null);
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
- baseEntitlement.changePlanOverrideBillingPolicy(specWithTrial, ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
+ baseEntitlement.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(specWithTrial), clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Trial invoice
@@ -635,7 +636,7 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// BP creation : Will set Account BCD to the first (DateOfFirstRecurringNonZeroCharge is the subscription start date in this case)
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, overrides), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -654,7 +655,7 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
// Extra NULL_INVOICE event because invoice computes a future notification effective right away
final PlanPhaseSpecifier specWithTrial = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "trial", null);
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.NULL_INVOICE, NextEvent.INVOICE);
- baseEntitlement.changePlanOverrideBillingPolicy(specWithTrial, ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
+ baseEntitlement.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(specWithTrial), clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Trial invoice (with re-alignment invoice item from free plan)
@@ -694,7 +695,7 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// BP creation : Will set Account BCD to the first (DateOfFirstRecurringNonZeroCharge is the subscription start date in this case)
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, overrides), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -716,7 +717,7 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
// Change to the paying plan
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- baseEntitlement.changePlanOverrideBillingPolicy(toSpec, ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
+ baseEntitlement.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(toSpec), clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// First paying invoice
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
index 53bf21c..f6037c5 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
@@ -145,7 +145,7 @@ public class TestWithEntilementPlugin extends TestIntegrationBase {
@Override
public PriorEntitlementResult priorCall(final EntitlementContext entitlementContext, final Iterable<PluginProperty> properties) throws EntitlementPluginApiException {
if (planPhasePriceOverride != null) {
- final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().iterator().next().getEntitlementSpecifier().iterator().next().getPlanPhaseSpecifier(), planPhasePriceOverride);
+ final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().iterator().next().getEntitlementSpecifier().iterator().next().getPlanPhaseSpecifier(), null, planPhasePriceOverride);
final List<EntitlementSpecifier> entitlementSpecifiers = new ArrayList<EntitlementSpecifier>();
entitlementSpecifiers.add(entitlementSpecifier);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithFakeKPMPlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithFakeKPMPlugin.java
index f3892bf..44476e3 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithFakeKPMPlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithFakeKPMPlugin.java
@@ -95,10 +95,10 @@ public class TestWithFakeKPMPlugin extends TestIntegrationBase {
@Override
protected KillbillConfigSource getConfigSource() {
- ImmutableMap additionalProperties = new ImmutableMap.Builder()
+ return getConfigSource(null, new ImmutableMap.Builder()
+ .putAll(DEFAULT_BEATRIX_PROPERTIES)
.put("org.killbill.billing.util.broadcast.rate", "100ms")
- .build();
- return getConfigSource("/beatrix.properties", additionalProperties);
+ .build());
}
public class FakeKPMPlugin {
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
index e1e9460..d8c5a35 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
@@ -376,7 +376,7 @@ public class TestWithInvoicePlugin extends TestIntegrationBase {
// Trigger a manual invoice run
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), null, callContext);
+ invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), callContext);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 2, callContext,
new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")),
@@ -528,7 +528,7 @@ public class TestWithInvoicePlugin extends TestIntegrationBase {
testInvoicePluginApi.rescheduleDate = new DateTime(clock.getUTCNow()).plusDays(30);
try {
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), null, callContext);
+ invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), callContext);
Assert.fail();
} catch (final InvoiceApiException e) {
Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_NOTHING_TO_DO.getCode());
@@ -552,7 +552,7 @@ public class TestWithInvoicePlugin extends TestIntegrationBase {
// Reschedule next invoice one month in the future
testInvoicePluginApi.rescheduleDate = clock.getUTCNow().plusMonths(1);
try {
- invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), null, callContext);
+ invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), callContext);
Assert.fail();
} catch (final InvoiceApiException e) {
Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_NOTHING_TO_DO.getCode());
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java
index 0091248..28053af 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithPriceOverride.java
@@ -35,6 +35,7 @@ import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.invoice.api.InvoiceItemType;
import org.killbill.billing.payment.api.PluginProperty;
import org.testng.annotations.Test;
@@ -118,7 +119,8 @@ public class TestWithPriceOverride extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-evergreen", account.getCurrency(), null, new BigDecimal("279.95"), null));
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- bpSubscription.changePlanOverrideBillingPolicy(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), overrides, null, BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ bpSubscription.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(spec, null, overrides), null, BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 3, callContext,
@@ -165,7 +167,8 @@ public class TestWithPriceOverride extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("telescopic-scope-monthly-evergreen", account.getCurrency(), null, new BigDecimal("1200.00"), null));
busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- aoEntitlement.changePlanOverrideBillingPolicy(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), overrides, null, BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ aoEntitlement.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(spec, null, overrides), null, BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
}
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java
index 76d7ef4..2710710 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java
@@ -230,7 +230,7 @@ public class TestWithTaxItems extends TestIntegrationBase {
testInvoicePluginApi.addTaxItem(new TaxInvoiceItem(UUID.randomUUID(), null, account.getId(), null, "Tax Item", new LocalDate(2012, 4, 1), BigDecimal.ONE, account.getCurrency()));
// Verify dry-run scenario
- final Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2012, 5, 1), new TestDryRunArguments(DryRunType.TARGET_DATE), callContext);
+ final Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(2012, 5, 1), new TestDryRunArguments(DryRunType.TARGET_DATE), callContext);
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice,
ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")),
new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.TAX, new BigDecimal("1.0")),
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java
index 6ca9f1b..53aba95 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java
@@ -36,7 +36,9 @@ import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.api.DryRunType;
import org.killbill.billing.invoice.api.Invoice;
@@ -80,7 +82,7 @@ public class TestWithTimeZones extends TestIntegrationBase {
final TestDryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, null, null,
SubscriptionEventType.START_BILLING, null, null, null, null);
- final Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
+ final Invoice dryRunInvoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 9, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, expectedInvoices);
@@ -138,7 +140,7 @@ public class TestWithTimeZones extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
- UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -185,7 +187,7 @@ public class TestWithTimeZones extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
- UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -240,7 +242,7 @@ public class TestWithTimeZones extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
// Pass a date of today, to trigger TimeAwareContext#toUTCDateTime
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), clock.getUTCToday(), false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", clock.getUTCToday(), clock.getUTCToday(), false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -367,7 +369,7 @@ public class TestWithTimeZones extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial",null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
index b4a65ac..551822f 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
@@ -18,13 +18,8 @@
package org.killbill.billing.beatrix.integration.usage;
import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountData;
@@ -33,21 +28,11 @@ import org.killbill.billing.beatrix.integration.TestIntegrationBase;
import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
-import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.invoice.api.InvoiceItemType;
-import org.killbill.billing.mock.MockAccountBuilder;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.usage.api.SubscriptionUsageRecord;
-import org.killbill.billing.usage.api.UnitUsageRecord;
-import org.killbill.billing.usage.api.UsageApiException;
-import org.killbill.billing.usage.api.UsageRecord;
-import org.killbill.billing.util.callcontext.CallContext;
-import org.skife.jdbi.v2.Handle;
-import org.skife.jdbi.v2.tweak.HandleCallback;
import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
@@ -77,8 +62,8 @@ public class TestConsumableInArrear extends TestIntegrationBase {
//
final DefaultEntitlement aoSubscription = addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Bullets", ProductCategory.ADD_ON, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 1), 99L, callContext);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 15), 100L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 1), 99L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 15), 100L, callContext);
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(30);
@@ -96,8 +81,8 @@ public class TestConsumableInArrear extends TestIntegrationBase {
invoiceChecker.checkInvoice(account.getId(), 3, callContext,
new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.USAGE, BigDecimal.ZERO));
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 6, 1), 50L, callContext);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 6, 16), 300L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 6, 1), 50L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 6, 16), 300L, callContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
@@ -107,14 +92,18 @@ public class TestConsumableInArrear extends TestIntegrationBase {
new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.USAGE, new BigDecimal("11.80")));
// Should be ignored because this is outside of optimization range (org.killbill.invoice.readMaxRawUsagePreviousPeriod = 2) => we will only look for items > 2012-7-1 - 2 months = 2012-5-1
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 30), 100L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 30), 100L, callContext);
// Should be invoiced from past period
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 1), 199L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 1), 199L, callContext);
// New usage for this past period
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 7, 1), 50L, callContext);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 7, 16), 300L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 7, 1), 50L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 7, 16), 300L, callContext);
+
+ // Remove old data, should be ignored by the system because readMaxRawUsagePreviousPeriod = 2, so:
+ // * Last endDate invoiced is 2012-7-1 => Anything 2 period prior that will be ignored => Anything prior 2012-5-1 should be ignored
+ removeUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 15));
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
@@ -130,7 +119,7 @@ public class TestConsumableInArrear extends TestIntegrationBase {
int currentInvoice = 6;
for (int i = 0; i < 8; i++) {
- setUsage(aoSubscription.getId(), "bullets", startDate.plusDays(15), 350L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", startDate.plusDays(15), 350L, callContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
@@ -168,8 +157,8 @@ public class TestConsumableInArrear extends TestIntegrationBase {
//
final DefaultEntitlement aoSubscription = addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Bullets", ProductCategory.ADD_ON, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 1), 99L, callContext);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 15), 100L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 1), 99L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 4, 15), 100L, callContext);
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(30);
@@ -178,11 +167,11 @@ public class TestConsumableInArrear extends TestIntegrationBase {
new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2013, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")),
new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.USAGE, new BigDecimal("5.90")));
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 3), 99L, callContext);
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 5), 100L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 3), 99L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 5), 100L, callContext);
// This one should be ignored
- setUsage(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 29), 100L, callContext);
+ recordUsageData(aoSubscription.getId(), "bullets", new LocalDate(2012, 5, 29), 100L, callContext);
clock.addDays(27);
busHandler.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
@@ -215,8 +204,8 @@ public class TestConsumableInArrear extends TestIntegrationBase {
Assert.assertNull(bpSubscription.getSubscriptionBase().getChargedThroughDate());
// Record usage for first month
- setUsage(bpSubscription.getId(), "stones", new LocalDate(2012, 4, 5), 85L, callContext);
- setUsage(bpSubscription.getId(), "stones", new LocalDate(2012, 4, 15), 150L, callContext);
+ recordUsageData(bpSubscription.getId(), "stones", new LocalDate(2012, 4, 5), 85L, callContext);
+ recordUsageData(bpSubscription.getId(), "stones", new LocalDate(2012, 4, 15), 150L, callContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
@@ -242,8 +231,8 @@ public class TestConsumableInArrear extends TestIntegrationBase {
Assert.assertEquals(subscriptionBaseInternalApiApi.getSubscriptionFromId(bpSubscription.getId(), internalCallContext).getChargedThroughDate().compareTo(secondExpectedCTD), 0);
// Record usage for third month (verify invoicing resumes)
- setUsage(bpSubscription.getId(), "stones", new LocalDate(2012, 6, 5), 25L, callContext);
- setUsage(bpSubscription.getId(), "stones", new LocalDate(2012, 6, 15), 50L, callContext);
+ recordUsageData(bpSubscription.getId(), "stones", new LocalDate(2012, 6, 5), 25L, callContext);
+ recordUsageData(bpSubscription.getId(), "stones", new LocalDate(2012, 6, 15), 50L, callContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
@@ -255,13 +244,4 @@ public class TestConsumableInArrear extends TestIntegrationBase {
final DateTime thirdExpectedCTD = account.getReferenceTime().withMonthOfYear(7).withDayOfMonth(1);
Assert.assertEquals(subscriptionBaseInternalApiApi.getSubscriptionFromId(bpSubscription.getId(), internalCallContext).getChargedThroughDate().compareTo(thirdExpectedCTD), 0);
}
-
- private void setUsage(final UUID subscriptionId, final String unitType, final LocalDate startDate, final Long amount, final CallContext context) throws UsageApiException {
- final List<UsageRecord> usageRecords = new ArrayList<UsageRecord>();
- usageRecords.add(new UsageRecord(startDate, amount));
- final List<UnitUsageRecord> unitUsageRecords = new ArrayList<UnitUsageRecord>();
- unitUsageRecords.add(new UnitUsageRecord(unitType, usageRecords));
- final SubscriptionUsageRecord record = new SubscriptionUsageRecord(subscriptionId, UUID.randomUUID().toString(), unitUsageRecords);
- usageUserApi.recordRolledUpUsage(record, context);
- }
}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestInArrearWithCatalogVersions.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestInArrearWithCatalogVersions.java
new file mode 100644
index 0000000..894f939
--- /dev/null
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestInArrearWithCatalogVersions.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.beatrix.integration.usage;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.LocalDate;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountData;
+import org.killbill.billing.api.TestApiListener.NextEvent;
+import org.killbill.billing.beatrix.integration.TestIntegrationBase;
+import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
+import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
+import org.killbill.billing.entitlement.api.Entitlement;
+import org.killbill.billing.invoice.api.InvoiceItemType;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.platform.api.KillbillConfigSource;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class TestInArrearWithCatalogVersions extends TestIntegrationBase {
+
+ @Override
+ protected KillbillConfigSource getConfigSource() {
+ return super.getConfigSource(null, ImmutableMap.of("org.killbill.catalog.uri", "catalogs/testInArrearWithCatalogVersions",
+ "org.killbill.invoice.readMaxRawUsagePreviousPeriod", "0"));
+ }
+
+ @Test(groups = "slow")
+ public void testWithChangeAcrossCatalogs() throws Exception {
+ // 30 days month
+ clock.setDay(new LocalDate(2016, 4, 1));
+
+ final AccountData accountData = getAccountData(1);
+ final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+ accountChecker.checkAccount(account.getId(), accountData, callContext);
+
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("electricity-monthly");
+ busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 4, 1), 143L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 4, 18), 57L, callContext);
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addMonths(1);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 4, 1), new LocalDate(2016, 5, 1), InvoiceItemType.USAGE, new BigDecimal("300.00")));
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 2), 100L, callContext); // -> Uses v1 : $150
+
+ // Catalog change with new price on 2016-05-08
+ // Schedule CHANGE_PLAN on 2016-05-09
+ final Entitlement bp = entitlementApi.getEntitlementForId(entitlementId, callContext);
+
+ bp.changePlanWithDate(new DefaultEntitlementSpecifier(spec), new LocalDate("2016-05-09"), null, callContext);
+ assertListenerStatus();
+
+ busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addDays(8);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 1), new LocalDate(2016, 5, 9), InvoiceItemType.USAGE, new BigDecimal("150.00")));
+
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 10), 100L, callContext); // -> Uses v2 : $250
+
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addDays(23);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 3, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 9), new LocalDate(2016, 6, 1), InvoiceItemType.USAGE, new BigDecimal("250.00")));
+
+ }
+
+
+ @Test(groups = "slow")
+ public void testWithChangeWithinCatalog() throws Exception {
+ // 30 days month
+ clock.setDay(new LocalDate(2016, 4, 1));
+
+ final AccountData accountData = getAccountData(1);
+ final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+ accountChecker.checkAccount(account.getId(), accountData, callContext);
+
+ final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("electricity-monthly");
+ busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec1), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 4, 1), 143L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 4, 18), 57L, callContext);
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addMonths(1);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 4, 1), new LocalDate(2016, 5, 1), InvoiceItemType.USAGE, new BigDecimal("300.00")));
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 2), 100L, callContext); // -> Uses v1 : $150
+
+ final Entitlement bp = entitlementApi.getEntitlementForId(entitlementId, callContext);
+
+ final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("electricity-monthly-special");
+
+ bp.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), new LocalDate("2016-05-09"), null, callContext);
+ assertListenerStatus();
+
+ busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addDays(8);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 1), new LocalDate(2016, 5, 9), InvoiceItemType.USAGE, new BigDecimal("150.00")));
+
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 10), 100L, callContext); // -> Uses special plan : $100
+
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addDays(23);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 3, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 9), new LocalDate(2016, 6, 1), InvoiceItemType.USAGE, new BigDecimal("100.00")));
+
+ }
+
+
+
+
+ // We are not using catalog versions in this test but testing the overridden value of 'readMaxRawUsagePreviousPeriod = 0'
+ @Test(groups = "slow")
+ public void testWithRemovedData() throws Exception {
+ // 30 days month
+ clock.setDay(new LocalDate(2016, 4, 1));
+
+ final AccountData accountData = getAccountData(1);
+ final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+ accountChecker.checkAccount(account.getId(), accountData, callContext);
+
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("electricity-monthly");
+ busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 4, 5), 1L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 4, 5), 99L, callContext);
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addMonths(1);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 4, 1), new LocalDate(2016, 5, 1), InvoiceItemType.USAGE, new BigDecimal("150.00")));
+
+
+
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 5), 100L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 8), 900L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 9), 200L, callContext); // Move to tier 2.
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addMonths(1);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 1), new LocalDate(2016, 6, 1), InvoiceItemType.USAGE, new BigDecimal("1900.00")));
+
+
+
+ // Remove Usage data from period 2016-5-1 -> 2016-6-1 and verify there is no issue (readMaxRawUsagePreviousPeriod = 0 => We ignore any past invoiced period)
+ // Full deletion on the second tier
+ removeUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 5, 9));
+
+ //
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 6, 5), 100L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 6, 8), 900L, callContext);
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 6, 12), 50L, callContext); // Move to tier 2.
+ recordUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 6, 13), 50L, callContext);
+
+ busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ clock.addMonths(1);
+ assertListenerStatus();
+
+ invoiceChecker.checkInvoice(account.getId(), 3, callContext, ImmutableList.<ExpectedInvoiceItemCheck>of(
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 6, 1), new LocalDate(2016, 7, 1), InvoiceItemType.USAGE, new BigDecimal("1700.00"))));
+
+
+ // Remove Usage data from period 2016-6-1 -> 2016-7-1 and verify there is no issue (readMaxRawUsagePreviousPeriod = 0 => We ignore any past invoiced period)
+ // Partial deletion on the second tier
+ removeUsageData(entitlementId, "kilowatt-hour", new LocalDate(2016, 6, 13));
+
+ // No usage this MONTH
+ busHandler.pushExpectedEvents(NextEvent.INVOICE);
+ clock.addMonths(1);
+ assertListenerStatus();
+
+ // Check invoicing occurred and - i.e system did not detect deletion of passed invoiced data.
+ invoiceChecker.checkInvoice(account.getId(), 4, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2016, 7, 1), new LocalDate(2016, 8, 1), InvoiceItemType.USAGE, BigDecimal.ZERO));
+ }
+
+
+}
\ No newline at end of file
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/util/PaymentChecker.java b/beatrix/src/test/java/org/killbill/billing/beatrix/util/PaymentChecker.java
index 9925dde..d5975a4 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/util/PaymentChecker.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/util/PaymentChecker.java
@@ -25,7 +25,7 @@ import java.util.UUID;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoicePayment;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentTransaction;
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java b/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java
index 9472f6b..be4df72 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java
@@ -28,9 +28,9 @@ import javax.annotation.Nullable;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoicePayment;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoicePaymentType;
import org.killbill.billing.invoice.api.InvoiceUserApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentTransaction;
diff --git a/beatrix/src/test/resources/beatrixCatalogRetireElements.properties b/beatrix/src/test/resources/beatrixCatalogRetireElements.properties
index 65c1483..bd021d3 100644
--- a/beatrix/src/test/resources/beatrixCatalogRetireElements.properties
+++ b/beatrix/src/test/resources/beatrixCatalogRetireElements.properties
@@ -15,6 +15,6 @@
# under the License.
#
-org.killbill.catalog.uri=retiredCatalogs
+
org.killbill.payment.retry.days=8,8,8,8,8,8,8,8
org.killbill.osgi.bundle.install.dir=/var/tmp/beatrix-bundles
beatrix/src/test/resources/catalogs/default/catalogTest.xml 1465(+1465 -0)
diff --git a/beatrix/src/test/resources/catalogs/default/catalogTest.xml b/beatrix/src/test/resources/catalogs/default/catalogTest.xml
new file mode 100644
index 0000000..77a6048
--- /dev/null
+++ b/beatrix/src/test/resources/catalogs/default/catalogTest.xml
@@ -0,0 +1,1465 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ ~ Copyright 2010-2013 Ning, Inc.
+ ~ Copyright 2014-2018 Groupon, Inc
+ ~ Copyright 2014-2018 The Billing Project, LLC
+ ~
+ ~ The Billing Project licenses this file to you under the Apache License, version 2.0
+ ~ (the "License"); you may not use this file except in compliance with the
+ ~ License. You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ ~ License for the specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<!-- Use cases covered so far: Tiered Product (Pistol/Shotgun/Assault-Rifle)
+ Multiple changeEvent plan policies Multiple PlanAlignment (see below, trial
+ add-on alignments and rescue discount package) Product transition rules Add
+ on (Scopes, Hoster) Multi-pack addon (Extra-Ammo) Addon Trial aligned to
+ base plan (holster-monthly-regular) Addon Trial aligned to creation (holster-monthly-special)
+ Rescue discount package (assault-rifle-annual-rescue) Plan phase with a reccurring
+ and a one off (refurbish-maintenance) Phan with more than 2 phase (gunclub
+ discount plans) Use Cases to do: Tiered Add On Riskfree period -->
+<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
+
+ <effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
+ <catalogName>Firearms</catalogName>
+
+ <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
+ <currencies>
+ <currency>USD</currency>
+ <currency>EUR</currency>
+ <currency>GBP</currency>
+ </currencies>
+
+ <units>
+ <unit name="bullets"/>
+ <unit name="stones"/>
+ </units>
+
+ <products>
+ <product name="Knife">
+ <category>STANDALONE</category>
+ </product>
+ <product name="Blowdart">
+ <category>BASE</category>
+ </product>
+ <product name="Pistol">
+ <category>BASE</category>
+ <available>
+ <addonProduct>Cleaning</addonProduct>
+ <addonProduct>Bullets</addonProduct>
+ <addonProduct>Refurbish-Maintenance</addonProduct>
+ </available>
+ </product>
+ <product name="Shotgun">
+ <category>BASE</category>
+ <included>
+ <addonProduct>Cleaning</addonProduct>
+ </included>
+ <available>
+ <addonProduct>Telescopic-Scope</addonProduct>
+ <addonProduct>Laser-Scope</addonProduct>
+ <addonProduct>Holster</addonProduct>
+ <addonProduct>Bullets</addonProduct>
+ </available>
+ </product>
+ <product name="Assault-Rifle">
+ <category>BASE</category>
+ <included>
+ <addonProduct>Telescopic-Scope</addonProduct>
+ <addonProduct>Cleaning</addonProduct>
+ </included>
+ <available>
+ <addonProduct>Laser-Scope</addonProduct>
+ <addonProduct>Bullets</addonProduct>
+ </available>
+ </product>
+ <product name="Trebuchet">
+ <category>BASE</category>
+ </product>
+ <product name="Cleaning">
+ <category>ADD_ON</category>
+ </product>
+ <product name="Telescopic-Scope">
+ <category>ADD_ON</category>
+ </product>
+ <product name="Laser-Scope">
+ <category>ADD_ON</category>
+ </product>
+ <product name="Holster">
+ <category>ADD_ON</category>
+ </product>
+ <product name="Extra-Ammo">
+ <category>ADD_ON</category>
+ </product>
+ <product name="Refurbish-Maintenance">
+ <category>ADD_ON</category>
+ </product>
+ <product name="Bullets">
+ <category>ADD_ON</category>
+ </product>
+ </products>
+
+ <rules>
+ <changePolicy>
+ <changePolicyCase>
+ <phaseType>TRIAL</phaseType>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <toPriceList>rescue</toPriceList>
+ <policy>END_OF_TERM</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <toProduct>Assault-Rifle</toProduct>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <fromProduct>Pistol</fromProduct>
+ <toProduct>Shotgun</toProduct>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <fromBillingPeriod>MONTHLY</fromBillingPeriod>
+ <toBillingPeriod>ANNUAL</toBillingPeriod>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <fromBillingPeriod>ANNUAL</fromBillingPeriod>
+ <toBillingPeriod>MONTHLY</toBillingPeriod>
+ <policy>END_OF_TERM</policy>
+ </changePolicyCase>
+ <changePolicyCase>
+ <policy>END_OF_TERM</policy>
+ </changePolicyCase>
+ </changePolicy>
+ <changeAlignment>
+ <changeAlignmentCase>
+ <toPriceList>rescue</toPriceList>
+ <alignment>CHANGE_OF_PLAN</alignment>
+ </changeAlignmentCase>
+ <changeAlignmentCase>
+ <fromPriceList>rescue</fromPriceList>
+ <toPriceList>rescue</toPriceList>
+ <alignment>CHANGE_OF_PRICELIST</alignment>
+ </changeAlignmentCase>
+ <changeAlignmentCase>
+ <fromPriceList>notrial</fromPriceList>
+ <toPriceList>trial</toPriceList>
+ <alignment>CHANGE_OF_PLAN</alignment>
+ </changeAlignmentCase>
+ <changeAlignmentCase>
+ <alignment>START_OF_SUBSCRIPTION</alignment>
+ </changeAlignmentCase>
+ </changeAlignment>
+ <cancelPolicy>
+ <cancelPolicyCase>
+ <phaseType>TRIAL</phaseType>
+ <policy>IMMEDIATE</policy>
+ </cancelPolicyCase>
+ <cancelPolicyCase>
+ <policy>END_OF_TERM</policy>
+ </cancelPolicyCase>
+ </cancelPolicy>
+ <createAlignment>
+ <createAlignmentCase>
+ <product>Laser-Scope</product>
+ <alignment>START_OF_SUBSCRIPTION</alignment>
+ </createAlignmentCase>
+ <createAlignmentCase>
+ <alignment>START_OF_BUNDLE</alignment>
+ </createAlignmentCase>
+ </createAlignment>
+ <billingAlignment>
+ <billingAlignmentCase>
+ <productCategory>ADD_ON</productCategory>
+ <alignment>BUNDLE</alignment>
+ </billingAlignmentCase>
+ <billingAlignmentCase>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <alignment>SUBSCRIPTION</alignment>
+ </billingAlignmentCase>
+ <billingAlignmentCase>
+ <alignment>ACCOUNT</alignment>
+ </billingAlignmentCase>
+ </billingAlignment>
+ <priceList>
+ <priceListCase>
+ <fromPriceList>rescue</fromPriceList>
+ <toPriceList>DEFAULT</toPriceList>
+ </priceListCase>
+ </priceList>
+ </rules>
+
+ <plans>
+ <plan name="knife-monthly-notrial">
+ <product>Knife</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="blowdart-monthly-notrial">
+ <product>Blowdart</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-monthly-notrial">
+ <product>Pistol</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>19.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>19.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>19.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="blowdart-monthly">
+ <product>Blowdart</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>6</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>9.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>9.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>9.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="blowdart-monthly-trial">
+ <product>Blowdart</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-weekly">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>WEEKLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-thirty-days">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>THIRTY_DAYS</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-monthly">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+
+ <plan name="pistol-monthly-fixedterm">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="FIXEDTERM">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>12</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>29.95</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>29.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+
+ <plan name="shotgun-monthly" prettyName="Shotgun Monthly">
+ <product>Shotgun</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ <number>-1</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>249.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>149.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>169.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="assault-rifle-monthly">
+ <product>Assault-Rifle</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>599.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>349.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>399.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-quarterly">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>QUARTERLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>69.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>69.95</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>69.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-annual">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>199.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="shotgun-annual">
+ <product>Shotgun</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>2399.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>1499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>1699.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="assault-rifle-annual">
+ <product>Assault-Rifle</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>5999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>3499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>3999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-annual-gunclub-discount">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>6</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>9.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>9.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>9.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>199.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="pistol-annual-gunclub-discount-notrial">
+ <product>Pistol</product>
+ <initialPhases>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>6</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>9.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>9.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>9.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>199.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="shotgun-annual-gunclub-discount">
+ <product>Shotgun</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>6</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>19.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>49.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>69.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>2399.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>1499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>1699.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="assault-rifle-annual-gunclub-discount">
+ <product>Assault-Rifle</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>6</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>99.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>99.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>99.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>5999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>3499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>3999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="laser-scope-monthly">
+ <product>Laser-Scope</product>
+ <initialPhases>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>1</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>1999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>1499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>1999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ <plansAllowedInBundle>2</plansAllowedInBundle>
+ </plan>
+ <plan name="cleaning-monthly">
+ <product>Cleaning</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>2.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>1.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>0.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="telescopic-scope-monthly">
+ <product>Telescopic-Scope</product>
+ <initialPhases>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>1</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>399.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>299.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>399.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="extra-ammo-monthly">
+ <product>Extra-Ammo</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ <plansAllowedInBundle>-1</plansAllowedInBundle>
+ <!-- arbitrary number of these (multipack) -->
+ </plan>
+ <plan name="holster-monthly-regular">
+ <product>Holster</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>199.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="holster-monthly-special">
+ <product>Holster</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ </fixedPrice>
+ </fixed>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>199.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="assault-rifle-annual-rescue">
+ <product>Assault-Rifle</product>
+ <initialPhases>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>YEARS</unit>
+ <number>1</number>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>5999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>3499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>3999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>ANNUAL</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>5999.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>3499.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>3999.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="refurbish-maintenance">
+ <product>Refurbish-Maintenance</product>
+ <finalPhase type="FIXEDTERM">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>12</number>
+ </duration>
+ <fixed>
+ <fixedPrice>
+ <price>
+ <currency>USD</currency>
+ <value>599.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>599.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>599.95</value>
+ </price>
+ </fixedPrice>
+ </fixed>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>199.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>199.95</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
+ <plan name="bullets-usage-in-arrear" prettyName="Bullet Monthly Plan">
+ <product>Bullets</product>
+ <finalPhase type="EVERGREEN" prettyName="Bullet Monthly Plan Evergreen">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <usages>
+ <usage name="bullets-usage-in-arrear-usage" prettyName="Bullet Usage In Arrear" billingMode="IN_ARREAR" usageType="CONSUMABLE">
+ <billingPeriod>MONTHLY</billingPeriod>
+ <tiers>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>bullets</unit>
+ <size>100</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>2.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>1.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>0.95</value>
+ </price>
+ </prices>
+ <max>10</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>bullets</unit>
+ <size>1000</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>5.95</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>4.95</value>
+ </price>
+ <price>
+ <currency>GBP</currency>
+ <value>3.95</value>
+ </price>
+ </prices>
+ <max>100</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ </tiers>
+ </usage>
+ </usages>
+ </finalPhase>
+ <plansAllowedInBundle>-1</plansAllowedInBundle>
+ <!-- arbitrary number of these (multipack) -->
+ </plan>
+ <plan name="trebuchet-usage-in-arrear" prettyName="Trebuchet Monthly Plan">
+ <product>Trebuchet</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <usages>
+ <usage name="trebuchet-in-arrear-usage" billingMode="IN_ARREAR" usageType="CAPACITY">
+ <billingPeriod>MONTHLY</billingPeriod>
+ <tiers>
+ <tier>
+ <limits>
+ <limit>
+ <unit>stones</unit>
+ <max>100</max>
+ </limit>
+ </limits>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>100</value>
+ </price>
+ </recurringPrice>
+ </tier>
+ <tier>
+ <limits>
+ <limit>
+ <unit>stones</unit>
+ <max>-1</max>
+ </limit>
+ </limits>
+ <recurringPrice>
+ <price>
+ <currency>USD</currency>
+ <value>1000</value>
+ </price>
+ </recurringPrice>
+ </tier>
+ </tiers>
+ </usage>
+ </usages>
+ </finalPhase>
+ </plan>
+ </plans>
+ <priceLists>
+ <defaultPriceList name="DEFAULT">
+ <plans>
+ <plan>pistol-weekly</plan>
+ <plan>pistol-thirty-days</plan>
+ <plan>blowdart-monthly</plan>
+ <plan>pistol-monthly</plan>
+ <plan>shotgun-monthly</plan>
+ <plan>assault-rifle-monthly</plan>
+ <plan>pistol-annual</plan>
+ <plan>pistol-quarterly</plan>
+ <plan>shotgun-annual</plan>
+ <plan>assault-rifle-annual</plan>
+ <plan>trebuchet-usage-in-arrear</plan>
+ <plan>laser-scope-monthly</plan>
+ <plan>telescopic-scope-monthly</plan>
+ <plan>cleaning-monthly</plan>
+ <plan>extra-ammo-monthly</plan>
+ <plan>holster-monthly-regular</plan>
+ <plan>refurbish-maintenance</plan>
+ <plan>bullets-usage-in-arrear</plan>
+ <plan>holster-monthly-special</plan>
+ </plans>
+ </defaultPriceList>
+ <childPriceList name="gunclubDiscount">
+ <plans>
+ <plan>pistol-annual-gunclub-discount</plan>
+ <plan>shotgun-annual-gunclub-discount</plan>
+ <plan>assault-rifle-annual-gunclub-discount</plan>
+ </plans>
+ </childPriceList>
+ <childPriceList name="gunclubDiscountNoTrial">
+ <plans>
+ <plan>pistol-annual-gunclub-discount-notrial</plan>
+ </plans>
+ </childPriceList>
+ <childPriceList name="rescue">
+ <plans>
+ <plan>assault-rifle-annual-rescue</plan>
+ </plans>
+ </childPriceList>
+ <childPriceList name="fixedTerm">
+ <plans>
+ <plan>pistol-monthly-fixedterm</plan>
+ </plans>
+ </childPriceList>
+ <childPriceList name="notrial">
+ <plans>
+ <plan>knife-monthly-notrial</plan>
+ <plan>blowdart-monthly-notrial</plan>
+ <plan>pistol-monthly-notrial</plan>
+ </plans>
+ </childPriceList>
+ <childPriceList name="trial">
+ <plans>
+ <plan>blowdart-monthly-trial</plan>
+ </plans>
+ </childPriceList>
+ </priceLists>
+
+</catalog>
diff --git a/beatrix/src/test/resources/catalogs/testInArrearWithCatalogVersions/Utility-v1.xml b/beatrix/src/test/resources/catalogs/testInArrearWithCatalogVersions/Utility-v1.xml
new file mode 100644
index 0000000..d6564ba
--- /dev/null
+++ b/beatrix/src/test/resources/catalogs/testInArrearWithCatalogVersions/Utility-v1.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ ~ Copyright 2014 The Billing Project, Inc.
+ ~
+ ~ Ning licenses this file to you under the Apache License, version 2.0
+ ~ (the "License"); you may not use this file except in compliance with the
+ ~ License. You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ ~ License for the specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
+
+ <effectiveDate>2016-02-08T00:00:00+00:00</effectiveDate>
+ <catalogName>TestInArrearWithCatalogVersions</catalogName>
+
+ <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
+ <currencies>
+ <currency>USD</currency>
+ </currencies>
+
+ <units>
+ <unit name="kilowatt-hour"/>
+ </units>
+
+ <products>
+ <product name="Electricity">
+ <category>BASE</category>
+ </product>
+ </products>
+
+ <rules>
+ <changePolicy>
+ <changePolicyCase>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ </changePolicy>
+ <cancelPolicy>
+ <cancelPolicyCase>
+ <policy>IMMEDIATE</policy>
+ </cancelPolicyCase>
+ </cancelPolicy>
+ </rules>
+
+ <plans>
+
+ <plan name="electricity-monthly">
+ <product>Electricity</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <usages>
+ <usage name="electricity-monthly-usage" billingMode="IN_ARREAR" usageType="CONSUMABLE" tierBlockPolicy="ALL_TIERS">
+ <billingPeriod>MONTHLY</billingPeriod>
+ <tiers>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>kilowatt-hour</unit>
+ <size>1</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>1.50</value>
+ </price>
+ </prices>
+ <max>1000</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>kilowatt-hour</unit>
+ <size>1</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>2.00</value>
+ </price>
+ </prices>
+ <max>-1</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ </tiers>
+ </usage>
+ </usages>
+ </finalPhase>
+ </plan>
+
+ <plan name="electricity-monthly-special">
+ <product>Electricity</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <usages>
+ <usage name="electricity-monthly-special-uusage" billingMode="IN_ARREAR" usageType="CONSUMABLE" tierBlockPolicy="ALL_TIERS">
+ <billingPeriod>MONTHLY</billingPeriod>
+ <tiers>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>kilowatt-hour</unit>
+ <size>1</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>1.00</value>
+ </price>
+ </prices>
+ <max>1000</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ </tiers>
+ </usage>
+ </usages>
+ </finalPhase>
+ </plan>
+
+ </plans>
+ <priceLists>
+ <defaultPriceList name="DEFAULT">
+ <plans>
+ <plan>electricity-monthly</plan>
+ </plans>
+ </defaultPriceList>
+ <childPriceList name="Special">
+ <plans>
+ <plan>electricity-monthly-special</plan>
+ </plans>
+ </childPriceList>
+
+ </priceLists>
+</catalog>
diff --git a/beatrix/src/test/resources/catalogs/testInArrearWithCatalogVersions/Utility-v2.xml b/beatrix/src/test/resources/catalogs/testInArrearWithCatalogVersions/Utility-v2.xml
new file mode 100644
index 0000000..5700fbb
--- /dev/null
+++ b/beatrix/src/test/resources/catalogs/testInArrearWithCatalogVersions/Utility-v2.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ ~ Copyright 2014-2018 Groupon, Inc
+ ~ Copyright 2014-2018 The Billing Project, LLC
+ ~
+ ~ The Billing Project licenses this file to you under the Apache License, version 2.0
+ ~ (the "License"); you may not use this file except in compliance with the
+ ~ License. You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ ~ License for the specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
+
+ <effectiveDate>2016-05-08T00:00:00+00:00</effectiveDate>
+ <catalogName>TestInArrearWithCatalogVersions</catalogName>
+
+ <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
+ <currencies>
+ <currency>USD</currency>
+ </currencies>
+
+ <units>
+ <unit name="kilowatt-hour"/>
+ </units>
+
+ <products>
+ <product name="Electricity">
+ <category>BASE</category>
+ </product>
+ </products>
+
+ <rules>
+ <changePolicy>
+ <changePolicyCase>
+ <policy>IMMEDIATE</policy>
+ </changePolicyCase>
+ </changePolicy>
+ <cancelPolicy>
+ <cancelPolicyCase>
+ <policy>IMMEDIATE</policy>
+ </cancelPolicyCase>
+ </cancelPolicy>
+ </rules>
+
+ <plans>
+
+ <!-- Price increase from v1 version -->
+ <plan name="electricity-monthly">
+ <effectiveDateForExistingSubscriptions>2016-05-08T00:00:00+00:00</effectiveDateForExistingSubscriptions>
+ <product>Electricity</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <usages>
+ <usage name="electricity-monthly-usage" billingMode="IN_ARREAR" usageType="CONSUMABLE" tierBlockPolicy="ALL_TIERS">
+ <billingPeriod>MONTHLY</billingPeriod>
+ <tiers>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>kilowatt-hour</unit>
+ <size>1</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>2.50</value>
+ </price>
+ </prices>
+ <max>1000</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ <tier>
+ <blocks>
+ <tieredBlock>
+ <unit>kilowatt-hour</unit>
+ <size>1</size>
+ <prices>
+ <price>
+ <currency>USD</currency>
+ <value>3.00</value>
+ </price>
+ </prices>
+ <max>-1</max>
+ </tieredBlock>
+ </blocks>
+ </tier>
+ </tiers>
+ </usage>
+ </usages>
+ </finalPhase>
+ </plan>
+
+ </plans>
+ <priceLists>
+ <defaultPriceList name="DEFAULT">
+ <plans>
+ <plan>electricity-monthly</plan>
+ </plans>
+ </defaultPriceList>
+ </priceLists>
+</catalog>
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
index a61fa3c..f47f3a0 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
@@ -97,6 +97,8 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements
private String priceListName;
+ private DateTime catalogEffectiveDate;
+
// For deserialization
public DefaultPlan() {
initialPhases = new DefaultPlanPhase[0];
@@ -219,6 +221,7 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements
}
this.priceListName = this.priceListName != null ? this.priceListName : findPriceListForPlan(catalog);
+ this.catalogEffectiveDate = new DateTime(catalog.getEffectiveDate());
}
@Override
@@ -402,4 +405,8 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements
public void writeExternal(final ObjectOutput oo) throws IOException {
MapperHolder.mapper().writeValue(new ExternalizableOutput(oo), this);
}
+
+ public DateTime getCatalogEffectiveDate() {
+ return catalogEffectiveDate;
+ }
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
index c8a4bbd..58dbd76 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
@@ -542,9 +542,9 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
@Override
- public Entitlement changePlan(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+ public Entitlement changePlan(final EntitlementSpecifier spec, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
- logChangePlan(log, this, spec, overrides, null, null);
+ logChangePlan(log, this, spec, null, null);
checkForPermissions(Permission.ENTITLEMENT_CAN_CHANGE_PLAN, callContext);
@@ -579,7 +579,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final DateTime effectiveChangeDate;
try {
- effectiveChangeDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, null, null, overrides, context);
+ effectiveChangeDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, null, null, context);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e, e.getCode(), e.getMessage());
} catch (final CatalogApiException e) {
@@ -593,7 +593,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
try {
- getSubscriptionBase().changePlan(spec, overrides, callContext);
+ getSubscriptionBase().changePlan(spec, callContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
@@ -658,9 +658,9 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
@Override
- public Entitlement changePlanWithDate(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+ public Entitlement changePlanWithDate(final EntitlementSpecifier spec, @Nullable final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
- logChangePlan(log, this, spec, overrides, effectiveDate, null);
+ logChangePlan(log, this, spec, effectiveDate, null);
checkForPermissions(Permission.ENTITLEMENT_CAN_CHANGE_PLAN, callContext);
@@ -698,7 +698,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final DateTime resultingEffectiveDate;
try {
- resultingEffectiveDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, effectiveChangeDate, null, overrides, context);
+ resultingEffectiveDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, effectiveChangeDate, null, context);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e, e.getCode(), e.getMessage());
} catch (final CatalogApiException e) {
@@ -712,7 +712,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
try {
- getSubscriptionBase().changePlanWithDate(spec, overrides, resultingEffectiveDate, callContext);
+ getSubscriptionBase().changePlanWithDate(spec, resultingEffectiveDate, callContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
@@ -733,9 +733,9 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
@Override
- public Entitlement changePlanOverrideBillingPolicy(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final LocalDate unused, final BillingActionPolicy actionPolicy, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+ public Entitlement changePlanOverrideBillingPolicy(final EntitlementSpecifier spec, final LocalDate unused, final BillingActionPolicy actionPolicy, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
- logChangePlan(log, this, spec, overrides, null, actionPolicy);
+ logChangePlan(log, this, spec, null, actionPolicy);
checkForPermissions(Permission.ENTITLEMENT_CAN_CHANGE_PLAN, callContext);
@@ -768,7 +768,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final DateTime resultingEffectiveDate;
try {
- resultingEffectiveDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, null, actionPolicy, overrides, context);
+ resultingEffectiveDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, null, actionPolicy, context);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e, e.getCode(), e.getMessage());
} catch (final CatalogApiException e) {
@@ -781,7 +781,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
try {
- getSubscriptionBase().changePlanWithPolicy(spec, overrides, actionPolicy, callContext);
+ getSubscriptionBase().changePlanWithPolicy(spec, actionPolicy, callContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
index 595060f..11eea65 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
@@ -133,10 +133,9 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
@Override
- public UUID createBaseEntitlement(final UUID accountId, final PlanPhaseSpecifier planPhaseSpecifier, final String externalKey, final List<PlanPhasePriceOverride> overrides,
+ public UUID createBaseEntitlement(final UUID accountId, final EntitlementSpecifier entitlementSpecifier, final String externalKey,
@Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate, final boolean isMigrated, final boolean renameCancelledBundleIfExist,
final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
- final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(null,
externalKey,
ImmutableList.<EntitlementSpecifier>of(entitlementSpecifier),
@@ -163,9 +162,8 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
@Override
- public UUID addEntitlement(final UUID bundleId, final PlanPhaseSpecifier planPhaseSpecifier, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate,
+ public UUID addEntitlement(final UUID bundleId, final EntitlementSpecifier entitlementSpecifier, @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate,
final boolean isMigrated, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
- final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(bundleId,
null,
ImmutableList.<EntitlementSpecifier>of(entitlementSpecifier),
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java b/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
index 28e957a..e3360d9 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
@@ -24,7 +24,6 @@ import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.Entitlement;
@@ -219,8 +218,8 @@ public abstract class EntitlementLoggingHelper {
}
}
- public static void logChangePlan(final Logger log, final Entitlement entitlement, final PlanSpecifier spec,
- final List<PlanPhasePriceOverride> overrides, final LocalDate entitlementEffectiveDate, final BillingActionPolicy actionPolicy) {
+ public static void logChangePlan(final Logger log, final Entitlement entitlement, final EntitlementSpecifier entitlementSpecifier,
+ final LocalDate entitlementEffectiveDate, final BillingActionPolicy actionPolicy) {
if (log.isInfoEnabled()) {
final StringBuilder logLine = new StringBuilder("Change Entitlement Plan: ")
.append(" id = '")
@@ -231,31 +230,34 @@ public abstract class EntitlementLoggingHelper {
.append(entitlementEffectiveDate)
.append("'");
}
- if (spec.getPlanName() != null) {
- logLine.append(", plan='")
- .append(spec.getPlanName())
- .append("'");
- }
- if (spec.getProductName() != null) {
- logLine.append(", product='")
- .append(spec.getProductName())
- .append("'");
- }
- if (spec.getBillingPeriod() != null) {
- logLine.append(", billingPeriod='")
- .append(spec.getBillingPeriod())
- .append("'");
- }
- if (spec.getPriceListName() != null) {
- logLine.append(", priceList='")
- .append(spec.getPriceListName())
- .append("'");
- }
- logPlanPhasePriceOverrides(logLine, overrides);
- if (actionPolicy != null) {
- logLine.append(", actionPolicy='")
- .append(actionPolicy)
- .append("'");
+ if (entitlementSpecifier.getPlanPhaseSpecifier() != null) {
+
+ if (entitlementSpecifier.getPlanPhaseSpecifier().getPlanName() != null) {
+ logLine.append(", plan='")
+ .append(entitlementSpecifier.getPlanPhaseSpecifier().getPlanName())
+ .append("'");
+ }
+ if (entitlementSpecifier.getPlanPhaseSpecifier().getProductName() != null) {
+ logLine.append(", product='")
+ .append(entitlementSpecifier.getPlanPhaseSpecifier().getProductName())
+ .append("'");
+ }
+ if (entitlementSpecifier.getPlanPhaseSpecifier().getBillingPeriod() != null) {
+ logLine.append(", billingPeriod='")
+ .append(entitlementSpecifier.getPlanPhaseSpecifier().getBillingPeriod())
+ .append("'");
+ }
+ if (entitlementSpecifier.getPlanPhaseSpecifier().getPriceListName() != null) {
+ logLine.append(", priceList='")
+ .append(entitlementSpecifier.getPlanPhaseSpecifier().getPriceListName())
+ .append("'");
+ }
+ logPlanPhasePriceOverrides(logLine, entitlementSpecifier.getOverrides());
+ if (actionPolicy != null) {
+ logLine.append(", actionPolicy='")
+ .append(actionPolicy)
+ .append("'");
+ }
}
log.info(logLine.toString());
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
index 5a472f3..26cb2a4 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
@@ -52,11 +52,11 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
final Account account = createAccount(getAccountData(7));
- final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(planPhaseSpecifier), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
@@ -85,7 +85,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
@@ -119,7 +119,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
@@ -153,7 +153,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
@@ -187,7 +187,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -213,7 +213,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final DateTime ctd = clock.getUTCNow().plusDays(30).plusMonths(1);
@@ -256,7 +256,7 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -297,13 +297,14 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Immediate change during trial
testListener.pushExpectedEvent(NextEvent.CREATE);
- entitlement.changePlan(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ entitlement.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Verify the change is immediate
@@ -333,27 +334,27 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
// Create entitlement and check each field
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.PENDING);
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("pistol-monthly", null);
try {
- entitlement.changePlan(spec2, ImmutableList.<PlanPhasePriceOverride>of(), ImmutableList.<PluginProperty>of(), callContext);
+ entitlement.changePlan(new DefaultEntitlementSpecifier(spec2), ImmutableList.<PluginProperty>of(), callContext);
fail("Changing plan immediately prior the subscription is active is not allowed");
} catch (EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
}
try {
- entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), startDate.minusDays(1), ImmutableList.<PluginProperty>of(), callContext);
+ entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), startDate.minusDays(1), ImmutableList.<PluginProperty>of(), callContext);
fail("Changing plan immediately prior the subscription is active is not allowed");
} catch (EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
}
- entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), startDate, ImmutableList.<PluginProperty>of(), callContext);
+ entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), startDate, ImmutableList.<PluginProperty>of(), callContext);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
clock.addDays(10);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
index 46bb77b..bee0bf3 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
@@ -65,7 +65,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier baseSpec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(baseSpec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final DefaultEntitlement baseEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
Assert.assertEquals(baseEntitlement.getSubscriptionBase().getStartDate().compareTo(account.getReferenceTime().plusSeconds(5)), 0);
@@ -73,7 +73,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Add ADD_ON (verify date passed, i.e. initialDate, won't map to 2013-08-07T00:00:00.000Z)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID addOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final DefaultEntitlement addOnEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(addOnEntitlementId, callContext);
Assert.assertEquals(addOnEntitlement.getSubscriptionBase().getStartDate().compareTo(baseEntitlement.getSubscriptionBase().getStartDate()), 0);
@@ -90,7 +90,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -98,7 +98,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID addOnEntitlementId = entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOnEntitlementId = entitlementApi.addEntitlement(entitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
try {
entitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext);
@@ -155,7 +155,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -189,7 +189,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getAccountId(), account.getId());
@@ -282,14 +282,14 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Add ADD_ON
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec1), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement telescopicEntitlement = entitlementApi.getEntitlementForId(telescopicEntitlementId, callContext);
@@ -323,14 +323,14 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
final LocalDate startDate = initialDate.plusDays(10);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Add ADD_ON immediately. Because BASE is PENDING should fail
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
try {
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec1), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
fail("Should not succeed to create ADD_On prior BASE is active");
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_GET_NO_SUCH_BASE_SUBSCRIPTION.getCode());
@@ -338,7 +338,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Add ADD_ON with a startDate similar to BASE
- final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, startDate, startDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec1), startDate, startDate, false, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement telescopicEntitlement = entitlementApi.getEntitlementForId(telescopicEntitlementId, callContext);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.BLOCK);
@@ -376,7 +376,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -384,7 +384,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final LocalDate effectiveDateSpec1 = new LocalDate(clock.getUTCNow(), account.getTimeZone());
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, effectiveDateSpec1, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec1), effectiveDateSpec1, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement telescopicEntitlement = entitlementApi.getEntitlementForId(telescopicEntitlementId, callContext);
@@ -413,7 +413,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Try to add an ADD_ON, it should fail because BASE is blocked
try {
final PlanPhaseSpecifier spec3 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec3, null, blockingStateDate, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec3), blockingStateDate, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext);
fail("Should not be able to create ADD-ON because BP is paused");
} catch (EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -453,7 +453,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -545,7 +545,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement (with migrated flag so we can check later that transferred subscription is in right status)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(accountSrc.getId(), spec, accountSrc.getExternalKey(), null, null, null, true, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(accountSrc.getId(), new DefaultEntitlementSpecifier(spec), accountSrc.getExternalKey(), null, null, true, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
assertEquals(baseEntitlement.getSourceType(), EntitlementSourceType.MIGRATED);
@@ -593,7 +593,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.PHASE);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -640,7 +640,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -668,7 +668,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// effectiveDate = entitlementDate prior billingDate
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
try {
- entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), entitlementDate, ImmutableList.<PluginProperty>of(), callContext);
+ entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), entitlementDate, ImmutableList.<PluginProperty>of(), callContext);
Assert.fail("Change plan prior billingStartDate should fail");
} catch (EntitlementApiException e) {
Assert.assertEquals(e.getCode(), ErrorCode.SUB_INVALID_REQUESTED_DATE.getCode());
@@ -677,7 +677,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// effectiveDate is null (same as first case above), but **did** reach the billing startDate (and entitlement startDate) so will succeed
clock.addDeltaFromReality(1000); // Add one sec to make sure CHANGE event does not coincide with CREATE (realistic scenario), and therefore we do expect a CHANGE event
testListener.pushExpectedEvents(NextEvent.CHANGE);
- final Entitlement result = entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), null, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement result = entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
assertEquals(result.getState(), EntitlementState.ACTIVE);
@@ -698,7 +698,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -726,7 +726,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -751,7 +751,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -772,7 +772,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -793,7 +793,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -811,20 +811,20 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final String bundleKey2 = "bundleKey2";
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- entitlementApi.createBaseEntitlement(account.getId(), spec, bundleKey2, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), bundleKey2, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// First bundle of EntitlementSpecifier will specify all new subscription
final String bundleKey1 = "bundleKey1";
- final EntitlementSpecifier spec11 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null);
- final EntitlementSpecifier spec12 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null);
+ final EntitlementSpecifier spec11 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null));
+ final EntitlementSpecifier spec12 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null));
final List<EntitlementSpecifier> specs1 = ImmutableList.of(spec11, spec12);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier1 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey1, specs1, null, null, false);
// Second bundle of EntitlementSpecifier will specify the previously created 'existingEntitlement'
- final EntitlementSpecifier spec22 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null);
+ final EntitlementSpecifier spec22 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null));
final List<EntitlementSpecifier> specs2 = ImmutableList.of(spec22);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier2 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey2, specs2, null, null, false);
@@ -857,7 +857,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final String bundleKey2 = "bundleKey2";
- final EntitlementSpecifier spec22 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null);
+ final EntitlementSpecifier spec22 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null));
final List<EntitlementSpecifier> specs2 = ImmutableList.of(spec22);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier2 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey2, specs2, null, null, false);
@@ -874,8 +874,8 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final Account account = createAccount(getAccountData(7));
final String bundleKey1 = "bundleKey1";
- final EntitlementSpecifier spec11 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null);
- final EntitlementSpecifier spec12 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null);
+ final EntitlementSpecifier spec11 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null));
+ final EntitlementSpecifier spec12 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null));
final List<EntitlementSpecifier> specs1 = ImmutableList.of(spec11, spec12);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier1 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey1, specs1, null, null, false);
@@ -899,7 +899,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create STANDALONE entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -912,7 +912,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Add another STANDALONE entitlement
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Knife", BillingPeriod.MONTHLY, "notrial", null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID anotherStandaloneEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID anotherStandaloneEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(spec1), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement anotherStandaloneEntitlement = entitlementApi.getEntitlementForId(anotherStandaloneEntitlementId, callContext);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
index cb1aea3..4744f58 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
@@ -62,7 +62,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final Account account = createAccount(getAccountData(7));
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlement1Id = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlement1Id = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement1 = entitlementApi.getEntitlementForId(entitlement1Id, callContext);
// Sleep 1 sec so created date are apart from each other and ordering in the bundle does not default on the UUID which is random.
try {
@@ -70,7 +70,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
} catch (InterruptedException ignore) {
}
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), UUID.randomUUID().toString(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement2 = entitlementApi.getEntitlementForId(entitlement2Id, callContext);
@@ -117,7 +117,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), externalKey, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getAccountId(), account.getId());
@@ -152,7 +152,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), spec2, externalKey, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec2), externalKey, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement2 = entitlementApi.getEntitlementForId(entitlement2Id, callContext);
assertEquals(entitlement2.getAccountId(), account.getId());
@@ -224,7 +224,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -283,7 +283,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final LocalDate effectiveDate = initialDate.plusMonths(1);
// Create entitlement and check each field
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, effectiveDate, effectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), externalKey, effectiveDate, effectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(entitlement.getId(), callContext);
@@ -316,7 +316,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final LocalDate futureDate = new LocalDate(2013, 9, 1);
// No CREATE event as this is set in the future
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -345,7 +345,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
final Iterable<BlockingState> iterableForCreateState = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.SUBSCRIPTION), null, OrderingType.ASCENDING, SubscriptionApi.ALL_EVENTS, callContext);
@@ -421,7 +421,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -496,7 +496,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
@@ -510,7 +510,8 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
assertListenerStatus();
try {
- entitlement.changePlan(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ entitlement.changePlan(new DefaultEntitlementSpecifier(spec1), ImmutableList.<PluginProperty>of(), callContext);
fail();
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -520,7 +521,8 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// If a LocalDate is passed, it will align with the reference time (2013-08-08T00:00:00.000Z), which will fall before the blocking state above (+5s added above)
testListener.pushExpectedEvent(NextEvent.CHANGE);
- entitlement.changePlanWithDate(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Assault-Rifle");
@@ -536,7 +538,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -587,7 +589,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final LocalDate effectiveDate = initialDate.plusMonths(1);
try {
- entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, effectiveDate, effectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), externalKey, effectiveDate, effectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
Assert.fail();
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED.getCode());
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java
index 0721b06..8e90822 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java
@@ -47,9 +47,10 @@ public class TestRegessionSubscriptionApi extends EntitlementTestSuiteWithEmbedd
final LocalDate entitlementEffectiveDate = initialDate.minusDays(1);
final Account account = createAccount(getAccountData(7));
- final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+ final EntitlementSpecifier spec = new DefaultEntitlementSpecifier(planPhaseSpecifier);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, entitlementEffectiveDate, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), entitlementEffectiveDate, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Because of the BlockingState event ENT_STARTED, the entitlement date should be correctly set
Assert.assertEquals(entitlement.getEffectiveStartDate(), entitlementEffectiveDate);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
index 96fb988..e1391aa 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
@@ -32,6 +32,7 @@ import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementApiException;
@@ -146,7 +147,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -208,7 +209,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Try create subscription right now
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "xyzqe", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
fail("Should fail to create entitlement when ACCOUNT has been 'change' blocked");
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -217,7 +218,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Try create subscription in the future
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.plusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "xyzqe", null, initialDate.plusDays(3), false, true, ImmutableList.<PluginProperty>of(), callContext);
fail("Should fail to create entitlement when ACCOUNT has been 'change' blocked");
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -226,7 +227,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Try create subscription in the past
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "xyzqe", initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
}
@@ -239,7 +240,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "xyzqe", null, initialDate.minusDays(3), false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -251,7 +252,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Try create subscription right now
try {
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(entitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
fail("Should fail to create ADD_ON");
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -260,7 +261,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Try create subscription in the future
try {
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, initialDate.plusDays(2), null, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(entitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), null, initialDate.plusDays(2), false, ImmutableList.<PluginProperty>of(), callContext);
fail("Should fail to create ADD_ON");
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -269,7 +270,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Try create subscription in the past
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, initialDate.minusDays(2), null, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(entitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), initialDate.minusDays(2), null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
}
@@ -282,7 +283,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "xyzqe", null, initialDate.minusDays(3), false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
@@ -295,7 +296,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
try {
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, blockingChange, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(entitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), blockingChange, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
} catch (final EntitlementApiException e) {
assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
@@ -303,7 +304,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Create ADD_ON now (prior future BlockingState)
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ entitlementApi.addEntitlement(entitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java
index 7c5af2e..acb3809 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java
@@ -31,6 +31,7 @@ import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.junction.DefaultBlockingState;
import org.killbill.billing.payment.api.PluginProperty;
@@ -61,7 +62,7 @@ public class TestDefaultBlockingStateDao extends EntitlementTestSuiteWithEmbedde
// See TestEntitlementUtils for a more comprehensive test
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java b/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java
index 43974f9..cbbf7eb 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java
@@ -40,6 +40,7 @@ import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.entitlement.api.DefaultEntitlementApi;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
import org.killbill.billing.entitlement.api.EntitlementApiException;
@@ -75,14 +76,14 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Create base entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier baseSpec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(baseSpec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
baseEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Add ADD_ON
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID addOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOnSpec), null, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
addOnEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(addOnEntitlementId, callContext);
@@ -236,7 +237,8 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
@Test(groups = "slow", description = "Verify add-ons blocking states are added for EOT change plans")
public void testChangePlanEOT() throws Exception {
// Change plan EOT to Assault-Rifle (Telescopic-Scope is included)
- final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlanWithDate(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, new LocalDate(2013, 10, 7), ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec), new LocalDate(2013, 10, 7), ImmutableList.<PluginProperty>of(), callContext);
// No blocking event (EOT)
assertListenerStatus();
@@ -271,11 +273,12 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Add a second ADD_ON (Laser-Scope is available, not included)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier secondAddOnSpec = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID secondAddOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), secondAddOnSpec, null, clock.getUTCToday(), clock.getUTCToday(), false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID secondAddOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(secondAddOnSpec), clock.getUTCToday(), clock.getUTCToday(), false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Change plan EOT to Assault-Rifle (Telescopic-Scope is included)
- final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlanWithDate(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, new LocalDate(2013, 10, 7), ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec), new LocalDate(2013, 10, 7), ImmutableList.<PluginProperty>of(), callContext);
// No blocking event (EOT)
assertListenerStatus();
@@ -294,7 +297,8 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Change plan IMM (upgrade) to Assault-Rifle (Telescopic-Scope is included)
testListener.pushExpectedEvents(NextEvent.CHANGE, NextEvent.CANCEL, NextEvent.BLOCK);
- final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlan(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, ImmutableList.<PluginProperty>of(), callContext);
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlan(new DefaultEntitlementSpecifier(spec), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// We need to add a 1s delay before invoking the eventsStreamBuilder in the checks below, because
@@ -330,7 +334,7 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Add a second ADD_ON
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.PHASE);
final PlanPhaseSpecifier addOn2Spec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID addOn2EntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOn2Spec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOn2EntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), new DefaultEntitlementSpecifier(addOn2Spec), initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final Entitlement addOn2Entitlement = entitlementApi.getEntitlementForId(addOn2EntitlementId, callContext);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index d98be06..0f2cba2 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -29,6 +29,7 @@ import javax.inject.Inject;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
+import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
@@ -48,6 +49,7 @@ import org.killbill.billing.invoice.model.DefaultInvoicePayment;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -79,7 +81,7 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
return getInvoiceByIdInternal(invoiceId, context);
}
- private DefaultInvoice getInvoiceByIdInternal(final UUID invoiceId, final InternalTenantContext context)throws InvoiceApiException {
+ private DefaultInvoice getInvoiceByIdInternal(final UUID invoiceId, final InternalTenantContext context) throws InvoiceApiException {
return new DefaultInvoice(dao.getById(invoiceId, context));
}
@@ -180,7 +182,7 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
@Override
public boolean apply(final InvoicePaymentModelDao input) {
return input.getType() == type &&
- input.getSuccess();
+ input.getSuccess();
}
}).orNull();
return resultOrNull != null ? new DefaultInvoicePayment(resultOrNull) : null;
@@ -190,4 +192,34 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
public void commitInvoice(final UUID invoiceId, final InternalCallContext context) throws InvoiceApiException {
dao.changeInvoiceStatus(invoiceId, InvoiceStatus.COMMITTED, context);
}
+
+ @Override
+ public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
+ return ImmutableList.<InvoicePayment>copyOf(Collections2.transform(dao.getInvoicePaymentsByPaymentId(paymentId, internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context)),
+ new Function<InvoicePaymentModelDao, InvoicePayment>() {
+ @Override
+ public InvoicePayment apply(final InvoicePaymentModelDao input) {
+ return new DefaultInvoicePayment(input);
+ }
+ }
+ ));
+ }
+
+ @Override
+ public List<InvoicePayment> getInvoicePaymentsByAccount(final UUID accountId, final TenantContext context) {
+ return ImmutableList.<InvoicePayment>copyOf(Collections2.transform(dao.getInvoicePaymentsByAccount(internalCallContextFactory.createInternalTenantContext(accountId, ObjectType.ACCOUNT, context)),
+ new Function<InvoicePaymentModelDao, InvoicePayment>() {
+ @Override
+ public InvoicePayment apply(final InvoicePaymentModelDao input) {
+ return new DefaultInvoicePayment(input);
+ }
+ }
+ ));
+ }
+
+ @Override
+ public InvoicePayment getInvoicePaymentByCookieId(final String cookieId, final TenantContext context) {
+ final InvoicePaymentModelDao invoicePaymentModelDao = dao.getInvoicePaymentByCookieId(cookieId, internalCallContextFactory.createInternalTenantContext(context.getAccountId(), ObjectType.ACCOUNT, context));
+ return invoicePaymentModelDao == null ? null : new DefaultInvoicePayment(invoicePaymentModelDao);
+ }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 443c8ff..4bd2a7c 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -226,15 +226,20 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
}
@Override
+ public Invoice getInvoiceByInvoiceItem(final UUID uuid, final TenantContext tenantContext) throws InvoiceApiException {
+ return null;
+ }
+
+ @Override
public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate, final TenantContext context) {
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
final List<InvoiceModelDao> unpaidInvoicesByAccountId = dao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalTenantContext);
return fromInvoiceModelDao(unpaidInvoicesByAccountId, getCatalogSafelyForPrettyNames(internalTenantContext));
}
+
@Override
- public Invoice triggerInvoiceGeneration(final UUID accountId, @Nullable final LocalDate targetDate, final DryRunArguments dryRunArguments,
- final CallContext context) throws InvoiceApiException {
+ public Invoice triggerDryRunInvoiceGeneration(final UUID accountId, final LocalDate targetDate, final DryRunArguments dryRunArguments, final CallContext context) throws InvoiceApiException {
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(accountId, context);
final Invoice result = dispatcher.processAccount(true, accountId, targetDate, dryRunArguments, false, internalContext);
@@ -246,6 +251,18 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
}
@Override
+ public Invoice triggerInvoiceGeneration(final UUID accountId, @Nullable final LocalDate targetDate, final CallContext context) throws InvoiceApiException {
+ final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(accountId, context);
+
+ final Invoice result = dispatcher.processAccount(true, accountId, targetDate, null, false, internalContext);
+ if (result == null) {
+ throw new InvoiceApiException(ErrorCode.INVOICE_NOTHING_TO_DO, accountId, targetDate != null ? targetDate : "null");
+ } else {
+ return result;
+ }
+ }
+
+ @Override
public void tagInvoiceAsWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException, InvoiceApiException {
// Note: the tagApi is audited
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(invoiceId, ObjectType.INVOICE, context);
@@ -412,7 +429,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
}
@Override
- public void consumeExstingCBAOnAccountWithUnpaidInvoices(final UUID accountId, final CallContext context) {
+ public void consumeExistingCBAOnAccountWithUnpaidInvoices(final UUID accountId, final CallContext context) {
dao.consumeExstingCBAOnAccountWithUnpaidInvoices(accountId, internalCallContextFactory.createInternalCallContext(accountId, context));
}
@@ -548,7 +565,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
// Note! The amount is negated here!
inputItem.getAmount().negate(),
accountCurrency,
- inputItem.getDescription());
+ inputItem.getItemDetails());
break;
case TAX:
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index fd7d11a..e40b3b2 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -539,6 +539,16 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
@Override
+ public InvoicePaymentModelDao getInvoicePaymentByCookieId(final String cookieId, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<InvoicePaymentModelDao>() {
+ @Override
+ public InvoicePaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getPaymentForCookieId(cookieId, context);
+ }
+ });
+ }
+
+ @Override
public InvoicePaymentModelDao createRefund(final UUID paymentId, final BigDecimal requestedRefundAmount, final boolean isInvoiceAdjusted,
final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final String transactionExternalKey,
final InternalCallContext context) throws InvoiceApiException {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
index 205c55f..67c1d1b 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
@@ -64,6 +64,8 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
List<InvoicePaymentModelDao> getInvoicePaymentsByAccount(InternalTenantContext context);
+ InvoicePaymentModelDao getInvoicePaymentByCookieId(String cookieId, InternalTenantContext internalTenantContext);
+
BigDecimal getAccountBalance(UUID accountId, InternalTenantContext context);
BigDecimal getAccountCBA(UUID accountId, InternalTenantContext context);
@@ -174,7 +176,6 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
*/
List<InvoiceParentChildModelDao> getChildInvoicesByParentInvoiceId(UUID parentInvoiceId, final InternalCallContext context) throws InvoiceApiException;
-
/**
* Retrieve parent invoice by the parent account id
*
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
index 994eb58..2723b68 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -27,23 +27,22 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@KillBillSqlDaoStringTemplate
public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePaymentModelDao, InvoicePayment> {
-
@SqlQuery
public List<InvoicePaymentModelDao> getByPaymentId(@Bind("paymentId") final String paymentId,
@SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<InvoicePaymentModelDao> getAllPaymentsForInvoiceIncludedInit(@Bind("invoiceId") final String invoiceId,
- @SmartBindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<InvoicePaymentModelDao> getInvoicePayments(@Bind("paymentId") final String paymentId,
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java b/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java
index eabea2e..c2832cf 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -27,12 +27,10 @@ import org.killbill.billing.invoice.api.DefaultInvoiceService;
import org.killbill.billing.invoice.api.InvoiceApiHelper;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.invoice.api.InvoiceListenerService;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceService;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.invoice.api.formatters.InvoiceFormatterFactory;
import org.killbill.billing.invoice.api.formatters.ResourceBundleFactory;
-import org.killbill.billing.invoice.api.invoice.DefaultInvoicePaymentApi;
import org.killbill.billing.invoice.api.svcs.DefaultInvoiceInternalApi;
import org.killbill.billing.invoice.api.user.DefaultInvoiceUserApi;
import org.killbill.billing.invoice.config.MultiTenantInvoiceConfig;
@@ -85,11 +83,6 @@ public class DefaultInvoiceModule extends KillBillModule implements InvoiceModul
bind(InvoiceInternalApi.class).to(DefaultInvoiceInternalApi.class).asEagerSingleton();
}
- @Override
- public void installInvoicePaymentApi() {
- bind(InvoicePaymentApi.class).to(DefaultInvoicePaymentApi.class).asEagerSingleton();
- }
-
protected void installConfig() {
installConfig(new ConfigurationObjectFactory(skifeConfigSource).build(InvoiceConfig.class));
}
@@ -154,7 +147,6 @@ public class DefaultInvoiceModule extends KillBillModule implements InvoiceModul
installInvoiceDao();
installInvoiceUserApi();
installInvoiceInternalApi();
- installInvoicePaymentApi();
installResourceBundleFactory();
bind(RawUsageOptimizer.class).asEagerSingleton();
bind(InvoiceApiHelper.class).asEagerSingleton();
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index 9da5ffb..274925f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -48,6 +48,7 @@ import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.events.BusInternalEvent;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
@@ -1000,7 +1001,7 @@ public class InvoiceDispatcher {
}
@Override
- public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ public EntitlementSpecifier getEntitlementSpecifier() {
return null;
}
@@ -1029,10 +1030,6 @@ public class InvoiceDispatcher {
return null;
}
- @Override
- public List<PlanPhasePriceOverride> getPlanPhasePriceOverrides() {
- return null;
- }
@Override
public String toString() {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableUsageInArrear.java
index 747a501..22e812c 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableUsageInArrear.java
@@ -208,21 +208,19 @@ public class ContiguousIntervalConsumableUsageInArrear extends ContiguousInterva
remainingUnits = 0;
}
// We generate an entry if we consumed anything on this tier or if this is the first tier to also support $0 Usage item
- if (tierNum == 1 || nbUsedTierBlocks > 0) {
- if (hasPreviousUsage) {
- final Integer previousUsageQuantity = tierNum <= lastPreviousUsageTier ? previousUsage.get(tierNum - 1).getQuantity() : 0;
- if (tierNum < lastPreviousUsageTier) {
- Preconditions.checkState(nbUsedTierBlocks == previousUsageQuantity, "Expected usage for tier='%d', unit='%s' to be full, instead found units='[%d/%d]'",
- tierNum, tieredBlock.getUnit().getName(), nbUsedTierBlocks, previousUsageQuantity);
- } else {
- Preconditions.checkState(nbUsedTierBlocks - previousUsageQuantity >= 0, "Expected usage for tier='%d', unit='%s' to contain at least as mush as current usage, instead found units='[%d/%d]",
- tierNum, tieredBlock.getUnit().getName(), nbUsedTierBlocks, previousUsageQuantity);
- }
- nbUsedTierBlocks = nbUsedTierBlocks - previousUsageQuantity;
- }
- if (tierNum == 1 || nbUsedTierBlocks > 0) {
- toBeBilledDetails.add(new UsageConsumableInArrearTierUnitAggregate(tierNum, tieredBlock.getUnit().getName(), tieredBlock.getPrice().getPrice(getCurrency()), blockTierSize, nbUsedTierBlocks));
+ if (hasPreviousUsage) {
+ final Integer previousUsageQuantity = tierNum <= lastPreviousUsageTier ? previousUsage.get(tierNum - 1).getQuantity() : 0;
+ if (tierNum < lastPreviousUsageTier) {
+ Preconditions.checkState(nbUsedTierBlocks == previousUsageQuantity, String.format("Expected usage for tier='%d', unit='%s' to be full, instead found units='[%d/%d]'",
+ tierNum, tieredBlock.getUnit().getName(), nbUsedTierBlocks, previousUsageQuantity));
+ } else {
+ Preconditions.checkState(nbUsedTierBlocks - previousUsageQuantity >= 0, String.format("Expected usage for tier='%d', unit='%s' to contain at least as mush as current usage, instead found units='[%d/%d]",
+ tierNum, tieredBlock.getUnit().getName(), nbUsedTierBlocks, previousUsageQuantity));
}
+ nbUsedTierBlocks = nbUsedTierBlocks - previousUsageQuantity;
+ }
+ if (tierNum == 1 || nbUsedTierBlocks > 0) {
+ toBeBilledDetails.add(new UsageConsumableInArrearTierUnitAggregate(tierNum, tieredBlock.getUnit().getName(), tieredBlock.getPrice().getPrice(getCurrency()), blockTierSize, nbUsedTierBlocks));
}
}
return toBeBilledDetails;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
index f83f6da..bcc13cb 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
@@ -234,12 +234,22 @@ public abstract class ContiguousIntervalUsageInArrear {
@VisibleForTesting
List<RolledUpUsage> getRolledUpUsage() {
+
+ final List<RolledUpUsage> result = new ArrayList<RolledUpUsage>();
+
final Iterator<RawUsage> rawUsageIterator = rawSubscriptionUsage.iterator();
if (!rawUsageIterator.hasNext()) {
- return ImmutableList.of();
+ final LocalDate startDate = transitionTimes.get(transitionTimes.size() - 2);
+ final LocalDate endDate = transitionTimes.get(transitionTimes.size() - 1);
+ for (String unitType : unitTypes) {
+ final List<RolledUpUnit> emptyRolledUptUnits = new ArrayList<RolledUpUnit>();
+ emptyRolledUptUnits.add(new DefaultRolledUpUnit(unitType, 0L));
+ final DefaultRolledUpUsage defaultForUnit = new DefaultRolledUpUsage(getSubscriptionId(), startDate, endDate, emptyRolledUptUnits);
+ result.add(defaultForUnit);
+ }
+ return result;
}
- final List<RolledUpUsage> result = new ArrayList<RolledUpUsage>();
//
// Skip all items before our first transition date
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java
index b0f27f8..1e513ee 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java
@@ -67,7 +67,7 @@ public class RawUsageOptimizer {
}
public RawUsageOptimizerResult getInArrearUsage(final LocalDate firstEventStartDate, final LocalDate targetDate, final Iterable<InvoiceItem> existingUsageItems, final Map<String, Usage> knownUsage, final InternalCallContext internalCallContext) {
- final LocalDate targetStartDate = config.getMaxRawUsagePreviousPeriod(internalCallContext) > 0 ? getOptimizedRawUsageStartDate(firstEventStartDate, targetDate, existingUsageItems, knownUsage, internalCallContext) : firstEventStartDate;
+ final LocalDate targetStartDate = config.getMaxRawUsagePreviousPeriod(internalCallContext) >= 0 ? getOptimizedRawUsageStartDate(firstEventStartDate, targetDate, existingUsageItems, knownUsage, internalCallContext) : firstEventStartDate;
log.debug("ConsumableInArrear accountRecordId='{}', rawUsageStartDate='{}', firstEventStartDate='{}'",
internalCallContext.getAccountRecordId(), targetStartDate, firstEventStartDate);
final List<RawUsage> rawUsageData = usageApi.getRawUsageForAccount(targetStartDate, targetDate, internalCallContext);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java
index 93bbd42..bb3d830 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingMode;
@@ -132,52 +133,56 @@ public class SubscriptionUsageInArrear {
List<ContiguousIntervalUsageInArrear> computeInArrearUsageInterval() {
final List<ContiguousIntervalUsageInArrear> usageIntervals = Lists.newLinkedList();
- final Map<String, ContiguousIntervalUsageInArrear> inFlightInArrearUsageIntervals = new HashMap<String, ContiguousIntervalUsageInArrear>();
+ final Map<UsageKey, ContiguousIntervalUsageInArrear> inFlightInArrearUsageIntervals = new HashMap<UsageKey, ContiguousIntervalUsageInArrear>();
- final Set<String> allSeenUsage = new HashSet<String>();
+ final Set<UsageKey> allSeenUsage = new HashSet<UsageKey>();
for (final BillingEvent event : subscriptionBillingEvents) {
+
+
// Extract all in arrear /consumable usage section for that billing event.
final List<Usage> usages = findUsageInArrearUsages(event);
- allSeenUsage.addAll(Collections2.transform(usages, new Function<Usage, String>() {
+ allSeenUsage.addAll(Collections2.transform(usages, new Function<Usage, UsageKey>() {
@Override
- public String apply(final Usage input) {
- return input.getName();
+ public UsageKey apply(final Usage input) {
+ return new UsageKey(input.getName(), event.getCatalogEffectiveDate());
}
}));
// All inflight usage interval are candidates to be closed unless we see that current billing event referencing the same usage section.
- final Set<String> toBeClosed = new HashSet<String>(allSeenUsage);
+ final Set<UsageKey> toBeClosed = new HashSet<UsageKey>(allSeenUsage);
for (final Usage usage : usages) {
+ final UsageKey usageKey = new UsageKey(usage.getName(), event.getCatalogEffectiveDate());
+
// Add inflight usage interval if non existent
- ContiguousIntervalUsageInArrear existingInterval = inFlightInArrearUsageIntervals.get(usage.getName());
+ ContiguousIntervalUsageInArrear existingInterval = inFlightInArrearUsageIntervals.get(usageKey);
if (existingInterval == null) {
existingInterval = usage.getUsageType() == UsageType.CAPACITY ?
new ContiguousIntervalCapacityUsageInArrear(usage, accountId, invoiceId, rawSubscriptionUsage, targetDate, rawUsageStartDate, usageDetailMode, internalTenantContext) :
new ContiguousIntervalConsumableUsageInArrear(usage, accountId, invoiceId, rawSubscriptionUsage, targetDate, rawUsageStartDate, usageDetailMode, internalTenantContext);
- inFlightInArrearUsageIntervals.put(usage.getName(), existingInterval);
+ inFlightInArrearUsageIntervals.put(usageKey, existingInterval);
}
// Add billing event for that usage interval
existingInterval.addBillingEvent(event);
// Remove usage interval for toBeClosed set
- toBeClosed.remove(usage.getName());
+ toBeClosed.remove(usageKey);
}
// Build the usage interval that are no longer referenced
- for (final String usageName : toBeClosed) {
- final ContiguousIntervalUsageInArrear interval = inFlightInArrearUsageIntervals.remove(usageName);
+ for (final UsageKey usageKey : toBeClosed) {
+ final ContiguousIntervalUsageInArrear interval = inFlightInArrearUsageIntervals.remove(usageKey);
if (interval != null) {
interval.addBillingEvent(event);
usageIntervals.add(interval.build(true));
}
}
}
- for (final String usageName : inFlightInArrearUsageIntervals.keySet()) {
- usageIntervals.add(inFlightInArrearUsageIntervals.get(usageName).build(false));
+ for (final UsageKey usageKey : inFlightInArrearUsageIntervals.keySet()) {
+ usageIntervals.add(inFlightInArrearUsageIntervals.get(usageKey).build(false));
}
inFlightInArrearUsageIntervals.clear();
return usageIntervals;
@@ -233,4 +238,40 @@ public class SubscriptionUsageInArrear {
return perUsageNotificationDates != null ? perUsageNotificationDates : ImmutableMap.<String, LocalDate>of();
}
}
+
+ private static class UsageKey {
+
+ private final String usageName;
+ private final DateTime catalogVersion;
+
+ public UsageKey(final String usageName, final DateTime catalogVersion) {
+ this.usageName = usageName;
+ this.catalogVersion = catalogVersion;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final UsageKey usageKey = (UsageKey) o;
+
+ if (usageName != null ? !usageName.equals(usageKey.usageName) : usageKey.usageName != null) {
+ return false;
+ }
+ return catalogVersion != null ? catalogVersion.compareTo(usageKey.catalogVersion) == 0 : usageKey.catalogVersion == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = usageName != null ? usageName.hashCode() : 0;
+ result = 31 * result + (catalogVersion != null ? catalogVersion.hashCode() : 0);
+ return result;
+ }
+ }
+
}
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 140ff05..3552f3c 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -72,8 +72,6 @@ getAllPaymentsForInvoiceIncludedInit() ::= <<
;
>>
-
-
getInvoicePayments() ::= <<
SELECT <allTableFields("")>
FROM <tableName()>
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
index 4ce8e42..0935479 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -245,6 +245,11 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
}
@Override
+ public InvoicePaymentModelDao getInvoicePaymentByCookieId(final String cookieId, final InternalTenantContext internalTenantContext) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void notifyOfPaymentCompletion(final InvoicePaymentModelDao invoicePayment, final InternalCallContext context) {
synchronized (monitor) {
payments.put(invoicePayment.getId(), invoicePayment);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java
index e097fac..6c064ab 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java
@@ -22,7 +22,6 @@ import org.killbill.billing.GuicyKillbillTestSuiteNoDB;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.currency.api.CurrencyConversionApi;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.invoice.api.formatters.ResourceBundleFactory;
import org.killbill.billing.invoice.dao.InvoiceDao;
@@ -33,6 +32,7 @@ import org.killbill.billing.invoice.glue.TestInvoiceModuleNoDB;
import org.killbill.billing.invoice.usage.RawUsageOptimizer;
import org.killbill.billing.junction.BillingInternalApi;
import org.killbill.billing.lifecycle.api.BusService;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.usage.api.UsageUserApi;
@@ -65,8 +65,6 @@ public abstract class InvoiceTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
@Inject
protected InvoiceUserApi invoiceUserApi;
@Inject
- protected InvoicePaymentApi invoicePaymentApi;
- @Inject
protected InvoiceGenerator generator;
@Inject
protected InvoiceConfig invoiceConfig;
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
index 523e480..1ecaa5f 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
@@ -24,7 +24,6 @@ import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.DefaultInvoiceService;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceService;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.invoice.dao.InvoiceDao;
@@ -33,6 +32,7 @@ import org.killbill.billing.invoice.glue.TestInvoiceModuleWithEmbeddedDb;
import org.killbill.billing.invoice.notification.NextBillingDateNotifier;
import org.killbill.billing.junction.BillingInternalApi;
import org.killbill.billing.lifecycle.api.BusService;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.util.api.TagUserApi;
@@ -70,8 +70,6 @@ public abstract class InvoiceTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
@Inject
protected InvoiceUserApi invoiceUserApi;
@Inject
- protected InvoicePaymentApi invoicePaymentApi;
- @Inject
protected InvoiceGenerator generator;
@Inject
protected BillingInternalApi billingApi;
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
index 30d07e7..c19fdce 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
@@ -38,6 +38,7 @@ import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.account.api.ImmutableAccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.callcontext.MutableCallContext;
import org.killbill.billing.callcontext.MutableInternalCallContext;
import org.killbill.billing.catalog.MockPlan;
import org.killbill.billing.catalog.MockPlanPhase;
@@ -50,6 +51,7 @@ import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.entity.EntityPersistenceException;
import org.killbill.billing.invoice.api.DryRunArguments;
@@ -264,16 +266,18 @@ public class TestInvoiceHelper {
.paymentMethodId(UUID.randomUUID())
.timeZone(DateTimeZone.UTC)
.createdDate(clock.getUTCNow())
+
.build();
+ final MutableCallContext mutableCallContext = new MutableCallContext(internalCallContext);
final Account account;
if (isFastTest()) {
- account = GuicyKillbillTestSuiteNoDB.createMockAccount(accountData, accountUserApi, accountApi, immutableAccountApi, nonEntityDao, clock, internalCallContextFactory, callContext, internalCallContext);
+ account = GuicyKillbillTestSuiteNoDB.createMockAccount(accountData, accountUserApi, accountApi, immutableAccountApi, nonEntityDao, clock, internalCallContextFactory, mutableCallContext, internalCallContext);
} else {
account = accountUserApi.createAccount(accountData, callContext);
}
- GuicyKillbillTestSuite.refreshCallContext(account.getId(), clock, internalCallContextFactory, callContext, internalCallContext);
+ GuicyKillbillTestSuite.refreshCallContext(account.getId(), clock, internalCallContextFactory, mutableCallContext, internalCallContext);
return account;
}
@@ -421,6 +425,11 @@ public class TestInvoiceHelper {
}
@Override
+ public DateTime getCatalogEffectiveDate() {
+ return null;
+ }
+
+ @Override
public int compareTo(final BillingEvent e1) {
if (!getSubscription().getId().equals(e1.getSubscription().getId())) { // First order by subscription
return getSubscription().getId().compareTo(e1.getSubscription().getId());
@@ -446,7 +455,7 @@ public class TestInvoiceHelper {
}
@Override
- public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ public EntitlementSpecifier getEntitlementSpecifier() {
return null;
}
@@ -474,11 +483,6 @@ public class TestInvoiceHelper {
public BillingActionPolicy getBillingActionPolicy() {
return null;
}
-
- @Override
- public List<PlanPhasePriceOverride> getPlanPhasePriceOverrides() {
- return null;
- }
}
// Unfortunately, this helper is shared across fast and slow tests
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 be8b17c..e1a9249 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
@@ -78,7 +78,6 @@ import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoiceItemType;
import org.killbill.billing.invoice.api.InvoicePayment;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.jaxrs.JaxrsExecutors;
import org.killbill.billing.jaxrs.json.AccountEmailJson;
@@ -102,6 +101,7 @@ import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.api.OverdueApiException;
import org.killbill.billing.overdue.api.OverdueState;
import org.killbill.billing.overdue.config.api.OverdueException;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -188,7 +188,7 @@ public class AccountResource extends JaxRsResourceBase {
final Context context,
final RecordIdApi recordIdApi,
final NotificationQueueService notificationQueueService) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountApi, paymentApi, subscriptionApi, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountApi, paymentApi, invoicePaymentApi, subscriptionApi, clock, context);
this.subscriptionApi = subscriptionApi;
this.invoiceApi = invoiceApi;
this.invoicePaymentApi = invoicePaymentApi;
@@ -693,7 +693,7 @@ public class AccountResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
- invoiceApi.consumeExstingCBAOnAccountWithUnpaidInvoices(accountId, callContext);
+ invoiceApi.consumeExistingCBAOnAccountWithUnpaidInvoices(accountId, callContext);
return Response.status(Status.NO_CONTENT).build();
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
index 20dc70b..454f7bf 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
@@ -17,7 +17,6 @@
package org.killbill.billing.jaxrs.resources;
-import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
@@ -56,6 +55,7 @@ import org.killbill.billing.jaxrs.json.AdminPaymentJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.payment.api.AdminPaymentApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -127,6 +127,7 @@ public class AdminResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final AdminPaymentApi adminPaymentApi,
final InvoiceUserApi invoiceUserApi,
final CacheControllerDispatcher cacheControllerDispatcher,
@@ -137,7 +138,7 @@ public class AdminResource extends JaxRsResourceBase {
final KillbillHealthcheck killbillHealthcheck,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.adminPaymentApi = adminPaymentApi;
this.invoiceUserApi = invoiceUserApi;
this.tenantApi = tenantApi;
@@ -289,7 +290,7 @@ public class AdminResource extends JaxRsResourceBase {
final Tag tag = iterator.next();
final UUID accountId = tag.getObjectId();
try {
- invoiceUserApi.triggerInvoiceGeneration(accountId, clock.getUTCToday(), null, callContext);
+ invoiceUserApi.triggerInvoiceGeneration(accountId, clock.getUTCToday(), callContext);
generator.writeStringField(accountId.toString(), OK);
} catch (final InvoiceApiException e) {
if (e.getCode() != ErrorCode.INVOICE_NOTHING_TO_DO.getCode()) {
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 89af32f..8c2ea77 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
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -59,6 +61,7 @@ import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.api.AuditUserApi;
@@ -105,9 +108,10 @@ public class BundleResource extends JaxRsResourceBase {
final SubscriptionApi subscriptionApi,
final EntitlementApi entitlementApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, subscriptionApi, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, subscriptionApi, clock, context);
this.entitlementApi = entitlementApi;
this.subscriptionApi = subscriptionApi;
}
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 adb0acb..356ea48 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
@@ -66,6 +66,7 @@ import org.killbill.billing.jaxrs.json.PlanDetailJson;
import org.killbill.billing.jaxrs.json.SimplePlanJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.tenant.api.TenantApiException;
import org.killbill.billing.util.api.AuditUserApi;
@@ -102,11 +103,12 @@ public class CatalogResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final CatalogUserApi catalogUserApi,
final SubscriptionApi subscriptionApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.catalogUserApi = catalogUserApi;
this.subscriptionApi = subscriptionApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
index f93fd74..655e3d0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2015 Groupon, Inc
- * Copyright 2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -31,7 +31,7 @@ import org.killbill.billing.jaxrs.json.AccountJson;
import org.killbill.billing.jaxrs.json.PaymentMethodJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
-import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PaymentMethod;
@@ -40,10 +40,8 @@ import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.callcontext.CallContext;
-import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.clock.Clock;
-import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -57,9 +55,10 @@ public abstract class ComboPaymentResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
protected Account getOrCreateAccount(final AccountJson accountJson, final CallContext callContext) throws AccountApiException {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
index 8634bb4..f68cb30 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
@@ -46,6 +46,7 @@ import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.jaxrs.json.CreditJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.api.AuditUserApi;
@@ -80,9 +81,10 @@ public class CreditResource extends JaxRsResourceBase {
final CustomFieldUserApi customFieldUserApi,
final AuditUserApi auditUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.invoiceUserApi = invoiceUserApi;
this.accountUserApi = accountUserApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
index 92a8f76..ad85ec7 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2014 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -37,6 +39,7 @@ import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
@@ -74,9 +77,10 @@ public class CustomFieldResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
@TimedResource
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
index e40ea0e..58220c3 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -34,6 +36,7 @@ import javax.ws.rs.core.StreamingOutput;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -66,9 +69,10 @@ public class ExportResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.exportUserApi = exportUserApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
index 0c46744..2b8eb6b 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
@@ -45,6 +45,7 @@ import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
@@ -73,8 +74,8 @@ public class InvoiceItemResource extends JaxRsResourceBase {
@Inject
public InvoiceItemResource(final JaxrsUriBuilder uriBuilder, final TagUserApi tagUserApi, final CustomFieldUserApi customFieldUserApi,
final AuditUserApi auditUserApi, final AccountUserApi accountUserApi, final PaymentApi paymentApi,
- final SubscriptionApi subscriptionApi, final Clock clock, final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, subscriptionApi, clock, context);
+ final InvoicePaymentApi invoicePaymentApi, final SubscriptionApi subscriptionApi, final Clock clock, final Context context) {
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, subscriptionApi, clock, context);
}
@TimedResource
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
index 8632ec0..543ee93 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -20,9 +20,7 @@ package org.killbill.billing.jaxrs.resources;
import java.math.BigDecimal;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -47,8 +45,8 @@ 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.Currency;
import org.killbill.billing.invoice.api.InvoicePayment;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoicePaymentType;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.InvoiceItemJson;
@@ -58,10 +56,14 @@ import org.killbill.billing.jaxrs.json.PaymentTransactionJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentOptions;
+import org.killbill.billing.payment.api.PaymentTransaction;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.api.TransactionStatus;
import org.killbill.billing.util.UUIDs;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
@@ -88,7 +90,7 @@ import io.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path(JaxrsResource.INVOICE_PAYMENTS_PATH)
-@Api(value = JaxrsResource.INVOICE_PAYMENTS_PATH, description = "Operations on invoice payments", tags="InvoicePayment")
+@Api(value = JaxrsResource.INVOICE_PAYMENTS_PATH, description = "Operations on invoice payments", tags = "InvoicePayment")
public class InvoicePaymentResource extends JaxRsResourceBase {
private static final String ID_PARAM_NAME = "paymentId";
@@ -105,7 +107,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.invoicePaymentApi = invoicePaymentApi;
}
@@ -162,47 +164,65 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
verifyNonNullOrEmpty(json, "InvoicePaymentTransactionJson body should be specified");
- final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
- final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
- final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
+ final CallContext callContextNoAccountId = context.createCallContextNoAccountId(createdBy, reason, comment, request);
+ final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContextNoAccountId);
+ final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContextNoAccountId);
+ final CallContext callContext = context.createCallContextWithAccountId(account.getId(), createdBy, reason, comment, request);
final Iterable<PluginProperty> pluginProperties;
final String transactionExternalKey = json.getTransactionExternalKey() != null ? json.getTransactionExternalKey() : UUIDs.randomUUID().toString();
final String paymentExternalKey = json.getPaymentExternalKey() != null ? json.getPaymentExternalKey() : UUIDs.randomUUID().toString();
- if (json.isAdjusted() != null && json.isAdjusted()) {
- if (json.getAdjustments() != null && json.getAdjustments().size() > 0) {
- final Map<UUID, BigDecimal> adjustments = new HashMap<UUID, BigDecimal>();
+
+ final boolean isAdjusted = json.isAdjusted() != null && json.isAdjusted();
+ final Map<UUID, BigDecimal> adjustments = new HashMap<UUID, BigDecimal>();
+ if (isAdjusted) {
+ if (json.getAdjustments() != null && !json.getAdjustments().isEmpty()) {
for (final InvoiceItemJson item : json.getAdjustments()) {
adjustments.put(item.getInvoiceItemId(), item.getAmount());
}
- pluginProperties = extractPluginProperties(pluginPropertiesString,
- new PluginProperty("IPCD_REFUND_WITH_ADJUSTMENTS", "true", false),
- new PluginProperty("IPCD_REFUND_IDS_AMOUNTS", adjustments, false));
+ pluginProperties = extractPluginProperties(pluginPropertiesString);
} else {
- pluginProperties = extractPluginProperties(pluginPropertiesString,
- new PluginProperty("IPCD_REFUND_WITH_ADJUSTMENTS", "true", false));
+ pluginProperties = extractPluginProperties(pluginPropertiesString);
}
} else {
pluginProperties = extractPluginProperties(pluginPropertiesString);
}
- final Payment result;
+ final UUID paymentIdToRedirectTo;
if (externalPayment) {
- UUID externalPaymentMethodId = paymentMethodId;
-
- final Collection<PluginProperty> pluginPropertiesForExternalRefund = new LinkedList<PluginProperty>();
- Iterables.addAll(pluginPropertiesForExternalRefund, pluginProperties);
- pluginPropertiesForExternalRefund.add(new PluginProperty("IPCD_PAYMENT_ID", paymentId, false));
-
- result = paymentApi.createCreditWithPaymentControl(account, externalPaymentMethodId, null, json.getAmount(), account.getCurrency(), json.getEffectiveDate(),
- paymentExternalKey, transactionExternalKey, pluginPropertiesForExternalRefund,
- createInvoicePaymentControlPluginApiPaymentOptions(true), callContext);
+ invoicePaymentApi.createCreditForInvoicePayment(isAdjusted,
+ adjustments,
+ account,
+ paymentId,
+ paymentMethodId,
+ null,
+ json.getAmount(),
+ account.getCurrency(),
+ json.getEffectiveDate(),
+ paymentExternalKey,
+ transactionExternalKey,
+ pluginProperties,
+ createInvoicePaymentControlPluginApiPaymentOptions(true),
+ callContext);
+ // /!\ Note! The invoicePayment#paymentId points to the original payment (PURCHASE) here, NOT the new one (CREDIT)
+ paymentIdToRedirectTo = paymentApi.getPaymentByTransactionExternalKey(transactionExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext).getId();
} else {
- result = paymentApi.createRefundWithPaymentControl(account, payment.getId(), json.getAmount(), account.getCurrency(), json.getEffectiveDate(), transactionExternalKey,
- pluginProperties, createInvoicePaymentControlPluginApiPaymentOptions(false), callContext);
+ invoicePaymentApi.createRefundForInvoicePayment(isAdjusted,
+ adjustments,
+ account,
+ payment.getId(),
+ json.getAmount(),
+ account.getCurrency(),
+ json.getEffectiveDate(),
+ transactionExternalKey,
+ pluginProperties,
+ createInvoicePaymentControlPluginApiPaymentOptions(false),
+ callContext);
+ // Note that the InvoicePayment may not be created (i.e. return null), even though the refund went through (wrong item adjustments for instance)
+ paymentIdToRedirectTo = payment.getId();
}
- return uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", result.getId(), request);
+ return uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", paymentIdToRedirectTo, request);
}
@TimedResource
@@ -230,7 +250,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
final String transactionExternalKey = json.getTransactionExternalKey() != null ? json.getTransactionExternalKey() : UUIDs.randomUUID().toString();
final Payment result = paymentApi.createChargebackWithPaymentControl(account, payment.getId(), json.getAmount(), account.getCurrency(), json.getEffectiveDate(),
- transactionExternalKey, createInvoicePaymentControlPluginApiPaymentOptions(false), callContext);
+ transactionExternalKey, createInvoicePaymentControlPluginApiPaymentOptions(false), callContext);
return uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", result.getId(), request);
}
@@ -261,7 +281,6 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
return uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", result.getId(), request);
}
-
@TimedResource(name = "completeInvoicePaymentTransaction")
@PUT
@Path("/{paymentId:" + UUID_PATTERN + "}")
@@ -285,7 +304,6 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final UriInfo uriInfo,
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-
final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), tenantContext);
final List<InvoicePayment> invoicePayments = invoicePaymentApi.getInvoicePayments(paymentId, tenantContext);
@@ -302,19 +320,34 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
return Response.status(Status.NOT_FOUND).build();
}
- final PluginProperty invoiceProperty = new PluginProperty("IPCD_INVOICE_ID" /* InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID (contract with plugin) */,
- invoiceId.toString(), false);
- final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString, invoiceProperty);
+ final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final List<String> controlPluginNames = new ArrayList<String>();
- controlPluginNames.add("__INVOICE_PAYMENT_CONTROL_PLUGIN__");
controlPluginNames.addAll(paymentControlPluginNames);
- completeTransactionInternal(json, payment, controlPluginNames, pluginProperties, tenantContext, createdBy, reason, comment, uriInfo, request);
+ final Account account = accountUserApi.getAccountById(payment.getAccountId(), tenantContext);
+ final BigDecimal amount = json == null ? null : json.getAmount();
+ final Currency currency = json == null ? null : json.getCurrency();
+
+ final CallContext callContext = context.createCallContextWithAccountId(account.getId(), createdBy, reason, comment, request);
+
+ final PaymentTransaction pendingOrSuccessTransaction = lookupPendingOrSuccessTransaction(payment,
+ json != null ? json.getTransactionId() : null,
+ json != null ? json.getTransactionExternalKey() : null,
+ json != null ? json.getTransactionType() : null);
+ // If transaction was already completed, return early (See #626)
+ if (pendingOrSuccessTransaction.getTransactionStatus() == TransactionStatus.SUCCESS) {
+ return Response.status(Status.NO_CONTENT).build();
+ }
+
+ final PaymentOptions paymentOptions = createControlPluginApiPaymentOptions(paymentControlPluginNames);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account, invoiceId, payment.getPaymentMethodId(), payment.getId(), amount, currency, null,
+ payment.getExternalKey(), pendingOrSuccessTransaction.getExternalKey(),
+ pluginProperties, paymentOptions, callContext);
+
return Response.status(Status.NO_CONTENT).build();
}
-
@TimedResource
@GET
@Path("/{paymentId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
@@ -346,7 +379,6 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
}
-
@TimedResource
@PUT
@Path("/{paymentId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
@@ -365,7 +397,6 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
context.createCallContextNoAccountId(createdBy, reason, comment, request));
}
-
@TimedResource
@DELETE
@Path("/{paymentId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 64870ae..8855f0f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -62,6 +62,7 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionApiException;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.api.DryRunArguments;
@@ -80,6 +81,7 @@ import org.killbill.billing.jaxrs.json.PhasePriceOverrideJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -146,6 +148,7 @@ public class InvoiceResource extends JaxRsResourceBase {
public InvoiceResource(final AccountUserApi accountUserApi,
final InvoiceUserApi invoiceApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final JaxrsUriBuilder uriBuilder,
final TagUserApi tagUserApi,
@@ -153,7 +156,7 @@ public class InvoiceResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final TenantUserApi tenantApi,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.invoiceApi = invoiceApi;
this.tenantApi = tenantApi;
this.defaultLocale = Locale.getDefault();
@@ -304,8 +307,7 @@ public class InvoiceResource extends JaxRsResourceBase {
final LocalDate inputDate = toLocalDate(targetDate);
try {
- final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(accountId, inputDate, null,
- callContext);
+ final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(accountId, inputDate, callContext);
return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", generatedInvoice.getId(), request);
} catch (InvoiceApiException e) {
if (e.getCode() == ErrorCode.INVOICE_NOTHING_TO_DO.getCode()) {
@@ -394,8 +396,7 @@ public class InvoiceResource extends JaxRsResourceBase {
final DryRunArguments dryRunArguments = new DefaultDryRunArguments(dryRunSubscriptionSpec, account);
try {
- final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(accountId, inputDate, dryRunArguments,
- callContext);
+ final Invoice generatedInvoice = invoiceApi.triggerDryRunInvoiceGeneration(accountId, inputDate, dryRunArguments, callContext);
return Response.status(Status.OK).entity(new InvoiceJson(generatedInvoice, true, null, null)).build();
} catch (InvoiceApiException e) {
if (e.getCode() == ErrorCode.INVOICE_NOTHING_TO_DO.getCode()) {
@@ -696,10 +697,10 @@ public class InvoiceResource extends JaxRsResourceBase {
final UUID paymentMethodId = externalPayment ? null :
(payment.getPaymentMethodId() != null ? payment.getPaymentMethodId() : account.getPaymentMethodId());
- final Payment result = createPurchaseForInvoice(account, invoiceId, payment.getPurchasedAmount(), paymentMethodId, externalPayment,
- payment.getPaymentExternalKey(), null, pluginProperties, callContext);
+ final InvoicePayment result = createPurchaseForInvoice(account, invoiceId, payment.getPurchasedAmount(), paymentMethodId, externalPayment,
+ payment.getPaymentExternalKey(), null, pluginProperties, callContext);
return result != null ?
- uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", result.getId(), request) :
+ uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", result.getPaymentId(), request) :
Response.status(Status.NO_CONTENT).build();
}
@@ -1073,10 +1074,9 @@ public class InvoiceResource extends JaxRsResourceBase {
private final SubscriptionEventType action;
private final UUID subscriptionId;
private final LocalDate effectiveDate;
- private final PlanPhaseSpecifier specifier;
+ private final EntitlementSpecifier specifier;
private final UUID bundleId;
private final BillingActionPolicy billingPolicy;
- private final List<PlanPhasePriceOverride> overrides;
public DefaultDryRunArguments(final InvoiceDryRunJson input, final Account account) {
if (input == null) {
@@ -1087,7 +1087,6 @@ public class InvoiceResource extends JaxRsResourceBase {
this.specifier = null;
this.bundleId = null;
this.billingPolicy = null;
- this.overrides = null;
} else {
this.dryRunType = input.getDryRunType() != null ? input.getDryRunType() : DryRunType.TARGET_DATE;
this.action = input.getDryRunAction() != null ? input.getDryRunAction() : null;
@@ -1103,8 +1102,7 @@ public class InvoiceResource extends JaxRsResourceBase {
input.getPriceListName(),
input.getPhaseType() != null ? input.getPhaseType() : null) :
null;
- this.specifier = planPhaseSpecifier;
- this.overrides = input.getPriceOverrides() != null ?
+ final List<PlanPhasePriceOverride> overrides = input.getPriceOverrides() != null ?
ImmutableList.copyOf(Iterables.transform(input.getPriceOverrides(), new Function<PhasePriceOverrideJson, PlanPhasePriceOverride>() {
@Nullable
@Override
@@ -1117,6 +1115,20 @@ public class InvoiceResource extends JaxRsResourceBase {
}
}
})) : ImmutableList.<PlanPhasePriceOverride>of();
+ this.specifier = new EntitlementSpecifier() {
+ @Override
+ public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ return planPhaseSpecifier;
+ }
+ @Override
+ public Integer getBillCycleDay() {
+ return null;
+ }
+ @Override
+ public List<PlanPhasePriceOverride> getOverrides() {
+ return overrides;
+ }
+ };
}
}
@@ -1126,7 +1138,7 @@ public class InvoiceResource extends JaxRsResourceBase {
}
@Override
- public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ public EntitlementSpecifier getEntitlementSpecifier() {
return specifier;
}
@@ -1155,10 +1167,6 @@ public class InvoiceResource extends JaxRsResourceBase {
return billingPolicy;
}
- @Override
- public List<PlanPhasePriceOverride> getPlanPhasePriceOverrides() {
- return overrides;
- }
@Override
public String toString() {
@@ -1170,7 +1178,6 @@ public class InvoiceResource extends JaxRsResourceBase {
sb.append(", specifier=").append(specifier);
sb.append(", bundleId=").append(bundleId);
sb.append(", billingPolicy=").append(billingPolicy);
- sb.append(", overrides=").append(overrides);
sb.append('}');
return sb.toString();
}
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 87b2c37..92dc6b6 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
@@ -22,7 +22,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URI;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -72,6 +71,7 @@ import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.junction.DefaultBlockingState;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -132,6 +132,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
protected final AuditUserApi auditUserApi;
protected final AccountUserApi accountUserApi;
protected final PaymentApi paymentApi;
+ protected final InvoicePaymentApi invoicePaymentApi;
protected final SubscriptionApi subscriptionApi;
protected final Context context;
protected final Clock clock;
@@ -145,6 +146,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final SubscriptionApi subscriptionApi,
final Clock clock,
final Context context) {
@@ -154,6 +156,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
this.auditUserApi = auditUserApi;
this.accountUserApi = accountUserApi;
this.paymentApi = paymentApi;
+ this.invoicePaymentApi = invoicePaymentApi;
this.subscriptionApi = subscriptionApi;
this.clock = clock;
this.context = context;
@@ -541,22 +544,20 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
return properties;
}
- protected Payment createPurchaseForInvoice(final Account account, final UUID invoiceId, final BigDecimal amountToPay, final UUID paymentMethodId, final Boolean externalPayment, final String paymentExternalKey, final String transactionExternalKey, final Iterable<PluginProperty> pluginProperties, final CallContext callContext) throws PaymentApiException {
-
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final Iterator<PluginProperty> pluginPropertyIterator = pluginProperties.iterator();
- while (pluginPropertyIterator.hasNext()) {
- properties.add(pluginPropertyIterator.next());
- }
-
- final PluginProperty invoiceProperty = new PluginProperty("IPCD_INVOICE_ID" /* InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID (contract with plugin) */,
- invoiceId.toString(), false);
- properties.add(invoiceProperty);
+ protected InvoicePayment createPurchaseForInvoice(final Account account, final UUID invoiceId, final BigDecimal amountToPay, final UUID paymentMethodId, final Boolean externalPayment, final String paymentExternalKey, final String transactionExternalKey, final Iterable<PluginProperty> pluginProperties, final CallContext callContext) throws PaymentApiException {
try {
- return paymentApi.createPurchaseWithPaymentControl(account, paymentMethodId, null, amountToPay, account.getCurrency(), null, paymentExternalKey, transactionExternalKey,
- properties, createInvoicePaymentControlPluginApiPaymentOptions(externalPayment), callContext);
+ return invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoiceId,
+ paymentMethodId,
+ null, amountToPay,
+ account.getCurrency(),
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ pluginProperties,
+ createInvoicePaymentControlPluginApiPaymentOptions(externalPayment),
+ callContext);
} catch (final PaymentApiException e) {
-
if (e.getCode() == ErrorCode.PAYMENT_PLUGIN_EXCEPTION.getCode() /* &&
e.getMessage().contains("Invalid amount") */) { /* Plugin received bad input */
throw e;
@@ -568,7 +569,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
}
protected PaymentOptions createInvoicePaymentControlPluginApiPaymentOptions(final boolean isExternalPayment) {
- return createControlPluginApiPaymentOptions(isExternalPayment, ImmutableList.<String>of("__INVOICE_PAYMENT_CONTROL_PLUGIN__"));
+ return createControlPluginApiPaymentOptions(isExternalPayment, ImmutableList.<String>of());
}
protected PaymentOptions createControlPluginApiPaymentOptions(@Nullable final List<String> paymentControlPluginNames) {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java
index c16907c..ca518a4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -47,6 +47,7 @@ import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.osgi.api.PluginInfo;
import org.killbill.billing.osgi.api.PluginServiceInfo;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -84,10 +85,11 @@ public class NodesInfoResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final KillbillNodesApi killbillInfoApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.killbillInfoApi = killbillInfoApi;
}
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 782c07a..6b6009a 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
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -39,6 +39,7 @@ import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.api.OverdueConfig;
import org.killbill.billing.overdue.config.DefaultOverdueConfig;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -74,10 +75,11 @@ public class OverdueResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final OverdueApi overdueApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.overdueApi = overdueApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
index 93dfef0..2d80b56 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -41,6 +41,7 @@ import org.killbill.billing.jaxrs.json.HostedPaymentPageFieldsJson;
import org.killbill.billing.jaxrs.json.HostedPaymentPageFormDescriptorJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PaymentGatewayApi;
@@ -80,9 +81,10 @@ public class PaymentGatewayResource extends ComboPaymentResource {
final AccountUserApi accountUserApi,
final PaymentGatewayApi paymentGatewayApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, clock, context);
this.paymentGatewayApi = paymentGatewayApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
index 84e76a5..04cd766 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -50,6 +50,7 @@ import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.PaymentMethodJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PaymentMethod;
@@ -93,9 +94,10 @@ public class PaymentMethodResource extends JaxRsResourceBase {
final CustomFieldUserApi customFieldUserApi,
final AuditUserApi auditUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
@TimedResource(name = "getPaymentMethod")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index 25d5865..27ccdf6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -55,6 +55,7 @@ import org.killbill.billing.jaxrs.json.PaymentTransactionJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -104,9 +105,10 @@ public class PaymentResource extends ComboPaymentResource {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, clock, context);
}
@TimedResource(name = "getPayment")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java
index 936ba41..9f0f41f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -32,6 +32,7 @@ import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.osgi.api.PluginInfo;
import org.killbill.billing.osgi.api.PluginsInfoApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -60,10 +61,11 @@ public class PluginInfoResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final PluginsInfoApi pluginsInfoApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.pluginsInfoApi = pluginsInfoApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java
index 5a14c1e..a9a2d4c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java
@@ -58,6 +58,7 @@ import javax.ws.rs.core.UriInfo;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -94,9 +95,10 @@ public class PluginResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.osgiServlet = osgiServlet;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
index 1ccf9ab..dc77b6c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -42,6 +44,7 @@ import org.killbill.billing.jaxrs.json.SubjectJson;
import org.killbill.billing.jaxrs.json.UserRolesJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.security.Permission;
import org.killbill.billing.security.SecurityApiException;
@@ -79,9 +82,10 @@ public class SecurityResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.securityApi = securityApi;
}
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 1d50fdb..432eafd 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
@@ -58,6 +58,7 @@ import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
import org.killbill.billing.entitlement.api.EntitlementApi;
@@ -86,6 +87,7 @@ import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.jaxrs.util.KillbillEventHandler;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.api.AuditUserApi;
@@ -136,9 +138,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
final SubscriptionApi subscriptionApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, subscriptionApi, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, subscriptionApi, clock, context);
this.killbillHandler = killbillHandler;
this.entitlementApi = entitlementApi;
this.subscriptionApi = subscriptionApi;
@@ -378,6 +381,11 @@ public class SubscriptionResource extends JaxRsResourceBase {
}
@Override
+ public Integer getBillCycleDay() {
+ return null;
+ }
+
+ @Override
public List<PlanPhasePriceOverride> getOverrides() {
return overrides;
}
@@ -529,11 +537,11 @@ public class SubscriptionResource extends JaxRsResourceBase {
final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(entitlement.getPriceOverrides(), planSpec, account.getCurrency());
if (requestedDate == null && billingPolicy == null) {
- newEntitlement = current.changePlan(planSpec, overrides, pluginProperties, ctx);
+ newEntitlement = current.changePlan(new DefaultEntitlementSpecifier(planSpec, null, overrides), pluginProperties, ctx);
} else if (billingPolicy == null) {
- newEntitlement = current.changePlanWithDate(planSpec, overrides, inputLocalDate, pluginProperties, ctx);
+ newEntitlement = current.changePlanWithDate(new DefaultEntitlementSpecifier(planSpec, null, overrides), inputLocalDate, pluginProperties, ctx);
} else {
- newEntitlement = current.changePlanOverrideBillingPolicy(planSpec, overrides, null, billingPolicy, pluginProperties, ctx);
+ newEntitlement = current.changePlanOverrideBillingPolicy(new DefaultEntitlementSpecifier(planSpec, null, overrides), null, billingPolicy, pluginProperties, ctx);
}
isImmediateOp = newEntitlement.getLastActiveProduct().getName().equals(entitlement.getProductName()) &&
newEntitlement.getLastActivePlan().getRecurringBillingPeriod() == entitlement.getBillingPeriod() &&
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
index d72811b..ff8b124 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -43,6 +45,7 @@ import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.TagDefinitionJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
@@ -78,9 +81,10 @@ public class TagDefinitionResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
@TimedResource
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
index 96114a0..4429014 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2014 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -36,6 +38,7 @@ import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.jaxrs.json.AuditLogJson;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.audit.AuditLogWithHistory;
@@ -77,9 +80,10 @@ public class TagResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
@TimedResource
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
index dabce06..ad072cf 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -46,6 +48,7 @@ import org.killbill.billing.jaxrs.json.TenantJson;
import org.killbill.billing.jaxrs.json.TenantKeyValueJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.tenant.api.Tenant;
import org.killbill.billing.tenant.api.TenantApiException;
@@ -88,10 +91,11 @@ public class TenantResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final CatalogUserApi catalogUserApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.tenantApi = tenantApi;
this.catalogUserApi = catalogUserApi;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
index 5a78b55..9e22594 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
@@ -23,11 +23,8 @@ import java.util.Iterator;
import javax.inject.Inject;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
-import javax.ws.rs.HEAD;
-import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@@ -35,28 +32,23 @@ 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.joda.time.LocalDate;
import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountUserApi;
-import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogUserApi;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
-import org.killbill.billing.tenant.api.TenantApiException;
-import org.killbill.billing.tenant.api.TenantKV.TenantKey;
import org.killbill.billing.tenant.api.TenantUserApi;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.api.RecordIdApi;
import org.killbill.billing.util.api.TagUserApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
-import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.bus.api.BusEvent;
import org.killbill.bus.api.BusEventWithMetadata;
@@ -107,9 +99,9 @@ public class TestResource extends JaxRsResourceBase {
public TestResource(final JaxrsUriBuilder uriBuilder, final TagUserApi tagUserApi, final CustomFieldUserApi customFieldUserApi,
final AuditUserApi auditUserApi, final AccountUserApi accountUserApi, final RecordIdApi recordIdApi,
final PersistentBus persistentBus, final NotificationQueueService notificationQueueService, final PaymentApi paymentApi,
- final TenantUserApi tenantApi, final CatalogUserApi catalogUserApi,
+ final InvoicePaymentApi invoicePaymentApi, final TenantUserApi tenantApi, final CatalogUserApi catalogUserApi,
final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.persistentBus = persistentBus;
this.notificationQueueService = notificationQueueService;
this.recordIdApi = recordIdApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
index cad1ac3..bceabc9 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -48,6 +48,7 @@ import org.killbill.billing.jaxrs.json.PaymentTransactionJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
@@ -72,6 +73,7 @@ import org.killbill.commons.metrics.TimedResource;
import com.google.common.collect.ImmutableList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@@ -90,9 +92,10 @@ public class TransactionResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
@TimedResource(name = "getPaymentByTransactionId")
@@ -115,6 +118,25 @@ public class TransactionResource extends JaxRsResourceBase {
return Response.status(Response.Status.OK).entity(result).build();
}
+ @TimedResource(name = "getPaymentByTransactionExternalKey")
+ @GET
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve a payment by transaction external key", response = PaymentJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Payment not found")})
+ public Response getPaymentByTransactionExternalKey(@ApiParam(required = true) @QueryParam(QUERY_TRANSACTION_EXTERNAL_KEY) final String paymentTransactionExternalKey,
+ @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+ @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+ final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final Payment payment = paymentApi.getPaymentByTransactionExternalKey(paymentTransactionExternalKey, withPluginInfo, withAttempts, pluginProperties, tenantContext);
+ final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
+ final PaymentJson result = new PaymentJson(payment, accountAuditLogs);
+ return Response.status(Response.Status.OK).entity(result).build();
+ }
+
@TimedResource
@POST
@Path("/{transactionId:" + UUID_PATTERN + "}/")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
index 7aa2203..3660b35 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
@@ -1,5 +1,6 @@
/*
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -37,7 +38,6 @@ import org.joda.time.LocalDate;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.entitlement.api.Entitlement;
-import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementApi;
import org.killbill.billing.entitlement.api.EntitlementApiException;
import org.killbill.billing.jaxrs.json.RolledUpUsageJson;
@@ -46,6 +46,7 @@ import org.killbill.billing.jaxrs.json.SubscriptionUsageRecordJson.UnitUsageReco
import org.killbill.billing.jaxrs.json.SubscriptionUsageRecordJson.UsageRecordJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.usage.api.RolledUpUsage;
import org.killbill.billing.usage.api.SubscriptionUsageRecord;
@@ -89,10 +90,11 @@ public class UsageResource extends JaxRsResourceBase {
final AccountUserApi accountUserApi,
final UsageUserApi usageUserApi,
final PaymentApi paymentApi,
+ final InvoicePaymentApi invoicePaymentApi,
final EntitlementApi entitlementApi,
final Clock clock,
final Context context) {
- super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
this.usageUserApi = usageUserApi;
this.entitlementApi = entitlementApi;
}
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java
index 979f012..807b78f 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/resources/TestJaxRsResourceBase.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2015 Groupon, Inc
- * Copyright 2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -67,7 +67,7 @@ public class TestJaxRsResourceBase extends JaxrsTestSuiteNoDB {
private static final class JaxRsResourceBaseTest extends JaxRsResourceBase {
public JaxRsResourceBaseTest() {
- super(null, null, null, null, null, null, null, null, null);
+ super(null, null, null, null, null, null, null, null, null, null);
}
}
@@ -113,7 +113,7 @@ public class TestJaxRsResourceBase extends JaxrsTestSuiteNoDB {
private static class UsageResourceTest extends UsageResource {
public UsageResourceTest() {
- super(null, null, null, null, null, null, null, null, null, null);
+ super(null, null, null, null, null, null, null, null, null, null, null);
}
}
}
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java
index f70b3e4..b7d5a78 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -38,7 +38,7 @@ import org.killbill.billing.util.UUIDs;
public class TestDateConversion extends JaxRsResourceBase {
public TestDateConversion() throws AccountApiException {
- super(null, null, null, null, Mockito.mock(AccountUserApi.class), null, null, new ClockMock(), null);
+ super(null, null, null, null, Mockito.mock(AccountUserApi.class), null, null, null, new ClockMock(), null);
}
public UUID setupAccount(DateTimeZone accountTimeZone) throws AccountApiException {
junction/pom.xml 3(+1 -2)
diff --git a/junction/pom.xml b/junction/pom.xml
index 4cef49f..bfc8c82 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -91,12 +91,11 @@
<dependency>
<groupId>org.kill-bill.billing</groupId>
<artifactId>killbill-catalog</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.kill-bill.billing</groupId>
<artifactId>killbill-catalog</artifactId>
+ <type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java
index c08a7be..f7285c5 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java
@@ -24,6 +24,7 @@ import java.util.List;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
+import org.killbill.billing.catalog.DefaultPlan;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
@@ -59,6 +60,8 @@ public class DefaultBillingEvent implements BillingEvent {
private final boolean isDisableEvent;
private final PlanPhase nextPlanPhase;
+ private final DateTime catalogEffectiveDate;
+
public DefaultBillingEvent(final SubscriptionInternalEvent transition,
final SubscriptionBase subscription,
final int billCycleDayLocal,
@@ -88,6 +91,8 @@ public class DefaultBillingEvent implements BillingEvent {
final PlanPhase prevPlanPhase = (prevPhaseName != null && prevPlan != null) ? prevPlan.findPhase(prevPhaseName) : null;
this.billingPeriod = getRecurringBillingPeriod(prevPlanPhase);
}
+ // TODO It would be nice to have an Plan api to get that date; actually the following would be nice
+ this.catalogEffectiveDate = ((DefaultPlan) plan).getCatalogEffectiveDate();
this.billCycleDayLocal = billCycleDayLocal;
this.catalog = catalog;
@@ -124,6 +129,8 @@ public class DefaultBillingEvent implements BillingEvent {
this.usages = initializeUsage(isActive);
this.isDisableEvent = isDisableEvent;
this.nextPlanPhase = isDisableEvent ? null : planPhase;
+ this.catalogEffectiveDate = plan != null ? ((DefaultPlan) plan).getCatalogEffectiveDate() : null;
+
}
@Override
@@ -348,4 +355,9 @@ public class DefaultBillingEvent implements BillingEvent {
}
return result;
}
+
+ @Override
+ public DateTime getCatalogEffectiveDate() {
+ return catalogEffectiveDate;
+ }
}
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
index 275aaa3..debc72c 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
@@ -34,6 +34,7 @@ import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.DefaultEntitlementApi;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.junction.DefaultBlockingState;
@@ -61,7 +62,7 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final SubscriptionBase subscription = subscriptionInternalApi.getSubscriptionFromId(entitlement.getId(), internalCallContext);
assertListenerStatus();
@@ -207,7 +208,7 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final SubscriptionBase subscription = subscriptionInternalApi.getSubscriptionFromId(entitlement.getId(), internalCallContext);
assertListenerStatus();
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java
index e2bcac5..20e99ad 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultApiBase.java
@@ -25,6 +25,7 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.config.definition.PaymentConfig;
import com.google.common.collect.ImmutableList;
@@ -39,15 +40,14 @@ public class DefaultApiBase {
this.internalCallContextFactory = internalCallContextFactory;
}
- protected List<String> toPaymentControlPluginNames(final PaymentOptions paymentOptions, final CallContext callContext) {
+ protected List<String> toPaymentControlPluginNames(final PaymentOptions paymentOptions, final TenantContext callContext) {
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(callContext);
// Special path for JAX-RS InvoicePayment endpoints (see JaxRsResourceBase)
final List<String> controlPluginNames = paymentConfig.getPaymentControlPluginNames(internalTenantContext);
if (controlPluginNames != null &&
paymentOptions.getPaymentControlPluginNames() != null &&
- paymentOptions.getPaymentControlPluginNames().size() == 1 &&
- InvoicePaymentControlPluginApi.PLUGIN_NAME.equals(paymentOptions.getPaymentControlPluginNames().get(0))) {
+ paymentOptions.getPaymentControlPluginNames().isEmpty()) {
final List<String> paymentControlPluginNames = new LinkedList<String>(paymentOptions.getPaymentControlPluginNames());
paymentControlPluginNames.addAll(controlPluginNames);
return paymentControlPluginNames;
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java
new file mode 100644
index 0000000..c836e97
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultInvoicePaymentApi.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.payment.api;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.invoice.api.InvoiceInternalApi;
+import org.killbill.billing.invoice.api.InvoicePayment;
+import org.killbill.billing.payment.api.svcs.InvoicePaymentPaymentOptions;
+import org.killbill.billing.util.UUIDs;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
+
+import com.google.common.base.MoreObjects;
+import com.google.inject.Inject;
+
+public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
+
+ private final PaymentApi paymentApi;
+ private final InvoiceInternalApi invoiceInternalApi;
+ private final InvoicePaymentInternalApi invoicePaymentInternalApi;
+ private final InternalCallContextFactory internalCallContextFactory;
+
+ @Inject
+ public DefaultInvoicePaymentApi(final PaymentApi paymentApi,
+ final InvoiceInternalApi invoiceInternalApi,
+ final InvoicePaymentInternalApi invoicePaymentInternalApi,
+ final InternalCallContextFactory internalCallContextFactory) {
+ this.paymentApi = paymentApi;
+ this.invoiceInternalApi = invoiceInternalApi;
+ this.invoicePaymentInternalApi = invoicePaymentInternalApi;
+ this.internalCallContextFactory = internalCallContextFactory;
+ }
+
+ @Override
+ public InvoicePayment createPurchaseForInvoicePayment(final Account account,
+ final UUID invoiceId,
+ final UUID paymentMethodId,
+ final UUID paymentId,
+ final BigDecimal amount,
+ final Currency currency,
+ final DateTime effectiveDate,
+ final String paymentExternalKey,
+ final String paymentTransactionExternalKey,
+ final Iterable<PluginProperty> properties,
+ final PaymentOptions paymentOptions,
+ final CallContext context) throws PaymentApiException {
+ return invoicePaymentInternalApi.createPurchaseForInvoicePayment(true,
+ account,
+ invoiceId,
+ paymentMethodId,
+ paymentId,
+ amount,
+ currency,
+ effectiveDate,
+ paymentExternalKey,
+ paymentTransactionExternalKey,
+ properties,
+ paymentOptions,
+ internalCallContextFactory.createInternalCallContext(account.getId(), context));
+ }
+
+ @Override
+ public InvoicePayment createRefundForInvoicePayment(final boolean isAdjusted,
+ final Map<UUID, BigDecimal> adjustments,
+ final Account account,
+ final UUID paymentId,
+ final BigDecimal amount,
+ final Currency currency,
+ final DateTime effectiveDate,
+ final String originalPaymentTransactionExternalKey,
+ final Iterable<PluginProperty> originalProperties,
+ final PaymentOptions paymentOptions,
+ final CallContext context) throws PaymentApiException {
+ final Collection<PluginProperty> pluginProperties = preparePluginPropertiesForRefundOrCredit(isAdjusted, adjustments, originalProperties);
+ final String paymentTransactionExternalKey = MoreObjects.firstNonNull(originalPaymentTransactionExternalKey, UUIDs.randomUUID().toString());
+
+ paymentApi.createRefundWithPaymentControl(account,
+ paymentId,
+ amount,
+ currency,
+ effectiveDate,
+ paymentTransactionExternalKey,
+ pluginProperties,
+ InvoicePaymentPaymentOptions.create(paymentOptions),
+ context);
+
+ return invoiceInternalApi.getInvoicePaymentByCookieId(paymentTransactionExternalKey, context);
+ }
+
+ @Override
+ public InvoicePayment createCreditForInvoicePayment(final boolean isAdjusted,
+ final Map<UUID, BigDecimal> adjustments,
+ final Account account,
+ final UUID originalPaymentId,
+ final UUID paymentMethodId,
+ final UUID paymentId,
+ final BigDecimal amount,
+ final Currency currency,
+ final DateTime effectiveDate,
+ final String paymentExternalKey,
+ final String originalPaymentTransactionExternalKey,
+ final Iterable<PluginProperty> originalProperties,
+ final PaymentOptions paymentOptions,
+ final CallContext context) throws PaymentApiException {
+ final Collection<PluginProperty> pluginProperties = preparePluginPropertiesForRefundOrCredit(isAdjusted, adjustments, originalProperties);
+ pluginProperties.add(new PluginProperty("IPCD_PAYMENT_ID", originalPaymentId, false));
+
+ final String paymentTransactionExternalKey = MoreObjects.firstNonNull(originalPaymentTransactionExternalKey, UUIDs.randomUUID().toString());
+
+ paymentApi.createCreditWithPaymentControl(account,
+ paymentMethodId,
+ paymentId,
+ amount,
+ currency,
+ effectiveDate,
+ paymentExternalKey,
+ paymentTransactionExternalKey,
+ pluginProperties,
+ InvoicePaymentPaymentOptions.create(paymentOptions),
+ context);
+
+ return invoiceInternalApi.getInvoicePaymentByCookieId(paymentTransactionExternalKey, context);
+ }
+
+ @Override
+ public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
+ return invoiceInternalApi.getInvoicePayments(paymentId, context);
+ }
+
+ @Override
+ public List<InvoicePayment> getInvoicePaymentsByAccount(final UUID accountId, final TenantContext context) {
+ return invoiceInternalApi.getInvoicePaymentsByAccount(accountId, context);
+ }
+
+ private Collection<PluginProperty> preparePluginPropertiesForRefundOrCredit(final boolean isAdjusted,
+ @Nullable final Map<UUID, BigDecimal> adjustments,
+ final Iterable<PluginProperty> originalProperties) {
+ final Collection<PluginProperty> pluginProperties = new LinkedList<PluginProperty>();
+ if (originalProperties != null) {
+ for (final PluginProperty pluginProperty : originalProperties) {
+ pluginProperties.add(pluginProperty);
+ }
+ }
+ pluginProperties.add(new PluginProperty("IPCD_REFUND_WITH_ADJUSTMENTS", isAdjusted, false));
+ if (adjustments != null) {
+ pluginProperties.add(new PluginProperty("IPCD_REFUND_IDS_AMOUNTS", adjustments, false));
+ }
+ return pluginProperties;
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index c9ffb84..1418ef1 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -131,10 +131,6 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
checkNotNullParameter(account, "account");
- if (paymentId == null) {
- checkNotNullParameter(amount, "amount");
- checkNotNullParameter(currency, "currency");
- }
checkNotNullParameter(properties, "plugin properties");
checkExternalKeyLength(paymentExternalKey);
@@ -228,8 +224,6 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
checkNotNullParameter(account, "account");
checkNotNullParameter(paymentId, "paymentId");
- checkNotNullParameter(amount, "amount");
- checkNotNullParameter(currency, "currency");
checkNotNullParameter(properties, "plugin properties");
checkExternalKeyLength(paymentTransactionExternalKey);
@@ -323,11 +317,6 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
checkNotNullParameter(account, "account");
- if (paymentId == null) {
- checkNotNullParameter(amount, "amount");
- checkNotNullParameter(currency, "currency");
- }
-
checkNotNullParameter(properties, "plugin properties");
checkExternalKeyLength(paymentTransactionExternalKey);
@@ -515,9 +504,6 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
checkNotNullParameter(account, "account");
- if (paymentId == null) {
- checkNotNullParameter(currency, "currency");
- }
checkNotNullParameter(paymentId, "paymentId");
checkNotNullParameter(properties, "plugin properties");
checkExternalKeyLength(paymentTransactionExternalKey);
@@ -617,10 +603,6 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
checkNotNullParameter(account, "account");
- if (paymentId == null) {
- checkNotNullParameter(amount, "amount");
- checkNotNullParameter(currency, "currency");
- }
checkNotNullParameter(properties, "plugin properties");
checkExternalKeyLength(paymentTransactionExternalKey);
@@ -816,8 +798,6 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
checkNotNullParameter(account, "account");
- checkNotNullParameter(amount, "amount");
- checkNotNullParameter(currency, "currency");
checkNotNullParameter(paymentId, "paymentId");
final String transactionType = TransactionType.CHARGEBACK.name();
@@ -1105,6 +1085,15 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
return payment;
}
+ @Override
+ public Payment getPaymentByTransactionExternalKey(final String transactionExternalKey, final boolean withPluginInfo, final boolean withAttempts, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+ final Payment payment = paymentProcessor.getPaymentByTransactionExternalKey(transactionExternalKey, withPluginInfo, withAttempts, properties, context, internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context));
+ if (payment == null) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, transactionExternalKey);
+ }
+ return payment;
+ }
+
private PaymentTransaction findPaymentTransaction(final Payment payment, @Nullable final String paymentTransactionExternalKey) {
// By design, the payment transactions are already correctly sorted (by effective date asc)
if (paymentTransactionExternalKey == null) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultInvoicePaymentInternalApi.java b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultInvoicePaymentInternalApi.java
new file mode 100644
index 0000000..682e88b
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultInvoicePaymentInternalApi.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.payment.api.svcs;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.invoice.api.InvoiceInternalApi;
+import org.killbill.billing.invoice.api.InvoicePayment;
+import org.killbill.billing.payment.api.DefaultApiBase;
+import org.killbill.billing.payment.api.InvoicePaymentInternalApi;
+import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentOptions;
+import org.killbill.billing.payment.api.PaymentTransaction;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.api.TransactionType;
+import org.killbill.billing.payment.core.PaymentMethodProcessor;
+import org.killbill.billing.payment.core.PluginControlPaymentProcessor;
+import org.killbill.billing.util.UUIDs;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.config.definition.PaymentConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+import static org.killbill.billing.payment.logging.PaymentLoggingHelper.logEnterAPICall;
+import static org.killbill.billing.payment.logging.PaymentLoggingHelper.logExitAPICall;
+
+public class DefaultInvoicePaymentInternalApi extends DefaultApiBase implements InvoicePaymentInternalApi {
+
+ private static final Logger log = LoggerFactory.getLogger(DefaultInvoicePaymentInternalApi.class);
+
+ private final InvoiceInternalApi invoiceInternalApi;
+ private final PluginControlPaymentProcessor pluginControlPaymentProcessor;
+ private final PaymentMethodProcessor paymentMethodProcessor;
+
+ @Inject
+ public DefaultInvoicePaymentInternalApi(final InvoiceInternalApi invoiceInternalApi,
+ final PluginControlPaymentProcessor pluginControlPaymentProcessor,
+ final PaymentMethodProcessor paymentMethodProcessor,
+ final PaymentConfig paymentConfig,
+ final InternalCallContextFactory internalCallContextFactory) {
+ super(paymentConfig, internalCallContextFactory);
+ this.invoiceInternalApi = invoiceInternalApi;
+ this.pluginControlPaymentProcessor = pluginControlPaymentProcessor;
+ this.paymentMethodProcessor = paymentMethodProcessor;
+ }
+
+ @Override
+ public InvoicePayment createPurchaseForInvoicePayment(final boolean isApiPayment,
+ final Account account,
+ final UUID invoiceId,
+ final UUID paymentMethodId,
+ final UUID paymentId,
+ final BigDecimal amount,
+ final Currency currency,
+ final DateTime effectiveDate,
+ final String paymentExternalKey,
+ final String paymentTransactionExternalKey,
+ final Iterable<PluginProperty> originalProperties,
+ final PaymentOptions paymentOptions,
+ final InternalCallContext internalCallContext) throws PaymentApiException {
+ checkExternalKeyLength(paymentTransactionExternalKey);
+
+ final Collection<PluginProperty> pluginProperties = new LinkedList<PluginProperty>();
+ if (originalProperties != null) {
+ for (final PluginProperty pluginProperty : originalProperties) {
+ pluginProperties.add(pluginProperty);
+ }
+ }
+ pluginProperties.add(new PluginProperty("IPCD_INVOICE_ID", invoiceId.toString(), false));
+
+ final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext);
+
+ final List<String> defaultOrUserSpecifiedPaymentControlPluginNames = toPaymentControlPluginNames(paymentOptions, callContext);
+ final List<String> paymentControlPluginNames = InvoicePaymentPaymentOptions.addInvoicePaymentControlPlugin(defaultOrUserSpecifiedPaymentControlPluginNames);
+
+ final UUID resolvedPaymentMethodId = (paymentMethodId == null && paymentOptions.isExternalPayment()) ?
+ paymentMethodProcessor.createOrGetExternalPaymentMethod(UUIDs.randomUUID().toString(), account, pluginProperties, callContext, internalCallContext) :
+ paymentMethodId;
+
+ final String transactionType = TransactionType.PURCHASE.name();
+ Payment payment = null;
+ PaymentTransaction paymentTransaction = null;
+ PaymentApiException exception = null;
+ try {
+ logEnterAPICall(log, transactionType, account, paymentMethodId, paymentId, null, amount, currency, paymentExternalKey, paymentTransactionExternalKey, null, paymentControlPluginNames);
+
+ payment = pluginControlPaymentProcessor.createPurchase(isApiPayment,
+ account,
+ resolvedPaymentMethodId,
+ paymentId,
+ amount,
+ currency,
+ effectiveDate,
+ paymentExternalKey,
+ paymentTransactionExternalKey,
+ pluginProperties,
+ paymentControlPluginNames,
+ callContext,
+ internalCallContext);
+
+ paymentTransaction = payment.getTransactions().get(payment.getTransactions().size() - 1);
+ } catch (final PaymentApiException e) {
+ exception = e;
+ throw e;
+ } finally {
+ logExitAPICall(log,
+ transactionType,
+ account,
+ payment != null ? payment.getPaymentMethodId() : null,
+ payment != null ? payment.getId() : null,
+ paymentTransaction != null ? paymentTransaction.getId() : null,
+ paymentTransaction != null ? paymentTransaction.getProcessedAmount() : null,
+ paymentTransaction != null ? paymentTransaction.getProcessedCurrency() : null,
+ payment != null ? payment.getExternalKey() : null,
+ paymentTransaction != null ? paymentTransaction.getExternalKey() : null,
+ paymentTransaction != null ? paymentTransaction.getTransactionStatus() : null,
+ paymentControlPluginNames,
+ exception);
+ }
+
+ return paymentTransaction != null ? invoiceInternalApi.getInvoicePaymentByCookieId(paymentTransaction.getExternalKey(), callContext) : null;
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/svcs/InvoicePaymentPaymentOptions.java b/payment/src/main/java/org/killbill/billing/payment/api/svcs/InvoicePaymentPaymentOptions.java
new file mode 100644
index 0000000..ad2c6d3
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/InvoicePaymentPaymentOptions.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.payment.api.svcs;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.killbill.billing.payment.api.PaymentOptions;
+import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
+
+public class InvoicePaymentPaymentOptions implements PaymentOptions {
+
+ private final boolean isExternalPayment;
+ private final List<String> paymentControlPluginNames;
+
+ public InvoicePaymentPaymentOptions(final boolean isExternalPayment, final List<String> getPaymentControlPluginNames) {
+ this.isExternalPayment = isExternalPayment;
+ this.paymentControlPluginNames = getPaymentControlPluginNames;
+ }
+
+ public static InvoicePaymentPaymentOptions create(final PaymentOptions paymentOptions) {
+ final List<String> controlPluginNamesFromUser = paymentOptions.getPaymentControlPluginNames();
+ final List<String> paymentControlPluginNames = addInvoicePaymentControlPlugin(controlPluginNamesFromUser);
+ return new InvoicePaymentPaymentOptions(paymentOptions.isExternalPayment(), paymentControlPluginNames);
+ }
+
+ public static List<String> addInvoicePaymentControlPlugin(final Collection<String> controlPluginNamesFromUser) {
+ final List<String> paymentControlPluginNames = new LinkedList<String>();
+ paymentControlPluginNames.addAll(controlPluginNamesFromUser);
+ if (!paymentControlPluginNames.contains(InvoicePaymentControlPluginApi.PLUGIN_NAME)) {
+ paymentControlPluginNames.add(InvoicePaymentControlPluginApi.PLUGIN_NAME);
+ }
+ return paymentControlPluginNames;
+ }
+
+ @Override
+ public boolean isExternalPayment() {
+ return isExternalPayment;
+ }
+
+ @Override
+ public List<String> getPaymentControlPluginNames() {
+ return paymentControlPluginNames;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("InvoicePaymentPaymentOptions{");
+ sb.append("isExternalPayment=").append(isExternalPayment);
+ sb.append(", paymentControlPluginNames=").append(paymentControlPluginNames);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/bus/PaymentBusEventHandler.java b/payment/src/main/java/org/killbill/billing/payment/bus/PaymentBusEventHandler.java
index 99973ac..7255944 100644
--- a/payment/src/main/java/org/killbill/billing/payment/bus/PaymentBusEventHandler.java
+++ b/payment/src/main/java/org/killbill/billing/payment/bus/PaymentBusEventHandler.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -19,8 +19,6 @@
package org.killbill.billing.payment.bus;
import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -31,16 +29,11 @@ import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.events.InvoiceCreationInternalEvent;
import org.killbill.billing.events.PaymentInternalEvent;
-import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.InvoicePaymentInternalApi;
import org.killbill.billing.payment.api.PaymentApiException;
-import org.killbill.billing.payment.api.PaymentTransaction;
+import org.killbill.billing.payment.api.PaymentOptions;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.payment.api.TransactionType;
-import org.killbill.billing.payment.core.PluginControlPaymentProcessor;
import org.killbill.billing.payment.core.janitor.Janitor;
-import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
-import org.killbill.billing.util.UUIDs;
-import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.UserType;
@@ -48,37 +41,32 @@ import org.killbill.billing.util.config.definition.PaymentConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
-import static org.killbill.billing.payment.logging.PaymentLoggingHelper.logEnterAPICall;
-import static org.killbill.billing.payment.logging.PaymentLoggingHelper.logExitAPICall;
-
public class PaymentBusEventHandler {
private static final Logger log = LoggerFactory.getLogger(PaymentBusEventHandler.class);
private final AccountInternalApi accountApi;
+ private final InvoicePaymentInternalApi invoicePaymentInternalApi;
private final InternalCallContextFactory internalCallContextFactory;
- private final PluginControlPaymentProcessor pluginControlPaymentProcessor;
private final PaymentConfig paymentConfig;
private final Janitor janitor;
@Inject
public PaymentBusEventHandler(final PaymentConfig paymentConfig,
final AccountInternalApi accountApi,
- final PluginControlPaymentProcessor pluginControlPaymentProcessor,
+ final InvoicePaymentInternalApi invoicePaymentInternalApi,
final Janitor janitor,
final InternalCallContextFactory internalCallContextFactory) {
this.paymentConfig = paymentConfig;
this.accountApi = accountApi;
+ this.invoicePaymentInternalApi = invoicePaymentInternalApi;
this.janitor = janitor;
this.internalCallContextFactory = internalCallContextFactory;
- this.pluginControlPaymentProcessor = pluginControlPaymentProcessor;
}
@AllowConcurrentEvents
@@ -92,40 +80,38 @@ public class PaymentBusEventHandler {
public void processInvoiceEvent(final InvoiceCreationInternalEvent event) {
log.info("Received invoice creation notification for accountId='{}', invoiceId='{}'", event.getAccountId(), event.getInvoiceId());
- final Collection<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty propertyInvoiceId = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, event.getInvoiceId().toString(), false);
- properties.add(propertyInvoiceId);
-
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(event.getSearchKey2(), event.getSearchKey1(), "PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
- final CallContext callContext = internalCallContextFactory.createCallContext(internalContext);
final BigDecimal amountToBePaid = null; // We let the plugin compute how much should be paid
final List<String> paymentControlPluginNames = paymentConfig.getPaymentControlPluginNames(internalContext) != null ? new LinkedList<String>(paymentConfig.getPaymentControlPluginNames(internalContext)) : new LinkedList<String>();
- paymentControlPluginNames.add(InvoicePaymentControlPluginApi.PLUGIN_NAME);
- final String transactionType = TransactionType.PURCHASE.name();
- Account account = null;
- Payment payment = null;
- PaymentTransaction paymentTransaction = null;
+ final Account account;
try {
account = accountApi.getAccountById(event.getAccountId(), internalContext);
- logEnterAPICall(log,
- transactionType,
- account,
- account.getPaymentMethodId(),
- null,
- null,
- amountToBePaid,
- account.getCurrency(),
- null,
- null,
- null,
- paymentControlPluginNames);
-
- payment = pluginControlPaymentProcessor.createPurchase(false, account, account.getPaymentMethodId(), null, amountToBePaid, account.getCurrency(), null, null, null, properties, paymentControlPluginNames, callContext, internalContext);
-
- paymentTransaction = payment.getTransactions().get(payment.getTransactions().size() - 1);
+ invoicePaymentInternalApi.createPurchaseForInvoicePayment(false,
+ account,
+ event.getInvoiceId(),
+ account.getPaymentMethodId(),
+ null,
+ amountToBePaid,
+ account.getCurrency(),
+ null,
+ null,
+ null,
+ ImmutableList.<PluginProperty>of(),
+ new PaymentOptions() {
+ @Override
+ public boolean isExternalPayment() {
+ return false;
+ }
+
+ @Override
+ public List<String> getPaymentControlPluginNames() {
+ return paymentControlPluginNames;
+ }
+ },
+ internalContext);
} catch (final AccountApiException e) {
log.warn("Failed to process invoice payment", e);
} catch (final PaymentApiException e) {
@@ -133,20 +119,6 @@ public class PaymentBusEventHandler {
if (e.getCode() != ErrorCode.PAYMENT_PLUGIN_API_ABORTED.getCode()) {
log.warn("Failed to process invoice payment {}", e.toString());
}
- } finally {
- logExitAPICall(log,
- transactionType,
- account,
- payment != null ? payment.getPaymentMethodId() : null,
- payment != null ? payment.getId() : null,
- paymentTransaction != null ? paymentTransaction.getId() : null,
- paymentTransaction != null ? paymentTransaction.getProcessedAmount() : null,
- paymentTransaction != null ? paymentTransaction.getProcessedCurrency() : null,
- payment != null ? payment.getExternalKey() : null,
- paymentTransaction != null ? paymentTransaction.getExternalKey() : null,
- paymentTransaction != null ? paymentTransaction.getTransactionStatus() : null,
- paymentControlPluginNames,
- null);
}
}
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index ecaa6d8..e3bfbfa 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -435,12 +435,22 @@ public class PaymentProcessor extends ProcessorBase {
public Payment getPaymentByTransactionId(final UUID transactionId, final boolean withPluginInfo, final boolean withAttempts, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
final PaymentTransactionModelDao paymentTransactionDao = paymentDao.getPaymentTransaction(transactionId, internalTenantContext);
if (null != paymentTransactionDao) {
- PaymentModelDao paymentModelDao = paymentDao.getPayment(paymentTransactionDao.getPaymentId(), internalTenantContext);
+ final PaymentModelDao paymentModelDao = paymentDao.getPayment(paymentTransactionDao.getPaymentId(), internalTenantContext);
return toPayment(paymentModelDao, withPluginInfo, withAttempts, properties, tenantContext, internalTenantContext);
}
return null;
}
+ public Payment getPaymentByTransactionExternalKey(final String transactionExternalKey, final boolean withPluginInfo, final boolean withAttempts, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+ final List<PaymentTransactionModelDao> paymentTransactionDao = paymentDao.getPaymentTransactionsByExternalKey(transactionExternalKey, internalTenantContext);
+ if (paymentTransactionDao.isEmpty()) {
+ return null;
+ }
+ // All transactions must be on the same payment (see sanity in buildPaymentStateContext)
+ final PaymentModelDao paymentModelDao = paymentDao.getPayment(paymentTransactionDao.get(0).getPaymentId(), internalTenantContext);
+ return toPayment(paymentModelDao, withPluginInfo, withAttempts, properties, tenantContext, internalTenantContext);
+ }
+
private Payment performOperation(final boolean isApiPayment,
@Nullable final UUID attemptId,
final TransactionType transactionType,
diff --git a/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java b/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
index 7586a8b..d9d06b0 100644
--- a/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2014 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -23,14 +23,19 @@ import javax.inject.Provider;
import org.killbill.automaton.DefaultStateMachineConfig;
import org.killbill.automaton.StateMachineConfig;
import org.killbill.billing.control.plugin.api.PaymentControlPluginApi;
+import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.AdminPaymentApi;
import org.killbill.billing.payment.api.DefaultAdminPaymentApi;
+import org.killbill.billing.payment.api.DefaultInvoicePaymentApi;
import org.killbill.billing.payment.api.DefaultPaymentApi;
import org.killbill.billing.payment.api.DefaultPaymentGatewayApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
+import org.killbill.billing.payment.api.InvoicePaymentInternalApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentGatewayApi;
import org.killbill.billing.payment.api.PaymentService;
+import org.killbill.billing.payment.api.svcs.DefaultInvoicePaymentInternalApi;
import org.killbill.billing.payment.bus.PaymentBusEventHandler;
import org.killbill.billing.payment.config.MultiTenantPaymentConfig;
import org.killbill.billing.payment.caching.EhCacheStateMachineConfigCache;
@@ -151,6 +156,8 @@ public class PaymentModule extends KillBillModule {
bind(PaymentPluginServiceRegistration.class).asEagerSingleton();
bind(PaymentApi.class).to(DefaultPaymentApi.class).asEagerSingleton();
+ bind(InvoicePaymentApi.class).to(DefaultInvoicePaymentApi.class).asEagerSingleton();
+ bind(InvoicePaymentInternalApi.class).to(DefaultInvoicePaymentInternalApi.class).asEagerSingleton();
bind(PaymentGatewayApi.class).to(DefaultPaymentGatewayApi.class).asEagerSingleton();
bind(AdminPaymentApi.class).to(DefaultAdminPaymentApi.class).asEagerSingleton();
bind(PaymentBusEventHandler.class).asEagerSingleton();
diff --git a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
index d87a2f0..ecb7dd2 100644
--- a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -88,12 +88,12 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
public static final String CREATED_BY = "InvoicePaymentControlPluginApi";
- /* Don't change value String for properties as they are referenced from jaxrs without the constants which are not accessible */
public static final String PLUGIN_NAME = "__INVOICE_PAYMENT_CONTROL_PLUGIN__";
- public static final String PROP_IPCD_INVOICE_ID = "IPCD_INVOICE_ID";
- public static final String PROP_IPCD_REFUND_IDS_WITH_AMOUNT_KEY = "IPCD_REFUND_IDS_AMOUNTS";
- public static final String PROP_IPCD_REFUND_WITH_ADJUSTMENTS = "IPCD_REFUND_WITH_ADJUSTMENTS";
- public static final String PROP_IPCD_PAYMENT_ID = "IPCD_PAYMENT_ID";
+
+ private static final String PROP_IPCD_INVOICE_ID = "IPCD_INVOICE_ID";
+ private static final String PROP_IPCD_REFUND_IDS_WITH_AMOUNT_KEY = "IPCD_REFUND_IDS_AMOUNTS";
+ private static final String PROP_IPCD_REFUND_WITH_ADJUSTMENTS = "IPCD_REFUND_WITH_ADJUSTMENTS";
+ private static final String PROP_IPCD_PAYMENT_ID = "IPCD_PAYMENT_ID";
private final PaymentConfig paymentConfig;
private final InvoiceInternalApi invoiceApi;
@@ -198,7 +198,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
case REFUND:
final Map<UUID, BigDecimal> idWithAmount = extractIdsWithAmountFromProperties(pluginProperties);
final PluginProperty prop = getPluginProperty(pluginProperties, PROP_IPCD_REFUND_WITH_ADJUSTMENTS);
- final boolean isAdjusted = prop != null ? Boolean.valueOf((String) prop.getValue()) : false;
+ final boolean isAdjusted = prop != null && prop.getValue() != null ? Boolean.valueOf(prop.getValue().toString()) : false;
invoiceApi.recordRefund(paymentControlContext.getPaymentId(), paymentControlContext.getAmount(), isAdjusted, idWithAmount, paymentControlContext.getTransactionExternalKey(), internalContext);
break;
@@ -230,7 +230,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
case CREDIT:
final Map<UUID, BigDecimal> idWithAmountMap = extractIdsWithAmountFromProperties(pluginProperties);
final PluginProperty properties = getPluginProperty(pluginProperties, PROP_IPCD_REFUND_WITH_ADJUSTMENTS);
- final boolean isInvoiceAdjusted = properties != null ? Boolean.valueOf((String) properties.getValue()) : false;
+ final boolean isInvoiceAdjusted = properties != null && properties.getValue() != null ? Boolean.valueOf(properties.getValue().toString()) : false;
final PluginProperty legacyPayment = getPluginProperty(pluginProperties, PROP_IPCD_PAYMENT_ID);
final UUID paymentId = legacyPayment != null ? (UUID) legacyPayment.getValue() : paymentControlContext.getPaymentId();
@@ -416,7 +416,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
}
final PluginProperty prop = getPluginProperty(pluginProperties, PROP_IPCD_REFUND_WITH_ADJUSTMENTS);
- final boolean isAdjusted = prop != null ? Boolean.valueOf((String) prop.getValue()) : false;
+ final boolean isAdjusted = prop != null && prop.getValue() != null ? Boolean.valueOf(prop.getValue().toString()) : false;
if (isAdjusted) {
try {
invoiceApi.validateInvoiceItemAdjustments(paymentControlPluginContext.getPaymentId(), idWithAmount, internalContext);
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index 5d45b6c..ec94497 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -26,10 +26,8 @@ import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
import org.joda.time.LocalDate;
-import org.joda.time.LocalDate.Property;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.catalog.api.Currency;
@@ -868,9 +866,19 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
requestedAmount,
new BigDecimal("1.0"),
Currency.USD));
- final Payment payment = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
-
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
assertEquals(payment.getExternalKey(), paymentExternalKey);
assertEquals(payment.getPaymentMethodId(), account.getPaymentMethodId());
assertEquals(payment.getAccountId(), account.getId());
@@ -899,7 +907,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
}
@Test(groups = "slow")
- public void testCreatePurchaseWithExternalKeyOverLimit() throws PaymentApiException, InvoiceApiException, EventBusException {
+ public void testCreatePurchaseWithExternalKeyOverLimit() throws InvoiceApiException, EventBusException {
final BigDecimal requestedAmount = BigDecimal.TEN;
final LocalDate now = clock.getUTCToday();
@@ -909,13 +917,22 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
final String transactionExternalKey = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,.";
try {
- paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
Assert.fail();
} catch (final PaymentApiException e) {
assertEquals(e.getCode(), ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED.getCode());
}
-
}
@Test(groups = "slow")
@@ -943,8 +960,18 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
new BigDecimal("1.0"),
Currency.USD));
try {
- paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
} catch (final PaymentApiException expected) {
assertTrue(true);
}
@@ -1000,8 +1027,18 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
new BigDecimal("1.0"),
Currency.USD));
try {
- paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
} catch (final PaymentApiException expected) {
assertTrue(true);
}
@@ -1031,9 +1068,18 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
assertEquals(payment.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
// Make sure we can retry and that works
- paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
-
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
final List<Payment> accountPayments2 = paymentApi.getAccountPayments(account.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
assertEquals(accountPayments2.size(), 1);
@@ -1075,8 +1121,18 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
Currency.USD));
try {
- paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
Assert.fail("Unexpected success");
} catch (final PaymentApiException e) {
}
@@ -1107,8 +1163,19 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
Currency.USD);
invoice.addInvoiceItem(invoiceItem);
- final Payment payment = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
final List<PluginProperty> refundProperties = ImmutableList.<PluginProperty>of();
final Payment payment2 = paymentApi.createRefundWithPaymentControl(account, payment.getId(), requestedAmount, Currency.USD, null, transactionExternalKey2,
@@ -1150,8 +1217,19 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
Currency.USD);
invoice.addInvoiceItem(invoiceItem);
- final Payment payment = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
final List<PluginProperty> refundProperties = ImmutableList.<PluginProperty>of();
@@ -1188,17 +1266,27 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
Currency.USD);
invoice.addInvoiceItem(invoiceItem);
- final Payment payment = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
final List<PluginProperty> refundProperties = new ArrayList<PluginProperty>();
final HashMap<UUID, BigDecimal> uuidBigDecimalHashMap = new HashMap<UUID, BigDecimal>();
uuidBigDecimalHashMap.put(invoiceItem.getId(), null);
- final PluginProperty refundIdsProp = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_IDS_WITH_AMOUNT_KEY, uuidBigDecimalHashMap, false);
- refundProperties.add(refundIdsProp);
- final Payment payment2 = paymentApi.createRefundWithPaymentControl(account, payment.getId(), null, Currency.USD, null, transactionExternalKey2,
- refundProperties, INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createRefundForInvoicePayment(true, uuidBigDecimalHashMap, account, payment.getId(), null, Currency.USD, null, transactionExternalKey2,
+ refundProperties, INVOICE_PAYMENT, callContext);
+ final Payment payment2 = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
assertEquals(payment2.getTransactions().size(), 2);
assertEquals(payment2.getExternalKey(), paymentExternalKey);
@@ -2576,12 +2664,6 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
}
}
- private List<PluginProperty> createPropertiesForInvoice(final Invoice invoice) {
- final List<PluginProperty> result = new ArrayList<PluginProperty>();
- result.add(new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false));
- return result;
- }
-
// Search by a key supported by the search in MockPaymentProviderPlugin
private void checkPaymentMethodPagination(final UUID paymentMethodId, final Long maxNbRecords, final boolean deleted) throws PaymentApiException {
final Pagination<PaymentMethod> foundPaymentMethods = paymentApi.searchPaymentMethods(paymentMethodId.toString(), 0L, maxNbRecords + 1, false, ImmutableList.<PluginProperty>of(), callContext);
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
index 2b41c96..6a83d74 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -19,7 +19,6 @@
package org.killbill.billing.payment.api;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -29,16 +28,14 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.payment.MockRecurringInvoiceItem;
import org.killbill.billing.payment.PaymentTestSuiteNoDB;
-import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
import org.killbill.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
-import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
-import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import static org.testng.Assert.assertEquals;
@@ -49,17 +46,6 @@ import static org.testng.Assert.fail;
public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
private static final Logger log = LoggerFactory.getLogger(TestPaymentApiNoDB.class);
- private static final PaymentOptions PAYMENT_OPTIONS = new PaymentOptions() {
- @Override
- public boolean isExternalPayment() {
- return false;
- }
-
- @Override
- public List<String> getPaymentControlPluginNames() {
- return ImmutableList.<String>of(InvoicePaymentControlPluginApi.PLUGIN_NAME);
- }
- };
private final Iterable<PluginProperty> PLUGIN_PROPERTIES = ImmutableList.<PluginProperty>of();
private Account account;
@@ -86,7 +72,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
@Test(groups = "fast")
public void testSimpleInvoicePaymentWithNoAmount() throws Exception {
- final BigDecimal invoiceAmount = new BigDecimal("10.0011");
+ final BigDecimal invoiceAmount = new BigDecimal("10");
final BigDecimal requestedAmount = null;
final BigDecimal expectedAmount = null;
@@ -138,22 +124,28 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
Currency.USD));
try {
-
- final List<PluginProperty> properties = new ArrayList<PluginProperty>();
- final PluginProperty prop1 = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false);
- properties.add(prop1);
-
- final Payment paymentInfo = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(), null,
- invoice.getId().toString(), UUID.randomUUID().toString(), properties, PAYMENT_OPTIONS, callContext);
- if (expectedAmount == null) {
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ account.getCurrency(),
+ null,
+ invoice.getId().toString(),
+ UUID.randomUUID().toString(),
+ ImmutableList.<PluginProperty>of(),
+ PAYMENT_OPTIONS,
+ callContext);
+ final Payment paymentInfo = paymentApi.getPaymentByExternalKey(invoice.getId().toString(), false, false, ImmutableList.<PluginProperty>of(), callContext);
+ if (requestedAmount != null && expectedAmount == null) {
fail("Expected to fail because requested amount > invoice amount");
}
assertNotNull(paymentInfo.getId());
- assertTrue(paymentInfo.getPurchasedAmount().compareTo(expectedAmount) == 0);
+ assertTrue(paymentInfo.getPurchasedAmount().compareTo(MoreObjects.firstNonNull(expectedAmount, invoiceAmount)) == 0);
assertNotNull(paymentInfo.getPaymentNumber());
assertEquals(paymentInfo.getExternalKey(), invoice.getId().toString());
assertEquals(paymentInfo.getCurrency(), Currency.USD);
- assertTrue(paymentInfo.getTransactions().get(0).getAmount().compareTo(expectedAmount) == 0);
+ assertTrue(paymentInfo.getTransactions().get(0).getAmount().compareTo(MoreObjects.firstNonNull(expectedAmount, invoiceAmount)) == 0);
assertEquals(paymentInfo.getTransactions().get(0).getCurrency(), Currency.USD);
assertEquals(paymentInfo.getTransactions().get(0).getPaymentId(), paymentInfo.getId());
assertEquals(paymentInfo.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
index c429872..ed3df88 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -18,14 +18,19 @@
package org.killbill.billing.payment;
+import java.util.List;
+
import javax.inject.Named;
import org.killbill.billing.GuicyKillbillTestSuiteNoDB;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
+import org.killbill.billing.payment.api.InvoicePaymentInternalApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentGatewayApi;
+import org.killbill.billing.payment.api.PaymentOptions;
import org.killbill.billing.payment.caching.StateMachineConfigCache;
import org.killbill.billing.payment.core.PaymentExecutors;
import org.killbill.billing.payment.core.PaymentMethodProcessor;
@@ -52,6 +57,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -76,6 +82,10 @@ public abstract class PaymentTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
@Inject
protected PaymentApi paymentApi;
@Inject
+ protected InvoicePaymentApi invoicePaymentApi;
+ @Inject
+ protected InvoicePaymentInternalApi invoicePaymentInternalApi;
+ @Inject
protected PaymentGatewayApi paymentGatewayApi;
@Inject
protected AccountInternalApi accountInternalApi;
@@ -105,6 +115,18 @@ public abstract class PaymentTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
@Inject
protected TenantInternalApi tenantInternalApi;
+ protected static final PaymentOptions PAYMENT_OPTIONS = new PaymentOptions() {
+ @Override
+ public boolean isExternalPayment() {
+ return false;
+ }
+
+ @Override
+ public List<String> getPaymentControlPluginNames() {
+ return ImmutableList.<String>of();
+ }
+ };
+
@Override
protected KillbillConfigSource getConfigSource() {
return getConfigSource("/payment.properties",
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
index 61dca40..82ee233 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -24,6 +24,7 @@ import org.killbill.billing.control.plugin.api.PaymentControlPluginApi;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.AdminPaymentApi;
+import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentGatewayApi;
import org.killbill.billing.payment.caching.StateMachineConfigCache;
@@ -82,6 +83,8 @@ public abstract class PaymentTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
@Inject
protected PaymentApi paymentApi;
@Inject
+ protected InvoicePaymentApi invoicePaymentApi;
+ @Inject
protected AdminPaymentApi adminPaymentApi;
@Inject
protected PaymentGatewayApi paymentGatewayApi;
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java b/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
index 704250d..7a9a1e1 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
@@ -47,7 +46,6 @@ import org.killbill.billing.payment.api.TransactionType;
import org.killbill.billing.payment.bus.PaymentBusEventHandler;
import org.killbill.billing.payment.core.janitor.Janitor;
import org.killbill.billing.payment.dao.PaymentAttemptModelDao;
-import org.killbill.billing.payment.dao.PaymentModelDao;
import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
import org.killbill.billing.payment.glue.DefaultPaymentService;
import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
@@ -68,8 +66,6 @@ import org.killbill.notificationq.api.NotificationEventWithMetadata;
import org.killbill.notificationq.api.NotificationQueueService;
import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
import org.skife.config.TimeSpan;
-import org.skife.jdbi.v2.Handle;
-import org.skife.jdbi.v2.tweak.HandleCallback;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
@@ -157,6 +153,10 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
@AfterMethod(groups = "slow")
public void afterMethod() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
+
retryService.stop();
eventBus.unregister(handler);
@@ -191,8 +191,19 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
Currency.USD));
testListener.pushExpectedEvent(NextEvent.PAYMENT);
- final Payment payment = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
testListener.assertListenerStatus();
assertEquals(payment.getTransactions().size(), 1);
assertEquals(payment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
@@ -247,19 +258,29 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
invoice.addInvoiceItem(invoiceItem);
testListener.pushExpectedEvent(NextEvent.PAYMENT);
- final Payment payment = paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createPurchaseForInvoicePayment(account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ requestedAmount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ ImmutableList.<PluginProperty>of(),
+ INVOICE_PAYMENT,
+ callContext);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
testListener.assertListenerStatus();
final List<PluginProperty> refundProperties = new ArrayList<PluginProperty>();
final HashMap<UUID, BigDecimal> uuidBigDecimalHashMap = new HashMap<UUID, BigDecimal>();
uuidBigDecimalHashMap.put(invoiceItem.getId(), new BigDecimal("1.0"));
- final PluginProperty refundIdsProp = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_REFUND_IDS_WITH_AMOUNT_KEY, uuidBigDecimalHashMap, false);
- refundProperties.add(refundIdsProp);
testListener.pushExpectedEvent(NextEvent.PAYMENT);
- final Payment payment2 = paymentApi.createRefundWithPaymentControl(account, payment.getId(), null, Currency.USD, null, transactionExternalKey2,
- refundProperties, INVOICE_PAYMENT, callContext);
+ invoicePaymentApi.createRefundForInvoicePayment(false, uuidBigDecimalHashMap, account, payment.getId(), null, Currency.USD, null, transactionExternalKey2,
+ refundProperties, INVOICE_PAYMENT, callContext);
+ final Payment payment2 = paymentApi.getPayment(payment.getId(), false, false, refundProperties, callContext);
testListener.assertListenerStatus();
assertEquals(payment2.getTransactions().size(), 2);
@@ -527,12 +548,6 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
});
}
- private List<PluginProperty> createPropertiesForInvoice(final Invoice invoice) {
- final List<PluginProperty> result = new ArrayList<PluginProperty>();
- result.add(new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false));
- return result;
- }
-
private void assertNotificationsCompleted(final InternalCallContext internalCallContext, final long timeoutSec) {
try {
await().atMost(timeoutSec, SECONDS).until(new Callable<Boolean>() {
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java b/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java
index 5114550..0ecd4e3 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java
@@ -30,6 +30,7 @@ import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.account.api.ImmutableAccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.callcontext.MutableCallContext;
import org.killbill.billing.callcontext.MutableInternalCallContext;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.events.InvoiceCreationInternalEvent;
@@ -148,14 +149,16 @@ public class TestPaymentHelper {
Mockito.when(accountData.getCreatedDate()).thenReturn(clock.getUTCNow());
Mockito.when(accountData.getReferenceTime()).thenReturn(clock.getUTCNow());
+ final MutableCallContext mutableCallContext = new MutableCallContext(internalCallContext);
+
Account account;
if (isFastTest()) {
- account = GuicyKillbillTestSuiteNoDB.createMockAccount(accountData, accountApi, accountInternalApi, immutableAccountInternalApi, nonEntityDao, clock, internalCallContextFactory, context, internalCallContext);
+ account = GuicyKillbillTestSuiteNoDB.createMockAccount(accountData, accountApi, accountInternalApi, immutableAccountInternalApi, nonEntityDao, clock, internalCallContextFactory, mutableCallContext, internalCallContext);
} else {
account = accountApi.createAccount(accountData, context);
}
- GuicyKillbillTestSuite.refreshCallContext(account.getId(), clock, internalCallContextFactory, context, internalCallContext);
+ GuicyKillbillTestSuite.refreshCallContext(account.getId(), clock, internalCallContextFactory, mutableCallContext, internalCallContext);
if (addPaymentMethod) {
final PaymentMethodPlugin pm = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java b/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java
index 5d3ae1a..d1da4a7 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -19,7 +19,6 @@
package org.killbill.billing.payment;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -36,7 +35,6 @@ import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.dao.PaymentAttemptModelDao;
import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
-import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
@@ -55,6 +53,7 @@ import static org.testng.Assert.assertTrue;
public class TestRetryService extends PaymentTestSuiteNoDB {
private static final int TIMEOUT = 10;
+ private static final ImmutableList<PluginProperty> NO_PROPERTIES = ImmutableList.<PluginProperty>of();
private MockPaymentProviderPlugin mockPaymentProviderPlugin;
@@ -119,8 +118,19 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
final String paymentExternalKey = UUID.randomUUID().toString();
final String transactionExternalKey = UUID.randomUUID().toString();
try {
- pluginControlPaymentProcessor.createPurchase(false, account, account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), ImmutableList.<String>of(InvoicePaymentControlPluginApi.PLUGIN_NAME), callContext, internalCallContext);
+ invoicePaymentInternalApi.createPurchaseForInvoicePayment(false,
+ account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ amount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ NO_PROPERTIES,
+ PAYMENT_OPTIONS,
+ internalCallContext);
} catch (final PaymentApiException e) {
failed = true;
}
@@ -164,8 +174,19 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
final String paymentExternalKey = UUID.randomUUID().toString();
final String transactionExternalKey = UUID.randomUUID().toString();
- pluginControlPaymentProcessor.createPurchase(false, account, account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), ImmutableList.<String>of(InvoicePaymentControlPluginApi.PLUGIN_NAME), callContext, internalCallContext);
+ invoicePaymentInternalApi.createPurchaseForInvoicePayment(false,
+ account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ amount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ NO_PROPERTIES,
+ PAYMENT_OPTIONS,
+ internalCallContext);
Payment payment = getPaymentForExternalKey(paymentExternalKey);
List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
@@ -237,8 +258,19 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
final String paymentExternalKey = UUID.randomUUID().toString();
final String transactionExternalKey = UUID.randomUUID().toString();
- pluginControlPaymentProcessor.createPurchase(false, account, account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), ImmutableList.<String>of(InvoicePaymentControlPluginApi.PLUGIN_NAME), callContext, internalCallContext);
+ invoicePaymentInternalApi.createPurchaseForInvoicePayment(false,
+ account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ amount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ NO_PROPERTIES,
+ PAYMENT_OPTIONS,
+ internalCallContext);
Payment payment = getPaymentForExternalKey(paymentExternalKey);
List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
@@ -320,8 +352,19 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
final String paymentExternalKey = UUID.randomUUID().toString();
final String transactionExternalKey = UUID.randomUUID().toString();
- pluginControlPaymentProcessor.createPurchase(false, account, account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey,
- createPropertiesForInvoice(invoice), ImmutableList.<String>of(InvoicePaymentControlPluginApi.PLUGIN_NAME), callContext, internalCallContext);
+ invoicePaymentInternalApi.createPurchaseForInvoicePayment(false,
+ account,
+ invoice.getId(),
+ account.getPaymentMethodId(),
+ null,
+ amount,
+ Currency.USD,
+ null,
+ paymentExternalKey,
+ transactionExternalKey,
+ NO_PROPERTIES,
+ PAYMENT_OPTIONS,
+ internalCallContext);
Payment payment = getPaymentForExternalKey(paymentExternalKey);
List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
@@ -393,20 +436,6 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
clock.addDays(nbDays);
}
- private int getMaxRetrySizeForFailureType(final FailureType failureType) {
- if (failureType == FailureType.PAYMENT_FAILURE) {
- return paymentConfig.getPaymentFailureRetryDays(internalCallContext).size();
- } else {
- return 0;
- }
- }
-
- private List<PluginProperty> createPropertiesForInvoice(final Invoice invoice) {
- final List<PluginProperty> result = new ArrayList<PluginProperty>();
- result.add(new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false));
- return result;
- }
-
private enum FailureType {
PLUGIN_EXCEPTION,
PAYMENT_FAILURE
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 2abb443..5329355 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.141.76</version>
+ <version>0.141.83</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.19.17-SNAPSHOT</version>
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/DefaultHealthcheckPluginRegistry.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/DefaultHealthcheckPluginRegistry.java
new file mode 100644
index 0000000..a56baf9
--- /dev/null
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/DefaultHealthcheckPluginRegistry.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.server.modules;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.killbill.billing.osgi.api.Healthcheck;
+import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultHealthcheckPluginRegistry implements OSGIServiceRegistration<Healthcheck> {
+
+ private static final Logger log = LoggerFactory.getLogger(DefaultHealthcheckPluginRegistry.class);
+
+ private final Map<String, Healthcheck> pluginsByName = new ConcurrentHashMap<String, Healthcheck>();
+
+ @Override
+ public void registerService(final OSGIServiceDescriptor desc, final Healthcheck healthcheck) {
+ log.info("Registering service='{}'", desc.getRegistrationName());
+ pluginsByName.put(desc.getRegistrationName(), healthcheck);
+ }
+
+ @Override
+ public void unregisterService(final String serviceName) {
+ log.info("Unregistering service='{}'", serviceName);
+ pluginsByName.remove(serviceName);
+ }
+
+ @Override
+ public Healthcheck getServiceForName(final String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Null healthcheck name");
+ }
+ return pluginsByName.get(name);
+ }
+
+ @Override
+ public Set<String> getAllServices() {
+ return pluginsByName.keySet();
+ }
+
+ @Override
+ public Class<Healthcheck> getServiceType() {
+ return Healthcheck.class;
+ }
+}
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index 5d43a8f..f43a948 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -54,6 +54,8 @@ import org.killbill.billing.jaxrs.resources.TransactionResource;
import org.killbill.billing.jaxrs.resources.UsageResource;
import org.killbill.billing.jaxrs.util.KillbillEventHandler;
import org.killbill.billing.junction.glue.DefaultJunctionModule;
+import org.killbill.billing.osgi.api.Healthcheck;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.overdue.glue.DefaultOverdueModule;
import org.killbill.billing.payment.glue.PaymentModule;
import org.killbill.billing.platform.api.KillbillConfigSource;
@@ -94,6 +96,7 @@ import org.skife.jdbi.v2.ResultSetMapperFactory;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
import ch.qos.logback.classic.helpers.MDCInsertingServletFilter;
+import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.name.Names;
@@ -114,6 +117,8 @@ public class KillbillServerModule extends KillbillPlatformModule {
configureResources();
configureFilters();
configurePushNotification();
+
+ bind(new TypeLiteral<OSGIServiceRegistration<Healthcheck>>() {}).to(DefaultHealthcheckPluginRegistry.class).asEagerSingleton();
}
@Override
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestSecurity.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestSecurity.java
index e9bd390..0405446 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestSecurity.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestSecurity.java
@@ -171,7 +171,7 @@ public class TestSecurity extends TestJaxrsBase {
securityApi.updateUserRoles(username, new UserRoles(username, null, ImmutableList.of(newRoleDefinition)), requestOptions);
permissions = securityApi.getCurrentUserPermissions(requestOptions);
// This will only work if correct shiro cache invalidation was performed... requires lots of sweat to get it to work ;-)
- Assert.assertEquals(permissions.size(), 2);
+ Assert.assertEquals(permissions.size(), 1);
securityApi.invalidateUser(username, requestOptions);
try {
README.md 24(+8 -16)
diff --git a/README.md b/README.md
index 3ffcee9..378d98d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,10 @@
-## Kill Bill
+<p align="center">
+ <img src="https://github.com/killbill/killbill-docs/raw/v3-0.19/userguide/assets/img/logo.png" alt="Kill Bill logo" style="max-width:100%;">
+</p>
-Kill Bill is the Open-Source Billing & Payment Platform.
+# Kill Bill
+
+Kill Bill is the open-source subscription billing and payments platform.
## Among features
@@ -13,20 +17,8 @@ You can find more information on [killbill.io](http://killbill.io).
## Getting started
-* [Tutorials](http://killbill.io/tutorials/)
-* [User guides](http://killbill.io/userguide/) (source in the [killbill-docs](https://github.com/killbill/killbill-docs) repo)
-* [Wiki](https://github.com/killbill/killbill/wiki)
-
-## Build
-
-Build is handled by Maven:
-
-```
-mvn clean install -DskipTests=true
-```
-
-Note: some third-party artifacts (such as metrics-guice) are released in Bintray. Make sure to follow the instructions [here](https://bintray.com/bintray/jcenter) (Set me up! button) to update your settings.xml.
+All of our documentation can be found at [docs.killbill.io](http://docs.killbill.io) (sources in the [killbill/killbill-docs](https://github.com/killbill/killbill-docs) repository).
## License
-Kill Bill is released under the [Apache license](http://www.apache.org/licenses/LICENSE-2.0).
+Kill Bill is released under the [Apache license 2.0](http://www.apache.org/licenses/LICENSE-2.0).
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java
index 79774ef..c7ef770 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java
@@ -38,6 +38,7 @@ import org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.subscription.api.svcs.DefaultSubscriptionInternalApi;
@@ -132,12 +133,13 @@ public class SubscriptionApiBase {
final DateTime utcNow = clock.getUTCNow();
List<SubscriptionBaseEvent> dryRunEvents = null;
- final PlanPhaseSpecifier inputSpec = dryRunArguments.getPlanPhaseSpecifier();
+ final EntitlementSpecifier entitlementSpecifier = dryRunArguments.getEntitlementSpecifier();
+ final PlanPhaseSpecifier inputSpec = entitlementSpecifier.getPlanPhaseSpecifier();
final boolean isInputSpecNullOrEmpty = inputSpec == null ||
(inputSpec.getPlanName() == null && inputSpec.getProductName() == null && inputSpec.getBillingPeriod() == null);
// Create an overridesWithContext with a null context to indicate this is dryRun and no price overridden plan should be created.
- final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(dryRunArguments.getPlanPhasePriceOverrides(), null);
+ final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(entitlementSpecifier.getOverrides(), null);
final Plan plan = isInputSpecNullOrEmpty ?
null :
catalog.createOrFindPlan(inputSpec, overridesWithContext, utcNow);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
index a877800..6bcfbc2 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
@@ -33,6 +33,7 @@ import org.killbill.billing.catalog.api.PlanChangeResult;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
@@ -61,20 +62,20 @@ public interface SubscriptionBaseApiService {
throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime dryRunChangePlan(DefaultSubscriptionBase subscription, PlanPhaseSpecifier spec, DateTime requestedDate, BillingActionPolicy policy, TenantContext context) throws SubscriptionBaseApiException;
+ public DateTime dryRunChangePlan(DefaultSubscriptionBase subscription, EntitlementSpecifier spec, DateTime requestedDate, BillingActionPolicy policy, TenantContext context) throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime changePlan(DefaultSubscriptionBase subscription, PlanPhaseSpecifier spec, List<PlanPhasePriceOverride> overrides, CallContext context)
+ public DateTime changePlan(DefaultSubscriptionBase subscription, EntitlementSpecifier spec, CallContext context)
throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime changePlanWithRequestedDate(DefaultSubscriptionBase subscription, PlanPhaseSpecifier spec,
- List<PlanPhasePriceOverride> overrides, DateTime requestedDate, CallContext context)
+ public DateTime changePlanWithRequestedDate(DefaultSubscriptionBase subscription, EntitlementSpecifier spec,
+ DateTime requestedDate, CallContext context)
throws SubscriptionBaseApiException;
// Return the effective date of the change
- public DateTime changePlanWithPolicy(DefaultSubscriptionBase subscription, PlanPhaseSpecifier spec,
- List<PlanPhasePriceOverride> overrides, BillingActionPolicy policy, CallContext context)
+ public DateTime changePlanWithPolicy(DefaultSubscriptionBase subscription, EntitlementSpecifier spec,
+ BillingActionPolicy policy, CallContext context)
throws SubscriptionBaseApiException;
public int handleBasePlanEvent(final DefaultSubscriptionBase subscription, final SubscriptionBaseEvent event, Catalog fullCatalog, final CallContext context) throws CatalogApiException;
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index dfdb63e..317f272 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -48,6 +48,7 @@ import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun.DryRunChangeReason;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.api.SubscriptionBase;
@@ -360,10 +361,9 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
@Override
public DateTime getDryRunChangePlanEffectiveDate(final SubscriptionBase subscription,
- final PlanPhaseSpecifier spec,
+ final EntitlementSpecifier spec,
final DateTime requestedDateWithMs,
final BillingActionPolicy requestedPolicy,
- final List<PlanPhasePriceOverride> overrides,
final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
final CallContext callContext = internalCallContextFactory.createCallContext(context);
@@ -372,8 +372,8 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : null;
final DateTime effectiveCatalogDate = effectiveDate != null ? effectiveDate : context.getCreatedDate();
- final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, callContext);
- final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveCatalogDate, subscription.getStartDate());
+ final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(spec.getOverrides(), callContext);
+ final Plan plan = catalog.createOrFindPlan(spec.getPlanPhaseSpecifier(), overridesWithContext, effectiveCatalogDate, subscription.getStartDate());
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
if (plan.getPlansAllowedInBundle() != -1
&& plan.getPlansAllowedInBundle() > 0
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
index 762437d..da5ae17 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
@@ -40,14 +40,13 @@ import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
-import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementSourceType;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entity.EntityBase;
-import org.killbill.billing.payment.api.TransactionType;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseApiService;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
@@ -203,7 +202,6 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
}
}
-
@Override
public Plan getCurrentPlan() {
return (getPreviousTransition() == null) ? null
@@ -275,9 +273,9 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
}
@Override
- public DateTime changePlan(final PlanPhaseSpecifier spec,
- final List<PlanPhasePriceOverride> overrides, final CallContext context) throws SubscriptionBaseApiException {
- return apiService.changePlan(this, spec, overrides, context);
+ public DateTime changePlan(final EntitlementSpecifier spec,
+ final CallContext context) throws SubscriptionBaseApiException {
+ return apiService.changePlan(this, spec, context);
}
@Override
@@ -286,15 +284,15 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
}
@Override
- public DateTime changePlanWithDate(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides,
+ public DateTime changePlanWithDate(final EntitlementSpecifier spec,
final DateTime requestedDate, final CallContext context) throws SubscriptionBaseApiException {
- return apiService.changePlanWithRequestedDate(this, spec, overrides, requestedDate, context);
+ return apiService.changePlanWithRequestedDate(this, spec, requestedDate, context);
}
@Override
- public DateTime changePlanWithPolicy(final PlanPhaseSpecifier spec,
- final List<PlanPhasePriceOverride> overrides, final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
- return apiService.changePlanWithPolicy(this, spec, overrides, policy, context);
+ public DateTime changePlanWithPolicy(final EntitlementSpecifier spec,
+ final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
+ return apiService.changePlanWithPolicy(this, spec, policy, context);
}
@Override
@@ -579,7 +577,6 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
return getFutureEndDate() != null;
}
-
public boolean isPendingChangePlan() {
final SubscriptionBaseTransitionDataIterator it = new SubscriptionBaseTransitionDataIterator(
@@ -595,8 +592,6 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
return false;
}
-
-
public DateTime getPlanChangeEffectiveDate(final BillingActionPolicy policy, @Nullable final BillingAlignment alignment, @Nullable final Integer accountBillCycleDayLocal, final InternalTenantContext context) {
final DateTime candidateResult;
@@ -607,7 +602,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
case START_OF_TERM:
if (chargedThroughDate == null) {
candidateResult = getStartDate();
- // Will take care of billing IN_ARREAR or subscriptions that are not invoiced up to date
+ // Will take care of billing IN_ARREAR or subscriptions that are not invoiced up to date
} else if (!chargedThroughDate.isAfter(clock.getUTCNow())) {
candidateResult = chargedThroughDate;
} else {
@@ -615,7 +610,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
// In certain path (dryRun, or default catalog START_OF_TERM policy), the info is not easily available and as a result, such policy is not implemented
Preconditions.checkState(alignment != null && context != null && accountBillCycleDayLocal != null, "START_OF_TERM not implemented in dryRun use case");
- Preconditions.checkState(alignment != BillingAlignment.BUNDLE || category != ProductCategory.ADD_ON, "START_OF_TERM not implemented for AO configured with a BUNDLE billing alignment");
+ Preconditions.checkState(alignment != BillingAlignment.BUNDLE || category != ProductCategory.ADD_ON, "START_OF_TERM not implemented for AO configured with a BUNDLE billing alignment");
// If BCD was overriden at the subscription level, we take its latest value (it should also be reflected in the chargedThroughDate) but still required for
// alignment purpose
@@ -630,7 +625,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
proposedDate = proposedDate.minus(billingPeriod.getPeriod());
}
- final LocalDate resultingLocalDate = BillCycleDayCalculator.alignProposedBillCycleDate(proposedDate, bcd, billingPeriod, context);
+ final LocalDate resultingLocalDate = BillCycleDayCalculator.alignProposedBillCycleDate(proposedDate, bcd, billingPeriod, context);
candidateResult = context.toUTCDateTime(resultingLocalDate);
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
index 9273757..31f9959 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
@@ -50,6 +50,7 @@ import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.subscription.alignment.PlanAligner;
import org.killbill.billing.subscription.alignment.TimedPhase;
import org.killbill.billing.subscription.api.SubscriptionBase;
@@ -313,7 +314,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
@Override
public DateTime dryRunChangePlan(final DefaultSubscriptionBase subscription,
- final PlanPhaseSpecifier spec,
+ final EntitlementSpecifier spec,
@Nullable final DateTime requestedDateWithMs,
@Nullable final BillingActionPolicy requestedPolicy,
final TenantContext context) throws SubscriptionBaseApiException {
@@ -321,7 +322,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
BillingActionPolicy policyMaybeNull = requestedPolicy;
if (requestedDateWithMs == null && requestedPolicy == null) {
- final PlanChangeResult planChangeResult = getPlanChangeResult(subscription, spec, now, context);
+ final PlanChangeResult planChangeResult = getPlanChangeResult(subscription, spec.getPlanPhaseSpecifier(), now, context);
policyMaybeNull = planChangeResult.getPolicy();
}
@@ -335,15 +336,15 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
- public DateTime changePlan(final DefaultSubscriptionBase subscription, final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final CallContext context) throws SubscriptionBaseApiException {
+ public DateTime changePlan(final DefaultSubscriptionBase subscription, final EntitlementSpecifier spec, final CallContext context) throws SubscriptionBaseApiException {
validateSubscriptionStateForChangePlan(subscription, null);
- final PlanChangeResult planChangeResult = getPlanChangeResult(subscription, spec, context.getCreatedDate(), context);
+ final PlanChangeResult planChangeResult = getPlanChangeResult(subscription, spec.getPlanPhaseSpecifier(), context.getCreatedDate(), context);
final DateTime effectiveDate = dryRunChangePlan(subscription, spec, null, planChangeResult.getPolicy(), context);
validateEffectiveDate(subscription, effectiveDate);
try {
- doChangePlan(subscription, spec, overrides, effectiveDate, context);
+ doChangePlan(subscription, spec, effectiveDate, context);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -352,14 +353,14 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
- public DateTime changePlanWithRequestedDate(final DefaultSubscriptionBase subscription, final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides,
+ public DateTime changePlanWithRequestedDate(final DefaultSubscriptionBase subscription, final EntitlementSpecifier spec,
final DateTime requestedDateWithMs, final CallContext context) throws SubscriptionBaseApiException {
final DateTime effectiveDate = dryRunChangePlan(subscription, spec, requestedDateWithMs, null, context);
validateEffectiveDate(subscription, effectiveDate);
validateSubscriptionStateForChangePlan(subscription, requestedDateWithMs);
try {
- doChangePlan(subscription, spec, overrides, effectiveDate, context);
+ doChangePlan(subscription, spec, effectiveDate, context);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -368,13 +369,13 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
- public DateTime changePlanWithPolicy(final DefaultSubscriptionBase subscription, final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
+ public DateTime changePlanWithPolicy(final DefaultSubscriptionBase subscription, final EntitlementSpecifier spec, final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
final DateTime effectiveDate = dryRunChangePlan(subscription, spec, null, policy, context);
validateSubscriptionStateForChangePlan(subscription, effectiveDate);
try {
- doChangePlan(subscription, spec, overrides, effectiveDate, context);
+ doChangePlan(subscription, spec, effectiveDate, context);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -400,18 +401,18 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
private void doChangePlan(final DefaultSubscriptionBase subscription,
- final PlanPhaseSpecifier spec,
- final List<PlanPhasePriceOverride> overrides,
+ final EntitlementSpecifier spec,
final DateTime effectiveDate,
final CallContext context) throws SubscriptionBaseApiException, CatalogApiException {
final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
- final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, context);
+ final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(spec.getOverrides(), context);
final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
- final Plan newPlan = fullCatalog.createOrFindPlan(spec, overridesWithContext, effectiveDate, subscription.getStartDate());
+ final PlanPhaseSpecifier planPhaseSpecifier = spec.getPlanPhaseSpecifier();
+ final Plan newPlan = fullCatalog.createOrFindPlan(planPhaseSpecifier, overridesWithContext, effectiveDate, subscription.getStartDate());
- final PhaseType initialPhaseType = spec.getPhaseType();
+ final PhaseType initialPhaseType = planPhaseSpecifier.getPhaseType();
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(newPlan.getProduct().getCategory().toString())) {
if (newPlan.getPlansAllowedInBundle() != -1
&& newPlan.getPlansAllowedInBundle() > 0
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java
index 88305a8..f156d6e 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java
@@ -31,6 +31,7 @@ import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.Product;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.subscription.SubscriptionTestSuiteWithEmbeddedDB;
import org.killbill.billing.subscription.api.SubscriptionBase;
@@ -270,7 +271,8 @@ public class TestTransfer extends SubscriptionTestSuiteWithEmbeddedDB {
final String newBaseProduct1 = "Assault-Rifle";
final BillingPeriod newBaseTerm1 = BillingPeriod.ANNUAL;
testListener.pushExpectedEvent(NextEvent.CHANGE);
- newBaseSubscription.changePlan(new PlanPhaseSpecifier(newBaseProduct1, newBaseTerm1, basePriceList), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(newBaseProduct1, newBaseTerm1, basePriceList);
+ newBaseSubscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier, null, null), callContext);
assertListenerStatus();
newPlan = newBaseSubscription.getCurrentPlan();
@@ -286,7 +288,8 @@ public class TestTransfer extends SubscriptionTestSuiteWithEmbeddedDB {
final String newBaseProduct2 = "Pistol";
final BillingPeriod newBaseTerm2 = BillingPeriod.ANNUAL;
- newBaseSubscriptionWithCtd.changePlan(new PlanPhaseSpecifier(newBaseProduct2, newBaseTerm2, basePriceList), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier1 = new PlanPhaseSpecifier(newBaseProduct2, newBaseTerm2, basePriceList);
+ newBaseSubscriptionWithCtd.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier1, null, null), callContext);
newPlan = newBaseSubscriptionWithCtd.getCurrentPlan();
assertEquals(newPlan.getProduct().getName(), newBaseProduct1);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
index 48f3c80..3fe1e66 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
@@ -93,7 +93,7 @@ public class TestSubscriptionHelper {
this.internalCallContextFactory = internalCallContextFactory;
}
- public DryRunArguments createDryRunArguments(final UUID subscriptionId, final UUID bundleId, final PlanPhaseSpecifier spec, final LocalDate requestedDate, final SubscriptionEventType type, final BillingActionPolicy billingActionPolicy) {
+ public DryRunArguments createDryRunArguments(final UUID subscriptionId, final UUID bundleId, final EntitlementSpecifier spec, final LocalDate requestedDate, final SubscriptionEventType type, final BillingActionPolicy billingActionPolicy) {
return new DryRunArguments() {
@Override
public DryRunType getDryRunType() {
@@ -101,7 +101,7 @@ public class TestSubscriptionHelper {
}
@Override
- public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ public EntitlementSpecifier getEntitlementSpecifier() {
return spec;
}
@@ -130,10 +130,6 @@ public class TestSubscriptionHelper {
return billingActionPolicy;
}
- @Override
- public List<PlanPhasePriceOverride> getPlanPhasePriceOverrides() {
- return null;
- }
};
}
@@ -186,6 +182,11 @@ public class TestSubscriptionHelper {
}
@Override
+ public Integer getBillCycleDay() {
+ return null;
+ }
+
+ @Override
public List<PlanPhasePriceOverride> getOverrides() {
return null;
}
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
index 4999f00..1934905 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
@@ -34,6 +34,7 @@ import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun.DryRunChangeReason;
@@ -313,7 +314,8 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
testListener.pushExpectedEvent(NextEvent.CHANGE);
testListener.pushExpectedEvent(NextEvent.CANCEL);
- baseSubscription.changePlan(new PlanPhaseSpecifier(newBaseProduct, newBaseTerm, newBasePriceList, null), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(newBaseProduct, newBaseTerm, newBasePriceList, null);
+ baseSubscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// REFETCH AO SUBSCRIPTION AND CHECK THIS CANCELLED
@@ -369,7 +371,8 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
assertEquals(aoStatus.get(0).getPriceList(), aoSubscription.getCurrentPriceList().getName());
assertEquals(aoStatus.get(0).getReason(), DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN);
- baseSubscription.changePlan(new PlanPhaseSpecifier(newBaseProduct, newBaseTerm, newBasePriceList), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(newBaseProduct, newBaseTerm, newBasePriceList);
+ baseSubscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
// REFETCH AO SUBSCRIPTION AND CHECK THIS IS ACTIVE
aoSubscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(aoSubscription.getId(), internalCallContext);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java
index 9b4c902..1ca9893 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java
@@ -37,7 +37,9 @@ import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.Entitlement;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.SubscriptionTestSuiteWithEmbeddedDB;
@@ -104,7 +106,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// CHANGE PLAN
testListener.pushExpectedEvent(NextEvent.CHANGE);
- subscription.changePlan(new PlanPhaseSpecifier(toProd, toTerm, toPlanSet), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(toProd, toTerm, toPlanSet);
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHECK CHANGE PLAN
@@ -145,7 +148,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// RE READ SUBSCRIPTION + CHANGE PLAN
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
- subscription.changePlan(new PlanPhaseSpecifier(toProd, toTerm, toPlanSet), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(toProd, toTerm, toPlanSet);
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHECK CHANGE PLAN
@@ -188,7 +192,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
clock.addDeltaFromReality(it.toDurationMillis());
// CHANGE PLAN IMM
- subscription.changePlan(new PlanPhaseSpecifier(toProd, toTerm, toPlanSet), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(toProd, toTerm, toPlanSet);
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.TRIAL);
assertListenerStatus();
@@ -242,7 +247,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// CHANGE PLAN
currentTime = clock.getUTCNow();
- subscription.changePlan(new PlanPhaseSpecifier(toProd, toTerm, toPlanSet), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(toProd, toTerm, toPlanSet);
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
checkChangePlan(subscription, fromProd, ProductCategory.BASE, fromTerm, PhaseType.EVERGREEN);
@@ -308,12 +314,14 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
// CHANGE EOT
- subscription.changePlan(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount"), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount");
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHANGE
testListener.pushExpectedEvent(NextEvent.CHANGE);
- subscription.changePlan(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount"), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier1 = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount");
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier1), callContext);
assertListenerStatus();
final Plan currentPlan = subscription.getCurrentPlan();
@@ -350,11 +358,13 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
// CHANGE EOT
- subscription.changePlan(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, "gunclubDiscount"), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, "gunclubDiscount");
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHANGE EOT
- subscription.changePlan(new PlanPhaseSpecifier("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount"), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier1 = new PlanPhaseSpecifier("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount");
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier1), callContext);
assertListenerStatus();
// CHECK NO CHANGE OCCURED YET
@@ -416,7 +426,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// CHANGE IMMEDIATE TO A 3 PHASES PLAN
testListener.pushExpectedEvent(NextEvent.CHANGE);
- subscription.changePlan(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount"), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount");
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
// CHECK EVERYTHING LOOKS CORRECT
@@ -470,7 +481,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
try {
- aoSubscription.changePlanWithDate(new PlanPhaseSpecifier(baseProduct, baseTerm, basePriceList), null, clock.getUTCNow(), callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(baseProduct, baseTerm, basePriceList);
+ aoSubscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), clock.getUTCNow(), callContext);
Assert.fail("Should not allow plan change across product type");
} catch (final SubscriptionBaseApiException e) {
Assert.assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_INVALID.getCode());
@@ -490,7 +502,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
- final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", baseTerm, basePriceList, null);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", baseTerm, basePriceList);
+ final EntitlementSpecifier spec = new DefaultEntitlementSpecifier(planPhaseSpecifier, null, null);
// First try with default api (no date -> IMM) => Call should fail because subscription is PENDING
final DryRunArguments dryRunArguments1 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, null, SubscriptionEventType.CHANGE, null);
@@ -509,7 +522,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
}
try {
- subscription.changePlanWithDate(spec, null, subscription.getStartDate().minusDays(1), callContext);
+ subscription.changePlanWithDate(spec, subscription.getStartDate().minusDays(1), callContext);
fail("Change plan should have failed : subscription PENDING");
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_INVALID_REQUESTED_DATE.getCode());
@@ -521,7 +534,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// Check we are seeing the right PENDING transition (pistol-monthly), not the START but the CHANGE on the same date
assertEquals(((DefaultSubscriptionBase) result2.get(0)).getCurrentOrPendingPlan().getName(), "pistol-monthly");
- subscription.changePlanWithDate(spec, null, subscription.getStartDate(), callContext);
+ subscription.changePlanWithDate(spec, subscription.getStartDate(), callContext);
assertListenerStatus();
// Move clock to startDate
@@ -543,7 +556,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// CHANGE PLAN IMMEDIATELY: the CHANGE event will be transformed into a CREATE
testListener.pushExpectedEvent(NextEvent.CREATE);
- subscription.changePlanWithDate(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, subscription.getStartDate(), callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), subscription.getStartDate(), callContext);
assertListenerStatus();
checkChangePlan(subscription, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PhaseType.TRIAL);
@@ -562,7 +576,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// CHANGE PLAN ALMOST IMMEDIATELY
testListener.pushExpectedEvent(NextEvent.CHANGE);
- subscription.changePlan(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlan(new DefaultEntitlementSpecifier(planPhaseSpecifier), callContext);
assertListenerStatus();
checkChangePlan(subscription, "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PhaseType.TRIAL);
@@ -583,7 +598,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// Change plan in the future
final DateTime targetDate = clock.getUTCNow().plusDays(3);
- subscription.changePlanWithDate(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, targetDate, callContext);assertListenerStatus();
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), targetDate, callContext);assertListenerStatus();
DefaultSubscriptionBase refreshedSubscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
assertEquals(refreshedSubscription.getAllTransitions().size(), 3);
@@ -626,7 +642,8 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// Change plan in the future
final DateTime futureChangeDate = futureStartDate.plusDays(5);
- subscription.changePlanWithDate(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, futureChangeDate, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), futureChangeDate, callContext);
assertListenerStatus();
DefaultSubscriptionBase refreshedSubscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
index 4f0a717..8b97f5d 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
@@ -30,6 +30,7 @@ import org.killbill.billing.catalog.api.Duration;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
+import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.subscription.SubscriptionTestSuiteNoDB;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
@@ -97,7 +98,8 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
assertListenerStatus();
try {
- subscription.changePlanWithDate(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCNow(), callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), clock.getUTCNow(), callContext);
Assert.fail("Exception expected, error code: " + ErrorCode.SUB_CHANGE_NON_ACTIVE);
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
@@ -109,7 +111,8 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
final SubscriptionBase subscription = testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
try {
- subscription.changePlanWithPolicy(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, BillingActionPolicy.ILLEGAL, callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlanWithPolicy(new DefaultEntitlementSpecifier(planPhaseSpecifier), BillingActionPolicy.ILLEGAL, callContext);
Assert.fail("Call changePlanWithPolicy should have failed");
} catch (final SubscriptionBaseError error) {
assertTrue(true);
@@ -117,7 +120,8 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
}
// Assume the call takes less than a second
- assertEquals(DefaultClock.truncateMs(subscription.changePlanWithPolicy(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, BillingActionPolicy.IMMEDIATE, callContext)),
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ assertEquals(DefaultClock.truncateMs(subscription.changePlanWithPolicy(new DefaultEntitlementSpecifier(planPhaseSpecifier), BillingActionPolicy.IMMEDIATE, callContext)),
DefaultClock.truncateMs(clock.getUTCNow()));
assertEquals(subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext).getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.MONTHLY);
}
@@ -144,7 +148,8 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
subscription.cancelWithPolicy(BillingActionPolicy.END_OF_TERM, -1, callContext);
try {
- subscription.changePlanWithDate(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCNow(), callContext);
+ final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), clock.getUTCNow(), callContext);
Assert.fail("Exception expected, error code: " + ErrorCode.SUB_CHANGE_FUTURE_CANCELLED);
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_FUTURE_CANCELLED.getCode());
diff --git a/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java b/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java
index 725df20..b79ffba 100644
--- a/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java
+++ b/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java
@@ -26,7 +26,7 @@ import org.killbill.billing.util.callcontext.UserType;
public class MutableCallContext implements CallContext {
- private final CallContext delegate;
+ private CallContext delegate;
private DateTime createdDate;
public MutableCallContext(final MutableInternalCallContext internalCallContext) {
@@ -34,6 +34,10 @@ public class MutableCallContext implements CallContext {
this.createdDate = delegate.getCreatedDate();
}
+ public void setDelegate(final UUID accountId, final MutableInternalCallContext internalCallContext) {
+ this.delegate = internalCallContext.toCallContext(accountId, null);
+ }
+
@Override
public UUID getUserToken() {
return delegate.getUserToken();
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
index a8f886a..f2b2a72 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
@@ -105,7 +105,7 @@ public class GuicyKillbillTestSuite implements IHookable {
public static void refreshCallContext(final UUID accountId,
final Clock clock,
final InternalCallContextFactory internalCallContextFactory,
- final TenantContext callContext,
+ final MutableCallContext callContext,
final MutableInternalCallContext internalCallContext) {
final InternalTenantContext tmp = internalCallContextFactory.createInternalTenantContext(accountId, callContext);
internalCallContext.setAccountRecordId(tmp.getAccountRecordId());
@@ -113,6 +113,8 @@ public class GuicyKillbillTestSuite implements IHookable {
internalCallContext.setReferenceTime(tmp.getReferenceLocalTime());
internalCallContext.setCreatedDate(clock.getUTCNow());
internalCallContext.setUpdatedDate(clock.getUTCNow());
+
+ callContext.setDelegate(accountId, internalCallContext);
}
protected KillbillConfigSource getConfigSource() {
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java
index a337c8f..06c00ad 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java
@@ -27,6 +27,7 @@ import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.account.api.ImmutableAccountInternalApi;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.callcontext.MutableCallContext;
import org.killbill.billing.callcontext.MutableInternalCallContext;
import org.killbill.billing.dao.MockNonEntityDao;
import org.killbill.billing.util.callcontext.CallContext;
@@ -44,7 +45,7 @@ public class GuicyKillbillTestSuiteNoDB extends GuicyKillbillTestSuite {
final NonEntityDao nonEntityDao,
final Clock clock,
final InternalCallContextFactory internalCallContextFactory,
- final CallContext callContext,
+ final MutableCallContext callContext,
final MutableInternalCallContext internalCallContext) throws AccountApiException {
final Account account = accountUserApi.createAccount(accountData, callContext);
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
index c4ca078..530530f 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteWithEmbeddedDB.java
@@ -66,6 +66,7 @@ public class GuicyKillbillTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuite
}
cleanupAllTables();
+ callContext.setDelegate(null, internalCallContext);
controlCacheDispatcher.clearAll();
}
diff --git a/util/src/test/java/org/killbill/billing/mock/glue/MockInvoiceModule.java b/util/src/test/java/org/killbill/billing/mock/glue/MockInvoiceModule.java
index 3824d12..eaa612a 100644
--- a/util/src/test/java/org/killbill/billing/mock/glue/MockInvoiceModule.java
+++ b/util/src/test/java/org/killbill/billing/mock/glue/MockInvoiceModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2012 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -20,7 +20,6 @@ package org.killbill.billing.mock.glue;
import org.killbill.billing.glue.InvoiceModule;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
-import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.util.glue.KillBillModule;
@@ -38,15 +37,9 @@ public class MockInvoiceModule extends KillBillModule implements InvoiceModule {
}
@Override
- public void installInvoicePaymentApi() {
- bind(InvoicePaymentApi.class).toInstance(Mockito.mock(InvoicePaymentApi.class));
- }
-
- @Override
protected void configure() {
installInvoiceUserApi();
installInvoiceInternalApi();
- installInvoicePaymentApi();
}
@Override
diff --git a/util/src/test/java/org/killbill/billing/mock/MockSubscription.java b/util/src/test/java/org/killbill/billing/mock/MockSubscription.java
index b6a4dfd..f686884 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockSubscription.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockSubscription.java
@@ -33,6 +33,7 @@ import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementSourceType;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransition;
@@ -83,8 +84,8 @@ public class MockSubscription implements SubscriptionBase {
}
@Override
- public DateTime changePlan(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final CallContext context) throws SubscriptionBaseApiException {
- return sub.changePlan(spec, overrides, context);
+ public DateTime changePlan(final EntitlementSpecifier spec, final CallContext context) throws SubscriptionBaseApiException {
+ return sub.changePlan(spec, context);
}
@Override
@@ -93,15 +94,14 @@ public class MockSubscription implements SubscriptionBase {
}
@Override
- public DateTime changePlanWithDate(final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final DateTime requestedDate,
+ public DateTime changePlanWithDate(final EntitlementSpecifier spec,final DateTime requestedDate,
final CallContext context) throws SubscriptionBaseApiException {
- return sub.changePlanWithDate(spec, overrides, requestedDate, context);
+ return sub.changePlanWithDate(spec, requestedDate, context);
}
@Override
- public DateTime changePlanWithPolicy(final PlanPhaseSpecifier spec,
- final List<PlanPhasePriceOverride> overrides, final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
- return sub.changePlanWithPolicy(spec, overrides, policy, context);
+ public DateTime changePlanWithPolicy(final EntitlementSpecifier spec, final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
+ return sub.changePlanWithPolicy(spec, policy, context);
}
@Override