diff --git a/Dockerfile b/Dockerfile index f09b0f9..fcc2d39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM imixs/imixs-office-workflow:5.0.3-SNAPSHOT +FROM imixs/imixs-office-workflow:5.1.1-SNAPSHOT +#FROM imixs/imixs-office-workflow:5.0.3-SNAPSHOT # Setup debug configuration diff --git a/doc/BUSINESSPARTNER.md b/doc/BUSINESSPARTNER.md new file mode 100644 index 0000000..b6c7613 --- /dev/null +++ b/doc/BUSINESSPARTNER.md @@ -0,0 +1,49 @@ +# BusinessPartner + +Wir haben einen Workflow für die Verwaltung von BusinessPartner. +Ein BusinessPartner wird über die bestehende Cargosoft Schnittstelle aus den Debitoren/Kreditoren automatisch importiert und synchronisiert. + +In Imixs ist es dann aber möglich zusätzliche Attribute zu einem Businesspartner zu speichern. Beispielsweise: + +- Zahlungsziel +- Bankverbindungen +- Emailadressen für Mahnwesen + +Die Businessparnter werden zentral nur in dem Hauptsystem in Bremen importiert und verwaltet. Damit ein AGL System auf die BusinessPartner zugreifen kann wird eine Rest API Schnittstelle verwendet. Diese kann über Environmentvariablen aktiviert werden: + + # Rest Service BusinessPartner API + WORKFLOW_SERVICE_ENDPOINT: "http://app:8080/api" + WORKFLOW_SERVICE_USER: "admin" + WORKFLOW_SERVICE_PASSWORD: "xxxxxxxx" + +## BusinessPartner Suche + +Es gibt einen Controller und ein widget um nach Business Partnern zu suchen. + + + +Z.b. kann das als Custom Part in eine Form eingebunden werden: + +```xml + +``` + +Das widget legt dann automatisch die felder `bpid` und `bpidname` an. + +Alternativ kann im Backend über die EJB BusinessPartnerService nach bpid gesucht werden: + +```java + List resultList = businessPartnerService.search(phrase); + // oder + ItemCollection bp= businessPartnerService.getBusinessPartnerByID("BP0001"); +``` + +# Daten Migration + +\_vendor_zip_code + +\_vendor_fax + + (type:cargosoftkreditor) AND ($modified:[20010101 TO 20250215]) + +Wir müssen gundsätzlich erstmal über all $nosnapshot = true eintragen! diff --git a/doc/METRICS.md b/doc/METRICS.md new file mode 100644 index 0000000..b7326b1 --- /dev/null +++ b/doc/METRICS.md @@ -0,0 +1,47 @@ +# Metrics + +**Konzept Verworfen!** + +## Background: + +https://blog.imixs.org/2025/02/02/business-intelligence-built-on-metrics-part-ii/ + +**Die Implementierung war Teil von Version 1.3.1!** + +## Testing + +Curl + + $ curl -s http://localhost:9990/metrics + + + $ curl -s http://localhost:9990/metrics | grep BP4218 + +``` + +application_dbtr_balance{country="", currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 60911.28 +application_dbtr_balance{country="US",currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 257955.41 + + +application_dbtr_sales{country="", currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 60911.28 +application_dbtr_sales{country="US", currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 279028.91 + + +``` + +Rayonier Advanced Materials + +Debitor 74218 + +293.535,19 EUR + +Metric saldo: 318866.69 + +# Jetzt berechnen wir neu... + +https://alexander-logistics.office-workflow.de/api/metrics/dbtr/rebuild + +application_dbtr_balance{country="", currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 60911.28 +application_dbtr_balance{country="US",currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 364457.85 +application_dbtr_sales{country="", currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 60911.28 +application_dbtr_sales{country="US", currency="EUR",department="Import Zellulose/Holz",id="BP4218",name="Rayonier Advanced Materials",type="dbtr"} 364457.85 diff --git a/doc/images/businesspartner-widget.png b/doc/images/businesspartner-widget.png new file mode 100644 index 0000000..2aab829 Binary files /dev/null and b/doc/images/businesspartner-widget.png differ diff --git a/docker-compose.yml b/docker-compose.yml index 5ca177a..5c1c8b4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -36,10 +36,15 @@ services: #OCR_PDF_MODE: "OCR_ONLY | TEXT_ONLY | TEXT_AND_OCR (default)" OCR_PDF_MODE: "OCR_ONLY" + # Rest Service BusinessPartner API + WORKFLOW_SERVICE_ENDPOINT: "http://app:8080/api" + WORKFLOW_SERVICE_USER: "admin" + WORKFLOW_SERVICE_PASSWORD: "adminadmin" + LLM_SERVICE_ENDPOINT_USER: "admin" LLM_SERVICE_ENDPOINT_PASSWORD: "imixs4.null" - METRICS_ENABLED: "true" + METRICS_ENABLED: "false" ports: - "8080:8080" @@ -100,18 +105,18 @@ services: EXIM_PASSWORD: "www149.your-server.de:webmaster@imixs.com:$MAILPASSWORD" EXIM_ALLOWED_SENDERS: "10.0.0.0/8:172.18.0.0/12:192.168.0.0/16" - prometheus: - image: prom/prometheus:latest - ports: - - "9090:9090" - volumes: - - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - - prometheusdata:/prometheus/ + # prometheus: + # image: prom/prometheus:latest + # ports: + # - "9090:9090" + # volumes: + # - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml + # - prometheusdata:/prometheus/ - grafana: - image: grafana/grafana:latest - ports: - - "3000:3000" + # grafana: + # image: grafana/grafana:latest + # ports: + # - "3000:3000" volumes: dbdata: diff --git a/office-alexander-logistics-app/pom.xml b/office-alexander-logistics-app/pom.xml index 3809eb2..f427508 100644 --- a/office-alexander-logistics-app/pom.xml +++ b/office-alexander-logistics-app/pom.xml @@ -6,7 +6,7 @@ office-alexander-logistics com.alexander-logistics - 1.3.1 + 1.3.2 office-alexander-logistics-app war diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java index 81c382b..d879912 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java @@ -84,11 +84,17 @@ public class AGLAnalyticControllerDebitor implements Serializable { String chartData = ""; public void onEvent(@Observes AnalyticEvent event) { - if (!"workitem".equals(event.getWorkitem().getType()) - || !event.getWorkitem().getModelVersion().startsWith("analyse-debitor")) { + if (!"workitem".equals(event.getWorkitem().getType())) { // no op return; } + + if (!event.getWorkitem().getModelVersion().startsWith("businesspartner") + && !event.getWorkitem().getModelVersion().startsWith("analyse-debitor")) { + // no op + return; + } + String dbtrNumber = event.getWorkitem().getItemValueString("dbtr.number"); String dbtrNumberLast = event.getWorkitem().getItemValueString("dbtr.number.last"); diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java index c02a15f..c1d3b9a 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java @@ -23,49 +23,149 @@ *******************************************************************************/ package com.alexanderlogistics; +import java.io.IOException; import java.io.Serializable; +import java.io.StringWriter; +import java.io.Writer; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.imixs.workflow.ItemCollection; import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.exceptions.AccessDeniedException; +import org.imixs.workflow.exceptions.QueryException; import org.imixs.workflow.faces.data.WorkflowEvent; -import jakarta.ejb.EJB; +import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.event.Observes; -import jakarta.faces.view.ViewScoped; +import jakarta.faces.context.FacesContext; +import jakarta.inject.Inject; import jakarta.inject.Named; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; /** - * Der BusinessPartnerController stellt methoden für die BusinessPartner Forms - * bereit. + * Der BusinessPartnerController stellt Methoden für die BusinessPartner Forms + * sowie für die das Suche-Widget 'businesspartner_search' bereit. * * * @author rsoika * @version 1.0 */ - @Named -@ViewScoped +@ConversationScoped public class BusinessPartnerController implements Serializable { private static final long serialVersionUID = 1L; protected List ibanList = null; + protected List invoicesOut = null; + protected List invoicesIn = null; + protected List dunnings = null; - @EJB + @Inject DocumentService documentService; + @Inject + BusinessPartnerService businessPartnerService; + + private List searchResult = null; + private static Logger logger = Logger.getLogger(BusinessPartnerController.class.getName()); + public List getInvoicesOut() { + if (invoicesOut == null) { + invoicesOut = new ArrayList<>(); + } + return invoicesOut; + } + + public List getInvoicesIn() { + if (invoicesIn == null) { + invoicesIn = new ArrayList<>(); + } + return invoicesIn; + } + + public List getDunnings() { + if (dunnings == null) { + dunnings = new ArrayList<>(); + } + return dunnings; + } + + /** + * This method searches a text phrase within the list of DATEV kreditoren + *

