From 90d624d5857bc794d2b4c98a6e1cfbe6ff638f78 Mon Sep 17 00:00:00 2001 From: Ralph Soika Date: Thu, 13 Feb 2025 18:23:07 +0100 Subject: [PATCH] =?UTF-8?q?BusinessPartner=20Suche=20=C3=BCber=20Rest=20AP?= =?UTF-8?q?I?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/BUSINESSPARTNER.md | 39 ++ doc/images/businesspartner-widget.png | Bin 0 -> 7702 bytes docker-compose.yml | 5 + .../BusinessPartnerController.java | 64 +-- .../BusinessPartnerService.java | 182 ++++++- .../api/BusinessPartnerRestService.java | 104 ++++ .../xml/BusinessPartnerImportService.java | 60 ++- ...=> section_businesspartner_banklist.xhtml} | 0 pom.xml | 2 +- workflow/businesspartner-de-1.0.0.bpmn | 479 ++++++++++++++---- .../rechnungseingang-de-1.2.40-debug_BP.bpmn | 4 +- 11 files changed, 766 insertions(+), 173 deletions(-) create mode 100644 doc/BUSINESSPARTNER.md create mode 100644 doc/images/businesspartner-widget.png create mode 100644 office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/BusinessPartnerRestService.java rename office-alexander-logistics-app/src/main/webapp/pages/workitems/forms/alexander/{sub_businesspartner_ibanlist.xhtml => section_businesspartner_banklist.xhtml} (100%) diff --git a/doc/BUSINESSPARTNER.md b/doc/BUSINESSPARTNER.md new file mode 100644 index 0000000..7a9b900 --- /dev/null +++ b/doc/BUSINESSPARTNER.md @@ -0,0 +1,39 @@ +# 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"); +``` diff --git a/doc/images/businesspartner-widget.png b/doc/images/businesspartner-widget.png new file mode 100644 index 0000000000000000000000000000000000000000..2aab829425f7902d2472eb312c7d06bdb1d60458 GIT binary patch literal 7702 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 var3 = this.ibanList.iterator(); - - while (var3.hasNext()) { - ItemCollection orderItem = (ItemCollection) var3.next(); - mapOrderItems.add(orderItem.getAllItems()); - } - - workitem.replaceItemValue("partner.iban.list", mapOrderItems); - } - - } - - 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); - - } - } - - } - - /** - * Liefert die ChildItems mit den IBAN daten - * - * @param workitem - * @return - */ - public List getIBANList(ItemCollection workitem) { - List result = 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); - result.add(itemCol); - } - } - return result; - } - /** * Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen * BusinessPartner erzeugt. @@ -269,7 +214,7 @@ public class BusinessPartnerController implements Serializable { // get iban list // {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]} - ibanList = getIBANList(businessPartner); + ibanList = BusinessPartnerService.getBanks(businessPartner); int i = 1; for (ItemCollection iban : ibanList) { objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). // @@ -299,4 +244,5 @@ public class BusinessPartnerController implements Serializable { val = val.replace("'", ""); return val; } + } 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 index 70b8571..8533054 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java @@ -27,16 +27,24 @@ package com.alexanderlogistics; +import java.io.UnsupportedEncodingException; 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.melman.DocumentClient; +import org.imixs.melman.FormAuthenticator; +import org.imixs.melman.RestAPIException; 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; @@ -62,15 +70,79 @@ import jakarta.inject.Inject; 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()); + private FormAuthenticator formAuthenticator; + @Inject - DocumentService documentService; + @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() { + // init clients + try { + initAuthenticator(); + } catch (RestAPIException e) { + logger.severe("Failed to initalize Rest Clients: " + e.getMessage()); + } + } + + /** + * Diese Methode sucht einen Business Partner anhand seiner BPID + * + * @param bpid + * - business partner id phrase + * @return - matching business partner + */ + public ItemCollection getBusinessPartnerByID(String bpid) { + long l = System.currentTimeMillis(); + if (bpid == null || bpid.isEmpty()) { + return null; + } + List result; + try { + String sQuery = "(type:\"workitem\") AND ($modelversion:businesspartner-*)"; + sQuery += " AND (name:" + bpid.trim() + ")"; + logger.finest("SearchQuery= " + sQuery); + + // register client + DocumentClient documentClient = getDocumentClient(); + documentClient.setPageSize(MAX_SEARCH_RESULT); + documentClient.setPageSize(1); + result = documentClient.searchDocuments(sQuery); + if (result.size() > 0) { + logger.info("🕐 get BusinessPartner by id in " + (System.currentTimeMillis() - l) + "ms"); + return result.get(0); + } + } catch (RestAPIException | UnsupportedEncodingException e) { + logger.warning("Failed to get BusinessPartner: " + e.getMessage()); + } + return null; + } + /** * Diese Methode sucht Business Partner anhand einer Suchphrase * @@ -79,7 +151,7 @@ public class BusinessPartnerService { * @return - list of matching business partners */ public List search(String phrase) { - + long l = System.currentTimeMillis(); List searchResult = new ArrayList(); if (phrase == null || phrase.isEmpty()) { return searchResult; @@ -94,13 +166,113 @@ public class BusinessPartnerService { logger.finest("SearchQuery= " + sQuery); - searchResult = documentService.find(sQuery, MAX_SEARCH_RESULT, 0); - } catch (Exception e) { + // register client + DocumentClient documentClient = getDocumentClient(); + documentClient.setPageSize(MAX_SEARCH_RESULT); + searchResult = documentClient.searchDocuments(sQuery); + + } catch (RestAPIException | UnsupportedEncodingException e) { logger.warning(" lucene error - " + e.getMessage()); + formAuthenticator = null; } // sort by txtname.. Collections.sort(searchResult, new ItemCollectionComparator("$workflowsummary", true)); + + logger.info("🕐 BusinessPartner search: " + searchResult.size() + " entries in " + + (System.currentTimeMillis() - l) + "ms"); return searchResult; } + + private DocumentClient getDocumentClient() { + DocumentClient documentClient = null; + try { + if (formAuthenticator == null) { + initAuthenticator(); + } + documentClient = new DocumentClient(workflowServiceEndpoint.get()); + documentClient.registerClientRequestFilter(formAuthenticator); + } catch (RestAPIException e) { + logger.warning("Failed to init RestClient: " + e.getMessage()); + formAuthenticator = null; + } + + return documentClient; + } + + /** + * 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; + } + + /** + * Helper method to initalize a Melman FormAuthenticator + * + * @throws RestAPIException + */ + public void initAuthenticator() throws RestAPIException { + logger.info("⚡ Init FormAuthenticator..."); + + // form authenticator + formAuthenticator = new FormAuthenticator(workflowServiceEndpoint.get(), workflowServiceUser.get(), + workflowServicePassword.get()); + + } } diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/BusinessPartnerRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/BusinessPartnerRestService.java new file mode 100644 index 0000000..bf0771c --- /dev/null +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/BusinessPartnerRestService.java @@ -0,0 +1,104 @@ +/* + * Imixs-Workflow + * + * Copyright (C) 2001-2020 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: + * https://www.imixs.org + * https://github.com/imixs/imixs-workflow + * + * Contributors: + * Imixs Software Solutions GmbH - Project Management + * Ralph Soika - Software Developer + */ + +package com.alexanderlogistics.api; + +import java.util.logging.Logger; + +import org.imixs.workflow.ItemCollection; +import org.imixs.workflow.exceptions.QueryException; +import org.imixs.workflow.jaxrs.DocumentRestService; + +import com.alexanderlogistics.BusinessPartnerService; + +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.QueryParam; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +/** + * BusinessPartnerRestService api endpoint '/businesspartner' provides methods + * to read and post business partner data + * + * @version 1.0 + * @author rsoika + * + */ +@Stateless +@Produces({ MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, + MediaType.TEXT_XML }) +@Path("/businesspartner") +public class BusinessPartnerRestService { + + @Inject + DocumentRestService documentRestService; + + @Inject + BusinessPartnerService businessPartnerService; + + private static Logger logger = Logger.getLogger(BusinessPartnerRestService.class.getName()); + + @GET + @Path("/ping") + public String ping() { + logger.info("GET ping"); + return "ping: " + System.currentTimeMillis(); + } + + /** + * Test method + * + * @param workflowgroup + * @param task + * @return + * @throws QueryException + */ + @GET + @Path("/{bpid}") + @Produces({ MediaType.TEXT_HTML }) + public Response getBusinessPartnerByID(@PathParam("bpid") String bpid, + @QueryParam("items") String items, + @QueryParam("format") String format) + throws QueryException { + + ItemCollection workitem = businessPartnerService.getBusinessPartnerByID(bpid); + if (workitem == null) { + // document not found + return Response.status(Response.Status.NOT_FOUND).build(); + } + + return documentRestService.convertResult(workitem, items, format); + + } + +} 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 a91aec8..8c238b6 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 @@ -36,6 +36,7 @@ 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; @@ -46,6 +47,7 @@ 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; @@ -158,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) { @@ -234,7 +262,10 @@ public class BusinessPartnerImportService { } - // build partner.iban.list + // 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++) { @@ -243,10 +274,20 @@ public class BusinessPartnerImportService { 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("id", "bank" + (i + 1)); + bank.setItemValue("name", "Bank " + (i + 1)); bank.setItemValue("iban", iban); bank.setItemValue("bic", bic); @@ -258,7 +299,7 @@ public class BusinessPartnerImportService { ItemCollection orderItem = (ItemCollection) var3.next(); mapOrderItems.add(orderItem.getAllItems()); } - businessPartner.setItemValue("partner.iban.list", mapOrderItems); + businessPartner.setItemValue(BusinessPartnerService.ITEM_IBAN_LIST, mapOrderItems); } } catch (QueryException e) { @@ -269,6 +310,15 @@ public class BusinessPartnerImportService { 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/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 100% 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 diff --git a/pom.xml b/pom.xml index 6f9dd46..f634655 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 10.0.0 - 5.0.4-SNAPSHOT + 5.0.4 6.0.9 5.0.0 3.0.2 diff --git a/workflow/businesspartner-de-1.0.0.bpmn b/workflow/businesspartner-de-1.0.0.bpmn index a2f0880..99777e7 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,30 @@ textAnnotation_LyGTCw event_TuyuwQ event_h0Kk5g + task_delO7Q + event_1OVorA + event_baWU4w + event_ofjVfg + event_i7yQVw + gateway_uK0c6g + event_6250fg - + + + + + + + + + + + + + + sequenceFlow_25otUg sequenceFlow_S9LVXg @@ -63,7 +87,6 @@ - sequenceFlow_NNbMhg sequenceFlow_rwdWxw @@ -77,13 +100,40 @@ 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
@@ -93,34 +143,59 @@ + + 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 - + - - - @@ -128,18 +203,13 @@ - sequenceFlow_2uNvPw sequenceFlow_1mXO8A + sequenceFlow_b0Bj3Q + sequenceFlow_T5L9aQ - - - - - - @@ -174,13 +244,10 @@ - + ]]> - - - sequenceFlow_avahXg @@ -196,10 +263,10 @@ - + - + @@ -207,6 +274,9 @@ + + + sequenceFlow_9atLFA @@ -229,139 +299,346 @@ + + + + + + + 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 +
+ + + + + + + + + + + + + + sequenceFlow_iwMsIg + sequenceFlow_BHsRkQ + + + + + + + + + sequenceFlow_pvIENQ + sequenceFlow_b4BcVA + + + + + + + + + + + + + + + + + + + + + sequenceFlow_BWOtzA + + + + + + + sequenceFlow_ofWWuw + + + + + + + + + + + + + sequenceFlow_S9LVXg + sequenceFlow_jAU3VA + sequenceFlow_iwMsIg + + + + + + + + + + + + + + + + + + + sequenceFlow_kS2fMA + + + +
- + - + - + - + - + - + - + - - + + - + - + - + - + - - - - - - - + + + - + - + - - - - - - - - - - + + - - - + + - + - + - - - - - - + - + - - - - - - - + + + + - - - + + + + - + - - - - - + - + - + - - - - + + + - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn b/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn index 83ab4a1..d747661 100644 --- a/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn +++ b/workflow/rechnungseingang-de-1.2.40-debug_BP.bpmn @@ -5547,8 +5547,8 @@ result.isValid=true; - - + +