mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-22 21:55:39 +00:00
bug5260: add schedule background task for fetching and updating user subscriptions
This commit is contained in:
+12
-8
@@ -9,8 +9,6 @@ import java.util.logging.Logger;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.chargebee.Result;
|
||||
import com.chargebee.models.HostedPage;
|
||||
import com.chargebee.models.HostedPage.Content;
|
||||
@@ -30,7 +28,6 @@ import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.subscription.Subscription;
|
||||
import com.sap.sse.security.shared.subscription.SubscriptionPlan;
|
||||
import com.sap.sse.security.shared.subscription.chargebee.ChargebeeSubscription;
|
||||
import com.sap.sse.security.shared.subscription.chargebee.ChargebeeSubscriptionProvider;
|
||||
import com.sap.sse.security.subscription.chargebee.ChargebeeApiService;
|
||||
|
||||
/**
|
||||
@@ -59,8 +56,8 @@ public class ChargebeeSubscriptionServiceImpl extends BaseSubscriptionServiceImp
|
||||
.billingAddressLastName(usernames.getB()).billingAddressCountry("US").request();
|
||||
response.setHostedPageJSONString(result.hostedPage().toJson());
|
||||
} else {
|
||||
response.setError("User has already subscribed to "
|
||||
+ SubscriptionPlan.getPlan(planId).getName() + " plan");
|
||||
response.setError(
|
||||
"User has already subscribed to " + SubscriptionPlan.getPlan(planId).getName() + " plan");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error in generating Chargebee hosted page data ", e);
|
||||
@@ -118,7 +115,8 @@ public class ChargebeeSubscriptionServiceImpl extends BaseSubscriptionServiceImp
|
||||
if (subscriptions != null) {
|
||||
List<SubscriptionItem> itemList = new ArrayList<SubscriptionItem>();
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (StringUtils.isNotEmpty(subscription.getSubscriptionId())) {
|
||||
if (subscription.hasSubscriptionId() && !subscription.getSubscriptionStatus()
|
||||
.equals(ChargebeeSubscription.SUBSCRIPTION_STATUS_CANCELLED)) {
|
||||
itemList.add(
|
||||
new ChargebeeSubscriptionItem(subscription.getPlanId(), subscription.getTrialStart(),
|
||||
subscription.getTrialEnd(), subscription.getSubscriptionStatus(),
|
||||
@@ -148,8 +146,14 @@ public class ChargebeeSubscriptionServiceImpl extends BaseSubscriptionServiceImp
|
||||
Result resultData = cancel(subscription.getSubscriptionId()).request();
|
||||
if (resultData.subscription().status().name().toLowerCase()
|
||||
.equals(ChargebeeSubscription.SUBSCRIPTION_STATUS_CANCELLED)) {
|
||||
Subscription newSubscription = ChargebeeSubscription.createEmptySubscription(
|
||||
subscription.getPlanId(), subscription.getLatestEventTime(), TimePoint.now());
|
||||
Subscription newSubscription = new ChargebeeSubscription(subscription.getSubscriptionId(),
|
||||
subscription.getPlanId(), subscription.getCustomerId(), subscription.getTrialStart(),
|
||||
subscription.getTrialEnd(), ChargebeeSubscription.SUBSCRIPTION_STATUS_CANCELLED,
|
||||
subscription.getPaymentStatus(), subscription.getTransactionType(),
|
||||
subscription.getTransactionStatus(), subscription.getInvoiceId(),
|
||||
subscription.getInvoiceStatus(), subscription.getSubscriptionCreatedAt(),
|
||||
TimePoint.of(resultData.subscription().updatedAt()), subscription.getLatestEventTime(),
|
||||
TimePoint.now());
|
||||
updateUserSubscription(user, newSubscription);
|
||||
result = true;
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -103,7 +103,6 @@ public class ChargebeeWebHookHandler extends SubscriptionWebHookHandler {
|
||||
case CUSTOMER_DELETED:
|
||||
updateUserSubscription(user, buildEmptySubscription(userSubscription, event));
|
||||
break;
|
||||
case SUBSCRIPTION_CANCELLED:
|
||||
case SUBSCRIPTION_DELETED:
|
||||
if (userSubscription != null && userSubscription.getSubscriptionId() != null
|
||||
&& userSubscription.getSubscriptionId().equals(event.getSubscriptionId())) {
|
||||
@@ -117,6 +116,7 @@ public class ChargebeeWebHookHandler extends SubscriptionWebHookHandler {
|
||||
case PAYMENT_FAILED:
|
||||
case SUBSCRIPTION_PAUSED:
|
||||
case SUBSCRIPTION_RESUMED:
|
||||
case SUBSCRIPTION_CANCELLED:
|
||||
updateUserSubscription(user, buildSubscription(userSubscription, event));
|
||||
break;
|
||||
case PAYMENT_REFUNDED:
|
||||
|
||||
+12
@@ -201,12 +201,24 @@ public abstract class Subscription implements Serializable {
|
||||
return planId != null && !planId.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasSubscriptionId() {
|
||||
return subscriptionId != null && !subscriptionId.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is active, base on this user will gain roles for the subscription
|
||||
*
|
||||
* @return true if status subscription is in trial or status is active and user has success payment
|
||||
*/
|
||||
public abstract boolean isActiveSubscription();
|
||||
|
||||
/**
|
||||
* Check if subscription is updated more recently than other subscription
|
||||
*/
|
||||
public boolean isUpdatedMoreRecently(Subscription otherSubscription) {
|
||||
return getManualUpdatedAt().asMillis() > otherSubscription.getManualUpdatedAt().asMillis()
|
||||
|| getLatestEventTime().asMillis() > otherSubscription.getLatestEventTime().asMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
+16
-1
@@ -1,5 +1,6 @@
|
||||
package com.sap.sse.security.shared.subscription;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -25,7 +26,21 @@ public class SubscriptionData {
|
||||
MANUAL_UPDATED_AT,
|
||||
PROVIDER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create empty subscription data instance that only holds plan id, latest webhook event update time, and manuall
|
||||
* updated time. This subscription is used for keeping updated time of subscription for a user, then it would
|
||||
* prevent issue of outdated data be persisted
|
||||
*/
|
||||
public static SubscriptionData createEmptySubscriptionDataWithUpdateTimes(String planId, TimePoint latestEventTime,
|
||||
TimePoint manualUpdatedTime) {
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
data.put(DataAttribute.PLAN_ID.name(), planId);
|
||||
data.put(DataAttribute.LATEST_EVENT_TIME.name(), latestEventTime.asMillis());
|
||||
data.put(DataAttribute.MANUAL_UPDATED_AT.name(), manualUpdatedTime.asMillis());
|
||||
return new SubscriptionData(data);
|
||||
}
|
||||
|
||||
private Map<String, Object> data;
|
||||
|
||||
public SubscriptionData(Map<String, Object> data) {
|
||||
|
||||
+1
-1
@@ -15,5 +15,5 @@ public interface SubscriptionDataHandler {
|
||||
/**
|
||||
* Restore subscription from data
|
||||
*/
|
||||
Subscription restore(SubscriptionData data);
|
||||
Subscription toSubscription(SubscriptionData data);
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import com.sap.sse.security.shared.subscription.SubscriptionData;
|
||||
public class ChargebeeSubscriptionDataHandler extends AbstractSubscriptionDataHandler {
|
||||
|
||||
@Override
|
||||
public Subscription restore(SubscriptionData data) {
|
||||
public Subscription toSubscription(SubscriptionData data) {
|
||||
return new ChargebeeSubscription(data.getSubscriptionId(), data.getPlanId(), data.getCustomerId(),
|
||||
data.getTrialStart(), data.getTrialEnd(), data.getSubscriptionStatus(), data.getPaymentStatus(),
|
||||
data.getTransactionType(), data.getTransactionStatus(), data.getInvoiceId(), data.getInvoiceStatus(),
|
||||
|
||||
+1
-1
@@ -526,7 +526,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
try {
|
||||
final SubscriptionProvider subscriptionProvider = SubscriptionFactory.getInstance()
|
||||
.getSubscriptionProvider(subscriptionData.getProvider());
|
||||
subscriptions[i++] = subscriptionProvider.getDataHandler().restore(subscriptionData);
|
||||
subscriptions[i++] = subscriptionProvider.getDataHandler().toSubscription(subscriptionData);
|
||||
} catch (InvalidSubscriptionProviderException e) {
|
||||
logger.log(Level.SEVERE, "Failed to load subscription for user " + subscriptionData.getCustomerId(),
|
||||
e);
|
||||
|
||||
@@ -661,5 +661,10 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
* Persist user subscription data
|
||||
*/
|
||||
void updateUserSubscription(String username, Subscription subscription) throws UserManagementException;
|
||||
|
||||
/**
|
||||
* Remove all user subscriptions of a payment service provider
|
||||
*/
|
||||
void removeProviderUserSubscriptions(String username, String providerName) throws UserManagementException;
|
||||
|
||||
}
|
||||
|
||||
@@ -112,5 +112,7 @@ public interface ReplicableSecurityService extends SecurityService {
|
||||
Void internalResetPassword(String username, String passwordResetSecret);
|
||||
|
||||
Void internalUpdateSubscription(String username, Subscription newSubscription) throws UserManagementException;
|
||||
|
||||
Void internalRemoveProviderSubscriptions(String username, String provider) throws UserManagementException;
|
||||
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ import com.sap.sse.security.operations.DeleteUserOperation;
|
||||
import com.sap.sse.security.operations.PutRoleDefinitionToUserGroupOperation;
|
||||
import com.sap.sse.security.operations.RemoveAccessTokenOperation;
|
||||
import com.sap.sse.security.operations.RemovePermissionForUserOperation;
|
||||
import com.sap.sse.security.operations.RemoveProviderSubscriptionsOperation;
|
||||
import com.sap.sse.security.operations.RemoveRoleDefinitionFromUserGroupOperation;
|
||||
import com.sap.sse.security.operations.RemoveRoleFromUserOperation;
|
||||
import com.sap.sse.security.operations.RemoveUserFromUserGroupOperation;
|
||||
@@ -2509,18 +2510,52 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
if (user != null) {
|
||||
String newSubscriptionPlanId = newSubscription.getPlanId();
|
||||
Subscription currentSubscription = user.getSubscriptionByPlan(newSubscriptionPlanId);
|
||||
logger.info(() -> "Update user subscription for plan " + newSubscriptionPlanId);
|
||||
logger.info(() -> "Current user plan subscription: "
|
||||
+ (currentSubscription != null ? currentSubscription.toString() : "null"));
|
||||
logger.info(
|
||||
() -> "New plan subscription: " + (newSubscription != null ? newSubscription.toString() : "null"));
|
||||
if (shouldUpdateUserRolesForSubscription(user, currentSubscription, newSubscription)) {
|
||||
updateUserRolesOnSubscriptionChange(user, currentSubscription, newSubscription);
|
||||
if (shouldProcessNewSubscription(currentSubscription, newSubscription)) {
|
||||
logger.info(() -> "Update user subscription for plan " + newSubscriptionPlanId);
|
||||
logger.info(() -> "Current user plan subscription: "
|
||||
+ (currentSubscription != null ? currentSubscription.toString() : "null"));
|
||||
logger.info(() -> "New plan subscription: "
|
||||
+ (newSubscription != null ? newSubscription.toString() : "null"));
|
||||
if (shouldUpdateUserRolesForSubscription(user, currentSubscription, newSubscription)) {
|
||||
updateUserRolesOnSubscriptionChange(user, currentSubscription, newSubscription);
|
||||
}
|
||||
Subscription[] newSubscriptions = buildNewUserSubscriptions(user, newSubscription);
|
||||
if (newSubscriptions != null) {
|
||||
user.setSubscriptions(newSubscriptions);
|
||||
}
|
||||
store.updateUser(user);
|
||||
} else {
|
||||
logger.info(() -> "New subscription has been ignored: " + newSubscription);
|
||||
}
|
||||
Subscription[] newSubscriptions = buildNewUserSubscriptions(user, newSubscription);
|
||||
if (newSubscriptions != null) {
|
||||
user.setSubscriptions(newSubscriptions);
|
||||
return null;
|
||||
} else {
|
||||
throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProviderUserSubscriptions(String username, String providerName) throws UserManagementException {
|
||||
final User user = getUserByName(username);
|
||||
if (user != null) {
|
||||
apply(new RemoveProviderSubscriptionsOperation(username, providerName));
|
||||
} else {
|
||||
throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalRemoveProviderSubscriptions(String username, String providerName)
|
||||
throws UserManagementException {
|
||||
User user = getUserByName(username);
|
||||
if (user != null) {
|
||||
Iterable<Subscription> subscriptions = user.getSubscriptions();
|
||||
List<Subscription> newSubscriptionList = new ArrayList<Subscription>();
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (!subscription.getProvider().equals(providerName)) {
|
||||
newSubscriptionList.add(subscription);
|
||||
}
|
||||
}
|
||||
user.setSubscriptions(newSubscriptionList.toArray(new Subscription[] {}));
|
||||
store.updateUser(user);
|
||||
return null;
|
||||
} else {
|
||||
@@ -2528,6 +2563,36 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if new subscription should be processed, such as if it has a valid plan, or it's the most recent
|
||||
* subscription of a plan
|
||||
*/
|
||||
private boolean shouldProcessNewSubscription(Subscription currentSubscription, Subscription newSubscription) {
|
||||
final boolean shouldProcess;
|
||||
if (!newSubscription.hasPlan()) {
|
||||
// New subscription doesn't have plan id, that means it's an empty subscription model which is used for
|
||||
// clearing all user subscriptions
|
||||
shouldProcess = true;
|
||||
} else if (SubscriptionPlan.getPlan(newSubscription.getPlanId()) != null) {
|
||||
if (currentSubscription == null) {
|
||||
// New subscription plan is valid, but current subscription of the plan is empty
|
||||
shouldProcess = true;
|
||||
} else if (!newSubscription.hasSubscriptionId()) {
|
||||
// New subscription has plan id but doesn't have subscription id, this is an empty subscription for the
|
||||
// plan that holds updated dates data for the plan's subscription
|
||||
shouldProcess = newSubscription.isUpdatedMoreRecently(currentSubscription);
|
||||
} else {
|
||||
// Only process new subscription if it is the most recently created subscription
|
||||
shouldProcess = newSubscription.getSubscriptionCreatedAt().asMillis() >= currentSubscription
|
||||
.getSubscriptionCreatedAt().asMillis();
|
||||
}
|
||||
} else {
|
||||
// New subscription doesn't have a valid plan
|
||||
shouldProcess = false;
|
||||
}
|
||||
return shouldProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build new subscription list for user from new subscription. This might update a subscription model, or add new
|
||||
* one to user's subscription list. In case no updates for current user subscriptions then null will be returned
|
||||
@@ -2536,13 +2601,27 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
Subscription[] newUserSubscriptions = null;
|
||||
Iterable<Subscription> subscriptions = user.getSubscriptions();
|
||||
if (newSubscription != null) {
|
||||
if (subscriptions == null || !subscriptions.iterator().hasNext() || !newSubscription.hasPlan()) {
|
||||
if (subscriptions == null || !subscriptions.iterator().hasNext()) {
|
||||
newUserSubscriptions = new Subscription[] { newSubscription };
|
||||
} else if (!newSubscription.hasPlan()) {
|
||||
// New subscription has no plan, that means new subscription is just an empty one with some meta data
|
||||
// for updated dates, and user has been deleted from provider. In this case we need to remove all
|
||||
// current subscriptions of the user for this provider
|
||||
List<Subscription> newSubscriptionList = new ArrayList<Subscription>();
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (!subscription.getProvider().equals(newSubscription.getProvider())) {
|
||||
newSubscriptionList.add(subscription);
|
||||
}
|
||||
}
|
||||
newSubscriptionList.add(newSubscription);
|
||||
newUserSubscriptions = newSubscriptionList.toArray(new Subscription[] {});
|
||||
} else {
|
||||
List<Subscription> newSubscriptionList = new ArrayList<Subscription>();
|
||||
boolean foundCurrentSubscription = false;
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (!subscription.hasPlan() || subscription.getPlanId().equals(newSubscription.getPlanId())) {
|
||||
if (!foundCurrentSubscription && ((!subscription.hasPlan()
|
||||
&& subscription.getProvider().equals(newSubscription.getProvider()))
|
||||
|| subscription.getPlanId().equals(newSubscription.getPlanId()))) {
|
||||
newSubscriptionList.add(newSubscription);
|
||||
foundCurrentSubscription = true;
|
||||
} else {
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.sap.sse.security.operations;
|
||||
|
||||
import com.sap.sse.security.impl.ReplicableSecurityService;
|
||||
|
||||
/**
|
||||
* Remove user subscriptions of a provider operation
|
||||
*/
|
||||
public class RemoveProviderSubscriptionsOperation implements SecurityOperation<Void> {
|
||||
private static final long serialVersionUID = -3121534374405832205L;
|
||||
|
||||
private String username;
|
||||
private String providerName;
|
||||
|
||||
public RemoveProviderSubscriptionsOperation(String username, String providerName) {
|
||||
this.username = username;
|
||||
this.providerName = providerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(ReplicableSecurityService toState) throws Exception {
|
||||
toState.internalRemoveProviderSubscriptions(username, providerName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+51
-3
@@ -1,13 +1,18 @@
|
||||
package com.sap.sse.security.subscription;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.subscription.Subscription;
|
||||
import com.sap.sse.security.shared.subscription.SubscriptionData;
|
||||
import com.sap.sse.security.shared.subscription.SubscriptionFactory;
|
||||
import com.sap.sse.security.shared.subscription.SubscriptionProvider;
|
||||
|
||||
@@ -34,13 +39,14 @@ public class SubscriptionUpdateTask implements Runnable {
|
||||
}
|
||||
|
||||
private void fetchAndUserSubscriptions(User user, Iterable<SubscriptionProvider> subscriptionProviders) {
|
||||
logger.info(() -> "Start checking and updating subscriptions for user: " + user.getName());
|
||||
for (SubscriptionProvider provider : subscriptionProviders) {
|
||||
SubscriptionApiService apiService = SubscriptionServiceFactory.getInstance()
|
||||
.getApiService(provider.getProviderName());
|
||||
if (apiService != null) {
|
||||
try {
|
||||
Iterable<Subscription> userSubscriptions = apiService.getUserSubscriptions(user);
|
||||
checkAndUpdateSubscriptions(user, userSubscriptions);
|
||||
checkAndUpdateSubscriptions(user, userSubscriptions, provider);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Failed to fetch and update subscriptions for user " + user.getName(), e);
|
||||
}
|
||||
@@ -48,8 +54,50 @@ public class SubscriptionUpdateTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndUpdateSubscriptions(User user, Iterable<Subscription> userSubscriptions) {
|
||||
// TODO: implement checking and updating subscriptions
|
||||
private void checkAndUpdateSubscriptions(User user, Iterable<Subscription> userSubscriptions,
|
||||
SubscriptionProvider provider) throws UserManagementException {
|
||||
logger.info(() -> "Subscriptions from provider " + provider.getProviderName() + " for user " + user.getName()
|
||||
+ ": " + userSubscriptions);
|
||||
Iterable<Subscription> currentSubscriptions = user.getSubscriptions();
|
||||
if ((userSubscriptions == null || !userSubscriptions.iterator().hasNext())
|
||||
&& (currentSubscriptions != null && currentSubscriptions.iterator().hasNext())) {
|
||||
// No subscriptions so we need to remove all current subscriptions of user for the provider
|
||||
Subscription emptySubscription = createEmptySubscription(provider, null);
|
||||
getSecurityService().updateUserSubscription(user.getName(), emptySubscription);
|
||||
// getSecurityService().removeProviderUserSubscriptions(user.getName(), providerName);
|
||||
} else if (userSubscriptions != null) {
|
||||
if (currentSubscriptions != null) {
|
||||
Map<String, Boolean> existingPlans = getExistingPlans(userSubscriptions);
|
||||
for (Subscription subscription : currentSubscriptions) {
|
||||
if (subscription.hasPlan() && !existingPlans.containsKey(subscription.getPlanId())) {
|
||||
// Current subscription plan doesn't exist in subscription list from provider, that means
|
||||
// subscription for the plan has been deleted, then we need to remove the subscription from
|
||||
// database
|
||||
Subscription emptySubscription = createEmptySubscription(provider, subscription.getPlanId());
|
||||
getSecurityService().updateUserSubscription(user.getName(), emptySubscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Subscription subscription : userSubscriptions) {
|
||||
getSecurityService().updateUserSubscription(user.getName(), subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Subscription createEmptySubscription(SubscriptionProvider provider, String planId) {
|
||||
return provider.getDataHandler().toSubscription(
|
||||
SubscriptionData.createEmptySubscriptionDataWithUpdateTimes(planId, TimePoint.now(), TimePoint.now()));
|
||||
}
|
||||
|
||||
private Map<String, Boolean> getExistingPlans(Iterable<Subscription> subscriptions) {
|
||||
final Map<String, Boolean> existingPlans = new HashMap<String, Boolean>();
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (subscription.hasPlan()) {
|
||||
existingPlans.put(subscription.getPlanId(), true);
|
||||
}
|
||||
}
|
||||
return existingPlans;
|
||||
}
|
||||
|
||||
private SecurityService getSecurityService() {
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ public class ChargebeeApiService implements SubscriptionApiService {
|
||||
*/
|
||||
private Pair<Iterable<SubscriptionItem>, String> fetchSubscriptions(User user, String offset) throws Exception {
|
||||
SubscriptionListRequest request = com.chargebee.models.Subscription.list().limit(100).customerId()
|
||||
.is(user.getName()).includeDeleted(false);
|
||||
.is(user.getName()).includeDeleted(false).sortByCreatedAt(SortOrder.DESC);
|
||||
if (offset != null && !offset.isEmpty()) {
|
||||
request.offset(offset);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user