+ * JSF Integration: + * + * {@code + + * } + */ + public void search(String regexPattern) { + List resultList = null; + searchResult = new ArrayList(); + // get the param from faces context.... + FacesContext fc = FacesContext.getCurrentInstance(); + String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase"); + if (phrase == null) { + return; + } + + logger.fine("search prase '" + phrase + "'"); + if (phrase == null || phrase.length() < 2) { + return; + } + logger.fine("search for=" + phrase); + resultList = businessPartnerService.search(phrase); + // Compile the regex pattern + logger.fine("regex=" + regexPattern); + Pattern pattern = null; + if (regexPattern != null && !regexPattern.isEmpty()) { + pattern = Pattern.compile(regexPattern); + } + + // Filter by Regex and convert ItemCollection into a BusinessPartnerSearchEntry + for (ItemCollection businessPartner : resultList) { + String name = businessPartner.getItemValueString("name"); + // Prüfen, ob der name der Regex entspricht + if (pattern != null) { + Matcher matcher = pattern.matcher(name); + if (!matcher.matches()) { + // Kein passendes Konto + continue; + } + } + String display = businessPartner.getItemValueString("$workflowsummary"); + + display = display.replace("\"", ""); + display = display.replace("'", ""); + + searchResult.add(new BusinessPartnerSearchEntry(name, display, buildJsonData(businessPartner))); + + } + } + + /** + * Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste + * Eintrag + * + * @return + */ + public List getSearchResult() { + return searchResult; + } + /** * WorkflowEvent listener to convert the IBAN child list embeded HashMaps into - * ItemCollections and - * reconvert them before processing + * ItemCollections and reconvert them before processing * * @param workflowEvent * @throws AccessDeniedException @@ -74,24 +174,64 @@ public class BusinessPartnerController implements Serializable { int eventType = workflowEvent.getEventType(); ItemCollection workitem = workflowEvent.getWorkitem(); - if (workitem == null) { + if (workitem == null || !workitem.getModelVersion().startsWith("businesspartner-")) { return; } // reset orderItems if workItem has changed if (WorkflowEvent.WORKITEM_CHANGED == eventType || WorkflowEvent.WORKITEM_CREATED == eventType) { // reset state - explodeIBANList(workitem); + ibanList = BusinessPartnerService.explodeBanks(workitem); + loadStats(workitem); } // before the workitem is saved we update the field txtOrderItems if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) { - implodeIBANList(workitem); + BusinessPartnerService.implodeBanks(workitem, ibanList); } if (WorkflowEvent.WORKITEM_AFTER_PROCESS == eventType) { // reset state - explodeIBANList(workitem); + ibanList = BusinessPartnerService.explodeBanks(workitem); + } + + } + + /** + * Hilfsmethode die die offenen Rechnungen läd. Wird von WorktiemChanged Event + * aufgerufen. + * + * @param workitem + */ + private void loadStats(ItemCollection workitem) { + + try { + // Ausgangsrechnungen + String dbtrNumber = workitem.getItemValueString("dbtr.number"); + if (!dbtrNumber.isEmpty()) { + if (dbtrNumber.startsWith("D")) { + dbtrNumber = dbtrNumber.substring(1); + } + String query = "(type:workitem) AND ($modelversion:rechnungsausgang-*) " + + " AND (dbtr.number:" + dbtrNumber + ")"; + invoicesOut = documentService.findStubs(query, 999, 0, "invoice.number", false); + + // Mahnungen + query = "(type:workitem) AND ($modelversion:mahnlauf-*) " + + " AND (dbtr.number:" + dbtrNumber + ")"; + dunnings = documentService.findStubs(query, 999, 0, "invoice.number", false); + } + + // Eingangsrechnungen + String cdtrNumber = workitem.getItemValueString("cdtr.number"); + if (!cdtrNumber.isEmpty()) { + String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) " + + " AND (cdtr.number:" + cdtrNumber + ")"; + invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false); + } + + } catch (QueryException e) { + logger.severe("failed to load stats: " + e.getMessage()); } } @@ -113,10 +253,10 @@ public class BusinessPartnerController implements Serializable { * * @param name - name of dbtr */ - public void removeIBAN(String name) { - if (name != null && ibanList != null) { + public void removeIBAN(String id) { + if (id != null && ibanList != null) { for (ItemCollection cdtr : ibanList) { - if (name.equals(cdtr.getItemValueString("name"))) { + if (id.equals(cdtr.getItemValueString("id"))) { ibanList.remove(cdtr); break; } @@ -124,36 +264,50 @@ public class BusinessPartnerController implements Serializable { } } - protected void implodeIBANList(ItemCollection workitem) { - List mapOrderItems = new ArrayList(); - if (this.ibanList != null) { - logger.fine("Convert child items into Map..."); - Iterator var3 = this.ibanList.iterator(); + /** + * Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen + * BusinessPartner erzeugt. + * + * @return + */ + private String buildJsonData(ItemCollection businessPartner) { + JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). // + add("name", jsonVal(businessPartner.getItemValueString("name"))). // + add("cdtr.number", jsonVal(businessPartner.getItemValueString("cdtr.number"))). // + add("dbtr.number", jsonVal(businessPartner.getItemValueString("dbtr.number"))). // + add("partner.name", jsonVal(businessPartner.getItemValueString("partner.name"))); - while (var3.hasNext()) { - ItemCollection orderItem = (ItemCollection) var3.next(); - mapOrderItems.add(orderItem.getAllItems()); - } - - workitem.replaceItemValue("partner.iban.list", mapOrderItems); + // get iban list + // {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]} + ibanList = BusinessPartnerService.getBanks(businessPartner); + int i = 1; + for (ItemCollection iban : ibanList) { + objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). // + add("bic" + 1, jsonVal(iban.getItemValueString("bic")));// } + JsonObject jsonObject = objectBuilder.build(); + + String jsonString = "{}"; + try (Writer writer = new StringWriter()) { + Json.createWriter(writer).write(jsonObject); + jsonString = writer.toString(); + } catch (IOException e) { + logger.warning("Unable to build json structure"); + } + return jsonString; } - protected void explodeIBANList(ItemCollection workitem) { - this.ibanList = new ArrayList(); - List mapOrderItems = workitem.getItemValue("partner.iban.list"); - Iterator var4 = mapOrderItems.iterator(); - while (var4.hasNext()) { - Object mapOderItem = var4.next(); - if (mapOderItem instanceof Map) { - ItemCollection itemCol = new ItemCollection((Map) mapOderItem); - - this.ibanList.add(itemCol); - - } - } - + /** + * Helper method to remove " and ' characters - causing problems + * + * @param val + * @return + */ + public static String jsonVal(String val) { + val = val.replace("\"", ""); + val = val.replace("'", ""); + return val; } } diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java new file mode 100644 index 0000000..dcd7234 --- /dev/null +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java @@ -0,0 +1,48 @@ +package com.alexanderlogistics; + +/** + * Diese Kleine Hilfsklasse dient als DTO für die Übertragugn eines + * Sucheregenisses nach kreditoren an das Frontend. Die Klasse besteht aus einem + * Key, einer DisplayZeile für die Darstellung und einen JSON String der + * beliebige Daten enthalten kann. + * + * @author rsoika + * + */ +public class BusinessPartnerSearchEntry { + + private String key; + private String display; + private String data; + + public BusinessPartnerSearchEntry(String key, String display, String data) { + super(); + this.key = key; + this.display = display; + this.data = data; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } +} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java new file mode 100644 index 0000000..9addc98 --- /dev/null +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Imixs Workflow + * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH, + * http://www.imixs.com + * + * 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 2 + * 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 can receive a copy of the GNU General Public + * License at http://www.gnu.org/licenses/gpl.html + * + * Project: + * http://www.imixs.org + * http://java.net/projects/imixs-workflow + * + * Contributors: + * Imixs Software Solutions GmbH - initial API and implementation + * Ralph Soika - Software Developer + *******************************************************************************/ + +package com.alexanderlogistics; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.logging.Logger; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.imixs.workflow.ItemCollection; +import org.imixs.workflow.ItemCollectionComparator; +import org.imixs.workflow.engine.DocumentService; +import org.imixs.workflow.engine.index.SchemaService; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.security.DeclareRoles; +import jakarta.annotation.security.RolesAllowed; +import jakarta.annotation.security.RunAs; +import jakarta.ejb.Singleton; +import jakarta.inject.Inject; + +/** + * Der BusinessPartnerService stellt Methoden für den Zugriff auf Business + * Partner bereit. + * + * @author rsoika + * + */ + +@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", + "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", + "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) +@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", + "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", + "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) +@Singleton +@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS") +public class BusinessPartnerService { + + public static final int MAX_SEARCH_RESULT = 100; + public static final String ITEM_IBAN_LIST = "partner.bank.list"; + public static final String WORKFLOW_SERVICE_ENDPOINT = "workflow.service.endpoint"; + public static final String WORKFLOW_SERVICE_USER = "workflow.service.user"; + public static final String WORKFLOW_SERVICE_PASSWORD = "workflow.service.password"; + + private static Logger logger = Logger.getLogger(BusinessPartnerService.class.getName()); + + @Inject + @ConfigProperty(name = WORKFLOW_SERVICE_ENDPOINT) + Optional workflowServiceEndpoint; + + @Inject + @ConfigProperty(name = WORKFLOW_SERVICE_USER) + Optional workflowServiceUser; + + @Inject + @ConfigProperty(name = WORKFLOW_SERVICE_PASSWORD) + Optional workflowServicePassword; + + @Inject + DocumentService documentService; + + @Inject + SchemaService schemaService; + + /** + * Initialize the rest clients + */ + @PostConstruct + public void init() { + + } + + /** + * Diese Methode sucht einen Business Partner anhand seiner BPID + * + * @param bpid + * - business partner id phrase + * @return - matching business partner + */ + public ItemCollection getBusinessPartnerByID(String bpid) { + if (bpid == null || bpid.isEmpty()) { + return null; + } + List result; + try { + String sQuery = "(type:\"workitem\" OR type:\"workitemarchive\" ) AND ($modelversion:businesspartner-*)"; + sQuery += " AND (name:" + bpid.trim() + ")"; + logger.finest("SearchQuery= " + sQuery); + result = documentService.find(sQuery, 1, 0); + if (result.size() > 0) { + return result.get(0); + } + } catch (Exception e) { + logger.warning(" lucene error - " + e.getMessage()); + } + return null; + } + + /** + * Diese Methode sucht Business Partner anhand einer Suchphrase + * + * @param phrase + * - search phrase + * @return - list of matching business partners + */ + public List search(String phrase) { + + List searchResult = new ArrayList(); + if (phrase == null || phrase.isEmpty()) { + return searchResult; + } + + try { + phrase = phrase.trim(); + // phrase = LuceneSearchService.escapeSearchTerm(phrase); + phrase = schemaService.normalizeSearchTerm(phrase); + String sQuery = "(type:\"workitem\" OR type:\"workitemarchive\") AND ($modelversion:businesspartner-*)"; + sQuery += " AND (" + phrase + "*)"; + + logger.finest("SearchQuery= " + sQuery); + + searchResult = documentService.find(sQuery, MAX_SEARCH_RESULT, 0); + } catch (Exception e) { + logger.warning(" lucene error - " + e.getMessage()); + } + + // sort by txtname.. + Collections.sort(searchResult, new ItemCollectionComparator("$workflowsummary", true)); + return searchResult; + } + + /** + * Packt die Liste der Bank Details (ItemCollections) in ein Workitem + * + * @param workitem + */ + public static void implodeBanks(ItemCollection workitem, List ibanList) { + List mapOrderItems = new ArrayList(); + if (ibanList != null) { + logger.fine("Convert child items into Map..."); + Iterator var3 = ibanList.iterator(); + + while (var3.hasNext()) { + ItemCollection orderItem = (ItemCollection) var3.next(); + mapOrderItems.add(orderItem.getAllItems()); + } + + workitem.replaceItemValue(BusinessPartnerService.ITEM_IBAN_LIST, mapOrderItems); + } + + } + + /** + * Enpackt die iban Map Liste von eiem Worktiem in eine Liste von ItemCollection + * + * @param workitem + */ + public static List explodeBanks(ItemCollection workitem) { + List ibanList = new ArrayList(); + List mapOrderItems = workitem.getItemValue(BusinessPartnerService.ITEM_IBAN_LIST); + Iterator var4 = mapOrderItems.iterator(); + while (var4.hasNext()) { + Object mapOderItem = var4.next(); + if (mapOderItem instanceof Map) { + ItemCollection itemCol = new ItemCollection((Map) mapOderItem); + + ibanList.add(itemCol); + + } + } + return ibanList; + } + + /** + * Liefert die ChildItems mit den IBAN daten + * + * @param workitem + * @return + */ + public static List getBanks(ItemCollection workitem) { + List result = new ArrayList<>(); + List mapOrderItems = workitem.getItemValue(BusinessPartnerService.ITEM_IBAN_LIST); + Iterator var4 = mapOrderItems.iterator(); + while (var4.hasNext()) { + Object mapOderItem = var4.next(); + if (mapOderItem instanceof Map) { + ItemCollection itemCol = new ItemCollection((Map) mapOderItem); + result.add(itemCol); + } + } + return result; + } + +} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java index b6bc313..24cdc3e 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java @@ -8,9 +8,6 @@ import java.util.Map; import java.util.regex.Pattern; import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.exceptions.PluginException; - -import com.alexanderlogistics.metrics.MetricDataService; /** * Hilfsmethoden für die Berechnung und Validierung von Ein und @@ -185,30 +182,6 @@ public class InvoiceUtil { } - /** - * Diese Hilfsmethode berechnet die BusinessPartnerID aus einer Invoice - * - * @param Invoice - * @return - * @throws PluginException - */ - public static String getBPId(ItemCollection invoice) throws PluginException { - String key = ""; - if (isCreditorInvoice(invoice)) { - // key ist cdtr.number - key = invoice.getItemValueString("cdtr.number"); - } else { - // key ist dbtr.number - key = invoice.getItemValueString("dbtr.number"); - } - if (key.isEmpty()) { - throw new PluginException(MetricDataService.class.getName(), ERROR_INVALID_INVOICEDATA, - "Failed to create metrics - missing dbtr/cdtr number!"); - } - - return InvoiceUtil.buildBPID(key); - } - /** * Diese Hilfmethode berechnet die BusinessPartner Namen aus einer Invoice * diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java index 4a20ba9..5de1489 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java @@ -63,11 +63,15 @@ import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import com.alexanderlogistics.BusinessPartnerService; import com.alexanderlogistics.InvoiceUtil; +import com.alexanderlogistics.KreditorDebitorService; import com.alexanderlogistics.mahnlauf.MahnlaufService; import com.alexanderlogistics.xml.CargosoftXMLInvoiceImportService; import jakarta.ejb.Stateless; +import jakarta.ejb.TransactionAttribute; +import jakarta.ejb.TransactionAttributeType; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -112,6 +116,9 @@ public class CargosoftMigrationRestService implements Serializable { @Inject TeamService teamService; + @Inject + BusinessPartnerService businessPartnerService; + private static Logger logger = Logger.getLogger(CargosoftMigrationRestService.class.getName()); public CargosoftMigrationRestService() { @@ -641,6 +648,98 @@ public class CargosoftMigrationRestService implements Serializable { } } + /** + * Dieser agent prüft ob es für Cargosoft Krediotren/Debitoren Daten schon ein + * passendes Businesspartner Workitem gibt. + * Wenn nicht speichert der Service einmal das cargosft entity was dann zur + * automatischen Neuanlage des businesspartner workflows führt. + * + * @return + * @throws QueryException + * @throws AccessDeniedException + * @throws ProcessingErrorException + * @throws PluginException + * @throws ModelException + */ + @GET + @Path("/bp-import") + @Produces({ MediaType.TEXT_PLAIN }) + public String importBusinessPartner() + throws QueryException, AccessDeniedException, ProcessingErrorException, PluginException, ModelException { + StringBuffer messageBuffer = new StringBuffer(); + int MAX_COUNT = 1000; + String query = "(type:" + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + ")"; + int updates = 0; + long l = System.currentTimeMillis(); + int batchSize = 500; + int totalObjects = 0; + log("├── Migrate " + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR, messageBuffer); + + // Gesamtanzahl ermitteln + int totalCount = documentService.count(query); + log("│   ├── found " + totalCount + " " + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + " entities ", + messageBuffer); + + // Berechne Anzahl der benötigten Pages + int totalPages = (int) Math.ceil((double) totalCount / batchSize); + + // Verarbeite Page für Page + for (int pageIndex = 0; pageIndex < totalPages; pageIndex++) { + + List cargosoftDataList = documentService.find(query, batchSize, pageIndex); + + for (ItemCollection cargosoftItemCol : cargosoftDataList) { + totalObjects++; + if (verifyBusinessPartner(cargosoftItemCol, messageBuffer)) { + updates++; + } + if (updates >= MAX_COUNT) + break; + } + + // Fortschritt loggen + log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + + " (" + updates + " total updates)", messageBuffer); + // Optional: Kurze Pause nach jedem 5. Batch + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if (updates >= MAX_COUNT) + break; + + } + long duration = System.currentTimeMillis() - l; + double objectsPerSecond = totalObjects / (duration / 1000.0); + log("├── Successfully imported " + updates + " business partner objects in " + + duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer); + + return messageBuffer.toString(); + } + + /** + * Hilfsmethode speichert eine cargoosft kreditor object... + * + * @param bpID + * @param messageBuffer + * @return + */ + @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) + public boolean verifyBusinessPartner(ItemCollection cargosoftItemCol, StringBuffer messageBuffer) { + String vendorNummer = cargosoftItemCol.getItemValueString("_vendor_num"); + String bpID = InvoiceUtil.buildBPID(vendorNummer); + ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpID); + if (businessPartner == null) { + documentService.save(cargosoftItemCol); + logger.finest("│   │   ├── import " + bpID); + return true; + } + return false; + } + /** * Erzeugt einen XML Baum aus dem XML Raw Daten * @@ -721,4 +820,10 @@ public class CargosoftMigrationRestService implements Serializable { } } + + private void log(String message, StringBuffer messageLog) { + logger.info(message); + messageLog.append(message + "\n"); + + } } diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricCreditorRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricCreditorRestService.java deleted file mode 100644 index 773252a..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricCreditorRestService.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.alexanderlogistics.metrics; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.engine.DocumentService; -import org.imixs.workflow.exceptions.PluginException; -import org.imixs.workflow.exceptions.QueryException; - -import com.alexanderlogistics.InvoiceUtil; - -import jakarta.ejb.Stateless; -import jakarta.inject.Inject; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; - -@Path("metrics/cdtr") -@Stateless -public class MetricCreditorRestService { - - private static Logger logger = Logger.getLogger(MetricCreditorRestService.class.getName()); - - @Inject - DocumentService documentService; - - @Inject - MetricCreditorService metricCreditorService; - - @Inject - MetricDataService metricDataService; - - @GET - @Path("/ping") - @Produces({ MediaType.TEXT_PLAIN }) - public String ping() { - logger.info("GET ping"); - return "ping: " + System.currentTimeMillis(); - } - - /** - * This method initializes the metrics for all creditors with open invoices. - * - * The method deletes all existing metrics and creates new metric entires for - * each creditor. - * - * @return - */ - @GET - @Path("/rebuild") - @Produces({ MediaType.TEXT_PLAIN }) - public Response rebuildMetrics() { - StringBuffer messageBuffer = new StringBuffer(); - long l = System.currentTimeMillis(); - log("├── init cdtr metrics...", messageBuffer); - try { - // first clear the metric cache - metricCreditorService.reset(); - log("│   ├── reset metric cache", messageBuffer); - // run in new transaction! - metricDataService.deleteAllMetrics(MetricCreditorService.TYPE_METRIC_CREDITOR); - log("│   ├── delete metrics", messageBuffer); - - computeMetrics(); - log("│   ├── computing metrics finished in " + (System.currentTimeMillis() - l) + "ms", messageBuffer); - - logger.info("│   ├── save and init metrics..."); - // run in new transaction! - metricCreditorService.refreshGauges(); - - String message = "├── rebuild cdtr metrics completed in " - + (System.currentTimeMillis() - l) - + "ms"; - log(message, messageBuffer); - return Response.ok().entity(messageBuffer.toString()).build(); - - } catch (Exception e) { - e.printStackTrace(); - return Response.serverError() - .entity("Failed to initialize metrics: " + e.getMessage()) - .build(); - } - } - - /** - * This method initializes the metrics for all creditors with open invoices. - * - * The method deletes all existing metrics and creates new metric entires for - * each creditor. - * - * @return - */ - @GET - @Path("/rebuild/{cdtrnumber}") - @Produces({ MediaType.TEXT_PLAIN }) - public Response rebuildMetricsForCreditor(@PathParam("cdtrnumber") String cdtrnumber) { - StringBuffer messageBuffer = new StringBuffer(); - long l = System.currentTimeMillis(); - log("├── init cdtr metrics for " + cdtrnumber + "...", messageBuffer); - try { - - logger.info("│   │   ├── group invoices by creditor " + cdtrnumber + "..."); - - int count = 0; - - // First we need to remove all metrics for this creditor - String bpID = InvoiceUtil.buildBPID(cdtrnumber); - logger.info("│   │   ├── delete metrics for " + bpID + "..."); - List oldMetricKeys = metricDataService - .deleteAllMetricsByBPID(MetricCreditorService.TYPE_METRIC_CREDITOR, bpID); - logger.info("│   │   ├── found " + oldMetricKeys.size() + " metrics for " + bpID + "..."); - metricCreditorService.reset(oldMetricKeys); - // next rebuild gauges and metrics for this creditor - List invoices = documentService.find( - "($modelversion:rechnungseingang-* OR $modelversion:gutschriftabgleich-*) " + - " AND type:workitem AND cdtr.number:" + cdtrnumber, - 9999, 0, "invoice.number", false); - logger.info("│   │   ├──found " + invoices.size() + " open invoices"); - - List newMetricKeys = new ArrayList<>(); - for (ItemCollection invoice : invoices) { - try { - ItemCollection metricData = metricCreditorService.getMetricByInvoice(invoice); - newMetricKeys.add(metricData.getItemValueString("name")); - // Jetzt Rechnung addieren - metricCreditorService.addInvoice(metricData, invoice); - logger.info("│   │   │   ├──update metric " + InvoiceUtil.getBPId(invoice) + " Invoice: " - + invoice.getItemValueString("invoice.number") + " Saldo: " - + invoice.getItemValueDouble(MetricCreditorService.ITEM_TOTAL)); - - metricCreditorService.putMetric(metricData); - count++; - } catch (PluginException e) { - // invalid invoice - e.g. no cdtr. number - } - } - - logger.info("│   │   ├── updated metric for " + count + " invoices."); - - log("│   ├── computing metrics finished in " + (System.currentTimeMillis() - l) + "ms", messageBuffer); - - logger.info("│   ├── save and init metrics..."); - // run in new transaction! - metricCreditorService.refreshGauges(newMetricKeys); - - String message = "├── rebuild cdtr metrics completed in " - + (System.currentTimeMillis() - l) - + "ms"; - log(message, messageBuffer); - return Response.ok().entity(messageBuffer.toString()).build(); - - } catch (Exception e) { - e.printStackTrace(); - return Response.serverError() - .entity("Failed to initialize metrics: " + e.getMessage()) - .build(); - } - } - - /** - * Diese Methode berechnet alle Metriken auf basis der existierenden Rechnungen - * neu - * - */ - public void computeMetrics() { - - logger.info("│   │   ├── group invoices by creditor..."); - try { - int count = 0; - List invoices = documentService.find( - "($modelversion:rechnungseingang-* OR $modelversion:gutschriftabgleich-*) " + - " AND type:workitem", - 9999, 0, - "invoice.number", false); - logger.info("│   │   ├──found " + invoices.size() + " open invoices"); - for (ItemCollection invoice : invoices) { - try { - ItemCollection metricData = metricCreditorService.getMetricByInvoice(invoice); - // Jetzt Rechnung addieren - metricCreditorService.addInvoice(metricData, invoice); - logger.info("│   │   │   ├──update metric " + InvoiceUtil.getBPId(invoice)); - metricCreditorService.putMetric(metricData); - count++; - } catch (PluginException e) { - // invalid invoice - e.g. no cdtr. number - } - - } - logger.info("│   │   ├── updated metric for " + count + " invoices."); - } catch (QueryException e) { - e.printStackTrace(); - } - } - - private void log(String message, StringBuffer messageLog) { - logger.info(message); - messageLog.append(message + "\n"); - - } - -} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricCreditorService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricCreditorService.java deleted file mode 100644 index 1905456..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricCreditorService.java +++ /dev/null @@ -1,369 +0,0 @@ -package com.alexanderlogistics.metrics; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; - -import org.eclipse.microprofile.config.inject.ConfigProperty; -import org.eclipse.microprofile.metrics.Metadata; -import org.eclipse.microprofile.metrics.MetricRegistry; -import org.eclipse.microprofile.metrics.Tag; -import org.eclipse.microprofile.metrics.annotation.RegistryScope; -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.engine.DocumentService; -import org.imixs.workflow.engine.ProcessingEvent; -import org.imixs.workflow.exceptions.PluginException; -import org.imixs.workflow.exceptions.QueryException; - -import com.alexanderlogistics.InvoiceUtil; -import com.alexanderlogistics.KreditorDebitorService; - -import jakarta.annotation.security.DeclareRoles; -import jakarta.annotation.security.RolesAllowed; -import jakarta.annotation.security.RunAs; -import jakarta.ejb.TransactionAttribute; -import jakarta.ejb.TransactionAttributeType; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; - -/** - * Dieser Service reagiert auch ProcessingEvents und speichert/aktualisiert die - * zugehörige Creditor Metric Entity (type=metric.creditor). - *

- * Beim Rechnungseingang gilt eine Rechnung als Bezahlt wenn diese einen finalen - * Status erreicht hat (>=5800) - *

- * Der Service liest in einem AFTER_PROCESS Event den alten invoice.saldo aus. - * Hierzu wird die Rechnung in einer neuen Transaktion geladen was einem - * 'Dirty-Read' entspricht. Dadurch kennt die Methode den letzten saldo der - * Rechnung. Hat sich nun der aktuelle Saldo geändert, aktualisiert der Serivce - * die entsprechende Metric. - * - * - */ -@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", - "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", - "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) -@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", - "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", - "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) -@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS") -@ApplicationScoped -public class MetricCreditorService { - - private static Logger logger = Logger.getLogger(MetricCreditorService.class.getName()); - private final ConcurrentHashMap metricCache = new ConcurrentHashMap<>(); - private final Set registeredGauges = ConcurrentHashMap.newKeySet(); - - public static final String TYPE_METRIC_CREDITOR = "metric.creditor"; - public static final String ITEM_TOTAL = "invoice.total"; - public static final String ITEM_SALDO = "invoice.saldo"; - - @Inject - @RegistryScope(scope = MetricRegistry.APPLICATION_SCOPE) - MetricRegistry metricRegistry; - - @Inject - DocumentService documentService; - - @Inject - KreditorDebitorService kreditorDebitorService; - - @Inject - MetricDataService metricDataService; - - @Inject - @ConfigProperty(name = "metrics.enabled", defaultValue = "false") - private boolean metricsEnabled; - - /** - * Reset the internal metricCache and clears all registered Gauges. - */ - public void reset() { - metricCache.clear(); - registeredGauges.clear(); - } - - /** - * Reset the internal metricCache and clears all registered Gauges for a list of - * metric keys. - */ - public void reset(List metricKeys) { - for (String metricKey : metricKeys) { - metricCache.remove(metricKey); - metricRegistry.remove(metricKey); - } - } - - /** - * Process Metric only if some data has changed.... - * - * @param processingEvent - * @throws PluginException - */ - public void onProcessingEvent(@Observes ProcessingEvent processingEvent) { - long l = System.currentTimeMillis(); - if (!metricsEnabled) { - return; - } - - ItemCollection invoice = processingEvent.getDocument(); - if (!InvoiceUtil.isCreditorInvoice(invoice)) { - // skip event - return; - } - - // update metric and the metric cache - if (processingEvent.getEventType() == ProcessingEvent.AFTER_PROCESS) { - // load the last invoice metric and reduce the saldo... - ItemCollection lastInvoice = metricDataService.readDirtyWorkitem(invoice.getUniqueID()); - if (lastInvoice != null) { - try { - ItemCollection lastMetricData = getMetricByInvoice(lastInvoice); - subtractInvoice(lastMetricData, lastInvoice); - putMetric(lastMetricData); - metricDataService.saveMetric(lastMetricData); - } catch (PluginException e) { - // invalid invoice - e.g. no cdtr. number - } - } - - try { - // load the invoice metric and add the saldo... - ItemCollection metricData = getMetricByInvoice(invoice); - // Saldo-Berechnung - addInvoice(metricData, invoice); - putMetric(metricData); - metricDataService.saveMetric(metricData); - - // Update the Gauge - updateGauge(metricData); - logger.info("Metric cdtr update took " + (System.currentTimeMillis() - l) + "ms"); - } catch (PluginException e) { - // invalid invoice - e.g. no cdtr. number - } - } - - } - - /** - * Returns the corresponding metric data object for an invoice. The method uses - * an internal cache. If the metric was not yet cached the method loads the - * metric from the database. If not metric exists in the database the method - * automatically creates a new metric data object. - * - * The method throws a PluginException if no metric can be build from this - * invoice (e.g. missing cdtr.number). - * - * @param invoice - * @return - * @throws PluginException - */ - public ItemCollection getMetricByInvoice(ItemCollection invoice) throws PluginException { - if (invoice == null) { - return null; - } - String metricKey = MetricDataService.buildKeyByInvoice(invoice); - ItemCollection metricData = metricCache.get(metricKey); - if (metricData == null) { - metricData = loadMetric(invoice); - } - // if metric still null we create a new metric data object. - if (metricData == null) { - metricData = createMetaData(invoice); - } - return metricData; - } - - /** - * Returns a metric data object by key - * - * @param key - * @return - */ - public ItemCollection getMetric(String key) { - return metricCache.get(key); - } - - /** - * Puts a metric data object into the cache. - * - * @param metricData - */ - public void putMetric(ItemCollection metricData) { - metricCache.put(metricData.getItemValueString("name"), metricData); - } - - /** - * Returns a list with all cached metric keys. - * The method returns an unmodifiable list to prevent modifications. - * - * @return - */ - public List getMetricKeys() { - return Collections.unmodifiableList(new ArrayList<>(metricCache.keySet())); - } - - /** - * This method loads a metric entity for a given invoice workitem. If no metric - * entity exits, the method - * creates a new metric entity. - * - * @param invoice - * @return - * @throws PluginException - */ - private ItemCollection loadMetric(ItemCollection invoice) throws PluginException { - ItemCollection creditorMetric = null; - if (invoice == null) { - return null; - } - try { - String metricKey = MetricDataService.buildKeyByInvoice(invoice); - String query = "(type:" + TYPE_METRIC_CREDITOR + ") AND (name:" + metricKey + ")"; - List result = documentService.find(query, 1, 0, "$modified", true); - if (result.size() > 0) { - creditorMetric = result.get(0); - } - } catch (IllegalArgumentException | QueryException e) { - throw new PluginException(PluginException.class.getName(), - "Failed to load metric object for invoice " + invoice.getUniqueID() + ": ", e.getMessage(), e); - } - return creditorMetric; - } - - /** - * Creates an empty Creditor Meta Data Object (ItemCollection) - *

