killbill-aplcache

add time zone, locale, and next billing date to Account; move

1/6/2012 9:29:56 PM

Details

diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
index b953707..2975ed3 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
@@ -20,6 +20,7 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.customfield.CustomizableEntityBase;
 import com.ning.billing.util.tag.DefaultTag;
@@ -40,22 +41,25 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
     private final String paymentProviderName;
     private final BigDecimal balance;
     private final DefaultTagStore tags;
+    private final DateTimeZone timeZone;
+    private final String locale;
+    private final DateTime nextBillingDate;
 
-    public DefaultAccount(AccountData data) {
-        this(UUID.randomUUID(), data.getExternalKey(), data.getEmail(), data.getName(),
-                data.getFirstNameLength(), data.getPhone(), data.getCurrency(), data.getBillCycleDay(),
-                data.getPaymentProviderName(), BigDecimal.ZERO);
+    public DefaultAccount(final AccountData data) {
+        this(UUID.randomUUID(), data);
     }
 
-    public DefaultAccount(UUID id, AccountData data) {
+    public DefaultAccount(final UUID id, final AccountData data) {
         this(id, data.getExternalKey(), data.getEmail(), data.getName(),
                 data.getFirstNameLength(), data.getPhone(), data.getCurrency(), data.getBillCycleDay(),
-                data.getPaymentProviderName(), BigDecimal.ZERO);
+                data.getPaymentProviderName(), BigDecimal.ZERO, data.getTimeZone(), data.getLocale(),
+                data.getNextBillingDate());
     }
 
-    public DefaultAccount(UUID id, String externalKey, String email, String name, int firstNameLength,
-                          String phone, Currency currency, int billCycleDay, String paymentProviderName,
-                          BigDecimal balance) {
+    public DefaultAccount(final UUID id, final String externalKey, final String email, final String name, final int firstNameLength,
+                          final String phone, final Currency currency, final int billCycleDay, final String paymentProviderName,
+                          final BigDecimal balance, final DateTimeZone timeZone, final String locale,
+                          final DateTime nextBillingDate) {
         super(id);
         this.externalKey = externalKey;
         this.email = email;
@@ -66,6 +70,9 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
         this.billCycleDay = billCycleDay;
         this.paymentProviderName = paymentProviderName;
         this.balance = balance;
+        this.timeZone = timeZone;
+        this.locale = locale;
+        this.nextBillingDate = nextBillingDate;
 
         this.tags = new DefaultTagStore(id, getObjectName());
     }
@@ -116,6 +123,26 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
     }
 
     @Override
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    @Override
+    public DateTimeZone getTimeZone() {
+        return timeZone;
+    }
+
+    @Override
+    public String getLocale() {
+        return locale;
+    }
+
+    @Override
+    public DateTime getNextBillingDate() {
+        return nextBillingDate;
+    }
+
+    @Override
     public List<Tag> getTagList() {
         return tags.getEntityList();
     }
@@ -157,9 +184,4 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
     public boolean processPayment() {
         return tags.processPayment();
     }
-
-    @Override
-    public BigDecimal getBalance() {
-        return balance;
-    }
 }
