killbill-aplcache

Details

diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 5adc2b2..677473e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -351,6 +351,12 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                     invoiceForCredit = new DefaultInvoice(accountId, effectiveDate, effectiveDate, currency, InvoiceStatus.DRAFT);
                 } else {
                     invoiceForCredit = getInvoiceAndCheckCurrency(invoiceId, currency, context);
+                    // TODO check with @sbrossie if really want to add this validation
+                    /*
+                    if (InvoiceStatus.COMMITTED.equals(invoiceForCredit.getStatus())) {
+                        throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_STATUS_CREDIT, invoiceId);
+                    }
+                    */
                 }
 
                 // Create the new credit
@@ -483,4 +489,9 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
         return invoice;
     }
 
+    @Override
+    public void invoiceStatusTransition(final UUID accountId, final UUID invoiceId, final CallContext context) throws InvoiceApiException {
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(accountId, context);
+        dao.changeInvoiceStatus(accountId, invoiceId, InvoiceStatus.COMMITTED, internalCallContext);
+    }
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 1ef6f7f..a82b77f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -41,6 +41,7 @@ import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.invoice.api.InvoicePaymentType;
+import org.killbill.billing.invoice.api.InvoiceStatus;
 import org.killbill.billing.invoice.api.user.DefaultInvoiceAdjustmentEvent;
 import org.killbill.billing.invoice.notification.NextBillingDatePoster;
 import org.killbill.billing.util.UUIDs;
@@ -257,7 +258,10 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                         createInvoiceItemFromTransaction(transInvoiceItemSqlDao, invoiceItemModelDao, context);
                     }
                     cbaDao.addCBAComplexityFromTransaction(invoice, entitySqlDaoWrapperFactory, context);
-                    notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoice.getAccountId(), callbackDateTimePerSubscriptions, context);
+                    if (InvoiceStatus.COMMITTED.equals(invoice.getStatus())) {
+                        // only notify on the bus if the state is COMMITTED
+                        notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoice.getAccountId(), callbackDateTimePerSubscriptions, context);
+                    }
                 }
                 return null;
             }
@@ -295,6 +299,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                         cbaDao.addCBAComplexityFromTransaction(invoiceModelDao.getId(), entitySqlDaoWrapperFactory, context);
 
                         // Notify the bus since the balance of the invoice changed
+                        // TODO check invoice status before sent it to the bus
                         // TODO should we post an InvoiceCreationInternalEvent event instead? Note! This will trigger a payment (see InvoiceHandler)
                         notifyBusOfInvoiceAdjustment(entitySqlDaoWrapperFactory, invoiceModelDao.getId(), invoiceModelDao.getAccountId(), context.getUserToken(), context);
                     }
@@ -854,4 +859,33 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
         }
     }
 
+    @Override
+    public void changeInvoiceStatus(final UUID accountId, final UUID invoiceId, final InvoiceStatus newStatus,
+                                    final InternalCallContext context) throws InvoiceApiException {
+        transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<Void>() {
+            @Override
+            public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+                final InvoiceSqlDao transactional = entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class);
+
+                // Retrieve the invoice and make sure it belongs to the right account
+                final InvoiceModelDao invoice = transactional.getById(invoiceId.toString(), context);
+                if (invoice == null || !invoice.getAccountId().equals(accountId)) {
+                    throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
+                }
+
+                if (invoice.getStatus().equals(newStatus)) {
+                    throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_STATUS, newStatus, invoiceId, invoice.getStatus());
+                }
+
+                transactional.updateStatus(invoiceId.toString(), accountId.toString(), newStatus.toString(), context);
+
+                if (InvoiceStatus.COMMITTED.equals(newStatus)) {
+                    // now notify on the bus
+                    //notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoice.getAccountId(), callbackDateTimePerSubscriptions, context);
+                }
+
+                return null;
+            }
+        });
+    }
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
index 25c9249..1c18499 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
@@ -32,6 +32,7 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
+import org.killbill.billing.invoice.api.InvoiceStatus;
 import org.killbill.billing.util.entity.Pagination;
 import org.killbill.billing.util.entity.dao.EntityDao;
 