- * The ItemCollection stores the name and number and also all saldos for all - * currencies - * - * @param invoice - invoice ItemCollection - * @return - * @throws PluginException - */ - private ItemCollection createMetaData(ItemCollection invoice) throws PluginException { - if (invoice == null) { - return null; - } - String key = MetricDataService.buildKeyByInvoice(invoice); - ItemCollection metricData = new ItemCollection(); - metricData.setType(TYPE_METRIC_CREDITOR); - metricData.setItemValue("name", key); - metricData.setItemValue("bp.id", InvoiceUtil.getBPId(invoice)); - metricData.setItemValue("bp.name", InvoiceUtil.getBPName(invoice)); - metricData.setItemValue("country", invoice.getItemValueString("invoice.country")); - metricData.setItemValue("currency", invoice.getItemValueString("invoice.currency")); - metricData.setItemValue("department", invoice.getItemValueString("space.name")); - - return metricData; - } - - /** - * Helper method to register a gauge for a creditor - * - * @param cdtrNumber - the creditor number - * @param cdtrName - the creditor name - */ - public void updateGauge(ItemCollection metricData) { - - String metricKey = metricData.getItemValueString("name"); - String bpName = metricData.getItemValueString("bp.name"); - String bpId = metricData.getItemValueString("bp.id"); - String country = metricData.getItemValueString("country"); - String department = metricData.getItemValueString("department"); - String currency = metricData.getItemValueString("currency"); - - // Prüfen ob Gauge bereits registriert ist - if (registeredGauges.add(metricKey)) { // returns true newly added - List tags = new ArrayList<>(); - tags.add(new Tag("type", "cdtr")); - tags.add(new Tag("id", bpId)); - tags.add(new Tag("name", bpName)); - tags.add(new Tag("country", country)); - tags.add(new Tag("currency", currency)); - tags.add(new Tag("department", department)); - logger.fine("register new metric for department: " + department + - ", " + metricData.getItemValueString(ITEM_SALDO) + - " " + currency); - Metadata metadata = Metadata.builder() - .withName("cdtr.balance") - .withDescription("Creditor Balance") - .build(); - - metricCache.get(metricKey); - metricRegistry.gauge(metadata, - () -> metricCache.get(metricKey).getItemValueDouble(ITEM_SALDO), - tags.toArray(new Tag[0])); - } else { - logger.fine("Cdtr Gauge already registered for department: " + department); - } - - } - - /** - * Addiert den saldo einer Invoice zu einem metricData object - * - * @param metricData - * @param invoice - */ - public void addInvoice(ItemCollection metricData, ItemCollection invoice) { - double invoiceTotal = invoice.getItemValueDouble(ITEM_TOTAL); - if (!"workitem".equals(invoice.getType()) || invoice.getTaskID() >= 5800) { - // vorgang ist archiviert oder gelöscht worden => saldo = 0! - invoiceTotal = 0.0; - } - // is the metric new? - if (!metricData.hasItem(ITEM_SALDO)) { - // init metric with the total value! - metricData.setItemValue(ITEM_SALDO, InvoiceUtil.round(invoiceTotal)); - } else { - double lastSaldo = metricData.getItemValueDouble(ITEM_SALDO); - metricData.setItemValue(ITEM_SALDO, InvoiceUtil.round(lastSaldo + invoiceTotal)); - } - } - - public void subtractInvoice(ItemCollection metricData, ItemCollection invoice) { - if (metricData == null || invoice == null) { - return; - } - double invoiceTotal = invoice.getItemValueDouble(ITEM_TOTAL); - if (!"workitem".equals(invoice.getType()) || invoice.getTaskID() >= 5800) { - // vorgang ist archiviert oder gelöscht worden => saldo = 0! - invoiceTotal = 0.0; - } - // subtract only if metric saldo exists - if (metricData.hasItem(ITEM_SALDO)) { - double lastSaldo = metricData.getItemValueDouble(ITEM_SALDO); - metricData.setItemValue(ITEM_SALDO, InvoiceUtil.round(lastSaldo - invoiceTotal)); - } - } - - /** - * Helper Method that refreshes all gauges. The method is called by the - * RestService during a rebuild. - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public void refreshGauges() { - List keys = getMetricKeys(); - refreshGauges(keys); - } - - /** - * Helper Method that refreshes all gauges. The method is called by the - * RestService during a rebuild. - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public void refreshGauges(List keys) { - for (String hashKey : keys) { - ItemCollection metricData = getMetric(hashKey); - documentService.save(metricData); - updateGauge(metricData); - } - } - -} \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDataService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDataService.java deleted file mode 100644 index aa0b03e..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDataService.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.alexanderlogistics.metrics; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.engine.DocumentService; -import org.imixs.workflow.engine.index.SearchService; -import org.imixs.workflow.exceptions.PluginException; -import org.imixs.workflow.exceptions.QueryException; - -import com.alexanderlogistics.InvoiceUtil; - -import jakarta.annotation.security.DeclareRoles; -import jakarta.annotation.security.RunAs; -import jakarta.ejb.Stateless; -import jakarta.ejb.TransactionAttribute; -import jakarta.ejb.TransactionAttributeType; -import jakarta.inject.Inject; - -/** - * The MetricDataService provides methods to lookup and update metric data - * objects. - * The service runs with manager access. - * - * - */ -@DeclareRoles({ "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) -@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS") -@Stateless -public class MetricDataService { - - @Inject - DocumentService documentService; - - /** - * Runs with Manager access - * - * @param metricData - */ - public void saveMetric(ItemCollection metricData) { - documentService.save(metricData); - } - - /** - * This helper method reads a 'dirty' workitem in a new transaction. This is - * used for calculating the new metric values - * - * @param uniqueId - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public ItemCollection readDirtyWorkitem(String uniqueId) { - ItemCollection dirtyInvoice = documentService.load(uniqueId); - return dirtyInvoice; - } - - /** - * This method deletes all metrics - * - * @throws PluginException - * - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public void deleteAllMetrics(String metricType) throws PluginException { - try { - String query = "(type:" + metricType + ")"; - List result = documentService.find(query, SearchService.DEFAULT_MAX_SEARCH_RESULT, 0); - for (ItemCollection metric : result) { - documentService.remove(metric); - } - - } catch (IllegalArgumentException | QueryException e) { - throw new PluginException(MetricDataService.class.getName(), - "Failed to delete metrics", e.getMessage(), e); - } - } - - /** - * This method deletes all metrics for a given BP ID - * - * @throws PluginException - * - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public List deleteAllMetricsByBPID(String metricType, String bpID) throws PluginException { - List result = new ArrayList<>(); - try { - String query = "(type:" + metricType + ")"; - List metricList = documentService.find(query, SearchService.DEFAULT_MAX_SEARCH_RESULT, 0); - for (ItemCollection metric : metricList) { - if (metric.getItemValueString("bp.id").equals(bpID)) { - result.add(metric.getItemValueString("name")); - documentService.remove(metric); - } - } - - } catch (IllegalArgumentException | QueryException e) { - throw new PluginException(MetricDataService.class.getName(), - "Failed to delete metrics", e.getMessage(), e); - } - return result; - } - - /** - * Builds the metric hash key by the invoice attributes. The returned key can be - * used for caching the metric. - * - * The metric key does not include the dbtr/cdtr name as this name is not - * relevant for building a hashkey. - * - * @param invoice - The invoice ItemCollection containing the necessary - * attributes - * @return A unique hash string based on the invoice attributes - * @throws PluginException - * @throws IllegalArgumentException if the invoice is null - */ - public static String buildKeyByInvoice(ItemCollection invoice) throws PluginException { - // Validate input - Objects.requireNonNull(invoice, "Invoice must not be null"); - - String bpNumber = InvoiceUtil.getBPId(invoice); - String country = invoice.getItemValueString("invoice.country"); - String currency = invoice.getItemValueString("invoice.currency"); - String department = invoice.getItemValueString("space.name"); - - // Concatenate the values and create a hash - String combinedValue = String.format("%s::%s::%s::%s", - bpNumber, - country, - currency, - department); - - String hash = String.valueOf(combinedValue.hashCode()); - // a hash can start with '-' which we need to avoid and create a alphanumeric - // key instead! - return "HASH" + hash; - } - -} \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorRestService.java deleted file mode 100644 index 34c9c35..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorRestService.java +++ /dev/null @@ -1,221 +0,0 @@ -package com.alexanderlogistics.metrics; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.engine.DocumentService; -import org.imixs.workflow.exceptions.PluginException; -import org.imixs.workflow.exceptions.QueryException; - -import com.alexanderlogistics.InvoiceUtil; - -import jakarta.ejb.Stateless; -import jakarta.inject.Inject; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; - -@Path("metrics/dbtr") -@Stateless -public class MetricDebitorRestService { - - private static Logger logger = Logger.getLogger(MetricDebitorRestService.class.getName()); - - @Inject - DocumentService documentService; - - @Inject - MetricDebitorService metricDebitorService; - - @Inject - MetricDataService metricDataService; - - @GET - @Path("/ping") - @Produces({ MediaType.TEXT_PLAIN }) - public String ping() { - logger.info("GET ping"); - return "ping: " + System.currentTimeMillis(); - } - - /** - * This method initializes the metrics for all debitors with open invoices. - * - * The method first deletes all existing metrics and than creates or updates the - * metric entires for each debitor. - * - * @return - */ - @GET - @Path("/rebuild") - @Produces({ MediaType.TEXT_PLAIN }) - public Response rebuildMetrics() { - // Map metricCache = new HashMap(); - long l = System.currentTimeMillis(); - logger.info("├── init dbtr metrics..."); - - try { - // first clear the metric cache - metricDebitorService.reset(); - logger.info("│   ├── reset metric cache"); - // run in new transaction! - metricDataService.deleteAllMetrics(MetricDebitorService.TYPE_METRIC_DEBITOR); - logger.info("│   ├── delete metrics"); - - computeMetrics(); - logger.info("│   ├── computing metrics finished in " + (System.currentTimeMillis() - l) + "ms"); - - logger.info("│   ├── save and init metrics ..."); - // run in new transaction! - metricDebitorService.refreshGauges(); - - String message = "├── rebuild dbtr metrics completed in " - + (System.currentTimeMillis() - l) - + "ms"; - logger.info(message); - return Response.ok().entity(message).build(); - - } catch (Exception e) { - e.printStackTrace(); - return Response.serverError() - .entity("Failed to initialize metrics: " + e.getMessage()) - .build(); - } - } - - /** - * This method initializes the metrics for all creditors with open invoices. - * - * The method deletes all existing metrics and creates new metric entires for - * each creditor. - * - * @return - */ - @GET - @Path("/rebuild/{dbtrnumber}") - @Produces({ MediaType.TEXT_PLAIN }) - public Response rebuildMetricsForDebitor(@PathParam("dbtrnumber") String dbtrnumber) { - StringBuffer messageBuffer = new StringBuffer(); - long l = System.currentTimeMillis(); - log("├── init dbtr metrics for " + dbtrnumber + "...", messageBuffer); - try { - - logger.info("│   │   ├── group invoices by creditor " + dbtrnumber + "..."); - - int count = 0; - - // First we need to remove all metrics for this creditor - String bpID = InvoiceUtil.buildBPID(dbtrnumber); - logger.info("│   │   ├── delete metrics for " + bpID + "..."); - List oldMetricKeys = metricDataService - .deleteAllMetricsByBPID(MetricDebitorService.TYPE_METRIC_DEBITOR, bpID); - logger.info("│   │   ├── found " + oldMetricKeys.size() + " metrics for " + bpID + "..."); - metricDebitorService.reset(oldMetricKeys); - // next rebuild gauges and metrics for this creditor - String queryDbtrNumber = dbtrnumber; - if (queryDbtrNumber.startsWith("D")) { - queryDbtrNumber = queryDbtrNumber.substring(1); // DAS IST DER CARGOSOFT IRRSINN - } - String query = "$modelversion:rechnungsausgang-* AND type:workitem " + - " AND type:workitem AND dbtr.number:" + queryDbtrNumber; - logger.fine("Query = " + query); - List invoices = documentService.find( - query, - 9999, 0, "invoice.number", false); - logger.info("│   │   ├──found " + invoices.size() + " open invoices"); - - List newMetricKeys = new ArrayList<>(); - for (ItemCollection invoice : invoices) { - try { - ItemCollection metricData = metricDebitorService.getMetricByInvoice(invoice); - String metricKey = metricData.getItemValueString("name"); - newMetricKeys.add(metricKey); - // Jetzt Rechnung addieren - logger.info("│   │   │   ├──update metric (" + metricKey + ")" + InvoiceUtil.getBPId(invoice) - + " Invoice: " - + invoice.getItemValueString("invoice.number") + " Saldo: " - + invoice.getItemValueDouble(MetricDebitorService.ITEM_SALDO)); - logger.info("│   │   │   │   ├── last metric saldo: " - + metricData.getItemValueDouble(MetricDebitorService.ITEM_SALDO)); - metricDebitorService.addInvoice(metricData, invoice); - logger.info("│   │   │   │   ├── new metric saldo: " - + metricData.getItemValueDouble(MetricDebitorService.ITEM_SALDO)); - metricDebitorService.putMetric(metricData); - count++; - } catch (PluginException e) { - // invalid invoice - e.g. no dbtr. number - } - } - - logger.info("│   │   ├── updated metric for " + count + " invoices."); - - log("│   ├── computing metrics finished in " + (System.currentTimeMillis() - l) + "ms", messageBuffer); - - logger.info("│   ├── save and init metrics..."); - // run in new transaction! - metricDebitorService.refreshGauges(newMetricKeys); - - String message = "├── rebuild dbtr metrics completed in " - + (System.currentTimeMillis() - l) - + "ms"; - log(message, messageBuffer); - return Response.ok().entity(messageBuffer.toString()).build(); - - } catch (Exception e) { - e.printStackTrace(); - return Response.serverError() - .entity("Failed to initialize metrics: " + e.getMessage()) - .build(); - } - } - - /** - * Diese Methode berechnet alle Metriken auf basis der existierenden Rechnungen - * neu - * - */ - public void computeMetrics() { - - logger.info("│   │   ├── group invoices by debitor..."); - try { - int count = 0; - List invoices = documentService.find( - "$modelversion:rechnungsausgang-* AND type:workitem", - 9999, 0, - "invoice.number", false); - - logger.info("│   │   ├── found " + invoices.size() + " open invoices"); - for (ItemCollection invoice : invoices) { - try { - - ItemCollection metricData = metricDebitorService.getMetricByInvoice(invoice); - - // Jetzt Rechnung addieren - metricDebitorService.addInvoice(metricData, invoice); - logger.info("│   │   │   ├──update metric " + InvoiceUtil.getBPId(invoice)); - metricDebitorService.putMetric(metricData); - count++; - } catch (PluginException e) { - // invalid invoice - e.g. no dbtr. number - } - - } - logger.info("│   │   ├── updated metric for " + count + " invoices."); - } catch (QueryException e) { - e.printStackTrace(); - } - - } - - private void log(String message, StringBuffer messageLog) { - logger.info(message); - messageLog.append(message + "\n"); - - } -} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorService.java deleted file mode 100644 index f2af247..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorService.java +++ /dev/null @@ -1,367 +0,0 @@ -package com.alexanderlogistics.metrics; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; - -import org.eclipse.microprofile.config.inject.ConfigProperty; -import org.eclipse.microprofile.metrics.Metadata; -import org.eclipse.microprofile.metrics.MetricRegistry; -import org.eclipse.microprofile.metrics.Tag; -import org.eclipse.microprofile.metrics.annotation.RegistryScope; -import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.engine.DocumentService; -import org.imixs.workflow.engine.ProcessingEvent; -import org.imixs.workflow.exceptions.PluginException; -import org.imixs.workflow.exceptions.QueryException; - -import com.alexanderlogistics.InvoiceUtil; - -import jakarta.annotation.security.DeclareRoles; -import jakarta.annotation.security.RolesAllowed; -import jakarta.annotation.security.RunAs; -import jakarta.ejb.TransactionAttribute; -import jakarta.ejb.TransactionAttributeType; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; - -/** - * Dieser Service reagiert auch ProcessingEvents und speichert/aktualisiert die - * zugehörige Debitoren Metric Entity (type=metric.debitor). - *

- * Der Service liest in einem AFTER_PROCESS Event den alten invoice.saldo aus. - * Hierzu wird die Rechnung in einer neuen Transaktion geladen was einem - * 'Dirty-Read' entspricht. Dadurch kennt die Methode den letzten saldo der - * Rechnung. Hat sich nun der aktuelle Saldo geändert, aktualisiert der Serivce - * die entsprechende Metric. - * - * - */ -@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", - "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", - "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) -@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", - "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", - "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) -@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS") -@ApplicationScoped -public class MetricDebitorService { - - private static Logger logger = Logger.getLogger(MetricDebitorService.class.getName()); - private final ConcurrentHashMap metricCache = new ConcurrentHashMap<>(); - private final Set registeredGauges = ConcurrentHashMap.newKeySet(); - - public static final String TYPE_METRIC_DEBITOR = "metric.debitor"; - public static final String ITEM_SALDO = "invoice.saldo"; - - @Inject - @RegistryScope(scope = MetricRegistry.APPLICATION_SCOPE) - MetricRegistry metricRegistry; - - @Inject - DocumentService documentService; - - @Inject - MetricDataService metricDataService; - - @Inject - @ConfigProperty(name = "metrics.enabled", defaultValue = "false") - private boolean metricsEnabled; - - /** - * Reset internal metricCache and clear registered Gauges. - */ - public void reset() { - metricCache.clear(); - registeredGauges.clear(); - } - - /** - * Reset the internal metricCache and clears all registered Gauges for a list of - * metric keys. - */ - public void reset(List metricKeys) { - for (String metricKey : metricKeys) { - metricCache.remove(metricKey); - metricRegistry.remove(metricKey); - } - } - - /** - * Process Metric only if some data has changed.... - * - * @param processingEvent - * @throws PluginException - */ - public void onProcessingEvent(@Observes ProcessingEvent processingEvent) { - long l = System.currentTimeMillis(); - if (!metricsEnabled) { - return; - } - - ItemCollection invoice = processingEvent.getDocument(); - if (!invoice.getModelVersion().startsWith("rechnungsausgang-")) { - // skip event - return; - } - - // update metric and the metric cache - if (processingEvent.getEventType() == ProcessingEvent.AFTER_PROCESS) { - // load the last invoice metric and reduce the saldo... - ItemCollection lastInvoice = metricDataService.readDirtyWorkitem(invoice.getUniqueID()); - if (lastInvoice != null) { - try { - ItemCollection lastMetricData = getMetricByInvoice(lastInvoice); - subtractInvoice(lastMetricData, lastInvoice); - putMetric(lastMetricData); - metricDataService.saveMetric(lastMetricData); - } catch (PluginException e) { - // invalid invoice - e.g. no cdtr. number - } - } - - try { - // load the invoice metric and add the saldo... - ItemCollection metricData = getMetricByInvoice(invoice); - // Saldo-Berechnung - addInvoice(metricData, invoice); - putMetric(metricData); - metricDataService.saveMetric(metricData); - - // Update the Gauge - updateGauge(metricData); - logger.info("Metric dbtr update took " + (System.currentTimeMillis() - l) + "ms"); - } catch (PluginException e) { - // invalid invoice - e.g. no dbtr. number - } - } - - } - - /** - * Returns the corresponding metric data object for an invoice. The method uses - * an internal cache. If the metric was not yet cached the method loads the - * metric from the database. If not metric exists in the database the method - * automatically creates a new metric data object. - * - * The method throws a PluginException if no metric can be build from this - * invoice (e.g. missing dbtr.number). - * - * @param invoice - * @return - * @throws PluginException - */ - public ItemCollection getMetricByInvoice(ItemCollection invoice) throws PluginException { - if (invoice == null) { - return null; - } - String metricKey = MetricDataService.buildKeyByInvoice(invoice); - ItemCollection metricData = metricCache.get(metricKey); - if (metricData == null) { - metricData = loadMetric(invoice); - } - // if metric still null we create a new metric data object. - if (metricData == null) { - metricData = createMetaData(invoice); - } - return metricData; - } - - /** - * Returns a metric data object by key - * - * @param key - * @return - */ - public ItemCollection getMetric(String key) { - return metricCache.get(key); - } - - /** - * Puts a metric data object into the cache. - * - * @param metricData - */ - public void putMetric(ItemCollection metricData) { - metricCache.put(metricData.getItemValueString("name"), metricData); - } - - /** - * Returns a list with all cached metric keys. - * The method returns an unmodifiable list to prevent modifications. - * - * @return - */ - public List getMetricKeys() { - return Collections.unmodifiableList(new ArrayList<>(metricCache.keySet())); - } - - /** - * This method loads a metric entity for a given invoice workitem. If no metric - * entity exits, the method - * creates a new metric entity. - * - * @param invoice - * @return - * @throws PluginException - */ - private ItemCollection loadMetric(ItemCollection invoice) throws PluginException { - ItemCollection debitorMetric = null; - if (invoice == null) { - return null; - } - try { - String metricKey = MetricDataService.buildKeyByInvoice(invoice); - String query = "(type:" + TYPE_METRIC_DEBITOR + ") AND (name:" + metricKey + ")"; - List result = documentService.find(query, 1, 0, "$modified", true); - if (result.size() > 0) { - debitorMetric = result.get(0); - } - } catch (IllegalArgumentException | QueryException e) { - throw new PluginException(PluginException.class.getName(), - "Failed to load metric object for invoice " + invoice.getUniqueID() + ": ", e.getMessage(), e); - } - return debitorMetric; - } - - /** - * Creates an empty Debitor Meta Data Object (ItemCollection) - *

