/*
* Copyright (C) 2014 GG-Net GmbH - Oliver Günther
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.ggnet.dwoss.redtape.dossiertable;
import java.net.URL;
import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.ggnet.saft.core.Client;
import eu.ggnet.dwoss.redtape.RedTapeAgent;
import eu.ggnet.dwoss.redtape.api.LegacyBridge;
import eu.ggnet.dwoss.redtape.entity.Dossier;
import eu.ggnet.dwoss.redtape.IDossierSelectionHandler;
import eu.ggnet.dwoss.common.DwOssCore;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import static eu.ggnet.dwoss.redtape.dossiertable.DossierTableController.IMAGE_NAME.*;
import static eu.ggnet.saft.core.Client.lookup;
/**
*
* @author pascal.perau
*/
public class DossierTableController {
@Getter
@RequiredArgsConstructor
static enum IMAGE_NAME {
CLOSED_ICON("closed_icon.png"),
COMPLAINT_ICON("complaint_icon.png"),
CANCELED_ICON("canceled_icon.png"),
COMPLAINT_REJECTED_ICON("complaint_rejected_icon.png"),
COMPLAINT_WITHDRAWN_ICON("complaint_withdrawn_icon.png"),
COMPLAINT_ACCEPTED_ICON("complaint_accepted_icon.png"),
ANNULATION_INVOICE_ICON("annulation_invoice_icon.png"),
CREDIT_MEMO_ICON("credit_memo_icon.png"),
HELP_BASIC_OPEN("basic_open_sample_loaded.png"),
HELP_FILTER_ALL("filter_all.png"),
HELP_FILTER_SALE_OPEN("filter_sale_open.png"),
HELP_FILTER_SALE_CLOSED("filter_sale_closed.png"),
HELP_FILTER_ACC_OPEN("filter_acc_open.png"),
HELP_FILTER_ACC_CLOSED("filter_acc_closed.png"),
HELP_CHANGE_COLUMNS("change_columns.png");
private final String fileName;
}
private final static Dossier[] T = new Dossier[0];
private abstract class DossierLoader extends SwingWorker<Void, Dossier> {
protected final Logger L = LoggerFactory.getLogger(this.getClass());
protected final long customerId;
private final String loader;
public DossierLoader(long customerId, String loader) {
this.customerId = customerId;
this.loader = loader;
L.debug("new Loader({},hashcode={})", loader, hashCode());
}
protected abstract List<Dossier> find(int last, int amount);
@Override
protected Void doInBackground() throws Exception {
List<Dossier> foundDossiers;
int amount = 3;
int last = 0;
view.progressBar.setIndeterminate(true);
view.progressBar.setString("Lade " + loader + " Vorgänge");
do {
foundDossiers = find(last, amount);
last += amount;
publish(foundDossiers.toArray(T));
L.debug("T({}) published: {}", Thread.currentThread().getName(), toIdIdentifieres(foundDossiers));
} while (!foundDossiers.isEmpty() && !isCancelled());
L.debug("T({}) is complete", Thread.currentThread().getName());
return null;
}
@Override
protected void process(List<Dossier> dossiers) {
if ( !isCancelled() ) {
for (Dossier dossier : dossiers) {
model.add(dossier);
}
L.debug("T({}) processed: {} ", Thread.currentThread().getName(), toIdIdentifieres(dossiers));
}
}
@Override
protected void done() {
try {
get();
view.progressBar.setIndeterminate(false);
view.progressBar.setString(loader + " Vorgänge geladen");
} catch (CancellationException ex) {
L.debug("Worker {} canceled", this);
} catch (InterruptedException | ExecutionException ex) {
DwOssCore.show(null, ex);
}
}
}
private class ClosedDossierLoader extends DossierLoader {
public ClosedDossierLoader(long customerId) {
super(customerId, "Geschlossene");
}
@Override
protected List<Dossier> find(int last, int amount) {
return lookup(RedTapeAgent.class).findDossiersClosedByCustomerIdEager(customerId, last, amount);
}
}
private class LegacyDossierLoader extends DossierLoader {
public LegacyDossierLoader(long customerId) {
super(customerId, lookup(LegacyBridge.class).name());
}
@Override
protected List<Dossier> find(int last, int amount) {
return lookup(LegacyBridge.class).findByCustomerId(customerId, last, amount);
}
}
private class OpenDossierLoader extends DossierLoader {
public OpenDossierLoader(long customerId) {
super(customerId, "Offene");
}
@Override
protected List<Dossier> find(int last, int amount) {
if ( last == 0 ) return lookup(RedTapeAgent.class).findDossiersOpenByCustomerIdEager(customerId);
return new ArrayList<>();
}
}
private DossierTableView view;
private DossierTableModel model;
private DossierLoader closedLoader;
private DossierLoader openLoader;
private DossierLoader legacyLoader;
private IDossierSelectionHandler selectionHandler;
private boolean openLoaded = false;
private boolean closedLoaded = false;
private boolean legacyLoaded = false;
public DossierTableModel getModel() {
return model;
}
public void setModel(DossierTableModel model) {
this.model = model;
}
public DossierTableView getView() {
return view;
}
public void setView(DossierTableView view) {
this.view = view;
}
public IDossierSelectionHandler getSelectionHandler() {
return selectionHandler;
}
public void setSelectionHandler(IDossierSelectionHandler selectionHandler) {
this.selectionHandler = selectionHandler;
}
public void loadOpenDossiers(long customerId) {
if ( model == null || openLoaded ) return;
openLoader = new OpenDossierLoader(customerId);
openLoaded = true;
openLoader.execute();
}
public void loadClosedDossiers(long customerId) {
if ( model == null || customerId <= 0 || closedLoaded ) return;
closedLoader = new ClosedDossierLoader(customerId);
closedLoaded = true;
closedLoader.execute();
}
public void loadLegacyDossiers(long customerId) {
if ( model == null || customerId <= 0 || legacyLoaded || !Client.hasFound(LegacyBridge.class) ) return;
legacyLoader = new LegacyDossierLoader(customerId);
legacyLoaded = true;
legacyLoader.execute();
}
public void resetLoader() {
if ( openLoader != null ) openLoader.cancel(true);
if ( closedLoader != null ) closedLoader.cancel(true);
if ( legacyLoader != null ) legacyLoader.cancel(true);
openLoaded = false;
closedLoaded = false;
legacyLoaded = false;
}
public void selectionChanged(Dossier dos) {
selectionHandler.selected(dos);
}
/**
* Generates a html formated String that represents a description of usage for the DossierTableView.
* <p/>
* @return a html formated String that represents a description of usage for the DossierTableView.
*/
public String generateHelp() {
String res = "<h1>Nutzung der Vorgangstabelle</h1><ol type=\"disc\">";
res += "<li>Wurde ein Kunde ausgewählt sind standardmäßig alle verkaufstechnisch offenen Vorgänge geladen."
+ "<br />Bei einer Auswahl verhält sich der Rest der Anwendung wie gehabt (Dokumente u. Positionen werden geladen).<br />"
+ "<img src=\"" + load(HELP_BASIC_OPEN) + "\"><br /></li>";
res += "<li>Zusätzlich kann jetzt zwischen fünf verschiedenen Filtern gewechselt werden der Vorgänge aus/einblendet:<br />"
+ "- <img src=\"" + load(HELP_FILTER_ALL) + "\"> liefert alle Vorgänge.<br />"
+ "- <img src=\"" + load(HELP_FILTER_SALE_OPEN) + "\"> liefert alle verkaufstechnisch offenen Vorgänge.<br />"
+ "- <img src=\"" + load(HELP_FILTER_SALE_CLOSED) + "\"> liefert alle verkaufstechnisch geschlossenen Vorgänge.<br />"
+ "- <img src=\"" + load(HELP_FILTER_ACC_OPEN) + "\"> liefert alle buchhalterisch offenen Vorgänge.<br />"
+ "- <img src=\"" + load(HELP_FILTER_ACC_CLOSED) + "\"> liefert alle buchhalterisch abgeschlossenen Vorgänge.<br /></li>";
res += "<li>Zusätzlich zu einer Drag&Drop funktion für Spalten kann jede Spalte ein/ausgeblendet werden:<br />"
+ "<img src=\"" + load(HELP_CHANGE_COLUMNS) + "\"></li>";
res += "</ol>";
return res;
}
private static List<String> toIdIdentifieres(Collection<Dossier> dossiers) {
List<String> result = new ArrayList<>();
for (Dossier dossier : dossiers) {
result.add("(id=" + dossier.getId() + "," + dossier.getIdentifier() + ")");
}
return result;
}
static URL load(IMAGE_NAME image) {
return DossierIconPanelRenderer.class.getResource(image.getFileName());
}
}