killbill-uncached

refund: expose effective date in Refund objects This is really

7/24/2012 6:11:03 PM

Details

diff --git a/api/src/main/java/com/ning/billing/payment/api/Refund.java b/api/src/main/java/com/ning/billing/payment/api/Refund.java
index ed2e15c..d6bb3ea 100644
--- a/api/src/main/java/com/ning/billing/payment/api/Refund.java
+++ b/api/src/main/java/com/ning/billing/payment/api/Refund.java
@@ -13,17 +13,27 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.api;
 
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.ning.billing.catalog.api.Currency;
 
 public interface Refund {
+
     public UUID getId();
+
     public UUID getPaymentId();
+
     public boolean isAdjusted();
+
     public BigDecimal getRefundAmount();
+
     public Currency getCurrency();
+
+    public DateTime getEffectiveDate();
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/RefundJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/RefundJson.java
index f65f6d7..ff1547a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/RefundJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/RefundJson.java
@@ -18,10 +18,12 @@ package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
+import org.joda.time.DateTime;
+
 import com.ning.billing.payment.api.Refund;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class RefundJson {
 
@@ -29,24 +31,27 @@ public class RefundJson {
     private final String paymentId;
     private final BigDecimal refundAmount;
     private final Boolean isAdjusted;
+    private final DateTime requestedDate;
+    private final DateTime effectiveDate;
 
-    public RefundJson(Refund input) {
-        this(input.getId().toString(), input.getPaymentId().toString(), input.getRefundAmount(), input.isAdjusted());
+    public RefundJson(final Refund input) {
+        this(input.getId().toString(), input.getPaymentId().toString(), input.getRefundAmount(), input.isAdjusted(),
+             input.getEffectiveDate(), input.getEffectiveDate());
     }
 
     @JsonCreator
     public RefundJson(@JsonProperty("refund_id") final String refundId,
-            @JsonProperty("paymentId") String paymentId,
-            @JsonProperty("refundAmount") BigDecimal refundAmount,
-            @JsonProperty("adjusted") final Boolean isAdjusted) {
+                      @JsonProperty("paymentId") final String paymentId,
+                      @JsonProperty("refundAmount") final BigDecimal refundAmount,
+                      @JsonProperty("adjusted") final Boolean isAdjusted,
+                      @JsonProperty("requestedDate") final DateTime requestedDate,
+                      @JsonProperty("effectiveDate") final DateTime effectiveDate) {
         this.refundId = refundId;
         this.paymentId = paymentId;
         this.refundAmount = refundAmount;
         this.isAdjusted = isAdjusted;
-    }
-
-    public RefundJson() {
-        this(null, null, null, null);
+        this.requestedDate = requestedDate;
+        this.effectiveDate = effectiveDate;
     }
 
     public String getRefundId() {
@@ -65,61 +70,111 @@ public class RefundJson {
         return isAdjusted;
     }
 
+    public DateTime getRequestedDate() {
+        return requestedDate;
+    }
+
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("RefundJson");
+        sb.append("{refundId='").append(refundId).append('\'');
+        sb.append(", paymentId='").append(paymentId).append('\'');
+        sb.append(", refundAmount=").append(refundAmount);
+        sb.append(", isAdjusted=").append(isAdjusted);
+        sb.append(", requestedDate=").append(requestedDate);
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result
-                + ((isAdjusted == null) ? 0 : isAdjusted.hashCode());
-        result = prime * result
-                + ((paymentId == null) ? 0 : paymentId.hashCode());
-        result = prime * result
-                + ((refundAmount == null) ? 0 : refundAmount.hashCode());
-        result = prime * result
-                + ((refundId == null) ? 0 : refundId.hashCode());
+        int result = refundId != null ? refundId.hashCode() : 0;
+        result = 31 * result + (paymentId != null ? paymentId.hashCode() : 0);
+        result = 31 * result + (refundAmount != null ? refundAmount.hashCode() : 0);
+        result = 31 * result + (isAdjusted != null ? isAdjusted.hashCode() : 0);
+        result = 31 * result + (requestedDate != null ? requestedDate.hashCode() : 0);
+        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
         return result;
     }
 
     @Override
     public boolean equals(final Object obj) {
-        if (! this.equalsNoId(obj)) {
+        if (!this.equalsNoIdNoDates(obj)) {
             return false;
         } else {
-            RefundJson other = (RefundJson) obj;
-            if (getRefundId() == null) {
-                return other.getRefundId() == null;
-            } else {
-                return getRefundId().equals(other.getRefundId());
+            final RefundJson other = (RefundJson) obj;
+            if (refundId == null) {
+                if (other.getRefundId() != null) {
+                    return false;
+                }
+            } else if (!refundId.equals(other.getRefundId())) {
+                return false;
             }
+
+            if (requestedDate == null) {
+                if (other.getRequestedDate() != null) {
+                    return false;
+                }
+            } else if (requestedDate.compareTo(other.getRequestedDate()) != 0) {
+                return false;
+            }
+
+            if (effectiveDate == null) {
+                if (other.getEffectiveDate() != null) {
+                    return false;
+                }
+            } else if (effectiveDate.compareTo(other.getEffectiveDate()) != 0) {
+                return false;
+            }
+
+            return true;
         }
     }
 
-    public boolean equalsNoId(final Object obj) {
-        if (this == obj)
+    public boolean equalsNoIdNoDates(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+
+        if (getClass() != obj.getClass()) {
             return false;
-        RefundJson other = (RefundJson) obj;
+        }
+
+        final RefundJson other = (RefundJson) obj;
         if (isAdjusted == null) {
-            if (other.isAdjusted != null)
+            if (other.isAdjusted != null) {
                 return false;
-        } else if (!isAdjusted.equals(other.isAdjusted))
+            }
+        } else if (!isAdjusted.equals(other.isAdjusted)) {
             return false;
+        }
+
         if (paymentId == null) {
-            if (other.paymentId != null)
+            if (other.paymentId != null) {
                 return false;
-        } else if (!paymentId.equals(other.paymentId))
+            }
+        } else if (!paymentId.equals(other.paymentId)) {
             return false;
+        }
+
         if (refundAmount == null) {
-            if (other.refundAmount != null)
+            if (other.refundAmount != null) {
                 return false;
+            }
         } else if (!refundAmount.equals(other.refundAmount)) {
             return false;
         }
+
         return true;
     }
-
-
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultRefund.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultRefund.java
index 729e701..81c8257 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultRefund.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultRefund.java
@@ -13,11 +13,14 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.api;
 
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.entity.EntityBase;
 
@@ -27,14 +30,16 @@ public class DefaultRefund extends EntityBase implements Refund {
     private final BigDecimal amount;
     private final Currency currency;
     private final boolean isAdjusted;
+    private final DateTime effectiveDate;
 
     public DefaultRefund(final UUID id, final UUID paymentId, final BigDecimal amount,
-            final Currency currency, final boolean isAdjusted) {
+                         final Currency currency, final boolean isAdjusted, final DateTime effectiveDate) {
         super(id);
         this.paymentId = paymentId;
         this.amount = amount;
         this.currency = currency;
         this.isAdjusted = isAdjusted;
+        this.effectiveDate = effectiveDate;
     }
 
     @Override
@@ -56,4 +61,62 @@ public class DefaultRefund extends EntityBase implements Refund {
     public boolean isAdjusted() {
         return isAdjusted;
     }
+
+    @Override
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultRefund");
+        sb.append("{paymentId=").append(paymentId);
+        sb.append(", amount=").append(amount);
+        sb.append(", currency=").append(currency);
+        sb.append(", isAdjusted=").append(isAdjusted);
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultRefund that = (DefaultRefund) o;
+
+        if (isAdjusted != that.isAdjusted) {
+            return false;
+        }
+        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+            return false;
+        }
+        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = paymentId != null ? paymentId.hashCode() : 0;
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (isAdjusted ? 1 : 0);
+        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+        return result;
+    }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
index d5ca7e9..69fbb4b 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
@@ -147,7 +147,8 @@ public class RefundProcessor extends ProcessorBase {
 
                     paymentDao.updateRefundStatus(refundInfo.getId(), RefundStatus.COMPLETED, context);
 
-                    return new DefaultRefund(refundInfo.getId(), paymentId, refundInfo.getAmount(), account.getCurrency(), isAdjusted);
+                    return new DefaultRefund(refundInfo.getId(), paymentId, refundInfo.getAmount(), account.getCurrency(),
+                                             isAdjusted, refundInfo.getCreatedDate());
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_REFUND, account.getId(), e.getMessage());
                 } catch (InvoiceApiException e) {
@@ -172,7 +173,8 @@ public class RefundProcessor extends ProcessorBase {
         if (completePluginCompletedRefund(filteredInput)) {
             result = paymentDao.getRefund(refundId);
         }
-        return new DefaultRefund(result.getId(), result.getPaymentId(), result.getAmount(), result.getCurrency(), result.isAdjsuted());
+        return new DefaultRefund(result.getId(), result.getPaymentId(), result.getAmount(), result.getCurrency(),
+                                 result.isAdjsuted(), result.getCreatedDate());
     }
 
 
@@ -200,7 +202,8 @@ public class RefundProcessor extends ProcessorBase {
         return new ArrayList<Refund>(Collections2.transform(in, new Function<RefundModelDao, Refund>() {
             @Override
             public Refund apply(RefundModelDao cur) {
-                return new DefaultRefund(cur.getId(), cur.getPaymentId(), cur.getAmount(), cur.getCurrency(), cur.isAdjsuted());
+                return new DefaultRefund(cur.getId(), cur.getPaymentId(), cur.getAmount(), cur.getCurrency(),
+                                         cur.isAdjsuted(), cur.getCreatedDate());
             }
         }));
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java
index 286fe51..5c5c4a1 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java
@@ -13,15 +13,19 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.entity.EntityBase;
 
-
 public class RefundModelDao extends EntityBase {
 
     private final UUID accountId;
@@ -31,14 +35,15 @@ public class RefundModelDao extends EntityBase {
     private final boolean isAdjusted;
     private final RefundStatus refundStatus;
 
-    public RefundModelDao(final UUID accountId, final UUID paymentId,
-            final BigDecimal amount, final Currency currency, final boolean isAdjusted) {
-        this(UUID.randomUUID(), accountId, paymentId, amount, currency, isAdjusted, RefundStatus.CREATED);
+    public RefundModelDao(final UUID accountId, final UUID paymentId, final BigDecimal amount,
+                          final Currency currency, final boolean isAdjusted) {
+        this(UUID.randomUUID(), accountId, paymentId, amount, currency, isAdjusted, RefundStatus.CREATED, null, null);
     }
 
-    public RefundModelDao(final UUID id, final UUID accountId, final UUID paymentId,
-            final BigDecimal amount, final Currency currency, final boolean isAdjusted, final RefundStatus refundStatus) {
-        super(id);
+    public RefundModelDao(final UUID id, final UUID accountId, final UUID paymentId, final BigDecimal amount,
+                          final Currency currency, final boolean isAdjusted, final RefundStatus refundStatus,
+                          @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate) {
+        super(id, createdDate, updatedDate);
         this.accountId = accountId;
         this.paymentId = paymentId;
         this.amount = amount;
@@ -76,4 +81,72 @@ public class RefundModelDao extends EntityBase {
         PLUGIN_COMPLETED,
         COMPLETED,
     }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("RefundModelDao");
+        sb.append("{accountId=").append(accountId);
+        sb.append(", paymentId=").append(paymentId);
+        sb.append(", amount=").append(amount);
+        sb.append(", currency=").append(currency);
+        sb.append(", isAdjusted=").append(isAdjusted);
+        sb.append(", refundStatus=").append(refundStatus);
+        sb.append(", createdDate=").append(createdDate);
+        sb.append(", updatedDate=").append(updatedDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final RefundModelDao that = (RefundModelDao) o;
+
+        if (isAdjusted != that.isAdjusted) {
+            return false;
+        }
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+            return false;
+        }
+        if (createdDate != null ? !createdDate.equals(that.createdDate) : that.createdDate != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (refundStatus != that.refundStatus) {
+            return false;
+        }
+        if (updatedDate != null ? !updatedDate.equals(that.updatedDate) : that.updatedDate != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = accountId != null ? accountId.hashCode() : 0;
+        result = 31 * result + (paymentId != null ? paymentId.hashCode() : 0);
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (isAdjusted ? 1 : 0);
+        result = 31 * result + (refundStatus != null ? refundStatus.hashCode() : 0);
+        result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0);
+        result = 31 * result + (updatedDate != null ? updatedDate.hashCode() : 0);
+        return result;
+    }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java
index e6bea41..7d1ff1a 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/RefundSqlDao.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.payment.dao;
 
 import java.math.BigDecimal;
@@ -21,6 +22,7 @@ import java.sql.SQLException;
 import java.util.List;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
@@ -43,15 +45,13 @@ import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.dao.MapperBase;
 import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 
-
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(RefundSqlDao.RefundModelDaoMapper.class)
 public interface RefundSqlDao extends Transactional<RefundSqlDao>, UpdatableEntitySqlDao<RefundModelDao>, Transmogrifier, CloseMe {
 
-
     @SqlUpdate
     void insertRefund(@Bind(binder = RefundModelDaoBinder.class) final RefundModelDao refundInfo,
-                       @CallContextBinder final CallContext context);
+                      @CallContextBinder final CallContext context);
 
     @SqlUpdate
     void updateStatus(@Bind("id") final String refundId, @Bind("refundStatus") final String status);
@@ -70,10 +70,10 @@ public interface RefundSqlDao extends Transactional<RefundSqlDao>, UpdatableEnti
     public void insertHistoryFromTransaction(@RefundHistoryBinder final EntityHistory<RefundModelDao> payment,
                                              @CallContextBinder final CallContext context);
 
-
     public static final class RefundModelDaoBinder extends BinderBase implements Binder<Bind, RefundModelDao> {
+
         @Override
-        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final RefundModelDao refund) {
+        public void bind(final SQLStatement stmt, final Bind bind, final RefundModelDao refund) {
             stmt.bind("id", refund.getId().toString());
             stmt.bind("accountId", refund.getAccountId().toString());
             stmt.bind("paymentId", refund.getPaymentId().toString());
@@ -81,6 +81,7 @@ public interface RefundSqlDao extends Transactional<RefundSqlDao>, UpdatableEnti
             stmt.bind("currency", refund.getCurrency().toString());
             stmt.bind("isAdjusted", refund.isAdjsuted());
             stmt.bind("refundStatus", refund.getRefundStatus().toString());
+            // createdDate and updatedDate are populated by the @CallContextBinder
         }
     }
 
@@ -96,7 +97,9 @@ public interface RefundSqlDao extends Transactional<RefundSqlDao>, UpdatableEnti
             final boolean isAdjusted = rs.getBoolean("is_adjusted");
             final Currency currency = Currency.valueOf(rs.getString("currency"));
             final RefundStatus refundStatus = RefundStatus.valueOf(rs.getString("refund_status"));
-            return new RefundModelDao(id, accountId, paymentId, amount, currency, isAdjusted, refundStatus);
+            final DateTime createdDate = getDateTime(rs, "created_date");
+            final DateTime updatedDate = getDateTime(rs, "updated_date");
+            return new RefundModelDao(id, accountId, paymentId, amount, currency, isAdjusted, refundStatus, createdDate, updatedDate);
         }
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
index dc4f2f4..0afc6b8 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
@@ -92,7 +92,7 @@ public class TestPayment extends TestJaxrsBase {
 
         // Issue the refund
 
-        final RefundJson refundJson = new RefundJson(null, paymentId, paymentAmount, false);
+        final RefundJson refundJson = new RefundJson(null, paymentId, paymentAmount, false, null, null);
         baseJson = mapper.writeValueAsString(refundJson);
         response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
@@ -105,7 +105,13 @@ public class TestPayment extends TestJaxrsBase {
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
         final RefundJson refundJsonCheck = mapper.readValue(baseJson, RefundJson.class);
-        Assert.assertTrue(refundJsonCheck.equalsNoId(refundJson));
+        Assert.assertTrue(refundJsonCheck.equalsNoIdNoDates(refundJson));
+        Assert.assertEquals(refundJsonCheck.getEffectiveDate().getYear(), clock.getUTCNow().getYear());
+        Assert.assertEquals(refundJsonCheck.getEffectiveDate().getMonthOfYear(), clock.getUTCNow().getMonthOfYear());
+        Assert.assertEquals(refundJsonCheck.getEffectiveDate().getDayOfMonth(), clock.getUTCNow().getDayOfMonth());
+        Assert.assertEquals(refundJsonCheck.getRequestedDate().getYear(), clock.getUTCNow().getYear());
+        Assert.assertEquals(refundJsonCheck.getRequestedDate().getMonthOfYear(), clock.getUTCNow().getMonthOfYear());
+        Assert.assertEquals(refundJsonCheck.getRequestedDate().getDayOfMonth(), clock.getUTCNow().getDayOfMonth());
 
         uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
diff --git a/util/src/main/java/com/ning/billing/util/entity/EntityBase.java b/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
index 3cf0be4..1ac2fd0 100644
--- a/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
@@ -18,21 +18,42 @@ package com.ning.billing.util.entity;
 
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 public abstract class EntityBase implements Entity {
+
     protected final UUID id;
+    protected final DateTime createdDate;
+    protected final DateTime updatedDate;
 
     // used to hydrate objects
     public EntityBase(final UUID id) {
-        this.id = id;
+        this(id, null, null);
     }
 
     // used to create new objects
     public EntityBase() {
-        this.id = UUID.randomUUID();
+        this(UUID.randomUUID(), null, null);
+    }
+
+    public EntityBase(final UUID id, final DateTime createdDate, final DateTime updatedDate) {
+        this.id = id;
+        this.createdDate = createdDate;
+        this.updatedDate = updatedDate;
     }
 
     @Override
     public UUID getId() {
         return id;
     }
+
+    // TODO surface it in Entity
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    // TODO surface it in Entity
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
 }