- * The ItemCollection stores the name and number and also all saldos for all - * currencies - * - * @param invoice - invoice ItemCollection - * @return - * @throws PluginException - */ - private ItemCollection createMetaData(ItemCollection invoice) throws PluginException { - if (invoice == null) { - return null; - } - String key = MetricDataService.buildKeyByInvoice(invoice); - ItemCollection metricData = new ItemCollection(); - metricData.setType(TYPE_METRIC_DEBITOR); - metricData.setItemValue("name", key); - metricData.setItemValue("bp.id", InvoiceUtil.getBPId(invoice)); - metricData.setItemValue("bp.name", InvoiceUtil.getBPName(invoice)); - metricData.setItemValue("country", invoice.getItemValueString("invoice.country")); - metricData.setItemValue("currency", invoice.getItemValueString("invoice.currency")); - metricData.setItemValue("department", invoice.getItemValueString("space.name")); - - return metricData; - } - - /** - * Helper method to register a gauge for a debitor - * - * @param metricData - the metricData ItemCollection - */ - public void updateGauge(ItemCollection metricData) { - - String metricKey = metricData.getItemValueString("name"); - String bpName = metricData.getItemValueString("bp.name"); - String bpId = metricData.getItemValueString("bp.id"); - String country = metricData.getItemValueString("country"); - String department = metricData.getItemValueString("department"); - String currency = metricData.getItemValueString("currency"); - - // Prüfen ob Gauge bereits registriert ist - if (registeredGauges.add(metricKey)) { // returns true newly added - List tags = new ArrayList<>(); - tags.add(new Tag("type", "dbtr")); - tags.add(new Tag("id", bpId)); - tags.add(new Tag("name", bpName)); - tags.add(new Tag("country", country)); - tags.add(new Tag("currency", currency)); - tags.add(new Tag("department", department)); - logger.fine("register new metric for department: " + department + - ", " + metricData.getItemValueString(ITEM_SALDO) + - " " + currency); - Metadata metadata = Metadata.builder() - .withName("dbtr.balance") - .withDescription("Debitor Balance") - .build(); - - metricCache.get(metricKey); - metricRegistry.gauge(metadata, - () -> metricCache.get(metricKey).getItemValueDouble(ITEM_SALDO), - tags.toArray(new Tag[0])); - } else { - logger.fine("Gauge already registered for department: " + department); - } - - } - - /** - * Addiert den saldo einer Invoice zu einem metricData object - * - * @param metricData - * @param invoice - */ - public void addInvoice(ItemCollection metricData, ItemCollection invoice) { - double invoiceTotal = invoice.getItemValueDouble(ITEM_SALDO); - if (!"workitem".equals(invoice.getType()) || invoice.getTaskID() >= 5800) { - // vorgang ist archiviert oder gelöscht worden => saldo = 0! - invoiceTotal = 0.0; - } - - logger.fine("│   │   │   │   ├── Invoice: " + invoice.getItemValueString("invoice.number") + " Saldo=" - + invoiceTotal); - // is the metric new? - if (!metricData.hasItem(ITEM_SALDO)) { - // init metric with the total value! - metricData.setItemValue(ITEM_SALDO, InvoiceUtil.round(invoiceTotal)); - } else { - double lastSaldo = metricData.getItemValueDouble(ITEM_SALDO); - logger.fine("│   │   │   │   ├──letzter Metric Saldo=" + lastSaldo); - metricData.setItemValue(ITEM_SALDO, InvoiceUtil.round(lastSaldo + invoiceTotal)); - } - } - - public void subtractInvoice(ItemCollection metricData, ItemCollection invoice) { - if (metricData == null || invoice == null) { - return; - } - double invoiceTotal = invoice.getItemValueDouble(ITEM_SALDO); - logger.fine("│   │   │   │   ├──Invoice: " + invoice.getItemValueString("invoice.number") + " Saldo=" - + invoiceTotal); - if (!"workitem".equals(invoice.getType()) || invoice.getTaskID() >= 5800) { - // vorgang ist archiviert oder gelöscht worden => saldo = 0! - invoiceTotal = 0.0; - } - // subtract only if metric saldo exists - if (metricData.hasItem(ITEM_SALDO)) { - double lastSaldo = metricData.getItemValueDouble(ITEM_SALDO); - logger.fine("│   │   │   │   ├──letzter Metric Saldo=" + lastSaldo); - metricData.setItemValue(ITEM_SALDO, InvoiceUtil.round(lastSaldo - invoiceTotal)); - } - } - - /** - * Helper Method that refreshes all gauges. The method is called by the - * RestService during a rebuild. - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public void refreshGauges() { - List keys = getMetricKeys(); - refreshGauges(keys); - } - - /** - * Helper Method that refreshes all gauges. The method is called by the - * RestService during a rebuild. - */ - @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) - public void refreshGauges(List keys) { - for (String hashKey : keys) { - ItemCollection metricData = getMetric(hashKey); - documentService.save(metricData); - updateGauge(metricData); - } - } - -} \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java index 84c4974..286076f 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java @@ -28,10 +28,15 @@ package com.alexanderlogistics.xml; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.logging.Logger; +import org.imixs.archive.core.SnapshotService; import org.imixs.workflow.ItemCollection; +import org.imixs.workflow.WorkflowKernel; import org.imixs.workflow.engine.DocumentEvent; import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.engine.ModelService; @@ -42,8 +47,13 @@ import org.imixs.workflow.exceptions.PluginException; import org.imixs.workflow.exceptions.ProcessingErrorException; import org.imixs.workflow.exceptions.QueryException; +import com.alexanderlogistics.BusinessPartnerService; import com.alexanderlogistics.InvoiceUtil; +import com.alexanderlogistics.KreditorDebitorService; +import jakarta.annotation.security.DeclareRoles; +import jakarta.annotation.security.RolesAllowed; +import jakarta.annotation.security.RunAs; import jakarta.ejb.EJB; import jakarta.ejb.Stateless; import jakarta.enterprise.event.Observes; @@ -56,10 +66,22 @@ import jakarta.enterprise.event.Observes; * ein und prüft ob der Workflow schon existiert oder ggf. aktualisiert werden * muss. * + * Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der + * Business partner erstmals neu angelegt wird. + * + * The service set also the flag NOSNAPSHOT=true for the crgosoftcreditor + * document type. * * @author rsoika * */ +@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", + "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", + "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) +@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS", + "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS", + "org.imixs.ACCESSLEVEL.MANAGERACCESS" }) +@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS") @Stateless public class BusinessPartnerImportService { @@ -92,8 +114,16 @@ public class BusinessPartnerImportService { if (event.getEventType() == DocumentEvent.ON_DOCUMENT_SAVE) { // check type! if ("cargosoftkreditor".equals(event.getDocument().getType())) { - logger.info("Verify business partner object...."); + // set NOSNAPSHOT=true + event.getDocument().setItemValue(SnapshotService.NOSNAPSHOT, true); + // run only if we have the model 'businesspartner-*'; + if (modelService.findVersionsByRegEx("(businesspartner*)").size() == 0) { + // no business partner workflow found + return; + } + + logger.fine("Verify business partner object...."); ItemCollection importDoc = event.getDocument(); String name = event.getDocument().getItemValueString("name"); @@ -103,7 +133,7 @@ public class BusinessPartnerImportService { // Prüfen ob es diesen partner schon gibt? ItemCollection businesspartner = lookupBusinessPartner(partnerID); if (businesspartner == null) { - businesspartner = createBusinessPartner(); + businesspartner = createBusinessPartner(partnerID); } ItemCollection oldBussinessPartnerItemColl = (ItemCollection) businesspartner.clone(); @@ -130,7 +160,33 @@ public class BusinessPartnerImportService { // hat sich das Objekt verändert? if (!businesspartner.equals(oldBussinessPartnerItemColl)) { - businesspartner.event(201); // update/create + + // Prüfe IBAN auf plausibilität + List bankList = BusinessPartnerService.getBanks(businesspartner); + boolean ibanDublette = false; + List dublettenIban = new ArrayList<>(); + for (ItemCollection bank : bankList) { + String iban = bank.getItemValueString("iban"); + // erkenne fehlerhaften kontonummern + if (dublettenIban.contains(iban)) { + // ACHTUNG - uneindeutige Bankverbindung + ibanDublette = true; + } else { + dublettenIban.add(iban); + } + } + + int eventID = 200; // default + // event errechnen + if (!businesspartner.hasItem(WorkflowKernel.LASTEVENT)) { + // create new! + if (ibanDublette) { + eventID = 300; // Exception + } else { + eventID = 100; // update/create + } + } + businesspartner.setEventID(eventID); try { workflowService.processWorkItemByNewTransaction(businesspartner); } catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException e) { @@ -147,15 +203,122 @@ public class BusinessPartnerImportService { * * @return */ - private ItemCollection createBusinessPartner() { + private ItemCollection createBusinessPartner(String partnerID) { ItemCollection businessPartner = new ItemCollection(); businessPartner.setType("workitem"); businessPartner.setWorkflowGroup("Business Partner"); businessPartner.task(1000); + // Hier migrieren wir jetzt auch die alten IBAN/BIC Daten + try { + String cargoShortID = partnerID.substring(2); + String query = "(type:" + KreditorDebitorService.TYPE_CARGOSOFTKREDITOR + ")"; + query = query + " AND ( name:K7" + cargoShortID + " OR name:D1" + cargoShortID + " )"; + + List oldList = documentService.find(query, 2, 0); + + // es können 2 Datensätze ankommen + + // Items: + // cdtr.mail (Liste) + // cdtr.creditperiod + // cdtr.iban , cdtr.iban2 - 4 + // cdtr.bic , cdtr.bic2 - 4 + List ibanList = new ArrayList<>(); + List bicList = new ArrayList<>(); + for (ItemCollection oldData : oldList) { + if (!oldData.getItemValueString("cdtr.mail").isEmpty()) { + businessPartner.setItemValue("cdtr.mail", oldData.getItemValue("cdtr.mail")); + } + if (!oldData.getItemValueString("cdtr.creditperiod").isEmpty()) { + businessPartner.setItemValue("cdtr.creditperiod", oldData.getItemValue("cdtr.creditperiod")); + } + + if (!oldData.getItemValueString("cdtr.iban").isEmpty()) { + ibanList.add(oldData.getItemValueString("cdtr.iban")); + } + if (!oldData.getItemValueString("cdtr.bic").isEmpty()) { + bicList.add(oldData.getItemValueString("cdtr.bic")); + } + + if (!oldData.getItemValueString("cdtr.iban2").isEmpty()) { + ibanList.add(oldData.getItemValueString("cdtr.iban2")); + } + if (!oldData.getItemValueString("cdtr.bic2").isEmpty()) { + bicList.add(oldData.getItemValueString("cdtr.bic2")); + } + if (!oldData.getItemValueString("cdtr.iban3").isEmpty()) { + ibanList.add(oldData.getItemValueString("cdtr.iban3")); + } + if (!oldData.getItemValueString("cdtr.bic3").isEmpty()) { + bicList.add(oldData.getItemValueString("cdtr.bic3")); + } + if (!oldData.getItemValueString("cdtr.iban4").isEmpty()) { + ibanList.add(oldData.getItemValueString("cdtr.iban4")); + } + if (!oldData.getItemValueString("cdtr.bic4").isEmpty()) { + bicList.add(oldData.getItemValueString("cdtr.bic4")); + } + + } + + // build partner.iban.list - dublettenprüfung und Trim + List dubletten = new ArrayList<>(); + List dublettenIban = new ArrayList<>(); + + if (ibanList.size() > 0) { + List bankList = new ArrayList<>(); + for (int i = 0; i < ibanList.size(); i++) { + String iban = ibanList.get(i); + String bic = ""; + if (bicList.size() > i) { + bic = bicList.get(i); + } + + iban = superTrim(iban); + bic = superTrim(bic); + if (dubletten.contains(iban + "/" + bic)) { + // voll dublette + continue; + } else { + dubletten.add(iban + "/" + bic); + } + + ItemCollection bank = new ItemCollection(); + // {cdtr.iban=[A], name=[cdtr1], cdtr.name=[a], cdtr.bic=[a]} + bank.setItemValue("id", "bank" + (i + 1)); + bank.setItemValue("name", "Bank " + (i + 1)); + bank.setItemValue("iban", iban); + bank.setItemValue("bic", bic); + + bankList.add(bank); + } + Iterator var3 = bankList.iterator(); + List mapOrderItems = new ArrayList(); + while (var3.hasNext()) { + ItemCollection orderItem = (ItemCollection) var3.next(); + mapOrderItems.add(orderItem.getAllItems()); + } + businessPartner.setItemValue(BusinessPartnerService.ITEM_IBAN_LIST, mapOrderItems); + } + + } catch (QueryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return businessPartner; } + /** + * entfernt alle leerzeichen + */ + public String superTrim(String data) { + String result = data.trim(); + result = result.replace(" ", ""); + return result; + } + /** * Sucht nach einem Business partner * diff --git a/office-alexander-logistics-app/src/main/webapp/layout/css/custom.css b/office-alexander-logistics-app/src/main/webapp/layout/css/custom.css index 47eb6c4..007f3b9 100644 --- a/office-alexander-logistics-app/src/main/webapp/layout/css/custom.css +++ b/office-alexander-logistics-app/src/main/webapp/layout/css/custom.css @@ -7,4 +7,30 @@ !important; background-position: 4px 6px, center !important; padding-left: 22px !important; +} +.tooltip-link { + position: relative; + display: inline-block; +} + +.tooltip-text { + visibility: hidden; + width: 300px; + background-color: black; + color: #fff; + text-align: center; + border-radius: 5px; + padding: 5px; + position: absolute; + z-index: 1; + bottom: 125%; /* Position above the link */ + left: 50%; + margin-left: -150px; /* Center the tooltip */ + opacity: 0; + transition: opacity 0.3s; +} + +.tooltip-link:hover .tooltip-text { + visibility: visible; + opacity: 1; } \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_dunnings.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_dunnings.xhtml new file mode 100644 index 0000000..2fe56af --- /dev/null +++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_dunnings.xhtml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MahnungStatus#{message.modified}
+ #{dunning.item['$workflowsummary']} + + #{dunning.item['$workflowstatus']} + + #{message.by} #{userController.getUserName(dunning.item['$editor'])}
+
+ + + + + +
\ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_invoices_in.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_invoices_in.xhtml new file mode 100644 index 0000000..c18ea6e --- /dev/null +++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_invoices_in.xhtml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RechnungStatus#{message.modified}
+ #{invoice.item['$workflowsummary']} + + #{invoice.item['$workflowstatus']} + + #{message.by} #{userController.getUserName(invoice.item['$editor'])}
+
+ + + + + +
\ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_invoices_out.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_invoices_out.xhtml new file mode 100644 index 0000000..5068d04 --- /dev/null +++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_bp_invoices_out.xhtml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RechnungStatus#{message.modified}
+ #{invoice.item['$workflowsummary']} + + + + + + #{invoice.item['$workflowstatus']} + + #{message.by} #{userController.getUserName(invoice.item['$editor'])}
+
+ + + + + +
\ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/sub_businesspartner_ibanlist.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_businesspartner_banklist.xhtml similarity index 76% rename from office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/sub_businesspartner_ibanlist.xhtml rename to office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_businesspartner_banklist.xhtml index bee7855..54bf918 100644 --- a/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/sub_businesspartner_ibanlist.xhtml +++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/section_businesspartner_banklist.xhtml @@ -10,35 +10,35 @@ - - + + - +
NameBank - *ID + *Bank IBAN BIC
- + - - - + + actionListener="#{businessPartnerController.removeIBAN(bank.item['id'])}"> diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/businesspartner_search.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/businesspartner_search.xhtml new file mode 100644 index 0000000..2173bb7 --- /dev/null +++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/businesspartner_search.xhtml @@ -0,0 +1,79 @@ + + + + + + + + +
+ #{workitem.item[item_konto_name]} + + + + + + + +
+ + + +
+
+
+ +
+ + + + + + +
\ No newline at end of file diff --git a/pom.xml b/pom.xml index b6e3c92..b6f3eab 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.alexander-logistics office-alexander-logistics - 1.3.1 + 1.3.2 pom Imixs Office Workflow - Custom Build @@ -25,17 +25,19 @@ 10.0.0 - 5.0.4-SNAPSHOT - 6.0.9-SNAPSHOT + 5.0.4 + 6.0.9 5.0.0 - 3.0.2 - 3.0.3-SNAPSHOT + + + 3.1.1-SNAPSHOT + 3.0.3 2.0.2 6.0 9.9.1-4 2.0.26 - 1.1.1-SNAPSHOT + 1.1.1 src/main/webapp diff --git a/workflow/businesspartner-de-1.0.0.bpmn b/workflow/businesspartner-de-1.0.0.bpmn index 9fc7a62..226b47c 100644 --- a/workflow/businesspartner-de-1.0.0.bpmn +++ b/workflow/businesspartner-de-1.0.0.bpmn @@ -4,6 +4,7 @@ + association_83sZPw @@ -25,9 +26,12 @@ - - - + + + + + + @@ -49,10 +53,37 @@ textAnnotation_LyGTCw event_TuyuwQ event_h0Kk5g + task_delO7Q + event_1OVorA + event_baWU4w + event_ofjVfg + event_i7yQVw + gateway_uK0c6g + event_6250fg + event_VM0fEQ + gateway_s0J53g + task_NohgrQ + event_AMs05g + event_feLZFQ + event_GTXFMw + event_u8OBFg - + + + + + + + + + + + + + + sequenceFlow_25otUg sequenceFlow_S9LVXg @@ -63,7 +94,6 @@ - sequenceFlow_NNbMhg sequenceFlow_rwdWxw @@ -77,13 +107,42 @@ partner.name (partner.id)]]> + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + +
- sequenceFlow_knUYpQ - sequenceFlow_2uNvPw - sequenceFlow_NNbMhg sequenceFlow_avahXg sequenceFlow_9atLFA + sequenceFlow_T5L9aQ + sequenceFlow_b4BcVA + sequenceFlow_8O1EtQ + sequenceFlow_ShuXXA + sequenceFlow_03b60w
@@ -93,94 +152,139 @@ + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + + + +
sequenceFlow_1mXO8A sequenceFlow_rwdWxw sequenceFlow_gC0I9w + sequenceFlow_kS2fMA
- + - + Partnermanagement]]> - sequenceFlow_S9LVXg - sequenceFlow_knUYpQ + sequenceFlow_jAU3VA + sequenceFlow_8O1EtQ - + - - - + + home]]> + - sequenceFlow_2uNvPw sequenceFlow_1mXO8A + sequenceFlow_b0Bj3Q + sequenceFlow_neSsFQ - - - - - - - - - - - - + - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - + - - - - - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + ]]> - - - sequenceFlow_avahXg @@ -196,10 +300,10 @@ - + - + @@ -207,6 +311,9 @@ + + + sequenceFlow_9atLFA @@ -229,139 +336,547 @@ + + + + + + + partner.name (partner.id)]]> + + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + + + + +
+ + sequenceFlow_NNbMhg + sequenceFlow_avahXg + sequenceFlow_pvIENQ + sequenceFlow_BWOtzA + sequenceFlow_ofWWuw + sequenceFlow_b0Bj3Q + sequenceFlow_BHsRkQ +
+ + + + + + + + + + Partnermanagement]]> + + + + sequenceFlow_BHsRkQ + sequenceFlow_5pT4Tw + + + + + + + + + + + home]]> + + + + sequenceFlow_pvIENQ + sequenceFlow_b4BcVA + + + + + + + + + + + + + + + + + + sequenceFlow_BWOtzA + + + + + + + + Partnermanagement]]> + + + + + + + sequenceFlow_ofWWuw + + + + + + + + + + + + + sequenceFlow_S9LVXg + sequenceFlow_jAU3VA + sequenceFlow_8BTEtw + + + + + + + + + + + + + + + + sequenceFlow_kS2fMA + + + + + + + + Partnermanagement]]> + + + + + + + sequenceFlow_T5L9aQ + sequenceFlow_MPlPww + + sequenceFlow_rNZ3tw + + + + sequenceFlow_MPlPww + sequenceFlow_aH0vCQ + sequenceFlow_ShuXXA + + + + + + + + partner.name (partner.id)]]> + + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + + + + +
+ + sequenceFlow_9atLFA + sequenceFlow_8O1EtQ + sequenceFlow_aH0vCQ + sequenceFlow_neSsFQ + sequenceFlow_zd6RWA + sequenceFlow_rNZ3tw +
+ + + + + + + + + + + + + + + + + sequenceFlow_5pT4Tw + + + + + sequenceFlow_8BTEtw + + + + + + + + + + + sequenceFlow_03b60w + + + + + + + + sequenceFlow_zd6RWA + + + + + + +
- + - + - + - + - + - + - + - - + + - + - + - + - + - - - - - - - + + + - + - + - - - - - - - - - - + + - - - + + - + - + - - - - - - + - + - - - - - - - + + + + - - - + + + + - + - - - - - + - + - + - - - - + + + - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/businesspartner-en-1.0.0.bpmn b/workflow/businesspartner-en-1.0.0.bpmn new file mode 100644 index 0000000..0fd6526 --- /dev/null +++ b/workflow/businesspartner-en-1.0.0.bpmn @@ -0,0 +1,883 @@ + + + + + + + association_83sZPw + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_ToMZaQ + event_WmkBvw + event_1clvlg + task_Q80A1Q + task_B8Pi7A + event_aSdkwg + event_Tr0aug + dataObject_UQIXAQ + event_vwH0cA + textAnnotation_LyGTCw + event_TuyuwQ + event_h0Kk5g + task_delO7Q + event_1OVorA + event_baWU4w + event_ofjVfg + event_i7yQVw + gateway_uK0c6g + event_6250fg + event_VM0fEQ + gateway_s0J53g + task_NohgrQ + event_AMs05g + event_feLZFQ + event_GTXFMw + event_u8OBFg + + + + + + + + + + + + + + + + + + + sequenceFlow_25otUg + sequenceFlow_S9LVXg + + + + sequenceFlow_25otUg + + + + sequenceFlow_rwdWxw + + + + + + + + + + + partner.name (partner.id)]]> + + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + +
+ + sequenceFlow_avahXg + sequenceFlow_9atLFA + sequenceFlow_T5L9aQ + sequenceFlow_b4BcVA + sequenceFlow_8O1EtQ + sequenceFlow_ShuXXA + sequenceFlow_03b60w +
+ + + + partner.name (partner.id)]]> + + + + + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + + + + +
+ + sequenceFlow_1mXO8A + sequenceFlow_rwdWxw + sequenceFlow_gC0I9w + sequenceFlow_kS2fMA +
+ + + + + + + + + + Partnermanagement]]> + + + + sequenceFlow_jAU3VA + sequenceFlow_8O1EtQ + + + + + + + + + + + home]]> + + + + sequenceFlow_1mXO8A + sequenceFlow_b0Bj3Q + sequenceFlow_neSsFQ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + sequenceFlow_avahXg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + sequenceFlow_9atLFA + + + + + + + + + + + + + + + sequenceFlow_gC0I9w + + + + + + + + + + + partner.name (partner.id)]]> + + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + + + + +
+ + sequenceFlow_NNbMhg + sequenceFlow_avahXg + sequenceFlow_pvIENQ + sequenceFlow_BWOtzA + sequenceFlow_ofWWuw + sequenceFlow_b0Bj3Q + sequenceFlow_BHsRkQ +
+ + + + + + + + + + Partnermanagement]]> + + + + sequenceFlow_BHsRkQ + sequenceFlow_5pT4Tw + + + + + + + + + + + home]]> + + + + sequenceFlow_pvIENQ + sequenceFlow_b4BcVA + + + + + + + + + + + + + + + + + + sequenceFlow_BWOtzA + + + + + + + + Partnermanagement]]> + + + + + + + sequenceFlow_ofWWuw + + + + + + + + + + + + + sequenceFlow_S9LVXg + sequenceFlow_jAU3VA + sequenceFlow_8BTEtw + + + + + + + + + + + + + + + + sequenceFlow_kS2fMA + + + + + + + + Partnermanagement]]> + + + + + + + sequenceFlow_T5L9aQ + sequenceFlow_MPlPww + + sequenceFlow_rNZ3tw + + + + sequenceFlow_MPlPww + sequenceFlow_aH0vCQ + sequenceFlow_ShuXXA + + + + + + + + partner.name (partner.id)]]> + + + Adresse:
+partner.name
+partner.address
+partner.zip partner.city
+
+ +BPID: partner.id
+Kreditoren-Nr.: cdtr.number
+Debitoren-Nr.: dbtr.number
+]]>
+
+ + + + + + + + + + + + + + + + + + +
+ + sequenceFlow_9atLFA + sequenceFlow_8O1EtQ + sequenceFlow_aH0vCQ + sequenceFlow_neSsFQ + sequenceFlow_zd6RWA + sequenceFlow_rNZ3tw +
+ + + + + + + + + + + + + + + + + sequenceFlow_5pT4Tw + + + + + sequenceFlow_8BTEtw + + + + + + + + + + + sequenceFlow_03b60w + + + + + + + + sequenceFlow_zd6RWA + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/workflow/dwc/rechnungsausgang-dwc-1.0.2.bpmn b/workflow/dwc/rechnungsausgang-dwc-1.0.2.bpmn index f856ad9..2a3bafe 100644 --- a/workflow/dwc/rechnungsausgang-dwc-1.0.2.bpmn +++ b/workflow/dwc/rechnungsausgang-dwc-1.0.2.bpmn @@ -1291,7 +1291,7 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht - + @@ -1404,7 +1404,7 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht - + diff --git a/workflow/posteingang-de-2.0.1.bpmn b/workflow/posteingang-de-2.0.1.bpmn new file mode 100644 index 0000000..7931e8e --- /dev/null +++ b/workflow/posteingang-de-2.0.1.bpmn @@ -0,0 +1,1625 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + BoundaryEvent_1 + Task_4 + IntermediateCatchEvent_2 + Task_2 + IntermediateCatchEvent_3 + StartEvent_1 + EndEvent_1 + + dataObject_FS1r0Q + task_uB6BGQ + textAnnotation_CtU05A + task_PsBytg + dataObject_CRa7xA + event_Zxhr0w + dataObject_vVKXIg + event_yQLmNA + task_0YaQ2w + dataObject_HHM58Q + event_xOeBKg + event_pDFoXg + dataObject_ZhBiZg + event_4DNGzg + dataObject_KPUiiw + event_wmNwPA + event_tFxV0w + event_88sCAA + event_T901Jg + event_7rbeVA + gateway_qDAhHw + event_9mJrhQ + gateway_gd9zQQ + TextAnnotation_1 + gateway_MgL04w + event_VEvZRQ + event_Xk1mPA + event_a1P5WQ + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + home +Empfang +]]> + + + + + + + + + + + + false + + + + sequenceFlow_fRPOrw + sequenceFlow_4gpPgw + + + + sequenceFlow_fRPOrw + + + + + + + + + + + + + + + + + true + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_9 + sequenceFlow_4gpPgw + sequenceFlow_CbkmwA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +X-Tika-OCRLanguage=eng+deu +X-Tika-PDFocrStrategy=OCR_ONLY +(PDF|pdf)$ +10 +Empfang]]> + + + + + + + + + + + + false + + + + SequenceFlow_9 + SequenceFlow_2 + + + DataOutput_1 + + + DataOutput_1 + + + sequenceFlow_VlPVJg + + + + + + + + txtlastcomment]]> + + + + + + + + + + + + + + + + + + + + + + + + cdtr.name (invoice.language)]]> + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_12 + sequenceFlow_gXJm0w + + + SequenceFlow_12 + + + + + + + SequenceFlow_2 + + 1000 + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + true + + + + + + + + + sequenceFlow_fN22Gg + sequenceFlow_bh4DIw + sequenceFlow_ofQKHg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + document.type ⇒ document.company (Import: document.import.type - Langauge: document.language) ]]> + + + true + + + + + + + + document.type
+Company: document.company
]]>
+
+
+ + sequenceFlow_JpNUKg + sequenceFlow_8SpIiA + sequenceFlow_I8o4DA + sequenceFlow_KKWo0w +
+ + + + + + + + + + + + +]]> + + + + + + + + sequenceFlow_3YcMGQ + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + https://llama.cpp.imixs.com/ + XML + false + + + cdtr.name,invoice.number,invoice.date,invoice.total,payment.date,cdtr.iban,cdtr.bic,total + ON + +false + +]]> + + + + + + DataOutput_2 + + + DataOutput_2 + + + sequenceFlow_aC0skQ + sequenceFlow_YMtfiw + sequenceFlow_PWXjog + + + + + + + + + + + + + + document.type ⇒ document.company (Import: document.import.type - Langauge: document.language) ]]> + + + true + + + + + + + + + sequenceFlow_JpNUKg + sequenceFlow_lmU9IA + sequenceFlow_aC0skQ + sequenceFlow_A62nqQ + sequenceFlow_DdWK6A + + + + + + + + + + + {"n_predict": 4096, "temperature": 0 } + invoice.summary + +[INST]Transfer the invoice data into an XML object with the following structure: + + + ... + ... + 2024-12-31 + 2024-12-31 + 1234.00 + ... + ... + + +Transfer the individual invoice data to the XML tags, taking into account the following suggestions for mapping: + + - Company name ==> "cdtr.name" (the name of the company that issued the invoice document, not the recipient) + - Invoice number ==> "invoice.number" + - Invoice Date ==> "invoice.date" + - Total ==> "invoice.total" (in EUR or if not available in USD or PLN) + - IBAN ==> "cdtr.iban" + - BIC or SWIFT ==> "cdtr.bic" + - Payment date / Due date ==> "invoice.duedate" + +Note: Output only the XML object! Don't add explanations or comments. Use only the XML structure specified in this example and do not create any other XML tags. If you don't have data for some fields, leave the corresponding XML tags blank. Format date values (invoice.date, invoice.duedate) into the ISO 8601 format (YYYY-MM-DD). Format numbers and amounts (type="double") according to ISO 4217. + +<> + +[/INST] + +]]]]> + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + (^rechnungseingang-[a-z]{2,3}-\d+(?:\.\d+)?$) + 5000 + 990 + +]]> + + + + + + DataOutput_2 + + + DataOutput_2 + + sequenceFlow_gXJm0w + sequenceFlow_gpPDLg + sequenceFlow_eccehA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + https://llama.cpp.imixs.com/ + XML + +Empfang + + +]]> + + + + + + DataOutput_2 + + + DataOutput_2 + + + sequenceFlow_fN22Gg + sequenceFlow_naZnAA + sequenceFlow_PgyOMw + + + + + {"n_predict": 512, "temperature": 0 } + ^.+\.([pP][dD][fF])$ + +[INST] Assign the invoice to one of the following categories: + +- Cargo-Invoice - in case the invoice is about cargo and logistic services +- Credit - in case of a credit note +- Invoice - in all other cases + +Extract also the company name and the language the invoice is written in. + +Note: The company name is the name of the company that issued the invoice document and not the name of the recipient. As a rule, it is not Alexander Global Logistics either. The company name is often at the beginning or end of the invoice document. + +Output the infromation as one XML object that has the following structure: + + + Type + Kraxi GmbH + German + + +Note: Do not generate any other information instead of the XML object. Do not generate more than one XML Object. + +[/INST] +]]]]> + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + https://llama.cpp.imixs.com/ + invoice.summary + false + +false +]]> + + + + + + DataOutput_2 + + + DataOutput_2 + + + sequenceFlow_8SpIiA + sequenceFlow_A62nqQ + sequenceFlow_Di4BQA + + + + + + + + + + + {"n_predict": 4096, "temperature": 0} + ^.+\.([pP][dD][fF])$ + +[INST] + +Summarize the data from this invoice document: + + - Vendor information + - General Billing data + - Invoice total information + - Payment summary (including bank data) + - Invoice items + +Note: The vendor information refers to the sender of the invoice. The company name is the name of the company that issued the invoice document and not the name of the recipient. As a rule, it is not Alexander Global Logistics either. The company name is often at the beginning or end of the invoice document. + +Use only the default values and do not perform any calculations, summing or changes to these values yourself. Format numbers and amounts according to ISO 4217. + +If possible summarize the invoice lines in a table. + +[/INST] +]]]]> + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + sequenceFlow_3YcMGQ + sequenceFlow_p0asUQ + + + + + + sequenceFlow_DdWK6A + + + + + + + + sequenceFlow_PgyOMw + + + + + sequenceFlow_Di4BQA + + + + + + + + + + + sequenceFlow_PWXjog + + + + + + + sequenceFlow_naZnAA + sequenceFlow_tcjWAA + sequenceFlow_I8o4DA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + adapter.error_code: adapter.error_message]]> + + + false + + + + + + DataOutput_2 + + + DataOutput_2 + + sequenceFlow_tcjWAA + sequenceFlow_gpPDLg + sequenceFlow_d0zSHA + + + + + + + + + + + + + + + sequenceFlow_I8o4DA + sequenceFlow_VlPVJg + sequenceFlow_bh4DIw + sequenceFlow_d0zSHA + + + + + + + + + + + + + For the OCR Adapter the following minimal options should be set: + + * X-Tika-PDFocrStrategy=OCR_AND_TEXT_EXTRACTION + * X-Tika-OCRLanguage=eng+deu + +These options allow OCR and text extraction suporting English and German language. + +Additional Tika Options can be set but are NOT needed in most cases: + + * X-Tika-PDFOcrImageType=RGB (setting the RGB color mode) + * X-Tika-PDFOcrDPI=400 (setting DPI) + +Setting the OcrDPI is only recommended if the DPI is know! + +Possible ImageTypes are: + + * ARGB Alpha, Red, Green, Blue + * BINARY Black or white. + * GRAY Shades of gray + * RGB Red, Green, Blue + + + + + + sequenceFlow_YMtfiw + sequenceFlow_eccehA + sequenceFlow_p0asUQ + + + + + + + + + + + + + + + + + sequenceFlow_KKWo0w + + + + + + + + sequenceFlow_ofQKHg + + + + + + + + sequenceFlow_CbkmwA + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/workflow/posteingang-en-2.0.1.bpmn b/workflow/posteingang-en-2.0.1.bpmn index 9c09540..bbb9d77 100644 --- a/workflow/posteingang-en-2.0.1.bpmn +++ b/workflow/posteingang-en-2.0.1.bpmn @@ -1,13 +1,5 @@ - - + @@ -45,16 +37,15 @@ true - - + + - + - + - + BoundaryEvent_1 @@ -64,7 +55,7 @@ IntermediateCatchEvent_3 StartEvent_1 EndEvent_1 - + dataObject_FS1r0Q task_uB6BGQ textAnnotation_CtU05A @@ -118,11 +109,11 @@ Betrag: _amount (Brutto € _amount_brutto) _description]]>
- + - + @@ -135,12 +126,12 @@ Betrag: _amount (Brutto € _amount_brutto - + - + home @@ -165,7 +156,7 @@ Betrag: _amount (Brutto € _amount_bruttosequenceFlow_4gpPgw - + sequenceFlow_fRPOrw @@ -185,8 +176,8 @@ Betrag: _amount (Brutto € _amount_brutto true - - + + @@ -205,7 +196,7 @@ Betrag: _amount (Brutto € _amount_brutto - + @@ -214,7 +205,7 @@ Betrag: _amount (Brutto € _amount_brutto - + @@ -245,7 +236,7 @@ Betrag: _amount (Brutto € _amount_brutto - + @@ -271,18 +262,18 @@ Betrag: _amount (Brutto € _amount_brutto SequenceFlow_9 SequenceFlow_2 - + DataOutput_1 DataOutput_1 - + sequenceFlow_VlPVJg - + @@ -302,13 +293,13 @@ Betrag: _amount (Brutto € _amount_brutto - + - + - + cdtr.name (invoice.language)]]> @@ -320,21 +311,20 @@ Betrag: _amount (Brutto € _amount_brutto SequenceFlow_12 - + - + SequenceFlow_2 1000 - + - - + + @@ -359,13 +349,13 @@ Betrag: _amount (Brutto € _amount_brutto true - - + + - + sequenceFlow_fN22Gg sequenceFlow_bh4DIw sequenceFlow_WBx7JQ @@ -374,22 +364,19 @@ Betrag: _amount (Brutto € _amount_brutto - + - - + + - - + + - - + + - + @@ -408,8 +395,8 @@ Assign invoice to process 'Front Desk']]> true - - + + @@ -418,7 +405,7 @@ Assign invoice to process 'Front Desk']]> Company: document.company
]]>
- + sequenceFlow_JpNUKg sequenceFlow_8SpIiA sequenceFlow_I8o4DA @@ -439,11 +426,11 @@ Company: document.company
]]> ]]>
- + - - + + sequenceFlow_Z8050g @@ -457,7 +444,7 @@ Company: document.company
]]> ]]>
- + @@ -468,7 +455,7 @@ Company: document.company
]]>
- + @@ -477,7 +464,7 @@ Company: document.company
]]>
- + @@ -508,7 +495,7 @@ Company: document.company
]]>
- + @@ -538,14 +525,14 @@ Company: document.company
]]>
- + DataOutput_2 DataOutput_2 - + sequenceFlow_aC0skQ sequenceFlow_YMtfiw sequenceFlow_PWXjog @@ -567,13 +554,13 @@ Company: document.company
]]> true - - + + - + sequenceFlow_JpNUKg sequenceFlow_lmU9IA sequenceFlow_aC0skQ @@ -581,14 +568,13 @@ Company: document.company
]]> sequenceFlow_WIiVnQ - + - + - + {"n_predict": 4096, "temperature": 0 } ]]> - - + + @@ -640,7 +625,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t
- + @@ -649,7 +634,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t - + @@ -680,7 +665,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t - + @@ -703,8 +688,8 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t ]]> - - + + DataOutput_2 @@ -716,7 +701,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t sequenceFlow_I8Pggg - + @@ -727,7 +712,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t
- + @@ -736,7 +721,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t - + @@ -767,7 +752,7 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t - + @@ -793,21 +778,20 @@ Note: Output only the XML object! Don't add explanations or comments. Use only t - + DataOutput_2 DataOutput_2 - + sequenceFlow_fN22Gg sequenceFlow_naZnAA sequenceFlow_PgyOMw - + {"n_predict": 512, "temperature": 0 } ]]> - - + + - + - + @@ -858,7 +841,7 @@ Note: Do not generate any other information instead of the XML object. Do not ge
- + @@ -867,7 +850,7 @@ Note: Do not generate any other information instead of the XML object. Do not ge - + @@ -898,7 +881,7 @@ Note: Do not generate any other information instead of the XML object. Do not ge - + @@ -924,27 +907,26 @@ Note: Do not generate any other information instead of the XML object. Do not ge - + DataOutput_2 DataOutput_2 - + sequenceFlow_8SpIiA sequenceFlow_A62nqQ sequenceFlow_Di4BQA - + - + - + {"n_predict": 4096, "temperature": 0} ]]> - - + + @@ -993,7 +974,7 @@ If possible summarize the invoice lines in a table. - + @@ -1006,12 +987,12 @@ If possible summarize the invoice lines in a table. - + - + @@ -1026,13 +1007,13 @@ If possible summarize the invoice lines in a table. false - + - + - + @@ -1047,43 +1028,42 @@ If possible summarize the invoice lines in a table. sequenceFlow_Z8050g sequenceFlow_0XHjPA - + - - + + sequenceFlow_WIiVnQ - + - - + + sequenceFlow_PgyOMw - - + + sequenceFlow_Di4BQA - + - + - - + + sequenceFlow_PWXjog - + - - + + sequenceFlow_naZnAA sequenceFlow_tcjWAA sequenceFlow_I8o4DA @@ -1097,7 +1077,7 @@ If possible summarize the invoice lines in a table.
- + @@ -1106,7 +1086,7 @@ If possible summarize the invoice lines in a table. - + @@ -1137,7 +1117,7 @@ If possible summarize the invoice lines in a table. - + @@ -1152,8 +1132,8 @@ If possible summarize the invoice lines in a table. false - - + + DataOutput_2 @@ -1163,525 +1143,484 @@ If possible summarize the invoice lines in a table. sequenceFlow_tcjWAA sequenceFlow_gpPDLg sequenceFlow_d0zSHA - + - - + + - + - + - - + + sequenceFlow_I8o4DA sequenceFlow_VlPVJg sequenceFlow_bh4DIw sequenceFlow_d0zSHA - + - - + + - + For the OCR Adapter the following minimal options should be set: - * X-Tika-PDFocrStrategy=OCR_AND_TEXT_EXTRACTION - * X-Tika-OCRLanguage=eng+deu + * X-Tika-PDFocrStrategy=OCR_AND_TEXT_EXTRACTION + * X-Tika-OCRLanguage=eng+deu - These options allow OCR and text extraction suporting English and German language. +These options allow OCR and text extraction suporting English and German language. - Additional Tika Options can be set but are NOT needed in most cases: +Additional Tika Options can be set but are NOT needed in most cases: - * X-Tika-PDFOcrImageType=RGB (setting the RGB color mode) - * X-Tika-PDFOcrDPI=400 (setting DPI) + * X-Tika-PDFOcrImageType=RGB (setting the RGB color mode) + * X-Tika-PDFOcrDPI=400 (setting DPI) - Setting the OcrDPI is only recommended if the DPI is know! +Setting the OcrDPI is only recommended if the DPI is know! - Possible ImageTypes are: +Possible ImageTypes are: - * ARGB Alpha, Red, Green, Blue - * BINARY Black or white. - * GRAY Shades of gray - * RGB Red, Green, Blue + * ARGB Alpha, Red, Green, Blue + * BINARY Black or white. + * GRAY Shades of gray + * RGB Red, Green, Blue - + - + sequenceFlow_YMtfiw sequenceFlow_I8Pggg sequenceFlow_0XHjPA - + - + - + - + - - + + sequenceFlow_n3o55Q - + - - + + sequenceFlow_WBx7JQ - + - - + + sequenceFlow_B0T5KA - + - + - + - + - + - + - + - - + + - + - + - + - + - - + + - + - + - + - + - + - + - + - - - - + + + + - - - - + + + + - - - - - - + + + + + + - + - + - + - + - - - + + + - - - + + + - - - + + + - - - - + + + + - + - + - + - - - - + + + + - + - + - + - + - - - - - + + + + + - + - + - + - - - + + + - - - + + + - + - + - - - - - + + + + + - + - + - - - + + + - + - + - + - + - - - - - + + + + + - - - + + + - - - + + + - + - + - - - + + + - - - + + + - + - + - - - - - + + + + + - + - + - + - + - - - - + + + + - + - + - + - + - - - - - + + + + + - - - - - + + + + + - + - + - - - - - + + + + + - + - + - + - + - - - - + + + + - - - + + + - - - + + + - + - + - - - + + + - - - - - + + + + + - - - - + + + + - + - + - - - + + + - - - + + + - - - + + + - - - - - + + + + + - + - + - - - + + + - + - + - - - + + + - + - + - - - + + + - + - \ No newline at end of file + diff --git a/workflow/rechnungsausgang-de-1.0.12.bpmn b/workflow/rechnungsausgang-de-1.0.12.bpmn index 8b89f6c..1d26998 100644 --- a/workflow/rechnungsausgang-de-1.0.12.bpmn +++ b/workflow/rechnungsausgang-de-1.0.12.bpmn @@ -96,7 +96,7 @@ th { font-weight: bold;}
- + Task_2 @@ -3638,8 +3638,8 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - - + + @@ -3652,8 +3652,8 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - - + + @@ -3691,13 +3691,13 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + - + @@ -3727,7 +3727,7 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + @@ -3736,13 +3736,13 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + - + @@ -3761,14 +3761,14 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + - + @@ -3782,7 +3782,7 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + @@ -3792,7 +3792,7 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + @@ -3807,8 +3807,8 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - - + + @@ -3865,13 +3865,13 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + - + @@ -3942,7 +3942,7 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - + @@ -3968,20 +3968,20 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - - + + - - + + - - + + @@ -4105,8 +4105,8 @@ if (workitem.getItemValueString('txtcomment') == '' ) { - - + + diff --git a/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn b/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn new file mode 100644 index 0000000..d747661 --- /dev/null +++ b/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn @@ -0,0 +1,8495 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + Task_2 + ExclusiveGateway_1 + StartEvent_1 + IntermediateCatchEvent_6 + IntermediateCatchEvent_27 + EventBasedGateway_1 + Task_10 + EndEvent_5 + IntermediateCatchEvent_40 + IntermediateThrowEvent_4 + IntermediateCatchEvent_49 + IntermediateCatchEvent_19 + IntermediateThrowEvent_3 + IntermediateCatchEvent_31 + IntermediateCatchEvent_13 + Task_14 + EventBasedGateway_3 + IntermediateCatchEvent_30 + Task_13 + EndEvent_4 + IntermediateCatchEvent_56 + IntermediateThrowEvent_9 + IntermediateCatchEvent_60 + IntermediateCatchEvent_3 + ExclusiveGateway_9 + IntermediateCatchEvent_5000-20 + + DataObject_5 + DataObject_2 + TextAnnotation_4 + + + + Task_1 + IntermediateCatchEvent_9 + IntermediateCatchEvent_10 + IntermediateCatchEvent_11 + IntermediateThrowEvent_5 + IntermediateCatchEvent_1 + IntermediateCatchEvent_45 + IntermediateCatchEvent_61 + IntermediateCatchEvent_64 + DataObject_7 + event_GwjqFw + + + + Task_5005 + IntermediateCatchEvent_5005-20 + IntermediateCatchEvent_5005-30 + IntermediateCatchEvent_2 + IntermediateCatchEvent_36 + IntermediateCatchEvent_42 + IntermediateCatchEvent_55 + EventBasedGateway_2 + ExclusiveGateway_6 + ExclusiveGateway_4 + TextAnnotation_1 + TextAnnotation_3 + Task_4 + Task_12 + IntermediateCatchEvent_5005-10 + IntermediateCatchEvent_12 + EndEvent_1 + IntermediateCatchEvent_21 + IntermediateThrowEvent_2 + IntermediateCatchEvent_25 + IntermediateCatchEvent_26 + IntermediateCatchEvent_28 + IntermediateCatchEvent_32 + IntermediateThrowEvent_8 + ExclusiveGateway_7 + ExclusiveGateway_10 + event_bBR4QQ + event_NvdVrw + DataObject_1 + + + + IntermediateCatchEvent_44 + IntermediateCatchEvent_53 + IntermediateCatchEvent_54 + IntermediateThrowEvent_7 + IntermediateCatchEvent_50 + DataObject_6 + Task_17 + Task_18 + IntermediateCatchEvent_43 + IntermediateCatchEvent_47 + IntermediateCatchEvent_51 + IntermediateThrowEvent_6 + IntermediateCatchEvent_52 + ExclusiveGateway_3 + EventBasedGateway_5 + EventBasedGateway_6 + ExclusiveGateway_8 + + + EndEvent_3 + Task_5000 + IntermediateCatchEvent_5000-10 + IntermediateCatchEvent_33 + IntermediateCatchEvent_38 + IntermediateCatchEvent_15 + EndEvent_6 + EventBasedGateway_4 + Task_16 + IntermediateCatchEvent_37 + IntermediateCatchEvent_24 + Task_8 + IntermediateCatchEvent_16 + Task_9 + IntermediateCatchEvent_7 + ExclusiveGateway_2 + IntermediateCatchEvent_29 + IntermediateCatchEvent_39 + IntermediateCatchEvent_20 + Task_3 + IntermediateCatchEvent_17 + ExclusiveGateway_5 + IntermediateCatchEvent_35 + IntermediateThrowEvent_1 + IntermediateCatchEvent_58 + IntermediateCatchEvent_22 + Task_5 + Task_15 + IntermediateCatchEvent_48 + Task_11 + IntermediateCatchEvent_4 + IntermediateCatchEvent_14 + IntermediateCatchEvent_57 + Task_7 + IntermediateCatchEvent_18 + EndEvent_2 + IntermediateCatchEvent_5 + Task_6 + IntermediateCatchEvent_46 + Task_19 + IntermediateCatchEvent_63 + IntermediateCatchEvent_34 + IntermediateCatchEvent_59 + IntermediateCatchEvent_41 + IntermediateCatchEvent_65 + IntermediateCatchEvent_66 + + event_TyXP5Q + DataObject_3 + IntermediateCatchEvent_62 + TextAnnotation_5 + TextAnnotation_2 + event_e0gqXQ + gateway_ApXfeg + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_31 + SequenceFlow_1 + SequenceFlow_123 + SequenceFlow_32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_31 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home + + stop + false + + + start + false +]]> + + + + + + + + + space.name]]> + + + false + + + + + + + SequenceFlow_46 + SequenceFlow_122 + + + SequenceFlow_0 + SequenceFlow_21 + SequenceFlow_125 + SequenceFlow_33 + + + + + + + SequenceFlow_0 + + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus +Zollkurse +]]> + SequenceFlow_38 + SequenceFlow_83 + SequenceFlow_106 + SequenceFlow_104 + SequenceFlow_121 + SequenceFlow_134 + SequenceFlow_37 + SequenceFlow_10 + sequenceFlow_wq0Y0w + + + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +space.name + +cargosoft-export-1.0 +1000 +100 +(?!txtworkflowhistory)(^[a-zA-Z]|^_) + + + stop + false +]]> + + + + + + + + + + + + false + + + 0 && (parseFloat(a)!=parseFloat(b)) ) { + result.isValid=false; + result.errorMessage="Der Rechnungsbetrag " + a+ " stimmt nicht mit dem Positionsbetrag " + b + " überein."; + }]]> + + + + SequenceFlow_8 + SequenceFlow_111 + SequenceFlow_51 + + + DataOutput_1 + + + DataOutput_1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +false]]> + + + + + + + + + + + + false + + + + SequenceFlow_38 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +space.name + +false]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_10 + SequenceFlow_97 + SequenceFlow_110 + + + SequenceFlow_37 + SequenceFlow_8 + SequenceFlow_54 + SequenceFlow_96 + + + + + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_33 + SequenceFlow_95 + SequenceFlow_49 + SequenceFlow_20 + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +suggest +false + + start + false +]]> + + + + + + + + + + + + false + + + + + SequenceFlow_22 + SequenceFlow_77 + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_56 + SequenceFlow_15 + SequenceFlow_24 + SequenceFlow_55 + SequenceFlow_50 + SequenceFlow_81 + SequenceFlow_88 + sequenceFlow_dbshCw + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_29 + SequenceFlow_2 + + + SequenceFlow_32 + SequenceFlow_29 + SequenceFlow_30 + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_30 + SequenceFlow_72 + SequenceFlow_67 + + + + + + + + + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_44 + SequenceFlow_90 + SequenceFlow_47 + sequenceFlow_ucyuIw + sequenceFlow_SvEjiw + + + SequenceFlow_47 + + + + + + + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_55 + SequenceFlow_12 + + + + + + SequenceFlow_18 + SequenceFlow_1 + SequenceFlow_68 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + SequenceFlow_6 + SequenceFlow_18 + + + + SequenceFlow_51 + SequenceFlow_6 + + + + + + + SequenceFlow_126 + + + + + + + + + + + SequenceFlow_12 + SequenceFlow_53 + SequenceFlow_19 + SequenceFlow_25 + + + + + + sepa-export-manual-3.0 +1000 +payment.type +70 +20]]> + + + + + + + + + SequenceFlow_19 + SequenceFlow_23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Rechnungscontrolling +]]> + + + + + + + + + + + + false + + + + SequenceFlow_21 + + + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_26 + SequenceFlow_11 + SequenceFlow_118 + SequenceFlow_132 + SequenceFlow_28 + SequenceFlow_36 + SequenceFlow_127 + sequenceFlow_Dy0E0A + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_26 + + + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +space.name + + stop + false + + + start + false +]]> + + + + + + + + + $owner]]> + + + false + + + + + + + SequenceFlow_28 + SequenceFlow_105 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +space.name +false + + stop + false +]]> + + + + + + + + + + + + true + + + + + + + + + + + SequenceFlow_36 + SequenceFlow_35 + + + SequenceFlow_35 + + + + + + + + + + + SequenceFlow_39 + + + + + + + + + + txtlastcomment]]> + + + + + + + + + numsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_39 + SequenceFlow_59 + SequenceFlow_40 + + + SequenceFlow_40 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + space.name]]> + + + false + + + + SequenceFlow_11 + + + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_23 + SequenceFlow_41 + SequenceFlow_14 + sequenceFlow_swRy5A + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + SequenceFlow_14 + SequenceFlow_42 + + + + + + + + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_42 + SequenceFlow_3 + SequenceFlow_43 + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + + + + false + + + + SequenceFlow_43 + SequenceFlow_5 + SequenceFlow_44 + + + + + + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + + + + false + + + + + + + + + + + + + + + SequenceFlow_50 + SequenceFlow_53 + + + + + + + + + + + + + + + + cdtr.name invoice.number]]> + + + + + + + + + cdtr.name +Rechnungsnummer: invoice.number +Betrag: invoice.total invoice.currency + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + + + + + + + SequenceFlow_54 + SequenceFlow_7 + + + + + + + SequenceFlow_63 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + numsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_17 + SequenceFlow_60 + SequenceFlow_9 + + + SequenceFlow_9 + + + + + + + SequenceFlow_17 + + + + + + + + SequenceFlow_20 + SequenceFlow_65 + SequenceFlow_71 + SequenceFlow_22 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +Wollen Sie den Vorgang wirklich löschen? + + stop + false + +cancel]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_49 + SequenceFlow_76 + SequenceFlow_48 + + + SequenceFlow_48 + + + + + + + + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_2 + SequenceFlow_78 + SequenceFlow_89 + SequenceFlow_72 + SequenceFlow_86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + SequenceFlow_60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + SequenceFlow_59 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + suggest +false + + gutschriftabgleich-de-1.0 + 5001 + 980 + ]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_65 + SequenceFlow_69 + + + + + + + + + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_69 + SequenceFlow_70 + + + + + + SequenceFlow_70 + + + + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + numsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_4 + SequenceFlow_34 + SequenceFlow_119 + SequenceFlow_5 + + + + workitem['payment.type'][0]=="no_sepa" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_7 + SequenceFlow_62 + SequenceFlow_61 + SequenceFlow_73 + + + + + + + + + + + cdtr.name invoice.number]]> + + + + + + + + + cdtr.name +Rechnungsnummer: invoice.number +Betrag: invoice.total invoice.currency + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +Wollen Sie den Vorgang wirklich archivieren? +cancel]]> + + + + + + + + + + + + false + + + + + + + + SequenceFlow_61 + SequenceFlow_63 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_62 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_56 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + suggest +false + + rechnungseingang-sachrechnung-de-1.0 + 5001 + 980 + ]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_71 + SequenceFlow_64 + + + + + + + + + txtlastcomment]]> + + + + + + + + + cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_64 + SequenceFlow_66 + + + SequenceFlow_66 + + + + + + + + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgcdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_74 + SequenceFlow_77 + SequenceFlow_126 + SequenceFlow_46 + SequenceFlow_85 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + + SequenceFlow_74 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +space.name +false]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_73 + SequenceFlow_75 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_78 + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_79 + SequenceFlow_124 + SequenceFlow_131 + SequenceFlow_57 + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + + + + false + + + + SequenceFlow_57 + SequenceFlow_58 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_79 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +Wollen Sie den Vorgang wirklich löschen?]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_81 + SequenceFlow_80 + + + SequenceFlow_80 + + + + + + + + + + + SequenceFlow_82 + + + + + + + + + txtlastcomment +numsequencenumber_sub]]> + + + + + + + + + numsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_84 + SequenceFlow_87 + SequenceFlow_82 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + SequenceFlow_84 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_86 + SequenceFlow_87 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_88 + SequenceFlow_89 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_83 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +Wollen Sie den Vorgang wirklich archivieren? + + stop + false + +cancel]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_16 + SequenceFlow_13 + + + SequenceFlow_13 + + + + + + + + + + + SequenceFlow_85 + SequenceFlow_76 + SequenceFlow_16 + SequenceFlow_116 + + + + + + + SequenceFlow_90 + + + + + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +space.name]]> + + + + + + + + + $owner]]> + + + false + + + + + + + SequenceFlow_96 + SequenceFlow_120 + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_91 + SequenceFlow_92 + SequenceFlow_94 + SequenceFlow_117 + SequenceFlow_100 + SequenceFlow_101 + SequenceFlow_93 + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_102 + SequenceFlow_114 + SequenceFlow_109 + SequenceFlow_112 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_94 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_92 + + + + + + + + + + + + SequenceFlow_101 + SequenceFlow_98 + SequenceFlow_111 + + + + + + + + + cdtr.name invoice.number]]> + + + + + + + + + cdtr.name +Rechnungsnummer: invoice.number +Betrag: invoice.total invoice.currency + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false]]> + + + + + + + + + + + + false + + + + + + + + + + SequenceFlow_98 + SequenceFlow_102 + + + + + + + + + + + + + + + + + + cdtr.name invoice.number]]> + + + + + + + + + cdtr.name +Rechnungsnummer: invoice.number +Betrag: invoice.total invoice.currency + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +false +Wollen Sie den Vorgang wirklich archivieren? +cancel]]> + + + + + + + + + + + + false + + + + + + + + SequenceFlow_109 + SequenceFlow_108 + + + + SequenceFlow_108 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home +space.name +false]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_112 + SequenceFlow_113 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_114 + + + + + + + + + + + + + + + + + + + + space.name)]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + Message-Eskalation +]]> + + + + + + + + + SequenceFlow_99 + SequenceFlow_103 + + + + + + + + SequenceFlow_93 + SequenceFlow_97 + SequenceFlow_99 + + + + + + + + + + + + + SequenceFlow_105 + SequenceFlow_106 + SequenceFlow_107 + + + + + + + + + + workitem['sb.assist'] + && ( workitem['sb.assist'][0]!="-" && workitem['sb.assist'][0]!="") + + + + SequenceFlow_103 + + + + + SequenceFlow_110 + + + + + + + + SequenceFlow_113 + SequenceFlow_107 + SequenceFlow_117 + + + + + + + SequenceFlow_118 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_34 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_41 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + posteingang-de-2.0 + 120 + 1 +]]> + + + + + + + + + + + + false + + + SequenceFlow_95 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false +]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false +]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_104 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + stop + false +]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_116 + SequenceFlow_115 + + + SequenceFlow_115 + + + + + + + + + + + + + + + + + + + SequenceFlow_119 + + + DataOutput_2 + + + DataOutput_2 + + + + + + + + + SequenceFlow_120 + SequenceFlow_91 + SequenceFlow_121 + + + + + + + + + + + + + + SequenceFlow_67 + SequenceFlow_4 + SequenceFlow_15 + + + + + + + + + + + + + + + + + + SequenceFlow_123 + + + DataOutput_3 + + + DataOutput_3 + + + + + + + + + + + + + + + + + SequenceFlow_124 + + + DataOutput_4 + + + DataOutput_4 + + + + + + + + + SequenceFlow_125 + + + + + + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$editor +space.name + + stop + false + + + start + false +]]> + + + + + + + + + $owner]]> + + + true + + + + + + + + + + + SequenceFlow_127 + SequenceFlow_128 + + + + + + + + + + + + + + txtlastcomment]]> + + + + + + + + + _imgnumsequencenumber: cdtr.name invoice.number (invoice.currency invoice.total) space.name]]> + + + true + + + + + + + + + + + + + + + + + $workflowgroup - $workflowstatus]]> + SequenceFlow_68 + SequenceFlow_129 + SequenceFlow_133 + SequenceFlow_130 + + + + + + + + + + + _subject]]> + + + + + + + + + _amount (Brutto € _amount_brutto) +_description]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home]]> + + + + + + + + + + + + false + + + + + + + SequenceFlow_130 + SequenceFlow_131 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + SequenceFlow_129 + + + + + + + + + + + + SequenceFlow_122 + SequenceFlow_132 + SequenceFlow_135 + + + + + + + + + + SequenceFlow_75 + SequenceFlow_128 + SequenceFlow_136 + SequenceFlow_134 + + + + + + + + + sb.team]]> + + + + + + SequenceFlow_135 + SequenceFlow_136 + + + + workitem['sb.team'] + && ( workitem['sb.team'][0]!="-" && workitem['sb.team'][0]!="") + + + + + + + + + + + + + + + + + + SequenceFlow_24 + + + DataOutput_5 + + + DataOutput_5 + + + + + + + + + + + + + + + + + SequenceFlow_133 + + + DataOutput_6 + + + DataOutput_6 + + + + + + + + + + + + Es handelt sich um einen SEPA Lauf. Die Rechnung muss explizit freigegeben werden. + Ändern von IBAN und Fälligkeit ist hier möglich + + + + + + + Datenübergabe an Cargosoft. + + Export erfolgt über eine asynchrone Verarbeitung im Modell 'cargosoft-export' + + + + + + + + + + Liegt eine Logistik Leistung vor, wird ein Fachbereich ausgewählt + + + + + + + Buchhaltung setzt Flag, wenn Mahnung eingetroffen ist + + + + + + + + + + + + + + + + + + + Auslandszahlungen werden gleich ausgeführt + + + + + + + + + payment.type ]]> + + + + + + + + + + + + sequenceFlow_swRy5A + sequenceFlow_dbshCw + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + false + + + + + + + sequenceFlow_ucyuIw + + + + + + + + + + + + + + space.name)]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + Message-Eskalation +]]> + + + + + + + + + + + sequenceFlow_wq0Y0w + sequenceFlow_iH4SSA + + + + + + + + sequenceFlow_iH4SSA + + + + + + + + + + + + + + space.name)]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + Message-Eskalation +]]> + + + + + + + + + + + sequenceFlow_Dy0E0A + + + + + + + SequenceFlow_25 + sequenceFlow_SvEjiw + SequenceFlow_58 + + + + + + + + + + space.name +Kreditor: cdtr.name +Rechnungsnummer: invoice.number +Betrag: invoice.total invoice.currency + +application.urlindex.jsf?workitem=$uniqueid + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/sepa-export-manual-3.0.0.bpmn b/workflow/sepa-export-manual-3.0.0.bpmn index b774774..38fdf5e 100644 --- a/workflow/sepa-export-manual-3.0.0.bpmn +++ b/workflow/sepa-export-manual-3.0.0.bpmn @@ -54,10 +54,10 @@ - + - + IntermediateCatchEvent_6 @@ -800,7 +800,7 @@ result.isValid=true; - + @@ -859,7 +859,7 @@ result.isValid=true; - + @@ -1012,7 +1012,7 @@ result.isValid=true; - + @@ -1073,7 +1073,7 @@ result.isValid=true; - + @@ -1106,7 +1106,7 @@ result.isValid=true; - + @@ -1140,9 +1140,9 @@ result.isValid=true; - - - + + + @@ -1158,21 +1158,21 @@ result.isValid=true; - - - + + + - + - + @@ -1188,19 +1188,19 @@ result.isValid=true; - + - + - + - - - + + +