Details
diff --git a/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java b/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java
index ed67f74..aadea54 100644
--- a/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java
@@ -113,4 +113,13 @@ public class DefaultAccountInternalApi implements AccountInternalApi {
final InternalCallContext context) throws AccountApiException {
accountDao.updatePaymentMethod(accountId, paymentMethodId, context);
}
+
+ @Override
+ public UUID getByRecordId(final Long recordId, final InternalCallContext context) throws AccountApiException {
+ final AccountModelDao accountModelDao = accountDao.getByRecordId(recordId, context);
+ if (accountModelDao == null) {
+ throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_RECORD_ID, recordId);
+ }
+ return accountModelDao.getId();
+ }
}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index 8ab5f98..62d6cdf 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -47,4 +47,6 @@ public interface AccountDao extends EntityDao<AccountModelDao, Account, AccountA
public void removeEmail(AccountEmailModelDao email, InternalCallContext context);
public List<AccountEmailModelDao> getEmailsByAccountId(UUID accountId, InternalTenantContext context);
+
+ public AccountModelDao getByRecordId(Long recordId, InternalCallContext context);
}
diff --git a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
index a5d6fd4..18e2ac3 100644
--- a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
@@ -215,4 +215,14 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
}
});
}
+
+ @Override
+ public AccountModelDao getByRecordId(final Long recordId, final InternalCallContext context) {
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<AccountModelDao>() {
+ @Override
+ public AccountModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(AccountSqlDao.class).getByRecordId(recordId, context);
+ }
+ });
+ }
}
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
index e4ad71a..553f618 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
@@ -140,4 +140,9 @@ public class MockAccountDao extends MockEntityDaoBase<AccountModelDao, Account,
}
}));
}
+
+ @Override
+ public AccountModelDao getByRecordId(final Long recordId, final InternalCallContext context) {
+ return null;
+ }
}
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 17e40bf..a734a78 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -155,6 +155,7 @@ public enum ErrorCode {
ACCOUNT_CANNOT_CHANGE_EXTERNAL_KEY(3005, "External keys cannot be updated. Original key remains: %s"),
ACCOUNT_CREATION_FAILED(3006, "Account creation failed."),
ACCOUNT_UPDATE_FAILED(3007, "Account update failed."),
+ ACCOUNT_DOES_NOT_EXIST_FOR_RECORD_ID(3008, "Account does not exist for recordId %s"),
ACCOUNT_EMAIL_ALREADY_EXISTS(3500, "Account email already exists %s"),
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithOverdueEnforcementOffTag.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithOverdueEnforcementOffTag.java
new file mode 100644
index 0000000..095cef7
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueWithOverdueEnforcementOffTag.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.overdue;
+
+import java.math.BigDecimal;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.api.TestApiListener.NextEvent;
+import com.ning.billing.beatrix.integration.BeatrixIntegrationModule;
+import com.ning.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
+import com.ning.billing.invoice.api.InvoiceItemType;
+import com.ning.billing.util.svcapi.junction.DefaultBlockingState;
+import com.ning.billing.util.tag.ControlTagType;
+
+import static junit.framework.Assert.assertTrue;
+
+@Test(groups = "slow")
+@Guice(modules = {BeatrixIntegrationModule.class})
+public class TestOverdueWithOverdueEnforcementOffTag extends TestOverdueBase {
+
+
+ @Override
+ public String getOverdueConfig() {
+ final String configXml = "<overdueConfig>" +
+ " <bundleOverdueStates>" +
+ " <state name=\"OD1\">" +
+ " <condition>" +
+ " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " <unit>DAYS</unit><number>5</number>" +
+ " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " </condition>" +
+ " <externalMessage>Reached OD1</externalMessage>" +
+ " <blockChanges>true</blockChanges>" +
+ " <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+ " <autoReevaluationInterval>" +
+ " <unit>DAYS</unit><number>5</number>" +
+ " </autoReevaluationInterval>" +
+ " </state>" +
+ " </bundleOverdueStates>" +
+ "</overdueConfig>";
+ return configXml;
+ }
+
+ @Test(groups = "slow")
+ public void testNonOverdueAccountWithOverdueEnforcementOffTag() throws Exception {
+
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+ // Set the OVERDUE_ENFORCEMENT_OFF tag
+ tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId(), callContext);
+
+ // Set next invoice to fail and create subscription
+ paymentPlugin.makeAllInvoicesFailWithError(true);
+ final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
+
+ // DAY 30 have to get out of trial before first payment
+ addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
+
+ // DAY 36 -- RIGHT AFTER OD1
+ addDaysAndCheckForCompletion(6);
+
+ // Should still be in clear state
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // Now remove OVERDUE_ENFORCEMENT_OFF tag
+ tagUserApi.removeTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId(), callContext);
+
+ checkODState("OD1");
+ }
+
+
+
+ @Test(groups = "slow")
+ public void testOverdueAccountWithOverdueEnforcementOffTag() throws Exception {
+
+ clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
+
+ // Set next invoice to fail and create subscription
+ paymentPlugin.makeAllInvoicesFailWithError(true);
+ final Subscription baseSubscription = createSubscriptionAndCheckForCompletion(bundle.getId(), productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
+
+ invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 5, 1), callContext);
+
+ // DAY 30 have to get out of trial before first payment
+ addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
+
+ invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
+ invoiceChecker.checkChargedThroughDate(baseSubscription.getId(), new LocalDate(2012, 6, 30), callContext);
+
+ // DAY 36 -- RIGHT AFTER OD1
+ addDaysAndCheckForCompletion(6);
+
+ // Account should be in overdue
+ checkODState("OD1");
+
+ // Set the OVERDUE_ENFORCEMENT_OFF tag
+ tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId(), callContext);
+
+ // Should now be in clear state
+ checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
+
+ // Now remove OVERDUE_ENFORCEMENT_OFF tag
+ tagUserApi.removeTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId(), callContext);
+
+ // Account should be back in overdue
+ checkODState("OD1");
+ }
+}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java b/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java
index bf0734a..0463a50 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java
@@ -17,7 +17,7 @@
package com.ning.billing.invoice.api;
import com.ning.billing.invoice.InvoiceListener;
-import com.ning.billing.invoice.TagHandler;
+import com.ning.billing.invoice.InvoiceTagHandler;
import com.ning.billing.invoice.notification.NextBillingDateNotifier;
import com.ning.billing.lifecycle.LifecycleHandlerType;
import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
@@ -32,11 +32,11 @@ public class DefaultInvoiceService implements InvoiceService {
public static final String INVOICE_SERVICE_NAME = "invoice-service";
private final NextBillingDateNotifier dateNotifier;
private final InvoiceListener invoiceListener;
- private final TagHandler tagHandler;
+ private final InvoiceTagHandler tagHandler;
private final InternalBus eventBus;
@Inject
- public DefaultInvoiceService(final InvoiceListener invoiceListener, final TagHandler tagHandler, final InternalBus eventBus, final NextBillingDateNotifier dateNotifier) {
+ public DefaultInvoiceService(final InvoiceListener invoiceListener, final InvoiceTagHandler tagHandler, final InternalBus eventBus, final NextBillingDateNotifier dateNotifier) {
this.invoiceListener = invoiceListener;
this.tagHandler = tagHandler;
this.eventBus = eventBus;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java b/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java
index 6651d23..ad1ccc3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java
@@ -20,7 +20,7 @@ import org.skife.config.ConfigurationObjectFactory;
import com.ning.billing.glue.InvoiceModule;
import com.ning.billing.invoice.InvoiceListener;
-import com.ning.billing.invoice.TagHandler;
+import com.ning.billing.invoice.InvoiceTagHandler;
import com.ning.billing.invoice.api.DefaultInvoiceService;
import com.ning.billing.invoice.api.InvoiceMigrationApi;
import com.ning.billing.invoice.api.InvoiceNotifier;
@@ -106,7 +106,7 @@ public class DefaultInvoiceModule extends AbstractModule implements InvoiceModul
}
protected void installTagHandler() {
- bind(TagHandler.class).asEagerSingleton();
+ bind(InvoiceTagHandler.class).asEagerSingleton();
}
protected void installInvoiceGenerator() {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
index a6621cd..bc2110a 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -22,14 +22,15 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
import org.joda.time.Period;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ning.billing.ErrorCode;
+import com.ning.billing.ObjectType;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.catalog.api.ActionPolicy;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
@@ -56,7 +57,10 @@ import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
import com.ning.billing.util.svcapi.junction.BlockingInternalApi;
import com.ning.billing.util.svcapi.junction.DefaultBlockingState;
+import com.ning.billing.util.svcapi.tag.TagInternalApi;
import com.ning.billing.util.svcsapi.bus.InternalBus;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
@@ -73,29 +77,37 @@ public class OverdueStateApplicator<T extends Blockable> {
private final AccountInternalApi accountApi;
private final EntitlementInternalApi entitlementUserApi;
private final OverdueEmailGenerator overdueEmailGenerator;
+ final TagInternalApi tagApi;
private final EmailSender emailSender;
@Inject
public OverdueStateApplicator(final BlockingInternalApi accessApi, final AccountInternalApi accountApi, final EntitlementInternalApi entitlementUserApi,
final Clock clock, final OverdueCheckPoster poster, final OverdueEmailGenerator overdueEmailGenerator,
- final EmailConfig config, final InternalBus bus) {
+ final EmailConfig config, final InternalBus bus, final TagInternalApi tagApi) {
this.blockingApi = accessApi;
this.accountApi = accountApi;
this.entitlementUserApi = entitlementUserApi;
this.clock = clock;
this.poster = poster;
this.overdueEmailGenerator = overdueEmailGenerator;
+ this.tagApi = tagApi;
this.emailSender = new DefaultEmailSender(config);
this.bus = bus;
}
+
public void apply(final OverdueState<T> firstOverdueState, final BillingState<T> billingState,
final T overdueable, final String previousOverdueStateName,
final OverdueState<T> nextOverdueState, final InternalCallContext context) throws OverdueException {
try {
- log.debug("OverdueStateApplicator <enter> : time = " + clock.getUTCNow() + ", previousState = " + previousOverdueStateName + ", nextState = " + nextOverdueState);
+ if (isAccountTaggedWith_OVERDUE_ENFORCEMENT_OFF(context)) {
+ log.debug("OverdueStateApplicator:apply returns because account (recordId = " + context.getAccountRecordId() + ") is set with OVERDUE_ENFORCEMENT_OFF ");
+ return;
+ }
+
+ log.debug("OverdueStateApplicator:apply <enter> : time = " + clock.getUTCNow() + ", previousState = " + previousOverdueStateName + ", nextState = " + nextOverdueState);
final boolean conditionForNextNotfication = !nextOverdueState.isClearState() ||
// We did not reach the first state yet but we have an unpaid invoice
@@ -125,7 +137,7 @@ public class OverdueStateApplicator<T extends Blockable> {
}
if (nextOverdueState.isClearState()) {
- clear(overdueable, context);
+ clearFutureNotification(overdueable, context);
}
try {
@@ -135,6 +147,21 @@ public class OverdueStateApplicator<T extends Blockable> {
}
}
+ public void clear(final T overdueable, final String previousOverdueStateName, final OverdueState<T> clearState, final InternalCallContext context) throws OverdueException {
+
+ log.debug("OverdueStateApplicator:clear : time = " + clock.getUTCNow() + ", previousState = " + previousOverdueStateName);
+
+ storeNewState(overdueable, clearState, context);
+
+ clearFutureNotification(overdueable, context);
+
+ try {
+ bus.post(createOverdueEvent(overdueable, previousOverdueStateName, clearState.getName(), context), context);
+ } catch (Exception e) {
+ log.error("Error posting overdue change event to bus", e);
+ }
+ }
+
private OverdueChangeInternalEvent createOverdueEvent(final T overdueable, final String previousOverdueStateName, final String nextOverdueStateName, final InternalCallContext context) throws BlockingApiException {
return new DefaultOverdueChangeEvent(overdueable.getId(), Blockable.Type.get(overdueable), previousOverdueStateName, nextOverdueStateName, context.getUserToken(), context.getAccountRecordId(), context.getTenantRecordId());
}
@@ -148,7 +175,7 @@ public class OverdueStateApplicator<T extends Blockable> {
blockChanges(nextOverdueState),
blockEntitlement(nextOverdueState),
blockBilling(nextOverdueState)),
- context);
+ context);
} catch (Exception e) {
throw new OverdueException(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED, blockable.getId(), blockable.getClass().getName());
}
@@ -170,7 +197,7 @@ public class OverdueStateApplicator<T extends Blockable> {
poster.insertOverdueCheckNotification(overdueable, timeOfNextCheck, context);
}
- protected void clear(final T blockable, final InternalCallContext context) {
+ protected void clearFutureNotification(final T blockable, final InternalCallContext context) {
// Need to clear the override table here too (when we add it)
poster.clearNotificationsFor(blockable, context);
}
@@ -275,4 +302,24 @@ public class OverdueStateApplicator<T extends Blockable> {
log.warn(String.format("Unable to generate overdue notification email for account %s and overdueable %s", account.getId(), overdueable.getId()), e);
}
}
+
+ //
+ // Uses context information to retrieve account matching the Overduable object and check whether we should do any overdue processing
+ //
+ private boolean isAccountTaggedWith_OVERDUE_ENFORCEMENT_OFF(final InternalCallContext context) throws OverdueException {
+
+ try {
+ final UUID accountId = accountApi.getByRecordId(context.getAccountRecordId(), context);
+
+ final List<Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT, context);
+ for (Tag cur : accountTags) {
+ if (cur.getTagDefinitionId().equals(ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId())) {
+ return true;
+ }
+ }
+ return false;
+ } catch (AccountApiException e) {
+ throw new OverdueException(e);
+ }
+ }
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
index 3340a49..5d5bdb0 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
@@ -54,6 +54,13 @@ public class OverdueDispatcher {
}
}
+ public void clearOverdueForAccount(final UUID accountId, final InternalCallContext context) {
+ final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(accountId, context);
+ for (final SubscriptionBundle bundle : bundles) {
+ clearOverdue(Type.SUBSCRIPTION_BUNDLE, bundle.getId(), context);
+ }
+ }
+
public void processOverdue(final Blockable.Type type, final UUID blockableId, final InternalCallContext context) {
try {
factory.createOverdueWrapperFor(type, blockableId, context).refresh(context);
@@ -61,4 +68,12 @@ public class OverdueDispatcher {
log.error(String.format("Error processing Overdue for blockable %s (type %s)", blockableId, type), e);
}
}
+
+ public void clearOverdue(final Blockable.Type type, final UUID blockableId, final InternalCallContext context) {
+ try {
+ factory.createOverdueWrapperFor(type, blockableId, context).clear(context);
+ } catch (BillingExceptionBase e) {
+ log.error(String.format("Error processing Overdue for blockable %s (type %s)", blockableId, type), e);
+ }
+ }
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
index 1733da5..52ed173 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
@@ -21,14 +21,18 @@ import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.ning.billing.ObjectType;
import com.ning.billing.ovedue.notification.OverdueCheckNotificationKey;
import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.events.ControlTagCreationInternalEvent;
+import com.ning.billing.util.events.ControlTagDeletionInternalEvent;
import com.ning.billing.util.events.InvoiceAdjustmentInternalEvent;
import com.ning.billing.util.events.PaymentErrorInternalEvent;
import com.ning.billing.util.events.PaymentInfoInternalEvent;
+import com.ning.billing.util.tag.ControlTagType;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
@@ -48,6 +52,23 @@ public class OverdueListener {
}
@Subscribe
+ public void handle_OVERDUE_ENFORCEMENT_OFF_Insert(final ControlTagCreationInternalEvent event) {
+ if (event.getTagDefinition().getName().equals(ControlTagType.OVERDUE_ENFORCEMENT_OFF.toString()) && event.getObjectType() == ObjectType.ACCOUNT) {
+ final UUID accountId = event.getObjectId();
+ dispatcher.clearOverdueForAccount(accountId, createCallContext(event.getUserToken(), event.getAccountRecordId(), event.getTenantRecordId()));
+ }
+ }
+
+ @Subscribe
+ public void handle_OVERDUE_ENFORCEMENT_OFF_Removal(final ControlTagDeletionInternalEvent event) {
+ if (event.getTagDefinition().getName().equals(ControlTagType.OVERDUE_ENFORCEMENT_OFF.toString()) && event.getObjectType() == ObjectType.ACCOUNT) {
+ final UUID accountId = event.getObjectId();
+ dispatcher.processOverdueForAccount(accountId, createCallContext(event.getUserToken(), event.getAccountRecordId(), event.getTenantRecordId()));
+ }
+ }
+
+
+ @Subscribe
public void handlePaymentInfoEvent(final PaymentInfoInternalEvent event) {
log.debug("Received PaymentInfo event {}", event);
dispatcher.processOverdueForAccount(event.getAccountId(), createCallContext(event.getUserToken(), event.getAccountRecordId(), event.getTenantRecordId()));
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index d663978..f40db15 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -64,6 +64,11 @@ public class OverdueWrapper<T extends Blockable> {
return nextOverdueState;
}
+ public void clear(final InternalCallContext context) throws OverdueException, OverdueApiException {
+ final String previousOverdueStateName = api.getBlockingStateFor(overdueable, context).getStateName();
+ overdueStateApplicator.clear(overdueable, previousOverdueStateName, overdueStateSet.getClearState(), context);
+ }
+
public BillingState<T> billingState(final InternalTenantContext context) throws OverdueException {
return billingStateCalcuator.calculateBillingState(overdueable, context);
}
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
index ff3a672..4e283e1 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
@@ -65,6 +65,7 @@ import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.globallocker.MySqlGlobalLocker;
import com.ning.billing.util.glue.BusModule;
import com.ning.billing.util.glue.NotificationQueueModule;
+import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.notificationq.NotificationQueueService;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
@@ -114,7 +115,8 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
@BeforeClass(groups = "slow")
public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException, EntitlementUserApiException, AccountApiException {
- final Injector g = Guice.createInjector(Stage.PRODUCTION, new MockInvoiceModule(), new MockPaymentModule(), new BusModule(), new DefaultOverdueModule() {
+ final Injector g = Guice.createInjector(Stage.PRODUCTION, new MockInvoiceModule(), new MockPaymentModule(), new BusModule(), new TagStoreModule(),
+ new DefaultOverdueModule() {
@Override
protected void configure() {
super.configure();
diff --git a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
index 78ff704..e6a3a8e 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
@@ -60,6 +60,7 @@ import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.NotificationQueueModule;
+import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
@@ -71,7 +72,7 @@ import com.google.inject.Inject;
@Guice(modules = {DefaultOverdueModule.class, OverdueListenerTesterModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class,
CallContextModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, NotificationQueueModule.class,
- EmailModule.class, TemplateModule.class, TestDbiModule.class, MockEntitlementModule.class, MockInvoiceModule.class, MockAccountModule.class})
+ EmailModule.class, TemplateModule.class, TestDbiModule.class, TagStoreModule.class, MockEntitlementModule.class, MockInvoiceModule.class, MockAccountModule.class})
public abstract class OverdueTestBase extends OverdueTestSuiteWithEmbeddedDB {
protected final String configXml =
"<overdueConfig>" +
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index d3a06d3..ed3946f 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -310,7 +310,7 @@ public class PaymentProcessor extends ProcessorBase {
}
public void retryFailedPayment(final UUID paymentId, final InternalCallContext context) {
- log.info("STEPH retrying failed payment " + paymentId + " time = " + clock.getUTCNow());
+ log.info("Retrying failed payment " + paymentId + " time = " + clock.getUTCNow());
retryFailedPaymentInternal(paymentId, context, PaymentStatus.PAYMENT_FAILURE);
}
@@ -450,7 +450,6 @@ public class PaymentProcessor extends ProcessorBase {
break;
case ERROR:
- log.info("STEPH payment failure...");
allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
// Schedule if non instant payment and max attempt for retry not reached yet
if (!isInstantPayment) {
@@ -510,7 +509,7 @@ public class PaymentProcessor extends ProcessorBase {
final boolean isScheduledForRetry = failedPaymentRetryService.scheduleRetry(paymentId, retryAttempt);
- log.info("STEPH scheduleRetryOnPaymentFailure id = " + paymentId + ", retryAttempt = " + retryAttempt + ", retry :" + isScheduledForRetry);
+ log.debug("scheduleRetryOnPaymentFailure id = " + paymentId + ", retryAttempt = " + retryAttempt + ", retry :" + isScheduledForRetry);
return isScheduledForRetry ? PaymentStatus.PAYMENT_FAILURE : PaymentStatus.PAYMENT_FAILURE_ABORTED;
}
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java b/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
index 81f0ef5..3c24f10 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
@@ -25,7 +25,7 @@ import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.payment.api.PaymentService;
import com.ning.billing.payment.bus.InvoiceHandler;
-import com.ning.billing.payment.bus.TagHandler;
+import com.ning.billing.payment.bus.PaymentTagHandler;
import com.ning.billing.payment.retry.AutoPayRetryService;
import com.ning.billing.payment.retry.FailedPaymentRetryService;
import com.ning.billing.payment.retry.PluginFailureRetryService;
@@ -40,7 +40,7 @@ public class DefaultPaymentService implements PaymentService {
public static final String SERVICE_NAME = "payment-service";
private final InvoiceHandler invoiceHandler;
- private final TagHandler tagHandler;
+ private final PaymentTagHandler tagHandler;
private final InternalBus eventBus;
private final PaymentApi api;
private final FailedPaymentRetryService failedRetryService;
@@ -49,7 +49,7 @@ public class DefaultPaymentService implements PaymentService {
@Inject
public DefaultPaymentService(final InvoiceHandler invoiceHandler,
- final TagHandler tagHandler,
+ final PaymentTagHandler tagHandler,
final PaymentApi api, final InternalBus eventBus,
final FailedPaymentRetryService failedRetryService,
final PluginFailureRetryService timedoutRetryService,
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
index 906a0b6..f85e86e 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
@@ -25,6 +25,7 @@ import org.skife.config.ConfigSource;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.config.SimplePropertyConfigSource;
+import com.ning.billing.payment.bus.PaymentTagHandler;
import com.ning.billing.payment.dao.DefaultPaymentDao;
import com.ning.billing.util.config.PaymentConfig;
import com.ning.billing.payment.api.DefaultPaymentApi;
@@ -32,7 +33,6 @@ import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.payment.api.PaymentService;
import com.ning.billing.payment.api.svcs.DefaultPaymentInternalApi;
import com.ning.billing.payment.bus.InvoiceHandler;
-import com.ning.billing.payment.bus.TagHandler;
import com.ning.billing.payment.core.PaymentMethodProcessor;
import com.ning.billing.payment.core.PaymentProcessor;
import com.ning.billing.payment.core.RefundProcessor;
@@ -114,7 +114,7 @@ public class PaymentModule extends AbstractModule {
bind(PaymentInternalApi.class).to(DefaultPaymentInternalApi.class).asEagerSingleton();
bind(PaymentApi.class).to(DefaultPaymentApi.class).asEagerSingleton();
bind(InvoiceHandler.class).asEagerSingleton();
- bind(TagHandler.class).asEagerSingleton();
+ bind(PaymentTagHandler.class).asEagerSingleton();
bind(PaymentService.class).to(DefaultPaymentService.class).asEagerSingleton();
installPaymentProviderPlugins(paymentConfig);
installPaymentDao();
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/account/AccountInternalApi.java b/util/src/main/java/com/ning/billing/util/svcapi/account/AccountInternalApi.java
index 60b36b1..b86da74 100644
--- a/util/src/main/java/com/ning/billing/util/svcapi/account/AccountInternalApi.java
+++ b/util/src/main/java/com/ning/billing/util/svcapi/account/AccountInternalApi.java
@@ -40,4 +40,6 @@ public interface AccountInternalApi {
public void removePaymentMethod(UUID accountId, InternalCallContext context) throws AccountApiException;
public void updatePaymentMethod(UUID accountId, UUID paymentMethodId, InternalCallContext context) throws AccountApiException;
+
+ public UUID getByRecordId(Long recordId, InternalCallContext context) throws AccountApiException;
}