package com.casamind.adware.client.presenter;
import java.util.ArrayList;
import java.util.List;
import com.casamind.adware.client.Adware;
import com.casamind.adware.client.event.EntityDeletedEvent;
import com.casamind.adware.client.event.EntityEditCancelledEvent;
import com.casamind.adware.client.event.EntityEditEvent;
import com.casamind.adware.client.event.EntityUpdatedEvent;
import com.casamind.adware.client.event.UserMessageEvent;
import com.casamind.adware.client.helper.RPCCall;
import com.casamind.adware.client.resources.DisplayMessages;
import com.casamind.adware.client.resources.ErrorMessages;
import com.casamind.adware.client.resources.UIConstants;
import com.casamind.adware.client.service.DataServiceAsync;
import com.casamind.adware.client.service.MailServiceAsync;
import com.casamind.adware.shared.AccessLevels;
import com.casamind.adware.shared.EntityTypes;
import com.casamind.adware.shared.InfoTypes;
import com.casamind.adware.shared.Pages;
import com.casamind.adware.shared.model.EntitySummary;
import com.casamind.adware.shared.model.ProductSummaryDTO;
import com.casamind.adware.shared.model.PublisherSummaryDTO;
import com.casamind.adware.shared.model.SlotDTO;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ListDataProvider;
public class SlotEditPresenter implements Presenter {
private SlotDTO slot;
private List<EntitySummary> compList;
private List<EntitySummary> pubList;
private final DataServiceAsync dataService;
private final MailServiceAsync mailService;
private final SimpleEventBus eventBus;
private final Display display;
private final ErrorMessages errorMessages = GWT.create(ErrorMessages.class);
private final DisplayMessages displayMessages = GWT.create(DisplayMessages.class);
private final UIConstants constants = GWT.create(UIConstants.class);
public interface Display {
HasText getStartDate();
HasText getEndDate();
HasText getNumberOfSlots();
HasText getPrice();
HasValue<Boolean> getSeq();
HasValue<Boolean> getAlt();
HasClickHandlers getSaveButton();
HasClickHandlers getDeleteButton();
HasClickHandlers getCancelButton();
Widget asWidget();
ListBox getPublisherList();
ListBox getCompanyList();
HasData<ProductSummaryDTO> getSelectedProductsGrid();
HasData<ProductSummaryDTO> getOtherProductsGrid();
Column<ProductSummaryDTO, String> getSelectedProductsDeleteColumn();
Column<ProductSummaryDTO, String> getSelectedProductsClickableColumn();
Column<ProductSummaryDTO, String> getOtherProductsDeleteColumn();
Column<ProductSummaryDTO, String> getOtherProductsClickableColumn();
ListDataProvider<ProductSummaryDTO> getSelectedProductsDataProvider();
ListDataProvider<ProductSummaryDTO> getOtherProductsDataProvider();
void addSelectedProductsDataDisplay(HasData<ProductSummaryDTO> display);
void addOtherProductsDataDisplay(HasData<ProductSummaryDTO> display);
void redrawSelectedProductsGrid();
void redrawOtherProductsGrid();
void handleEntityChanged();
void setStatus(int status);
}
public SlotEditPresenter(DataServiceAsync dataService, MailServiceAsync mailService, SimpleEventBus eventBus, Display display) {
this.dataService = dataService;
this.mailService = mailService;
this.eventBus = eventBus;
this.display = display;
this.slot = new SlotDTO();
this.compList = new ArrayList<EntitySummary>();
this.pubList = new ArrayList<EntitySummary>();
bind();
}
public SlotEditPresenter(final DataServiceAsync dataService, MailServiceAsync mailService, SimpleEventBus eventBus, Display display, final Long id) {
this(dataService, mailService, eventBus, display);
if (id == null) {
if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Publisher) {
this.pubList.add(Adware.get().getCurrentPublisher());
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.display.getPublisherList().addItem(Adware.get().getCurrentPublisher().getDisplayName());
} else if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Company) {
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.compList.add(Adware.get().getCurrentCompany());
populatePublisherList(Adware.get().getCurrentCompany().getId(), null);
} else {
populateCompanyList(null, null);
}
this.display.getSelectedProductsGrid().setRowCount(0);
this.display.getOtherProductsGrid().setRowCount(0);
} else {
new RPCCall<SlotDTO>() {
@Override
protected void callService(AsyncCallback<SlotDTO> cb) {
dataService.getSlot(id, cb);
}
@Override
public void onSuccess(SlotDTO result) {
if (result != null) {
slot = result;
SlotEditPresenter.this.display.getStartDate().setText(DateTimeFormat.getFormat(PredefinedFormat.DATE_TIME_MEDIUM).format(slot.getStartDate()));
SlotEditPresenter.this.display.getEndDate().setText(DateTimeFormat.getFormat(PredefinedFormat.DATE_TIME_MEDIUM).format(slot.getEndDate()));
SlotEditPresenter.this.display.getPrice().setText(slot.getPrice() + " " + constants.currencyCode());
SlotEditPresenter.this.display.getNumberOfSlots().setText(slot.getNbSlots() + "");
if (slot.isSequential() == null) {
SlotEditPresenter.this.display.getAlt().setValue((Boolean) false);
SlotEditPresenter.this.display.getSeq().setValue((Boolean) true);
} else {
SlotEditPresenter.this.display.getAlt().setValue((Boolean) !slot.isSequential());
SlotEditPresenter.this.display.getSeq().setValue((Boolean) slot.isSequential());
}
SlotEditPresenter.this.display.setStatus(slot.getStatus());
populateCellTables(slot.getOwnerId());
selectItemsInLists(slot.getCompany().getId(), slot.getPublisher().getId());
} else {
Window.alert(errorMessages.unknownError());
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
}
private void setSelectedItems(Long companyId, Long publisherId) {
populateCompanyList(companyId, publisherId);
}
private void selectItemsInLists(Long companyId, Long publisherId) {
if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Publisher) {
this.pubList.add(Adware.get().getCurrentPublisher());
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.display.getPublisherList().addItem(Adware.get().getCurrentPublisher().getDisplayName());
} else if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Company) {
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().getDisplayName());
this.compList.add(Adware.get().getCurrentCompany());
populatePublisherList(companyId, publisherId);
} else {
setSelectedItems(slot.getCompany().getId(), slot.getPublisher().getId());
}
}
private void populateCompanyList(final Long companyId, final Long publisherId) {
new RPCCall<List<EntitySummary>>() {
@Override
protected void callService(AsyncCallback<List<EntitySummary>> cb) {
dataService.getCompanies(cb);
}
@Override
public void onSuccess(List<EntitySummary> result) {
for (EntitySummary entity : result) {
SlotEditPresenter.this.display.getCompanyList().addItem(entity.getDisplayName());
SlotEditPresenter.this.compList.add(entity);
}
if (SlotEditPresenter.this.display.getCompanyList().getItemCount() > 0) {
if (companyId == null) {
SlotEditPresenter.this.display.getCompanyList().setSelectedIndex(0);
populatePublisherList(SlotEditPresenter.this.compList.get(0).getId(), null);
} else {
int index = indexOf(SlotEditPresenter.this.compList, companyId);
if (index != -1) {
SlotEditPresenter.this.display.getCompanyList().setSelectedIndex(index);
populatePublisherList(companyId, publisherId);
}
}
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
this.display.getCompanyList().addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
int index = SlotEditPresenter.this.display.getCompanyList().getSelectedIndex();
Long id = SlotEditPresenter.this.compList.get(index).getId();
populatePublisherList(id, null);
}
});
}
private void populatePublisherList(final Long companyId, final Long publisherId) {
this.display.getPublisherList().clear();
this.pubList.clear();
display.getPublisherList().addItem("*");
pubList.add(new PublisherSummaryDTO(new Long(0), "*", "", new Long(0)));
new RPCCall<List<PublisherSummaryDTO>>() {
@Override
protected void callService(AsyncCallback<List<PublisherSummaryDTO>> cb) {
dataService.getPublisherSummariesByCompanyId(companyId, cb);
}
@Override
public void onSuccess(List<PublisherSummaryDTO> result) {
for (EntitySummary entity : result) {
SlotEditPresenter.this.display.getPublisherList().addItem(entity.getDisplayName());
SlotEditPresenter.this.pubList.add(entity);
}
if (SlotEditPresenter.this.display.getPublisherList().getItemCount() > 0) {
if (publisherId == null) {
SlotEditPresenter.this.display.getPublisherList().setSelectedIndex(0);
} else {
int index = indexOf(SlotEditPresenter.this.pubList, publisherId);
if (index != -1) {
SlotEditPresenter.this.display.getPublisherList().setSelectedIndex(index);
}
}
int index = SlotEditPresenter.this.display.getPublisherList().getSelectedIndex();
Long id = index == 0 ? companyId : SlotEditPresenter.this.pubList.get(index).getId();
populateCellTables(id);
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
this.display.getPublisherList().addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
int index = SlotEditPresenter.this.display.getPublisherList().getSelectedIndex();
Long id = index == 0 ? companyId : SlotEditPresenter.this.pubList.get(index).getId();
populateCellTables(id);
}
});
}
private void populateCellTables(final Long ownerId) {
this.display.getSelectedProductsDataProvider().getList().clear();
for (ProductSummaryDTO entity : this.slot.getProducts()) {
this.display.getSelectedProductsDataProvider().getList().add(entity);
}
new RPCCall<List<ProductSummaryDTO>>() {
@Override
protected void callService(AsyncCallback<List<ProductSummaryDTO>> cb) {
dataService.getProductSummariesBySlotOwnerId(ownerId, cb);
}
@Override
public void onSuccess(List<ProductSummaryDTO> result) {
SlotEditPresenter.this.display.getOtherProductsDataProvider().getList().clear();
for (ProductSummaryDTO entity : result) {
if (!contains(SlotEditPresenter.this.slot.getProducts(), entity.getId())) {
SlotEditPresenter.this.display.getOtherProductsDataProvider().getList().add(entity);
}
}
SlotEditPresenter.this.display.addOtherProductsDataDisplay(SlotEditPresenter.this.display.getOtherProductsGrid());
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
this.display.addSelectedProductsDataDisplay(this.display.getSelectedProductsGrid());
}
public void bind() {
this.display.getAlt().addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
slot.setSequential(false);
}
});
this.display.getSeq().addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
slot.setSequential(true);
}
});
this.display.getSaveButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
doSave();
}
});
this.display.getDeleteButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
doWithdraw();
}
});
this.display.getCancelButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
eventBus.fireEvent(new EntityEditCancelledEvent());
}
});
this.display.getSelectedProductsClickableColumn().setFieldUpdater(new FieldUpdater<ProductSummaryDTO, String>() {
public void update(int index, ProductSummaryDTO object, String value) {
eventBus.fireEvent(new EntityEditEvent(object, EntityTypes.Product));
}
});
this.display.getSelectedProductsDeleteColumn().setFieldUpdater(new FieldUpdater<ProductSummaryDTO, String>() {
public void update(int index, final ProductSummaryDTO object, String value) {
SlotEditPresenter.this.slot.getProducts().remove(object);
display.getSelectedProductsDataProvider().getList().remove(object);
display.redrawSelectedProductsGrid();
display.getOtherProductsDataProvider().getList().add(object);
display.redrawOtherProductsGrid();
display.handleEntityChanged();
}
});
this.display.getOtherProductsClickableColumn().setFieldUpdater(new FieldUpdater<ProductSummaryDTO, String>() {
public void update(int index, ProductSummaryDTO object, String value) {
eventBus.fireEvent(new EntityEditEvent(object, EntityTypes.Product));
}
});
this.display.getOtherProductsDeleteColumn().setFieldUpdater(new FieldUpdater<ProductSummaryDTO, String>() {
public void update(int index, final ProductSummaryDTO object, String value) {
SlotEditPresenter.this.slot.getProducts().add(object);
display.getOtherProductsDataProvider().getList().remove(object);
display.redrawOtherProductsGrid();
display.getSelectedProductsDataProvider().getList().add(object);
display.redrawSelectedProductsGrid();
display.handleEntityChanged();
}
});
}
private void doWithdraw() {
if (slot == null || slot.getId() == null)
return;
if (Window.confirm(errorMessages.warningWithdrawSlot())) {
deleteEntity(slot);
}
}
private void deleteEntity(final SlotDTO slot) {
new RPCCall<Boolean>() {
@Override
protected void callService(AsyncCallback<Boolean> cb) {
dataService.withdrawSlot(slot, cb);
}
@Override
public void onSuccess(Boolean result) {
if (result == true) {
eventBus.fireEvent(new EntityDeletedEvent());
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Info, 0));
sendCancellationMail(slot, "NOT IMPLEMENTED");
} else {
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Error, 0));
}
}
@Override
public void onFailure(Throwable caught) {
if (caught instanceof com.casamind.adware.shared.exception.NotLoggedInException) {
Window.alert(errorMessages.youNeedToLogin());
} else {
Window.alert(errorMessages.rpcError(caught.toString()));
}
}
}.retry(3);
}
private void sendCancellationMail(final SlotDTO dto, final String reason) {
new RPCCall<Void>() {
@Override
protected void callService(AsyncCallback<Void> cb) {
mailService.slotCancelled(dto, reason, cb);
}
@Override
public void onSuccess(Void result) {
eventBus.fireEvent(new UserMessageEvent(displayMessages.confirmationMailTaskScheduled(), InfoTypes.Info, 0));
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void doSave() {
if (pubList.get(display.getPublisherList().getSelectedIndex()).getId().longValue() != 0) {
slot.setOwnerId(pubList.get(display.getPublisherList().getSelectedIndex()).getId());
} else {
slot.setOwnerId(compList.get(display.getCompanyList().getSelectedIndex()).getId());
}
slot.setSequential((Boolean) display.getSeq().getValue());
slot.setConfigured(true);
new RPCCall<SlotDTO>() {
@Override
protected void callService(AsyncCallback<SlotDTO> cb) {
dataService.updateSlot(slot, cb);
}
@Override
public void onSuccess(SlotDTO result) {
if (result != null) {
eventBus.fireEvent(new EntityUpdatedEvent(result));
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Info, 0));
} else {
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Error, 0));
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private int indexOf(List<EntitySummary> list, Long id) {
for (EntitySummary entity : list) {
if (entity.getId().longValue() == id.longValue()) {
return list.indexOf(entity);
}
}
return -1;
}
private boolean contains(List<ProductSummaryDTO> list, Long id) {
for (ProductSummaryDTO entity : list) {
if (entity.getId().longValue() == id.longValue())
return true;
}
return false;
}
@Override
public void go(DeckPanel container) {
for (int i = 0; i < container.getWidgetCount(); i++) {
if (!Pages.isHomePage(container.getWidget(i).getClass()))
container.remove(i);
}
container.add(display.asWidget());
container.showWidget(container.getWidgetIndex(display.asWidget()));
}
}