killbill-memoizeit
Changes
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithWrittenOffTag.java 111(+111 -0)
invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java 13(+13 -0)
Details
diff --git a/api/src/main/java/org/killbill/billing/tag/TagInternalApi.java b/api/src/main/java/org/killbill/billing/tag/TagInternalApi.java
index 7181a4f..90eda82 100644
--- a/api/src/main/java/org/killbill/billing/tag/TagInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/tag/TagInternalApi.java
@@ -40,6 +40,9 @@ public interface TagInternalApi {
*/
public List<Tag> getTags(UUID objectId, ObjectType objectType, InternalTenantContext context);
+
+ public List<Tag> getTagsForAccountType(ObjectType objectType, boolean includedDeleted, InternalTenantContext internalTenantContext);
+
public void addTag(final UUID objectId, final ObjectType objectType, UUID tagDefinitionId, InternalCallContext context) throws TagApiException;
public void removeTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, InternalCallContext context) throws TagApiException;
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithWrittenOffTag.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithWrittenOffTag.java
new file mode 100644
index 0000000..f5d854c
--- /dev/null
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithWrittenOffTag.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.beatrix.integration;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.api.TestApiListener.NextEvent;
+import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.invoice.api.Invoice;
+import org.killbill.billing.invoice.api.InvoiceUserApi;
+import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.util.api.TagApiException;
+import org.killbill.billing.util.api.TagDefinitionApiException;
+import org.killbill.billing.util.api.TagUserApi;
+import org.killbill.billing.util.tag.ControlTagType;
+import org.killbill.billing.util.tag.Tag;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class TestIntegrationWithWrittenOffTag extends TestIntegrationBase {
+
+ @Inject
+ private InvoiceUserApi invoiceApi;
+
+ @Inject
+ private TagUserApi tagApi;
+
+ private Account account;
+ private String productName;
+ private BillingPeriod term;
+
+ @Override
+ @BeforeMethod(groups = "slow")
+ public void beforeMethod() throws Exception {
+ super.beforeMethod();
+ account = createAccountWithNonOsgiPaymentMethod(getAccountData(25));
+ assertNotNull(account);
+ productName = "Shotgun";
+ term = BillingPeriod.MONTHLY;
+ }
+
+ @Test(groups = "slow")
+ public void testWithWrittenOffInvoice() throws Exception {
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+
+ // Put the account in AUTO_PAY_OFF to make sure payment system does not try to pay initial invoices
+ add_AUTO_PAY_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
+
+ // set next invoice to fail and create network
+ final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
+ assertNotNull(bpEntitlement);
+
+ List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
+ assertEquals(invoices.size(), 1);
+
+ busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE);
+ clock.addDays(31);
+ assertListenerStatus();
+
+ invoices = invoiceApi.getInvoicesByAccount(account.getId(), callContext);
+ assertEquals(invoices.size(), 2);
+
+ // Tag non $0 invoice with WRITTEN_OFF and remove AUTO_PAY_OFF => System should still not pay anything
+ add_WRITTEN_OFF_Tag(invoices.get(1).getId(), ObjectType.INVOICE);
+ remove_AUTO_PAY_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
+ assertListenerStatus();
+
+ List<Payment> accountPayments = paymentApi.getAccountPayments(account.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+ assertEquals(accountPayments.size(), 0);
+
+ }
+
+ private void add_WRITTEN_OFF_Tag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
+ busHandler.pushExpectedEvent(NextEvent.TAG);
+ tagApi.addTag(id, type, ControlTagType.WRITTEN_OFF.getId(), callContext);
+ assertListenerStatus();
+ final List<Tag> tags = tagApi.getTagsForObject(id, type, false, callContext);
+ assertEquals(tags.size(), 1);
+ }
+
+}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index a4a7621..80472a9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -42,8 +42,6 @@ import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.api.InvoicePaymentType;
import org.killbill.billing.invoice.api.WithAccountLock;
import org.killbill.billing.invoice.dao.InvoiceDao;
-import org.killbill.billing.invoice.dao.InvoiceDaoHelper;
-import org.killbill.billing.invoice.dao.InvoiceItemModelDao;
import org.killbill.billing.invoice.dao.InvoiceModelDao;
import org.killbill.billing.invoice.dao.InvoicePaymentModelDao;
import org.killbill.billing.invoice.model.DefaultInvoice;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
index 00df900..a5cf5c4 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
@@ -21,6 +21,8 @@ import java.util.Comparator;
import java.util.List;
import java.util.UUID;
+import javax.inject.Inject;
+
import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.model.CreditBalanceAdjInvoiceItem;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -34,8 +36,9 @@ public class CBADao {
private final InvoiceDaoHelper invoiceDaoHelper;
- public CBADao() {
- this.invoiceDaoHelper = new InvoiceDaoHelper();
+ @Inject
+ public CBADao(final InvoiceDaoHelper invoiceDaoHelper) {
+ this.invoiceDaoHelper = invoiceDaoHelper;
}
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 8f97ea4..9f86bc9 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
@@ -104,14 +104,16 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
final CacheControllerDispatcher cacheControllerDispatcher,
final NonEntityDao nonEntityDao,
final InvoiceConfig invoiceConfig,
+ final InvoiceDaoHelper invoiceDaoHelper,
+ final CBADao cbaDao,
final InternalCallContextFactory internalCallContextFactory) {
super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao), InvoiceSqlDao.class);
this.nextBillingDatePoster = nextBillingDatePoster;
this.eventBus = eventBus;
this.invoiceConfig = invoiceConfig;
this.internalCallContextFactory = internalCallContextFactory;
- this.invoiceDaoHelper = new InvoiceDaoHelper();
- this.cbaDao = new CBADao();
+ this.invoiceDaoHelper = invoiceDaoHelper;
+ this.cbaDao = cbaDao;
this.clock = clock;
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
index 407aa6f..f6b6619 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
@@ -28,23 +28,36 @@ import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
+import javax.inject.Inject;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
+import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceItemType;
+import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import org.killbill.billing.util.tag.ControlTagType;
+import org.killbill.billing.util.tag.Tag;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
public class InvoiceDaoHelper {
+ private final TagInternalApi tagInternalApi;
+
+ @Inject
+ public InvoiceDaoHelper(final TagInternalApi tagInternalApi) {
+ this.tagInternalApi = tagInternalApi;
+ }
+
/**
* Find amounts to adjust for individual items, if not specified.
* The user gives us a list of items to adjust associated with a given amount (how much to refund per invoice item).
@@ -204,11 +217,13 @@ public class InvoiceDaoHelper {
public void populateChildren(final InvoiceModelDao invoice, final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalTenantContext context) {
getInvoiceItemsWithinTransaction(ImmutableList.<InvoiceModelDao>of(invoice), entitySqlDaoWrapperFactory, context);
getInvoicePaymentsWithinTransaction(ImmutableList.<InvoiceModelDao>of(invoice), entitySqlDaoWrapperFactory, context);
+ setInvoiceWrittenOff(invoice, context);
}
public void populateChildren(final Iterable<InvoiceModelDao> invoices, final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalTenantContext context) {
getInvoiceItemsWithinTransaction(invoices, entitySqlDaoWrapperFactory, context);
getInvoicePaymentsWithinTransaction(invoices, entitySqlDaoWrapperFactory, context);
+ setInvoicesWrittenOff(invoices, context);
}
public List<InvoiceModelDao> getAllInvoicesByAccountFromTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalTenantContext context) {
@@ -267,4 +282,37 @@ public class InvoiceDaoHelper {
}
}
}
+
+ private void setInvoicesWrittenOff(final Iterable<InvoiceModelDao> invoices, final InternalTenantContext internalTenantContext) {
+
+ final List<Tag> tags = tagInternalApi.getTagsForAccountType(ObjectType.INVOICE, false, internalTenantContext);
+ final Iterable<Tag> writtenOffTags = filterForWrittenOff(tags);
+ for (final Tag cur : writtenOffTags) {
+ final InvoiceModelDao foundInvoice = Iterables.tryFind(invoices, new Predicate<InvoiceModelDao>() {
+ @Override
+ public boolean apply(final InvoiceModelDao input) {
+ return input.getId().equals(cur.getObjectId());
+ }
+ }).orNull();
+ if (foundInvoice != null) {
+ foundInvoice.setIsWrittenOff(true);
+ }
+ }
+ }
+
+ private void setInvoiceWrittenOff(final InvoiceModelDao invoice, final InternalTenantContext internalTenantContext) {
+ final List<Tag> tags = tagInternalApi.getTags(invoice.getId(), ObjectType.INVOICE, internalTenantContext);
+ final Iterable<Tag> writtenOffTags = filterForWrittenOff(tags);
+ invoice.setIsWrittenOff(writtenOffTags.iterator().hasNext());
+ }
+
+ private Iterable<Tag> filterForWrittenOff(final List<Tag> tags) {
+ return Iterables.filter(tags, new Predicate<Tag>() {
+ @Override
+ public boolean apply(final Tag input) {
+ return input.getTagDefinitionId().equals(ControlTagType.WRITTEN_OFF.getId());
+ }
+ });
+ }
+
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
index 5d62bf0..0316d8d 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDao.java
@@ -46,6 +46,8 @@ public class InvoiceModelDao extends EntityModelDaoBase implements EntityModelDa
private List<InvoicePaymentModelDao> invoicePayments = new LinkedList<InvoicePaymentModelDao>();
private Currency processedCurrency;
+ private boolean isWrittenOff;
+
public InvoiceModelDao() { /* For the DAO mapper */ }
public InvoiceModelDao(final UUID id, @Nullable final DateTime createdDate, final UUID accountId,
@@ -58,6 +60,7 @@ public class InvoiceModelDao extends EntityModelDaoBase implements EntityModelDa
this.targetDate = targetDate;
this.currency = currency;
this.migrated = migrated;
+ this.isWrittenOff = false;
}
public InvoiceModelDao(final UUID accountId, final LocalDate invoiceDate, final LocalDate targetDate, final Currency currency, final boolean migrated) {
@@ -157,6 +160,14 @@ public class InvoiceModelDao extends EntityModelDaoBase implements EntityModelDa
this.invoicePayments = invoicePayments;
}
+ public boolean isWrittenOff() {
+ return isWrittenOff;
+ }
+
+ public void setIsWrittenOff(final boolean isWrittenOff) {
+ this.isWrittenOff = isWrittenOff;
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java b/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java
index 1973ff2..3080c5a 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceModule.java
@@ -36,8 +36,10 @@ import org.killbill.billing.invoice.api.invoice.DefaultInvoicePaymentApi;
import org.killbill.billing.invoice.api.migration.DefaultInvoiceMigrationApi;
import org.killbill.billing.invoice.api.svcs.DefaultInvoiceInternalApi;
import org.killbill.billing.invoice.api.user.DefaultInvoiceUserApi;
+import org.killbill.billing.invoice.dao.CBADao;
import org.killbill.billing.invoice.dao.DefaultInvoiceDao;
import org.killbill.billing.invoice.dao.InvoiceDao;
+import org.killbill.billing.invoice.dao.InvoiceDaoHelper;
import org.killbill.billing.invoice.generator.DefaultInvoiceGenerator;
import org.killbill.billing.invoice.generator.FixedAndRecurringInvoiceItemGenerator;
import org.killbill.billing.invoice.generator.InvoiceGenerator;
@@ -70,6 +72,8 @@ public class DefaultInvoiceModule extends KillBillModule implements InvoiceModul
protected void installInvoiceDao() {
bind(InvoiceDao.class).to(DefaultInvoiceDao.class).asEagerSingleton();
+ bind(InvoiceDaoHelper.class).asEagerSingleton();
+ bind(CBADao.class).asEagerSingleton();
}
@Override
@@ -162,7 +166,6 @@ public class DefaultInvoiceModule extends KillBillModule implements InvoiceModul
installInvoiceMigrationApi();
installResourceBundleFactory();
bind(RawUsageOptimizer.class).asEagerSingleton();
- ;
bind(InvoiceApiHelper.class).asEagerSingleton();
}
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
index 0394a5a..514e368 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
@@ -51,6 +51,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
private final LocalDate targetDate;
private final Currency currency;
private final boolean migrationInvoice;
+ private final boolean isWrittenOff;
private final Currency processedCurrency;
@@ -63,7 +64,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
public DefaultInvoice(final UUID invoiceId, final UUID accountId, @Nullable final Integer invoiceNumber, final LocalDate invoiceDate,
final LocalDate targetDate, final Currency currency, final boolean isMigrationInvoice) {
- this(invoiceId, null, accountId, invoiceNumber, invoiceDate, targetDate, currency, currency, isMigrationInvoice);
+ this(invoiceId, null, accountId, invoiceNumber, invoiceDate, targetDate, currency, currency, isMigrationInvoice, false);
}
@@ -71,7 +72,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
public DefaultInvoice(final InvoiceModelDao invoiceModelDao) {
this(invoiceModelDao.getId(), invoiceModelDao.getCreatedDate(), invoiceModelDao.getAccountId(),
invoiceModelDao.getInvoiceNumber(), invoiceModelDao.getInvoiceDate(), invoiceModelDao.getTargetDate(),
- invoiceModelDao.getCurrency(), invoiceModelDao.getProcessedCurrency(), invoiceModelDao.isMigrated());
+ invoiceModelDao.getCurrency(), invoiceModelDao.getProcessedCurrency(), invoiceModelDao.isMigrated(), invoiceModelDao.isWrittenOff());
addInvoiceItems(Collections2.transform(invoiceModelDao.getInvoiceItems(), new Function<InvoiceItemModelDao, InvoiceItem>() {
@Override
public InvoiceItem apply(final InvoiceItemModelDao input) {
@@ -88,7 +89,8 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
private DefaultInvoice(final UUID invoiceId, @Nullable final DateTime createdDate, final UUID accountId,
@Nullable final Integer invoiceNumber, final LocalDate invoiceDate,
- final LocalDate targetDate, final Currency currency, final Currency processedCurrency, final boolean isMigrationInvoice) {
+ final LocalDate targetDate, final Currency currency, final Currency processedCurrency,
+ final boolean isMigrationInvoice, final boolean isWrittenOff) {
super(invoiceId, createdDate, createdDate);
this.accountId = accountId;
this.invoiceNumber = invoiceNumber;
@@ -97,6 +99,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
this.currency = currency;
this.processedCurrency = processedCurrency;
this.migrationInvoice = isMigrationInvoice;
+ this.isWrittenOff = isWrittenOff;
this.invoiceItems = new ArrayList<InvoiceItem>();
this.payments = new ArrayList<InvoicePayment>();
}
@@ -105,7 +108,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
// Semi deep copy where we copy the lists but not the elements in the lists since they are immutables.
@Override
public Object clone() {
- final Invoice clonedInvoice = new DefaultInvoice(getId(), getCreatedDate(), getAccountId(), getInvoiceNumber(), getInvoiceDate(), getTargetDate(), getCurrency(), getProcessedCurrency(), isMigrationInvoice());
+ final Invoice clonedInvoice = new DefaultInvoice(getId(), getCreatedDate(), getAccountId(), getInvoiceNumber(), getInvoiceDate(), getTargetDate(), getCurrency(), getProcessedCurrency(), isMigrationInvoice(), isWrittenOff());
clonedInvoice.getInvoiceItems().addAll(getInvoiceItems());
clonedInvoice.getPayments().addAll(getPayments());
return clonedInvoice;
@@ -228,12 +231,17 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
@Override
public BigDecimal getBalance() {
- return InvoiceCalculatorUtils.computeInvoiceBalance(currency, invoiceItems, payments);
+ return isWrittenOff ? BigDecimal.ZERO : InvoiceCalculatorUtils.computeInvoiceBalance(currency, invoiceItems, payments);
+ }
+
+ public boolean isWrittenOff() {
+ return isWrittenOff;
}
@Override
public String toString() {
return "DefaultInvoice [items=" + invoiceItems + ", payments=" + payments + ", id=" + id + ", accountId=" + accountId + ", invoiceDate=" + invoiceDate + ", targetDate=" + targetDate + ", currency=" + currency + ", amountPaid=" + getPaidAmount() + "]";
}
+
}
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 afac77d..edbe79f 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
@@ -61,6 +61,8 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
invoiceId = invoiceUtil.generateRegularInvoice(account, clock.getUTCNow(), callContext);
}
+
+
@Test(groups = "slow")
public void testPostExternalChargeOnNewInvoice() throws Exception {
// Initial account balance
@@ -342,14 +344,25 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
public void testAddRemoveWrittenOffTag() throws InvoiceApiException, TagApiException {
+
+ final Invoice originalInvoice = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(originalInvoice.getBalance(), new BigDecimal("0.77"));
+
invoiceUserApi.tagInvoiceAsWrittenOff(invoiceId, callContext);
List<Tag> tags = tagUserApi.getTagsForObject(invoiceId, ObjectType.INVOICE, false, callContext);
assertEquals(tags.size(), 1);
assertEquals(tags.get(0).getTagDefinitionId(), ControlTagType.WRITTEN_OFF.getId());
+ final Invoice invoiceWithTag = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoiceWithTag.getBalance(), BigDecimal.ZERO);
+
+
invoiceUserApi.tagInvoiceAsNotWrittenOff(invoiceId, callContext);
tags = tagUserApi.getTagsForObject(invoiceId, ObjectType.INVOICE, false, callContext);
assertEquals(tags.size(), 0);
+
+ final Invoice invoiceAfterTagRemoval = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoiceAfterTagRemoval.getBalance(), new BigDecimal("0.77"));
}
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestDefaultInvoiceDaoUnit.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestDefaultInvoiceDaoUnit.java
index 052ac21..4c30673 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestDefaultInvoiceDaoUnit.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestDefaultInvoiceDaoUnit.java
@@ -65,7 +65,6 @@ public class TestDefaultInvoiceDaoUnit extends InvoiceTestSuiteNoDB {
final InvoicePaymentModelDao invoicePayment = Mockito.mock(InvoicePaymentModelDao.class);
Mockito.when(invoicePayment.getAmount()).thenReturn(paymentAmount);
- final InvoiceDaoHelper invoiceDaoHelper = new InvoiceDaoHelper();
final BigDecimal actualRefundAmount = invoiceDaoHelper.computePositiveRefundAmount(invoicePayment, requestedAmount, invoiceItemIdsWithAmounts);
Assert.assertEquals(actualRefundAmount, expectedRefundAmount);
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java
index 2e2692e..6945f02 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteNoDB.java
@@ -27,6 +27,7 @@ import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceUserApi;
import org.killbill.billing.invoice.api.formatters.ResourceBundleFactory;
import org.killbill.billing.invoice.dao.InvoiceDao;
+import org.killbill.billing.invoice.dao.InvoiceDaoHelper;
import org.killbill.billing.invoice.generator.FixedAndRecurringInvoiceItemGenerator;
import org.killbill.billing.invoice.generator.InvoiceGenerator;
import org.killbill.billing.invoice.glue.TestInvoiceModuleNoDB;
@@ -99,6 +100,8 @@ public abstract class InvoiceTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
@Inject
protected RawUsageOptimizer rawUsageOptimizer;
@Inject
+ protected InvoiceDaoHelper invoiceDaoHelper;
+ @Inject
protected FixedAndRecurringInvoiceItemGenerator fixedAndRecurringInvoiceItemGenerator;
@Override
protected KillbillConfigSource getConfigSource() {
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
index 638f017..725d6d7 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
@@ -35,6 +35,7 @@ import org.killbill.billing.invoice.api.InvoiceItemType;
import org.killbill.billing.invoice.api.InvoicePaymentType;
import org.killbill.billing.invoice.api.formatters.InvoiceFormatter;
import org.killbill.billing.invoice.api.formatters.ResourceBundleFactory.ResourceBundleType;
+import org.killbill.billing.invoice.dao.InvoiceModelDao;
import org.killbill.billing.invoice.model.CreditAdjInvoiceItem;
import org.killbill.billing.invoice.model.CreditBalanceAdjInvoiceItem;
import org.killbill.billing.invoice.model.DefaultInvoice;
@@ -370,7 +371,12 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
@Test(groups = "fast")
public void testProcessedCurrencyExists() throws Exception {
- final Invoice invoice = new DefaultInvoice(UUID.randomUUID(), UUID.randomUUID(), new Integer(234), new LocalDate(), new LocalDate(), Currency.BRL, false);
+
+ // Use InvoiceModelDao to build the invoice to be able to set the processedCurrency (No suitable CTOR for DefaultInvoice on purpose)
+ final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(UUID.randomUUID(), new LocalDate(), new LocalDate(), Currency.BRL);
+ invoiceModelDao.setProcessedCurrency(Currency.USD);
+
+ final Invoice invoice = new DefaultInvoice(invoiceModelDao);
checkOutput(invoice,
"{{#invoice.processedCurrency}}" +
diff --git a/util/src/main/java/org/killbill/billing/util/tag/api/DefaultTagUserApi.java b/util/src/main/java/org/killbill/billing/util/tag/api/DefaultTagUserApi.java
index 6426727..44f530c 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/api/DefaultTagUserApi.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/api/DefaultTagUserApi.java
@@ -188,7 +188,7 @@ public class DefaultTagUserApi implements TagUserApi {
@Override
public List<Tag> getTagsForAccountType(final UUID accountId, final ObjectType objectType, final boolean includedDeleted, final TenantContext context) {
- return withModelTransform(tagDao.getTagsForAccountType(accountId, objectType, includedDeleted, internalCallContextFactory.createInternalTenantContext(accountId, context)));
+ return withModelTransform(tagDao.getTagsForAccountType(objectType, includedDeleted, internalCallContextFactory.createInternalTenantContext(accountId, context)));
}
@Override
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
index 0ee5cde..865af9d 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
@@ -84,7 +84,7 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
}
@Override
- public List<TagModelDao> getTagsForAccountType(final UUID accountId, final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
+ public List<TagModelDao> getTagsForAccountType(final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
final List<TagModelDao> allTags = getTagsForAccount(includedDeleted, internalTenantContext);
return ImmutableList.<TagModelDao>copyOf(Collections2.filter(allTags, new Predicate<TagModelDao>() {
@Override
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/TagDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/TagDao.java
index e8932a6..5dd9135 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/TagDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/TagDao.java
@@ -35,7 +35,7 @@ public interface TagDao extends EntityDao<TagModelDao, Tag, TagApiException> {
List<TagModelDao> getTagsForObject(UUID objectId, ObjectType objectType, boolean includedDeleted, InternalTenantContext internalTenantContext);
- List<TagModelDao> getTagsForAccountType(UUID accountId, ObjectType objectType, boolean includedDeleted, InternalTenantContext internalTenantContext);
+ List<TagModelDao> getTagsForAccountType(ObjectType objectType, boolean includedDeleted, InternalTenantContext internalTenantContext);
List<TagModelDao> getTagsForAccount(boolean includedDeleted, InternalTenantContext internalTenantContext);
}
diff --git a/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java b/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java
index e40f7f5..9db3025 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java
@@ -35,6 +35,7 @@ import org.killbill.billing.util.tag.dao.TagModelDaoHelper;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
public class DefaultTagInternalApi implements TagInternalApi {
@@ -61,15 +62,12 @@ public class DefaultTagInternalApi implements TagInternalApi {
@Override
public List<Tag> getTags(final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
- return ImmutableList.<Tag>copyOf(Collections2.transform(tagDao.getTagsForObject(objectId, objectType, false, context),
- new Function<TagModelDao, Tag>() {
- @Override
- public Tag apply(final TagModelDao input) {
- return TagModelDaoHelper.isControlTag(input.getTagDefinitionId()) ?
- new DefaultControlTag(ControlTagType.getTypeFromId(input.getTagDefinitionId()), objectType, objectId, input.getCreatedDate()) :
- new DescriptiveTag(input.getTagDefinitionId(), objectType, objectId, input.getCreatedDate());
- }
- }));
+ return toTagList(tagDao.getTagsForObject(objectId, objectType, false, context));
+ }
+
+ @Override
+ public List<Tag> getTagsForAccountType(final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
+ return toTagList(tagDao.getTagsForAccountType(objectType, includedDeleted, internalTenantContext));
}
@Override
@@ -85,4 +83,17 @@ public class DefaultTagInternalApi implements TagInternalApi {
throws TagApiException {
tagDao.deleteTag(objectId, objectType, tagDefinitionId, context);
}
+
+ private List<Tag> toTagList(final List<TagModelDao> input) {
+ return ImmutableList.<Tag>copyOf(Iterables.transform(input, new Function<TagModelDao, Tag>() {
+ @Override
+ public Tag apply(final TagModelDao input) {
+ return TagModelDaoHelper.isControlTag(input.getTagDefinitionId()) ?
+ new DefaultControlTag(ControlTagType.getTypeFromId(input.getTagDefinitionId()), input.getObjectType(), input.getObjectId(), input.getCreatedDate()) :
+ new DescriptiveTag(input.getTagDefinitionId(), input.getObjectType(), input.getObjectId(), input.getCreatedDate());
+ }
+ }));
+ }
+
+
}
diff --git a/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java b/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java
index dcbe233..a2238e9 100644
--- a/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java
+++ b/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java
@@ -87,7 +87,7 @@ public class MockTagDao extends MockEntityDaoBase<TagModelDao, Tag, TagApiExcept
}
@Override
- public List<TagModelDao> getTagsForAccountType(final UUID accountId, final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
+ public List<TagModelDao> getTagsForAccountType(final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
throw new UnsupportedOperationException();
}