\ No newline at end of file
diff --git a/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java b/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
index e05e967..2b51693 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
@@ -21,6 +21,8 @@ import com.ning.billing.catalog.api.Currency;
 
 import java.math.BigDecimal;
 import java.util.UUID;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 
 public class AccountBuilder {
     private UUID id;
@@ -33,31 +35,34 @@ public class AccountBuilder {
     private int billingCycleDay;
     private String paymentProviderName;
     private BigDecimal balance;
+    private DateTimeZone timeZone;
+    private String locale;
+    private DateTime nextBillingDate;
 
     public AccountBuilder() {
         this(UUID.randomUUID());
     }
 
-    public AccountBuilder(UUID id) {
+    public AccountBuilder(final UUID id) {
         this.id = id;
     }
 
-    public AccountBuilder externalKey(String externalKey) {
+    public AccountBuilder externalKey(final String externalKey) {
         this.externalKey = externalKey;
         return this;
     }
 
-    public AccountBuilder email(String email) {
+    public AccountBuilder email(final String email) {
         this.email = email;
         return this;
     }
 
-    public AccountBuilder name(String name) {
+    public AccountBuilder name(final String name) {
         this.name = name;
         return this;
     }
 
-    public AccountBuilder firstNameLength(int firstNameLength) {
+    public AccountBuilder firstNameLength(final int firstNameLength) {
         this.firstNameLength = firstNameLength;
         return this;
     }
@@ -67,28 +72,44 @@ public class AccountBuilder {
         return this;
     }
 
-    public AccountBuilder billingCycleDay(int billingCycleDay) {
+    public AccountBuilder billingCycleDay(final int billingCycleDay) {
         this.billingCycleDay = billingCycleDay;
         return this;
     }
 
-    public AccountBuilder currency(Currency currency) {
+    public AccountBuilder currency(final Currency currency) {
         this.currency = currency;
         return this;
     }
 
-    public AccountBuilder paymentProviderName(String paymentProviderName) {
+    public AccountBuilder paymentProviderName(final String paymentProviderName) {
         this.paymentProviderName = paymentProviderName;
         return this;
     }
 
-    public AccountBuilder balance(BigDecimal balance) {
+    public AccountBuilder balance(final BigDecimal balance) {
         this.balance = balance;
         return this;
     }
 
+    public AccountBuilder timeZone(final DateTimeZone timeZone) {
+        this.timeZone = timeZone;
+        return this;
+    }
+
+    public AccountBuilder locale(final String locale) {
+        this.locale = locale;
+        return this;
+    }
+
+    public AccountBuilder nextBillingDate(final DateTime nextBillingDate) {
+        this.nextBillingDate = nextBillingDate;
+        return this;
+    }
+
     public DefaultAccount build() {
         return new DefaultAccount(id, externalKey, email, name, firstNameLength,
-                                  phone, currency, billingCycleDay, paymentProviderName, balance);
+                                  phone, currency, billingCycleDay, paymentProviderName,
+                                  balance, timeZone, locale, nextBillingDate);
     }
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
index 21122e2..c57362d 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
@@ -22,6 +22,8 @@ import com.ning.billing.account.api.user.AccountBuilder;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.UuidMapper;
 import com.ning.billing.util.entity.EntityDao;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
@@ -44,6 +46,7 @@ import java.lang.annotation.Target;
 import java.math.BigDecimal;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Timestamp;
 import java.util.UUID;
 
 @ExternalizedSqlViaStringTemplate3
@@ -73,15 +76,28 @@ public interface AccountSqlDao extends EntityDao<Account>, Transactional<Account
             int firstNameLength = result.getInt("first_name_length");
             String phone = result.getString("phone");
             int billingCycleDay = result.getInt("billing_cycle_day");
+
             String currencyString = result.getString("currency");
             Currency currency = (currencyString == null) ? null : Currency.valueOf(currencyString);
+
             String paymentProviderName = result.getString("payment_provider_name");
 
+            String timeZoneId = result.getString("time_zone");
+            DateTimeZone timeZone = (timeZoneId == null) ? null : DateTimeZone.forID(timeZoneId);
+
+            String locale = result.getString("locale");
+
+            Timestamp nextBillingDateTimestamp = result.getTimestamp("next_billing_date");
+            DateTime nextBillingDate = nextBillingDateTimestamp == null ? null : new DateTime(nextBillingDateTimestamp);
+
             return new AccountBuilder(id).externalKey(externalKey).email(email)
                                          .name(name).firstNameLength(firstNameLength)
                                          .phone(phone).currency(currency)
                                          .billingCycleDay(billingCycleDay)
                                          .paymentProviderName(paymentProviderName)
+                                         .timeZone(timeZone)
+                                         .locale(locale)
+                                         .nextBillingDate(nextBillingDate)
                                          .build();
         }
     }
@@ -100,10 +116,20 @@ public interface AccountSqlDao extends EntityDao<Account>, Transactional<Account
                         q.bind("name", account.getName());
                         q.bind("firstNameLength", account.getFirstNameLength());
                         q.bind("phone", account.getPhone());
+
                         Currency currency = account.getCurrency();
                         q.bind("currency", (currency == null) ? null : currency.toString());
+
                         q.bind("billingCycleDay", account.getBillCycleDay());
                         q.bind("paymentProviderName", account.getPaymentProviderName());
+
+                        DateTimeZone timeZone = account.getTimeZone();
+                        q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
+
+                        q.bind("locale", account.getLocale());
+
+                        DateTime nextBillingDate = account.getNextBillingDate();
+                        q.bind("nextBillingDate", (nextBillingDate == null) ? null : nextBillingDate.toDate());
                     }
                 };
             }
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
index 4f6a9f9..097a0b6 100644
--- a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
@@ -2,34 +2,38 @@ group AccountDaoSql;
 
 create() ::= <<
     INSERT INTO accounts
-    (id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day, payment_provider_name)
+      (id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day,
+      payment_provider_name, time_zone, locale, next_billing_date)
     VALUES
-    (:id, :externalKey, :email, :name, :firstNameLength, :phone, :currency, :billingCycleDay, :paymentProviderName);
+      (:id, :externalKey, :email, :name, :firstNameLength, :phone, :currency, :billingCycleDay,
+      :paymentProviderName, :timeZone, :locale, :nextBillingDate);
 >>
 
 update() ::= <<
     UPDATE accounts
     SET email = :email, name = :name, first_name_length = :firstNameLength, phone = :phone,
-        currency = :currency, billing_cycle_day = :billingCycleDay, payment_provider_name = :paymentProviderName
+        currency = :currency, billing_cycle_day = :billingCycleDay, payment_provider_name = :paymentProviderName,
+        time_zone = :timeZone, locale = :locale, next_billing_date = :nextBillingDate
     WHERE id = :id AND external_key = :externalKey;
 >>
 
 getAccountByKey() ::= <<
-    select id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day, payment_provider_name
+    select id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day,
+      payment_provider_name, time_zone, locale, next_billing_date
     from accounts
     where external_key = :externalKey;
 >>
 
 getById() ::= <<
-    select
-      a.id, a.external_key, a.email, a.name, a.first_name_length,
-      a.phone, a.currency, a.billing_cycle_day, a.payment_provider_name
-    from accounts a
-    where a.id = :id;
+    select id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day,
+      payment_provider_name, time_zone, locale, next_billing_date
+    from accounts
+    where id = :id;
 >>
 
 get() ::= <<
-    select id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day, payment_provider_name
+    select id, external_key, email, name, first_name_length, phone, currency, billing_cycle_day,
+      payment_provider_name, time_zone, locale, next_billing_date
     from accounts;
 >>
 
diff --git a/account/src/main/resources/com/ning/billing/account/ddl.sql b/account/src/main/resources/com/ning/billing/account/ddl.sql
index ccfed72..e8b0bcc 100644
--- a/account/src/main/resources/com/ning/billing/account/ddl.sql
+++ b/account/src/main/resources/com/ning/billing/account/ddl.sql
@@ -9,6 +9,9 @@ CREATE TABLE accounts (
     currency char(3) DEFAULT NULL,
     billing_cycle_day int DEFAULT NULL,
     payment_provider_name varchar(20) DEFAULT NULL,
+    time_zone varchar(50) DEFAULT NULL,
+    locale varchar(5) DEFAULT NULL,
+    next_billing_date datetime DEFAULT NULL,
     PRIMARY KEY(id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX accounts_external_key ON accounts(external_key);
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
index a4b0b98..b3b1882 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
@@ -19,6 +19,7 @@ package com.ning.billing.account.dao;
 import java.util.List;
 import java.util.UUID;
 import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.testng.annotations.Test;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
@@ -179,6 +180,20 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
             public String getPaymentProviderName() {
                 return account.getPaymentProviderName();
             }
+            @Override
+            public DateTimeZone getTimeZone() {
+                return DateTimeZone.forID("Australia/Darwin");
+            }
+
+            @Override
+            public String getLocale() {
+                return "EN-GB";
+            }
+
+            @Override
+            public DateTime getNextBillingDate() {
+                return null;
+            }
         };
 
         Account updatedAccount = new DefaultAccount(account.getId(), accountData);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
index 3b38c8c..7488d5b 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.catalog.api.Currency;
@@ -88,6 +89,21 @@ public class MockAccount implements Account
     }
 
     @Override
+    public DateTimeZone getTimeZone() {
+        return DateTimeZone.forID("Pacific/Fiji");
+    }
+
+    @Override
+    public String getLocale() {
+        return "EN-US";
+    }
+
+    @Override
+    public DateTime getNextBillingDate() {
+        return null;
+    }
+
+    @Override
     public UUID getId()
     {
         return id;
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountData.java b/api/src/main/java/com/ning/billing/account/api/AccountData.java
index 9b8f399..62195e5 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountData.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountData.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.account.api;
 
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.entity.Entity;
 
@@ -36,4 +38,10 @@ public interface AccountData {
     public Currency getCurrency();
 
     public String getPaymentProviderName();
+
+    public DateTimeZone getTimeZone();
+
+    public String getLocale();
+
+    public DateTime getNextBillingDate();
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
index ff3a443..9e06be2 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
@@ -22,6 +22,7 @@ import java.net.URL;
 import java.util.List;
 import java.util.UUID;
 import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -310,6 +311,20 @@ public abstract class TestApiBase {
             public String getPaymentProviderName() {
                 return "Paypal";
             }
+            @Override
+            public DateTimeZone getTimeZone() {
+                return DateTimeZone.forID("Europe/Paris");
+            }
+
+            @Override
+            public String getLocale() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public DateTime getNextBillingDate() {
+                return null;
+            }
         };
         return accountData;
     }
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 a3ff37d..5d8b44f 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -11,7 +11,6 @@ CREATE TABLE invoice_items (
   currency char(3) NOT NULL,
   PRIMARY KEY(id)
 ) ENGINE=innodb;
-
 CREATE INDEX invoice_items_subscription_id ON invoice_items(subscription_id ASC);
 
 DROP TABLE IF EXISTS invoices;
@@ -23,7 +22,6 @@ CREATE TABLE invoices (
   currency char(3) NOT NULL,
   PRIMARY KEY(id)
 ) ENGINE=innodb;
-
 CREATE INDEX invoices_account_id ON invoices(account_id ASC);
 
 DROP TABLE IF EXISTS invoice_payments;
diff --git a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
new file mode 100644
index 0000000..d2c44a4
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util.tag;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.DefaultClock;
+import com.ning.billing.util.tag.dao.TagDescriptionDao;
+import com.ning.billing.util.tag.dao.TagStoreDao;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+@Test(groups={"util"})
+public class TestTagStore {
+    private final static String ACCOUNT_TYPE = "ACCOUNT";
+    private final Clock clock = new DefaultClock();
+    private final MysqlTestingHelper helper = new MysqlTestingHelper();
+    private IDBI dbi;
+    private TagDescription tag1;
+    private TagDescription tag2;
+
+    @BeforeClass(alwaysRun = true)
+    protected void setup() throws IOException {
+        // Health check test to make sure MySQL is setup properly
+        try {
+            final String utilDdl = IOUtils.toString(TestTagStore.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+
+            helper.startMysql();
+            helper.initDb(utilDdl);
+
+            dbi = helper.getDBI();
+
+            tag1 = new DefaultTagDescription("tag1", "First tag", true, true, "test", clock.getUTCNow());
+            tag2 = new DefaultTagDescription("tag2", "Second tag", false, false, "test", clock.getUTCNow());
+
+            TagDescriptionDao dao = dbi.onDemand(TagDescriptionDao.class);
+            dao.create(tag1);
+            dao.create(tag2);
+        }
+        catch (Throwable t) {
+            fail(t.toString());
+        }
+    }
+
+    @AfterClass(alwaysRun = true)
+    public void stopMysql()
+    {
+        helper.stopMysql();
+    }
+
+    @Test
+    public void testTagCreationAndRetrieval() {
+        UUID accountId = UUID.randomUUID();
+
+        TagStore tagStore = new DefaultTagStore(accountId, ACCOUNT_TYPE);
+        Tag tag = new DefaultTag(tag2, "test", clock.getUTCNow());
+        tagStore.add(tag);
+
+        TagStoreDao dao = dbi.onDemand(TagStoreDao.class);
+        dao.save(accountId.toString(), ACCOUNT_TYPE, tagStore.getEntityList());
+
+        List<Tag> savedTags = dao.load(accountId.toString(), ACCOUNT_TYPE);
+        assertEquals(savedTags.size(), 1);
+
+        Tag savedTag = savedTags.get(0);
+        assertEquals(savedTag.getTagDescriptionId(), tag.getTagDescriptionId());
+        assertEquals(savedTag.getAddedBy(), tag.getAddedBy());
+        assertEquals(savedTag.getDateAdded().compareTo(tag.getDateAdded()), 0);
+        assertEquals(savedTag.getGenerateInvoice(), tag.getGenerateInvoice());
+        assertEquals(savedTag.getName(), tag.getName());
+        assertEquals(savedTag.getProcessPayment(), tag.getProcessPayment());
+        assertEquals(savedTag.getId(), tag.getId());
+    }
+}