neue Code Formatierung

This commit is contained in:
Ralph Soika 2025-05-07 11:37:31 +02:00
parent be064fb965
commit 0f7627419a
93 changed files with 6864 additions and 6078 deletions

210
BPMN-KI-Test/prompt1.txt Normal file
View file

@ -0,0 +1,210 @@
Du bist Prozessberater und Spezialisiert auf die Analyse von BPMN Modellen.
Bitte beschreibe den im folgenden BPMN 2.0 Modell definierten Prozess und erstelle eine kurze Zusammenfassung:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bpmn2:definitions xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:open-bpmn="http://open-bpmn.org/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exporter="org.openbpmn" exporterVersion="1.0.0" targetNamespace="http://open-bpmn.org"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL">
<bpmn2:collaboration id="collaboration_1" name="Default Collaboration">
<bpmn2:participant id="participant_TgW2JA" name="Default Process" processRef="process_1" />
<bpmn2:participant id="participant_tgRhJQ" name="Rechnungseingang" processRef="process_lYaFpg">
<bpmn2:documentation id="documentation_wSfXcQ"><![CDATA[Dieser Workflow dient dazu eingehende Rechnungen zu prüfen und zur Bezahlung weiterzuleiten. Es wird unterschieden von Sachrechnungen, die vom Sekretariat bearbeitet werden können und Cargo-Rechnungen die durch die Logistikabteilung anhand von Logistikaufträgen geprüft werden.
Nachdem die Rechnung bezahlt wurde wird der Vorgang archiviert. ]]></bpmn2:documentation>
</bpmn2:participant>
</bpmn2:collaboration>
<bpmn2:extensionElements>
<open-bpmn:auto-align>true</open-bpmn:auto-align>
</bpmn2:extensionElements>
<bpmn2:process definitionalCollaborationRef="collaboration_1" id="process_1"
name="Default Process" processType="Public">
<bpmn2:documentation id="documentation_wXazVg" />
</bpmn2:process>
<bpmn2:process definitionalCollaborationRef="collaboration_1" id="process_lYaFpg"
isExecutable="true" name="Rechnungseingang" processType="Private">
<bpmn2:laneSet id="laneset_fDygyw" name="Lane Set">
<bpmn2:lane id="lane_BgoDFg" name="Sekretariat">
<bpmn2:documentation id="documentation_hIztzA" />
<bpmn2:flowNodeRef>task_7Y3UUA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_bH7Wag</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_oNXxgg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_GEqHhQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_VJXKGg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_SP75zg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_ASbu1A</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_Vyo0Zw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_xAzhzw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_YH3bnw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_1qR49w</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_fHgZBg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_YnFi7A</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_eMP9Xw" name="Fachbereich">
<bpmn2:documentation id="documentation_6ihnmQ" />
<bpmn2:flowNodeRef>event_A1J0OA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_5lS3mw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_Hn5ZhQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_dJ89xQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_30uUNA</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="event_bH7Wag" name="Start">
<bpmn2:documentation id="documentation_pguolw" />
<bpmn2:outgoing>sequenceFlow_8yitUQ</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="task_7Y3UUA" name="Rechnungsprüfung">
<bpmn2:documentation id="documentation_oKsT5Q"><![CDATA[Inhaltliche Prüufng der Rechnung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_BGVbSA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_FyAf3g</bpmn2:outgoing>
<bpmn2:incoming>sequenceFlow_hvQWmg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_j4GDgg</bpmn2:incoming>
</bpmn2:task>
<bpmn2:endEvent id="event_oNXxgg" name="Ende">
<bpmn2:documentation id="documentation_1heF3g" />
<bpmn2:incoming>sequenceFlow_iVpj0g</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:intermediateCatchEvent id="event_GEqHhQ" name="Import">
<bpmn2:documentation id="documentation_gR2xbw" />
<bpmn2:incoming>sequenceFlow_8yitUQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_BGVbSA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_8yitUQ" sourceRef="event_bH7Wag" targetRef="event_GEqHhQ">
<bpmn2:documentation id="documentation_2Zd0Aw" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_BGVbSA" sourceRef="event_GEqHhQ" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_6k088A" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_VJXKGg" name="Sachrechnung">
<bpmn2:documentation id="documentation_DaDN3w"><![CDATA[Weiterleiten zur Sachprüfung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_rZXh6g</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_sNlWkQ</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:task id="task_SP75zg" name="Budgetprüfung">
<bpmn2:documentation id="documentation_qP2Sew" />
<bpmn2:incoming>sequenceFlow_sNlWkQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_nxZ9bA</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:task id="task_5lS3mw" name="Prüfung Logistik Auftrag">
<bpmn2:documentation id="documentation_zweAkw"><![CDATA[Prüfung der Rechnung und Abgleich mit Logistikauftrag]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_DXGQrw</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_UebylQ</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:eventBasedGateway gatewayDirection="Diverging" id="gateway_ASbu1A" name="">
<bpmn2:documentation id="documentation_09gukg" />
<bpmn2:incoming>sequenceFlow_FyAf3g</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_rZXh6g</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_i7cH2A</bpmn2:outgoing>
</bpmn2:eventBasedGateway>
<bpmn2:sequenceFlow id="sequenceFlow_FyAf3g" sourceRef="task_7Y3UUA" targetRef="gateway_ASbu1A">
<bpmn2:documentation id="documentation_tv00MQ" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_rZXh6g" sourceRef="gateway_ASbu1A" targetRef="event_VJXKGg">
<bpmn2:documentation id="documentation_EPAmhQ" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_sNlWkQ" sourceRef="event_VJXKGg" targetRef="task_SP75zg">
<bpmn2:documentation id="documentation_iXrfpg" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_A1J0OA" name="Cargo Rechnung">
<bpmn2:documentation id="documentation_RWi6LA"><![CDATA[Weiterleitung zur Prüfung Logistikauftrag]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_i7cH2A</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_DXGQrw</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_i7cH2A" sourceRef="gateway_ASbu1A" targetRef="event_A1J0OA">
<bpmn2:documentation id="documentation_pz6J4g" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_DXGQrw" sourceRef="event_A1J0OA" targetRef="task_5lS3mw">
<bpmn2:documentation id="documentation_ngSLdQ" />
</bpmn2:sequenceFlow>
<bpmn2:exclusiveGateway gatewayDirection="Diverging" id="gateway_Vyo0Zw" name="">
<bpmn2:documentation id="documentation_Pm90XA" />
<bpmn2:incoming>sequenceFlow_nxZ9bA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_9tp42Q</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_h4SfiQ</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:intermediateCatchEvent id="event_dJ89xQ" name="Freigabe">
<bpmn2:documentation id="documentation_sB06Ag"><![CDATA[Rechnung in Ordnung und freigegeben zur Bezahlung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_PLk0RA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_A0FQoA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:exclusiveGateway gatewayDirection="Diverging" id="gateway_Hn5ZhQ" name="">
<bpmn2:documentation id="documentation_aLEQqQ" />
<bpmn2:incoming>sequenceFlow_UebylQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_PLk0RA</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_xVEjcA</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="sequenceFlow_UebylQ" sourceRef="task_5lS3mw" targetRef="gateway_Hn5ZhQ">
<bpmn2:documentation id="documentation_MZdr7Q" />
</bpmn2:sequenceFlow>
<bpmn2:task id="task_xAzhzw" name="Bezahlung">
<bpmn2:documentation id="documentation_zO3SRw" />
<bpmn2:incoming>sequenceFlow_9OrwEg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_A0FQoA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_OfKNWA</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="sequenceFlow_nxZ9bA" sourceRef="task_SP75zg" targetRef="gateway_Vyo0Zw">
<bpmn2:documentation id="documentation_G4qmmA" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_PLk0RA" sourceRef="gateway_Hn5ZhQ" targetRef="event_dJ89xQ">
<bpmn2:documentation id="documentation_Y5qwSA" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_YH3bnw" name="Freigeben">
<bpmn2:documentation id="documentation_C05Bhw"><![CDATA[Rechnung in Ordnung und freigegeben zur Bezahlung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_9tp42Q</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_9OrwEg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_9tp42Q" sourceRef="gateway_Vyo0Zw" targetRef="event_YH3bnw">
<bpmn2:documentation id="documentation_PIQaSg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_9OrwEg" sourceRef="event_YH3bnw" targetRef="task_xAzhzw">
<bpmn2:documentation id="documentation_0eagTw" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_1qR49w" name="Ablehnen">
<bpmn2:documentation id="documentation_cdpcXA" />
<bpmn2:incoming>sequenceFlow_h4SfiQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_hvQWmg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:intermediateCatchEvent id="event_30uUNA" name="Ablehnen">
<bpmn2:documentation id="documentation_VazNUA" />
<bpmn2:incoming>sequenceFlow_xVEjcA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_j4GDgg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_h4SfiQ" sourceRef="gateway_Vyo0Zw" targetRef="event_1qR49w">
<bpmn2:documentation id="documentation_Q2yPDw" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_hvQWmg" sourceRef="event_1qR49w" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_qkneSw" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_xVEjcA" sourceRef="gateway_Hn5ZhQ" targetRef="event_30uUNA">
<bpmn2:documentation id="documentation_l9waIg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_j4GDgg" sourceRef="event_30uUNA" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_4vaLww" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_A0FQoA" sourceRef="event_dJ89xQ" targetRef="task_xAzhzw">
<bpmn2:documentation id="documentation_fAB90Q" />
</bpmn2:sequenceFlow>
<bpmn2:task id="task_fHgZBg" name="Archiviert">
<bpmn2:documentation id="documentation_Idessw"><![CDATA[Rechnungsprüfung abgeschlossen und Rechnung archiveirt.]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_A0FQoA</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_sUEtcA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_iVpj0g</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:intermediateCatchEvent id="event_YnFi7A" name="Bezahlt">
<bpmn2:documentation id="documentation_Jz0LKg"><![CDATA[Rechnungsbetrag wurde überwiesen]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_OfKNWA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_sUEtcA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_OfKNWA" sourceRef="task_xAzhzw" targetRef="event_YnFi7A">
<bpmn2:documentation id="documentation_DdJpCg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_sUEtcA" sourceRef="event_YnFi7A" targetRef="task_fHgZBg">
<bpmn2:documentation id="documentation_uG0SGg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_iVpj0g" sourceRef="task_fHgZBg" targetRef="event_oNXxgg">
<bpmn2:documentation id="documentation_Is0LqQ" />
</bpmn2:sequenceFlow>
</bpmn2:process>
</bpmn2:definitions>

11
BPMN-KI-Test/prompt2.txt Normal file
View file

@ -0,0 +1,11 @@
Wir haben einen Geschäftsprozess für die Eingangsrechnungsprüfung in einem Unternehmen.
Rechnungen werden importiert und dann zur "Rechnungsprüfung" geleitet. Dieser Zusstand ist in einem BPMN 2.0 Diagram als Task Element abgebildet.
Der Mitarbeiter hat nun über die beiden Aktionen "Sachrechnung" und "Cargorechnung" die Möglichkeit die Rechnung zu klassifizieren. Diese beiden Aktionen sind in einem
BPMN 2.0 Diagram als Event Elemente dargestellt. Das Event 'Sachrechnung' führt zum Status (Task) "Budgetprüfung" (die vom Sekretariat durchgeführt wird)
und das Event 'Cargorechnung' führt zum Status 'Prüfung Logistikauftrag' (die vom Fachbereich durchgeführt werden kann). In beiden Zuständen kann nun der Mitarbeiter die Rechnung
über das Event "Freigeben" zur Bezahlung freigeben (Task) oder mit "Ablehnen" zurück an die initiale "Rechnungsprüfung" zurücksenden. Nach der Bezahlung kann der Mitarbeiter
die Rechnung über die Aktion (Event) "Bezahlt" in den finalen Status (Task) 'Archiviert' senden.
In einem BPMN Diagram sind diese Verzweigungen bei den Entscheidungen mit Gateways dargestellt.
Erstelle für diesen Prozessablauf eine sehr kompakte Darstellungsform, die für ein KI Prompt Template geeignet ist.

View file

@ -0,0 +1,389 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bpmn2:definitions xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:open-bpmn="http://open-bpmn.org/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exporter="org.openbpmn" exporterVersion="1.0.0" targetNamespace="http://open-bpmn.org" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL">
<bpmn2:collaboration id="collaboration_1" name="Default Collaboration">
<bpmn2:participant id="participant_TgW2JA" name="Default Process" processRef="process_1"/>
<bpmn2:participant id="participant_tgRhJQ" name="Rechnungseingang" processRef="process_lYaFpg">
<bpmn2:documentation id="documentation_wSfXcQ"><![CDATA[Dieser Workflow dient dazu eingehende Rechnungen zu prüfen und zur Bezahlung weiterzuleiten. Es wird unterschieden von Sachrechnungen, die vom Sekretariat bearbeitet werden können und Cargo-Rechnungen die durch die Logistikabteilung anhand von Logistikaufträgen geprüft werden.
Nachdem die Rechnung bezahlt wurde wird der Vorgang archiviert. ]]></bpmn2:documentation>
</bpmn2:participant>
</bpmn2:collaboration>
<bpmn2:extensionElements>
<open-bpmn:auto-align>true</open-bpmn:auto-align>
</bpmn2:extensionElements>
<bpmn2:process definitionalCollaborationRef="collaboration_1" id="process_1" name="Default Process" processType="Public">
<bpmn2:documentation id="documentation_wXazVg"/>
</bpmn2:process>
<bpmn2:process definitionalCollaborationRef="collaboration_1" id="process_lYaFpg" isExecutable="true" name="Rechnungseingang" processType="Private">
<bpmn2:laneSet id="laneset_fDygyw" name="Lane Set">
<bpmn2:lane id="lane_BgoDFg" name="Sekretariat">
<bpmn2:documentation id="documentation_hIztzA"/>
<bpmn2:flowNodeRef>task_7Y3UUA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_bH7Wag</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_oNXxgg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_GEqHhQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_VJXKGg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_SP75zg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_ASbu1A</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_Vyo0Zw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_xAzhzw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_YH3bnw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_1qR49w</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_fHgZBg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_YnFi7A</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_eMP9Xw" name="Fachbereich">
<bpmn2:documentation id="documentation_6ihnmQ"/>
<bpmn2:flowNodeRef>event_A1J0OA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_5lS3mw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_Hn5ZhQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_dJ89xQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_30uUNA</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="event_bH7Wag" name="Start">
<bpmn2:documentation id="documentation_pguolw"/>
<bpmn2:outgoing>sequenceFlow_8yitUQ</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="task_7Y3UUA" name="Rechnungsprüfung">
<bpmn2:documentation id="documentation_oKsT5Q"><![CDATA[Inhaltliche Prüufng der Rechnung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_BGVbSA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_FyAf3g</bpmn2:outgoing>
<bpmn2:incoming>sequenceFlow_hvQWmg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_j4GDgg</bpmn2:incoming>
</bpmn2:task>
<bpmn2:endEvent id="event_oNXxgg" name="Ende">
<bpmn2:documentation id="documentation_1heF3g"/>
<bpmn2:incoming>sequenceFlow_iVpj0g</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:intermediateCatchEvent id="event_GEqHhQ" name="Import">
<bpmn2:documentation id="documentation_gR2xbw"/>
<bpmn2:incoming>sequenceFlow_8yitUQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_BGVbSA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_8yitUQ" sourceRef="event_bH7Wag" targetRef="event_GEqHhQ">
<bpmn2:documentation id="documentation_2Zd0Aw"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_BGVbSA" sourceRef="event_GEqHhQ" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_6k088A"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_VJXKGg" name="Sachrechnung">
<bpmn2:documentation id="documentation_DaDN3w"><![CDATA[Weiterleiten zur Sachprüfung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_rZXh6g</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_sNlWkQ</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:task id="task_SP75zg" name="Budgetprüfung">
<bpmn2:documentation id="documentation_qP2Sew"/>
<bpmn2:incoming>sequenceFlow_sNlWkQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_nxZ9bA</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:task id="task_5lS3mw" name="Prüfung Logistik Auftrag">
<bpmn2:documentation id="documentation_zweAkw"><![CDATA[Prüfung der Rechnung und Abgleich mit Logistikauftrag]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_DXGQrw</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_UebylQ</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:eventBasedGateway gatewayDirection="Diverging" id="gateway_ASbu1A" name="">
<bpmn2:documentation id="documentation_09gukg"/>
<bpmn2:incoming>sequenceFlow_FyAf3g</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_rZXh6g</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_i7cH2A</bpmn2:outgoing>
</bpmn2:eventBasedGateway>
<bpmn2:sequenceFlow id="sequenceFlow_FyAf3g" sourceRef="task_7Y3UUA" targetRef="gateway_ASbu1A">
<bpmn2:documentation id="documentation_tv00MQ"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_rZXh6g" sourceRef="gateway_ASbu1A" targetRef="event_VJXKGg">
<bpmn2:documentation id="documentation_EPAmhQ"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_sNlWkQ" sourceRef="event_VJXKGg" targetRef="task_SP75zg">
<bpmn2:documentation id="documentation_iXrfpg"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_A1J0OA" name="Cargo Rechnung">
<bpmn2:documentation id="documentation_RWi6LA"><![CDATA[Weiterleitung zur Prüfung Logistikauftrag]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_i7cH2A</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_DXGQrw</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_i7cH2A" sourceRef="gateway_ASbu1A" targetRef="event_A1J0OA">
<bpmn2:documentation id="documentation_pz6J4g"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_DXGQrw" sourceRef="event_A1J0OA" targetRef="task_5lS3mw">
<bpmn2:documentation id="documentation_ngSLdQ"/>
</bpmn2:sequenceFlow>
<bpmn2:exclusiveGateway gatewayDirection="Diverging" id="gateway_Vyo0Zw" name="">
<bpmn2:documentation id="documentation_Pm90XA"/>
<bpmn2:incoming>sequenceFlow_nxZ9bA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_9tp42Q</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_h4SfiQ</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:intermediateCatchEvent id="event_dJ89xQ" name="Freigabe">
<bpmn2:documentation id="documentation_sB06Ag"><![CDATA[Rechnung in Ordnung und freigegeben zur Bezahlung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_PLk0RA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_A0FQoA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:exclusiveGateway gatewayDirection="Diverging" id="gateway_Hn5ZhQ" name="">
<bpmn2:documentation id="documentation_aLEQqQ"/>
<bpmn2:incoming>sequenceFlow_UebylQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_PLk0RA</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_xVEjcA</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="sequenceFlow_UebylQ" sourceRef="task_5lS3mw" targetRef="gateway_Hn5ZhQ">
<bpmn2:documentation id="documentation_MZdr7Q"/>
</bpmn2:sequenceFlow>
<bpmn2:task id="task_xAzhzw" name="Bezahlung">
<bpmn2:documentation id="documentation_zO3SRw"/>
<bpmn2:incoming>sequenceFlow_9OrwEg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_A0FQoA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_OfKNWA</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="sequenceFlow_nxZ9bA" sourceRef="task_SP75zg" targetRef="gateway_Vyo0Zw">
<bpmn2:documentation id="documentation_G4qmmA"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_PLk0RA" sourceRef="gateway_Hn5ZhQ" targetRef="event_dJ89xQ">
<bpmn2:documentation id="documentation_Y5qwSA"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_YH3bnw" name="Freigeben">
<bpmn2:documentation id="documentation_C05Bhw"><![CDATA[Rechnung in Ordnung und freigegeben zur Bezahlung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_9tp42Q</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_9OrwEg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_9tp42Q" sourceRef="gateway_Vyo0Zw" targetRef="event_YH3bnw">
<bpmn2:documentation id="documentation_PIQaSg"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_9OrwEg" sourceRef="event_YH3bnw" targetRef="task_xAzhzw">
<bpmn2:documentation id="documentation_0eagTw"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_1qR49w" name="Ablehnen">
<bpmn2:documentation id="documentation_cdpcXA"/>
<bpmn2:incoming>sequenceFlow_h4SfiQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_hvQWmg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:intermediateCatchEvent id="event_30uUNA" name="Ablehnen">
<bpmn2:documentation id="documentation_VazNUA"/>
<bpmn2:incoming>sequenceFlow_xVEjcA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_j4GDgg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_h4SfiQ" sourceRef="gateway_Vyo0Zw" targetRef="event_1qR49w">
<bpmn2:documentation id="documentation_Q2yPDw"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_hvQWmg" sourceRef="event_1qR49w" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_qkneSw"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_xVEjcA" sourceRef="gateway_Hn5ZhQ" targetRef="event_30uUNA">
<bpmn2:documentation id="documentation_l9waIg"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_j4GDgg" sourceRef="event_30uUNA" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_4vaLww"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_A0FQoA" sourceRef="event_dJ89xQ" targetRef="task_xAzhzw">
<bpmn2:documentation id="documentation_fAB90Q"/>
</bpmn2:sequenceFlow>
<bpmn2:task id="task_fHgZBg" name="Archiviert">
<bpmn2:documentation id="documentation_Idessw"><![CDATA[Rechnungsprüfung abgeschlossen und Rechnung archiveirt.]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_A0FQoA</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_sUEtcA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_iVpj0g</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:intermediateCatchEvent id="event_YnFi7A" name="Bezahlt">
<bpmn2:documentation id="documentation_Jz0LKg"><![CDATA[Rechnungsbetrag wurde überwiesen]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_OfKNWA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_sUEtcA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_OfKNWA" sourceRef="task_xAzhzw" targetRef="event_YnFi7A">
<bpmn2:documentation id="documentation_DdJpCg"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_sUEtcA" sourceRef="event_YnFi7A" targetRef="task_fHgZBg">
<bpmn2:documentation id="documentation_uG0SGg"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_iVpj0g" sourceRef="task_fHgZBg" targetRef="event_oNXxgg">
<bpmn2:documentation id="documentation_Is0LqQ"/>
</bpmn2:sequenceFlow>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1" name="OpenBPMN Diagram">
<bpmndi:BPMNPlane bpmnElement="collaboration_1" id="BPMNPlane_1">
<bpmndi:BPMNShape bpmnElement="event_bH7Wag" id="BPMNShape_uh055A">
<dc:Bounds height="36.0" width="36.0" x="307.0" y="-233.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_iQJHWQ">
<dc:Bounds height="20.0" width="100.0" x="275.0" y="-194.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="event_oNXxgg" id="BPMNShape_UInW7g">
<dc:Bounds height="36.0" width="36.0" x="1777.0" y="-233.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_34qp2g">
<dc:Bounds height="20.0" width="100.0" x="1745.0" y="-194.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="task_7Y3UUA" id="BPMNShape_6O8H3A">
<dc:Bounds height="50.0" width="110.0" x="520.0" y="-240.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="participant_tgRhJQ" id="BPMNShape_nrps0Q">
<dc:Bounds height="630.0" width="1650.0" x="230.0" y="-370.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="lane_BgoDFg" id="BPMNShape_Lane_D1gWUg">
<dc:Bounds height="258.0" width="1620.0" x="260.0" y="-370.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="lane_eMP9Xw" id="BPMNShape_Lane_j8rKkg">
<dc:Bounds height="372.0" width="1620.0" x="260.0" y="-112.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="event_GEqHhQ" id="BPMNShape_NYeOlw">
<dc:Bounds height="36.0" width="36.0" x="397.0" y="-233.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_u0gAdw">
<dc:Bounds height="20.0" width="100.0" x="365.0" y="-194.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_8yitUQ" id="BPMNEdge_SKFqeQ" sourceElement="BPMNShape_uh055A" targetElement="BPMNShape_NYeOlw">
<di:waypoint x="343.0" y="-215.0"/>
<di:waypoint x="397.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_BGVbSA" id="BPMNEdge_qcdmuA" sourceElement="BPMNShape_NYeOlw" targetElement="BPMNShape_6O8H3A">
<di:waypoint x="433.0" y="-215.0"/>
<di:waypoint x="520.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_VJXKGg" id="BPMNShape_QCvdOw">
<dc:Bounds height="36.0" width="36.0" x="797.0" y="-233.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_6j9aVg">
<dc:Bounds height="20.0" width="100.0" x="765.0" y="-194.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="task_SP75zg" id="BPMNShape_dnAc8g">
<dc:Bounds height="50.0" width="110.0" x="930.0" y="-240.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="task_5lS3mw" id="BPMNShape_VFDbeg">
<dc:Bounds height="50.0" width="110.0" x="920.0" y="0.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="gateway_ASbu1A" id="BPMNShape_LIkiBA">
<dc:Bounds height="50.0" width="50.0" x="680.0" y="-240.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_uZQpOQ">
<dc:Bounds height="20.0" width="100.0" x="655.0" y="-187.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_FyAf3g" id="BPMNEdge_F0Y1Tw" sourceElement="BPMNShape_6O8H3A" targetElement="BPMNShape_LIkiBA">
<di:waypoint x="630.0" y="-215.0"/>
<di:waypoint x="680.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_rZXh6g" id="BPMNEdge_luL2IA" sourceElement="BPMNShape_LIkiBA" targetElement="BPMNShape_QCvdOw">
<di:waypoint x="730.0" y="-215.0"/>
<di:waypoint x="797.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_sNlWkQ" id="BPMNEdge_vB8usw" sourceElement="BPMNShape_QCvdOw" targetElement="BPMNShape_dnAc8g">
<di:waypoint x="833.0" y="-215.0"/>
<di:waypoint x="930.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_A1J0OA" id="BPMNShape_KJbgeQ">
<dc:Bounds height="36.0" width="36.0" x="787.0" y="7.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_Rmen0A">
<dc:Bounds height="20.0" width="100.0" x="755.0" y="46.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_i7cH2A" id="BPMNEdge_HBLd5A" sourceElement="BPMNShape_LIkiBA" targetElement="BPMNShape_KJbgeQ">
<di:waypoint x="703.0" y="-192.0"/>
<di:waypoint x="703.0" y="25.0"/>
<di:waypoint x="787.0" y="25.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_DXGQrw" id="BPMNEdge_s15wBA" sourceElement="BPMNShape_KJbgeQ" targetElement="BPMNShape_VFDbeg">
<di:waypoint x="823.0" y="25.0"/>
<di:waypoint x="920.0" y="25.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="gateway_Vyo0Zw" id="BPMNShape_QihA6g">
<dc:Bounds height="50.0" width="50.0" x="1090.0" y="-240.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_cyvcMA">
<dc:Bounds height="20.0" width="100.0" x="1065.0" y="-187.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="event_dJ89xQ" id="BPMNShape_4M1lNg">
<dc:Bounds height="36.0" width="36.0" x="1187.0" y="7.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_gdYGpg">
<dc:Bounds height="20.0" width="100.0" x="1155.0" y="46.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="gateway_Hn5ZhQ" id="BPMNShape_mr0ibw">
<dc:Bounds height="50.0" width="50.0" x="1080.0" y="0.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_5l4dRA">
<dc:Bounds height="20.0" width="100.0" x="1055.0" y="53.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_UebylQ" id="BPMNEdge_U0wIKg" sourceElement="BPMNShape_VFDbeg" targetElement="BPMNShape_mr0ibw">
<di:waypoint x="1030.0" y="25.0"/>
<di:waypoint x="1080.0" y="25.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="task_xAzhzw" id="BPMNShape_JrIJDQ">
<dc:Bounds height="50.0" width="110.0" x="1290.0" y="-240.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_nxZ9bA" id="BPMNEdge_KKXvFg" sourceElement="BPMNShape_dnAc8g" targetElement="BPMNShape_QihA6g">
<di:waypoint x="1040.0" y="-215.0"/>
<di:waypoint x="1090.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_PLk0RA" id="BPMNEdge_8UEsHA" sourceElement="BPMNShape_mr0ibw" targetElement="BPMNShape_4M1lNg">
<di:waypoint x="1130.0" y="25.0"/>
<di:waypoint x="1187.0" y="25.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_YH3bnw" id="BPMNShape_GUBmSg">
<dc:Bounds height="36.0" width="36.0" x="1197.0" y="-233.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_c48Mng">
<dc:Bounds height="20.0" width="100.0" x="1165.0" y="-194.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_9tp42Q" id="BPMNEdge_0AkLow" sourceElement="BPMNShape_QihA6g" targetElement="BPMNShape_GUBmSg">
<di:waypoint x="1140.0" y="-215.0"/>
<di:waypoint x="1197.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_9OrwEg" id="BPMNEdge_eqL00Q" sourceElement="BPMNShape_GUBmSg" targetElement="BPMNShape_JrIJDQ">
<di:waypoint x="1233.0" y="-215.0"/>
<di:waypoint x="1290.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_1qR49w" id="BPMNShape_rbG2Zg">
<dc:Bounds height="36.0" width="36.0" x="1097.0" y="-333.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_2qmYIA">
<dc:Bounds height="20.0" width="100.0" x="1065.0" y="-294.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="event_30uUNA" id="BPMNShape_xUycJQ">
<dc:Bounds height="36.0" width="36.0" x="1087.0" y="127.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_40xf3g">
<dc:Bounds height="20.0" width="100.0" x="1055.0" y="166.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_h4SfiQ" id="BPMNEdge_7m0QHg" sourceElement="BPMNShape_QihA6g" targetElement="BPMNShape_rbG2Zg">
<di:waypoint x="1115.0" y="-240.0"/>
<di:waypoint x="1115.0" y="-297.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_hvQWmg" id="BPMNEdge_xx0UyQ" sourceElement="BPMNShape_rbG2Zg" targetElement="BPMNShape_6O8H3A">
<di:waypoint x="1097.0" y="-315.0"/>
<di:waypoint x="575.0" y="-315.0"/>
<di:waypoint x="575.0" y="-240.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_xVEjcA" id="BPMNEdge_5276Pw" sourceElement="BPMNShape_mr0ibw" targetElement="BPMNShape_xUycJQ">
<di:waypoint x="1105.0" y="50.0"/>
<di:waypoint x="1105.0" y="127.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_j4GDgg" id="BPMNEdge_3xc00w" sourceElement="BPMNShape_xUycJQ" targetElement="BPMNShape_6O8H3A">
<di:waypoint x="1087.0" y="145.0"/>
<di:waypoint x="575.0" y="145.0"/>
<di:waypoint x="575.0" y="-190.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_A0FQoA" id="BPMNEdge_vgxzvQ" sourceElement="BPMNShape_4M1lNg" targetElement="BPMNShape_JrIJDQ">
<di:waypoint x="1223.0" y="25.0"/>
<di:waypoint x="1345.0" y="25.0"/>
<di:waypoint x="1345.0" y="-190.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="task_fHgZBg" id="BPMNShape_79up9g">
<dc:Bounds height="50.0" width="110.0" x="1600.0" y="-240.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="event_YnFi7A" id="BPMNShape_THdIqQ">
<dc:Bounds height="36.0" width="36.0" x="1457.0" y="-233.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_P4dNKg">
<dc:Bounds height="20.0" width="100.0" x="1425.0" y="-194.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_OfKNWA" id="BPMNEdge_p2wDpg" sourceElement="BPMNShape_JrIJDQ" targetElement="BPMNShape_THdIqQ">
<di:waypoint x="1400.0" y="-215.0"/>
<di:waypoint x="1457.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_sUEtcA" id="BPMNEdge_lOlEPw" sourceElement="BPMNShape_THdIqQ" targetElement="BPMNShape_79up9g">
<di:waypoint x="1493.0" y="-215.0"/>
<di:waypoint x="1600.0" y="-215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_iVpj0g" id="BPMNEdge_XmQNXg" sourceElement="BPMNShape_79up9g" targetElement="BPMNShape_UInW7g">
<di:waypoint x="1710.0" y="-215.0"/>
<di:waypoint x="1777.0" y="-215.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>

View file

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bpmn2:definitions xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:open-bpmn="http://open-bpmn.org/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exporter="org.openbpmn" exporterVersion="1.0.0" targetNamespace="http://open-bpmn.org"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL">
<bpmn2:collaboration id="collaboration_1" name="Default Collaboration">
<bpmn2:participant id="participant_TgW2JA" name="Default Process" processRef="process_1" />
<bpmn2:participant id="participant_tgRhJQ" name="Rechnungseingang" processRef="process_lYaFpg">
<bpmn2:documentation id="documentation_wSfXcQ"><![CDATA[Dieser Workflow dient dazu eingehende Rechnungen zu prüfen und zur Bezahlung weiterzuleiten. Es wird unterschieden von Sachrechnungen, die vom Sekretariat bearbeitet werden können und Cargo-Rechnungen die durch die Logistikabteilung anhand von Logistikaufträgen geprüft werden.
Nachdem die Rechnung bezahlt wurde wird der Vorgang archiviert. ]]></bpmn2:documentation>
</bpmn2:participant>
</bpmn2:collaboration>
<bpmn2:extensionElements>
<open-bpmn:auto-align>true</open-bpmn:auto-align>
</bpmn2:extensionElements>
<bpmn2:process definitionalCollaborationRef="collaboration_1" id="process_1"
name="Default Process" processType="Public">
<bpmn2:documentation id="documentation_wXazVg" />
</bpmn2:process>
<bpmn2:process definitionalCollaborationRef="collaboration_1" id="process_lYaFpg"
isExecutable="true" name="Rechnungseingang" processType="Private">
<bpmn2:laneSet id="laneset_fDygyw" name="Lane Set">
<bpmn2:lane id="lane_BgoDFg" name="Sekretariat">
<bpmn2:documentation id="documentation_hIztzA" />
<bpmn2:flowNodeRef>task_7Y3UUA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_bH7Wag</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_oNXxgg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_GEqHhQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_VJXKGg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_SP75zg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_ASbu1A</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_Vyo0Zw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_xAzhzw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_YH3bnw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_1qR49w</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_fHgZBg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_YnFi7A</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_eMP9Xw" name="Fachbereich">
<bpmn2:documentation id="documentation_6ihnmQ" />
<bpmn2:flowNodeRef>event_A1J0OA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>task_5lS3mw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_Hn5ZhQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_dJ89xQ</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_30uUNA</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="event_bH7Wag" name="Start">
<bpmn2:documentation id="documentation_pguolw" />
<bpmn2:outgoing>sequenceFlow_8yitUQ</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="task_7Y3UUA" name="Rechnungsprüfung">
<bpmn2:documentation id="documentation_oKsT5Q"><![CDATA[Inhaltliche Prüufng der Rechnung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_BGVbSA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_FyAf3g</bpmn2:outgoing>
<bpmn2:incoming>sequenceFlow_hvQWmg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_j4GDgg</bpmn2:incoming>
</bpmn2:task>
<bpmn2:endEvent id="event_oNXxgg" name="Ende">
<bpmn2:documentation id="documentation_1heF3g" />
<bpmn2:incoming>sequenceFlow_iVpj0g</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:intermediateCatchEvent id="event_GEqHhQ" name="Import">
<bpmn2:documentation id="documentation_gR2xbw" />
<bpmn2:incoming>sequenceFlow_8yitUQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_BGVbSA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_8yitUQ" sourceRef="event_bH7Wag" targetRef="event_GEqHhQ">
<bpmn2:documentation id="documentation_2Zd0Aw" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_BGVbSA" sourceRef="event_GEqHhQ" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_6k088A" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_VJXKGg" name="Sachrechnung">
<bpmn2:documentation id="documentation_DaDN3w"><![CDATA[Weiterleiten zur Sachprüfung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_rZXh6g</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_sNlWkQ</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:task id="task_SP75zg" name="Budgetprüfung">
<bpmn2:documentation id="documentation_qP2Sew" />
<bpmn2:incoming>sequenceFlow_sNlWkQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_nxZ9bA</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:task id="task_5lS3mw" name="Prüfung Logistik Auftrag">
<bpmn2:documentation id="documentation_zweAkw"><![CDATA[Prüfung der Rechnung und Abgleich mit Logistikauftrag]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_DXGQrw</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_UebylQ</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:eventBasedGateway gatewayDirection="Diverging" id="gateway_ASbu1A" name="">
<bpmn2:documentation id="documentation_09gukg" />
<bpmn2:incoming>sequenceFlow_FyAf3g</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_rZXh6g</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_i7cH2A</bpmn2:outgoing>
</bpmn2:eventBasedGateway>
<bpmn2:sequenceFlow id="sequenceFlow_FyAf3g" sourceRef="task_7Y3UUA" targetRef="gateway_ASbu1A">
<bpmn2:documentation id="documentation_tv00MQ" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_rZXh6g" sourceRef="gateway_ASbu1A" targetRef="event_VJXKGg">
<bpmn2:documentation id="documentation_EPAmhQ" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_sNlWkQ" sourceRef="event_VJXKGg" targetRef="task_SP75zg">
<bpmn2:documentation id="documentation_iXrfpg" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_A1J0OA" name="Cargo Rechnung">
<bpmn2:documentation id="documentation_RWi6LA"><![CDATA[Weiterleitung zur Prüfung Logistikauftrag]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_i7cH2A</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_DXGQrw</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_i7cH2A" sourceRef="gateway_ASbu1A" targetRef="event_A1J0OA">
<bpmn2:documentation id="documentation_pz6J4g" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_DXGQrw" sourceRef="event_A1J0OA" targetRef="task_5lS3mw">
<bpmn2:documentation id="documentation_ngSLdQ" />
</bpmn2:sequenceFlow>
<bpmn2:exclusiveGateway gatewayDirection="Diverging" id="gateway_Vyo0Zw" name="">
<bpmn2:documentation id="documentation_Pm90XA" />
<bpmn2:incoming>sequenceFlow_nxZ9bA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_9tp42Q</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_h4SfiQ</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:intermediateCatchEvent id="event_dJ89xQ" name="Freigabe">
<bpmn2:documentation id="documentation_sB06Ag"><![CDATA[Rechnung in Ordnung und freigegeben zur Bezahlung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_PLk0RA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_A0FQoA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:exclusiveGateway gatewayDirection="Diverging" id="gateway_Hn5ZhQ" name="">
<bpmn2:documentation id="documentation_aLEQqQ" />
<bpmn2:incoming>sequenceFlow_UebylQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_PLk0RA</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_xVEjcA</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="sequenceFlow_UebylQ" sourceRef="task_5lS3mw" targetRef="gateway_Hn5ZhQ">
<bpmn2:documentation id="documentation_MZdr7Q" />
</bpmn2:sequenceFlow>
<bpmn2:task id="task_xAzhzw" name="Bezahlung">
<bpmn2:documentation id="documentation_zO3SRw" />
<bpmn2:incoming>sequenceFlow_9OrwEg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_A0FQoA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_OfKNWA</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="sequenceFlow_nxZ9bA" sourceRef="task_SP75zg" targetRef="gateway_Vyo0Zw">
<bpmn2:documentation id="documentation_G4qmmA" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_PLk0RA" sourceRef="gateway_Hn5ZhQ" targetRef="event_dJ89xQ">
<bpmn2:documentation id="documentation_Y5qwSA" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_YH3bnw" name="Freigeben">
<bpmn2:documentation id="documentation_C05Bhw"><![CDATA[Rechnung in Ordnung und freigegeben zur Bezahlung]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_9tp42Q</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_9OrwEg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_9tp42Q" sourceRef="gateway_Vyo0Zw" targetRef="event_YH3bnw">
<bpmn2:documentation id="documentation_PIQaSg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_9OrwEg" sourceRef="event_YH3bnw" targetRef="task_xAzhzw">
<bpmn2:documentation id="documentation_0eagTw" />
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_1qR49w" name="Ablehnen">
<bpmn2:documentation id="documentation_cdpcXA" />
<bpmn2:incoming>sequenceFlow_h4SfiQ</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_hvQWmg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:intermediateCatchEvent id="event_30uUNA" name="Ablehnen">
<bpmn2:documentation id="documentation_VazNUA" />
<bpmn2:incoming>sequenceFlow_xVEjcA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_j4GDgg</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_h4SfiQ" sourceRef="gateway_Vyo0Zw" targetRef="event_1qR49w">
<bpmn2:documentation id="documentation_Q2yPDw" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_hvQWmg" sourceRef="event_1qR49w" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_qkneSw" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_xVEjcA" sourceRef="gateway_Hn5ZhQ" targetRef="event_30uUNA">
<bpmn2:documentation id="documentation_l9waIg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_j4GDgg" sourceRef="event_30uUNA" targetRef="task_7Y3UUA">
<bpmn2:documentation id="documentation_4vaLww" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_A0FQoA" sourceRef="event_dJ89xQ" targetRef="task_xAzhzw">
<bpmn2:documentation id="documentation_fAB90Q" />
</bpmn2:sequenceFlow>
<bpmn2:task id="task_fHgZBg" name="Archiviert">
<bpmn2:documentation id="documentation_Idessw"><![CDATA[Rechnungsprüfung abgeschlossen und Rechnung archiveirt.]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_A0FQoA</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_sUEtcA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_iVpj0g</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:intermediateCatchEvent id="event_YnFi7A" name="Bezahlt">
<bpmn2:documentation id="documentation_Jz0LKg"><![CDATA[Rechnungsbetrag wurde überwiesen]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_OfKNWA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_sUEtcA</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_OfKNWA" sourceRef="task_xAzhzw" targetRef="event_YnFi7A">
<bpmn2:documentation id="documentation_DdJpCg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_sUEtcA" sourceRef="event_YnFi7A" targetRef="task_fHgZBg">
<bpmn2:documentation id="documentation_uG0SGg" />
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_iVpj0g" sourceRef="task_fHgZBg" targetRef="event_oNXxgg">
<bpmn2:documentation id="documentation_Is0LqQ" />
</bpmn2:sequenceFlow>
</bpmn2:process>
</bpmn2:definitions>

17
BPMN-KI-Test/schema-1.txt Normal file
View file

@ -0,0 +1,17 @@
Prozess: Eingangsrechnungsprüfung
START -> [Task] Rechnungsprüfung
|
|-- [Event] Sachrechnung --> [Task] Budgetprüfung (Sekretariat)
| |
| |-- [Event] Freigeben --> [Task] Bezahlung
| |-- [Event] Ablehnen --> [Task] Rechnungsprüfung
|
|-- [Event] Cargorechnung --> [Task] Prüfung Logistikauftrag (Fachbereich)
|
|-- [Event] Freigeben --> [Task] Bezahlung
|-- [Event] Ablehnen --> [Task] Rechnungsprüfung
[Task] Bezahlung
|
|-- [Event] Bezahlt --> [Task] Archiviert (ENDE)

46
BPMN-KI-Test/schema-2.txt Normal file
View file

@ -0,0 +1,46 @@
prozess: Eingangsrechnungsprüfung
start_event: Rechnung importiert
tasks:
- name: Rechnungsprüfung
type: user_task
gateway:
name: Klassifikation
type: exclusive
paths:
- event: Sachrechnung
next_task: Budgetprüfung
role: Sekretariat
- event: Cargorechnung
next_task: Prüfung Logistikauftrag
role: Fachbereich
- name: Budgetprüfung
type: user_task
gateway:
name: Entscheidung
type: exclusive
paths:
- event: Freigeben
next_task: Bezahlung
- event: Ablehnen
next_task: Rechnungsprüfung
- name: Prüfung Logistikauftrag
type: user_task
gateway:
name: Entscheidung
type: exclusive
paths:
- event: Freigeben
next_task: Bezahlung
- event: Ablehnen
next_task: Rechnungsprüfung
- name: Bezahlung
type: service_task
event:
name: Bezahlt
next_task: Archiviert
- name: Archiviert
type: end_event

View file

@ -8,9 +8,15 @@ https://api-console.zoho.eu/
https://api-console.zoho.eu/client/1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
```
OrganizationID=20105697367
client ID= 1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
client secret= ee9ba49f16e77c64abb89cea13542d2326d8d03ce8
zoho.accesstoken 1000.18f5fbeaf572425b8062d015d541aad5.a704efa994774ef33d7af75106468a13
zoho.apidomain https://www.zohoapis.eu
zoho.clientid 1000.GR5FTPZYB06HEWSFSSX4DJU3OBD4EJ
zoho.clientsecret 3f3e74c5212bbc924a7ebf77f887c6296db1106c47
zoho.code 1000.c184c7592a218fee58f7b7855b56eb77.7b533ff9f570fd6ab3296784caeec072
zoho.organization 20105697367
zoho.refreshtoken 1000.98fe4d0c4f676237b400bf8a3dc219f3.03d6bacf5b988d339eb788c4ecff440e
zoho.scope ZohoBooks.contacts.ALL ZohoBooks.invoices.CREATE ZohoBooks.invoices.READ ZohoBooks.invoices.UPDATE
```
# API Dokumentation
@ -86,3 +92,16 @@ Danach den Code token kopieren:
1000.7fe6315e8848b92a2f281b885677d37a.428c02dc2309606c86271842f1f67de4
**Note:** Der Code muss für Test immer wieder neu erstellt werden, da er nur für einige Minuten gültig ist!
# Disable auto-generated invoice number
Um die Automatische Vergabe von Rechnungsnummern in Zoho zu deaktivieren kann wie folgt vorgegangen werden:
1. Unter 'Invoices' eine neue Rechnung anlegen#
2. Im Feld 'Invoice#' das Zahnrad anklicken:
<img src="disable-auto-generated-number-01.png" />
3. Und dort die Option "Enter invoice numbers manually" auswählen
<img src="disable-auto-generated-number-02.png" />

26
doc/zoho/SECRETS.md Normal file
View file

@ -0,0 +1,26 @@
# Zoho Web API
AGL Dubai nutzt Zoho als Platform zusammen mit einer lokalen Steuerkanzlei
## Test/Prod Account Imixs
https://api-console.zoho.eu/
https://api-console.zoho.eu/client/1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
```
OrganizationID=20105697367
client ID= 1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
client secret= ee9ba49f16e77c64abb89cea13542d2326d8d03ce8
```
# API Dokumentation
- API Docu: https://www.zoho.com/books/api/v3/introduction/
- Authentication: https://www.zoho.com/books/api/v3/oauth/
# Testumgebung
https://books.zoho.eu/app/20105697367
https://accounts.zoho.eu/home#
Base API URI= https://accounts.zoho.eu/

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -117,8 +117,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
ItemCollection process = documentService
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
if (process != null) {
link = link + "&processref=" + process.getUniqueID()
+ "&phrase=" + getDbtNr();
link = link + "&processref=" + process.getUniqueID() + "&phrase=" + getDbtNr();
}
if ("analytic.invoices.count.all".equals(event.getKey())) {
event.setValue("" + countAll);
@ -188,8 +187,8 @@ public class AGLAnalyticControllerDebitor implements Serializable {
}
String label = "<span class=\"pull-right\">" + formatCurrency(totalCurrency1) + " " + currencies.get(0)
+ "</span>";
label = label + "</br><span class=\"pull-right\">" +
formatCurrency(totalCurrency2) + " " + currencies.get(1) + "</span>";
label = label + "</br><span class=\"pull-right\">" + formatCurrency(totalCurrency2) + " " + currencies.get(1)
+ "</span>";
return label;
}
@ -200,8 +199,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
stats = null;
} else {
logger.info(" ├──load invoices for " + getDbtNr() + "....");
String query = "(type:workitem) AND dbtr.number:" + getDbtNr()
+ " AND $modelversion:rechnungsausgang-*";
String query = "(type:workitem) AND dbtr.number:" + getDbtNr() + " AND $modelversion:rechnungsausgang-*";
try {
logger.info(" ├──refresh invoice stats for " + getDbtNr() + "....");
invoices = documentService.find(query, 999, 0, "$created", false);
@ -404,15 +402,12 @@ public class AGLAnalyticControllerDebitor implements Serializable {
String startDateStr = startDate.format(formatter);
String endDateStr = endDate.format(formatter);
String query = "(type:workitemarchive) AND "
+ " invoice.date:[" + startDateStr + " TO " + endDateStr + "] AND "
+ "dbtr.number:" + getDbtNr()
+ " AND $modelversion:rechnungsausgang-* AND ($taskid:[5900 TO 5999])";
String query = "(type:workitemarchive) AND " + " invoice.date:[" + startDateStr + " TO " + endDateStr + "] AND "
+ "dbtr.number:" + getDbtNr() + " AND $modelversion:rechnungsausgang-* AND ($taskid:[5900 TO 5999])";
logger.fine("query = " + query);
try {
List<ItemCollection> invoices = documentService
.findStubs(query, 9999, 0, "$created", false);
List<ItemCollection> invoices = documentService.findStubs(query, 9999, 0, "$created", false);
for (ItemCollection invoice : invoices) {
try {
@ -477,14 +472,12 @@ public class AGLAnalyticControllerDebitor implements Serializable {
// Wir selektieren alle Zahlungseingänge interessieren uns aber nur für den
// letzten
String sQuery = " (type:\"workitem\" OR type:\"workitemarchive\") " + //
" AND ($modelversion:zahlungseingang-*) AND ($workitemref:\""
+ invoice.getUniqueID() + "\" )";
" AND ($modelversion:zahlungseingang-*) AND ($workitemref:\"" + invoice.getUniqueID() + "\" )";
List<ItemCollection> workitems = null;
try {
workitems = documentService.findStubs(sQuery, 99, 0,
"payment.date", true);
workitems = documentService.findStubs(sQuery, 99, 0, "payment.date", true);
if (workitems.size() > 0) {
return workitems.get(0).getItemValueDate("payment.date");
}

View file

@ -23,8 +23,7 @@ import jakarta.inject.Named;
/**
* Der AGLAnalyticControllerOPListe berechnet Analyse Daten über alle offenen
* Rechnungen
* und bietet im Workflow noch eine Excel-Export Funktion
* Rechnungen und bietet im Workflow noch eine Excel-Export Funktion
*
* @author rsoika
*
@ -146,10 +145,7 @@ public class AGLAnalyticControllerOPListe implements Serializable {
* Läd die statistik daten zu einem department die Anzahl an aktuellen
* Rechnungen zu ermitteln
*
* int countAll = 0;
* int countOpen = 0;
* int countDue = 0;
* int countDunning = 0;
* int countAll = 0; int countOpen = 0; int countDue = 0; int countDunning = 0;
*
*/
private void calculateStats() {
@ -163,8 +159,8 @@ public class AGLAnalyticControllerOPListe implements Serializable {
try {
if (departmentID == null || !departmentID.isEmpty()) {
countAll = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
+ " AND $modelversion:rechnungsausgang-*");
countAll = documentService.count(
"(type:workitem) AND $uniqueidref:" + departmentID + " AND $modelversion:rechnungsausgang-*");
countDue = documentService.count("(type:workitem) AND $uniqueidref:" + departmentID
+ " AND $modelversion:rechnungsausgang-* AND $taskid:[5100 TO 5199]");

View file

@ -66,8 +66,7 @@ public class AGLAnalyticControllerSteuer implements Serializable {
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
String link = "/pages/workitems/worklist.xhtml";
if (process != null) {
link = link + "?processref=" + process.getUniqueID()
+ "&workflowgroup=Steuerbescheid";
link = link + "?processref=" + process.getUniqueID() + "&workflowgroup=Steuerbescheid";
}
if ("analytic.steuer.eust".equals(event.getKey())) {
event.setValue(computeSteuerbescheideEUST());
@ -122,9 +121,8 @@ public class AGLAnalyticControllerSteuer implements Serializable {
}
/**
* Berechnet die Summe aller offenen EUST Beträge
* // tax.code=[0], amount=[3885.16], activity.type=[EUST],
* // filenumber=[LA-PAP-2408-024]}
* Berechnet die Summe aller offenen EUST Beträge // tax.code=[0],
* amount=[3885.16], activity.type=[EUST], // filenumber=[LA-PAP-2408-024]}
*
* @return
*/
@ -323,25 +321,18 @@ public class AGLAnalyticControllerSteuer implements Serializable {
}
// Step 3: Prepare the JSON structure
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder()
.add("type", "bar")
.add("data", Json.createObjectBuilder()
.add("datasets", Json.createArrayBuilder()
JsonObjectBuilder jsonBuilder = Json
.createObjectBuilder().add("type", "bar").add("data", Json
.createObjectBuilder().add("datasets", Json.createArrayBuilder()
.add(Json.createObjectBuilder() // First dataset for 'tax'
.add("label", "Zoll")
.add("backgroundColor", "#96f")
.add("borderWidth", 1)
.add("label", "Zoll").add("backgroundColor", "#96f").add("borderWidth", 1)
.add("data", dataBuilderZoll))
.add(Json.createObjectBuilder() // Second dataset for 'eust'
.add("label", "EUSt")
.add("backgroundColor", "#36a2eb")
.add("borderWidth", 1)
.add("label", "EUSt").add("backgroundColor", "#36a2eb").add("borderWidth", 1)
.add("data", dataBuilderEust))
.add(Json.createObjectBuilder() // Third dataset for 'Saldo'
.add("label", "Saldo")
.add("backgroundColor", "#ff6384")
.add("borderWidth", 1)
.add("label", "Saldo").add("backgroundColor", "#ff6384").add("borderWidth", 1)
.add("data", dataBuilderSaldo)))
.add("labels", labelsBuilder));
@ -373,15 +364,7 @@ public class AGLAnalyticControllerSteuer implements Serializable {
private String accumulateSteuerbescheideAbteilungByWeek() {
logger.fine("accumulate steuer by Abteilung week...");
String[] colors = {
"#36a2eb",
"#ff6384",
"#4bc0c0",
"#ff9f40",
"#96f",
"#ffcd56",
"#c9cbcf"
};
String[] colors = { "#36a2eb", "#ff6384", "#4bc0c0", "#ff9f40", "#96f", "#ffcd56", "#c9cbcf" };
List<ItemCollection> list = getSteuerbescheide();
Map<String, SteuerData> totalByWeek = new HashMap<>();
@ -448,8 +431,7 @@ public class AGLAnalyticControllerSteuer implements Serializable {
// Step 3: Baue die Balken pro abrteilung
JsonArrayBuilder datasets = Json.createArrayBuilder();
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder()
.add("type", "bar");
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder().add("type", "bar");
JsonObjectBuilder dataDing = Json.createObjectBuilder();
int iColor = 0;
@ -478,9 +460,7 @@ public class AGLAnalyticControllerSteuer implements Serializable {
}
datasets.add(Json.createObjectBuilder() // First dataset for 'tax'
.add("label", _abteilung)
.add("backgroundColor", colors[iColor])
.add("borderWidth", 1)
.add("label", _abteilung).add("backgroundColor", colors[iColor]).add("borderWidth", 1)
.add("data", dataBuilderTotals));
iColor++;

View file

@ -49,8 +49,7 @@ import jakarta.inject.Inject;
*
* <p>
* Der Adapter kopiert die Steuerbescheiddaten in neue Zeilen, welche ab
* Zeilennummer
* 16 eingefügt werden.
* Zeilennummer 16 eingefügt werden.
* <p>
*
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
@ -90,14 +89,12 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List<String> currencyList = configItemCollection.getItemValue("currency.out");
if (currencyList == null || currencyList.size() < 2) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
// read the Steuerbescheide options
ItemCollection steuerbescheideConfig = workflowService.evalWorkflowResult(event, "steuerbescheide",
document,
ItemCollection steuerbescheideConfig = workflowService.evalWorkflowResult(event, "steuerbescheide", document,
false);
if (steuerbescheideConfig == null || !steuerbescheideConfig.hasItem("excel-export")) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), CONFIG_ERROR,
@ -120,8 +117,7 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
logger.info("... loading poi configuration..");
// Process POI instructions
// read the config
ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", document,
false);
ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", document, false);
if (poiConfig == null || !poiConfig.hasItem("findreplace")) {
throw new PluginException(POIFindReplaceAdapter.class.getSimpleName(), CONFIG_ERROR,
"missing poi configuration");
@ -133,8 +129,7 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
this.updateFileData(document.getFileData(targetName), document, replaceDevList, eval);
} catch (PluginException | IOException | QueryException e) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update steuerbescheide: " + e.getMessage());
}
logger.info("... completed!");
@ -142,8 +137,8 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
}
/**
* This helper method inserts a row for each invoice at row 16
* into the excel template file
* This helper method inserts a row for each invoice at row 16 into the excel
* template file
* <p>
* The method copies the Row A16 as a reference row
* <p>
@ -153,8 +148,7 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
* @throws PluginException
* @throws QueryException
*/
private void insertInvoiceRows(ItemCollection document, String fileName)
throws PluginException, QueryException {
private void insertInvoiceRows(ItemCollection document, String fileName) throws PluginException, QueryException {
// load dummy rechnungen
List<ItemCollection> invoices = loadSteuerbescheide();
@ -183,8 +177,7 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
XSSFRow row = sheet.createRow(rowPos);
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
// insert values
row.getCell(0)
.setCellValue(invoice.getItemValueDate("$created"));
row.getCell(0).setCellValue(invoice.getItemValueDate("$created"));
row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)
.setCellValue(invoice.getItemValueString("invoice.number"));
row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK)
@ -228,16 +221,14 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
null);
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
// update the fileData
document.addFileData(fileDataNew);
logger.finest("......new document added");
} catch (IOException e) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@ -258,13 +249,11 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
* @param document
* @throws PluginException
*/
private void appendExcelTemplate(ItemCollection document, String textblockRef, String template,
String targetName)
private void appendExcelTemplate(ItemCollection document, String textblockRef, String template, String targetName)
throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid steuerbescheide configuration in model event - textblock/template reference not defined!");
}
@ -273,10 +262,8 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
// do we found the document?
if (fileData == null) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
"invalid steuerbescheide configuration in model event - template=" + template
+ " not found!");
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid steuerbescheide configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document
@ -293,9 +280,8 @@ public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
private List<ItemCollection> loadSteuerbescheide() {
List<ItemCollection> result = new ArrayList<>();
try {
result = documentService.find(
"$modelversion:steuerbescheid-* AND type:workitem", 9999, 0,
"invoice.number", false);
result = documentService.find("$modelversion:steuerbescheid-* AND type:workitem", 9999, 0, "invoice.number",
false);
} catch (QueryException e) {
e.printStackTrace();
}

View file

@ -52,8 +52,7 @@ import jakarta.inject.Inject;
*
* <p>
* Der Adapter kopiert die ausgangsrechnungen in neue Zeilen, welche ab
* Zeilennummer
* 16 eingefügt werden.
* Zeilennummer 16 eingefügt werden.
* <p>
*
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
@ -92,9 +91,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
List<String> currencyList = invoiceService.getCurrenciesOut();
// read the options
ItemCollection ausgangsrechnungConfig = workflowService.evalWorkflowResult(event, "soa",
document,
false);
ItemCollection ausgangsrechnungConfig = workflowService.evalWorkflowResult(event, "soa", document, false);
if (ausgangsrechnungConfig == null || !ausgangsrechnungConfig.hasItem("excel-export")) {
throw new PluginException(AGLAnalyticExcelAdapterDebitor.class.getSimpleName(), CONFIG_ERROR,
"missing soa configuration in model event - please check model configuration");
@ -129,14 +126,12 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
null);
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
document.addFileData(fileDataNew);
logger.finest("......new document added");
} catch (IOException | QueryException e) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@ -153,8 +148,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
processPOIUpdate(document, event, targetName);
} catch (PluginException e) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update steuerbescheide: " + e.getMessage());
}
logger.info("... completed!");
@ -213,8 +207,8 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
}
/**
* This helper method inserts a row for each invoice at row 16
* into the excel template file
* This helper method inserts a row for each invoice at row 16 into the excel
* template file
* <p>
* The method copies the Row A16 as a reference row
* <p>
@ -249,8 +243,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
XSSFRow row = sheet.createRow(rowPos);
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
// insert values
row.getCell(0)
.setCellValue(invoice.getItemValueDate("$created"));
row.getCell(0).setCellValue(invoice.getItemValueDate("$created"));
row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)
.setCellValue(invoice.getItemValueString("invoice.number"));
row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK)
@ -318,12 +311,10 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
* @throws PluginException
*/
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
String targetName)
throws PluginException {
String targetName) throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid SOA configuration in model event - textblock/template reference not defined!");
}
@ -332,10 +323,8 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
// do we found the document?
if (fileData == null) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
"invalid SOA configuration in model event - template=" + template
+ " not found!");
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid SOA configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document
@ -352,12 +341,9 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
private List<ItemCollection> loadInvoices(String dbtrNumber) {
List<ItemCollection> result = new ArrayList<>();
String query = "(type:workitem) AND dbtr.number:" + dbtrNumber
+ " AND $modelversion:rechnungsausgang-*";
String query = "(type:workitem) AND dbtr.number:" + dbtrNumber + " AND $modelversion:rechnungsausgang-*";
try {
result = documentService.find(
query, 9999, 0,
"invoice.number", false);
result = documentService.find(query, 9999, 0, "invoice.number", false);
} catch (QueryException e) {
e.printStackTrace();
}

View file

@ -109,9 +109,8 @@ public class BusinessPartnerController implements Serializable {
*
* {@code
<h:commandScript name="datevSearch" action=
* "#{datevSearchController.searchCdtr()}"
* render="autocomplete-resultlist-datev" onevent="autocompleteShowResult" />
* }
* "#{datevSearchController.searchCdtr()}" render=
* "autocomplete-resultlist-datev" onevent="autocompleteShowResult" /> }
*/
public void search(String options) {
List<ItemCollection> resultList = null;
@ -160,10 +159,9 @@ public class BusinessPartnerController implements Serializable {
/**
* Diese Helper Method liefert true wenn in den Options von Form Part 'reRender'
* angegeben wurde.
* Damit löst die Suchmaske businesspartner_search.xhtml eine komplette rerender
* Phase der Form aus.
* Dies ist z.b. für den workflow 'analyse-debitor.bpmn' nützlich
* angegeben wurde. Damit löst die Suchmaske businesspartner_search.xhtml eine
* komplette rerender Phase der Form aus. Dies ist z.b. für den workflow
* 'analyse-debitor.bpmn' nützlich
*
* @param options
* @return
@ -277,16 +275,16 @@ public class BusinessPartnerController implements Serializable {
if (!dbtrNumber.isEmpty()) {
invoicesOut = businessPartnerService.findOutgoingInvoices(dbtrNumber);
// Mahnungen
String query = "(type:workitem) AND ($modelversion:mahnlauf-*) "
+ " AND (dbtr.number:" + dbtrNumber + ")";
String 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 + ")";
String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) " + " AND (cdtr.number:"
+ cdtrNumber + ")";
invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false);
}
@ -329,8 +327,8 @@ public class BusinessPartnerController implements Serializable {
* user has selected a new businesspartner.
* <p>
* The method lookups the given BusinessPartner and updates the metadata for
* dbtr/cdtr depending on the workflow type.
* A form will than rerender the opList section.
* dbtr/cdtr depending on the workflow type. A form will than rerender the
* opList section.
*/
public void updateMetaData() {
FacesContext fc = FacesContext.getCurrentInstance();
@ -345,8 +343,7 @@ public class BusinessPartnerController implements Serializable {
businessPartner.getItemValueString("cdtr.number"));
workflowController.getWorkitem().setItemValue("cdtr.name",
businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("cdtr.mail",
businessPartner.getItemValue("cdtr.mail"));
workflowController.getWorkitem().setItemValue("cdtr.mail", businessPartner.getItemValue("cdtr.mail"));
}
// Ausgangsrechnung
@ -355,8 +352,7 @@ public class BusinessPartnerController implements Serializable {
businessPartner.getItemValueString("dbtr.number"));
workflowController.getWorkitem().setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("dbtr.mail",
businessPartner.getItemValue("dbtr.mail"));
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
}
// Zahlungseingang
@ -365,8 +361,7 @@ public class BusinessPartnerController implements Serializable {
businessPartner.getItemValueString("dbtr.number"));
workflowController.getWorkitem().setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("dbtr.mail",
businessPartner.getItemValue("dbtr.mail"));
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
}
// Analyse Debitor
@ -375,8 +370,7 @@ public class BusinessPartnerController implements Serializable {
businessPartner.getItemValueString("dbtr.number"));
workflowController.getWorkitem().setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("dbtr.mail",
businessPartner.getItemValue("dbtr.mail"));
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
}
}

View file

@ -51,7 +51,7 @@ 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.ejb.Stateless;
import jakarta.inject.Inject;
/**
@ -68,7 +68,7 @@ import jakarta.inject.Inject;
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@Singleton
@Stateless
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
public class BusinessPartnerService {
@ -121,9 +121,8 @@ public class BusinessPartnerService {
/**
* Diese Methode aktualisiert das business Partner object. Sie wird von den
* Invoice Plugins genutzt.
* Die Methode wirft eine PluginException falls das BusinessPartner Objekt
* gesperrt oder in verification ist!
* Invoice Plugins genutzt. Die Methode wirft eine PluginException falls das
* BusinessPartner Objekt gesperrt oder in verification ist!
*
* Gleichzeitig wird bei Rechnungen in Abhängigkeit der Rechnungsart die
* dbtr./cdtr. items sowie mail und country aktualisiert.
@ -145,8 +144,18 @@ public class BusinessPartnerService {
workitem.setItemValue("partner.id", partnerID);
}
if (partnerID == null || partnerID.isEmpty()) {
return;
}
// load Business Partner
ItemCollection businessPartner = getBusinessPartnerByID(partnerID);
if (businessPartner == null) {
return;
}
// because the method can be called multiple times within one worklfow
// processing cycle
// we need to load the object within the current transaction context
businessPartner = documentService.load(businessPartner.getUniqueID());
if (businessPartner != null) {
workitem.setItemValue("partner.name", businessPartner.getItemValueString("partner.name"));
@ -166,13 +175,11 @@ public class BusinessPartnerService {
// Validate Business Partner Status!
if (businessPartner.getTaskID() == TASK_VERIFICATION) {
throw new PluginException(InvoicePlugin.class.getName(),
ERROR_BUSINESSPARTNER_VERIFICATION,
throw new PluginException(InvoicePlugin.class.getName(), ERROR_BUSINESSPARTNER_VERIFICATION,
"Businesspartner is in verification. Invoice can't be processed!");
}
if (businessPartner.getTaskID() == TASK_LOCKED) {
throw new PluginException(InvoicePlugin.class.getName(),
ERROR_BUSINESSPARTNER_LOCKED,
throw new PluginException(InvoicePlugin.class.getName(), ERROR_BUSINESSPARTNER_LOCKED,
"Businesspartner is locked. Invoice can't be processed!");
}
// update business partner status...
@ -225,8 +232,7 @@ public class BusinessPartnerService {
/**
* Diese Methode sucht einen Business Partner anhand seiner BPID
*
* @param bpid
* - business partner id phrase
* @param bpid - business partner id phrase
* @return - matching business partner
*/
public ItemCollection getBusinessPartnerByID(String bpid) {
@ -251,8 +257,7 @@ public class BusinessPartnerService {
/**
* Diese Methode sucht Business Partner anhand einer Suchphrase
*
* @param phrase
* - search phrase
* @param phrase - search phrase
* @return - list of matching business partners
*/
public List<ItemCollection> search(String phrase) {
@ -386,8 +391,7 @@ public class BusinessPartnerService {
List<ItemCollection> bankenListe = explodeBanks(businessPartner);
for (ItemCollection bank : bankenListe) {
if (iban.equals(bank.getItemValueString("iban"))
&& bic.equals(bank.getItemValueString("bic"))) {
if (iban.equals(bank.getItemValueString("iban")) && bic.equals(bank.getItemValueString("bic"))) {
// known!
return true;
}

View file

@ -113,8 +113,8 @@ public class CargosoftExportAdapter implements SignalAdapter {
// finally append the success event id
document.event(EVENT_SUCCESS);
} catch (PluginException | IOException
| jakarta.xml.bind.JAXBException | javax.xml.transform.TransformerException e) {
} catch (PluginException | IOException | jakarta.xml.bind.JAXBException
| javax.xml.transform.TransformerException e) {
logger.severe("cargosoft export failed: " + e.getMessage());
document.setItemValue("cargosoft.error", e.getMessage());
document.event(EVENT_FAILURE);

View file

@ -246,8 +246,7 @@ public class CustomSearchController implements Serializable {
Date endDate = endCalendar.getTime();
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
String dateRange = "[" + dateformat.format(startDate) + " TO "
+ dateformat.format(endDate) + "]";
String dateRange = "[" + dateformat.format(startDate) + " TO " + dateformat.format(endDate) + "]";
return dateRange;
}
@ -277,8 +276,7 @@ public class CustomSearchController implements Serializable {
Date endDate = endCalendar.getTime();
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
String dateRange = "[" + dateformat.format(startDate) + " TO "
+ dateformat.format(endDate) + "]";
String dateRange = "[" + dateformat.format(startDate) + " TO " + dateformat.format(endDate) + "]";
return dateRange;
}

View file

@ -91,8 +91,8 @@ public class DebitorStatistikController implements Serializable {
}
/**
* Gibt eine bookmarkable url zurück.
* Wir vom Aktualisieren button in der Page genutzt
* Gibt eine bookmarkable url zurück. Wir vom Aktualisieren button in der Page
* genutzt
*
* @return
*/
@ -115,8 +115,7 @@ public class DebitorStatistikController implements Serializable {
return 0;
}
try {
result = documentService
.count("(type:workitem OR type:workitemarchive) AND dbtr.number:" + getDbtNr()
result = documentService.count("(type:workitem OR type:workitemarchive) AND dbtr.number:" + getDbtNr()
+ " AND $workflowgroup:\"Rechnungsausgang\"");
} catch (QueryException e) {
logger.severe("Failed to get statistic: " + e.getMessage());
@ -139,8 +138,7 @@ public class DebitorStatistikController implements Serializable {
return 0;
}
try {
result = documentService
.count("(type:workitem OR type:workitemarchive) AND dbtr.number:" + getDbtNr()
result = documentService.count("(type:workitem OR type:workitemarchive) AND dbtr.number:" + getDbtNr()
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5900 TO 5999])");
} catch (QueryException e) {
logger.severe("Failed to get statistic: " + e.getMessage());
@ -163,8 +161,7 @@ public class DebitorStatistikController implements Serializable {
return 0;
}
try {
result = documentService
.count("(type:workitem) AND dbtr.number:" + getDbtNr()
result = documentService.count("(type:workitem) AND dbtr.number:" + getDbtNr()
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5000 TO 5099])");
} catch (QueryException e) {
logger.severe("Failed to get statistic: " + e.getMessage());
@ -187,8 +184,7 @@ public class DebitorStatistikController implements Serializable {
return 0;
}
try {
result = documentService
.count("(type:workitem) AND dbtr.number:" + getDbtNr()
result = documentService.count("(type:workitem) AND dbtr.number:" + getDbtNr()
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5100 TO 5199])");
} catch (QueryException e) {
logger.severe("Failed to get statistic: " + e.getMessage());
@ -211,8 +207,7 @@ public class DebitorStatistikController implements Serializable {
return 0;
}
try {
result = documentService
.count("(type:workitem ) AND dbtr.number:" + getDbtNr()
result = documentService.count("(type:workitem ) AND dbtr.number:" + getDbtNr()
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5200 TO 5299])");
} catch (QueryException e) {
logger.severe("Failed to get statistic: " + e.getMessage());
@ -235,8 +230,7 @@ public class DebitorStatistikController implements Serializable {
return 0;
}
try {
result = documentService
.count("(type:workitem OR type:workitemarchive) AND dbtr.number:" + getDbtNr()
result = documentService.count("(type:workitem OR type:workitemarchive) AND dbtr.number:" + getDbtNr()
+ " AND $workflowgroup:\"Rechnungsausgang\" AND ($taskid:[5300 TO 5399])");
} catch (QueryException e) {
logger.severe("Failed to get statistic: " + e.getMessage());
@ -311,8 +305,7 @@ public class DebitorStatistikController implements Serializable {
// df.format(to) + "])";
logger.fine("query = " + query);
try {
List<ItemCollection> invoices = documentService
.findStubs(query, 9999, 0, "$created", false);
List<ItemCollection> invoices = documentService.findStubs(query, 9999, 0, "$created", false);
for (ItemCollection invoice : invoices) {
try {
@ -435,14 +428,12 @@ public class DebitorStatistikController implements Serializable {
// Wir selektieren alle Zahlungseingänge interessieren usn aber nur für den
// letzten
String sQuery = " (type:\"workitem\" OR type:\"workitemarchive\") " + //
" AND ($workflowgroup:Zahlungseingang) AND ($workitemref:\""
+ invoice.getUniqueID() + "\" )";
" AND ($workflowgroup:Zahlungseingang) AND ($workitemref:\"" + invoice.getUniqueID() + "\" )";
List<ItemCollection> workitems = null;
try {
workitems = documentService.findStubs(sQuery, 99, 0,
"payment.date", true);
workitems = documentService.findStubs(sQuery, 99, 0, "payment.date", true);
if (workitems.size() > 0) {
return workitems.get(0).getItemValueDate("payment.date");
}

View file

@ -36,8 +36,8 @@ import jakarta.inject.Inject;
* 2.2.22 - Das Plugin erzeugt auch das Feld _img welches die Images von
* Sofortüberweisung, Mahnung und Ablehnung anzeigt.
*
* 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id
* zusätzlich processed es das BP Workitem
* 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id zusätzlich
* processed es das BP Workitem
*
* @author rsoika
* @version 1.0
@ -403,8 +403,7 @@ public class InvoicePlugin extends AbstractPlugin {
if (result == null || result.size() == 0) {
String message = resourceBundleHandler.findMessage("ERROR_CDTR_INVALID");
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
message);
throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
} else {
// update cargosoft crediotr name

View file

@ -89,8 +89,7 @@ public class InvoiceService {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List<String> currencyList = configItemCollection.getItemValue("currency.out");
if (currencyList == null || currencyList.size() < 1) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
return currencyList;
@ -108,8 +107,7 @@ public class InvoiceService {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List<String> currencyList = configItemCollection.getItemValue("currency.out");
if (currencyList == null || currencyList.size() < 1) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
return currencyList.get(0);
@ -127,16 +125,14 @@ public class InvoiceService {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List<String> currencyList = configItemCollection.getItemValue("currency.in");
if (currencyList == null || currencyList.size() < 1) {
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
return currencyList;
}
/**
* Prüft ob der Vorgang überflällig ist.
* Default ist 21 tage.
* Prüft ob der Vorgang überflällig ist. Default ist 21 tage.
*/
public boolean isOverdue(Date date, int taskid) {
Date now = new Date();

View file

@ -13,9 +13,7 @@ import org.imixs.workflow.ItemCollection;
* Hilfsmethoden für die Berechnung und Validierung von Ein und
* Ausgangsrechnugnen
*
* - Rundungs Methode
* - Berechnung der Positionsnummern
* - Explode Childitems
* - Rundungs Methode - Berechnung der Positionsnummern - Explode Childitems
*
* See:
* https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places
@ -63,9 +61,7 @@ public class InvoiceUtil {
String regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
+ "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
return Pattern.compile(regexPattern)
.matcher(emailAddress)
.matches();
return Pattern.compile(regexPattern).matcher(emailAddress).matches();
}
// @Deprecated
@ -130,10 +126,9 @@ public class InvoiceUtil {
/**
* Diese Methode berechnet das feld 'invoice.positions' welches eine Valueliste
* mit allen Positionsnummern aus dem Childliste enthält.
* Es wird sowohl für Ausgangs wie Eingangsrechnungen genutzt.
* Das feld wird indiziert, so dass eine gezielte Suche nach positiosnummern
* möglich ist.
* mit allen Positionsnummern aus dem Childliste enthält. Es wird sowohl für
* Ausgangs wie Eingangsrechnungen genutzt. Das feld wird indiziert, so dass
* eine gezielte Suche nach positiosnummern möglich ist.
*
* @param workitem
*/

View file

@ -74,8 +74,7 @@ public class OPListController implements Serializable {
* Diese Methode wird für Zahlungseingänge und Mahnläufe verwendet.
* <p>
* Die Methode liefert die Rechnungen zur gegebenen dbtrNumber. Die Methode
* nutzt
* einen lokalen cache um die Zugriffe zu beschleunigen.
* nutzt einen lokalen cache um die Zugriffe zu beschleunigen.
* <p>
* Befindet sich ein Zahlungseingang in Erstellung (Task=1000) werden alle
* offenen Rechnungen geholt.
@ -185,8 +184,7 @@ public class OPListController implements Serializable {
// einer Rechnung mit dem Event 100 (Mahnlauf erstellen) kommen, oder
// wenn der Mahnlauf von außen gerate eben neu erzeugt wurde
if (workflowController.getWorkitem().getItemValueInteger("$lastevent") == 100
||
workflowController.getWorkitem().getItemValueInteger("$lastevent") == 0) {
|| workflowController.getWorkitem().getItemValueInteger("$lastevent") == 0) {
List<String> intialSelection = new ArrayList<String>();
for (ItemCollection invoice : invoiceList) {
// ist die Rechnung fällig?
@ -323,9 +321,9 @@ public class OPListController implements Serializable {
}
/**
* Berechnet die Summer aller Rechnungen zu einer Währung.
* Es werden nur Rechnungen berücksichtigt, deren Haupt Währung der übergebenen
* Währung entspricht.
* Berechnet die Summer aller Rechnungen zu einer Währung. Es werden nur
* Rechnungen berücksichtigt, deren Haupt Währung der übergebenen Währung
* entspricht.
*
* @param currency
* @return

View file

@ -95,9 +95,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
}
// read the template options
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste",
document,
false);
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
"missing opliste configuration in model event - please check model configuration");
@ -132,13 +130,11 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
null);
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
document.addFileData(fileDataNew);
logger.finest("......new document added");
} catch (IOException | QueryException e) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@ -157,8 +153,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
} catch (
PluginException e) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update op-liste: " + e.getMessage());
}
logger.fine("... completed!");
@ -211,8 +206,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
* @throws QueryException
*/
private void insertInvoiceRows(XSSFSheet sheet, ItemCollection document, String fileName, boolean filter,
List<String> currencyList)
throws PluginException, QueryException {
List<String> currencyList) throws PluginException, QueryException {
String spaceID = document.getItemValueString("space.ref");
logger.fine("... space.ref=" + spaceID + " ...grouping invoices by spaceid....");
@ -349,12 +343,10 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
* @throws PluginException
*/
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
String targetName)
throws PluginException {
String targetName) throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - textblock/template reference not defined!");
}
@ -363,10 +355,8 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
// do we found the document?
if (fileData == null) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - template=" + template
+ " not found!");
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document

View file

@ -119,9 +119,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
Collections.sort(spaces, new ItemCollectionComparator("space.name", true));
// read the template options
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste",
document,
false);
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
"missing opliste configuration in model event - please check model configuration");
@ -155,14 +153,12 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
null);
FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
document.addFileData(fileDataNew);
logger.finest("......new document added");
} catch (IOException | QueryException e) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@ -180,8 +176,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
} catch (
PluginException e) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update op-liste: " + e.getMessage());
}
logger.fine("... completed!");
@ -254,8 +249,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
* @throws QueryException
*/
private void insertInvoiceRows(XSSFWorkbook doc, XSSFSheet sheet, List<String> currencyList,
List<ItemCollection> spaces)
throws PluginException, QueryException {
List<ItemCollection> spaces) throws PluginException, QueryException {
List<String> spaceNames = new ArrayList<String>();
@ -285,8 +279,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
}
/*
* --- Phase 1 -------------------------------------------------------
* Im folgenden gruppieren wir die Rechnungen nach Woche
* --- Phase 1 ------------------------------------------------------- Im
* folgenden gruppieren wir die Rechnungen nach Woche
*/
// XSSFCell cellKWTotalReference = referenceRowTotal.getCell(14);
@ -306,10 +300,10 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
totalDataMapUeberFaellig.put("TOTAL", new TotalInvoiceData("TOTAL"));
/*
* --- Phase 3 -------------------------------------------------------
* now build a new row for each week and print out the collected invoice data
* first iterate over all objects and collect all known weeks and sort them into
* a ordered list....
* --- Phase 3 ------------------------------------------------------- now build
* a new row for each week and print out the collected invoice data first
* iterate over all objects and collect all known weeks and sort them into a
* ordered list....
*/
List<String> sortedWeekList = new ArrayList<String>();
Iterator<Map.Entry<String, WeekInvoiceData>> iterator = weekDataMap.entrySet().iterator();
@ -323,9 +317,9 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
Collections.sort(sortedWeekList);
/*
* --- Phase 4 -------------------------------------------------------
* Nun müssen wir so viele Zeilen nach unten schieben wie wir gleich einfügen.
* Dazu müssen wir kurz einen Probelauf machen um die geplante Anzahl zu
* --- Phase 4 ------------------------------------------------------- Nun
* müssen wir so viele Zeilen nach unten schieben wie wir gleich einfügen. Dazu
* müssen wir kurz einen Probelauf machen um die geplante Anzahl zu
* errechnen....
*/
int rowPos = 11;
@ -333,8 +327,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
sheet.shiftRows(rowPos + 1, 2999, insertCount, true, true);
/*
* --- Phase 5 -------------------------------------------------------
* Jetzt Zahlen Zeile für Zeile einfügen....
* --- Phase 5 ------------------------------------------------------- Jetzt
* Zahlen Zeile für Zeile einfügen....
*/
boolean ueberFaellig = true;
for (String week : sortedWeekList) {
@ -399,9 +393,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
}
/*
* --- Phase 6 -------------------------------------------------------
* now lets update the totals...
* Überfällig
* --- Phase 6 ------------------------------------------------------- now lets
* update the totals... Überfällig
*/
int _rowNo = sortedWeekList.size() + 14;
XSSFRow rowUeberFaellig = sheet.getRow(_rowNo);
@ -462,14 +455,12 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
* Diese Methode gruppiert eine Rechnungsliste nach Kalenderwoche
*
* @param spaceID - Space Ref to select a list of invoices associated with
* a
* space
* a space
* @param weekDataCache - a local cache storing all invoices by week
*
*
*/
private void groupInvoicesByWeek(String spaceID, String spaceName,
Map<String, WeekInvoiceData> weekDataCache) {
private void groupInvoicesByWeek(String spaceID, String spaceName, Map<String, WeekInvoiceData> weekDataCache) {
logger.info("...group invoices for " + spaceName + "/" + spaceID);
try {
@ -482,9 +473,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
// compute Week
Date dueDate = invoice.getItemValueDate("invoice.duedate");
LocalDate localDate = dueDate.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
LocalDate localDate = dueDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int weekNumber = localDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
int weekBasedYear = localDate.get(IsoFields.WEEK_BASED_YEAR);
String weekCategory = weekBasedYear + "/" + String.format("%02d", weekNumber);
@ -526,12 +515,10 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
* @throws PluginException
*/
private FileData appendExcelTemplate(ItemCollection document, String textblockRef, String template,
String targetName)
throws PluginException {
String targetName) throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - textblock/template reference not defined!");
}
@ -540,10 +527,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
// do we found the document?
if (fileData == null) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(),
InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - template=" + template
+ " not found!");
throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document
@ -555,8 +540,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
}
/**
* Data Element for invoice totals per week and space.
* The object holds multiple currencies.
* Data Element for invoice totals per week and space. The object holds multiple
* currencies.
*/
class WeekInvoiceData {
@ -601,8 +586,8 @@ class WeekInvoiceData {
}
/**
* Data Element for invoice totals per space.
* The object holds multiple currencies.
* Data Element for invoice totals per space. The object holds multiple
* currencies.
*/
class TotalInvoiceData {

View file

@ -34,8 +34,7 @@ import jakarta.inject.Named;
/**
* The OPListExportController is used to configure the OpListeExporterService.
* This service is
* used to export workitems.
* This service is used to export workitems.
* <p>
* The Controller creates a configuration entity "type=configuration;
* txtname=OPLIST_EXPORT_CONFIGURATION".

View file

@ -139,8 +139,8 @@ public class OPListExportScheduler implements Scheduler {
List<ItemCollection> invoices = new ArrayList<ItemCollection>();
try {
invoices = documentService.find(
"$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" + space.getUniqueID(),
999, 0);
"$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" + space.getUniqueID(), 999,
0);
} catch (QueryException e) {
logger.warning("Failed to compute invoice list: " + e.getMessage());
e.printStackTrace();

View file

@ -28,8 +28,8 @@ import jakarta.inject.Inject;
*
* Bei Sachrechnungen
*
* sequencenumber + "_" + invoice.number.stripped + ".pdf"
* wird das Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.
* sequencenumber + "_" + invoice.number.stripped + ".pdf" wird das
* Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.
*
*
*
@ -59,8 +59,7 @@ public class RenameFilenamesAdapter implements SignalAdapter {
for (FileData fileData : fileDataSet) {
String fileName = fileData.getName();
// only PDF files and X-Rechnung
if ((fileName.toLowerCase().endsWith(".pdf")
|| fileName.toLowerCase().endsWith(".xml"))) {
if ((fileName.toLowerCase().endsWith(".pdf") || fileName.toLowerCase().endsWith(".xml"))) {
// Build new Filename
String newFileName = buildFileName(fileName, workitem, fileNameCounter);

View file

@ -14,9 +14,9 @@ import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* Der SEPAExportControllerAGL dient dazu die IBAN/BIC einstellungen in
* einem SEPA Export zu aktualiseren. Er wird von der Form
* sepa_export.xhtml aus per Ajax angesteuert.
* Der SEPAExportControllerAGL dient dazu die IBAN/BIC einstellungen in einem
* SEPA Export zu aktualiseren. Er wird von der Form sepa_export.xhtml aus per
* Ajax angesteuert.
*
* @author rsoika
*

View file

@ -12,8 +12,8 @@ import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* Der SteuerListController dient dazu in einem Stuerbescheid
* die einzelnen Zeilen auszugeben.
* Der SteuerListController dient dazu in einem Stuerbescheid die einzelnen
* Zeilen auszugeben.
*
* @author rsoika
*

View file

@ -17,11 +17,8 @@ import jakarta.inject.Inject;
* Das SteuerbescheidPlugin prüft ob
*
* - die ATC Nummer aus dem Steuerbescheid in einer Ausgangsrechnung gefunden
* wird ($taskID<5990)
* - invoice.atc.number
* - der Betrag "invoice.total.net"
* - die Währung???
* - die Positionsnummer ???
* wird ($taskID<5990) - invoice.atc.number - der Betrag "invoice.total.net" -
* die Währung??? - die Positionsnummer ???
*
*
* @author rsoika
@ -77,8 +74,8 @@ public class SteuerbescheidPlugin extends AbstractPlugin {
}
/**
* Aktualisiert die EUST/ZOLL Fälligkeiten in den Detailtabellen
* Die Daten kommen von der KI und werden auf die Positionsnummern gemappt.
* Aktualisiert die EUST/ZOLL Fälligkeiten in den Detailtabellen Die Daten
* kommen von der KI und werden auf die Positionsnummern gemappt.
*
*/
protected void updateFaelligkeit(ItemCollection workitem) {
@ -164,8 +161,7 @@ public class SteuerbescheidPlugin extends AbstractPlugin {
protected List<ItemCollection> findInvoices(String atcNumber) {
List<ItemCollection> result = new ArrayList<ItemCollection>();
String query = "(type:workitem OR type:workitemarchive) AND ($taskid:[5000 TO 5990])"
+ " AND invoice.atc.number:\"" + atcNumber + "\" "
+ " AND $workflowgroup:\"Rechnungsausgang\" ";
+ " AND invoice.atc.number:\"" + atcNumber + "\" " + " AND $workflowgroup:\"Rechnungsausgang\" ";
try {
result = documentService.find(query, 999, 0, "$created", false);
return result;

View file

@ -127,13 +127,11 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
String mainCurrency = invoiceService.getCurrenciesOutMain();
if ((!invoiceCurrency.equals(paymentCurrency))
&& (!invoiceCurrency.equals(mainCurrency) &&
!paymentCurrency.equals(mainCurrency))) {
&& (!invoiceCurrency.equals(mainCurrency) && !paymentCurrency.equals(mainCurrency))) {
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT4");
message = message.replace("{1}", mainCurrency);
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
message);
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
if (!invoiceCurrency.equals(paymentCurrency)) {
@ -142,8 +140,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
message = message.replace("{1}", paymentCurrency);
message = message.replace("{2}", invoiceNumber);
throw new PluginException(PluginException.class.getName(),
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
message);
ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
}
@ -151,8 +148,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
* Falls die Währung der Rechnung von der Währung der Zahlung abweicht, dann
* rechnen wir den PaymentAmmout mit der Rate aus.
*/
if ("EUR".equals(paymentCurrency) &&
!invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
if ("EUR".equals(paymentCurrency) && !invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
invoicePaymentAmount = invoicePaymentAmount * invoiceRate;
// runde auf 2 Stellen
invoicePaymentAmount = (float) InvoiceUtil.round(invoicePaymentAmount);

View file

@ -15,8 +15,8 @@ import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
/**
* The PromptExampleAdapterXML is a CDI bean that creates XML examples based
* on the last 3 invoices.
* The PromptExampleAdapterXML is a CDI bean that creates XML examples based on
* the last 3 invoices.
*
* The adapter only runs if the prompt template contains
*
@ -79,8 +79,7 @@ public class PromptExampleAdapterXML {
if (invoices != null && invoices.size() > 0) {
// Build an example for each invoice
for (ItemCollection invoice : invoices) {
promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData,
exampleHeaderXML);
promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData, exampleHeaderXML);
}
}
prompt = prompt.replace("<<EXAMPLES_XML>>", "" + promptExamples);
@ -126,13 +125,11 @@ public class PromptExampleAdapterXML {
example.append(
" <invoice.number>" + invoice.getItemValueString("invoice.number") + "</invoice.number>\n");
if (invoice.getItemValueDate("invoice.date") != null) {
example.append(
" <invoice.date>" + dateFormat.format(invoice.getItemValueDate("invoice.date"))
example.append(" <invoice.date>" + dateFormat.format(invoice.getItemValueDate("invoice.date"))
+ "</invoice.date>\n");
}
if (invoice.getItemValueDate("invoice.duedate") != null) {
example.append(
" <invoice.duedate>" + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
example.append(" <invoice.duedate>" + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
+ "</invoice.duedate>\n");
}
example.append(" <invoice.total type=\"double\">" + invoice.getItemValueDouble("invoice.total")
@ -154,8 +151,7 @@ public class PromptExampleAdapterXML {
List<ItemCollection> result = new ArrayList<>();
String searchTerm = "(type:workitemarchive) AND ($modelversion:rechnungseingang*) AND ($taskid:5900) AND NOT ($uniqueid:"
+ currentID + ") AND (document.company:\""
+ companyName + "\")";
+ currentID + ") AND (document.company:\"" + companyName + "\")";
try {
result = documentService.find(searchTerm, 3, 0, "$modified", true);
} catch (QueryException e) {

View file

@ -145,8 +145,7 @@ public class CargosoftMigrationRestService implements Serializable {
isRunning = true;
int totalCount = documentService.count(query);
log("│   ├── found " + totalCount + " cargosoft entries",
messageBuffer);
log("│   ├── found " + totalCount + " cargosoft entries", messageBuffer);
// Berechne Anzahl der benötigten Pages
int totalPages = (int) Math.ceil((double) totalCount / batchSize);
@ -169,8 +168,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
// Fortschritt loggen
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
" (" + totalObjects + " objects read, " + syncs + " total syncs)", messageBuffer);
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + " (" + totalObjects
+ " objects read, " + syncs + " total syncs)", messageBuffer);
// Optional: Kurze Pause nach jedem 5. Batch
try {
Thread.sleep(100);
@ -185,8 +184,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
long duration = System.currentTimeMillis() - l;
double objectsPerSecond = totalObjects / (duration / 1000.0);
log("├── Successfully " + syncs + " business partner objects synced in " +
duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
log("├── Successfully " + syncs + " business partner objects synced in " + duration + "ms ("
+ String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
isRunning = false;
return messageBuffer.toString();
@ -273,8 +272,8 @@ public class CargosoftMigrationRestService implements Serializable {
// Fortschritt loggen
iterations++;
log("│ ├── Processed page " + (iterations) + " of " + totalPages +
" (" + deletions + " total deletions)", messageBuffer);
log("│ ├── Processed page " + (iterations) + " of " + totalPages + " (" + deletions + " total deletions)",
messageBuffer);
// Optional: Kurze Pause nach jedem 5. Batch
try {
@ -290,8 +289,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
long duration = System.currentTimeMillis() - l;
double objectsPerSecond = totalObjects / (duration / 1000.0);
log("├── Successfully " + deletions + " business partner objects deleted in " +
duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
log("├── Successfully " + deletions + " business partner objects deleted in " + duration + "ms ("
+ String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
isRunning = false;
return messageBuffer.toString();
@ -373,8 +372,8 @@ public class CargosoftMigrationRestService implements Serializable {
// Fortschritt loggen
// Fortschritt loggen
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
" (" + deletions + " total deletions)", messageBuffer);
log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + " (" + deletions
+ " total deletions)", messageBuffer);
// Optional: Kurze Pause nach jedem 5. Batch
try {
Thread.sleep(100);
@ -389,8 +388,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
long duration = System.currentTimeMillis() - l;
double objectsPerSecond = totalObjects / (duration / 1000.0);
log("├── Successfully " + deletions + " duplicated cargosoft objects deleted in " +
duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
log("├── Successfully " + deletions + " duplicated cargosoft objects deleted in " + duration + "ms ("
+ String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
isRunning = false;
return messageBuffer.toString();

View file

@ -139,9 +139,7 @@ public class DataRestService {
protected Client createClient(String serviceAPI, String sessionID) {
// Create a Cookie object with a name and a value
Cookie cookie = new Cookie.Builder("JSESSIONID")
.value(sessionID)
.path("/")
Cookie cookie = new Cookie.Builder("JSESSIONID").value(sessionID).path("/")
// .domain("domain.com")
.build();

View file

@ -132,8 +132,7 @@ public class ExcelExportController implements Serializable {
// query Sachprüfung
if (!filter.getItemValueString("space.ref").isEmpty()
&& !"-".equals(filter.getItemValueString("space.ref"))) {
if (!filter.getItemValueString("space.ref").isEmpty() && !"-".equals(filter.getItemValueString("space.ref"))) {
query += " AND ($uniqueidref:" + filter.getItemValueString("space.ref") + ")";
}
if (workflowController.getWorkitem() != null

View file

@ -17,8 +17,8 @@ import jakarta.inject.Inject;
/**
* Der InkassoAppendAdapter verknüpft eine Rechnung mit einem Inkasso Workflow
* zum aktuellen Debitor. Existiert aktuell kein Inkasso für diesen
* Debitor erzeugt der Adapter automatisch eine neue Prozessinstanz.
* zum aktuellen Debitor. Existiert aktuell kein Inkasso für diesen Debitor
* erzeugt der Adapter automatisch eine neue Prozessinstanz.
* <p>
* Wurde die Rechnung bereits einem Inkasso zugeordnet passiert nichts.
*
@ -41,8 +41,8 @@ public class InkassoAppendAdapter implements SignalAdapter {
WorkflowService workflowService;
/**
* This method finds or create the Inkasso and adds a reference
* ($workitemref) to the current invoice.
* This method finds or create the Inkasso and adds a reference ($workitemref)
* to the current invoice.
*
* @throws PluginException
*/
@ -59,8 +59,8 @@ public class InkassoAppendAdapter implements SignalAdapter {
/**
* Diese method hängt eine referenz der aktuellen Rechnung an den Inkasso
* Workflow an. Gibt es noch keinen, wird einer erzeugt.
* Die method liefert das Inkasso Workitem zurück.
* Workflow an. Gibt es noch keinen, wird einer erzeugt. Die method liefert das
* Inkasso Workitem zurück.
*
* @param document
* @throws PluginException

View file

@ -15,8 +15,8 @@ import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* Der InkassoController dient dazu eine bereits zugewiesene Rechnung
* wieder aus dem Inkasso zu entfernen.
* Der InkassoController dient dazu eine bereits zugewiesene Rechnung wieder aus
* dem Inkasso zu entfernen.
* <p>
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
* abgezogen werden.

View file

@ -29,8 +29,8 @@ import jakarta.inject.Inject;
* processed invoices. This item is used in the Workflow Model to construct a
* HTML Table wen sending the mail.
* <p>
* The Adapter also splits the item 'dbtr.mail' into a multi value field if
* the value contains email addresses separated with new lines.
* The Adapter also splits the item 'dbtr.mail' into a multi value field if the
* value contains email addresses separated with new lines.
*
*
* @version 1.0
@ -198,8 +198,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
for (String mail : mailListe) {
logger.fine(" test mail address:'" + mail + "'");
if (!InvoiceUtil.validateEmail(mail)) {
throw new PluginException(MahnlaufExecuteAdapter.class.getName(),
"INVALID_EMAIL",
throw new PluginException(MahnlaufExecuteAdapter.class.getName(), "INVALID_EMAIL",
"Die Daten konnten nicht aktualisiert werden! Bitte geben Sie eine gültige E-Mail Adresse ein!");
}
}

View file

@ -63,8 +63,7 @@ public class MahnlaufRefAddAdapter implements SignalAdapter {
if (invoice.getTaskID() < MahnlaufService.TASK_MAHNLAUF_START
|| invoice.getTaskID() > MahnlaufService.TASK_MAHNLAUF_END) {
throw new PluginException(MahnlaufRefAddAdapter.class.getName(),
MahnlaufService.ERROR_CONFIG,
throw new PluginException(MahnlaufRefAddAdapter.class.getName(), MahnlaufService.ERROR_CONFIG,
"Der Mahnlauf kann nur für Rechnungen erstellt werden die bereits die Fälligkeit erreicht haben.");
}
@ -92,8 +91,8 @@ public class MahnlaufRefAddAdapter implements SignalAdapter {
workflowService.processWorkItem(mahnLaufWorkitem);
} catch (QueryException | ModelException e) {
throw new PluginException(MahnlaufRefAddAdapter.class.getName(),
MahnlaufService.ERROR_CONFIG, "Unable to create Mahnlauf", e);
throw new PluginException(MahnlaufRefAddAdapter.class.getName(), MahnlaufService.ERROR_CONFIG,
"Unable to create Mahnlauf", e);
}
// set mahnlauf ref

View file

@ -49,8 +49,8 @@ import jakarta.ejb.Singleton;
import jakarta.inject.Inject;
/**
* Der MahnlaufService wird vom MahnlaufExecuteAdapter um
* Ausgangsrechnungen zu akutalisieren.
* Der MahnlaufService wird vom MahnlaufExecuteAdapter um Ausgangsrechnungen zu
* akutalisieren.
*
* @author rsoika
*

View file

@ -59,11 +59,10 @@ import jakarta.enterprise.event.Observes;
/**
* Der BusinessPartnerImportService hängt sich an den standard CSVImport Service
* der die Cargosoft Stammdaten aktualisiert.
* Es ist ein simples Observer Pattern das auf das Document Event
* "ON_DOCUMENT_SAVE" reagiert. Hier hängt sich der BusinessPartnerImportService
* ein und prüft ob der Workflow schon existiert oder ggf. aktualisiert werden
* muss.
* der die Cargosoft Stammdaten aktualisiert. Es ist ein simples Observer
* Pattern das auf das Document Event "ON_DOCUMENT_SAVE" reagiert. Hier hängt
* sich der BusinessPartnerImportService ein und prüft ob der Workflow schon
* existiert oder ggf. aktualisiert werden muss.
* <p>
* Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der
* Business partner erstmals neu angelegt wird.

View file

@ -89,17 +89,16 @@ import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
/**
* Der CargosoftXMLEAkteImportService erweitert den FTPImportService und
* kann XML EAkten (Steuerbescheide) von Cargosoft importieren.
* Der Service reagiert auf DocumentImportEvents und kann über das Options Feld
* konfiguriert werden.
* Der CargosoftXMLEAkteImportService erweitert den FTPImportService und kann
* XML EAkten (Steuerbescheide) von Cargosoft importieren. Der Service reagiert
* auf DocumentImportEvents und kann über das Options Feld konfiguriert werden.
* <p>
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
* speziellen Verfahren geparsed und dann als Steuerbescheid importiert.
* <p>
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt
* diese beim Import nicht mit der Mandanten Nummer in der XML Datei überein,
* wird das XML Dokument gelöscht und nicht importiert.
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt diese
* beim Import nicht mit der Mandanten Nummer in der XML Datei überein, wird das
* XML Dokument gelöscht und nicht importiert.
*
*
*
@ -162,8 +161,7 @@ public class CargosoftXMLEAkteImportService {
return;
}
documentImportService.logMessage("...CARGOSOFT_EAKTE_XML Import started: mandant.id=" + mandantID,
event);
documentImportService.logMessage("...CARGOSOFT_EAKTE_XML Import started: mandant.id=" + mandantID, event);
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
@ -216,8 +214,8 @@ public class CargosoftXMLEAkteImportService {
ftpClient.connect(ftpServer, ftpPort);
if (ftpClient.login(ftpUser, ftpPassword) == false) {
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"FTP_ERROR", "FTP file transfer failed: login failed!");
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
"FTP file transfer failed: login failed!");
}
ftpClient.enterLocalPassiveMode();
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
@ -225,8 +223,7 @@ public class CargosoftXMLEAkteImportService {
ftpClient.setControlEncoding("UTF-8");
} catch (IOException e) {
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"FTP_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
}
return ftpClient;
@ -250,8 +247,8 @@ public class CargosoftXMLEAkteImportService {
// try to enter the working directory and read all files...
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
if (bWorkingDir == false) {
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"FTP_ERROR", "...failed to change into working directory: ");
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
"...failed to change into working directory: ");
}
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
@ -299,10 +296,10 @@ public class CargosoftXMLEAkteImportService {
// "processed/");
// }
} catch (AccessDeniedException | ProcessingErrorException | PluginException
| ModelException | XPathExpressionException | TransformerException e) {
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"FTP_ERROR", e.getMessage());
} catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException
| XPathExpressionException | TransformerException e) {
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
e.getMessage());
}
}
documentImportService.logMessage("..." + count + " new files imported.", event);
@ -313,8 +310,7 @@ public class CargosoftXMLEAkteImportService {
int r = ftpClient.getReplyCode();
logger.severe("FTP ReplyCode=" + r);
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"FTP_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
} finally {
// do logout....
@ -324,8 +320,7 @@ public class CargosoftXMLEAkteImportService {
ftpClient.disconnect();
} catch (IOException e) {
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"FTP_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
}
}
}
@ -344,9 +339,8 @@ public class CargosoftXMLEAkteImportService {
* @throws XPathExpressionException
*/
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
Map<String, List<String>> spacePosMappings)
throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException,
XPathExpressionException, TransformerException {
Map<String, List<String>> spacePosMappings) throws AccessDeniedException, ProcessingErrorException,
PluginException, ModelException, XPathExpressionException, TransformerException {
ItemCollection workitem = new ItemCollection();
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
@ -375,37 +369,37 @@ public class CargosoftXMLEAkteImportService {
// invoice.rate
// invoice.base.amount
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='client']", workitem,
"mandant.id", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='client']", workitem, "mandant.id",
String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_voucher_number']",
workitem, "invoice.number", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_voucher_number']", workitem,
"invoice.number", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_address_number']",
workitem, "cdtr.number", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_address_number']", workitem,
"cdtr.number", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='voucherdate']",
workitem, "invoice.date", Date.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='voucherdate']", workitem,
"invoice.date", Date.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency']",
workitem, "invoice.currency", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency']", workitem,
"invoice.currency", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency_rate']",
workitem, "invoice.rate", Double.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency_rate']", workitem,
"invoice.rate", Double.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_net_amount']",
workitem, "invoice.total.net", Double.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_tax_amount']",
workitem, "invoice.total.tax", Double.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='reference']",
workitem, "invoice.atc.number", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_period']",
workitem, "invoice.booking_period", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_net_amount']", workitem,
"invoice.total.net", Double.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_tax_amount']", workitem,
"invoice.total.tax", Double.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='reference']", workitem,
"invoice.atc.number", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_period']", workitem,
"invoice.booking_period", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_date']",
workitem, "invoice.booking_date", Date.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_text']",
workitem, "invoice.booking_text", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_date']", workitem,
"invoice.booking_date", Date.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_text']", workitem,
"invoice.booking_text", String.class);
// verify if invoice is already imported.
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
@ -440,8 +434,7 @@ public class CargosoftXMLEAkteImportService {
attacheFiles(doc, workitem);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
"XML_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "XML_ERROR", e.getMessage());
}
return workitem;
}
@ -452,8 +445,7 @@ public class CargosoftXMLEAkteImportService {
*
* /Invoices/Invoice/InvoiceHeader/Client/Code
*
* Beispiel Datum:
* <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
* Beispiel Datum: <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
*
* @param doc - xml doc
* @param expression - xpath expression
@ -513,9 +505,9 @@ public class CargosoftXMLEAkteImportService {
}
/**
* This method attache the pdf file and the XML file to the workitem.
* The method removes the file content first form the xml tree and attache the
* XML without the pdf data.
* This method attache the pdf file and the XML file to the workitem. The method
* removes the file content first form the xml tree and attache the XML without
* the pdf data.
*
* @throws XPathExpressionException
* @throws TransformerException
@ -526,24 +518,23 @@ public class CargosoftXMLEAkteImportService {
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
// read filename and content....
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Filename",
workitem, "import.filename", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Content",
workitem, "import.filedata", String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Filename", workitem, "import.filename",
String.class);
readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Content", workitem, "import.filedata",
String.class);
// attache the PDF file content
String fileDataString = workitem.getItemValueString("import.filedata");
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
FileData fileData = new FileData(workitem.getItemValueString("import.filename"),
decodedPDFData, "application/pdf", null);
FileData fileData = new FileData(workitem.getItemValueString("import.filename"), decodedPDFData,
"application/pdf", null);
workitem.addFileData(fileData);
// remove the temp items..
workitem.removeItem("import.filename");
workitem.removeItem("import.filedata");
// next remove the Attachments/AttachmentContent from the dom tree
XPathExpression attachmentsExpr = xpath
.compile("/CargoSoftEFile/EFile/Attachments/Attachment/Content");
XPathExpression attachmentsExpr = xpath.compile("/CargoSoftEFile/EFile/Attachments/Attachment/Content");
NodeList contentNodes = (NodeList) attachmentsExpr.evaluate(doc, XPathConstants.NODESET);
// Remove the matching nodes
for (int i = 0; i < contentNodes.getLength(); i++) {
@ -594,8 +585,7 @@ public class CargosoftXMLEAkteImportService {
* child Workitem for each row.
*
* The method assumes that the rows are starting with the type 'row_n_' where
* 'n' is the row number.
* We start with row 1 and read until we found more rows.
* 'n' is the row number. We start with row 1 and read until we found more rows.
*
* Example:
*

View file

@ -89,19 +89,18 @@ import jakarta.inject.Inject;
/**
* Der CargosoftXMLInvoiceImportImportService erweitert den FTPImportService und
* kann XML Invoice Dokumente von Cargosoft importieren.
* Der Service reagiert auf DocumentImportEvents und kann über das Options Feld
* konfiguriert werden.
* kann XML Invoice Dokumente von Cargosoft importieren. Der Service reagiert
* auf DocumentImportEvents und kann über das Options Feld konfiguriert werden.
* <p>
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
* speziellen Verfahren geparsed und dann als Ausgangsrechnungen importiert.
* Der Service ersetzt den alten DATEV Import. Falls eine Rechnung schon
* existiert (Rechnungsnummer) wird der Datensatz vom FTP Laufwerk gelöscht und
* nicht importiert.
* speziellen Verfahren geparsed und dann als Ausgangsrechnungen importiert. Der
* Service ersetzt den alten DATEV Import. Falls eine Rechnung schon existiert
* (Rechnungsnummer) wird der Datensatz vom FTP Laufwerk gelöscht und nicht
* importiert.
* <p>
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt
* diese beim Import nicht mit der Mandanten Nummer in der XML Datei überein,
* wird das XML Dokument gelöscht und nicht importiert.
* In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt diese
* beim Import nicht mit der Mandanten Nummer in der XML Datei überein, wird das
* XML Dokument gelöscht und nicht importiert.
*
*
*
@ -164,8 +163,7 @@ public class CargosoftXMLInvoiceImportService {
return;
}
documentImportService.logMessage("...CARGOSOFT_INVOICE_XML Import started: mandant.id=" + mandantID,
event);
documentImportService.logMessage("...CARGOSOFT_INVOICE_XML Import started: mandant.id=" + mandantID, event);
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
@ -218,8 +216,8 @@ public class CargosoftXMLInvoiceImportService {
ftpClient.connect(ftpServer, ftpPort);
if (ftpClient.login(ftpUser, ftpPassword) == false) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"FTP_ERROR", "FTP file transfer failed: login failed!");
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
"FTP file transfer failed: login failed!");
}
ftpClient.enterLocalPassiveMode();
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
@ -227,8 +225,7 @@ public class CargosoftXMLInvoiceImportService {
ftpClient.setControlEncoding("UTF-8");
} catch (IOException e) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"FTP_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR", e.getMessage());
}
return ftpClient;
@ -252,8 +249,8 @@ public class CargosoftXMLInvoiceImportService {
// try to enter the working directory and read all files...
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
if (bWorkingDir == false) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"FTP_ERROR", "...failed to change into working directory: ");
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
"...failed to change into working directory: ");
}
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
@ -301,10 +298,10 @@ public class CargosoftXMLInvoiceImportService {
// "processed/");
// }
} catch (AccessDeniedException | ProcessingErrorException | PluginException
| ModelException | XPathExpressionException | TransformerException e) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"FTP_ERROR", e.getMessage());
} catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException
| XPathExpressionException | TransformerException e) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
e.getMessage());
}
}
documentImportService.logMessage("..." + count + " new files imported.", event);
@ -315,8 +312,7 @@ public class CargosoftXMLInvoiceImportService {
int r = ftpClient.getReplyCode();
logger.severe("FTP ReplyCode=" + r);
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"FTP_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR", e.getMessage());
} finally {
// do logout....
@ -326,8 +322,8 @@ public class CargosoftXMLInvoiceImportService {
ftpClient.disconnect();
} catch (IOException e) {
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"FTP_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
e.getMessage());
}
}
}
@ -346,9 +342,8 @@ public class CargosoftXMLInvoiceImportService {
* @throws XPathExpressionException
*/
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
Map<String, List<String>> spacePosMappings)
throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException,
XPathExpressionException, TransformerException {
Map<String, List<String>> spacePosMappings) throws AccessDeniedException, ProcessingErrorException,
PluginException, ModelException, XPathExpressionException, TransformerException {
ItemCollection workitem = new ItemCollection();
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
@ -377,11 +372,11 @@ public class CargosoftXMLInvoiceImportService {
// invoice.rate
// invoice.base.amount
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Client/Codes/Code", workitem,
"mandant.id", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Client/Codes/Code", workitem, "mandant.id",
String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceNumber",
workitem, "invoice.number", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceNumber", workitem, "invoice.number",
String.class);
// verify if invoice is already imported.
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
@ -389,14 +384,14 @@ public class CargosoftXMLInvoiceImportService {
return null;
}
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Codes/Code",
workitem, "invoice.type", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Description",
workitem, "invoice.type.description", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Codes/Code", workitem, "invoice.type",
String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Description", workitem,
"invoice.type.description", String.class);
// Rechnungssumme errechnen.....
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/NetAmount/Amount/Value",
workitem, "invoice.total.net", Double.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/NetAmount/Amount/Value", workitem,
"invoice.total.net", Double.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VATAmount/Amount/Value",
workitem, "invoice.total.tax", Double.class);
if (!workitem.hasItem("invoice.total.tax")) {
@ -416,34 +411,33 @@ public class CargosoftXMLInvoiceImportService {
}
// Steuer
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VAT/VATRate",
workitem, "invoice.vatrate", Double.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VAT/VATRate", workitem,
"invoice.vatrate", Double.class);
// Booking Period
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/BookingPeriod",
workitem, "invoice.bookingperiod", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/BookingPeriod", workitem, "invoice.bookingperiod",
String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceCurrency/Codes/Code",
workitem, "invoice.currency", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceCurrency/Codes/Code", workitem,
"invoice.currency", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceDate",
workitem, "invoice.date", Date.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceDate", workitem, "invoice.date", Date.class);
readXMLValue(doc,
"/Invoices/Invoice/InvoiceHeader/PaymentConditions/PaymentCondition/Codes/Code[@Type='cs']",
workitem, "payment.term", String.class);
// kostenstelle
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/CostUnit/Description",
workitem, "invoice.CostUnit", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/CostUnit/Description", workitem, "invoice.CostUnit",
String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate",
workitem, "invoice.duedate", Date.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate",
workitem, "invoice.reminder", Date.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate", workitem, "invoice.duedate",
Date.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate", workitem, "invoice.reminder",
Date.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAddress/Codes/Code",
workitem, "dbtr.number", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAddress/Codes/Code", workitem, "dbtr.number",
String.class);
String dbtrNumber = workitem.getItemValueString("dbtr.number");
if (dbtrNumber.startsWith("K") || dbtrNumber.startsWith("D")) {
workitem.setItemValue("dbtr.number", dbtrNumber.substring(1));
@ -487,8 +481,7 @@ public class CargosoftXMLInvoiceImportService {
attacheFiles(doc, workitem);
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
"XML_ERROR", e.getMessage());
throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "XML_ERROR", e.getMessage());
}
return workitem;
}
@ -512,8 +505,7 @@ public class CargosoftXMLInvoiceImportService {
*
* /Invoices/Invoice/InvoiceHeader/Client/Code
*
* Beispiel Datum:
* <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
* Beispiel Datum: <InvoiceDate>2024-05-13T00:00:00+02:00</InvoiceDate>
*
* @param doc - xml doc
* @param expression - xpath expression
@ -566,11 +558,9 @@ public class CargosoftXMLInvoiceImportService {
/**
* Hilfsmethode die die ATC Nummer sucht und in das workitem feld
* invoice.atc.number einträgt.
* Wir gehen davon aus, das wir über die ChildItems diese aus dem billingtexts
* schon ermittel haben.
* Es können mehrere ATC nummern existieren. Diese werden in einer Liste
* gespeichert
* invoice.atc.number einträgt. Wir gehen davon aus, das wir über die ChildItems
* diese aus dem billingtexts schon ermittel haben. Es können mehrere ATC
* nummern existieren. Diese werden in einer Liste gespeichert
*
* @param doc
* @param workitem
@ -595,15 +585,9 @@ public class CargosoftXMLInvoiceImportService {
*
* InvoiceRows/InvoiceRow
*
* Each row has the following items:
* _childitems {
* datev.shzeichen=[H],
* datev.kurs=[0.0],
* datev.basisumsatz=[0.0],
* datev.text=[R LA-PAP-2405-051],
* datev.konto=[3851],
* datev.umsatz=[3307.81],
* datev.wkz=[EUR]}}
* Each row has the following items: _childitems { datev.shzeichen=[H],
* datev.kurs=[0.0], datev.basisumsatz=[0.0], datev.text=[R LA-PAP-2405-051],
* datev.konto=[3851], datev.umsatz=[3307.81], datev.wkz=[EUR]}}
*
* @param doc - xml doc
* @param workitem
@ -622,8 +606,7 @@ public class CargosoftXMLInvoiceImportService {
XPathExpression netAmountExchangeRateExpr = xPath
.compile("InvoiceAmount/NetAmount/Amount/ExchangeRate/text()");
XPathExpression netActivityTypeExpr = xPath
.compile("ActivityType/Codes/Code[@Type='cs']/text()");
XPathExpression netActivityTypeExpr = xPath.compile("ActivityType/Codes/Code[@Type='cs']/text()");
NodeList rowList = doc.getElementsByTagName("InvoiceRow");
double _kurs = 0.0;
@ -732,13 +715,10 @@ public class CargosoftXMLInvoiceImportService {
}
/**
* G = Gutschrift
* SR = Stornorechnung
* GK = Sammelgutschrift
* SS = Sammelrechnung Storno
* G = Gutschrift SR = Stornorechnung GK = Sammelgutschrift SS = Sammelrechnung
* Storno
*
* müssen wir das vorzeichen ändern
* dies wird über den Invoice.Type geprüft
* müssen wir das vorzeichen ändern dies wird über den Invoice.Type geprüft
*
* @return
*/
@ -748,9 +728,9 @@ public class CargosoftXMLInvoiceImportService {
}
/**
* This method attache the pdf file and the XML file to the workitem.
* The method removes the file content first form the xml tree and attache the
* XML without the pdf data.
* This method attache the pdf file and the XML file to the workitem. The method
* removes the file content first form the xml tree and attache the XML without
* the pdf data.
*
* @throws XPathExpressionException
* @throws TransformerException
@ -761,16 +741,16 @@ public class CargosoftXMLInvoiceImportService {
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
// read filename and content....
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Filename",
workitem, "import.filename", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Content",
workitem, "import.filedata", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Filename", workitem,
"import.filename", String.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Content", workitem, "import.filedata",
String.class);
// attache the PDF file content
String fileDataString = workitem.getItemValueString("import.filedata");
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
FileData fileData = new FileData(workitem.getItemValueString("import.filename"),
decodedPDFData, "application/pdf", null);
FileData fileData = new FileData(workitem.getItemValueString("import.filename"), decodedPDFData,
"application/pdf", null);
workitem.addFileData(fileData);
// remove the temp items..
workitem.removeItem("import.filename");

View file

@ -52,7 +52,6 @@ import jakarta.json.bind.JsonbConfig;
public class ZohoAPIService {
private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
private static final String ZOHO_API_BASE_URL = "https://www.zohoapis.eu/books/v3/";
@Inject
ZohoOAuthManager zohoOAuthManager;
@ -62,12 +61,9 @@ public class ZohoAPIService {
@PostConstruct
void init() {
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
JsonbConfig config = new JsonbConfig()
.withDateFormat("yyyy-MM-dd", Locale.getDefault())
JsonbConfig config = new JsonbConfig().withDateFormat("yyyy-MM-dd", Locale.getDefault())
.setProperty("jsonb.fail-on-unknown-properties", false); // Ignoriert unbekannte Felder
this.jsonb = JsonbBuilder.create(config);
}
@ -78,20 +74,16 @@ public class ZohoAPIService {
logger.info("├── Zoho lookup contact '" + companyName + "'...");
try {
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
+ zohoOAuthManager.getOrganization() + "&company_name="
+ URLEncoder.encode(companyName, StandardCharsets.UTF_8);
logger.fine("│ ├── uri= " + uri);
logger.fine("│ ├── accessToken=" + accessToken);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
.header("Authorization", "Zoho-oauthtoken " + accessToken)
.header("Content-Type", "application/json")
.GET()
.build();
.header("Content-Type", "application/json").GET().build();
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// Print response details to console
logger.fine("├── Zoho Response:");
@ -99,12 +91,11 @@ public class ZohoAPIService {
logger.fine("│ ├── Response Body: " + response.body());
if (response.statusCode() >= 300) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to find Contacts - Status code: " + response.statusCode() +
", Response: " + response.body());
"Failed to find Contacts - Status code: " + response.statusCode() + ", Response: "
+ response.body());
}
ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(),
ZohoContactFindResponse.class);
ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(), ZohoContactFindResponse.class);
if (contactsResponse != null && contactsResponse.getContacts() != null) {
// Durchsuche die Ergebnisse nach exakter Übereinstimmung
@ -117,8 +108,7 @@ public class ZohoAPIService {
}
return null;
} catch (Exception e) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to find contacts", e);
throw new PluginException(this.getClass().getName(), "Zoho API error", "Failed to find contacts", e);
}
}
@ -155,19 +145,16 @@ public class ZohoAPIService {
logger.fine("│ ├── " + requestBody);
// https://www.zohoapis.com/books/v3/invoices?organization_id=10234695'
String uri = ZOHO_API_BASE_URL + "invoices?organization_id="
String uri = zohoOAuthManager.getBaseURI() + "invoices?organization_id="
+ zohoOAuthManager.getOrganization();
logger.fine("│ ├── uri= " + uri);
logger.fine("│ ├── accessToken=" + accessToken);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
.header("Authorization", "Zoho-oauthtoken " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// Print response details to console
logger.fine("├── Zoho Response:");
@ -175,8 +162,8 @@ public class ZohoAPIService {
if (response.statusCode() >= 300) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to create invoice. Status code: " + response.statusCode() +
", Response: " + response.body());
"Failed to create invoice. Status code: " + response.statusCode() + ", Response: "
+ response.body());
}
// Erfolgreiche Erstellung
@ -184,8 +171,7 @@ public class ZohoAPIService {
logger.fine("│ ├── Response Body: " + bodyContent);
System.out.print(bodyContent);
ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent,
ZohoInvoiceCreateResponse.class);
ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoInvoiceCreateResponse.class);
logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
@ -196,8 +182,7 @@ public class ZohoAPIService {
// now add attachments (optional)
if (files != null) {
for (FileData file : files) {
attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices",
accessToken);
attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
}
}
@ -233,30 +218,26 @@ public class ZohoAPIService {
// JSON serialisieren
String requestBody = jsonb.toJson(newContact);
logger.fine("│ ├── " + requestBody);
String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
+ zohoOAuthManager.getOrganization();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
.header("Authorization", "Zoho-oauthtoken " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.fine("├── Zoho Response:");
logger.fine("│ ├── Status Code: " + response.statusCode());
logger.fine("│ ├── Response Body: " + response.body());
if (response.statusCode() >= 300) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to create invoice. Status code: " + response.statusCode() +
", Response: " + response.body());
"Failed to create invoice. Status code: " + response.statusCode() + ", Response: "
+ response.body());
}
// Erfolgreiche Erstellung
ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(),
ZohoContactCreateResponse.class);
ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(), ZohoContactCreateResponse.class);
if (createResponse != null) {
logger.info("│ ├── OK - contactID=" + createResponse.getContact().getContactId());
return createResponse.getContact();
@ -277,25 +258,20 @@ public class ZohoAPIService {
ZohoInvoice zohoInvoice = new ZohoInvoice();
// Basisinformationen
logger.fine("invoice.date=" + invoice.getItemValueDate("invoice.date"));
logger.fine("invoice.duedate=" + invoice.getItemValueDate("invoice.duedate"));
// LocalDate.ofInstant(date.toInstant(), ZoneId.systemDefault())
zohoInvoice.setInvoiceNumber(invoice.getItemValueString("invoice.number"));
zohoInvoice.setDate(
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(),
ZoneId.systemDefault()));
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
zohoInvoice.setDueDate(
LocalDate.ofInstant(invoice.getItemValueDate("invoice.duedate").toInstant(),
ZoneId.systemDefault()));
LocalDate.ofInstant(invoice.getItemValueDate("invoice.duedate").toInstant(), ZoneId.systemDefault()));
zohoInvoice.setTotal(invoice.getItemValueDouble("invoice.total"));
// Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst)
zohoInvoice.setCustomerId(contactID);
List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
List<ZohoInvoiceItem> lineItems = positionen.stream()
.map(item -> {
List<ZohoInvoiceItem> lineItems = positionen.stream().map(item -> {
ItemCollection itemCol = (ItemCollection) item;
ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
lineItem.setName(itemCol.getItemValueString("datev.text"));
@ -303,8 +279,7 @@ public class ZohoAPIService {
lineItem.setRate(itemCol.getItemValueDouble("datev.umsatz"));
lineItem.setQuantity(1);
return lineItem;
})
.collect(Collectors.toList());
}).collect(Collectors.toList());
zohoInvoice.setLineItems(lineItems);
return zohoInvoice;
@ -321,7 +296,9 @@ public class ZohoAPIService {
*/
public void attacheFileData(String invoiceId, FileData file, String uriPattern, String accessToken)
throws PluginException {
String uri = ZOHO_API_BASE_URL + uriPattern + "/" + invoiceId + "/attachment" +
String uri = zohoOAuthManager.getBaseURI() + uriPattern + "/" + //
invoiceId + //
"/attachment" + //
"?organization_id=" + zohoOAuthManager.getOrganization();
logger.info("│ ├── add attachment '" + file.getName() + "'...");
@ -332,29 +309,22 @@ public class ZohoAPIService {
String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
// Build multipart request body
byte[] header = ("--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"attachment\"; filename=\""
+ file.getName() + "\"\r\n" +
"Content-Type: " + file.getContentType() + "\r\n\r\n")
.getBytes(StandardCharsets.UTF_8);
byte[] header = ("--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"attachment\"; filename=\"" + file.getName() + "\"\r\n"
+ "Content-Type: " + file.getContentType() + "\r\n\r\n").getBytes(StandardCharsets.UTF_8);
byte[] footer = ("\r\n--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8);
logger.fine("│ ├── content size=" + file.getContent().length);
HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.ofByteArrays(
Arrays.asList(header, file.getContent(), footer));
HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers
.ofByteArrays(Arrays.asList(header, file.getContent(), footer));
// Create and send the request
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
.header("Authorization", "Zoho-oauthtoken " + accessToken)
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.POST(bodyPublisher)
.build();
.header("Content-Type", "multipart/form-data; boundary=" + boundary).POST(bodyPublisher).build();
HttpResponse<String> response = httpClient.send(
request,
HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.fine("├── Zoho Response:");
logger.fine("│ ├── Status Code: " + response.statusCode());
@ -362,8 +332,8 @@ public class ZohoAPIService {
if (response.statusCode() >= 300) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to add attachment. Status code: " + response.statusCode() +
", Response: " + response.body());
"Failed to add attachment. Status code: " + response.statusCode() + ", Response: "
+ response.body());
}
logger.info("│ ├── OK - Attachment added successfully");

View file

@ -52,8 +52,8 @@ import jakarta.ws.rs.core.MediaType;
* verwenden!
*
* Der Service stellt im Grunde nur eine Callback URL für einen normalen Zoho
* Client ein. Also wenn jemand einen solchen Token über den Browser
* anfordert. Der URL muss dann odrt als CallBack URL angegeben sein!
* Client ein. Also wenn jemand einen solchen Token über den Browser anfordert.
* Der URL muss dann odrt als CallBack URL angegeben sein!
*
* Beispiel:
*
@ -90,8 +90,7 @@ public class ZohoOAuthCallbackService {
*
* state=testing
* code=1000.c27802b99c007ad8db93a5a7291cb15a.8cb60b6a51df13ea627ef3ac7c2e4791
* location=eu
* accounts-server=https%3A%2F%2Faccounts.zoho.eu
* location=eu accounts-server=https%3A%2F%2Faccounts.zoho.eu
*
*
* @param workflowgroup
@ -102,11 +101,8 @@ public class ZohoOAuthCallbackService {
@GET
@Path("/grant")
@Produces({ MediaType.TEXT_HTML })
public String getGrantToken(
@QueryParam("state") String state,
@QueryParam("code") String code,
@QueryParam("location") String location,
@QueryParam("accounts-server") String accountsServer)
public String getGrantToken(@QueryParam("state") String state, @QueryParam("code") String code,
@QueryParam("location") String location, @QueryParam("accounts-server") String accountsServer)
throws QueryException {
logger.info("├── Receive Grant Token from Zoho");

View file

@ -47,9 +47,7 @@ public class ZohoOAuthManager {
@PostConstruct
void init() {
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
this.jsonb = JsonbBuilder.create();
}
@ -87,6 +85,18 @@ public class ZohoOAuthManager {
return null;
}
public String getBaseURI() throws PluginException {
String uri = "";
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
if (zohoConfig != null) {
uri = zohoConfig.getItemValueString("zoho.uri");
if (!uri.endsWith("/")) {
uri = uri + "/";
}
}
return uri;
}
/**
* Step 3: Generate Access and Refresh Token
*
@ -107,24 +117,21 @@ public class ZohoOAuthManager {
String clientID = zohoConfig.getItemValueString("zoho.clientid");
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
"?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8) +
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
"&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
"&redirect_uri=" + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
"&grant_type=authorization_code";
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
+ URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
logger.fine("│ ├── Request URI=" + requestUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
.build();
HttpResponse<String> response;
response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.fine("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
@ -132,23 +139,20 @@ public class ZohoOAuthManager {
logger.fine("│ ├── Response Body=" + response.body());
if (response.body().contains("error")) {
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
ZohoOAuthManager.ERROR_CONFIG,
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
"Ungültiger Access Code!");
}
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
TokenResponse.class);
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
saveTokenData(zohoConfig, tokenResponse);
} else {
throw new RuntimeException("Failed to get tokens: " +
response.statusCode() + " - " + response.body());
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
}
} catch (IOException | InterruptedException e) {
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
ZohoOAuthManager.ERROR_CONFIG, "Unable to resolve access tokens: " + e.getMessage());
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
"Unable to resolve access tokens: " + e.getMessage());
}
}
@ -168,26 +172,21 @@ public class ZohoOAuthManager {
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
try {
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
"?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
"&client_secret=" + URLEncoder.encode(clientSecret,
StandardCharsets.UTF_8)
+
"&grant_type=refresh_token";
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?refresh_token="
+ URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
logger.fine("│ ├── Request URI=" + requestUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
.build();
HttpResponse<String> response;
response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.fine("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
@ -195,19 +194,17 @@ public class ZohoOAuthManager {
// 1. Response-Logging für Debugging
logger.fine("│ ├── Response Body=" + response.body());
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
TokenResponse.class);
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
saveTokenData(zohoConfig, tokenResponse);
return zohoConfig.getItemValueString("zoho.accessToken");
} else {
throw new RuntimeException("Failed to get tokens: " +
response.statusCode() + " - " + response.body());
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
}
} catch (IOException | InterruptedException e) {
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
ZohoOAuthManager.ERROR_CONFIG, "Unable to refresh access tokens: " + e.getMessage());
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
"Unable to refresh access tokens: " + e.getMessage());
}
}

View file

@ -114,8 +114,7 @@ public class AnalyticController implements Serializable {
}
/**
* Computes an analytic value. The method cache the value in the
* item key.
* Computes an analytic value. The method cache the value in the item key.
*
* An observer controller is responsible to cache or reset the cached values if
* needed.

View file

@ -12,7 +12,7 @@
/*<![CDATA[*/
function handleSubmit(event) {
// remove ajax kringel
setTimeout(function() {
setTimeout(function () {
document.body.classList.remove('loading');
}, 5000);
}
@ -32,7 +32,8 @@
<h:panelGroup layout="block" styleClass="imixs-body" id="analyse_panel">
<div class="imixs-form-panel">
<div class="ui-state-highlight ui-corner-all" style="margin-bottom: 10px; padding: .5em;">
<p>Der folgende Report exportiert <i>Ausgangsrechnungen</i>, in eine Excel Datei. Der Export ist auf maximal 3000 Einträge pro Tabelle beschränkt
<p>Der folgende Report exportiert <i>Ausgangsrechnungen</i>, in eine Excel Datei. Der
Export ist auf maximal 3000 Einträge pro Tabelle beschränkt
</p>
</div>
<div class="imixs-form-section-2">
@ -67,10 +68,12 @@
<dd>
<h:selectOneMenu noSelectionOption="true"
value="#{excelExportController.filter.item['space.ref']}">
<f:selectItem itemLabel=" - " itemValue="-" ></f:selectItem>
<c:forEach items="#{spaceRefFormController.getSpaces(workflowController.workitem, options)}"
<f:selectItem itemLabel=" - " itemValue="-"></f:selectItem>
<c:forEach
items="#{spaceRefFormController.getSpaces(workflowController.workitem, options)}"
var="space">
<f:selectItem itemLabel="#{space.item['name']}" itemValue="#{space.item['$UniqueID']}">
<f:selectItem itemLabel="#{space.item['name']}"
itemValue="#{space.item['$UniqueID']}">
</f:selectItem>
</c:forEach>
</h:selectOneMenu>
@ -82,7 +85,7 @@
Debitor:
</dt>
<dd>
<ui:include src="/pages/workitems/parts/alexander/debitor_search.xhtml" >
<ui:include src="/pages/workitems/parts/alexander/businesspartner_search.xhtml">
<ui:param name="workitem" value="#{workflowController.workitem}" />
<ui:param name="item" value="#{excelExportController.item}" />
</ui:include>
@ -94,8 +97,7 @@
Positionsnummer:
</dt>
<dd>
<h:inputText
value="#{excelExportController.filter.item['invoice.text']}">
<h:inputText value="#{excelExportController.filter.item['invoice.text']}">
</h:inputText>
</dd>
</dl>

View file

@ -19,13 +19,13 @@
/*]]>*/
</script>
<h:form id="import_form_id">
<h:form id="import_form_id" autocomplete="off">
<div class="imixs-form">
<div class="imixs-header">
<h1>ZOHO - API </h1>
<!-- ########## Error ########## -->
<ui:include src="/error_message.xhtml" />
</div>
<div class="imixs-body">
@ -41,8 +41,27 @@
<!-- API Tokens -->
<div class="imixs-form-section-2">
<dl>
<dt>Client ID</dt>
<dt>API Base URL <span class="imixs-required">*</span></dt>
<dd>
<h:inputText required="true"
value="#{zohoController.workitem.item['zoho.uri']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>Organization <span class="imixs-required">*</span></dt>
<dd>
<h:inputText required="true"
value="#{zohoController.workitem.item['zoho.organization']}">
</h:inputText>
</dd>
</dl>
<dl>
<dt>Client ID <span class="imixs-required">*</span></dt>
<dd>
<h:inputText required="false"
value="#{zohoController.workitem.item['zoho.clientid']}">
@ -51,27 +70,20 @@
</dd>
</dl>
<dl>
<dt>Client Secret</dt>
<dt>Client Secret <span class="imixs-required">*</span></dt>
<dd>
<h:inputSecret required="false" redisplay="true"
value="#{zohoController.workitem.item['zoho.clientsecret']}">
</h:inputSecret>
</dd>
</dl>
<dl>
<dt>Organization</dt>
<dd>
<h:inputText required="false"
value="#{zohoController.workitem.item['zoho.organization']}">
</h:inputText>
</dd>
</dl>
</div>
<!-- Grant Token -->
<div class="imixs-form-section-2">
<dl>
<dt>Access Code</dt>
<dt>Access Code <span class="imixs-required">*</span> </dt>
<dd>
<h:inputSecret required="false" redisplay="true"
value="#{zohoController.workitem.item['zoho.code']}">

View file

@ -59,8 +59,8 @@ public class TestIMAPOutlookOAuth {
/*
* Neue Daten
*
* Wert: zDL8Q~iEy8AX~dEmIOHrVv3aBTCZLrHIFmShibZ_
* Geheime ID: bcaa558a-3300-4498-94e1-2267f418afd5
* Wert: zDL8Q~iEy8AX~dEmIOHrVv3aBTCZLrHIFmShibZ_ Geheime ID:
* bcaa558a-3300-4498-94e1-2267f418afd5
*/
@Test

View file

@ -66,34 +66,20 @@ public class DueDateBugfix {
* Erledigte
*
*
* EXTF_202301_202302030602_1295
* EXTF_202301_202302060601_1296
* EXTF_202301_202302070603_1297
* EXTF_202301_202302080603_1298
* EXTF_202301_202302090604_1299
* EXTF_202301_202302100603_1300
* EXTF_202301_202302130601_1301
* EXTF_202301_202302140604_1302
* EXTF_202301_202302141840_1303
* EXTF_202301_202302160944_1304
* EXTF_202302_202302020601_1294
* EXTF_202302_202302030602_1295
* EXTF_202302_202302060601_1296
* EXTF_202302_202302070603_1297
* EXTF_202302_202302080603_1298
* EXTF_202302_202302090604_1299
* EXTF_202302_202302100604_1300
* EXTF_202302_202302130601_1301
* EXTF_202302_202302140604_1302
* EXTF_202302_202302141840_1303
* EXTF_202302_202302160944_1304
* EXTF_202303_202302070603_1297
* EXTF_202303_202302080603_1298
* EXTF_202303_202302090604_1299
* EXTF_202303_202302100603_1300
* EXTF_202303_202302130601_1301
* EXTF_202303_202302140604_1302
* EXTF_202303_202302141840_1303
* EXTF_202301_202302030602_1295 EXTF_202301_202302060601_1296
* EXTF_202301_202302070603_1297 EXTF_202301_202302080603_1298
* EXTF_202301_202302090604_1299 EXTF_202301_202302100603_1300
* EXTF_202301_202302130601_1301 EXTF_202301_202302140604_1302
* EXTF_202301_202302141840_1303 EXTF_202301_202302160944_1304
* EXTF_202302_202302020601_1294 EXTF_202302_202302030602_1295
* EXTF_202302_202302060601_1296 EXTF_202302_202302070603_1297
* EXTF_202302_202302080603_1298 EXTF_202302_202302090604_1299
* EXTF_202302_202302100604_1300 EXTF_202302_202302130601_1301
* EXTF_202302_202302140604_1302 EXTF_202302_202302141840_1303
* EXTF_202302_202302160944_1304 EXTF_202303_202302070603_1297
* EXTF_202303_202302080603_1298 EXTF_202303_202302090604_1299
* EXTF_202303_202302100603_1300 EXTF_202303_202302130601_1301
* EXTF_202303_202302140604_1302 EXTF_202303_202302141840_1303
* EXTF_202303_202302160944_1304
*
*/

View file

@ -17,8 +17,8 @@ import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.Response;
/**
* Test to request data via a JSESSIONID only....
* This technique is used by the DataRestService
* Test to request data via a JSESSIONID only.... This technique is used by the
* DataRestService
*
*/
@Ignore
@ -36,11 +36,8 @@ public class TestDataClient {
@BeforeEach
public void setup() throws PluginException {
// Create a Cookie object with a name and a value
Cookie cookie = new Cookie.Builder("JSESSIONID")
.value(sessionID)
.path("/")
.domain("alexander-logistics.office-workflow.de")
.build();
Cookie cookie = new Cookie.Builder("JSESSIONID").value(sessionID).path("/")
.domain("alexander-logistics.office-workflow.de").build();
client = new DocumentClient(restAPI.trim());
CookieAuthenticator aut = new CookieAuthenticator(cookie);

View file

@ -52,9 +52,7 @@ public class TestUpdateTokens {
@BeforeEach
public void setup() throws PluginException, ModelException {
logger.info("setup test environment ...");
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
this.jsonb = JsonbBuilder.create();
}
@ -72,25 +70,22 @@ public class TestUpdateTokens {
code = "1000.48bd85a3965cf724f4691757cfd8d93b.8ae5e3ee7d70f90d307da4d289a9b067";
try {
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
"?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8) +
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
"&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
"&redirect_uri=" + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
"&grant_type=authorization_code";
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
+ URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
logger.info("│ ├── Request URI=" + requestUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
.build();
HttpResponse<String> response;
response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.info("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
@ -101,8 +96,7 @@ public class TestUpdateTokens {
assertNotNull(response.body());
assertFalse(response.body().contains("error"));
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
TokenResponse.class);
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
accessToken = tokenResponse.getAccess_token();
assertNotNull(accessToken);
@ -111,8 +105,7 @@ public class TestUpdateTokens {
logger.info("│ ├── refreshToken=" + refreshToken);
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
} else {
throw new RuntimeException("Failed to get tokens: " +
response.statusCode() + " - " + response.body());
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
}
} catch (IOException | InterruptedException e) {
@ -136,24 +129,21 @@ public class TestUpdateTokens {
refreshToken = "1000.cf458816e97f848df8134ce1c7e923a1.5b9dbdee317e35d7f0c619e7648d55ff";
try {
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
"?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
"&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
"&grant_type=refresh_token";
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?refresh_token="
+ URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
logger.info("│ ├── Request URI=" + requestUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
.build();
HttpResponse<String> response;
response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.info("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
@ -161,15 +151,13 @@ public class TestUpdateTokens {
// 1. Response-Logging für Debugging
logger.info("│ ├── Response Body=" + response.body());
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
TokenResponse.class);
TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
String accessToken = tokenResponse.getAccess_token();
logger.info("│ ├── accessToken=" + accessToken);
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
} else {
throw new RuntimeException("Failed to get tokens: " +
response.statusCode() + " - " + response.body());
throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
}
} catch (IOException | InterruptedException e) {
@ -196,15 +184,10 @@ public class TestUpdateTokens {
String url = "https://www.zohoapis.eu/books/v3/organizations";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.header("Authorization", "Zoho-oauthtoken " + accessToken)
.build();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET()
.header("Authorization", "Zoho-oauthtoken " + accessToken).build();
HttpResponse<String> response = httpClient.send(
request,
HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.info("│ ├── Response statusCode=" + response.statusCode());
@ -227,8 +210,8 @@ public class TestUpdateTokens {
* Token
*
*
* curl --request GET \
* --url 'https://www.zohoapis.com/books/v3/invoices?organization_id=10234695' \
* curl --request GET \ --url
* 'https://www.zohoapis.com/books/v3/invoices?organization_id=10234695' \
* --header 'Authorization: Zoho-oauthtoken
* 1000.41d9xxxxxxxxxxxxxxxxxxxxxxxxc2d1.8fccxxxxxxxxxxxxxxxxxxxxxxxx125f'
*
@ -244,15 +227,10 @@ public class TestUpdateTokens {
String url = "https://www.zohoapis.eu/books/v3/invoices?organization_id=20105697367";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.header("Authorization", "Zoho-oauthtoken " + accessToken)
.build();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET()
.header("Authorization", "Zoho-oauthtoken " + accessToken).build();
HttpResponse<String> response = httpClient.send(
request,
HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.info("│ ├── Response statusCode=" + response.statusCode());

View file

@ -1,97 +1,97 @@
{
"code": 0,
"message": "success",
"invoices": [
"code" : 0,
"message" : "success",
"invoices" : [
{
"ach_payment_initiated": false,
"invoice_id": "777249000000055583",
"zcrm_potential_id": "",
"customer_id": "777249000000055569",
"zcrm_potential_name": "",
"customer_name": "Mr. Foo",
"company_name": "",
"status": "overdue",
"invoice_number": "INV-000001",
"reference_number": "23452345",
"date": "2025-04-21",
"due_date": "2025-04-21",
"due_days": "Overdue by 3 days",
"email": "ralph.soika@imixs.com",
"project_name": "",
"billing_address": {
"address": "",
"street2": "",
"city": "",
"state": "",
"zipcode": "",
"country": "",
"phone": "",
"fax": "",
"attention": ""
"ach_payment_initiated" : false,
"invoice_id" : "777249000000055583",
"zcrm_potential_id" : "",
"customer_id" : "777249000000055569",
"zcrm_potential_name" : "",
"customer_name" : "Mr. Foo",
"company_name" : "",
"status" : "overdue",
"invoice_number" : "INV-000001",
"reference_number" : "23452345",
"date" : "2025-04-21",
"due_date" : "2025-04-21",
"due_days" : "Overdue by 3 days",
"email" : "ralph.soika@imixs.com",
"project_name" : "",
"billing_address" : {
"address" : "",
"street2" : "",
"city" : "",
"state" : "",
"zipcode" : "",
"country" : "",
"phone" : "",
"fax" : "",
"attention" : ""
},
"shipping_address": {
"address": "",
"street2": "",
"city": "",
"state": "",
"zipcode": "",
"country": "",
"phone": "",
"fax": "",
"attention": ""
"shipping_address" : {
"address" : "",
"street2" : "",
"city" : "",
"state" : "",
"zipcode" : "",
"country" : "",
"phone" : "",
"fax" : "",
"attention" : ""
},
"country": "",
"phone": "",
"created_by": "Ralph Soika",
"total": 50.00,
"balance": 50.00,
"payment_expected_date": "",
"custom_fields": [],
"custom_field_hash": {},
"tags": [],
"salesperson_name": "",
"shipping_charge": 0.00,
"adjustment": 0.00,
"created_time": "2025-04-21T13:36:26+0200",
"last_modified_time": "2025-04-21T13:42:56+0200",
"updated_time": "2025-04-21T13:42:56+0200",
"is_viewed_by_client": false,
"has_attachment": true,
"client_viewed_time": "",
"is_viewed_in_mail": false,
"is_emailed": true,
"mail_first_viewed_time": "",
"mail_last_viewed_time": "",
"is_correction_invoice": false,
"color_code": "",
"current_sub_status_id": "",
"current_sub_status": "overdue",
"currency_id": "777249000000000071",
"schedule_time": "",
"currency_code": "EUR",
"currency_symbol": "€",
"template_type": "standard",
"invoice_url": "https://zohosecurepay.eu/books/imixs/secure?CInvoiceID=2-64277fbd3cd8bc86f8e581a3a7e1544618c191c094de1ae938827291b0828c92b5f796a1ec94bfb1fdcce7621ddf18bf61770563d9fd283207b7fa0e24d232a416b0b5e010c61cd7 ",
"transaction_type": "renewal",
"reminders_sent": 0,
"last_reminder_sent_date": "",
"last_payment_date": "",
"template_id": "777249000000000103",
"documents": "",
"salesperson_id": "",
"write_off_amount": 0.00,
"exchange_rate": 1.00,
"unprocessed_payment_amount": 0.00
"country" : "",
"phone" : "",
"created_by" : "Ralph Soika",
"total" : 50.0,
"balance" : 50.0,
"payment_expected_date" : "",
"custom_fields" : [ ],
"custom_field_hash" : { },
"tags" : [ ],
"salesperson_name" : "",
"shipping_charge" : 0.0,
"adjustment" : 0.0,
"created_time" : "2025-04-21T13:36:26+0200",
"last_modified_time" : "2025-04-21T13:42:56+0200",
"updated_time" : "2025-04-21T13:42:56+0200",
"is_viewed_by_client" : false,
"has_attachment" : true,
"client_viewed_time" : "",
"is_viewed_in_mail" : false,
"is_emailed" : true,
"mail_first_viewed_time" : "",
"mail_last_viewed_time" : "",
"is_correction_invoice" : false,
"color_code" : "",
"current_sub_status_id" : "",
"current_sub_status" : "overdue",
"currency_id" : "777249000000000071",
"schedule_time" : "",
"currency_code" : "EUR",
"currency_symbol" : "€",
"template_type" : "standard",
"invoice_url" : "https://zohosecurepay.eu/books/imixs/secure?CInvoiceID=2-64277fbd3cd8bc86f8e581a3a7e1544618c191c094de1ae938827291b0828c92b5f796a1ec94bfb1fdcce7621ddf18bf61770563d9fd283207b7fa0e24d232a416b0b5e010c61cd7 ",
"transaction_type" : "renewal",
"reminders_sent" : 0,
"last_reminder_sent_date" : "",
"last_payment_date" : "",
"template_id" : "777249000000000103",
"documents" : "",
"salesperson_id" : "",
"write_off_amount" : 0.0,
"exchange_rate" : 1.0,
"unprocessed_payment_amount" : 0.0
}
],
"page_context": {
"page": 1,
"per_page": 200,
"has_more_page": false,
"report_name": "Invoices",
"applied_filter": "Status.All",
"custom_fields": [],
"sort_column": "created_time",
"sort_order": "D"
"page_context" : {
"page" : 1,
"per_page" : 200,
"has_more_page" : false,
"report_name" : "Invoices",
"applied_filter" : "Status.All",
"custom_fields" : [ ],
"sort_column" : "created_time",
"sort_order" : "D"
}
}

39
pom.xml
View file

@ -128,8 +128,45 @@
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
<!-- Imixs Code Formatter and Checkstyle -->
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>2.26.0</version>
<configuration>
<configFile>
https://raw.githubusercontent.com/imixs/imixs-workflow/refs/heads/master/imixs-code-style.xml</configFile>
<lineEnding>LF</lineEnding>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<configLocation>
https://raw.githubusercontent.com/imixs/imixs-workflow/master/imixs-checkstyle-8.44.xml</configLocation>
<failOnViolation>true</failOnViolation>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>office-alexander-logistics</finalName>
</build>
<dependencyManagement>

View file

@ -74,6 +74,7 @@
<bpmn2:flowNodeRef>event_kT136g</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_jkHxJA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_zzWQSA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_k4Ms1Q</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:task id="task_ToMZaQ" imixs:processid="1000" name="Neuanlage">
@ -155,6 +156,7 @@
<bpmn2:outgoing>sequenceFlow_03b60w</bpmn2:outgoing>
<bpmn2:incoming>sequenceFlow_u8PLGw</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_ZTiO7w</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_gIdPow</bpmn2:incoming>
</bpmn2:task>
<bpmn2:task id="task_B8Pi7A" imixs:processid="1800" name="Locked">
<bpmn2:extensionElements>
@ -719,7 +721,40 @@
<bpmn2:sequenceFlow id="sequenceFlow_ZTiO7w" sourceRef="event_zzWQSA" targetRef="task_Q80A1Q">
<bpmn2:documentation id="documentation_S2i1Tg"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_k4Ms1Q" imixs:activityid="30" name="Excel Export">
<bpmn2:extensionElements>
<imixs:item name="rtfresultlog" type="xs:string">
<imixs:value><![CDATA[Analysis data archived and Excel report generated]]></imixs:value>
</imixs:item>
<imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[1]]></imixs:value>
</imixs:item>
<imixs:item name="txtactivityresult" type="xs:string">
<imixs:value><![CDATA[<soa name="excel-export">
<textblock>SOA Template</textblock>
<template>soa_template.xlsx</template>
<target-name>soa_<itemvalue>dbtr.number</itemvalue>_<itemvalue format="yyyy-MM-dd">$lasteventdate</itemvalue>.xlsx</target-name>
</soa>
<poi-update name="findreplace">
<find>F6</find>
<replace><itemvalue format="dd.MM.yyyy">$lasteventdate</itemvalue></replace>
<type>date</type>
</poi-update>
<poi-update name="findreplace">
<find>A7</find>
<replace><itemvalue>dbtr.name</itemvalue></replace>
</poi-update>]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements>
<bpmn2:documentation id="documentation_r37NEQ"/>
<bpmn2:signalEventDefinition id="signalEventDefinition_rRKGpw" signalRef="signal_1"/>
<bpmn2:outgoing>sequenceFlow_gIdPow</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_gIdPow" sourceRef="event_k4Ms1Q" targetRef="task_Q80A1Q">
<bpmn2:documentation id="documentation_q0cGQQ"/>
</bpmn2:sequenceFlow>
</bpmn2:process>
<bpmn2:signal id="signal_1" name="com.alexanderlogistics.AGLAnalyticExcelAdapterDebitor"/>
<bpmndi:BPMNDiagram id="BPMNDiagram_1" name="OpenBPMN Diagram">
<bpmndi:BPMNPlane bpmnElement="collaboration_1" id="BPMNPlane_1">
<bpmndi:BPMNShape bpmnElement="event_WmkBvw" id="BPMNShape_heefeQ">
@ -1070,6 +1105,18 @@
<di:waypoint x="714.0" y="465.0"/>
<di:waypoint x="690.0" y="465.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_k4Ms1Q" id="BPMNShape_m0PeLw">
<dc:Bounds height="36.0" width="36.0" x="827.0" y="357.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_fOaAtQ">
<dc:Bounds height="20.0" width="100.0" x="795.0" y="396.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_gIdPow" id="BPMNEdge_QW8gQQ" sourceElement="BPMNShape_m0PeLw" targetElement="BPMNShape_7JA0nw">
<di:waypoint x="827.0" y="375.0"/>
<di:waypoint x="759.0" y="375.0"/>
<di:waypoint x="759.0" y="465.0"/>
<di:waypoint x="690.0" y="465.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>