@@ -139,4 +140,14 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
      */
     public void consumeExstingCBAOnAccountWithUnpaidInvoices(final UUID accountId, final InternalCallContext context);
 
+    /**
+     * Update invoice state
+     *
+     * @param accountId the account id
+     * @param invoiceId the invoice id
+     * @param newState the new invoice state
+     * @param context the tenant context
+     * @throws InvoiceApiException
+     */
+    void changeInvoiceStatus(UUID accountId, UUID invoiceId, InvoiceStatus newState, InternalCallContext context) throws InvoiceApiException;
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
index 3b46cf6..15d7354 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
@@ -19,13 +19,17 @@ package org.killbill.billing.invoice.dao;
 import java.util.List;
 import java.util.UUID;
 
+import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.invoice.api.Invoice;
+import org.killbill.billing.util.audit.ChangeType;
+import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
 import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
 @EntitySqlDaoStringTemplate
 public interface InvoiceSqlDao extends EntitySqlDao<InvoiceModelDao, Invoice> {
@@ -38,5 +42,11 @@ public interface InvoiceSqlDao extends EntitySqlDao<InvoiceModelDao, Invoice> {
     UUID getInvoiceIdByPaymentId(@Bind("paymentId") final String paymentId,
                                  @BindBean final InternalTenantContext context);
 
+    @SqlUpdate
+    @Audited(ChangeType.UPDATE)
+    public void updateStatus(@Bind("id") String invoiceId,
+                             @Bind("accountId") String accountId,
+                             @Bind("status") String status,
+                             @BindBean final InternalCallContext context);
 }
 
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 6bfdcf3..0cd6e79 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -52,3 +52,11 @@ getInvoiceIdByPaymentId() ::= <<
    <AND_CHECK_TENANT("i.")>
    <AND_CHECK_TENANT("ip.")>
 >>
+
+updateStatus() ::= <<
+    UPDATE <tableName()>
+    SET status = :status
+    WHERE id = :id
+     AND account_id = :accountId
+    <AND_CHECK_TENANT()>;
+>>
\ No newline at end of file
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index a572def..4161dd0 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -32,6 +32,7 @@ import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoiceItemType;
+import org.killbill.billing.invoice.api.InvoiceStatus;
 import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
 import org.killbill.billing.util.api.TagApiException;
 import org.killbill.billing.util.callcontext.CallContext;
@@ -365,4 +366,40 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
         final Invoice invoiceAfterTagRemoval = invoiceUserApi.getInvoice(invoiceId, callContext);
         assertEquals(invoiceAfterTagRemoval.getBalance().compareTo(BigDecimal.ZERO), 1);
     }
+
+    @Test(groups = "slow")
+    public void testInvoiceStatusTransition() throws Exception {
+        // Verify the initial invoice balance
+        final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, callContext).getBalance();
+        Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1);
+
+        // Verify the initial account balance
+        final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
+        Assert.assertEquals(accountBalance, invoiceBalance);
+
+        // Adjust the invoice for the full amount
+        final BigDecimal creditAmount = BigDecimal.TEN;
+        final InvoiceItem creditInvoiceItem = invoiceUserApi.insertCreditForInvoice(accountId, null, creditAmount,
+                                                                                    clock.getUTCToday(), accountCurrency, callContext);
+
+        final UUID invoiceId = creditInvoiceItem.getInvoiceId();
+        Invoice creditInvoice = invoiceUserApi.getInvoice(invoiceId, callContext);
+        Assert.assertEquals(creditInvoice.getStatus(), InvoiceStatus.DRAFT);
+        Assert.assertEquals(creditInvoiceItem.getInvoiceId(), creditInvoice.getId());
+
+        // move invoice from DRAFT to COMMITTED
+        invoiceUserApi.invoiceStatusTransition(this.accountId, creditInvoice.getId(), callContext);
+        creditInvoice = invoiceUserApi.getInvoice(invoiceId, callContext);
+        Assert.assertEquals(creditInvoice.getStatus(), InvoiceStatus.COMMITTED);
+
+        // TODO verify post actions (event bus ???)
+
+        // Verify the adjusted invoice balance
+//        final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(this.invoiceId, callContext).getBalance();
+//        Assert.assertEquals(adjustedInvoiceBalance.compareTo(BigDecimal.ZERO), 0);
+
+        // Verify the adjusted account balance
+//        final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
+//        Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
+    }
 }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
