package com.casamind.adware.client.presenter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.casamind.adware.client.Adware;
import com.casamind.adware.client.event.EntityEditCancelledEvent;
import com.casamind.adware.client.event.EntityEditEvent;
import com.casamind.adware.client.event.NavigationEvent;
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.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.SlotStatus;
import com.casamind.adware.shared.model.CompanyDTO;
import com.casamind.adware.shared.model.CompanySummaryDTO;
import com.casamind.adware.shared.model.EntitySummary;
import com.casamind.adware.shared.model.PublisherDTO;
import com.casamind.adware.shared.model.PublisherSummaryDTO;
import com.casamind.adware.shared.model.SlotDTO;
import com.casamind.adware.shared.model.UserAccountDTO;
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.shared.SimpleEventBus;
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.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ListDataProvider;
public class AdminSlotsPresenter implements Presenter {
private UserAccountDTO user;
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 messages = GWT.create(DisplayMessages.class);
public interface Display {
Widget asWidget();
HasClickHandlers getResourcesLink();
HasClickHandlers getSearchButton();
HasClickHandlers getCancelButton();
HasClickHandlers getInvoiceButton();
HasClickHandlers getApproveButton();
HasClickHandlers getRejectButton();
HasClickHandlers getReclaimButton();
HasData<SlotDTO> getSlotsGrid();
Column<SlotDTO, String> getSlotsClickableColumn();
Column<SlotDTO, String> getSlotsOwnerColumn();
Column<SlotDTO, String> getSlotsRejectColumn();
Column<SlotDTO, String> getSlotsApproveColumn();
Column<SlotDTO, String> getSlotsInvoiceColumn();
ListDataProvider<SlotDTO> getSlotsDataProvider();
ListBox getCompanyList();
ListBox getPublisherList();
Integer getStatus();
void addSlotsDataDisplay(HasData<SlotDTO> display);
void redrawSlotsGrid();
void setEnableButton(HasClickHandlers invoiceButton, boolean b);
}
public AdminSlotsPresenter(DataServiceAsync dataService, MailServiceAsync mailService, SimpleEventBus eventBus, Display display) {
this.dataService = dataService;
this.mailService = mailService;
this.eventBus = eventBus;
this.display = display;
this.compList = new ArrayList<EntitySummary>();
this.pubList = new ArrayList<EntitySummary>();
bind();
}
public AdminSlotsPresenter(final DataServiceAsync dataService, final MailServiceAsync mailService, SimpleEventBus eventBus, Display display, UserAccountDTO user) {
this(dataService, mailService, eventBus, display);
this.user = user;
if (Adware.get().getCurrentUser().getAccessLevel() == AccessLevels.Publisher) {
this.pubList.add(Adware.get().getCurrentPublisher());
this.compList.add(Adware.get().getCurrentCompany());
this.display.getPublisherList().addItem(Adware.get().getCurrentPublisher().getDisplayName());
this.display.getCompanyList().addItem(Adware.get().getCurrentCompany().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 {
// the user is Admin
populateCompanyList(null, null);
}
this.display.getSlotsGrid().setRowCount(0);
this.display.setEnableButton(this.display.getInvoiceButton(), false);
this.display.setEnableButton(this.display.getApproveButton(), false);
this.display.setEnableButton(this.display.getRejectButton(), false);
this.display.setEnableButton(this.display.getReclaimButton(), false);
}
private void populateCompanyList(final Long companyId, final Long publisherId) {
this.compList.add(new CompanySummaryDTO(new Long(0), "*"));
this.display.getCompanyList().addItem("*");
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) {
AdminSlotsPresenter.this.display.getCompanyList().addItem(entity.getDisplayName());
AdminSlotsPresenter.this.compList.add((CompanySummaryDTO) entity);
}
if (AdminSlotsPresenter.this.display.getCompanyList().getItemCount() > 0) {
if (companyId == null) {
AdminSlotsPresenter.this.display.getCompanyList().setSelectedIndex(0);
populatePublisherList(AdminSlotsPresenter.this.compList.get(0).getId(), null);
} else {
int index = indexOf(AdminSlotsPresenter.this.compList, companyId);
if (index != -1) {
AdminSlotsPresenter.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 = AdminSlotsPresenter.this.display.getCompanyList().getSelectedIndex();
Long id = AdminSlotsPresenter.this.compList.get(index).getId();
if (id == 0) {
display.getPublisherList().clear();
pubList.clear();
display.getPublisherList().addItem("*");
pubList.add(new PublisherSummaryDTO(new Long(0), "*", "", new Long(0)));
} else {
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 (PublisherSummaryDTO entity : result) {
AdminSlotsPresenter.this.display.getPublisherList().addItem(entity.getDisplayName());
AdminSlotsPresenter.this.pubList.add(entity);
}
if (AdminSlotsPresenter.this.display.getPublisherList().getItemCount() > 0) {
if (publisherId == null) {
AdminSlotsPresenter.this.display.getPublisherList().setSelectedIndex(0);
} else {
int index = indexOf(AdminSlotsPresenter.this.pubList, publisherId);
if (index != -1) {
AdminSlotsPresenter.this.display.getPublisherList().setSelectedIndex(index);
}
}
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void populateCellTables(List<SlotDTO> list) {
for (SlotDTO entity : list) {
this.display.getSlotsDataProvider().getList().add(entity);
}
this.display.addSlotsDataDisplay(this.display.getSlotsGrid());
}
private void bind() {
this.display.getResourcesLink().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
eventBus.fireEvent(new NavigationEvent(Pages.ResourcesAdmin));
}
});
this.display.getSlotsClickableColumn().setFieldUpdater(new FieldUpdater<SlotDTO, String>() {
public void update(int index, SlotDTO object, String value) {
eventBus.fireEvent(new EntityEditEvent(object, EntityTypes.Slot));
}
});
this.display.getSlotsOwnerColumn().setFieldUpdater(new FieldUpdater<SlotDTO, String>() {
public void update(int index, SlotDTO object, String value) {
navigateToOwner(object);
}
});
this.display.getSlotsApproveColumn().setFieldUpdater(new FieldUpdater<SlotDTO, String>() {
public void update(int index, SlotDTO object, String value) {
doApprove(object);
}
});
this.display.getSlotsRejectColumn().setFieldUpdater(new FieldUpdater<SlotDTO, String>() {
public void update(int index, SlotDTO object, String value) {
doReject(object);
}
});
this.display.getSlotsInvoiceColumn().setFieldUpdater(new FieldUpdater<SlotDTO, String>() {
public void update(int index, SlotDTO object, String value) {
if (object.getStatus() == SlotStatus.Ordered)
doInvoice(object);
}
});
this.display.getSearchButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
display.getSlotsDataProvider().getList().clear();
display.setEnableButton(display.getInvoiceButton(), false);
display.setEnableButton(display.getApproveButton(), false);
display.setEnableButton(display.getRejectButton(), false);
display.setEnableButton(display.getReclaimButton(), false);
doSearch(display.getStatus());
}
});
this.display.getCancelButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
eventBus.fireEvent(new EntityEditCancelledEvent());
}
});
this.display.getInvoiceButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
List<SlotDTO> selectedItems = getSelectedItems();
if (selectedItems.size() > 0) {
doInvoice(selectedItems);
} else {
Window.alert(messages.noItemsSelected());
}
}
});
this.display.getApproveButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
List<SlotDTO> selectedItems = getSelectedItems();
if (selectedItems.size() > 0) {
doApprove(selectedItems);
} else {
Window.alert(messages.noItemsSelected());
}
}
});
this.display.getRejectButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
List<SlotDTO> selectedItems = getSelectedItems();
if (selectedItems.size() > 0) {
doReject(selectedItems);
} else {
Window.alert(messages.noItemsSelected());
}
}
});
this.display.getReclaimButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
List<SlotDTO> selectedItems = getSelectedItems();
if (selectedItems.size() > 0) {
doReclaim(selectedItems);
} else {
Window.alert(messages.noItemsSelected());
}
}
});
}
private List<SlotDTO> getSelectedItems() {
List<SlotDTO> items = new ArrayList<SlotDTO>();
for (SlotDTO entity : display.getSlotsDataProvider().getList()) {
if (display.getSlotsGrid().getSelectionModel().isSelected(entity) == true) {
items.add(entity);
}
}
return items;
}
private void doSearch(final int status) {
display.setEnableButton(display.getSearchButton(), false);
new RPCCall<List<SlotDTO>>() {
@Override
protected void callService(AsyncCallback<List<SlotDTO>> cb) {
dataService.getSlotsByOwnerAndStatus(((EntitySummary) compList.get(display.getCompanyList().getSelectedIndex())).getId(), ((EntitySummary) pubList.get(display.getPublisherList().getSelectedIndex())).getId(), status, cb);
}
@Override
public void onSuccess(List<SlotDTO> result) {
if (result != null && result.size() > 0) {
populateCellTables(result);
setEnableActionButtons(status);
}
display.setEnableButton(display.getSearchButton(), true);
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void setEnableActionButtons(int status) {
if (status == SlotStatus.Ordered) {
display.setEnableButton(display.getInvoiceButton(), true);
display.setEnableButton(display.getRejectButton(), true);
} else if (status == SlotStatus.Invoiced) {
display.setEnableButton(display.getApproveButton(), true);
display.setEnableButton(display.getRejectButton(), true);
} else if (status == SlotStatus.Approved) {
display.setEnableButton(display.getRejectButton(), true);
} else if (status == SlotStatus.Cancelled || status == SlotStatus.Rejected) {
display.setEnableButton(display.getApproveButton(), true);
display.setEnableButton(display.getInvoiceButton(), true);
display.setEnableButton(display.getReclaimButton(), true);
}
}
private void doApprove(List<SlotDTO> objects) {
if (Window.confirm(errorMessages.warningApproveSlot())) {
for (SlotDTO object : objects) {
object.setStatus(SlotStatus.Approved);
}
doUpdate(objects);
}
}
private void doReject(List<SlotDTO> objects) {
if (Window.confirm(errorMessages.warningRejectSlot())) {
for (SlotDTO object : objects) {
object.setStatus(SlotStatus.Rejected);
}
doUpdate(objects);
}
}
private void doInvoice(List<SlotDTO> objects) {
if (Window.confirm(errorMessages.warningInvoiceSlot())) {
for (SlotDTO object : objects) {
object.setStatus(SlotStatus.Invoiced);
}
doUpdate(objects);
}
}
private void doReclaim(List<SlotDTO> objects) {
if (Window.confirm(errorMessages.warningInvoiceSlot())) {
for (SlotDTO object : objects) {
object.setStatus(SlotStatus.Reclaimed);
}
doUpdate(objects);
}
}
private void doUpdate(final List<SlotDTO> objects) {
new RPCCall<List<SlotDTO>>() {
@Override
protected void callService(AsyncCallback<List<SlotDTO>> cb) {
dataService.updateSlots(objects, cb);
}
@Override
public void onSuccess(List<SlotDTO> results) {
display.getSlotsDataProvider().getList().remove(objects);
display.redrawSlotsGrid();
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Info, 0));
List<SlotDTO> invoiced = new ArrayList<SlotDTO>();
List<SlotDTO> approved = new ArrayList<SlotDTO>();
List<SlotDTO> rejected = new ArrayList<SlotDTO>();
List<SlotDTO> cancelled = new ArrayList<SlotDTO>();
List<SlotDTO> reclaimed = new ArrayList<SlotDTO>();
for (SlotDTO result : results) {
if (result.getStatus() == SlotStatus.Invoiced) {
invoiced.add(result);
} else if (result.getStatus() == SlotStatus.Approved) {
approved.add(result);
} else if (result.getStatus() == SlotStatus.Rejected) {
rejected.add(result);
} else if (result.getStatus() == SlotStatus.Cancelled) {
cancelled.add(result);
} else if (result.getStatus() == SlotStatus.Reclaimed) {
reclaimed.add(result);
}
}
acknowledgeActionResults(invoiced);
acknowledgeActionResults(approved);
acknowledgeActionResults(rejected);
acknowledgeActionResults(cancelled);
acknowledgeActionResults(reclaimed);
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void acknowledgeActionResults(List<SlotDTO> list){
if(list != null && list.size() > 0){
if (list.get(0).getStatus() == SlotStatus.Invoiced) {
sendInvoiceMail(list);
} else if (list.get(0).getStatus() == SlotStatus.Approved) {
sendApprovalMail(list);
} else if (list.get(0).getStatus() == SlotStatus.Rejected) {
sendRejectionMail(list, "NOT IMPLEMENTED");
} else if (list.get(0).getStatus() == SlotStatus.Cancelled) {
sendCancellationMail(list, "NOT IMPLEMENTED");
} else if (list.get(0).getStatus() == SlotStatus.Reclaimed) {
sendCancellationMail(list, "NOT IMPLEMENTED");
}
}
}
private void sendApprovalMail(final List<SlotDTO> objects) {
new RPCCall<Void>() {
@Override
protected void callService(AsyncCallback<Void> cb) {
mailService.slotsApproved(dto, cb);
}
@Override
public void onSuccess(Void result) {
eventBus.fireEvent(new UserMessageEvent(messages.confirmationMailTaskScheduled(), InfoTypes.Info, 0));
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void sendInvoiceMail(final List<SlotDTO> objects) {
new RPCCall<Void>() {
@Override
protected void callService(AsyncCallback<Void> cb) {
Date dueDate = new Date();
CalendarUtil.addMonthsToDate(dueDate, 1);
mailService.slotInvoiced(dto, dueDate, cb);
}
@Override
public void onSuccess(Void result) {
eventBus.fireEvent(new UserMessageEvent(messages.confirmationMailTaskScheduled(), InfoTypes.Info, 0));
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void sendRejectionMail(final List<SlotDTO> objects, final String reason) {
new RPCCall<Void>() {
@Override
protected void callService(AsyncCallback<Void> cb) {
mailService.slotRejected(dto, reason, cb);
}
@Override
public void onSuccess(Void result) {
eventBus.fireEvent(new UserMessageEvent(messages.confirmationMailTaskScheduled(), InfoTypes.Info, 0));
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void sendCancellationMail(final List<SlotDTO> objects, 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(messages.confirmationMailTaskScheduled(), InfoTypes.Info, 0));
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
private void navigateToOwner(final SlotDTO dto) {
new RPCCall<PublisherDTO>() {
@Override
protected void callService(AsyncCallback<PublisherDTO> cb) {
dataService.getPublisher(dto.getOwnerId(), cb);
}
@Override
public void onSuccess(PublisherDTO result) {
if (result != null) {
eventBus.fireEvent(new EntityEditEvent(result, EntityTypes.Publisher));
} else {
new RPCCall<CompanyDTO>() {
@Override
protected void callService(AsyncCallback<CompanyDTO> cb) {
dataService.getCompany(dto.getOwnerId(), cb);
}
@Override
public void onSuccess(CompanyDTO result) {
if (result != null) {
eventBus.fireEvent(new EntityEditEvent(result, EntityTypes.Company));
} else {
eventBus.fireEvent(new UserMessageEvent(null, InfoTypes.Error, 0));
}
}
@Override
public void onFailure(Throwable caught) {
Window.alert(errorMessages.rpcError(caught.getMessage()));
}
}.retry(3);
}
}
@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;
}
@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()));
}
}