killbill-memoizeit
Changes
api/pom.xml 4(+4 -0)
beatrix/pom.xml 6(+3 -3)
invoice/pom.xml 4(+4 -0)
invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceProviderPluginRegistryProvider.java 37(+37 -0)
invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultInvoiceProviderPluginRegistry.java 71(+71 -0)
invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultNoOpInvoiceProviderPlugin.java 44(+44 -0)
invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginModule.java 36(+36 -0)
invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginProvider.java 62(+62 -0)
invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceItemFormatter.java 4(+2 -2)
osgi/pom.xml 5(+5 -0)
osgi-bundles/bundles/jruby/pom.xml 4(+4 -0)
osgi-bundles/bundles/logger/pom.xml 2(+1 -1)
pom.xml 18(+16 -2)
util/pom.xml 4(+4 -0)
Details
api/pom.xml 4(+4 -0)
diff --git a/api/pom.xml b/api/pom.xml
index 3652418..f4ad0f6 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -46,6 +46,10 @@
</dependency>
<dependency>
<groupId>org.kill-bill.billing.plugin</groupId>
+ <artifactId>killbill-plugin-api-invoice</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.kill-bill.billing.plugin</groupId>
<artifactId>killbill-plugin-api-payment</artifactId>
</dependency>
<dependency>
diff --git a/api/src/main/java/org/killbill/billing/invoice/plugin/api/NoOpInvoicePluginApi.java b/api/src/main/java/org/killbill/billing/invoice/plugin/api/NoOpInvoicePluginApi.java
new file mode 100644
index 0000000..57d02f0
--- /dev/null
+++ b/api/src/main/java/org/killbill/billing/invoice/plugin/api/NoOpInvoicePluginApi.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.plugin.api;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: consulthys
+ * Date: 21.05.14
+ * Time: 17:51
+ * To change this template use File | Settings | File Templates.
+ */
+public interface NoOpInvoicePluginApi extends InvoicePluginApi {
+}
beatrix/pom.xml 6(+3 -3)
diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 842c677..0a12caf 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -246,9 +246,9 @@
</goals>
<configuration>
<tasks>
- <copy file="${basedir}/../osgi-bundles/tests/beatrix/target/killbill-osgi-bundles-test-beatrix-${project.version}-jar-with-dependencies.jar" tofile="${basedir}/src/test/resources/killbill-osgi-bundles-test-beatrix-jar-with-dependencies.jar" />
- <copy file="${basedir}/../osgi-bundles/tests/payment/target/killbill-osgi-bundles-test-payment-${project.version}-jar-with-dependencies.jar" tofile="${basedir}/src/test/resources/killbill-osgi-bundles-test-payment-jar-with-dependencies.jar" />
- <copy file="${basedir}/../osgi-bundles/bundles/jruby/target/killbill-osgi-bundles-jruby-${project.version}.jar" tofile="${basedir}/src/test/resources/killbill-osgi-bundles-jruby.jar" />
+ <copy file="${basedir}/../osgi-bundles/tests/beatrix/target/killbill-osgi-bundles-test-beatrix-${project.version}-jar-with-dependencies.jar" tofile="${basedir}/src/test/resources/killbill-osgi-bundles-test-beatrix-jar-with-dependencies.jar"></copy>
+ <copy file="${basedir}/../osgi-bundles/tests/payment/target/killbill-osgi-bundles-test-payment-${project.version}-jar-with-dependencies.jar" tofile="${basedir}/src/test/resources/killbill-osgi-bundles-test-payment-jar-with-dependencies.jar"></copy>
+ <copy file="${basedir}/../osgi-bundles/bundles/jruby/target/killbill-osgi-bundles-jruby-${project.version}.jar" tofile="${basedir}/src/test/resources/killbill-osgi-bundles-jruby.jar"></copy>
</tasks>
</configuration>
</execution>
invoice/pom.xml 4(+4 -0)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index 27f3025..610c62c 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -108,6 +108,10 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.kill-bill.billing.plugin</groupId>
+ <artifactId>killbill-plugin-api-invoice</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.kill-bill.commons</groupId>
<artifactId>killbill-clock</artifactId>
</dependency>
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java b/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java
index 472b796..e815d1f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java
@@ -58,7 +58,8 @@ public abstract class InvoiceCalculatorUtils {
// Regular line item (charges)
public static boolean isCharge(final InvoiceItem invoiceItem) {
- return InvoiceItemType.EXTERNAL_CHARGE.equals(invoiceItem.getInvoiceItemType()) ||
+ return InvoiceItemType.TAX.equals(invoiceItem.getInvoiceItemType()) ||
+ InvoiceItemType.EXTERNAL_CHARGE.equals(invoiceItem.getInvoiceItemType()) ||
InvoiceItemType.FIXED.equals(invoiceItem.getInvoiceItemType()) ||
InvoiceItemType.USAGE.equals(invoiceItem.getInvoiceItemType()) ||
InvoiceItemType.RECURRING.equals(invoiceItem.getInvoiceItemType());
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 3a035b2..1822e52 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
@@ -16,6 +16,8 @@
package org.killbill.billing.invoice.glue;
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.skife.config.ConfigSource;
import org.skife.config.ConfigurationObjectFactory;
@@ -48,6 +50,7 @@ import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.util.template.translation.TranslatorConfig;
import com.google.inject.AbstractModule;
+import com.google.inject.TypeLiteral;
public class DefaultInvoiceModule extends AbstractModule implements InvoiceModule {
@@ -120,10 +123,15 @@ public class DefaultInvoiceModule extends AbstractModule implements InvoiceModul
bind(InvoiceGenerator.class).to(DefaultInvoiceGenerator.class).asEagerSingleton();
}
+ protected void installInvoicePluginApi() {
+ bind(new TypeLiteral<OSGIServiceRegistration<InvoicePluginApi>>() {}).toProvider(DefaultInvoiceProviderPluginRegistryProvider.class).asEagerSingleton();
+ }
+
@Override
protected void configure() {
installConfig();
+ installInvoicePluginApi();
installInvoiceService();
installInvoiceNotifier();
installNotifiers();
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceProviderPluginRegistryProvider.java b/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceProviderPluginRegistryProvider.java
new file mode 100644
index 0000000..3337d41
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/glue/DefaultInvoiceProviderPluginRegistryProvider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.glue;
+
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
+import org.killbill.billing.invoice.provider.DefaultInvoiceProviderPluginRegistry;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class DefaultInvoiceProviderPluginRegistryProvider implements Provider<OSGIServiceRegistration<InvoicePluginApi>> {
+
+ @Inject
+ public DefaultInvoiceProviderPluginRegistryProvider() {
+ }
+
+ @Override
+ public OSGIServiceRegistration<InvoicePluginApi> get() {
+ final DefaultInvoiceProviderPluginRegistry pluginRegistry = new DefaultInvoiceProviderPluginRegistry();
+
+ return pluginRegistry;
+ }}
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 3b74980..8061b47 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -32,8 +32,12 @@ import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.BillingMode;
import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
import org.killbill.billing.invoice.usage.UsageUtils;
import org.killbill.billing.junction.BillingEvent;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.util.callcontext.CallContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -104,9 +108,11 @@ public class InvoiceDispatcher {
private final GlobalLocker locker;
private final PersistentBus eventBus;
private final Clock clock;
+ private final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry;
@Inject
- public InvoiceDispatcher(final InvoiceGenerator generator, final AccountInternalApi accountApi,
+ public InvoiceDispatcher(final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry,
+ final InvoiceGenerator generator, final AccountInternalApi accountApi,
final BillingInternalApi billingApi,
final SubscriptionBaseInternalApi SubscriptionApi,
final InvoiceDao invoiceDao,
@@ -115,6 +121,7 @@ public class InvoiceDispatcher {
final GlobalLocker locker,
final PersistentBus eventBus,
final Clock clock) {
+ this.pluginRegistry = pluginRegistry;
this.generator = generator;
this.billingApi = billingApi;
this.subscriptionApi = SubscriptionApi;
@@ -206,6 +213,15 @@ public class InvoiceDispatcher {
}
} else {
if (!dryRun) {
+ // Ask external invoice plugins if additional items (tax, etc) shall be added to the invoice
+ List<InvoicePluginApi> invoicePlugins = this.getInvoicePlugins();
+ CallContext callContext = buildCallContext(context);
+ for (InvoicePluginApi invoicePlugin : invoicePlugins) {
+ List<InvoiceItem> items = invoicePlugin.getAdditionalInvoiceItems(invoice, ImmutableList.<PluginProperty>of(), callContext);
+ if (items != null) {
+ invoice.addInvoiceItems(items);
+ }
+ }
// Extract the set of invoiceId for which we see items that don't belong to current generated invoice
final Set<UUID> adjustedUniqueOtherInvoiceId = new TreeSet<UUID>();
@@ -288,6 +304,17 @@ public class InvoiceDispatcher {
return context.toTenantContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT));
}
+ private CallContext buildCallContext(final InternalCallContext context) {
+ return context.toCallContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT));
+ }
+
+ private List<InvoicePluginApi> getInvoicePlugins() {
+ List<InvoicePluginApi> invoicePlugins = new ArrayList<InvoicePluginApi>();
+ for (String name : this.pluginRegistry.getAllServices()) {
+ invoicePlugins.add(this.pluginRegistry.getServiceForName(name));
+ }
+ return invoicePlugins;
+ }
@VisibleForTesting
Map<UUID, List<DateTime>> createNextFutureNotificationDate(final List<InvoiceItemModelDao> invoiceItems, final Map<String, Usage> knownUsages, final DateAndTimeZoneContext dateAndTimeZoneContext) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
index 32adcfd..7eeda4b 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
@@ -85,6 +85,9 @@ public class InvoiceItemFactory {
case USAGE:
item = new UsageInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, description, amount, currency);
break;
+ case TAX:
+ item = new TaxInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, description, startDate, amount, currency);
+ break;
default:
throw new RuntimeException("Unexpected type of event item " + type);
}
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
new file mode 100644
index 0000000..24fb389
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.invoice.api.InvoiceItemType;
+
+public class TaxInvoiceItem extends InvoiceItemBase {
+
+ public TaxInvoiceItem(final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId, @Nullable final String description,
+ final LocalDate date, final BigDecimal amount, final Currency currency) {
+ this(UUID.randomUUID(), invoiceId, accountId, bundleId, description, date, amount, currency);
+ }
+
+ public TaxInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
+ @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
+ this(id, null, invoiceId, accountId, bundleId, description, date, amount, currency);
+ }
+
+ public TaxInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
+ @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
+ super(id, createdDate, invoiceId, accountId, bundleId, null, description, null, null, null, date, null, amount, currency);
+ }
+
+ @Override
+ public String getDescription() {
+ if (description != null) {
+ return description;
+ }
+
+ return "Tax";
+ }
+
+ @Override
+ public InvoiceItemType getInvoiceItemType() {
+ return InvoiceItemType.TAX;
+ }
+}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultInvoiceProviderPluginRegistry.java b/invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultInvoiceProviderPluginRegistry.java
new file mode 100644
index 0000000..404b9fc
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultInvoiceProviderPluginRegistry.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.provider;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
+import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+public class DefaultInvoiceProviderPluginRegistry implements OSGIServiceRegistration<InvoicePluginApi> {
+
+ private final static Logger log = LoggerFactory.getLogger(DefaultInvoiceProviderPluginRegistry.class);
+
+ private final Map<String, InvoicePluginApi> pluginsByName = new ConcurrentHashMap<String, InvoicePluginApi>();
+
+ @Inject
+ public DefaultInvoiceProviderPluginRegistry() {
+ }
+
+
+ @Override
+ public void registerService(final OSGIServiceDescriptor desc, final InvoicePluginApi service) {
+ log.info("DefaultInvoiceProviderPluginRegistry registering service " + desc.getRegistrationName());
+ pluginsByName.put(desc.getRegistrationName(), service);
+ }
+
+ @Override
+ public void unregisterService(final String serviceName) {
+ log.info("DefaultInvoiceProviderPluginRegistry unregistering service " + serviceName);
+ pluginsByName.remove(serviceName);
+ }
+
+ @Override
+ public InvoicePluginApi getServiceForName(final String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Null invoice plugin API name");
+ }
+ final InvoicePluginApi plugin = pluginsByName.get(name);
+ return plugin;
+ }
+
+ @Override
+ public Set<String> getAllServices() {
+ return pluginsByName.keySet();
+ }
+
+ @Override
+ public Class<InvoicePluginApi> getServiceType() {
+ return InvoicePluginApi.class;
+ }}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultNoOpInvoiceProviderPlugin.java b/invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultNoOpInvoiceProviderPlugin.java
new file mode 100644
index 0000000..826782c
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/provider/DefaultNoOpInvoiceProviderPlugin.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.provider;
+
+import java.util.List;
+
+import org.killbill.billing.invoice.api.Invoice;
+import org.killbill.billing.invoice.api.InvoiceItem;
+import org.killbill.billing.invoice.plugin.api.NoOpInvoicePluginApi;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.clock.Clock;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+
+public class DefaultNoOpInvoiceProviderPlugin implements NoOpInvoicePluginApi {
+
+ private final Clock clock;
+
+ @Inject
+ public DefaultNoOpInvoiceProviderPlugin(final Clock clock) {
+ this.clock = clock;
+ }
+
+ @Override
+ public List<InvoiceItem> getAdditionalInvoiceItems(final Invoice invoice, Iterable<PluginProperty> properties, CallContext context) {
+ return ImmutableList.<InvoiceItem>of();
+ }
+}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginModule.java b/invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginModule.java
new file mode 100644
index 0000000..e4ced96
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginModule.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.provider;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.name.Names;
+
+public class NoOpInvoiceProviderPluginModule extends AbstractModule {
+ private final String instanceName;
+
+ public NoOpInvoiceProviderPluginModule(final String instanceName) {
+ this.instanceName = instanceName;
+ }
+
+ @Override
+ protected void configure() {
+ bind(DefaultNoOpInvoiceProviderPlugin.class)
+ .annotatedWith(Names.named(instanceName))
+ .toProvider(new NoOpInvoiceProviderPluginProvider(instanceName))
+ .asEagerSingleton();
+ }
+}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginProvider.java b/invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginProvider.java
new file mode 100644
index 0000000..0b863f4
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/provider/NoOpInvoiceProviderPluginProvider.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.invoice.provider;
+
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
+import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.clock.Clock;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class NoOpInvoiceProviderPluginProvider implements Provider<DefaultNoOpInvoiceProviderPlugin> {
+
+ private final String instanceName;
+
+ private Clock clock;
+ private OSGIServiceRegistration<InvoicePluginApi> registry;
+
+ public NoOpInvoiceProviderPluginProvider(final String instanceName) {
+ this.instanceName = instanceName;
+
+ }
+
+ @Inject
+ public void setPaymentProviderPluginRegistry(final OSGIServiceRegistration<InvoicePluginApi> registry, final Clock clock) {
+ this.clock = clock;
+ this.registry = registry;
+ }
+
+ @Override
+ public DefaultNoOpInvoiceProviderPlugin get() {
+
+ final DefaultNoOpInvoiceProviderPlugin plugin = new DefaultNoOpInvoiceProviderPlugin(clock);
+ final OSGIServiceDescriptor desc = new OSGIServiceDescriptor() {
+ @Override
+ public String getPluginSymbolicName() {
+ return null;
+ }
+ @Override
+ public String getRegistrationName() {
+ return instanceName;
+ }
+ };
+ registry.registerService(desc, plugin);
+ return plugin;
+ }
+}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/tree/AccountItemTree.java b/invoice/src/main/java/org/killbill/billing/invoice/tree/AccountItemTree.java
index be44a10..e005d56 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/tree/AccountItemTree.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/tree/AccountItemTree.java
@@ -94,6 +94,7 @@ public class AccountItemTree {
Preconditions.checkState(!isBuilt);
switch (existingItem.getInvoiceItemType()) {
case EXTERNAL_CHARGE:
+ case TAX:
case CBA_ADJ:
case CREDIT_ADJ:
case REFUND_ADJ:
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
index 43155d7..291738b 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
@@ -34,7 +34,9 @@ import org.killbill.billing.invoice.dao.InvoiceDao;
import org.killbill.billing.invoice.generator.InvoiceGenerator;
import org.killbill.billing.invoice.glue.TestInvoiceModuleWithEmbeddedDb;
import org.killbill.billing.invoice.notification.NextBillingDateNotifier;
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
import org.killbill.billing.junction.BillingInternalApi;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.util.config.KillbillConfigSource;
import org.killbill.billing.util.api.TagUserApi;
@@ -108,6 +110,8 @@ public abstract class InvoiceTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
protected TestInvoiceHelper invoiceUtil;
@Inject
protected TestInvoiceNotificationQListener testInvoiceNotificationQListener;
+ @Inject
+ protected OSGIServiceRegistration<InvoicePluginApi> pluginRegistry;
@Override
protected KillbillConfigSource getConfigSource() throws IOException, URISyntaxException {
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceItemFormatter.java b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceItemFormatter.java
index 4fda588..fab0bd5 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceItemFormatter.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceItemFormatter.java
@@ -88,7 +88,7 @@ public class TestDefaultInvoiceItemFormatter extends InvoiceTestSuiteNoDB {
startDate, BigDecimal.TEN, Currency.USD);
checkOutput(fixedItem,
"{{#invoiceItem}}<td>{{formattedStartDate}}{{#formattedEndDate}} - {{formattedEndDate}}{{/formattedEndDate}}</td>{{/invoiceItem}}",
- "<td>Dec 1, 2012</td>");
+ "<td>1 déc. 2012</td>");
}
@Test(groups = "fast")
@@ -100,7 +100,7 @@ public class TestDefaultInvoiceItemFormatter extends InvoiceTestSuiteNoDB {
startDate, endDate, BigDecimal.TEN, BigDecimal.TEN, Currency.USD);
checkOutput(recurringItem,
"{{#invoiceItem}}<td>{{formattedStartDate}}{{#formattedEndDate}} - {{formattedEndDate}}{{/formattedEndDate}}</td>{{/invoiceItem}}",
- "<td>Dec 1, 2012 - Dec 31, 2012</td>");
+ "<td>1 déc. 2012 - 31 déc. 2012</td>");
}
private void checkOutput(final InvoiceItem invoiceItem, final String template, final String expected) {
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
index 3a43455..fb34cba 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
@@ -88,7 +88,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
final DateTime target = new DateTime();
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
- final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao,
+ final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi, invoiceDao,
nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
@@ -141,7 +141,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
- final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao,
+ final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi, invoiceDao,
nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
@@ -199,7 +199,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
null, "planName", "phaseName", null, startDate, endDate, new BigDecimal("23.9"), new BigDecimal("23.9"), Currency.EUR, null);
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
- final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao,
+ final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi, invoiceDao,
nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
index 22e1331..85e9aec 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
@@ -29,6 +29,8 @@ import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.BillingMode;
import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.mockito.Mockito;
import org.skife.jdbi.v2.IDBI;
import org.testng.Assert;
@@ -137,6 +139,7 @@ public class TestInvoiceHelper {
private final InvoiceGenerator generator;
private final BillingInternalApi billingApi;
private final AccountInternalApi accountApi;
+ private final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry;
private final AccountUserApi accountUserApi;
private final SubscriptionBaseInternalApi subscriptionApi;
private final BusService busService;
@@ -152,10 +155,11 @@ public class TestInvoiceHelper {
private final InvoiceItemSqlDao invoiceItemSqlDao;
@Inject
- public TestInvoiceHelper(final InvoiceGenerator generator, final IDBI dbi,
+ public TestInvoiceHelper(final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry, final InvoiceGenerator generator, final IDBI dbi,
final BillingInternalApi billingApi, final AccountInternalApi accountApi, final AccountUserApi accountUserApi, final SubscriptionBaseInternalApi subscriptionApi, final BusService busService,
final InvoiceDao invoiceDao, final GlobalLocker locker, final Clock clock, final NonEntityDao nonEntityDao, final InternalCallContext internalCallContext,
final InternalCallContextFactory internalCallContextFactory) {
+ this.pluginRegistry = pluginRegistry;
this.generator = generator;
this.billingApi = billingApi;
this.accountApi = accountApi;
@@ -189,7 +193,7 @@ public class TestInvoiceHelper {
Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
- final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi,
+ final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi,
invoiceDao, nonEntityDao, invoiceNotifier, locker, busService.getBus(),
clock);
osgi/pom.xml 5(+5 -0)
diff --git a/osgi/pom.xml b/osgi/pom.xml
index 78a04a9..f1c864a 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -105,6 +105,11 @@
</dependency>
<dependency>
<groupId>org.kill-bill.billing.plugin</groupId>
+ <artifactId>killbill-plugin-api-invoice</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.kill-bill.billing.plugin</groupId>
<artifactId>killbill-plugin-api-notification</artifactId>
<scope>provided</scope>
</dependency>
diff --git a/osgi/src/main/java/org/killbill/billing/osgi/KillbillActivator.java b/osgi/src/main/java/org/killbill/billing/osgi/KillbillActivator.java
index 98385d7..b138de5 100644
--- a/osgi/src/main/java/org/killbill/billing/osgi/KillbillActivator.java
+++ b/osgi/src/main/java/org/killbill/billing/osgi/KillbillActivator.java
@@ -28,6 +28,7 @@ import javax.inject.Named;
import javax.servlet.Servlet;
import javax.sql.DataSource;
+import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
import org.killbill.billing.osgi.api.OSGIConfigProperties;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -76,6 +77,7 @@ public class KillbillActivator implements BundleActivator, ServiceListener {
final OSGIConfigProperties configProperties,
final OSGIServiceRegistration<Servlet> servletRouter,
final OSGIServiceRegistration<PaymentPluginApi> paymentProviderPluginRegistry,
+ final OSGIServiceRegistration<InvoicePluginApi> invoiceProviderPluginRegistry,
final OSGIServiceRegistration<CurrencyPluginApi> currencyProviderPluginRegistry) {
this.osgiKillbill = osgiKillbill;
this.defaultHttpService = defaultHttpService;
@@ -83,7 +85,7 @@ public class KillbillActivator implements BundleActivator, ServiceListener {
this.observable = observable;
this.configProperties = configProperties;
this.registrar = new OSGIKillbillRegistrar();
- this.allRegistrationHandlers = ImmutableList.<OSGIServiceRegistration>of(servletRouter, paymentProviderPluginRegistry, currencyProviderPluginRegistry);
+ this.allRegistrationHandlers = ImmutableList.<OSGIServiceRegistration>of(servletRouter, paymentProviderPluginRegistry, invoiceProviderPluginRegistry, currencyProviderPluginRegistry);
}
@Override
osgi-bundles/bundles/jruby/pom.xml 4(+4 -0)
diff --git a/osgi-bundles/bundles/jruby/pom.xml b/osgi-bundles/bundles/jruby/pom.xml
index 4e18cab..7970f30 100644
--- a/osgi-bundles/bundles/jruby/pom.xml
+++ b/osgi-bundles/bundles/jruby/pom.xml
@@ -68,6 +68,10 @@
<artifactId>killbill-plugin-api-payment</artifactId>
</dependency>
<dependency>
+ <groupId>org.kill-bill.billing.plugin</groupId>
+ <artifactId>killbill-plugin-api-invoice</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.kill-bill.commons</groupId>
<artifactId>killbill-concurrent</artifactId>
</dependency>
osgi-bundles/bundles/logger/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/bundles/logger/pom.xml b/osgi-bundles/bundles/logger/pom.xml
index 8f61570..e4ad0ce 100644
--- a/osgi-bundles/bundles/logger/pom.xml
+++ b/osgi-bundles/bundles/logger/pom.xml
@@ -56,7 +56,7 @@
<configuration>
<instructions>
<Bundle-Activator>org.killbill.billing.osgi.bundles.logger.Activator</Bundle-Activator>
- <Export-Package />
+ <Export-Package></Export-Package>
<Private-Package>org.killbill.billing.osgi.bundles.logger.*</Private-Package>
<!-- Optional resolution because exported by the Felix system bundle -->
<Import-Package>*;resolution:=optional</Import-Package>
pom.xml 18(+16 -2)
diff --git a/pom.xml b/pom.xml
index ec22fad..1cae7a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright 2010-2013 Ning, Inc.
+ ~ Copyright 2014 Groupon, Inc
~
- ~ Ning licenses this file to you under the Apache License, version 2.0
+ ~ Groupon 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:
~
@@ -59,4 +59,18 @@
<properties>
<killbill.version>${project.version}</killbill.version>
</properties>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.kill-bill.billing</groupId>
+ <artifactId>killbill-api</artifactId>
+ <version>0.9.6-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.kill-bill.billing.plugin</groupId>
+ <artifactId>killbill-plugin-api-invoice</artifactId>
+ <version>0.7.4-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
</project>
util/pom.xml 4(+4 -0)
diff --git a/util/pom.xml b/util/pom.xml
index 59e79cc..9d38388 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -130,6 +130,10 @@
</dependency>
<dependency>
<groupId>org.kill-bill.billing.plugin</groupId>
+ <artifactId>killbill-plugin-api-invoice</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.kill-bill.billing.plugin</groupId>
<artifactId>killbill-plugin-api-notification</artifactId>
</dependency>
<dependency>
diff --git a/util/src/main/java/org/killbill/billing/util/config/OSGIConfig.java b/util/src/main/java/org/killbill/billing/util/config/OSGIConfig.java
index f3d2738..494ef83 100644
--- a/util/src/main/java/org/killbill/billing/util/config/OSGIConfig.java
+++ b/util/src/main/java/org/killbill/billing/util/config/OSGIConfig.java
@@ -50,6 +50,7 @@ public interface OSGIConfig extends KillbillConfig {
"org.killbill.billing.beatrix.bus.api," + /* TODO PIERRE Remove it after plugins classes have been regenerated */
"org.killbill.billing.catalog.api," +
"org.killbill.billing.invoice.api," +
+ "org.killbill.billing.invoice.plugin.api," +
"org.killbill.billing.entitlement.api," +
"org.killbill.billing," +
"org.killbill.billing.notification.api," +