package com.sap.opportunity.ui.client;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.Orientation;
import com.extjs.gxt.ui.client.Style.VerticalAlignment;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.SliderEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.CardPanel;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.Slider;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.layout.TableLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.sap.opportunity.ui.client.dto.Opportunity;
public class OpportunitiesPanel extends LayoutContainer {
private final OpportunityServiceAsync oppService = GWT.create(OpportunityService.class);
private EditorGrid<Opportunity> grid;
private Grid<Opportunity> historyGrid;
private CardPanel gridPanel;
private ListStore<Opportunity> liveStore;
private ListStore<Opportunity> historyStore;
private Date transactionTime;
private AsyncCallback<List<OpportunityDTO>> liveCB = new AsyncCallback<List<OpportunityDTO>>() {
public void onSuccess(List<OpportunityDTO> result) {
statusDisplay.finishRPC();
liveStore.removeAll();
for (OpportunityDTO odto : result) {
liveStore.add(new Opportunity(odto));
}
}
public void onFailure(Throwable caught) {
statusDisplay.finishRPC();
statusDisplay.error("Could not get list of Opportunities from server.");
liveStore.removeAll();
GWT.log("Could not get list of Opportunities from server.", caught);
}
};
private AsyncCallback<Void> updateCB = new AsyncCallback<Void>() {
public void onSuccess(Void result) {
statusDisplay.finishRPC();
updateOpportunityList();
saveListener.opportunitiesSaved();
}
public void onFailure(Throwable caught) {
statusDisplay.finishRPC();
statusDisplay.error("Failed to update data on server.");
GWT.log("Failed to update data on server.", caught);
}
};
private AsyncCallback<List<OpportunityDTO>> historyCB = new AsyncCallback<List<OpportunityDTO>>() {
public void onSuccess(List<OpportunityDTO> result) {
statusDisplay.finishRPC();
historyStore.removeAll();
for (OpportunityDTO odto : result) {
historyStore.add(new Opportunity(odto));
}
}
public void onFailure(Throwable caught) {
statusDisplay.finishRPC();
statusDisplay.error("Could not get list of Opportunities from server.");
historyStore.removeAll();
GWT.log("Could not get list of Opportunities from server.", caught);
}
};
private Button resetButton;
private Button saveButton;
private Button addButton;
private SimpleComboBox<String> phaseFilter;
private Slider revenueSlider;
private IStatusDisplay statusDisplay;
private ISaveListener saveListener;
public OpportunitiesPanel(IStatusDisplay status, ISaveListener listener) {
super();
statusDisplay = status;
saveListener = listener;
((ServiceDefTarget) oppService).setServiceEntryPoint("http://localhost:8282/runlet/main/opportunity");
setLayout(new FitLayout());
// setup column model
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig column = new ColumnConfig();
column.setId("description");
column.setHeader("Description");
column.setWidth(80);
TextField<String> text = new TextField<String>();
text.setAllowBlank(false);
text.setAutoValidate(true);
column.setEditor(new CellEditor(text));
configs.add(column);
column = new ColumnConfig();
column.setId("prospect");
column.setHeader("Prospect");
column.setWidth(80);
text = new TextField<String>();
text.setAllowBlank(false);
text.setAutoValidate(true);
column.setEditor(new CellEditor(text));
configs.add(column);
final SimpleComboBox<String> combo = new SimpleComboBox<String>();
combo.setTriggerAction(TriggerAction.ALL);
combo.add("Initial");
combo.add("Final Phase");
combo.add("Decision Making");
CellEditor editor = new CellEditor(combo) {
@Override
public Object preProcessValue(Object value) {
if (value == null) {
return value;
}
return combo.findModel(value.toString());
}
@Override
public Object postProcessValue(Object value) {
if (value == null) {
return value;
}
return ((ModelData) value).get("value");
}
};
column = new ColumnConfig();
column.setId("phase");
column.setHeader("Phase");
column.setWidth(110);
column.setEditor(editor);
configs.add(column);
column = new ColumnConfig();
column.setId("competitors");
column.setHeader("Competitor");
column.setWidth(80);
column.setEditor(new CellEditor(new TextField<String>()));
configs.add(column);
DateField dateField = new DateField();
dateField.getPropertyEditor().setFormat(DateTimeFormat.getFormat("MM/dd/y"));
column = new ColumnConfig();
column.setId("closeDate");
column.setHeader("Closing Date");
column.setWidth(95);
column.setEditor(new CellEditor(dateField));
column.setDateTimeFormat(DateTimeFormat.getMediumDateFormat());
configs.add(column);
column = new ColumnConfig();
column.setId("responsibleEmployee");
column.setHeader("Employee Resp.");
column.setWidth(80);
column.setEditor(new CellEditor(new TextField<String>()));
configs.add(column);
column = new ColumnConfig();
column.setId("expectedSalesVolume");
column.setHeader("Expected Sales Volume");
column.setAlignment(HorizontalAlignment.RIGHT);
column.setWidth(135);
column.setNumberFormat(NumberFormat.getCurrencyFormat());
column.setEditor(new CellEditor(new NumberField()));
configs.add(column);
column = new ColumnConfig();
column.setId("probability");
column.setHeader("Probability [%]");
column.setAlignment(HorizontalAlignment.RIGHT);
column.setWidth(80);
column.setNumberFormat(NumberFormat.getPercentFormat());
column.setEditor(new CellEditor(new NumberField()));
configs.add(column);
ColumnModel cm = new ColumnModel(configs);
// setup component layout
ContentPanel cp = new ContentPanel();
cp.setHeading("Opportunities");
cp.setSize(600, 300);
cp.setLayout(new FitLayout());
gridPanel = new CardPanel();
liveStore = new ListStore<Opportunity>();
grid = new EditorGrid<Opportunity>(liveStore, cm);
grid.setBorders(true);
gridPanel.add(grid);
historyStore = new ListStore<Opportunity>();
historyGrid = new Grid<Opportunity>(historyStore, cm);
historyGrid.setBorders(true);
gridPanel.add(historyGrid);
cp.add(gridPanel);
cp.setTopComponent(getTopPanel());
cp.setButtonAlign(HorizontalAlignment.CENTER);
resetButton = new Button("Reset", new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
liveStore.rejectChanges();
}
});
cp.addButton(resetButton);
saveButton = new Button("Save", new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
List<Record> changed = liveStore.getModifiedRecords();
if (changed.size() > 0) {
List<OpportunityDTO> dtos = new ArrayList<OpportunityDTO>(changed.size());
for (Record r : changed) {
if (r.getModel() instanceof Opportunity) {
dtos.add(((Opportunity) r.getModel()).toDTO());
}
}
statusDisplay.startRPC();
oppService.updateOpportunities(dtos, updateCB);
}
// liveStore.commitChanges();
}
});
cp.addButton(saveButton);
add(cp);
updateOpportunityList();
}
private LayoutContainer getTopPanel() {
ContentPanel panel = new ContentPanel();
panel.setBorders(false);
panel.setHeaderVisible(false);
panel.setLayout(new RowLayout(Orientation.VERTICAL));
panel.add(getFilterPanel());
panel.add(getToolBar());
return panel;
}
private LayoutContainer getFilterPanel() {
ContentPanel panel = new ContentPanel();
panel.setHeaderVisible(false);
TableLayout layout = new TableLayout(2);
layout.setCellPadding(5);
layout.setCellHorizontalAlign(HorizontalAlignment.LEFT);
layout.setCellVerticalAlign(VerticalAlignment.MIDDLE);
panel.setLayout(layout);
// 1st row
LabelField filterLabel = new LabelField("Current Phase:");
panel.add(filterLabel);
final LabelField revenueLabel = new LabelField("Expected Revenue Greater than or equal to 0 $:");
panel.add(revenueLabel);
phaseFilter = new SimpleComboBox<String>();
phaseFilter.setTriggerAction(TriggerAction.ALL);
phaseFilter.add("All");
phaseFilter.add("Initial");
phaseFilter.add("Final Phase");
phaseFilter.add("Decision Making");
phaseFilter.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>() {
@Override
public void selectionChanged(
SelectionChangedEvent<SimpleComboValue<String>> se) {
updateOpportunityList();
}
});
panel.add(phaseFilter);
revenueSlider = new Slider();
revenueSlider.setWidth(250);
revenueSlider.setMinValue(0);
revenueSlider.setMaxValue(100000);
revenueSlider.setIncrement(1000);
panel.add(revenueSlider);
revenueSlider.addListener(Events.Change, new Listener<SliderEvent>() {
@Override
public void handleEvent(SliderEvent se) {
revenueLabel.setText("Expected Revenue Greater than or equal to " + se.getNewValue() + " $:");
updateOpportunityList();
}
});
return panel;
}
private void updateOpportunityList() {
String phase = phaseFilter.getSelectedIndex() < 0 ? "All" : phaseFilter.getSimpleValue();
int revenue = revenueSlider.getValue();
statusDisplay.startRPC();
if (isHistoryMode()) {
updateHistoryList(phase, revenue);
} else {
updateLiveList(phase, revenue);
}
}
private void updateLiveList(String phase, int revenue) {
// if phase is selected
if (phase.equals("All")) {
if (revenue > 0) {
// query with revenue filter only
oppService.getOpportunities(revenue, liveCB);
} else {
// query without any filter
oppService.getOpportunities(liveCB);
}
} else {
if (revenue > 0) {
// query with revenue and phase filter
oppService.getOpportunities(revenue, phase, liveCB);
} else {
// query with phase filter only
oppService.getOpportunities(phase, liveCB);
}
}
}
private void updateHistoryList(String phase, int revenue) {
// if phase is selected
if (phase.equals("All")) {
if (revenue > 0) {
// query with revenue filter only
oppService.getHistoricOpportunities(transactionTime, revenue, historyCB);
} else {
// query without any filter
oppService.getHistoricOpportunities(transactionTime, historyCB);
}
} else {
if (revenue > 0) {
// query with revenue and phase filter
oppService.getHistoricOpportunities(transactionTime, revenue, phase, historyCB);
} else {
// query with phase filter only
oppService.getHistoricOpportunities(transactionTime, phase, historyCB);
}
}
}
private ToolBar getToolBar() {
ToolBar toolBar = new ToolBar();
toolBar.setSpacing(6);
addButton = new Button("Add Opportunity");
addButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
Opportunity opportunity = new Opportunity();
opportunity.setCloseDate(new Date());
opportunity.setExpectedSalesVolume(0.);
opportunity.setPhase("Decision Making");
grid.stopEditing();
liveStore.insert(opportunity, 0);
grid.startEditing(0, 0);
}
});
toolBar.add(addButton);
return toolBar;
}
public void switchToHistoryMode() {
if (!isHistoryMode()) {
gridPanel.setActiveItem(historyGrid);
resetButton.setEnabled(false);
saveButton.setEnabled(false);
addButton.setEnabled(false);
}
}
public void switchToLiveMode() {
if (isHistoryMode()) {
gridPanel.setActiveItem(grid);
resetButton.setEnabled(true);
saveButton.setEnabled(true);
addButton.setEnabled(true);
}
}
public boolean isHistoryMode() {
return gridPanel.getActiveItem() == historyGrid;
}
public void updateHistoryData(Date transactionTime) {
this.transactionTime = transactionTime;
switchToHistoryMode();
updateOpportunityList();
}
}