index 65e3b0e..39b4913 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
@@ -34,6 +34,7 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
+import org.killbill.billing.invoice.api.InvoiceStatus;
 import org.killbill.billing.invoice.api.user.DefaultInvoiceCreationEvent;
 import org.killbill.billing.util.entity.DefaultPagination;
 import org.killbill.billing.util.entity.Pagination;
@@ -362,4 +363,8 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice, 
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public void changeInvoiceStatus(final UUID accountId, final UUID invoiceId, final InvoiceStatus newState, final InternalCallContext context) throws InvoiceApiException {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java b/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java
index 0f90be1..87a72de 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java
@@ -38,6 +38,7 @@ import org.killbill.billing.invoice.api.InvoiceInternalApi;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoicePayment;
 import org.killbill.billing.invoice.api.InvoicePaymentType;
+import org.killbill.billing.invoice.api.InvoiceStatus;
 import org.killbill.billing.invoice.dao.InvoiceDao;
 import org.killbill.billing.invoice.dao.InvoiceItemModelDao;
 import org.killbill.billing.invoice.dao.InvoiceModelDao;
@@ -96,6 +97,7 @@ public class InvoiceTestUtils {
         Mockito.when(invoice.getTargetDate()).thenReturn(clock.getUTCToday());
         Mockito.when(invoice.getCurrency()).thenReturn(currency);
         Mockito.when(invoice.isMigrationInvoice()).thenReturn(false);
+        Mockito.when(invoice.getStatus()).thenReturn(InvoiceStatus.COMMITTED);
 
         final List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
         final List<InvoiceItemModelDao> invoiceModelItems = new ArrayList<InvoiceItemModelDao>();
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 845bfd0..4aea81f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -940,6 +940,32 @@ public class InvoiceResource extends JaxRsResourceBase {
                                 context.createContext(createdBy, reason, comment, request));
     }
 
+    @TimedResource
+    @POST
+    @Path("/{invoiceId:" + UUID_PATTERN + "}/" + ACCOUNTS + "/{accountId:" + UUID_PATTERN + "}/" + INVOICE_STATUS_TRANSITION)
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    @ApiOperation(value = "Perform the invoice status transition from DRAFT to COMMITTED")
+    @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id or invoice id supplied"),
+                           @ApiResponse(code = 404, message = "Invoice not found")})
+    public Response invoiceStatusTransition(@PathParam("accountId") final String accountIdString,
+                                            @PathParam("invoiceId") final String invoiceIdString,
+                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                            @HeaderParam(HDR_REASON) final String reason,
+                                            @HeaderParam(HDR_COMMENT) final String comment,
+                                            @javax.ws.rs.core.Context final HttpServletRequest request,
+                                            @javax.ws.rs.core.Context final UriInfo uriInfo) throws InvoiceApiException {
+
+        final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+        final UUID accountId = UUID.fromString(accountIdString);
+        final UUID invoiceId = UUID.fromString(invoiceIdString);
+
+        invoiceApi.invoiceStatusTransition(accountId, invoiceId, callContext);
+
+        return Response.status(Response.Status.OK).build();
+    }
+
     @Override
     protected ObjectType getObjectType() {
         return ObjectType.INVOICE;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index f97c91a..92f1ac8 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -236,6 +236,7 @@ public interface JaxrsResource {
     public static final String INVOICE_MP_TEMPLATE = "manualPayTemplate";
     public static final String INVOICE_TRANSLATION = "translation";
     public static final String INVOICE_CATALOG_TRANSLATION = "catalogTranslation";
+    public static final String INVOICE_STATUS_TRANSITION = "statusTransition";
 
     public static final String COMBO = "combo";
 
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
index 4457006..d76a3e7 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
@@ -30,8 +30,10 @@ import org.joda.time.LocalDate;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.model.Account;
 import org.killbill.billing.client.model.AuditLog;
+import org.killbill.billing.client.model.Credit;
 import org.killbill.billing.client.model.Invoice;
 import org.killbill.billing.client.model.InvoiceDryRun;
 import org.killbill.billing.client.model.InvoiceItem;
@@ -41,6 +43,7 @@ import org.killbill.billing.client.model.Invoices;
 import org.killbill.billing.client.model.PaymentMethod;
 import org.killbill.billing.entitlement.api.SubscriptionEventType;
 import org.killbill.billing.invoice.api.DryRunType;
+import org.killbill.billing.invoice.api.InvoiceStatus;
 import org.killbill.billing.payment.provider.ExternalPaymentProviderPlugin;
 import org.killbill.billing.util.api.AuditLevel;
 import org.testng.Assert;
@@ -553,4 +556,74 @@ public class TestInvoice extends TestJaxrsBase {
         }
         Assert.assertNull(page);
     }
+
+    @Test(groups = "slow", description = "Can add a credit to a new invoice")
+    public void testCreateCreditInvoiceAndMoveStatus() throws Exception {
+
+        final Account account = createAccountWithDefaultPaymentMethod();
+
+        final DateTime effectiveDate = clock.getUTCNow();
+        final BigDecimal creditAmount = BigDecimal.TEN;
+        final Credit credit = new Credit();
+        credit.setAccountId(account.getAccountId());
+        credit.setInvoiceId(null);
+        credit.setCreditAmount(creditAmount);
+        final Credit creditJson = killBillClient.createCredit(credit, createdBy, reason, comment);
+
+        Invoice invoice = killBillClient.getInvoice(creditJson.getInvoiceId());
+        Assert.assertEquals(invoice.getStatus(), InvoiceStatus.DRAFT.toString());
+
+        killBillClient.invoiceStatusTransition(account.getAccountId(), invoice.getInvoiceId(), createdBy, reason, comment);
+
+        invoice = killBillClient.getInvoice(creditJson.getInvoiceId());
+        Assert.assertEquals(invoice.getStatus(), InvoiceStatus.COMMITTED.toString());
+
+    }
+
+    @Test(groups = "slow", description = "Forcing method to fail.", expectedExceptions = KillBillClientException.class,
+            expectedExceptionsMessageRegExp = ".* type=ACCOUNT doesn't exist!")
+    public void testMoveInvoiceStatusWithInvalidIds() throws Exception {
+
+        killBillClient.invoiceStatusTransition(UUID.randomUUID(), UUID.randomUUID(), createdBy, reason, comment);
+
+    }
+
+    /*
+    @Test(groups = "slow", description = "Forcing method to fail.", expectedExceptions = KillBillClientException.class,
+            expectedExceptionsMessageRegExp = ".* type=ACCOUNT doesn't exist!")
+    public void testErrorTransition() throws Exception {
+
+        final Account account = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Invoice invoice = killBillClient.getInvoicesForAccount(account.getAccountId()).get(0);
+        Assert.assertEquals(invoice.getStatus(), InvoiceStatus.COMMITTED.toString());
+
+        killBillClient.invoiceStatusTransition(account.getAccountId(), invoice.getInvoiceId(), createdBy, reason, comment);
+
+    }
+    */
+
+    /*
+    @Test(groups = "slow", description = "Forcing method to fail.", expectedExceptions = KillBillClientException.class,
+            expectedExceptionsMessageRegExp = "No invoice could be found .*")
+    public void testMoveInvoiceStatusWithInvalidAccount() throws Exception {
+
+        final Account account = createAccountWithDefaultPaymentMethod();
+        final Account otherAccount = createAccountWithDefaultPaymentMethod();
+
+        final DateTime effectiveDate = clock.getUTCNow();
+        final BigDecimal creditAmount = BigDecimal.TEN;
+        final Credit credit = new Credit();
+        credit.setAccountId(account.getAccountId());
+        credit.setInvoiceId(null);
+        credit.setCreditAmount(creditAmount);
+        final Credit creditJson = killBillClient.createCredit(credit, createdBy, reason, comment);
+
+        Invoice invoice = killBillClient.getInvoice(creditJson.getInvoiceId());
+        Assert.assertEquals(invoice.getStatus(), InvoiceStatus.DRAFT.toString());
+
+        killBillClient.invoiceStatusTransition(otherAccount.getAccountId(), invoice.getInvoiceId(), createdBy, reason, comment);
+
+    }
+    */
+
 }