diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
index baf703f..166c884 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
@@ -40,6 +40,7 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
public class BillCycleDayCalculator {
@@ -84,7 +85,7 @@ public class BillCycleDayCalculator {
switch (alignment) {
case ACCOUNT:
result = account.getBillCycleDay();
- if (result.getDayOfMonthUTC() == 0) {
+ if (result == null || result.getDayOfMonthUTC() == 0) {
result = calculateBcdFromSubscription(subscription, plan, account);
}
break;
@@ -110,7 +111,8 @@ public class BillCycleDayCalculator {
return result;
}
- private BillCycleDay calculateBcdFromSubscription(final Subscription subscription, final Plan plan, final Account account) throws AccountApiException {
+ @VisibleForTesting
+ BillCycleDay calculateBcdFromSubscription(final Subscription subscription, final Plan plan, final Account account) throws AccountApiException {
final DateTime date = plan.dateOfFirstRecurringNonZeroCharge(subscription.getStartDate());
// There are really two kinds of billCycleDay:
// - a System billingCycleDay which should be computed from UTC time (in order to get the correct notification time at
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
new file mode 100644
index 0000000..1e3104d
--- /dev/null
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillCycleDayCalculator.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010-2012 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.junction.plumbing.billing;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.BillCycleDay;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.Subscription;
+
+public class TestBillCycleDayCalculator {
+
+ @Test(groups = "fast")
+ public void testCalculateBCDWithTimeZoneHST() throws Exception {
+ final DateTimeZone accountTimeZone = DateTimeZone.forID("HST");
+ final DateTime startDateUTC = new DateTime("2012-07-16T21:17:03.000Z", DateTimeZone.UTC);
+ final int bcdUTC = 16;
+ final int bcdLocal = 16;
+
+ verifyBCDCalculation(accountTimeZone, startDateUTC, bcdUTC, bcdLocal);
+ }
+
+ @Test(groups = "fast")
+ public void testCalculateBCDWithTimeZoneCEST() throws Exception {
+ final DateTimeZone accountTimeZone = DateTimeZone.forID("Europe/Paris");
+ final DateTime startDateUTC = new DateTime("2012-07-16T21:17:03.000Z", DateTimeZone.UTC);
+ final int bcdUTC = 16;
+ final int bcdLocal = 16;
+
+ verifyBCDCalculation(accountTimeZone, startDateUTC, bcdUTC, bcdLocal);
+ }
+
+ @Test(groups = "fast")
+ public void testCalculateBCDWithTimeZoneUTC() throws Exception {
+ final DateTimeZone accountTimeZone = DateTimeZone.UTC;
+ final DateTime startDateUTC = new DateTime("2012-07-16T21:17:03.000Z", DateTimeZone.UTC);
+ final int bcdUTC = 16;
+ final int bcdLocal = 16;
+
+ verifyBCDCalculation(accountTimeZone, startDateUTC, bcdUTC, bcdLocal);
+ }
+
+ @Test(groups = "fast")
+ public void testCalculateBCDWithTimeZoneEEST() throws Exception {
+ final DateTimeZone accountTimeZone = DateTimeZone.forID("+0300");
+ final DateTime startDateUTC = new DateTime("2012-07-16T21:17:03.000Z", DateTimeZone.UTC);
+ final int bcdUTC = 16;
+ final int bcdLocal = 17;
+
+ verifyBCDCalculation(accountTimeZone, startDateUTC, bcdUTC, bcdLocal);
+ }
+
+ @Test(groups = "fast")
+ public void testCalculateBCDWithTimeZoneJST() throws Exception {
+ final DateTimeZone accountTimeZone = DateTimeZone.forID("Asia/Tokyo");
+ final DateTime startDateUTC = new DateTime("2012-07-16T21:17:03.000Z", DateTimeZone.UTC);
+ final int bcdUTC = 16;
+ final int bcdLocal = 17;
+
+ verifyBCDCalculation(accountTimeZone, startDateUTC, bcdUTC, bcdLocal);
+ }
+
+ private void verifyBCDCalculation(final DateTimeZone accountTimeZone, final DateTime startDateUTC, final int bcdUTC, final int bcdLocal) throws AccountApiException {
+ final BillCycleDayCalculator billCycleDayCalculator = new BillCycleDayCalculator(Mockito.mock(CatalogService.class), Mockito.mock(EntitlementUserApi.class));
+
+ final Subscription subscription = Mockito.mock(Subscription.class);
+ Mockito.when(subscription.getStartDate()).thenReturn(startDateUTC);
+
+ final Plan plan = Mockito.mock(Plan.class);
+ Mockito.when(plan.dateOfFirstRecurringNonZeroCharge(startDateUTC)).thenReturn(startDateUTC);
+
+ final Account account = Mockito.mock(Account.class);
+ Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone);
+
+ final BillCycleDay bcd = billCycleDayCalculator.calculateBcdFromSubscription(subscription, plan, account);
+ Assert.assertEquals(bcd.getDayOfMonthUTC(), bcdUTC);
+ Assert.assertEquals(bcd.getDayOfMonthLocal(), bcdLocal);
+ }
+}