package com.arcbees.gwtpwebsite.client.application.order;
import javax.inject.Inject;
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;
import com.arcbees.gwtpwebsite.client.application.ApplicationPresenter;
import com.arcbees.gwtpwebsite.client.editor.EditorFactory;
import com.arcbees.gwtpwebsite.client.editor.OrderEditorPresenter;
import com.arcbees.gwtpwebsite.client.event.FormUpdatedEvent;
import com.arcbees.gwtpwebsite.client.event.TokenAskedEvent;
import com.arcbees.gwtpwebsite.client.event.TokenReceivedEvent;
import com.arcbees.gwtpwebsite.client.money.MoneyFormatter;
import com.arcbees.gwtpwebsite.client.place.NameTokens;
import com.arcbees.gwtpwebsite.client.resource.MyConstants;
import com.arcbees.gwtpwebsite.client.resource.MyMessages;
import com.arcbees.gwtpwebsite.client.rest.OrderService;
import com.arcbees.gwtpwebsite.shared.domain.Order;
import com.arcbees.gwtpwebsite.shared.domain.OrderConfirmation;
import com.arcbees.gwtpwebsite.shared.domain.Plan;
import com.arcbees.gwtpwebsite.shared.place.ParameterTokens;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.HasUiHandlers;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
public class OrderPresenter extends Presenter<OrderPresenter.MyView, OrderPresenter.MyProxy> implements OrderUiHandlers,
FormUpdatedEvent.FormUpdatedHandler, TokenReceivedEvent.TokenReceivedHandler {
interface MyView extends View, HasUiHandlers<OrderUiHandlers> {
void setPrice(String price);
void setSubtitle(String subtitle);
void setDescription(String description);
void setLoading(boolean loading);
void showConfirmationNumber(String confirmationNumber);
void hideConfirmationContainer();
void showConfirmationContainer();
void showErrorMessage(String message);
void hideErrorMessage();
void setBuyButtonActivated(Boolean activated);
void hideForm();
void showForm();
}
@ProxyStandard
@NameToken(NameTokens.order)
interface MyProxy extends ProxyPlace<OrderPresenter> {
}
static final Object SLOT_ORDER_EDITOR = new Object();
private final PlaceManager placeManager;
private final MoneyFormatter moneyFormatter;
private final OrderService orderService;
private final MyMessages myMessages;
private final MyConstants myConstants;
private final EditorFactory editorFactory;
private OrderEditorPresenter orderEditor;
@Inject
OrderPresenter(EventBus eventBus,
MyView view,
MyProxy proxy,
PlaceManager placeManager,
MoneyFormatter moneyFormatter,
OrderService orderService,
MyMessages myMessages,
MyConstants myConstants,
EditorFactory editorFactory) {
super(eventBus, view, proxy, ApplicationPresenter.TYPE_SetMainContent);
this.placeManager = placeManager;
this.moneyFormatter = moneyFormatter;
this.orderService = orderService;
this.myMessages = myMessages;
this.myConstants = myConstants;
this.editorFactory = editorFactory;
getView().setUiHandlers(this);
}
@Override
public void prepareFromRequest(PlaceRequest request) {
String planString = request.getParameter(ParameterTokens.PLAN, "");
Plan plan = null;
try {
plan = Plan.valueOf(planString);
} catch (IllegalArgumentException e) {
placeManager.revealDefaultPlace();
}
if (plan != null) {
buildForm(plan);
}
}
@Override
public void onSubscribeClicked() {
getEventBus().fireEvent(new TokenAskedEvent());
getView().setLoading(true);
getView().hideErrorMessage();
getView().hideConfirmationContainer();
getView().setBuyButtonActivated(false);
}
@Override
public void onFormUpdated(FormUpdatedEvent event) {
getView().setBuyButtonActivated(orderEditor.isOrderValid());
}
@Override
public void onTokenReceived(TokenReceivedEvent event) {
Order order = orderEditor.getOrder();
order.setCardToken(event.getToken());
orderService.sendOrder(order, new MethodCallback<OrderConfirmation>() {
@Override
public void onFailure(Method method, Throwable exception) {
onSendOrderFailure(method);
}
@Override
public void onSuccess(Method method, OrderConfirmation response) {
showConfirmationNumber(response.getConfirmationNumber());
getView().setLoading(false);
getView().setBuyButtonActivated(true);
getView().hideForm();
}
});
}
private void onSendOrderFailure(Method method) {
if (method.getResponse().getStatusCode() == 400) {
getView().showErrorMessage(myConstants.formBaseInputErrorMessage());
} else if (method.getResponse().getStatusCode() == 500) {
getView().showErrorMessage(myConstants.formSendErrorMessage());
}
getView().setLoading(false);
getView().setBuyButtonActivated(true);
}
@Override
protected void onBind() {
super.onBind();
addRegisteredHandler(FormUpdatedEvent.TYPE, this);
addRegisteredHandler(TokenReceivedEvent.TYPE, this);
}
@Override
protected void onReveal() {
super.onReveal();
getView().hideConfirmationContainer();
getView().hideErrorMessage();
}
private void showConfirmationNumber(String confirmationNumber) {
getView().showConfirmationNumber(confirmationNumber);
getView().showConfirmationContainer();
}
private void buildForm(Plan plan) {
String formattedPrice = moneyFormatter.formatAmount(plan.getMonthlyPriceInCents());
getView().setPrice(myMessages.monthlyPrice(formattedPrice));
switch (plan) {
case BASIC:
getView().setSubtitle(myConstants.basicSupportSubtitle());
getView().setDescription(myConstants.basicSupportDescription());
break;
case PROFESSIONAL:
getView().setSubtitle(myConstants.professionalSupportSubtitle());
getView().setDescription(myConstants.professionalSupportDescription());
break;
case CORPORATE:
getView().setSubtitle(myConstants.corporateSupportSubtitle());
getView().setDescription(myConstants.corporateSupportDescription());
break;
}
orderEditor = editorFactory.create(plan);
setInSlot(SLOT_ORDER_EDITOR, orderEditor);
getView().showForm();
getView().setBuyButtonActivated(false);
}
}