killbill-aplcache

Details

diff --git a/account/src/main/java/org/killbill/billing/account/api/DefaultAccount.java b/account/src/main/java/org/killbill/billing/account/api/DefaultAccount.java
index 957b2e2..37c3b55 100644
--- a/account/src/main/java/org/killbill/billing/account/api/DefaultAccount.java
+++ b/account/src/main/java/org/killbill/billing/account/api/DefaultAccount.java
@@ -37,6 +37,7 @@ public class DefaultAccount extends EntityBase implements Account {
     private final String name;
     private final Integer firstNameLength;
     private final Currency currency;
+    private final UUID parentAccountId;
     private final Integer billCycleDayLocal;
     private final UUID paymentMethodId;
     private final DateTimeZone timeZone;
@@ -65,6 +66,7 @@ public class DefaultAccount extends EntityBase implements Account {
              data.getName(),
              data.getFirstNameLength(),
              data.getCurrency(),
+             data.getParentAccountId(),
              data.getBillCycleDayLocal(),
              data.getPaymentMethodId(),
              data.getTimeZone(),
@@ -84,7 +86,8 @@ public class DefaultAccount extends EntityBase implements Account {
     // This call is used for testing and update from an existing account
     public DefaultAccount(final UUID id, final String externalKey, final String email,
                           final String name, final Integer firstNameLength,
-                          final Currency currency, final Integer billCycleDayLocal, final UUID paymentMethodId,
+                          final Currency currency, final UUID parentAccountId,
+                          final Integer billCycleDayLocal, final UUID paymentMethodId,
                           final DateTimeZone timeZone, final String locale,
                           final String address1, final String address2, final String companyName,
                           final String city, final String stateOrProvince, final String country,
@@ -98,6 +101,7 @@ public class DefaultAccount extends EntityBase implements Account {
              name,
              firstNameLength,
              currency,
+             parentAccountId,
              billCycleDayLocal,
              paymentMethodId,
              timeZone,
@@ -117,7 +121,8 @@ public class DefaultAccount extends EntityBase implements Account {
     public DefaultAccount(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate,
                           final String externalKey, final String email,
                           final String name, final Integer firstNameLength,
-                          final Currency currency, final Integer billCycleDayLocal, final UUID paymentMethodId,
+                          final Currency currency, final UUID parentAccountId,
+                          final Integer billCycleDayLocal, final UUID paymentMethodId,
                           final DateTimeZone timeZone, final String locale,
                           final String address1, final String address2, final String companyName,
                           final String city, final String stateOrProvince, final String country,
@@ -129,6 +134,7 @@ public class DefaultAccount extends EntityBase implements Account {
         this.name = name;
         this.firstNameLength = firstNameLength;
         this.currency = currency;
+        this.parentAccountId = parentAccountId;
         this.billCycleDayLocal = billCycleDayLocal == null ? DEFAULT_BILLING_CYCLE_DAY_LOCAL : billCycleDayLocal;
         this.paymentMethodId = paymentMethodId;
         this.timeZone = timeZone;
@@ -154,6 +160,7 @@ public class DefaultAccount extends EntityBase implements Account {
              accountModelDao.getName(),
              accountModelDao.getFirstNameLength(),
              accountModelDao.getCurrency(),
+             accountModelDao.getParentAccountId(),
              accountModelDao.getBillingCycleDayLocal(),
              accountModelDao.getPaymentMethodId(),
              accountModelDao.getTimeZone(),
@@ -196,6 +203,11 @@ public class DefaultAccount extends EntityBase implements Account {
     }
 
     @Override
+    public UUID getParentAccountId() {
+        return parentAccountId;
+    }
+
+    @Override
     public Integer getBillCycleDayLocal() {
         return billCycleDayLocal;
     }
@@ -327,6 +339,7 @@ public class DefaultAccount extends EntityBase implements Account {
         accountData.setCountry(country != null ? country : currentAccount.getCountry());
         accountData.setPostalCode(postalCode != null ? postalCode : currentAccount.getPostalCode());
         accountData.setPhone(phone != null ? phone : currentAccount.getPhone());
+        accountData.setParentAccountId(parentAccountId != null ? parentAccountId : currentAccount.getParentAccountId());
         final Boolean isMigrated = this.isMigrated != null ? this.isMigrated : currentAccount.isMigrated();
         if (isMigrated != null) {
             accountData.setIsMigrated(isMigrated);
@@ -351,6 +364,7 @@ public class DefaultAccount extends EntityBase implements Account {
                ", firstNameLength=" + firstNameLength +
                ", phone=" + phone +
                ", currency=" + currency +
+               ", parentAccountId=" + parentAccountId +
                ", billCycleDayLocal=" + billCycleDayLocal +
                ", paymentMethodId=" + paymentMethodId +
                ", timezone=" + timeZone +
@@ -400,6 +414,9 @@ public class DefaultAccount extends EntityBase implements Account {
         if (currency != that.currency) {
             return false;
         }
+        if (parentAccountId != null ? !parentAccountId.equals(that.parentAccountId) : that.parentAccountId != null) {
+            return false;
+        }
         if (email != null ? !email.equals(that.email) : that.email != null) {
             return false;
         }
@@ -448,6 +465,7 @@ public class DefaultAccount extends EntityBase implements Account {
         result = 31 * result + (name != null ? name.hashCode() : 0);
         result = 31 * result + (firstNameLength != null ? firstNameLength.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (parentAccountId != null ? parentAccountId.hashCode() : 0);
         result = 31 * result + billCycleDayLocal;
         result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
         result = 31 * result + (timeZone != null ? timeZone.hashCode() : 0);
diff --git a/account/src/main/java/org/killbill/billing/account/api/DefaultMutableAccountData.java b/account/src/main/java/org/killbill/billing/account/api/DefaultMutableAccountData.java
index 010a76d..27d3d52 100644
--- a/account/src/main/java/org/killbill/billing/account/api/DefaultMutableAccountData.java
+++ b/account/src/main/java/org/killbill/billing/account/api/DefaultMutableAccountData.java
@@ -33,6 +33,7 @@ public class DefaultMutableAccountData implements MutableAccountData {
     private String name;
     private Integer firstNameLength;
     private Currency currency;
+    private UUID parentAccountId;
     private int billCycleDayLocal;
     private UUID paymentMethodId;
     private DateTimeZone timeZone;
@@ -49,7 +50,8 @@ public class DefaultMutableAccountData implements MutableAccountData {
     private Boolean isNotifiedForInvoices;
 
     public DefaultMutableAccountData(final String externalKey, final String email, final String name,
-                                     final int firstNameLength, final Currency currency, final int billCycleDayLocal,
+                                     final int firstNameLength, final Currency currency,
+                                     final UUID parentAccountId, final int billCycleDayLocal,
                                      final UUID paymentMethodId, final DateTimeZone timeZone,
                                      final String locale, final String address1, final String address2,
                                      final String companyName, final String city, final String stateOrProvince,
@@ -60,6 +62,7 @@ public class DefaultMutableAccountData implements MutableAccountData {
         this.name = name;
         this.firstNameLength = firstNameLength;
         this.currency = currency;
+        this.parentAccountId = parentAccountId;
         this.billCycleDayLocal = billCycleDayLocal;
         this.paymentMethodId = paymentMethodId;
         this.timeZone = timeZone;
@@ -82,6 +85,7 @@ public class DefaultMutableAccountData implements MutableAccountData {
         this.name = accountData.getName();
         this.firstNameLength = accountData.getFirstNameLength();
         this.currency = accountData.getCurrency();
+        this.parentAccountId = accountData.getParentAccountId();
         this.billCycleDayLocal = accountData.getBillCycleDayLocal() == null ? DEFAULT_BILLING_CYCLE_DAY_LOCAL : accountData.getBillCycleDayLocal();
         this.paymentMethodId = accountData.getPaymentMethodId();
         this.timeZone = accountData.getTimeZone();
@@ -287,4 +291,15 @@ public class DefaultMutableAccountData implements MutableAccountData {
     public void setIsNotifiedForInvoices(final boolean isNotifiedForInvoices) {
         this.isNotifiedForInvoices = isNotifiedForInvoices;
     }
+
+    @Override
+    public UUID getParentAccountId() {
+        return parentAccountId;
+    }
+
+    @Override
+    public void setParentAccountId(final UUID parentAccountId) {
+        this.parentAccountId = parentAccountId;
+    }
+
 }
diff --git a/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountCreationEvent.java b/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountCreationEvent.java
index afd5664..9b81dd1 100644
--- a/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountCreationEvent.java
+++ b/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountCreationEvent.java
@@ -104,6 +104,7 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
 
     public static class DefaultAccountData implements AccountData {
 
+        private final UUID parentAccountId;
         private final String externalKey;
         private final String name;
         private final Integer firstNameLength;
@@ -131,6 +132,7 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
                  d.getEmail(),
                  d.getBillingCycleDayLocal(),
                  d.getCurrency() != null ? d.getCurrency().name() : null,
+                 d.getParentAccountId(),
                  d.getPaymentMethodId(),
                  d.getTimeZone() != null ? d.getTimeZone().getID() : null,
                  d.getLocale(),
@@ -153,6 +155,7 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
                                   @JsonProperty("email") final String email,
                                   @JsonProperty("billCycleDayLocal") final Integer billCycleDayLocal,
                                   @JsonProperty("currency") final String currency,
+                                  @JsonProperty("parentAccountId") final UUID parentAccountId,
                                   @JsonProperty("paymentMethodId") final UUID paymentMethodId,
                                   @JsonProperty("timeZone") final String timeZone,
                                   @JsonProperty("locale") final String locale,
@@ -172,6 +175,7 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
             this.email = email;
             this.billCycleDayLocal = billCycleDayLocal;
             this.currency = currency;
+            this.parentAccountId = parentAccountId;
             this.paymentMethodId = paymentMethodId;
             this.timeZone = timeZone;
             this.locale = locale;
@@ -221,6 +225,11 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
             }
         }
 
+        @Override
+        public UUID getParentAccountId() {
+            return parentAccountId;
+        }
+
         @JsonIgnore
         @Override
         public DateTimeZone getTimeZone() {
@@ -346,6 +355,9 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
             if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
                 return false;
             }
+            if (parentAccountId != null ? !parentAccountId.equals(that.parentAccountId) : that.parentAccountId != null) {
+                return false;
+            }
             if (email != null ? !email.equals(that.email) : that.email != null) {
                 return false;
             }
@@ -388,6 +400,7 @@ public class DefaultAccountCreationEvent extends BusEventBase implements Account
             result = 31 * result + (email != null ? email.hashCode() : 0);
             result = 31 * result + (billCycleDayLocal != null ? billCycleDayLocal.hashCode() : 0);
             result = 31 * result + (currency != null ? currency.hashCode() : 0);
+            result = 31 * result + (parentAccountId != null ? parentAccountId.hashCode() : 0);
             result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
             result = 31 * result + (timeZone != null ? timeZone.hashCode() : 0);
             result = 31 * result + (locale != null ? locale.hashCode() : 0);
diff --git a/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java
index b137cc0..46f72e6 100644
--- a/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/org/killbill/billing/account/api/user/DefaultAccountUserApi.java
@@ -32,6 +32,7 @@ import org.killbill.billing.account.api.DefaultAccountEmail;
 import org.killbill.billing.account.dao.AccountDao;
 import org.killbill.billing.account.dao.AccountEmailModelDao;
 import org.killbill.billing.account.dao.AccountModelDao;
+import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.util.cache.CacheControllerDispatcher;
 import org.killbill.billing.util.callcontext.CallContext;
@@ -84,8 +85,14 @@ public class DefaultAccountUserApi extends DefaultAccountApiBase implements Acco
             throw new AccountApiException(ErrorCode.ACCOUNT_ALREADY_EXISTS, data.getExternalKey());
         }
 
+        final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(context);
+
+        if (data.getParentAccountId() != null) {
+            getAccountById(data.getParentAccountId(), internalContext);
+        }
+
         final AccountModelDao account = new AccountModelDao(data);
-        accountDao.create(account, internalCallContextFactory.createInternalCallContext(context));
+        accountDao.create(account, internalContext);
 
         return new DefaultAccount(account);
     }
diff --git a/account/src/main/java/org/killbill/billing/account/dao/AccountModelDao.java b/account/src/main/java/org/killbill/billing/account/dao/AccountModelDao.java
index ac70362..8cd2ece 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/AccountModelDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/AccountModelDao.java
@@ -43,6 +43,7 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
     private String name;
     private Integer firstNameLength;
     private Currency currency;
+    private UUID parentAccountId;
     private int billingCycleDayLocal;
     private UUID paymentMethodId;
     private DateTimeZone timeZone;
@@ -58,11 +59,13 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
     private Boolean migrated;
     private Boolean isNotifiedForInvoices;
 
+
     public AccountModelDao() { /* For the DAO mapper */ }
 
     public AccountModelDao(final UUID id, final DateTime createdDate, final DateTime updatedDate, final String externalKey,
                            final String email, final String name, final Integer firstNameLength, final Currency currency,
-                           final int billingCycleDayLocal, final UUID paymentMethodId, final DateTimeZone timeZone,
+                           final UUID parentAccountId, final int billingCycleDayLocal,
+                           final UUID paymentMethodId, final DateTimeZone timeZone,
                            final String locale, final String address1, final String address2, final String companyName,
                            final String city, final String stateOrProvince, final String country, final String postalCode,
                            final String phone, final Boolean migrated, final Boolean notifiedForInvoices) {
@@ -72,6 +75,7 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
         this.name = name;
         this.firstNameLength = firstNameLength;
         this.currency = currency;
+        this.parentAccountId = parentAccountId;
         this.billingCycleDayLocal = billingCycleDayLocal;
         this.paymentMethodId = paymentMethodId;
         this.timeZone = MoreObjects.firstNonNull(timeZone, DateTimeZone.UTC);
@@ -97,6 +101,7 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
              account.getName(),
              account.getFirstNameLength(),
              account.getCurrency(),
+             account.getParentAccountId(),
              MoreObjects.firstNonNull(account.getBillCycleDayLocal(), DEFAULT_BILLING_CYCLE_DAY_LOCAL),
              account.getPaymentMethodId(),
              account.getTimeZone(),
@@ -162,6 +167,14 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
         this.currency = currency;
     }
 
+    public UUID getParentAccountId() {
+        return parentAccountId;
+    }
+
+    public void setParentAccountId(final UUID parentAccountId) {
+        this.parentAccountId = parentAccountId;
+    }
+
     public Integer getBillingCycleDayLocal() {
         return billingCycleDayLocal;
     }
@@ -285,6 +298,7 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
         sb.append(", name='").append(name).append('\'');
         sb.append(", firstNameLength=").append(firstNameLength);
         sb.append(", currency=").append(currency);
+        sb.append(", parentAccountId=").append(parentAccountId);
         sb.append(", billingCycleDayLocal=").append(billingCycleDayLocal);
         sb.append(", paymentMethodId=").append(paymentMethodId);
         sb.append(", timeZone=").append(timeZone);
@@ -338,6 +352,9 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
         if (currency != that.currency) {
             return false;
         }
+        if (parentAccountId != null ? !parentAccountId.equals(that.parentAccountId) : that.parentAccountId != null) {
+            return false;
+        }
         if (email != null ? !email.equals(that.email) : that.email != null) {
             return false;
         }
@@ -386,6 +403,7 @@ public class AccountModelDao extends EntityModelDaoBase implements EntityModelDa
         result = 31 * result + (name != null ? name.hashCode() : 0);
         result = 31 * result + (firstNameLength != null ? firstNameLength.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (parentAccountId != null ? parentAccountId.hashCode() : 0);
         result = 31 * result + billingCycleDayLocal;
         result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
         result = 31 * result + (timeZone != null ? timeZone.hashCode() : 0);
diff --git a/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
index a500028..d63c10b 100644
--- a/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
@@ -11,6 +11,7 @@ tableFields(prefix) ::= <<
 , <prefix>first_name_length
 , <prefix>currency
 , <prefix>billing_cycle_day_local
+, <prefix>parent_account_id
 , <prefix>payment_method_id
 , <prefix>time_zone
 , <prefix>locale
@@ -37,6 +38,7 @@ tableValues() ::= <<
 , :firstNameLength
 , :currency
 , :billingCycleDayLocal
+, :parentAccountId
 , :paymentMethodId
 , :timeZone
 , :locale
@@ -63,7 +65,7 @@ accountRecordIdValueWithComma(prefix) ::= ""
 update() ::= <<
     UPDATE accounts
     SET email = :email, name = :name, first_name_length = :firstNameLength,
-        currency = :currency, billing_cycle_day_local = :billingCycleDayLocal,
+        currency = :currency, billing_cycle_day_local = :billingCycleDayLocal, parent_account_id = :parentAccountId,
         payment_method_id = :paymentMethodId, time_zone = :timeZone, locale = :locale,
         address1 = :address1, address2 = :address2, company_name = :companyName, city = :city, state_or_province = :stateOrProvince,
         country = :country, postal_code = :postalCode, phone = :phone,
diff --git a/account/src/main/resources/org/killbill/billing/account/ddl.sql b/account/src/main/resources/org/killbill/billing/account/ddl.sql
index 01158e4..dda08a6 100644
--- a/account/src/main/resources/org/killbill/billing/account/ddl.sql
+++ b/account/src/main/resources/org/killbill/billing/account/ddl.sql
@@ -10,6 +10,7 @@ CREATE TABLE accounts (
     first_name_length int DEFAULT NULL,
     currency varchar(3) DEFAULT NULL,
     billing_cycle_day_local int DEFAULT NULL,
+    parent_account_id varchar(36) DEFAULT NULL,
     payment_method_id varchar(36) DEFAULT NULL,
     time_zone varchar(50) NOT NULL,
     locale varchar(5) DEFAULT NULL,
@@ -45,6 +46,7 @@ CREATE TABLE account_history (
     first_name_length int DEFAULT NULL,
     currency varchar(3) DEFAULT NULL,
     billing_cycle_day_local int DEFAULT NULL,
+    parent_account_id varchar(36) DEFAULT NULL,
     payment_method_id varchar(36) DEFAULT NULL,
     time_zone varchar(50) NOT NULL,
     locale varchar(5) DEFAULT NULL,
diff --git a/account/src/test/java/org/killbill/billing/account/AccountTestUtils.java b/account/src/test/java/org/killbill/billing/account/AccountTestUtils.java
index 9c6220d..082aa22 100644
--- a/account/src/test/java/org/killbill/billing/account/AccountTestUtils.java
+++ b/account/src/test/java/org/killbill/billing/account/AccountTestUtils.java
@@ -102,7 +102,7 @@ public abstract class AccountTestUtils {
         final String country = Locale.GERMANY.getCountry();
         final String postalCode = UUID.randomUUID().toString().substring(0, 4);
 
-        return new DefaultMutableAccountData(externalKey, email, name, firstNameLength, currency,
+        return new DefaultMutableAccountData(externalKey, email, name, firstNameLength, currency, null,
                                              billCycleDayLocal, paymentMethodId, timeZone,
                                              locale, address1, address2, companyName, city, stateOrProvince,
                                              country, postalCode, phone, false, true);
diff --git a/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java b/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java
index 39bbb72..f6d4ab3 100644
--- a/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java
+++ b/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApi.java
@@ -25,6 +25,7 @@ import java.util.concurrent.Callable;
 
 import org.killbill.billing.account.AccountTestSuiteWithEmbeddedDB;
 import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountData;
 import org.killbill.billing.account.api.DefaultAccount;
 import org.killbill.billing.account.api.DefaultMutableAccountData;
@@ -70,7 +71,7 @@ public class TestDefaultAccountUserApi extends AccountTestSuiteWithEmbeddedDB {
         final Account account = accountUserApi.createAccount(new DefaultAccount(createTestAccount()), callContext);
 
         // Update the address and leave other fields null
-        final MutableAccountData mutableAccountData = new DefaultMutableAccountData(null, null, null, 0, null, 0, null,
+        final MutableAccountData mutableAccountData = new DefaultMutableAccountData(null, null, null, 0, null, null, 0, null,
                                                                                     null, null, null, null, null, null,
                                                                                     null, null, null, null, false, false);
         final String newAddress1 = UUID.randomUUID().toString();
@@ -129,4 +130,34 @@ public class TestDefaultAccountUserApi extends AccountTestSuiteWithEmbeddedDB {
             return accountCreationInternalEvents;
         }
     }
+
+    @Test(groups = "slow", description = "Test Account create Parent and Child")
+    public void testCreateParentAndChildAccounts() throws Exception {
+
+        final Account parentAccount = accountUserApi.createAccount(new DefaultAccount(createTestAccount()), callContext);
+
+        final AccountModelDao childAccountModel = createTestAccount();
+        childAccountModel.setParentAccountId(parentAccount.getId());
+        final AccountData childAccountData = new DefaultAccount(childAccountModel);
+        final Account childAccount = accountUserApi.createAccount(childAccountData, callContext);
+
+        final Account retrievedChildAccount = accountUserApi.getAccountById(childAccount.getId(), callContext);
+
+        Assert.assertNull(parentAccount.getParentAccountId());
+        Assert.assertNotNull(retrievedChildAccount.getParentAccountId());
+        Assert.assertEquals(retrievedChildAccount.getId(), childAccount.getId());
+        Assert.assertEquals(retrievedChildAccount.getParentAccountId(), parentAccount.getId());
+    }
+
+    @Test(groups = "slow", description = "Test Account create Child with a non existing Parent",
+            expectedExceptions = AccountApiException.class, expectedExceptionsMessageRegExp = "Account does not exist for id .*")
+    public void testCreateChildAccountWithInvalidParent() throws Exception {
+
+        final AccountModelDao childAccountModel = createTestAccount();
+        childAccountModel.setParentAccountId(UUID.randomUUID());
+        final AccountData childAccountData = new DefaultAccount(childAccountModel);
+        final Account childAccount = accountUserApi.createAccount(childAccountData, callContext);
+
+    }
+
 }
diff --git a/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApiWithMocks.java b/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApiWithMocks.java
index f3d7863..c9b7c3d 100644
--- a/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApiWithMocks.java
+++ b/account/src/test/java/org/killbill/billing/account/api/user/TestDefaultAccountUserApiWithMocks.java
@@ -78,7 +78,7 @@ public class TestDefaultAccountUserApiWithMocks extends AccountTestSuiteNoDB {
         final String phone = UUID.randomUUID().toString();
         final Boolean isMigrated = true;
         final Boolean isNotifiedForInvoices = false;
-        final AccountData data = new DefaultAccount(id, externalKey, email, name, firstNameLength, currency, billCycleDay,
+        final AccountData data = new DefaultAccount(id, externalKey, email, name, firstNameLength, currency, null, billCycleDay,
                                                     paymentMethodId, timeZone, locale, address1, address2, companyName,
                                                     city, stateOrProvince, country, postalCode, phone, isMigrated, isNotifiedForInvoices);
 
diff --git a/account/src/test/java/org/killbill/billing/account/api/user/TestEventJson.java b/account/src/test/java/org/killbill/billing/account/api/user/TestEventJson.java
index 23ccdf7..96fefc3 100644
--- a/account/src/test/java/org/killbill/billing/account/api/user/TestEventJson.java
+++ b/account/src/test/java/org/killbill/billing/account/api/user/TestEventJson.java
@@ -50,7 +50,7 @@ public class TestEventJson extends AccountTestSuiteNoDB {
 
     @Test(groups = "fast", description="Test Account event serialization")
     public void testAccountCreationEvent() throws Exception {
-        final DefaultAccountData data = new DefaultAccountData("dsfdsf", "bobo", 3, "bobo@yahoo.com", 12, "USD", UUID.randomUUID(),
+        final DefaultAccountData data = new DefaultAccountData("dsfdsf", "bobo", 3, "bobo@yahoo.com", 12, "USD", null, UUID.randomUUID(),
                                                                "UTC", "US", "21 avenue", "", "Gling", "San Franciso", "CA", "94110", "USA", "4126789887", false, false);
         final DefaultAccountCreationEvent e = new DefaultAccountCreationEvent(data, UUID.randomUUID(), 1L, 2L, null);
         final String json = mapper.writeValueAsString(e);
diff --git a/account/src/test/java/org/killbill/billing/account/dao/TestAccountDao.java b/account/src/test/java/org/killbill/billing/account/dao/TestAccountDao.java
index fc3fece..cc46a02 100644
--- a/account/src/test/java/org/killbill/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/org/killbill/billing/account/dao/TestAccountDao.java
@@ -64,7 +64,7 @@ public class TestAccountDao extends AccountTestSuiteWithEmbeddedDB {
     public void testMinimalFields() throws Exception {
         final String email = UUID.randomUUID().toString();
         final String name = UUID.randomUUID().toString();
-        final AccountData accountData = new DefaultMutableAccountData(null, email, name, 0, null,
+        final AccountData accountData = new DefaultMutableAccountData(null, email, name, 0, null, null,
                                                                       0, null, null, null, null,
                                                                       null, null, null, null, null,
                                                                       null, null, false, true);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java
index 91763c0..6287755 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java
@@ -48,6 +48,8 @@ public class AccountJson extends JsonBase {
     private final Integer billCycleDayLocal;
     private final String currency;
     @ApiModelProperty(dataType = "java.util.UUID")
+    private final String parentAccountId;
+    @ApiModelProperty(dataType = "java.util.UUID")
     private final String paymentMethodId;
     private final String timeZone;
     private final String address1;
@@ -73,6 +75,7 @@ public class AccountJson extends JsonBase {
         this.email = account.getEmail();
         this.billCycleDayLocal = account.getBillCycleDayLocal();
         this.currency = account.getCurrency() != null ? account.getCurrency().toString() : null;
+        this.parentAccountId = account.getParentAccountId() != null ? account.getParentAccountId().toString() : null;
         this.paymentMethodId = account.getPaymentMethodId() != null ? account.getPaymentMethodId().toString() : null;
         this.timeZone = account.getTimeZone() != null ? account.getTimeZone().toString() : null;
         this.address1 = account.getAddress1();
@@ -96,6 +99,7 @@ public class AccountJson extends JsonBase {
                        @JsonProperty("email") final String email,
                        @JsonProperty("billCycleDayLocal") final Integer billCycleDayLocal,
                        @JsonProperty("currency") final String currency,
+                       @JsonProperty("parentAccountId") final String parentAccountId,
                        @JsonProperty("paymentMethodId") final String paymentMethodId,
                        @JsonProperty("timeZone") final String timeZone,
                        @JsonProperty("address1") final String address1,
@@ -121,6 +125,7 @@ public class AccountJson extends JsonBase {
         this.email = email;
         this.billCycleDayLocal = billCycleDayLocal;
         this.currency = currency;
+        this.parentAccountId = parentAccountId;
         this.paymentMethodId = paymentMethodId;
         this.timeZone = timeZone;
         this.address1 = address1;
@@ -245,6 +250,15 @@ public class AccountJson extends JsonBase {
             public String getAddress1() {
                 return address1;
             }
+
+            @Override
+            public UUID getParentAccountId() {
+                if (Strings.emptyToNull(parentAccountId) == null) {
+                    return null;
+                } else {
+                    return UUID.fromString(parentAccountId);
+                }
+            }
         };
     }
 
@@ -284,6 +298,10 @@ public class AccountJson extends JsonBase {
         return currency;
     }
 
+    public String getParentAccountId() {
+        return parentAccountId;
+    }
+
     public String getPaymentMethodId() {
         return paymentMethodId;
     }
@@ -350,6 +368,7 @@ public class AccountJson extends JsonBase {
                ", email='" + email + '\'' +
                ", billCycleDayLocal=" + billCycleDayLocal +
                ", currency='" + currency + '\'' +
+               ", parentAccountId=" + parentAccountId + '\'' +
                ", paymentMethodId='" + paymentMethodId + '\'' +
                ", timeZone='" + timeZone + '\'' +
                ", address1='" + address1 + '\'' +
@@ -407,6 +426,9 @@ public class AccountJson extends JsonBase {
         if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
             return false;
         }
+        if (parentAccountId != null ? !parentAccountId.equals(that.parentAccountId) : that.parentAccountId != null) {
+            return false;
+        }
         if (email != null ? !email.equals(that.email) : that.email != null) {
             return false;
         }
@@ -458,6 +480,7 @@ public class AccountJson extends JsonBase {
         result = 31 * result + (email != null ? email.hashCode() : 0);
         result = 31 * result + (billCycleDayLocal != null ? billCycleDayLocal.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (parentAccountId != null ? parentAccountId.hashCode() : 0);
         result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
         result = 31 * result + (timeZone != null ? timeZone.hashCode() : 0);
         result = 31 * result + (address1 != null ? address1.hashCode() : 0);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java
index 4a87407..d828960 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java
@@ -53,7 +53,7 @@ public class TestAccountJson extends JaxrsTestSuiteNoDB {
         final Boolean isNotifiedForInvoice = false;
 
         final AccountJson accountJson = new AccountJson(accountId, name, length, externalKey,
-                                                        email, billCycleDayLocal, currency, paymentMethodId,
+                                                        email, billCycleDayLocal, currency, null, paymentMethodId,
                                                         timeZone, address1, address2, postalCode, company, city, state,
                                                         country, locale, phone, isMigrated, isNotifiedForInvoice, null, null, null);
         Assert.assertEquals(accountJson.getAccountId(), accountId);

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index f211d9a..1256982 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.76</version>
+        <version>0.77-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.15.11-SNAPSHOT</version>
diff --git a/util/src/test/java/org/killbill/billing/mock/MockAccountBuilder.java b/util/src/test/java/org/killbill/billing/mock/MockAccountBuilder.java
index 65a54d9..74b1552 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockAccountBuilder.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockAccountBuilder.java
@@ -313,6 +313,11 @@ public class MockAccountBuilder {
             }
 
             @Override
+            public UUID getParentAccountId() {
+                return null;
+            }
+
+            @Override
             public UUID getId() {
                 return id;
             }