killbill-aplcache

improve checks for existence of accounts on create/update;

1/6/2012 10:34:20 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 2975ed3..5c32c00 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
@@ -69,7 +69,13 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
         this.currency = currency;
         this.billCycleDay = billCycleDay;
         this.paymentProviderName = paymentProviderName;
-        this.balance = balance;
+
+        if (balance == null) {
+            this.balance = BigDecimal.ZERO;
+        } else {
+            this.balance = balance;
+        }
+
         this.timeZone = timeZone;
         this.locale = locale;
         this.nextBillingDate = nextBillingDate;
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 2b51693..6a86605 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
@@ -34,7 +34,7 @@ public class AccountBuilder {
     private Currency currency;
     private int billingCycleDay;
     private String paymentProviderName;
-    private BigDecimal balance;
+    private BigDecimal balance = BigDecimal.ZERO;
     private DateTimeZone timeZone;
     private String locale;
     private DateTime nextBillingDate;
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeNotification.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeNotification.java
index 178100f..297b16d 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeNotification.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeNotification.java
@@ -75,6 +75,17 @@ public class DefaultAccountChangeNotification implements AccountChangeNotificati
 
         addIfValueChanged(tmpChangedFields,"paymentProviderName",
                 oldData.getPaymentProviderName(), newData.getPaymentProviderName());
+
+        addIfValueChanged(tmpChangedFields, "locale", oldData.getLocale(), newData.getLocale());
+
+        addIfValueChanged(tmpChangedFields, "timeZone",
+                oldData.getTimeZone().toString(),
+                newData.getTimeZone().toString());
+
+        addIfValueChanged(tmpChangedFields, "nextBillingDate",
+                oldData.getNextBillingDate().toString(),
+                newData.getNextBillingDate().toString());
+
         return tmpChangedFields;
     }
 
@@ -85,7 +96,7 @@ public class DefaultAccountChangeNotification implements AccountChangeNotificati
         // If only one is null
         } else if (newData == null || oldData == null) {
             inputList.add(new DefaultChangedField(key, oldData, newData));
-        // If non are null we can safely compare values
+        // If neither are null we can safely compare values
         } else if (!newData.equals(oldData)) {
             inputList.add(new DefaultChangedField(key, oldData, newData));
         }
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index d6bf995..08080b4 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -38,19 +38,12 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
 
     @Override
     public Account createAccount(final AccountData data, final List<CustomField> fields, List<Tag> tags) throws AccountApiException {
-        String key = data.getExternalKey();
-        Account existingAccount = dao.getAccountByKey(key);
+        Account account = new DefaultAccount(data);
+        account.addFields(fields);
+        account.addTags(tags);
 
-        if (existingAccount == null) {
-            Account account = new DefaultAccount(data);
-            account.addFields(fields);
-            account.addTags(tags);
-
-            dao.create(account);
-            return account;
-        } else {
-            throw new AccountApiException(ErrorCode.ACCOUNT_ALREADY_EXISTS, key);
-        }
+        dao.create(account);
+        return account;
     }
 
     @Override
diff --git a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
index 5b4ed6e..1724095 100644
--- a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
@@ -22,7 +22,9 @@ import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
 import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountChangeNotification;
 import com.ning.billing.account.api.AccountCreationNotification;
 import com.ning.billing.account.api.DefaultAccount;
