mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-07 11:32:16 +00:00
Payment: Refactor and update to support multiple subscriptions for a user at a time
This commit is contained in:
1 parent
bad67dd2fe
commit
436c90eba8
27 files changed
+641
-462
No files matched your search
+148
@@ -0,0 +1,148 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.subscriptiontab;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.cell.client.AbstractCell;
|
||||
import com.google.gwt.cell.client.ValueUpdater;
|
||||
import com.google.gwt.core.client.Duration;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.ButtonElement;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.uibinder.client.UiRenderer;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.subscription.UserSubscriptionView;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.subscription.chargebee.SubscriptionItem;
|
||||
import com.sap.sse.security.shared.SubscriptionPlan;
|
||||
import com.sap.sse.security.shared.SubscriptionPlanHolder;
|
||||
|
||||
public class SubscriptionCell extends AbstractCell<SubscriptionItem> {
|
||||
interface Style extends CssResource {
|
||||
String subscriptionContainer();
|
||||
|
||||
String textRow();
|
||||
|
||||
String trialText();
|
||||
|
||||
String errorText();
|
||||
|
||||
String blueText();
|
||||
|
||||
String hide();
|
||||
|
||||
String cancelButton();
|
||||
}
|
||||
|
||||
interface MyUiRenderer extends UiRenderer {
|
||||
void render(SafeHtmlBuilder sb, String planName, String subscriptionStatus, String trial, String paymentStatus,
|
||||
String subscriptionStatusCssClass, String paymentStatusCssClass, String trialCssClass);
|
||||
|
||||
void onBrowserEvent(SubscriptionCell cell, NativeEvent event, Element parent, SubscriptionItem value);
|
||||
|
||||
Style getStyle();
|
||||
|
||||
ButtonElement getCancelButton(Element parent);
|
||||
}
|
||||
|
||||
private static MyUiRenderer renderer = GWT.create(MyUiRenderer.class);
|
||||
|
||||
private UserSubscriptionView.Presenter presenter;
|
||||
|
||||
public SubscriptionCell(UserSubscriptionView.Presenter presenter) {
|
||||
super("click");
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Context context, SubscriptionItem subscription, SafeHtmlBuilder sb) {
|
||||
SubscriptionPlan plan = getSubscriptionPlan(subscription);
|
||||
if (plan != null) {
|
||||
String planName = plan.getName();
|
||||
String subscriptionStatus = subscription.getSubscriptionStatusLabel();
|
||||
String subscriptionStatusCssClass = "";
|
||||
String paymentStatus = "";
|
||||
String paymentStatusCssClass = "";
|
||||
String trial = "";
|
||||
String trialCssClass = "";
|
||||
if (subscription.isActive()) {
|
||||
subscriptionStatusCssClass = renderer.getStyle().blueText();
|
||||
paymentStatus = subscription.getPaymentStatusLabel();
|
||||
paymentStatusCssClass = subscription.isPaymentSuccess() ? renderer.getStyle().blueText()
|
||||
: renderer.getStyle().errorText();
|
||||
} else {
|
||||
paymentStatusCssClass = renderer.getStyle().hide();
|
||||
if (subscription.isInTrial()) {
|
||||
trial = buildTrialText(subscription);
|
||||
} else {
|
||||
trialCssClass = renderer.getStyle().hide();
|
||||
}
|
||||
}
|
||||
renderer.render(sb, planName, subscriptionStatus, trial, paymentStatus, subscriptionStatusCssClass,
|
||||
paymentStatusCssClass, trialCssClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrowserEvent(Context context, Element parent, SubscriptionItem value, NativeEvent event,
|
||||
ValueUpdater<SubscriptionItem> valueUpdater) {
|
||||
renderer.onBrowserEvent(this, event, parent, value);
|
||||
}
|
||||
|
||||
@UiHandler({ "cancelButton" })
|
||||
void onCancelButtonPressed(ClickEvent event, Element parent, SubscriptionItem subscription) {
|
||||
renderer.getCancelButton(parent).setDisabled(true);
|
||||
presenter.cancelSubscription(subscription.getPlanId());
|
||||
}
|
||||
|
||||
private SubscriptionPlan getSubscriptionPlan(SubscriptionItem subscription) {
|
||||
return subscription != null ? SubscriptionPlanHolder.getInstance().getPlan(subscription.getPlanId()) : null;
|
||||
}
|
||||
|
||||
private String buildTrialText(SubscriptionItem subscription) {
|
||||
return StringMessages.INSTANCE.trialText(getTrialRemainingText(subscription),
|
||||
DateTimeFormat.getFormat("yyyy-MM-dd HH:mm").format(new Date(subscription.getTrialEnd() * 1000)));
|
||||
}
|
||||
|
||||
private String getTrialRemainingText(SubscriptionItem subscription) {
|
||||
long now = Math.round(Duration.currentTimeMillis() / 1000);
|
||||
long remain = subscription.getTrialEnd() - now;
|
||||
StringBuilder remainText = new StringBuilder();
|
||||
if (remain <= 0) {
|
||||
remainText.append(StringMessages.INSTANCE.numHours(0));
|
||||
} else {
|
||||
int days = (int) (remain / 86400);
|
||||
if (days > 0) {
|
||||
remainText.append(StringMessages.INSTANCE.numDays(days));
|
||||
}
|
||||
remain = remain % 86400;
|
||||
int hours = (int) (remain / 3600);
|
||||
if (hours > 0) {
|
||||
if (remainText.length() > 0) {
|
||||
remainText.append(" ");
|
||||
}
|
||||
remainText.append(StringMessages.INSTANCE.numHours(hours));
|
||||
}
|
||||
if (days == 0) {
|
||||
remain = remain % 3600;
|
||||
int mins = (int) (remain / 60);
|
||||
if (mins > 0) {
|
||||
if (remainText.length() > 0) {
|
||||
remainText.append(" ");
|
||||
}
|
||||
remainText.append(StringMessages.INSTANCE.numMinutes(mins));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remainText.length() == 0) {
|
||||
remainText.append(StringMessages.INSTANCE.numHours(0));
|
||||
}
|
||||
|
||||
return remainText.toString();
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:um="urn:import:com.sap.sailing.gwt.home.shared.usermanagement.decorator"
|
||||
xmlns:c="urn:import:com.google.gwt.user.cellview.client">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="planName" type="java.lang.String" />
|
||||
<ui:with field="subscriptionStatus" type="java.lang.String" />
|
||||
<ui:with field="trial" type="java.lang.String" />
|
||||
<ui:with field="paymentStatus" type="java.lang.String" />
|
||||
<ui:with field="subscriptionStatusCssClass" type="java.lang.String" />
|
||||
<ui:with field="paymentStatusCssClass" type="java.lang.String" />
|
||||
<ui:with field="trialCssClass" type="java.lang.String" />
|
||||
<ui:style field="style" type="com.sap.sailing.gwt.home.desktop.places.user.profile.subscriptiontab.SubscriptionCell.Style">
|
||||
.subscriptionContainer {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.textRow {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.trialText {
|
||||
color: #ff0000;
|
||||
}
|
||||
.errorText{
|
||||
color: #ff0000;
|
||||
}
|
||||
.blueText {
|
||||
color: #0000ff;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
.cancelButton {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</ui:style>
|
||||
<div class="{style.subscriptionContainer}">
|
||||
<div>Subscription plan: <span><ui:text from="{planName}" /></span></div>
|
||||
<div class="{style.textRow} {subscriptionStatusCssClass}">
|
||||
Subscription status: <span><ui:text from="{subscriptionStatus}" /></span>
|
||||
</div>
|
||||
<div ui:field="trialDivUi" class="{style.textRow} {style.trialText} {trialCssClass}"><ui:text from="{trial}" /></div>
|
||||
<div ui:field="paymentStatusDivUi" class="{style.textRow} {paymentStatusCssClass}">
|
||||
Payment charge status: <span><ui:text from="{paymentStatus}" /></span>
|
||||
</div>
|
||||
<button ui:field="cancelButton" class="{res.mainCss.button} {res.mainCss.buttonprimary} {style.cancelButton}">
|
||||
<ui:text from="{i18n.cancelSubscription}" />
|
||||
</button>
|
||||
</div>
|
||||
</ui:UiBinder>
|
||||
+4
-10
@@ -15,17 +15,11 @@ public interface SubscriptionProfileDesktopResources extends ClientBundle {
|
||||
SubscriptionProfileCss css();
|
||||
|
||||
public interface SubscriptionProfileCss extends CssResource {
|
||||
String emptySubscriptionsLabel();
|
||||
|
||||
String bottomButton();
|
||||
|
||||
String trialText();
|
||||
|
||||
String textRow();
|
||||
|
||||
String errorText();
|
||||
|
||||
String blueText();
|
||||
|
||||
String plansLabel();
|
||||
|
||||
String sectionLabel();
|
||||
|
||||
String plansInput();
|
||||
|
||||
|
||||
+7
-14
@@ -1,27 +1,20 @@
|
||||
.emptySubscriptionsLabel {
|
||||
color: #777;
|
||||
}
|
||||
.bottomButton {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.textRow {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.trialText {
|
||||
color: #ff0000;
|
||||
}
|
||||
.errorText{
|
||||
color: #ff0000;
|
||||
}
|
||||
.blueText {
|
||||
color: #0000ff;
|
||||
}
|
||||
.planInputContainer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.plansLabel {
|
||||
.sectionLabel {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.4em;
|
||||
margin-bottom: 0.8em;
|
||||
margin-top: 1.5em;
|
||||
padding: 0;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.plansInput {
|
||||
display: block;
|
||||
|
||||
+26
-132
@@ -1,25 +1,26 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.subscriptiontab;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.gwt.core.client.Duration;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.SpanElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.cellview.client.CellList;
|
||||
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.subscription.UserSubscriptionView;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.subscription.chargebee.SubscriptionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.subscription.chargebee.SubscriptionItem;
|
||||
import com.sap.sse.gwt.client.Notification;
|
||||
import com.sap.sse.gwt.client.Notification.NotificationType;
|
||||
import com.sap.sse.security.shared.SubscriptionPlan;
|
||||
@@ -39,45 +40,28 @@ public class UserSubscription extends Composite implements UserSubscriptionView
|
||||
@UiField
|
||||
DivElement rootUi;
|
||||
@UiField
|
||||
Button updateSubscriptionButtonUi;
|
||||
@UiField
|
||||
Button cancelSubscriptionButtonUi;
|
||||
@UiField
|
||||
SpanElement planNameSpanUi;
|
||||
@UiField
|
||||
DivElement trialDivUi;
|
||||
@UiField
|
||||
DivElement subscriptionGroupUi;
|
||||
@UiField
|
||||
SpanElement subscriptionStatusSpanUi;
|
||||
@UiField
|
||||
SpanElement paymentStatusSpanUi;
|
||||
@UiField
|
||||
DivElement paymentStatusDivUi;
|
||||
Button subscribeButtonUi;
|
||||
@UiField
|
||||
ListBox planListUi;
|
||||
@UiField(provided = true)
|
||||
CellList<SubscriptionItem> subscriptionListUi;
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
public UserSubscription(UserSubscriptionView.Presenter presenter) {
|
||||
initSubscriptionCellList(presenter);
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
presenter.setView(this);
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@UiHandler("updateSubscriptionButtonUi")
|
||||
@UiHandler("subscribeButtonUi")
|
||||
public void handleUpdateSubscriptionClick(ClickEvent e) {
|
||||
updateSubscriptionButtonUi.setEnabled(false);
|
||||
subscribeButtonUi.setEnabled(false);
|
||||
presenter.openCheckout(planListUi.getSelectedValue());
|
||||
}
|
||||
|
||||
@UiHandler("cancelSubscriptionButtonUi")
|
||||
public void handleCancelSubscriptionClick(ClickEvent e) {
|
||||
cancelSubscriptionButtonUi.setEnabled(false);
|
||||
presenter.cancelSubscription();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
@@ -91,136 +75,46 @@ public class UserSubscription extends Composite implements UserSubscriptionView
|
||||
|
||||
@Override
|
||||
public void onOpenCheckoutError(String error) {
|
||||
updateSubscriptionButtonUi.setEnabled(true);
|
||||
subscribeButtonUi.setEnabled(true);
|
||||
Notification.notify(error, NotificationType.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCloseCheckoutModal() {
|
||||
updateSubscriptionButtonUi.setEnabled(true);
|
||||
subscribeButtonUi.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateView(SubscriptionDTO subscription) {
|
||||
resetElementsVisibleState();
|
||||
|
||||
updatePlanList(subscription);
|
||||
|
||||
updateSubscriptionButtonUi.setEnabled(true);
|
||||
|
||||
SubscriptionPlan plan = getSubscriptionPlan(subscription);
|
||||
if (subscription == null || plan == null) {
|
||||
updateViewWithFreePlan();
|
||||
subscribeButtonUi.setEnabled(true);
|
||||
if (subscription == null) {
|
||||
subscriptionListUi.setRowData(new ArrayList<SubscriptionItem>());
|
||||
} else {
|
||||
updateViewWithPlan(subscription, plan);
|
||||
subscriptionListUi.setRowData(Arrays.asList(subscription.getSubscriptionItems()));
|
||||
}
|
||||
|
||||
subscriptionListUi.redraw();
|
||||
show();
|
||||
}
|
||||
|
||||
private SubscriptionPlan getSubscriptionPlan(SubscriptionDTO subscription) {
|
||||
return subscription != null ? SubscriptionPlanHolder.getInstance().getPlan(subscription.getPlanId()) : null;
|
||||
}
|
||||
|
||||
private void updateViewWithFreePlan() {
|
||||
planNameSpanUi.setInnerText(StringMessages.INSTANCE.freePlan());
|
||||
hideElement(subscriptionGroupUi);
|
||||
cancelSubscriptionButtonUi.setVisible(false);
|
||||
}
|
||||
|
||||
private void updateViewWithPlan(SubscriptionDTO subscription, SubscriptionPlan plan) {
|
||||
planNameSpanUi.setInnerText(plan.getName());
|
||||
subscriptionStatusSpanUi.setInnerText(subscription.getSubscriptionStatusLabel());
|
||||
if (subscription.isActive()) {
|
||||
subscriptionStatusSpanUi.addClassName(SubscriptionProfileDesktopResources.INSTANCE.css().blueText());
|
||||
paymentStatusSpanUi.setInnerText(subscription.getPaymentStatusLabel());
|
||||
paymentStatusSpanUi.addClassName(
|
||||
subscription.isPaymentSuccess() ? SubscriptionProfileDesktopResources.INSTANCE.css().blueText()
|
||||
: SubscriptionProfileDesktopResources.INSTANCE.css().errorText());
|
||||
} else {
|
||||
hideElement(paymentStatusDivUi);
|
||||
|
||||
if (subscription.isInTrial()) {
|
||||
trialDivUi.setInnerText(buildTrialText(subscription));
|
||||
} else {
|
||||
hideElement(trialDivUi);
|
||||
}
|
||||
}
|
||||
private void initSubscriptionCellList(Presenter presenter) {
|
||||
subscriptionListUi = new CellList<SubscriptionItem>(new SubscriptionCell(presenter));
|
||||
Label emptyWidget = new Label(StringMessages.INSTANCE.noSubscriptions());
|
||||
emptyWidget.setStyleName(SubscriptionProfileDesktopResources.INSTANCE.css().emptySubscriptionsLabel());
|
||||
subscriptionListUi.setEmptyListWidget(emptyWidget);
|
||||
subscriptionListUi.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED);
|
||||
}
|
||||
|
||||
private void updatePlanList(SubscriptionDTO subscription) {
|
||||
planListUi.clear();
|
||||
if (subscription == null) {
|
||||
planListUi.addItem("", "");
|
||||
planListUi.setSelectedIndex(0);
|
||||
}
|
||||
SubscriptionPlan[] planList = SubscriptionPlanHolder.getInstance().getPlanList();
|
||||
int i = 0;
|
||||
for (SubscriptionPlan plan : planList) {
|
||||
planListUi.addItem(plan.getName(), plan.getId());
|
||||
if (subscription != null && subscription.getPlanId().equals(plan.getId())) {
|
||||
planListUi.setSelectedIndex(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private String buildTrialText(SubscriptionDTO subscription) {
|
||||
return StringMessages.INSTANCE.trialText(getTrialRemainingText(subscription),
|
||||
DateTimeFormat.getFormat("yyyy-MM-dd HH:mm").format(new Date(subscription.getTrialEnd() * 1000)));
|
||||
}
|
||||
|
||||
private String getTrialRemainingText(SubscriptionDTO subscription) {
|
||||
long now = Math.round(Duration.currentTimeMillis() / 1000);
|
||||
long remain = subscription.getTrialEnd() - now;
|
||||
StringBuilder remainText = new StringBuilder();
|
||||
if (remain <= 0) {
|
||||
remainText.append(StringMessages.INSTANCE.numHours(0));
|
||||
} else {
|
||||
int days = (int) (remain / 86400);
|
||||
if (days > 0) {
|
||||
remainText.append(StringMessages.INSTANCE.numDays(days));
|
||||
}
|
||||
remain = remain % 86400;
|
||||
int hours = (int) (remain / 3600);
|
||||
if (hours > 0) {
|
||||
if (remainText.length() > 0) {
|
||||
remainText.append(" ");
|
||||
}
|
||||
remainText.append(StringMessages.INSTANCE.numHours(hours));
|
||||
}
|
||||
if (days == 0) {
|
||||
remain = remain % 3600;
|
||||
int mins = (int) (remain / 60);
|
||||
if (mins > 0) {
|
||||
if (remainText.length() > 0) {
|
||||
remainText.append(" ");
|
||||
}
|
||||
remainText.append(StringMessages.INSTANCE.numMinutes(mins));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remainText.length() == 0) {
|
||||
remainText.append(StringMessages.INSTANCE.numHours(0));
|
||||
}
|
||||
|
||||
return remainText.toString();
|
||||
}
|
||||
|
||||
private void resetElementsVisibleState() {
|
||||
showElement(subscriptionGroupUi);
|
||||
cancelSubscriptionButtonUi.setVisible(true);
|
||||
showElement(paymentStatusDivUi);
|
||||
showElement(trialDivUi);
|
||||
}
|
||||
|
||||
private void hideElement(Element element) {
|
||||
element.getStyle().setDisplay(Display.NONE);
|
||||
}
|
||||
|
||||
private void showElement(Element element) {
|
||||
element.getStyle().setDisplay(Display.BLOCK);
|
||||
planListUi.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
|
||||
+5
-12
@@ -8,23 +8,16 @@
|
||||
type="com.sap.sailing.gwt.home.desktop.places.user.profile.subscriptiontab.SubscriptionProfileDesktopResources" />
|
||||
<g:HTMLPanel addStyleNames="{res.mediaCss.grid} {res.mainCss.spacermarginbottommediumsmall}">
|
||||
<div ui:field="rootUi" class="{res.mediaCss.column} {res.mediaCss.small12} {res.mainCss.spacermargintopmedium}">
|
||||
<div>Subscription plan: <span ui:field="planNameSpanUi"></span></div>
|
||||
<div ui:field="subscriptionGroupUi">
|
||||
<div class="{local_res.css.textRow}">Subscription status: <span ui:field="subscriptionStatusSpanUi"></span></div>
|
||||
<div ui:field="trialDivUi" class="{local_res.css.textRow} {local_res.css.trialText}"></div>
|
||||
<div ui:field="paymentStatusDivUi" class="{local_res.css.textRow}">Payment charge status: <span ui:field="paymentStatusSpanUi"></span></div>
|
||||
</div>
|
||||
<div class="{local_res.css.sectionLabel}">Your subscriptions</div>
|
||||
<c:CellList ui:field="subscriptionListUi"></c:CellList>
|
||||
<div class="{res.mediaCss.medium4} {res.mediaCss.small12} {local_res.css.planInputContainer}">
|
||||
<label class="{local_res.css.plansLabel}">
|
||||
<label class="{local_res.css.sectionLabel}">
|
||||
<ui:text from="{i18n.plans}" />
|
||||
</label>
|
||||
<g:ListBox ui:field="planListUi" addStyleNames="{local_res.css.plansInput}" />
|
||||
</div>
|
||||
<g:Button ui:field="updateSubscriptionButtonUi" addStyleNames="{res.mainCss.button} {res.mainCss.buttonprimary} {local_res.css.bottomButton}">
|
||||
<ui:text from="{i18n.updateSubscription}" />
|
||||
</g:Button>
|
||||
<g:Button ui:field="cancelSubscriptionButtonUi" addStyleNames="{res.mainCss.button} {res.mainCss.buttonprimary} {local_res.css.bottomButton}">
|
||||
<ui:text from="{i18n.cancelSubscription}" />
|
||||
<g:Button ui:field="subscribeButtonUi" addStyleNames="{res.mainCss.button} {res.mainCss.buttonprimary} {local_res.css.bottomButton}">
|
||||
<ui:text from="{i18n.subscribe}" />
|
||||
</g:Button>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
|
||||
+24
-22
@@ -71,24 +71,7 @@ public class UserSubscriptionPresenter<C extends ClientFactoryWithDispatch & Err
|
||||
@Override
|
||||
public void loadSubscription() {
|
||||
view.onStartLoadSubscription();
|
||||
|
||||
clientFactory.getSubscriptionService().getSubscription(new AsyncCallback<SubscriptionDTO>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(SubscriptionDTO result) {
|
||||
if (result != null && result.getError() != null && !result.getError().isEmpty()) {
|
||||
showError(StringMessages.INSTANCE.errorLoadingUserSubscription(result.getError()));
|
||||
return;
|
||||
}
|
||||
|
||||
view.updateView(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
showError(StringMessages.INSTANCE.errorLoadingUserSubscription(caught.getMessage()));
|
||||
}
|
||||
});
|
||||
fetchSubscription();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,8 +108,8 @@ public class UserSubscriptionPresenter<C extends ClientFactoryWithDispatch & Err
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelSubscription() {
|
||||
clientFactory.getSubscriptionService().cancelSubscription(new AsyncCallback<Boolean>() {
|
||||
public void cancelSubscription(String planId) {
|
||||
clientFactory.getSubscriptionService().cancelSubscription(planId, new AsyncCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
@@ -134,8 +117,7 @@ public class UserSubscriptionPresenter<C extends ClientFactoryWithDispatch & Err
|
||||
showError(StringMessages.INSTANCE.failedCancelSubscription());
|
||||
return;
|
||||
}
|
||||
|
||||
view.updateView(null);
|
||||
fetchSubscription();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,6 +127,26 @@ public class UserSubscriptionPresenter<C extends ClientFactoryWithDispatch & Err
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchSubscription() {
|
||||
clientFactory.getSubscriptionService().getSubscription(new AsyncCallback<SubscriptionDTO>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(SubscriptionDTO result) {
|
||||
if (result != null && result.getError() != null && !result.getError().isEmpty()) {
|
||||
showError(StringMessages.INSTANCE.errorLoadingUserSubscription(result.getError()));
|
||||
return;
|
||||
}
|
||||
|
||||
view.updateView(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
showError(StringMessages.INSTANCE.errorLoadingUserSubscription(caught.getMessage()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void requestFinishingPlanUpdating(String hostedPageId) {
|
||||
clientFactory.getSubscriptionService().updatePlanSuccess(hostedPageId, new AsyncCallback<SubscriptionDTO>() {
|
||||
|
||||
|
||||
+4
-1
@@ -62,7 +62,10 @@ public interface UserSubscriptionView extends IsWidget {
|
||||
|
||||
/**
|
||||
* Request to cancel current user's subscription
|
||||
*
|
||||
* @param planId
|
||||
* Id of plan to cancel
|
||||
*/
|
||||
public void cancelSubscription();
|
||||
public void cancelSubscription(String planId);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -2386,7 +2386,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String whitelabelFooterLanguage();
|
||||
String whitelabelSailing();
|
||||
String subscription();
|
||||
String updateSubscription();
|
||||
String noSubscriptions();
|
||||
String subscribe();
|
||||
String cancelSubscription();
|
||||
String openPortal();
|
||||
String plans();
|
||||
|
||||
+2
-1
@@ -2391,7 +2391,8 @@ autoRestartTrackingUponCompetitorSetChange=Restart tracking of races automatical
|
||||
whitelabelFooterLanguage=Sailing in
|
||||
whitelabelSailing=Sailing
|
||||
subscription=Subscription
|
||||
updateSubscription=Update Subscription
|
||||
noSubscriptions=No subscriptions
|
||||
subscribe=Subscribe
|
||||
cancelSubscription=Cancel Subscription
|
||||
openPortal=Open Portal
|
||||
plans=Plans
|
||||
|
||||
+3
-1
@@ -37,6 +37,8 @@ public interface SubscriptionService extends RemoteService {
|
||||
|
||||
/**
|
||||
* Cancel current user subscription
|
||||
*
|
||||
* @param planId id of canceled plan
|
||||
*/
|
||||
public boolean cancelSubscription();
|
||||
public boolean cancelSubscription(String planId);
|
||||
}
|
||||
+1
-1
@@ -16,5 +16,5 @@ public interface SubscriptionServiceAsync {
|
||||
|
||||
public void getSubscription(AsyncCallback<SubscriptionDTO> callback);
|
||||
|
||||
void cancelSubscription(AsyncCallback<Boolean> callback);
|
||||
void cancelSubscription(String planId, AsyncCallback<Boolean> callback);
|
||||
}
|
||||
+42
-56
@@ -1,6 +1,8 @@
|
||||
package com.sap.sailing.gwt.ui.server.subscription.chargebee;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
@@ -22,6 +24,7 @@ import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||
import com.sap.sailing.gwt.ui.client.subscription.chargebee.SubscriptionService;
|
||||
import com.sap.sailing.gwt.ui.shared.subscription.chargebee.HostedPageResultDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.subscription.chargebee.SubscriptionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.subscription.chargebee.SubscriptionItem;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.Subscription;
|
||||
@@ -65,30 +68,17 @@ public class SubscriptionServiceImpl extends RemoteServiceServlet implements Sub
|
||||
|
||||
try {
|
||||
User user = getCurrentUser();
|
||||
|
||||
if (isUserSubscribedToPlan(user.getSubscription(), planId)) {
|
||||
if (isUserSubscribedToPlan(user, planId)) {
|
||||
response.setError("User has already subscribed to "
|
||||
+ SubscriptionPlanHolder.getInstance().getPlan(planId).getName() + " plan");
|
||||
return response;
|
||||
}
|
||||
|
||||
Result result;
|
||||
|
||||
if (!hasUserSubscription(user.getSubscription())) {
|
||||
Pair<String, String> usernames = getUserFirstAndLastName(user.getFullName());
|
||||
String locale = user.getLocaleOrDefault().getLanguage();
|
||||
|
||||
// Make a checkout-new request
|
||||
result = HostedPage.checkoutNew().customerId(user.getName()).customerEmail(user.getEmail())
|
||||
.customerFirstName(usernames.getA()).customerLastName(usernames.getB()).customerLocale(locale)
|
||||
.subscriptionPlanId(planId).billingAddressFirstName(usernames.getA())
|
||||
.billingAddressLastName(usernames.getB()).billingAddressCountry("US").request();
|
||||
} else {
|
||||
// Make a checkout-existing request
|
||||
result = HostedPage.checkoutExisting().subscriptionId(user.getSubscription().getSubscriptionId())
|
||||
.subscriptionPlanId(planId).request();
|
||||
}
|
||||
|
||||
Pair<String, String> usernames = getUserFirstAndLastName(user.getFullName());
|
||||
String locale = user.getLocaleOrDefault().getLanguage();
|
||||
Result result = HostedPage.checkoutNew().customerId(user.getName()).customerEmail(user.getEmail())
|
||||
.customerFirstName(usernames.getA()).customerLastName(usernames.getB()).customerLocale(locale)
|
||||
.subscriptionPlanId(planId).billingAddressFirstName(usernames.getA())
|
||||
.billingAddressLastName(usernames.getB()).billingAddressCountry("US").request();
|
||||
response.setHostedPageJSONString(result.hostedPage().toJson());
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error in generating Chargebee hosted page data ", e);
|
||||
@@ -100,7 +90,7 @@ public class SubscriptionServiceImpl extends RemoteServiceServlet implements Sub
|
||||
|
||||
@Override
|
||||
public SubscriptionDTO updatePlanSuccess(String hostedPageId) {
|
||||
SubscriptionDTO subscriptionDto = new SubscriptionDTO();
|
||||
SubscriptionDTO subscriptionDto;
|
||||
|
||||
try {
|
||||
User user = getCurrentUser();
|
||||
@@ -118,15 +108,10 @@ public class SubscriptionServiceImpl extends RemoteServiceServlet implements Sub
|
||||
|
||||
getSecurityService().updateUserSubscription(user.getName(), subscription);
|
||||
|
||||
subscriptionDto.setPlanId(subscription.getPlanId());
|
||||
subscriptionDto.setTrialStart(subscription.getTrialStart());
|
||||
subscriptionDto.setTrialEnd(subscription.getTrialEnd());
|
||||
subscriptionDto.setSubscriptionStatus(subscription.getSubscriptionStatus());
|
||||
subscriptionDto.setPaymentStatus(subscription.getPaymentStatus());
|
||||
subscriptionDto = getSubscription();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error in saving subscription ", e);
|
||||
|
||||
subscriptionDto.setError(e.getMessage());
|
||||
subscriptionDto = new SubscriptionDTO(null, e.getMessage());
|
||||
}
|
||||
|
||||
return subscriptionDto;
|
||||
@@ -134,47 +119,48 @@ public class SubscriptionServiceImpl extends RemoteServiceServlet implements Sub
|
||||
|
||||
@Override
|
||||
public SubscriptionDTO getSubscription() {
|
||||
SubscriptionDTO subscriptionDto = new SubscriptionDTO();
|
||||
SubscriptionDTO subscriptionDto = null;
|
||||
try {
|
||||
final User user = getCurrentUser();
|
||||
final Subscription subscription = user.getSubscription();
|
||||
if (subscription == null || subscription.getPlanId() == null || subscription.getPlanId().isEmpty()) {
|
||||
return null;
|
||||
final Subscription[] subscriptions = user.getSubscriptions();
|
||||
if (subscriptions != null && subscriptions.length > 0) {
|
||||
List<SubscriptionItem> itemList = new ArrayList<SubscriptionItem>();
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (StringUtils.isNotEmpty(subscription.getSubscriptionId())) {
|
||||
itemList.add(new SubscriptionItem(subscription.getPlanId(), subscription.getTrialStart(),
|
||||
subscription.getTrialEnd(), subscription.getSubscriptionStatus(),
|
||||
subscription.getPaymentStatus()));
|
||||
}
|
||||
}
|
||||
if (!itemList.isEmpty()) {
|
||||
subscriptionDto = new SubscriptionDTO(itemList.toArray(new SubscriptionItem[0]), null);
|
||||
}
|
||||
}
|
||||
subscriptionDto.setPlanId(subscription.getPlanId());
|
||||
subscriptionDto.setSubscriptionStatus(subscription.getSubscriptionStatus());
|
||||
subscriptionDto.setPaymentStatus(subscription.getPaymentStatus());
|
||||
subscriptionDto.setTrialStart(subscription.getTrialStart());
|
||||
subscriptionDto.setTrialEnd(subscription.getTrialEnd());
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error in getting subscription ", e);
|
||||
|
||||
subscriptionDto.setError(e.getMessage());
|
||||
subscriptionDto = new SubscriptionDTO(null, e.getMessage());
|
||||
}
|
||||
|
||||
return subscriptionDto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancelSubscription() {
|
||||
public boolean cancelSubscription(String planId) {
|
||||
try {
|
||||
User user = getCurrentUser();
|
||||
Subscription subscription = user.getSubscription();
|
||||
if (subscription == null) {
|
||||
Subscription subscription = user.getSubscriptionByPlan(planId);
|
||||
if (!isValidSubscription(subscription)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String subscriptionId = subscription.getSubscriptionId();
|
||||
if (subscriptionId != null && !subscriptionId.isEmpty()) {
|
||||
Result result = cancel(subscriptionId).request();
|
||||
if (!result.subscription().status().name().toLowerCase()
|
||||
.equals(ChargebeeSubscription.SUBSCRIPTION_STATUS_CANCELLED)) {
|
||||
return false;
|
||||
}
|
||||
Result result = cancel(subscription.getSubscriptionId()).request();
|
||||
if (!result.subscription().status().name().toLowerCase()
|
||||
.equals(ChargebeeSubscription.SUBSCRIPTION_STATUS_CANCELLED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Subscription newSubscription = ChargebeeSubscription
|
||||
.createEmptySubscription(subscription.getLatestEventTime(), System.currentTimeMillis() / 1000);
|
||||
Subscription newSubscription = ChargebeeSubscription.createEmptySubscription(subscription.getPlanId(),
|
||||
subscription.getLatestEventTime(), System.currentTimeMillis() / 1000);
|
||||
getSecurityService().updateUserSubscription(user.getName(), newSubscription);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
@@ -212,13 +198,13 @@ public class SubscriptionServiceImpl extends RemoteServiceServlet implements Sub
|
||||
return StringUtils.isNotEmpty(planId) && SubscriptionPlanHolder.getInstance().getPlan(planId) != null;
|
||||
}
|
||||
|
||||
private boolean isUserSubscribedToPlan(Subscription userSubscription, String planId) {
|
||||
return userSubscription != null && userSubscription.getPlanId() != null
|
||||
&& userSubscription.getPlanId().equals(planId);
|
||||
private boolean isUserSubscribedToPlan(User user, String planId) {
|
||||
Subscription subscription = user.getSubscriptionByPlan(planId);
|
||||
return isValidSubscription(subscription);
|
||||
}
|
||||
|
||||
private boolean hasUserSubscription(Subscription userSubscription) {
|
||||
return userSubscription != null && userSubscription.getPlanId() != null;
|
||||
private boolean isValidSubscription(Subscription subscription) {
|
||||
return subscription != null && StringUtils.isNotEmpty(subscription.getSubscriptionId());
|
||||
}
|
||||
|
||||
private Pair<String, String> getUserFirstAndLastName(String fullName) {
|
||||
|
||||
+12
-117
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.shared.subscription.chargebee;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.subscription.chargebee.SubscriptionService;
|
||||
|
||||
/**
|
||||
@@ -10,141 +9,37 @@ import com.sap.sailing.gwt.ui.client.subscription.chargebee.SubscriptionService;
|
||||
* @author Tu Tran
|
||||
*/
|
||||
public class SubscriptionDTO implements IsSerializable {
|
||||
public static String PAYMENT_STATUS_SUCCESS = "success";
|
||||
public static String PAYMENT_STATUS_NO_SUCCESS = "no_success";
|
||||
public static String SUBSCRIPTION_STATUS_TRIAL = "in_trial";
|
||||
public static String SUBSCRIPTION_STATUS_ACTIVE = "active";
|
||||
|
||||
/**
|
||||
* User current subscription plan id
|
||||
* User's subscriptions
|
||||
*/
|
||||
private String planId;
|
||||
|
||||
/**
|
||||
* Trial start timestamp
|
||||
*/
|
||||
private long trialStart;
|
||||
|
||||
/**
|
||||
* Trial end timestamp
|
||||
*/
|
||||
private long trialEnd;
|
||||
|
||||
/**
|
||||
* Subscription status: active or in_trial
|
||||
*/
|
||||
private String subscriptionStatus;
|
||||
|
||||
/**
|
||||
* Subscription payment status: success or no_success
|
||||
*/
|
||||
private String paymentStatus;
|
||||
private SubscriptionItem[] subscriptionItems;
|
||||
|
||||
/**
|
||||
* Error message
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* Check if subscription is in trial status
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isInTrial() {
|
||||
return subscriptionStatus != null && subscriptionStatus.equals(SUBSCRIPTION_STATUS_TRIAL);
|
||||
public SubscriptionDTO() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is in active status
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return subscriptionStatus != null && subscriptionStatus.equals(SUBSCRIPTION_STATUS_ACTIVE);
|
||||
public SubscriptionDTO(SubscriptionItem[] subscriptionItems, String error) {
|
||||
this.subscriptionItems = subscriptionItems;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public boolean isPaymentSuccess() {
|
||||
return paymentStatus != null && paymentStatus.equals(PAYMENT_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription status i18n label
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSubscriptionStatusLabel() {
|
||||
if (subscriptionStatus != null) {
|
||||
if (subscriptionStatus.equals(SUBSCRIPTION_STATUS_TRIAL)) {
|
||||
return StringMessages.INSTANCE.inTrial();
|
||||
} else if (subscriptionStatus.equals(SUBSCRIPTION_STATUS_ACTIVE)) {
|
||||
return StringMessages.INSTANCE.active();
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription payment status i18n label
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPaymentStatusLabel() {
|
||||
if (paymentStatus != null) {
|
||||
if (paymentStatus.equals(PAYMENT_STATUS_SUCCESS)) {
|
||||
return StringMessages.INSTANCE.paymentStatusSuccess();
|
||||
} else {
|
||||
return StringMessages.INSTANCE.paymentStatusNoSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getPlanId() {
|
||||
return planId;
|
||||
}
|
||||
|
||||
public void setPlanId(String planId) {
|
||||
this.planId = planId;
|
||||
}
|
||||
|
||||
public long getTrialStart() {
|
||||
return trialStart;
|
||||
}
|
||||
|
||||
public void setTrialStart(long trialStart) {
|
||||
this.trialStart = trialStart;
|
||||
}
|
||||
|
||||
public long getTrialEnd() {
|
||||
return trialEnd;
|
||||
}
|
||||
|
||||
public void setTrialEnd(long trialEnd) {
|
||||
this.trialEnd = trialEnd;
|
||||
}
|
||||
|
||||
public String getSubscriptionStatus() {
|
||||
return subscriptionStatus;
|
||||
}
|
||||
|
||||
public void setSubscriptionStatus(String subscriptionStatus) {
|
||||
this.subscriptionStatus = subscriptionStatus;
|
||||
}
|
||||
|
||||
public String getPaymentStatus() {
|
||||
return paymentStatus;
|
||||
}
|
||||
|
||||
public void setPaymentStatus(String paymentStatus) {
|
||||
this.paymentStatus = paymentStatus;
|
||||
public SubscriptionItem[] getSubscriptionItems() {
|
||||
return subscriptionItems;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setSubscriptionItems(SubscriptionItem[] subscriptionItems) {
|
||||
this.subscriptionItems = subscriptionItems;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
package com.sap.sailing.gwt.ui.shared.subscription.chargebee;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
|
||||
public class SubscriptionItem implements IsSerializable {
|
||||
public static String PAYMENT_STATUS_SUCCESS = "success";
|
||||
public static String PAYMENT_STATUS_NO_SUCCESS = "no_success";
|
||||
public static String SUBSCRIPTION_STATUS_TRIAL = "in_trial";
|
||||
public static String SUBSCRIPTION_STATUS_ACTIVE = "active";
|
||||
|
||||
/**
|
||||
* User current subscription plan id
|
||||
*/
|
||||
private String planId;
|
||||
|
||||
/**
|
||||
* Trial start timestamp
|
||||
*/
|
||||
private long trialStart;
|
||||
|
||||
/**
|
||||
* Trial end timestamp
|
||||
*/
|
||||
private long trialEnd;
|
||||
|
||||
/**
|
||||
* Subscription status: active or in_trial
|
||||
*/
|
||||
private String subscriptionStatus;
|
||||
|
||||
/**
|
||||
* Subscription payment status: success or no_success
|
||||
*/
|
||||
private String paymentStatus;
|
||||
|
||||
public SubscriptionItem() {
|
||||
}
|
||||
|
||||
public SubscriptionItem(String planId, long trialStart, long trialEnd, String subscriptionStatus,
|
||||
String paymentStatus) {
|
||||
this.planId = planId;
|
||||
this.trialStart = trialStart;
|
||||
this.trialEnd = trialEnd;
|
||||
this.subscriptionStatus = subscriptionStatus;
|
||||
this.paymentStatus = paymentStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is in trial status
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isInTrial() {
|
||||
return subscriptionStatus != null && subscriptionStatus.equals(SUBSCRIPTION_STATUS_TRIAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if subscription is in active status
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return subscriptionStatus != null && subscriptionStatus.equals(SUBSCRIPTION_STATUS_ACTIVE);
|
||||
}
|
||||
|
||||
public boolean isPaymentSuccess() {
|
||||
return paymentStatus != null && paymentStatus.equals(PAYMENT_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription status i18n label
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSubscriptionStatusLabel() {
|
||||
if (subscriptionStatus != null) {
|
||||
if (subscriptionStatus.equals(SUBSCRIPTION_STATUS_TRIAL)) {
|
||||
return StringMessages.INSTANCE.inTrial();
|
||||
} else if (subscriptionStatus.equals(SUBSCRIPTION_STATUS_ACTIVE)) {
|
||||
return StringMessages.INSTANCE.active();
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscription payment status i18n label
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPaymentStatusLabel() {
|
||||
if (paymentStatus != null) {
|
||||
if (paymentStatus.equals(PAYMENT_STATUS_SUCCESS)) {
|
||||
return StringMessages.INSTANCE.paymentStatusSuccess();
|
||||
} else {
|
||||
return StringMessages.INSTANCE.paymentStatusNoSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getPlanId() {
|
||||
return planId;
|
||||
}
|
||||
|
||||
public long getTrialStart() {
|
||||
return trialStart;
|
||||
}
|
||||
|
||||
public long getTrialEnd() {
|
||||
return trialEnd;
|
||||
}
|
||||
|
||||
public String getSubscriptionStatus() {
|
||||
return subscriptionStatus;
|
||||
}
|
||||
|
||||
public String getPaymentStatus() {
|
||||
return paymentStatus;
|
||||
}
|
||||
|
||||
public void setPlanId(String planId) {
|
||||
this.planId = planId;
|
||||
}
|
||||
|
||||
public void setTrialStart(long trialStart) {
|
||||
this.trialStart = trialStart;
|
||||
}
|
||||
|
||||
public void setTrialEnd(long trialEnd) {
|
||||
this.trialEnd = trialEnd;
|
||||
}
|
||||
|
||||
public void setSubscriptionStatus(String subscriptionStatus) {
|
||||
this.subscriptionStatus = subscriptionStatus;
|
||||
}
|
||||
|
||||
public void setPaymentStatus(String paymentStatus) {
|
||||
this.paymentStatus = paymentStatus;
|
||||
}
|
||||
}
|
||||
+2
@@ -20,10 +20,12 @@ public class ChargebeeSubscriptionPermissionsAuthorizationFilter extends Subscri
|
||||
try {
|
||||
final Object requestBody = JSONValue.parseWithException(request.getReader());
|
||||
final JSONObject requestObject = Helpers.toJSONObjectSafe(requestBody);
|
||||
logger.log(Level.INFO, "Payment service webhook data: " + requestObject.toJSONString());
|
||||
final SubscriptionWebHookEvent event = new SubscriptionWebHookEvent(requestObject);
|
||||
if (!event.isValidEvent()) {
|
||||
throw new IllegalArgumentException("Invalid webhook event");
|
||||
}
|
||||
request.setAttribute("event", event);
|
||||
return event.getCustomerId();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Subscription permission checking error", e);
|
||||
|
||||
+23
-23
@@ -6,13 +6,8 @@ import java.util.logging.Logger;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
|
||||
import com.sap.sailing.server.gateway.subscription.SubscriptionWebHookHandler;
|
||||
import com.sap.sailing.server.gateway.subscription.SubscriptionWebHookServlet;
|
||||
import com.sap.sse.security.shared.Subscription;
|
||||
@@ -37,38 +32,43 @@ public class ChargebeeWebHookHandler extends SubscriptionWebHookHandler {
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
|
||||
final Object requestBody = JSONValue.parseWithException(request.getReader());
|
||||
final JSONObject requestObject = Helpers.toJSONObjectSafe(requestBody);
|
||||
logger.log(Level.INFO, "Payment service webhook data: " + requestObject.toJSONString());
|
||||
final SubscriptionWebHookEvent event = new SubscriptionWebHookEvent(requestObject);
|
||||
if (!event.isValidEvent()) {
|
||||
throw new IllegalArgumentException("Invalid webhook event");
|
||||
}
|
||||
final SubscriptionWebHookEvent event = (SubscriptionWebHookEvent) request.getAttribute("event");
|
||||
final User user = getUser(event.getCustomerId());
|
||||
if (user != null && !isOutdatedEvent(event, user.getSubscription())) {
|
||||
if (user != null && !isOutdatedEvent(event, user)) {
|
||||
processEvent(event, user);
|
||||
}
|
||||
sendSuccess(response);
|
||||
} catch (ParseException e) {
|
||||
logger.log(Level.SEVERE, "Failed to parse subscription webhook event data", e);
|
||||
sendFail(response);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Failed to proccess subscription webhook event", e);
|
||||
sendFail(response);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOutdatedEvent(SubscriptionWebHookEvent event, Subscription userSubscription) {
|
||||
private boolean isOutdatedEvent(SubscriptionWebHookEvent event, User user) {
|
||||
final long occuredAt = event.getEventOccurredAt();
|
||||
return userSubscription != null && (occuredAt < userSubscription.getLatestEventTime()
|
||||
|| occuredAt < userSubscription.getManuallyUpdatedAt());
|
||||
final String planId = event.getPlanId();
|
||||
if (StringUtils.isNotEmpty(planId)) {
|
||||
Subscription subscription = user.getSubscriptionByPlan(planId);
|
||||
return subscription != null && (occuredAt < subscription.getLatestEventTime()
|
||||
|| occuredAt < subscription.getManuallyUpdatedAt());
|
||||
} else {
|
||||
Subscription[] subscriptions = user.getSubscriptions();
|
||||
if (subscriptions != null && subscriptions.length > 0) {
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (occuredAt < subscription.getLatestEventTime()
|
||||
|| occuredAt < subscription.getManuallyUpdatedAt()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void processEvent(SubscriptionWebHookEvent event, User user) throws UserManagementException {
|
||||
final SubscriptionWebHookEventType eventType = event.getEventType();
|
||||
if (eventType != null) {
|
||||
final Subscription userSubscription = user.getSubscription();
|
||||
final Subscription userSubscription = user.getSubscriptionByPlan(event.getPlanId());
|
||||
switch (eventType) {
|
||||
case CUSTOMER_DELETED:
|
||||
updateUserSubscription(user, buildEmptySubscription(userSubscription, event));
|
||||
@@ -92,7 +92,7 @@ public class ChargebeeWebHookHandler extends SubscriptionWebHookHandler {
|
||||
}
|
||||
|
||||
private Subscription buildEmptySubscription(Subscription currentSubscription, SubscriptionWebHookEvent event) {
|
||||
return ChargebeeSubscription.createEmptySubscription(event.getEventOccurredAt(),
|
||||
return ChargebeeSubscription.createEmptySubscription(event.getPlanId(), event.getEventOccurredAt(),
|
||||
currentSubscription != null ? currentSubscription.getManuallyUpdatedAt() : 0);
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -29,7 +29,7 @@ public class SubscriptionWebHookEvent {
|
||||
}
|
||||
|
||||
public boolean isValidEvent() {
|
||||
return eventId != null && eventType != null;
|
||||
return eventId != null;
|
||||
}
|
||||
|
||||
public String getEventId() {
|
||||
@@ -41,7 +41,8 @@ public class SubscriptionWebHookEvent {
|
||||
try {
|
||||
return SubscriptionWebHookEventType.valueOf(eventTypeAsUppercaseString);
|
||||
} catch (NullPointerException | IllegalArgumentException e) {
|
||||
logger.warning("Exception trying to extract subscription event type "+eventTypeAsUppercaseString+": "+e.getMessage());
|
||||
logger.warning("Exception trying to extract subscription event type " + eventTypeAsUppercaseString + ": "
|
||||
+ e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +131,7 @@ public class SubscriptionWebHookEvent {
|
||||
private String toLowerCase(String str) {
|
||||
return str != null ? str.toLowerCase() : null;
|
||||
}
|
||||
|
||||
|
||||
private String toUpperCase(String str) {
|
||||
return str != null ? str.toUpperCase() : null;
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ public class ChargebeeSubscription extends Subscription {
|
||||
|
||||
private static final long serialVersionUID = -3682427457347116687L;
|
||||
|
||||
public static Subscription createEmptySubscription(long latestEventTime, long manualUpdatedAt) {
|
||||
return new ChargebeeSubscription(null, null, null, 0, 0, null, null, 0, 0, latestEventTime, manualUpdatedAt);
|
||||
public static Subscription createEmptySubscription(String planId, long latestEventTime, long manualUpdatedAt) {
|
||||
return new ChargebeeSubscription(null, planId, null, 0, 0, null, null, 0, 0, latestEventTime, manualUpdatedAt);
|
||||
}
|
||||
|
||||
public ChargebeeSubscription(String subscriptionId, String planId, String customerId, long trialStart,
|
||||
|
||||
@@ -113,7 +113,9 @@ public interface User extends SecurityUser<RoleDefinition, Role, UserGroup> {
|
||||
|
||||
String createRandomSecret();
|
||||
|
||||
void setSubscription(Subscription subscription);
|
||||
|
||||
Subscription getSubscription();
|
||||
Subscription[] getSubscriptions();
|
||||
|
||||
void setSubscriptions(Subscription[] subscriptions);
|
||||
|
||||
Subscription getSubscriptionByPlan(String planId);
|
||||
}
|
||||
+17
-5
@@ -89,7 +89,7 @@ public class UserImpl extends SecurityUserImpl<RoleDefinition, Role, UserGroup,
|
||||
|
||||
private List<Role> roleListForSerialization;
|
||||
|
||||
private Subscription subscription;
|
||||
private Subscription[] subscriptions;
|
||||
|
||||
public UserImpl(String name, String email, Map<String, UserGroup> defaultTenantForServer,
|
||||
UserGroupProvider userGroupProvider, Account... accounts) {
|
||||
@@ -380,12 +380,24 @@ public class UserImpl extends SecurityUserImpl<RoleDefinition, Role, UserGroup,
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscription getSubscription() {
|
||||
return subscription;
|
||||
public Subscription[] getSubscriptions() {
|
||||
return subscriptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubscription(Subscription subscription) {
|
||||
this.subscription = subscription;
|
||||
public void setSubscriptions(Subscription[] subscriptions) {
|
||||
this.subscriptions = subscriptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscription getSubscriptionByPlan(String planId) {
|
||||
if (planId != null && !planId.equals("") && subscriptions != null && subscriptions.length > 0) {
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (subscription.getPlanId() != null && subscription.getPlanId().equals(planId)) {
|
||||
return subscription;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+26
-23
@@ -360,8 +360,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
// is also only interested in the object's ID
|
||||
new MongoObjectFactoryImpl(db).storeUser(result);
|
||||
}
|
||||
final Document subscriptionDoc = (Document) userDBObject.get(FieldNames.User.SUBSCRIPTION.name());
|
||||
result.setSubscription(loadSubscription(subscriptionDoc));
|
||||
final List<?> subscriptionDocs = (List<?>) userDBObject.get(FieldNames.User.SUBSCRIPTIONS.name());
|
||||
result.setSubscriptions(loadSubscriptions(subscriptionDocs));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -507,28 +507,31 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Subscription loadSubscription(Document subscriptionDoc) {
|
||||
final Subscription result;
|
||||
if (subscriptionDoc != null) {
|
||||
String customerId = subscriptionDoc.getString(FieldNames.Subscription.CUSTOMER_ID.name());
|
||||
String planId = subscriptionDoc.getString(FieldNames.Subscription.PLAN_ID.name());
|
||||
String subscriptionStatus = subscriptionDoc.getString(FieldNames.Subscription.SUBSCRIPTION_STATUS.name());
|
||||
String subscriptionId = subscriptionDoc.getString(FieldNames.Subscription.SUBSCRIPTION_ID.name());
|
||||
long trialStart = subscriptionDoc.getLong(FieldNames.Subscription.TRIAL_START.name());
|
||||
long trialEnd = subscriptionDoc.getLong(FieldNames.Subscription.TRIAL_END.name());
|
||||
String paymentStatus = subscriptionDoc.getString(FieldNames.Subscription.PAYMENT_STATUS.name());
|
||||
long subscriptionCreatedAt = subscriptionDoc
|
||||
.getLong(FieldNames.Subscription.SUBSCRIPTION_CREATED_AT.name());
|
||||
long subscriptionUpdatedAt = subscriptionDoc
|
||||
.getLong(FieldNames.Subscription.SUBSCRIPTION_UPDATED_AT.name());
|
||||
long latestEventTime = subscriptionDoc.getLong(FieldNames.Subscription.LATEST_EVENT_TIME.name());
|
||||
long manualUpdatedAt = subscriptionDoc.getLong(FieldNames.Subscription.MANUAL_UPDATED_AT.name());
|
||||
result = new ChargebeeSubscription(subscriptionId, planId, customerId, trialStart, trialEnd,
|
||||
subscriptionStatus, paymentStatus, subscriptionCreatedAt, subscriptionUpdatedAt, latestEventTime,
|
||||
manualUpdatedAt);
|
||||
private Subscription[] loadSubscriptions(List<?> subscriptionsDoc) {
|
||||
final Subscription[] subscriptions;
|
||||
if (subscriptionsDoc != null) {
|
||||
subscriptions = new Subscription[subscriptionsDoc.size()];
|
||||
int i = 0;
|
||||
for (Object o : subscriptionsDoc) {
|
||||
final Document doc = (Document) o;
|
||||
final String customerId = doc.getString(FieldNames.Subscription.CUSTOMER_ID.name());
|
||||
final String planId = doc.getString(FieldNames.Subscription.PLAN_ID.name());
|
||||
final String subscriptionStatus = doc.getString(FieldNames.Subscription.SUBSCRIPTION_STATUS.name());
|
||||
final String subscriptionId = doc.getString(FieldNames.Subscription.SUBSCRIPTION_ID.name());
|
||||
final long trialStart = doc.getLong(FieldNames.Subscription.TRIAL_START.name());
|
||||
final long trialEnd = doc.getLong(FieldNames.Subscription.TRIAL_END.name());
|
||||
final String paymentStatus = doc.getString(FieldNames.Subscription.PAYMENT_STATUS.name());
|
||||
final long subscriptionCreatedAt = doc.getLong(FieldNames.Subscription.SUBSCRIPTION_CREATED_AT.name());
|
||||
final long subscriptionUpdatedAt = doc.getLong(FieldNames.Subscription.SUBSCRIPTION_UPDATED_AT.name());
|
||||
final long latestEventTime = doc.getLong(FieldNames.Subscription.LATEST_EVENT_TIME.name());
|
||||
final long manualUpdatedAt = doc.getLong(FieldNames.Subscription.MANUAL_UPDATED_AT.name());
|
||||
subscriptions[i++] = new ChargebeeSubscription(subscriptionId, planId, customerId, trialStart, trialEnd,
|
||||
subscriptionStatus, paymentStatus, subscriptionCreatedAt, subscriptionUpdatedAt,
|
||||
latestEventTime, manualUpdatedAt);
|
||||
}
|
||||
} else {
|
||||
result = null;
|
||||
subscriptions = null;
|
||||
}
|
||||
return result;
|
||||
return subscriptions;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class FieldNames {
|
||||
VALIDATION_SECRET,
|
||||
DEFAULT_TENANT_SERVER,
|
||||
DEFAULT_TENANT_GROUP,
|
||||
SUBSCRIPTION;
|
||||
SUBSCRIPTIONS;
|
||||
}
|
||||
|
||||
public static enum Settings {
|
||||
|
||||
+22
-16
@@ -230,7 +230,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
defaultTennants.add(tenant);
|
||||
}
|
||||
dbUser.put(FieldNames.User.DEFAULT_TENANT_IDS.name(), defaultTennants);
|
||||
dbUser.put(FieldNames.User.SUBSCRIPTION.name(), createSubscriptionObject(user.getSubscription()));
|
||||
dbUser.put(FieldNames.User.SUBSCRIPTIONS.name(), createSubscriptions(user.getSubscriptions()));
|
||||
usersCollection.withWriteConcern(WriteConcern.ACKNOWLEDGED).replaceOne(query, dbUser, new UpdateOptions().upsert(true));
|
||||
}
|
||||
|
||||
@@ -334,21 +334,27 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
return dbSettingTypes;
|
||||
}
|
||||
|
||||
private Document createSubscriptionObject(Subscription subscription) {
|
||||
final Document result;
|
||||
if (subscription != null) {
|
||||
result = new Document();
|
||||
result.put(FieldNames.Subscription.SUBSCRIPTION_ID.name(), subscription.getSubscriptionId());
|
||||
result.put(FieldNames.Subscription.PLAN_ID.name(), subscription.getPlanId());
|
||||
result.put(FieldNames.Subscription.CUSTOMER_ID.name(), subscription.getCustomerId());
|
||||
result.put(FieldNames.Subscription.TRIAL_START.name(), subscription.getTrialStart());
|
||||
result.put(FieldNames.Subscription.TRIAL_END.name(), subscription.getTrialEnd());
|
||||
result.put(FieldNames.Subscription.SUBSCRIPTION_STATUS.name(), subscription.getSubscriptionStatus());
|
||||
result.put(FieldNames.Subscription.PAYMENT_STATUS.name(), subscription.getPaymentStatus());
|
||||
result.put(FieldNames.Subscription.SUBSCRIPTION_CREATED_AT.name(), subscription.getSubscriptionCreatedAt());
|
||||
result.put(FieldNames.Subscription.SUBSCRIPTION_UPDATED_AT.name(), subscription.getSubscriptionUpdatedAt());
|
||||
result.put(FieldNames.Subscription.LATEST_EVENT_TIME.name(), subscription.getLatestEventTime());
|
||||
result.put(FieldNames.Subscription.MANUAL_UPDATED_AT.name(), subscription.getManuallyUpdatedAt());
|
||||
private BasicDBList createSubscriptions(Subscription[] subscriptions) {
|
||||
final BasicDBList result;
|
||||
if (subscriptions != null) {
|
||||
result = new BasicDBList();
|
||||
for (Subscription subscription : subscriptions) {
|
||||
final Document doc = new Document();
|
||||
doc.put(FieldNames.Subscription.SUBSCRIPTION_ID.name(), subscription.getSubscriptionId());
|
||||
doc.put(FieldNames.Subscription.PLAN_ID.name(), subscription.getPlanId());
|
||||
doc.put(FieldNames.Subscription.CUSTOMER_ID.name(), subscription.getCustomerId());
|
||||
doc.put(FieldNames.Subscription.TRIAL_START.name(), subscription.getTrialStart());
|
||||
doc.put(FieldNames.Subscription.TRIAL_END.name(), subscription.getTrialEnd());
|
||||
doc.put(FieldNames.Subscription.SUBSCRIPTION_STATUS.name(), subscription.getSubscriptionStatus());
|
||||
doc.put(FieldNames.Subscription.PAYMENT_STATUS.name(), subscription.getPaymentStatus());
|
||||
doc.put(FieldNames.Subscription.SUBSCRIPTION_CREATED_AT.name(),
|
||||
subscription.getSubscriptionCreatedAt());
|
||||
doc.put(FieldNames.Subscription.SUBSCRIPTION_UPDATED_AT.name(),
|
||||
subscription.getSubscriptionUpdatedAt());
|
||||
doc.put(FieldNames.Subscription.LATEST_EVENT_TIME.name(), subscription.getLatestEventTime());
|
||||
doc.put(FieldNames.Subscription.MANUAL_UPDATED_AT.name(), subscription.getManuallyUpdatedAt());
|
||||
result.add(doc);
|
||||
}
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
+7
-2
@@ -210,12 +210,17 @@ public class UserProxy implements User {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubscription(Subscription subscription) {
|
||||
public Subscription[] getSubscriptions() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscription getSubscription() {
|
||||
public void setSubscriptions(Subscription[] subscriptions) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscription getSubscriptionByPlan(String planId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,8 @@ Require-Bundle: javax.servlet;bundle-version="3.1.0",
|
||||
com.sap.sse.shared.android,
|
||||
com.sap.sse.replication.interfaces;visibility:=reexport,
|
||||
com.sap.sse.security.persistence,
|
||||
com.sap.sse.security.interface;visibility:=reexport
|
||||
com.sap.sse.security.interface;visibility:=reexport,
|
||||
org.apache.commons.lang;bundle-version="2.6.0"
|
||||
Web-ContextPath: /security
|
||||
Export-Package: com.sap.sse.security,
|
||||
com.sap.sse.security.impl;x-friends:="com.sap.sailing.domain.test,com.sap.sailing.server.testsupport",
|
||||
|
||||
@@ -36,6 +36,7 @@ import javax.servlet.Filter;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
@@ -2532,11 +2533,18 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
throws UserManagementException {
|
||||
User user = getUserByName(username);
|
||||
if (user != null) {
|
||||
Subscription currentSubscription = user.getSubscription();
|
||||
if (shouldUpdateUserRolesForSubscription(currentSubscription, newSubscription)) {
|
||||
updateUserRolesOnSubscriptionChange(user, currentSubscription, newSubscription);
|
||||
String newSubscriptionPlanId = newSubscription.getPlanId();
|
||||
if (StringUtils.isNotEmpty(newSubscriptionPlanId)) {
|
||||
Subscription currentSubscription = user.getSubscriptionByPlan(newSubscriptionPlanId);
|
||||
if (shouldUpdateUserRolesForSubscription(currentSubscription, newSubscription)) {
|
||||
updateUserRolesOnSubscriptionChange(user, currentSubscription, newSubscription);
|
||||
}
|
||||
|
||||
user.setSubscriptions(buildNewUserSubscriptions(user, newSubscription));
|
||||
} else {
|
||||
user.setSubscriptions(new Subscription[] { newSubscription });
|
||||
}
|
||||
user.setSubscription(newSubscription);
|
||||
|
||||
store.updateUser(user);
|
||||
return null;
|
||||
} else {
|
||||
@@ -2544,6 +2552,33 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
}
|
||||
}
|
||||
|
||||
private Subscription[] buildNewUserSubscriptions(User user, Subscription newSubscription) {
|
||||
Subscription[] newUserSubscriptions = null;
|
||||
Subscription[] subscriptions = user.getSubscriptions();
|
||||
if (newSubscription != null) {
|
||||
if (subscriptions == null || subscriptions.length == 0) {
|
||||
newUserSubscriptions = new Subscription[] { newSubscription };
|
||||
} else {
|
||||
int i = 0;
|
||||
for (Subscription subscription : subscriptions) {
|
||||
if (subscription.getPlanId().equals(newSubscription.getPlanId())) {
|
||||
subscriptions[i] = newSubscription;
|
||||
newUserSubscriptions = subscriptions;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i == subscriptions.length) {
|
||||
newUserSubscriptions = Arrays.copyOf(subscriptions, subscriptions.length + 1);
|
||||
newUserSubscriptions[newUserSubscriptions.length - 1] = newSubscription;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newUserSubscriptions = subscriptions;
|
||||
}
|
||||
return newUserSubscriptions;
|
||||
}
|
||||
|
||||
private void updateUserRolesOnSubscriptionChange(User user, Subscription currentSubscription,
|
||||
Subscription newSubscription) throws UserManagementException {
|
||||
logger.log(Level.INFO, "Update user subscription roles for user " + user.getName());
|
||||
@@ -2554,8 +2589,6 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
if (currentPlan != null) {
|
||||
UUID[] roleDefinitionIds = currentPlan.getRoleDefinitionIds();
|
||||
for (UUID roleDefId : roleDefinitionIds) {
|
||||
// see also bug5300: this works, based on the AbstractRole.equals definition,
|
||||
// as long as no qualified roles are assigned
|
||||
store.removeRoleFromUser(user.getName(), new Role(getRoleDefinition(roleDefId), null, user));
|
||||
}
|
||||
}
|
||||
@@ -2565,7 +2598,6 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
if (newPlan != null) {
|
||||
UUID[] roleDefinitionIds = newPlan.getRoleDefinitionIds();
|
||||
for (UUID roleDefId : roleDefinitionIds) {
|
||||
// see also bug5300: we may want to support qualified roles, too, in the future
|
||||
store.addRoleForUser(user.getName(), new Role(getRoleDefinition(roleDefId), null, user));
|
||||
}
|
||||
}
|
||||
@@ -2584,7 +2616,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
result = true;
|
||||
} else {
|
||||
result = newSubscription != null && currentSubscription != null
|
||||
&& newSubscription.isActiveSubscription() != currentSubscription.isActiveSubscription();
|
||||
&& newSubscription.isActiveSubscription() != currentSubscription.isActiveSubscription();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2594,24 +2626,33 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
*/
|
||||
private boolean isUserSubscriptionPlanChanged(Subscription currentSubscription, Subscription newSubscription) {
|
||||
final boolean result;
|
||||
if ((currentSubscription == null || currentSubscription.getPlanId() == null)
|
||||
&& (newSubscription == null || newSubscription.getPlanId() == null)) {
|
||||
if ((currentSubscription == null || currentSubscription.getSubscriptionId() == null)
|
||||
&& (newSubscription == null || newSubscription.getSubscriptionId() == null)) {
|
||||
result = false;
|
||||
} else {
|
||||
String currentPlan = null;
|
||||
String newPlan = null;
|
||||
String currentSubscriptionId = null;
|
||||
String newSubscriptionId = null;
|
||||
if (currentSubscription != null) {
|
||||
currentPlan = currentSubscription.getPlanId();
|
||||
currentSubscriptionId = currentSubscription.getSubscriptionId();
|
||||
}
|
||||
if (newSubscription != null) {
|
||||
newPlan = newSubscription.getPlanId();
|
||||
newSubscriptionId = newSubscription.getSubscriptionId();
|
||||
}
|
||||
if (currentPlan == null && newPlan == null) {
|
||||
result = false;
|
||||
} else if (currentPlan != null && newPlan != null) {
|
||||
result = !currentPlan.equals(newPlan);
|
||||
} else {
|
||||
if ((currentSubscriptionId == null && newSubscriptionId != null)
|
||||
|| (currentSubscriptionId != null && newSubscriptionId == null)) {
|
||||
result = true;
|
||||
} else {
|
||||
if (currentPlan == null && newPlan == null) {
|
||||
result = false;
|
||||
} else if (currentPlan != null && newPlan != null) {
|
||||
result = !currentPlan.equals(newPlan);
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in new issue
Block a user