Details
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
index ed205d5..cf4b16a 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -19,6 +19,7 @@ package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
import java.util.List;
+import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
@@ -33,12 +34,14 @@ import org.killbill.billing.account.api.AccountData;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
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.entitlement.api.DefaultEntitlement;
import org.killbill.billing.invoice.api.DefaultInvoiceService;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoiceItemType;
+import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
import org.killbill.billing.invoice.model.TaxInvoiceItem;
import org.killbill.billing.invoice.notification.DefaultNextBillingDateNotifier;
import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
@@ -54,11 +57,15 @@ import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificatio
import org.killbill.queue.retry.RetryNotificationEvent;
import org.killbill.queue.retry.RetryableService;
import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
public class TestWithInvoicePlugin extends TestIntegrationBase {
@@ -93,6 +100,65 @@ public class TestWithInvoicePlugin extends TestIntegrationBase {
}, testInvoicePluginApi);
}
+ @BeforeMethod(groups = "slow")
+ public void setUp() throws Exception {
+ testInvoicePluginApi.additionalInvoiceItem = null;
+ }
+
+ @Test(groups = "slow")
+ public void testBasicAdditionalExternalChargeItem() throws Exception {
+ // We take april as it has 30 days (easier to play with BCD)
+ // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
+ clock.setDay(new LocalDate(2012, 4, 1));
+
+ final AccountData accountData = getAccountData(1);
+ final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+ accountChecker.checkAccount(account.getId(), accountData, callContext);
+
+ final UUID pluginInvoiceItemId = UUID.randomUUID();
+ final UUID pluginLinkedItemId = UUID.randomUUID();
+ testInvoicePluginApi.additionalInvoiceItem = new ExternalChargeInvoiceItem(pluginInvoiceItemId,
+ clock.getUTCNow(),
+ null,
+ account.getId(),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "My charge",
+ clock.getUTCToday(),
+ null,
+ BigDecimal.TEN,
+ null,
+ Currency.USD,
+ pluginLinkedItemId,
+ null);
+
+ // Create original subscription (Trial PHASE) -> $0 invoice but plugin added one item
+ final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext,
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")),
+ new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.EXTERNAL_CHARGE, BigDecimal.TEN));
+ subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
+
+ final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
+ assertEquals(invoices.size(), 1);
+ final List<InvoiceItem> invoiceItems = invoices.get(0).getInvoiceItems();
+ final InvoiceItem externalCharge = Iterables.tryFind(invoiceItems, new Predicate<InvoiceItem>() {
+ @Override
+ public boolean apply(final InvoiceItem input) {
+ return input.getInvoiceItemType() == InvoiceItemType.EXTERNAL_CHARGE;
+ }
+ }).orNull();
+ assertNotNull(externalCharge);
+ // verify the ID is the one passed by the plugin #818
+ assertEquals(externalCharge.getId(), pluginInvoiceItemId);
+ // verify the ID is the one passed by the plugin #887
+ assertEquals(externalCharge.getLinkedItemId(), pluginLinkedItemId);
+ }
+
@Test(groups = "slow")
public void testWithRetries() throws Exception {
// We take april as it has 30 days (easier to play with BCD)
@@ -250,13 +316,17 @@ public class TestWithInvoicePlugin extends TestIntegrationBase {
public class TestInvoicePluginApi implements InvoicePluginApi {
boolean shouldThrowException = false;
+ InvoiceItem additionalInvoiceItem;
@Override
public List<InvoiceItem> getAdditionalInvoiceItems(final Invoice invoice, final boolean isDryRun, final Iterable<PluginProperty> pluginProperties, final CallContext callContext) {
if (shouldThrowException) {
throw new InvoicePluginApiRetryException();
+ } else if (additionalInvoiceItem != null) {
+ return ImmutableList.<InvoiceItem>of(additionalInvoiceItem);
+ } else {
+ return ImmutableList.<InvoiceItem>of(createTaxInvoiceItem(invoice));
}
- return ImmutableList.<InvoiceItem>of(createTaxInvoiceItem(invoice));
}
private InvoiceItem createTaxInvoiceItem(final Invoice invoice) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index ad28373..8dc4193 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -48,7 +48,6 @@ import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.events.BusInternalEvent;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
@@ -77,6 +76,7 @@ import org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFu
import org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates.UsageDef;
import org.killbill.billing.invoice.model.DefaultInvoice;
import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
+import org.killbill.billing.invoice.model.InvoiceItemCatalogBase;
import org.killbill.billing.invoice.model.InvoiceItemFactory;
import org.killbill.billing.invoice.model.ItemAdjInvoiceItem;
import org.killbill.billing.invoice.model.ParentInvoiceItem;
@@ -571,7 +571,30 @@ public class InvoiceDispatcher {
if (exitingItem != null) {
invoice.removeInvoiceItem(exitingItem);
}
- invoice.addInvoiceItem(cur);
+
+ final InvoiceItem sanitizedInvoiceItemFromPlugin = new InvoiceItemCatalogBase(cur.getId(),
+ cur.getCreatedDate(),
+ MoreObjects.firstNonNull(cur.getInvoiceId(), invoice.getId()),
+ cur.getAccountId(),
+ cur.getBundleId(),
+ cur.getSubscriptionId(),
+ cur.getDescription(),
+ cur.getPlanName(),
+ cur.getPhaseName(),
+ cur.getUsageName(),
+ cur.getPrettyPlanName(),
+ cur.getPrettyPhaseName(),
+ cur.getPrettyUsageName(),
+ cur.getStartDate(),
+ cur.getEndDate(),
+ cur.getAmount(),
+ cur.getRate(),
+ cur.getCurrency(),
+ cur.getLinkedItemId(),
+ cur.getQuantity(),
+ cur.getItemDetails(),
+ cur.getInvoiceItemType());
+ invoice.addInvoiceItem(sanitizedInvoiceItemFromPlugin);
}
// Use credit after we call the plugin (https://github.com/killbill/killbill/issues/637)
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java
index 6a7eb2e..305fd7d 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -32,10 +32,7 @@ public abstract class AdjInvoiceItem extends InvoiceItemBase {
AdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId,
final LocalDate startDate, final LocalDate endDate, @Nullable final String description,
- final BigDecimal amount, final Currency currency, @Nullable final UUID reversingId) {
- super(id, createdDate, invoiceId, accountId, null, null, description, startDate, endDate, amount, null, currency, reversingId);
+ final BigDecimal amount, final Currency currency, @Nullable final UUID reversingId, final InvoiceItemType invoiceItemType) {
+ super(id, createdDate, invoiceId, accountId, null, null, description, startDate, endDate, amount, null, currency, reversingId, invoiceItemType);
}
-
- @Override
- public abstract InvoiceItemType getInvoiceItemType();
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java
index 597c4a1..68ef0d8 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -38,15 +38,9 @@ public class CreditAdjInvoiceItem extends AdjInvoiceItem {
this(UUIDs.randomUUID(), null, invoiceId, accountId, date, description, amount, currency);
}
-
public CreditAdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final LocalDate date,
@Nullable final String description, final BigDecimal amount, final Currency currency) {
- super(id, createdDate, invoiceId, accountId, date, date, description, amount, currency, null);
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.CREDIT_ADJ;
+ super(id, createdDate, invoiceId, accountId, date, date, description, amount, currency, null, InvoiceItemType.CREDIT_ADJ);
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/CreditBalanceAdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/CreditBalanceAdjInvoiceItem.java
index 5dfe7cc..a70f0bf 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/CreditBalanceAdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/CreditBalanceAdjInvoiceItem.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -45,12 +45,7 @@ public class CreditBalanceAdjInvoiceItem extends AdjInvoiceItem {
public CreditBalanceAdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId,
final LocalDate date, final UUID linkedInvoiceItemId,
@Nullable final String description, final BigDecimal amount, final Currency currency) {
- super(id, createdDate, invoiceId, accountId, date, date, description, amount, currency, linkedInvoiceItemId);
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.CBA_ADJ;
+ super(id, createdDate, invoiceId, accountId, date, date, description, amount, currency, linkedInvoiceItemId, InvoiceItemType.CBA_ADJ);
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java
index c56e7f0..78ff132 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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:
*
@@ -41,13 +43,13 @@ public class ExternalChargeInvoiceItem extends InvoiceItemCatalogBase {
public ExternalChargeInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final String description, final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final Currency currency, @Nullable final String itemDetails) {
- super(id, createdDate, invoiceId, accountId, bundleId, null, description, null, null, null, startDate, endDate, amount, null, currency, null, null, itemDetails);
+ super(id, createdDate, invoiceId, accountId, bundleId, null, description, null, null, null, startDate, endDate, amount, null, currency, null, null, itemDetails, InvoiceItemType.EXTERNAL_CHARGE);
}
public ExternalChargeInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId,
final String planName, final String phaseName, final String prettyPlanName, final String prettyPhaseName, @Nullable final String description, final LocalDate startDate, final LocalDate endDate,
final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId, @Nullable String itemDetails) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, startDate, endDate, amount, rate, currency, linkedItemId, null, itemDetails);
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, startDate, endDate, amount, rate, currency, linkedItemId, null, itemDetails, InvoiceItemType.EXTERNAL_CHARGE);
}
@Override
@@ -62,9 +64,4 @@ public class ExternalChargeInvoiceItem extends InvoiceItemCatalogBase {
return String.format("%s (external charge)", getPlanName());
}
}
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.EXTERNAL_CHARGE;
- }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java
index b177056..9f9d90e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java
@@ -40,13 +40,13 @@ public class FixedPriceInvoiceItem extends InvoiceItemCatalogBase {
public FixedPriceInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId,
final UUID subscriptionId, final String planName, final String phaseName,
@Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, date, null, amount, null, currency, null);
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, date, null, amount, null, currency, null, InvoiceItemType.FIXED);
}
public FixedPriceInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId,
final UUID subscriptionId, final String planName, final String phaseName, final String prettyPlanName, final String prettyPhaseName,
@Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, date, null, amount, null, currency, null);
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, date, null, amount, null, currency, null, InvoiceItemType.FIXED);
}
@Override
@@ -65,9 +65,4 @@ public class FixedPriceInvoiceItem extends InvoiceItemCatalogBase {
}
}
}
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.FIXED;
- }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
index b183ebe..ed31c6a 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2014 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -42,6 +42,7 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
protected final BigDecimal amount;
protected final Currency currency;
protected final String description;
+ protected final InvoiceItemType invoiceItemType;
/* Fixed and recurring specific */
protected final UUID subscriptionId;
@@ -59,34 +60,27 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description,
- final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, final UUID reversedItemId) {
- this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId, null, null);
+ final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, final UUID reversedItemId, final InvoiceItemType invoiceItemType) {
+ this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId, null, null, invoiceItemType);
}
public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description,
final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, final UUID reversedItemId,
- @Nullable final Integer quantity, @Nullable final String itemDetails) {
- this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId, quantity, itemDetails);
+ @Nullable final Integer quantity, @Nullable final String itemDetails, final InvoiceItemType invoiceItemType) {
+ this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId, quantity, itemDetails, invoiceItemType);
}
// For parent invoices
public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID childAccountId,
- final BigDecimal amount, final Currency currency, final String description) {
- this(id, createdDate, invoiceId, accountId, childAccountId, null, null, description, null, null, amount, null, currency, null, null, null);
- }
-
- public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID childAccountId, @Nullable final UUID bundleId,
- @Nullable final UUID subscriptionId, @Nullable final String description,
- @Nullable final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency,
- final UUID reversedItemId) {
- this(id, createdDate, invoiceId, accountId, childAccountId, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId, null, null);
+ final BigDecimal amount, final Currency currency, final String description, final InvoiceItemType invoiceItemType) {
+ this(id, createdDate, invoiceId, accountId, childAccountId, null, null, description, null, null, amount, null, currency, null, null, null, invoiceItemType);
}
private InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID childAccountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description,
@Nullable final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency,
- final UUID reversedItemId, @Nullable final Integer quantity, @Nullable final String itemDetails) {
+ final UUID reversedItemId, @Nullable final Integer quantity, @Nullable final String itemDetails, final InvoiceItemType invoiceItemType) {
super(id, createdDate, createdDate);
this.invoiceId = invoiceId;
this.accountId = accountId;
@@ -102,6 +96,7 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
this.linkedItemId = reversedItemId;
this.quantity = quantity;
this.itemDetails = itemDetails;
+ this.invoiceItemType = invoiceItemType;
}
@Override
@@ -313,8 +308,12 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
}
@Override
- public abstract InvoiceItemType getInvoiceItemType();
+ public InvoiceItemType getInvoiceItemType() {
+ return invoiceItemType;
+ }
@Override
- public abstract String getDescription();
+ public String getDescription() {
+ return description;
+ }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java
index 9ad25ce..4afb0e8 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -26,8 +26,9 @@ import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoiceItem;
+import org.killbill.billing.invoice.api.InvoiceItemType;
-public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements InvoiceItem {
+public class InvoiceItemCatalogBase extends InvoiceItemBase implements InvoiceItem {
protected final String planName;
protected final String phaseName;
@@ -39,31 +40,30 @@ public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements
public InvoiceItemCatalogBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
- final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId) {
- this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, null, null, null, startDate, endDate, amount, rate, currency, linkedItemId, null, null);
+ final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId, final InvoiceItemType invoiceItemType) {
+ this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, null, null, null, startDate, endDate, amount, rate, currency, linkedItemId, null, null, invoiceItemType);
}
public InvoiceItemCatalogBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId,
- @Nullable final Integer quantity, @Nullable final String itemDetails) {
- this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, null, null, null, startDate, endDate, amount, rate, currency, linkedItemId, quantity, itemDetails);
+ @Nullable final Integer quantity, @Nullable final String itemDetails, final InvoiceItemType invoiceItemType) {
+ this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, null, null, null, startDate, endDate, amount, rate, currency, linkedItemId, quantity, itemDetails, invoiceItemType);
}
public InvoiceItemCatalogBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
@Nullable final String prettyPlanName, @Nullable final String prettyPhaseName, @Nullable final String prettyUsageName,
- final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId) {
- this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, startDate, endDate, amount, rate, currency, linkedItemId, null, null);
+ final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId, final InvoiceItemType invoiceItemType) {
+ this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, startDate, endDate, amount, rate, currency, linkedItemId, null, null, invoiceItemType);
}
-
public InvoiceItemCatalogBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
@Nullable final String prettyPlanName, @Nullable final String prettyPhaseName, @Nullable final String prettyUsageName,
final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId,
- @Nullable final Integer quantity, @Nullable final String itemDetails) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, linkedItemId, quantity, itemDetails);
+ @Nullable final Integer quantity, @Nullable final String itemDetails, final InvoiceItemType invoiceItemType) {
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, linkedItemId, quantity, itemDetails, invoiceItemType);
this.planName = planName;
this.phaseName = phaseName;
this.usageName = usageName;
@@ -72,7 +72,6 @@ public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements
this.prettyUsageName = prettyUsageName;
}
-
@Override
public String getPlanName() {
return planName;
@@ -88,7 +87,6 @@ public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements
return usageName;
}
-
@Override
public String getPrettyPlanName() {
return prettyPlanName;
@@ -104,12 +102,11 @@ public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements
return prettyUsageName;
}
-
@Override
public boolean matches(final Object o) {
if (!super.matches(o)) {
- return false;
+ return false;
}
final InvoiceItemCatalogBase that = (InvoiceItemCatalogBase) o;
if (phaseName != null ? !phaseName.equals(that.phaseName) : that.phaseName != null) {
@@ -134,38 +131,17 @@ public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements
public String toString() {
// Note: we don't use all fields here, as the output would be overwhelming
// (we output all invoice items as they are generated).
- final StringBuilder sb = new StringBuilder();
- sb.append(getInvoiceItemType());
- sb.append("{");
- if (planName != null) {
- sb.append("planName=").append(planName);
- }
- if (phaseName != null) {
- sb.append("phaseName=").append(phaseName);
- }
- if (usageName != null) {
- sb.append("usageName=").append(usageName);
- }
- if (startDate != null) {
- sb.append("startDate=").append(startDate);
- }
- if (endDate != null) {
- sb.append("endDate=").append(endDate);
- }
- if (amount != null) {
- sb.append("amount=").append(amount);
- }
- if (rate != null) {
- sb.append("rate=").append(rate);
- }
- if (subscriptionId != null) {
- sb.append("subscriptionId=").append(subscriptionId);
- }
- if (linkedItemId != null) {
- sb.append("linkedItemId=").append(linkedItemId);
- }
+ final StringBuilder sb = new StringBuilder().append(invoiceItemType).append("{");
+ sb.append("planName='").append(planName).append('\'');
+ sb.append(", phaseName='").append(phaseName).append('\'');
+ sb.append(", usageName='").append(usageName).append('\'');
+ sb.append(", startDate=").append(startDate);
+ sb.append(", endDate=").append(endDate);
+ sb.append(", amount=").append(amount);
+ sb.append(", subscriptionId=").append(subscriptionId);
+ sb.append(", rate=").append(rate);
+ sb.append(", linkedItemId=").append(linkedItemId);
sb.append('}');
return sb.toString();
}
-
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/ItemAdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/ItemAdjInvoiceItem.java
index a8ffffc..0f6bcbc 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/ItemAdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/ItemAdjInvoiceItem.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -40,15 +40,9 @@ public class ItemAdjInvoiceItem extends AdjInvoiceItem {
linkedInvoiceItem.getDescription(), amount, currency, linkedInvoiceItem.getId());
}
-
public ItemAdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final LocalDate startDate,
@Nullable final String description, final BigDecimal amount, final Currency currency, final UUID linkedItemId) {
- super(id, createdDate, invoiceId, accountId, startDate, startDate, description, amount, currency, linkedItemId);
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.ITEM_ADJ;
+ super(id, createdDate, invoiceId, accountId, startDate, startDate, description, amount, currency, linkedItemId, InvoiceItemType.ITEM_ADJ);
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/ParentInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/ParentInvoiceItem.java
index 0dc8c8d..be5769b 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/ParentInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/ParentInvoiceItem.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -32,12 +32,7 @@ public class ParentInvoiceItem extends InvoiceItemBase {
public ParentInvoiceItem(@Nullable final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID childAccountId,
final BigDecimal amount, final Currency currency, final String description) {
- super(id, createdDate, invoiceId, accountId, childAccountId, amount, currency, description);
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.PARENT_SUMMARY;
+ super(id, createdDate, invoiceId, accountId, childAccountId, amount, currency, description, InvoiceItemType.PARENT_SUMMARY);
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java
index 45b9866..678ca98 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -48,7 +48,7 @@ public class RecurringInvoiceItem extends InvoiceItemCatalogBase {
public RecurringInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId,
final String planName, final String phaseName, final String prettyPlanName, final String prettyPhaseName, @Nullable final String description, final LocalDate startDate, final LocalDate endDate,
final BigDecimal amount, final BigDecimal rate, final Currency currency) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, startDate, endDate, amount, rate, currency, null);
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, startDate, endDate, amount, rate, currency, null, InvoiceItemType.RECURRING);
}
@Override
@@ -60,9 +60,4 @@ public class RecurringInvoiceItem extends InvoiceItemCatalogBase {
public BigDecimal getRate() {
return rate;
}
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.RECURRING;
- }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/RepairAdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/RepairAdjInvoiceItem.java
index 2eca25f..9d42b86 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/RepairAdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/RepairAdjInvoiceItem.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -45,12 +45,7 @@ public class RepairAdjInvoiceItem extends AdjInvoiceItem {
public RepairAdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final LocalDate startDate, final LocalDate endDate,
@Nullable final String description, final BigDecimal amount, final Currency currency, final UUID reversingId) {
- super(id, createdDate, invoiceId, accountId, startDate, endDate, description, amount, currency, reversingId);
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.REPAIR_ADJ;
+ super(id, createdDate, invoiceId, accountId, startDate, endDate, description, amount, currency, reversingId, InvoiceItemType.REPAIR_ADJ);
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
index cd708e9..4acad06 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
@@ -1,7 +1,8 @@
/*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Groupon licenses this file to you under the Apache License, version 2.0
+ * 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:
*
@@ -43,7 +44,7 @@ public class TaxInvoiceItem extends InvoiceItemCatalogBase {
@Nullable final UUID subscriptionId, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
@Nullable final String prettyPlanName, @Nullable final String prettyPhaseName, @Nullable final String prettyUsageName,
final LocalDate date, @Nullable final String description, final BigDecimal amount, final Currency currency, @Nullable final UUID linkedItemId) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, date, null, amount, null, currency, linkedItemId);
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, date, null, amount, null, currency, linkedItemId, InvoiceItemType.TAX);
}
@Override
@@ -54,9 +55,4 @@ public class TaxInvoiceItem extends InvoiceItemCatalogBase {
return "Tax";
}
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.TAX;
- }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
index e5841aa..6857259 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 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
@@ -49,12 +49,7 @@ public class UsageInvoiceItem extends InvoiceItemCatalogBase {
final String prettyPlanName, final String prettyPhaseName, final String prettyUsageName,
final LocalDate startDate, final LocalDate endDate, @Nullable final String description, final BigDecimal amount, final BigDecimal rate,
final Currency currency, @Nullable final Integer quantity, @Nullable final String itemDetails) {
- super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, startDate, endDate, amount, rate, currency, null, quantity, itemDetails);
- }
-
- @Override
- public InvoiceItemType getInvoiceItemType() {
- return InvoiceItemType.USAGE;
+ super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, startDate, endDate, amount, rate, currency, null, quantity, itemDetails, InvoiceItemType.USAGE);
}
@Override
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
index b0f210e..6d9f9b6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
@@ -106,7 +106,7 @@ public class JaxrsUriBuilder {
// Use "remote" value to support X-Forwarded headers (assumes RemoteIpValve or similar is configured)
// See https://github.com/killbill/killbill/issues/566
uriBuilder.scheme(request.getScheme())
- .host(MoreObjects.firstNonNull(jaxrsConfig.getJaxrsLocationHost(), uriInfo.getAbsolutePath().getHost())) // Should we look for X-Forwarded-By instead?
+ .host(MoreObjects.firstNonNull(jaxrsConfig.getJaxrsLocationHost(), request.getServerName()))
.port(request.getServerPort());
} else {
uriBuilder.scheme(uriInfo.getAbsolutePath().getScheme())
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 29ccf26..4b93ff5 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
@@ -438,7 +438,10 @@ public class TestInvoice extends TestJaxrsBase {
final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
// Get the invoices
- assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
+ final Invoices originalInvoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+ assertEquals(originalInvoices.size(), 2);
+
+ final UUID firstInvoiceItemId = originalInvoices.get(0).getItems().get(0).getInvoiceItemId();
// Post an external charge
final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -448,6 +451,7 @@ public class TestInvoice extends TestJaxrsBase {
externalCharge.setCurrency(accountJson.getCurrency());
externalCharge.setDescription(UUID.randomUUID().toString());
externalCharge.setItemDetails("Item Details");
+ externalCharge.setLinkedInvoiceItemId(firstInvoiceItemId);
final LocalDate startDate = clock.getUTCToday();
externalCharge.setStartDate(startDate);
@@ -464,6 +468,7 @@ public class TestInvoice extends TestJaxrsBase {
assertEquals(invoiceWithItems.getItems().get(0).getStartDate().compareTo(startDate), 0);
assertEquals(invoiceWithItems.getItems().get(0).getEndDate().compareTo(endDate), 0);
assertEquals(invoiceWithItems.getItems().get(0).getItemDetails(), "Item Details");
+ assertEquals(invoiceWithItems.getItems().get(0).getLinkedInvoiceItemId(), firstInvoiceItemId);
// Verify the total number of invoices
assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);