package com.alexanderlogistics; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.logging.Logger; import javax.enterprise.context.ConversationScoped; import javax.enterprise.event.Observes; import javax.faces.context.FacesContext; import javax.inject.Inject; import javax.inject.Named; import org.imixs.workflow.ItemCollection; import org.imixs.workflow.WorkflowKernel; import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.engine.WorkflowService; import org.imixs.workflow.exceptions.QueryException; import org.imixs.workflow.faces.data.WorkflowController; import org.imixs.workflow.faces.data.WorkflowEvent; /** * Der OPListeController dient dazu eine liste aller offenen Ausgangsrechnungen * zu bilden *

* Zusätzlich bietet er die funktionen zum auszifferne. Dies bedeutet, der * controller ermittelt zunächst alle offenen Rechnungen zu einem Debitor. Diese * Rechnungen werden in eine ChildItems Collection überführt. Der User kann nun * im Interface einzelne Rechnungen selektieren. Wird das Workitem gespeichert, * errechnet der Controller die selectieren Invoices und verknpüft diese final * mit dem Zahlungseingang. * * * @author rsoika * */ @Named("opListController") @ConversationScoped public class OPListController implements Serializable { private static final long serialVersionUID = 1L; public static final int TASK_ERSTELLUNG = 1000; private static Logger logger = Logger.getLogger(OPListController.class.getName()); private String lastDbtrNumber = null; private List invoiceList = null; @Inject protected WorkflowController workflowController; @Inject protected WorkflowService workflowService; @Inject ZahlungseingangService zahlungseingangService; @Inject protected DocumentService documentService; /** * Diese Methode liefert die Rechnungen zur gegebenen dbtrNumber. Die Methode * nutzt einen lokalen cache um die Zugriffe zu beschleunigen. *

* Befindet sich der Zahlungseingang in Erstellung (Task=1000) werden alle * offenen Rechnungen geholt *

* Befindet sich der Zahlungseingang nicht mehr in erstellung werden nur die * Rechnugnen aus $workitemRef geholt! * * @param _dbtrNumber * @return */ @SuppressWarnings("unchecked") public List getInvoices(String _dbtrNumber) { // Compute all open invoices if TASK_ERSTELLUNG.... if (workflowController.getWorkitem().getTaskID() == TASK_ERSTELLUNG) { // return empty list if dbtr is not set if (_dbtrNumber == null || _dbtrNumber.isEmpty()) { invoiceList = new ArrayList(); return invoiceList; } // if last dbtr number is equal then return the current list.... if (invoiceList != null && lastDbtrNumber != null && lastDbtrNumber.equals(_dbtrNumber)) { return invoiceList; } // load new invoice list.... lastDbtrNumber = _dbtrNumber; invoiceList = new ArrayList(); logger.info("....loading open Invoices for " + _dbtrNumber); // Aus der dbtrNummer muss das führendde D entfernt werden // wir speichern dieses zwar im Zahlungseingangs Workflow, aber eine // Ausganksrechnung kennt das nicht // Das ganze ist ein übles Relikt aus Cargosoft und kann nicht vermieden werden if (_dbtrNumber.startsWith("D")) { _dbtrNumber = _dbtrNumber.substring(1); } // (type:workitem OR type:workitemarchive) String query = "(type:workitem) AND ($modelversion:rechnungsausgang-*) AND (dbtr.number:" + _dbtrNumber + ")"; try { invoiceList = documentService.find(query, 999, 0, "$created", false); } catch (QueryException e) { logger.severe("Failed to get op liste:" + e.getMessage()); } } else { // We are no longer in TASK_ERSTELLUNG, so // fetch only selected invoices invoiceList = new ArrayList(); if (!workflowController.getWorkitem().isItemEmpty("$workitemref")) { List selection = workflowController.getWorkitem().getItemValue("$workitemref"); for (String id : selection) { if (id != null && !id.isEmpty()) { invoiceList.add(documentService.load(id)); } } } } // finally we set the 'selection' item depending on the $workitemList // and the payment amount form the 'payment.details' List selection = workflowController.getWorkitem().getItemValue("$workitemref"); List paymentList = zahlungseingangService.loadPaymentDetails(workflowController.getWorkitem()); for (ItemCollection invoice : invoiceList) { if (selection.contains(invoice.getUniqueID())) { invoice.setItemValue("selected", true); // set amount for (ItemCollection payment : paymentList) { if (invoice.getUniqueID().equals(payment.getUniqueID())) { invoice.setItemValue("payment.amount", payment.getItemValue("payment.amount")); break; } } } } return invoiceList; } // /** // * Liefert die Payments die mit diesem workitem verbunden sind... // * @return // */ // public List getPayments() { // List result=new ArrayList(); // // // result=workitemLinkController.getExternalReferences("($WorkflowGroup:Zahlungseingang"); //// if (workflowController.getWorkitem()!=null) { //// List liste = workflowService.getWorkListByRef(workflowController.getWorkitem().getUniqueID()); //// //// for (ItemCollection refWorkitem: liste) { //// if (refWorkitem.getItemValueString(WorkflowKernel.WORKFLOWGROUP).startsWith("Zahlungseingang")) { //// result.add(refWorkitem); //// } //// } //// } //// // return result; // } /** * On Before Process we store the selected invoices in $worktiemRef * * @param workflowEvent */ public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) { if (workflowEvent == null || workflowEvent.getWorkitem() == null) { return; } // store a collection of child items if you are in a Zahlungseingang if (workflowEvent.getWorkitem().getModelVersion().startsWith("zahlungseingang") && workflowEvent.getEventType() == WorkflowEvent.WORKITEM_BEFORE_PROCESS) { updateChildList(workflowEvent.getWorkitem()); } } public ItemCollection loadInvoice(String id) { return documentService.load(id); } /** * Diese Methode aktualisiert das item ChildWOrkitems mit allen selektierten * Invoices udn berechnet den payment total */ @SuppressWarnings("rawtypes") public void updateChildList(ItemCollection workitem) { double paymentTotal = 0; List mapInvoiceItems = new ArrayList(); // convert the child ItemCollection elements into a List of Map logger.info("Convert child items into Map..."); // iterate over all order items.. List selectionList = new ArrayList(); for (ItemCollection invoice : invoiceList) { if (invoice.getItemValueBoolean("selected")) { logger.info("calculate - " + invoice.getUniqueID()); selectionList.add(invoice.getUniqueID()); paymentTotal = paymentTotal + invoice.getItemValueDouble("payment.amount"); ItemCollection invoiceStub = new ItemCollection(); invoiceStub.setItemValue(WorkflowKernel.UNIQUEID, invoice.getUniqueID()); invoiceStub.setItemValue("payment.amount", invoice.getItemValue("payment.amount")); mapInvoiceItems.add(invoiceStub.getAllItems()); } } // rond with 2 digits workitem.replaceItemValue("payment.total", Math.round(paymentTotal * 100.0) / 100.0); // update childitems workitem.replaceItemValue(ZahlungseingangService.ITEM_PAYMENT_DETAILS, mapInvoiceItems); // Update $workitemref workitem.setItemValue("$workitemref", selectionList); } /** * This JSF backing method is called by cargosft-debitor-serach.xhtml after the * user has selected a new debitor. *

* The new dbtrNumber is slected form the curren ajax request param 'dbtrNumber' *

* The method just updates the dbtr.number of the current workitem. The form * will than rerender the opList section. */ public void updateDbtrNumber() { FacesContext fc = FacesContext.getCurrentInstance(); String dbtrNumber = fc.getExternalContext().getRequestParameterMap().get("dbtrNumber"); logger.fine(".........dbtrNumber = " + dbtrNumber); workflowController.getWorkitem().setItemValue("dbtr.number", dbtrNumber); } /** * Hilfsmethode delegates to ZahlungseingangServcie * * @param payment * @return */ public List loadPaymentDetails(ItemCollection payment) { return zahlungseingangService.loadPaymentDetails(payment); } /** * Berechnet den gesammten OP Saldo * * @return */ public double calculateInvoiceTotal() { double result = 0; for (ItemCollection invoice : invoiceList) { result = result + invoice.getItemValueDouble("invoice.total"); } // rond with 2 digits return Math.round(result * 100.0) / 100.0; } /** * Berechnet den gesammten OP Saldo * * @return */ public double calculateInvoiceSaldo() { double result = 0; for (ItemCollection invoice : invoiceList) { result = result + invoice.getItemValueDouble("invoice.saldo"); } // rond with 2 digits return Math.round(result * 100.0) / 100.0; } }