/*******************************************************************************
* Copyright (c) 2005-2009, G. Weirich and Elexis
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* G. Weirich - initial implementation
* Joerg M. Sigle (js, jsigle) - bug fixes
*
*******************************************************************************/
package ch.elexis.core.ui.views;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.ViewPart;
import ch.elexis.core.constants.StringConstants;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.util.Extensions;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.core.ui.actions.GlobalActions;
import ch.elexis.core.ui.constants.ExtensionPointConstantsUi;
import ch.elexis.core.ui.dialogs.DailyOrderDialog;
import ch.elexis.core.ui.dialogs.NeueBestellungDialog;
import ch.elexis.core.ui.dialogs.OrderImportDialog;
import ch.elexis.core.ui.dialogs.SelectBestellungDialog;
import ch.elexis.core.ui.editors.KontaktSelektorDialogCellEditor;
import ch.elexis.core.ui.editors.PersistentObjectEditingSupport;
import ch.elexis.core.ui.exchange.IDataSender;
import ch.elexis.core.ui.exchange.XChangeException;
import ch.elexis.core.ui.icons.Images;
import ch.elexis.core.ui.util.SWTHelper;
import ch.elexis.core.ui.util.ViewMenus;
import ch.elexis.data.Artikel;
import ch.elexis.data.Bestellung;
import ch.elexis.data.BestellungEntry;
import ch.elexis.data.Kontakt;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.Query;
import ch.elexis.data.Stock;
import ch.elexis.data.StockEntry;
import ch.rgw.tools.ExHandler;
public class BestellView extends ViewPart implements ISaveablePart2 {
public static final String ID = "ch.elexis.BestellenView"; //$NON-NLS-1$
private Form form;
private FormToolkit tk = UiDesk.getToolkit();
private TableViewer tv;
private Bestellung actBestellung;
private ViewMenus viewmenus;
private IAction removeAction, dailyWizardAction, wizardAction, loadAction, printAction,
sendAction, newAction;
private IAction exportClipboardAction, checkInAction;
@Override
public void createPartControl(final Composite parent){
parent.setLayout(new FillLayout());
form = tk.createForm(parent);
Composite body = form.getBody();
body.setLayout(new GridLayout());
Table table = new Table(body, SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
table.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true));
table.setHeaderVisible(true);
table.setLinesVisible(false);
tv = new TableViewer(table);
TableViewerColumn tvc0 = new TableViewerColumn(tv, SWT.CENTER);
tvc0.getColumn().setText(Messages.BestellView_Number);
tvc0.getColumn().setWidth(40);
PersistentObjectEditingSupport poes =
new PersistentObjectEditingSupport(tv, BestellungEntry.FLD_COUNT);
tvc0.setEditingSupport(poes);
TableViewerColumn tvc1 = new TableViewerColumn(tv, SWT.LEFT);
tvc1.getColumn().setText(Messages.BestellView_Article);
tvc1.getColumn().setWidth(280);
TableViewerColumn tvc2 = new TableViewerColumn(tv, SWT.LEFT);
tvc2.getColumn().setText(Messages.BestellView_Dealer);
tvc2.getColumn().setWidth(250);
tvc2.setEditingSupport(new EditingSupport(tv) {
@Override
protected void setValue(Object element, Object value){
BestellungEntry se = (BestellungEntry) element;
if (se == null) {
return;
}
se.setProvider((Kontakt) value);
getViewer().refresh();
}
@Override
protected Object getValue(Object element){
BestellungEntry se = (BestellungEntry) element;
if (se == null) {
return null;
}
return (Kontakt) se.getProvider();
}
@Override
protected CellEditor getCellEditor(Object element){
return new KontaktSelektorDialogCellEditor(((TableViewer) getViewer()).getTable(),
"Lieferant auswählen", "Bitte selektieren Sie den Lieferant");
}
@Override
protected boolean canEdit(Object element){
BestellungEntry be = (BestellungEntry) element;
return (be != null);
}
});
TableViewerColumn tvc3 = new TableViewerColumn(tv, SWT.LEFT);
tvc3.getColumn().setText("Lager"); //$NON-NLS-1$
tvc3.getColumn().setWidth(50);
tv.setContentProvider(new IStructuredContentProvider() {
public Object[] getElements(final Object inputElement){
if (actBestellung != null) {
return actBestellung.getEntries().toArray();
}
return new Object[0];
}
public void dispose(){}
public void inputChanged(final Viewer viewer, final Object oldInput,
final Object newInput){}
});
tv.setLabelProvider(new BestellungLabelProvider());
tv.setSorter(new ViewerSorter() {
@Override
public int compare(final Viewer viewer, final Object e1, final Object e2){
BestellungEntry be1 = (BestellungEntry) e1;
BestellungEntry be2 = (BestellungEntry) e2;
String s1 = be1.getArticle().getName();
String s2 = be2.getArticle().getName();
return s1.compareTo(s2);
}
});
Transfer[] types = new Transfer[] {
TextTransfer.getInstance()
};
tv.addDropSupport(DND.DROP_COPY, types, new DropTargetAdapter() {
@Override
public void dragEnter(final DropTargetEvent event){
event.detail = DND.DROP_COPY;
}
@Override
public void drop(final DropTargetEvent event){
String drp = (String) event.data;
String[] dl = drp.split(StringConstants.COMMA);
if (actBestellung == null) {
NeueBestellungDialog nbDlg = new NeueBestellungDialog(getViewSite().getShell(),
Messages.BestellView_CreateNewOrder, Messages.BestellView_EnterOrderTitle);
if (nbDlg.open() == Dialog.OK) {
setBestellung(new Bestellung(nbDlg.getTitle(), CoreHub.actUser));
} else {
return;
}
}
List<StockEntry> stockEntriesToOrder = new ArrayList<StockEntry>();
for (String obj : dl) {
PersistentObject dropped = CoreHub.poFactory.createFromString(obj);
if (dropped instanceof StockEntry) {
stockEntriesToOrder.add((StockEntry) dropped);
} else if (dropped instanceof Artikel) {
Artikel art = (Artikel) dropped;
if(art.isProduct()) {
// TODO user message?
return;
}
// SINGLE SHOT ORDER
actBestellung.addBestellungEntry((Artikel) dropped, null, null, 1);
}
}
for (StockEntry se : stockEntriesToOrder) {
int current = se.getCurrentStock();
int max = se.getMaximumStock();
if (max == 0) {
max = se.getMinimumStock();
}
int toOrder = max - current;
actBestellung.addBestellungEntry(se.getArticle(), se.getStock(),
se.getProvider(), toOrder);
}
tv.refresh();
}
});
makeActions();
viewmenus = new ViewMenus(getViewSite());
viewmenus.createToolbar(newAction, dailyWizardAction, wizardAction, loadAction, printAction,
sendAction);
viewmenus.createMenu(newAction, dailyWizardAction, wizardAction, loadAction, printAction,
sendAction, exportClipboardAction);
viewmenus.createViewerContextMenu(tv, new IAction[] {
removeAction
});
form.getToolBarManager().add(checkInAction);
form.updateToolBar();
setBestellung(null);
tv.setInput(getViewSite());
}
private void setBestellung(final Bestellung b){
actBestellung = b;
if (b != null && !form.isDisposed()) {
form.setText(b.getLabel());
tv.refresh();
checkInAction.setEnabled(true);
} else {
checkInAction.setEnabled(false);
}
}
@Override
public void setFocus(){
}
private List<BestellungEntry> prepareOrderList(Kontakt receiver){
ArrayList<BestellungEntry> best = new ArrayList<BestellungEntry>();
List<BestellungEntry> list = actBestellung.getEntries();
for (BestellungEntry bestellungEntry : list) {
if (receiver == null) {
receiver = bestellungEntry.getProvider();
if (!receiver.exists()) {
receiver = null;
continue;
}
}
if (bestellungEntry.getProvider() != null
&& bestellungEntry.getProvider().getId().equals(receiver.getId())) {
best.add(bestellungEntry);
}
}
return best;
}
class BestellungLabelProvider extends LabelProvider implements ITableLabelProvider {
public Image getColumnImage(final Object element, final int columnIndex){
return null;
}
public String getColumnText(final Object element, final int columnIndex){
BestellungEntry be = (BestellungEntry) element;
switch (columnIndex) {
case 0:
return Integer.toString(be.getCount());
case 1:
return be.getArticle().getLabel();
case 2:
Kontakt k = be.getProvider();
return (k != null) ? k.getLabel() : Messages.BestellView_Unknown; //$NON-NLS-1$
case 3:
Stock s = be.getStock();
return (s != null) ? s.getCode() : StringConstants.EMPTY;
default:
return "?"; //$NON-NLS-1$
}
}
}
private void makeActions(){
removeAction = new Action(Messages.BestellView_RemoveArticle) { //$NON-NLS-1$
@Override
public void run(){
IStructuredSelection sel = (IStructuredSelection) tv.getSelection();
if ((sel != null) && (!sel.isEmpty())) {
if (actBestellung != null) {
@SuppressWarnings("unchecked")
List<BestellungEntry> selections = sel.toList();
for (BestellungEntry entry : selections) {
actBestellung.removeEntry(entry);
}
tv.refresh();
}
}
}
};
dailyWizardAction = new Action(Messages.BestellView_AutomaticDailyOrder) {
{
setToolTipText(Messages.BestellView_CreateAutomaticDailyOrder);
setImageDescriptor(Images.IMG_WIZ_DAY.getImageDescriptor());
}
@Override
public void run(){
if (actBestellung == null) {
setBestellung(
new Bestellung(Messages.BestellView_AutomaticDaily, CoreHub.actUser)); //$NON-NLS-1$
}
DailyOrderDialog doDlg = new DailyOrderDialog(UiDesk.getTopShell(), actBestellung);
doDlg.open();
tv.refresh(true);
}
};
wizardAction = new Action(Messages.BestellView_AutomaticOrder) { //$NON-NLS-1$
{
setToolTipText(Messages.BestellView_CreateAutomaticOrder); //$NON-NLS-1$
setImageDescriptor(Images.IMG_WIZARD.getImageDescriptor());
}
@Override
public void run(){
if (actBestellung == null) {
setBestellung(new Bestellung(Messages.BestellView_Automatic, CoreHub.actUser));
}
Query<StockEntry> qbe = new Query<StockEntry>(StockEntry.class, null, null,
StockEntry.TABLENAME, new String[] {
StockEntry.FLD_CURRENT, StockEntry.FLD_MAX
});
qbe.add(StockEntry.FLD_CURRENT, Query.LESS, StockEntry.FLD_MIN);
List<StockEntry> stockEntries = qbe.execute();
for (StockEntry se : stockEntries) {
CoreHub.getOrderService().addRefillForStockEntryToOrder(se, actBestellung);
}
tv.refresh(true);
}
};
newAction = new Action(Messages.BestellView_CreateNewOrder) { //$NON-NLS-1$
@Override
public void run(){
NeueBestellungDialog nbDlg = new NeueBestellungDialog(getViewSite().getShell(),
Messages.BestellView_CreateNewOrder, Messages.BestellView_EnterOrderTitle);
if (nbDlg.open() == Dialog.OK) {
setBestellung(new Bestellung(nbDlg.getTitle(), CoreHub.actUser));
} else {
return;
}
tv.refresh();
}
};
printAction = new Action(Messages.BestellView_PrintOrder) { //$NON-NLS-1$
@Override
public void run(){
if (actBestellung != null) {
Kontakt receiver = null;
List<BestellungEntry> best = prepareOrderList(receiver);
try {
BestellBlatt bb =
(BestellBlatt) getViewSite().getPage().showView(BestellBlatt.ID);
bb.createOrder(receiver, best);
tv.refresh();
Bestellung.markAsOrdered(best);
} catch (PartInitException e) {
ExHandler.handle(e);
}
}
}
};
sendAction = new Action(Messages.BestellView_SendOrder) {
@Override
public void run(){
if (actBestellung == null)
return;
// organise items in supplier and non-supplier lists
List<BestellungEntry> orderableItems = new ArrayList<BestellungEntry>();
List<BestellungEntry> noSupplierItems = new ArrayList<BestellungEntry>();
for (BestellungEntry item : actBestellung.getEntries()) {
Kontakt supplier = item.getProvider();
if (supplier != null && supplier.exists()) {
orderableItems.add(item);
} else {
noSupplierItems.add(item);
}
}
boolean runOrder = true;
if (!noSupplierItems.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (BestellungEntry noSupItem : noSupplierItems) {
sb.append(noSupItem.getArticle().getLabel());
sb.append("\n");
}
runOrder =
SWTHelper.askYesNo(Messages.BestellView_NoSupplierArticle, MessageFormat
.format(Messages.BestellView_NoSupplierArticleMsg, sb.toString()));
}
if (runOrder) {
List<IConfigurationElement> list =
Extensions.getExtensions(ExtensionPointConstantsUi.TRANSPORTER);
for (IConfigurationElement ic : list) {
String handler = ic.getAttribute("type");
if (handler != null && handler.contains(Bestellung.class.getName())) {
try {
IDataSender sender = (IDataSender) ic.createExecutableExtension(
ExtensionPointConstantsUi.TRANSPORTER_EXPC);
sender.store(actBestellung);
sender.finalizeExport();
SWTHelper.showInfo(Messages.BestellView_OrderSentCaption,
Messages.BestellView_OrderSentBody);
tv.refresh();
Bestellung.markAsOrdered(orderableItems);
} catch (CoreException ex) {
ExHandler.handle(ex);
} catch (XChangeException xx) {
SWTHelper.showError(Messages.BestellView_OrderNotPossible,
Messages.BestellView_NoAutomaticOrderAvailable
+ xx.getLocalizedMessage());
}
}
}
}
}
};
loadAction = new Action(Messages.BestellView_OpenOrder) {
@Override
public void run(){
SelectBestellungDialog dlg = new SelectBestellungDialog(getViewSite().getShell());
dlg.setMessage(Messages.BestellView_SelectOrder); //$NON-NLS-1$
dlg.setTitle(Messages.BestellView_ReadOrder); //$NON-NLS-1$
if (dlg.open() == Dialog.OK) {
if (dlg.getResult().length > 0) {
Bestellung res = (Bestellung) dlg.getResult()[0];
setBestellung(res);
}
}
}
};
printAction.setImageDescriptor(Images.IMG_PRINTER.getImageDescriptor());
printAction.setToolTipText(Messages.BestellView_PrintOrder);
newAction.setImageDescriptor(Images.IMG_ADDITEM.getImageDescriptor());
newAction.setToolTipText(Messages.BestellView_CreateNewOrder);
sendAction.setImageDescriptor(Images.IMG_NETWORK.getImageDescriptor());
sendAction.setToolTipText(Messages.BestellView_transmitOrder);
loadAction.setImageDescriptor(Images.IMG_IMPORT.getImageDescriptor());
loadAction.setToolTipText(Messages.BestellView_loadEarlierOrder);
exportClipboardAction = new Action(Messages.BestellView_copyToClipboard) {
{
setToolTipText(Messages.BestellView_copyToClipBioardForGalexis);
}
@Override
public void run(){
if (actBestellung != null) {
Kontakt receiver = null;
List<BestellungEntry> best = prepareOrderList(receiver);
StringBuffer export = new StringBuffer();
for (BestellungEntry item : best) {
String pharmaCode = item.getArticle().getPharmaCode();
int num = item.getCount();
String name = item.getArticle().getName();
String line = pharmaCode + ", " + num + ", " + name; //$NON-NLS-1$ //$NON-NLS-2$
export.append(line);
export.append(System.getProperty("line.separator")); //$NON-NLS-1$
}
String clipboardText = export.toString();
Clipboard clipboard = new Clipboard(UiDesk.getDisplay());
TextTransfer textTransfer = TextTransfer.getInstance();
Transfer[] transfers = new Transfer[] {
textTransfer
};
Object[] data = new Object[] {
clipboardText
};
clipboard.setContents(data, transfers);
clipboard.dispose();
}
}
};
checkInAction = new Action(Messages.BestellView_CheckInCaption) { //$NON-NLS-1$
{
setImageDescriptor(Images.IMG_TICK.getImageDescriptor());
setToolTipText(Messages.BestellView_CheckInBody); //$NON-NLS-1$
}
@Override
public void run(){
if (actBestellung != null && actBestellung.exists()) {
OrderImportDialog dialog =
new OrderImportDialog(getSite().getShell(), actBestellung);
dialog.open();
} else {
SWTHelper.alert(Messages.BestellView_NoOrder, //$NON-NLS-1$
Messages.BestellView_NoOrderLoaded); //$NON-NLS-1$
}
}
};
}
/*
* Die folgenden 6 Methoden implementieren das Interface ISaveablePart2 Wir benötigen das
* Interface nur, um das Schliessen einer View zu verhindern, wenn die Perspektive fixiert ist.
* Gibt es da keine einfachere Methode?
*/
public int promptToSaveOnClose(){
return GlobalActions.fixLayoutAction.isChecked() ? ISaveablePart2.CANCEL
: ISaveablePart2.NO;
}
public void doSave(final IProgressMonitor monitor){ /* leer */
}
public void doSaveAs(){ /* leer */
}
public boolean isDirty(){
return true;
}
public boolean isSaveAsAllowed(){
return false;
}
public boolean isSaveOnCloseNeeded(){
return true;
}
public void addItemsToOrder(List<Artikel> articlesToOrder){
if (actBestellung == null) {
NeueBestellungDialog nbDlg = new NeueBestellungDialog(getViewSite().getShell(),
Messages.BestellView_CreateNewOrder, Messages.BestellView_EnterOrderTitle);
if (nbDlg.open() == Dialog.OK) {
setBestellung(new Bestellung(nbDlg.getTitle(), CoreHub.actUser));
} else {
return;
}
}
for (Artikel arti : articlesToOrder) {
// SINGLE SHOT ORDER
actBestellung.addBestellungEntry((Artikel) arti, null, null, 1);
}
if (tv != null && !tv.getControl().isDisposed()) {
tv.refresh();
}
}
/**
* @return the current defined {@link Bestellung} in this view
*/
public Bestellung getActBestellung(){
return actBestellung;
}
/**
* Find the default supplier. Shows a warning if supplier is null or inexisting
*
* @param cfgSupplier
* value delivered from the plugins configured supplier field
* @param selDialogTitle
* title of the dialog
* @return the supplier or null if none could be resolved.
*/
public static Kontakt resolveDefaultSupplier(String cfgSupplier, String selDialogTitle){
Kontakt supplier = null;
if (cfgSupplier != null && !cfgSupplier.isEmpty()) {
supplier = Kontakt.load(cfgSupplier);
}
//warn that there is no supplier
if (supplier == null || !supplier.exists()) {
MessageDialog.openWarning(UiDesk.getTopShell(), selDialogTitle,
Messages.BestellView_CantOrderNoSupplier);
}
return supplier;
}
}