killbill-aplcache
Changes
beatrix/src/test/resources/catalogSample.xml 14(+14 -0)
entitlement/pom.xml 6(+6 -0)
entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultBillingEvent.java 41(+28 -13)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadSubscription.java 144(+144 -0)
Details
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java b/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java
index a1cf572..2628b36 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java
@@ -23,6 +23,7 @@ import com.ning.billing.catalog.api.InternationalPrice;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
public interface BillingEvent extends Comparable<BillingEvent> {
@@ -88,4 +89,9 @@ public interface BillingEvent extends Comparable<BillingEvent> {
* @return the recurring price for the phase
*/
public InternationalPrice getRecurringPrice();
+
+ /**
+ * @return the transition type of the underlying subscription event that triggered this
+ */
+ public SubscriptionTransitionType getTransitionType();
}
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
index a9070fd..8cadd9a 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
@@ -28,12 +28,14 @@ public interface InvoiceItem extends Entity, Comparable<InvoiceItem> {
UUID getSubscriptionId();
+ String getPlanName();
+
+ String getPhaseName();
+
DateTime getStartDate();
DateTime getEndDate();
- String getDescription();
-
BigDecimal getRecurringAmount();
BigDecimal getRecurringRate();
beatrix/src/test/resources/catalogSample.xml 14(+14 -0)
diff --git a/beatrix/src/test/resources/catalogSample.xml b/beatrix/src/test/resources/catalogSample.xml
index ce3b250..966ebf1 100644
--- a/beatrix/src/test/resources/catalogSample.xml
+++ b/beatrix/src/test/resources/catalogSample.xml
@@ -183,6 +183,20 @@ Use Cases to do:
</rules>
<plans>
+ <plan name="pistol-monthly-no-trial">
+ <product>Pistol</product>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <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>
+ </finalPhase>
+ </plan>
<plan name="pistol-monthly">
<product>Pistol</product>
<initialPhases>
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
index 2df4f1f..06e16e6 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
@@ -171,7 +171,7 @@ public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implem
return this;
}
- protected DefaultPlanPhase setReccuringPrice(DefaultInternationalPrice price) {
+ protected DefaultPlanPhase setRecurringPrice(DefaultInternationalPrice price) {
this.recurringPrice = price;
return this;
}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
index cb6a887..5fc51b8 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
@@ -64,7 +64,7 @@ public class MockCatalog extends StandaloneCatalog {
DefaultProduct[] products = getCurrentProducts();
DefaultPlan[] plans = new DefaultPlan[products.length];
for(int i = 0; i < products.length; i++) {
- DefaultPlanPhase phase = new DefaultPlanPhase().setPhaseType(PhaseType.EVERGREEN).setBillingPeriod(BillingPeriod.MONTHLY).setReccuringPrice(new DefaultInternationalPrice());
+ DefaultPlanPhase phase = new DefaultPlanPhase().setPhaseType(PhaseType.EVERGREEN).setBillingPeriod(BillingPeriod.MONTHLY).setRecurringPrice(new DefaultInternationalPrice());
plans[i] = new MockPlan().setName(products[i].getName().toLowerCase() + "-plan").setProduct(products[i]).setFinalPhase(phase);
}
setPlans(plans);
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
index 2ef5768..d4ae5ff 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
@@ -18,6 +18,7 @@ package com.ning.billing.catalog;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.TimeUnit;
import javax.annotation.Nullable;
@@ -33,7 +34,7 @@ public class MockPlanPhase extends DefaultPlanPhase {
setBillingPeriod(billingPeriod);
setPhaseType(type);
setDuration(duration);
- setReccuringPrice(recurringPrice);
+ setRecurringPrice(recurringPrice);
setFixedPrice(fixedPrice);
}
@@ -59,7 +60,7 @@ public class MockPlanPhase extends DefaultPlanPhase {
setBillingPeriod(billingPeriod);
setPhaseType(phaseType);
setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
- setReccuringPrice(recurringPrice);
+ setRecurringPrice(recurringPrice);
setFixedPrice(fixedPrice);
setPlan(new MockPlan(this));
}
@@ -68,10 +69,17 @@ public class MockPlanPhase extends DefaultPlanPhase {
setBillingPeriod(BillingPeriod.MONTHLY);
setPhaseType(PhaseType.EVERGREEN);
setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
- setReccuringPrice(new MockInternationalPrice());
+ setRecurringPrice(new MockInternationalPrice());
setFixedPrice(null);
setPlan(mockPlan);
}
-
+ public MockPlanPhase(Plan plan, PhaseType phaseType) {
+ setBillingPeriod(BillingPeriod.MONTHLY);
+ setPhaseType(phaseType);
+ setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
+ setRecurringPrice(new MockInternationalPrice());
+ setFixedPrice(null);
+ setPlan(plan);
+ }
}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
index d778c4b..9b07bfe 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
@@ -32,17 +32,17 @@ public class TestPlanPhase {
public void testValidation() {
log.info("Testing Plan Phase Validation");
- DefaultPlanPhase pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setReccuringPrice(null).setFixedPrice(new DefaultInternationalPrice());
+ DefaultPlanPhase pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setRecurringPrice(null).setFixedPrice(new DefaultInternationalPrice());
ValidationErrors errors = pp.validate(new MockCatalog(), new ValidationErrors());
errors.log(log);
Assert.assertEquals(errors.size(), 1);
- pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setReccuringPrice(new MockInternationalPrice());
+ pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setRecurringPrice(new MockInternationalPrice());
errors = pp.validate(new MockCatalog(), new ValidationErrors());
errors.log(log);
Assert.assertEquals(errors.size(), 1);
- pp = new MockPlanPhase().setReccuringPrice(null).setFixedPrice(null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD);
+ pp = new MockPlanPhase().setRecurringPrice(null).setFixedPrice(null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD);
errors = pp.validate(new MockCatalog(), new ValidationErrors());
errors.log(log);
Assert.assertEquals(errors.size(), 1);
entitlement/pom.xml 6(+6 -0)
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 805436d..83388f8 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -48,6 +48,12 @@
<dependency>
<groupId>com.ning.billing</groupId>
<artifactId>killbill-catalog</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing</groupId>
+ <artifactId>killbill-catalog</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadSubscription.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadSubscription.java
new file mode 100644
index 0000000..e55ba79
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadSubscription.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2010-2011 Ning, 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.
+ */
+
+package com.ning.billing.entitlement.api.billing;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+
+public class BrainDeadSubscription implements Subscription {
+
+ @Override
+ public void cancel(DateTime requestedDate, boolean eot)
+ throws EntitlementUserApiException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void uncancel() throws EntitlementUserApiException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void changePlan(String productName, BillingPeriod term,
+ String planSet, DateTime requestedDate)
+ throws EntitlementUserApiException {
+ throw new UnsupportedOperationException();
+
+
+ }
+
+ @Override
+ public void pause() throws EntitlementUserApiException {
+ throw new UnsupportedOperationException();
+
+
+ }
+
+ @Override
+ public void resume() throws EntitlementUserApiException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public UUID getId() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public UUID getBundleId() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public SubscriptionState getState() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public DateTime getStartDate() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public DateTime getEndDate() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public Plan getCurrentPlan() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public String getCurrentPriceList() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public PlanPhase getCurrentPhase() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public DateTime getChargedThroughDate() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public DateTime getPaidThroughDate() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public List<SubscriptionTransition> getActiveTransitions() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public List<SubscriptionTransition> getAllTransitions() {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public SubscriptionTransition getPendingTransition() {
+ throw new UnsupportedOperationException();
+
+ }
+
+}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java
new file mode 100644
index 0000000..100d184
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2010-2011 Ning, 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.
+ */
+
+package com.ning.billing.entitlement.api.billing;
+
+import java.math.BigDecimal;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.catalog.DefaultPrice;
+import com.ning.billing.catalog.MockInternationalPrice;
+import com.ning.billing.catalog.MockPlan;
+import com.ning.billing.catalog.MockPlanPhase;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.InternationalPrice;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
+
+public class TestDefaultBillingEvent {
+ public static final UUID ID_ZERO = new UUID(0L,0L);
+ public static final UUID ID_ONE = new UUID(0L,1L);
+ public static final UUID ID_TWO = new UUID(0L,2L);
+
+ @Test(groups={"fast"})
+ public void testEventOrderingSubscription() {
+
+ BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+ BillingEvent event1 = createEvent(subscription(ID_ONE), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+ BillingEvent event2 = createEvent(subscription(ID_TWO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+
+ SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+ set.add(event2);
+ set.add(event1);
+ set.add(event0);
+
+ Iterator<BillingEvent> it = set.iterator();
+
+ Assert.assertEquals(event0, it.next());
+ Assert.assertEquals(event1, it.next());
+ Assert.assertEquals(event2, it.next());
+ }
+
+ @Test(groups={"fast"})
+ public void testEventOrderingDate() {
+
+ BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+ BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-02-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+ BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-03-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+
+ SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+ set.add(event2);
+ set.add(event1);
+ set.add(event0);
+
+ Iterator<BillingEvent> it = set.iterator();
+
+ Assert.assertEquals(event0, it.next());
+ Assert.assertEquals(event1, it.next());
+ Assert.assertEquals(event2, it.next());
+ }
+
+ @Test(groups={"fast"})
+ public void testEventOrderingType() {
+
+ BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+ BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CHANGE);
+ BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL);
+
+ SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+ set.add(event2);
+ set.add(event1);
+ set.add(event0);
+
+ Iterator<BillingEvent> it = set.iterator();
+
+ Assert.assertEquals(event0, it.next());
+ Assert.assertEquals(event1, it.next());
+ Assert.assertEquals(event2, it.next());
+ }
+
+ @Test(groups={"fast"})
+ public void testEventOrderingMix() {
+
+ BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+ BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-02T00:02:04.000Z"), SubscriptionTransitionType.CHANGE);
+ BillingEvent event2 = createEvent(subscription(ID_ONE), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL);
+
+ SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+ set.add(event2);
+ set.add(event1);
+ set.add(event0);
+
+ Iterator<BillingEvent> it = set.iterator();
+
+ Assert.assertEquals(event0, it.next());
+ Assert.assertEquals(event1, it.next());
+ Assert.assertEquals(event2, it.next());
+ }
+
+
+ private BillingEvent createEvent(Subscription sub, DateTime effectiveDate, SubscriptionTransitionType type) {
+ InternationalPrice zeroPrice = new MockInternationalPrice(new DefaultPrice(BigDecimal.ZERO, Currency.USD));
+ int billCycleDay = 1;
+
+ Plan shotgun = new MockPlan();
+ PlanPhase shotgunMonthly = createMockMonthlyPlanPhase(null, BigDecimal.ZERO, PhaseType.TRIAL);
+
+ return new DefaultBillingEvent(sub , effectiveDate,
+ shotgun, shotgunMonthly,
+ zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
+ BillingModeType.IN_ADVANCE, "Test Event 1", type);
+ }
+
+ private MockPlanPhase createMockMonthlyPlanPhase(@Nullable final BigDecimal recurringRate,
+ final BigDecimal fixedRate, PhaseType phaseType) {
+ return new MockPlanPhase(new MockInternationalPrice(new DefaultPrice(recurringRate, Currency.USD)),
+ new MockInternationalPrice(new DefaultPrice(fixedRate, Currency.USD)),
+ BillingPeriod.MONTHLY, phaseType);
+ }
+
+ private Subscription subscription(final UUID id) {
+ return new BrainDeadSubscription() {
+ public UUID getId() {
+ return id;
+ }
+ };
+ }
+
+}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java
index 76e0dbf..84a21ef 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemSqlDao.java
@@ -79,9 +79,10 @@ public interface InvoiceItemSqlDao extends EntityDao<InvoiceItem> {
q.bind("id", item.getId().toString());
q.bind("invoiceId", item.getInvoiceId().toString());
q.bind("subscriptionId", item.getSubscriptionId().toString());
+ q.bind("planName", item.getPlanName());
+ q.bind("phaseName", item.getPhaseName());
q.bind("startDate", item.getStartDate().toDate());
q.bind("endDate", item.getEndDate() == null ? null : item.getEndDate().toDate());
- q.bind("description", item.getDescription());
q.bind("recurringAmount", item.getRecurringAmount() == null ? BigDecimal.ZERO : item.getRecurringAmount());
q.bind("recurringRate", item.getRecurringRate() == null ? BigDecimal.ZERO : item.getRecurringRate());
q.bind("fixedAmount", item.getFixedAmount() == null ? BigDecimal.ZERO : item.getFixedAmount());
@@ -98,16 +99,17 @@ public interface InvoiceItemSqlDao extends EntityDao<InvoiceItem> {
UUID id = UUID.fromString(result.getString("id"));
UUID invoiceId = UUID.fromString(result.getString("invoice_id"));
UUID subscriptionId = UUID.fromString(result.getString("subscription_id"));
+ String planName = result.getString("plan_name");
+ String phaseName = result.getString("phase_name");
DateTime startDate = new DateTime(result.getTimestamp("start_date"));
DateTime endDate = new DateTime(result.getTimestamp("end_date"));
- String description = result.getString("description");
BigDecimal recurringAmount = result.getBigDecimal("recurring_amount");
BigDecimal recurringRate = result.getBigDecimal("recurring_rate");
BigDecimal fixedAmount = result.getBigDecimal("fixed_amount");
Currency currency = Currency.valueOf(result.getString("currency"));
- return new DefaultInvoiceItem(id, invoiceId, subscriptionId, startDate, endDate,
- description, recurringAmount, recurringRate, fixedAmount, currency);
+ return new DefaultInvoiceItem(id, invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
+ recurringAmount, recurringRate, fixedAmount, currency);
}
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
index e12adc3..948638c 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
@@ -16,6 +16,7 @@
package com.ning.billing.invoice;
+import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.UUID;
@@ -111,20 +112,36 @@ public class InvoiceListener {
if (invoice == null) {
log.info("Generated null invoice.");
+ outputDebugData(events, invoiceItemList);
+ } else {
+ log.info("Generated invoice {} with {} items.", invoice.getId().toString(), invoice.getNumberOfItems());
+
if (VERBOSE_OUTPUT) {
- for (BillingEvent event : events) {
- log.info(event.toString());
- }
- for (InvoiceItem item : invoiceItemList) {
+ log.info("New items");
+ for (InvoiceItem item : invoice.getInvoiceItems()) {
log.info(item.toString());
}
}
- } else {
- log.info("Generated invoice {} with {} items.", invoice.getId().toString(), invoice.getNumberOfItems());
+
+ outputDebugData(events, invoiceItemList);
if (invoice.getNumberOfItems() > 0) {
invoiceDao.create(invoice);
}
}
}
+
+ private void outputDebugData(Collection<BillingEvent> events, Collection<InvoiceItem> invoiceItemList) {
+ if (VERBOSE_OUTPUT) {
+ log.info("Events");
+ for (BillingEvent event : events) {
+ log.info(event.toString());
+ }
+
+ log.info("Existing items");
+ for (InvoiceItem item : invoiceItemList) {
+ log.info(item.toString());
+ }
+ }
+ }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 30a6957..9bbc0c7 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -16,11 +16,9 @@
package com.ning.billing.invoice.model;
-
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
+import java.util.Iterator;
import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
@@ -29,7 +27,6 @@ import org.slf4j.LoggerFactory;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.CatalogApiException;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.InternationalPrice;
import com.ning.billing.entitlement.api.billing.BillingEvent;
import com.ning.billing.entitlement.api.billing.BillingModeType;
import com.ning.billing.invoice.api.Invoice;
@@ -80,18 +77,18 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
Collections.sort(currentItems);
Collections.sort(existingItems);
- List<InvoiceItem> existingItemsToRemove = new ArrayList<InvoiceItem>();
-
for (final InvoiceItem currentItem : currentItems) {
+ Iterator<InvoiceItem> it = existingItems.iterator();
+
// see if there are any existing items that are covered by the current item
- for (final InvoiceItem existingItem : existingItems) {
+ while (it.hasNext()) {
+ InvoiceItem existingItem = it.next();
if (currentItem.duplicates(existingItem)) {
currentItem.subtract(existingItem);
- existingItemsToRemove.add(existingItem);
+ it.remove();
}
}
}
- existingItems.removeAll(existingItemsToRemove);
// remove cancelling pairs of invoice items
existingItems.removeCancellingPairs();
@@ -134,14 +131,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
return items;
}
- private void processEvent(final UUID invoiceId, final BillingEvent event, final List<InvoiceItem> items,
+ private void processEvent(final UUID invoiceId, final BillingEvent event, final InvoiceItemList items,
final DateTime targetDate, final Currency targetCurrency) {
try {
BigDecimal recurringRate = event.getRecurringPrice() == null ? null : event.getRecurringPrice().getPrice(targetCurrency);
BigDecimal fixedPrice = event.getFixedPrice() == null ? null : event.getFixedPrice().getPrice(targetCurrency);
BigDecimal numberOfBillingPeriods;
- BigDecimal recurringAmount =null;
+ BigDecimal recurringAmount = null;
if (recurringRate != null) {
numberOfBillingPeriods = calculateNumberOfBillingPeriods(event, targetDate);
@@ -150,8 +147,9 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
BillingMode billingMode = getBillingMode(event.getBillingMode());
DateTime billThroughDate = billingMode.calculateEffectiveEndDate(event.getEffectiveDate(), targetDate, event.getBillCycleDay(), event.getBillingPeriod());
- if (!billThroughDate.isAfter(targetDate.plusMonths(event.getBillingPeriod().getNumberOfMonths()))) {
- addInvoiceItem(invoiceId, items, event, billThroughDate, recurringAmount, recurringRate, fixedPrice, targetCurrency);
+ if ((event.getBillingPeriod() == BillingPeriod.NO_BILLING_PERIOD) || (!billThroughDate.isAfter(targetDate.plusMonths(event.getBillingPeriod().getNumberOfMonths())))) {
+ BigDecimal effectiveFixedPrice = items.hasInvoiceItemForPhase(event.getPlanPhase().getName()) ? null : fixedPrice;
+ addInvoiceItem(invoiceId, items, event, billThroughDate, recurringAmount, recurringRate, effectiveFixedPrice, targetCurrency);
}
} catch (CatalogApiException e) {
log.error(String.format("Encountered a catalog error processing invoice %s for billing event on date %s",
@@ -161,13 +159,13 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
private void processEvents(final UUID invoiceId, final BillingEvent firstEvent, final BillingEvent secondEvent,
- final List<InvoiceItem> items, final DateTime targetDate, final Currency targetCurrency) {
+ final InvoiceItemList items, final DateTime targetDate, final Currency targetCurrency) {
try {
BigDecimal recurringRate = firstEvent.getRecurringPrice() == null ? null : firstEvent.getRecurringPrice().getPrice(targetCurrency);
BigDecimal fixedPrice = firstEvent.getFixedPrice() == null ? null : firstEvent.getFixedPrice().getPrice(targetCurrency);
BigDecimal numberOfBillingPeriods;
- BigDecimal recurringAmount =null;
+ BigDecimal recurringAmount = null;
if (recurringRate != null) {
numberOfBillingPeriods = calculateNumberOfBillingPeriods(firstEvent, secondEvent, targetDate);
@@ -177,7 +175,8 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
BillingMode billingMode = getBillingMode(firstEvent.getBillingMode());
DateTime billThroughDate = billingMode.calculateEffectiveEndDate(firstEvent.getEffectiveDate(), secondEvent.getEffectiveDate(), targetDate, firstEvent.getBillCycleDay(), firstEvent.getBillingPeriod());
- addInvoiceItem(invoiceId, items, firstEvent, billThroughDate, recurringAmount, recurringRate, fixedPrice, targetCurrency);
+ BigDecimal effectiveFixedPrice = items.hasInvoiceItemForPhase(firstEvent.getPlanPhase().getName()) ? null : fixedPrice;
+ addInvoiceItem(invoiceId, items, firstEvent, billThroughDate, recurringAmount, recurringRate, effectiveFixedPrice, targetCurrency);
} catch (CatalogApiException e) {
log.error(String.format("Encountered a catalog error processing invoice %s for billing event on date %s",
invoiceId.toString(),
@@ -185,11 +184,12 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
}
- private void addInvoiceItem(final UUID invoiceId, final List<InvoiceItem> items, final BillingEvent event,
+ private void addInvoiceItem(final UUID invoiceId, final InvoiceItemList items, final BillingEvent event,
final DateTime billThroughDate, final BigDecimal amount, final BigDecimal rate,
final BigDecimal fixedAmount, final Currency currency) {
- DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, event.getSubscription().getId(), event.getEffectiveDate(),
- billThroughDate, event.getDescription(), amount, rate, fixedAmount, currency);
+ DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, event.getSubscription().getId(),
+ event.getPlan().getName(), event.getPlanPhase().getName(), event.getEffectiveDate(),
+ billThroughDate, amount, rate, fixedAmount, currency);
items.add(item);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceItem.java
index 9e229fb..508fab8 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceItem.java
@@ -17,8 +17,9 @@
package com.ning.billing.invoice.model;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
import com.ning.billing.invoice.api.InvoiceItem;
-import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
import org.joda.time.DateTime;
import javax.annotation.Nullable;
@@ -29,30 +30,34 @@ public class DefaultInvoiceItem implements InvoiceItem {
private final UUID id;
private final UUID invoiceId;
private final UUID subscriptionId;
+ private final String planName;
+ private final String phaseName;
private DateTime startDate;
private DateTime endDate;
- private final String description;
private BigDecimal recurringAmount;
private final BigDecimal recurringRate;
private BigDecimal fixedAmount;
private final Currency currency;
- public DefaultInvoiceItem(UUID invoiceId, UUID subscriptionId, DateTime startDate, DateTime endDate,
- String description, BigDecimal recurringAmount, BigDecimal recurringRate,
+ public DefaultInvoiceItem(UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate,
+ BigDecimal recurringAmount, BigDecimal recurringRate,
BigDecimal fixedAmount, Currency currency) {
- this(UUID.randomUUID(), invoiceId, subscriptionId, startDate, endDate, description,
+ this(UUID.randomUUID(), invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
recurringAmount, recurringRate, fixedAmount, currency);
}
- public DefaultInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, DateTime startDate, DateTime endDate,
- String description, BigDecimal recurringAmount, BigDecimal recurringRate,
+ public DefaultInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate,
+ BigDecimal recurringAmount, BigDecimal recurringRate,
BigDecimal fixedAmount, Currency currency) {
this.id = id;
this.invoiceId = invoiceId;
this.subscriptionId = subscriptionId;
+ this.planName = planName;
+ this.phaseName = phaseName;
this.startDate = startDate;
this.endDate = endDate;
- this.description = description;
this.recurringAmount = recurringAmount;
this.recurringRate = recurringRate;
this.fixedAmount = fixedAmount;
@@ -63,9 +68,10 @@ public class DefaultInvoiceItem implements InvoiceItem {
this.id = UUID.randomUUID();
this.invoiceId = invoiceId;
this.subscriptionId = that.getSubscriptionId();
+ this.planName = that.getPlanName();
+ this.phaseName = that.getPhaseName();
this.startDate = that.getStartDate();
this.endDate = that.getEndDate();
- this.description = that.getDescription();
this.recurringAmount = that.getRecurringAmount();
this.recurringRate = that.getRecurringRate();
this.fixedAmount = that.getFixedAmount();
@@ -76,7 +82,7 @@ public class DefaultInvoiceItem implements InvoiceItem {
public InvoiceItem asCredit(UUID invoiceId) {
BigDecimal recurringAmountNegated = recurringAmount == null ? null : recurringAmount.negate();
BigDecimal fixedAmountNegated = fixedAmount == null ? null : fixedAmount.negate();
- return new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, endDate, description,
+ return new DefaultInvoiceItem(invoiceId, subscriptionId, planName, phaseName, startDate, endDate,
recurringAmountNegated, recurringRate, fixedAmountNegated, currency);
}
@@ -96,6 +102,16 @@ public class DefaultInvoiceItem implements InvoiceItem {
}
@Override
+ public String getPlanName() {
+ return planName;
+ }
+
+ @Override
+ public String getPhaseName() {
+ return phaseName;
+ }
+
+ @Override
public DateTime getStartDate() {
return startDate;
}
@@ -106,11 +122,6 @@ public class DefaultInvoiceItem implements InvoiceItem {
}
@Override
- public String getDescription() {
- return description;
- }
-
- @Override
public BigDecimal getRecurringAmount() {
return recurringAmount;
}
@@ -144,7 +155,8 @@ public class DefaultInvoiceItem implements InvoiceItem {
return 1;
}
- return getStartDate().compareTo(that.getStartDate());
+ int compareStartDates = getStartDate().compareTo(that.getStartDate());
+ return compareStartDates;
} else {
return compareSubscriptions;
}
@@ -156,18 +168,15 @@ public class DefaultInvoiceItem implements InvoiceItem {
if (this.startDate.equals(that.getStartDate()) && this.endDate.equals(that.getEndDate())) {
this.startDate = this.endDate;
this.recurringAmount = safeSubtract(this.recurringAmount, that.getRecurringAmount());
- this.fixedAmount = safeSubtract(this.fixedAmount, that.getFixedAmount());
} else {
if (this.startDate.equals(that.getStartDate())) {
this.startDate = that.getEndDate();
this.recurringAmount = safeSubtract(this.recurringAmount, that.getRecurringAmount());
- this.fixedAmount = safeSubtract(this.fixedAmount, that.getFixedAmount());
}
if (this.endDate.equals(that.getEndDate())) {
this.endDate = that.getStartDate();
this.recurringAmount = safeSubtract(this.recurringAmount, that.getRecurringAmount());
- this.fixedAmount = safeSubtract(this.fixedAmount, that.getFixedAmount());
}
}
}
@@ -192,13 +201,14 @@ public class DefaultInvoiceItem implements InvoiceItem {
@Override
public boolean duplicates(InvoiceItem that) {
- if(!this.getSubscriptionId().equals(that.getSubscriptionId())) {return false;}
-
- //if (!compareNullableBigDecimal(this.getRecurringAmount(), that.getRecurringAmount())) {return false;}
+ if (!this.getSubscriptionId().equals(that.getSubscriptionId())) {return false;}
+
+ if (!this.planName.equals(that.getPlanName())) {return false;}
+ if (!this.phaseName.equals(that.getPhaseName())) {return false;}
+
if (!compareNullableBigDecimal(this.getRecurringRate(), that.getRecurringRate())) {return false;}
- if (!compareNullableBigDecimal(this.getFixedAmount(), that.getFixedAmount())) {return false;}
- if(!this.getCurrency().equals(that.getCurrency())) {return false;}
+ if (!this.getCurrency().equals(that.getCurrency())) {return false;}
DateRange thisDateRange = new DateRange(this.getStartDate(), this.getEndDate());
return thisDateRange.contains(that.getStartDate()) && thisDateRange.contains(that.getEndDate());
@@ -247,6 +257,8 @@ public class DefaultInvoiceItem implements InvoiceItem {
sb.append("InvoiceItem = {").append("id = ").append(id.toString()).append(", ");
sb.append("invoiceId = ").append(invoiceId.toString()).append(", ");
sb.append("subscriptionId = ").append(subscriptionId.toString()).append(", ");
+ sb.append("planName = ").append(planName).append(", ");
+ sb.append("phaseName = ").append(phaseName).append(", ");
sb.append("startDate = ").append(startDate.toString()).append(", ");
sb.append("endDate = ").append(startDate.toString()).append(", ");
sb.append("recurringAmount = ");
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
index 5a10928..13ccb60 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
@@ -76,13 +76,26 @@ public class InvoiceItemList extends ArrayList<InvoiceItem> {
Iterator<InvoiceItem> iterator = this.iterator();
while (iterator.hasNext()) {
InvoiceItem item = iterator.next();
- Boolean hasZeroRecurringAmount = item.getRecurringAmount() == null || (item.getRecurringAmount().compareTo(BigDecimal.ZERO) == 0);
- Boolean hasRecurringRate = item.getRecurringRate() == null || (item.getRecurringRate().compareTo(BigDecimal.ZERO) != 0);
- Boolean hasZeroFixedAmount = item.getFixedAmount() == null || (item.getFixedAmount().compareTo(BigDecimal.ZERO) == 0);
- if (hasZeroRecurringAmount && hasRecurringRate & hasZeroFixedAmount) {
+ boolean fixedAmountNull = (item.getFixedAmount() == null);
+ boolean recurringRateNull = (item.getRecurringRate() == null);
+ boolean recurringAmountZero = (item.getRecurringRate() !=null) && (item.getRecurringAmount().compareTo(BigDecimal.ZERO) == 0);
+
+ if (fixedAmountNull && (recurringRateNull || recurringAmountZero)) {
+ iterator.remove();
+ } else if (item.getStartDate().compareTo(item.getEndDate()) == 0) {
iterator.remove();
}
}
}
+
+ public boolean hasInvoiceItemForPhase(final String phaseName) {
+ for (final InvoiceItem item : this) {
+ if (item.getPhaseName().equals(phaseName)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index 39fcd24..5b37548 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -4,9 +4,10 @@ invoiceItemFields(prefix) ::= <<
<prefix>id,
<prefix>invoice_id,
<prefix>subscription_id,
+ <prefix>plan_name,
+ <prefix>phase_name,
<prefix>start_date,
<prefix>end_date,
- <prefix>description,
<prefix>recurring_amount,
<prefix>recurring_rate,
<prefix>fixed_amount,
@@ -40,14 +41,14 @@ getInvoiceItemsBySubscription() ::= <<
create() ::= <<
INSERT INTO invoice_items(<invoiceItemFields()>)
- VALUES(:id, :invoiceId, :subscriptionId, :startDate, :endDate, :description,
+ VALUES(:id, :invoiceId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
:recurringAmount, :recurringRate, :fixedAmount, :currency);
>>
update() ::= <<
UPDATE invoice_items
- SET invoice_id = :invoiceId, subscription_id = :subscriptionId, start_date = :startDate, end_date = :endDate,
- description = :description, recurring_amount = :recurringAmount, recurring_rate = :recurringRate,
+ SET invoice_id = :invoiceId, subscription_id = :subscriptionId, plan_name = :planName, phase_name = :phaseName,
+ start_date = :startDate, end_date = :endDate, recurring_amount = :recurringAmount, recurring_rate = :recurringRate,
fixed_amount = :fixedAmount, currency = :currency
WHERE id = :id;
>>
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
index 348f423..1cf6f23 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -3,9 +3,10 @@ CREATE TABLE invoice_items (
id char(36) NOT NULL,
invoice_id char(36) NOT NULL,
subscription_id char(36) NOT NULL,
+ plan_name varchar(50) NOT NULL,
+ phase_name varchar(50) NOT NULL,
start_date datetime NOT NULL,
end_date datetime NULL,
- description varchar(100) NOT NULL,
recurring_amount numeric(10,4) NOT NULL,
recurring_rate numeric(10,4) NOT NULL,
fixed_amount numeric(10,4) NOT NULL,
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index b63c230..2369467 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -27,6 +27,7 @@ import com.ning.billing.entitlement.api.billing.BillingEvent;
import com.ning.billing.entitlement.api.billing.BillingModeType;
import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoicePayment;
@@ -83,7 +84,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
UUID subscriptionId = UUID.randomUUID();
DateTime startDate = new DateTime(2010, 1, 1, 0, 0, 0, 0);
DateTime endDate = new DateTime(2010, 4, 1, 0, 0, 0, 0);
- InvoiceItem invoiceItem = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, endDate, "test", new BigDecimal("21.00"), new BigDecimal("7.00"), null, Currency.USD);
+ InvoiceItem invoiceItem = new DefaultInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, endDate, new BigDecimal("21.00"), new BigDecimal("7.00"), null, Currency.USD);
invoice.addInvoiceItem(invoiceItem);
invoiceDao.create(invoice);
@@ -180,7 +181,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate = new BigDecimal("9.0");
BigDecimal amount = rate.multiply(new BigDecimal("3.0"));
- DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, targetDate, endDate, "test", amount, rate, null, Currency.USD);
+ DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", targetDate, endDate, amount, rate, null, Currency.USD);
invoice.addInvoiceItem(item);
invoiceDao.create(invoice);
@@ -275,16 +276,16 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
DateTime endDate = startDate.plusMonths(1);
- DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoiceId1, subscriptionId1, startDate, endDate, "test A", rate1, rate1, null, Currency.USD);
+ DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoiceId1, subscriptionId1, "test plan", "test A", startDate, endDate, rate1, rate1, null, Currency.USD);
invoiceItemDao.create(item1);
- DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoiceId1, subscriptionId2, startDate, endDate, "test B", rate2, rate2, null, Currency.USD);
+ DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoiceId1, subscriptionId2, "test plan", "test B", startDate, endDate, rate2, rate2, null, Currency.USD);
invoiceItemDao.create(item2);
- DefaultInvoiceItem item3 = new DefaultInvoiceItem(invoiceId1, subscriptionId3, startDate, endDate, "test C", rate3, rate3, null, Currency.USD);
+ DefaultInvoiceItem item3 = new DefaultInvoiceItem(invoiceId1, subscriptionId3, "test plan", "test C", startDate, endDate, rate3, rate3, null, Currency.USD);
invoiceItemDao.create(item3);
- DefaultInvoiceItem item4 = new DefaultInvoiceItem(invoiceId1, subscriptionId4, startDate, endDate, "test D", rate4, rate4, null, Currency.USD);
+ DefaultInvoiceItem item4 = new DefaultInvoiceItem(invoiceId1, subscriptionId4, "test plan", "test D", startDate, endDate, rate4, rate4, null, Currency.USD);
invoiceItemDao.create(item4);
// create invoice 2 (subscriptions 1-3)
@@ -296,13 +297,13 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
startDate = endDate;
endDate = startDate.plusMonths(1);
- DefaultInvoiceItem item5 = new DefaultInvoiceItem(invoiceId2, subscriptionId1, startDate, endDate, "test A", rate1, rate1, null, Currency.USD);
+ DefaultInvoiceItem item5 = new DefaultInvoiceItem(invoiceId2, subscriptionId1, "test plan", "test phase A", startDate, endDate, rate1, rate1, null, Currency.USD);
invoiceItemDao.create(item5);
- DefaultInvoiceItem item6 = new DefaultInvoiceItem(invoiceId2, subscriptionId2, startDate, endDate, "test B", rate2, rate2, null, Currency.USD);
+ DefaultInvoiceItem item6 = new DefaultInvoiceItem(invoiceId2, subscriptionId2, "test plan", "test phase B", startDate, endDate, rate2, rate2, null, Currency.USD);
invoiceItemDao.create(item6);
- DefaultInvoiceItem item7 = new DefaultInvoiceItem(invoiceId2, subscriptionId3, startDate, endDate, "test C", rate3, rate3, null, Currency.USD);
+ DefaultInvoiceItem item7 = new DefaultInvoiceItem(invoiceId2, subscriptionId3, "test plan", "test phase C", startDate, endDate, rate3, rate3, null, Currency.USD);
invoiceItemDao.create(item7);
// check that each subscription returns the correct number of invoices
@@ -361,10 +362,10 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate1 = new BigDecimal("17.0");
BigDecimal rate2 = new BigDecimal("42.0");
- DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), startDate, endDate, "test A", rate1, rate1, null, Currency.USD);
+ DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase A", startDate, endDate, rate1, rate1, null, Currency.USD);
invoiceItemDao.create(item1);
- DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), startDate, endDate, "test B", rate2, rate2, null, Currency.USD);
+ DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase B", startDate, endDate, rate2, rate2, null, Currency.USD);
invoiceItemDao.create(item2);
BigDecimal payment1 = new BigDecimal("48.0");
@@ -388,10 +389,10 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate1 = new BigDecimal("17.0");
BigDecimal rate2 = new BigDecimal("42.0");
- DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), startDate, endDate, "test A", rate1, rate1, null, Currency.USD);
+ DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase A", startDate, endDate, rate1, rate1, null, Currency.USD);
invoiceItemDao.create(item1);
- DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), startDate, endDate, "test B", rate2, rate2, null, Currency.USD);
+ DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase B", startDate, endDate, rate2, rate2, null, Currency.USD);
invoiceItemDao.create(item2);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
@@ -426,10 +427,10 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate1 = new BigDecimal("17.0");
BigDecimal rate2 = new BigDecimal("42.0");
- DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), startDate, endDate, "test A", rate1, rate1, null, Currency.USD);
+ DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase A", startDate, endDate, rate1, rate1, null, Currency.USD);
invoiceItemDao.create(item1);
- DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), startDate, endDate, "test B", rate2, rate2, null, Currency.USD);
+ DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoice1.getId(), UUID.randomUUID(), "test plan", "test phase B", startDate, endDate, rate2, rate2, null, Currency.USD);
invoiceItemDao.create(item2);
DateTime upToDate;
@@ -452,7 +453,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate3 = new BigDecimal("21.0");
- DefaultInvoiceItem item3 = new DefaultInvoiceItem(invoice2.getId(), UUID.randomUUID(), startDate2, endDate2, "test C", rate3, rate3, null, Currency.USD);
+ DefaultInvoiceItem item3 = new DefaultInvoiceItem(invoice2.getId(), UUID.randomUUID(), "test plan", "test phase C", startDate2, endDate2, rate3, rate3, null, Currency.USD);
invoiceItemDao.create(item3);
upToDate = new DateTime(2011, 1, 1, 0, 0, 0, 0);
@@ -487,7 +488,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0, 0);
BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan1, phase1, null,
recurringPrice, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
- "testEvent1");
+ "testEvent1", SubscriptionTransitionType.CREATE);
BillingEventSet events = new BillingEventSet();
events.add(event1);
@@ -505,7 +506,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0, 0);
BillingEvent event2 = new DefaultBillingEvent(subscription, effectiveDate2, plan2, phase2, null,
recurringPrice2, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
- "testEvent2");
+ "testEvent2", SubscriptionTransitionType.CREATE);
events.add(event2);
// second invoice should be for one half (14/28 days) the difference between the rate plans
@@ -536,7 +537,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BillingEvent event = new DefaultBillingEvent(subscription, effectiveDate, plan, phase, null,
recurringPrice, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
- "testEvent");
+ "testEvent", SubscriptionTransitionType.CREATE);
BillingEventSet events = new BillingEventSet();
events.add(event);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
index 92a90b3..b2c2f23 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
@@ -45,7 +45,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
DateTime endDate = new DateTime(2011, 11, 1, 0, 0, 0, 0);
BigDecimal rate = new BigDecimal("20.00");
- InvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, endDate, "test", rate, rate, rate, Currency.USD);
+ InvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, endDate, rate, rate, rate, Currency.USD);
invoiceItemDao.create(item);
InvoiceItem thisItem = invoiceItemDao.getById(item.getId().toString());
@@ -55,7 +55,6 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
assertEquals(thisItem.getSubscriptionId(), item.getSubscriptionId());
assertEquals(thisItem.getStartDate(), item.getStartDate());
assertEquals(thisItem.getEndDate(), item.getEndDate());
- assertEquals(thisItem.getDescription(), item.getDescription());
assertEquals(thisItem.getRecurringAmount().compareTo(item.getRecurringAmount()), 0);
assertEquals(thisItem.getRecurringRate().compareTo(item.getRecurringRate()), 0);
assertEquals(thisItem.getFixedAmount().compareTo(item.getFixedAmount()), 0);
@@ -70,7 +69,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
for (int i = 0; i < 3; i++) {
UUID invoiceId = UUID.randomUUID();
- DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate.plusMonths(i), startDate.plusMonths(i + 1), "test", rate, rate, null, Currency.USD);
+ DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate.plusMonths(i), startDate.plusMonths(i + 1), rate, rate, null, Currency.USD);
invoiceItemDao.create(item);
}
@@ -87,7 +86,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
for (int i = 0; i < 5; i++) {
UUID subscriptionId = UUID.randomUUID();
BigDecimal amount = rate.multiply(new BigDecimal(i + 1));
- DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, startDate.plusMonths(1), "test", amount, amount, amount, Currency.USD);
+ DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, startDate.plusMonths(1), amount, amount, amount, Currency.USD);
invoiceItemDao.create(item);
}
@@ -108,7 +107,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
BigDecimal rate = new BigDecimal("20.00");
UUID subscriptionId = UUID.randomUUID();
- DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, startDate.plusMonths(1), "test", rate, rate, rate, Currency.USD);
+ DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", startDate, startDate.plusMonths(1), rate, rate, rate, Currency.USD);
invoiceItemDao.create(item);
List<InvoiceItem> items = invoiceItemDao.getInvoiceItemsByAccount(accountId.toString());
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index 659f183..8cd47ff 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -32,6 +32,7 @@ import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.dao.MockSubscription;
@@ -45,14 +46,12 @@ import org.testng.annotations.Test;
import javax.annotation.Nullable;
import java.math.BigDecimal;
-import java.util.List;
import java.util.UUID;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
@Test(groups = {"fast", "invoicing", "invoiceGenerator"})
public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
@@ -461,7 +460,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
BillingEvent event1 = new DefaultBillingEvent(subscription, new DateTime("2012-01-31T00:02:04.000Z"),
shotgun, shotgunMonthly,
zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
- BillingModeType.IN_ADVANCE, "Test Event 1");
+ BillingModeType.IN_ADVANCE, "Test Event 1", SubscriptionTransitionType.CREATE);
events.add(event1);
@@ -470,7 +469,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
BillingEvent event2 = new DefaultBillingEvent(subscription, new DateTime("2012-01-31T00:02:04.000Z"),
assaultRifle, assaultRifleMonthly,
zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
- BillingModeType.IN_ADVANCE, "Test Event 2");
+ BillingModeType.IN_ADVANCE, "Test Event 2", SubscriptionTransitionType.CREATE);
events.add(event2);
Plan pistol = new MockPlan();
@@ -481,21 +480,21 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
BillingEvent event3 = new DefaultBillingEvent(subscription, new DateTime("2012-01-31T00:02:05.000Z"),
pistol, pistolMonthlyTrial,
zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
- BillingModeType.IN_ADVANCE, "Test Event 3");
+ BillingModeType.IN_ADVANCE, "Test Event 3", SubscriptionTransitionType.CREATE);
events.add(event3);
BillingEvent event4 = new DefaultBillingEvent(subscription, new DateTime("2012-03-01T00:02:04.000Z"),
pistol, pistolMonthlyEvergreen,
null, pistolEvergreenPrice, BillingPeriod.MONTHLY, billCycleDay,
- BillingModeType.IN_ADVANCE, "Test Event 4");
+ BillingModeType.IN_ADVANCE, "Test Event 4",SubscriptionTransitionType.CREATE);
events.add(event4);
InvoiceItemList items = new InvoiceItemList();
UUID subscriptionId = UUID.randomUUID();
- InvoiceItem item1 = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, new DateTime("2012-01-30T16:02:04.000-08:00"), new DateTime("2012-01-30T16:02:04.000-08:00"), "1", ZERO, ZERO, ZERO, Currency.USD);
- InvoiceItem item2 = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, new DateTime("2012-02-29T16:02:04.000-08:00"), new DateTime("2012-02-29T16:02:04.000-08:00"), "2", ZERO, new BigDecimal("249.95"), ZERO, Currency.USD);
- InvoiceItem item3 = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, new DateTime("2012-01-30T16:02:04.000-08:00"), new DateTime("2012-01-30T16:02:04.000-08:00"), "3", ZERO, ZERO, ZERO, Currency.USD);
+ InvoiceItem item1 = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, shotgun.getName(), shotgunMonthly.getName(), new DateTime("2012-01-30T16:02:04.000-08:00"), new DateTime("2012-01-30T16:02:04.000-08:00"), ZERO, ZERO, ZERO, Currency.USD);
+ InvoiceItem item2 = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, assaultRifle.getName(), assaultRifleMonthly.getName(), new DateTime("2012-02-29T16:02:04.000-08:00"), new DateTime("2012-02-29T16:02:04.000-08:00"), ZERO, new BigDecimal("249.95"), ZERO, Currency.USD);
+ InvoiceItem item3 = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, pistol.getName(), pistolMonthlyTrial.getName(), new DateTime("2012-01-30T16:02:04.000-08:00"), new DateTime("2012-01-30T16:02:04.000-08:00"), ZERO, ZERO, ZERO, Currency.USD);
items.add(item1);
items.add(item2);
items.add(item3);
@@ -506,6 +505,42 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertTrue(invoice.getNumberOfItems() > 0);
}
+ @Test
+ public void testImmediateChange() {
+ UUID accountId = UUID.randomUUID();
+ Subscription subscription = new MockSubscription();
+ Plan plan1 = new MockPlan("plan 1");
+ PlanPhase phase1 = new MockPlanPhase(plan1, PhaseType.TRIAL);
+ Plan plan2 = new MockPlan("plan 2");
+ PlanPhase phase2 = new MockPlanPhase(plan2, PhaseType.TRIAL);
+ InternationalPrice zeroPrice = new MockInternationalPrice(new DefaultPrice(ZERO, Currency.USD));
+ BillingEventSet events = new BillingEventSet();
+
+ BillingEvent event1 = new DefaultBillingEvent(subscription, new DateTime("2012-01-31T00:02:04.000Z"),
+ plan1, phase1,
+ zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, 1,
+ BillingModeType.IN_ADVANCE, "Test Event 1",
+ SubscriptionTransitionType.CREATE);
+ events.add(event1);
+
+ Invoice invoice1 = generator.generateInvoice(accountId, events, null, new DateTime("2012-01-31T00:02:04.000Z"), Currency.USD);
+ assertNotNull(invoice1);
+ assertEquals(invoice1.getNumberOfItems(), 1);
+
+ BillingEvent event2 = new DefaultBillingEvent(subscription, new DateTime("2012-01-31T00:02:04.000Z"),
+ plan2, phase2,
+ zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, 1,
+ BillingModeType.IN_ADVANCE, "Test Event 2",
+ SubscriptionTransitionType.CHANGE);
+ events.add(event2);
+ InvoiceItemList items = new InvoiceItemList(invoice1.getInvoiceItems());
+ Invoice invoice2 = generator.generateInvoice(accountId, events, items, new DateTime("2012-01-31T00:02:04.000Z"), Currency.USD);
+
+ assertNotNull(invoice2);
+ assertEquals(invoice2.getNumberOfItems(), 1);
+ assertEquals(invoice2.getInvoiceItems().get(0).getPlanName(), plan2.getName());
+ }
+
private MockPlanPhase createMockMonthlyPlanPhase() {
return new MockPlanPhase(null, null, BillingPeriod.MONTHLY);
}
@@ -516,7 +551,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
}
private MockPlanPhase createMockMonthlyPlanPhase(@Nullable final BigDecimal recurringRate,
- final BigDecimal fixedRate, PhaseType phaseType) {
+ @Nullable final BigDecimal fixedRate, PhaseType phaseType) {
return new MockPlanPhase(new MockInternationalPrice(new DefaultPrice(recurringRate, Currency.USD)),
new MockInternationalPrice(new DefaultPrice(fixedRate, Currency.USD)),
BillingPeriod.MONTHLY, phaseType);
@@ -539,7 +574,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
return new DefaultBillingEvent(sub, startDate, plan, planPhase,
planPhase.getFixedPrice(),
planPhase.getRecurringPrice(), planPhase.getBillingPeriod(),
- billCycleDay, BillingModeType.IN_ADVANCE,"Test");
+ billCycleDay, BillingModeType.IN_ADVANCE,"Test", SubscriptionTransitionType.CREATE);
}
private void testInvoiceGeneration(final BillingEventSet events, final InvoiceItemList existingInvoiceItems,
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index 22d3c50..b722567 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -68,14 +68,14 @@ public abstract class TestPaymentApi {
final UUID subscriptionId = UUID.randomUUID();
invoice.addInvoiceItem(new DefaultInvoiceItem(invoice.getId(),
- subscriptionId,
- now,
- now.plusMonths(1),
- "Test",
- amount,
- new BigDecimal("1.0"),
- null,
- Currency.USD));
+ subscriptionId,
+ "test plan", "test phase",
+ now,
+ now.plusMonths(1),
+ amount,
+ new BigDecimal("1.0"),
+ null,
+ Currency.USD));
List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()));
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index b4df1ba..2bae34b 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -68,9 +68,10 @@ public class TestHelper {
for (InvoiceItem item : items) {
invoice.addInvoiceItem(new DefaultInvoiceItem(invoice.getId(),
item.getSubscriptionId(),
+ item.getPlanName(),
+ item.getPhaseName(),
item.getStartDate(),
item.getEndDate(),
- item.getDescription(),
item.getRecurringAmount(),
item.getRecurringRate(),
item.getFixedAmount(),
@@ -84,7 +85,7 @@ public class TestHelper {
final DateTime now = new DateTime(DateTimeZone.UTC);
final UUID subscriptionId = UUID.randomUUID();
final BigDecimal amount = new BigDecimal("10.00");
- final InvoiceItem item = new DefaultInvoiceItem(null, subscriptionId, now, now.plusMonths(1), "Test", amount, new BigDecimal("1.0"), null, Currency.USD);
+ final InvoiceItem item = new DefaultInvoiceItem(null, subscriptionId, "test plan", "test phase", now, now.plusMonths(1), amount, new BigDecimal("1.0"), null, Currency.USD);
return createTestInvoice(account, now, Currency.USD, item);
}