@@ -125,20 +127,33 @@ public class DefaultAccountDao implements AccountDao {
 
     @Override
     public void create(final Account account) {
-        final String accountId = account.getId().toString();
+        final String key = account.getExternalKey();
         final String objectType = DefaultAccount.OBJECT_TYPE;
 
         accountDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
             @Override
             public Void inTransaction(AccountSqlDao accountDao, TransactionStatus status) throws Exception {
-                Account currentAccount = accountDao.getById(accountId);
+                Account currentAccount = accountDao.getAccountByKey(key);
+                if (currentAccount != null) {
+                    throw new AccountApiException(ErrorCode.ACCOUNT_ALREADY_EXISTS, account.getExternalKey());
+                }
+
                 accountDao.create(account);
 
+                String accountId = account.getId().toString();
                 FieldStoreDao fieldStoreDao = accountDao.become(FieldStoreDao.class);
-                fieldStoreDao.save(accountId, objectType, account.getFieldList());
+
+                List<CustomField> fieldList = account.getFieldList();
+                if (fieldList != null) {
+                    fieldStoreDao.save(accountId, objectType, account.getFieldList());
+                }
 
                 TagStoreDao tagStoreDao = fieldStoreDao.become(TagStoreDao.class);
-                tagStoreDao.save(accountId, objectType, account.getTagList());
+
+                List<Tag> tagList = account.getTagList();
+                if (tagList != null) {
+                    tagStoreDao.save(accountId, objectType, account.getTagList());
+                }
 
                 AccountCreationNotification creationEvent = new DefaultAccountCreationEvent(account);
                 eventBus.post(creationEvent);
@@ -150,23 +165,36 @@ public class DefaultAccountDao implements AccountDao {
 
     @Override
     public void update(final Account account) {
-        final String accountId = account.getId().toString();
+        final String key = account.getExternalKey();
         final String objectType = DefaultAccount.OBJECT_TYPE;
 
         accountDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
             @Override
             public Void inTransaction(AccountSqlDao accountDao, TransactionStatus status) throws Exception {
-                Account currentAccount = accountDao.getById(accountId);
+                Account currentAccount = accountDao.getAccountByKey(key);
+
+                if (currentAccount == null) {
+                    throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST, key);
+                }
 
                 accountDao.update(account);
 
+                String accountId = account.getId().toString();
                 FieldStoreDao fieldStoreDao = accountDao.become(FieldStoreDao.class);
                 fieldStoreDao.clear(accountId, objectType);
-                fieldStoreDao.save(accountId, objectType, account.getFieldList());
+
+                List<CustomField> fieldList = account.getFieldList();
+                if (fieldList != null) {
+                    fieldStoreDao.save(accountId, objectType, account.getFieldList());
+                }
 
                 TagStoreDao tagStoreDao = fieldStoreDao.become(TagStoreDao.class);
                 tagStoreDao.clear(accountId, objectType);
-                tagStoreDao.save(accountId, objectType, account.getTagList());
+
+                List<Tag> tagList = account.getTagList();
+                if (tagList != null) {
+                    tagStoreDao.save(accountId, objectType, tagList);
+                }
 
                 AccountChangeNotification changeEvent = new DefaultAccountChangeNotification(account.getId(), currentAccount, account);
                 if (changeEvent.hasChanges()) {
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 b3b1882..2ecbe48 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
@@ -49,10 +49,13 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
         String thisEmail = email + " " + UUID.randomUUID();
         String name = firstName + " " + lastName;
         String phone = "123-456-7890";
+        String locale = "EN-US";
+        DateTimeZone timeZone = DateTimeZone.forID("America/Los_Angeles");
 
         int firstNameLength = firstName.length();
         return new AccountBuilder().externalKey(thisKey).name(name).phone(phone).firstNameLength(firstNameLength)
-                                   .email(thisEmail).currency(Currency.USD).build();
+                                   .email(thisEmail).currency(Currency.USD).locale(locale)
+                                   .timeZone(timeZone).build();
     }
 
     public void testBasic() {
@@ -187,7 +190,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
 
             @Override
             public String getLocale() {
-                return "EN-GB";
+                return "FR-CA";
             }
 
             @Override
@@ -208,6 +211,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
         assertEquals(savedAccount.getPaymentProviderName(), updatedAccount.getPaymentProviderName());
         assertEquals(savedAccount.getBillCycleDay(), updatedAccount.getBillCycleDay());
         assertEquals(savedAccount.getFirstNameLength(), updatedAccount.getFirstNameLength());
-
+        assertEquals(savedAccount.getTimeZone(), updatedAccount.getTimeZone());
+        assertEquals(savedAccount.getLocale(), updatedAccount.getLocale());
     }
 }
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 8e3352c..cfff7a7 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -90,7 +90,8 @@ public enum ErrorCode {
     *
     */
     ACCOUNT_ALREADY_EXISTS(3000, "Account already exists for key %s"),
-    ACCOUNT_INVALID_NAME(3001, "An invalid name was specified when creating or updating an account.")
+    ACCOUNT_INVALID_NAME(3001, "An invalid name was specified when creating or updating an account."),
+    ACCOUNT_DOES_NOT_EXIST(3002, "Account does not exist for key %s")
     ;
 
     private int code;